fix: Improve condo ID handling and add error message

Prevents client-side generation of condo IDs, delegating this to the backend/service for consistency.
Introduces an alert for save condo errors and ensures the active condo is correctly updated or set.
Adds logic to auto-select the first condo if none is active.
This commit is contained in:
2025-12-07 12:54:51 +01:00
parent ce53d2ea09
commit 9459834b0e
6 changed files with 56 additions and 80 deletions

View File

@@ -224,20 +224,30 @@ export const SettingsPage: React.FC = () => {
const handleCondoSubmit = async (e: React.FormEvent) => {
e.preventDefault();
try {
// FIX: Do not generate ID for new condo, let backend/service handle it (POST vs PUT check)
const payload: Condo = {
id: editingCondo ? editingCondo.id : crypto.randomUUID(),
id: editingCondo ? editingCondo.id : '',
name: condoForm.name,
address: condoForm.address,
defaultMonthlyQuota: condoForm.defaultMonthlyQuota
};
await CondoService.saveCondo(payload);
const savedCondo = await CondoService.saveCondo(payload);
const list = await CondoService.getCondos();
setCondos(list);
if (activeCondo?.id === payload.id) setActiveCondo(payload);
if (activeCondo?.id === savedCondo.id) {
setActiveCondo(savedCondo);
}
// Auto-select if it's the first one or none selected
if (!activeCondo && list.length === 1) {
CondoService.setActiveCondo(savedCondo.id);
}
setShowCondoModal(false);
window.dispatchEvent(new Event('condo-updated'));
} catch (e) { console.error(e); }
} catch (e) { console.error(e); alert("Errore nel salvataggio del condominio"); }
};
const handleDeleteCondo = async (id: string) => {
@@ -300,7 +310,10 @@ export const SettingsPage: React.FC = () => {
setFamilies([...families, newFamily]);
}
setShowFamilyModal(false);
} catch (e) { console.error(e); }
} catch (e: any) {
console.error(e);
alert(`Errore: ${e.message || "Impossibile salvare la famiglia"}`);
}
};
// --- User Handlers ---
@@ -359,7 +372,7 @@ export const SettingsPage: React.FC = () => {
...noticeForm,
date: editingNotice ? editingNotice.date : new Date().toISOString()
};
const saved = await CondoService.saveNotice(payload);
await CondoService.saveNotice(payload);
setNotices(await CondoService.getNotices());
setShowNoticeModal(false);
} catch (e) { console.error(e); }
@@ -383,7 +396,7 @@ export const SettingsPage: React.FC = () => {
setShowReadDetailsModal(true);
};
// --- Alert Handlers (Placeholder for brevity, logic same as before) ---
// --- Alert Handlers ---
const openAddAlertModal = () => { setEditingAlert(null); setAlertForm({ subject: '', body: '', daysOffset: 1, offsetType: 'before_next_month', sendHour: 9, active: true }); setShowAlertModal(true); };
const openEditAlertModal = (alert: AlertDefinition) => { setEditingAlert(alert); setAlertForm(alert); setShowAlertModal(true); };
const handleAlertSubmit = async (e: React.FormEvent) => {
@@ -463,7 +476,7 @@ export const SettingsPage: React.FC = () => {
{isAdmin && activeTab === 'general' && (
<div className="space-y-6 animate-fade-in">
{!activeCondo ? (
<div className="bg-amber-50 border border-amber-200 text-amber-800 p-4 rounded-lg">Nessun condominio selezionato.</div>
<div className="bg-amber-50 border border-amber-200 text-amber-800 p-4 rounded-lg">Nessun condominio selezionato. Crea un condominio nella sezione "Lista Condomini".</div>
) : (
<div className="bg-white rounded-xl shadow-sm border border-slate-200 p-6 md:p-8 max-w-2xl">
<h3 className="text-lg font-bold text-slate-800 mb-4 flex items-center gap-2"><Building className="w-5 h-5 text-blue-600" /> Dati Condominio Corrente</h3>
@@ -514,32 +527,40 @@ export const SettingsPage: React.FC = () => {
{/* Families Tab */}
{isAdmin && activeTab === 'families' && (
<div className="space-y-4 animate-fade-in">
<div className="flex justify-between items-center">
<div className="text-sm text-slate-500">Famiglie in: <span className="font-bold text-slate-800">{activeCondo?.name}</span></div>
<button onClick={openAddFamilyModal} className="bg-blue-600 text-white px-4 py-2 rounded-lg font-medium flex items-center gap-2"><Plus className="w-4 h-4" /> Aggiungi</button>
</div>
<div className="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
<table className="w-full text-left text-sm text-slate-600">
<thead className="bg-slate-50 text-slate-700 font-semibold border-b"><tr><th className="px-6 py-4">Nome</th><th className="px-6 py-4">Interno</th><th className="px-6 py-4">Email</th><th className="px-6 py-4">Quota</th><th className="px-6 py-4 text-right">Azioni</th></tr></thead>
<tbody className="divide-y divide-slate-100">
{families.map(family => (
<tr key={family.id} className="hover:bg-slate-50">
<td className="px-6 py-4 font-medium text-slate-900">{family.name}</td>
<td className="px-6 py-4">{family.unitNumber}</td>
<td className="px-6 py-4 text-slate-400">{family.contactEmail}</td>
<td className="px-6 py-4">
{family.customMonthlyQuota ? (
<span className="font-bold text-blue-600"> {family.customMonthlyQuota}</span>
) : (
<span className="text-slate-400 italic">Default ( {activeCondo?.defaultMonthlyQuota})</span>
)}
</td>
<td className="px-6 py-4 text-right"><div className="flex justify-end gap-2"><button onClick={() => openEditFamilyModal(family)} className="text-blue-600"><Pencil className="w-4 h-4" /></button><button onClick={() => handleDeleteFamily(family.id)} className="text-red-600"><Trash2 className="w-4 h-4" /></button></div></td>
</tr>
))}
</tbody>
</table>
</div>
{!activeCondo ? (
<div className="p-8 text-center bg-slate-50 rounded-xl border border-dashed border-slate-300">
<p className="text-slate-500">Seleziona o crea un condominio per gestire le famiglie.</p>
</div>
) : (
<>
<div className="flex justify-between items-center">
<div className="text-sm text-slate-500">Famiglie in: <span className="font-bold text-slate-800">{activeCondo.name}</span></div>
<button onClick={openAddFamilyModal} className="bg-blue-600 text-white px-4 py-2 rounded-lg font-medium flex items-center gap-2"><Plus className="w-4 h-4" /> Aggiungi</button>
</div>
<div className="bg-white rounded-xl shadow-sm border border-slate-200 overflow-hidden">
<table className="w-full text-left text-sm text-slate-600">
<thead className="bg-slate-50 text-slate-700 font-semibold border-b"><tr><th className="px-6 py-4">Nome</th><th className="px-6 py-4">Interno</th><th className="px-6 py-4">Email</th><th className="px-6 py-4">Quota</th><th className="px-6 py-4 text-right">Azioni</th></tr></thead>
<tbody className="divide-y divide-slate-100">
{families.map(family => (
<tr key={family.id} className="hover:bg-slate-50">
<td className="px-6 py-4 font-medium text-slate-900">{family.name}</td>
<td className="px-6 py-4">{family.unitNumber}</td>
<td className="px-6 py-4 text-slate-400">{family.contactEmail}</td>
<td className="px-6 py-4">
{family.customMonthlyQuota ? (
<span className="font-bold text-blue-600"> {family.customMonthlyQuota}</span>
) : (
<span className="text-slate-400 italic">Default ( {activeCondo.defaultMonthlyQuota})</span>
)}
</td>
<td className="px-6 py-4 text-right"><div className="flex justify-end gap-2"><button onClick={() => openEditFamilyModal(family)} className="text-blue-600"><Pencil className="w-4 h-4" /></button><button onClick={() => handleDeleteFamily(family.id)} className="text-red-600"><Trash2 className="w-4 h-4" /></button></div></td>
</tr>
))}
</tbody>
</table>
</div>
</>
)}
</div>
)}