a selected page opens the builder, not a highlighted row
The nav already said it: Pages is a section, and the pages are rows under it. Two things, two screens. The detail panel was showing one screen with a row lit up, which made the list the answer to both questions. ?section=pages the list — what exists, what it is called, where it lives, in what order ?section=pages&page=4 that page — what is on it Both addressable, which is why the distinction is a query parameter rather than state. Pressing PAGES itself now clears `page`. Without that the section row and the row for whichever page was last open lead to the same screen and there is no way back to the list but the browser's back button. Scoped exactly like `media`, and for the same reason: a parameter belonging to one section should not ride along into the others. The list stops having a selection — selecting a page leaves the screen entirely — so its rows are plain rows again and the panel no longer reads or writes the URL at all. Adding a page deliberately does NOT open it. The next thing anybody does is name it, and the name lives on the list; jumping into the builder would mean coming straight back. SitePreview is now shared, lifted out of LayoutPanel with the dev-port lookup beside it. Layout passes the theme it is editing; a page passes nothing and just gets its own page. The builder shows the real page at its real address today, which is what the blocks will be judged against when they exist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { ChevronDown, ChevronUp, Loader2, Lock, Plus, Trash2 } from 'lucide-react';
|
||||
import { useSearchParams } from 'react-router';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { useClient } from 'hooks/useClient';
|
||||
@@ -34,8 +33,6 @@ export const PagesPanel = () => {
|
||||
const clientRef = useRef(client);
|
||||
clientRef.current = client;
|
||||
|
||||
const [params, setParams] = useSearchParams();
|
||||
const selected = Number(params.get('page')) || null;
|
||||
|
||||
const [stored, setStored] = useState<Page[] | null>(null);
|
||||
const [draft, setDraft] = useState<Page[]>([]);
|
||||
@@ -120,21 +117,14 @@ export const PagesPanel = () => {
|
||||
const add = () =>
|
||||
act(async () => {
|
||||
const created = await clientRef.current.post<{ data: Page }>('/fofos-admin/pages', { title: 'New page' });
|
||||
// Selected on arrival: a new row at the bottom of a long list is easy to lose, and the next
|
||||
// thing anybody does is rename it.
|
||||
const next = new URLSearchParams(params);
|
||||
next.set('page', String(created.data.id));
|
||||
setParams(next, { replace: true });
|
||||
// Deliberately does NOT open the new page. The next thing anybody does is name it, and the
|
||||
// name lives on this screen — jumping into the builder would mean coming straight back.
|
||||
void created;
|
||||
});
|
||||
|
||||
const remove = (page: Page) =>
|
||||
act(async () => {
|
||||
await clientRef.current.delete(`/fofos-admin/pages/${page.id}`);
|
||||
if (selected === page.id) {
|
||||
const next = new URLSearchParams(params);
|
||||
next.delete('page');
|
||||
setParams(next, { replace: true });
|
||||
}
|
||||
});
|
||||
|
||||
const move = (index: number, by: number) => {
|
||||
@@ -155,17 +145,7 @@ export const PagesPanel = () => {
|
||||
|
||||
<div className="flex flex-col gap-2">
|
||||
{draft.map((page, index) => (
|
||||
<div
|
||||
key={page.id}
|
||||
onPointerDown={() => {
|
||||
const next = new URLSearchParams(params);
|
||||
next.set('page', String(page.id));
|
||||
setParams(next, { replace: true });
|
||||
}}
|
||||
className={`flex flex-col gap-2 rounded-lg border p-3 ${
|
||||
selected === page.id ? 'border-primary' : 'border-border'
|
||||
}`}
|
||||
>
|
||||
<div key={page.id} className="flex flex-col gap-2 rounded-lg border border-border p-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<div className="flex shrink-0 flex-col text-muted-foreground">
|
||||
<button
|
||||
|
||||
Reference in New Issue
Block a user