feat(11-04): add client-side search bar to catalog page, remove ServiceForm

- New CatalogSearch client component: filters ServiceWithTags[] by name/tag, case-insensitive, instant (no reload)
- page.tsx now passes filtered services through CatalogSearch -> ServiceTable
- ServiceForm.tsx deleted — quick-add row in ServiceTable replaces its create-service UX
This commit is contained in:
2026-06-13 16:01:17 +02:00
parent c0bedf300e
commit 912a892ba5
3 changed files with 39 additions and 110 deletions
@@ -1,102 +0,0 @@
"use client";
import { useRef, useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { createService } from "@/app/admin/catalog/actions";
export function ServiceForm() {
const [open, setOpen] = useState(false);
const [error, setError] = useState<string | null>(null);
const [, startTransition] = useTransition();
const router = useRouter();
const formRef = useRef<HTMLFormElement>(null);
function handleSubmit(fd: FormData) {
setError(null);
startTransition(async () => {
try {
await createService(fd);
formRef.current?.reset();
setOpen(false);
router.refresh();
} catch (e) {
setError(e instanceof Error ? e.message : "Errore nel salvataggio");
}
});
}
if (!open) {
return (
<Button
onClick={() => setOpen(true)}
className="bg-[#1A463C] text-white hover:bg-[#1A463C]/90"
>
+ Aggiungi servizio
</Button>
);
}
return (
<div className="bg-white border border-[#e5e7eb] rounded-xl p-4 space-y-4">
<h3 className="font-medium text-[#1a1a1a]">Nuovo servizio</h3>
<form ref={formRef} action={handleSubmit} className="space-y-3">
<div className="space-y-1">
<Label htmlFor="name">Nome</Label>
<Input id="name" name="name" placeholder="es. Strategia di brand" required />
</div>
<div className="space-y-1">
<Label htmlFor="description">Descrizione (opzionale)</Label>
<Input
id="description"
name="description"
placeholder="es. Incluso: analisi competitor, posizionamento"
/>
</div>
<div className="space-y-1">
<Label htmlFor="category">Categoria (opzionale)</Label>
<Input
id="category"
name="category"
placeholder="es. Branding, Social media, Consulenza"
/>
</div>
<div className="space-y-1">
<Label htmlFor="unit_price">Prezzo unitario ()</Label>
<Input
id="unit_price"
name="unit_price"
type="number"
step="0.01"
min="0.01"
placeholder="0.00"
required
/>
</div>
{error && <p className="text-xs text-red-600">{error}</p>}
<div className="flex gap-2">
<Button
type="submit"
size="sm"
className="bg-[#1A463C] text-white hover:bg-[#1A463C]/90"
>
Aggiungi
</Button>
<Button
type="button"
variant="ghost"
size="sm"
onClick={() => {
setOpen(false);
setError(null);
}}
>
Annulla
</Button>
</div>
</form>
</div>
);
}