@canvas-digital/blog-sdk 2.0.4 → 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 (52) hide show
  1. package/dist/components/admin/AdminPostDetail.js +5 -5
  2. package/dist/components/admin/BrandSettings.js +5 -5
  3. package/dist/components/admin/BrandSwitcher.js +1 -1
  4. package/dist/components/admin/Chips.js +5 -5
  5. package/dist/components/admin/CommentsManager.js +6 -6
  6. package/dist/components/admin/Dashboard.js +1 -1
  7. package/dist/components/admin/MediaLibrary.js +5 -5
  8. package/dist/components/admin/MediaPicker.js +4 -4
  9. package/dist/components/admin/PostList.js +3 -3
  10. package/dist/components/admin/PostsTable.d.ts.map +1 -1
  11. package/dist/components/admin/PostsTable.js +10 -10
  12. package/dist/components/admin/Shell.js +3 -3
  13. package/dist/components/admin/TermManager.js +4 -4
  14. package/dist/components/admin/UsersManager.js +3 -3
  15. package/dist/components/admin/charts.js +7 -7
  16. package/dist/components/admin/editor/PostEditor.js +16 -16
  17. package/dist/components/admin/editor/RichTextEditor.js +8 -8
  18. package/dist/components/admin/editor/YoastCollapsible.js +2 -2
  19. package/dist/components/admin/editor/YoastInsightsPanel.js +1 -1
  20. package/dist/components/admin/editor/YoastInternalLinksPanel.js +1 -1
  21. package/dist/components/admin/editor/YoastSeoAnalysisPanel.js +6 -6
  22. package/dist/components/admin/editor/YoastSeoMetabox.js +8 -8
  23. package/dist/components/admin/editor/YoastSnippetField.js +2 -2
  24. package/dist/components/admin/internal/States.js +3 -3
  25. package/dist/components/admin/seo/Ga4Settings.js +6 -6
  26. package/dist/components/admin/seo/RedirectAnalyticsDashboard.js +1 -1
  27. package/dist/components/admin/seo/RedirectDetail.js +6 -6
  28. package/dist/components/admin/seo/RedirectForm.js +1 -1
  29. package/dist/components/admin/seo/RedirectList.js +4 -4
  30. package/dist/components/admin/seo/RobotsEditor.js +1 -1
  31. package/dist/components/admin/seo/shared.js +2 -2
  32. package/dist/components/admin/tools/ToolsHub.js +4 -4
  33. package/dist/components/user/BlogCard.js +3 -3
  34. package/dist/components/user/BlogCategories.js +1 -1
  35. package/dist/components/user/BlogDetail.js +1 -1
  36. package/dist/components/user/BlogList.js +1 -1
  37. package/dist/components/user/BlogSearch.js +2 -2
  38. package/dist/components/user/BlogTags.js +1 -1
  39. package/dist/components/user/FeaturedBlogs.js +1 -1
  40. package/dist/components/user/RelatedBlogs.js +1 -1
  41. package/dist/components/user/SiteMediaHero.js +1 -1
  42. package/dist/components/user/detail/ArticleDetailHero.js +5 -5
  43. package/dist/components/user/detail/ArticleRailDetails.js +2 -2
  44. package/dist/components/user/detail/CommentSection.js +2 -2
  45. package/dist/components/user/detail/HeroFadeSlide.js +1 -1
  46. package/dist/components/user/detail/ReadingProgress.js +1 -1
  47. package/dist/components/user/detail/ShareRow.js +1 -1
  48. package/dist/components/user/internal/States.js +4 -4
  49. package/dist/lib/lexical-doc.js +1 -1
  50. package/dist/pages/admin/BlogAdmin.js +7 -7
  51. package/dist/style.css +1018 -1018
  52. package/package.json +2 -1
@@ -19,11 +19,11 @@ const TABS = [
19
19
  { id: 'schema', label: 'Schema' },
20
20
  { id: 'social', label: 'Social' },
21
21
  ];
22
- const Dot = ({ tone }) => (_jsx("span", { className: `yoast-dot yoast-dot-${tone}`, "aria-hidden": "true" }));
22
+ const Dot = ({ tone }) => (_jsx("span", { className: `blog_yoast-dot blog_yoast-dot-${tone}`, "aria-hidden": "true" }));
23
23
  const CheckList = ({ title, items, count }) => {
24
24
  if (!items.length)
25
25
  return null;
26
- return (_jsxs("div", { className: "seo-group", children: [title ? (_jsxs("p", { className: "seo-group-title", children: [title, count ? _jsxs("span", { className: "yoast-count", children: [" (", items.length, ")"] }) : null] })) : null, _jsx("ul", { className: "seo-checks", children: items.map((c) => (_jsxs("li", { children: [_jsx(Dot, { tone: c.tone }), _jsxs("div", { children: [_jsx("strong", { children: c.label }), _jsx("span", { children: c.detail })] })] }, c.id))) })] }));
26
+ return (_jsxs("div", { className: "blog_seo-group", children: [title ? (_jsxs("p", { className: "blog_seo-group-title", children: [title, count ? _jsxs("span", { className: "blog_yoast-count", children: [" (", items.length, ")"] }) : null] })) : null, _jsx("ul", { className: "blog_seo-checks", children: items.map((c) => (_jsxs("li", { children: [_jsx(Dot, { tone: c.tone }), _jsxs("div", { children: [_jsx("strong", { children: c.label }), _jsx("span", { children: c.detail })] })] }, c.id))) })] }));
27
27
  };
