Skip to content
Extraits de code Groupes Projets
Valider 7c3f1e4f rédigé par Mohamed Lemine BAILLAHI's avatar Mohamed Lemine BAILLAHI
Parcourir les fichiers

Merge branch 'feature/MS-35' into 'develop'

MS-35/Added the ability to delete a cart item  and display sale session ID

Closes MS-35

See merge request !466
parents 387c74e3 593e5a4d
Branches
1 requête de fusion!466MS-35/Added the ability to delete a cart item and display sale session ID
......@@ -126,7 +126,10 @@ export default function UserCartListView() {
},
[pageSize, enqueueSnackbar, table, tableData]
);
const refresh = () => {
revalidate()
};
const handleViewRow = useCallback(
(uid: string) => {
......@@ -230,7 +233,7 @@ export default function UserCartListView() {
onSelectRow={() => table.onSelectRow(row.clientDTO.uid.toString())}
onDeleteRow={() => handleDeleteRow(row.clientDTO.uid.toString())}
onViewRow={() => handleViewRow(row.clientDTO.uid.toString())}
revalidate={revalidate}
revalidate={refresh}
/>
))
)}
......
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import Box from "@mui/material/Box";
import Paper from "@mui/material/Paper";
import Stack from "@mui/material/Stack";
......@@ -10,15 +10,25 @@ import TableCell from "@mui/material/TableCell";
import IconButton from "@mui/material/IconButton";
import ListItemText from "@mui/material/ListItemText";
import Chip from "@mui/material/Chip";
import { Avatar } from "@mui/material";
import { Avatar, Snackbar, Alert } from "@mui/material"; // Ajout de Snackbar et Alert
import { fCurrency } from "../../../../utils/format-number";
import Iconify from "../../../components/iconify";
import { ConfirmDialog } from "../../../components/custom-dialog";
import { usePopover } from "../../../components/custom-popover";
import { useBoolean } from "../../../../hooks/use-boolean";
import { useGetCart, useDeleteCartItem } from "@/shared/api/cart";
import { ICart, ICartDTO, IClientCartDTO, IDetailsProductCartDTO, IItemCart } from "@/shared/types/cart";
import {
ICart,
ICartDTO,
IClientCartDTO,
IDetailsProductCartDTO,
IItemCart,
IItemCartStatus,
} from "@/shared/types/cart";
import { IUserItem } from "@/shared/types/saleSession";
import Loading from "@/app/loading";
import LoadingButton from "@mui/lab/LoadingButton";
import { mutate } from "swr";
// ----------------------------------------------------------------------
......@@ -28,7 +38,7 @@ type Props = {
onViewRow: VoidFunction;
onSelectRow: VoidFunction;
onDeleteRow: VoidFunction;
revalidate: () => void;
revalidate: () => void;
};
export default function UserCartTableRow({
......@@ -37,16 +47,21 @@ export default function UserCartTableRow({
onViewRow,
onSelectRow,
onDeleteRow,
revalidate
revalidate,
}: Props) {
// const { cart, isLoading: cartLoading, mutate: updateCart } = useGetCart(client.uid.toString());
const [isDeleting, setIsDeleting] = useState(false);
const confirm = useBoolean();
const collapse = useBoolean();
const popover = usePopover();
const [itemIdToDelete, setItemIdToDelete] = useState<string | null>(null);
const [openSnackbar, setOpenSnackbar] = useState(false);
const [snackbarMessage, setSnackbarMessage] = useState("");
const [productDetails, setProductDetails] = useState(
client.productDetailsCartDTOS
);
const handleOpenConfirmDialog = (itemId: string) => {
setItemIdToDelete(itemId);
confirm.onTrue();
......@@ -67,25 +82,33 @@ export default function UserCartTableRow({
const handleDeleteIconClick = (itemId: string) => {
handleOpenConfirmDialog(itemId);
};
const handleDeleteItem = async (itemId: string) => {
try {
setIsDeleting(true);
const updatedProductDetails = client.productDetailsCartDTOS.map(
(item) => {
if (item.itemId.toString() === itemId) {
return { ...item, status: "DELETED_BO" };
}
return item;
}
);
await useDeleteCartItem(client.id.toString(), itemId);
await useDeleteCartItem(client.clientDTO.toString(), itemId);
revalidate();
revalidate();
setProductDetails(updatedProductDetails);
setIsDeleting(false);
setSnackbarMessage("L'élément a été supprimé avec succès !");
setOpenSnackbar(true);
confirm.onFalse();
} catch (error) {
console.error("Erreur lors de la suppression de l'élément:", error);
setIsDeleting(false);
setSnackbarMessage("Une erreur est survenue lors de la suppression.");
setOpenSnackbar(true);
}
};
const renderPrimary = (
<TableRow hover selected={selected}>
<TableCell sx={{ display: "flex", alignItems: "center" }}>
......@@ -120,7 +143,16 @@ export default function UserCartTableRow({
);
const renderSecondary = (
<TableRow>
<TableRow
sx={{
...(client.productDetailsCartDTOS.some(
(item: IDetailsProductCartDTO) =>
item.status === "DELETED_BO" || item.status === "DELETED_SITE"
) && {
pointerEvents: "none",
}),
}}
>
<TableCell sx={{ p: 1, border: "none" }} colSpan={9}>
<Collapse
in={collapse.value}
......@@ -129,70 +161,97 @@ export default function UserCartTableRow({
sx={{ bgcolor: "background.neutral" }}
>
<Stack component={Paper} sx={{ m: 1.5 }}>
{client.productDetailsCartDTOS.map((item: IDetailsProductCartDTO) => (
<Stack
key={item.productCartDTOS.productId}
direction="row"
alignItems="center"
sx={{
p: (theme) => theme.spacing(1.5, 2, 1.5, 1.5),
"&:not(:last-of-type)": {
borderBottom: (theme) =>
`solid 2px ${theme.palette.background.neutral}`,
},
}}
>
<Avatar
src={
item.productCartDTOS?.mainImagePath?.replace("Optional[", "").replace("]", "") || " "
}
variant="rounded"
sx={{ width: 48, height: 48, mr: 2 }}
/>
<ListItemText
primary={`${item.productCartDTOS?.name}${item.productCartDTOS?.ugs ? ' - ' + item.productCartDTOS?.ugs : ''}`}
secondary={
<Chip
size="small"
label={item.source === "LIVE" ? "Live" : "Site"}
sx={{
backgroundColor: item.source === "WEB" ? "#00b8d9" : "#22c55e",
color: "white",
{client.productDetailsCartDTOS.map(
(item: IDetailsProductCartDTO) => {
const isDeleted =
item.status === "DELETED_BO" ||
item.status === "DELETED_SITE";
return (
<Stack
key={item.productCartDTOS.productId}
direction="row"
alignItems="center"
sx={{
p: (theme) => theme.spacing(1.5, 2, 1.5, 1.5),
"&:not(:last-of-type)": {
borderBottom: (theme) =>
`solid 2px ${theme.palette.background.neutral}`,
},
backgroundColor: isDeleted ? "#e4e1f6" : "transparent",
pointerEvents: isDeleted ? "none" : "auto",
}}
>
<Avatar
src={
item.productCartDTOS?.mainImagePath
?.replace("Optional[", "")
.replace("]", "") || " "
}
variant="rounded"
sx={{ width: 48, height: 48, mr: 2 }}
/>
<ListItemText
primary={`${item.productCartDTOS?.name}${
item.productCartDTOS?.ugs
? " - " + item.productCartDTOS?.ugs
: ""
}`}
secondary={
<>
<Chip
size="small"
label={item.source === "LIVE" ? "Live" : "Site"}
sx={{
backgroundColor:
item.source === "WEB" ? "#00b8d9" : "#22c55e",
color: "white",
}}
/>
<Box sx={{ marginTop: 1 }}>
{item.source === "LIVE"
? `Session de Vente: #${item.sessionOrderId}`
: "Source inconue"}
</Box>
</>
}
primaryTypographyProps={{ typography: "body2" }}
secondaryTypographyProps={{
component: "span",
color: "text.disabled",
mt: 0.5,
}}
/>
}
primaryTypographyProps={{ typography: "body2" }}
secondaryTypographyProps={{
component: "span",
color: "text.disabled",
mt: 0.5,
}}
/>
<Stack direction="row" alignItems="center" spacing={6}>
{item.productCartDTOS.promoPrice != 0 || null ?
<Box sx={{ width: 110, textAlign: "right" }}>
{fCurrency(item.productCartDTOS.promoPrice)}
</Box>
:
<Box sx={{ width: 110, textAlign: "right" }}>
{fCurrency(item.productCartDTOS.regularPrice)}
</Box>
}
<Box>x{item.quantity}</Box>
<Box sx={{ width: 110, textAlign: "right" }}>
{fCurrency(item.totalPrice)}
</Box>
<IconButton
color="error"
onClick={() => handleDeleteIconClick(item.itemId.toString())}
disabled={isDeleting}
>
<Iconify icon="solar:trash-bin-trash-bold" />
</IconButton>
</Stack>
</Stack>
))}
<Stack direction="row" alignItems="center" spacing={6}>
{item.productCartDTOS.promoPrice !== 0 || null ? (
<Box sx={{ width: 110, textAlign: "right" }}>
{fCurrency(item.productCartDTOS.promoPrice)}
</Box>
) : (
<Box sx={{ width: 110, textAlign: "right" }}>
{fCurrency(item.productCartDTOS.regularPrice)}
</Box>
)}
<Box>x{item.quantity}</Box>
<Box sx={{ width: 110, textAlign: "right" }}>
{fCurrency(item.totalPrice)}
</Box>
<IconButton
color="error"
onClick={() =>
handleDeleteIconClick(item.itemId.toString())
}
disabled={isDeleted || isDeleting} // Désactive le bouton si l'élément est supprimé ou en cours de suppression
>
<Iconify icon="solar:trash-bin-trash-bold" />
</IconButton>
</Stack>
</Stack>
);
}
)}
</Stack>
</Collapse>
</TableCell>
......@@ -211,11 +270,31 @@ export default function UserCartTableRow({
title="Confirmer la suppression"
content="Êtes-vous sûr de vouloir supprimer cet article de votre panier ?"
action={
<Button variant="contained" color="error" onClick={handleConfirmDelete}>
<LoadingButton
variant="contained"
color="error"
onClick={handleConfirmDelete}
loading={isDeleting}
>
Supprimer
</Button>
</LoadingButton>
}
/>
{/* Snackbar pour afficher les messages */}
<Snackbar
open={openSnackbar}
autoHideDuration={3000}
onClose={() => setOpenSnackbar(false)}
anchorOrigin={{
vertical: "top",
horizontal: "right",
}}
>
<Alert onClose={() => setOpenSnackbar(false)} severity="success">
{snackbarMessage}
</Alert>
</Snackbar>
</>
);
}
......@@ -60,11 +60,12 @@ export type ICartTableFilters = {
};
export enum IItemCartStatus {
CONSULTED = "Consulté",
NOT_CONSULTED = "Non Consulté",
DELETED = "Supprimée",
}
CONSULTED ,
NOT_CONSULTED ,
DELETED_BO,
DELETED_SITE
}
export interface ICartDTO {
id: number;
clientDTO: IClientCartDTO;
......@@ -100,6 +101,8 @@ export interface IDetailsProductCartDTO {
quantity: number,
totalPrice: number,
productCartDTOS: IProductCartDTO,
status?: string;
sessionOrderId?:number;
source:string;
}
export interface ICartClientPage {
......
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