@canvas-digital/blog-sdk 2.0.2 → 2.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/blog-client.iife.js +1 -1
  2. package/dist/components/admin/AdminPostDetail.js +5 -5
  3. package/dist/components/admin/BrandSettings.js +5 -5
  4. package/dist/components/admin/BrandSwitcher.js +1 -1
  5. package/dist/components/admin/Chips.js +5 -5
  6. package/dist/components/admin/CommentsManager.js +6 -6
  7. package/dist/components/admin/Dashboard.js +1 -1
  8. package/dist/components/admin/MediaLibrary.js +5 -5
  9. package/dist/components/admin/MediaPicker.js +4 -4
  10. package/dist/components/admin/PostList.d.ts.map +1 -1
  11. package/dist/components/admin/PostList.js +13 -4
  12. package/dist/components/admin/PostsTable.d.ts +6 -1
  13. package/dist/components/admin/PostsTable.d.ts.map +1 -1
  14. package/dist/components/admin/PostsTable.js +15 -9
  15. package/dist/components/admin/Shell.js +3 -3
  16. package/dist/components/admin/TermManager.js +4 -4
  17. package/dist/components/admin/UsersManager.js +3 -3
  18. package/dist/components/admin/charts.js +7 -7
  19. package/dist/components/admin/editor/PostEditor.js +16 -16
  20. package/dist/components/admin/editor/RichTextEditor.js +8 -8
  21. package/dist/components/admin/editor/YoastCollapsible.js +2 -2
  22. package/dist/components/admin/editor/YoastInsightsPanel.js +1 -1
  23. package/dist/components/admin/editor/YoastInternalLinksPanel.js +1 -1
  24. package/dist/components/admin/editor/YoastSeoAnalysisPanel.js +6 -6
  25. package/dist/components/admin/editor/YoastSeoMetabox.js +8 -8
  26. package/dist/components/admin/editor/YoastSnippetField.js +2 -2
  27. package/dist/components/admin/internal/States.js +3 -3
  28. package/dist/components/admin/mock/store.d.ts.map +1 -1
  29. package/dist/components/admin/mock/store.js +3 -2
  30. package/dist/components/admin/seo/Ga4Settings.js +6 -6
  31. package/dist/components/admin/seo/RedirectAnalyticsDashboard.js +1 -1
  32. package/dist/components/admin/seo/RedirectDetail.js +6 -6
  33. package/dist/components/admin/seo/RedirectForm.js +1 -1
  34. package/dist/components/admin/seo/RedirectList.js +4 -4
  35. package/dist/components/admin/seo/RobotsEditor.js +1 -1
  36. package/dist/components/admin/seo/shared.js +2 -2
  37. package/dist/components/admin/tools/ToolsHub.js +4 -4
  38. package/dist/components/user/BlogCard.js +3 -3
  39. package/dist/components/user/BlogCategories.js +1 -1
  40. package/dist/components/user/BlogDetail.js +1 -1
  41. package/dist/components/user/BlogList.js +1 -1
  42. package/dist/components/user/BlogSearch.js +2 -2
  43. package/dist/components/user/BlogTags.js +1 -1
  44. package/dist/components/user/FeaturedBlogs.js +1 -1
  45. package/dist/components/user/RelatedBlogs.js +1 -1
  46. package/dist/components/user/SiteMediaHero.js +1 -1
  47. package/dist/components/user/detail/ArticleDetailHero.js +5 -5
  48. package/dist/components/user/detail/ArticleRailDetails.js +2 -2
  49. package/dist/components/user/detail/CommentSection.js +2 -2
  50. package/dist/components/user/detail/HeroFadeSlide.js +1 -1
  51. package/dist/components/user/detail/ReadingProgress.js +1 -1
  52. package/dist/components/user/detail/ShareRow.js +1 -1
  53. package/dist/components/user/internal/States.js +4 -4
  54. package/dist/lib/lexical-doc.js +1 -1
  55. package/dist/pages/admin/BlogAdmin.d.ts.map +1 -1
  56. package/dist/pages/admin/BlogAdmin.js +23 -11
  57. package/dist/services/admin-sdk-client.d.ts +9 -0
  58. package/dist/services/admin-sdk-client.d.ts.map +1 -1
  59. package/dist/services/admin-sdk-client.js +17 -0
  60. package/dist/style.css +1023 -1016
  61. package/package.json +2 -1
@@ -14,17 +14,17 @@ const toLocalInput = (iso) => {
14
14
  };
15
15
  const StateChip = ({ row }) => {
16
16
  if (row.trashed)
17
- return _jsx("span", { className: "chip chip-blocked", children: "Trashed" });
17
+ return _jsx("span", { className: "blog_chip blog_chip-blocked", children: "Trashed" });
18
18
  if (row.status === "published")
19
- return _jsx("span", { className: "chip chip-live", children: "Live" });
19
+ return _jsx("span", { className: "blog_chip blog_chip-live", children: "Live" });
20
20
  if (row.scheduledFor && row.status === "draft") {
21
- return _jsx("span", { className: "chip chip-approved", children: "Scheduled" });
21
+ return _jsx("span", { className: "blog_chip blog_chip-approved", children: "Scheduled" });
22
22
  }
23
23
  const rs = row.reviewState;
24
- const cls = rs === "in-review" ? "chip-review" : rs === "approved" ? "chip-approved" : "chip-writing";
25
- return _jsx("span", { className: `chip ${cls}`, children: REVIEW_LABELS[rs] ?? "Draft" });
24
+ const cls = rs === "in-review" ? "blog_chip-review" : rs === "approved" ? "blog_chip-approved" : "blog_chip-writing";
25
+ return _jsx("span", { className: `blog_chip ${cls}`, children: REVIEW_LABELS[rs] ?? "Draft" });
26
26
  };