28
28
  const highlightPhrase = (text, phrase) => {
29
29
  if (!phrase.trim() || !text)
@@ -76,26 +76,26 @@ export const YoastSeoMetabox = ({ title, slug, excerpt, visibility, featuredImag
76
76
  const previewHost = `${(siteName || 'example').toLowerCase().replace(/[^a-z0-9]+/g, '')}.com`;
77
77
  const hasKeyphrase = Boolean(seo.focusKeyphrase.trim());
78
78
  const seoTitleQuickVars = SEO_TITLE_QUICK;
79
- return (_jsxs("div", { className: "box yoast-box", id: "wpseo_meta", children: [_jsx("div", { className: "box-head", children: _jsx("h3", { children: "Yoast SEO" }) }), _jsx("div", { className: "yoast-tabs", role: "tablist", "aria-label": "Yoast SEO", children: TABS.map(({ id, label }) => (_jsxs("button", { type: "button", role: "tab", id: `yoast-tab-${id}`, "aria-selected": tab === id, "aria-controls": `yoast-panel-${id}`, className: `yoast-tab${tab === id ? ' is-active' : ''}`, onClick: () => setTab(id), children: [_jsx(Dot, { tone: tabTone[id] }), label] }, id))) }), _jsxs("div", { className: "box-body yoast-inside wpseo-metabox-content", children: [tab === 'seo' ? (_jsxs("div", { className: "yoast-panel yoast-panel-seo", role: "tabpanel", id: "yoast-panel-seo", "aria-labelledby": "yoast-tab-seo", children: [_jsx("p", { className: "yoast-intro", children: "Optimize your content for discovery." }), _jsxs("div", { className: "yoast-accordion", children: [_jsx(YoastCollapsible, { title: "Focus keyphrase", defaultOpen: false, status: !hasKeyphrase ? _jsx("span", { className: "yoast-status-bad", title: "Missing focus keyphrase", children: "!" }) : _jsx(Dot, { tone: seoTone }), children: _jsx("div", { className: "yoast-accordion-panel", children: _jsxs("div", { className: "yoast-field", children: [_jsx("input", { id: "yoast-focus-keyphrase", className: "fld yoast-input", value: seo.focusKeyphrase, "aria-label": "Focus keyphrase", onChange: (e) => onSeoChange('focusKeyphrase', e.target.value) }), _jsxs("p", { className: "yoast-help", children: ["Use the main word or phrase you want your content found for across search, AI, and beyond.", ' ', _jsx("a", { className: "yoast-learn-more", href: "https://yoast.com/focus-keyword/", target: "_blank", rel: "noreferrer", children: "Learn more about keyword research" })] }), _jsx("button", { type: "button", className: "yoast-link-btn", disabled: true, title: "Requires Yoast SEO Premium", children: "Get related keyphrases" })] }) }) }), !hasKeyphrase ? (_jsx("p", { className: "yoast-accordion-note", role: "status", children: "Please enter a focus keyphrase to see your SEO score." })) : null, _jsx(YoastCollapsible, { title: "Google preview", defaultOpen: false, children: _jsxs("div", { className: "yoast-accordion-panel", children: [_jsxs("div", { className: "yoast-preview-toolbar", children: [_jsx("span", { className: "yoast-preview-label", children: "Preview as:" }), _jsxs("div", { className: "yoast-preview-modes", role: "group", "aria-label": "Preview device", children: [_jsx("button", { type: "button", className: `yoast-preview-mode${previewMode === 'mobile' ? ' is-active' : ''}`, "aria-pressed": previewMode === 'mobile', onClick: () => setPreviewMode('mobile'), children: "Mobile result" }), _jsx("button", { type: "button", className: `yoast-preview-mode${previewMode === 'desktop' ? ' is-active' : ''}`, "aria-pressed": previewMode === 'desktop', onClick: () => setPreviewMode('desktop'), children: "Desktop result" })] })] }), _jsxs("div", { className: `yoast-google-card yoast-google-${previewMode}`, children: [_jsxs("div", { className: "yoast-google-site", children: [_jsx("span", { className: "yoast-google-favicon", "aria-hidden": "true", children: siteName.charAt(0).toUpperCase() }), _jsxs("div", { className: "yoast-google-site-meta", children: [_jsx("div", { className: "yoast-google-site-name", children: siteName }), _jsxs("div", { className: "serp-url mono", children: [previewHost, " \u203A blog \u203A ", slugDisplay] })] })] }), _jsx("div", { className: "serp-title yoast-google-title", children: highlightPhrase(seoTitle || title || 'Your post title', seo.focusKeyphrase) }), _jsx("div", { className: "serp-desc yoast-google-desc", children: highlightPhrase(metaDesc || 'Please provide a meta description by editing the snippet below.', seo.focusKeyphrase) })] }), _jsxs("div", { className: "yoast-snippet-fields stack", children: [_jsx(YoastSnippetField, { id: "yoast-seo-title", label: "SEO title", value: seo.metaTitle, placeholder: title || 'Falls back to the post title', maxLength: SEO_FIELD_LIMITS.metaTitle, expandedLength: seoTitle.length, meterGoodMin: 30, meterGoodMax: 60, meterMax: SEO_FIELD_LIMITS.metaTitle, variables: SEO_TITLE_VARIABLES, quickVariables: seoTitleQuickVars, generateLabel: "Generate SEO title", error: fieldErrors['seo.metaTitle'], onChange: (v) => {
79
+ return (_jsxs("div", { className: "blog_box blog_yoast-box", id: "wpseo_meta", children: [_jsx("div", { className: "blog_box-head", children: _jsx("h3", { children: "Yoast SEO" }) }), _jsx("div", { className: "blog_yoast-tabs", role: "tablist", "aria-label": "Yoast SEO", children: TABS.map(({ id, label }) => (_jsxs("button", { type: "button", role: "tab", id: `yoast-tab-${id}`, "aria-selected": tab === id, "aria-controls": `yoast-panel-${id}`, className: `blog_yoast-tab${tab === id ? ' blog_is-active' : ''}`, onClick: () => setTab(id), children: [_jsx(Dot, { tone: tabTone[id] }), label] }, id))) }), _jsxs("div", { className: "blog_box-body blog_yoast-inside blog_wpseo-metabox-content", children: [tab === 'seo' ? (_jsxs("div", { className: "blog_yoast-panel blog_yoast-panel-seo", role: "tabpanel", id: "yoast-panel-seo", "aria-labelledby": "yoast-tab-seo", children: [_jsx("p", { className: "blog_yoast-intro", children: "Optimize your content for discovery." }), _jsxs("div", { className: "blog_yoast-accordion", children: [_jsx(YoastCollapsible, { title: "Focus keyphrase", defaultOpen: false, status: !hasKeyphrase ? _jsx("span", { className: "blog_yoast-status-bad", title: "Missing focus keyphrase", children: "!" }) : _jsx(Dot, { tone: seoTone }), children: _jsx("div", { className: "blog_yoast-accordion-panel", children: _jsxs("div", { className: "blog_yoast-field", children: [_jsx("input", { id: "yoast-focus-keyphrase", className: "blog_fld blog_yoast-input", value: seo.focusKeyphrase, "aria-label": "Focus keyphrase", onChange: (e) => onSeoChange('focusKeyphrase', e.target.value) }), _jsxs("p", { className: "blog_yoast-help", children: ["Use the main word or phrase you want your content found for across search, AI, and beyond.", ' ', _jsx("a", { className: "blog_yoast-learn-more", href: "https://yoast.com/focus-keyword/", target: "_blank", rel: "noreferrer", children: "Learn more about keyword research" })] }), _jsx("button", { type: "button", className: "blog_yoast-link-btn", disabled: true, title: "Requires Yoast SEO Premium", children: "Get related keyphrases" })] }) }) }), !hasKeyphrase ? (_jsx("p", { className: "blog_yoast-accordion-note", role: "status", children: "Please enter a focus keyphrase to see your SEO score." })) : null, _jsx(YoastCollapsible, { title: "Google preview", defaultOpen: false, children: _jsxs("div", { className: "blog_yoast-accordion-panel", children: [_jsxs("div", { className: "blog_yoast-preview-toolbar", children: [_jsx("span", { className: "blog_yoast-preview-label", children: "Preview as:" }), _jsxs("div", { className: "blog_yoast-preview-modes", role: "group", "aria-label": "Preview device", children: [_jsx("button", { type: "button", className: `blog_yoast-preview-mode${previewMode === 'mobile' ? ' blog_is-active' : ''}`, "aria-pressed": previewMode === 'mobile', onClick: () => setPreviewMode('mobile'), children: "Mobile result" }), _jsx("button", { type: "button", className: `blog_yoast-preview-mode${previewMode === 'desktop' ? ' blog_is-active' : ''}`, "aria-pressed": previewMode === 'desktop', onClick: () => setPreviewMode('desktop'), children: "Desktop result" })] })] }), _jsxs("div", { className: `blog_yoast-google-card blog_yoast-google-${previewMode}`, children: [_jsxs("div", { className: "blog_yoast-google-site", children: [_jsx("span", { className: "blog_yoast-google-favicon", "aria-hidden": "true", children: siteName.charAt(0).toUpperCase() }), _jsxs("div", { className: "blog_yoast-google-site-meta", children: [_jsx("div", { className: "blog_yoast-google-site-name", children: siteName }), _jsxs("div", { className: "blog_serp-url blog_mono", children: [previewHost, " \u203A blog \u203A ", slugDisplay] })] })] }), _jsx("div", { className: "blog_serp-title blog_yoast-google-title", children: highlightPhrase(seoTitle || title || 'Your post title', seo.focusKeyphrase) }), _jsx("div", { className: "blog_serp-desc blog_yoast-google-desc", children: highlightPhrase(metaDesc || 'Please provide a meta description by editing the snippet below.', seo.focusKeyphrase) })] }), _jsxs("div", { className: "blog_yoast-snippet-fields blog_stack", children: [_jsx(YoastSnippetField, { id: "yoast-seo-title", label: "SEO title", value: seo.metaTitle, placeholder: title || 'Falls back to the post title', maxLength: SEO_FIELD_LIMITS.metaTitle, expandedLength: seoTitle.length, meterGoodMin: 30, meterGoodMax: 60, meterMax: SEO_FIELD_LIMITS.metaTitle, variables: SEO_TITLE_VARIABLES, quickVariables: seoTitleQuickVars, generateLabel: "Generate SEO title", error: fieldErrors['seo.metaTitle'], onChange: (v) => {
80
80
  onClearFieldError('seo.metaTitle');
81
81
  onSeoChange('metaTitle', v);
82
- }, onGenerate: () => onSeoChange('metaTitle', generateSeoTitleSnippet(titleTemplate)) }), _jsxs("div", { className: "yoast-field", children: [_jsx("label", { className: "yoast-label", htmlFor: "yoast-slug", children: "Slug" }), _jsx("input", { id: "yoast-slug", className: "fld yoast-input mono", value: slug, placeholder: slugify(title) || 'post-slug', onChange: (e) => onSlugChange(e.target.value), onBlur: onSlugBlur })] }), _jsx(YoastSnippetField, { id: "yoast-meta-description", label: "Meta description", value: seo.metaDescription, placeholder: "Falls back to the excerpt. Aim for 140\u2013160 characters.", multiline: true, maxLength: SEO_FIELD_LIMITS.metaDescription, expandedLength: metaDesc.length, meterGoodMin: 120, meterGoodMax: 156, meterMax: SEO_FIELD_LIMITS.metaDescription, variables: META_DESCRIPTION_VARIABLES, quickVariables: META_DESCRIPTION_VARIABLES.slice(0, 2), generateLabel: "Generate meta description", error: fieldErrors['seo.metaDescription'], onChange: (v) => {
82
+ }, onGenerate: () => onSeoChange('metaTitle', generateSeoTitleSnippet(titleTemplate)) }), _jsxs("div", { className: "blog_yoast-field", children: [_jsx("label", { className: "blog_yoast-label", htmlFor: "yoast-slug", children: "Slug" }), _jsx("input", { id: "yoast-slug", className: "blog_fld blog_yoast-input blog_mono", value: slug, placeholder: slugify(title) || 'post-slug', onChange: (e) => onSlugChange(e.target.value), onBlur: onSlugBlur })] }), _jsx(YoastSnippetField, { id: "yoast-meta-description", label: "Meta description", value: seo.metaDescription, placeholder: "Falls back to the excerpt. Aim for 140\u2013160 characters.", multiline: true, maxLength: SEO_FIELD_LIMITS.metaDescription, expandedLength: metaDesc.length, meterGoodMin: 120, meterGoodMax: 156, meterMax: SEO_FIELD_LIMITS.metaDescription, variables: META_DESCRIPTION_VARIABLES, quickVariables: META_DESCRIPTION_VARIABLES.slice(0, 2), generateLabel: "Generate meta description", error: fieldErrors['seo.metaDescription'], onChange: (v) => {
83
83
  onClearFieldError('seo.metaDescription');
84
84
  onSeoChange('metaDescription', v);
85
- }, onGenerate: () => onSeoChange('metaDescription', generateMetaDescriptionSnippet(snippetCtx)) })] })] }) }), _jsx(YoastCollapsible, { title: "SEO analysis", defaultOpen: false, status: _jsx(Dot, { tone: hasKeyphrase ? seoTone : 'bad' }), children: _jsx(YoastSeoAnalysisPanel, { checks: seoChecks, tone: seoTone, hasKeyphrase: hasKeyphrase }) }), _jsx(YoastCollapsible, { title: "Track SEO performance", defaultOpen: false, children: _jsxs("div", { className: "yoast-accordion-panel", children: [_jsx("p", { className: "yoast-help", children: "Track your rankings and see how your content performs in search." }), _jsxs("button", { type: "button", className: "yoast-premium-inline-btn", disabled: true, children: [_jsx("span", { className: "yoast-footer-badge", children: "Wincher" }), "Track SEO performance"] })] }) }), _jsx(YoastCollapsible, { title: "Cornerstone content", defaultOpen: false, children: _jsxs("div", { className: "yoast-accordion-panel", children: [_jsxs("label", { className: "yoast-toggle-row", children: [_jsx("input", { type: "checkbox", checked: cornerstone, onChange: (e) => setCornerstone(e.target.checked) }), _jsx("span", { children: "Mark as cornerstone content" })] }), _jsx("p", { className: "yoast-help", children: "Cornerstone articles should be the most important on your site." })] }) }), _jsx(YoastCollapsible, { title: "Advanced", defaultOpen: false, children: _jsx("div", { className: "yoast-accordion-panel", children: _jsxs("div", { className: "stack", children: [_jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Allow search engines to show this Post in search results?" }), _jsxs("select", { className: "fld", value: seo.noindex || visibility === 'private' ? 'no' : 'default', onChange: (e) => onSeoChange('noindex', e.target.value === 'no'), children: [_jsx("option", { value: "default", children: "Default for Posts (Yes)" }), _jsx("option", { value: "yes", children: "Yes" }), _jsx("option", { value: "no", children: "No" })] })] }), _jsxs("fieldset", { className: "yoast-radio-fieldset", children: [_jsx("legend", { children: "Should search engines follow links on this Post?" }), _jsxs("label", { children: [_jsx("input", { type: "radio", name: "yoast-nofollow", checked: !seo.nofollow, onChange: () => onSeoChange('nofollow', false) }), "Yes"] }), _jsxs("label", { children: [_jsx("input", { type: "radio", name: "yoast-nofollow", checked: seo.nofollow, onChange: () => onSeoChange('nofollow', true) }), "No"] })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Meta robots advanced" }), _jsxs("select", { className: "fld", value: metaRobots, onChange: (e) => setMetaRobots(e.target.value), children: [_jsx("option", { value: "", children: "\u2014 None \u2014" }), _jsx("option", { value: "noimageindex", children: "No Image Index" }), _jsx("option", { value: "noarchive", children: "No Archive" }), _jsx("option", { value: "nosnippet", children: "No Snippet" })] })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Breadcrumbs title" }), _jsx("input", { className: "fld", value: seo.breadcrumbTitle, placeholder: title || 'Same as post title', onChange: (e) => onSeoChange('breadcrumbTitle', e.target.value) })] }), _jsxs("label", { className: "fld-row", id: "seo-canonical", children: [_jsx("span", { className: "fld-lbl", children: "Canonical URL" }), _jsx("input", { className: `fld mono${fieldErrors['seo.canonicalOverride'] ? ' is-invalid' : ''}`, type: "url", inputMode: "url", autoComplete: "off", spellCheck: false, value: seo.canonicalOverride, placeholder: "https://brand.com/blog/post", onChange: (e) => {
85
+ }, onGenerate: () => onSeoChange('metaDescription', generateMetaDescriptionSnippet(snippetCtx)) })] })] }) }), _jsx(YoastCollapsible, { title: "SEO analysis", defaultOpen: false, status: _jsx(Dot, { tone: hasKeyphrase ? seoTone : 'bad' }), children: _jsx(YoastSeoAnalysisPanel, { checks: seoChecks, tone: seoTone, hasKeyphrase: hasKeyphrase }) }), _jsx(YoastCollapsible, { title: "Track SEO performance", defaultOpen: false, children: _jsxs("div", { className: "blog_yoast-accordion-panel", children: [_jsx("p", { className: "blog_yoast-help", children: "Track your rankings and see how your content performs in search." }), _jsxs("button", { type: "button", className: "blog_yoast-premium-inline-btn", disabled: true, children: [_jsx("span", { className: "blog_yoast-footer-badge", children: "Wincher" }), "Track SEO performance"] })] }) }), _jsx(YoastCollapsible, { title: "Cornerstone content", defaultOpen: false, children: _jsxs("div", { className: "blog_yoast-accordion-panel", children: [_jsxs("label", { className: "blog_yoast-toggle-row", children: [_jsx("input", { type: "checkbox", checked: cornerstone, onChange: (e) => setCornerstone(e.target.checked) }), _jsx("span", { children: "Mark as cornerstone content" })] }), _jsx("p", { className: "blog_yoast-help", children: "Cornerstone articles should be the most important on your site." })] }) }), _jsx(YoastCollapsible, { title: "Advanced", defaultOpen: false, children: _jsx("div", { className: "blog_yoast-accordion-panel", children: _jsxs("div", { className: "blog_stack", children: [_jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Allow search engines to show this Post in search results?" }), _jsxs("select", { className: "blog_fld", value: seo.noindex || visibility === 'private' ? 'no' : 'default', onChange: (e) => onSeoChange('noindex', e.target.value === 'no'), children: [_jsx("option", { value: "default", children: "Default for Posts (Yes)" }), _jsx("option", { value: "yes", children: "Yes" }), _jsx("option", { value: "no", children: "No" })] })] }), _jsxs("fieldset", { className: "blog_yoast-radio-fieldset", children: [_jsx("legend", { children: "Should search engines follow links on this Post?" }), _jsxs("label", { children: [_jsx("input", { type: "radio", name: "yoast-nofollow", checked: !seo.nofollow, onChange: () => onSeoChange('nofollow', false) }), "Yes"] }), _jsxs("label", { children: [_jsx("input", { type: "radio", name: "yoast-nofollow", checked: seo.nofollow, onChange: () => onSeoChange('nofollow', true) }), "No"] })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Meta robots advanced" }), _jsxs("select", { className: "blog_fld", value: metaRobots, onChange: (e) => setMetaRobots(e.target.value), children: [_jsx("option", { value: "", children: "\u2014 None \u2014" }), _jsx("option", { value: "noimageindex", children: "No Image Index" }), _jsx("option", { value: "noarchive", children: "No Archive" }), _jsx("option", { value: "nosnippet", children: "No Snippet" })] })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Breadcrumbs title" }), _jsx("input", { className: "blog_fld", value: seo.breadcrumbTitle, placeholder: title || 'Same as post title', onChange: (e) => onSeoChange('breadcrumbTitle', e.target.value) })] }), _jsxs("label", { className: "blog_fld-row", id: "seo-canonical", children: [_jsx("span", { className: "blog_fld-lbl", children: "Canonical URL" }), _jsx("input", { className: `blog_fld blog_mono${fieldErrors['seo.canonicalOverride'] ? ' blog_is-invalid' : ''}`, type: "url", inputMode: "url", autoComplete: "off", spellCheck: false, value: seo.canonicalOverride, placeholder: "https://brand.com/blog/post", onChange: (e) => {
86
86
  onSeoChange('canonicalOverride', e.target.value);
87
87
  onClearFieldError('seo.canonicalOverride');
88
88
  }, onBlur: (e) => {
89
89
  const check = validateCanonicalOverride(e.target.value);
90
90
  if (check !== true)
91
91
  onSetFieldError('seo.canonicalOverride', check);
92
- } }), fieldErrors['seo.canonicalOverride'] ? (_jsx("span", { className: "fld-error", children: fieldErrors['seo.canonicalOverride'] })) : (_jsx("span", { className: "fld-hint", children: CANONICAL_HINT }))] })] }) }) }), _jsx(YoastCollapsible, { title: "Insights", defaultOpen: false, children: _jsx(YoastInsightsPanel, { contentText: contentText }) }), _jsx(YoastCollapsible, { title: "Internal linking suggestions", defaultOpen: false, children: _jsx(YoastInternalLinksPanel, { contentHtml: contentHtml }) })] })] })) : null, tab === 'readability' ? (_jsxs("div", { className: "yoast-panel", role: "tabpanel", id: "yoast-panel-readability", "aria-labelledby": "yoast-tab-readability", children: [_jsx("p", { className: "yoast-intro", children: "Make your content easy to read. Yoast SEO checks sentence length, passive voice, and more." }), _jsx("div", { className: "yoast-accordion", children: _jsx(YoastCollapsible, { title: "Readability analysis", status: _jsx(Dot, { tone: readTone }), defaultOpen: false, children: _jsx(YoastReadabilityPanel, { checks: readChecks, tone: readTone }) }) })] })) : null, tab === 'schema' ? (_jsxs("div", { className: "yoast-panel", role: "tabpanel", id: "yoast-panel-schema", "aria-labelledby": "yoast-tab-schema", children: [_jsx("p", { className: "yoast-intro", children: "Yoast SEO automatically describes your pages using schema.org. You can change the article type below." }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Page type" }), _jsx("input", { className: "fld", value: "Web Page", readOnly: true, disabled: true }), _jsx("span", { className: "fld-hint", children: "Fixed for blog posts." })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Article type" }), _jsxs("select", { className: "fld", value: seo.schemaType, onChange: (e) => onSeoChange('schemaType', e.target.value), children: [_jsx("option", { value: "Article", children: "Article" }), _jsx("option", { value: "BlogPosting", children: "Blog posting" }), _jsx("option", { value: "NewsArticle", children: "News article" })] })] }), _jsxs("div", { className: "yoast-schema-preview", children: [_jsx("p", { className: "yoast-section-title", children: "Structured data preview" }), _jsxs("ul", { className: "yoast-schema-list", children: [_jsxs("li", { children: [_jsx("strong", { children: seo.schemaType }), " \u2014 headline, dates, authors, publisher"] }), _jsxs("li", { children: [_jsx("strong", { children: "BreadcrumbList" }), " \u2014 Home \u203A Blog \u203A ", categoryName || 'category', " \u203A post"] }), _jsxs("li", { children: [_jsx("strong", { children: "Organization" }), " \u2014 ", siteName] })] })] })] })) : null, tab === 'social' ? (_jsxs("div", { className: "yoast-panel", role: "tabpanel", id: "yoast-panel-social", "aria-labelledby": "yoast-tab-social", children: [_jsx("p", { className: "yoast-intro", children: "Determine how your post should look on social media and in messaging apps." }), _jsxs("div", { className: "yoast-social-preview", children: [socialImage ? (_jsx("img", { className: "yoast-social-img", src: socialImage.url, alt: socialImage.alt || '' })) : (_jsx("div", { className: "yoast-social-img yoast-social-img-empty", children: "No image set" })), _jsxs("div", { className: "yoast-social-text", children: [_jsx("div", { className: "yoast-social-site", children: siteName.toUpperCase() }), _jsx("div", { className: "yoast-social-title", children: socialTitle || 'Post title' }), _jsx("div", { className: "yoast-social-desc", children: socialDesc || 'Description preview…' })] })] }), _jsxs("label", { className: "fld-row", children: [_jsxs("span", { className: "fld-lbl", children: ["Social title ", _jsxs("em", { children: [socialTitle.length, "/", SEO_FIELD_LIMITS.ogTitle] })] }), _jsx("input", { className: `fld${fieldErrors['seo.ogTitle'] ? ' is-invalid' : ''}`, maxLength: SEO_FIELD_LIMITS.ogTitle, value: seo.ogTitle, placeholder: seoTitle || title || 'Falls back to SEO title', onChange: (e) => {
92
+ } }), fieldErrors['seo.canonicalOverride'] ? (_jsx("span", { className: "blog_fld-error", children: fieldErrors['seo.canonicalOverride'] })) : (_jsx("span", { className: "blog_fld-hint", children: CANONICAL_HINT }))] })] }) }) }), _jsx(YoastCollapsible, { title: "Insights", defaultOpen: false, children: _jsx(YoastInsightsPanel, { contentText: contentText }) }), _jsx(YoastCollapsible, { title: "Internal linking suggestions", defaultOpen: false, children: _jsx(YoastInternalLinksPanel, { contentHtml: contentHtml }) })] })] })) : null, tab === 'readability' ? (_jsxs("div", { className: "blog_yoast-panel", role: "tabpanel", id: "yoast-panel-readability", "aria-labelledby": "yoast-tab-readability", children: [_jsx("p", { className: "blog_yoast-intro", children: "Make your content easy to read. Yoast SEO checks sentence length, passive voice, and more." }), _jsx("div", { className: "blog_yoast-accordion", children: _jsx(YoastCollapsible, { title: "Readability analysis", status: _jsx(Dot, { tone: readTone }), defaultOpen: false, children: _jsx(YoastReadabilityPanel, { checks: readChecks, tone: readTone }) }) })] })) : null, tab === 'schema' ? (_jsxs("div", { className: "blog_yoast-panel", role: "tabpanel", id: "yoast-panel-schema", "aria-labelledby": "yoast-tab-schema", children: [_jsx("p", { className: "blog_yoast-intro", children: "Yoast SEO automatically describes your pages using schema.org. You can change the article type below." }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Page type" }), _jsx("input", { className: "blog_fld", value: "Web Page", readOnly: true, disabled: true }), _jsx("span", { className: "blog_fld-hint", children: "Fixed for blog posts." })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Article type" }), _jsxs("select", { className: "blog_fld", value: seo.schemaType, onChange: (e) => onSeoChange('schemaType', e.target.value), children: [_jsx("option", { value: "Article", children: "Article" }), _jsx("option", { value: "BlogPosting", children: "Blog posting" }), _jsx("option", { value: "NewsArticle", children: "News article" })] })] }), _jsxs("div", { className: "blog_yoast-schema-preview", children: [_jsx("p", { className: "blog_yoast-section-title", children: "Structured data preview" }), _jsxs("ul", { className: "blog_yoast-schema-list", children: [_jsxs("li", { children: [_jsx("strong", { children: seo.schemaType }), " \u2014 headline, dates, authors, publisher"] }), _jsxs("li", { children: [_jsx("strong", { children: "BreadcrumbList" }), " \u2014 Home \u203A Blog \u203A ", categoryName || 'category', " \u203A post"] }), _jsxs("li", { children: [_jsx("strong", { children: "Organization" }), " \u2014 ", siteName] })] })] })] })) : null, tab === 'social' ? (_jsxs("div", { className: "blog_yoast-panel", role: "tabpanel", id: "yoast-panel-social", "aria-labelledby": "yoast-tab-social", children: [_jsx("p", { className: "blog_yoast-intro", children: "Determine how your post should look on social media and in messaging apps." }), _jsxs("div", { className: "blog_yoast-social-preview", children: [socialImage ? (_jsx("img", { className: "blog_yoast-social-img", src: socialImage.url, alt: socialImage.alt || '' })) : (_jsx("div", { className: "blog_yoast-social-img blog_yoast-social-img-empty", children: "No image set" })), _jsxs("div", { className: "blog_yoast-social-text", children: [_jsx("div", { className: "blog_yoast-social-site", children: siteName.toUpperCase() }), _jsx("div", { className: "blog_yoast-social-title", children: socialTitle || 'Post title' }), _jsx("div", { className: "blog_yoast-social-desc", children: socialDesc || 'Description preview…' })] })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsxs("span", { className: "blog_fld-lbl", children: ["Social title ", _jsxs("em", { children: [socialTitle.length, "/", SEO_FIELD_LIMITS.ogTitle] })] }), _jsx("input", { className: `blog_fld${fieldErrors['seo.ogTitle'] ? ' blog_is-invalid' : ''}`, maxLength: SEO_FIELD_LIMITS.ogTitle, value: seo.ogTitle, placeholder: seoTitle || title || 'Falls back to SEO title', onChange: (e) => {
93
93
  onClearFieldError('seo.ogTitle');
94
94
  onSeoChange('ogTitle', e.target.value);
95
- } }), fieldErrors['seo.ogTitle'] ? _jsx("span", { className: "fld-error", children: fieldErrors['seo.ogTitle'] }) : null] }), _jsxs("label", { className: "fld-row", children: [_jsxs("span", { className: "fld-lbl", children: ["Social description ", _jsxs("em", { children: [seo.ogDescription.length, "/", SEO_FIELD_LIMITS.ogDescription] })] }), _jsx("textarea", { className: `fld${fieldErrors['seo.ogDescription'] ? ' is-invalid' : ''}`, rows: 3, maxLength: SEO_FIELD_LIMITS.ogDescription, value: seo.ogDescription, placeholder: metaDesc || 'Falls back to meta description', onChange: (e) => {
95
+ } }), fieldErrors['seo.ogTitle'] ? _jsx("span", { className: "blog_fld-error", children: fieldErrors['seo.ogTitle'] }) : null] }), _jsxs("label", { className: "blog_fld-row", children: [_jsxs("span", { className: "blog_fld-lbl", children: ["Social description ", _jsxs("em", { children: [seo.ogDescription.length, "/", SEO_FIELD_LIMITS.ogDescription] })] }), _jsx("textarea", { className: `blog_fld${fieldErrors['seo.ogDescription'] ? ' blog_is-invalid' : ''}`, rows: 3, maxLength: SEO_FIELD_LIMITS.ogDescription, value: seo.ogDescription, placeholder: metaDesc || 'Falls back to meta description', onChange: (e) => {
96
96
  onClearFieldError('seo.ogDescription');
97
97
  onSeoChange('ogDescription', e.target.value);
98
- } }), fieldErrors['seo.ogDescription'] ? _jsx("span", { className: "fld-error", children: fieldErrors['seo.ogDescription'] }) : null] }), _jsxs("div", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Social image" }), seo.ogImage ? (_jsxs("div", { className: "thumb-row", children: [_jsx("img", { className: "thumb", src: seo.ogImage.url, alt: seo.ogImage.alt }), _jsxs("div", { className: "btn-row", children: [_jsx("button", { type: "button", className: "btn btn-tiny", onClick: onPickOgImage, children: "Replace" }), _jsx("button", { type: "button", className: "btn btn-tiny", onClick: () => onSeoChange('ogImage', null), children: "Remove" })] })] })) : (_jsxs("div", { className: "stack", children: [_jsx("button", { type: "button", className: "btn btn-tiny", onClick: onPickOgImage, children: "Choose image" }), _jsx("span", { className: "fld-hint", children: featuredImage
98
+ } }), fieldErrors['seo.ogDescription'] ? _jsx("span", { className: "blog_fld-error", children: fieldErrors['seo.ogDescription'] }) : null] }), _jsxs("div", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Social image" }), seo.ogImage ? (_jsxs("div", { className: "blog_thumb-row", children: [_jsx("img", { className: "blog_thumb", src: seo.ogImage.url, alt: seo.ogImage.alt }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: onPickOgImage, children: "Replace" }), _jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: () => onSeoChange('ogImage', null), children: "Remove" })] })] })) : (_jsxs("div", { className: "blog_stack", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: onPickOgImage, children: "Choose image" }), _jsx("span", { className: "blog_fld-hint", children: featuredImage
99
99
  ? 'Falls back to the featured image when blank. 1200×630 recommended.'
100
100
  : 'Set a featured image or choose a social image. 1200×630 recommended.' })] }))] })] })) : null] })] }));
