realbox edit components
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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, {
|
||||||
|
|||||||
@@ -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} />;
|
||||||
|
|||||||
@@ -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[];
|
|
||||||
};
|
|
||||||
@@ -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, // ⬅️ To‘g‘ri yo‘l
|
||||||
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} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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,7 +181,10 @@ 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} />
|
||||||
|
|||||||
Reference in New Issue
Block a user