@extends('layouts.dashboard') @section('content') @php /** * Full-page content-page editor (create + edit). Replaces the old modal, and is deliberately the * same screen as the blog editor: same top bar, same 8/4 split, same Publish card on the right โ€” * two editors in one admin should not be two different shapes. * * The modal drove its FAQ / legal guidance and its core-page draft lock from JavaScript, because a * single dialog had to re-dress itself for whichever row was clicked. A page knows its own slug * before it renders, so both are decided here in PHP and the script is gone. * * @var array|null $page existing page when editing, null when creating * @var array $seo search-result settings ['title','description','image','noindex'] * @var array $coreSlugs footer-linked slugs that must stay published */ $isEdit = $page !== null; $seo = $seo ?? ['title' => '', 'description' => '', 'image' => '', 'noindex' => false]; $slug = strtolower((string) ($page['slug'] ?? '')); $status = (string) ($page['status'] ?? 'published'); // Core pages are linked in the footer and the server force-publishes them, so the option is // disabled rather than offered and then silently overruled. $isCore = in_array($slug, $coreSlugs, true); // A legal page's table of contents is built from its heading structure, so that markup contract is // stated on the page that has it and nowhere else. $isLegal = in_array($slug, ['privacy', 'terms', 'cookies', 'refund', 'refund-policy', 'cookie-policy'], true); @endphp @php /* .qm-d2: the dashboard density standard (app.css ยง35) */ @endphp
{{ t_raw('admin.pages.back_link') }} @if ($isEdit && $status === 'published' && $slug !== '') {{ t_raw('admin.pages.view_live') }} @endif
@csrf
{{ t_raw('admin.pages.body_help') }} @if ($isLegal)

{{ t_raw('admin.pages.structured_heading') }}

{{ t_raw('admin.pages.legal_help_label') }} {{ t_raw('admin.pages.legal_help_text') }}

@endif

{{ t_raw('admin.pages.publish_heading') }}

@if ($isCore)

{{ t_raw('admin.pages.core_status_note') }}

@endif
@if ($isEdit)
@php // Read-only, and carries no name so it cannot post: the slug is the public // URL and the key the four core pages are recognised by. Shown because an // editor needs to know which page they are on; generated from the title on // first save rather than typed. @endphp
@endif
@php // Search-result appearance. Publishing metadata, so it sits in the rail beside the // status rather than under the body: it is edited once and then rarely, while the // body is the whole job. Nothing here is required โ€” left empty, the page's own // title and the site default are used. The description is the page's own // meta_description column rather than a second SEO field, because storing it twice // would let the two disagree. @endphp

{{ t_raw('admin.seo.page_section') }}

@php // The shared media field: browse the library, upload or crop โ€” never a typed // path. Seo::shareImage() resolves anything under assets/, and the library // writes to assets/uploads/, so a picked image works as an og:image. @endphp {!! media_field_html('seo_image', $seo['image'], ['accept' => 'image', 'allowClear' => true, 'id' => 'page-seo-image']) !!}

{{ t_raw('admin.seo.hint_noindex') }}

{{ t_raw('common.cancel') }}
@php /* /.qm-d2 */ @endphp @endsection