27
- export const PostsTable = ({ rows, categories, state, showBrand, onEdit, onView }) => {
27
+ export const PostsTable = ({ rows, minRows = 0, totalCount, page, pageSize, categories, state, showBrand, onEdit, onView, }) => {
28
28
  const store = useAdminMock();
29
29
  const [pending, start] = useTransition();
30
30
  const [selected, setSelected] = useState([]);
@@ -86,7 +86,11 @@ export const PostsTable = ({ rows, categories, state, showBrand, onEdit, onView
86
86
  }
87
87
  run(() => store.bulkPostAction(selected, bulk), `${selected.length} post(s) updated.`);
88
88
  };
89
- return (_jsxs("div", { className: "list", children: [_jsxs("div", { className: "list-bar", children: [_jsxs("div", { className: "bulk", children: [_jsxs("select", { className: "fld fld-sm", value: bulk, onChange: (e) => setBulk(e.target.value), "aria-label": "Bulk action", children: [_jsx("option", { value: "", children: "Bulk actions\u2026" }), isTrash ? (_jsxs(_Fragment, { children: [_jsx("option", { value: "restore", children: "Restore" }), _jsx("option", { value: "delete", children: "Delete permanently" })] })) : (_jsxs(_Fragment, { children: [_jsx("option", { value: "submit", children: "Submit for review" }), _jsx("option", { value: "approve", children: "Approve" }), _jsx("option", { value: "send-back", children: "Send back to writing" }), _jsx("option", { value: "publish", children: "Publish" }), _jsx("option", { value: "draft", children: "Switch to draft" }), _jsx("option", { value: "trash", children: "Move to trash" })] }))] }), _jsx("button", { type: "button", className: "btn", disabled: !bulk || !selected.length || pending, onClick: applyBulk, children: "Apply" }), _jsx("span", { className: "note", children: selected.length ? `${selected.length} selected` : `${rows.length} shown` })] }), pending ? _jsx("span", { className: "note", children: "Working\u2026" }) : null] }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl tbl-list", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "col-check", children: _jsx("input", { type: "checkbox", checked: allChecked, "aria-label": "Select all posts", onChange: (e) => setSelected(e.target.checked ? rows.map((r) => r.id) : []) }) }), _jsx("th", { children: "Title" }), showBrand ? _jsx("th", { className: "col-narrow", children: "Brand" }) : null, _jsx("th", { className: "col-narrow", children: "Byline" }), _jsx("th", { className: "col-narrow", children: "Category" }), _jsx("th", { className: "col-narrow", children: "Date" }), _jsx("th", { className: "col-narrow num", children: "Views 30d" }), _jsx("th", { className: "col-narrow", children: "Status" })] }) }), _jsxs("tbody", { children: [rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: showBrand ? 8 : 7, children: _jsx("p", { className: "d-empty", children: "No posts match this view." }) }) })) : null, rows.map((row) => (_jsxs(Fragment, { children: [_jsxs("tr", { className: selected.includes(row.id) ? "is-selected" : undefined, children: [_jsx("td", { className: "col-check", children: _jsx("input", { type: "checkbox", checked: selected.includes(row.id), "aria-label": `Select ${row.title}`, onChange: (e) => setSelected((list) => e.target.checked ? [...list, row.id] : list.filter((id) => id !== row.id)) }) }), _jsxs("td", { className: "col-title", children: [_jsx("button", { type: "button", className: "row-title", onClick: () => onEdit(row.id), children: row.title || "(no title)" }), row.blockers.length && row.status !== "published" && !row.trashed ? (_jsx("ul", { className: "blockers", children: row.blockers.map((b) => (_jsxs("li", { children: ["needs ", b] }, b))) })) : null, _jsx("div", { className: "row-actions", children: isTrash ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => run(() => store.bulkPostAction([row.id], "restore"), "Restored."), children: "Restore" }), _jsx("button", { type: "button", className: "danger", onClick: () => {
89
+ return (_jsxs("div", { className: "blog_list", children: [_jsxs("div", { className: "blog_list-bar", children: [_jsxs("div", { className: "blog_bulk", children: [_jsxs("select", { className: "blog_fld blog_fld-sm", value: bulk, onChange: (e) => setBulk(e.target.value), "aria-label": "Bulk action", children: [_jsx("option", { value: "", children: "Bulk actions\u2026" }), isTrash ? (_jsxs(_Fragment, { children: [_jsx("option", { value: "restore", children: "Restore" }), _jsx("option", { value: "delete", children: "Delete permanently" })] })) : (_jsxs(_Fragment, { children: [_jsx("option", { value: "submit", children: "Submit for review" }), _jsx("option", { value: "approve", children: "Approve" }), _jsx("option", { value: "send-back", children: "Send back to writing" }), _jsx("option", { value: "publish", children: "Publish" }), _jsx("option", { value: "draft", children: "Switch to draft" }), _jsx("option", { value: "trash", children: "Move to trash" })] }))] }), _jsx("button", { type: "button", className: "blog_btn", disabled: !bulk || !selected.length || pending, onClick: applyBulk, children: "Apply" }), _jsx("span", { className: "blog_note", children: selected.length
90
+ ? `${selected.length} selected`
91
+ : totalCount != null && page != null && pageSize != null
92
+ ? `${rows.length} on this page · ${totalCount} total`
93
+ : `${rows.length} shown` })] }), pending ? _jsx("span", { className: "blog_note", children: "Working\u2026" }) : null] }), error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "blog_form-ok", role: "status", children: flash })) : null, _jsx("div", { className: "blog_tw", children: _jsxs("table", { className: "blog_tbl blog_tbl-list", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { className: "blog_col-check", children: _jsx("input", { type: "checkbox", checked: allChecked, "aria-label": "Select all posts", onChange: (e) => setSelected(e.target.checked ? rows.map((r) => r.id) : []) }) }), _jsx("th", { children: "Title" }), showBrand ? _jsx("th", { className: "blog_col-narrow", children: "Brand" }) : null, _jsx("th", { className: "blog_col-narrow", children: "Byline" }), _jsx("th", { className: "blog_col-narrow", children: "Category" }), _jsx("th", { className: "blog_col-narrow", children: "Date" }), _jsx("th", { className: "blog_col-narrow blog_num", children: "Views 30d" }), _jsx("th", { className: "blog_col-narrow", children: "Status" })] }) }), _jsxs("tbody", { children: [rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: showBrand ? 8 : 7, children: _jsx("p", { className: "blog_d-empty", children: "No posts match this view." }) }) })) : null, rows.map((row) => (_jsxs(Fragment, { children: [_jsxs("tr", { className: selected.includes(row.id) ? "blog_is-selected" : undefined, children: [_jsx("td", { className: "blog_col-check", children: _jsx("input", { type: "checkbox", checked: selected.includes(row.id), "aria-label": `Select ${row.title}`, onChange: (e) => setSelected((list) => e.target.checked ? [...list, row.id] : list.filter((id) => id !== row.id)) }) }), _jsxs("td", { className: "blog_col-title", children: [_jsx("button", { type: "button", className: "blog_row-title", onClick: () => onEdit(row.id), children: row.title || "(no title)" }), row.blockers.length && row.status !== "published" && !row.trashed ? (_jsx("ul", { className: "blog_blockers", children: row.blockers.map((b) => (_jsxs("li", { children: ["needs ", b] }, b))) })) : null, _jsx("div", { className: "blog_row-actions", children: isTrash ? (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: () => run(() => store.bulkPostAction([row.id], "restore"), "Restored."), children: "Restore" }), _jsx("button", { type: "button", className: "blog_danger", onClick: () => {
90
94
  if (window.confirm("Delete this post permanently? This cannot be undone.")) {
91
95
  run(() => store.bulkPostAction([row.id], "delete"), "Deleted.");
92
96
  }
@@ -94,7 +98,7 @@ export const PostsTable = ({ rows, categories, state, showBrand, onEdit, onView
94
98
  setScheduling(row.id);
95
99
  setWhen(toLocalInput(row.scheduledFor) ||
96
100
  toLocalInput(new Date(Date.now() + 3600000).toISOString()));
97
- }, children: "Schedule" })] })) : null, row.status === "published" && row.canPublish ? (_jsx("button", { type: "button", onClick: () => run(() => store.unpublish(row.id), "Switched to draft."), children: "Unpublish" })) : null, _jsx("button", { type: "button", onClick: () => run(() => store.duplicatePost(row.id), "Copied as a new draft."), children: "Duplicate" }), _jsx("button", { type: "button", className: "danger", onClick: () => run(() => store.bulkPostAction([row.id], "trash"), "Moved to trash."), children: "Trash" }), row.status === "published" && onView ? (_jsx("button", { type: "button", onClick: () => onView(row.id), children: "View" })) : null] })) }), scheduling === row.id ? (_jsxs("div", { className: "inline-form", children: [_jsx("input", { type: "datetime-local", className: "fld fld-sm", value: when, onChange: (e) => setWhen(e.target.value), "aria-label": "Publish date and time" }), _jsx("button", { type: "button", className: "btn btn-primary btn-tiny", onClick: () => run(() => store.schedulePost(row.id, new Date(when).toISOString()), "Scheduled."), children: "Confirm" }), _jsx("button", { type: "button", className: "btn btn-tiny", onClick: () => setScheduling(null), children: "Cancel" })] })) : null] }), showBrand ? _jsx("td", { className: "col-narrow muted", children: row.brandName ?? "—" }) : null, _jsx("td", { className: "col-narrow muted", children: row.authorNames.join(", ") || "—" }), _jsx("td", { className: "col-narrow muted", children: row.categoryNames.join(", ") || "—" }), _jsx("td", { className: "col-narrow muted", children: row.status === "published" ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "cell-lbl", children: "Published" }), fmtDate(row.publishedAt)] })) : row.scheduledFor ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "cell-lbl", children: "Scheduled" }), fmtDateTime(row.scheduledFor)] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "cell-lbl", children: "Edited" }), fmtDate(row.updatedAt)] })) }), _jsx("td", { className: "col-narrow num", children: row.views == null ? "—" : row.views }), _jsx("td", { className: "col-narrow", children: _jsx(StateChip, { row: row }) })] }), editing === row.id && editRow ? (_jsx("tr", { className: "quick-row", children: _jsx("td", { colSpan: showBrand ? 8 : 7, children: _jsxs("div", { className: "quick", children: [_jsx("p", { className: "quick-head", children: "Quick edit \u2014 metadata only, the body stays untouched" }), _jsxs("div", { className: "quick-grid", children: [_jsxs("label", { children: [_jsx("span", { children: "Title" }), _jsx("input", { className: "fld", value: draft.title, onChange: (e) => setDraft((d) => ({ ...d, title: e.target.value })) })] }), _jsxs("label", { children: [_jsx("span", { children: "Slug" }), _jsx("input", { className: "fld mono", value: draft.slug, onChange: (e) => setDraft((d) => ({ ...d, slug: e.target.value })) })] }), _jsxs("div", { className: "span-2", children: [_jsx("span", { className: "fld-lbl", style: { display: "block", marginBottom: 6 }, children: "Categories" }), _jsx("div", { className: "pick-list pick-list-compact", children: categories.length === 0 ? (_jsx("p", { className: "note", children: "No categories." })) : (categories.map((c) => (_jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: draft.category.includes(c.id), onChange: () => toggleDraftCategory(c.id) }), c.name] }, c.id)))) })] }), _jsxs("label", { children: [_jsx("span", { children: "Published date" }), _jsx("input", { type: "datetime-local", className: "fld", value: draft.date, onChange: (e) => setDraft((d) => ({ ...d, date: e.target.value })) })] }), _jsxs("label", { children: [_jsx("span", { children: "Status" }), _jsxs("select", { className: "fld", value: draft.status, disabled: !row.canPublish, onChange: (e) => setDraft((d) => ({ ...d, status: e.target.value })), children: [_jsx("option", { value: "draft", children: "Draft" }), _jsx("option", { value: "published", children: "Published" })] })] })] }), _jsxs("div", { className: "btn-row", children: [_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: () => run(() => store.quickEditPost({
101
+ }, children: "Schedule" })] })) : null, row.status === "published" && row.canPublish ? (_jsx("button", { type: "button", onClick: () => run(() => store.unpublish(row.id), "Switched to draft."), children: "Unpublish" })) : null, _jsx("button", { type: "button", onClick: () => run(() => store.duplicatePost(row.id), "Copied as a new draft."), children: "Duplicate" }), _jsx("button", { type: "button", className: "blog_danger", onClick: () => run(() => store.bulkPostAction([row.id], "trash"), "Moved to trash."), children: "Trash" }), row.status === "published" && onView ? (_jsx("button", { type: "button", onClick: () => onView(row.id), children: "View" })) : null] })) }), scheduling === row.id ? (_jsxs("div", { className: "blog_inline-form", children: [_jsx("input", { type: "datetime-local", className: "blog_fld blog_fld-sm", value: when, onChange: (e) => setWhen(e.target.value), "aria-label": "Publish date and time" }), _jsx("button", { type: "button", className: "blog_btn blog_btn-primary blog_btn-tiny", onClick: () => run(() => store.schedulePost(row.id, new Date(when).toISOString()), "Scheduled."), children: "Confirm" }), _jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: () => setScheduling(null), children: "Cancel" })] })) : null] }), showBrand ? _jsx("td", { className: "blog_col-narrow blog_muted", children: row.brandName ?? "—" }) : null, _jsx("td", { className: "blog_col-narrow blog_muted", children: row.authorNames.join(", ") || "—" }), _jsx("td", { className: "blog_col-narrow blog_muted", children: row.categoryNames.join(", ") || "—" }), _jsx("td", { className: "blog_col-narrow blog_muted", children: row.status === "published" ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "blog_cell-lbl", children: "Published" }), fmtDate(row.publishedAt)] })) : row.scheduledFor ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "blog_cell-lbl", children: "Scheduled" }), fmtDateTime(row.scheduledFor)] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "blog_cell-lbl", children: "Edited" }), fmtDate(row.updatedAt)] })) }), _jsx("td", { className: "blog_col-narrow blog_num", children: row.views == null ? "—" : row.views }), _jsx("td", { className: "blog_col-narrow", children: _jsx(StateChip, { row: row }) })] }), editing === row.id && editRow ? (_jsx("tr", { className: "blog_quick-row", children: _jsx("td", { colSpan: showBrand ? 8 : 7, children: _jsxs("div", { className: "blog_quick", children: [_jsx("p", { className: "blog_quick-head", children: "Quick edit \u2014 metadata only, the body stays untouched" }), _jsxs("div", { className: "blog_quick-grid", children: [_jsxs("label", { children: [_jsx("span", { children: "Title" }), _jsx("input", { className: "blog_fld", value: draft.title, onChange: (e) => setDraft((d) => ({ ...d, title: e.target.value })) })] }), _jsxs("label", { children: [_jsx("span", { children: "Slug" }), _jsx("input", { className: "blog_fld blog_mono", value: draft.slug, onChange: (e) => setDraft((d) => ({ ...d, slug: e.target.value })) })] }), _jsxs("div", { className: "blog_span-2", children: [_jsx("span", { className: "blog_fld-lbl", style: { display: "block", marginBottom: 6 }, children: "Categories" }), _jsx("div", { className: "blog_pick-list blog_pick-list-compact", children: categories.length === 0 ? (_jsx("p", { className: "blog_note", children: "No categories." })) : (categories.map((c) => (_jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: draft.category.includes(c.id), onChange: () => toggleDraftCategory(c.id) }), c.name] }, c.id)))) })] }), _jsxs("label", { children: [_jsx("span", { children: "Published date" }), _jsx("input", { type: "datetime-local", className: "blog_fld", value: draft.date, onChange: (e) => setDraft((d) => ({ ...d, date: e.target.value })) })] }), _jsxs("label", { children: [_jsx("span", { children: "Status" }), _jsxs("select", { className: "blog_fld", value: draft.status, disabled: !row.canPublish, onChange: (e) => setDraft((d) => ({ ...d, status: e.target.value })), children: [_jsx("option", { value: "draft", children: "Draft" }), _jsx("option", { value: "published", children: "Published" })] })] })] }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: () => run(() => store.quickEditPost({
98
102
  id: row.id,
99
103
  title: draft.title,
100
104
  slug: draft.slug,
@@ -102,5 +106,7 @@ export const PostsTable = ({ rows, categories, state, showBrand, onEdit, onView
102
106
  publishedAt: draft.date ? new Date(draft.date).toISOString() : null,
103
107
  scheduledFor: row.scheduledFor,
104
108
  status: draft.status,
105
- }), "Saved."), children: "Save" }), _jsx("button", { type: "button", className: "btn", onClick: () => setEditing(null), children: "Cancel" }), _jsx("span", { className: "note", children: "Changing the slug of a live post writes a 301 from the old URL automatically." })] })] }) }) })) : null] }, row.id)))] })] }) })] }));
109
+ }), "Saved."), children: "Save" }), _jsx("button", { type: "button", className: "blog_btn", onClick: () => setEditing(null), children: "Cancel" }), _jsx("span", { className: "blog_note", children: "Changing the slug of a live post writes a 301 from the old URL automatically." })] })] }) }) })) : null] }, row.id))), minRows > 0 && rows.length > 0 && rows.length < minRows
110
+ ? Array.from({ length: minRows - rows.length }).map((_, i) => (_jsx("tr", { className: "blog_tbl-row-pad", "aria-hidden": "true", children: _jsx("td", { colSpan: showBrand ? 8 : 7 }) }, `pad-${i}`)))
111
+ : null] })] }) })] }));
106
112
  };
@@ -92,8 +92,8 @@ const NAV = [
92
92
  },
93
93
  ];
