EmberClone/apps/web/src/components/Stepper.tsx

73 lines
2.4 KiB
TypeScript

import React from 'react';
import { Check } from 'lucide-react';
interface Step {
label: string;
description?: string;
}
interface StepperProps {
steps: Step[];
currentStep: number;
}
const Stepper: React.FC<StepperProps> = ({ steps, currentStep }) => {
return (
<div className="w-full py-4">
<div className="flex items-start justify-between w-full">
{steps.map((step, index) => {
const isCompleted = index < currentStep;
const isActive = index === currentStep;
const isPending = index > currentStep;
return (
<div key={index} className="relative flex flex-col items-center flex-1">
{/* Connector Line */}
{index !== steps.length - 1 && (
<div
className={`absolute top-5 left-1/2 w-full h-0.5 transition-colors duration-300 ${
isCompleted ? 'bg-green-500' : 'bg-gray-200'
}`}
style={{ left: '50%' }}
/>
)}
{/* Step Circle */}
<div
className={`relative z-10 flex items-center justify-center w-10 h-10 rounded-full border-2 transition-all duration-300 ${
isCompleted
? 'bg-green-500 border-green-500 text-white'
: isActive
? 'bg-white border-blue-600 text-blue-600 ring-4 ring-blue-50'
: 'bg-white border-gray-300 text-gray-400'
}`}
>
{isCompleted ? (
<Check className="w-6 h-6" strokeWidth={3} />
) : (
<span className="text-sm font-semibold">{index + 1}</span>
)}
</div>
{/* Labels */}
<div className="mt-3 text-center px-2">
<p className={`text-sm font-medium transition-colors duration-300 ${
isActive ? 'text-blue-600' : isCompleted ? 'text-green-600' : 'text-gray-500'
}`}>
{step.label}
</p>
{step.description && (
<p className="text-xs text-gray-400 mt-1 max-w-[120px] mx-auto">
{step.description}
</p>
)}
</div>
</div>
);
})}
</div>
</div>
);
};
export default Stepper;