Files
vu/src/ui/shell.ts
T
will a5dc6502d7
Deploy / deploy (push) Failing after 1m8s
Milestone 0/1: shell, calendar/psalter/hours scaffold, Prime
Client-side-first PWA (Vite/TS, no backend) per the approved plan: day-
navigable shell listing all 8 hours, Prime fully resolves via the
calendar -> psalter -> ordo pipeline, the other 7 hours are registered
but flagged not-implemented. Sanctoral/temporal calendar data uses a
day -> id indirection layer (saints, easter-offsets, fixed-date-calendar)
so reassigning a feast to a different day is a data edit, not a code
change. Docker (Caddy-serving-static) + Gitea CI workflow scaffolded to
match the eec/drip/bookshop operational pattern.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-09 15:20:06 -04:00

38 lines
1.3 KiB
TypeScript

import { subscribe } from '../app-state';
import { renderDayNav } from './day-nav';
import { renderHourList } from './hour-list';
import { renderHourView } from './hour-view';
import { renderLanguageToggle } from './bilingual-toggle';
export function mountShell(root: HTMLElement): void {
root.innerHTML = `
<header class="site-header">
<span class="site-title">vu</span>
<div data-slot="language-toggle"></div>
</header>
<div data-slot="day-nav"></div>
<main id="main" class="app-main">
<nav data-slot="hour-list" class="hour-list-nav" aria-label="Hours"></nav>
<div data-slot="hour-view" class="hour-view-region"></div>
</main>
`;
const dayNavEl = root.querySelector<HTMLElement>('[data-slot="day-nav"]');
const hourListEl = root.querySelector<HTMLElement>('[data-slot="hour-list"]');
const hourViewEl = root.querySelector<HTMLElement>('[data-slot="hour-view"]');
const languageToggleEl = root.querySelector<HTMLElement>('[data-slot="language-toggle"]');
if (!dayNavEl || !hourListEl || !hourViewEl || !languageToggleEl) {
throw new Error('shell markup is missing an expected slot');
}
function render(): void {
renderDayNav(dayNavEl!);
renderHourList(hourListEl!);
renderHourView(hourViewEl!);
renderLanguageToggle(languageToggleEl!);
}
render();
subscribe(render);
}