"Genera Attestato" button on the association detail page downloads the certificate PDF from the new backend endpoint; the edit dialog gained a ratification-code field (used on the certificate). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017hQcuUQFue2bFvrYw2UQhK
139 lines
4.7 KiB
TypeScript
139 lines
4.7 KiB
TypeScript
"use client";
|
|
|
|
import { useEffect, useState } from "react";
|
|
import { Loader2, Pencil } from "lucide-react";
|
|
import { Button } from "@/components/ui/button";
|
|
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogFooter,
|
|
DialogHeader,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from "@/components/ui/dialog";
|
|
import { Input } from "@/components/ui/input";
|
|
import { Label } from "@/components/ui/label";
|
|
import { Switch } from "@/components/ui/switch";
|
|
import { updateAssociation } from "@/lib/api";
|
|
import type { Association } from "@/lib/models";
|
|
|
|
export function EditAssociationDialog({
|
|
association,
|
|
onSaved,
|
|
}: {
|
|
association: Association;
|
|
onSaved: (association: Association) => void;
|
|
}) {
|
|
const [open, setOpen] = useState(false);
|
|
const [saving, setSaving] = useState(false);
|
|
const [name, setName] = useState(association.name);
|
|
const [address, setAddress] = useState(association.address);
|
|
const [vatNumber, setVatNumber] = useState(association.vatNumber ?? "");
|
|
const [runtsId, setRuntsId] = useState(association.runtsId ?? "");
|
|
const [ratificationCode, setRatificationCode] = useState(association.ratificationCode ?? "");
|
|
const [isShown, setIsShown] = useState(association.isShown ?? true);
|
|
|
|
useEffect(() => {
|
|
if (open) {
|
|
setName(association.name);
|
|
setAddress(association.address);
|
|
setVatNumber(association.vatNumber ?? "");
|
|
setRuntsId(association.runtsId ?? "");
|
|
setRatificationCode(association.ratificationCode ?? "");
|
|
setIsShown(association.isShown ?? true);
|
|
}
|
|
}, [open, association]);
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setSaving(true);
|
|
try {
|
|
const updated = await updateAssociation(association.id!, {
|
|
...association,
|
|
name,
|
|
address,
|
|
vatNumber,
|
|
runtsId,
|
|
ratificationCode,
|
|
isShown,
|
|
});
|
|
onSaved(updated);
|
|
setOpen(false);
|
|
} catch (error) {
|
|
console.error("Failed to update association:", error);
|
|
alert("Impossibile salvare le modifiche");
|
|
} finally {
|
|
setSaving(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<Dialog open={open} onOpenChange={setOpen}>
|
|
<DialogTrigger asChild>
|
|
<Button variant="outline">
|
|
<Pencil className="size-4" />
|
|
Modifica
|
|
</Button>
|
|
</DialogTrigger>
|
|
<DialogContent className="sm:max-w-lg">
|
|
<DialogHeader>
|
|
<DialogTitle>Modifica associazione</DialogTitle>
|
|
</DialogHeader>
|
|
<form onSubmit={handleSubmit} className="space-y-5">
|
|
<div className="grid gap-4 sm:grid-cols-2">
|
|
<div className="space-y-2 sm:col-span-2">
|
|
<Label htmlFor="e-name">Nome associazione *</Label>
|
|
<Input id="e-name" value={name} onChange={(e) => setName(e.target.value)} required />
|
|
</div>
|
|
|
|
<div className="space-y-2 sm:col-span-2">
|
|
<Label htmlFor="e-address">Indirizzo *</Label>
|
|
<Input id="e-address" value={address} onChange={(e) => setAddress(e.target.value)} required />
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="e-vatNumber">Partita IVA</Label>
|
|
<Input id="e-vatNumber" value={vatNumber} onChange={(e) => setVatNumber(e.target.value)} />
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="e-runtsId">Codice RUNTS</Label>
|
|
<Input id="e-runtsId" value={runtsId} onChange={(e) => setRuntsId(e.target.value)} />
|
|
</div>
|
|
|
|
<div className="space-y-2">
|
|
<Label htmlFor="e-ratificationCode">Codice ratifica (es. LO183)</Label>
|
|
<Input
|
|
id="e-ratificationCode"
|
|
value={ratificationCode}
|
|
onChange={(e) => setRatificationCode(e.target.value)}
|
|
placeholder="Usato nell'attestato di adesione"
|
|
/>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between rounded-lg border p-3 sm:col-span-2">
|
|
<div>
|
|
<Label htmlFor="e-isShown">Associazione attiva</Label>
|
|
<p className="text-sm text-muted-foreground">
|
|
Le associazioni non attive non compaiono nell'elenco
|
|
</p>
|
|
</div>
|
|
<Switch id="e-isShown" checked={isShown} onCheckedChange={setIsShown} />
|
|
</div>
|
|
</div>
|
|
|
|
<DialogFooter>
|
|
<Button type="button" variant="outline" onClick={() => setOpen(false)}>
|
|
Annulla
|
|
</Button>
|
|
<Button type="submit" disabled={saving}>
|
|
{saving && <Loader2 className="size-4 animate-spin" />}
|
|
{saving ? "Salvataggio..." : "Salva modifiche"}
|
|
</Button>
|
|
</DialogFooter>
|
|
</form>
|
|
</DialogContent>
|
|
</Dialog>
|
|
);
|
|
}
|