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.
1 line
No EOL
5.6 KiB
JavaScript
1 line
No EOL
5.6 KiB
JavaScript
import{i as e,n as t,t as n}from"./jsx-runtime-ByY1xr43.js";import{a as r,i}from"./index-B0uH73Hx.js";var a=e(t(),1),o=n();function s(){let[e,t]=(0,a.useState)(``),[n,s]=(0,a.useState)(``),[c,l]=(0,a.useState)(``),[u,d]=(0,a.useState)(`floor`),[f,p]=(0,a.useState)(``),[m,h]=(0,a.useState)(`auto`),[g,_]=(0,a.useState)(``),[v,y]=(0,a.useState)(``),[b,x]=(0,a.useState)(``),[S,C]=(0,a.useState)(null),w=r({mutationFn:e=>i.post(`/api/generate-hospital-course`,e),onSuccess:e=>C({hospitalCourse:e.hospitalCourse,format:e.format||`auto`})});function T(t){t.preventDefault(),C(null);let r=v.split(/\n\s*\n/).map(e=>e.trim()).filter(Boolean).map((e,t)=>({date:`Day ${t+1}`,type:`Progress Note`,content:e}));w.mutate({notes:r,hAndP:g?{date:`Admission`,content:g}:void 0,patientAge:e,patientGender:n,pmh:c,setting:u,los:f?parseInt(f):void 0,formatPreference:m,additionalInstructions:b||void 0})}let E=`w-full rounded-md border border-input bg-background px-3 py-2 text-sm`;return(0,o.jsxs)(`div`,{className:`max-w-4xl mx-auto p-6 space-y-4`,children:[(0,o.jsxs)(`header`,{children:[(0,o.jsx)(`h1`,{className:`text-2xl font-semibold`,children:`Hospital Course`}),(0,o.jsx)(`p`,{className:`text-sm text-muted-foreground`,children:`Progress notes + H&P → hospital course summary (prose, day-by-day, or organ-system format).`})]}),(0,o.jsxs)(`form`,{onSubmit:T,className:`space-y-4`,children:[(0,o.jsxs)(`div`,{className:`grid grid-cols-3 gap-3`,children:[(0,o.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,o.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:`Age`}),(0,o.jsx)(`input`,{className:E,value:e,onChange:e=>t(e.target.value)})]}),(0,o.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,o.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:`Gender`}),(0,o.jsxs)(`select`,{className:E,value:n,onChange:e=>s(e.target.value),children:[(0,o.jsx)(`option`,{value:``,children:`Select`}),(0,o.jsx)(`option`,{children:`Male`}),(0,o.jsx)(`option`,{children:`Female`})]})]}),(0,o.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,o.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:`Setting`}),(0,o.jsxs)(`select`,{className:E,value:u,onChange:e=>d(e.target.value),children:[(0,o.jsx)(`option`,{value:`floor`,children:`Floor`}),(0,o.jsx)(`option`,{value:`picu`,children:`PICU`}),(0,o.jsx)(`option`,{value:`nicu`,children:`NICU`}),(0,o.jsx)(`option`,{value:`psych`,children:`Psych`})]})]})]}),(0,o.jsxs)(`div`,{className:`grid grid-cols-3 gap-3`,children:[(0,o.jsxs)(`label`,{className:`flex flex-col gap-1 col-span-2`,children:[(0,o.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:`PMH`}),(0,o.jsx)(`input`,{className:E,placeholder:`e.g. Asthma, hypothyroidism`,value:c,onChange:e=>l(e.target.value)})]}),(0,o.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,o.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:`LOS (days)`}),(0,o.jsx)(`input`,{className:E,type:`number`,value:f,onChange:e=>p(e.target.value)})]})]}),(0,o.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,o.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:`Format`}),(0,o.jsxs)(`select`,{className:E,value:m,onChange:e=>h(e.target.value),children:[(0,o.jsx)(`option`,{value:`auto`,children:`Auto (infer from setting + LOS)`}),(0,o.jsx)(`option`,{value:`prose`,children:`Prose summary`}),(0,o.jsx)(`option`,{value:`dayByDay`,children:`Day-by-day`}),(0,o.jsx)(`option`,{value:`organSystem`,children:`Organ-system (ICU)`})]})]}),(0,o.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,o.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:`H&P`}),(0,o.jsx)(`textarea`,{className:E+` min-h-[120px] font-mono text-sm`,value:g,onChange:e=>_(e.target.value)})]}),(0,o.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,o.jsxs)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:[`Progress notes `,(0,o.jsx)(`span`,{className:`normal-case font-normal text-muted-foreground`,children:`(separate each note with a blank line)`})]}),(0,o.jsx)(`textarea`,{className:E+` min-h-[200px] font-mono text-sm`,value:v,onChange:e=>y(e.target.value)})]}),(0,o.jsxs)(`label`,{className:`flex flex-col gap-1`,children:[(0,o.jsx)(`span`,{className:`text-xs font-semibold uppercase tracking-wider text-muted-foreground`,children:`Additional instructions`}),(0,o.jsx)(`textarea`,{className:E+` min-h-[60px] text-sm`,value:b,onChange:e=>x(e.target.value)})]}),w.error&&(0,o.jsx)(`div`,{className:`text-sm text-destructive`,children:w.error.message}),(0,o.jsx)(`button`,{type:`submit`,disabled:w.isPending||!v.trim(),className:`rounded-md bg-primary text-primary-foreground px-4 py-2 text-sm font-medium disabled:opacity-50`,children:w.isPending?`Generating…`:`Generate Hospital Course`})]}),S&&(0,o.jsxs)(`section`,{className:`rounded-lg border border-border bg-card`,children:[(0,o.jsxs)(`header`,{className:`px-4 py-2 border-b border-border flex items-center justify-between bg-muted/40`,children:[(0,o.jsxs)(`h2`,{className:`text-sm font-semibold`,children:[`Hospital Course `,(0,o.jsxs)(`span`,{className:`text-xs font-normal text-muted-foreground`,children:[`(`,S.format,`)`]})]}),(0,o.jsx)(`button`,{onClick:()=>navigator.clipboard.writeText(S.hospitalCourse),className:`text-xs text-muted-foreground underline`,children:`Copy`})]}),(0,o.jsx)(`div`,{className:`p-4 whitespace-pre-wrap text-sm`,children:S.hospitalCourse})]})]})}export{s as default}; |