// App shell: sidebar (desktop) + bottom nav (mobile) + vues // ── Sidebar (desktop uniquement) ───────────────────── function Sidebar({ view, setView, items, openForm, user, onLogout, syncError }) { const userInfo = USERS[user] || { name: user, color: 'var(--terracotta)', avatar: (user||'?')[0].toUpperCase() }; const today = TODAY; const todayCount = itemsOnDate(items, today).filter(x => x.kind === 'task' && ['todo','progress'].includes(statusOn(x, today))).length; const overdue = items.filter(x => x.kind === 'task' && (x.recurrence?.kind || 'none') === 'none' && isBefore(fromYmd(x.date), today) && !['done','cancelled'].includes(x.status)).length; const eventsCount = items.filter(x => x.kind !== 'task').length; const NavItem = ({ id, icon, label, badge, badgeColor }) => { const active = view === id; return ( ); }; return ( ); } // ── Bottom navigation (mobile uniquement) ───────────── function BottomNav({ view, setView, items }) { const today = TODAY; const todayCount = itemsOnDate(items, today).filter(x => x.kind === 'task' && ['todo','progress'].includes(statusOn(x, today))).length; const overdueCount = items.filter(x => x.kind === 'task' && (x.recurrence?.kind || 'none') === 'none' && isBefore(fromYmd(x.date), today) && !['done','cancelled'].includes(x.status)).length; const eventsCount = items.filter(x => x.kind !== 'task').length; const tabs = [ { id: 'dashboard', icon: 'sparkle', label: 'Accueil', badge: todayCount, badgeColor: 'var(--terracotta)' }, { id: 'calendar', icon: 'calendar', label: 'Calendrier' }, { id: 'tasks', icon: 'list', label: 'Tâches' }, { id: 'overdue', icon: 'bell', label: 'En retard', badge: overdueCount, badgeColor: 'var(--prio-high)' }, { id: 'events', icon: 'cake', label: 'Événements', badge: eventsCount, badgeColor: 'var(--event)' }, ]; return ( ); } // ── App principal ───────────────────────────────────── function App() { const { user, login, logout, loading } = useAuthSB(); const { items, upsert, remove, setStatusOn, syncError, reload } = useStoreSB(); const [view, setView] = React.useState('dashboard'); const [formOpen, setFormOpen] = React.useState(false); const [editing, setEditing] = React.useState(null); const openForm = (initial) => { setEditing(initial || null); setFormOpen(true); }; const onEdit = (item) => { setEditing(item); setFormOpen(true); }; // Recharge les items dès que l'utilisateur est connecté React.useEffect(() => { if (user) reload(); }, [user]); const handleLogin = async (key) => { await login(key); }; if (loading) return (