- build.py: vendor templates/client into mcp/templates/client with client.json manifest (16 kinds); register drone-npm as a third CI shape (types: pypi/npm/docker); root *.py stale doc numbers fixed - registry.py: registry://client resource + list_client_components / get_client_component / get_client_template tools; build prompt gains the client scaffold step (docs://modules/ui_admin); compliance prompt covers npm packages; drone docs describe all three shapes - repos.json (+mcp): doc-weaver, react-auth, react-openapi (npm Type B, package.json version source), vet (app Type C, VERSION) - docs: 90_drone_pipelines gains Type B npm section; 91_versioning covers package.json as a version source; 94_repository_inventory gains the npm package table and services/apps Type C; lib index updated Verified: bundle regen (24 modules, client 16, drone 3, repos 13); registry client readers exercised against the vendored bundle.
95 lines
2.6 KiB
JavaScript
95 lines
2.6 KiB
JavaScript
/**
|
|
* Application entry point.
|
|
*
|
|
* Creates the React root from `#root` and mounts the app: `AuthProvider`
|
|
* (JWT session against `VITE_AUTH_BASE_URL`) wraps a `LoginGate` (renders
|
|
* `AuthPage` until authenticated) which wraps `AppProvider` (fed by
|
|
* `specConfiguration`) → `BrowserRouter` → `AppTheme` → `Header` → routed
|
|
* content (`Home` at `/`, `Admin` at `/admin/*`) → `Footer`.
|
|
*
|
|
* @packageDocumentation
|
|
*/
|
|
|
|
import * as React from 'react';
|
|
import { createRoot } from 'react-dom/client';
|
|
import { BrowserRouter, Routes, Route } from "react-router-dom";
|
|
import { Box, CssBaseline, Toolbar } from "@mui/material";
|
|
import { AuthProvider, AuthPage, useAuth } from "@aetoskia/react-auth";
|
|
import Home from './Home';
|
|
import { Admin, AppProvider } from '@aetoskia/react-openapi';
|
|
import { specConfiguration } from './openapi-config';
|
|
import Header from './Header';
|
|
import Footer from './Footer';
|
|
import AppTheme from './shared-theme/AppTheme';
|
|
|
|
const authServer = import.meta.env.VITE_AUTH_BASE_URL;
|
|
|
|
const authConfig = {
|
|
serverUrl: authServer,
|
|
loginPath: "/login",
|
|
registerPath: "/register",
|
|
logoutPath: "/logout",
|
|
mePath: "/me",
|
|
introspectPath: "/introspect",
|
|
};
|
|
|
|
/**
|
|
* Route guard: renders the split-screen `AuthPage` until a user is
|
|
* authenticated, then renders the full application shell.
|
|
*
|
|
* @returns The login gate or the authenticated app.
|
|
*/
|
|
function LoginGate() {
|
|
const auth = useAuth();
|
|
const [mode, setMode] = React.useState("login");
|
|
|
|
if (!auth.currentUser) {
|
|
return (
|
|
<AppTheme>
|
|
<CssBaseline enableColorScheme />
|
|
<AuthPage
|
|
mode={mode}
|
|
onBack={() => {}}
|
|
onSwitchMode={() => setMode((m) => (m === "login" ? "register" : "login"))}
|
|
login={auth.login}
|
|
register={auth.register}
|
|
loading={auth.loading}
|
|
error={auth.error}
|
|
currentUser={auth.currentUser}
|
|
/>
|
|
</AppTheme>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<AppProvider specConfiguration={specConfiguration}>
|
|
<BrowserRouter>
|
|
<AppTheme>
|
|
<CssBaseline enableColorScheme />
|
|
<Header />
|
|
|
|
<Box sx={{ pb: 8 }}>
|
|
<Toolbar />
|
|
|
|
<Routes>
|
|
<Route path="/" element={<Home />} />
|
|
<Route path="/admin/*" element={<Admin basePath="/admin" />} />
|
|
</Routes>
|
|
</Box>
|
|
|
|
<Footer />
|
|
</AppTheme>
|
|
</BrowserRouter>
|
|
</AppProvider>
|
|
);
|
|
}
|
|
|
|
const rootElement = document.getElementById('root');
|
|
const root = createRoot(rootElement);
|
|
|
|
root.render(
|
|
<AuthProvider authConfig={authConfig}>
|
|
<LoginGate />
|
|
</AuthProvider>
|
|
);
|