import { Col, Row } from "antd"; import ProText from "components/ProText"; import { Status } from "pages/checkout/hooks/types"; import type { CSSProperties } from "react"; import { Fragment, useMemo } from "react"; import { useTranslation } from "react-i18next"; import { colors } from "ThemeConstants"; interface StepperProps { statuses?: Status[]; } 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, hasCanceledStatus]); const steps = useMemo( () => 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, stepCount, hasCanceledStatus, canceledStatus, t], ); return ( <>
{steps.map((step, index) => { // 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, borderRadius: "50%", backgroundColor: "#FFF", border: "2px solid #BDBDBD", } : { width: 12, height: 12, borderRadius: "50%", backgroundColor: colors.primary, }; // 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 (
{index < steps.length - 1 && (
)}
); })}
{steps.map((step, index) => ( {step.label} {index < steps.length - 1 && } ))}
); }