409 lines
10 KiB
TypeScript
409 lines
10 KiB
TypeScript
import { createOrUpdateUser, deleteUser, getAllUsers } from '@/api/Admin'
|
|
import { ButtonCopy } from '@/components/CopyClipboard/CopyClipboard'
|
|
import DataTableAll from '@/components/DataTable/DataTable'
|
|
import { get, post } from '@/rtk/helpers/apiService'
|
|
import { update, Xdelete } from '@/rtk/helpers/CRUD'
|
|
import { TUser } from '@/variables/types'
|
|
import {
|
|
Badge,
|
|
Box,
|
|
Button,
|
|
Code,
|
|
Dialog,
|
|
Group,
|
|
Modal,
|
|
MultiSelect,
|
|
Switch,
|
|
Text,
|
|
TextInput,
|
|
} from '@mantine/core'
|
|
import { useForm } from '@mantine/form'
|
|
import { IconEdit, IconX } from '@tabler/icons-react'
|
|
import { useEffect, useState } from 'react'
|
|
import classes from './UsersManagement.module.css'
|
|
const UsersManagement = () => {
|
|
const [users, setUsers] = useState<TUser[]>([])
|
|
const [action, setAction] = useState('')
|
|
const [activeBtn, setActiveBtn] = useState(false)
|
|
const [item, setItem] = useState({ id: 0, is_permanent: false })
|
|
const [disableBtn, setDisableBtn] = useState(false)
|
|
const [info, setInfo] = useState('')
|
|
const [isPermanentConfirmOpen, setIsPermanentConfirmOpen] =
|
|
useState<boolean>(false)
|
|
|
|
const columns = [
|
|
{
|
|
name: 'id',
|
|
size: '5%',
|
|
header: 'ID',
|
|
},
|
|
{
|
|
name: 'name',
|
|
size: '20%',
|
|
header: 'Name',
|
|
},
|
|
{
|
|
name: 'email',
|
|
size: '25%',
|
|
header: 'Email',
|
|
},
|
|
{
|
|
name: 'permission',
|
|
size: '20%',
|
|
header: 'Permission',
|
|
render: (row: TUser) => {
|
|
if (row.permission.includes(',')) {
|
|
return row?.permission?.split(',').map((p) => {
|
|
return <Badge mr={'sm'}>{p}</Badge>
|
|
})
|
|
} else {
|
|
return <Badge>{row.permission}</Badge>
|
|
}
|
|
},
|
|
},
|
|
{
|
|
name: 'is_permanent',
|
|
size: '20%',
|
|
header: 'Employment Type',
|
|
render: (row: TUser) => {
|
|
return row.is_permanent ? (
|
|
<Badge color="teal">Permanent</Badge>
|
|
) : (
|
|
<Badge color="violet">Probation</Badge>
|
|
)
|
|
},
|
|
},
|
|
{
|
|
name: '#',
|
|
size: '10%',
|
|
header: 'Action',
|
|
render: (row: TUser) => {
|
|
return (
|
|
<Box className={classes.optionIcon}>
|
|
<IconEdit
|
|
className={classes.editIcon}
|
|
onClick={() => {
|
|
setAction('edit')
|
|
setItem(row)
|
|
form.reset()
|
|
form.setValues(row)
|
|
}}
|
|
width={20}
|
|
height={20}
|
|
/>
|
|
<IconX
|
|
className={classes.deleteIcon}
|
|
onClick={() => {
|
|
setAction('delete')
|
|
setItem(row)
|
|
}}
|
|
width={20}
|
|
height={20}
|
|
/>
|
|
</Box>
|
|
)
|
|
},
|
|
},
|
|
]
|
|
|
|
const form = useForm({
|
|
initialValues: {
|
|
id: 0,
|
|
name: '',
|
|
email: '',
|
|
permission: '',
|
|
is_permanent: false,
|
|
},
|
|
})
|
|
|
|
const getAll = async () => {
|
|
try {
|
|
const res = await get(getAllUsers)
|
|
if (res.status) {
|
|
setUsers(res.data)
|
|
}
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
}
|
|
|
|
const handleCreate = async (values: TUser) => {
|
|
try {
|
|
const { id, ...data } = values
|
|
const res = await post(createOrUpdateUser, data)
|
|
if (res.status === true) {
|
|
setAction('review')
|
|
form.reset()
|
|
getAll()
|
|
setInfo(JSON.stringify(res.data, null, 2))
|
|
}
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
}
|
|
|
|
const handleUpdate = async (values: TUser) => {
|
|
try {
|
|
const res = await update(createOrUpdateUser, values, getAll)
|
|
if (res === true) {
|
|
setAction('')
|
|
setIsPermanentConfirmOpen(false)
|
|
form.reset()
|
|
}
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
}
|
|
|
|
const handleDelete = async (id: number) => {
|
|
try {
|
|
await Xdelete(deleteUser, { id: id }, getAll)
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
}
|
|
|
|
useEffect(() => {
|
|
getAll()
|
|
}, [])
|
|
|
|
return (
|
|
<div>
|
|
<div className={classes.title}>
|
|
<h3>
|
|
<Text>Admin/</Text>
|
|
Users Management
|
|
</h3>
|
|
<Button
|
|
onClick={() => {
|
|
setAction('add')
|
|
form.reset()
|
|
}}
|
|
>
|
|
+ Add
|
|
</Button>
|
|
</div>
|
|
<Box mt={'md'}>
|
|
<DataTableAll data={users} columns={columns} size="" searchInput />
|
|
</Box>
|
|
|
|
{/* Add/Edit User modal */}
|
|
<Modal
|
|
opened={action === 'add' || action === 'edit'}
|
|
onClose={() => {
|
|
setAction('')
|
|
setIsPermanentConfirmOpen(false)
|
|
form.reset()
|
|
}}
|
|
title={
|
|
<Text pl={'sm'} fw={700} fz={'lg'}>
|
|
{action === 'add' ? 'Add User' : 'Update User'}
|
|
</Text>
|
|
}
|
|
>
|
|
<form
|
|
onSubmit={form.onSubmit(async (values) => {
|
|
setDisableBtn(true)
|
|
if (action === 'edit') {
|
|
if (values.is_permanent && !item.is_permanent) {
|
|
setIsPermanentConfirmOpen(true)
|
|
} else {
|
|
await handleUpdate(values)
|
|
}
|
|
} else {
|
|
await handleCreate(values)
|
|
}
|
|
setDisableBtn(false)
|
|
})}
|
|
>
|
|
<Box pl={'md'} pr={'md'}>
|
|
<TextInput
|
|
label="Name"
|
|
mb={'md'}
|
|
value={form.values.name}
|
|
error={form.errors.name}
|
|
onChange={(e) => form.setFieldValue('name', e.target.value)}
|
|
required
|
|
/>
|
|
|
|
<TextInput
|
|
label="Email"
|
|
mb={'md'}
|
|
value={form.values.email}
|
|
error={form.errors.email}
|
|
onChange={(e) => form.setFieldValue('email', e.target.value)}
|
|
required
|
|
/>
|
|
|
|
<MultiSelect
|
|
label={'Permission(s)'}
|
|
required
|
|
data={['staff', 'admin', 'hr', 'tester', 'accountant']}
|
|
value={
|
|
typeof form.values.permission === 'string'
|
|
? form.values.permission
|
|
.split(',')
|
|
.filter((p) => p.trim() !== '')
|
|
: form.values.permission
|
|
}
|
|
error={form.errors.permisstion}
|
|
onChange={(e) =>
|
|
form.setFieldValue(
|
|
'permission',
|
|
e!.filter((p) => p.trim() !== '').join(','),
|
|
)
|
|
}
|
|
mb={'md'}
|
|
/>
|
|
|
|
{action === 'edit' && !item.is_permanent ? (
|
|
<Switch
|
|
label="Permanent employee"
|
|
style={{ width: 'fit-content' }}
|
|
checked={form.values.is_permanent}
|
|
onChange={(event) =>
|
|
form.setFieldValue(
|
|
'is_permanent',
|
|
event.currentTarget.checked,
|
|
)
|
|
}
|
|
/>
|
|
) : (
|
|
''
|
|
)}
|
|
|
|
<Box ta={'center'}>
|
|
{action === 'add' ? (
|
|
<Button
|
|
mt={'lg'}
|
|
bg={'green'}
|
|
type="submit"
|
|
disabled={disableBtn}
|
|
>
|
|
Create
|
|
</Button>
|
|
) : (
|
|
<Button
|
|
mt={'lg'}
|
|
bg={'green'}
|
|
type="submit"
|
|
disabled={disableBtn}
|
|
>
|
|
Save
|
|
</Button>
|
|
)}
|
|
</Box>
|
|
</Box>
|
|
</form>
|
|
</Modal>
|
|
|
|
<Modal
|
|
opened={action === 'review'}
|
|
onClose={() => {
|
|
setAction('')
|
|
}}
|
|
size={'lg'}
|
|
title={
|
|
<Text pl={'sm'} fw={700} fz={'lg'}>
|
|
Information to get started
|
|
</Text>
|
|
}
|
|
>
|
|
<Text c={'red'} fz={'sm'} fw={700}>
|
|
!! Important note: Please remind user to change password after logging
|
|
in !!
|
|
</Text>
|
|
<Code block>
|
|
<Box ta={'right'}>
|
|
<ButtonCopy value={info} />
|
|
</Box>
|
|
{info}
|
|
</Code>
|
|
</Modal>
|
|
|
|
{/* Confirm change to permanent employee */}
|
|
<Modal
|
|
opened={isPermanentConfirmOpen}
|
|
onClose={() => setIsPermanentConfirmOpen(false)}
|
|
centered
|
|
size="sm"
|
|
classNames={{
|
|
content: classes.deleteModal,
|
|
}}
|
|
>
|
|
<Text className={classes.deleteModalTitle}>Confirm Update</Text>
|
|
<Text className={classes.deleteModalContent}>
|
|
This action will change the employment type from{' '}
|
|
<strong>Probation</strong> to <strong>Permanent</strong>.
|
|
</Text>
|
|
<Text className={classes.deleteModalContent}>
|
|
Are you sure you want to proceed?
|
|
</Text>
|
|
|
|
<Box className={classes.deleteModalFooter}>
|
|
<Button
|
|
variant="outline"
|
|
onClick={() => {
|
|
setIsPermanentConfirmOpen(false)
|
|
}}
|
|
disabled={disableBtn}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
<Button
|
|
className={classes.deleteButton}
|
|
onClick={async () => {
|
|
setDisableBtn(true)
|
|
await handleUpdate(form.values)
|
|
setDisableBtn(false)
|
|
}}
|
|
disabled={disableBtn}
|
|
>
|
|
Confirm
|
|
</Button>
|
|
</Box>
|
|
</Modal>
|
|
|
|
<Dialog
|
|
className={classes.dialog}
|
|
opened={action === 'delete'}
|
|
withCloseButton
|
|
onClose={() => setAction('')}
|
|
size="lg"
|
|
radius="md"
|
|
position={{ top: 30, right: 10 }}
|
|
>
|
|
<Text className={classes.dialogText} size="sm" mb="xs" fw={500}>
|
|
Do you want to delete this user?
|
|
<Group justify="center" m={10}>
|
|
<Button
|
|
disabled={activeBtn}
|
|
fw={700}
|
|
size="xs"
|
|
variant="light"
|
|
onClick={async () => {
|
|
setActiveBtn(true)
|
|
await handleDelete(item.id)
|
|
setActiveBtn(false)
|
|
setAction('')
|
|
}}
|
|
>
|
|
Yes
|
|
</Button>
|
|
<Button
|
|
fw={700}
|
|
size="xs"
|
|
variant="light"
|
|
onClick={() => setAction('')}
|
|
>
|
|
Cancel
|
|
</Button>
|
|
</Group>
|
|
</Text>
|
|
</Dialog>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default UsersManagement
|