diff --git a/pages/Settings.tsx b/pages/Settings.tsx index ff5d858..3006d60 100644 --- a/pages/Settings.tsx +++ b/pages/Settings.tsx @@ -2,7 +2,13 @@ import React, { useEffect, useState } from 'react'; import { CondoService } from '../services/mockDb'; import { AppSettings, Family, User, AlertDefinition, Condo, Notice, NoticeIconType, NoticeRead } from '../types'; -import { Save, Building, Coins, Plus, Pencil, Trash2, X, CalendarCheck, AlertTriangle, User as UserIcon, Server, Bell, Clock, FileText, Lock, Megaphone, CheckCircle2, Info, Hammer, Link as LinkIcon, Eye, Calendar, List, UserCog, Mail, Power, MapPin, CreditCard, ToggleLeft, ToggleRight, LayoutGrid, PieChart, Users, Send } from 'lucide-react'; +import { + Save, Building, Coins, Plus, Pencil, Trash2, X, CalendarCheck, + AlertTriangle, User as UserIcon, Server, Bell, Clock, FileText, + Lock, Megaphone, CheckCircle2, Info, Hammer, Link as LinkIcon, + Eye, Calendar, List, UserCog, Mail, Power, MapPin, CreditCard, + ToggleLeft, ToggleRight, LayoutGrid, PieChart, Users, Send +} from 'lucide-react'; export const SettingsPage: React.FC = () => { const currentUser = CondoService.getCurrentUser(); @@ -176,353 +182,347 @@ export const SettingsPage: React.FC = () => { fetchData(); }, [isPrivileged]); - // --- Profile Handlers --- - const handleProfileSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setProfileSaving(true); - setProfileMsg(''); - try { - await CondoService.updateProfile(profileForm); - setProfileMsg('Profilo aggiornato con successo!'); - setTimeout(() => setProfileMsg(''), 3000); - setProfileForm(prev => ({ ...prev, password: '' })); - } catch (e) { - setProfileMsg('Errore aggiornamento profilo'); - } finally { - setProfileSaving(false); - } + // --- HANDLERS --- + + const handleProfileSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setProfileSaving(true); + setProfileMsg(''); + try { + await CondoService.updateProfile(profileForm); + setProfileMsg('Profilo aggiornato con successo!'); + setTimeout(() => setProfileMsg(''), 3000); + setProfileForm(prev => ({ ...prev, password: '' })); + } catch (e) { + setProfileMsg('Errore aggiornamento profilo'); + } finally { + setProfileSaving(false); + } }; + const handleGeneralSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + if (!activeCondo) return; + setSaving(true); + setSuccessMsg(''); + try { + await CondoService.saveCondo(activeCondo); + setSuccessMsg('Dati condominio aggiornati!'); + setTimeout(() => setSuccessMsg(''), 3000); + const list = await CondoService.getCondos(); + setCondos(list); + } catch (e) { + console.error(e); + } finally { + setSaving(false); + } + }; - // --- General Handlers --- - const handleGeneralSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - if (!activeCondo) return; - setSaving(true); - setSuccessMsg(''); - try { - await CondoService.saveCondo(activeCondo); - setSuccessMsg('Dati condominio aggiornati!'); - setTimeout(() => setSuccessMsg(''), 3000); - const list = await CondoService.getCondos(); - setCondos(list); - } catch (e) { - console.error(e); - } finally { - setSaving(false); - } + const handleFeaturesSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + if (!globalSettings) return; + setSaving(true); + try { + await CondoService.updateSettings(globalSettings); + setSuccessMsg('Funzionalità salvate!'); + setTimeout(() => setSuccessMsg(''), 3000); + window.location.reload(); + } catch(e) { + console.error(e); + } finally { + setSaving(false); + } + }; + + const handleSmtpSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + if (!globalSettings) return; + setSaving(true); + try { + await CondoService.updateSettings(globalSettings); + setSuccessMsg('Configurazione SMTP salvata!'); + setTimeout(() => { + setSuccessMsg(''); + setShowSmtpModal(false); + }, 2000); + } catch (e) { + console.error(e); + } finally { + setSaving(false); + } + }; + + const handleSmtpTest = async () => { + if (!globalSettings?.smtpConfig) return; + setTestingSmtp(true); + setTestSmtpMsg(''); + try { + await CondoService.testSmtpConfig(globalSettings.smtpConfig); + setTestSmtpMsg('Successo! Email di prova inviata.'); + } catch(e: any) { + setTestSmtpMsg('Errore: ' + (e.message || "Impossibile connettersi")); + } finally { + setTestingSmtp(false); + } + }; + + const handleNewYear = async () => { + if (!globalSettings) return; + const nextYear = globalSettings.currentYear + 1; + if (window.confirm(`Sei sicuro di voler chiudere l'anno ${globalSettings.currentYear} e aprire il ${nextYear}?`)) { + setSaving(true); + try { + const newSettings = { ...globalSettings, currentYear: nextYear }; + await CondoService.updateSettings(newSettings); + setGlobalSettings(newSettings); + setSuccessMsg(`Anno ${nextYear} aperto!`); + } catch(e) { + console.error(e); + } finally { + setSaving(false); + } + } }; - const handleFeaturesSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - if (!globalSettings) return; - setSaving(true); - try { - await CondoService.updateSettings(globalSettings); - setSuccessMsg('Funzionalità salvate!'); - setTimeout(() => setSuccessMsg(''), 3000); - window.location.reload(); // Refresh to apply changes to layout - } catch(e) { console.error(e); } finally { setSaving(false); } + // CRUD Handlers + const openAddCondoModal = () => { + setEditingCondo(null); + setCondoForm({ name: '', address: '', streetNumber: '', city: '', province: '', zipCode: '', notes: '', paypalClientId: '', defaultMonthlyQuota: 100 }); + setShowCondoModal(true); }; - const handleSmtpSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - if (!globalSettings) return; - setSaving(true); - try { - await CondoService.updateSettings(globalSettings); - setSuccessMsg('Configurazione SMTP salvata!'); - setTimeout(() => { setSuccessMsg(''); setShowSmtpModal(false); }, 2000); - } catch (e) { - console.error(e); - } finally { - setSaving(false); - } + const openEditCondoModal = (c: Condo) => { + setEditingCondo(c); + setCondoForm({ name: c.name, address: c.address || '', streetNumber: c.streetNumber || '', city: c.city || '', province: c.province || '', zipCode: c.zipCode || '', notes: c.notes || '', paypalClientId: c.paypalClientId || '', defaultMonthlyQuota: c.defaultMonthlyQuota }); + setShowCondoModal(true); }; - const handleSmtpTest = async () => { - if (!globalSettings?.smtpConfig) return; - setTestingSmtp(true); - setTestSmtpMsg(''); - try { - await CondoService.testSmtpConfig(globalSettings.smtpConfig); - setTestSmtpMsg('Successo! Email di prova inviata.'); - } catch(e: any) { - setTestSmtpMsg('Errore: ' + (e.message || "Impossibile connettersi")); - } finally { - setTestingSmtp(false); - } - }; - - const handleNewYear = async () => { - if (!globalSettings) return; - const nextYear = globalSettings.currentYear + 1; - if (window.confirm(`Sei sicuro di voler chiudere l'anno ${globalSettings.currentYear} e aprire il ${nextYear}?`)) { - setSaving(true); - try { - const newSettings = { ...globalSettings, currentYear: nextYear }; - await CondoService.updateSettings(newSettings); - setGlobalSettings(newSettings); - setSuccessMsg(`Anno ${nextYear} aperto!`); - } catch(e) { console.error(e); } finally { setSaving(false); } - } - }; - - // --- Condo Management Handlers --- - const openAddCondoModal = () => { - setEditingCondo(null); - setCondoForm({ name: '', address: '', streetNumber: '', city: '', province: '', zipCode: '', notes: '', paypalClientId: '', defaultMonthlyQuota: 100 }); - setShowCondoModal(true); - }; - - const openEditCondoModal = (c: Condo) => { - setEditingCondo(c); - setCondoForm({ - name: c.name, - address: c.address || '', - streetNumber: c.streetNumber || '', - city: c.city || '', - province: c.province || '', - zipCode: c.zipCode || '', - notes: c.notes || '', - paypalClientId: c.paypalClientId || '', - defaultMonthlyQuota: c.defaultMonthlyQuota - }); - setShowCondoModal(true); - }; - - const handleCondoSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - try { - const payload: Condo = { + const handleCondoSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + try { + const payload: Condo = { id: editingCondo ? editingCondo.id : '', - name: condoForm.name, - address: condoForm.address, - streetNumber: condoForm.streetNumber, - city: condoForm.city, - province: condoForm.province, - zipCode: condoForm.zipCode, - notes: condoForm.notes, - paypalClientId: condoForm.paypalClientId, - defaultMonthlyQuota: condoForm.defaultMonthlyQuota - }; - - const savedCondo = await CondoService.saveCondo(payload); - const list = await CondoService.getCondos(); - setCondos(list); - - 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')); + name: condoForm.name, + address: condoForm.address, + streetNumber: condoForm.streetNumber, + city: condoForm.city, + province: condoForm.province, + zipCode: condoForm.zipCode, + notes: condoForm.notes, + paypalClientId: condoForm.paypalClientId, + defaultMonthlyQuota: condoForm.defaultMonthlyQuota + }; + const savedCondo = await CondoService.saveCondo(payload); + const list = await CondoService.getCondos(); + setCondos(list); + if (activeCondo?.id === savedCondo.id) { setActiveCondo(savedCondo); } + if (!activeCondo && list.length === 1) { CondoService.setActiveCondo(savedCondo.id); } + setShowCondoModal(false); + window.dispatchEvent(new Event('condo-updated')); } catch (e) { console.error(e); alert("Errore nel salvataggio del condominio. Assicurati di essere amministratore."); - } + } + }; + + const handleDeleteCondo = async (id: string) => { + if(!window.confirm("Eliminare questo condominio? Attenzione: operazione irreversibile.")) return; + try { + await CondoService.deleteCondo(id); + setCondos(await CondoService.getCondos()); + window.dispatchEvent(new Event('condo-updated')); + } catch (e) { + console.error(e); + } }; - const handleDeleteCondo = async (id: string) => { - if(!window.confirm("Eliminare questo condominio? Attenzione: operazione irreversibile.")) return; - try { - await CondoService.deleteCondo(id); - setCondos(await CondoService.getCondos()); - window.dispatchEvent(new Event('condo-updated')); - } catch (e) { console.error(e); } + const openAddFamilyModal = () => { + setEditingFamily(null); + setFamilyForm({ name: '', unitNumber: '', stair: '', floor: '', notes: '', contactEmail: '', customMonthlyQuota: '' }); + setShowFamilyModal(true); }; - // --- Family Handlers --- - const openAddFamilyModal = () => { - setEditingFamily(null); - setFamilyForm({ name: '', unitNumber: '', stair: '', floor: '', notes: '', contactEmail: '', customMonthlyQuota: '' }); - setShowFamilyModal(true); + const openEditFamilyModal = (family: Family) => { + setEditingFamily(family); + setFamilyForm({ name: family.name, unitNumber: family.unitNumber, stair: family.stair || '', floor: family.floor || '', notes: family.notes || '', contactEmail: family.contactEmail || '', customMonthlyQuota: family.customMonthlyQuota ? family.customMonthlyQuota.toString() : '' }); + setShowFamilyModal(true); }; - const openEditFamilyModal = (family: Family) => { - setEditingFamily(family); - setFamilyForm({ - name: family.name, - unitNumber: family.unitNumber, - stair: family.stair || '', - floor: family.floor || '', - notes: family.notes || '', - contactEmail: family.contactEmail || '', - customMonthlyQuota: family.customMonthlyQuota ? family.customMonthlyQuota.toString() : '' - }); - setShowFamilyModal(true); + const handleDeleteFamily = async (id: string) => { + if (!window.confirm('Eliminare questa famiglia?')) return; + try { + await CondoService.deleteFamily(id); + setFamilies(families.filter(f => f.id !== id)); + } catch (e) { + console.error(e); + } }; - const handleDeleteFamily = async (id: string) => { - if (!window.confirm('Eliminare questa famiglia?')) return; - try { - await CondoService.deleteFamily(id); - setFamilies(families.filter(f => f.id !== id)); - } catch (e) { console.error(e); } + const handleFamilySubmit = async (e: React.FormEvent) => { + e.preventDefault(); + try { + const quota = familyForm.customMonthlyQuota && familyForm.customMonthlyQuota.trim() !== '' ? parseFloat(familyForm.customMonthlyQuota) : undefined; + const payload: any = { + name: familyForm.name, + unitNumber: familyForm.unitNumber, + stair: familyForm.stair, + floor: familyForm.floor, + notes: familyForm.notes, + contactEmail: familyForm.contactEmail, + customMonthlyQuota: quota + }; + if (editingFamily) { + const updatedFamily = { ...editingFamily, ...payload }; + await CondoService.updateFamily(updatedFamily); + setFamilies(families.map(f => f.id === updatedFamily.id ? updatedFamily : f)); + } else { + const newFamily = await CondoService.addFamily(payload); + setFamilies([...families, newFamily]); + } + setShowFamilyModal(false); + } catch (e: any) { + console.error(e); + alert(`Errore: ${e.message || "Impossibile salvare la famiglia."}`); + } + }; + + const openAddUserModal = () => { + setEditingUser(null); + setUserForm({ name: '', email: '', password: '', phone: '', role: 'user', familyId: '', receiveAlerts: true }); + setShowUserModal(true); }; - const handleFamilySubmit = async (e: React.FormEvent) => { - e.preventDefault(); - try { - // Handle parsing safely - const quota = familyForm.customMonthlyQuota && familyForm.customMonthlyQuota.trim() !== '' - ? parseFloat(familyForm.customMonthlyQuota) - : undefined; - - const payload: any = { - name: familyForm.name, - unitNumber: familyForm.unitNumber, - stair: familyForm.stair, - floor: familyForm.floor, - notes: familyForm.notes, - contactEmail: familyForm.contactEmail, - customMonthlyQuota: quota - }; - - if (editingFamily) { - const updatedFamily = { ...editingFamily, ...payload }; - await CondoService.updateFamily(updatedFamily); - setFamilies(families.map(f => f.id === updatedFamily.id ? updatedFamily : f)); - } else { - const newFamily = await CondoService.addFamily(payload); - setFamilies([...families, newFamily]); - } - setShowFamilyModal(false); - } catch (e: any) { - console.error(e); - alert(`Errore: ${e.message || "Impossibile salvare la famiglia. Controlla i permessi."}`); - } + const openEditUserModal = (user: User) => { + setEditingUser(user); + setUserForm({ name: user.name || '', email: user.email, password: '', phone: user.phone || '', role: user.role || 'user', familyId: user.familyId || '', receiveAlerts: user.receiveAlerts ?? true }); + setShowUserModal(true); }; - // --- User Handlers --- - const openAddUserModal = () => { - setEditingUser(null); - setUserForm({ name: '', email: '', password: '', phone: '', role: 'user', familyId: '', receiveAlerts: true }); - setShowUserModal(true); - }; - const openEditUserModal = (user: User) => { - setEditingUser(user); - setUserForm({ - name: user.name || '', - email: user.email, - password: '', - phone: user.phone || '', - role: user.role || 'user', - familyId: user.familyId || '', - receiveAlerts: user.receiveAlerts ?? true - }); - setShowUserModal(true); - }; - const handleUserSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - try { - if (editingUser) { - await CondoService.updateUser(editingUser.id, userForm); - } else { - await CondoService.createUser(userForm); - } - // Refresh user list for active condo - setUsers(await CondoService.getUsers(activeCondo?.id)); - setShowUserModal(false); - } catch (e) { alert("Errore nel salvataggio utente"); } - }; - const handleDeleteUser = async (id: string) => { - if(!window.confirm("Eliminare utente?")) return; - await CondoService.deleteUser(id); - setUsers(users.filter(u => u.id !== id)); + const handleUserSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + try { + if (editingUser) { + await CondoService.updateUser(editingUser.id, userForm); + } else { + await CondoService.createUser(userForm); + } + setUsers(await CondoService.getUsers(activeCondo?.id)); + setShowUserModal(false); + } catch (e) { + alert("Errore nel salvataggio utente"); + } }; - // --- Notice Handlers --- - const openAddNoticeModal = () => { - setEditingNotice(null); - setNoticeTargetMode('all'); - setNoticeForm({ title: '', content: '', type: 'info', link: '', condoId: activeCondo?.id || '', active: true, targetFamilyIds: [] }); - setShowNoticeModal(true); + const handleDeleteUser = async (id: string) => { + if(!window.confirm("Eliminare utente?")) return; + await CondoService.deleteUser(id); + setUsers(users.filter(u => u.id !== id)); }; - const openEditNoticeModal = (n: Notice) => { - setEditingNotice(n); - const isTargeted = n.targetFamilyIds && n.targetFamilyIds.length > 0; - setNoticeTargetMode(isTargeted ? 'specific' : 'all'); - setNoticeForm({ - title: n.title, - content: n.content, - type: n.type, - link: n.link || '', - condoId: n.condoId, - active: n.active, - targetFamilyIds: n.targetFamilyIds || [] - }); - setShowNoticeModal(true); + + const openAddNoticeModal = () => { + setEditingNotice(null); + setNoticeTargetMode('all'); + setNoticeForm({ title: '', content: '', type: 'info', link: '', condoId: activeCondo?.id || '', active: true, targetFamilyIds: [] }); + setShowNoticeModal(true); }; - const handleNoticeSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - try { - const payload: Notice = { - id: editingNotice ? editingNotice.id : '', - ...noticeForm, - targetFamilyIds: noticeTargetMode === 'all' ? [] : noticeForm.targetFamilyIds, - date: editingNotice ? editingNotice.date : new Date().toISOString() - }; - await CondoService.saveNotice(payload); - // Refresh notices for active condo + + const openEditNoticeModal = (n: Notice) => { + setEditingNotice(n); + const isTargeted = n.targetFamilyIds && n.targetFamilyIds.length > 0; + setNoticeTargetMode(isTargeted ? 'specific' : 'all'); + setNoticeForm({ title: n.title, content: n.content, type: n.type, link: n.link || '', condoId: n.condoId, active: n.active, targetFamilyIds: n.targetFamilyIds || [] }); + setShowNoticeModal(true); + }; + + const handleNoticeSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + try { + const payload: Notice = { + id: editingNotice ? editingNotice.id : '', + ...noticeForm, + targetFamilyIds: noticeTargetMode === 'all' ? [] : noticeForm.targetFamilyIds, + date: editingNotice ? editingNotice.date : new Date().toISOString() + }; + await CondoService.saveNotice(payload); setNotices(await CondoService.getNotices(activeCondo?.id)); - setShowNoticeModal(false); - } catch (e) { console.error(e); } + setShowNoticeModal(false); + } catch (e) { + console.error(e); + } }; - const handleDeleteNotice = async (id: string) => { - if(!window.confirm("Eliminare annuncio?")) return; - await CondoService.deleteNotice(id); - setNotices(notices.filter(n => n.id !== id)); + + const handleDeleteNotice = async (id: string) => { + if(!window.confirm("Eliminare annuncio?")) return; + await CondoService.deleteNotice(id); + setNotices(notices.filter(n => n.id !== id)); + }; + + const toggleNoticeActive = async (notice: Notice) => { + try { + const updated = { ...notice, active: !notice.active }; + await CondoService.saveNotice(updated); + setNotices(notices.map(n => n.id === notice.id ? updated : n)); + } catch(e) { + console.error(e); + } + }; + + const toggleNoticeFamilyTarget = (familyId: string) => { + setNoticeForm(prev => { + const current = prev.targetFamilyIds; + if (current.includes(familyId)) { + return { ...prev, targetFamilyIds: current.filter(id => id !== familyId) }; + } else { + return { ...prev, targetFamilyIds: [...current, familyId] }; + } + }); + }; + + const openReadDetails = (noticeId: string) => { + setSelectedNoticeId(noticeId); + setShowReadDetailsModal(true); }; - const toggleNoticeActive = async (notice: Notice) => { - try { - const updated = { ...notice, active: !notice.active }; - await CondoService.saveNotice(updated); - setNotices(notices.map(n => n.id === notice.id ? updated : n)); - } catch(e) { console.error(e); } - }; - - const toggleNoticeFamilyTarget = (familyId: string) => { - setNoticeForm(prev => { - const current = prev.targetFamilyIds; - if (current.includes(familyId)) { - return { ...prev, targetFamilyIds: current.filter(id => id !== familyId) }; - } else { - return { ...prev, targetFamilyIds: [...current, familyId] }; - } - }); + const openAddAlertModal = () => { + setEditingAlert(null); + setAlertForm({ subject: '', body: '', daysOffset: 1, offsetType: 'before_next_month', sendHour: 9, active: true }); + setShowAlertModal(true); }; - const openReadDetails = (noticeId: string) => { - setSelectedNoticeId(noticeId); - setShowReadDetailsModal(true); + const openEditAlertModal = (alert: AlertDefinition) => { + setEditingAlert(alert); + setAlertForm(alert); + setShowAlertModal(true); }; - // --- 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) => { - e.preventDefault(); - try { - const payload: AlertDefinition = { id: editingAlert ? editingAlert.id : '', subject: alertForm.subject!, body: alertForm.body!, daysOffset: Number(alertForm.daysOffset), offsetType: alertForm.offsetType as any, sendHour: Number(alertForm.sendHour), active: alertForm.active! }; - // Save alert with current condoId - const saved = await CondoService.saveAlert(payload); - setAlerts(editingAlert ? alerts.map(a => a.id === saved.id ? saved : a) : [...alerts, saved]); - setShowAlertModal(false); - } catch (e) { console.error(e); } + const handleAlertSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + try { + const payload: AlertDefinition = { + id: editingAlert ? editingAlert.id : '', + subject: alertForm.subject!, + body: alertForm.body!, + daysOffset: Number(alertForm.daysOffset), + offsetType: alertForm.offsetType as any, + sendHour: Number(alertForm.sendHour), + active: alertForm.active! + }; + const saved = await CondoService.saveAlert(payload); + setAlerts(editingAlert ? alerts.map(a => a.id === saved.id ? saved : a) : [...alerts, saved]); + setShowAlertModal(false); + } catch (e) { + console.error(e); + } }; - const handleDeleteAlert = async (id: string) => { if(!window.confirm("Eliminare avviso?")) return; await CondoService.deleteAlert(id); setAlerts(alerts.filter(a => a.id !== id)); }; + const handleDeleteAlert = async (id: string) => { + if(!window.confirm("Eliminare avviso?")) return; + await CondoService.deleteAlert(id); + setAlerts(alerts.filter(a => a.id !== id)); + }; const getCondoName = (id: string) => condos.find(c => c.id === id)?.name || 'Sconosciuto'; - // Helpers for Toggle Feature const toggleFeature = (key: keyof AppSettings['features']) => { if (!globalSettings) return; setGlobalSettings({ @@ -534,35 +534,26 @@ export const SettingsPage: React.FC = () => { }); }; - // --- TABS CONFIG --- const tabs: {id: TabType, label: string, icon: React.ReactNode}[] = [ { id: 'profile', label: 'Profilo', icon: }, ]; - - // "Funzionalità" visible ONLY to SuperAdmin if (isSuperAdmin) { tabs.push({ id: 'features', label: 'Funzionalità', icon: }); } - - // Other tabs visible to Privileged (Admin + PowerUser) if (isPrivileged) { tabs.push( { id: 'general', label: 'Condominio', icon: } ); - if (globalSettings?.features.multiCondo) { tabs.push({ id: 'condos', label: 'Lista Condomini', icon: }); } - tabs.push( { id: 'families', label: 'Famiglie', icon: }, { id: 'users', label: 'Utenti', icon: } ); - if (globalSettings?.features.notices) { tabs.push({ id: 'notices', label: 'Bacheca', icon: }); } - tabs.push( { id: 'alerts', label: 'Avvisi Email', icon: } ); @@ -572,279 +563,162 @@ export const SettingsPage: React.FC = () => { return (
+ {/* HEADER */}

