Update Layout.tsx

This commit is contained in:
2025-12-10 23:20:12 +01:00
committed by GitHub
parent 074daa7110
commit 462858d293

View File

@@ -2,7 +2,7 @@
import React, { useEffect, useState } from 'react';
import { NavLink, Outlet } from 'react-router-dom';
import { Users, Settings, Building, LogOut, Menu, X, ChevronDown, Check, LayoutDashboard, Megaphone, Info, AlertTriangle, Hammer, Calendar, MessageSquareWarning, PieChart, Briefcase } from 'lucide-react';
import { CondoService } from '../services/mockDb';
import { CondoService } from '../services/api';
import { Condo, Notice, AppSettings } from '../types';
export const Layout: React.FC = () => {
@@ -19,6 +19,9 @@ export const Layout: React.FC = () => {
const [activeNotice, setActiveNotice] = useState<Notice | null>(null);
const [hasNewExpenses, setHasNewExpenses] = useState(false);
// Ticket Badges
const [ticketBadgeCount, setTicketBadgeCount] = useState(0);
const fetchContext = async () => {
// Fetch global settings to check features
try {
@@ -37,16 +40,63 @@ export const Layout: React.FC = () => {
const active = await CondoService.getActiveCondo();
setActiveCondo(active);
// --- NOTIFICATION LOGIC ---
const lastViewedTicketsStr = localStorage.getItem('lastViewedTickets');
const lastViewedTickets = lastViewedTicketsStr ? parseInt(lastViewedTicketsStr) : 0;
// 1. Tickets Badge Logic
try {
if (settings?.features.tickets || true) { // Check features if available or default
const tickets = await CondoService.getTickets();
let count = 0;
for (const t of tickets) {
const ticketDate = new Date(t.createdAt).getTime();
const isTicketNew = ticketDate > lastViewedTickets;
const isArchived = t.status === 'RESOLVED' || t.status === 'CLOSED';
if (isAdmin) {
// Admin: Count new unarchived tickets OR tickets with new comments from users
if (isTicketNew && !isArchived) {
count++;
} else {
// Check for new comments from users
// Optimization: In a real app we'd need a lighter query.
// Here we iterate because we have the data or fetch lightly.
// Assuming getTickets includes basic info or we need to check updatedAt
const updatedDate = new Date(t.updatedAt).getTime();
if (updatedDate > lastViewedTickets) {
// Deep check: fetch comments only if recently updated
const comments = await CondoService.getTicketComments(t.id);
const hasNewUserReply = comments.some(c => new Date(c.createdAt).getTime() > lastViewedTickets && c.userId !== user?.id);
if (hasNewUserReply) count++;
}
}
} else {
// User: Count tickets with new comments from Admin (or others)
const updatedDate = new Date(t.updatedAt).getTime();
if (updatedDate > lastViewedTickets) {
const comments = await CondoService.getTicketComments(t.id);
const hasNewReply = comments.some(c => new Date(c.createdAt).getTime() > lastViewedTickets && c.userId !== user?.id);
if (hasNewReply) count++;
}
}
}
setTicketBadgeCount(count);
}
} catch(e) { console.error("Error calc ticket badges", e); }
// Check for notices & expenses for User
if (!isAdmin && active && user) {
try {
// 1. Check Notices
// 2. Check Notices
const unread = await CondoService.getUnreadNoticesForUser(user.id, active.id);
if (unread.length > 0) {
setActiveNotice(unread[0]);
}
// 2. Check New Extraordinary Expenses
// 3. Check New Extraordinary Expenses
const myExpenses = await CondoService.getMyExpenses();
const lastViewed = localStorage.getItem('lastViewedExpensesTime');
const lastViewedTime = lastViewed ? parseInt(lastViewed) : 0;
@@ -65,10 +115,12 @@ export const Layout: React.FC = () => {
// Listen for updates from Settings or Expense views
const handleUpdate = () => fetchContext();
window.addEventListener('condo-updated', handleUpdate);
window.addEventListener('expenses-viewed', handleUpdate); // Listen for manual trigger when user views page
window.addEventListener('expenses-viewed', handleUpdate);
window.addEventListener('tickets-viewed', handleUpdate); // Listen for ticket view
return () => {
window.removeEventListener('condo-updated', handleUpdate);
window.removeEventListener('expenses-viewed', handleUpdate);
window.removeEventListener('tickets-viewed', handleUpdate);
};
}, [isAdmin]);
@@ -276,8 +328,17 @@ export const Layout: React.FC = () => {
{/* Hide Tickets if disabled */}
{settings?.features.tickets && (
<NavLink to="/tickets" className={navClass} onClick={closeMenu}>
<MessageSquareWarning className="w-5 h-5" />
<span className="font-medium">Segnalazioni</span>
<div className="flex items-center justify-between w-full">
<div className="flex items-center gap-3">
<MessageSquareWarning className="w-5 h-5" />
<span className="font-medium">Segnalazioni</span>
</div>
{ticketBadgeCount > 0 && (
<span className="bg-red-500 text-white text-[10px] font-bold px-1.5 h-5 min-w-[20px] rounded-full flex items-center justify-center shadow-sm">
{ticketBadgeCount > 99 ? '99+' : ticketBadgeCount}
</span>
)}
</div>
</NavLink>
)}