101
101
  };
@@ -4,7 +4,7 @@ import { useEffect, useId, useRef, useState } from 'react';
4
4
  const LengthMeter = ({ length, goodMin, goodMax, max, }) => {
5
5
  const pct = Math.min(100, Math.round((length / max) * 100));
6
6
  const tone = length === 0 ? 'bad' : length < goodMin || length > goodMax ? 'ok' : 'good';
7
- return (_jsx("div", { className: "yoast-meter", "aria-hidden": "true", children: _jsx("div", { className: "yoast-meter-track", children: _jsx("div", { className: `yoast-meter-fill yoast-meter-${tone}`, style: { width: `${pct}%` } }) }) }));
7
+ return (_jsx("div", { className: "blog_yoast-meter", "aria-hidden": "true", children: _jsx("div", { className: "blog_yoast-meter-track", children: _jsx("div", { className: `blog_yoast-meter-fill blog_yoast-meter-${tone}`, style: { width: `${pct}%` } }) }) }));
8
8
  };
9
9
  export const YoastSnippetField = ({ id, label, value, placeholder, multiline, maxLength, expandedLength, meterGoodMin, meterGoodMax, meterMax, variables, quickVariables = [], generateLabel, error, onChange, onGenerate, }) => {
10
10
  const listId = useId();
@@ -47,5 +47,5 @@ export const YoastSnippetField = ({ id, label, value, placeholder, multiline, ma
47
47
  maxLength,
48
48
  onChange: (e) => onChange(e.target.value),
49
49
  };
50
- return (_jsxs("div", { className: "yoast-snippet-field", children: [_jsxs("div", { className: "yoast-snippet-label-row", children: [_jsx("label", { className: "yoast-label", htmlFor: id, children: label }), _jsxs("div", { className: "yoast-snippet-actions yoast-snippet-actions-top btn-row", children: [_jsxs("div", { className: "yoast-var-picker", ref: pickerRef, children: [_jsx("button", { type: "button", className: "btn btn-tiny", "aria-expanded": varsOpen, "aria-controls": listId, onClick: () => setVarsOpen((v) => !v), children: "Insert variable" }), varsOpen ? (_jsx("ul", { className: "yoast-var-menu", id: listId, role: "listbox", children: variables.map((v) => (_jsx("li", { children: _jsxs("button", { type: "button", role: "option", className: "yoast-var-option", onClick: () => insertToken(v.token), children: [_jsx("span", { className: "yoast-var-option-label", children: v.label }), _jsx("span", { className: "yoast-var-option-token mono", children: v.token })] }) }, v.label))) })) : null] }), _jsx("button", { type: "button", className: "btn btn-tiny", onClick: onGenerate, children: generateLabel })] })] }), _jsxs("div", { className: "yoast-composite-field", children: [quickVariables.length ? (_jsx("div", { className: "yoast-var-chips yoast-var-chips-inset", "aria-label": `${label} variables`, children: quickVariables.map((v) => (_jsx("button", { type: "button", className: "yoast-var-chip token", onClick: () => insertToken(v.token), children: v.label }, v.label))) })) : null, multiline ? _jsx("textarea", { ...fieldProps, ref: textareaRef, rows: 3 }) : _jsx("input", { ...fieldProps, ref: inputRef, type: "text" })] }), _jsxs("div", { className: "yoast-field-foot", children: [_jsx(LengthMeter, { length: expandedLength, goodMin: meterGoodMin, goodMax: meterGoodMax, max: meterMax }), _jsxs("span", { className: "yoast-char-count", children: [expandedLength, " / ", meterMax] })] }), error ? _jsx("span", { className: "fld-error", children: error }) : null] }));
50
+ return (_jsxs("div", { className: "blog_yoast-snippet-field", children: [_jsxs("div", { className: "blog_yoast-snippet-label-row", children: [_jsx("label", { className: "blog_yoast-label", htmlFor: id, children: label }), _jsxs("div", { className: "blog_yoast-snippet-actions blog_yoast-snippet-actions-top blog_btn-row", children: [_jsxs("div", { className: "blog_yoast-var-picker", ref: pickerRef, children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", "aria-expanded": varsOpen, "aria-controls": listId, onClick: () => setVarsOpen((v) => !v), children: "Insert variable" }), varsOpen ? (_jsx("ul", { className: "blog_yoast-var-menu", id: listId, role: "listbox", children: variables.map((v) => (_jsx("li", { children: _jsxs("button", { type: "button", role: "option", className: "blog_yoast-var-option", onClick: () => insertToken(v.token), children: [_jsx("span", { className: "blog_yoast-var-option-label", children: v.label }), _jsx("span", { className: "blog_yoast-var-option-token blog_mono", children: v.token })] }) }, v.label))) })) : null] }), _jsx("button", { type: "button", className: "blog_btn blog_btn-tiny", onClick: onGenerate, children: generateLabel })] })] }), _jsxs("div", { className: "blog_yoast-composite-field", children: [quickVariables.length ? (_jsx("div", { className: "blog_yoast-var-chips blog_yoast-var-chips-inset", "aria-label": `${label} variables`, children: quickVariables.map((v) => (_jsx("button", { type: "button", className: "blog_yoast-var-chip blog_token", onClick: () => insertToken(v.token), children: v.label }, v.label))) })) : null, multiline ? _jsx("textarea", { ...fieldProps, ref: textareaRef, rows: 3 }) : _jsx("input", { ...fieldProps, ref: inputRef, type: "text" })] }), _jsxs("div", { className: "blog_yoast-field-foot", children: [_jsx(LengthMeter, { length: expandedLength, goodMin: meterGoodMin, goodMax: meterGoodMax, max: meterMax }), _jsxs("span", { className: "blog_yoast-char-count", children: [expandedLength, " / ", meterMax] })] }), error ? _jsx("span", { className: "blog_fld-error", children: error }) : null] }));
51
51
  };
@@ -1,14 +1,14 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  export function LoadingState({ label = "Loading..." }) {
3
- return (_jsx("div", { className: "bp-state bp-state--loading", role: "status", children: label }));
3
+ return (_jsx("div", { className: "blog_bp-state blog_bp-state--loading", role: "status", children: label }));
4
4
  }
5
5
  export function ErrorState({ message, authError, }) {
6
- return (_jsx("div", { className: "bp-state bp-state--error", role: "alert", children: authError
6
+ return (_jsx("div", { className: "blog_bp-state blog_bp-state--error", role: "alert", children: authError
7
7
  ? "Authentication failed. Check the admin API key. Never use an admin key in a public website."
8
8
  : message || "Something went wrong." }));
9
9
  }
10
10
  export function EmptyState({ label = "Nothing here yet." }) {
11
- return _jsx("div", { className: "bp-state bp-state--empty", children: label });
11
+ return _jsx("div", { className: "blog_bp-state blog_bp-state--empty", children: label });
12
12
  }
13
13
  export function Field({ label, children, }) {
14
14
  return (_jsxs("label", { style: { display: "grid", gap: "0.35rem", marginBottom: "0.85rem" }, children: [_jsx("span", { style: { fontSize: "0.85rem", color: "var(--bp-color-muted)" }, children: label }), children] }));
@@ -23,9 +23,9 @@ export function Ga4Settings({ brandId, canEdit = true }) {
23
23
  setFlash("Google Analytics settings saved.");
24
24
  });
25
25
  };
26
- return (_jsxs("fieldset", { className: "seo-module", disabled: !canEdit, children: [!canEdit ? _jsxs("p", { className: "explain", children: ["Only platform admins can change analytics for ", brandName, "."] }) : 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: "grid grid-2 seo-grid", children: _jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "GA4 measurement" }) }), _jsxs("div", { className: "panel-body stack", children: [_jsx(SeoStatus, { ok: connected, label: connected ? "Measurement ID ready" : "Not connected", detail: connected
26
+ return (_jsxs("fieldset", { className: "blog_seo-module", disabled: !canEdit, children: [!canEdit ? _jsxs("p", { className: "blog_explain", children: ["Only platform admins can change analytics for ", brandName, "."] }) : 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_grid blog_grid-2 blog_seo-grid", children: _jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "GA4 measurement" }) }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsx(SeoStatus, { ok: connected, label: connected ? "Measurement ID ready" : "Not connected", detail: connected
27
27
  ? "ID is saved in the mock store for this session."
28
- : "Paste a GA4 Measurement ID to start collecting traffic." }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Measurement ID" }), _jsx("input", { className: "fld mono", placeholder: "G-XXXXXXXXXX", value: value, onChange: (e) => setValue(e.target.value) })] }), canEdit ? (_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: save, children: pending ? "Saving…" : "Save" })) : null] })] }) })] }));
28
+ : "Paste a GA4 Measurement ID to start collecting traffic." }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Measurement ID" }), _jsx("input", { className: "blog_fld blog_mono", placeholder: "G-XXXXXXXXXX", value: value, onChange: (e) => setValue(e.target.value) })] }), canEdit ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: save, children: pending ? "Saving…" : "Save" })) : null] })] }) })] }));
29
29
  }
30
30
  export function SearchConsoleSettings({ brandId, canEdit = true }) {
31
31
  const store = useAdminMock();
@@ -49,9 +49,9 @@ export function SearchConsoleSettings({ brandId, canEdit = true }) {
49
49
  setFlash("Search Console verification saved.");
50
50
  });
51
51
  };
52
- return (_jsxs("fieldset", { className: "seo-module", disabled: !canEdit, children: [!canEdit ? _jsxs("p", { className: "explain", children: ["Only platform admins can change verification for ", brandName, "."] }) : 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: "grid grid-2 seo-grid", children: _jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "HTML tag verification" }) }), _jsxs("div", { className: "panel-body stack", children: [_jsx(SeoStatus, { ok: connected, label: connected ? "Meta tag will publish" : "Not verified yet", detail: connected
52
+ return (_jsxs("fieldset", { className: "blog_seo-module", disabled: !canEdit, children: [!canEdit ? _jsxs("p", { className: "blog_explain", children: ["Only platform admins can change verification for ", brandName, "."] }) : 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_grid blog_grid-2 blog_seo-grid", children: _jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "HTML tag verification" }) }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsx(SeoStatus, { ok: connected, label: connected ? "Meta tag will publish" : "Not verified yet", detail: connected
53
53
  ? `Emitted as google-site-verification on ${primaryDomain}.`
54
- : "Paste the content value from Search Console’s HTML tag method." }), _jsxs("label", { className: "fld-row", children: [_jsxs("span", { className: "fld-lbl", children: ["Verification token ", _jsx("em", { children: "content=\u2026 only, not the full meta tag" })] }), _jsx("input", { className: "fld mono", value: value, onChange: (e) => setValue(e.target.value) })] }), canEdit ? (_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: save, children: pending ? "Saving…" : "Save" })) : null] })] }) })] }));
54
+ : "Paste the content value from Search Console’s HTML tag method." }), _jsxs("label", { className: "blog_fld-row", children: [_jsxs("span", { className: "blog_fld-lbl", children: ["Verification token ", _jsx("em", { children: "content=\u2026 only, not the full meta tag" })] }), _jsx("input", { className: "blog_fld blog_mono", value: value, onChange: (e) => setValue(e.target.value) })] }), canEdit ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: save, children: pending ? "Saving…" : "Save" })) : null] })] }) })] }));
55
55
  }
