refine admin cards and form headers
CI / quality (push) Has been cancelled

This commit is contained in:
MOH
2026-03-15 08:59:19 +01:00
parent 623b492787
commit 6caf723695
14 changed files with 371 additions and 246 deletions
@@ -5,9 +5,11 @@ import { useSearchParams } from "next/navigation";
import {
FileText,
FolderPlus,
FolderTree,
Hash,
Layers3,
Pencil,
CheckCircle2,
ShieldCheck,
ShieldOff,
Text,
@@ -18,6 +20,7 @@ import type { deleteCategoryAction, upsertCategoryAction } from "@/app/_admin/po
import { AppCard } from "@/components/ui/app-card";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { StatsCard } from "@/components/dashboard/stats-card";
import { CardContent } from "@/components/ui/card";
import { Checkbox } from "@/components/ui/checkbox";
import {
@@ -107,11 +110,11 @@ function CategoryLocaleFields({
const descriptionKey = `description${locale.key}` as const;
return (
<AppCard key={`${idPrefix}-${locale.key}`} level={2} padding="sm" className="space-y-4 rounded-nested">
<AppCard key={`${idPrefix}-${locale.key}`} level={2} layer="single" padding="sm" className="space-y-4 rounded-nested">
<p className="text-sm font-medium text-foreground">{locale.label}</p>
<div className="space-y-2">
<Label htmlFor={`${idPrefix}-${nameKey}`}>Name</Label>
<Label htmlFor={`${idPrefix}-${nameKey}`} className="sr-only">Name</Label>
<div className="relative">
<Text className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
@@ -126,7 +129,7 @@ function CategoryLocaleFields({
</div>
<div className="space-y-2">
<Label htmlFor={`${idPrefix}-${descriptionKey}`}>{copy.description}</Label>
<Label htmlFor={`${idPrefix}-${descriptionKey}`} className="sr-only">{copy.description}</Label>
<div className="relative">
<FileText className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-muted-foreground" />
<Textarea
@@ -165,7 +168,7 @@ function CategoryStatusFields({
</div>
<div className="grid gap-4 lg:grid-cols-[minmax(0,1fr)_220px]">
<AppCard level={2} padding="sm" className="rounded-nested">
<AppCard level={2} layer="single" padding="sm" className="rounded-nested">
<div className="flex items-start gap-3">
{isActive ? (
<ShieldCheck className="mt-0.5 h-4 w-4 text-status-success" />
@@ -224,7 +227,7 @@ function CategoryForm({
<div className="grid gap-4 lg:grid-cols-3">
<div className="space-y-2">
<Label htmlFor={`${formId}-slug`}>Slug</Label>
<Label htmlFor={`${formId}-slug`} className="sr-only">Slug</Label>
<div className="relative">
<Text className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
@@ -239,7 +242,7 @@ function CategoryForm({
</div>
<div className="space-y-2">
<Label htmlFor={`${formId}-sortOrder`}>{copy.sortOrder}</Label>
<Label htmlFor={`${formId}-sortOrder`} className="sr-only">{copy.sortOrder}</Label>
<div className="relative">
<Hash className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
<Input
@@ -249,6 +252,7 @@ function CategoryForm({
min="0"
defaultValue={values?.sortOrder ?? 0}
required
placeholder={copy.sortOrder}
className="pl-9"
/>
</div>
@@ -291,11 +295,11 @@ function EditCategoryDialog({
</DialogHeader>
<div className="grid gap-3 sm:grid-cols-3">
<AppCard level={2} padding="sm" className="rounded-nested">
<AppCard level={2} layer="single" padding="sm" className="rounded-nested">
<p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">Projects</p>
<p className="mt-2 text-lg font-semibold text-foreground">{category.projectCount}</p>
</AppCard>
<AppCard level={2} padding="sm" className="rounded-nested">
<AppCard level={2} layer="single" padding="sm" className="rounded-nested">
<p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">Status</p>
<div className="mt-2">
<Badge variant={category.isActive ? "success" : "warning"}>
@@ -303,7 +307,7 @@ function EditCategoryDialog({
</Badge>
</div>
</AppCard>
<AppCard level={2} padding="sm" className="rounded-nested">
<AppCard level={2} layer="single" padding="sm" className="rounded-nested">
<p className="text-xs uppercase tracking-[0.18em] text-muted-foreground">Order</p>
<p className="mt-2 text-lg font-semibold text-foreground">{category.sortOrder}</p>
</AppCard>
@@ -371,23 +375,11 @@ export function PortfolioCategoriesManager({
return (
<div className="space-y-4">
<div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
<div className="flex flex-wrap items-center gap-x-4 gap-y-2 text-sm text-muted-foreground">
<span>
Total:
{" "}
<span className="font-semibold text-foreground">{categories.length}</span>
</span>
<span>
Active:
{" "}
<span className="font-semibold text-foreground">{activeCount}</span>
</span>
<span>
Assigned:
{" "}
<span className="font-semibold text-foreground">{assignedProjects}</span>
</span>
<div className="flex flex-col gap-4 xl:flex-row xl:items-end xl:justify-between">
<div className="grid gap-4 md:grid-cols-3 xl:min-w-[620px]">
<StatsCard title="Total" value={String(categories.length)} icon={FolderTree} />
<StatsCard title="Active" value={String(activeCount)} icon={CheckCircle2} />
<StatsCard title="Assigned" value={String(assignedProjects)} icon={Layers3} />
</div>
<Dialog open={createOpen} onOpenChange={setCreateOpen}>
@@ -403,7 +395,7 @@ export function PortfolioCategoriesManager({
<DialogDescription>{copy.modalDescription}</DialogDescription>
</DialogHeader>
<AppCard level={2} padding="sm" className="rounded-nested">
<AppCard level={2} layer="single" padding="sm" className="rounded-nested">
<div className="grid gap-3 sm:grid-cols-3">
<div className="space-y-1">
<p className="text-sm font-medium text-foreground">1. Basics</p>
@@ -434,7 +426,7 @@ export function PortfolioCategoriesManager({
</Dialog>
</div>
<AppCard level={3}>
<AppCard level={3} layer="single">
<CardContent className="space-y-4 p-6">
<div className="flex items-center gap-3">
<Layers3 className="h-5 w-5 text-brand-primary" />
@@ -449,6 +441,7 @@ export function PortfolioCategoriesManager({
<AppCard
key={category.id}
level={2}
layer="single"
padding="sm"
className="rounded-nested"
>