handle cancel case in order stepper
This commit is contained in:
@@ -13,29 +13,68 @@ interface StepperProps {
|
||||
export default function Stepper({ statuses = [] }: StepperProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
// Check if order has canceled_by_customer status
|
||||
const hasCanceledStatus = useMemo(
|
||||
() => statuses.some((status) => status?.alias === "canceled_by_customer"),
|
||||
[statuses],
|
||||
);
|
||||
|
||||
// Get the canceled status if it exists
|
||||
const canceledStatus = useMemo(
|
||||
() => statuses.find((status) => status?.alias === "canceled_by_customer"),
|
||||
[statuses],
|
||||
);
|
||||
|
||||
const labels = useMemo(
|
||||
() => [t("order.reserved"), t("order.prepare"), t("order.ready")],
|
||||
[t],
|
||||
);
|
||||
|
||||
// Determine number of steps: 2 if canceled, 3 otherwise
|
||||
const stepCount = hasCanceledStatus ? 2 : 3;
|
||||
|
||||
const activeIndex = useMemo(() => {
|
||||
if (hasCanceledStatus) {
|
||||
// For canceled orders, the last step (index 1) is always active
|
||||
return 1;
|
||||
}
|
||||
const reachedStatuses = statuses.length > 0 ? statuses.length - 1 : 0;
|
||||
return Math.min(Math.max(reachedStatuses, 0), 2);
|
||||
}, [statuses.length]);
|
||||
}, [statuses.length, hasCanceledStatus]);
|
||||
|
||||
const steps = useMemo(
|
||||
() =>
|
||||
Array.from({ length: 3 }, (_, index) => {
|
||||
const status = statuses[index];
|
||||
const label = status?.name || status?.alias || labels[index] || "";
|
||||
Array.from({ length: stepCount }, (_, index) => {
|
||||
let status;
|
||||
let label;
|
||||
let isCanceled = false;
|
||||
|
||||
if (hasCanceledStatus) {
|
||||
if (index === 0) {
|
||||
// First step: show first status or default label
|
||||
status = statuses[0];
|
||||
label = status?.name || status?.alias || labels[0] || "";
|
||||
} else if (index === 1) {
|
||||
// Second step: show canceled status
|
||||
status = canceledStatus;
|
||||
label = status?.name || status?.alias || t("order.canceled") || "";
|
||||
isCanceled = true;
|
||||
}
|
||||
} else {
|
||||
// Normal flow: 3 steps
|
||||
status = statuses[index];
|
||||
label = status?.name || status?.alias || labels[index] || "";
|
||||
}
|
||||
|
||||
const isPending = index > activeIndex;
|
||||
return {
|
||||
key: status ? `status-${status.id}` : `placeholder-${index}`,
|
||||
label,
|
||||
isPending,
|
||||
isCanceled,
|
||||
};
|
||||
}),
|
||||
[activeIndex, labels, statuses],
|
||||
[activeIndex, labels, statuses, stepCount, hasCanceledStatus, canceledStatus, t],
|
||||
);
|
||||
|
||||
return (
|
||||
@@ -57,7 +96,16 @@ export default function Stepper({ statuses = [] }: StepperProps) {
|
||||
}}
|
||||
>
|
||||
{steps.map((step, index) => {
|
||||
const circleStyle: CSSProperties = step.isPending
|
||||
// Determine circle style based on state
|
||||
const circleStyle: CSSProperties = step.isCanceled
|
||||
? {
|
||||
width: 12,
|
||||
height: 12,
|
||||
borderRadius: "50%",
|
||||
backgroundColor: "#EF4444", // Red for canceled
|
||||
border: "2px solid #EF4444",
|
||||
}
|
||||
: step.isPending
|
||||
? {
|
||||
width: 12,
|
||||
height: 12,
|
||||
@@ -72,11 +120,21 @@ export default function Stepper({ statuses = [] }: StepperProps) {
|
||||
backgroundColor: colors.primary,
|
||||
};
|
||||
|
||||
const lineStyle: CSSProperties = {
|
||||
height: 1.5,
|
||||
backgroundColor: step.isPending ? "#BDBDBD" : colors.primary,
|
||||
margin: "0 8px",
|
||||
};
|
||||
// Determine line style based on state
|
||||
// Line should be red if the next step is canceled
|
||||
const nextStep = index < steps.length - 1 ? steps[index + 1] : null;
|
||||
const lineStyle: CSSProperties =
|
||||
nextStep?.isCanceled
|
||||
? {
|
||||
height: 1.5,
|
||||
backgroundColor: "#EF4444", // Red for canceled
|
||||
margin: "0 8px",
|
||||
}
|
||||
: {
|
||||
height: 1.5,
|
||||
backgroundColor: step.isPending ? "#BDBDBD" : colors.primary,
|
||||
margin: "0 8px",
|
||||
};
|
||||
|
||||
return (
|
||||
<Fragment key={step.key}>
|
||||
@@ -120,7 +178,11 @@ export default function Stepper({ statuses = [] }: StepperProps) {
|
||||
lineHeight: "140%",
|
||||
letterSpacing: "0%",
|
||||
textAlign: "center",
|
||||
color: step.isPending ? "#99A2AE" : "#333333",
|
||||
color: step.isCanceled
|
||||
? "#EF4444" // Red for canceled
|
||||
: step.isPending
|
||||
? "#99A2AE"
|
||||
: "#333333",
|
||||
}}
|
||||
>
|
||||
{step.label}
|
||||
|
||||
@@ -37,7 +37,6 @@ import { QRBottomSheet } from "pages/pay/components/splitBill/QRBottomSheet";
|
||||
import NewRateIcon from "components/Icons/order/NewRateIcon";
|
||||
import NoteIcon from "components/Icons/NoteIcon";
|
||||
import SuccessIcon from "components/Icons/SuccessIcon";
|
||||
import ProInputCard from "components/ProInputCard/ProInputCard";
|
||||
import { SplitBillParticipantsBottomSheet } from "./components/SplitBillParticipantsBottomSheet";
|
||||
|
||||
export default function OrderPage() {
|
||||
@@ -49,10 +48,6 @@ export default function OrderPage() {
|
||||
const hasRefetchedRef = useRef(false);
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [isRateOrderOpen, setIsRateOrderOpen] = useState(false);
|
||||
const [
|
||||
isSplitBillParticipantsBottomSheetOpen,
|
||||
setIsSplitBillParticipantsBottomSheetOpen,
|
||||
] = useState(false);
|
||||
const { data: orderDetails } = useGetOrderDetailsQuery(
|
||||
{
|
||||
orderID: orderId || "",
|
||||
@@ -65,6 +60,19 @@ export default function OrderPage() {
|
||||
refetchOnMountOrArgChange: true,
|
||||
},
|
||||
);
|
||||
const hasClosedStatus = orderDetails?.status?.some(
|
||||
(status) => status?.alias === "closed",
|
||||
);
|
||||
|
||||
const hasCanceledByCustomerStatus = orderDetails?.status?.some(
|
||||
(status) => status?.alias === "canceled_by_customer",
|
||||
);
|
||||
|
||||
const [
|
||||
isSplitBillParticipantsBottomSheetOpen,
|
||||
setIsSplitBillParticipantsBottomSheetOpen,
|
||||
] = useState(false);
|
||||
|
||||
|
||||
// Get restaurant subdomain for refetching
|
||||
const restaurantSubdomain = restaurant?.subdomain;
|
||||
@@ -74,13 +82,6 @@ export default function OrderPage() {
|
||||
skip: !restaurantSubdomain,
|
||||
},
|
||||
);
|
||||
const hasClosedStatus = orderDetails?.status?.some(
|
||||
(status) => status?.alias === "closed",
|
||||
);
|
||||
|
||||
const hasCanceledByCustomerStatus = orderDetails?.status?.some(
|
||||
(status) => status?.alias === "canceled_by_customer",
|
||||
);
|
||||
|
||||
// Reset refetch flag when orderId changes
|
||||
useEffect(() => {
|
||||
@@ -90,7 +91,10 @@ export default function OrderPage() {
|
||||
// Refetch restaurant details when order status has alias "closed"
|
||||
useEffect(() => {
|
||||
if (orderDetails?.status && !hasRefetchedRef.current) {
|
||||
if (hasClosedStatus && restaurantSubdomain) {
|
||||
if (
|
||||
(hasClosedStatus || hasCanceledByCustomerStatus) &&
|
||||
restaurantSubdomain
|
||||
) {
|
||||
refetchRestaurantDetails();
|
||||
hasRefetchedRef.current = true;
|
||||
}
|
||||
@@ -671,7 +675,7 @@ export default function OrderPage() {
|
||||
onClose={() => setIsRateOrderOpen(false)}
|
||||
/>
|
||||
|
||||
{(!hasClosedStatus && !hasCanceledByCustomerStatus) && (
|
||||
{!hasClosedStatus && !hasCanceledByCustomerStatus && (
|
||||
<CancelOrderBottomSheet />
|
||||
)}
|
||||
</Layout.Content>
|
||||
|
||||
Reference in New Issue
Block a user