56
56
  export function SeoBrandList({ rows, onOpen, canEdit = true, canClear, onClear, clearLabel = "Clear", }) {
57
57
  const [pending, start] = useTransition();
@@ -66,14 +66,14 @@ export function SeoBrandList({ rows, onOpen, canEdit = true, canClear, onClear,
66
66
  alert(res.error);
67
67
  });
68
68
  };
69
- return (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "All brands" }), _jsx("span", { className: "hint", children: rows.length })] }), _jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Brand" }), _jsx("th", { children: "Status" }), _jsx("th", { children: "Summary" })] }) }), _jsx("tbody", { children: rows.map((row) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("button", { type: "button", className: "row-title", onClick: () => onOpen(row.slug), children: row.name }), _jsx("span", { className: "cell-sub mono", children: row.primaryDomain }), _jsxs("div", { className: "row-actions", children: [_jsx("button", { type: "button", onClick: () => onOpen(row.slug), children: "View" }), canEdit ? (_jsx("button", { type: "button", onClick: () => onOpen(row.slug), children: "Edit" })) : null, canClear && onClear && row.status !== "missing" && row.status !== "default" ? (_jsx("button", { type: "button", className: "danger", disabled: pending, onClick: () => clear(row), children: clearLabel })) : null] })] }), _jsx("td", { children: _jsx("span", { className: `chip ${row.status === "configured" ? "chip-approved" : row.status === "default" ? "chip-writing" : "chip-draft"}`, children: row.statusLabel }) }), _jsx("td", { className: "muted", children: row.summary })] }, row.id))) })] }) })] }));
69
+ return (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "All brands" }), _jsx("span", { className: "blog_hint", children: rows.length })] }), _jsx("div", { className: "blog_tw", children: _jsxs("table", { className: "blog_tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Brand" }), _jsx("th", { children: "Status" }), _jsx("th", { children: "Summary" })] }) }), _jsx("tbody", { children: rows.map((row) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("button", { type: "button", className: "blog_row-title", onClick: () => onOpen(row.slug), children: row.name }), _jsx("span", { className: "blog_cell-sub blog_mono", children: row.primaryDomain }), _jsxs("div", { className: "blog_row-actions", children: [_jsx("button", { type: "button", onClick: () => onOpen(row.slug), children: "View" }), canEdit ? (_jsx("button", { type: "button", onClick: () => onOpen(row.slug), children: "Edit" })) : null, canClear && onClear && row.status !== "missing" && row.status !== "default" ? (_jsx("button", { type: "button", className: "blog_danger", disabled: pending, onClick: () => clear(row), children: clearLabel })) : null] })] }), _jsx("td", { children: _jsx("span", { className: `blog_chip ${row.status === "configured" ? "blog_chip-approved" : row.status === "default" ? "blog_chip-writing" : "blog_chip-draft"}`, children: row.statusLabel }) }), _jsx("td", { className: "blog_muted", children: row.summary })] }, row.id))) })] }) })] }));
70
70
  }
71
71
  export function SitemapPanel({ brandId }) {
72
72
  const store = useAdminMock();
73
73
  const brand = store.brands.find((b) => b.id === brandId);
74
74
  const url = store.data.sitemapNotes[brandId] ?? `https://${brand?.primaryDomain ?? "example.com"}/sitemap.xml`;
75
75
  const postCount = store.filterPosts({ state: "live", brandId }).length;
76
- return (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "XML Sitemap" }), _jsx("span", { className: "hint", children: brand?.name })] }), _jsxs("div", { className: "panel-body stack", children: [_jsxs("p", { className: "note", style: { marginTop: 0 }, children: ["Mock sitemap for ", brand?.name, ". ", postCount, " published posts would be included."] }), _jsx("p", { className: "mono", children: url }), _jsx("button", { type: "button", className: "btn", onClick: () => {
76
+ return (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "XML Sitemap" }), _jsx("span", { className: "blog_hint", children: brand?.name })] }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsxs("p", { className: "blog_note", style: { marginTop: 0 }, children: ["Mock sitemap for ", brand?.name, ". ", postCount, " published posts would be included."] }), _jsx("p", { className: "blog_mono", children: url }), _jsx("button", { type: "button", className: "blog_btn", onClick: () => {
77
77
  void navigator.clipboard?.writeText(url);
78
78
  alert("Sitemap URL copied.");
79
79
  }, children: "Copy URL" })] })] }));
@@ -20,5 +20,5 @@ const logTime = (iso) => {
20
20
  };
