Skip to content
Extraits de code Groupes Projets
Valider e8a07bc7 rédigé par salaheddine zidani's avatar salaheddine zidani
Parcourir les fichiers

Merge branch 'develop' into 'feature/MYD-192'

# Conflicts:
#   .env
1 requête de fusion!239MYD-192/ Delete order, update order status, order details
Pipeline #5780 réussi avec l'étape
in 5 minutes et 38 secondes
Affichage de
avec 1057 ajouts et 8 suppressions
...@@ -39,5 +39,3 @@ NEXT_PUBLIC_DEFAULT_IMAGE_URL=https://mydressin-rec.s3.eu-west-3.amazonaws.com/I ...@@ -39,5 +39,3 @@ NEXT_PUBLIC_DEFAULT_IMAGE_URL=https://mydressin-rec.s3.eu-west-3.amazonaws.com/I
#GATEWAY API URL #GATEWAY API URL
NEXT_PUBLIC_MYDRESSIN_GATEWAY_API_URL=https://mydressin-api.mc-test.xyz NEXT_PUBLIC_MYDRESSIN_GATEWAY_API_URL=https://mydressin-api.mc-test.xyz
import ShippingMainView from "@/shared/sections/shipping/general/ShippingMainView";
export const metadata = {
title: 'Dashboard: Livraison',
};
export default function ListShipmentPage() {
return <ShippingMainView defaultValue='5'/>;
}
import ShippingMainView from "@/shared/sections/shipping/general/ShippingMainView";
export const metadata = {
title: 'Dashboard: Livraison',
};
export default function ListShipmentPage() {
return <ShippingMainView defaultValue='5'/>;
}
import { MondialRelayMode, ShippingMethodType } from "@/contexts/types/Shipping";
export enum ShipmentStatus {
FAILED = 'FAILED',
WAITING_FOR_PAYMENT = 'WAITING_FOR_PAYMENT',
PENDING = 'PENDING',
IN_PROGRESS = 'IN_PROGRESS',
SHIPPED = 'SHIPPED',
DELIVERED = 'DELIVERED',
CANCELED = 'CANCELED',
}
export const shipmentStatusLabels = {
[ShipmentStatus.FAILED]: 'Échec de l\'expédition',
[ShipmentStatus.WAITING_FOR_PAYMENT]: 'En attente de paiement',
[ShipmentStatus.PENDING]: 'En attente',
[ShipmentStatus.IN_PROGRESS]: 'En cours',
[ShipmentStatus.SHIPPED]: 'Expédié',
[ShipmentStatus.DELIVERED]: 'Livré',
[ShipmentStatus.CANCELED]: 'Annulé',
};
export enum MondialRelayShipmentStatus {
SHIPMENT_CREATED = 'SHIPMENT_CREATED',
REGISTERED_PACKAGE = 'REGISTERED_PACKAGE',
}
export const mondialRelayShipmentStatusLabels = {
[MondialRelayShipmentStatus.SHIPMENT_CREATED]: 'Expédition créée',
[MondialRelayShipmentStatus.REGISTERED_PACKAGE]: 'Colis enregistré',
};
export interface Shipment {
id: number;
createdAt: Date;
updatedAt: Date;
clientId: number;
userId: number;
orderId: number;
shipmentStatus: ShipmentStatus;
total: number;
shippingMethodType: ShippingMethodType;
shippingFirstName: string;
shippingLastName: string;
shippingCompanyName?: string;
shippingEmail: string;
shippingPhoneNumber: string;
shippingStreet: string;
shippingHome: string;
shippingCity: string;
shippingZipCode: string;
shippingCountry: string;
trackingNumber: string;
}
export interface ShipmentMondialRelay extends Shipment {
mondialRelayMode: MondialRelayMode;
mondialRelayShipmentStatus: MondialRelayShipmentStatus;
}
export interface ShipmentColissimo extends Shipment {
labelCreatedAt: Date;
}
export type ShipmentTableFilterValue = string | string[] | Date | null;
export type ShipmentTableFilters = {
country: string[];
shippingMethod: string[];
status: string[];
startDate: Date | null;
endDate: Date | null;
};
...@@ -32,14 +32,14 @@ export const paths = { ...@@ -32,14 +32,14 @@ export const paths = {
termeChoix: { termeChoix: {
root: (attributId: string) => root: (attributId: string) =>
`${ROOTS.DASHBOARD}/product/attribut/${attributId}/termeChoix`, `${ROOTS.DASHBOARD}/product/attribut/${attributId}/termeChoix`,
editChoix : (attributId: string, choiceId: string )=> editChoix: (attributId: string, choiceId: string) =>
`${ROOTS.DASHBOARD}/product/attribut/${attributId}/termeChoix/${choiceId}/edit`, `${ROOTS.DASHBOARD}/product/attribut/${attributId}/termeChoix/${choiceId}/edit`,
}, },
termeImage: { termeImage: {
root: (id: string) => root: (id: string) =>
`${ROOTS.DASHBOARD}/product/attribut/${id}/termeImage`, `${ROOTS.DASHBOARD}/product/attribut/${id}/termeImage`,
editImage : (attributId: string, imageId: string )=> editImage: (attributId: string, imageId: string) =>
`${ROOTS.DASHBOARD}/product/attribut/${attributId}/termeImage/${imageId}/edit`, `${ROOTS.DASHBOARD}/product/attribut/${attributId}/termeImage/${imageId}/edit`,
}, },
termeLabel: { termeLabel: {
...@@ -122,6 +122,10 @@ export const paths = { ...@@ -122,6 +122,10 @@ export const paths = {
shippingClass: { shippingClass: {
shippingClassList: `${ROOTS.DASHBOARD}/shipping/general/shippingClass`, shippingClassList: `${ROOTS.DASHBOARD}/shipping/general/shippingClass`,
}, },
shipments: {
shipmentList: `${ROOTS.DASHBOARD}/shipping/general/shipments`,
details: (id: string) => `${ROOTS.DASHBOARD}/shipping/general/shipments/${id}`,
},
}, },
colissimo: `${ROOTS.DASHBOARD}/shipping/colissimo`, colissimo: `${ROOTS.DASHBOARD}/shipping/colissimo`,
mondialRelayInPost: { mondialRelayInPost: {
...@@ -167,7 +171,7 @@ export const paths = { ...@@ -167,7 +171,7 @@ export const paths = {
listSupplierOrder: `${ROOTS.DASHBOARD}/driver/supplierOrder`, listSupplierOrder: `${ROOTS.DASHBOARD}/driver/supplierOrder`,
details: (id: string) => `${ROOTS.DASHBOARD}/driver/supplierOrder/${id}/details`, details: (id: string) => `${ROOTS.DASHBOARD}/driver/supplierOrder/${id}/details`,
supplier: `${ROOTS.DASHBOARD}/driver/supplier`, supplier: `${ROOTS.DASHBOARD}/driver/supplier`,
supplierDetails : (id: string) => `${ROOTS.DASHBOARD}/driver/supplier/${id}/details` supplierDetails: (id: string) => `${ROOTS.DASHBOARD}/driver/supplier/${id}/details`
}, },
}, },
promo: { promo: {
...@@ -177,7 +181,7 @@ export const paths = { ...@@ -177,7 +181,7 @@ export const paths = {
all_promo: `${ROOTS.DASHBOARD}/promo`, all_promo: `${ROOTS.DASHBOARD}/promo`,
details: (id: string) => `${ROOTS.DASHBOARD}/promo/${id}`, details: (id: string) => `${ROOTS.DASHBOARD}/promo/${id}`,
edit: (id: number) => `${ROOTS.DASHBOARD}/promo/${id}/edit`, edit: (id: number) => `${ROOTS.DASHBOARD}/promo/${id}/edit`,
Duplicatepromo: (id: string) => `${ROOTS.DASHBOARD}/promo/duplicate/${id}`, Duplicatepromo: (id: string) => `${ROOTS.DASHBOARD}/promo/duplicate/${id}`,
}, },
giftcard: { giftcard: {
......
...@@ -175,6 +175,11 @@ export const endpoints = { ...@@ -175,6 +175,11 @@ export const endpoints = {
delete: (shippingAreaId: string) => delete: (shippingAreaId: string) =>
`/api/shipping/area/${shippingAreaId}`, `/api/shipping/area/${shippingAreaId}`,
}, },
shipments: {
getAll: `/api/shipping/shipment/all_shipments`,
getById: (shipmentId: string) =>
`/api/shipping/shipment/${shipmentId}`,
},
}, },
media: { media: {
getAll: `/api/medias/all-medias`, getAll: `/api/medias/all-medias`,
......
import { useMemo } from "react";
import useSWR, { mutate } from "swr";
import axiosInstance, { endpoints, fetcher } from "./server";
import { Order, OrderStatus } from "@/contexts/types/main-order";
import { Shipment } from "@/contexts/types/shipment";
const options = {
revalidateIfStale: false,
revalidateOnFocus: false,
revalidateOnReconnect: false,
};
///////////////////-----------Order Management----------///////////////////////
//////////////////////////////////////////////////////////////////////////////
export function getAllShipments() {
const URL = [endpoints.shipping.shipments.getAll];
const { data, error, isLoading, isValidating, mutate } = useSWR<Shipment[]>(URL, fetcher, options);
console.log("data of order : "+data);
const memoizedValue = useMemo(
() => ({
shipmentsData: (data as Shipment[]) || [],
shipmentsError: error,
shipmentsLoading: isLoading,
shipmentsValidating: isValidating,
mutateShipments: mutate,
}),
[data, error]
);
return memoizedValue;
}
export function getShipmentById(shipmentId: string) {
const { data, error, isLoading, isValidating, mutate } = useSWR<Shipment>(
shipmentId ? endpoints.shipping.shipments.getById(shipmentId) : null,
fetcher,
options
);
const memoizedValue = useMemo(
() => ({
shipmentData: data,
shipmentError: error,
shipmentLoading: isLoading,
shipmentValidating: isValidating,
mutateShipment: mutate,
}),
[data, error]
);
return memoizedValue;
}
...@@ -18,6 +18,7 @@ import ShippingAreaTableView from './shippingAreas/ShippingAreaTableView'; ...@@ -18,6 +18,7 @@ import ShippingAreaTableView from './shippingAreas/ShippingAreaTableView';
import DeliveryRulesView from './deliveryRules/DeliveryRulesView'; import DeliveryRulesView from './deliveryRules/DeliveryRulesView';
import ShippingClassTableView from './shippingClass/ShippingClassTableView'; import ShippingClassTableView from './shippingClass/ShippingClassTableView';
import ShippingStatisticsView from './statistics/ShippingStatisticsView'; import ShippingStatisticsView from './statistics/ShippingStatisticsView';
import ShipmentListView from './shipments/ShipmentListView';
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------
...@@ -38,9 +39,13 @@ const TABS = [ ...@@ -38,9 +39,13 @@ const TABS = [
{ {
value: '4', value: '4',
label: "Classes d'expédition", label: "Classes d'expédition",
},, },
{ {
value: '5', value: '5',
label: 'Expéditions',
},
{
value: '6',
label: 'Statistiques', label: 'Statistiques',
}, },
]; ];
...@@ -83,7 +88,10 @@ export default function ShippingMainView({ defaultValue }: ShippingMainViewProps ...@@ -83,7 +88,10 @@ export default function ShippingMainView({ defaultValue }: ShippingMainViewProps
{currentTab === '4' && <ShippingClassTableView />} {currentTab === '4' && <ShippingClassTableView />}
{currentTab === '5' && <ShippingStatisticsView />} {currentTab === '5' && <ShipmentListView />}
{currentTab === '6' && <ShippingStatisticsView />}
</Container> </Container>
); );
} }
"use client";
import isEqual from "lodash/isEqual";
import { useState, useEffect, useCallback } from "react";
import Stack from "@mui/material/Stack";
import Button from "@mui/material/Button";
import Card from "@mui/material/Card";
import Box from "@mui/material/Box";
import {
DataGrid,
GridColDef,
GridToolbarContainer,
GridRowSelectionModel,
GridToolbarQuickFilter,
GridToolbarColumnsButton,
GridColumnVisibilityModel,
} from "@mui/x-data-grid";
import { paths } from "@/routes/paths";
import { useRouter } from "@/hooks";
import { useBoolean } from "@/hooks/use-boolean";
import { isAfter, isBetween } from '@/utils/format-time';
import { useSnackbar } from "@/shared/components/snackbar";
import EmptyContent from "@/shared/components/empty-content";
import { useSettingsContext } from "@/shared/components/settings";
import CustomBreadcrumbs from "@/shared/components/custom-breadcrumbs";
import Select, { SelectChangeEvent } from "@mui/material/Select";
import FormControl from "@mui/material/FormControl";
import InputLabel from "@mui/material/InputLabel";
import MenuItem from "@mui/material/MenuItem";
import {
RenderCellID,
RenderCellCreatedAt,
RenderCellCustomer,
RenderCellAdress,
RenderCellCountry,
RenderCellShippingMethod,
RenderCellStatus,
RenderCellTrackingNumber
} from "./shipment-table-row";
import { ShippingMethodType, shippingMethodTypeLabels } from "@/contexts/types/Shipping";
import { countries } from "@/shared/assets/data";
import { Shipment, ShipmentStatus, shipmentStatusLabels, ShipmentTableFilters, ShipmentTableFilterValue } from "@/contexts/types/shipment";
import ShipmentTableToolbar from "./shipment-table-toolbar";
import ShipmentTableFiltersResult from "./shipment-table-filters-result";
import { getAllShipments } from "@/shared/api/shipment";
// ----------------------------------------------------------------------
const Country_OPTIONS = countries
.filter(country => country.label && country.code)
.map(country => ({
value: country.label,
label: country.label,
}));
const ShippingMethod_OPTIONS = Object.keys(ShippingMethodType).map((key) => ({
value: ShippingMethodType[key as keyof typeof ShippingMethodType],
label: shippingMethodTypeLabels[ShippingMethodType[key as keyof typeof ShippingMethodType]],
}));
const Status_OPTIONS = Object.keys(ShipmentStatus).map((key) => ({
value: ShipmentStatus[key as keyof typeof ShipmentStatus],
label: shipmentStatusLabels[ShipmentStatus[key as keyof typeof ShipmentStatus]],
}));
const defaultFilters: ShipmentTableFilters = {
country: [],
shippingMethod: [],
status: [],
startDate: null,
endDate: null,
};
const HIDE_COLUMNS = {
category: false,
};
const HIDE_COLUMNS_TOGGLABLE = ["category", "actions"];
// ----------------------------------------------------------------------
export default function ShipmentListView() {
const { enqueueSnackbar } = useSnackbar();
const confirmRows = useBoolean();
const router = useRouter();
const settings = useSettingsContext();
const { shipmentsData, shipmentsError, shipmentsLoading } = getAllShipments();
const [tableData, setTableData] = useState<Shipment[]>(shipmentsData);
const [filters, setFilters] = useState(defaultFilters);
const [selectedRowIds, setSelectedRowIds] = useState<GridRowSelectionModel>(
[]
);
const [columnVisibilityModel, setColumnVisibilityModel] =
useState<GridColumnVisibilityModel>(HIDE_COLUMNS);
useEffect(() => {
if (shipmentsData.length) {
setTableData(shipmentsData);
}
}, [shipmentsData]);
const dateError = isAfter(filters.startDate, filters.endDate);
const dataFiltered = applyFilter({
inputData: tableData,
filters,
dateError,
});
const canReset = !isEqual(defaultFilters, filters);
const handleFilters = useCallback(
(name: string, value: ShipmentTableFilterValue) => {
setFilters((prevState) => ({
...prevState,
[name]: value,
}));
},
[]
);
const handleResetFilters = useCallback(() => {
setFilters(defaultFilters);
}, []);
const handleViewRow = useCallback(
(id: string) => {
router.push(paths.dashboard.admin.shipping.general.shipments.details(id));
},
[router]
);
const columns: GridColDef[] = [
{
field: "id",
headerName: "ID",
flex: 1,
width: 40,
filterable: true,
hideable: false,
renderCell: (params) => <RenderCellID params={params} />,
},
{
field: "createdAt",
headerName: "Date Création",
width: 120,
hideable: false,
renderCell: (params) => <RenderCellCreatedAt params={params} />,
},
{
field: "customer",
headerName: "Client",
minWidth: 190,
renderCell: (params) => <RenderCellCustomer params={params} />,
},
{
field: "adress",
headerName: "Adresse",
minWidth: 180,
renderCell: (params) => <RenderCellAdress params={params} />,
},
{
field: "country",
headerName: "Pays",
minWidth: 100,
renderCell: (params) => <RenderCellCountry params={params} />,
},
{
field: "shippingMethod",
headerName: "Méthode de livraison",
minWidth: 200,
renderCell: (params) => <RenderCellShippingMethod params={params} />,
},
{
field: "status",
headerName: "Status",
minWidth: 110,
renderCell: (params) => <RenderCellStatus params={params} />,
},
{
field: "trackingNumber",
headerName: "Numéro de suivi",
minWidth: 130,
align: 'right',
renderCell: (params) => <RenderCellTrackingNumber params={params} />,
},
];
const getTogglableColumns = () =>
columns
.filter((column) => !HIDE_COLUMNS_TOGGLABLE.includes(column.field))
.map((column) => column.field);
const [actionGroupe, setActionGroupe] = useState("");
const handleChangeActionGroupe = (event: SelectChangeEvent) => {
setActionGroupe(event.target.value as string);
};
return (
<>
<CustomBreadcrumbs
heading="Liste des expéditions"
links={[
{ name: 'Dashboard', href: paths.dashboard.root, },
{ name: 'Livraison', href: paths.dashboard.admin.shipping.general.root, },
{ name: "Expéditions" },
]}
sx={{
mb: {
xs: 3,
md: 5,
},
}}
/>
<Card>
<Box
sx={{
width: "100%",
flexGrow: { md: 1 },
display: { md: "flex" },
flexDirection: { md: "column" },
}}
>
<DataGrid
checkboxSelection
disableRowSelectionOnClick
rows={dataFiltered}
columns={columns}
getRowHeight={() => "auto"}
pageSizeOptions={[5, 10, 25]}
initialState={{
pagination: {
paginationModel: { pageSize: 10 },
},
}}
onRowSelectionModelChange={(newSelectionModel) => {
setSelectedRowIds(newSelectionModel);
}}
columnVisibilityModel={columnVisibilityModel}
onColumnVisibilityModelChange={(newModel) =>
setColumnVisibilityModel(newModel)
}
slots={{
toolbar: () => (
<>
<GridToolbarContainer>
<ShipmentTableToolbar
filters={filters}
onFilters={handleFilters}
countryOptions={Country_OPTIONS}
shippingMethodOptions={ShippingMethod_OPTIONS}
statusOptions={Status_OPTIONS}
dateError={dateError}
/>
<GridToolbarQuickFilter />
<Stack
spacing={1}
flexGrow={1}
direction="row"
alignItems="center"
justifyContent="flex-end"
>
<GridToolbarColumnsButton />
</Stack>
</GridToolbarContainer>
{canReset && (
<ShipmentTableFiltersResult
filters={filters}
onFilters={handleFilters}
onResetFilters={handleResetFilters}
results={dataFiltered.length}
sx={{ p: 2.5, pt: 0 }}
shippingMethodOptions={ShippingMethod_OPTIONS}
statusOptions={Status_OPTIONS}
/>
)}
</>
),
noRowsOverlay: () => <EmptyContent title="No Data" />,
noResultsOverlay: () => <EmptyContent title="No results found" />,
}}
slotProps={{
columnsPanel: {
getTogglableColumns,
},
}}
/>
</Box>
</Card>
</>
);
}
// ----------------------------------------------------------------------
function applyFilter({
inputData,
filters,
dateError,
}: {
inputData: Shipment[];
filters: ShipmentTableFilters;
dateError: boolean;
}) {
const { country, shippingMethod, status, startDate, endDate } = filters;
if (country.length) {
inputData = inputData.filter((shipment) =>
country.includes(shipment.shippingCountry)
);
}
if (shippingMethod.length) {
inputData = inputData.filter((shipment) =>
shippingMethod.includes(shipment.shippingMethodType)
);
}
if (status.length) {
inputData = inputData.filter((shipment) =>
status.includes(shipment.shipmentStatus)
);
}
if (!dateError) {
if (startDate && endDate) {
inputData = inputData.filter((shipment) => isBetween(shipment.createdAt, startDate, endDate));
}
}
return inputData;
}
import { useCallback } from "react";
import Box from "@mui/material/Box";
import Chip from "@mui/material/Chip";
import Paper from "@mui/material/Paper";
import Button from "@mui/material/Button";
import Stack, { StackProps } from "@mui/material/Stack";
import Iconify from "@/shared/components/iconify";
import { ShipmentTableFilters, ShipmentTableFilterValue } from "@/contexts/types/shipment";
// ----------------------------------------------------------------------
type Props = StackProps & {
filters: ShipmentTableFilters;
onFilters: (name: string, value: ShipmentTableFilterValue) => void;
//
onResetFilters: VoidFunction;
//
results: number;
shippingMethodOptions: {
value: string;
label: string;
}[];
statusOptions: {
value: string;
label: string;
}[];
};
export default function ShipmentTableFiltersResult({
filters,
onFilters,
//
onResetFilters,
//
results,
shippingMethodOptions,
statusOptions,
...other
}: Props) {
const handleRemoveCountry = useCallback(
(inputValue: string) => {
const newValue = filters.country.filter((item) => item !== inputValue);
onFilters("country", newValue);
},
[filters.country, onFilters]
);
const handleRemoveShippingMethod = useCallback(
(inputValue: string) => {
const newValue = filters.shippingMethod.filter((item) => item !== inputValue);
onFilters("shippingMethod", newValue);
},
[filters.shippingMethod, onFilters]
);
const handleRemoveStatus = useCallback(
(inputValue: string) => {
const newValue = filters.status.filter((item) => item !== inputValue);
onFilters("status", newValue);
},
[filters.status, onFilters]
);
return (
<Stack spacing={1.5} {...other}>
<Box sx={{ typography: "body2" }}>
<strong>{results}</strong>
<Box component="span" sx={{ color: "text.secondary", ml: 0.25 }}>
results found
</Box>
</Box>
<Stack
flexGrow={1}
spacing={1}
direction="row"
flexWrap="wrap"
alignItems="center"
>
{!!filters.country.length && (
<Block label="Pays:">
{filters.country.map((item) => (
<Chip
key={item}
label={item}
size="small"
onDelete={() => handleRemoveCountry(item)}
/>
))}
</Block>
)}
{!!filters.shippingMethod.length && (
<Block label="Méthode d'expédition:">
{filters.shippingMethod.map((item) => {
const label = shippingMethodOptions.find((option) => option.value === item)?.label || item;
return (
<Chip
key={item}
label={label}
size="small"
onDelete={() => handleRemoveShippingMethod(item)}
/>
);
})}
</Block>
)}
{!!filters.status.length && (
<Block label="Status:">
{filters.status.map((item) => {
const label = statusOptions.find((option) => option.value === item)?.label || item;
return (
<Chip
key={item}
label={label}
size="small"
onDelete={() => handleRemoveStatus(item)}
/>
);
})}
</Block>
)}
<Button
color="error"
onClick={onResetFilters}
startIcon={<Iconify icon="solar:trash-bin-trash-bold" />}
>
Clear
</Button>
</Stack>
</Stack>
);
}
// ----------------------------------------------------------------------
type BlockProps = StackProps & {
label: string;
};
function Block({ label, children, sx, ...other }: BlockProps) {
return (
<Stack
component={Paper}
variant="outlined"
spacing={1}
direction="row"
sx={{
p: 1,
borderRadius: 1,
overflow: "hidden",
borderStyle: "dashed",
...sx,
}}
{...other}
>
<Box component="span" sx={{ typography: "subtitle2" }}>
{label}
</Box>
<Stack spacing={1} direction="row" flexWrap="wrap">
{children}
</Stack>
</Stack>
);
}
import { GridCellParams } from "@mui/x-data-grid";
import ListItemText from "@mui/material/ListItemText";
import { fTime, fDate } from "@/utils/format-time";
import Label from "@/shared/components/label";
import { Button } from "@mui/material";
import { IOrderColissimoStatus } from "@/shared/types/shipping";
import { ShipmentStatus, shipmentStatusLabels } from "@/contexts/types/shipment";
import { useEffect, useState } from "react";
import { IClientItem } from "@/shared/types/user";
import { useGetUserById } from "@/shared/api/user";
import { ShippingMethodType, shippingMethodTypeLabels } from "@/contexts/types/Shipping";
// ----------------------------------------------------------------------
const ShippingMethod_OPTIONS = Object.keys(ShippingMethodType).map((key) => ({
value: ShippingMethodType[key as keyof typeof ShippingMethodType],
label: shippingMethodTypeLabels[ShippingMethodType[key as keyof typeof ShippingMethodType]],
}));
const Status_OPTIONS = Object.keys(ShipmentStatus).map((key) => ({
value: ShipmentStatus[key as keyof typeof ShipmentStatus],
label: shipmentStatusLabels[ShipmentStatus[key as keyof typeof ShipmentStatus]],
}));
type ParamsProps = {
params: GridCellParams;
};
export function RenderCellID({ params }: ParamsProps) {
return <>{params.row.id}</>;
}
export function RenderCellCreatedAt({ params }: ParamsProps) {
return (
<ListItemText
primary={fDate(params.row.createdAt)}
secondary={fTime(params.row.createdAt)}
primaryTypographyProps={{ typography: "body2", noWrap: true }}
secondaryTypographyProps={{
mt: 0.5,
component: "span",
typography: "caption",
}}
/>
);
}
export function RenderCellCustomer({ params }: ParamsProps) {
const { userData, userError } = useGetUserById(Number(params.row.clientId));
const [clientData, setClientData] = useState<IClientItem | null>(null);
useEffect(() => {
if (userData && userData.roles.name === "CLIENT") {
setClientData(userData as IClientItem);
}
}, [userData]);
return (
<>
{clientData ? (
<ListItemText
primary={clientData.firstName + ' ' + clientData.lastName}
secondary={clientData.email}
/>
) : (
<></>
)}
</>
);
}
export function RenderCellAdress({ params }: ParamsProps) {
return <>{params.row.shippingStreet + ` ` + params.row.shippingHome}</>;
}
export function RenderCellCountry({ params }: ParamsProps) {
return <>{params.row.shippingCountry}</>;
}
export function RenderCellShippingMethod({ params }: ParamsProps) {
const shippingMethodLabel = ShippingMethod_OPTIONS.find(
(option) => option.value === params.row.shippingMethodType
)?.label || params.row.shippingMethodType;
return <>{shippingMethodLabel}</>;
}
export function RenderCellStatus({ params }: ParamsProps) {
const statusLabel = Status_OPTIONS.find(
(option) => option.value === params.row.shipmentStatus
)?.label || params.row.shipmentStatus;
return (
<Label
variant="soft"
color={
(params.row.shipmentStatus === ShipmentStatus.CANCELED && "error") ||
(params.row.shipmentStatus === ShipmentStatus.WAITING_FOR_PAYMENT && "info") ||
(params.row.shipmentStatus === ShipmentStatus.DELIVERED && "success") ||
(params.row.shipmentStatus === ShipmentStatus.FAILED && "default") ||
(params.row.shipmentStatus === ShipmentStatus.PENDING && "secondary") ||
(params.row.shipmentStatus === ShipmentStatus.SHIPPED && "primary") ||
"default"
}
>
{statusLabel}
</Label>
);
}
export function RenderCellTrackingNumber({ params }: ParamsProps) {
return <>{params.row.trackingNumber}</>;
}
\ No newline at end of file
import { useState, useCallback } from "react";
import MenuItem from "@mui/material/MenuItem";
import Checkbox from "@mui/material/Checkbox";
import Box from "@mui/material/Box";
import InputLabel from "@mui/material/InputLabel";
import FormControl from "@mui/material/FormControl";
import OutlinedInput from "@mui/material/OutlinedInput";
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
import Select, { SelectChangeEvent } from "@mui/material/Select";
import { formHelperTextClasses } from '@mui/material/FormHelperText';
import { IOrderColissimoTableFilters, IOrderColissimoTableFilterValue } from "@/shared/types/shipping";
import { IconButton, Menu, Typography } from '@mui/material';
import { GridFilterAltIcon } from "@mui/x-data-grid";
import { ShipmentTableFilters, ShipmentTableFilterValue } from "@/contexts/types/shipment";
// ----------------------------------------------------------------------
type Props = {
filters: ShipmentTableFilters;
onFilters: (name: string, value: ShipmentTableFilterValue) => void;
dateError: boolean;
//
countryOptions: {
value: string;
label: string;
}[];
shippingMethodOptions: {
value: string;
label: string;
}[];
statusOptions: {
value: string;
label: string;
}[];
};
export default function ShipmentTableToolbar({
filters,
onFilters,
//
countryOptions,
shippingMethodOptions,
statusOptions,
dateError
}: Props) {
const [country, setCountry] = useState<string[]>(filters.country);
const [shippingMethod, setShippingMethod] = useState<string[]>(filters.shippingMethod);
const [status, setStatus] = useState<string[]>(filters.status);
const handleChangeCountry = useCallback(
(event: SelectChangeEvent<string[]>) => {
const {
target: { value },
} = event;
setCountry(typeof value === "string" ? value.split(",") : value);
},
[]
);
const handleChangeShippingMethod = useCallback(
(event: SelectChangeEvent<string[]>) => {
const {
target: { value },
} = event;
setShippingMethod(typeof value === "string" ? value.split(",") : value);
},
[]
);
const handleChangeStatus = useCallback(
(event: SelectChangeEvent<string[]>) => {
const {
target: { value },
} = event;
setStatus(typeof value === "string" ? value.split(",") : value);
},
[]
);
const handleCloseCountry = useCallback(() => {
onFilters("country", country);
}, [onFilters, country]);
const handleCloseShippingMethod = useCallback(() => {
onFilters("shippingMethod", shippingMethod);
}, [onFilters, shippingMethod]);
const handleCloseStatus = useCallback(() => {
onFilters("status", status);
}, [onFilters, status]);
const handleFilterStartDate = useCallback(
(newValue: Date | null) => {
onFilters('startDate', newValue);
},
[onFilters]
);
const handleFilterEndDate = useCallback(
(newValue: Date | null) => {
onFilters('endDate', newValue);
},
[onFilters]
);
const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};
return (
<>
<Box>
<Box
sx={{
display: 'grid',
gridTemplateColumns: 'repeat(5, 1fr)',
gap: 2,
width: '100%',
}}
>
<FormControl
sx={{
flexShrink: 0,
width: { xs: 1, md: 220 },
}}
>
<InputLabel>Pays</InputLabel>
<Select
multiple
value={country}
onChange={handleChangeCountry}
input={<OutlinedInput label="Pays" />}
renderValue={(selected) => selected.map((value) => value).join(", ")}
onClose={handleCloseCountry}
sx={{ textTransform: "capitalize" }}
>
{countryOptions.map((option) => (
<MenuItem key={option.value} value={option.value}>
<Checkbox
disableRipple
size="small"
checked={country.includes(option.value)}
/>
{option.label}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl
sx={{
flexShrink: 0,
width: { xs: 1, md: 220 },
}}
>
<InputLabel>Méthode de livraison</InputLabel>
<Select
multiple
value={shippingMethod}
onChange={handleChangeShippingMethod}
input={<OutlinedInput label="Méthode de livraison" />}
renderValue={(selected) =>
selected
.map((value) => shippingMethodOptions.find((option) => option.value === value)?.label)
.join(", ")
}
onClose={handleCloseShippingMethod}
sx={{ textTransform: "capitalize" }}
>
{shippingMethodOptions.map((option) => (
<MenuItem key={option.value} value={option.value}>
<Checkbox
disableRipple
size="small"
checked={shippingMethod.includes(option.value)}
/>
{option.label}
</MenuItem>
))}
</Select>
</FormControl>
<FormControl
sx={{
flexShrink: 0,
width: { xs: 1, md: 200 },
}}
>
<InputLabel>Status</InputLabel>
<Select
multiple
value={status}
onChange={handleChangeStatus}
input={<OutlinedInput label="Status" />}
renderValue={(selected) =>
selected
.map((value) => statusOptions.find((option) => option.value === value)?.label)
.join(", ")
}
onClose={handleCloseStatus}
sx={{ textTransform: "capitalize" }}
>
{statusOptions.map((option) => (
<MenuItem key={option.value} value={option.value}>
<Checkbox
disableRipple
size="small"
checked={status.includes(option.value)}
/>
{option.label}
</MenuItem>
))}
</Select>
</FormControl>
<DatePicker
label="Date début"
value={filters.startDate}
onChange={handleFilterStartDate}
slotProps={{
textField: {
fullWidth: true,
},
}}
sx={{
maxWidth: { md: 200 },
}}
/>
<DatePicker
label="Date fin"
value={filters.endDate}
onChange={handleFilterEndDate}
slotProps={{
textField: {
fullWidth: true,
error: dateError,
helperText: dateError && 'La date de fin doit être ultérieure à la date de début.',
},
}}
sx={{
maxWidth: { md: 200 },
[`& .${formHelperTextClasses.root}`]: {
position: { md: 'absolute' },
bottom: { md: -40 },
},
}}
/>
</Box>
</Box>
</>
);
}
...@@ -204,6 +204,7 @@ export default function InvoiceTableRow({ ...@@ -204,6 +204,7 @@ export default function InvoiceTableRow({
.then((response) => { .then((response) => {
setConfirmLoading(false); setConfirmLoading(false);
setOpenConfirmDialog(false); setOpenConfirmDialog(false);
onDeleteRow();
enqueueSnackbar("Commande de vente confirmée avec succès !", { variant: "success" }); enqueueSnackbar("Commande de vente confirmée avec succès !", { variant: "success" });
onEditRow(); onEditRow();
}) })
......
0% ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter