diff --git a/pages/FamilyList.tsx b/pages/FamilyList.tsx index 04e481a..7d22fbc 100644 --- a/pages/FamilyList.tsx +++ b/pages/FamilyList.tsx @@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { CondoService } from '../services/mockDb'; import { Family, Condo, Notice, AppSettings, Ticket, TicketStatus } from '../types'; -import { Search, ChevronRight, UserCircle, Building, Bell, AlertTriangle, Hammer, Calendar, Info, Link as LinkIcon, Check, Wallet, Briefcase, MessageSquareWarning, ArrowRight, CheckCircle2, ChevronDown, ChevronUp, Eye } from 'lucide-react'; +import { Search, ChevronRight, UserCircle, Building, Bell, AlertTriangle, Hammer, Calendar, Info, Link as LinkIcon, Check, Wallet, Briefcase, MessageSquareWarning, ArrowRight, CheckCircle2, ChevronDown, ChevronUp, Eye, Inbox } from 'lucide-react'; export const FamilyList: React.FC = () => { const navigate = useNavigate(); @@ -34,18 +34,30 @@ export const FamilyList: React.FC = () => { const fetchData = async () => { try { CondoService.seedPayments(); - const [fams, condo, allNotices, appSettings] = await Promise.all([ - CondoService.getFamilies(), - CondoService.getActiveCondo(), - CondoService.getNotices(), - CondoService.getSettings() + + // 1. Fetch Global Settings & Active Condo FIRST + const [appSettings, condo] = await Promise.all([ + CondoService.getSettings(), + CondoService.getActiveCondo() + ]); + + setSettings(appSettings); + setActiveCondo(condo); + + if (!condo) { + setLoading(false); + return; + } + + // 2. Fetch specific data using condo.id (prevents race conditions) + const [fams, allNotices] = await Promise.all([ + CondoService.getFamilies(condo.id), + CondoService.getNotices(condo.id) ]); setFamilies(fams); - setActiveCondo(condo); - setSettings(appSettings); // --- USER SPECIFIC DASHBOARD DATA --- - if (currentUser && !isPrivileged && currentUser.familyId && condo) { + if (currentUser && !isPrivileged && currentUser.familyId) { // 1. Find My Family const me = fams.find(f => f.id === currentUser.familyId) || null; setMyFamily(me); @@ -98,7 +110,7 @@ export const FamilyList: React.FC = () => { } // --- NOTICE LOGIC --- - if (condo && currentUser && appSettings.features.notices) { + if (currentUser && appSettings.features.notices) { // Filter: Must be same condo AND Active // Visibility: Admin sees all. User sees Public OR Targeted. const relevantNotices = allNotices.filter(n => { @@ -184,104 +196,99 @@ export const FamilyList: React.FC = () => {
{/* 1. BACHECA CONDOMINIALE (Notices) */} - {/* This section is rendered if notices feature is enabled and there are notices */} - {settings?.features.notices && notices.length > 0 && ( + {/* Visualizzata SEMPRE se la feature รจ attiva, anche se vuota */} + {settings?.features.notices && (

Bacheca Condominiale

-
- {notices.map(notice => { - const isRead = userReadIds.includes(notice.id); - const isExpanded = expandedNoticeId === notice.id; - - // Style configuration - // New notices get a distinct border and white background. - // Read notices get a slate background and are slightly dimmed to indicate "archive" status. - let containerClass = isRead - ? 'bg-slate-50 border-slate-200' - : 'bg-white border-blue-200 shadow-sm ring-1 ring-blue-50'; - - if (notice.type === 'warning' && !isRead) { - containerClass = 'bg-amber-50/50 border-amber-300 shadow-sm ring-1 ring-amber-50'; - } + + {notices.length === 0 ? ( +
+ +

Nessun avviso in bacheca.

+
+ ) : ( +
+ {notices.map(notice => { + const isRead = userReadIds.includes(notice.id); + const isExpanded = expandedNoticeId === notice.id; + + let containerClass = isRead + ? 'bg-slate-50 border-slate-200' + : 'bg-white border-blue-200 shadow-sm ring-1 ring-blue-50'; + + if (notice.type === 'warning' && !isRead) { + containerClass = 'bg-amber-50/50 border-amber-300 shadow-sm ring-1 ring-amber-50'; + } - return ( -
-
- {/* Icon Column */} -
- -
+ return ( +
+
+
+ +
- {/* Content Column */} -
- {/* Header: Title + Badges */} -
-
-

{notice.title}

- {!isRead && ( - - Nuovo - - )} - {isRead && ( - - Letto - - )} +
+
+
+

{notice.title}

+ {!isRead && ( + + Nuovo + + )} + {isRead && ( + + Letto + + )} +
+ {new Date(notice.date).toLocaleDateString()}
- {new Date(notice.date).toLocaleDateString()} -
- {/* Body Text */} -
- {notice.content} -
+
+ {notice.content} +
- {/* Footer Actions */} -
-
- {/* Expand Button (only if long content) */} - {(notice.content.length > 120 || notice.content.includes('\n')) && ( +
+
+ {(notice.content.length > 120 || notice.content.includes('\n')) && ( + + )} + {notice.link && ( + + Apri Allegato + + )} +
+ + {!isRead && ( )} - - {/* Link Button */} - {notice.link && ( - - Apri Allegato - + {isRead && ( + + Archiviato + )}
- - {/* Mark as Read Button (Only if not read) */} - {!isRead && ( - - )} - {/* Re-read indicator (optional visual cue) */} - {isRead && ( - - Archiviato - - )}
-
- ); - })} -
+ ); + })} +
+ )}
)}