import { useEffect, useRef, useState } from 'react' import { NavLink, Outlet, useLocation } from 'react-router-dom' import { api } from './api' import { AuthModal, ToastHost } from './components' import Embers from './Embers.jsx' export default function App() { // null until /auth/me resolves; in local mode multi_user=false hides all auth UI. const [me, setMe] = useState(null) const [authMode, setAuthMode] = useState(null) // 'register' | 'login' | null const [navOpen, setNavOpen] = useState(false) // mobile hamburger menu const location = useLocation() const lastPath = useRef(null) useEffect(() => { api.getMe().then(setMe).catch(() => {}) }, []) // One pageview per route the reader actually lands on. Guarded on the path // rather than fired on every render: StrictMode runs effects twice in dev, // and a re-render for unrelated state is not a new page. useEffect(() => { if (lastPath.current === location.pathname) return const first = lastPath.current === null lastPath.current = location.pathname // document.referrer survives client-side navigation, so it is only honest // on the first view — after that this was our own page, not a referral. api.trackPageview(location.pathname, { referrer: first ? document.referrer : '', first, }) }, [location.pathname]) const onAuthed = (newMe, mode) => { setAuthMode(null) if (mode === 'login') { // Different user now — reload so every page refetches its scoped data. window.location.reload() } else { setMe(newMe) // register upgrades the same user in place; data unchanged } } const logout = async () => { try { await api.logout() } catch { /* already logged out */ } window.location.reload() } return ( {authMode && ( setAuthMode(null)} onAuthed={onAuthed} retentionDays={me?.guest_retention_days} /> )} ) }