Layout replaces one section per page

The admin was a section each for Home, About Us, Collections, Gallery, Collabs, Drops and Services,
because the site's pages were a constant in site-map.ts and a developer was the only one who could add
one. A page builder is going to replace that, so the nav stops enumerating pages.

What is left is the two things a page is NOT: Layout — the shell every page renders inside — and Pages,
listed but not built. Layout is first because it is first in the work: building pages before the frame
they sit in means building them twice.

The panel is a sketch of the page with the controls under it. Menu across the top, a body, the footer
at the bottom, in the chosen colours and typefaces — the same principle the header editor already
follows, where the admin renders the structure as the page will show it. It is honest about being a
sketch: drawing the logo and the rules would be a second implementation of the layout, and the two
would drift the first time either changed.

Fonts are a mapping, not free text. styles.css already declares four ROLES — body, sub, title,
display — and every template asks for a role rather than a typeface, so choosing a font is choosing
which of the four faces the build subsets plays each part. The list travels with the payload rather
than being copied here, because a picker offering a face the build never subsets renders as a fallback
nobody chose.

The per-page panels are NOT deleted. AboutPanel, HomePanel and RecordsPanel are still in the tree and
still work; they are unreachable, which is a line in sections.ts rather than a rewrite. The page
builder is not finished, and removing the only way to edit the live site's content before its
replacement exists would leave a gap with nothing in it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-31 01:38:05 +01:00
co-authored by Claude Opus 5
parent 72edabdc8f
commit 09b914c430
3 changed files with 551 additions and 110 deletions
+45 -97
View File
@@ -1,21 +1,30 @@
import type { LucideIcon } from 'lucide-react';
import { Home, Info, Layers, Images, Handshake, Sparkles, Wrench, Settings, Mail, Cog, FolderOpen } from 'lucide-react';
import { Images, Mail, Cog, FolderOpen, PanelsTopLeft, Files } from 'lucide-react';
/**
* The sections of the fofos admin, in nav order.
*
* ── The order is the client's site, not the database's ──
* ── There is no longer one section per page ──
*
* It follows the sitemap: the pages someone edits most, first. Site settings, Messages and
* Administration sit at the bottom because they are not pages — the site's settings, an inbox, and the
* plugin's own machinery.
* There was: Home, About Us, Collections, Gallery, Collabs, Drops, Services — a section each, because
* the site's pages were a constant in `site-map.ts` and a developer was the only one who could add
* one. Every new page meant a new entry here, a new panel, and a new API route.
*
* ── `site` and `administration` are different things ──
* That model is being replaced by a page builder, so the nav stops enumerating pages. What is left is
* the two things a page is not:
*
* "Site settings" is the CLIENT's — partners, social links, contact details, all of it public copy that
* whoever edits the site edits. "Administration" is OFFICER's end: where fofos is, how to reach it, and
* whatever else this plugin needs to know to do its job. One is content, the other is plumbing, and the
* people who touch them are not the same people. Nothing in Administration ever appears on the site.
* Layout the shell every page renders inside — the menu, the footer, the colours, the typefaces
* Pages the pages themselves, built rather than hard-coded
*
* The per-page panels have NOT been deleted. `AboutPanel`, `HomePanel` and `RecordsPanel` are still in
* the tree and still work; they are simply not reachable, which is a line in this file rather than a
* rewrite. That is deliberate — the page builder is not finished, and deleting the only way to edit
* the live site's content before its replacement exists would be a gap with nothing in it.
*
* ── `administration` ──
*
* OFFICER's end: where fofos is, how to reach it, and whatever else this plugin needs to do its job.
* Nothing in it ever appears on the site.
*
* ── `built` ──
*
@@ -27,19 +36,7 @@ import { Home, Info, Layers, Images, Handshake, Sparkles, Wrench, Settings, Mail
* the nav and what actually renders cannot disagree.
*/
export type SectionKey =
| 'administration'
| 'galleries'
| 'media'
| 'messages'
| 'site'
| 'about'
| 'home'
| 'gallery'
| 'drops'
| 'collabs'
| 'collections'
| 'services';
export type SectionKey = 'administration' | 'galleries' | 'media' | 'messages' | 'layout' | 'pages';
export type Section = {
key: SectionKey;
@@ -75,86 +72,37 @@ export type Section = {
export const SECTIONS: Section[] = [
{
key: 'home',
label: 'Home',
icon: Home,
hint: 'The hero, the intro, and the gallery',
path: '/fofos-admin/home',
/*
The shell every page renders inside, and therefore the first thing to decide.
First in the nav because it is first in the work: the menu, the footer, the colours and the
typefaces are the frame every page is built into, and building pages before the frame exists
means building them twice.
*/
key: 'layout',
label: 'Layout',
icon: PanelsTopLeft,
hint: 'The menu, the footer, the colours and the typefaces',
path: '/fofos-admin/layout',
built: true,
requires: 'connection',
},
{
key: 'about',
label: 'About Us',
icon: Info,
hint: 'The header photograph and the copy',
path: '/fofos-admin/about',
built: true,
requires: 'connection',
},
{
key: 'collections',
label: 'Collections',
icon: Layers,
hint: 'Collections, and the items in them',
path: '/fofos-admin/collections',
/*
The pages, built rather than hard-coded. Not started.
This is what replaced the seven per-page sections that used to be here. Listed while unbuilt on
purpose: the nav says what is coming, which is a better answer than a nav that quietly lost seven
entries and offers no account of where they went.
*/
key: 'pages',
label: 'Pages',
icon: Files,
hint: 'Build a page from blocks, and choose where it sits',
path: null,
built: false,
requires: 'connection',
},
{
key: 'gallery',
label: 'Gallery',
icon: Images,
hint: 'Standalone pieces',
path: '/fofos-admin/gallery',
built: true,
requires: 'connection',
},
{
key: 'collabs',
label: 'Collabs',
icon: Handshake,
hint: 'Projects with other people',
path: '/fofos-admin/collabs',
built: true,
requires: 'connection',
},
{
key: 'drops',
label: 'Drops',
icon: Sparkles,
hint: 'Releases',
path: '/fofos-admin/drops',
built: true,
requires: 'connection',
},
{
key: 'services',
label: 'Services',
icon: Wrench,
hint: 'A fixed tree — the words, not the shape',
path: '/fofos-admin/services',
built: false,
requires: 'connection',
},
{
key: 'site',
label: 'Site settings',
icon: Settings,
hint: 'Partners, social links, contact details',
path: '/fofos-admin/site',
built: false,
requires: 'connection',
},
{
key: 'messages',
label: 'Messages',
icon: Mail,
hint: 'What people sent through the contact form',
path: '/fofos-admin/messages',
built: true,
requires: 'connection',
},
{
/*
Galleries — an entity of their own, not a list hanging off a page.
@@ -223,7 +171,7 @@ export const SECTIONS: Section[] = [
];
/** Where the detail panel goes when the URL says nothing, or says something it does not recognise. */
export const DEFAULT_SECTION: SectionKey = 'messages';
export const DEFAULT_SECTION: SectionKey = 'layout';
export const isSectionKey = (value: string | null): value is SectionKey =>
SECTIONS.some((section) => section.key === value);