75 lines
2.1 KiB
TypeScript
75 lines
2.1 KiB
TypeScript
import { Check, ChevronDown, ChevronRight } from "lucide-react";
|
|
import { type ReactNode, useState } from "react";
|
|
import { Badge } from "@/shared/components/ui/badge";
|
|
import { Card, CardContent } from "@/shared/components/ui/card";
|
|
import { cn } from "@/shared/lib/utils";
|
|
|
|
type PhaseStatus = "erledigt" | "aktuell" | "offen";
|
|
|
|
interface PhaseCardProps {
|
|
label: string;
|
|
beschreibung: string;
|
|
status: PhaseStatus;
|
|
stepNumber: number;
|
|
children?: ReactNode;
|
|
}
|
|
|
|
export function PhaseCard({
|
|
label,
|
|
beschreibung,
|
|
status,
|
|
stepNumber,
|
|
children,
|
|
}: PhaseCardProps) {
|
|
const [expanded, setExpanded] = useState(false);
|
|
const showContent = status === "aktuell" || expanded;
|
|
|
|
return (
|
|
<Card
|
|
className={cn(
|
|
"transition-all",
|
|
status === "aktuell" && "ring-2 ring-primary border-primary",
|
|
status === "erledigt" && "opacity-60",
|
|
status !== "aktuell" && "cursor-pointer",
|
|
)}
|
|
onClick={() => status !== "aktuell" && setExpanded(!expanded)}
|
|
>
|
|
<CardContent className="space-y-3">
|
|
<div className="flex items-start gap-4">
|
|
<div
|
|
className={cn(
|
|
"flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 text-sm font-bold",
|
|
status === "erledigt" &&
|
|
"border-primary bg-primary text-primary-foreground",
|
|
status === "aktuell" && "border-primary text-primary",
|
|
status === "offen" &&
|
|
"border-muted-foreground/40 text-muted-foreground/40",
|
|
)}
|
|
>
|
|
{status === "erledigt" ? <Check className="size-4" /> : stepNumber}
|
|
</div>
|
|
<div className="flex min-w-0 flex-1 flex-col gap-1">
|
|
<div className="flex items-center gap-2">
|
|
<span className="font-medium">{label}</span>
|
|
{status === "aktuell" && <Badge>Aktuell</Badge>}
|
|
{status !== "aktuell" && (
|
|
<span className="ml-auto text-muted-foreground">
|
|
{expanded ? (
|
|
<ChevronDown className="size-4" />
|
|
) : (
|
|
<ChevronRight className="size-4" />
|
|
)}
|
|
</span>
|
|
)}
|
|
</div>
|
|
{showContent && (
|
|
<p className="text-sm text-muted-foreground">{beschreibung}</p>
|
|
)}
|
|
</div>
|
|
</div>
|
|
{children}
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
}
|