Adds .d.ts declarations beside the untyped JS modules imported from TS (api.js, navConfig.js, adminSchema.js, adminNav.js, src/data/*), with shapes taken from the server routes and migrations. get/post/ patch/del now return unknown unless the caller names the response. Fixes found along the way: - website/email/instagram are bare strings from splitLinks, not Link objects; OrganizationDetail's website and email pills rendered with no href or label and now link correctly. - The chapter map falls back to FALLBACK_COLOR for a region with no colour instead of painting its tiles black. Adds defineSection() so each page manifest entry's props are checked against its own Component. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
32 lines
1.5 KiB
TypeScript
32 lines
1.5 KiB
TypeScript
/* ═══════════════════════════════════════════════════════════════
|
|
ADMIN TITLE
|
|
|
|
The layout knows which section you're in; only the page knows
|
|
which record is on screen. Rather than have both write
|
|
document.title and race — child effects run before parent
|
|
effects, so the layout would win and the record name would
|
|
never survive — the page publishes a string and the layout is
|
|
the single writer.
|
|
|
|
Null is the normal state. A page that publishes nothing, or one
|
|
still loading, simply leaves the section title showing.
|
|
═══════════════════════════════════════════════════════════════ */
|
|
|
|
import { createContext, useContext, useEffect } from "react";
|
|
|
|
export type AdminTitleValue = { setDetail: (value: string | null) => void };
|
|
|
|
export const AdminTitleContext = createContext<AdminTitleValue | null>(null);
|
|
|
|
/* Publish the name of whatever this page is showing. Clears on
|
|
unmount, so navigating away can't leave a stale record name in
|
|
the tab. */
|
|
export function useAdminDetail(name: string | null | undefined) {
|
|
const setDetail = useContext(AdminTitleContext)?.setDetail;
|
|
|
|
useEffect(() => {
|
|
if (!setDetail) return undefined;
|
|
setDetail(name || null);
|
|
return () => setDetail(null);
|
|
}, [setDetail, name]);
|
|
}
|