import React from 'react';
import {
Box,
Icon,
Input,
InputGroup,
InputRightElement,
Button,
Flex,
useDisclosure,
Center,
useToast,
} from '@chakra-ui/react';
import AdminLayout from 'layouts/admin';
import { IconCirclePlus, IconReset } from 'components/icons/Icons';
import { Table, Thead, Tbody, Tr, Th } from '@chakra-ui/react';
import _ from 'lodash';
import { useRouter } from 'next/router';
import { AccountItem, MenuStatus, PaginationPanel, ProcessDialog } from 'components';
import { IoSearchOutline } from 'react-icons/io5';
import { PAGE_SIZE, StatusEnum } from 'constant';
import { usePagination } from '@ajna/pagination';
import { useTranslation } from 'react-i18next';
import { GetListAccountResponse, deleteAccount, getAccounts } from 'api/account';
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
import { IAccount } from 'types/model';
import { useDispatch } from 'react-redux';
import { setAppLoading } from 'store/slices/appSlice';
import { error, success } from 'utils/toast';
export default function Account() {
const router = useRouter();
const toast = useToast();
const dispatch = useDispatch();
const queryClient = useQueryClient();
const { t } = useTranslation(['common', 'account']);
const { isOpen, onOpen, onClose } = useDisclosure();
const [totalRecords, setTotalRecords] = React.useState<number>(0);
const [search, setSearch] = React.useState<string>('');
const [status, setStatus] = React.useState<StatusEnum | null>(null);
const [account, setAccount] = React.useState<IAccount>(null);
const headers = [
t('common:user_name'),
t('common:status'),
t('common:permisstion'),
t('common:created_date'),
t('common:created_by'),
t('common:action'),
];
const { pages, pagesCount, currentPage, setCurrentPage, isDisabled } = usePagination({
total: totalRecords,
limits: {
outer: 1,
inner: 2,
},
initialState: {
pageSize: PAGE_SIZE,
isDisabled: false,
currentPage: 1,
},
});
const { data } = useQuery<GetListAccountResponse>({
queryKey: ['list-account', status, currentPage, PAGE_SIZE],
queryFn: () =>
getAccounts({
locked: status ? status !== StatusEnum.ACTIVE : null,
page: currentPage,
size: PAGE_SIZE,
}),
});
const debouncedGetAccounts = _.debounce(async (searchValue) => {
const response = await getAccounts({
username: searchValue,
locked: status ? status !== StatusEnum.ACTIVE : null,
page: currentPage,
size: PAGE_SIZE,
});
queryClient.setQueryData(
['list-account', searchValue, status, currentPage, PAGE_SIZE],
response
);
}, 500);
const { mutate: deleteAccountMutate } = useMutation({
mutationKey: ['delete-account'],
mutationFn: deleteAccount,
onSuccess: () => {
toast(success({ title: t('common:delete_successfully') }));
queryClient.invalidateQueries({ queryKey: ['list-account'] });
},
onError: () => {
toast(error({ title: t('common:delete_failed') }));
},
});
React.useEffect(() => {
if (data) {
setTotalRecords(data.data.paging.totalRecord);
}
}, [data]);
return (
<AdminLayout>
<Box pt={{ base: '12px', md: '90px', xl: '90px' }}>
<Flex gap="6" justifyContent="space-between" flexDirection={{ base: 'column', md: 'row' }}>
<InputGroup size="xs" maxW="480px">
<Input
value={search}
onChange={(e) => {
setSearch(e.target.value);
debouncedGetAccounts(e.target.value);
}}
variant="search"
size="md"
placeholder={t('account:search_account_name')}
/>
<InputRightElement h="100%" px="6">
<Icon as={IoSearchOutline} boxSize="24px" color="black" />
</InputRightElement>
</InputGroup>
<Flex gap="6">
<MenuStatus status={status} onClick={(e) => setStatus(e)} />
<Button
boxSize="40px"
onClick={() => {
setSearch('');
setStatus(null);
}}>
<Icon as={IconReset} boxSize="24px" color="black" />
</Button>
<Button
leftIcon={
<Center position="absolute" left="0" insetY="0" h="100%" pl="4">
<IconCirclePlus boxSize="20px" left="4" justifyContent="center" my="auto" />
</Center>
}
width="150px"
size="md"
onClick={() => {
router.push('/admin/account/create');
}}>
{t('common:add_new')}
</Button>
</Flex>
</Flex>
</Box>
<Box mt="10" position="relative" bg="bg-1" minH="60vh" overflow="auto">
<Table variant="simple">
<Thead>
<Tr>
{headers.map((prop, index) => {
return (
<Th
pt="4"
textStyle="h4-sb"
borderBottom="0.5px solid black"
key={index}
textTransform="capitalize"
color="text-title"
isNumeric={index === headers.length - 1}>
{prop}
</Th>
);
})}
</Tr>
</Thead>
<Tbody>
{data &&
data.data.accountList &&
data.data.accountList.map((item, index) => {
return (
<AccountItem
key={index}
item={item}
onClick={() => {
router.push({
pathname: '/admin/account/detail',
query: item.id,
});
}}
onResetPassword={() => {}}
onDelete={() => {
setAccount(item);
onOpen();
}}
/>
);
})}
</Tbody>
</Table>
</Box>
<Flex justifyContent="flex-end">
<PaginationPanel
pagesCount={pagesCount}
currentPage={currentPage}
isDisabled={isDisabled}
onPageChange={setCurrentPage}
pages={pages}
mt="24px"
mb="8px"
/>
</Flex>
<ProcessDialog
title={t('account:description_delete_account')}
isOpen={isOpen}
onClose={onClose}
onConfirm={() => {
if (!account) {
return;
}
dispatch(setAppLoading(true));
deleteAccountMutate({ id: account.id });
}}
/>
</AdminLayout>
);
}