Files
MOPC-Portal/src/components/admin/pipeline/wizard-section.tsx

83 lines
2.5 KiB
TypeScript
Raw Normal View History

'use client'
import { cn } from '@/lib/utils'
import { Card, CardContent, CardHeader } from '@/components/ui/card'
import {
Collapsible,
CollapsibleContent,
CollapsibleTrigger,
} from '@/components/ui/collapsible'
import { Badge } from '@/components/ui/badge'
import { ChevronDown, CheckCircle2, AlertCircle } from 'lucide-react'
type WizardSectionProps = {
title: string
description?: string
stepNumber: number
isOpen: boolean
onToggle: () => void
isValid: boolean
hasErrors?: boolean
children: React.ReactNode
}
export function WizardSection({
title,
description,
stepNumber,
isOpen,
onToggle,
isValid,
hasErrors,
children,
}: WizardSectionProps) {
return (
<Collapsible open={isOpen} onOpenChange={onToggle}>
<Card className={cn(isOpen && 'ring-1 ring-ring')}>
<CollapsibleTrigger asChild>
<CardHeader className="cursor-pointer select-none hover:bg-muted/50 transition-colors">
<div className="flex items-center gap-3">
<Badge
variant={isValid ? 'default' : 'outline'}
className={cn(
'h-7 w-7 shrink-0 rounded-full p-0 flex items-center justify-center text-xs font-bold',
isValid
? 'bg-emerald-500 text-white hover:bg-emerald-500'
: hasErrors
? 'border-destructive text-destructive'
: ''
)}
>
{isValid ? (
<CheckCircle2 className="h-4 w-4" />
) : hasErrors ? (
<AlertCircle className="h-4 w-4" />
) : (
stepNumber
)}
</Badge>
<div className="flex-1 min-w-0">
<h3 className="text-sm font-semibold">{title}</h3>
{description && !isOpen && (
<p className="text-xs text-muted-foreground truncate mt-0.5">
{description}
</p>
)}
</div>
<ChevronDown
className={cn(
'h-4 w-4 text-muted-foreground transition-transform',
isOpen && 'rotate-180'
)}
/>
</div>
</CardHeader>
</CollapsibleTrigger>
<CollapsibleContent>
<CardContent className="pt-0">{children}</CardContent>
</CollapsibleContent>
</Card>
</Collapsible>
)
}