@actuate-media/cms-admin 0.19.0 → 0.21.0

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 (129) hide show
  1. package/dist/AdminRoot.d.ts.map +1 -1
  2. package/dist/AdminRoot.js +13 -9
  3. package/dist/AdminRoot.js.map +1 -1
  4. package/dist/__tests__/layout/sidebar-posts.test.js +6 -4
  5. package/dist/__tests__/layout/sidebar-posts.test.js.map +1 -1
  6. package/dist/__tests__/lib/seo-service-errors.test.d.ts +2 -0
  7. package/dist/__tests__/lib/seo-service-errors.test.d.ts.map +1 -0
  8. package/dist/__tests__/lib/seo-service-errors.test.js +46 -0
  9. package/dist/__tests__/lib/seo-service-errors.test.js.map +1 -0
  10. package/dist/__tests__/views/use-seo-resource.test.d.ts +2 -0
  11. package/dist/__tests__/views/use-seo-resource.test.d.ts.map +1 -0
  12. package/dist/__tests__/views/use-seo-resource.test.js +56 -0
  13. package/dist/__tests__/views/use-seo-resource.test.js.map +1 -0
  14. package/dist/actuate-admin.css +1 -1
  15. package/dist/components/Breadcrumbs.d.ts.map +1 -1
  16. package/dist/components/Breadcrumbs.js +4 -1
  17. package/dist/components/Breadcrumbs.js.map +1 -1
  18. package/dist/components/seo/Drawer.d.ts +11 -0
  19. package/dist/components/seo/Drawer.d.ts.map +1 -0
  20. package/dist/components/seo/Drawer.js +17 -0
  21. package/dist/components/seo/Drawer.js.map +1 -0
  22. package/dist/components/seo/RedirectEditorDrawer.d.ts +9 -0
  23. package/dist/components/seo/RedirectEditorDrawer.d.ts.map +1 -0
  24. package/dist/components/seo/RedirectEditorDrawer.js +94 -0
  25. package/dist/components/seo/RedirectEditorDrawer.js.map +1 -0
  26. package/dist/components/seo/SeoCopilotDrawer.d.ts +10 -0
  27. package/dist/components/seo/SeoCopilotDrawer.d.ts.map +1 -0
  28. package/dist/components/seo/SeoCopilotDrawer.js +34 -0
  29. package/dist/components/seo/SeoCopilotDrawer.js.map +1 -0
  30. package/dist/components/seo/SeoEditorDrawer.d.ts +8 -0
  31. package/dist/components/seo/SeoEditorDrawer.d.ts.map +1 -0
  32. package/dist/components/seo/SeoEditorDrawer.js +120 -0
  33. package/dist/components/seo/SeoEditorDrawer.js.map +1 -0
  34. package/dist/components/seo/SeoIssueFixDrawer.d.ts +8 -0
  35. package/dist/components/seo/SeoIssueFixDrawer.d.ts.map +1 -0
  36. package/dist/components/seo/SeoIssueFixDrawer.js +111 -0
  37. package/dist/components/seo/SeoIssueFixDrawer.js.map +1 -0
  38. package/dist/components/seo/primitives.d.ts +53 -0
  39. package/dist/components/seo/primitives.d.ts.map +1 -0
  40. package/dist/components/seo/primitives.js +101 -0
  41. package/dist/components/seo/primitives.js.map +1 -0
  42. package/dist/layout/Sidebar.d.ts.map +1 -1
  43. package/dist/layout/Sidebar.js +8 -5
  44. package/dist/layout/Sidebar.js.map +1 -1
  45. package/dist/lib/seo-service.d.ts +322 -0
  46. package/dist/lib/seo-service.d.ts.map +1 -0
  47. package/dist/lib/seo-service.js +331 -0
  48. package/dist/lib/seo-service.js.map +1 -0
  49. package/dist/router/index.d.ts.map +1 -1
  50. package/dist/router/index.js +4 -1
  51. package/dist/router/index.js.map +1 -1
  52. package/dist/views/ApiKeys.d.ts +4 -1
  53. package/dist/views/ApiKeys.d.ts.map +1 -1
  54. package/dist/views/ApiKeys.js +5 -3
  55. package/dist/views/ApiKeys.js.map +1 -1
  56. package/dist/views/Dashboard.js +2 -2
  57. package/dist/views/Dashboard.js.map +1 -1
  58. package/dist/views/MediaBrowser.d.ts.map +1 -1
  59. package/dist/views/MediaBrowser.js +36 -25
  60. package/dist/views/MediaBrowser.js.map +1 -1
  61. package/dist/views/Posts/NewPostTypeInstructions.js +2 -2
  62. package/dist/views/Posts/post-type-presets.d.ts +5 -0
  63. package/dist/views/Posts/post-type-presets.d.ts.map +1 -1
  64. package/dist/views/Posts/post-type-presets.js +10 -64
  65. package/dist/views/Posts/post-type-presets.js.map +1 -1
  66. package/dist/views/SEO.d.ts.map +1 -1
  67. package/dist/views/SEO.js +89 -132
  68. package/dist/views/SEO.js.map +1 -1
  69. package/dist/views/Settings.d.ts +4 -1
  70. package/dist/views/Settings.d.ts.map +1 -1
  71. package/dist/views/Settings.js +45 -6
  72. package/dist/views/Settings.js.map +1 -1
  73. package/dist/views/Users.d.ts +4 -1
  74. package/dist/views/Users.d.ts.map +1 -1
  75. package/dist/views/Users.js +5 -3
  76. package/dist/views/Users.js.map +1 -1
  77. package/dist/views/seo/AuditTab.d.ts +6 -0
  78. package/dist/views/seo/AuditTab.d.ts.map +1 -0
  79. package/dist/views/seo/AuditTab.js +57 -0
  80. package/dist/views/seo/AuditTab.js.map +1 -0
  81. package/dist/views/seo/ContentTab.d.ts +5 -0
  82. package/dist/views/seo/ContentTab.d.ts.map +1 -0
  83. package/dist/views/seo/ContentTab.js +27 -0
  84. package/dist/views/seo/ContentTab.js.map +1 -0
  85. package/dist/views/seo/OverviewTab.d.ts +8 -0
  86. package/dist/views/seo/OverviewTab.d.ts.map +1 -0
  87. package/dist/views/seo/OverviewTab.js +35 -0
  88. package/dist/views/seo/OverviewTab.js.map +1 -0
  89. package/dist/views/seo/RedirectsTab.d.ts +2 -0
  90. package/dist/views/seo/RedirectsTab.d.ts.map +1 -0
  91. package/dist/views/seo/RedirectsTab.js +130 -0
  92. package/dist/views/seo/RedirectsTab.js.map +1 -0
  93. package/dist/views/seo/TechnicalTab.d.ts +2 -0
  94. package/dist/views/seo/TechnicalTab.d.ts.map +1 -0
  95. package/dist/views/seo/TechnicalTab.js +105 -0
  96. package/dist/views/seo/TechnicalTab.js.map +1 -0
  97. package/dist/views/seo/useSeoResource.d.ts +8 -0
  98. package/dist/views/seo/useSeoResource.d.ts.map +1 -0
  99. package/dist/views/seo/useSeoResource.js +55 -0
  100. package/dist/views/seo/useSeoResource.js.map +1 -0
  101. package/package.json +2 -2
  102. package/src/AdminRoot.tsx +13 -9
  103. package/src/__tests__/layout/sidebar-posts.test.ts +6 -4
  104. package/src/__tests__/lib/seo-service-errors.test.ts +60 -0
  105. package/src/__tests__/views/use-seo-resource.test.tsx +68 -0
  106. package/src/components/Breadcrumbs.tsx +4 -1
  107. package/src/components/seo/Drawer.tsx +65 -0
  108. package/src/components/seo/RedirectEditorDrawer.tsx +235 -0
  109. package/src/components/seo/SeoCopilotDrawer.tsx +76 -0
  110. package/src/components/seo/SeoEditorDrawer.tsx +359 -0
  111. package/src/components/seo/SeoIssueFixDrawer.tsx +244 -0
  112. package/src/components/seo/primitives.tsx +240 -0
  113. package/src/layout/Sidebar.tsx +7 -10
  114. package/src/lib/seo-service.ts +660 -0
  115. package/src/router/index.ts +4 -1
  116. package/src/views/ApiKeys.tsx +10 -5
  117. package/src/views/Dashboard.tsx +2 -2
  118. package/src/views/MediaBrowser.tsx +89 -67
  119. package/src/views/Posts/NewPostTypeInstructions.tsx +2 -2
  120. package/src/views/Posts/post-type-presets.ts +15 -64
  121. package/src/views/SEO.tsx +186 -863
  122. package/src/views/Settings.tsx +93 -40
  123. package/src/views/Users.tsx +10 -4
  124. package/src/views/seo/AuditTab.tsx +229 -0
  125. package/src/views/seo/ContentTab.tsx +164 -0
  126. package/src/views/seo/OverviewTab.tsx +257 -0
  127. package/src/views/seo/RedirectsTab.tsx +398 -0
  128. package/src/views/seo/TechnicalTab.tsx +315 -0
  129. package/src/views/seo/useSeoResource.ts +66 -0
