Publish menus from the browser instead of scp
The admin signs in with the shared password, creates a Menu Set, drops photos into it (shrunk in the browser first), reorders Pages by dragging or with up/down buttons, previews the Draft exactly as customers would see it, and publishes it over the previous set. Restore and delete close the loop. Mutations need a session, a same-origin request and a CSRF token derived from the session; a Draft's media is served only to a session holder.
This commit is contained in:
1 parent
9cb4021229
commit
58ecfa0dc3
14 files changed
+1824
-15
No files matched your search
+19
-5
@@ -153,7 +153,8 @@ export function renderLanding(input: LandingInput): Html {
|
||||
bodyClass: 'landing-page',
|
||||
description: config.brand.tagline,
|
||||
noindex: false,
|
||||
script: false,
|
||||
styles: [],
|
||||
scripts: [],
|
||||
body: html`<main class="landing">
|
||||
<header class="masthead">
|
||||
<h1 class="wordmark">${config.brand.name}</h1>
|
||||
@@ -174,6 +175,8 @@ export interface SectionInput {
|
||||
published: ReadonlySet<string>;
|
||||
current: boolean;
|
||||
archives: readonly StoredSet[];
|
||||
/** Draft preview for the admin: adds a banner and skips the archive fold. */
|
||||
preview: boolean;
|
||||
}
|
||||
|
||||
export function renderSectionPage(input: SectionInput): Html {
|
||||
@@ -186,14 +189,23 @@ export function renderSectionPage(input: SectionInput): Html {
|
||||
${renderRail(config, section.slug, input.published)}
|
||||
<div class="pour" aria-hidden="true"><span class="pour__fill" data-pour></span></div>
|
||||
</header>
|
||||
${input.preview
|
||||
? html`<p class="notice notice--admin">
|
||||
Preview of a Draft — customers cannot see this yet.
|
||||
<a href="/admin/sets/${set.id}">Back to the editor</a>
|
||||
</p>`
|
||||
: ''}
|
||||
<h2 class="section-heading">
|
||||
<span class="section-heading__label">${set.manifest.label}</span>
|
||||
<span class="section-heading__date">${setDateLabel(set.manifest)}</span>
|
||||
</h2>
|
||||
${input.current ? '' : html`<p class="notice">This is an older menu. <a href="${currentHref}">See the current menu</a>.</p>`}
|
||||
${input.current || input.preview
|
||||
? ''
|
||||
: html`<p class="notice">This is an older menu. <a href="${currentHref}">See the current menu</a>.</p>`}
|
||||
${renderPages(section, set.manifest.pages)}
|
||||
<footer class="foot">
|
||||
${renderPageIndex(total)} ${renderOlderMenus(section, input.archives, currentHref)}
|
||||
${renderPageIndex(total)}
|
||||
${input.preview ? '' : renderOlderMenus(section, input.archives, currentHref)}
|
||||
</footer>
|
||||
<button class="counter" type="button" data-counter hidden>
|
||||
<span data-counter-current>1</span><span class="counter__total">/ ${total}</span>
|
||||
@@ -205,7 +217,8 @@ export function renderSectionPage(input: SectionInput): Html {
|
||||
bodyClass: 'section-page',
|
||||
description: config.brand.tagline,
|
||||
noindex: !input.current,
|
||||
script: true,
|
||||
styles: [],
|
||||
scripts: ['/assets/app.js'],
|
||||
body,
|
||||
});
|
||||
}
|
||||
@@ -228,7 +241,8 @@ export function renderNotFound(config: SiteConfig, live: readonly SectionConfig[
|
||||
bodyClass: 'landing-page',
|
||||
description: null,
|
||||
noindex: true,
|
||||
script: false,
|
||||
styles: [],
|
||||
scripts: [],
|
||||
body: html`<main class="landing">
|
||||
<header class="masthead">
|
||||
<h1 class="wordmark">${config.brand.name}</h1>
|
||||
|
||||
Reference in new issue
Block a user