update manage user & manage reward

This commit is contained in:
Raja Oktafrianto
2025-04-10 17:45:39 +07:00
parent 42e91f376b
commit 59d74d4304
10 changed files with 295 additions and 203 deletions

View File

@ -4,36 +4,42 @@ import { ManageUserContextProvider } from './hooks';
import { AddDialog } from './blocks/AddDialog';
import { DeleteDialog } from './blocks/DeleteDialog';
import { Breadcrumbs, Link } from '@mui/material';
import { Helmet } from 'react-helmet';
export default function ManageUserPage() {
return (
<ManageUserContextProvider>
<Container>
<h1 className="text-xl font-medium leading-none text-gray-900 mb-3">Manage User</h1>
<Breadcrumbs sx={{ mb: 2 }}>
<Link underline="none" color="inherit" href="/">
<span className="text-sm hover:underline">Dashboard</span>
</Link>
<>
<Helmet>
<title>TPAY | Manage User</title>
</Helmet>
<ManageUserContextProvider>
<Container>
<h1 className="text-xl font-medium leading-none text-gray-900 mb-3">Manage User</h1>
<Breadcrumbs sx={{ mb: 2 }}>
<Link underline="none" color="inherit" href="/">
<span className="text-sm hover:underline">Dashboard</span>
</Link>
<Link underline="none" color="inherit">
<span className="text-sm">Settings</span>
</Link>
<Link underline="none" color="inherit">
<span className="text-sm">Settings</span>
</Link>
<Link underline="none" color="inherit">
<span className="text-sm">User Management</span>
</Link>
<Link underline="none" color="inherit">
<span className="text-sm">User Management</span>
</Link>
<Link underline="none" color="inherit">
<span className="text-sm">Manage User</span>
</Link>
</Breadcrumbs>
<div className="grid gap-5 lg:gap-7.5">
<DataGridInner />
</div>
<EditDialog />
<AddDialog />
<DeleteDialog />
</Container>
</ManageUserContextProvider>
<Link underline="none" color="inherit">
<span className="text-sm">Manage User</span>
</Link>
</Breadcrumbs>
<div className="grid gap-5 lg:gap-7.5">
<DataGridInner />
</div>
<EditDialog />
<AddDialog />
<DeleteDialog />
</Container>
</ManageUserContextProvider>
</>
);
}

View File

