a place to manage each collection

Collections, above Galleries and Media, where the other things made of media already are.

There is no Create button and no Delete, and that is the design rather than an omission. Which
collections exist is a question about `originals/COLLECTIONS/`, so making one means making a folder —
in Media or in Finder, and both work. A Delete here would either drop the row and leave the
photographs, so the collection reappears on the next read, or delete somebody's pictures. Neither is
what Delete should mean in an admin.

The grid is for choosing the MAIN photo and nothing else. The photographs are already in filename
order and the gallery is the folder, so there is nothing to reorder and nothing to add — the one
decision is which picture leads. Pressing the chosen one again clears it, which is how "no choice, use
the first" stays reachable without a second control that only does that.

The badge says Main rather than Cover because it has to be true of the first photograph, which leads
by default, as well as of one somebody picked.

The fields are the other half — everything a directory cannot tell you: the name it goes by, the
address, and the specs from the client's sitemap. `folder` is shown and not editable, and the API
refuses to write it: it is an address, and renaming one moves files. Shown anyway, because it is the
only thing that says WHICH folder a collection is.

One draft, one save. Per-field writes would be eight requests for somebody filling in a form, and the
last to land would win in an order nobody controls.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-04 14:03:54 +01:00
co-authored by Claude Opus 5
parent dde7de67aa
commit 60eb6ecfc9
5 changed files with 364 additions and 2 deletions
+25 -2
View File
@@ -1,5 +1,5 @@
import type { LucideIcon } from 'lucide-react';
import { Images, Mail, Cog, FolderOpen, PanelsTopLeft, Files } from 'lucide-react';
import { Boxes, Cog, Files, FolderOpen, Images, Mail, PanelsTopLeft } from 'lucide-react';
/**
* The sections of the fofos admin, in nav order.
@@ -36,7 +36,14 @@ import { Images, Mail, Cog, FolderOpen, PanelsTopLeft, Files } from 'lucide-reac
* the nav and what actually renders cannot disagree.
*/
export type SectionKey = 'administration' | 'galleries' | 'media' | 'messages' | 'layout' | 'pages';
export type SectionKey =
| 'administration'
| 'collections'
| 'galleries'
| 'media'
| 'messages'
| 'layout'
| 'pages';
export type Section = {
key: SectionKey;
@@ -125,6 +132,22 @@ export const SECTIONS: Section[] = [
this section is useless without the development server answering, and opening it there would be
a screen where every action fails.
*/
key: 'collections',
label: 'Collections',
icon: Boxes,
hint: 'A folder of photographs, and what is said about it',
path: '/fofos-admin/collections',
built: true,
/*
Same reason as Galleries: a collection is a ROW read through the site's admin API, so this is
useless without the development server answering. What is different is that the row is only half
of it — which collections EXIST is a question about `originals/COLLECTIONS/`, and the folders are
registered as this list is read.
*/
requires: 'connection',
pinned: true,
},
{
key: 'galleries',
label: 'Galleries',
icon: Images,