69 lines
2.7 KiB
TypeScript
69 lines
2.7 KiB
TypeScript
import { Check } from "lucide-react";
|
|
import { faNum } from "../../lib/formatters";
|
|
import { cn } from "../../lib/utils";
|
|
|
|
export interface StepperProps {
|
|
current: number;
|
|
highestVisited: number;
|
|
completedSteps: Set<number>;
|
|
onGoto: (step: number) => void;
|
|
}
|
|
|
|
const STEPS = [
|
|
{ id: 1, label: "تأمینکننده" },
|
|
{ id: 2, label: "اقلام" },
|
|
{ id: 3, label: "شرایط پرداخت" },
|
|
{ id: 4, label: "پروژه" },
|
|
{ id: 5, label: "بازبینی و ثبت" },
|
|
];
|
|
|
|
// نوار ۵ مرحلهای ویزارد — واکنشگرا و ضدشکستگی در موبایل
|
|
export function Stepper({ current, completedSteps, onGoto }: StepperProps) {
|
|
return (
|
|
<div className="mb-4 flex items-center justify-between gap-1 sm:gap-2 rounded-xl border border-line bg-panel p-1.5 sm:p-2 shadow-xs select-none">
|
|
{STEPS.map(({ id: step, label }) => {
|
|
const isCurrent = step === current;
|
|
const isComplete = completedSteps.has(step);
|
|
|
|
return (
|
|
<button
|
|
key={step}
|
|
type="button"
|
|
className={cn(
|
|
"flex items-center justify-center gap-1.5 rounded-lg py-1.5 px-2 sm:px-3 text-xs transition-all duration-150 cursor-pointer",
|
|
// در موبایل مرحله جاری فضا میگیرد و بقیه جمعوجور میمانند تا سطر نشکند
|
|
isCurrent
|
|
? "flex-1 sm:flex-1 bg-blue-600 font-bold text-white shadow-xs"
|
|
: "flex-initial sm:flex-1 text-muted hover:text-foreground hover:bg-slate-50 dark:hover:bg-zinc-800/60",
|
|
isComplete && !isCurrent && "font-medium text-emerald-600 dark:text-emerald-400",
|
|
)}
|
|
onClick={() => onGoto(step)}
|
|
>
|
|
<span
|
|
className={cn(
|
|
"flex h-5 w-5 shrink-0 items-center justify-center rounded-full text-[11px] font-bold transition-colors",
|
|
isCurrent
|
|
? "bg-white/20 text-white"
|
|
: isComplete
|
|
? "bg-emerald-100 text-emerald-700 dark:bg-emerald-950/80 dark:text-emerald-300"
|
|
: "bg-muted/15 text-muted",
|
|
)}
|
|
>
|
|
{isComplete ? <Check className="h-3 w-3 stroke-[2.5]" /> : faNum(step)}
|
|
</span>
|
|
|
|
{/* در موبایل فقط نام مرحله جاری باز است؛ در صفحه بزرگتر همه نامها نمایش دارند */}
|
|
<span
|
|
className={cn(
|
|
"whitespace-nowrap truncate text-[11.5px] sm:text-xs",
|
|
!isCurrent && "hidden md:inline",
|
|
)}
|
|
>
|
|
{label}
|
|
</span>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
} |