e1b3e8c3d5
- PoolManager: defined field cells with value count, refined chips, inline ghost + button, focus ring, pending/empty states - TaxonomyManager: icon-badged section headers, ordered 2-col grid, sync explainer note - Settings page: wider container (max-w-4xl) for the grid to breathe Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
"use client";
|
|
|
|
import { Tag, BookOpen } from "lucide-react";
|
|
import { PoolManager } from "./PoolManager";
|
|
import { addTaxonomyValue, removeTaxonomyValue } from "@/app/admin/impostazioni/actions";
|
|
|
|
type FieldDef = { id: string; label: string };
|
|
|
|
const OFFER_FIELDS: FieldDef[] = [
|
|
{ id: "offer_categoria", label: "Categoria" },
|
|
{ id: "offer_ticket", label: "Ticket" },
|
|
{ id: "offer_tipo", label: "Tipo" },
|
|
{ id: "offer_obiettivo", label: "Obiettivo" },
|
|
];
|
|
|
|
const CATALOG_FIELDS: FieldDef[] = [
|
|
{ id: "service_fase", label: "Fase" },
|
|
{ id: "service_offerta", label: "Offerta" },
|
|
{ id: "service_pacchetto", label: "Pacchetto" },
|
|
];
|
|
|
|
function Section({
|
|
icon,
|
|
title,
|
|
subtitle,
|
|
fields,
|
|
pools,
|
|
}: {
|
|
icon: React.ReactNode;
|
|
title: string;
|
|
subtitle: string;
|
|
fields: FieldDef[];
|
|
pools: Record<string, string[]>;
|
|
}) {
|
|
return (
|
|
<div className="bg-white rounded-xl border border-[#e5e7eb] p-6">
|
|
<div className="flex items-start gap-3 mb-5">
|
|
<div className="grid h-9 w-9 shrink-0 place-items-center rounded-lg bg-[#1A463C]/8 text-[#1A463C]">
|
|
{icon}
|
|
</div>
|
|
<div>
|
|
<h2 className="text-base font-semibold text-[#1a1a1a] leading-tight">{title}</h2>
|
|
<p className="text-xs text-[#71717a] mt-0.5">{subtitle}</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
|
|
{fields.map((f) => (
|
|
<PoolManager
|
|
key={f.id}
|
|
label={f.label}
|
|
pool={pools[f.id] ?? []}
|
|
onAdd={(v) => addTaxonomyValue(f.id, v)}
|
|
onRemove={(v) => removeTaxonomyValue(f.id, v)}
|
|
/>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function TaxonomyManager({ pools }: { pools: Record<string, string[]> }) {
|
|
return (
|
|
<div className="space-y-6">
|
|
<Section
|
|
icon={<Tag className="h-[18px] w-[18px]" />}
|
|
title="Tassonomie Offerte"
|
|
subtitle="Valori dei campi Categoria, Ticket, Tipo e Obiettivo dell'editor offerte."
|
|
fields={OFFER_FIELDS}
|
|
pools={pools}
|
|
/>
|
|
<Section
|
|
icon={<BookOpen className="h-[18px] w-[18px]" />}
|
|
title="Tassonomie Catalogo"
|
|
subtitle="Valori dei campi Fase, Offerta e Pacchetto del catalogo servizi."
|
|
fields={CATALOG_FIELDS}
|
|
pools={pools}
|
|
/>
|
|
<p className="text-xs text-[#a1a1aa] leading-relaxed">
|
|
I valori si sincronizzano ovunque: creandone uno dall'editor offerte o dal catalogo
|
|
comparirà qui automaticamente. Eliminando un valore da qui viene rimosso ovunque sia usato.
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|