update user & reward

This commit is contained in:
Raja Oktafrianto
2025-04-12 13:27:16 +07:00
parent 4afc55952f
commit a44bbcc77a
5 changed files with 63 additions and 68 deletions

View File

@ -34,24 +34,25 @@ const DeleteDialog = () => {
return; return;
} }
// console.log('Ini datanya:', selectedReward); // console.log('Ini datanya:', selectedReward);
const response = await DeleteData(`${API_URL}/reward/delete/${selectedReward?.id}/true`, { const response = await DeleteData(`${API_URL}/reward/delete/${selectedReward}/true`, {
id: selectedReward.id id: selectedReward
}); });
// console.log('Response Delete:', response);
if (response?.status) { if (response?.status) {
setAlert({ show: false, message: '' }); setAlert((prev) => ({ ...prev, show: false, message: '' }));
handleDeleteDialog(false, null); handleDeleteDialog(false, null);
toast.success('Success Delete Reward'); toast.success('Success Delete Reward');
reload(); reload();
const deleteActivity = { const createActivity = {
module: 'Manage Reward', module: 'Manage Reward',
description: `Delete Reward => ${selectedReward}`, description: `Delete Reward => ${selectedReward}`,
action: 'D' action: 'D'
}; };
doSaveLogActivity(deleteActivity); doSaveLogActivity(createActivity);
} else { } else {
setAlert({ show: true, message: response?.message }); setAlert((prev) => ({ ...prev, show: true, message: response?.message }));
toast.error('Failed Delete Reward'); toast.error('Failed Delete Reward');
} }
}, [selectedReward, DeleteData, handleDeleteDialog, reload]); }, [selectedReward, DeleteData, handleDeleteDialog, reload]);

View File

