realbox edit components

This commit is contained in:
Samandar Turg'unboev
2025-05-24 23:02:52 +05:00
parent 417ab7dd74
commit ce2b8f3a62
7 changed files with 227 additions and 257 deletions

View File

@@ -3,9 +3,9 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "cross-env NEXT_PUBLIC_API_URL=https://cpcargo.uz next dev --port=3080", "dev": "cross-env NEXT_PUBLIC_API_URL=https://cpost.felixits.uz next dev --port=3080",
"build": "next build", "build": "next build",
"build:dev": "cross-env NEXT_PUBLIC_API_URL=https://cpcargo.uz next build", "build:dev": "cross-env NEXT_PUBLIC_API_URL=https://cpost.felixits.uz next build",
"build:prod": "cross-env NEXT_PUBLIC_API_URL=https://api.cpost-express.uz next build", "build:prod": "cross-env NEXT_PUBLIC_API_URL=https://api.cpost-express.uz next build",
"start": "next start", "start": "next start",
"lint": "next lint", "lint": "next lint",

View File

@@ -1,74 +1,44 @@
export type BoxStatus = 'READY_TO_INVOICE' | 'READY'; export type BoxStatus = 'READY_TO_INVOICE' | 'READY';
export const BoxStatusList: BoxStatus[] = ['READY_TO_INVOICE', 'READY']; export const BoxStatusList: BoxStatus[] = ['READY_TO_INVOICE', 'READY'];
export interface IBox { export interface IRealBox {
packetNetWeight: string;
totalNetWeight: string;
cargoId: string;
passportName: string;
id: number;
partyName: string;
boxType: string;
name: string;
volume: string;
boxWeight: number;
brutto: number;
hasInvoice: boolean;
totalItems: number;
status: BoxStatus;
totalBrutto: number;
}
export interface IBoxDetail {
packet: {
id: number;
cargoId: string;
packetNetWeight: number;
passportName: string;
totalItems: number;
totalNetWeight: number;
partyName: string;
partyId: string;
boxType: string;
name: string;
volume: string;
boxWeight: number;
brutto: number;
hasInvoice: boolean;
status: BoxStatus;
};
client: {
passportId: number;
passportName: string;
};
items: [
{
id: number;
partyName: string;
boxName: string; boxName: string;
cargoId: string; id: number;
trekId: string; packetsCount: number;
name: string; partyName: string;
nameRu: string;
amount: number;
weight: number;
price: number;
totalPrice: number;
hasImage: boolean;
imageUrl: string | null;
packetName: string;
status: BoxStatus;
},
];
} }
export type RealCreateBoxBodyType = { export interface IRealBoxDetail {
partyName: string, message: string;
packetDtos: number[] data: {
}; boxName: string;
party: {
id: number;
name: string;
};
packets: Array<{
id: number;
packetName: string;
}>;
};
}
export type UpdateRealBoxBodyType = { export interface RealCreateBoxBodyType {
boxId: string, partyName: string;
partyName: string, packetDtos: number[];
packetDtos: number[] }
};
export interface UpdateRealBoxBodyType {
boxId: string;
partyName: string;
packetDtos: number[];
}
export interface FormValues {
partyName: string;
paketIds: Array<{ id: string | number }>;
id?: number;
boxId?: string;
partyId?: number;
}

View File

