Files
sass-mohfarawati/components/admin/workspace-patterns.tsx
T
2026-03-13 16:14:04 +01:00

124 lines
3.1 KiB
TypeScript

import type { ReactNode } from "react";
import { AppCard } from "@/components/ui/app-card";
import { Badge } from "@/components/ui/badge";
import { CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { cn } from "@/lib/utils";
export function WorkspaceHero({
eyebrow,
title,
description,
aside,
}: {
eyebrow: string;
title: string;
description: string;
aside?: ReactNode;
}) {
return (
<AppCard level={3}>
<CardContent className="flex flex-col gap-4 p-6 lg:flex-row lg:items-end lg:justify-between lg:p-8">
<div className="space-y-2">
<p className="text-xs font-semibold uppercase tracking-[0.14em] text-muted-foreground">
{eyebrow}
</p>
<h2 className="text-2xl font-semibold text-foreground">{title}</h2>
<p className="max-w-3xl text-sm text-muted-foreground">{description}</p>
</div>
{aside ? <div className="flex flex-wrap gap-2">{aside}</div> : null}
</CardContent>
</AppCard>
);
}
export function WorkspaceSidebarPanel({
title,
children,
}: {
title: string;
children: ReactNode;
}) {
return (
<AppCard level={2}>
<CardHeader className="pb-4">
<CardTitle className="text-base">{title}</CardTitle>
</CardHeader>
<CardContent className="space-y-4">{children}</CardContent>
</AppCard>
);
}
export function WorkspaceStepButton({
active,
completed,
index,
label,
eyebrow,
onClick,
completeIcon,
}: {
active: boolean;
completed: boolean;
index: number;
label: string;
eyebrow: string;
onClick: () => void;
completeIcon?: ReactNode;
}) {
return (
<button
type="button"
onClick={onClick}
className={cn(
"flex w-full items-start gap-3 rounded-surface border px-4 py-3 text-left transition-colors",
active
? "border-input bg-accent/40"
: "border-input bg-background hover:bg-accent/20",
)}
>
<div className="flex h-9 w-9 shrink-0 items-center justify-center rounded-pill border border-input bg-background text-sm font-semibold text-foreground">
{completed ? completeIcon ?? "OK" : index + 1}
</div>
<div className="min-w-0">
<p className="text-xs font-semibold uppercase tracking-[0.12em] text-muted-foreground">
{eyebrow}
</p>
<p className="mt-1 text-sm font-medium text-foreground">{label}</p>
</div>
</button>
);
}
export function WorkspaceLocaleCard({
title,
hint,
children,
}: {
title: string;
hint: string;
children: ReactNode;
}) {
return (
<AppCard level={2}>
<CardHeader className="pb-4">
<CardTitle className="text-lg">{title}</CardTitle>
<CardDescription>{hint}</CardDescription>
</CardHeader>
<CardContent className="space-y-4">{children}</CardContent>
</AppCard>
);
}
export function WorkspaceStatusBadge({
done,
doneLabel = "Ready",
openLabel = "Open",
}: {
done: boolean;
doneLabel?: string;
openLabel?: string;
}) {
return <Badge variant={done ? "success" : "warning"}>{done ? doneLabel : openLabel}</Badge>;
}