94
94
  export const Shell = ({ children, active, onNavigate, title, subtitle, actions, wide, branding, className, userName = "Platform Admin", userRole = "Platform admin", onProfile, }) => {
95
- return (_jsxs("div", { className: cx("shell", className), children: [_jsxs("aside", { className: "side", children: [_jsxs("div", { className: "side-brand", children: [_jsx("div", { className: "side-mark", "aria-hidden": "true", style: branding?.logo ? { background: 'transparent', padding: 0 } : undefined, children: branding?.logo ? _jsx("img", { src: branding.logo, alt: branding.name ?? "Brand", style: { height: 24 } }) : (branding?.name || "B")[0] }), _jsxs("div", { children: [_jsx("div", { className: "side-name", children: branding?.name || "Blog Portal" }), _jsx("div", { className: "side-role", children: branding?.subtitle || "2 brands" })] })] }), _jsxs("button", { type: "button", className: "side-new", onClick: () => onNavigate("posts-new"), children: [_jsx("span", { "aria-hidden": "true", children: "\uFF0B" }), "New post"] }), _jsxs("div", { className: "side-scroll", children: [NAV.map((section, idx) => (_jsxs("div", { className: "side-group", children: [_jsx("p", { className: "side-sect", children: section.title }), _jsx("nav", { className: "side-nav", children: section.items.map((item) => {
95
+ return (_jsxs("div", { className: cx("blog_shell", className), children: [_jsxs("aside", { className: "blog_side", children: [_jsxs("div", { className: "blog_side-brand", children: [_jsx("div", { className: "blog_side-mark", "aria-hidden": "true", style: branding?.logo ? { background: 'transparent', padding: 0 } : undefined, children: branding?.logo ? _jsx("img", { src: branding.logo, alt: branding.name ?? "Brand", style: { height: 24 } }) : (branding?.name || "B")[0] }), _jsxs("div", { children: [_jsx("div", { className: "blog_side-name", children: branding?.name || "Blog Portal" }), _jsx("div", { className: "blog_side-role", children: branding?.subtitle || "2 brands" })] })] }), _jsxs("button", { type: "button", className: "blog_side-new", onClick: () => onNavigate("posts-new"), children: [_jsx("span", { "aria-hidden": "true", children: "\uFF0B" }), "New post"] }), _jsxs("div", { className: "blog_side-scroll", children: [NAV.map((section, idx) => (_jsxs("div", { className: "blog_side-group", children: [_jsx("p", { className: "blog_side-sect", children: section.title }), _jsx("nav", { className: "blog_side-nav", children: section.items.map((item) => {
96
96
  const isActive = active === item.key || item.children?.some(c => c.key === active);
97
- return (_jsxs("div", { children: [_jsxs("button", { type: "button", onClick: () => onNavigate(item.key), "aria-current": isActive ? "page" : undefined, children: [item.icon && _jsx(Icon, { path: ICONS[item.icon] }), item.label] }), item.children && isActive && (_jsx("div", { className: "side-sub", children: item.children.map((child) => (_jsx("button", { type: "button", onClick: () => onNavigate(child.key), "aria-current": active === child.key ? "page" : undefined, style: { cursor: "pointer", width: "100%", textAlign: "left", background: "none", border: "none", padding: "4px 8px", color: active === child.key ? "var(--d-surface)" : "var(--d-side-ink-2)" }, children: child.label }, child.key))) }))] }, item.key));
98
- }) })] }, idx))), _jsx("div", { className: "side-group", children: _jsx("nav", { className: "side-nav", children: _jsx("button", { type: "button", children: "Log out" }) }) })] }), _jsx("div", { className: "side-foot", children: _jsxs("button", { type: "button", className: "side-user-card", style: { width: "100%", background: "none", border: "none", textAlign: "left", cursor: "pointer" }, onClick: () => (onProfile ? onProfile() : onNavigate("profile")), children: [_jsx("div", { className: "side-user-avatar-fallback side-user-avatar", children: (userName || "P").slice(0, 1).toUpperCase() }), _jsxs("div", { className: "side-user-meta", children: [_jsx("div", { className: "side-user-name", style: { color: "#fff" }, children: userName }), _jsx("div", { className: "side-user-role", children: userRole })] })] }) })] }), _jsxs("main", { className: "main", children: [_jsxs("header", { className: "top", children: [_jsxs("div", { className: "top-title", children: [_jsx("h1", { children: title }), subtitle ? _jsx("p", { className: "sub", children: subtitle }) : null] }), _jsx("div", { className: "top-actions", children: actions })] }), _jsx("div", { className: wide ? 'body body-wide' : 'body', children: children })] })] }));
97
+ return (_jsxs("div", { children: [_jsxs("button", { type: "button", onClick: () => onNavigate(item.key), "aria-current": isActive ? "page" : undefined, children: [item.icon && _jsx(Icon, { path: ICONS[item.icon] }), item.label] }), item.children && isActive && (_jsx("div", { className: "blog_side-sub", children: item.children.map((child) => (_jsx("button", { type: "button", onClick: () => onNavigate(child.key), "aria-current": active === child.key ? "page" : undefined, style: { cursor: "pointer", width: "100%", textAlign: "left", background: "none", border: "none", padding: "4px 8px", color: active === child.key ? "var(--d-surface)" : "var(--d-side-ink-2)" }, children: child.label }, child.key))) }))] }, item.key));
98
+ }) })] }, idx))), _jsx("div", { className: "blog_side-group", children: _jsx("nav", { className: "blog_side-nav", children: _jsx("button", { type: "button", children: "Log out" }) }) })] }), _jsx("div", { className: "blog_side-foot", children: _jsxs("button", { type: "button", className: "blog_side-user-card", style: { width: "100%", background: "none", border: "none", textAlign: "left", cursor: "pointer" }, onClick: () => (onProfile ? onProfile() : onNavigate("profile")), children: [_jsx("div", { className: "blog_side-user-avatar-fallback blog_side-user-avatar", children: (userName || "P").slice(0, 1).toUpperCase() }), _jsxs("div", { className: "blog_side-user-meta", children: [_jsx("div", { className: "blog_side-user-name", style: { color: "#fff" }, children: userName }), _jsx("div", { className: "blog_side-user-role", children: userRole })] })] }) })] }), _jsxs("main", { className: "blog_main", children: [_jsxs("header", { className: "blog_top", children: [_jsxs("div", { className: "blog_top-title", children: [_jsx("h1", { children: title }), subtitle ? _jsx("p", { className: "blog_sub", children: subtitle }) : null] }), _jsx("div", { className: "blog_top-actions", children: actions })] }), _jsx("div", { className: wide ? 'blog_body blog_body-wide' : 'blog_body', children: children })] })] }));
99
99
  };
@@ -74,12 +74,12 @@ export function TermManager({ collection, onOpenPosts, }) {
74
74
  bio: row.bio,
75
75
  });
76
76
  };
77
- return (_jsxs("div", { className: "split", children: [_jsxs("section", { className: "panel panel-form", children: [_jsx("div", { className: "panel-head", children: _jsxs("h2", { children: ["Add ", labels.one] }) }), _jsxs("div", { className: "panel-body stack", children: [_jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Name" }), _jsx("input", { className: "fld", value: fresh.name, onChange: (e) => setFresh((f) => ({ ...f, name: e.target.value })), onKeyDown: (e) => {
77
+ return (_jsxs("div", { className: "blog_split", children: [_jsxs("section", { className: "blog_panel blog_panel-form", children: [_jsx("div", { className: "blog_panel-head", children: _jsxs("h2", { children: ["Add ", labels.one] }) }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Name" }), _jsx("input", { className: "blog_fld", value: fresh.name, onChange: (e) => setFresh((f) => ({ ...f, name: e.target.value })), onKeyDown: (e) => {
78
78
  if (e.key === "Enter") {
79
79
  e.preventDefault();
80
80
  create();
81
81
  }
82
- } })] }), _jsxs("label", { className: "fld-row", children: [_jsxs("span", { className: "fld-lbl", children: ["Slug ", _jsx("em", { children: "optional \u2014 derived from the name" })] }), _jsx("input", { className: "fld mono", value: fresh.slug, onChange: (e) => setFresh((f) => ({ ...f, slug: e.target.value })) })] }), isCategories ? (_jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Description" }), _jsx("textarea", { className: "fld", rows: 3, value: fresh.description, onChange: (e) => setFresh((f) => ({ ...f, description: e.target.value })) })] })) : null, isAuthors ? (_jsxs(_Fragment, { children: [_jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Job title" }), _jsx("input", { className: "fld", value: fresh.jobTitle, onChange: (e) => setFresh((f) => ({ ...f, jobTitle: e.target.value })) })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Bio" }), _jsx("textarea", { className: "fld", rows: 3, value: fresh.bio, onChange: (e) => setFresh((f) => ({ ...f, bio: e.target.value })) })] })] })) : null, _jsxs("button", { type: "button", className: "btn btn-primary", disabled: pending || !fresh.name.trim(), onClick: create, children: ["Add ", labels.one] }), _jsx("p", { className: "note", children: labels.blurb }), !store.activeBrandId ? _jsx("p", { className: "note", children: "Currently viewing all brands \u2014 choose one to add." }) : null] })] }), _jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsxs("h2", { children: [labels.many, " ", _jsx("span", { className: "hint", children: tenantName })] }), _jsx("span", { className: "hint", children: rows.length })] }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Name" }), _jsx("th", { children: "Slug" }), _jsx("th", { className: "num", children: "Posts" }), _jsx("th", {})] }) }), _jsxs("tbody", { children: [rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: 4, children: _jsx("p", { className: "d-empty", children: "Nothing here yet." }) }) })) : null, rows.map((row) => editing === row.id ? (_jsx("tr", { className: "quick-row", children: _jsx("td", { colSpan: 4, children: _jsxs("div", { className: "quick", children: [_jsxs("div", { className: "quick-grid", children: [_jsxs("label", { children: [_jsx("span", { children: "Name" }), _jsx("input", { className: "fld", value: draft.name, onChange: (e) => setDraft((d) => ({ ...d, name: e.target.value })) })] }), _jsxs("label", { children: [_jsx("span", { children: "Slug" }), _jsx("input", { className: "fld mono", value: draft.slug, onChange: (e) => setDraft((d) => ({ ...d, slug: e.target.value })) })] }), isCategories ? (_jsxs("label", { className: "span-2", children: [_jsx("span", { children: "Description" }), _jsx("textarea", { className: "fld", rows: 2, value: draft.description, onChange: (e) => setDraft((d) => ({ ...d, description: e.target.value })) })] })) : null, isAuthors ? (_jsxs(_Fragment, { children: [_jsxs("label", { children: [_jsx("span", { children: "Job title" }), _jsx("input", { className: "fld", value: draft.jobTitle, onChange: (e) => setDraft((d) => ({ ...d, jobTitle: e.target.value })) })] }), _jsxs("label", { className: "span-2", children: [_jsx("span", { children: "Bio" }), _jsx("textarea", { className: "fld", rows: 2, value: draft.bio, onChange: (e) => setDraft((d) => ({ ...d, bio: e.target.value })) })] })] })) : null] }), _jsxs("div", { className: "btn-row", children: [_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: () => run(() => store.saveTerm({
82
+ } })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsxs("span", { className: "blog_fld-lbl", children: ["Slug ", _jsx("em", { children: "optional \u2014 derived from the name" })] }), _jsx("input", { className: "blog_fld blog_mono", value: fresh.slug, onChange: (e) => setFresh((f) => ({ ...f, slug: e.target.value })) })] }), isCategories ? (_jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Description" }), _jsx("textarea", { className: "blog_fld", rows: 3, value: fresh.description, onChange: (e) => setFresh((f) => ({ ...f, description: e.target.value })) })] })) : null, isAuthors ? (_jsxs(_Fragment, { children: [_jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Job title" }), _jsx("input", { className: "blog_fld", value: fresh.jobTitle, onChange: (e) => setFresh((f) => ({ ...f, jobTitle: e.target.value })) })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Bio" }), _jsx("textarea", { className: "blog_fld", rows: 3, value: fresh.bio, onChange: (e) => setFresh((f) => ({ ...f, bio: e.target.value })) })] })] })) : null, _jsxs("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending || !fresh.name.trim(), onClick: create, children: ["Add ", labels.one] }), _jsx("p", { className: "blog_note", children: labels.blurb }), !store.activeBrandId ? _jsx("p", { className: "blog_note", children: "Currently viewing all brands \u2014 choose one to add." }) : null] })] }), _jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsxs("h2", { children: [labels.many, " ", _jsx("span", { className: "blog_hint", children: tenantName })] }), _jsx("span", { className: "blog_hint", children: rows.length })] }), error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "blog_form-ok", role: "status", children: flash })) : null, _jsx("div", { className: "blog_tw", children: _jsxs("table", { className: "blog_tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Name" }), _jsx("th", { children: "Slug" }), _jsx("th", { className: "blog_num", children: "Posts" }), _jsx("th", {})] }) }), _jsxs("tbody", { children: [rows.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: 4, children: _jsx("p", { className: "blog_d-empty", children: "Nothing here yet." }) }) })) : null, rows.map((row) => editing === row.id ? (_jsx("tr", { className: "blog_quick-row", children: _jsx("td", { colSpan: 4, children: _jsxs("div", { className: "blog_quick", children: [_jsxs("div", { className: "blog_quick-grid", children: [_jsxs("label", { children: [_jsx("span", { children: "Name" }), _jsx("input", { className: "blog_fld", value: draft.name, onChange: (e) => setDraft((d) => ({ ...d, name: e.target.value })) })] }), _jsxs("label", { children: [_jsx("span", { children: "Slug" }), _jsx("input", { className: "blog_fld blog_mono", value: draft.slug, onChange: (e) => setDraft((d) => ({ ...d, slug: e.target.value })) })] }), isCategories ? (_jsxs("label", { className: "blog_span-2", children: [_jsx("span", { children: "Description" }), _jsx("textarea", { className: "blog_fld", rows: 2, value: draft.description, onChange: (e) => setDraft((d) => ({ ...d, description: e.target.value })) })] })) : null, isAuthors ? (_jsxs(_Fragment, { children: [_jsxs("label", { children: [_jsx("span", { children: "Job title" }), _jsx("input", { className: "blog_fld", value: draft.jobTitle, onChange: (e) => setDraft((d) => ({ ...d, jobTitle: e.target.value })) })] }), _jsxs("label", { className: "blog_span-2", children: [_jsx("span", { children: "Bio" }), _jsx("textarea", { className: "blog_fld", rows: 2, value: draft.bio, onChange: (e) => setDraft((d) => ({ ...d, bio: e.target.value })) })] })] })) : null] }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: () => run(() => store.saveTerm({
83
83
  collection,
84
84
  id: row.id,
85
85
  brandId: row.brandId,
@@ -88,11 +88,11 @@ export function TermManager({ collection, onOpenPosts, }) {
88
88
  description: draft.description,
89
89
  jobTitle: draft.jobTitle,
90
90
  bio: draft.bio,
91
- }), "Saved."), children: "Save" }), _jsx("button", { type: "button", className: "btn", onClick: () => setEditing(null), children: "Cancel" })] })] }) }) }, row.id)) : (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("span", { className: "row-title", children: row.name }), row.jobTitle ? _jsx("span", { className: "cell-sub", children: row.jobTitle }) : null, row.description ? _jsx("span", { className: "cell-sub", children: row.description }) : null, _jsxs("div", { className: "row-actions", children: [_jsx("button", { type: "button", onClick: () => startEdit(row), children: "Edit" }), _jsx("button", { type: "button", className: "danger", onClick: () => {
91
+ }), "Saved."), children: "Save" }), _jsx("button", { type: "button", className: "blog_btn", onClick: () => setEditing(null), children: "Cancel" })] })] }) }) }, row.id)) : (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("span", { className: "blog_row-title", children: row.name }), row.jobTitle ? _jsx("span", { className: "blog_cell-sub", children: row.jobTitle }) : null, row.description ? _jsx("span", { className: "blog_cell-sub", children: row.description }) : null, _jsxs("div", { className: "blog_row-actions", children: [_jsx("button", { type: "button", onClick: () => startEdit(row), children: "Edit" }), _jsx("button", { type: "button", className: "blog_danger", onClick: () => {
92
92
  if (window.confirm(`Delete “${row.name}”?`)) {
93
93
  run(() => store.deleteTerm(collection, row.id), `${row.name} deleted.`);
94
94
  }
95
- }, children: "Delete" })] })] }), _jsx("td", { className: "mono muted", children: row.slug }), _jsx("td", { className: "num", children: row.count ? (_jsx("button", { type: "button", className: "btn btn-ghost btn-sm", onClick: () => onOpenPosts?.(row.id, row.name), children: row.count })) : (0) }), _jsx("td", {})] }, row.id)))] })] }) })] })] }));
95
+ }, children: "Delete" })] })] }), _jsx("td", { className: "blog_mono blog_muted", children: row.slug }), _jsx("td", { className: "blog_num", children: row.count ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-ghost blog_btn-sm", onClick: () => onOpenPosts?.(row.id, row.name), children: row.count })) : (0) }), _jsx("td", {})] }, row.id)))] })] }) })] })] }));
96
96
  }
97
97
  export function CategoryManager() {
98
98
  return _jsx(TermManager, { collection: "categories" });
@@ -89,8 +89,8 @@ export function UsersManager() {
89
89
  : d.roles.filter((r) => r.tenant !== tenantId),
90
90
  }));
