bananas-commerce-admin
Version:
What's this, an admin for apes?
173 lines • 6.99 kB
JavaScript
import React from "react";
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import { LoadingButton } 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 OrderItemsTable from "./OrderItemsTable";
import OrderStateChip from "./OrderStateChip";
const OrderAccordion = ({ 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 = {
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 (React.createElement(LoadingButton, { ...props, onClick: markAsArrived }, "Ready for pickup"));
}
if (["IN_TRANSIT", "READY_FOR_PICKUP", "SENT"].includes(details.state)) {
return (React.createElement(LoadingButton, { ...props, onClick: markAsDelivered }, "Mark as Delivered"));
}
return null;
};
return (React.createElement(Accordion, { sx: {
boxShadow: 0,
borderRadius: `${theme.spacing(3)} !important`,
borderWidth: "1px",
borderStyle: "solid",
borderColor: theme.palette.divider,
}, onChange: () => (details == null ? loadDetails() : void 0) },
React.createElement(AccordionSummary, { expandIcon: React.createElement(ExpandMoreIcon, null), sx: { margin: 1 } },
React.createElement(Typography, { sx: { marginY: "auto", flexGrow: 1 } }, title),
React.createElement(OrderStateChip, { element: details ?? order, sx: { marginRight: 2 } })),
details != null ? (React.createElement(Card, { sx: { border: "none", p: 0 } },
React.createElement(AccordionDetails, { sx: { p: 0 } },
React.createElement(OrderItemsTable, { isPending: details.state === "PENDING", items: details.items, onSelect: setSelected })),
React.createElement(AccordionActions, { sx: { mr: 1, mb: 1.5 } },
details.state === "PENDING" ? (React.createElement(Button, { color: "error", variant: "outlined", onClick: doCancel }, "Cancel order")) : null,
React.createElement(StatusButton, null)))) : (React.createElement(AccordionDetails, { sx: {
display: "flex",
justifyContent: "center",
alignItems: "center",
minHeight: 100,
} },
React.createElement(CircularProgress, { color: "secondary" })))));
};
export default OrderAccordion;
//# sourceMappingURL=OrderAccordion.js.map