SPB Git

Repository Public

App.tsx 3.7 KB 64 lines tsx

1// Routes. Public pages (share links, deposit portals, sign-in) never load the signed-in application.2import { lazy, Suspense, useEffect } from 'react';3import { Redirect, Route, Switch, useLocation } from 'wouter';4import { useAuth, useRefreshAuth } from './session.ts';5import { ErrorState, Loading } from './ui.tsx';67const Shell = lazy(() => import('./shell/Shell.tsx').then((m) => ({ default: m.Shell })));8const Explorer = lazy(() => import('./explorer/Explorer.tsx').then((m) => ({ default: m.Explorer })));9const Shares = lazy(() => import('./screens/Shares.tsx').then((m) => ({ default: m.Shares })));10const Requests = lazy(() => import('./screens/Requests.tsx').then((m) => ({ default: m.Requests })));11const RequestDetail = lazy(() => import('./screens/RequestDetail.tsx').then((m) => ({ default: m.RequestDetail })));12const Settings = lazy(() => import('./screens/Settings.tsx').then((m) => ({ default: m.Settings })));13const Admin = lazy(() => import('./screens/Admin.tsx').then((m) => ({ default: m.Admin })));14const Login = lazy(() => import('./screens/Login.tsx').then((m) => ({ default: m.Login })));15const Invite = lazy(() => import('./screens/Invite.tsx').then((m) => ({ default: m.Invite })));16const Recovery = lazy(() => import('./screens/Recovery.tsx').then((m) => ({ default: m.Recovery })));17const SharePage = lazy(() => import('./public-pages/SharePage.tsx').then((m) => ({ default: m.SharePage })));18const RequestPage = lazy(() => import('./public-pages/RequestPage.tsx').then((m) => ({ default: m.RequestPage })));1920function Private() {21  const { state, loading, error, refetch } = useAuth();22  const refresh = useRefreshAuth();23  const [loc, navigate] = useLocation();24  useEffect(() => { const h = () => { void refresh(); }; window.addEventListener('spd:unauthenticated', h); return () => window.removeEventListener('spd:unauthenticated', h); }, [refresh]);25  if (loading) return <Loading />;26  if (error || !state) return <ErrorState error={error} onRetry={() => void refetch()} />;27  if (!state.authenticated) return <Redirect to={loc === '/' ? '/login' : `/login?next=${encodeURIComponent(loc)}`} />;28  if (state.recovery) return <Redirect to="/recovery" />; // a recovery session can only enrol a passkey29  return (30    <Shell>31      <Switch>32        <Route path="/"><Explorer view="folder" folderId="root" /></Route>33        <Route path="/folder/:id">{(p) => <Explorer view="folder" folderId={p.id} />}</Route>34        <Route path="/recent"><Explorer view="recent" /></Route>35        <Route path="/starred"><Explorer view="starred" /></Route>36        <Route path="/trash"><Explorer view="trash" /></Route>37        <Route path="/search"><Explorer view="search" /></Route>38        <Route path="/duplicates"><Explorer view="duplicates" /></Route>39        <Route path="/shares"><Shares /></Route>40        <Route path="/requests"><Requests /></Route>41        <Route path="/requests/:id">{(p) => <RequestDetail id={p.id} />}</Route>42        <Route path="/settings/:tab?">{(p) => <Settings tab={p.tab} />}</Route>43        <Route path="/admin">{state.user?.role === 'admin' ? <Admin /> : <Redirect to="/" />}</Route>44        <Route><ErrorState error={{ code: 'not_found' }} onRetry={() => navigate('/')} /></Route>45      </Switch>46    </Shell>47  );48}4950export function App() {51  return (52    <Suspense fallback={<Loading />}>53      <Switch>54        <Route path="/s/:token">{(p) => <SharePage token={p.token} />}</Route>55        <Route path="/request/:token">{(p) => <RequestPage token={p.token} />}</Route>56        <Route path="/invite/:token">{(p) => <Invite token={p.token} />}</Route>57        <Route path="/login"><Login /></Route>58        <Route path="/recovery"><Recovery /></Route>59        <Route><Private /></Route>60      </Switch>61    </Suspense>62  );63}64
Files main
Menu

Theme