MPEDA / src /components /forms /StepWizard.tsx
sarveshpatel's picture
Upload 139 files
f305a41 verified
import { ReactNode } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
export interface StepConfig {
id: string;
title: string;
description?: string;
render: () => ReactNode;
}
interface StepWizardProps {
steps: StepConfig[];
currentIndex: number;
onNext: () => void;
onBack: () => void;
onSubmit: () => void;
isSubmitting?: boolean;
canGoNext: boolean;
}
export function StepWizard({
steps,
currentIndex,
onNext,
onBack,
onSubmit,
isSubmitting,
canGoNext,
}: StepWizardProps) {
const step = steps[currentIndex];
const isLast = currentIndex === steps.length - 1;
const progress = ((currentIndex + 1) / steps.length) * 100;
return (
<Card className="max-w-3xl mx-auto">
<CardHeader>
<div className="flex items-center justify-between mb-2">
<CardTitle className="text-lg font-display">
{step.title}
</CardTitle>
<span className="text-xs text-muted-foreground">
Step {currentIndex + 1} of {steps.length}
</span>
</div>
<div className="h-1.5 w-full overflow-hidden rounded-full bg-muted">
<div
className="h-full bg-primary transition-all"
style={{ width: `${progress}%` }}
/>
</div>
{step.description && (
<p className="mt-3 text-sm text-muted-foreground">{step.description}</p>
)}
</CardHeader>
<CardContent className="space-y-4">
{step.render()}
</CardContent>
<CardFooter className="flex justify-between gap-2">
<Button
type="button"
variant="outline"
size="sm"
onClick={onBack}
disabled={currentIndex === 0}
>
Back
</Button>
<div className="flex gap-2">
{!isLast && (
<Button
type="button"
size="sm"
onClick={onNext}
disabled={!canGoNext}
>
Next
</Button>
)}
{isLast && (
<Button
type="button"
size="sm"
onClick={onSubmit}
disabled={isSubmitting || !canGoNext}
>
{isSubmitting ? "Submitting..." : "Submit"}
</Button>
)}
</div>
</CardFooter>
</Card>
);
}