@@ -0,0 +1,94 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import { toast } from 'sonner';
5
+ import { createRedirectRule, updateRedirectRule, } from '../../lib/seo-service.js';
6
+ import { Drawer } from './Drawer.js';
7
+ import { btnPrimary, btnSecondary } from './primitives.js';
8
+ const STATUS_CODES = [
9
+ { value: 301, label: '301 — Permanent' },
10
+ { value: 302, label: '302 — Temporary' },
11
+ { value: 307, label: '307 — Temporary (preserve method)' },
12
+ { value: 308, label: '308 — Permanent (preserve method)' },
13
+ { value: 410, label: '410 — Gone (no destination)' },
14
+ ];
15
+ const inputCls = 'w-full rounded-md border border-border bg-input-background px-3 py-2 text-base text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';
16
+ function normalizePath(p) {
17
+ const t = p.trim();
18
+ if (!t)
19
+ return '';
20
+ if (/^https?:\/\//i.test(t))
21
+ return t;
22
+ return t.startsWith('/') ? t : `/${t}`;
23
+ }
24
+ export function RedirectEditorDrawer({ open, onOpenChange, rule, onSaved, }) {
25
+ const [form, setForm] = useState({
26
+ type: 301,
27
+ fromPath: '',
28
+ toPath: '',
29
+ enabled: true,
30
+ preserveQuery: false,
31
+ notes: '',
32
+ });
33
+ const [saving, setSaving] = useState(false);
34
+ const [clientError, setClientError] = useState(null);
35
+ useEffect(() => {
36
+ if (!open)
37
+ return;
38
+ if (rule) {
39
+ setForm({
40
+ type: rule.type,
41
+ fromPath: rule.fromPath,
42
+ toPath: rule.toPath,
43
+ enabled: rule.enabled,
44
+ preserveQuery: rule.preserveQuery,
45
+ notes: rule.notes ?? '',
46
+ });
47
+ }
48
+ else {
49
+ setForm({
50
+ type: 301,
51
+ fromPath: '',
52
+ toPath: '',
53
+ enabled: true,
54
+ preserveQuery: false,
55
+ notes: '',
56
+ });
57
+ }
58
+ setClientError(null);
59
+ }, [open, rule]);
60
+ const isGone = form.type === 410;
61
+ const update = (patch) => setForm((f) => ({ ...f, ...patch }));
62
+ async function handleSave() {
63
+ const fromPath = normalizePath(form.fromPath);
64
+ const toPath = isGone ? '' : normalizePath(form.toPath);
65
+ if (!fromPath) {
66
+ setClientError('Source path is required.');
67
+ return;
68
+ }
69
+ if (!isGone && !toPath) {
70
+ setClientError('Destination is required for redirect status codes.');
71
+ return;
72
+ }
73
+ if (!isGone && fromPath === toPath) {
74
+ setClientError('Source and destination cannot be identical (would create a loop).');
75
+ return;
76
+ }
77
+ setClientError(null);
78
+ setSaving(true);
79
+ const payload = { ...form, fromPath, toPath };
80
+ const res = rule
81
+ ? await updateRedirectRule(rule.id, payload)
82
+ : await createRedirectRule(payload);
83
+ setSaving(false);
84
+ if (res.error) {
85
+ toast.error(res.error);
86
+ return;
87
+ }
88
+ toast.success(rule ? 'Redirect updated.' : 'Redirect created.');
89
+ onOpenChange(false);
90
+ onSaved?.();
91
+ }
92
+ return (_jsx(Drawer, { open: open, onOpenChange: onOpenChange, title: rule ? 'Edit redirect' : 'New redirect', width: "max-w-lg", footer: _jsxs(_Fragment, { children: [_jsx("button", { className: btnSecondary, onClick: () => onOpenChange(false), disabled: saving, children: "Cancel" }), _jsx("button", { className: btnPrimary, onClick: handleSave, disabled: saving, children: saving ? 'Saving…' : rule ? 'Save changes' : 'Create redirect' })] }), children: _jsxs("div", { className: "space-y-4", children: [clientError && (_jsx("p", { className: "text-destructive bg-destructive/10 rounded-md px-3 py-2 text-sm", role: "alert", children: clientError })), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-foreground text-sm font-medium", htmlFor: "redir-type", children: "Status code" }), _jsx("select", { id: "redir-type", className: inputCls, value: form.type, onChange: (e) => update({ type: Number(e.target.value) }), children: STATUS_CODES.map((s) => (_jsx("option", { value: s.value, children: s.label }, s.value))) })] }), _jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-foreground text-sm font-medium", htmlFor: "redir-from", children: "Source path" }), _jsx("input", { id: "redir-from", className: inputCls, value: form.fromPath, onChange: (e) => update({ fromPath: e.target.value }), placeholder: "/old-path" })] }), !isGone && (_jsxs("div", { className: "space-y-1.5", children: [_jsx("label", { className: "text-foreground text-sm font-medium", htmlFor: "redir-to", children: "Destination" }), _jsx("input", { id: "redir-to", className: inputCls, value: form.toPath, onChange: (e) => update({ toPath: e.target.value }), placeholder: "/new-path or https://example.com/page" })] })), _jsxs("div", { className: "space-y-1.5", children: [_jsxs("label", { className: "text-foreground text-sm font-medium", htmlFor: "redir-notes", children: ["Notes ", _jsx("span", { className: "text-muted-foreground font-normal", children: "(optional)" })] }), _jsx("input", { id: "redir-notes", className: inputCls, value: form.notes ?? '', onChange: (e) => update({ notes: e.target.value }), placeholder: "Why this redirect exists" })] }), _jsxs("div", { className: "border-border space-y-3 rounded-lg border p-4", children: [_jsxs("label", { className: "flex items-center justify-between gap-3", children: [_jsx("span", { className: "text-foreground text-sm font-medium", children: "Enabled" }), _jsx("input", { type: "checkbox", role: "switch", "aria-checked": !!form.enabled, checked: !!form.enabled, onChange: (e) => update({ enabled: e.target.checked }), className: "accent-primary h-4 w-4" })] }), !isGone && (_jsxs("label", { className: "flex items-center justify-between gap-3", children: [_jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "text-foreground block text-sm font-medium", children: "Preserve query string" }), _jsx("span", { className: "text-muted-foreground block text-sm", children: "Append the original query params to the destination." })] }), _jsx("input", { type: "checkbox", role: "switch", "aria-checked": !!form.preserveQuery, checked: !!form.preserveQuery, onChange: (e) => update({ preserveQuery: e.target.checked }), className: "accent-primary h-4 w-4 shrink-0" })] }))] })] }) }));
93
+ }
94
+ //# sourceMappingURL=RedirectEditorDrawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RedirectEditorDrawer.js","sourceRoot":"","sources":["../../../src/components/seo/RedirectEditorDrawer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * AI Copilot drawer — summarizes the current SEO state and surfaces the top
3
+ * priorities. Degrades gracefully when AI is unconfigured. All AI text is
4
+ * advisory; the editor takes action via the tabs/drawers.
5
+ */
6
+ export declare function SeoCopilotDrawer({ open, onOpenChange, }: {
7
+ open: boolean;
8
+ onOpenChange: (open: boolean) => void;
9
+ }): import("react/jsx-runtime").JSX.Element;
10
+ //# sourceMappingURL=SeoCopilotDrawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeoCopilotDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/seo/SeoCopilotDrawer.tsx"],"names":[],"mappings":"AASA;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,YAAY,GACb,EAAE;IACD,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;CACtC,2CAuDA"}
@@ -0,0 +1,34 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState } from 'react';
4
+ import { Sparkles, Bot } from 'lucide-react';
5
+ import { toast } from 'sonner';
6
+ import { summarizeSeoAudit } from '../../lib/seo-service.js';
7
+ import { Drawer } from './Drawer.js';
8
+ import { SeoLoading, SeoEmptyState, btnPrimary } from './primitives.js';
9
+ /**
10
+ * AI Copilot drawer — summarizes the current SEO state and surfaces the top
11
+ * priorities. Degrades gracefully when AI is unconfigured. All AI text is
12
+ * advisory; the editor takes action via the tabs/drawers.
13
+ */
14
+ export function SeoCopilotDrawer({ open, onOpenChange, }) {
15
+ const [loading, setLoading] = useState(false);
16
+ const [summary, setSummary] = useState(null);
17
+ const [unavailable, setUnavailable] = useState(false);
18
+ async function handleSummarize() {
19
+ setLoading(true);
20
+ setUnavailable(false);
21
+ const res = await summarizeSeoAudit();
22
+ setLoading(false);
23
+ if (res.unavailable) {
24
+ setUnavailable(true);
25
+ return;
26
+ }
27
+ if (res.text)
28
+ setSummary(res.text);
29
+ else
30
+ toast.error('No summary was returned.');
31
+ }
32
+ return (_jsx(Drawer, { open: open, onOpenChange: onOpenChange, title: "SEO Copilot", description: "AI-assisted analysis of your site's SEO health", width: "max-w-md", footer: _jsxs("button", { className: btnPrimary, onClick: handleSummarize, disabled: loading, children: [_jsx(Sparkles, { className: `h-4 w-4 ${loading ? 'animate-pulse' : ''}`, "aria-hidden": true }), loading ? 'Analyzing…' : summary ? 'Re-analyze' : 'Analyze my SEO'] }), children: loading ? (_jsx(SeoLoading, { label: "Analyzing your SEO\u2026" })) : unavailable ? (_jsx(SeoEmptyState, { icon: _jsx(Bot, { size: 24 }), title: "AI is not configured", description: "Install and configure an AI provider (plugin-ai) to enable the SEO Copilot." })) : summary ? (_jsx("div", { className: "text-foreground space-y-3 text-sm leading-relaxed", children: summary.split(/\n+/).map((para, i) => (_jsx("p", { children: para }, i))) })) : (_jsx(SeoEmptyState, { icon: _jsx(Bot, { size: 24 }), title: "Ask the Copilot", description: "Get an AI summary of your open issues and the top priorities to fix first." })) }));
33
+ }
34
+ //# sourceMappingURL=SeoCopilotDrawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeoCopilotDrawer.js","sourceRoot":"","sources":["../../../src/components/seo/SeoCopilotDrawer.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAC5C,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AACpC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAEvE;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,IAAI,EACJ,YAAY,GAIb;IACC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC7C,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAA;IAC3D,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAErD,KAAK,UAAU,eAAe;QAC5B,UAAU,CAAC,IAAI,CAAC,CAAA;QAChB,cAAc,CAAC,KAAK,CAAC,CAAA;QACrB,MAAM,GAAG,GAAG,MAAM,iBAAiB,EAAE,CAAA;QACrC,UAAU,CAAC,KAAK,CAAC,CAAA;QACjB,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;YACpB,cAAc,CAAC,IAAI,CAAC,CAAA;YACpB,OAAM;QACR,CAAC;QACD,IAAI,GAAG,CAAC,IAAI;YAAE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;;YAC7B,KAAK,CAAC,KAAK,CAAC,0BAA0B,CAAC,CAAA;IAC9C,CAAC;IAED,OAAO,CACL,KAAC,MAAM,IACL,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,YAAY,EAC1B,KAAK,EAAC,aAAa,EACnB,WAAW,EAAC,gDAAgD,EAC5D,KAAK,EAAC,UAAU,EAChB,MAAM,EACJ,kBAAQ,SAAS,EAAE,UAAU,EAAE,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,OAAO,aACxE,KAAC,QAAQ,IAAC,SAAS,EAAE,WAAW,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,EAAE,wBAAgB,EAC/E,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,gBAAgB,IAC5D,YAGV,OAAO,CAAC,CAAC,CAAC,CACT,KAAC,UAAU,IAAC,KAAK,EAAC,0BAAqB,GAAG,CAC3C,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAChB,KAAC,aAAa,IACZ,IAAI,EAAE,KAAC,GAAG,IAAC,IAAI,EAAE,EAAE,GAAI,EACvB,KAAK,EAAC,sBAAsB,EAC5B,WAAW,EAAC,6EAA6E,GACzF,CACH,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CACZ,cAAK,SAAS,EAAC,mDAAmD,YAC/D,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CACrC,sBAAY,IAAI,IAAR,CAAC,CAAY,CACtB,CAAC,GACE,CACP,CAAC,CAAC,CAAC,CACF,KAAC,aAAa,IACZ,IAAI,EAAE,KAAC,GAAG,IAAC,IAAI,EAAE,EAAE,GAAI,EACvB,KAAK,EAAC,iBAAiB,EACvB,WAAW,EAAC,4EAA4E,GACxF,CACH,GACM,CACV,CAAA;AACH,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function SeoEditorDrawer({ open, onOpenChange, entityType, entityId, onSaved, }: {
2
+ open: boolean;
3
+ onOpenChange: (open: boolean) => void;
4
+ entityType: string | null;
5
+ entityId: string | null;
6
+ onSaved?: () => void;
7
+ }): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=SeoEditorDrawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeoEditorDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/seo/SeoEditorDrawer.tsx"],"names":[],"mappings":"AAgEA,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EACJ,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,OAAO,GACR,EAAE;IACD,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB,2CA0RA"}
@@ -0,0 +1,120 @@
1
+ 'use client';
2
+ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { cloneElement, isValidElement, useEffect, useId, useState } from 'react';
4
+ import { Sparkles, Check } from 'lucide-react';
5
+ import { toast } from 'sonner';
6
+ import { fetchSeoContentRecord, updateSeoFields, generateSeoField, } from '../../lib/seo-service.js';
7
+ import { Drawer } from './Drawer.js';
8
+ import { SeoLoading, SeoErrorState, btnPrimary, btnSecondary, gradeMeta } from './primitives.js';
9
+ const META_TITLE_MAX = 60;
10
+ const META_DESC_MAX = 160;
11
+ function CharCount({ value, max }) {
12
+ const over = value.length > max;
13
+ return (_jsxs("span", { className: `text-xs ${over ? 'text-destructive' : 'text-muted-foreground'}`, children: [value.length, "/", max] }));
14
+ }
15
+ function Field({ label, children, hint, }) {
16
+ // Associate the visible label with its control for screen readers. We inject
17
+ // a generated id onto the single child input/textarea (unless it already has
18
+ // one) and point the <label htmlFor> at it.
19
+ const generatedId = useId();
20
+ let control = children;
21
+ if (isValidElement(children) && children.props.id == null) {
22
+ control = cloneElement(children, { id: generatedId });
23
+ }
24
+ const controlId = isValidElement(control) ? control.props.id : undefined;
25
+ return (_jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("label", { htmlFor: controlId, className: "text-foreground text-sm font-medium", children: label }), hint] }), control] }));
26
+ }
27
+ const inputCls = 'w-full rounded-md border border-border bg-input-background px-3 py-2 text-base text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';
28
+ export function SeoEditorDrawer({ open, onOpenChange, entityType, entityId, onSaved, }) {
29
+ const [record, setRecord] = useState(null);
30
+ const [loading, setLoading] = useState(false);
31
+ const [error, setError] = useState(null);
32
+ const [saving, setSaving] = useState(false);
33
+ const [aiBusy, setAiBusy] = useState(null);
34
+ const [form, setForm] = useState({});
35
+ useEffect(() => {
36
+ if (!open || !entityType || !entityId)
37
+ return;
38
+ let alive = true;
39
+ setLoading(true);
40
+ setError(null);
41
+ fetchSeoContentRecord(entityType, entityId)
42
+ .then((rec) => {
43
+ if (!alive)
44
+ return;
45
+ if (!rec) {
46
+ setError('Could not load this record.');
47
+ return;
48
+ }
49
+ setRecord(rec);
50
+ setForm({
51
+ metaTitle: rec.metaTitle ?? '',
52
+ metaDescription: rec.metaDescription ?? '',
53
+ canonicalUrl: rec.canonicalUrl ?? '',
54
+ focusKeyword: rec.focusKeyword ?? '',
55
+ ogTitle: rec.ogTitle ?? '',
56
+ ogDescription: rec.ogDescription ?? '',
57
+ noindex: rec.noindex,
58
+ nofollow: rec.nofollow,
59
+ });
60
+ })
61
+ .catch((e) => alive && setError(e instanceof Error ? e.message : 'Failed to load'))
62
+ .finally(() => alive && setLoading(false));
63
+ return () => {
64
+ alive = false;
65
+ };
66
+ }, [open, entityType, entityId]);
67
+ const update = (patch) => setForm((f) => ({ ...f, ...patch }));
68
+ async function handleAiGenerate(field) {
69
+ if (!entityType || !entityId)
70
+ return;
71
+ setAiBusy(field);
72
+ try {
73
+ const result = await generateSeoField(field, { entityType, entityId });
74
+ if (result.unavailable) {
75
+ toast.error('AI is not configured. Add an AI provider to enable suggestions.');
76
+ return;
77
+ }
78
+ if (result.text) {
79
+ update({ [field]: result.text });
80
+ toast.success('AI suggestion applied — review before saving.');
81
+ }
82
+ else {
83
+ toast.error('No suggestion was returned.');
84
+ }
85
+ }
86
+ catch {
87
+ toast.error('AI request failed.');
88
+ }
89
+ finally {
90
+ setAiBusy(null);
91
+ }
92
+ }
93
+ async function handleSave() {
94
+ if (!entityType || !entityId)
95
+ return;
96
+ setSaving(true);
97
+ const res = await updateSeoFields(entityType, entityId, form);
98
+ setSaving(false);
99
+ if (res.error) {
100
+ toast.error(res.error);
101
+ return;
102
+ }
103
+ toast.success('SEO fields saved.');
104
+ onOpenChange(false);
105
+ onSaved?.();
106
+ }
107
+ const title = form.metaTitle || record?.title || 'Untitled';
108
+ const desc = form.metaDescription || 'No meta description set. Search engines may generate one.';
109
+ const url = record?.url ?? '';
110
+ function aiButton(field) {
111
+ return (_jsxs("button", { type: "button", onClick: () => handleAiGenerate(field), disabled: aiBusy !== null, className: "text-primary hover:bg-accent focus-visible:ring-ring inline-flex items-center gap-1 rounded-md px-2 py-0.5 text-xs font-medium focus-visible:ring-2 focus-visible:outline-none disabled:opacity-60", children: [_jsx(Sparkles, { className: `h-3.5 w-3.5 ${aiBusy === field ? 'animate-pulse' : ''}`, "aria-hidden": true }), aiBusy === field ? 'Generating…' : 'AI Generate'] }));
112
+ }
113
+ return (_jsx(Drawer, { open: open, onOpenChange: onOpenChange, title: "Edit SEO", description: record?.title, footer: _jsxs(_Fragment, { children: [_jsx("button", { className: btnSecondary, onClick: () => onOpenChange(false), disabled: saving, children: "Cancel" }), _jsx("button", { className: btnPrimary, onClick: handleSave, disabled: saving || loading, children: saving ? 'Saving…' : 'Save changes' })] }), children: loading ? (_jsx(SeoLoading, {})) : error ? (_jsx(SeoErrorState, { message: error })) : record ? (_jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "border-border rounded-lg border p-4", children: [_jsx("p", { className: "text-muted-foreground mb-2 text-xs font-medium tracking-wide uppercase", children: "Google preview" }), _jsx("p", { className: "text-success truncate text-sm", children: url }), _jsx("p", { className: "text-primary text-lg leading-snug", children: title }), _jsx("p", { className: "text-muted-foreground line-clamp-2 text-sm", children: desc })] }), _jsx(Field, { label: "Meta title", hint: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(CharCount, { value: form.metaTitle ?? '', max: META_TITLE_MAX }), aiButton('metaTitle')] }), children: _jsx("input", { className: inputCls, value: form.metaTitle ?? '', onChange: (e) => update({ metaTitle: e.target.value }), placeholder: "Page title for search results" }) }), _jsx(Field, { label: "Meta description", hint: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(CharCount, { value: form.metaDescription ?? '', max: META_DESC_MAX }), aiButton('metaDescription')] }), children: _jsx("textarea", { className: `${inputCls} min-h-20 resize-y`, value: form.metaDescription ?? '', onChange: (e) => update({ metaDescription: e.target.value }), placeholder: "Short summary shown under the title in search results" }) }), _jsx(Field, { label: "Focus keyword", hint: aiButton('focusKeyword'), children: _jsx("input", { className: inputCls, value: form.focusKeyword ?? '', onChange: (e) => update({ focusKeyword: e.target.value }), placeholder: "Primary keyword this page targets" }) }), _jsx(Field, { label: "Canonical URL", children: _jsx("input", { className: inputCls, value: form.canonicalUrl ?? '', onChange: (e) => update({ canonicalUrl: e.target.value }), placeholder: url || 'https://example.com/page' }) }), _jsxs("div", { className: "space-y-4", children: [_jsx("p", { className: "text-foreground text-sm font-medium", children: "Social sharing" }), _jsx(Field, { label: "Open Graph title", hint: aiButton('ogTitle'), children: _jsx("input", { className: inputCls, value: form.ogTitle ?? '', onChange: (e) => update({ ogTitle: e.target.value }), placeholder: form.metaTitle || 'Title when shared on social media' }) }), _jsx(Field, { label: "Open Graph description", hint: aiButton('ogDescription'), children: _jsx("textarea", { className: `${inputCls} min-h-16 resize-y`, value: form.ogDescription ?? '', onChange: (e) => update({ ogDescription: e.target.value }), placeholder: form.metaDescription || 'Description when shared on social media' }) }), _jsxs("div", { className: "border-border overflow-hidden rounded-lg border", children: [record.ogImage ? (
114
+ // eslint-disable-next-line @next/next/no-img-element
115
+ _jsx("img", { src: record.ogImage, alt: `Social preview for ${record.title}`, className: "bg-muted aspect-[1200/630] w-full object-cover" })) : (_jsx("div", { className: "bg-muted text-muted-foreground flex aspect-[1200/630] w-full items-center justify-center text-sm", children: "No OG image set" })), _jsxs("div", { className: "p-3", children: [_jsx("p", { className: "text-muted-foreground truncate text-xs uppercase", children: url.replace(/^https?:\/\//, '').split('/')[0] }), _jsx("p", { className: "text-foreground truncate text-sm font-medium", children: form.ogTitle || title }), _jsx("p", { className: "text-muted-foreground line-clamp-1 text-sm", children: form.ogDescription || desc })] })] })] }), _jsxs("div", { className: "border-border space-y-3 rounded-lg border p-4", children: [_jsxs("label", { className: "flex items-center justify-between gap-3", children: [_jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "text-foreground block text-sm font-medium", children: "No-index" }), _jsx("span", { className: "text-muted-foreground block text-sm", children: "Hide this page from search engines." })] }), _jsx("input", { type: "checkbox", role: "switch", "aria-checked": !!form.noindex, checked: !!form.noindex, onChange: (e) => update({ noindex: e.target.checked }), className: "accent-primary h-4 w-4" })] }), _jsxs("label", { className: "flex items-center justify-between gap-3", children: [_jsxs("span", { className: "min-w-0", children: [_jsx("span", { className: "text-foreground block text-sm font-medium", children: "No-follow" }), _jsx("span", { className: "text-muted-foreground block text-sm", children: "Tell crawlers not to follow links on this page." })] }), _jsx("input", { type: "checkbox", role: "switch", "aria-checked": !!form.nofollow, checked: !!form.nofollow, onChange: (e) => update({ nofollow: e.target.checked }), className: "accent-primary h-4 w-4" })] })] }), (() => {
116
+ const meta = gradeMeta(record.seoGrade);
117
+ return (_jsxs("div", { className: `flex items-center gap-2 rounded-lg px-3 py-2 text-sm ${meta.bg} ${meta.text}`, children: [_jsx(Check, { className: "h-4 w-4", "aria-hidden": true }), "Current SEO score: ", _jsx("span", { className: "font-medium", children: record.seoScore }), " (", meta.label, ")"] }));
118
+ })()] })) : null }));
119
+ }
120
+ //# sourceMappingURL=SeoEditorDrawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeoEditorDrawer.js","sourceRoot":"","sources":["../../../src/components/seo/SeoEditorDrawer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare function SeoIssueFixDrawer({ open, onOpenChange, issueId, onChanged, onNavigate, }: {
2
+ open: boolean;
3
+ onOpenChange: (open: boolean) => void;
4
+ issueId: string | null;
5
+ onChanged?: () => void;
6
+ onNavigate?: (path: string) => void;
7
+ }): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=SeoIssueFixDrawer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeoIssueFixDrawer.d.ts","sourceRoot":"","sources":["../../../src/components/seo/SeoIssueFixDrawer.tsx"],"names":[],"mappings":"AAyDA,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,YAAY,EACZ,OAAO,EACP,SAAS,EACT,UAAU,GACX,EAAE;IACD,IAAI,EAAE,OAAO,CAAA;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IACrC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,IAAI,CAAA;IACtB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC,2CA8KA"}
@@ -0,0 +1,111 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useEffect, useState } from 'react';
4
+ import { Sparkles, ArrowRight, ExternalLink, Image as ImageIcon, Gauge } from 'lucide-react';
5
+ import { toast } from 'sonner';
6
+ import { fetchSeoIssue, resolveSeoIssue, ignoreSeoIssue, reopenSeoIssue, explainSeoIssue, } from '../../lib/seo-service.js';
7
+ import { Drawer } from './Drawer.js';
8
+ import { SeoLoading, SeoErrorState, severityMeta, btnPrimary, btnSecondary } from './primitives.js';
9
+ /** Map a fix action to a destination route within the admin. */
10
+ function fixRoute(issue) {
11
+ const ent = issue.entityType;
12
+ const id = issue.entityId;
13
+ switch (issue.fixActionType) {
14
+ case 'edit-metadata':
15
+ case 'edit-canonical':
16
+ case 'edit-og':
17
+ case 'edit-schema':
18
+ if (ent && id) {
19
+ return {
20
+ label: 'Edit content SEO',
21
+ path: `/seo?tab=content&entityType=${ent}&entityId=${encodeURIComponent(id)}`,
22
+ icon: _jsx(ArrowRight, { className: "h-4 w-4", "aria-hidden": true }),
23
+ };
24
+ }
25
+ return null;
26
+ case 'fix-broken-link':
27
+ case 'create-redirect':
28
+ return {
29
+ label: 'Open redirects',
30
+ path: '/seo?tab=redirects',
31
+ icon: _jsx(ArrowRight, { className: "h-4 w-4", "aria-hidden": true }),
32
+ };
33
+ case 'optimize-media':
34
+ return {
35
+ label: 'Open Media Center',
36
+ path: '/media',
37
+ icon: _jsx(ImageIcon, { className: "h-4 w-4", "aria-hidden": true }),
38
+ };
39
+ case 'improve-speed':
40
+ return {
41
+ label: 'Technical settings',
42
+ path: '/seo?tab=technical',
43
+ icon: _jsx(Gauge, { className: "h-4 w-4", "aria-hidden": true }),
44
+ };
45
+ default:
46
+ return null;
47
+ }
48
+ }
49
+ export function SeoIssueFixDrawer({ open, onOpenChange, issueId, onChanged, onNavigate, }) {
50
+ const [issue, setIssue] = useState(null);
51
+ const [loading, setLoading] = useState(false);
52
+ const [error, setError] = useState(null);
53
+ const [busy, setBusy] = useState(false);
54
+ const [explanation, setExplanation] = useState(null);
55
+ const [explaining, setExplaining] = useState(false);
56
+ useEffect(() => {
57
+ if (!open || !issueId)
58
+ return;
59
+ let alive = true;
60
+ setLoading(true);
61
+ setError(null);
62
+ setExplanation(null);
63
+ fetchSeoIssue(issueId)
64
+ .then((i) => {
65
+ if (!alive)
66
+ return;
67
+ if (!i)
68
+ setError('Issue not found.');
69
+ else
70
+ setIssue(i);
71
+ })
72
+ .catch((e) => alive && setError(e instanceof Error ? e.message : 'Failed to load'))
73
+ .finally(() => alive && setLoading(false));
74
+ return () => {
75
+ alive = false;
76
+ };
77
+ }, [open, issueId]);
78
+ async function mutate(fn, successMsg) {
79
+ if (!issue)
80
+ return;
81
+ setBusy(true);
82
+ const res = await fn(issue.id);
83
+ setBusy(false);
84
+ if (res.error)
85
+ return toast.error(res.error);
86
+ toast.success(successMsg);
87
+ onOpenChange(false);
88
+ onChanged?.();
89
+ }
90
+ async function handleExplain() {
91
+ if (!issue)
92
+ return;
93
+ setExplaining(true);
94
+ const res = await explainSeoIssue(issue.id);
95
+ setExplaining(false);
96
+ if (res.unavailable) {
97
+ toast.error('AI is not configured.');
98
+ return;
99
+ }
100
+ setExplanation(res.text ?? 'No explanation available.');
101
+ }
102
+ const route = issue ? fixRoute(issue) : null;
103
+ return (_jsx(Drawer, { open: open, onOpenChange: onOpenChange, title: "Issue detail", width: "max-w-lg", footer: issue ? (_jsxs(_Fragment, { children: [issue.status === 'ignored' ? (_jsx("button", { className: btnSecondary, onClick: () => mutate(reopenSeoIssue, 'Issue reopened.'), disabled: busy, children: "Reopen" })) : (_jsx("button", { className: btnSecondary, onClick: () => mutate(ignoreSeoIssue, 'Issue ignored.'), disabled: busy, children: "Ignore" })), route && onNavigate ? (_jsxs("button", { className: btnPrimary, onClick: () => {
104
+ onNavigate(route.path);
105
+ onOpenChange(false);
106
+ }, children: [route.icon, route.label] })) : (_jsx("button", { className: btnPrimary, onClick: () => mutate(resolveSeoIssue, 'Issue resolved.'), disabled: busy, children: "Mark resolved" }))] })) : null, children: loading ? (_jsx(SeoLoading, {})) : error ? (_jsx(SeoErrorState, { message: error })) : issue ? (_jsxs("div", { className: "space-y-4", children: [(() => {
107
+ const meta = severityMeta(issue.severity);
108
+ return (_jsxs("span", { className: `inline-flex items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium ${meta.bg} ${meta.text}`, children: [_jsx("span", { className: `h-1.5 w-1.5 rounded-full ${meta.dot}`, "aria-hidden": true }), meta.label, " \u00B7 ", issue.category] }));
109
+ })(), _jsxs("div", { children: [_jsx("h3", { className: "text-foreground text-base font-medium", children: issue.title }), issue.entityTitle && (_jsx("p", { className: "text-muted-foreground mt-0.5 text-sm", children: issue.entityTitle }))] }), issue.url && (_jsxs("a", { href: issue.url, target: "_blank", rel: "noopener noreferrer", className: "text-primary inline-flex items-center gap-1 text-sm hover:underline", children: [issue.url, _jsx(ExternalLink, { className: "h-3.5 w-3.5", "aria-hidden": true })] })), issue.description && _jsx("p", { className: "text-foreground text-sm", children: issue.description }), issue.impact && (_jsxs("div", { className: "border-border rounded-md border p-3", children: [_jsx("p", { className: "text-muted-foreground text-xs font-medium tracking-wide uppercase", children: "Impact" }), _jsx("p", { className: "text-foreground mt-1 text-sm", children: issue.impact })] })), issue.recommendation && (_jsxs("div", { className: "border-border rounded-md border p-3", children: [_jsx("p", { className: "text-muted-foreground text-xs font-medium tracking-wide uppercase", children: "Recommendation" }), _jsx("p", { className: "text-foreground mt-1 text-sm", children: issue.recommendation })] })), _jsxs("div", { className: "border-border rounded-md border p-3", children: [_jsxs("button", { onClick: handleExplain, disabled: explaining, className: "text-primary focus-visible:ring-ring inline-flex items-center gap-1.5 text-sm font-medium focus-visible:ring-2 focus-visible:outline-none disabled:opacity-60", children: [_jsx(Sparkles, { className: `h-4 w-4 ${explaining ? 'animate-pulse' : ''}`, "aria-hidden": true }), explaining ? 'Asking AI…' : 'Explain with AI'] }), explanation && _jsx("p", { className: "text-foreground mt-2 text-sm", children: explanation })] })] })) : null }));
110
+ }
111
+ //# sourceMappingURL=SeoIssueFixDrawer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SeoIssueFixDrawer.js","sourceRoot":"","sources":["../../../src/components/seo/SeoIssueFixDrawer.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Shared SEO UI primitives — token-only, accessible building blocks used across
3
+ * the five SEO tabs. No raw palette colours: status uses the theme's
4
+ * success / warning / destructive / muted tokens.
5
+ */
6
+ import type { ReactNode } from 'react';
7
+ import type { SeoGrade, SeoSeverity } from '../../lib/seo-service.js';
8
+ export interface GradeMeta {
9
+ label: string;
10
+ text: string;
11
+ bg: string;
12
+ dot: string;
13
+ }
14
+ export declare function gradeMeta(grade: SeoGrade): GradeMeta;
15
+ /** Grade band from a numeric 0-100 score. */
16
+ export declare function gradeFromScore(score: number): SeoGrade;
17
+ export declare function severityMeta(severity: SeoSeverity): GradeMeta;
18
+ export declare function SeoStatusBadge({ label, tone, }: {
19
+ label: string;
20
+ tone: 'good' | 'fair' | 'poor' | 'critical' | 'neutral';
21
+ }): import("react/jsx-runtime").JSX.Element;
22
+ /** A horizontal score bar (0-100), coloured by grade. */
23
+ export declare function SeoScoreBar({ score, className }: {
24
+ score: number;
25
+ className?: string;
26
+ }): import("react/jsx-runtime").JSX.Element;
27
+ export declare function ScorePill({ score }: {
28
+ score: number;
29
+ }): import("react/jsx-runtime").JSX.Element;
30
+ export declare function SectionCard({ title, description, action, children, className, }: {
31
+ title?: string;
32
+ description?: string;
33
+ action?: ReactNode;
34
+ children: ReactNode;
35
+ className?: string;
36
+ }): import("react/jsx-runtime").JSX.Element;
37
+ export declare function SeoLoading({ label }: {
38
+ label?: string;
39
+ }): import("react/jsx-runtime").JSX.Element;
40
+ export declare function SeoEmptyState({ icon, title, description, action, }: {
41
+ icon?: ReactNode;
42
+ title: string;
43
+ description?: string;
44
+ action?: ReactNode;
45
+ }): import("react/jsx-runtime").JSX.Element;
46
+ export declare function SeoErrorState({ message, onRetry }: {
47
+ message: string;
48
+ onRetry?: () => void;
49
+ }): import("react/jsx-runtime").JSX.Element;
50
+ export declare const btnPrimary = "inline-flex items-center justify-center gap-2 rounded-md bg-primary px-4 py-2 text-base font-medium text-primary-foreground transition-colors hover:bg-primary/90 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-60";
51
+ export declare const btnSecondary = "inline-flex items-center justify-center gap-2 rounded-md border border-border bg-card px-4 py-2 text-base font-medium text-foreground transition-colors hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-60";
52
+ export declare const btnGhostIcon = "inline-flex items-center justify-center rounded-md p-2 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring";
53
+ //# sourceMappingURL=primitives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../../src/components/seo/primitives.tsx"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AAIrE,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,QAAQ,GAAG,SAAS,CAqBpD;AAED,6CAA6C;AAC7C,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ,CAKtD;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,WAAW,GAAG,SAAS,CAmB7D;AAID,wBAAgB,cAAc,CAAC,EAC7B,KAAK,EACL,IAAI,GACL,EAAE;IACD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;CACxD,2CA4BA;AAED,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,SAAc,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,2CAoB3F;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,2CAUrD;AAID,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,MAAM,EACN,QAAQ,EACR,SAAc,GACf,EAAE;IACD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,QAAQ,EAAE,SAAS,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,2CAeA;AAED,wBAAgB,UAAU,CAAC,EAAE,KAAkB,EAAE,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,2CAOpE;AAED,wBAAgB,aAAa,CAAC,EAC5B,IAAI,EACJ,KAAK,EACL,WAAW,EACX,MAAM,GACP,EAAE;IACD,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,SAAS,CAAA;CACnB,2CAaA;AAED,wBAAgB,aAAa,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,2CAkB5F;AAID,eAAO,MAAM,UAAU,kQAC0O,CAAA;AAEjQ,eAAO,MAAM,YAAY,wQAC8O,CAAA;AAEvQ,eAAO,MAAM,YAAY,iNACuL,CAAA"}