import { createRoot } from "react-dom/client"; import domReady from "./utils/domReady.ts"; import { StrictMode } from "react"; import "./index.css"; import "./components/ui/nativeSelect.css"; import App from "./App.tsx"; import { getMountContext } from "./utils/mountContext.ts"; import { warnIfRunningSupersededCode } from "./utils/staleDocumentCheck.ts"; import { captureNotificationLink } from "./utils/notificationLink.ts"; import { HashRouter } from "react-router-dom"; import { demoAppOrigin, demoPageFor } from "./utils/demoEntrance.ts"; import DemoVisit from "./pages/Demo/DemoVisit.tsx"; import DemoLanding from "./pages/Demo/DemoLanding.tsx"; import DemoEntryPage from "./pages/Demo/DemoEntryPage.tsx"; domReady(() => { const mountElement = document.getElementById('akashic-health-records-patient-portal-root')!; // THE MOUNT ID IS NOT THE MOUNT. All FIVE mounts render the SAME element id // `akashic-health-records-patient-portal-root` - the patient shortcode, the STAFF shortcode // (class-akashere-staff-shortcode.php:23), both public-form paths, and the wp-admin menu page. // So `#akashic-health-records-patient-portal-root` in a stylesheet means "anywhere this plugin // renders", NOT "the patient portal", and a rule written there lands on the staff portal and // WordPress admin too. // // The app has always known which experience it is (`wpData.context`, read by getMountContext), // but that fact never reached the DOM, so CSS could not act on it. This publishes it: // frontend = the patient portal - staff = the staff portal - admin = wp-admin - public = a // public form embedded in an ordinary page. // // Set BEFORE render so the first paint is already correct - the server-rendered placeholder in // that div is plain text with no controls, so there is no window in which a wrongly-sized // control is visible. mountElement.dataset.akashicMount = getMountContext(); // Before the router reads the address, so a notification link is held rather than routed. captureNotificationLink(); const root = createRoot(mountElement); // The demo entrance and its agreement have no practice behind them, so they render before the app, // which would resolve the demo label as a practice address. Hosted origins only. The demo origin // serves demo visits alone: every other page there is a visit, or the way back to the entrance. const demoPage = demoPageFor(); root.render( {demoPage === 'landing' ? : demoPage === 'entry' ? : window.location.origin === demoAppOrigin() ? : } ); /* * - say so when this tab is running code the server has already replaced. * * AFTER render and unawaited, on purpose: this is a diagnostic, and it must never sit between a * user and their first paint. It costs one small request for the page's own HTML. * * `visibilitychange` as well as boot, because the case it exists for is a tab left OPEN across a * deploy - that tab already booted, and boot-only would never fire for it. Re-checking when * somebody comes back to the tab is exactly when they are about to look at something and be * misled by it. */ void warnIfRunningSupersededCode(); document.addEventListener('visibilitychange', () => { if (document.visibilityState === 'visible') void warnIfRunningSupersededCode(); }); });