import { useState, useEffect } from 'react' import { BrowserRouter, Routes, Route, NavLink, Navigate } from 'react-router-dom' import { api, setCredentials, clearCredentials } from './api' import Login from './pages/Login' import Sources from './pages/Sources' import Import from './pages/Import' import Rules from './pages/Rules' import Mappings from './pages/Mappings' import Records from './pages/Records' import Log from './pages/Log' import Pivot from './pages/Pivot' import Remap from './pages/Remap' const NAV = [ { to: '/sources', label: 'Sources' }, { to: '/import', label: 'Import' }, { to: '/rules', label: 'Rules' }, { to: '/mappings', label: 'Mappings' }, { to: '/remap', label: 'Remap' }, { to: '/records', label: 'Records' }, { to: '/pivot', label: 'Pivot' }, { to: '/log', label: 'Log' }, ] export default function App() { const [authed, setAuthed] = useState(false) const [loginUser, setLoginUser] = useState('') const [sources, setSources] = useState([]) const [source, setSource] = useState(() => localStorage.getItem('selectedSource') || '') const [sidebarOpen, setSidebarOpen] = useState(false) async function handleLogin(user, pass) { setCredentials(user, pass) await api.getSources().then(s => { sessionStorage.setItem('df_user', user) sessionStorage.setItem('df_pass', pass) setSources(s) if (!source && s.length > 0) setSource(s[0].name) setAuthed(true) setLoginUser(user) }) } function handleLogout() { clearCredentials() sessionStorage.removeItem('df_user') sessionStorage.removeItem('df_pass') setAuthed(false) setLoginUser('') setSources([]) } // On mount, restore session if credentials are saved useEffect(() => { const user = sessionStorage.getItem('df_user') const pass = sessionStorage.getItem('df_pass') if (user && pass) handleLogin(user, pass).catch(() => handleLogout()) }, []) useEffect(() => { if (source) localStorage.setItem('selectedSource', source) }, [source]) if (!authed) return const sidebar = (
{/* Header */}
Dataflow
{loginUser}
{/* Source selector */}
setSidebarOpen(false)}>+
{/* Nav */}
) return (
{/* Mobile overlay */} {sidebarOpen && (
setSidebarOpen(false)} /> )} {/* Sidebar — fixed on mobile, static on desktop */}
{sidebar}
{/* Main */}
{/* Mobile top bar */}
Dataflow
} /> } /> } /> } /> } /> } /> } /> } /> } />
) }