91
91
  };
92
- return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "filterbar", children: [_jsx("button", { type: "button", className: "btn btn-primary", onClick: create, children: "\uFF0B Add person" }), _jsxs("span", { className: "note", children: [rows.length, " accounts"] })] }), error && !open ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsx("section", { className: "panel", children: _jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Person" }), _jsx("th", { children: "Platform role" }), _jsx("th", { children: "Brand access" }), _jsx("th", {})] }) }), _jsx("tbody", { children: rows.map((row) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsxs("span", { className: "row-title", children: [row.name, row.isSelf ? _jsx("span", { className: "chip chip-brand", children: "you" }) : null] }), _jsx("span", { className: "cell-sub mono", children: row.email }), _jsxs("div", { className: "row-actions", children: [_jsx("button", { type: "button", onClick: () => edit(row), children: "Edit" }), row.isSelf ? null : (_jsx("button", { type: "button", className: "danger", onClick: () => remove(row), children: "Delete" }))] })] }), _jsx("td", { className: "muted", children: GLOBAL_LABEL[row.globalRole] }), _jsx("td", { children: row.roles.length === 0 ? (_jsx("span", { className: "muted", children: "\u2014" })) : (_jsx("div", { className: "chips", children: row.roles.map((r) => (_jsxs("span", { className: "chip chip-brand", children: [r.tenantName, ": ", r.role.replace("-", " ")] }, `${row.id}-${r.tenant}`))) })) }), _jsx("td", {})] }, row.id))) })] }) }) }), open ? (_jsx("div", { className: "modal-backdrop", onMouseDown: () => setOpen(false), children: _jsxs("div", { className: "modal", role: "dialog", "aria-modal": "true", "aria-label": "Account", onMouseDown: (e) => e.stopPropagation(), children: [_jsxs("header", { className: "modal-head", children: [_jsx("h2", { children: draft.id ? "Edit account" : "Add person" }), _jsx("button", { type: "button", className: "icon-btn", onClick: () => setOpen(false), "aria-label": "Close", children: "\u2715" })] }), _jsxs("div", { className: "modal-body stack", children: [error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Name" }), _jsx("input", { className: "fld", value: draft.name, onChange: (e) => setDraft((d) => ({ ...d, name: e.target.value })) })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Email" }), _jsx("input", { className: "fld mono", type: "email", value: draft.email, onChange: (e) => setDraft((d) => ({ ...d, email: e.target.value })) })] }), _jsxs("label", { className: "fld-row", children: [_jsxs("span", { className: "fld-lbl", children: [draft.id ? "New password" : "Starting password", " ", _jsx("em", { children: "at least 12 characters" })] }), _jsx("input", { className: "fld", type: "password", autoComplete: "new-password", placeholder: draft.id ? "Leave blank to keep the current one" : "", value: draft.password, onChange: (e) => setDraft((d) => ({ ...d, password: e.target.value })) })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Platform role" }), _jsxs("select", { className: "fld", value: draft.globalRole, onChange: (e) => setDraft((d) => ({ ...d, globalRole: e.target.value })), children: [_jsx("option", { value: "none", children: "Brand roles only" }), _jsx("option", { value: "analyst", children: "Analyst \u2014 read-only across every brand" }), _jsx("option", { value: "platform-admin", children: "Platform admin \u2014 full control" })] })] }), _jsxs("div", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Brand access" }), _jsx("div", { className: "role-grid", children: tenants.map((t) => {
92
+ return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "blog_filterbar", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", onClick: create, children: "\uFF0B Add person" }), _jsxs("span", { className: "blog_note", children: [rows.length, " accounts"] })] }), error && !open ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "blog_form-ok", role: "status", children: flash })) : null, _jsx("section", { className: "blog_panel", children: _jsx("div", { className: "blog_tw", children: _jsxs("table", { className: "blog_tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Person" }), _jsx("th", { children: "Platform role" }), _jsx("th", { children: "Brand access" }), _jsx("th", {})] }) }), _jsx("tbody", { children: rows.map((row) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsxs("span", { className: "blog_row-title", children: [row.name, row.isSelf ? _jsx("span", { className: "blog_chip blog_chip-brand", children: "you" }) : null] }), _jsx("span", { className: "blog_cell-sub blog_mono", children: row.email }), _jsxs("div", { className: "blog_row-actions", children: [_jsx("button", { type: "button", onClick: () => edit(row), children: "Edit" }), row.isSelf ? null : (_jsx("button", { type: "button", className: "blog_danger", onClick: () => remove(row), children: "Delete" }))] })] }), _jsx("td", { className: "blog_muted", children: GLOBAL_LABEL[row.globalRole] }), _jsx("td", { children: row.roles.length === 0 ? (_jsx("span", { className: "blog_muted", children: "\u2014" })) : (_jsx("div", { className: "blog_chips", children: row.roles.map((r) => (_jsxs("span", { className: "blog_chip blog_chip-brand", children: [r.tenantName, ": ", r.role.replace("-", " ")] }, `${row.id}-${r.tenant}`))) })) }), _jsx("td", {})] }, row.id))) })] }) }) }), open ? (_jsx("div", { className: "blog_modal-backdrop", onMouseDown: () => setOpen(false), children: _jsxs("div", { className: "blog_modal", role: "dialog", "aria-modal": "true", "aria-label": "Account", onMouseDown: (e) => e.stopPropagation(), children: [_jsxs("header", { className: "blog_modal-head", children: [_jsx("h2", { children: draft.id ? "Edit account" : "Add person" }), _jsx("button", { type: "button", className: "blog_icon-btn", onClick: () => setOpen(false), "aria-label": "Close", children: "\u2715" })] }), _jsxs("div", { className: "blog_modal-body blog_stack", children: [error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Name" }), _jsx("input", { className: "blog_fld", value: draft.name, onChange: (e) => setDraft((d) => ({ ...d, name: e.target.value })) })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Email" }), _jsx("input", { className: "blog_fld blog_mono", type: "email", value: draft.email, onChange: (e) => setDraft((d) => ({ ...d, email: e.target.value })) })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsxs("span", { className: "blog_fld-lbl", children: [draft.id ? "New password" : "Starting password", " ", _jsx("em", { children: "at least 12 characters" })] }), _jsx("input", { className: "blog_fld", type: "password", autoComplete: "new-password", placeholder: draft.id ? "Leave blank to keep the current one" : "", value: draft.password, onChange: (e) => setDraft((d) => ({ ...d, password: e.target.value })) })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Platform role" }), _jsxs("select", { className: "blog_fld", value: draft.globalRole, onChange: (e) => setDraft((d) => ({ ...d, globalRole: e.target.value })), children: [_jsx("option", { value: "none", children: "Brand roles only" }), _jsx("option", { value: "analyst", children: "Analyst \u2014 read-only across every brand" }), _jsx("option", { value: "platform-admin", children: "Platform admin \u2014 full control" })] })] }), _jsxs("div", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Brand access" }), _jsx("div", { className: "blog_role-grid", children: tenants.map((t) => {
93
93
  const current = draft.roles.find((r) => r.tenant === t.id)?.role ?? "";
94
- return (_jsxs("div", { className: "role-row", children: [_jsx("span", { children: t.name }), _jsxs("select", { className: "fld fld-sm", value: current, onChange: (e) => setRole(t.id, e.target.value), "aria-label": `Role in ${t.name}`, children: [_jsx("option", { value: "", children: "No access" }), TENANT_ROLES.map((role) => (_jsx("option", { value: role, children: role.replace("-", " ") }, role)))] }), _jsx("span", { className: "note", children: current ? ROLE_HELP[current] : "" })] }, t.id));
95
- }) })] })] }), _jsxs("footer", { className: "modal-foot", children: [_jsx("span", { className: "note", children: "Publishing rights come from the brand role, never from the platform role." }), _jsxs("div", { className: "modal-foot-actions", children: [_jsx("button", { type: "button", className: "btn", onClick: () => setOpen(false), children: "Cancel" }), _jsx("button", { type: "button", className: "btn btn-primary", onClick: submit, disabled: pending, children: pending ? "Saving…" : draft.id ? "Save account" : "Create account" })] })] })] }) })) : null] }));
94
+ return (_jsxs("div", { className: "blog_role-row", children: [_jsx("span", { children: t.name }), _jsxs("select", { className: "blog_fld blog_fld-sm", value: current, onChange: (e) => setRole(t.id, e.target.value), "aria-label": `Role in ${t.name}`, children: [_jsx("option", { value: "", children: "No access" }), TENANT_ROLES.map((role) => (_jsx("option", { value: role, children: role.replace("-", " ") }, role)))] }), _jsx("span", { className: "blog_note", children: current ? ROLE_HELP[current] : "" })] }, t.id));
95
+ }) })] })] }), _jsxs("footer", { className: "blog_modal-foot", children: [_jsx("span", { className: "blog_note", children: "Publishing rights come from the brand role, never from the platform role." }), _jsxs("div", { className: "blog_modal-foot-actions", children: [_jsx("button", { type: "button", className: "blog_btn", onClick: () => setOpen(false), children: "Cancel" }), _jsx("button", { type: "button", className: "blog_btn blog_btn-primary", onClick: submit, disabled: pending, children: pending ? "Saving…" : draft.id ? "Save account" : "Create account" })] })] })] }) })) : null] }));
96
96
  }
