Cuts the initial bundle roughly in half. Users who open Home,
Extensions, or FAQ download ~343 kB / 106 kB gz instead of 817 kB /
230 kB gz. Heavy clinical reference data (PE_DATA, Fenton LMS,
Rosner BP splines, 15 Bedside drug panels, 10 Calculator formulas,
13 Settings sub-sections, 10 Admin sub-tabs) only loads when the
user opens that route.
client/src/App.tsx
Every route except Home / Extensions / FAQ wrapped in
React.lazy(() => import(...)) + <Suspense fallback>. Extensions and
FAQ stay in the main chunk because they're small (3 kB, 2 kB) and
likely visited early. The RouteFallback component shows a single
"Loading…" line — Vite prefetches chunks on hover so the delay is
typically invisible.
Resulting chunks (gzipped):
• index.js 106 kB React + Router + Query + Layout +
Home + Extensions + FAQ
• Bedside.js 33 kB 15 clinical dosing panels
• PeGuide.js 36 kB PE_DATA hierarchy + scales + sounds
• Calculators.js 42 kB All 10 calculators + BP Rosner
coefficients + Fenton + BMI LMS
• Settings.js 10 kB 13 Settings sub-sections
• Admin.js 7 kB 10 Admin sub-tabs
• Learning.js 3 kB
• Fenton chunk (shared) 3 kB Reused between Bedside neonatal
and the Growth Charts calculator
• Note pages (each) 1-2 kB Encounter / SOAP / Well / Sick /
Hospital / Chart / Dictation / Vax /
Catch-up individually chunked
Vite's 500 kB chunk-size warning is gone. No functional changes.
93 lines
5.1 KiB
TypeScript
93 lines
5.1 KiB
TypeScript
import { lazy, Suspense } from 'react';
|
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
import { BrowserRouter, Routes, Route, Navigate, Link } from 'react-router-dom';
|
|
import Layout from '@/components/Layout';
|
|
|
|
// Lightweight pages stay in the main chunk.
|
|
import Extensions from '@/pages/Extensions';
|
|
import Faq from '@/pages/Faq';
|
|
|
|
// Heavy pages lazy-load — keeps the initial bundle small so the home
|
|
// screen and quick tools (Extensions, FAQ) paint fast, and users only
|
|
// download the big clinical-reference tables (PE_DATA, Fenton LMS,
|
|
// Rosner BP splines, Bedside drug panels, Admin sub-tabs) when they
|
|
// open those specific routes.
|
|
const Dictation = lazy(() => import('@/pages/Dictation'));
|
|
const Encounter = lazy(() => import('@/pages/Encounter'));
|
|
const Soap = lazy(() => import('@/pages/Soap'));
|
|
const SickVisit = lazy(() => import('@/pages/SickVisit'));
|
|
const HospitalCourse = lazy(() => import('@/pages/HospitalCourse'));
|
|
const ChartReview = lazy(() => import('@/pages/ChartReview'));
|
|
const WellVisit = lazy(() => import('@/pages/WellVisit'));
|
|
const VaxSchedule = lazy(() => import('@/pages/VaxSchedule'));
|
|
const Catchup = lazy(() => import('@/pages/Catchup'));
|
|
const Settings = lazy(() => import('@/pages/Settings'));
|
|
const Learning = lazy(() => import('@/pages/Learning'));
|
|
const PeGuide = lazy(() => import('@/pages/PeGuide'));
|
|
const Bedside = lazy(() => import('@/pages/Bedside'));
|
|
const Calculators = lazy(() => import('@/pages/Calculators'));
|
|
const Admin = lazy(() => import('@/pages/Admin'));
|
|
|
|
const queryClient = new QueryClient({
|
|
defaultOptions: { queries: { staleTime: 30_000, retry: 1 } },
|
|
});
|
|
|
|
function RouteFallback() {
|
|
return (
|
|
<div className="max-w-3xl mx-auto p-6 text-sm text-muted-foreground">Loading…</div>
|
|
);
|
|
}
|
|
|
|
function Home() {
|
|
return (
|
|
<div className="max-w-3xl mx-auto p-6 space-y-4">
|
|
<h1 className="text-2xl font-semibold">Pediatric AI Scribe — React client</h1>
|
|
<p className="text-sm text-muted-foreground">
|
|
This is the new React tree. The legacy vanilla-JS app still lives at{' '}
|
|
<a href="/" className="underline">/</a>.
|
|
</p>
|
|
<p className="text-sm text-muted-foreground">Quick links:</p>
|
|
<ul className="list-disc pl-6 text-sm space-y-1">
|
|
<li><Link to="/encounter" className="underline">Encounter HPI</Link></li>
|
|
<li><Link to="/dictation" className="underline">Dictation HPI</Link></li>
|
|
<li><Link to="/soap" className="underline">SOAP Note</Link></li>
|
|
<li><Link to="/sickvisit" className="underline">Sick Visit</Link></li>
|
|
<li><Link to="/extensions" className="underline">Extensions & Pagers</Link></li>
|
|
<li><Link to="/faq" className="underline">FAQ</Link></li>
|
|
</ul>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default function App() {
|
|
return (
|
|
<QueryClientProvider client={queryClient}>
|
|
<BrowserRouter basename="/app">
|
|
<Routes>
|
|
<Route element={<Layout />}>
|
|
<Route path="/" element={<Home />} />
|
|
<Route path="/encounter" element={<Suspense fallback={<RouteFallback />}><Encounter /></Suspense>} />
|
|
<Route path="/dictation" element={<Suspense fallback={<RouteFallback />}><Dictation /></Suspense>} />
|
|
<Route path="/soap" element={<Suspense fallback={<RouteFallback />}><Soap /></Suspense>} />
|
|
<Route path="/sickvisit" element={<Suspense fallback={<RouteFallback />}><SickVisit /></Suspense>} />
|
|
<Route path="/hospital" element={<Suspense fallback={<RouteFallback />}><HospitalCourse /></Suspense>} />
|
|
<Route path="/chart" element={<Suspense fallback={<RouteFallback />}><ChartReview /></Suspense>} />
|
|
<Route path="/wellvisit" element={<Suspense fallback={<RouteFallback />}><WellVisit /></Suspense>} />
|
|
<Route path="/vaxschedule" element={<Suspense fallback={<RouteFallback />}><VaxSchedule /></Suspense>} />
|
|
<Route path="/catchup" element={<Suspense fallback={<RouteFallback />}><Catchup /></Suspense>} />
|
|
<Route path="/extensions" element={<Extensions />} />
|
|
<Route path="/settings" element={<Suspense fallback={<RouteFallback />}><Settings /></Suspense>} />
|
|
<Route path="/learning" element={<Suspense fallback={<RouteFallback />}><Learning /></Suspense>} />
|
|
<Route path="/peguide" element={<Suspense fallback={<RouteFallback />}><PeGuide /></Suspense>} />
|
|
<Route path="/bedside" element={<Suspense fallback={<RouteFallback />}><Bedside /></Suspense>} />
|
|
<Route path="/calculators" element={<Suspense fallback={<RouteFallback />}><Calculators /></Suspense>} />
|
|
<Route path="/admin" element={<Suspense fallback={<RouteFallback />}><Admin /></Suspense>} />
|
|
<Route path="/faq" element={<Faq />} />
|
|
{/* catch-all falls back to home while more tabs port over */}
|
|
<Route path="*" element={<Navigate to="/" replace />} />
|
|
</Route>
|
|
</Routes>
|
|
</BrowserRouter>
|
|
</QueryClientProvider>
|
|
);
|
|
}
|