Impostazioni

-

- {activeCondo ? `Gestione: ${activeCondo.name}` : 'Pannello di Controllo'} -

+

{activeCondo ? `Gestione: ${activeCondo.name}` : 'Pannello di Controllo'}

- {/* Tabs */} + {/* TABS NAVIGATION */}
{tabs.map(tab => ( - ))}
- {/* Profile Tab */} + {/* PROFILE TAB */} {activeTab === 'profile' && (
-

- Il Tuo Profilo -

+

Il Tuo Profilo

-
setProfileForm({...profileForm, name: e.target.value})} className="w-full border p-2.5 rounded-lg text-slate-700"/>
-
-
setProfileForm({...profileForm, phone: e.target.value})} className="w-full border p-2.5 rounded-lg text-slate-700"/>
-
setProfileForm({...profileForm, password: e.target.value})} className="w-full border p-2.5 rounded-lg text-slate-700"/>
+
+ + setProfileForm({...profileForm, name: e.target.value})} className="w-full border p-2.5 rounded-lg text-slate-700"/> +
+
+ + +
+
+ + setProfileForm({...profileForm, phone: e.target.value})} className="w-full border p-2.5 rounded-lg text-slate-700"/> +
+
+ + setProfileForm({...profileForm, password: e.target.value})} className="w-full border p-2.5 rounded-lg text-slate-700"/> +
+ {profileMsg &&

{profileMsg}

}
)} - {/* Features Tab (SUPER ADMIN ONLY) */} + {/* FEATURES TAB (ADMIN ONLY) */} {isSuperAdmin && activeTab === 'features' && globalSettings && (
-

- Funzionalità Piattaforma -

+

Funzionalità Piattaforma

-
- {/* Multi Condo */} + {/* Toggles */} +
+

Gestione Multicondominio

Abilita la gestione di più stabili.

+ +
+
+

Gestione Tickets

Abilita il sistema di segnalazione guasti.

+ +
+
+

Pagamenti PayPal

Permetti ai condomini di pagare online.

+ +
+
+

Bacheca Avvisi

Mostra la bacheca digitale.

+ +
+
+

Reportistica Avanzata

Abilita grafici incassi e bilancio.

+ +
+
+

Spese Straordinarie

Gestione lavori e preventivi.

+ +
+ + {/* NEW TOGGLE for Condo Financials View */}
-

Gestione Multicondominio

-

Abilita la gestione di più stabili. Se disattivo, il sistema gestirà un solo condominio.

+

Visualizza Spese Condominiali agli Utenti

+

Se attivo, gli utenti potranno vedere (sola lettura) il registro delle spese condominiali.

-
- {/* Tickets */} -
-
-

Gestione Tickets

-

Abilita il sistema di segnalazione guasti e richieste (Segnalazioni).

-
- -
- - {/* PayPal */} -
-
-

Pagamenti PayPal

-

Permetti ai condomini di pagare le rate tramite PayPal.

-
- -
- - {/* Notices */} -
-
-

Bacheca Avvisi

-

Mostra la bacheca digitale per comunicazioni ai condomini.

-
- -
- - {/* Reports */} -
-
-

Reportistica Avanzata

-

Abilita grafici e tabelle dettagliate sui pagamenti per amministratori.

-
- -
- - {/* Extraordinary Expenses */} -
-
-

Spese Straordinarie

-

Gestione lavori, preventivi e ripartizione quote extra.

-
- -
-
- -
- {successMsg} -
+
{successMsg}
)} - {/* General Tab */} + {/* GENERAL TAB */} {isPrivileged && activeTab === 'general' && (
- {!activeCondo ? ( -
Nessun condominio selezionato.
- ) : ( + {!activeCondo ?
Nessun condominio selezionato.
: (

Dati Condominio Corrente

setActiveCondo({ ...activeCondo, name: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" placeholder="Nome" required /> - -
- - setActiveCondo({ ...activeCondo, address: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" placeholder="Via/Piazza..." required/> -
- -
-
- - setActiveCondo({ ...activeCondo, streetNumber: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" required/> -
-
- - setActiveCondo({ ...activeCondo, zipCode: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700"/> -
-
- -
-
- - setActiveCondo({ ...activeCondo, city: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" required/> -
-
- - setActiveCondo({ ...activeCondo, province: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" required/> -
-
- -
- - -
- - {/* PayPal Configuration for Single Condo Mode */} - {globalSettings?.features.payPal && ( -
-
- - Configurazione Pagamenti -
-
- - setActiveCondo({...activeCondo, paypalClientId: e.target.value})} - /> -

Necessario per abilitare i pagamenti online delle rate.

-
-
- )} - -
- - setActiveCondo({ ...activeCondo, defaultMonthlyQuota: parseFloat(e.target.value) })} className="w-full border p-2.5 rounded-lg text-slate-700" placeholder="Quota Default" required /> -
+
setActiveCondo({ ...activeCondo, address: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" placeholder="Via/Piazza..." required/>
+
setActiveCondo({ ...activeCondo, streetNumber: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" required/>
setActiveCondo({ ...activeCondo, zipCode: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700"/>
+
setActiveCondo({ ...activeCondo, city: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" required/>
setActiveCondo({ ...activeCondo, province: e.target.value })} className="w-full border p-2.5 rounded-lg text-slate-700" required/>
+
+ {globalSettings?.features.payPal && (
Configurazione Pagamenti
setActiveCondo({...activeCondo, paypalClientId: e.target.value})} />

Necessario per abilitare i pagamenti online delle rate.

)} +
setActiveCondo({ ...activeCondo, defaultMonthlyQuota: parseFloat(e.target.value) })} className="w-full border p-2.5 rounded-lg text-slate-700" placeholder="Quota Default" required />
{successMsg}
)} - {globalSettings && ( -
-

Anno Fiscale

-

Corrente: {globalSettings.currentYear}

- -
- )} + {globalSettings && (

Anno Fiscale

Corrente: {globalSettings.currentYear}

)}
)} - {/* Condos List Tab */} + {/* CONDOS LIST TAB */} {isPrivileged && activeTab === 'condos' && (
-
-

I Tuoi Condomini

- -
+

I Tuoi Condomini

{condos.map(condo => (
{activeCondo?.id === condo.id &&
Attivo
}

{condo.name}

-
-

{condo.address} {condo.streetNumber}

- {condo.city &&

{condo.zipCode} {condo.city} ({condo.province})

} -
-
- - -
+

{condo.address} {condo.streetNumber}

{condo.city &&

{condo.zipCode} {condo.city} ({condo.province})

}
+
))}
)} - - {/* Families Tab */} + + {/* FAMILIES TAB */} {isPrivileged && activeTab === 'families' && (
- {!activeCondo ? ( -
-

Seleziona o crea un condominio per gestire le famiglie.

-
- ) : ( + {!activeCondo ? (

Seleziona o crea un condominio per gestire le famiglie.

) : ( <> -
-
Famiglie in: {activeCondo.name}
- -
+
Famiglie in: {activeCondo.name}
- - +
NomeDettagliEmailQuotaAzioni
{families.map(family => ( - + - + ))} @@ -855,44 +729,25 @@ export const SettingsPage: React.FC = () => { )} )} - - {/* Users Tab */} + + {/* USERS TAB */} {isPrivileged && activeTab === 'users' && (
-
- -
+
-
NomeDettagliEmailQuotaAzioni
{family.name} -
- Int: {family.unitNumber || '-'} - {(family.stair || family.floor) && ( - - {family.stair ? `Scala: ${family.stair} ` : ''} - {family.floor ? `Piano: ${family.floor}` : ''} - - )} -
-
Int: {family.unitNumber || '-'}{(family.stair || family.floor) && ({family.stair ? `Scala: ${family.stair} ` : ''} {family.floor ? `Piano: ${family.floor}` : ''})}
{family.contactEmail} - {family.customMonthlyQuota ? ( - € {family.customMonthlyQuota} - ) : ( - Default (€ {activeCondo.defaultMonthlyQuota}) - )} - {family.customMonthlyQuota ? (€ {family.customMonthlyQuota}) : (Default (€ {activeCondo.defaultMonthlyQuota}))}
- +
UtenteRuoloAzioni
- {users.map(u => ( - - - - - - ))} + {users.map(u => ())}
UtenteRuoloAzioni
{u.name}
{u.email}
{u.role}
{u.name}
{u.email}
{u.role}
)} - {/* NOTICES (BACHECA) TAB */} + {/* NOTICES TAB */} {isPrivileged && activeTab === 'notices' && (
-
-

Bacheca Condominiale

Pubblica avvisi visibili a tutti i condomini.

- -
- +

Bacheca Condominiale

Pubblica avvisi visibili a tutti i condomini.

{notices.map(notice => { const isTargeted = notice.targetFamilyIds && notice.targetFamilyIds.length > 0; @@ -900,53 +755,12 @@ export const SettingsPage: React.FC = () => {
-
- {notice.type === 'warning' ? : notice.type === 'maintenance' ? : notice.type === 'event' ? : } -
-
-

- {notice.title} - {isTargeted && ( - - Privato - - )} -

-

{getCondoName(notice.condoId)} • {new Date(notice.date).toLocaleDateString()}

-

{notice.content}

- {notice.link && Allegato} - {isTargeted && ( -

- Visibile a: {notice.targetFamilyIds!.length} famiglie -

- )} -
-
-
- {/* Toggle Active */} - - - {/* Reads Counter */} - +
{notice.type === 'warning' ? : notice.type === 'maintenance' ? : notice.type === 'event' ? : }
+

{notice.title}{isTargeted && ( Privato)}

{getCondoName(notice.condoId)} • {new Date(notice.date).toLocaleDateString()}

{notice.content}

{notice.link && Allegato}{isTargeted && (

Visibile a: {notice.targetFamilyIds!.length} famiglie

)}
+
-
- - -
+
); })} @@ -958,36 +772,14 @@ export const SettingsPage: React.FC = () => { {/* ALERTS TAB */} {isPrivileged && activeTab === 'alerts' && (
- - {/* SMTP Config Button */} -
- -
- -
-

Avvisi Automatici

Configura email automatiche per scadenze.

- -
+
+

Avvisi Automatici

Configura email automatiche per scadenze.

{alerts.map(alert => (
-

{alert.subject}

-

{alert.body}

-
- Offset: {alert.daysOffset} giorni ({alert.offsetType}) - Ore: {alert.sendHour}:00 - {alert.active ? 'Attivo' : 'Inattivo'} -
-
- - -
+

{alert.subject}

{alert.body}

+
Offset: {alert.daysOffset} giorni ({alert.offsetType})Ore: {alert.sendHour}:00{alert.active ? 'Attivo' : 'Inattivo'}
+
))} {alerts.length === 0 &&
Nessun alert configurato.
} @@ -995,108 +787,9 @@ export const SettingsPage: React.FC = () => {
)} - {/* ALERT MODAL (Existing) */} - {showAlertModal && ( -
-
-

{editingAlert ? 'Modifica Avviso' : 'Nuovo Avviso Automatico'}

-
- setAlertForm({...alertForm, subject: e.target.value})} required /> - +
+
+ +

Lasciare vuoto per usare il default del condominio (€ {activeCondo?.defaultMonthlyQuota})

+ setFamilyForm({...familyForm, customMonthlyQuota: e.target.value})} className="w-full border rounded-lg p-2.5 text-slate-700" placeholder="Es. 120.00"/> +
+
+ + +
+ +
+
+ )} + + {/* Alert Modal */} + {showAlertModal && ( +
+
+

{editingAlert ? 'Modifica Avviso' : 'Nuovo Avviso Automatico'}

+
+ setAlertForm({...alertForm, subject: e.target.value})} required /> + -
- -
- -

Lasciare vuoto per usare il default del condominio (€ {activeCondo?.defaultMonthlyQuota})

- setFamilyForm({...familyForm, customMonthlyQuota: e.target.value})} - className="w-full border rounded-lg p-2.5 text-slate-700" - placeholder="Es. 120.00" - /> -
- -
- - -
-
-
)}
);