'use client'; import ActionPopMenu from '@/components/common/ActionPopMenu'; import { ColumnData, MyTable } from '@/components/common/MyTable'; import BaseButton from '@/components/ui-kit/BaseButton'; import BaseInput from '@/components/ui-kit/BaseInput'; import BasePagination from '@/components/ui-kit/BasePagination'; import { selectDefaultStyles } from '@/components/ui-kit/BaseReactSelect'; import { useAuthContext } from '@/context/auth-context'; import { BoxStatus, BoxStatusList } from '@/data/box/box.model'; import { box_requests } from '@/data/box/box.requests'; import { Product } from '@/data/item/item.mode'; import { item_requests } from '@/data/item/item.requests'; import { party_requests } from '@/data/party/party.requests'; import { UserRoleEnum } from '@/data/user/user.model'; import { DEFAULT_PAGE_SIZE } from '@/helpers/constants'; import useInput from '@/hooks/useInput'; import { useMyTranslation } from '@/hooks/useMyTranslation'; import useRequest from '@/hooks/useRequest'; import AddPhotosModal from '@/routes/private/items/components/AddPhotosModal'; import EditItemModal from '@/routes/private/items/components/EditItemModal'; import { notifyUnknownError } from '@/services/notification'; import { getBoxStatusStyles, getStatusColor } from '@/theme/getStatusBoxStyles'; import { Add, Check, Circle, Delete, Edit, FilterList, FilterListOff, Search } from '@mui/icons-material'; import { Box, FormControl, MenuItem, Select, Stack, Typography } from '@mui/material'; import { useEffect, useMemo, useState } from 'react'; import AsyncSelect from 'react-select/async'; type Props = {}; const DashboardGoodsPage = (props: Props) => { const t = useMyTranslation(); const { user } = useAuthContext(); const [page, setPage] = useState(1); const [pageSize] = useState(DEFAULT_PAGE_SIZE); const [modal, setModal] = useState(null); const [selectedItem, setSelectedItem] = useState(null); const { value: keyword, onChange: handleKeyword, setValue: setKeyword } = useInput(''); const { value: trackKeyword, onChange: handleTrackKeyword, setValue: setTrackKeyword } = useInput(''); const [partyFilter, setPartyFilter] = useState<{ label: string; value: number } | undefined>(undefined); const [boxFilter, setBoxFilter] = useState<{ label: string; value: number } | undefined>(undefined); const [boxStatusFilter, setBoxStatusFilter] = useState(undefined); const [cargoType, setCargoType] = useState<'AUTO' | 'AVIA'>(user?.role === 'ADMIN' ? 'AVIA' : user?.cargoType || 'AUTO'); const [deleteIds, setDeleteIds] = useState([]); const getItemsQuery = useRequest( () => item_requests.getAll({ name: keyword, page: page, status: boxStatusFilter, packetId: boxFilter?.value, partyId: partyFilter?.value, trekId: trackKeyword, direction: 'desc', cargoType, sort: 'id', }), { selectData(data) { return data.data.data; }, dependencies: [page, boxStatusFilter, boxFilter, partyFilter, cargoType], } ); const { data: list, totalElements, totalPages, } = useMemo(() => { if (getItemsQuery.data?.data) { return { data: getItemsQuery.data.data, totalElements: getItemsQuery.data.totalElements, totalPages: getItemsQuery.data.totalPages, }; } else { return { data: [], totalElements: 0, totalPages: 0, }; } }, [getItemsQuery]); const loading = getItemsQuery.loading; const handleChange = (newPage: number) => { setPage(newPage); }; const resetFilter = () => { setPage(1); setKeyword(''); setTrackKeyword(''); setBoxStatusFilter(undefined); // @ts-expect-error setPartyFilter(null); // @ts-expect-error setBoxFilter(null); }; const closeModal = () => { setModal(null); setSelectedItem(null); }; const openEditModal = (item: Product) => { setModal('edit_item'); setSelectedItem(item); }; const openAddPhotoModal = (item: Product) => { setModal('add_photo_item'); setSelectedItem(item); }; const onSuccessEdit = () => { getItemsQuery.refetch(); closeModal(); }; const onDelete = async (id: number) => { if (deleteIds.includes(id)) return; try { setDeleteIds(p => [...p, id]); await item_requests.delete({ itemId: id }); getItemsQuery.refetch(); } catch (error) { notifyUnknownError(error); } finally { setDeleteIds(prev => prev.filter(i => i !== id)); } }; const { data: defaultPartyOptions } = useRequest(() => party_requests.getAll({ cargoType }), { enabled: true, selectData(data) { return data.data.data.data.map(p => ({ value: p.id, label: p.name })); }, dependencies: [cargoType], placeholderData: [], }); const { data: defaultBoxOptions } = useRequest( () => box_requests.getAll({ partyId: partyFilter?.value, cargoType, }), { enabled: !!partyFilter, selectData(data) { return data.data.data.data.map(p => ({ value: p.id, label: p.name })); }, placeholderData: [], dependencies: [partyFilter], } ); const partyOptions = (inputValue: string) => { return party_requests.getAll({ partyName: inputValue }).then(res => { return res.data.data.data.map(p => ({ label: p.name, value: p.id })); }); }; const boxOptions = (inputValue: string) => { return box_requests.getAll({ cargoId: inputValue }).then(res => { return res.data.data.data.map(p => ({ label: p.name, value: p.id })); }); }; useEffect(() => { const timeoutId = setTimeout(() => { setPage(1); getItemsQuery.refetch(); }, 350); return () => clearTimeout(timeoutId); }, [keyword, trackKeyword]); const columns: ColumnData[] = [ { label: t('No'), width: 100, renderCell(data, rowIndex) { return (page - 1) * pageSize + rowIndex + 1; }, }, { dataKey: 'id', label: t('id'), width: 100, }, { dataKey: 'name', label: t('product_name'), width: 300, }, { dataKey: 'trekId', label: t('track_id'), width: 300, }, { dataKey: 'boxName', label: t('box_number'), width: 300, }, { dataKey: 'partyName', label: t('party'), width: 300, }, { dataKey: 'weight', label: t('weight'), width: 300, }, { dataKey: 'amount', label: t('quantity'), width: 300, }, { dataKey: 'cargoId', label: t('cargo_id'), width: 300, }, { dataKey: 'price', label: t('price'), width: 150, }, { dataKey: 'totalPrice', label: t('total_price'), width: 150, }, { dataKey: 'status', label: t('box_status'), width: 240, renderHeaderCell(rowIndex) { return ( {t('box_status')} { return { icon: , label: t(stat), onClick() { setBoxStatusFilter(stat); setPage(1); }, }; })} mainIcon={} placement={{ anchorOrigin: { vertical: 'bottom', horizontal: 'center', }, transformOrigin: { horizontal: 'center', vertical: 'top', }, }} /> ); }, renderCell(data) { return {t(data.status)}; }, }, { label: '', width: 50, numeric: true, renderCell(data, rowIndex) { const isUzbekUser = user?.role === UserRoleEnum.UZB_WORKER; if (isUzbekUser && data.hasImage) { return ; } else if (isUzbekUser && !data.hasImage) { return ( , label: t('add_photo_to_item'), onClick: () => { openAddPhotoModal(data); }, }, ]} /> ); } return ( , label: t('edit'), onClick: () => { openEditModal(data); }, }, { icon: , label: t('delete'), onClick: () => { onDelete(data.id); }, dontCloseOnClick: true, loading: deleteIds.includes(data.id), }, ]} /> ); }, }, ]; return ( {t('products')} , }} value={keyword} onChange={handleKeyword} placeholder={t('filter_item_name')} /> { setPartyFilter(newValue); setPage(1); }} styles={selectDefaultStyles} noOptionsMessage={() => t('not_found')} loadingMessage={() => t('loading')} defaultOptions={defaultPartyOptions!} loadOptions={partyOptions} placeholder={t('filter_party_name')} /> { setBoxFilter(newValue); setPage(1); }} styles={selectDefaultStyles} noOptionsMessage={() => t('enter_box_name_to_find')} loadingMessage={() => t('loading')} defaultOptions={defaultBoxOptions!} loadOptions={boxOptions} placeholder={t('filter_box_name')} /> {user?.role === 'ADMIN' && ( )} } size='small' onClick={resetFilter}> {t('reset_filter')} {modal === 'edit_item' && !!selectedItem && ( )} {modal === 'add_photo_item' && !!selectedItem && ( )} ); }; export default DashboardGoodsPage;