@ -58,7 +58,9 @@ const EditDialog = () => {
const RewardType = { const RewardType = {
'Daily Check in': 'D', 'Daily Check in': 'D',
Referal: 'R' Referal: 'R',
'Level Pro': 'P',
'Level Prioritas': 'L'
} as const; } as const;
type RewardTypeValue = (typeof RewardType)[keyof typeof RewardType]; type RewardTypeValue = (typeof RewardType)[keyof typeof RewardType];
@ -68,7 +70,7 @@ const EditDialog = () => {
e.preventDefault(); e.preventDefault();
// console.log('Ini datanya:', selectedReward); // console.log('Ini datanya:', selectedReward);
const response = await PutData(`${API_URL}/reward/update/${selectedReward?.id}`, formField); const response = await PutData(`${API_URL}/reward/update/${selectedReward}`, formField);
if (response?.status) { if (response?.status) {
resetForm(); resetForm();
@ -126,7 +128,7 @@ const EditDialog = () => {
useEffect(() => { useEffect(() => {
if (selectedReward) { if (selectedReward) {
doFetchData(selectedReward.id.toString()); doFetchData(selectedReward);
} }
}, [selectedReward]); }, [selectedReward]);

View File

@ -6,7 +6,7 @@ import React, { createContext, useCallback, useMemo, useState } from 'react';
import { Toaster } from 'sonner'; import { Toaster } from 'sonner';
import ListToolbar from '../blocks/ListToolbar'; import ListToolbar from '../blocks/ListToolbar';
interface Reward { interface SelectedReward {
id: number; id: number;
name: string; name: string;
type: string; type: string;
@ -14,23 +14,14 @@ interface Reward {
status: string; status: string;
} }
const initialState = {
id: '',
name: '',
type: '',
amount: '',
status: ''
};
interface ContextProps { interface ContextProps {
showAddDialog: boolean; showAddDialog: boolean;
handleAddDialog: (show: boolean) => void; handleAddDialog: (show: boolean) => void;
showEditDialog: boolean; showEditDialog: boolean;
handleEditDialog: (show: boolean, selected_reward: Reward | null) => void; handleEditDialog: (show: boolean, selected_reward: string | null) => void;
showDeleteDialog: boolean; showDeleteDialog: boolean;
handleDeleteDialog: (show: boolean, selected_rewad: Reward | null) => void; handleDeleteDialog: (show: boolean, selected_reward: string | null) => void;
selectedReward: Reward | null; selectedReward: string | null;
reward: string | null;
} }
const initialProps: ContextProps = { const initialProps: ContextProps = {
@ -40,31 +31,29 @@ const initialProps: ContextProps = {
handleEditDialog: () => {}, handleEditDialog: () => {},
showDeleteDialog: false, showDeleteDialog: false,
handleDeleteDialog: () => {}, handleDeleteDialog: () => {},
selectedReward: null, selectedReward: null
reward: null
}; };
const ManageRewardContext = createContext<ContextProps>(initialProps); const ManageRewardContext = createContext<ContextProps>(initialProps);
const API_URL_MASTER_DATA = apiConfig.service_master_data; const API_URL_MASTER_DATA = apiConfig.service_master_data;
const ManageRewardContextProvider = ({ children }: { children: React.ReactNode }) => { const ManageRewardContextProvider = ({ children }: { children: React.ReactNode }) => {
const [reward, setRewards] = useState<string | null>(null);
const [showAddDialog, setShowAddDialog] = useState(false); const [showAddDialog, setShowAddDialog] = useState(false);
const [showEditDialog, setShowEditDialog] = useState(false); const [showEditDialog, setShowEditDialog] = useState(false);
const [showDeleteDialog, setShowDeleteDialog] = useState(false); const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [selectedReward, setSelectedReward] = useState<Reward | null>(null); const [selectedReward, setSelectedReward] = useState<string | null>(null);
const { GetData } = useCallApi(); const { GetData } = useCallApi();
const handleAddDialog = useCallback((show: boolean) => { const handleAddDialog = useCallback((show: boolean) => {
setShowAddDialog(show); setShowAddDialog(show);
}, []); }, []);
const handleEditDialog = useCallback((show: boolean, selected_reward: Reward | null) => { const handleEditDialog = useCallback((show: boolean, selected_reward: string | null) => {
setShowEditDialog(show); setShowEditDialog(show);
setSelectedReward(show ? selected_reward : null); setSelectedReward(show ? selected_reward : null);
}, []); }, []);
const handleDeleteDialog = useCallback((show: boolean, selected_reward: Reward | null) => { const handleDeleteDialog = useCallback((show: boolean, selected_reward: string | null) => {
setShowDeleteDialog(show); setShowDeleteDialog(show);
setSelectedReward(show ? selected_reward : null); setSelectedReward(show ? selected_reward : null);
}, []); }, []);
@ -135,13 +124,13 @@ const ManageRewardContextProvider = ({ children }: { children: React.ReactNode }
<> <>
<button <button
className="btn btn-sm btn-icon btn-clear btn-light" className="btn btn-sm btn-icon btn-clear btn-light"
onClick={() => handleEditDialog(true, row)} onClick={() => handleEditDialog(true, row.id)}
> >
<KeenIcon icon="notepad-edit" /> <KeenIcon icon="notepad-edit" />
</button> </button>
<button <button
className="btn btn-sm btn-icon btn-clear btn-light" className="btn btn-sm btn-icon btn-clear btn-light"
onClick={() => handleDeleteDialog(true, row)} onClick={() => handleDeleteDialog(true, row.id)}
> >
<KeenIcon icon="trash" /> <KeenIcon icon="trash" />
</button> </button>
@ -154,7 +143,7 @@ const ManageRewardContextProvider = ({ children }: { children: React.ReactNode }
} }
} }
], ],
[] [handleEditDialog, handleDeleteDialog]
); );
const getRewardList = async (page: number, limit: number, sorting: any, filter: any) => { const getRewardList = async (page: number, limit: number, sorting: any, filter: any) => {
@ -162,7 +151,7 @@ const ManageRewardContextProvider = ({ children }: { children: React.ReactNode }
sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting; sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting;
filter = filter.length == 0 ? {} : { any: filter[0].value?.toLowerCase() }; filter = filter.length == 0 ? {} : { any: filter[0].value?.toLowerCase() };
const response = await GetData(`${API_URL_MASTER_DATA}/reward/list`, { const response = await GetData(`${API_URL_MASTER_DATA}/reward/list`, {
limit, limit: limit,
page: page + 1, page: page + 1,
with_deleted: false, with_deleted: false,
order_field: sorting[0].id, order_field: sorting[0].id,
@ -171,7 +160,6 @@ const ManageRewardContextProvider = ({ children }: { children: React.ReactNode }
}); });
// console.log('API Response:', response?.data.list); // console.log('API Response:', response?.data.list);
// console.log('reward list :', response); // console.log('reward list :', response);
setRewards(response?.data.list);
return { data: response?.data.list, totalCount: response?.data.total_count }; return { data: response?.data.list, totalCount: response?.data.total_count };
} catch (error) { } catch (error) {
console.error('Error fethcing reward', error); console.error('Error fethcing reward', error);
@ -181,7 +169,6 @@ const ManageRewardContextProvider = ({ children }: { children: React.ReactNode }
return ( return (
<ManageRewardContext.Provider <ManageRewardContext.Provider
value={{ value={{
reward,
showAddDialog, showAddDialog,
handleAddDialog, handleAddDialog,
showEditDialog, showEditDialog,
@ -210,4 +197,4 @@ const ManageRewardContextProvider = ({ children }: { children: React.ReactNode }
}; };
export { ManageRewardContext, ManageRewardContextProvider }; export { ManageRewardContext, ManageRewardContextProvider };
export type { Reward }; export type { SelectedReward };

View File

@ -34,6 +34,7 @@ const DeleteDialog = () => {
const response = await DeleteData(`${API_URL}/user/delete/${selectedUser}/${enforce}`, { const response = await DeleteData(`${API_URL}/user/delete/${selectedUser}/${enforce}`, {
id: selectedUser id: selectedUser
}); });
// console.log('Delete Response User:', response);
if (response?.status) { if (response?.status) {
setAlert((prev) => ({ ...prev, show: false, message: '' })); setAlert((prev) => ({ ...prev, show: false, message: '' }));
handleDeleteDialog(false, null); handleDeleteDialog(false, null);

View File

@ -25,6 +25,7 @@ import {
} from '@/components/ui/dialog'; } from '@/components/ui/dialog';
import { CustomerProps } from './AddDialog'; import { CustomerProps } from './AddDialog';
import { useUserContext } from '../hooks'; import { useUserContext } from '../hooks';
import { ChevronDown } from 'lucide-react';
import { Input } from '@/components/ui/input'; import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button'; import { Button } from '@/components/ui/button';
import { apiConfig } from '@/config/api.config'; import { apiConfig } from '@/config/api.config';
@ -142,7 +143,7 @@ const EditDialog = () => {
const doFetchUserData = useCallback(async (id: string) => { const doFetchUserData = useCallback(async (id: string) => {
const response = await GetData(`${API_URL}/user/detail/${id}`, { id }); const response = await GetData(`${API_URL}/user/detail/${id}`, { id });
console.log('User detail response:', response?.data); // console.log('User detail response:', response?.data);
if (response?.status) { if (response?.status) {
setFormField((prev) => ({ setFormField((prev) => ({
@ -154,7 +155,7 @@ const EditDialog = () => {
status: response.data.status, status: response.data.status,
customerid: response.data.customerid customerid: response.data.customerid
})); }));
console.log('Customer ID dari user detail:', response.data.customerid); // console.log('Customer ID dari user detail:', response.data.customerid);
} else { } else {
setFormField((prev) => ({ setFormField((prev) => ({
...prev, ...prev,
@ -230,6 +231,34 @@ const EditDialog = () => {
)} )}
<form onSubmit={doUpdateUser}> <form onSubmit={doUpdateUser}>
<div className="card-body grid gap-5 p-0"> <div className="card-body grid gap-5 p-0">
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Name</label>
<Input
className="input"
type="text"
value={formField.name}
onChange={({ target }) =>
setFormField((prev) => ({ ...prev, name: target.value }))
}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Username</label>
<Input
className="input"
type="text"
value={formField.username}
onChange={({ target }) =>
setFormField((prev) => ({ ...prev, username: target.value }))
}
/>
</div>
</div>
<div className="w-full"> <div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5"> <div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Customer</label> <label className="form-label flex items-center gap-1 max-w-56">Customer</label>
@ -237,11 +266,14 @@ const EditDialog = () => {
<PopoverTrigger asChild> <PopoverTrigger asChild>
<button <button
type="button" type="button"
className="input col-span-5 text-left" className="input col-span-5 text-left flex justify-between"
style={{ color: 'inherit' }} style={{ color: 'inherit' }}
> >
{customers.find((customer) => customer.id === formField.customerid) <span>
?.username || 'Select Customer'} {customers.find((customer) => customer.id === formField.customerid)
?.username || 'Select Customer'}
</span>
<ChevronDown className="w-4 h-4 opacity-70" />
</button> </button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent className="w-[400px] p-0"> <PopoverContent className="w-[400px] p-0">
@ -279,34 +311,6 @@ const EditDialog = () => {
</div> </div>
</div> </div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Name</label>
<Input
className="input"
type="text"
value={formField.name}
onChange={({ target }) =>
setFormField((prev) => ({ ...prev, name: target.value }))
}
/>
</div>
</div>
<div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Username</label>
<Input
className="input"
type="text"
value={formField.username}
onChange={({ target }) =>
setFormField((prev) => ({ ...prev, username: target.value }))
}
/>
</div>
</div>
<div className="w-full"> <div className="w-full">
<div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5"> <div className="flex items-baseline flex-wrap lg:flex-nowrap gap-2.5">
<label className="form-label flex items-center gap-1 max-w-56">Email</label> <label className="form-label flex items-center gap-1 max-w-56">Email</label>