import React from "react"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import { LoadingButton, LoadingButtonProps } from "@mui/lab"; import Accordion from "@mui/material/Accordion"; import AccordionActions from "@mui/material/AccordionActions"; import AccordionDetails from "@mui/material/AccordionDetails"; import AccordionSummary from "@mui/material/AccordionSummary"; import Button from "@mui/material/Button"; import CircularProgress from "@mui/material/CircularProgress"; import { useTheme } from "@mui/material/styles"; import Typography from "@mui/material/Typography"; import { useSnackbar } from "notistack"; import Card from "../../../../components/Card"; import { useApi } from "../../../../contexts/ApiContext"; import { useDialog } from "../../../../contexts/DialogContext"; import { formatPurchaseNumber } from "../../../../util/format_purchase_number"; import { OrderDetail, OrderItem, OrderListItem } from "../../types/order"; import OrderItemsTable from "./OrderItemsTable"; import OrderStateChip from "./OrderStateChip"; interface OrderAccordionProps { order: OrderListItem; } const OrderAccordion: React.FC = ({ order }) => { const api = useApi(); const theme = useTheme(); const { enqueueSnackbar } = useSnackbar(); const [details, setDetails] = React.useState(null); const [buttonsLoading, setButtonsLoading] = React.useState(false); const [selected, setSelected] = React.useState([]); const title = [ formatPurchaseNumber(order.purchase_number), order.recipient && order.recipient?.given_name + " " + order.recipient?.family_name, order.email, order.phone, ] .map((v) => v?.trim()) .filter(Boolean) .join(" • "); const loadDetails = () => { setDetails(null); api.operations["fulfillment.order:detail"] .call({ params: { reference: order.reference, }, }) .then(async (response) => setDetails(await response.json())); }; const openDialog = useDialog(); const markAsArrived = async () => { if ( !(await openDialog( "Are you sure?", "This will notify the customer that the order is ready for pick up", )) ) { return; } setButtonsLoading(true); api.operations["fulfillment.order:ready-for-pickup"] .call({ params: { reference: order.reference }, body: selected, }) .then((response) => { if (response.ok) { enqueueSnackbar("Order is now ready for pickup", { variant: "success", }); } else { enqueueSnackbar("Failed to mark order as ready for pickup", { variant: "error", }); throw response; } }) .finally(() => { setButtonsLoading(false); loadDetails(); }); }; const markAsDelivered = async () => { if (!(await openDialog("Are you sure?", "This will mark the order as delivered"))) { return; } setButtonsLoading(true); api.operations["fulfillment.order:delivered"] .call({ params: { reference: order.reference }, }) .then((response) => { if (response.ok) { enqueueSnackbar("Successfully marked order as delivered", { variant: "success", }); } else { enqueueSnackbar("Failed to mark order as delivered", { variant: "error", }); throw response; } }) .finally(() => { setButtonsLoading(false); loadDetails(); }); }; const doCancel = async () => { if ( !(await openDialog( "Are you sure?", "This will fully cancel the order and release the authorized payment back to the customer", )) ) { return; } api.operations["fulfillment.order:cancel"] .call({ params: { reference: order.reference }, }) .then((response) => { if (response.ok) { enqueueSnackbar("Order cancelled", { variant: "success", }); } else { enqueueSnackbar("Failed to cancel order", { variant: "error", }); throw response; } }) .finally(() => { setButtonsLoading(false); loadDetails(); }); }; const StatusButton = () => { if (!details) { return null; } const props: LoadingButtonProps = { variant: "contained", color: "primary", loading: buttonsLoading, disabled: buttonsLoading, }; if (["DELIVERED", "CANCELLED"].includes(details.state)) { return null; } if (details.state === "PENDING") { props.disabled ||= selected.length === 0; return ( Ready for pickup ); } if (["IN_TRANSIT", "READY_FOR_PICKUP", "SENT"].includes(details.state)) { return ( Mark as Delivered ); } return null; }; return ( (details == null ? loadDetails() : void 0)} > } sx={{ margin: 1 }}> {/* TODO: Re-enable when we implement some kind of bulk update thing event.stopPropagation()} /> */} {title} {details != null ? ( {details.state === "PENDING" ? ( ) : null} ) : ( )} ); }; export default OrderAccordion;