'use client'; import ActionPopMenu from '@/components/common/ActionPopMenu'; import { ColumnData, MyTable } from '@/components/common/MyTable'; import StatusChangePopup from '@/components/common/StatusChangePopup'; import BaseButton from '@/components/ui-kit/BaseButton'; import BaseInput from '@/components/ui-kit/BaseInput'; import BasePagination from '@/components/ui-kit/BasePagination'; import { useAuthContext } from '@/context/auth-context'; import { BoxStatus, BoxStatusList, IBox } from '@/data/box/box.model'; import { box_requests } from '@/data/box/box.requests'; import { Product, UpdateProductBodyType } from '@/data/item/item.mode'; import { item_requests } from '@/data/item/item.requests'; import { DEFAULT_PAGE_SIZE, pageLinks } from '@/helpers/constants'; import useInput from '@/hooks/useInput'; import { useMyNavigation } from '@/hooks/useMyNavigation'; import { useMyTranslation } from '@/hooks/useMyTranslation'; import useRequest from '@/hooks/useRequest'; import { file_service } from '@/services/file-service'; import { notifyUnknownError } from '@/services/notification'; import { getStatusColor } from '@/theme/getStatusBoxStyles'; import { Add, Circle, Delete, Download, Edit, FilterList, FilterListOff, RemoveRedEye, Search } from '@mui/icons-material'; import { Box, Button, Card, CardContent, Modal, Stack, TextField, Typography } from '@mui/material'; import { useEffect, useMemo, useState } from 'react'; import { useForm } from 'react-hook-form'; type Props = {}; const style = { position: 'absolute', top: '50%', left: '50%', transform: 'translate(-50%, -50%)', width: 400, bgcolor: 'background.paper', border: '2px solid #000', boxShadow: 24, display: 'flex', flexDirection: 'column', gap: '10px', p: 4, }; const DashboardBoxesPage = (props: Props) => { const [open, setOpen] = useState(false); const handleOpen = () => setOpen(true); const handleClose = () => setOpen(false); const t = useMyTranslation(); const navigation = useMyNavigation(); const { isAdmin } = useAuthContext(); const [page, setPage] = useState(1); const [pageSize] = useState(DEFAULT_PAGE_SIZE); const { value: keyword, onChange: handleKeyword, setValue: setKeyword } = useInput(''); const [boxStatusFilter, setBoxStatusFilter] = useState(undefined); const [trackId, setTrackId] = useState(); const [deleteIds, setDeleteIds] = useState([]); const [downloadIds, setDownloadIds] = useState([]); const [changeStatusIds, setChangeStatusIds] = useState([]); const boxStatusOptions = useMemo(() => { const p = ['READY_TO_INVOICE'] as BoxStatus[]; if (isAdmin) { p.push('READY'); } return p; }, [isAdmin]); const getBoxesQuery = useRequest( () => box_requests.getAll({ page: page, cargoId: keyword, status: boxStatusFilter, direction: 'desc', sort: 'id', }), { dependencies: [page, boxStatusFilter], selectData(data) { return data.data.data; }, } ); const getListQuery = useRequest( () => item_requests.getAll({ page: page, trekId: trackId, }), { dependencies: [page, trackId], selectData(data) { return data.data.data; }, } ); const [values, setValues] = useState<{ [trackId: string]: number | '' }>({}); const handleAmountChange = (event: React.ChangeEvent, max: number, trackId: string) => { const val = Number(event.target.value); if (val >= 1 && val <= max) { setValues(prev => ({ ...prev, [trackId]: val })); } else if (event.target.value === '') { setValues(prev => ({ ...prev, [trackId]: '' })); } }; const { data: list, totalElements, totalPages, } = useMemo(() => { if (getBoxesQuery.data?.data) { return { data: getBoxesQuery.data.data, totalElements: getBoxesQuery.data.totalElements, totalPages: getBoxesQuery.data.totalPages, }; } else { return { data: [], totalElements: 0, totalPages: 0, }; } }, [getBoxesQuery]); const loading = getBoxesQuery.loading; const handleChange = (newPage: number) => { setTimeout(() => { setPage(newPage); }, 100); }; const resetFilter = () => { setPage(1); setKeyword(''); setBoxStatusFilter(undefined); }; const onDelete = async (id: number) => { if (deleteIds.includes(id)) return; try { setDeleteIds(p => [...p, id]); await box_requests.delete({ packetId: id }); getBoxesQuery.refetch(); } catch (error) { notifyUnknownError(error); } finally { setDeleteIds(prev => prev.filter(i => i !== id)); } }; const onDownloadExcel = async (id: number) => { if (downloadIds.includes(id)) return; try { setDownloadIds(p => [...p, id]); const response = await box_requests.downloadExcel({ packetId: id }); const file = new File([response.data], 'Box-excel.xlsx', { type: response.data.type }); file_service.download(file); } catch (error) { notifyUnknownError(error); } finally { setDownloadIds(prev => prev.filter(i => i !== id)); } }; const onChangeStatus = async (id: number, newStatus: BoxStatus) => { if (changeStatusIds.includes(id)) return; try { setChangeStatusIds(p => [...p, id]); await box_requests.changeStatus({ packetId: id, status: newStatus }); getBoxesQuery.refetch(); } catch (error) { notifyUnknownError(error); } finally { setChangeStatusIds(prev => prev.filter(i => i !== id)); } }; useEffect(() => { const timeoutId = setTimeout(() => { setPage(1); getBoxesQuery.refetch(); }, 350); return () => clearTimeout(timeoutId); }, [keyword]); // No, PartyName, PacketName, PartyTozaOg'irlik, CountOfItems, WeightOfItems, CargoID, PassportNameFamily - PacketStatusForInvoice const columns: ColumnData[] = [ { label: t('No'), width: 100, renderCell(data, rowIndex) { return (page - 1) * pageSize + rowIndex + 1; }, }, { dataKey: 'id', label: "Qo'shish", width: 120, renderCell: data => { return ( ); }, }, { dataKey: 'partyName', label: t('party_name'), width: 120, }, { dataKey: 'name', label: t('name'), width: 120, }, { dataKey: 'packetNetWeight', label: t('weight'), width: 120, }, { dataKey: 'totalItems', label: t('count_of_items'), width: 120, renderCell: data => { const getOneBox = useRequest( () => { return box_requests.find({ packetId: data.id }); }, { selectData(data) { const boxData = data.data.data; return { products_list: [ ...boxData.items.map(item => { let name = item.name; let nameRu = item.nameRu; return { id: item.id, price: item.price, cargoId: item.cargoId, trekId: item.trekId, name: name, acceptedNumber: item.acceptedNumber, nameRu: nameRu, amount: +item.amount, weight: +item.weight, }; }), ], }; }, } ); return (
{(() => { const total = getOneBox.data?.products_list.reduce( (acc, product) => { console.log(product, 'totalAccepted'); acc.totalAmount += +product.amount || 0; acc.totalAccepted += +product.acceptedNumber || 0; return acc; }, { totalAmount: 0, totalAccepted: 0 } ); return ( {total?.totalAmount} | {total?.totalAccepted} ); })()}
); }, }, { dataKey: 'totalNetWeight', label: t('party_weight'), width: 120, }, { dataKey: 'cargoId', label: t('cargo_id'), width: 120, }, { dataKey: 'passportName', label: t('client'), width: 120, }, { dataKey: 'status', label: t('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 ( { return { icon: ( ), label: t(stat), onClick: () => { onChangeStatus(data.id, stat); }, }; })} /> ); }, }, { label: '', width: 100, numeric: true, renderCell(data, rowIndex) { return ( , label: t('view_packet'), onClick: () => { navigation.push(pageLinks.dashboard.boxes.detail(data.id)); }, }, { icon: , label: t('edit'), onClick: () => { navigation.push(pageLinks.dashboard.boxes.edit(data.id)); }, }, { icon: , label: t('delete'), onClick: () => { onDelete(data.id); }, dontCloseOnClick: true, loading: deleteIds.includes(data.id), }, ...(data.status === 'READY' ? [ { icon: , label: t('download_excel'), onClick: () => { onDownloadExcel(data.id); }, loading: downloadIds.includes(data.id), dontCloseOnClick: true, }, ] : []), ]} /> ); }, }, ]; const [items, setItems] = useState(); const [loaer, setLoading] = useState(false); const { register, control, handleSubmit, watch, setValue, formState: { errors }, } = useForm({ defaultValues: { trekId: items?.trekId, name: items?.name, nameRu: items?.nameRu, amount: items?.amount, weight: items?.weight, acceptedNumber: Number(values), }, }); const updateItems = async (item: Product, acceptedNumber: number) => { try { setLoading(true); const updateBody: UpdateProductBodyType = { itemId: item.id, acceptedNumber, amount: item.amount, name: item.name, nameRu: item.nameRu, trekId: item.trekId, weight: item.weight, }; await item_requests.update(updateBody); // Ma'lumotni yangilab olamiz getListQuery.refetch(); getBoxesQuery.refetch(); setValues(prev => ({ ...prev, [item.trekId]: '' })); } catch (error) { notifyUnknownError(error); } finally { setLoading(false); } }; return ( } href={pageLinks.dashboard.boxes.create}> {t('create_packet')} {t('product_inspection')} {t('enter_product')} setTrackId(e.target.value)} /> {trackId && trackId.length > 0 && ( <> {getListQuery.loading ? ( {t('loading')}... // yoki ) : getListQuery.data?.data && getListQuery.data?.data.length > 0 ? ( getListQuery.data?.data.map(e => ( {t('track_id')}: {e.trekId} Nomi: {e.name || e.nameRu} Mahsulot soni: {e.amount} Paket nomi: {e?.packetName} handleAmountChange(change, e.amount, e.trekId)} inputProps={{ min: 1, max: e.amount }} /> )) ) : ( {t('no_products_found') || 'Mahsulot topilmadi'} )} )} {t('packet')} , }} placeholder={t('filter_packet_name')} value={keyword} onChange={e => { setKeyword(e.target.value); }} /> } size='small' onClick={resetFilter}> {t('reset_filter')} ); }; export default DashboardBoxesPage;