@@ -39,7 +39,7 @@ export const TrendArea = ({ data, height = 220 }) => {
39
39
  setHover(i >= 0 && i < data.length ? i : null);
40
40
  };
41
41
  const active = hover != null ? data[hover] : null;
42
- return (_jsxs("div", { className: "chart-holder", children: [_jsxs("svg", { viewBox: `0 0 ${W} ${H}`, className: "chart-svg", role: "img", "aria-label": `Daily views over the last ${data.length} days`, onMouseMove: onMove, onMouseLeave: () => setHover(null), children: [_jsx("defs", { children: _jsxs("linearGradient", { id: gradId, x1: "0", y1: "0", x2: "0", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: "var(--viz-1)", stopOpacity: "0.26" }), _jsx("stop", { offset: "100%", stopColor: "var(--viz-1)", stopOpacity: "0.02" })] }) }), ticks.map((t) => (_jsxs("g", { children: [_jsx("line", { x1: pad.l, x2: W - pad.r, y1: y(t), y2: y(t), stroke: "var(--viz-grid)", strokeWidth: "1" }), _jsx("text", { x: pad.l - 9, y: y(t) + 4, textAnchor: "end", className: "axis-label", fill: "var(--viz-muted)", children: fmt.format(Math.round(t)) })] }, t))), _jsx("path", { d: area, fill: `url(#${gradId})` }), _jsx("path", { d: line, fill: "none", stroke: "var(--viz-1)", strokeWidth: "2", strokeLinejoin: "round" }), [0, Math.floor(data.length / 2), data.length - 1].map((i) => (_jsx("text", { x: x(i), y: H - 8, textAnchor: i === 0 ? 'start' : i === data.length - 1 ? 'end' : 'middle', className: "axis-label", fill: "var(--viz-muted)", children: data[i] ? shortDate(data[i].date) : '' }, i))), active && hover != null ? (_jsxs("g", { children: [_jsx("line", { x1: x(hover), x2: x(hover), y1: pad.t, y2: pad.t + ih, stroke: "var(--viz-axis)", strokeWidth: "1" }), _jsx("circle", { cx: x(hover), cy: y(active.views), r: "5", fill: "var(--viz-1)", stroke: "var(--d-surface)", strokeWidth: "2" })] })) : null] }), active && hover != null ? (_jsxs("div", { className: "chart-tip", style: { left: `${(x(hover) / W) * 100}%` }, role: "status", children: [_jsx("div", { className: "tip-date", children: shortDate(active.date) }), _jsxs("div", { className: "tip-row", children: [_jsx("span", { className: "tip-swatch", style: { background: 'var(--viz-1)' } }), fmt.format(active.views), " views"] }), _jsxs("div", { className: "tip-sub", children: [fmt.format(active.uniques), " unique"] })] })) : null] }));
42
+ return (_jsxs("div", { className: "blog_chart-holder", children: [_jsxs("svg", { viewBox: `0 0 ${W} ${H}`, className: "blog_chart-svg", role: "img", "aria-label": `Daily views over the last ${data.length} days`, onMouseMove: onMove, onMouseLeave: () => setHover(null), children: [_jsx("defs", { children: _jsxs("linearGradient", { id: gradId, x1: "0", y1: "0", x2: "0", y2: "1", children: [_jsx("stop", { offset: "0%", stopColor: "var(--viz-1)", stopOpacity: "0.26" }), _jsx("stop", { offset: "100%", stopColor: "var(--viz-1)", stopOpacity: "0.02" })] }) }), ticks.map((t) => (_jsxs("g", { children: [_jsx("line", { x1: pad.l, x2: W - pad.r, y1: y(t), y2: y(t), stroke: "var(--viz-grid)", strokeWidth: "1" }), _jsx("text", { x: pad.l - 9, y: y(t) + 4, textAnchor: "end", className: "blog_axis-label", fill: "var(--viz-muted)", children: fmt.format(Math.round(t)) })] }, t))), _jsx("path", { d: area, fill: `url(#${gradId})` }), _jsx("path", { d: line, fill: "none", stroke: "var(--viz-1)", strokeWidth: "2", strokeLinejoin: "round" }), [0, Math.floor(data.length / 2), data.length - 1].map((i) => (_jsx("text", { x: x(i), y: H - 8, textAnchor: i === 0 ? 'start' : i === data.length - 1 ? 'end' : 'middle', className: "blog_axis-label", fill: "var(--viz-muted)", children: data[i] ? shortDate(data[i].date) : '' }, i))), active && hover != null ? (_jsxs("g", { children: [_jsx("line", { x1: x(hover), x2: x(hover), y1: pad.t, y2: pad.t + ih, stroke: "var(--viz-axis)", strokeWidth: "1" }), _jsx("circle", { cx: x(hover), cy: y(active.views), r: "5", fill: "var(--viz-1)", stroke: "var(--d-surface)", strokeWidth: "2" })] })) : null] }), active && hover != null ? (_jsxs("div", { className: "blog_chart-tip", style: { left: `${(x(hover) / W) * 100}%` }, role: "status", children: [_jsx("div", { className: "blog_tip-date", children: shortDate(active.date) }), _jsxs("div", { className: "blog_tip-row", children: [_jsx("span", { className: "blog_tip-swatch", style: { background: 'var(--viz-1)' } }), fmt.format(active.views), " views"] }), _jsxs("div", { className: "blog_tip-sub", children: [fmt.format(active.uniques), " unique"] })] })) : null] }));
43
43
  };
44
44
  /* ------------------------------------------------------------------ */
45
45
  /* Sparkline for stat cards */
@@ -51,7 +51,7 @@ export const Sparkline = ({ data }) => {
51
51
  const pts = data
52
52
  .map((v, i) => `${(i / Math.max(1, data.length - 1)) * W},${H - (v / max) * (H - 4) - 2}`)
53
53
  .join(' ');
54
- return (_jsxs("svg", { viewBox: `0 0 ${W} ${H}`, className: "spark", "aria-hidden": "true", children: [_jsx("polyline", { points: pts, fill: "none", stroke: "var(--viz-1)", strokeWidth: "2", strokeLinejoin: "round", strokeLinecap: "round" }), data.length ? (_jsx("circle", { cx: W, cy: H - (data[data.length - 1] / max) * (H - 4) - 2, r: "2.5", fill: "var(--viz-1)" })) : null] }));
54
+ return (_jsxs("svg", { viewBox: `0 0 ${W} ${H}`, className: "blog_spark", "aria-hidden": "true", children: [_jsx("polyline", { points: pts, fill: "none", stroke: "var(--viz-1)", strokeWidth: "2", strokeLinejoin: "round", strokeLinecap: "round" }), data.length ? (_jsx("circle", { cx: W, cy: H - (data[data.length - 1] / max) * (H - 4) - 2, r: "2.5", fill: "var(--viz-1)" })) : null] }));
55
55
  };
56
56
  /* ------------------------------------------------------------------ */
57
57
  /* Horizontal bar list — direct-labelled, which is also the contrast */