21
21
  export const RedirectAnalyticsDashboard = ({ data }) => {
22
22
  const hasSeries = data.series.some((d) => d.views > 0);
23
- return (_jsxs("div", { className: "redir-analytics", children: [_jsxs("section", { className: "kpis", children: [_jsxs("div", { className: "kpi", children: [_jsx("span", { className: "kpi-l", children: "Total Redirects" }), _jsx("div", { className: "kpi-row", children: _jsx("span", { className: "kpi-n", children: nf.format(data.totalRules) }) }), _jsx("span", { className: "kpi-sub", children: "Active rules in this scope" })] }), _jsxs("div", { className: "kpi", children: [_jsx("span", { className: "kpi-l", children: "Today" }), _jsx("div", { className: "kpi-row", children: _jsx("span", { className: "kpi-n", children: nf.format(data.hitsToday) }) }), _jsx("span", { className: "kpi-sub", children: "Hits since midnight UTC" })] }), _jsxs("div", { className: "kpi", children: [_jsx("span", { className: "kpi-l", children: "This Week" }), _jsx("div", { className: "kpi-row", children: _jsx("span", { className: "kpi-n", children: nf.format(data.hitsWeek) }) }), _jsx("span", { className: "kpi-sub", children: "Last 7 days" })] }), _jsxs("div", { className: "kpi", children: [_jsx("span", { className: "kpi-l", children: "This Month" }), _jsx("div", { className: "kpi-row", children: _jsx("span", { className: "kpi-n", children: nf.format(data.hitsMonth) }) }), _jsx("span", { className: "kpi-sub", children: "Last 30 days" })] })] }), _jsxs("div", { className: "redir-analytics-grid", children: [_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "Top Redirects" }), _jsx("span", { className: "hint", children: "30 days" })] }), _jsx("div", { className: "panel-body", children: _jsx(BarList, { items: data.topRedirects, unit: " hits", colorVar: "var(--viz-1)" }) })] }), _jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "Broken URLs" }), _jsx("span", { className: "hint", children: "404 / 410 / 451" })] }), _jsx("div", { className: "panel-body", children: _jsx(BarList, { items: data.brokenUrls, unit: " hits", colorVar: "var(--viz-4)" }) })] })] }), _jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "Last 30 Days" }), _jsx("span", { className: "hint", children: "Daily redirect hits" })] }), _jsx("div", { className: "panel-body", children: hasSeries ? (_jsx(TrendArea, { data: data.series, height: 200 })) : (_jsx("p", { className: "d-empty", style: { margin: 0 }, children: "No redirect traffic recorded yet." })) })] }), _jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Recent hits" }) }), _jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "When" }), _jsx("th", { children: "From" }), _jsx("th", { children: "To" }), _jsx("th", { children: "Type" })] }) }), _jsx("tbody", { children: data.recentLogs.map((log) => (_jsxs("tr", { children: [_jsx("td", { className: "mono muted", children: logTime(log.at) }), _jsx("td", { className: "mono", children: log.from }), _jsx("td", { className: "mono muted", children: log.to || "—" }), _jsx("td", { children: _jsx("span", { className: `chip ${log.ok ? "chip-approved" : "chip-draft"}`, children: log.type }) })] }, log.id))) })] }) })] })] }));
23
+ return (_jsxs("div", { className: "blog_redir-analytics", children: [_jsxs("section", { className: "blog_kpis", children: [_jsxs("div", { className: "blog_kpi", children: [_jsx("span", { className: "blog_kpi-l", children: "Total Redirects" }), _jsx("div", { className: "blog_kpi-row", children: _jsx("span", { className: "blog_kpi-n", children: nf.format(data.totalRules) }) }), _jsx("span", { className: "blog_kpi-sub", children: "Active rules in this scope" })] }), _jsxs("div", { className: "blog_kpi", children: [_jsx("span", { className: "blog_kpi-l", children: "Today" }), _jsx("div", { className: "blog_kpi-row", children: _jsx("span", { className: "blog_kpi-n", children: nf.format(data.hitsToday) }) }), _jsx("span", { className: "blog_kpi-sub", children: "Hits since midnight UTC" })] }), _jsxs("div", { className: "blog_kpi", children: [_jsx("span", { className: "blog_kpi-l", children: "This Week" }), _jsx("div", { className: "blog_kpi-row", children: _jsx("span", { className: "blog_kpi-n", children: nf.format(data.hitsWeek) }) }), _jsx("span", { className: "blog_kpi-sub", children: "Last 7 days" })] }), _jsxs("div", { className: "blog_kpi", children: [_jsx("span", { className: "blog_kpi-l", children: "This Month" }), _jsx("div", { className: "blog_kpi-row", children: _jsx("span", { className: "blog_kpi-n", children: nf.format(data.hitsMonth) }) }), _jsx("span", { className: "blog_kpi-sub", children: "Last 30 days" })] })] }), _jsxs("div", { className: "blog_redir-analytics-grid", children: [_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "Top Redirects" }), _jsx("span", { className: "blog_hint", children: "30 days" })] }), _jsx("div", { className: "blog_panel-body", children: _jsx(BarList, { items: data.topRedirects, unit: " hits", colorVar: "var(--viz-1)" }) })] }), _jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "Broken URLs" }), _jsx("span", { className: "blog_hint", children: "404 / 410 / 451" })] }), _jsx("div", { className: "blog_panel-body", children: _jsx(BarList, { items: data.brokenUrls, unit: " hits", colorVar: "var(--viz-4)" }) })] })] }), _jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "Last 30 Days" }), _jsx("span", { className: "blog_hint", children: "Daily redirect hits" })] }), _jsx("div", { className: "blog_panel-body", children: hasSeries ? (_jsx(TrendArea, { data: data.series, height: 200 })) : (_jsx("p", { className: "blog_d-empty", style: { margin: 0 }, children: "No redirect traffic recorded yet." })) })] }), _jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Recent hits" }) }), _jsx("div", { className: "blog_tw", children: _jsxs("table", { className: "blog_tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "When" }), _jsx("th", { children: "From" }), _jsx("th", { children: "To" }), _jsx("th", { children: "Type" })] }) }), _jsx("tbody", { children: data.recentLogs.map((log) => (_jsxs("tr", { children: [_jsx("td", { className: "blog_mono blog_muted", children: logTime(log.at) }), _jsx("td", { className: "blog_mono", children: log.from }), _jsx("td", { className: "blog_mono blog_muted", children: log.to || "—" }), _jsx("td", { children: _jsx("span", { className: `blog_chip ${log.ok ? "blog_chip-approved" : "blog_chip-draft"}`, children: log.type }) })] }, log.id))) })] }) })] })] }));
24
24
  };
@@ -7,7 +7,7 @@ export function RedirectDetail({ redirectId, onEdit, onBack, canEdit = true, })
7
7
  const row = store.getRedirect(redirectId);
8
8
  const [pending, start] = useTransition();
9
9
  if (!row) {
10
- return (_jsx("section", { className: "panel", children: _jsxs("div", { className: "panel-body", children: [_jsx("p", { className: "d-empty", children: "Redirect not found." }), _jsx("button", { type: "button", className: "btn", onClick: onBack, children: "Back to list" })] }) }));
10
+ return (_jsx("section", { className: "blog_panel", children: _jsxs("div", { className: "blog_panel-body", children: [_jsx("p", { className: "blog_d-empty", children: "Redirect not found." }), _jsx("button", { type: "button", className: "blog_btn", onClick: onBack, children: "Back to list" })] }) }));
11
11
  }
12
12
  const remove = () => {
13
13
  if (!confirm(`Delete redirect “${row.from}”?`))
@@ -21,10 +21,10 @@ export function RedirectDetail({ redirectId, onEdit, onBack, canEdit = true, })
21
21
  onBack();
22
22
  });
23
23
  };
24
- return (_jsxs(_Fragment, { children: [_jsx(RedirectDetailCard, { row: row }), _jsxs("div", { className: "btn-row", children: [canEdit ? (_jsx("button", { type: "button", className: "btn btn-primary", onClick: onEdit, children: "Edit" })) : null, canEdit ? (_jsx("button", { type: "button", className: "btn btn-ghost", disabled: pending, onClick: remove, children: pending ? "Deleting…" : "Delete" })) : null, _jsx("button", { type: "button", className: "btn", onClick: onBack, children: "Back to list" })] })] }));
24
+ return (_jsxs(_Fragment, { children: [_jsx(RedirectDetailCard, { row: row }), _jsxs("div", { className: "blog_btn-row", children: [canEdit ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", onClick: onEdit, children: "Edit" })) : null, canEdit ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-ghost", disabled: pending, onClick: remove, children: pending ? "Deleting…" : "Delete" })) : null, _jsx("button", { type: "button", className: "blog_btn", onClick: onBack, children: "Back to list" })] })] }));
25
25
  }
26
- export const RedirectDetailCard = ({ row }) => (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "Redirect details" }), _jsx("span", { className: `chip ${row.type === "301" || row.type === "308"
27
- ? "chip-approved"
26
+ export const RedirectDetailCard = ({ row }) => (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "Redirect details" }), _jsx("span", { className: `blog_chip ${row.type === "301" || row.type === "308"
27
+ ? "blog_chip-approved"
28
28
  : row.type === "404" || row.type === "410" || row.type === "451"
29
- ? "chip-draft"
30
- : "chip-writing"}`, children: row.type })] }), _jsx("div", { className: "panel-body", children: _jsxs("dl", { className: "seo-dl", children: [_jsxs("div", { children: [_jsx("dt", { children: "From" }), _jsx("dd", { className: "mono", children: row.from })] }), _jsxs("div", { children: [_jsx("dt", { children: "Target URL" }), _jsx("dd", { className: "mono", children: row.to || "—" })] }), _jsxs("div", { children: [_jsx("dt", { children: "Origin" }), _jsx("dd", { children: SOURCE_LABEL[row.source] ?? row.source })] }), _jsxs("div", { children: [_jsx("dt", { children: "Brand" }), _jsx("dd", { children: row.brandName ?? "—" })] }), _jsxs("div", { children: [_jsx("dt", { children: "Active" }), _jsx("dd", { children: row.active === false ? "No" : "Yes" })] }), row.note ? (_jsxs("div", { children: [_jsx("dt", { children: "Note" }), _jsx("dd", { children: row.note })] })) : null] }) })] }));
29
+ ? "blog_chip-draft"
30
+ : "blog_chip-writing"}`, children: row.type })] }), _jsx("div", { className: "blog_panel-body", children: _jsxs("dl", { className: "blog_seo-dl", children: [_jsxs("div", { children: [_jsx("dt", { children: "From" }), _jsx("dd", { className: "blog_mono", children: row.from })] }), _jsxs("div", { children: [_jsx("dt", { children: "Target URL" }), _jsx("dd", { className: "blog_mono", children: row.to || "—" })] }), _jsxs("div", { children: [_jsx("dt", { children: "Origin" }), _jsx("dd", { children: SOURCE_LABEL[row.source] ?? row.source })] }), _jsxs("div", { children: [_jsx("dt", { children: "Brand" }), _jsx("dd", { children: row.brandName ?? "—" })] }), _jsxs("div", { children: [_jsx("dt", { children: "Active" }), _jsx("dd", { children: row.active === false ? "No" : "Yes" })] }), row.note ? (_jsxs("div", { children: [_jsx("dt", { children: "Note" }), _jsx("dd", { children: row.note })] })) : null] }) })] }));
@@ -69,7 +69,7 @@ export function RedirectForm({ initial, mode, onDone, onCancel, }) {
69
69
  onDone();
70
70
  });
71
71
  };
72
- return (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: mode === "create" ? "Add redirect" : "Edit redirect" }), _jsx("span", { className: "hint", children: brandName })] }), _jsxs("div", { className: "panel-body stack", children: [error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, form.sources.map((src, i) => (_jsxs("div", { className: "btn-row", style: { alignItems: "flex-end" }, children: [_jsxs("label", { className: "fld-row", style: { flex: 1 }, children: [_jsx("span", { className: "fld-lbl", children: "From path" }), _jsx("input", { className: "fld mono", value: src.path, onChange: (e) => setSource(i, { path: e.target.value }), placeholder: "/old-path" })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Match" }), _jsxs("select", { className: "fld", value: src.match, onChange: (e) => setSource(i, { match: e.target.value }), children: [_jsx("option", { value: "exact", children: "Exact" }), _jsx("option", { value: "contains", children: "Contains" }), _jsx("option", { value: "regex", children: "Regex" })] })] })] }, i))), _jsx("button", { type: "button", className: "btn", onClick: () => setForm((f) => ({ ...f, sources: [...f.sources, emptySource()] })), children: "Add source path" }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Type" }), _jsx("select", { className: "fld", value: form.type, onChange: (e) => set("type", e.target.value), children: TYPE_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) })] }), needsTarget ? (_jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Target URL" }), _jsx("input", { className: "fld mono", value: form.to, onChange: (e) => set("to", e.target.value), placeholder: "/new-path" })] })) : null, _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Note" }), _jsx("input", { className: "fld", value: form.note, onChange: (e) => set("note", e.target.value) })] }), _jsxs("div", { className: "chips", children: [_jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.active, onChange: (e) => set("active", e.target.checked) }), " Active"] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.ignoreCase, onChange: (e) => set("ignoreCase", e.target.checked) }), " Ignore case"] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.ignoreTrailingSlash, onChange: (e) => set("ignoreTrailingSlash", e.target.checked) }), " ", "Ignore trailing slash"] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.forceHttps, onChange: (e) => set("forceHttps", e.target.checked) }), " Force HTTPS"] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: form.preserveQuery, onChange: (e) => set("preserveQuery", e.target.checked) }), " ", "Preserve query"] })] }), _jsxs("div", { className: "btn-row", children: [_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: submit, children: pending ? "Saving…" : mode === "create" ? "Create redirect" : "Save redirect" }), _jsx("button", { type: "button", className: "btn", onClick: onCancel, children: "Cancel" })] })] })] }));
72
+ return (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: mode === "create" ? "Add redirect" : "Edit redirect" }), _jsx("span", { className: "blog_hint", children: brandName })] }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, form.sources.map((src, i) => (_jsxs("div", { className: "blog_btn-row", style: { alignItems: "flex-end" }, children: [_jsxs("label", { className: "blog_fld-row", style: { flex: 1 }, children: [_jsx("span", { className: "blog_fld-lbl", children: "From path" }), _jsx("input", { className: "blog_fld blog_mono", value: src.path, onChange: (e) => setSource(i, { path: e.target.value }), placeholder: "/old-path" })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Match" }), _jsxs("select", { className: "blog_fld", value: src.match, onChange: (e) => setSource(i, { match: e.target.value }), children: [_jsx("option", { value: "exact", children: "Exact" }), _jsx("option", { value: "contains", children: "Contains" }), _jsx("option", { value: "regex", children: "Regex" })] })] })] }, i))), _jsx("button", { type: "button", className: "blog_btn", onClick: () => setForm((f) => ({ ...f, sources: [...f.sources, emptySource()] })), children: "Add source path" }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Type" }), _jsx("select", { className: "blog_fld", value: form.type, onChange: (e) => set("type", e.target.value), children: TYPE_OPTIONS.map((o) => (_jsx("option", { value: o.value, children: o.label }, o.value))) })] }), needsTarget ? (_jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Target URL" }), _jsx("input", { className: "blog_fld blog_mono", value: form.to, onChange: (e) => set("to", e.target.value), placeholder: "/new-path" })] })) : null, _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Note" }), _jsx("input", { className: "blog_fld", value: form.note, onChange: (e) => set("note", e.target.value) })] }), _jsxs("div", { className: "blog_chips", children: [_jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.active, onChange: (e) => set("active", e.target.checked) }), " Active"] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.ignoreCase, onChange: (e) => set("ignoreCase", e.target.checked) }), " Ignore case"] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.ignoreTrailingSlash, onChange: (e) => set("ignoreTrailingSlash", e.target.checked) }), " ", "Ignore trailing slash"] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.forceHttps, onChange: (e) => set("forceHttps", e.target.checked) }), " Force HTTPS"] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: form.preserveQuery, onChange: (e) => set("preserveQuery", e.target.checked) }), " ", "Preserve query"] })] }), _jsxs("div", { className: "blog_btn-row", children: [_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: submit, children: pending ? "Saving…" : mode === "create" ? "Create redirect" : "Save redirect" }), _jsx("button", { type: "button", className: "blog_btn", onClick: onCancel, children: "Cancel" })] })] })] }));
73
73
  }
