import "./App.css"; import { AppProvider, useApp } from "./context/AppContext.jsx"; import { useEffect, useRef, useState } from "react"; import LoginPage from "./components/LoginPage.jsx"; import NavBar from "./components/NavBar.jsx"; import GebruikersBeheer from "./components/GebruikersBeheer.jsx"; import DashboardTab from "./pages/DashboardTab.jsx"; import EigenVermogenTab from "./pages/EigenVermogenTab.jsx"; import SchuldTab from "./pages/SchuldTab.jsx"; import VoortgangTab from "./pages/VoortgangTab.jsx"; import { RED } from "./constants/index.js"; import { fmt } from "./utils/format.js"; import { version } from "./version.js"; import { useUpdateCheck } from "./hooks/useUpdateCheck.js"; import ProfielPopup from "./components/ProfielPopup.jsx"; import InstellingenModal from "./components/InstellingenModal.jsx"; function initials(naam = "") { const parts = naam.trim().split(/\s+/); if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase(); return naam.slice(0, 2).toUpperCase(); } const PAGES = [DashboardTab, EigenVermogenTab, SchuldTab, VoortgangTab]; function AppInner() { const { loggedIn, login, logout, locked, tab, showUsers, setShowUsers, showInstellingen, setShowInstellingen, loading, T, currentUser, avatar, idleMinutes, totEV } = useApp(); const [profielOpen, setProfielOpen] = useState(false); const [searchOpen, setSearchOpen] = useState(false); const nieuweVersie = useUpdateCheck(); // { latest, naam, notes, url } of null const [bellOpen, setBellOpen] = useState(false); const searchRef = useRef(null); const idleTimer = useRef(null); const IDLE_MS = (idleMinutes ?? 30) * 60 * 1000; const [sessionVerlopen, setSessionVerlopen] = useState(false); useEffect(() => { if (!loggedIn) return; const reset = () => { clearTimeout(idleTimer.current); idleTimer.current = setTimeout(() => { logout(); setSessionVerlopen(true); }, IDLE_MS); }; const events = ["mousemove", "mousedown", "keydown", "touchstart", "scroll"]; events.forEach((e) => window.addEventListener(e, reset, { passive: true })); reset(); return () => { events.forEach((e) => window.removeEventListener(e, reset)); clearTimeout(idleTimer.current); }; }, [loggedIn]); useEffect(() => { const handler = (e) => { if ((e.metaKey || e.ctrlKey) && e.key === "k") { e.preventDefault(); setSearchOpen(true); setTimeout(() => searchRef.current?.focus(), 50); } if (e.key === "Escape") setSearchOpen(false); }; window.addEventListener("keydown", handler); return () => window.removeEventListener("keydown", handler); }, []); if (!loggedIn) { if (sessionVerlopen) { return (