@@ -60,11 +60,11 @@ export const Sparkline = ({ data }) => {
60
60
  export const BarList = ({ items, colorVar = 'var(--viz-1)', unit = '', hrefFor, }) => {
61
61
  const max = Math.max(1, ...items.map((i) => i.value));
62
62
  if (items.length === 0)
63
- return _jsx("p", { className: "d-empty", children: "No data yet." });
64
- return (_jsx("ul", { className: "barlist", children: items.map((item) => {
63
+ return _jsx("p", { className: "blog_d-empty", children: "No data yet." });
64
+ return (_jsx("ul", { className: "blog_barlist", children: items.map((item) => {
65
65
  const href = hrefFor?.(item.label);
66
- const label = (_jsxs(_Fragment, { children: [_jsx("span", { className: "bl-label", title: item.label, children: item.label }), _jsxs("span", { className: "bl-value", children: [fmt.format(item.value), unit] })] }));
67
- return (_jsxs("li", { className: "bl-row", children: [_jsx("div", { className: "bl-head", children: href ? (_jsx("a", { href: href, className: "bl-link", children: label })) : (label) }), _jsx("div", { className: "bl-track", children: _jsx("div", { className: "bl-fill", style: { width: `${(item.value / max) * 100}%`, background: colorVar } }) })] }, item.label));
66
+ const label = (_jsxs(_Fragment, { children: [_jsx("span", { className: "blog_bl-label", title: item.label, children: item.label }), _jsxs("span", { className: "blog_bl-value", children: [fmt.format(item.value), unit] })] }));
67
+ return (_jsxs("li", { className: "blog_bl-row", children: [_jsx("div", { className: "blog_bl-head", children: href ? (_jsx("a", { href: href, className: "blog_bl-link", children: label })) : (label) }), _jsx("div", { className: "blog_bl-track", children: _jsx("div", { className: "blog_bl-fill", style: { width: `${(item.value / max) * 100}%`, background: colorVar } }) })] }, item.label));
68
68
  }) }));
69
69
  };
70
70
  /* ------------------------------------------------------------------ */
@@ -72,7 +72,7 @@ export const BarList = ({ items, colorVar = 'var(--viz-1)', unit = '', hrefFor,
72
72
  /* ------------------------------------------------------------------ */
73
73
  export const Funnel = ({ stages, }) => {
74
74
  const max = Math.max(1, ...stages.map((s) => s.value));
75
- return (_jsx("ul", { className: "funnel", children: stages.map((s) => (_jsxs("li", { children: [_jsxs("div", { className: "fn-head", children: [_jsx("span", { className: "fn-label", children: s.label }), _jsx("span", { className: "fn-value", children: fmt.format(s.value) })] }), _jsx("div", { className: "fn-track", children: _jsx("div", { className: "fn-fill", style: {
75
+ return (_jsx("ul", { className: "blog_funnel", children: stages.map((s) => (_jsxs("li", { children: [_jsxs("div", { className: "blog_fn-head", children: [_jsx("span", { className: "blog_fn-label", children: s.label }), _jsx("span", { className: "blog_fn-value", children: fmt.format(s.value) })] }), _jsx("div", { className: "blog_fn-track", children: _jsx("div", { className: "blog_fn-fill", style: {
76
76
  width: `${Math.max(2, (s.value / max) * 100)}%`,
77
77
  background: `var(--ord-${s.tone})`,
78
78
  } }) })] }, s.label))) }));
@@ -7,7 +7,7 @@ import { analyseReadability, analyseSeo, summariseTone, toneLabel, } from "../..
7
7
  import { YoastSeoMetabox } from "./YoastSeoMetabox";
8
8
  import { RichTextEditor } from "./RichTextEditor";
9
9
  import { MediaPicker } from "../MediaPicker";
10
- const ScoreDot = ({ tone }) => (_jsx("span", { className: `seo-dot seo-dot-${tone}`, "aria-hidden": "true" }));
10
+ const ScoreDot = ({ tone }) => (_jsx("span", { className: `blog_seo-dot blog_seo-dot-${tone}`, "aria-hidden": "true" }));
11
11
  export function PostEditor({ postId, onDone, }) {
12
12
  const store = useAdminMock();
13
13
  const existing = postId ? store.getPost(postId) : undefined;
@@ -359,23 +359,23 @@ export function PostEditor({ postId, onDone, }) {
359
359
  : "Immediately";
360
360
  const permalink = `/blog/${slug || slugify(title) || "…"}`;
361
361
  const categoryOptions = categoryTab === "popular" ? categories.slice(0, 8) : categories;
362
- return (_jsxs("div", { className: "ed-layout", children: [_jsxs("div", { className: "ed-main", children: [error ? (_jsx("p", { className: "form-error ed-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsx("div", { className: "ed-title-wrap", children: _jsx("input", { className: "fld ed-title", value: title, onChange: (e) => {
362
+ return (_jsxs("div", { className: "blog_ed-layout", children: [_jsxs("div", { className: "blog_ed-main", children: [error ? (_jsx("p", { className: "blog_form-error blog_ed-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "blog_form-ok", role: "status", children: flash })) : null, _jsx("div", { className: "blog_ed-title-wrap", children: _jsx("input", { className: "blog_fld blog_ed-title", value: title, onChange: (e) => {
363
363
  setTitle(e.target.value);
364
364
  if (!existing && !slugEditing)
365
365
  setSlug(slugify(e.target.value));
366
- }, placeholder: "Add title", "aria-label": "Post title" }) }), _jsxs("div", { className: "ed-permalink", children: [_jsx("span", { className: "lbl", children: "Permalink:" }), slugEditing ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "mono", children: "/blog/" }), _jsx("input", { className: "fld mono", style: { maxWidth: 220 }, value: slug, onChange: (e) => setSlug(e.target.value), onBlur: () => {
366
+ }, placeholder: "Add title", "aria-label": "Post title" }) }), _jsxs("div", { className: "blog_ed-permalink", children: [_jsx("span", { className: "blog_lbl", children: "Permalink:" }), slugEditing ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "blog_mono", children: "/blog/" }), _jsx("input", { className: "blog_fld blog_mono", style: { maxWidth: 220 }, value: slug, onChange: (e) => setSlug(e.target.value), onBlur: () => {
367
367
  setSlug(slugify(slug || title));
368
368
  setSlugEditing(false);
369
- } })] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "mono ed-permalink-value", children: permalink }), _jsx("button", { type: "button", className: "btn btn-tiny", onClick: () => setSlugEditing(true), children: "Edit" })] })), _jsxs("span", { className: "ed-bar-meta", style: { marginLeft: "auto" }, children: [wordCount, " words"] })] }), _jsx(RichTextEditor, { initialHtml: existing?.contentHtml ?? contentHtml, onChange: onContentChange, onPickImage: onPickImage, searchTargets: searchTargets }), _jsxs("div", { className: "box", children: [_jsxs("div", { className: "box-head", children: [_jsx("h3", { children: "Excerpt" }), _jsxs("span", { className: "box-hint", children: [excerpt.length, "/300"] })] }), _jsx("div", { className: "box-body", children: _jsx("textarea", { className: "fld", rows: 3, maxLength: 300, value: excerpt, placeholder: "One or two sentences. Used on index pages and as the meta description fallback.", onChange: (e) => setExcerpt(e.target.value) }) })] }), _jsx(YoastSeoMetabox, { title: title, slug: slug, excerpt: excerpt, visibility: visibility, featuredImage: featuredImage, seo: seo, seoInput: seoInput, siteName: brand?.name ?? "My Site", categoryName: categoryName, contentText: contentText, contentHtml: contentHtml, publishedAt: publishedAt, scheduledFor: scheduledFor, fieldErrors: fieldErrors, onSeoChange: onSeoChange, onSlugChange: setSlug, onSlugBlur: () => setSlug(slugify(slug || title)), onPickOgImage: () => setPickerFor("og"), onClearFieldError: (field) => setFieldErrors((current) => {
369
+ } })] })) : (_jsxs(_Fragment, { children: [_jsx("span", { className: "blog_mono blog_ed-permalink-value", children: permalink }), _jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: () => setSlugEditing(true), children: "Edit" })] })), _jsxs("span", { className: "blog_ed-bar-meta", style: { marginLeft: "auto" }, children: [wordCount, " words"] })] }), _jsx(RichTextEditor, { initialHtml: existing?.contentHtml ?? contentHtml, onChange: onContentChange, onPickImage: onPickImage, searchTargets: searchTargets }), _jsxs("div", { className: "blog_box", children: [_jsxs("div", { className: "blog_box-head", children: [_jsx("h3", { children: "Excerpt" }), _jsxs("span", { className: "blog_box-hint", children: [excerpt.length, "/300"] })] }), _jsx("div", { className: "blog_box-body", children: _jsx("textarea", { className: "blog_fld", rows: 3, maxLength: 300, value: excerpt, placeholder: "One or two sentences. Used on index pages and as the meta description fallback.", onChange: (e) => setExcerpt(e.target.value) }) })] }), _jsx(YoastSeoMetabox, { title: title, slug: slug, excerpt: excerpt, visibility: visibility, featuredImage: featuredImage, seo: seo, seoInput: seoInput, siteName: brand?.name ?? "My Site", categoryName: categoryName, contentText: contentText, contentHtml: contentHtml, publishedAt: publishedAt, scheduledFor: scheduledFor, fieldErrors: fieldErrors, onSeoChange: onSeoChange, onSlugChange: setSlug, onSlugBlur: () => setSlug(slugify(slug || title)), onPickOgImage: () => setPickerFor("og"), onClearFieldError: (field) => setFieldErrors((current) => {
370
370
  const next = { ...current };
371
371
  delete next[field];
372
372
  return next;
373
- }), onSetFieldError: (field, message) => setFieldErrors((current) => ({ ...current, [field]: message })) })] }), _jsxs("aside", { className: "ed-side", "aria-label": "Post settings", children: [_jsxs("div", { className: "box box-publish", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Publish" }) }), _jsxs("div", { className: "box-body stack", children: [_jsxs("div", { className: "btn-row", children: [_jsx("button", { type: "button", className: "btn", disabled: pending, onClick: () => persist(isLive ? "publish" : "draft"), children: pending ? "Saving…" : isLive ? "Update" : "Save Draft" }), _jsx("button", { type: "button", className: "btn", disabled: pending, title: "Preview", children: "Preview" })] }), _jsxs("div", { className: "facts wp-facts", children: [_jsxs("div", { className: "fact-row", children: [_jsx("span", { className: "fact-lbl", children: "Status:" }), _jsxs("span", { className: "fact-val", children: [isLive ? "Published" : "Draft", " ", _jsx("button", { type: "button", className: "linkish", onClick: () => setShowStatus((v) => !v), children: "Edit" })] })] }), showStatus ? (_jsx("div", { className: "fact-edit", children: _jsxs("select", { className: "fld fld-sm", value: isLive ? "published" : "draft", onChange: (e) => {
373
+ }), onSetFieldError: (field, message) => setFieldErrors((current) => ({ ...current, [field]: message })) })] }), _jsxs("aside", { className: "blog_ed-side", "aria-label": "Post settings", children: [_jsxs("div", { className: "blog_box blog_box-publish", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Publish" }) }), _jsxs("div", { className: "blog_box-body blog_stack", children: [_jsxs("div", { className: "blog_btn-row", children: [_jsx("button", { type: "button", className: "blog_btn", disabled: pending, onClick: () => persist(isLive ? "publish" : "draft"), children: pending ? "Saving…" : isLive ? "Update" : "Save Draft" }), _jsx("button", { type: "button", className: "blog_btn", disabled: pending, title: "Preview", children: "Preview" })] }), _jsxs("div", { className: "blog_facts blog_wp-facts", children: [_jsxs("div", { className: "blog_fact-row", children: [_jsx("span", { className: "blog_fact-lbl", children: "Status:" }), _jsxs("span", { className: "blog_fact-val", children: [isLive ? "Published" : "Draft", " ", _jsx("button", { type: "button", className: "blog_linkish", onClick: () => setShowStatus((v) => !v), children: "Edit" })] })] }), showStatus ? (_jsx("div", { className: "blog_fact-edit", children: _jsxs("select", { className: "blog_fld blog_fld-sm", value: isLive ? "published" : "draft", onChange: (e) => {
374
374
  if (e.target.value === "published")
375
375
  persist("publish");
376
376
  else if (isLive)
377
377
  persist("unpublish");
378
- }, children: [_jsx("option", { value: "draft", children: "Draft" }), _jsx("option", { value: "published", children: "Published" })] }) })) : null, _jsxs("div", { className: "fact-row", children: [_jsx("span", { className: "fact-lbl", children: "Visibility:" }), _jsxs("span", { className: "fact-val", children: [visibility === "private" ? "Private" : "Public", " ", _jsx("button", { type: "button", className: "linkish", onClick: () => setShowVisibility((v) => !v), children: "Edit" })] })] }), showVisibility ? (_jsx("div", { className: "fact-edit", children: _jsxs("select", { className: "fld fld-sm", value: visibility, onChange: (e) => setVisibility(e.target.value), children: [_jsx("option", { value: "public", children: "Public" }), _jsx("option", { value: "private", children: "Private" })] }) })) : null, _jsxs("div", { className: "fact-row", children: [_jsx("span", { className: "fact-lbl", children: scheduledFor && !isLive ? "Schedule:" : "Publish:" }), _jsxs("span", { className: "fact-val", children: [publishWhenLabel, " ", _jsx("button", { type: "button", className: "linkish", onClick: () => setShowSchedule((v) => !v), children: "Edit" })] })] })] }), showSchedule ? (_jsxs("div", { className: "stack", children: [_jsx("input", { type: "datetime-local", className: "fld", value: scheduleWhen, onChange: (e) => setScheduleWhen(e.target.value), "aria-label": "Publish date and time" }), _jsxs("div", { className: "btn-row", children: [_jsx("button", { type: "button", className: "btn btn-primary btn-tiny", disabled: pending, onClick: () => persist("schedule"), children: "OK" }), _jsx("button", { type: "button", className: "btn btn-tiny", onClick: () => setShowSchedule(false), children: "Cancel" }), scheduledFor ? (_jsx("button", { type: "button", className: "btn btn-tiny", disabled: pending, onClick: () => persist("unschedule"), children: "Clear" })) : null] })] })) : null, _jsxs("div", { className: "seo-summary publish-seo-summary wp-publish-scores", children: [_jsxs("div", { className: "fact-row", children: [_jsx("span", { className: "fact-lbl", children: "SEO analysis:" }), _jsxs("span", { className: "fact-val", children: [_jsx(ScoreDot, { tone: seoTone }), " ", toneLabel(seoTone)] })] }), _jsxs("div", { className: "fact-row", children: [_jsx("span", { className: "fact-lbl", children: "Readability:" }), _jsxs("span", { className: "fact-val", children: [_jsx(ScoreDot, { tone: readTone }), " ", toneLabel(readTone)] })] })] }), _jsxs("div", { className: "publish-foot", children: [_jsxs("div", { className: "publish-foot-left", children: [postIdCurrent ? (_jsx("button", { type: "button", className: "linkish", disabled: pending, onClick: copyToDraft, children: "Copy to a new draft" })) : null, postIdCurrent ? (_jsx("button", { type: "button", className: "btn-danger-link", disabled: pending, onClick: moveToTrash, children: "Move to Trash" })) : null] }), !isLive ? (_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: () => persist("publish"), children: pending ? "Publishing…" : "Publish" })) : null] })] })] }), _jsxs("div", { className: "box", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Format" }) }), _jsx("div", { className: "box-body", children: _jsx("div", { className: "pick-list pick-list-auto", children: [
378
+ }, children: [_jsx("option", { value: "draft", children: "Draft" }), _jsx("option", { value: "published", children: "Published" })] }) })) : null, _jsxs("div", { className: "blog_fact-row", children: [_jsx("span", { className: "blog_fact-lbl", children: "Visibility:" }), _jsxs("span", { className: "blog_fact-val", children: [visibility === "private" ? "Private" : "Public", " ", _jsx("button", { type: "button", className: "blog_linkish", onClick: () => setShowVisibility((v) => !v), children: "Edit" })] })] }), showVisibility ? (_jsx("div", { className: "blog_fact-edit", children: _jsxs("select", { className: "blog_fld blog_fld-sm", value: visibility, onChange: (e) => setVisibility(e.target.value), children: [_jsx("option", { value: "public", children: "Public" }), _jsx("option", { value: "private", children: "Private" })] }) })) : null, _jsxs("div", { className: "blog_fact-row", children: [_jsx("span", { className: "blog_fact-lbl", children: scheduledFor && !isLive ? "Schedule:" : "Publish:" }), _jsxs("span", { className: "blog_fact-val", children: [publishWhenLabel, " ", _jsx("button", { type: "button", className: "blog_linkish", onClick: () => setShowSchedule((v) => !v), children: "Edit" })] })] })] }), showSchedule ? (_jsxs("div", { className: "blog_stack", children: [_jsx("input", { type: "datetime-local", className: "blog_fld", value: scheduleWhen, onChange: (e) => setScheduleWhen(e.target.value), "aria-label": "Publish date and time" }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-primary blog_btn-tiny", disabled: pending, onClick: () => persist("schedule"), children: "OK" }), _jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: () => setShowSchedule(false), children: "Cancel" }), scheduledFor ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", disabled: pending, onClick: () => persist("unschedule"), children: "Clear" })) : null] })] })) : null, _jsxs("div", { className: "blog_seo-summary blog_publish-seo-summary blog_wp-publish-scores", children: [_jsxs("div", { className: "blog_fact-row", children: [_jsx("span", { className: "blog_fact-lbl", children: "SEO analysis:" }), _jsxs("span", { className: "blog_fact-val", children: [_jsx(ScoreDot, { tone: seoTone }), " ", toneLabel(seoTone)] })] }), _jsxs("div", { className: "blog_fact-row", children: [_jsx("span", { className: "blog_fact-lbl", children: "Readability:" }), _jsxs("span", { className: "blog_fact-val", children: [_jsx(ScoreDot, { tone: readTone }), " ", toneLabel(readTone)] })] })] }), _jsxs("div", { className: "blog_publish-foot", children: [_jsxs("div", { className: "blog_publish-foot-left", children: [postIdCurrent ? (_jsx("button", { type: "button", className: "blog_linkish", disabled: pending, onClick: copyToDraft, children: "Copy to a new draft" })) : null, postIdCurrent ? (_jsx("button", { type: "button", className: "blog_btn-danger-link", disabled: pending, onClick: moveToTrash, children: "Move to Trash" })) : null] }), !isLive ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: () => persist("publish"), children: pending ? "Publishing…" : "Publish" })) : null] })] })] }), _jsxs("div", { className: "blog_box", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Format" }) }), _jsx("div", { className: "blog_box-body", children: _jsx("div", { className: "blog_pick-list blog_pick-list-auto", children: [
379
379
  ["standard", "Standard"],
380
380
  ["video", "Video"],
381
381
  ["audio", "Audio"],
@@ -383,23 +383,23 @@ export function PostEditor({ postId, onDone, }) {
383
383
  ["gallery", "Gallery"],
384
384
  ["image", "Image"],
385
385
  ["link", "Link"],
386
- ].map(([value, label]) => (_jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "radio", name: "postFormat", checked: postFormat === value, onChange: () => setPostFormat(value) }), label] }, value))) }) })] }), _jsxs("div", { className: "box", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Categories" }) }), _jsxs("div", { className: "box-body stack", children: [_jsxs("div", { className: "yoast-preview-modes wp-cat-tabs", role: "tablist", "aria-label": "Category list", children: [_jsx("button", { type: "button", role: "tab", className: `yoast-preview-mode${categoryTab === "all" ? " is-active" : ""}`, "aria-selected": categoryTab === "all", onClick: () => setCategoryTab("all"), children: "All Categories" }), _jsx("button", { type: "button", role: "tab", className: `yoast-preview-mode${categoryTab === "popular" ? " is-active" : ""}`, "aria-selected": categoryTab === "popular", onClick: () => setCategoryTab("popular"), children: "Most Used" })] }), _jsx("div", { className: "pick-list", children: categoryOptions.length === 0 ? (_jsx("p", { className: "note", children: "No categories in this brand yet." })) : (categoryOptions.map((c) => (_jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: categoryIds.includes(c.id), onChange: () => setCategoryIds((ids) => ids.includes(c.id) ? ids.filter((x) => x !== c.id) : [...ids, c.id]) }), c.name] }, c.id)))) }), categoryIds.length > 1 ? (_jsxs("p", { className: "note", children: [categoryIds.length, " selected \u00B7 first selected is used for breadcrumbs."] })) : null, _jsx("button", { type: "button", className: "yoast-link-btn", onClick: () => document.getElementById("new-category-input")?.focus(), children: "+ Add New Category" }), _jsxs("div", { className: "btn-row", children: [_jsx("input", { id: "new-category-input", className: "fld", placeholder: "New category", value: newCategory, onChange: (e) => setNewCategory(e.target.value), onKeyDown: (e) => {
386
+ ].map(([value, label]) => (_jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "radio", name: "postFormat", checked: postFormat === value, onChange: () => setPostFormat(value) }), label] }, value))) }) })] }), _jsxs("div", { className: "blog_box", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Categories" }) }), _jsxs("div", { className: "blog_box-body blog_stack", children: [_jsxs("div", { className: "blog_yoast-preview-modes blog_wp-cat-tabs", role: "tablist", "aria-label": "Category list", children: [_jsx("button", { type: "button", role: "tab", className: `blog_yoast-preview-mode${categoryTab === "all" ? " blog_is-active" : ""}`, "aria-selected": categoryTab === "all", onClick: () => setCategoryTab("all"), children: "All Categories" }), _jsx("button", { type: "button", role: "tab", className: `blog_yoast-preview-mode${categoryTab === "popular" ? " blog_is-active" : ""}`, "aria-selected": categoryTab === "popular", onClick: () => setCategoryTab("popular"), children: "Most Used" })] }), _jsx("div", { className: "blog_pick-list", children: categoryOptions.length === 0 ? (_jsx("p", { className: "blog_note", children: "No categories in this brand yet." })) : (categoryOptions.map((c) => (_jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: categoryIds.includes(c.id), onChange: () => setCategoryIds((ids) => ids.includes(c.id) ? ids.filter((x) => x !== c.id) : [...ids, c.id]) }), c.name] }, c.id)))) }), categoryIds.length > 1 ? (_jsxs("p", { className: "blog_note", children: [categoryIds.length, " selected \u00B7 first selected is used for breadcrumbs."] })) : null, _jsx("button", { type: "button", className: "blog_yoast-link-btn", onClick: () => document.getElementById("new-category-input")?.focus(), children: "+ Add New Category" }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("input", { id: "new-category-input", className: "blog_fld", placeholder: "New category", value: newCategory, onChange: (e) => setNewCategory(e.target.value), onKeyDown: (e) => {
387
387
  if (e.key === "Enter") {
388
388
  e.preventDefault();
389
389
  addCategory();
390
390
  }
391
- } }), _jsx("button", { type: "button", className: "btn", onClick: addCategory, disabled: !newCategory.trim(), children: "Add" })] })] })] }), _jsxs("div", { className: "box", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Tags" }) }), _jsxs("div", { className: "box-body stack", children: [_jsxs("div", { className: "tokens", children: [tagIds.map((id) => {
391
+ } }), _jsx("button", { type: "button", className: "blog_btn", onClick: addCategory, disabled: !newCategory.trim(), children: "Add" })] })] })] }), _jsxs("div", { className: "blog_box", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Tags" }) }), _jsxs("div", { className: "blog_box-body blog_stack", children: [_jsxs("div", { className: "blog_tokens", children: [tagIds.map((id) => {
392
392
  const tag = tags.find((t) => t.id === id);
393
- return (_jsxs("span", { className: "token", children: [tag?.name ?? "tag", _jsx("button", { type: "button", "aria-label": `Remove ${tag?.name ?? "tag"}`, onClick: () => setTagIds((list) => list.filter((t) => t !== id)), children: "\u2715" })] }, id));
394
- }), newTags.map((name) => (_jsxs("span", { className: "token token-new", children: [name, _jsx("button", { type: "button", "aria-label": `Remove ${name}`, onClick: () => setNewTags((list) => list.filter((t) => t !== name)), children: "\u2715" })] }, name)))] }), _jsxs("div", { className: "btn-row", children: [_jsx("input", { className: "fld", placeholder: "Add a tag and press Enter", value: tagDraft, list: "tag-suggestions", onChange: (e) => setTagDraft(e.target.value), onKeyDown: (e) => {
393
+ return (_jsxs("span", { className: "blog_token", children: [tag?.name ?? "tag", _jsx("button", { type: "button", "aria-label": `Remove ${tag?.name ?? "tag"}`, onClick: () => setTagIds((list) => list.filter((t) => t !== id)), children: "\u2715" })] }, id));
394
+ }), newTags.map((name) => (_jsxs("span", { className: "blog_token blog_token-new", children: [name, _jsx("button", { type: "button", "aria-label": `Remove ${name}`, onClick: () => setNewTags((list) => list.filter((t) => t !== name)), children: "\u2715" })] }, name)))] }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("input", { className: "blog_fld", placeholder: "Add a tag and press Enter", value: tagDraft, list: "tag-suggestions", onChange: (e) => setTagDraft(e.target.value), onKeyDown: (e) => {
395
395
  if (e.key === "Enter" || e.key === ",") {
396
396
  e.preventDefault();
397
397
  addTagFromDraft();
398
398
  }
399
- } }), _jsx("datalist", { id: "tag-suggestions", children: tags.map((t) => (_jsx("option", { value: t.name }, t.id))) }), _jsx("button", { type: "button", className: "btn", onClick: addTagFromDraft, disabled: !tagDraft.trim(), children: "Add" })] }), tags.filter((t) => !tagIds.includes(t.id)).length ? (_jsxs("div", { className: "tag-most-used", children: [_jsx("p", { className: "note", children: "Most used" }), _jsx("div", { className: "tag-cloud", children: tags
399
+ } }), _jsx("datalist", { id: "tag-suggestions", children: tags.map((t) => (_jsx("option", { value: t.name }, t.id))) }), _jsx("button", { type: "button", className: "blog_btn", onClick: addTagFromDraft, disabled: !tagDraft.trim(), children: "Add" })] }), tags.filter((t) => !tagIds.includes(t.id)).length ? (_jsxs("div", { className: "blog_tag-most-used", children: [_jsx("p", { className: "blog_note", children: "Most used" }), _jsx("div", { className: "blog_tag-cloud", children: tags
400
400
  .filter((t) => !tagIds.includes(t.id))
401
401
  .slice(0, 12)
402
- .map((t) => (_jsx("button", { type: "button", className: "tag-cloud-item", onClick: () => setTagIds((ids) => [...ids, t.id]), children: t.name }, t.id))) })] })) : null, _jsx("p", { className: "note", children: "New tags are created when the post is saved." })] })] }), _jsxs("div", { className: "box", children: [_jsxs("div", { className: "box-head", children: [_jsx("h3", { children: "Featured image" }), _jsx("span", { className: "box-hint", children: "optional" })] }), _jsxs("div", { className: `box-body drop-target${featuredDrag ? " is-dragging" : ""}`, onDragOver: (e) => {
402
+ .map((t) => (_jsx("button", { type: "button", className: "blog_tag-cloud-item", onClick: () => setTagIds((ids) => [...ids, t.id]), children: t.name }, t.id))) })] })) : null, _jsx("p", { className: "blog_note", children: "New tags are created when the post is saved." })] })] }), _jsxs("div", { className: "blog_box", children: [_jsxs("div", { className: "blog_box-head", children: [_jsx("h3", { children: "Featured image" }), _jsx("span", { className: "blog_box-hint", children: "optional" })] }), _jsxs("div", { className: `blog_box-body blog_drop-target${featuredDrag ? " blog_is-dragging" : ""}`, onDragOver: (e) => {
403
403
  e.preventDefault();
404
404
  setFeaturedDrag(true);
405
405
  }, onDragLeave: () => setFeaturedDrag(false), onDrop: (e) => {
@@ -411,18 +411,18 @@ export function PostEditor({ postId, onDone, }) {
411
411
  if (e.target.files?.length)
412
412
  void uploadFeatured(e.target.files);
413
413
  e.target.value = "";
414
- } }), featuredImage ? (_jsxs("div", { className: "stack", children: [_jsx("img", { className: "feat", src: featuredImage.url, alt: featuredImage.alt || "" }), _jsxs("label", { className: "fld-row feat-alt", children: [_jsxs("span", { className: "fld-lbl", children: ["Alt text ", _jsx("em", { className: "fld-em", children: "recommended for accessibility" })] }), _jsx("textarea", { className: "fld", rows: 2, value: featuredImage.alt, placeholder: "Describe the image for screen readers and SEO\u2026", onChange: (e) => {
414
+ } }), featuredImage ? (_jsxs("div", { className: "blog_stack", children: [_jsx("img", { className: "blog_feat", src: featuredImage.url, alt: featuredImage.alt || "" }), _jsxs("label", { className: "blog_fld-row blog_feat-alt", children: [_jsxs("span", { className: "blog_fld-lbl", children: ["Alt text ", _jsx("em", { className: "blog_fld-em", children: "recommended for accessibility" })] }), _jsx("textarea", { className: "blog_fld", rows: 2, value: featuredImage.alt, placeholder: "Describe the image for screen readers and SEO\u2026", onChange: (e) => {
415
415
  setFeaturedImage((img) => (img ? { ...img, alt: e.target.value } : img));
416
416
  setFeaturedAltSaved(false);
417
417
  }, onBlur: () => {
418
418
  if (featuredImage)
419
419
  saveFeaturedAlt();
420
- }, "aria-describedby": "feat-alt-hint" }), _jsx("span", { id: "feat-alt-hint", className: "note feat-alt-foot", children: featuredAltBusy
420
+ }, "aria-describedby": "feat-alt-hint" }), _jsx("span", { id: "feat-alt-hint", className: "blog_note blog_feat-alt-foot", children: featuredAltBusy
421
421
  ? "Saving alt text…"
422
422
  : featuredAltSaved
423
423
  ? "Alt text saved to the media library."
424
- : "Saved on the image itself — used on the public post and in SEO." })] }), _jsxs("div", { className: "btn-row", children: [_jsx("button", { type: "button", className: "btn btn-tiny", disabled: featuredAltBusy, onClick: () => saveFeaturedAlt(), children: featuredAltBusy ? "Saving…" : "Save alt text" }), _jsx("button", { type: "button", className: "btn btn-tiny", onClick: () => setPickerFor("featured"), children: "Replace image" }), _jsx("button", { type: "button", className: "btn btn-tiny", disabled: featuredBusy, onClick: () => featuredFileRef.current?.click(), children: featuredBusy ? "Uploading…" : "Upload" }), _jsx("button", { type: "button", className: "btn btn-tiny", onClick: () => {
424
+ : "Saved on the image itself — used on the public post and in SEO." })] }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", disabled: featuredAltBusy, onClick: () => saveFeaturedAlt(), children: featuredAltBusy ? "Saving…" : "Save alt text" }), _jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: () => setPickerFor("featured"), children: "Replace image" }), _jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", disabled: featuredBusy, onClick: () => featuredFileRef.current?.click(), children: featuredBusy ? "Uploading…" : "Upload" }), _jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: () => {
425
425
  setFeaturedImage(null);
426
426
  setFeaturedAltSaved(false);
427
- }, children: "Remove featured image" })] })] })) : (_jsxs("div", { className: "stack", children: [_jsx("button", { type: "button", className: "btn btn-block", onClick: () => setPickerFor("featured"), children: "Set featured image" }), _jsxs("button", { type: "button", className: "dropzone-cta", disabled: featuredBusy, onClick: () => featuredFileRef.current?.click(), children: [_jsx("span", { className: "dropzone-icon", "aria-hidden": "true", children: "\u2B06" }), _jsx("span", { children: featuredBusy ? "Uploading…" : "Or drop an image here to upload" }), _jsx("span", { className: "note", children: "JPEG, PNG, WebP or AVIF \u00B7 up to 12 MB \u00B7 add alt text after upload" })] })] }))] })] }), _jsxs("div", { className: "box", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Post Attributes" }) }), _jsx("div", { className: "box-body stack", children: _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Template" }), _jsx("select", { className: "fld", value: template, onChange: (e) => setTemplate(e.target.value), children: _jsx("option", { value: "default", children: "Default template" }) })] }) })] }), _jsxs("div", { className: "box", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Authors" }) }), _jsxs("div", { className: "box-body stack", children: [_jsx("div", { className: "pick-list", children: authors.length === 0 ? (_jsxs("p", { className: "note", children: ["No authors for ", brand?.name ?? "this brand", " yet \u2014 create them on the Authors screen."] })) : (authors.map((a) => (_jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: authorIds.includes(a.id), onChange: (e) => setAuthorIds((ids) => e.target.checked ? [...ids, a.id] : ids.filter((x) => x !== a.id)) }), _jsxs("span", { children: [a.name, a.name === profile.name ? _jsx("span", { className: "box-hint", children: " \u00B7 you" }) : null] })] }, a.id)))) }), _jsx("p", { className: "note", children: "You are selected by default. Add or remove others anytime." }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Author Box" }), _jsx("select", { className: "fld", value: authorBox, onChange: (e) => setAuthorBox(e.target.value), children: _jsx("option", { value: "default", children: "Default Author Box" }) })] })] })] }), _jsxs("div", { className: "box", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Discussion" }) }), _jsxs("div", { className: "box-body stack", children: [_jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: allowComments, onChange: (e) => setAllowComments(e.target.checked) }), _jsx("span", { children: "Allow comments on this post" })] }), _jsx("p", { className: "note", children: "When checked, readers can leave comments on the published article. Uncheck to close the discussion without deleting existing comments." })] })] }), _jsxs("div", { className: "box", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Table of Contents" }) }), _jsxs("div", { className: "box-body stack", children: [_jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: showToc, onChange: (e) => setShowToc(e.target.checked) }), _jsx("span", { children: "Show Table of Contents on this post" })] }), _jsx("p", { className: "note", children: "When checked, the published article shows a right-side Table of Contents listing other published posts from this brand. Leave unchecked to hide the card." })] })] })] }), _jsx(MediaPicker, { open: pickerFor !== null, brandId: brandId || null, onClose: () => setPickerFor(null), onSelect: choosePicked, title: pickerFor === "og" ? "Social share image" : "Featured image" })] }));
427
+ }, children: "Remove featured image" })] })] })) : (_jsxs("div", { className: "blog_stack", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-block", onClick: () => setPickerFor("featured"), children: "Set featured image" }), _jsxs("button", { type: "button", className: "blog_dropzone-cta", disabled: featuredBusy, onClick: () => featuredFileRef.current?.click(), children: [_jsx("span", { className: "blog_dropzone-icon", "aria-hidden": "true", children: "\u2B06" }), _jsx("span", { children: featuredBusy ? "Uploading…" : "Or drop an image here to upload" }), _jsx("span", { className: "blog_note", children: "JPEG, PNG, WebP or AVIF \u00B7 up to 12 MB \u00B7 add alt text after upload" })] })] }))] })] }), _jsxs("div", { className: "blog_box", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Post Attributes" }) }), _jsx("div", { className: "blog_box-body blog_stack", children: _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Template" }), _jsx("select", { className: "blog_fld", value: template, onChange: (e) => setTemplate(e.target.value), children: _jsx("option", { value: "default", children: "Default template" }) })] }) })] }), _jsxs("div", { className: "blog_box", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Authors" }) }), _jsxs("div", { className: "blog_box-body blog_stack", children: [_jsx("div", { className: "blog_pick-list", children: authors.length === 0 ? (_jsxs("p", { className: "blog_note", children: ["No authors for ", brand?.name ?? "this brand", " yet \u2014 create them on the Authors screen."] })) : (authors.map((a) => (_jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: authorIds.includes(a.id), onChange: (e) => setAuthorIds((ids) => e.target.checked ? [...ids, a.id] : ids.filter((x) => x !== a.id)) }), _jsxs("span", { children: [a.name, a.name === profile.name ? _jsx("span", { className: "blog_box-hint", children: " \u00B7 you" }) : null] })] }, a.id)))) }), _jsx("p", { className: "blog_note", children: "You are selected by default. Add or remove others anytime." }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Author Box" }), _jsx("select", { className: "blog_fld", value: authorBox, onChange: (e) => setAuthorBox(e.target.value), children: _jsx("option", { value: "default", children: "Default Author Box" }) })] })] })] }), _jsxs("div", { className: "blog_box", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Discussion" }) }), _jsxs("div", { className: "blog_box-body blog_stack", children: [_jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: allowComments, onChange: (e) => setAllowComments(e.target.checked) }), _jsx("span", { children: "Allow comments on this post" })] }), _jsx("p", { className: "blog_note", children: "When checked, readers can leave comments on the published article. Uncheck to close the discussion without deleting existing comments." })] })] }), _jsxs("div", { className: "blog_box", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Table of Contents" }) }), _jsxs("div", { className: "blog_box-body blog_stack", children: [_jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: showToc, onChange: (e) => setShowToc(e.target.checked) }), _jsx("span", { children: "Show Table of Contents on this post" })] }), _jsx("p", { className: "blog_note", children: "When checked, the published article shows a right-side Table of Contents listing other published posts from this brand. Leave unchecked to hide the card." })] })] })] }), _jsx(MediaPicker, { open: pickerFor !== null, brandId: brandId || null, onClose: () => setPickerFor(null), onSelect: choosePicked, title: pickerFor === "og" ? "Social share image" : "Featured image" })] }));
428
428
  }