accepted items added
This commit is contained in:
@@ -9,6 +9,8 @@ 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';
|
||||
@@ -17,13 +19,32 @@ 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, Search } from '@mui/icons-material';
|
||||
import { Box, Button, Stack, Typography } from '@mui/material';
|
||||
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();
|
||||
@@ -31,6 +52,7 @@ const DashboardBoxesPage = (props: Props) => {
|
||||
const [pageSize] = useState(DEFAULT_PAGE_SIZE);
|
||||
const { value: keyword, onChange: handleKeyword, setValue: setKeyword } = useInput('');
|
||||
const [boxStatusFilter, setBoxStatusFilter] = useState<BoxStatus | undefined>(undefined);
|
||||
const [trackId, setTrackId] = useState<string>();
|
||||
|
||||
const [deleteIds, setDeleteIds] = useState<number[]>([]);
|
||||
const [downloadIds, setDownloadIds] = useState<number[]>([]);
|
||||
@@ -61,6 +83,31 @@ const DashboardBoxesPage = (props: Props) => {
|
||||
}
|
||||
);
|
||||
|
||||
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<HTMLInputElement | HTMLTextAreaElement>, 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,
|
||||
@@ -185,6 +232,62 @@ const DashboardBoxesPage = (props: Props) => {
|
||||
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 (
|
||||
<div>
|
||||
{(() => {
|
||||
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 (
|
||||
<Typography>
|
||||
{total?.totalAmount} | {total?.totalAccepted}
|
||||
</Typography>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
dataKey: 'totalNetWeight',
|
||||
@@ -272,6 +375,13 @@ const DashboardBoxesPage = (props: Props) => {
|
||||
return (
|
||||
<ActionPopMenu
|
||||
buttons={[
|
||||
{
|
||||
icon: <RemoveRedEye sx={{ path: { color: '#3489E4' } }} />,
|
||||
label: t('view_packet'),
|
||||
onClick: () => {
|
||||
navigation.push(pageLinks.dashboard.boxes.detail(data.id));
|
||||
},
|
||||
},
|
||||
{
|
||||
icon: <Edit sx={{ path: { color: '#3489E4' } }} />,
|
||||
label: t('edit'),
|
||||
@@ -307,6 +417,53 @@ const DashboardBoxesPage = (props: Props) => {
|
||||
},
|
||||
},
|
||||
];
|
||||
const [items, setItems] = useState<Product>();
|
||||
const [loaer, setLoading] = useState(false);
|
||||
const {
|
||||
register,
|
||||
control,
|
||||
handleSubmit,
|
||||
watch,
|
||||
setValue,
|
||||
formState: { errors },
|
||||
} = useForm<Product>({
|
||||
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 (
|
||||
<Box>
|
||||
@@ -314,6 +471,66 @@ const DashboardBoxesPage = (props: Props) => {
|
||||
<BaseButton colorVariant='blue' startIcon={<Add />} href={pageLinks.dashboard.boxes.create}>
|
||||
{t('create_packet')}
|
||||
</BaseButton>
|
||||
<Button onClick={handleOpen}>{t('product_inspection')}</Button>
|
||||
<Modal open={open} onClose={handleClose} aria-labelledby='modal-modal-title' aria-describedby='modal-modal-description'>
|
||||
<Box sx={style}>
|
||||
<Typography id='modal-modal-title' variant='h6' component='h2'>
|
||||
{t('product_inspection')}
|
||||
</Typography>
|
||||
<Typography id='modal-modal-description' sx={{ mt: 2 }}>
|
||||
{t('enter_product')}
|
||||
</Typography>
|
||||
<TextField
|
||||
id='outlined-basic'
|
||||
label={t('track_id')}
|
||||
variant='outlined'
|
||||
onChange={e => setTrackId(e.target.value)}
|
||||
/>
|
||||
{trackId && trackId.length > 0 && (
|
||||
<>
|
||||
{getListQuery.loading ? (
|
||||
<Typography sx={{ mt: 2 }}>{t('loading')}...</Typography> // yoki <CircularProgress />
|
||||
) : getListQuery.data?.data && getListQuery.data?.data.length > 0 ? (
|
||||
getListQuery.data?.data.map(e => (
|
||||
<Box key={e.id} sx={{ width: '100%', display: 'flex', flexDirection: 'column' }}>
|
||||
<Card sx={{ minWidth: 275, mb: 2 }}>
|
||||
<CardContent>
|
||||
<Typography sx={{ fontSize: 14 }}>
|
||||
{t('track_id')}: {e.trekId}
|
||||
</Typography>
|
||||
<Typography sx={{ fontSize: 14 }}>Nomi: {e.name || e.nameRu}</Typography>
|
||||
<Typography sx={{ fontSize: 14 }}>Mahsulot soni: {e.amount}</Typography>
|
||||
<Typography sx={{ fontSize: 14 }}>Paket nomi: {e?.packetName}</Typography>
|
||||
</CardContent>
|
||||
</Card>
|
||||
<TextField
|
||||
id={`amount-${e.trekId}`}
|
||||
label='Mahsulot soni'
|
||||
type='number'
|
||||
sx={{ width: '100%' }}
|
||||
value={values[e.trekId] ?? ''}
|
||||
onChange={change => handleAmountChange(change, e.amount, e.trekId)}
|
||||
inputProps={{ min: 1, max: e.amount }}
|
||||
/>
|
||||
<Button
|
||||
sx={{ mt: '10px' }}
|
||||
onClick={() => {
|
||||
if (values[e.trekId] !== '') {
|
||||
updateItems(e, Number(values[e.trekId]));
|
||||
}
|
||||
}}
|
||||
>
|
||||
{t('confirmation')}
|
||||
</Button>
|
||||
</Box>
|
||||
))
|
||||
) : (
|
||||
<Typography sx={{ mt: 2 }}>{t('no_products_found') || 'Mahsulot topilmadi'}</Typography>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Box>
|
||||
</Modal>
|
||||
</Stack>
|
||||
<Box
|
||||
width={1}
|
||||
|
||||
Reference in New Issue
Block a user