74
74
  export function redirectToFormValues(row) {
75
75
  return {
@@ -20,9 +20,9 @@ export function RedirectList({ onView, onEdit, onCreate, canEdit = true, }) {
20
20
  alert(res.error);
21
21
  });
22
22
  };
23
- return (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "All redirects" }), _jsx("span", { className: "hint", children: rows.length })] }), rows.length === 0 ? (_jsx("div", { className: "panel-body", children: _jsxs("p", { className: "d-empty", style: { margin: 0 }, children: ["No redirects yet.", " ", canEdit ? (_jsx("button", { type: "button", className: "btn btn-ghost btn-sm", onClick: onCreate, children: "Add the first one" })) : null] }) })) : (_jsx("div", { className: "tw", children: _jsxs("table", { className: "tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "From" }), _jsx("th", { children: "To" }), _jsx("th", { children: "Type" }), _jsx("th", { children: "Origin" }), showBrand ? _jsx("th", { children: "Brand" }) : null] }) }), _jsx("tbody", { children: rows.map((r) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("button", { type: "button", className: "row-title mono", onClick: () => onView(r.id), children: r.from }), r.note ? _jsx("span", { className: "cell-sub", children: r.note }) : null, _jsxs("div", { className: "row-actions", children: [_jsx("button", { type: "button", onClick: () => onView(r.id), children: "View" }), canEdit ? (_jsx("button", { type: "button", onClick: () => onEdit(r.id), children: "Edit" })) : null, canEdit ? (_jsx("button", { type: "button", className: "danger", disabled: pending, onClick: () => remove(r), children: "Delete" })) : null] })] }), _jsx("td", { className: "mono muted", children: r.to || "—" }), _jsxs("td", { children: [_jsx("span", { className: `chip ${r.type === "301" || r.type === "308"
24
- ? "chip-approved"
23
+ return (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "All redirects" }), _jsx("span", { className: "blog_hint", children: rows.length })] }), rows.length === 0 ? (_jsx("div", { className: "blog_panel-body", children: _jsxs("p", { className: "blog_d-empty", style: { margin: 0 }, children: ["No redirects yet.", " ", canEdit ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-ghost blog_btn-sm", onClick: onCreate, children: "Add the first one" })) : null] }) })) : (_jsx("div", { className: "blog_tw", children: _jsxs("table", { className: "blog_tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "From" }), _jsx("th", { children: "To" }), _jsx("th", { children: "Type" }), _jsx("th", { children: "Origin" }), showBrand ? _jsx("th", { children: "Brand" }) : null] }) }), _jsx("tbody", { children: rows.map((r) => (_jsxs("tr", { children: [_jsxs("td", { children: [_jsx("button", { type: "button", className: "blog_row-title blog_mono", onClick: () => onView(r.id), children: r.from }), r.note ? _jsx("span", { className: "blog_cell-sub", children: r.note }) : null, _jsxs("div", { className: "blog_row-actions", children: [_jsx("button", { type: "button", onClick: () => onView(r.id), children: "View" }), canEdit ? (_jsx("button", { type: "button", onClick: () => onEdit(r.id), children: "Edit" })) : null, canEdit ? (_jsx("button", { type: "button", className: "blog_danger", disabled: pending, onClick: () => remove(r), children: "Delete" })) : null] })] }), _jsx("td", { className: "blog_mono blog_muted", children: r.to || "—" }), _jsxs("td", { children: [_jsx("span", { className: `blog_chip ${r.type === "301" || r.type === "308"
24
+ ? "blog_chip-approved"
25
25
  : r.type === "404" || r.type === "410" || r.type === "451"
26
- ? "chip-draft"
27
- : "chip-writing"}`, children: r.type }), r.active === false ? _jsx("span", { className: "chip chip-draft", children: "Off" }) : null] }), _jsx("td", { className: "muted", children: SOURCE_LABEL[r.source] ?? r.source }), showBrand ? _jsx("td", { className: "muted", children: r.brandName ?? "—" }) : null] }, r.id))) })] }) }))] }));
26
+ ? "blog_chip-draft"
27
+ : "blog_chip-writing"}`, children: r.type }), r.active === false ? _jsx("span", { className: "blog_chip blog_chip-draft", children: "Off" }) : null] }), _jsx("td", { className: "blog_muted", children: SOURCE_LABEL[r.source] ?? r.source }), showBrand ? _jsx("td", { className: "blog_muted", children: r.brandName ?? "—" }) : null] }, r.id))) })] }) }))] }));
28
28
  }
@@ -46,5 +46,5 @@ export function RobotsEditor({ brandId, canEdit = true, }) {
46
46
  setFlash("Robots.txt saved.");
47
47
  });
48
48
  };
49
- return (_jsxs("fieldset", { className: "seo-module", disabled: !canEdit, children: [!canEdit ? _jsxs("p", { className: "explain", children: ["Only platform admins can change robots.txt for ", brandName, "."] }) : null, error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, flash ? (_jsx("p", { className: "form-ok", role: "status", children: flash })) : null, _jsxs("div", { className: "grid grid-2 seo-grid", children: [_jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsxs("h2", { children: ["Rules for ", brandName] }) }), _jsxs("div", { className: "panel-body stack", children: [_jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Allow paths (one per line)" }), _jsx("textarea", { className: "fld mono", rows: 4, value: allow, onChange: (e) => setAllow(e.target.value) })] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Disallow paths (one per line)" }), _jsx("textarea", { className: "fld mono", rows: 4, value: disallow, onChange: (e) => setDisallow(e.target.value) })] }), _jsxs("label", { className: "pick-row", children: [_jsx("input", { type: "checkbox", checked: includeSitemap, onChange: (e) => setIncludeSitemap(e.target.checked) }), " ", "Include sitemap URL"] }), _jsxs("label", { className: "fld-row", children: [_jsx("span", { className: "fld-lbl", children: "Extra rules" }), _jsx("textarea", { className: "fld mono", rows: 3, value: extraRules, onChange: (e) => setExtraRules(e.target.value) })] }), canEdit ? (_jsx("button", { type: "button", className: "btn btn-primary", disabled: pending, onClick: save, children: pending ? "Saving…" : "Save robots.txt" })) : null] })] }), _jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Preview" }) }), _jsx("div", { className: "panel-body", children: _jsx("pre", { className: "mono", style: { whiteSpace: "pre-wrap", margin: 0 }, children: preview }) })] })] })] }));
49
+ return (_jsxs("fieldset", { className: "blog_seo-module", disabled: !canEdit, children: [!canEdit ? _jsxs("p", { className: "blog_explain", children: ["Only platform admins can change robots.txt for ", brandName, "."] }) : 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, _jsxs("div", { className: "blog_grid blog_grid-2 blog_seo-grid", children: [_jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsxs("h2", { children: ["Rules for ", brandName] }) }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Allow paths (one per line)" }), _jsx("textarea", { className: "blog_fld blog_mono", rows: 4, value: allow, onChange: (e) => setAllow(e.target.value) })] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Disallow paths (one per line)" }), _jsx("textarea", { className: "blog_fld blog_mono", rows: 4, value: disallow, onChange: (e) => setDisallow(e.target.value) })] }), _jsxs("label", { className: "blog_pick-row", children: [_jsx("input", { type: "checkbox", checked: includeSitemap, onChange: (e) => setIncludeSitemap(e.target.checked) }), " ", "Include sitemap URL"] }), _jsxs("label", { className: "blog_fld-row", children: [_jsx("span", { className: "blog_fld-lbl", children: "Extra rules" }), _jsx("textarea", { className: "blog_fld blog_mono", rows: 3, value: extraRules, onChange: (e) => setExtraRules(e.target.value) })] }), canEdit ? (_jsx("button", { type: "button", className: "blog_btn blog_btn-primary", disabled: pending, onClick: save, children: pending ? "Saving…" : "Save robots.txt" })) : null] })] }), _jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Preview" }) }), _jsx("div", { className: "blog_panel-body", children: _jsx("pre", { className: "blog_mono", style: { whiteSpace: "pre-wrap", margin: 0 }, children: preview }) })] })] })] }));
50
50
  }
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useAdminMock } from "../mock/store";
3
- export const SeoStatus = ({ ok, label, detail, }) => (_jsxs("div", { className: `seo-status ${ok ? "is-ok" : "is-warn"}`, children: [_jsx("span", { className: "seo-status-dot", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("strong", { children: label }), _jsx("p", { children: detail })] })] }));
3
+ export const SeoStatus = ({ ok, label, detail, }) => (_jsxs("div", { className: `blog_seo-status ${ok ? "blog_is-ok" : "blog_is-warn"}`, children: [_jsx("span", { className: "blog_seo-status-dot", "aria-hidden": "true" }), _jsxs("div", { children: [_jsx("strong", { children: label }), _jsx("p", { children: detail })] })] }));
4
4
  export function BrandPickPanel({ title, onPick, }) {
5
5
  const store = useAdminMock();
6
- return (_jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Which brand?" }) }), _jsxs("div", { className: "panel-body", children: [_jsxs("p", { className: "explain", style: { marginTop: 0 }, children: [title, " \u2014 these settings are per brand. Pick one to continue."] }), _jsx("div", { className: "chips", children: store.brands.map((t) => (_jsx("button", { type: "button", className: "btn", onClick: () => onPick(t.id), children: t.name }, t.id))) })] })] }));
6
+ return (_jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Which brand?" }) }), _jsxs("div", { className: "blog_panel-body", children: [_jsxs("p", { className: "blog_explain", style: { marginTop: 0 }, children: [title, " \u2014 these settings are per brand. Pick one to continue."] }), _jsx("div", { className: "blog_chips", children: store.brands.map((t) => (_jsx("button", { type: "button", className: "blog_btn", onClick: () => onPick(t.id), children: t.name }, t.id))) })] })] }));
7
7
  }
@@ -50,7 +50,7 @@ export function ExportTool() {
50
50
  setBusy(false);
51
51
  }
52
52
  };
53
- return (_jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Choose what to export" }) }), _jsxs("div", { className: "panel-body stack", children: [_jsxs("p", { className: "note", style: { marginTop: 0 }, children: ["Download a JSON, XML, or CSV file from the mock store", brandSlug ? ` (currently ${brandName})` : " (all brands)", "."] }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, _jsxs("fieldset", { className: "export-fieldset", children: [_jsx("legend", { className: "sr-only", children: "Export type" }), options.map((opt) => (_jsxs("label", { className: `export-option${kind === opt.value ? " is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "export-kind", value: opt.value, checked: kind === opt.value, onChange: () => setKind(opt.value) }), _jsxs("span", { className: "export-option-body", children: [_jsx("span", { className: "export-option-label", children: opt.label }), _jsx("span", { className: "export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsxs("fieldset", { className: "export-fieldset", children: [_jsx("legend", { className: "export-fieldset-label", children: "File format" }), formats.map((opt) => (_jsxs("label", { className: `export-option${format === opt.value ? " is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "export-format", value: opt.value, checked: format === opt.value, onChange: () => setFormat(opt.value) }), _jsxs("span", { className: "export-option-body", children: [_jsx("span", { className: "export-option-label", children: opt.label }), _jsx("span", { className: "export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsx("div", { className: "btn-row", children: _jsx("button", { type: "button", className: "btn btn-primary", onClick: download, disabled: busy, children: busy ? "Preparing…" : `Download ${format.toUpperCase()} File` }) })] })] }));
53
+ return (_jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Choose what to export" }) }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsxs("p", { className: "blog_note", style: { marginTop: 0 }, children: ["Download a JSON, XML, or CSV file from the mock store", brandSlug ? ` (currently ${brandName})` : " (all brands)", "."] }), error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, _jsxs("fieldset", { className: "blog_export-fieldset", children: [_jsx("legend", { className: "blog_sr-only", children: "Export type" }), options.map((opt) => (_jsxs("label", { className: `blog_export-option${kind === opt.value ? " blog_is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "export-kind", value: opt.value, checked: kind === opt.value, onChange: () => setKind(opt.value) }), _jsxs("span", { className: "blog_export-option-body", children: [_jsx("span", { className: "blog_export-option-label", children: opt.label }), _jsx("span", { className: "blog_export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsxs("fieldset", { className: "blog_export-fieldset", children: [_jsx("legend", { className: "blog_export-fieldset-label", children: "File format" }), formats.map((opt) => (_jsxs("label", { className: `blog_export-option${format === opt.value ? " blog_is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "export-format", value: opt.value, checked: format === opt.value, onChange: () => setFormat(opt.value) }), _jsxs("span", { className: "blog_export-option-body", children: [_jsx("span", { className: "blog_export-option-label", children: opt.label }), _jsx("span", { className: "blog_export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsx("div", { className: "blog_btn-row", children: _jsx("button", { type: "button", className: "blog_btn blog_btn-primary", onClick: download, disabled: busy, children: busy ? "Preparing…" : `Download ${format.toUpperCase()} File` }) })] })] }));
54
54
  }
55
55
  export function ImportTool() {
56
56
  const store = useAdminMock();
@@ -95,12 +95,12 @@ export function ImportTool() {
95
95
  setBusy(false);
96
96
  }
97
97
  };
98
- return (_jsxs("section", { className: "panel", children: [_jsxs("div", { className: "panel-head", children: [_jsx("h2", { children: "Choose what to import" }), _jsx("span", { className: "hint", children: brandName })] }), _jsxs("div", { className: "panel-body stack", children: [_jsxs("p", { className: "note", style: { marginTop: 0 }, children: ["Upload a JSON file from Tools \u2192 Export. Scoped to ", brandSlug || brandName, "."] }), error ? (_jsx("p", { className: "form-error", role: "alert", children: error })) : null, result ? (_jsxs("div", { className: "form-ok", role: "status", children: ["Imported ", result.postsCreated, " post", result.postsCreated === 1 ? "" : "s", result.postsSkipped ? ` (${result.postsSkipped} skipped)` : "", ", ", result.commentsCreated, " comment", result.commentsCreated === 1 ? "" : "s", result.commentsSkipped ? ` (${result.commentsSkipped} skipped)` : "", "."] })) : null, _jsxs("fieldset", { className: "export-fieldset", children: [_jsx("legend", { className: "sr-only", children: "Import type" }), options.map((opt) => (_jsxs("label", { className: `export-option${kind === opt.value ? " is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "import-kind", value: opt.value, checked: kind === opt.value, onChange: () => setKind(opt.value) }), _jsxs("span", { className: "export-option-body", children: [_jsx("span", { className: "export-option-label", children: opt.label }), _jsx("span", { className: "export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsxs("div", { className: "import-file", children: [_jsx("input", { ref: fileRef, type: "file", accept: ".json,application/json", className: "sr-only", onChange: (e) => {
98
+ return (_jsxs("section", { className: "blog_panel", children: [_jsxs("div", { className: "blog_panel-head", children: [_jsx("h2", { children: "Choose what to import" }), _jsx("span", { className: "blog_hint", children: brandName })] }), _jsxs("div", { className: "blog_panel-body blog_stack", children: [_jsxs("p", { className: "blog_note", style: { marginTop: 0 }, children: ["Upload a JSON file from Tools \u2192 Export. Scoped to ", brandSlug || brandName, "."] }), error ? (_jsx("p", { className: "blog_form-error", role: "alert", children: error })) : null, result ? (_jsxs("div", { className: "blog_form-ok", role: "status", children: ["Imported ", result.postsCreated, " post", result.postsCreated === 1 ? "" : "s", result.postsSkipped ? ` (${result.postsSkipped} skipped)` : "", ", ", result.commentsCreated, " comment", result.commentsCreated === 1 ? "" : "s", result.commentsSkipped ? ` (${result.commentsSkipped} skipped)` : "", "."] })) : null, _jsxs("fieldset", { className: "blog_export-fieldset", children: [_jsx("legend", { className: "blog_sr-only", children: "Import type" }), options.map((opt) => (_jsxs("label", { className: `blog_export-option${kind === opt.value ? " blog_is-on" : ""}`, children: [_jsx("input", { type: "radio", name: "import-kind", value: opt.value, checked: kind === opt.value, onChange: () => setKind(opt.value) }), _jsxs("span", { className: "blog_export-option-body", children: [_jsx("span", { className: "blog_export-option-label", children: opt.label }), _jsx("span", { className: "blog_export-option-desc", children: opt.description })] })] }, opt.value)))] }), _jsxs("div", { className: "blog_import-file", children: [_jsx("input", { ref: fileRef, type: "file", accept: ".json,application/json", className: "blog_sr-only", onChange: (e) => {
99
99
  setFile(e.target.files?.[0] ?? null);
100
100
  setResult(null);
101
101
  setError(null);
102
- } }), _jsx("button", { type: "button", className: "btn", onClick: () => fileRef.current?.click(), disabled: busy, children: file ? "Change file" : "Choose file" }), _jsx("span", { className: "import-file-name mono", children: file ? file.name : "JSON" })] }), _jsx("div", { className: "btn-row", children: _jsx("button", { type: "button", className: "btn btn-primary", onClick: () => void runImport(), disabled: busy || !file, children: busy ? "Importing…" : "Run Import" }) })] })] }));
102
+ } }), _jsx("button", { type: "button", className: "blog_btn", onClick: () => fileRef.current?.click(), disabled: busy, children: file ? "Change file" : "Choose file" }), _jsx("span", { className: "blog_import-file-name blog_mono", children: file ? file.name : "JSON" })] }), _jsx("div", { className: "blog_btn-row", children: _jsx("button", { type: "button", className: "blog_btn blog_btn-primary", onClick: () => void runImport(), disabled: busy || !file, children: busy ? "Importing…" : "Run Import" }) })] })] }));
103
103
  }
104
104
  export function ToolsHub({ onExport, onImport }) {
105
- return (_jsxs(_Fragment, { children: [_jsx("p", { className: "explain", children: "Utilities for moving content in and out of the portal. Import and export are scoped to the brand selected in the top bar." }), _jsxs("section", { className: "panel", children: [_jsx("div", { className: "panel-head", children: _jsx("h2", { children: "Available Tools" }) }), _jsxs("ul", { className: "seo-link-list", children: [_jsx("li", { children: _jsxs("button", { type: "button", onClick: onExport, style: { width: "100%", textAlign: "left" }, children: [_jsxs("span", { children: [_jsx("strong", { children: "Export" }), _jsx("span", { className: "cell-sub", style: { display: "block", marginTop: 4 }, children: "Download posts and media as JSON, XML, or CSV." })] }), _jsx("span", { className: "mono", children: "Open \u2192" })] }) }), _jsx("li", { children: _jsxs("button", { type: "button", onClick: onImport, style: { width: "100%", textAlign: "left" }, children: [_jsxs("span", { children: [_jsx("strong", { children: "Import" }), _jsx("span", { className: "cell-sub", style: { display: "block", marginTop: 4 }, children: "Bulk import blog posts and comments from JSON." })] }), _jsx("span", { className: "mono", children: "Open \u2192" })] }) })] })] })] }));
105
+ return (_jsxs(_Fragment, { children: [_jsx("p", { className: "blog_explain", children: "Utilities for moving content in and out of the portal. Import and export are scoped to the brand selected in the top bar." }), _jsxs("section", { className: "blog_panel", children: [_jsx("div", { className: "blog_panel-head", children: _jsx("h2", { children: "Available Tools" }) }), _jsxs("ul", { className: "blog_seo-link-list", children: [_jsx("li", { children: _jsxs("button", { type: "button", onClick: onExport, style: { width: "100%", textAlign: "left" }, children: [_jsxs("span", { children: [_jsx("strong", { children: "Export" }), _jsx("span", { className: "blog_cell-sub", style: { display: "block", marginTop: 4 }, children: "Download posts and media as JSON, XML, or CSV." })] }), _jsx("span", { className: "blog_mono", children: "Open \u2192" })] }) }), _jsx("li", { children: _jsxs("button", { type: "button", onClick: onImport, style: { width: "100%", textAlign: "left" }, children: [_jsxs("span", { children: [_jsx("strong", { children: "Import" }), _jsx("span", { className: "blog_cell-sub", style: { display: "block", marginTop: 4 }, children: "Bulk import blog posts and comments from JSON." })] }), _jsx("span", { className: "blog_mono", children: "Open \u2192" })] }) })] })] })] }));
106
106
  }
@@ -10,13 +10,13 @@ export function BlogCard({ blog, theme, onSelect, href, lead = false, index = 0,
10
10
  const thumb = blog.featured_image;
11
11
  const showThumb = Boolean(thumb) && !imgFailed;
12
12
  const readingMinutes = estimateReadingMinutes([blog.excerpt, blog.content].filter(Boolean).join(" "));
13
- const body = (_jsxs(_Fragment, { children: [showThumb ? (_jsx("span", { className: "card-img", children: _jsx("img", { src: thumb, alt: blog.title, width: lead ? 1600 : 768, height: lead ? 900 : 512, loading: priority ? "eager" : "lazy", decoding: "async", onError: () => setImgFailed(true) }) })) : (_jsx("span", { className: "card-img card-img-blank", "aria-hidden": "true" })), _jsxs("span", { className: "card-body", children: [categoryName ? _jsx("span", { className: "card-eyebrow", children: categoryName }) : null, _jsx("span", { className: "card-title", children: blog.title }), resolved.showExcerpt && blog.excerpt ? (_jsx("span", { className: "card-excerpt", children: blog.excerpt })) : null, _jsxs("span", { className: "card-meta", children: [resolved.showDate && published ? (_jsx("time", { dateTime: published, children: formatDate(published) })) : null, resolved.showAuthor && blog.author?.name ? (_jsx("span", { children: blog.author.name })) : null, _jsxs("span", { children: [readingMinutes, " min read"] })] })] })] }));
14
- return (_jsx("li", { className: lead ? "card card-lead" : "card", style: { ["--motion-i"]: index }, children: href ? (_jsx("a", { href: href, children: body })) : (_jsx("button", { type: "button", className: "card-link", onClick: () => onSelect?.(blog), children: body })) }));
13
+ const body = (_jsxs(_Fragment, { children: [showThumb ? (_jsx("span", { className: "blog_card-img", children: _jsx("img", { src: thumb, alt: blog.title, width: lead ? 1600 : 768, height: lead ? 900 : 512, loading: priority ? "eager" : "lazy", decoding: "async", onError: () => setImgFailed(true) }) })) : (_jsx("span", { className: "blog_card-img blog_card-img-blank", "aria-hidden": "true" })), _jsxs("span", { className: "blog_card-body", children: [categoryName ? _jsx("span", { className: "blog_card-eyebrow", children: categoryName }) : null, _jsx("span", { className: "blog_card-title", children: blog.title }), resolved.showExcerpt && blog.excerpt ? (_jsx("span", { className: "blog_card-excerpt", children: blog.excerpt })) : null, _jsxs("span", { className: "blog_card-meta", children: [resolved.showDate && published ? (_jsx("time", { dateTime: published, children: formatDate(published) })) : null, resolved.showAuthor && blog.author?.name ? (_jsx("span", { children: blog.author.name })) : null, _jsxs("span", { children: [readingMinutes, " min read"] })] })] })] }));
14
+ return (_jsx("li", { className: lead ? "blog_card blog_card-lead" : "blog_card", style: { ["--motion-i"]: index }, children: href ? (_jsx("a", { href: href, children: body })) : (_jsx("button", { type: "button", className: "blog_card-link", onClick: () => onSelect?.(blog), children: body })) }));
15
15
  }
16
16
  export function BlogGrid({ blogs, theme, onSelect, getHref, className, leadFirst = false, }) {
17
17
  if (blogs.length === 0)
18
18
  return null;
19
19
  const lead = leadFirst ? blogs[0] : null;
20
20
  const rest = leadFirst ? blogs.slice(1) : blogs;
21
- return (_jsxs(_Fragment, { children: [lead ? (_jsx("ul", { className: "post-grid post-grid-lead", children: _jsx(BlogCard, { blog: lead, theme: theme, onSelect: onSelect, href: getHref?.(lead), lead: true, priority: true, index: 0 }) })) : null, rest.length > 0 ? (_jsx("ul", { className: className ? `post-grid ${className}` : "post-grid", children: rest.map((blog, i) => (_jsx(BlogCard, { blog: blog, theme: theme, onSelect: onSelect, href: getHref?.(blog), priority: !lead && i === 0, index: i }, blog.id))) })) : null] }));
21
+ return (_jsxs(_Fragment, { children: [lead ? (_jsx("ul", { className: "blog_post-grid blog_post-grid-lead", children: _jsx(BlogCard, { blog: lead, theme: theme, onSelect: onSelect, href: getHref?.(lead), lead: true, priority: true, index: 0 }) })) : null, rest.length > 0 ? (_jsx("ul", { className: className ? `post-grid ${className}` : "blog_post-grid", children: rest.map((blog, i) => (_jsx(BlogCard, { blog: blog, theme: theme, onSelect: onSelect, href: getHref?.(blog), priority: !lead && i === 0, index: i }, blog.id))) })) : null] }));
22
22
  }
@@ -7,5 +7,5 @@ import { EmptyState, ErrorState, LoadingState, Scope } from "./internal/States";
7
7
  export function BlogCategories({ config, theme, branding, className, onSelect, }) {
8
8
  const client = useMemo(() => new BlogClient(config), [config.apiUrl, config.publicApiKey, config.email, config.domain, config.timeoutMs]);
9
9
  const state = useAsync(() => client.getCategories(), [client], (data) => data.length === 0);
10
- return (_jsxs(Scope, { className: cx("bp-blog-categories", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading categories..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No categories yet." }) : null, state.status === "success" ? (_jsx("ul", { className: "bp-blog-categories__list", style: { listStyle: "none", padding: 0, margin: 0 }, children: state.data.map((category) => (_jsx("li", { style: { marginBottom: "0.5rem" }, children: _jsx("button", { type: "button", onClick: () => onSelect?.(category), children: category.name }) }, category.id))) })) : null] }));
10
+ return (_jsxs(Scope, { className: cx("blog_bp-blog-categories", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading categories..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No categories yet." }) : null, state.status === "success" ? (_jsx("ul", { className: "blog_bp-blog-categories__list", style: { listStyle: "none", padding: 0, margin: 0 }, children: state.data.map((category) => (_jsx("li", { style: { marginBottom: "0.5rem" }, children: _jsx("button", { type: "button", onClick: () => onSelect?.(category), children: category.name }) }, category.id))) })) : null] }));
11
11
  }
@@ -86,5 +86,5 @@ export function BlogDetail({ config, slug, theme, branding, className, trackView
86
86
  publishedAt: r.published_at,
87
87
  readingMinutes: estimateReadingMinutes(r.content || ""),
88
88
  }));
89
- return (_jsxs(Scope, { className: cx("bp-blog-detail", "bp-site-article", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.authError ? state.error : "Blog not found.", authError: state.authError })) : null, post ? (_jsxs(_Fragment, { children: [_jsx(ReadingProgress, {}), _jsx(ArticleDetailHero, { homeHref: homeHref, homeLabel: homeLabel, category: post.category ? { slug: post.category.slug, name: post.category.name } : null, categoryHref: post.category ? categoryPath(post.category.slug) : null, title: post.title, excerpt: post.excerpt, publishedAt: post.published_at, readingMinutes: readingMinutes, authors: authors, mediaUrl: mediaUrl, mediaAlt: post.title, onBack: onBack, onHome: onHome, onCategory: onCategory }), _jsxs("main", { className: "wrap article-shell", children: [_jsx(ArticleRailDetails, { className: "rail-details-mobile", owners: authors, related: railRelated, hrefFor: postPath, onSelect: onSelectRelated }), _jsxs("article", { className: "article", children: [_jsx("div", { className: "prose", dangerouslySetInnerHTML: { __html: contentHtml } }), categories.length > 0 || tags.length > 0 ? (_jsxs("div", { className: "tag-row", children: [categories.map((c) => onCategory ? (_jsx("button", { type: "button", className: "tag-pill", onClick: () => onCategory(c.slug), children: c.name }, c.id)) : (_jsx("a", { className: "tag-pill", href: categoryPath(c.slug), children: c.name }, c.id))), tags.map((t) => (_jsxs("span", { className: "tag-pill", children: ["#", t.name] }, t.id)))] })) : null, _jsx("div", { className: "share-foot", children: _jsx(ShareRow, { title: post.title, slug: post.slug, origin: origin || (config.domain ? `https://${config.domain}` : ""), path: postPath(post.slug) }) }), authors.map((a) => (_jsx("div", { className: "author-card", children: _jsxs("div", { children: [_jsxs("p", { className: "author-name", children: [a.name, a.jobTitle ? _jsxs("span", { children: [" \u2014 ", a.jobTitle] }) : null] }), a.bio ? _jsx("p", { className: "author-bio", children: a.bio }) : null] }) }, a.id))), _jsx(CommentSection, { postId: post.id, allowComments: allowComments, initialComments: initialComments, onSubmitComment: onSubmitComment })] }), _jsxs("aside", { className: "rail", children: [_jsx(ArticleRailDetails, { className: "rail-details-desktop", owners: authors, related: railRelated, hrefFor: postPath, onSelect: onSelectRelated }), headings.length > 1 ? (_jsxs("nav", { className: "toc", "aria-label": "On this page", children: [_jsx("p", { className: "rail-title", children: "On this page" }), _jsx("ol", { children: headings.map((h) => (_jsx("li", { className: h.level === 3 ? "sub" : undefined, children: _jsx("a", { href: `#${h.id}`, children: h.text }) }, h.id))) })] })) : null] })] })] })) : state.status === "success" || state.status === "empty" ? (_jsx(EmptyState, { label: "Blog not found." })) : null] }));
89
+ return (_jsxs(Scope, { className: cx("blog_bp-blog-detail", "blog_bp-site-article", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [state.status === "loading" ? _jsx(LoadingState, { label: "Loading..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.authError ? state.error : "Blog not found.", authError: state.authError })) : null, post ? (_jsxs(_Fragment, { children: [_jsx(ReadingProgress, {}), _jsx(ArticleDetailHero, { homeHref: homeHref, homeLabel: homeLabel, category: post.category ? { slug: post.category.slug, name: post.category.name } : null, categoryHref: post.category ? categoryPath(post.category.slug) : null, title: post.title, excerpt: post.excerpt, publishedAt: post.published_at, readingMinutes: readingMinutes, authors: authors, mediaUrl: mediaUrl, mediaAlt: post.title, onBack: onBack, onHome: onHome, onCategory: onCategory }), _jsxs("main", { className: "blog_wrap blog_article-shell", children: [_jsx(ArticleRailDetails, { className: "blog_rail-details-mobile", owners: authors, related: railRelated, hrefFor: postPath, onSelect: onSelectRelated }), _jsxs("article", { className: "blog_article", children: [_jsx("div", { className: "blog_prose", dangerouslySetInnerHTML: { __html: contentHtml } }), categories.length > 0 || tags.length > 0 ? (_jsxs("div", { className: "blog_tag-row", children: [categories.map((c) => onCategory ? (_jsx("button", { type: "button", className: "blog_tag-pill", onClick: () => onCategory(c.slug), children: c.name }, c.id)) : (_jsx("a", { className: "blog_tag-pill", href: categoryPath(c.slug), children: c.name }, c.id))), tags.map((t) => (_jsxs("span", { className: "blog_tag-pill", children: ["#", t.name] }, t.id)))] })) : null, _jsx("div", { className: "blog_share-foot", children: _jsx(ShareRow, { title: post.title, slug: post.slug, origin: origin || (config.domain ? `https://${config.domain}` : ""), path: postPath(post.slug) }) }), authors.map((a) => (_jsx("div", { className: "blog_author-card", children: _jsxs("div", { children: [_jsxs("p", { className: "blog_author-name", children: [a.name, a.jobTitle ? _jsxs("span", { children: [" \u2014 ", a.jobTitle] }) : null] }), a.bio ? _jsx("p", { className: "blog_author-bio", children: a.bio }) : null] }) }, a.id))), _jsx(CommentSection, { postId: post.id, allowComments: allowComments, initialComments: initialComments, onSubmitComment: onSubmitComment })] }), _jsxs("aside", { className: "blog_rail", children: [_jsx(ArticleRailDetails, { className: "blog_rail-details-desktop", owners: authors, related: railRelated, hrefFor: postPath, onSelect: onSelectRelated }), headings.length > 1 ? (_jsxs("nav", { className: "blog_toc", "aria-label": "On this page", children: [_jsx("p", { className: "blog_rail-title", children: "On this page" }), _jsx("ol", { children: headings.map((h) => (_jsx("li", { className: h.level === 3 ? "blog_sub" : undefined, children: _jsx("a", { href: `#${h.id}`, children: h.text }) }, h.id))) })] })) : null] })] })] })) : state.status === "success" || state.status === "empty" ? (_jsx(EmptyState, { label: "Blog not found." })) : null] }));
90
90
  }
@@ -52,5 +52,5 @@ export function BlogList({ config, theme, branding, className, params, onSelect,
52
52
  setCategoryId(id);
53
53
  setPage(1);
54
54
  };
55
- return (_jsxs(Scope, { className: cx("bp-site-index", branding?.className, className), style: themeVars(resolvedTheme, branding), css: branding?.css, children: [showMediaHero ? (_jsx(SiteMediaHero, { slides: heroSlides, siteName: siteName, onSelect: onSelect })) : (_jsxs("section", { className: "site-hero site-animate-in", children: [_jsxs("div", { className: "site-hero-inner", children: [_jsx("p", { className: "site-hero-eyebrow site-animate-item", children: siteName }), _jsx("h1", { className: "site-hero-title site-animate-item", children: heroTitle }), _jsx("p", { className: "site-hero-desc site-animate-item", children: heroDesc })] }), _jsx("div", { className: "site-hero-glow", "aria-hidden": "true" })] })), _jsxs("section", { className: "site-index-feed", "aria-label": feedLabel, children: [_jsxs("div", { className: "site-index-bridge", "aria-hidden": "true", children: [_jsx("span", { className: "site-index-bridge-glow" }), _jsx("span", { className: "site-index-bridge-line" })] }), _jsxs("div", { className: "site-index-feed-inner", children: [_jsxs("header", { className: "site-index-feed-head", children: [_jsx("p", { className: "site-index-feed-eyebrow", children: feedLabel }), _jsx("span", { className: "site-index-feed-rule", "aria-hidden": "true" })] }), _jsxs("div", { className: "site-page site-index-feed-body", children: [categories.length > 0 ? (_jsxs("nav", { className: "cat-bar site-animate-in", "aria-label": "Filter by category", children: [_jsx("button", { type: "button", className: "site-animate-item", "aria-current": !categoryId ? "page" : undefined, onClick: () => selectCategory(undefined), children: "All" }), categories.map((c) => (_jsx("button", { type: "button", className: "site-animate-item", "aria-current": categoryId === c.id ? "page" : undefined, onClick: () => selectCategory(c.id), children: c.name }, c.id)))] })) : null, state.status === "loading" ? _jsx(LoadingState, { label: "Loading blogs..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? (_jsx("p", { className: "empty site-animate-in", children: _jsx("span", { className: "site-animate-item", children: "Nothing published yet." }) })) : null, state.status === "success" ? (_jsxs(_Fragment, { children: [_jsx(BlogGrid, { blogs: state.data.items, theme: resolvedTheme, onSelect: onSelect, getHref: getHref, leadFirst: showLeadCard && state.data.items.length > 0 }), totalPages > 1 ? (_jsxs("div", { className: "pagination", children: [_jsx("button", { type: "button", disabled: page <= 1, onClick: () => setPage((value) => Math.max(1, value - 1)), children: "Previous" }), _jsxs("span", { children: ["Page ", page, " of ", totalPages] }), _jsx("button", { type: "button", disabled: page >= totalPages, onClick: () => setPage((value) => value + 1), children: "Next" })] })) : null] })) : null] })] })] })] }));
55
+ return (_jsxs(Scope, { className: cx("blog_bp-site-index", branding?.className, className), style: themeVars(resolvedTheme, branding), css: branding?.css, children: [showMediaHero ? (_jsx(SiteMediaHero, { slides: heroSlides, siteName: siteName, onSelect: onSelect })) : (_jsxs("section", { className: "blog_site-hero blog_site-animate-in", children: [_jsxs("div", { className: "blog_site-hero-inner", children: [_jsx("p", { className: "blog_site-hero-eyebrow blog_site-animate-item", children: siteName }), _jsx("h1", { className: "blog_site-hero-title blog_site-animate-item", children: heroTitle }), _jsx("p", { className: "blog_site-hero-desc blog_site-animate-item", children: heroDesc })] }), _jsx("div", { className: "blog_site-hero-glow", "aria-hidden": "true" })] })), _jsxs("section", { className: "blog_site-index-feed", "aria-label": feedLabel, children: [_jsxs("div", { className: "blog_site-index-bridge", "aria-hidden": "true", children: [_jsx("span", { className: "blog_site-index-bridge-glow" }), _jsx("span", { className: "blog_site-index-bridge-line" })] }), _jsxs("div", { className: "blog_site-index-feed-inner", children: [_jsxs("header", { className: "blog_site-index-feed-head", children: [_jsx("p", { className: "blog_site-index-feed-eyebrow", children: feedLabel }), _jsx("span", { className: "blog_site-index-feed-rule", "aria-hidden": "true" })] }), _jsxs("div", { className: "blog_site-page blog_site-index-feed-body", children: [categories.length > 0 ? (_jsxs("nav", { className: "blog_cat-bar blog_site-animate-in", "aria-label": "Filter by category", children: [_jsx("button", { type: "button", className: "blog_site-animate-item", "aria-current": !categoryId ? "page" : undefined, onClick: () => selectCategory(undefined), children: "All" }), categories.map((c) => (_jsx("button", { type: "button", className: "blog_site-animate-item", "aria-current": categoryId === c.id ? "page" : undefined, onClick: () => selectCategory(c.id), children: c.name }, c.id)))] })) : null, state.status === "loading" ? _jsx(LoadingState, { label: "Loading blogs..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? (_jsx("p", { className: "blog_empty blog_site-animate-in", children: _jsx("span", { className: "blog_site-animate-item", children: "Nothing published yet." }) })) : null, state.status === "success" ? (_jsxs(_Fragment, { children: [_jsx(BlogGrid, { blogs: state.data.items, theme: resolvedTheme, onSelect: onSelect, getHref: getHref, leadFirst: showLeadCard && state.data.items.length > 0 }), totalPages > 1 ? (_jsxs("div", { className: "blog_pagination", children: [_jsx("button", { type: "button", disabled: page <= 1, onClick: () => setPage((value) => Math.max(1, value - 1)), children: "Previous" }), _jsxs("span", { children: ["Page ", page, " of ", totalPages] }), _jsx("button", { type: "button", disabled: page >= totalPages, onClick: () => setPage((value) => value + 1), children: "Next" })] })) : null] })) : null] })] })] })] }));
56
56
  }
@@ -12,8 +12,8 @@ export function BlogSearch({ config, theme, branding, className, onSelect, getHr
12
12
  const state = useAsync(() => submitted
13
13
  ? client.searchBlogs(submitted, { page: 1, page_size: 12 })
14
14
  : Promise.resolve({ items: [], page: 1, pageSize: 12, total: 0 }), [client, submitted], (data) => submitted !== "" && data.items.length === 0);
15
- return (_jsxs(Scope, { className: cx("bp-site-index", "bp-blog-search", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [_jsxs("form", { className: "bp-blog-search__form", onSubmit: (event) => {
15
+ return (_jsxs(Scope, { className: cx("blog_bp-site-index", "blog_bp-blog-search", branding?.className, className), style: themeVars(theme, branding), css: branding?.css, children: [_jsxs("form", { className: "blog_bp-blog-search__form", onSubmit: (event) => {
16
16
  event.preventDefault();
17
17
  setSubmitted(query.trim());
18
- }, style: { display: "flex", gap: "0.5rem", marginBottom: "1rem" }, children: [_jsx("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: placeholder, "aria-label": "Search blogs", style: { flex: 1, padding: "0.6rem 0.75rem", borderRadius: "var(--bp-radius)" } }), _jsx("button", { type: "submit", children: "Search" })] }), !submitted ? _jsx("p", { className: "bp-state", children: "Enter a search term to find posts." }) : null, submitted && state.status === "loading" ? _jsx(LoadingState, { label: "Searching..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No matching posts." }) : null, state.status === "success" ? (_jsx(BlogGrid, { blogs: state.data.items, theme: theme, onSelect: onSelect, getHref: getHref })) : null] }));
18
+ }, style: { display: "flex", gap: "0.5rem", marginBottom: "1rem" }, children: [_jsx("input", { value: query, onChange: (event) => setQuery(event.target.value), placeholder: placeholder, "aria-label": "Search blogs", style: { flex: 1, padding: "0.6rem 0.75rem", borderRadius: "var(--bp-radius)" } }), _jsx("button", { type: "submit", children: "Search" })] }), !submitted ? _jsx("p", { className: "blog_bp-state", children: "Enter a search term to find posts." }) : null, submitted && state.status === "loading" ? _jsx(LoadingState, { label: "Searching..." }) : null, state.status === "error" ? (_jsx(ErrorState, { message: state.error, authError: state.authError })) : null, state.status === "empty" ? _jsx(EmptyState, { label: "No matching posts." }) : null, state.status === "success" ? (_jsx(BlogGrid, { blogs: state.data.items, theme: theme, onSelect: onSelect, getHref: getHref })) : null] }));
19
19
  }