Skip to content
Extraits de code Groupes Projets
Valider da21a1e3 rédigé par aya zouity's avatar aya zouity
Parcourir les fichiers

Added the ability to delete a cart item from the back office and display sale session ID

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