Untitled
unknown
plain_text
a year ago
6.9 kB
4
Indexable
Never
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> ); }