@@ -2,7 +2,7 @@ import { IBox, UpdateBoxBodyType, IBoxDetail, BoxStatus } from '@/data/box/box.m
import { CommonResponseType, PageAble } from '@/helpers/types'; import { CommonResponseType, PageAble } from '@/helpers/types';
import { request } from '@/services/request'; import { request } from '@/services/request';
import axios from 'axios'; import axios from 'axios';
import { RealCreateBoxBodyType, UpdateRealBoxBodyType } from './real-box.model'; import { IRealBox, IRealBoxDetail, RealCreateBoxBodyType, UpdateRealBoxBodyType } from './real-box.model';
export const real_box_requests = { export const real_box_requests = {
async getAll(params?: { async getAll(params?: {
@@ -10,27 +10,31 @@ export const real_box_requests = {
sort?: string; sort?: string;
direction?: string; direction?: string;
cargoId?: string; cargoId?: string;
boxName?: string,
partyId?: string | number; partyId?: string | number;
status?: BoxStatus; status?: BoxStatus;
}) { }) {
return request.get<CommonResponseType<PageAble<IBox>>>('/boxes/list', { params }); return request.get<CommonResponseType<PageAble<IRealBox>>>('/boxes/list', { params });
}, },
async create({ ...body }: RealCreateBoxBodyType) { async create({ ...body }: RealCreateBoxBodyType) {
return request.post<CommonResponseType>('/boxes/create', body); return request.post<CommonResponseType>('/boxes/create', body);
}, },
async update({ boxId, ...body }: UpdateRealBoxBodyType) { async update({ boxId, ...body }: UpdateRealBoxBodyType) {
return request.put<CommonResponseType>('/packets/update', body, { return request.put<CommonResponseType>('/boxes/change', body, {
params: { boxId }, params: { boxId },
}); });
}, },
async find(params: { packetId?: number | string }) { async find(params: { boxId?: number | string }) {
return request.get<CommonResponseType<IBoxDetail>>('/packets/find', { params }); return request.get<any>(`/boxes/find/${params.boxId}`,);
}, },
async delete(params: { packetId: number | string }) { async delete(params: { boxId: number | string }) {
return request.delete<CommonResponseType>('/packets/delete', { params }); return request.delete<CommonResponseType>('/boxes/delete', { params });
}, },
async downloadExcel(params: { packetId: number | string }) { async downloadExcel(params: { boxId: number | string }) {
return request.get<Blob>('/packets/download', { params, responseType: 'blob' }); return request.get<Blob>(`/boxes/download/`, { params });
},
async downloadQrCode(params: { boxId: number | string }) {
return request.get(`/qr/${params.boxId}`, { responseType: 'blob' });
}, },
async translateWithGoogleApi(params: { text: string }): Promise<string> { async translateWithGoogleApi(params: { text: string }): Promise<string> {
const response = await axios.post('https://translation.googleapis.com/language/translate/v2', undefined, { const response = await axios.post('https://translation.googleapis.com/language/translate/v2', undefined, {

View File

@@ -71,6 +71,7 @@ const DashboardEditBoxPage = (props: Props) => {
} }
); );
console.log(getOneBox, "pkets");
if (getOneBox.loading || !getOneBox.data) { if (getOneBox.loading || !getOneBox.data) {
return <Loader p={8} size={96} />; return <Loader p={8} size={96} />;

View File

@@ -1,25 +1,25 @@
'use client'; 'use client';
import BaseButton from '@/components/ui-kit/BaseButton'; import BaseButton from '@/components/ui-kit/BaseButton';
import BaseIconButton from '@/components/ui-kit/BaseIconButton';
import { party_requests } from '@/data/party/party.requests'; import { party_requests } from '@/data/party/party.requests';
import { box_requests } from '@/data/box/box.requests';
import { real_box_requests } from '@/data/real-box/real-box.requests';
import { pageLinks } from '@/helpers/constants'; import { pageLinks } from '@/helpers/constants';
import { notifyUnknownError } from '@/services/notification'; import { notifyUnknownError } from '@/services/notification';
import { Box, FormHelperText, Grid, Stack, Typography, styled } from '@mui/material'; import { Box, FormHelperText, Grid, Stack, Typography, styled } from '@mui/material';
import { AddCircleRounded, Close } from '@mui/icons-material';
import { useSearchParams } from 'next/navigation'; import { useSearchParams } from 'next/navigation';
import React, { useEffect, useMemo, useRef, useState } from 'react'; import React, { useEffect, useMemo, useRef, useState } from 'react';
import { Controller, useFieldArray, useForm } from 'react-hook-form'; import { Controller, useFieldArray, useForm } from 'react-hook-form';
import BaseIconButton from '@/components/ui-kit/BaseIconButton'; import AsyncSelect from 'react-select/async';
import { AddCircleRounded, Close } from '@mui/icons-material';
import useRequest from '@/hooks/useRequest';
import { useMyTranslation } from '@/hooks/useMyTranslation';
import { selectDefaultStyles } from '@/components/ui-kit/BaseReactSelect'; import { selectDefaultStyles } from '@/components/ui-kit/BaseReactSelect';
import { useAuthContext } from '@/context/auth-context'; import { useAuthContext } from '@/context/auth-context';
import { useMyNavigation } from '@/hooks/useMyNavigation'; import { useMyNavigation } from '@/hooks/useMyNavigation';
import AsyncSelect from 'react-select/async'; import { useMyTranslation } from '@/hooks/useMyTranslation';
import { box_requests } from '@/data/box/box.requests'; import { FormValues, RealCreateBoxBodyType, UpdateRealBoxBodyType } from '@/data/real-box/real-box.model';
import { real_box_requests } from '@/data/real-box/real-box.requests';
import get from 'lodash.get'; import get from 'lodash.get';
import useRequest from '@/hooks/useRequest';
const StyledCreateBox = styled(Box)` const StyledCreateBox = styled(Box)`
.item-row { .item-row {
@@ -34,36 +34,24 @@ const StyledCreateBox = styled(Box)`
} }
`; `;
type Props = { interface Props {
partiesData?: { value: number; label: string }[]; partiesData?: { value: number; label: string }[];
initialValues?: { initialValues?: {
id: number; id?: number;
boxId: string; boxId?: string;
box_name: string; partyId?: number;
partyId: number; partyName?: string;
partyName: string; paketIds?: Array<{ id: number; packetName: string }>;
packetId: string;
products_list: {
id: number;
price: number | string;
cargoId: string;
trekId: string;
name: string;
nameRu: string;
amount: number;
weight: number;
}[];
}; };
}; }
const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => { const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
const { user, isAdmin: isAdminUser } = useAuthContext(); const { user, isAdmin: isAdminUser } = useAuthContext();
const editMode = !!initialValues && !!initialValues.id; const editMode = !!initialValues?.id;
const isAdmin = isAdminUser && editMode;
const t = useMyTranslation(); const t = useMyTranslation();
const params = useSearchParams(); const params = useSearchParams();
const navigation = useMyNavigation(); const { push } = useMyNavigation();
const [partyId, setPartyId] = useState<number | string>(""); const [partyId, setPartyId] = useState<number | string>('');
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const helperRef = useRef<{ const helperRef = useRef<{
finished: boolean; finished: boolean;
@@ -82,20 +70,41 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
control, control,
handleSubmit, handleSubmit,
setValue, setValue,
reset,
formState: { errors }, formState: { errors },
} = useForm<any>({ } = useForm<FormValues>({
defaultValues: { defaultValues: {
partyId: params.get('party_id') ? +params.get('party_id')! : '', partyName: initialValues?.partyName || '',
paketIds: editMode paketIds: initialValues?.paketIds
? [{ id: initialValues?.partyId }] ? initialValues.paketIds.map((paket) => ({ id: paket.id }))
: params.get('party_id') : params.get('party_id')
? [{ id: +params.get('party_id')! }] ? [{ id: +params.get('party_id')! }]
: [{ id: '' }], : [{ id: '' }],
...initialValues, id: initialValues?.id,
boxId: initialValues?.boxId,
partyId: initialValues?.partyId,
}, },
}); });
const pakets = useFieldArray({ // Reset form when initialValues change (for edit mode)
useEffect(() => {
if (initialValues) {
reset({
partyName: initialValues.partyName || '',
paketIds: initialValues.paketIds
? initialValues.paketIds.map((paket) => ({ id: paket.id }))
: [{ id: '' }],
id: initialValues.id,
boxId: initialValues.boxId,
partyId: initialValues.partyId,
});
if (initialValues.partyId) {
setPartyId(initialValues.partyId);
}
}
}, [initialValues, reset]);
const { fields, append, remove } = useFieldArray({
control, control,
name: 'paketIds', name: 'paketIds',
keyName: 'key', keyName: 'key',
@@ -109,37 +118,34 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
partyId: partyId, partyId: partyId,
}), }),
{ {
selectData(data) { selectData: (data) => data?.data?.data ?? [],
return data?.data?.data; enabled: !!partyId,
}, },
}
); );
const { data: list } = useMemo(() => { const list = useMemo(() => {
if (getBoxesQuery.data?.data) { return getBoxesQuery.data?.data.filter((box: any) => box.status === 'READY_TO_INVOICE') ?? [];
return { }, [getBoxesQuery.data]);
data: getBoxesQuery.data.data.filter((box: any) => box.status === 'READY_TO_INVOICE'),
};
}
return { data: [] };
}, [getBoxesQuery, partyId]);
useEffect(() => { useEffect(() => {
if (partyId) { if (partyId) {
getBoxesQuery.refetch(); getBoxesQuery.refetch();
} }
}, [partyId]); }, [partyId, getBoxesQuery.refetch]);
const { data: defaultParties } = useRequest(() => party_requests.getAll({ status: 'COLLECTING' }), { const { data: defaultParties } = useRequest(
() => party_requests.getAll({ status: 'COLLECTING' }),
{
enabled: true, enabled: true,
selectData(data) { selectData: (data) =>
return data.data.data.data.map(p => ({ value: p.id, label: p.name })); data.data.data.data.map((p: any) => ({ value: p.id, label: p.name })),
}, onSuccess: (data) => {
onSuccess(data) {
if (!editMode && data?.data?.data?.data?.[0]) { if (!editMode && data?.data?.data?.data?.[0]) {
helperRef.current.settedDefaultParty = data.data.data.data[0]; const defaultParty = data.data.data.data[0];
setValue('partyId', data.data.data.data[0].id); helperRef.current.settedDefaultParty = defaultParty;
setValue('paketIds[0].id', data.data.data.data[0].id); setValue('partyName', defaultParty.name);
setValue('paketIds.0.id', defaultParty.id); // Use dot notation
setPartyId(defaultParty.id);
} }
helperRef.current.partyFinished = true; helperRef.current.partyFinished = true;
if (helperRef.current.clientFinished) { if (helperRef.current.clientFinished) {
@@ -147,16 +153,17 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
} }
}, },
placeholderData: [], placeholderData: [],
}); },
);
const onSubmit = handleSubmit(async values => { const onSubmit = handleSubmit(async (values) => {
try { try {
setLoading(true); setLoading(true);
const packetDtos = values.paketIds.map((paket: any) => paket.id).filter((id: any) => id); const packetDtos = values.paketIds.map((paket) => Number(paket.id)).filter((id) => id);
if (editMode) { if (editMode) {
const updateBody: UpdateRealBoxBodyType = { const updateBody: UpdateRealBoxBodyType = {
boxId: initialValues?.boxId, boxId: initialValues!.boxId!,
partyName: values.partyName, partyName: values.partyName,
packetDtos, packetDtos,
}; };
@@ -169,7 +176,7 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
await real_box_requests.create(createBody); await real_box_requests.create(createBody);
} }
navigation.push(pageLinks.dashboard.boxes.index); push(pageLinks.dashboard.real_boxes.index);
} catch (error) { } catch (error) {
notifyUnknownError(error); notifyUnknownError(error);
} finally { } finally {
@@ -177,18 +184,25 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
} }
}); });
const partyOptions = (inputValue: string) => { const partyOptions = async (inputValue: string) => {
return party_requests.getAll({ status: 'COLLECTING', partyName: inputValue }).then(res => { try {
return res.data.data.data.map(p => ({ label: p.name, value: p.id })); const res = await party_requests.getAll({
status: 'COLLECTING',
partyName: inputValue,
}); });
return res.data.data.data.map((p: any) => ({ label: p.name, value: p.id }));
} catch (error) {
notifyUnknownError(error);
return [];
}
}; };
const appendPaket = () => { const appendPaket = () => {
pakets.append({ id: '' }); append({ id: '' });
}; };
const removePaket = (index: number) => { const removePaket = (index: number) => {
pakets.remove(index); remove(index);
}; };
return ( return (
@@ -201,31 +215,31 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
backgroundColor: '#fff', backgroundColor: '#fff',
}} }}
> >
<Box component={'form'} onSubmit={onSubmit}> <Box component="form" onSubmit={onSubmit}>
<Typography variant='h5' mb={3.5}> <Typography variant="h5" mb={3.5}>
{editMode ? t('update_box') : t('create_box')} {editMode ? t('update_box') : t('create_box')}
</Typography> </Typography>
<Grid container columnSpacing={2.5} rowSpacing={3} mb={3.5}> <Grid container columnSpacing={2.5} rowSpacing={3} mb={3.5}>
<Grid item xs={12}> <Grid item xs={12}>
<Typography fontSize={'18px'} fontWeight={500} color='#5D5850' mb={2}> <Typography fontSize="18px" fontWeight={500} color="#5D5850" mb={2}>
{t('party_name')} {t('party_name')}
</Typography> </Typography>
<Controller <Controller
name='partyId' name="partyName"
control={control} control={control}
rules={{ required: requiredText }} rules={{ required: requiredText }}
render={({ field }) => ( render={({ field }) => (
<AsyncSelect <AsyncSelect
onChange={(newValue: any) => { onChange={(newValue: any) => {
field.onChange(newValue.value); field.onChange(newValue?.label ?? '');
setPartyId(newValue.value); setPartyId(newValue?.value ?? '');
}} }}
defaultValue={ defaultValue={
editMode editMode
? { ? {
value: initialValues.partyId, value: initialValues?.partyId,
label: initialValues.partyName, label: initialValues?.partyName,
} }
: partiesData?.length : partiesData?.length
? { ? {
@@ -239,12 +253,15 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
loadingMessage={() => t('loading')} loadingMessage={() => t('loading')}
onBlur={field.onBlur} onBlur={field.onBlur}
name={field.name} name={field.name}
defaultOptions={defaultParties!} defaultOptions={defaultParties ?? []}
loadOptions={partyOptions} loadOptions={partyOptions}
placeholder={t('enter_party_name_to_find')} placeholder={t('enter_party_name_to_find')}
/> />
)} )}
/> />
{!!errors.partyName && (
<FormHelperText sx={{ color: 'red' }}>{requiredText}</FormHelperText>
)}
</Grid> </Grid>
<Grid item xs={12}> <Grid item xs={12}>
@@ -256,10 +273,10 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
padding: '24px', padding: '24px',
}} }}
> >
<Typography fontSize={'18px'} fontWeight={500} color='#5D5850' mb={2}> <Typography fontSize="18px" fontWeight={500} color="#5D5850" mb={2}>
{t('packet')} {t('packet')}
</Typography> </Typography>
{pakets.fields.map((field, index) => ( {fields.map((field, index) => (
<Box key={field.key} className="item-row" mb={2}> <Box key={field.key} className="item-row" mb={2}>
<Box className="item-row-field" flex={1}> <Box className="item-row-field" flex={1}>
<Controller <Controller
@@ -269,13 +286,15 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
render={({ field: paketField }) => ( render={({ field: paketField }) => (
<AsyncSelect <AsyncSelect
onChange={(newValue: any) => { onChange={(newValue: any) => {
paketField.onChange(newValue?.value); paketField.onChange(newValue?.value ?? '');
}} }}
defaultValue={ defaultValue={
editMode && index === 0 && initialValues.packetId editMode && initialValues?.paketIds?.[index]
? { ? {
value: initialValues.packetId, value: initialValues.paketIds[index].id,
label: initialValues.box_name || `Box ${initialValues.packetId}`, label:
initialValues.paketIds[index].packetName ||
`Box ${initialValues.paketIds[index].id}`,
} }
: null : null
} }
@@ -284,19 +303,15 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
loadingMessage={() => t('loading')} loadingMessage={() => t('loading')}
onBlur={paketField.onBlur} onBlur={paketField.onBlur}
name={paketField.name} name={paketField.name}
defaultOptions={ defaultOptions={list.map((box: any) => ({
list.length > 0
? list.map((box: any) => ({
value: box.id, value: box.id,
label: box.box_name || box.name || `Box ${box.id}`, label: box.box_name || box.name || `Box ${box.id}`,
})) }))}
: []
}
loadOptions={async (inputValue: string) => { loadOptions={async (inputValue: string) => {
if (!partyId || partyId === '') return []; if (!partyId) return [];
try { try {
const res = await box_requests.getAll({ const res = await box_requests.getAll({
partyId: partyId, partyId,
}); });
return res.data.data.data.map((box: any) => ({ return res.data.data.data.map((box: any) => ({
label: box.box_name || box.name || `Box ${box.id}`, label: box.box_name || box.name || `Box ${box.id}`,
@@ -315,7 +330,7 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
<FormHelperText sx={{ color: 'red' }}>{requiredText}</FormHelperText> <FormHelperText sx={{ color: 'red' }}>{requiredText}</FormHelperText>
)} )}
</Box> </Box>
{pakets.fields.length > 1 && ( {fields.length > 1 && (
<Box className="item-row-field"> <Box className="item-row-field">
<BaseIconButton <BaseIconButton
size="small" size="small"
@@ -329,7 +344,7 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
)} )}
</Box> </Box>
))} ))}
<Stack alignItems={'center'} mt={2}> <Stack alignItems="center" mt={2}>
<BaseButton <BaseButton
sx={{ backgroundColor: '#239D5F' }} sx={{ backgroundColor: '#239D5F' }}
startIcon={<AddCircleRounded />} startIcon={<AddCircleRounded />}
@@ -342,7 +357,7 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
</Grid> </Grid>
</Grid> </Grid>
<BaseButton type='submit' colorVariant='blue' loading={loading}> <BaseButton type="submit" colorVariant="blue" loading={loading}>
{editMode ? t('update') : t('create')} {editMode ? t('update') : t('create')}
</BaseButton> </BaseButton>
</Box> </Box>
@@ -351,14 +366,3 @@ const DashboardCreateRealBoxPage = ({ initialValues, partiesData }: Props) => {
}; };
export default DashboardCreateRealBoxPage; export default DashboardCreateRealBoxPage;
export type RealCreateBoxBodyType = {
partyName: string;
packetDtos: number[];
};
export type UpdateRealBoxBodyType = {
boxId: string;
partyName: string;
packetDtos: number[];
};

View File

@@ -1,12 +1,11 @@
'use client'; 'use client';
import Loader from '@/components/common/Loader'; import Loader from '@/components/common/Loader';
import { box_requests } from '@/data/box/box.requests';
import useRequest from '@/hooks/useRequest'; import useRequest from '@/hooks/useRequest';
import DashboardCreateBoxPage from '@/routes/private/boxes-create/DashboardCreateBox';
import { useParams } from 'next/navigation'; import { useParams } from 'next/navigation';
import React from 'react'; import React, { useEffect } from 'react';
import DashboardCreateRealBoxPage from './DashboardCreateRealBox'; import DashboardCreateRealBoxPage from './DashboardCreateRealBox';
import { real_box_requests } from '@/data/real-box/real-box.requests';
type Props = {}; type Props = {};
@@ -16,70 +15,39 @@ const DashboardEditRealBoxPage = (props: Props) => {
const getOneBox = useRequest( const getOneBox = useRequest(
() => { () => {
return box_requests.find({ packetId: box_id }); return real_box_requests.find({ boxId: box_id });
}, },
{ {
selectData(data) { selectData(data) {
const boxData = data.data.data; const boxData = data.data; // ⬅️ Faqat data.data, data.data.data emas
if (!boxData) return null;
console.log(boxData.data, 'boxdata');
return { return {
id: +box_id, id: box_id,
box_name: boxData.packet.name, boxId: box_id!,
net_weight: +boxData.packet.brutto, partyId: boxData.data.party.id, // ⬅️ Togri yol
box_weight: +boxData.packet.boxWeight, partyName: boxData.data.party.name!,
box_type: boxData.packet.boxType, paketIds: boxData.data.packets!
box_size: boxData.packet.volume,
passportName: boxData.packet.passportName,
status: boxData.packet.status,
packetId: box_id,
partyId: +boxData.packet.partyId,
partyName: boxData.packet.partyName,
// client_id: boxData.client?.passportId,
passportId: boxData.client?.passportId,
client_id: boxData.packet?.cargoId,
clientId: boxData.client?.passportId,
clientName: boxData.client?.passportName,
products_list: [
...boxData.items.map(item => {
let name = item.name;
let nameRu = item.nameRu;
// try {
// name = item.name.split(' / ')[0];
// nameRu = item.name.split(' / ')[1];
// } catch (error) {
// console.error('prepare edit values error', error);
// }
return {
id: item.id,
price: item.price,
cargoId: item.cargoId,
trekId: item.trekId,
name: name,
nameRu: nameRu,
amount: +item.amount,
weight: +item.weight,
};
}),
],
}; };
}, },
} }
); );
useEffect(() => {
getOneBox.refetch()
}, [box_id])
console.log(getOneBox);
if (getOneBox.loading || !getOneBox.data) { if (getOneBox.loading || !getOneBox.data) {
return <Loader p={8} size={96} />; return <Loader p={8} size={96} />;
} }
return ( return (
<> <>
<DashboardCreateRealBoxPage /> <DashboardCreateRealBoxPage initialValues={getOneBox.data as any} />
</> </>
); );
}; };

View File

@@ -10,6 +10,7 @@ import BasePagination from '@/components/ui-kit/BasePagination';
import { useAuthContext } from '@/context/auth-context'; import { useAuthContext } from '@/context/auth-context';
import { BoxStatus, BoxStatusList, IBox } from '@/data/box/box.model'; import { BoxStatus, BoxStatusList, IBox } from '@/data/box/box.model';
import { box_requests } from '@/data/box/box.requests'; import { box_requests } from '@/data/box/box.requests';
import { IRealBox } from '@/data/real-box/real-box.model';
import { real_box_requests } from '@/data/real-box/real-box.requests'; import { real_box_requests } from '@/data/real-box/real-box.requests';
import { DEFAULT_PAGE_SIZE, pageLinks } from '@/helpers/constants'; import { DEFAULT_PAGE_SIZE, pageLinks } from '@/helpers/constants';
import useDebouncedInput from '@/hooks/useDebouncedInput'; import useDebouncedInput from '@/hooks/useDebouncedInput';
@@ -23,6 +24,7 @@ import { getBoxStatusStyles, getStatusColor } from '@/theme/getStatusBoxStyles';
import { Add, QrCode, AddCircleOutline, Circle, Delete, Download, Edit, FilterList, FilterListOff, Search, PlusOne } from '@mui/icons-material'; import { Add, QrCode, AddCircleOutline, Circle, Delete, Download, Edit, FilterList, FilterListOff, Search, PlusOne } from '@mui/icons-material';
import { Box, Button, Stack, Tooltip, Typography } from '@mui/material'; import { Box, Button, Stack, Tooltip, Typography } from '@mui/material';
import { useRouter } from 'next/navigation'; import { useRouter } from 'next/navigation';
import { log } from 'node:console';
import React, { useEffect, useMemo, useState } from 'react'; import React, { useEffect, useMemo, useState } from 'react';
type Props = {}; type Props = {};
@@ -84,6 +86,7 @@ const DashboardRealBoxesPage = (props: Props) => {
}; };
} }
}, [getBoxesQuery]); }, [getBoxesQuery]);
const loading = getBoxesQuery.loading; const loading = getBoxesQuery.loading;
const handleChange = (newPage: number) => { const handleChange = (newPage: number) => {
setTimeout(() => { setTimeout(() => {
@@ -102,7 +105,7 @@ const DashboardRealBoxesPage = (props: Props) => {
try { try {
setDeleteIds(p => [...p, id]); setDeleteIds(p => [...p, id]);
await box_requests.delete({ packetId: id }); await real_box_requests.delete({ boxId: id });
getBoxesQuery.refetch(); getBoxesQuery.refetch();
} catch (error) { } catch (error) {
notifyUnknownError(error); notifyUnknownError(error);
@@ -116,7 +119,7 @@ const DashboardRealBoxesPage = (props: Props) => {
try { try {
setDownloadIds(p => [...p, id]); setDownloadIds(p => [...p, id]);
const response = await box_requests.downloadExcel({ packetId: id }); const response = await real_box_requests.downloadExcel({ boxId: id });
const file = new File([response.data], 'Box-excel.xlsx', { type: response.data.type }); const file = new File([response.data], 'Box-excel.xlsx', { type: response.data.type });
file_service.download(file); file_service.download(file);
} catch (error) { } catch (error) {
@@ -126,6 +129,23 @@ const DashboardRealBoxesPage = (props: Props) => {
} }
}; };
const onDownloadQrCode = async (id: number) => {
if (downloadIds.includes(id)) return;
try {
setDownloadIds(p => [...p, id]);
const response = await real_box_requests.downloadQrCode({ boxId: id });
console.log(response, "rres");
const file = new File([response.data], 'qr.png', { type: response.data.type });
file_service.download(file);
} catch (error) {
notifyUnknownError(error);
console.log(error);
} finally {
setDownloadIds(prev => prev.filter(i => i !== id));
}
};
const onChangeStatus = async (id: number, newStatus: BoxStatus) => { const onChangeStatus = async (id: number, newStatus: BoxStatus) => {
if (changeStatusIds.includes(id)) return; if (changeStatusIds.includes(id)) return;
@@ -149,7 +169,7 @@ const DashboardRealBoxesPage = (props: Props) => {
}, [keyword]); }, [keyword]);
// No, PartyName, PacketName, PartyTozaOg'irlik, CountOfItems, WeightOfItems, CargoID, PassportNameFamily - PacketStatusForInvoice // No, PartyName, PacketName, PartyTozaOg'irlik, CountOfItems, WeightOfItems, CargoID, PassportNameFamily - PacketStatusForInvoice
const columns: ColumnData<IBox>[] = [ const columns: ColumnData<IRealBox>[] = [
{ {
label: t('No'), label: t('No'),
width: 100, width: 100,
@@ -161,9 +181,12 @@ const DashboardRealBoxesPage = (props: Props) => {
label: t("qr_code"), label: t("qr_code"),
width: 120, width: 120,
renderCell: data => { renderCell: data => {
return <Button> return <Button
onClick={() =>
onDownloadQrCode(data.id)
}>
<QrCode /> <QrCode />
</Button>; </Button >;
}, },
}, },
{ {
@@ -177,12 +200,12 @@ const DashboardRealBoxesPage = (props: Props) => {
}, },
}, },
{ {
dataKey: 'cargoId', dataKey: 'boxName',
label: t('cargo_id'), label: t('cargo_id'),
width: 120, width: 120,
}, },
{ {
dataKey: 'partyName', dataKey: "boxName",
label: t('party_name'), label: t('party_name'),
width: 120, width: 120,
}, },
@@ -197,7 +220,7 @@ const DashboardRealBoxesPage = (props: Props) => {
// width: 120, // width: 120,
// }, // },
{ {
dataKey: 'totalItems', dataKey: 'packetsCount',
label: t('count_of_items'), label: t('count_of_items'),
width: 120, width: 120,
}, },
@@ -360,7 +383,7 @@ const DashboardRealBoxesPage = (props: Props) => {
</Stack> </Stack>
</Stack> </Stack>
<Box mb={6}> <Box mb={6}>
<MyTable columns={columns} data={list} loading={loading} /> <MyTable columns={columns as any} data={list} loading={loading} />
</Box> </Box>
<Stack direction={'row'} justifyContent={'center'}> <Stack direction={'row'} justifyContent={'center'}>
<BasePagination page={page} pageSize={pageSize} totalCount={totalElements} onChange={handleChange} /> <BasePagination page={page} pageSize={pageSize} totalCount={totalElements} onChange={handleChange} />