@ -25,6 +25,13 @@ import { useCallApi } from '@/hooks';
import { doSaveLogActivity } from '@/actions/GlobalActions';
import clsx from 'clsx';
interface RoleListProps {
id: string;
name: string;
roles: string;
status: string;
}
interface CreateUserParams {
email: string;
username: string;
@ -40,9 +47,10 @@ type PasswordType = 'password' | 'retype_password';
const AddDialog = () => {
const parentRef = useRef<any | null>(null);
const { showAddDialog, handleAddDialog, roles } = useUserContext();
const { showAddDialog, handleAddDialog } = useUserContext();
const { reload } = useDataGrid();
const { PostData, PutData } = useCallApi();
const { PostData, GetData } = useCallApi();
const [roles, setRoles] = useState<RoleListProps[]>([]);
const [alert, setAlert] = useState({
show: false,
message: ''
@ -57,10 +65,6 @@ const AddDialog = () => {
status: ''
};
const [formField, setFormField] = useState(initialState);
const resetForm = () => {
setFormField(initialState);
setAlert({ show: false, message: '' });
};
const [showPassword, setShowPassword] = useState({
password: false,
retype_password: false
@ -97,6 +101,87 @@ const AddDialog = () => {
};
};
const resetForm = () => {
setFormField(initialState);
setAlert({ show: false, message: '' });
};
/* actions */
const doCreateUser = useCallback(
async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const response = await PostData(`${API_URL}/user/create`, formField);
if (response?.status) {
handleAddDialog(false);
resetForm();
reload();
const createActivity = {
module: 'Manage User',
description: `Create New User => ${formField.username}`,
action: 'C'
};
doSaveLogActivity(createActivity);
toast.success('Success Create User');
} else {
toast.error('Failed to create user');
setAlert({ show: true, message: 'Failed to create user. Please try again.' });
}
},
[formField]
);
const fetchRoles = useCallback(async () => {
const params = {
limit: 100,
page: 1,
with_deleted: false,
order_field: 'name',
order_direction: 'ASC',
filter: JSON.stringify({
status: 'Y'
})
};
const response = await GetData(`${API_URL}/user_role/list`, params);
// console.log('ini data:', response);
if (response?.status) {
const roleList = response.data?.list || [];
setRoles(roleList);
} else {
setRoles(() => []);
}
// console.log('ini data user_role:', response?.data);
}, []);
useEffect(() => {
fetchRoles();
}, [fetchRoles]);
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
console.log('Form data before submit:', formField);
if (
formField.email.trim() === '' ||
formField.username.trim() === '' ||
formField.password.trim() === '' ||
formField.retype_password.trim() === '' ||
formField.name.trim() === '' ||
formField.id_role.trim() === '' ||
formField.status.trim() === ''
) {
setAlert({ show: true, message: 'Please fill name field.' });
return;
}
doCreateUser(e);
// console.log(formField);
setAlert({ show: false, message: '' });
};
useEffect(() => {
const validation = validatePassword(formField.password, formField.retype_password);
setMessagePassword(validation.isValid);
@ -111,38 +196,6 @@ const AddDialog = () => {
}
}, [showAddDialog]);
/* actions */
const doCreateUser = useCallback(
async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const response = await PostData(`${API_URL}/user/create`, {
...formField,
id_role: undefined
});
if (response?.status) {
const responseUserAddRole = await PutData(
`${API_URL}/user/add_role/${response?.message?.id}/${formField.id_role}`,
{}
);
resetForm();
handleAddDialog(false);
toast.success('Success Create User');
reload();
const createActivity = {
module: 'Manage User',
description: `Create New User => ${formField.username}`,
action: 'C'
};
doSaveLogActivity(createActivity);
} else {
setAlert((prev) => ({ ...prev, show: true, message: response?.message }));
}
},
[formField]
);
const togglePassword = useCallback((event: MouseEvent<HTMLButtonElement>, key: string) => {
event.preventDefault();
setShowPassword((prev) => ({ ...prev, [key]: !prev[key as PasswordType] }));
@ -177,7 +230,7 @@ const AddDialog = () => {
<h3>{alert.message}</h3>
</Alert>
)}
<form action="" onSubmit={doCreateUser}>
<form action="" onSubmit={handleSubmit}>
<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">
@ -231,7 +284,10 @@ const AddDialog = () => {
<div className="grow">
<Select
value={formField.id_role}
onValueChange={(id_role) => setFormField((prev) => ({ ...prev, id_role }))}
onValueChange={(value) => {
console.log('Role selected:', value);
setFormField((prev) => ({ ...prev, id_role: value }));
}}
>
<SelectTrigger>
<SelectValue placeholder="Select" />

View File

@ -1,4 +1,11 @@
import { Dialog, DialogContent, DialogFooter, DialogHeader } from '@/components/ui/dialog';
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
DialogDescription
} from '@/components/ui/dialog';
import { useUserContext } from '../hooks';
import { Button } from '@/components/ui/button';
import { Alert, useDataGrid } from '@/components';
@ -42,12 +49,14 @@ const DeleteDialog = () => {
} else {
setAlert((prev) => ({ ...prev, show: true, message: response?.message }));
}
}, [selectedUser, enforce]);
}, [selectedUser, DeleteData, handleDeleteDialog, reload, enforce]);
return (
<Dialog open={showDeleteDialog} onOpenChange={(open) => handleDeleteDialog(open, null)}>
<DialogContent className="container-fixed max-w-md flex flex-col p-5 overflow-hidden [&>button]:hidden">
<DialogHeader className="p-0 border-0 block">
<DialogTitle></DialogTitle>
<DialogDescription></DialogDescription>
<Alert variant="warning">
<h3 className="text-lg">Are you sure?</h3>
<span className="text-sm">you will delete this data!</span>

View File

@ -24,6 +24,12 @@ import { toast } from 'sonner';
import { useCallApi } from '@/hooks';
import { doSaveLogActivity } from '@/actions/GlobalActions';
interface RoleListProps {
id: string;
name: string;
status: string;
}
const API_URL = apiConfig.service_dashboard;
const initialState = {
@ -31,15 +37,15 @@ const initialState = {
username: '',
email: '',
id_role: '',
id_role_old: '',
status: ''
};
const EditDialog = () => {
const parentRef = useRef<any | null>(null);
const { showEditDialog, selectedUser, handleEditDialog, roles } = useUserContext();
const { showEditDialog, selectedUser, handleEditDialog } = useUserContext();
const { reload } = useDataGrid();
const { GetData, PutData } = useCallApi();
const [roles, setRoles] = useState<RoleListProps[]>([]);
const [alert, setAlert] = useState({
show: false,
message: ''
@ -53,17 +59,11 @@ const EditDialog = () => {
};
/* actions */
const doResetForm = () => {
setAlert({ show: false, message: '' });
setFormField(initialState);
};
const doUpdateUser = useCallback(
async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const response = await PutData(`${API_URL}/user/update/${selectedUser}`, {
...formField,
id_role_old: undefined
...formField
});
if (formField.name.trim() === '') {
@ -90,18 +90,36 @@ const EditDialog = () => {
[selectedUser, formField]
);
const doFetchUserRole = useCallback(async (sorting: any) => {
try {
sorting = sorting.length == 0 ? [{ id: 'name', desc: false }] : sorting;
const response = await GetData(`${API_URL}/user_role/list`, {
limit: 100,
page: 1,
with_deleted: false,
order_field: sorting[0].id,
order_direction: sorting[0].desc == false ? 'ASC' : 'DESC'
});
// console.log('User ID_ROLE:', response?.data.id_role);
// console.log('Role: ', response?.data.list);
setRoles(response?.data.list);
} catch (error) {
console.error('Error fetching role', error);
}
}, []);
const doFetchUserData = useCallback(async (id: string) => {
const response = await GetData(`${API_URL}/user/detail/${id}`, { id });
if (response?.status) {
let id_role = response.data.role.id || '';
// console.log('User detail response:', response);
if (response?.status) {
setFormField((prev) => ({
...prev,
name: response.data.name,
username: response.data.username,
email: response.data.email,
id_role: id_role,
id_role_old: id_role,
id_role: response.data.idRole,
status: response.data.status
}));
} else {
@ -111,10 +129,10 @@ const EditDialog = () => {
username: '',
email: '',
id_role: '0',
id_role_old: '',
status: ''
}));
}
// console.log('Fetched ID Role:', response?.data.id_role);
}, []);
useEffect(() => {
@ -129,6 +147,23 @@ const EditDialog = () => {
}
}, [showEditDialog]);
useEffect(() => {
const fetchAllData = async () => {
await doFetchUserRole([{ id: 'name', desc: false }]);
if (selectedUser) {
await doFetchUserData(selectedUser);
}
};
fetchAllData();
}, [selectedUser]);
// console.log('ini role: ', roles);
// useEffect(() => {
// console.log('Selected User ID Role:', formField.id_role);
// // console.log('Available Roles:', roles);
// }, [formField.id_role, roles]);
return (
<Dialog open={showEditDialog} onOpenChange={(open) => handleEditDialog(open, null)}>
<DialogContent className="container-fixed max-w-[768px] flex flex-col p-5 overflow-hidden [&>button]:hidden">
@ -206,7 +241,10 @@ const EditDialog = () => {
<div className="grow">
<Select
value={formField.id_role}
onValueChange={(id_role) => setFormField((prev) => ({ ...prev, id_role }))}
onValueChange={(id_role) => {
// console.log('Role changed to:', id_role);
setFormField((prev) => ({ ...prev, id_role }));
}}
>
<SelectTrigger>
<SelectValue placeholder="Select" />

View File

@ -17,7 +17,6 @@ interface ContextProps {
showDeleteDialog: boolean;
handleDeleteDialog: (show: boolean, selected_user: string | null) => void;
selectedUser: string | null;
roles: RoleListProps[];
}
interface SelectedUser {
@ -30,12 +29,6 @@ interface SelectedUser {
check_new_password: string;
}
interface RoleListProps {
id: string;
name: string;
status: string;
}
const initialProps: ContextProps = {
showSearchDialog: false,
handleSearchDialog: (show: boolean) => {},
@ -45,8 +38,7 @@ const initialProps: ContextProps = {
handleAddDialog: () => {},
showDeleteDialog: false,
handleDeleteDialog: () => {},
selectedUser: null,
roles: []
selectedUser: null
};
const ManageUserContext = createContext<ContextProps>(initialProps);
@ -60,7 +52,6 @@ const ManageUserContextProvider = ({ children }: { children: React.ReactNode })
const [showAddDialog, setShowAddDialog] = useState(false);
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [selectedUser, setSelectedUser] = useState<string | null>(null);
const [roles, setRoles] = useState<RoleListProps[]>([]);
const { GetData } = useCallApi();
/* action */
@ -193,39 +184,16 @@ const ManageUserContextProvider = ({ children }: { children: React.ReactNode })
const response = await GetData(`${API_URL}/user/list`, {
limit: limit,
page: page + 1,
with_deleted: true,
with_deleted: false,
order_field: sorting[0].id,
order_direction: sorting[0].desc == false ? 'ASC' : 'DESC',
filter: JSON.stringify(filter)
});
console.log('response api:', response);
// console.log('response api:', response);
return { data: response?.data.list, totalCount: response?.data.total_count };
};
const fetchRoles = useCallback(async () => {
const params = {
limit: 100,
page: 1,
with_deleted: false,
order_field: 'name',
order_direction: 'ASC',
filter: JSON.stringify({
status: 'Y'
})
};
const response = await GetData(`${API_URL}/user_role/list`, params);
if (response?.status) {
setRoles(() => [...response.data.list]);
} else {
setRoles(() => []);
}
}, []);
useEffect(() => {
fetchRoles();
}, [fetchRoles]);
return (
<ManageUserContext.Provider
value={{
@ -236,7 +204,6 @@ const ManageUserContextProvider = ({ children }: { children: React.ReactNode })
selectedUser,
showAddDialog,
handleAddDialog,
roles,
showDeleteDialog,
handleDeleteDialog
}}