@actuate-media/cms-admin 0.73.0 → 0.75.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.
- package/CHANGELOG.md +28 -0
- package/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +3 -2
- package/dist/AdminRoot.js.map +1 -1
- package/dist/LoginRoot.d.ts.map +1 -1
- package/dist/LoginRoot.js +2 -1
- package/dist/LoginRoot.js.map +1 -1
- package/dist/__tests__/components/theme-provider-accent.test.d.ts +2 -0
- package/dist/__tests__/components/theme-provider-accent.test.d.ts.map +1 -0
- package/dist/__tests__/components/theme-provider-accent.test.js +64 -0
- package/dist/__tests__/components/theme-provider-accent.test.js.map +1 -0
- package/dist/__tests__/views/portal-container.test.js +13 -0
- package/dist/__tests__/views/portal-container.test.js.map +1 -1
- package/dist/__tests__/views/post-fields-modal.render.test.js +3 -6
- package/dist/__tests__/views/post-fields-modal.render.test.js.map +1 -1
- package/dist/__tests__/views/redirects-pane.render.test.js +6 -0
- package/dist/__tests__/views/redirects-pane.render.test.js.map +1 -1
- package/dist/__tests__/views/seo-content-pane.render.test.js +15 -4
- package/dist/__tests__/views/seo-content-pane.render.test.js.map +1 -1
- package/dist/actuate-admin.css +1 -1
- package/dist/components/CoauthorResultPopover.js +1 -1
- package/dist/components/EditorSeoAside.d.ts +23 -0
- package/dist/components/EditorSeoAside.d.ts.map +1 -0
- package/dist/components/EditorSeoAside.js +21 -0
- package/dist/components/EditorSeoAside.js.map +1 -0
- package/dist/components/MediaPickerModal.js +1 -1
- package/dist/components/SEOConfigPanel.js +1 -1
- package/dist/components/SchedulePublishDialog.js +1 -1
- package/dist/components/SharePreviewLinkDialog.js +1 -1
- package/dist/components/ThemeProvider.d.ts.map +1 -1
- package/dist/components/ThemeProvider.js +2 -1
- package/dist/components/ThemeProvider.js.map +1 -1
- package/dist/components/VersionHistory.js +1 -1
- package/dist/components/seo/EditorSeoScoreBadge.d.ts +7 -0
- package/dist/components/seo/EditorSeoScoreBadge.d.ts.map +1 -0
- package/dist/components/seo/EditorSeoScoreBadge.js +9 -0
- package/dist/components/seo/EditorSeoScoreBadge.js.map +1 -0
- package/dist/components/seo/SeoAccordion.d.ts +16 -0
- package/dist/components/seo/SeoAccordion.d.ts.map +1 -0
- package/dist/components/seo/SeoAccordion.js +21 -0
- package/dist/components/seo/SeoAccordion.js.map +1 -0
- package/dist/components/seo/SeoAnalysisList.d.ts +7 -0
- package/dist/components/seo/SeoAnalysisList.d.ts.map +1 -0
- package/dist/components/seo/SeoAnalysisList.js +32 -0
- package/dist/components/seo/SeoAnalysisList.js.map +1 -0
- package/dist/components/seo/SeoEditorPane.d.ts +15 -4
- package/dist/components/seo/SeoEditorPane.d.ts.map +1 -1
- package/dist/components/seo/SeoEditorPane.js +155 -35
- package/dist/components/seo/SeoEditorPane.js.map +1 -1
- package/dist/components/seo/SeoInsightsMetrics.d.ts +6 -0
- package/dist/components/seo/SeoInsightsMetrics.d.ts.map +1 -0
- package/dist/components/seo/SeoInsightsMetrics.js +16 -0
- package/dist/components/seo/SeoInsightsMetrics.js.map +1 -0
- package/dist/components/seo/SeoIssueFixPanel.d.ts.map +1 -1
- package/dist/components/seo/SeoIssueFixPanel.js +13 -3
- package/dist/components/seo/SeoIssueFixPanel.js.map +1 -1
- package/dist/components/seo/SeoLinkingSection.d.ts +9 -0
- package/dist/components/seo/SeoLinkingSection.d.ts.map +1 -0
- package/dist/components/seo/SeoLinkingSection.js +44 -0
- package/dist/components/seo/SeoLinkingSection.js.map +1 -0
- package/dist/components/seo/primitives.d.ts.map +1 -1
- package/dist/components/seo/primitives.js +3 -3
- package/dist/components/seo/primitives.js.map +1 -1
- package/dist/components/ui/Card.js +5 -5
- package/dist/components/ui/Card.js.map +1 -1
- package/dist/components/ui/InspectorPane.js +3 -3
- package/dist/components/ui/InspectorPane.js.map +1 -1
- package/dist/components/ui/PanelSection.d.ts +16 -0
- package/dist/components/ui/PanelSection.d.ts.map +1 -0
- package/dist/components/ui/PanelSection.js +15 -0
- package/dist/components/ui/PanelSection.js.map +1 -0
- package/dist/lib/admin-root-element.d.ts +9 -0
- package/dist/lib/admin-root-element.d.ts.map +1 -0
- package/dist/lib/admin-root-element.js +14 -0
- package/dist/lib/admin-root-element.js.map +1 -0
- package/dist/lib/editor-seo-content.d.ts +16 -0
- package/dist/lib/editor-seo-content.d.ts.map +1 -0
- package/dist/lib/editor-seo-content.js +139 -0
- package/dist/lib/editor-seo-content.js.map +1 -0
- package/dist/lib/portal-container.d.ts.map +1 -1
- package/dist/lib/portal-container.js +2 -3
- package/dist/lib/portal-container.js.map +1 -1
- package/dist/lib/seo-service.d.ts +91 -0
- package/dist/lib/seo-service.d.ts.map +1 -1
- package/dist/lib/seo-service.js +55 -2
- package/dist/lib/seo-service.js.map +1 -1
- package/dist/views/ApiKeys.js +2 -2
- package/dist/views/Dashboard.d.ts.map +1 -1
- package/dist/views/Dashboard.js +12 -14
- package/dist/views/Dashboard.js.map +1 -1
- package/dist/views/MediaBrowser.d.ts.map +1 -1
- package/dist/views/MediaBrowser.js +35 -6
- package/dist/views/MediaBrowser.js.map +1 -1
- package/dist/views/PageEditor.js +1 -1
- package/dist/views/Posts/PostTypeEditor.js +3 -3
- package/dist/views/SEO.d.ts.map +1 -1
- package/dist/views/SEO.js +4 -2
- package/dist/views/SEO.js.map +1 -1
- package/dist/views/ScriptTags.js +1 -1
- package/dist/views/ScriptTags.js.map +1 -1
- package/dist/views/Users.js +1 -1
- package/dist/views/page-editor/EditorTopBar.d.ts +6 -1
- package/dist/views/page-editor/EditorTopBar.d.ts.map +1 -1
- package/dist/views/page-editor/EditorTopBar.js +5 -2
- package/dist/views/page-editor/EditorTopBar.js.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.d.ts.map +1 -1
- package/dist/views/page-editor/PageSectionEditor.js +36 -1
- package/dist/views/page-editor/PageSectionEditor.js.map +1 -1
- package/dist/views/page-editor/PageSettingsModal.d.ts +1 -1
- package/dist/views/page-editor/PageSettingsModal.d.ts.map +1 -1
- package/dist/views/page-editor/PageSettingsModal.js +2 -13
- package/dist/views/page-editor/PageSettingsModal.js.map +1 -1
- package/dist/views/page-editor/SectionInspector.js +2 -2
- package/dist/views/page-editor/SectionsPanel.js +1 -1
- package/dist/views/post-editor/PostFieldsModal.d.ts +1 -1
- package/dist/views/post-editor/PostFieldsModal.d.ts.map +1 -1
- package/dist/views/post-editor/PostFieldsModal.js +17 -79
- package/dist/views/post-editor/PostFieldsModal.js.map +1 -1
- package/dist/views/post-editor/PostHeaderPanel.js +1 -1
- package/dist/views/post-editor/PostSectionEditor.d.ts.map +1 -1
- package/dist/views/post-editor/PostSectionEditor.js +37 -1
- package/dist/views/post-editor/PostSectionEditor.js.map +1 -1
- package/dist/views/seo/ContentTab.d.ts.map +1 -1
- package/dist/views/seo/ContentTab.js +7 -1
- package/dist/views/seo/ContentTab.js.map +1 -1
- package/dist/views/seo/LinksTab.d.ts +4 -0
- package/dist/views/seo/LinksTab.d.ts.map +1 -0
- package/dist/views/seo/LinksTab.js +111 -0
- package/dist/views/seo/LinksTab.js.map +1 -0
- package/dist/views/seo/OverviewTab.js +1 -1
- package/dist/views/seo/OverviewTab.js.map +1 -1
- package/dist/views/seo/RedirectsTab.d.ts.map +1 -1
- package/dist/views/seo/RedirectsTab.js +39 -6
- package/dist/views/seo/RedirectsTab.js.map +1 -1
- package/dist/views/seo/TechnicalTab.js +2 -2
- package/dist/views/settings/AISettingsTab.js +1 -1
- package/dist/views/settings/AiFeaturesCard.js +1 -1
- package/dist/views/settings/AiFeaturesCard.js.map +1 -1
- package/dist/views/settings/AppearanceTab.js +1 -1
- package/dist/views/settings/BrandVoiceCard.js +1 -1
- package/dist/views/settings/EmailSettingsTab.js +2 -2
- package/dist/views/settings/GeneralSettingsTab.js +1 -1
- package/dist/views/settings/SecurityStatusCard.js +1 -1
- package/dist/views/settings/SeoSettingsTab.js +4 -4
- package/dist/views/settings/UpdatesTab.js +2 -2
- package/dist/views/settings/components.js +3 -3
- package/dist/views/settings/components.js.map +1 -1
- package/package.json +2 -2
- package/src/AdminRoot.tsx +3 -2
- package/src/LoginRoot.tsx +2 -1
- package/src/__tests__/components/theme-provider-accent.test.tsx +84 -0
- package/src/__tests__/views/portal-container.test.tsx +14 -0
- package/src/__tests__/views/post-fields-modal.render.test.tsx +3 -9
- package/src/__tests__/views/redirects-pane.render.test.tsx +6 -0
- package/src/__tests__/views/seo-content-pane.render.test.tsx +16 -4
- package/src/components/CoauthorResultPopover.tsx +1 -1
- package/src/components/EditorSeoAside.tsx +68 -0
- package/src/components/MediaPickerModal.tsx +1 -1
- package/src/components/SEOConfigPanel.tsx +2 -2
- package/src/components/SchedulePublishDialog.tsx +1 -1
- package/src/components/SharePreviewLinkDialog.tsx +1 -1
- package/src/components/ThemeProvider.tsx +3 -1
- package/src/components/VersionHistory.tsx +1 -1
- package/src/components/seo/EditorSeoScoreBadge.tsx +26 -0
- package/src/components/seo/SeoAccordion.tsx +76 -0
- package/src/components/seo/SeoAnalysisList.tsx +113 -0
- package/src/components/seo/SeoEditorPane.tsx +532 -250
- package/src/components/seo/SeoInsightsMetrics.tsx +109 -0
- package/src/components/seo/SeoIssueFixPanel.tsx +16 -4
- package/src/components/seo/SeoLinkingSection.tsx +151 -0
- package/src/components/seo/primitives.tsx +7 -3
- package/src/components/ui/Card.tsx +5 -5
- package/src/components/ui/InspectorPane.tsx +3 -3
- package/src/components/ui/PanelSection.tsx +53 -0
- package/src/lib/admin-root-element.ts +15 -0
- package/src/lib/editor-seo-content.ts +144 -0
- package/src/lib/portal-container.ts +3 -2
- package/src/lib/seo-service.ts +150 -2
- package/src/views/ApiKeys.tsx +2 -2
- package/src/views/Dashboard.tsx +40 -53
- package/src/views/MediaBrowser.tsx +62 -12
- package/src/views/PageEditor.tsx +1 -1
- package/src/views/Posts/PostTypeEditor.tsx +3 -3
- package/src/views/SEO.tsx +6 -0
- package/src/views/ScriptTags.tsx +2 -2
- package/src/views/Users.tsx +1 -1
- package/src/views/page-editor/EditorTopBar.tsx +27 -0
- package/src/views/page-editor/PageSectionEditor.tsx +58 -3
- package/src/views/page-editor/PageSettingsModal.tsx +1 -45
- package/src/views/page-editor/SectionInspector.tsx +2 -2
- package/src/views/page-editor/SectionsPanel.tsx +1 -1
- package/src/views/post-editor/PostFieldsModal.tsx +19 -138
- package/src/views/post-editor/PostHeaderPanel.tsx +1 -1
- package/src/views/post-editor/PostSectionEditor.tsx +60 -3
- package/src/views/seo/ContentTab.tsx +11 -5
- package/src/views/seo/LinksTab.tsx +462 -0
- package/src/views/seo/OverviewTab.tsx +1 -1
- package/src/views/seo/RedirectsTab.tsx +97 -4
- package/src/views/seo/TechnicalTab.tsx +2 -2
- package/src/views/settings/AISettingsTab.tsx +3 -3
- package/src/views/settings/AiFeaturesCard.tsx +1 -1
- package/src/views/settings/AppearanceTab.tsx +1 -1
- package/src/views/settings/BrandVoiceCard.tsx +2 -2
- package/src/views/settings/EmailSettingsTab.tsx +2 -2
- package/src/views/settings/GeneralSettingsTab.tsx +3 -3
- package/src/views/settings/SecurityStatusCard.tsx +1 -1
- package/src/views/settings/SeoSettingsTab.tsx +6 -6
- package/src/views/settings/UpdatesTab.tsx +3 -3
- package/src/views/settings/components.tsx +3 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { useRef, useState } from 'react'
|
|
3
|
+
import { useEffect, useRef, useState } from 'react'
|
|
4
4
|
import {
|
|
5
5
|
Plus,
|
|
6
6
|
Trash2,
|
|
@@ -22,11 +22,14 @@ import {
|
|
|
22
22
|
deleteRedirectRule,
|
|
23
23
|
flattenRedirectChain,
|
|
24
24
|
generate404RecoverySuggestions,
|
|
25
|
+
fetchRedirectRecoverySettings,
|
|
26
|
+
saveRedirectRecoverySettings,
|
|
25
27
|
acceptRedirectSuggestion,
|
|
26
28
|
dismissRedirectSuggestion,
|
|
27
29
|
exportRedirectsCsv,
|
|
28
30
|
importRedirectsCsv,
|
|
29
31
|
type RedirectRule,
|
|
32
|
+
type RedirectRecoverySettings,
|
|
30
33
|
} from '../../lib/seo-service.js'
|
|
31
34
|
import {
|
|
32
35
|
SectionCard,
|
|
@@ -66,6 +69,91 @@ function OverviewCards({ onRefetchKey }: { onRefetchKey: number }) {
|
|
|
66
69
|
)
|
|
67
70
|
}
|
|
68
71
|
|
|
72
|
+
function RecoverySettingsCard() {
|
|
73
|
+
const { data, loading, error, refetch } = useSeoResource(fetchRedirectRecoverySettings, [])
|
|
74
|
+
const [saving, setSaving] = useState(false)
|
|
75
|
+
const [local, setLocal] = useState<RedirectRecoverySettings | null>(null)
|
|
76
|
+
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (data) setLocal(data)
|
|
79
|
+
}, [data])
|
|
80
|
+
|
|
81
|
+
async function handleSave() {
|
|
82
|
+
if (!local) return
|
|
83
|
+
setSaving(true)
|
|
84
|
+
const res = await saveRedirectRecoverySettings(local)
|
|
85
|
+
setSaving(false)
|
|
86
|
+
if (res.error) return toast.error(res.error)
|
|
87
|
+
toast.success('Recovery settings saved.')
|
|
88
|
+
refetch()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (loading) return null
|
|
92
|
+
if (error) return null
|
|
93
|
+
if (!local) return null
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
<SectionCard
|
|
97
|
+
title="404 recovery settings"
|
|
98
|
+
description="Control AI re-ranking and optional auto-redirect for high-confidence matches"
|
|
99
|
+
>
|
|
100
|
+
<div className="space-y-4">
|
|
101
|
+
<label className="flex items-start gap-3">
|
|
102
|
+
<input
|
|
103
|
+
type="checkbox"
|
|
104
|
+
className="border-border mt-1 h-4 w-4 rounded"
|
|
105
|
+
checked={local.aiRerank}
|
|
106
|
+
onChange={(e) => setLocal({ ...local, aiRerank: e.target.checked })}
|
|
107
|
+
/>
|
|
108
|
+
<span>
|
|
109
|
+
<span className="text-foreground text-sm font-medium">AI re-ranking</span>
|
|
110
|
+
<span className="text-muted-foreground block text-sm">
|
|
111
|
+
Use semantic search to resolve ambiguous matches (40–84% heuristic confidence).
|
|
112
|
+
</span>
|
|
113
|
+
</span>
|
|
114
|
+
</label>
|
|
115
|
+
<label className="flex items-start gap-3">
|
|
116
|
+
<input
|
|
117
|
+
type="checkbox"
|
|
118
|
+
className="border-border mt-1 h-4 w-4 rounded"
|
|
119
|
+
checked={local.autoApply}
|
|
120
|
+
onChange={(e) => setLocal({ ...local, autoApply: e.target.checked })}
|
|
121
|
+
/>
|
|
122
|
+
<span>
|
|
123
|
+
<span className="text-foreground text-sm font-medium">
|
|
124
|
+
Auto-apply high-confidence redirects
|
|
125
|
+
</span>
|
|
126
|
+
<span className="text-muted-foreground block text-sm">
|
|
127
|
+
Create 301 redirects automatically when confidence meets the threshold (off by
|
|
128
|
+
default).
|
|
129
|
+
</span>
|
|
130
|
+
</span>
|
|
131
|
+
</label>
|
|
132
|
+
<label className="block max-w-xs">
|
|
133
|
+
<span className="text-foreground text-sm font-medium">Auto-apply minimum confidence</span>
|
|
134
|
+
<input
|
|
135
|
+
type="number"
|
|
136
|
+
min={50}
|
|
137
|
+
max={100}
|
|
138
|
+
value={local.autoApplyMinConfidence}
|
|
139
|
+
disabled={!local.autoApply}
|
|
140
|
+
onChange={(e) =>
|
|
141
|
+
setLocal({
|
|
142
|
+
...local,
|
|
143
|
+
autoApplyMinConfidence: Math.max(50, Math.min(100, Number(e.target.value) || 85)),
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
className="border-border bg-input-background text-foreground focus-visible:ring-ring mt-1 w-full rounded-md border px-3 py-2 text-sm focus-visible:ring-2 focus-visible:outline-none disabled:opacity-50"
|
|
147
|
+
/>
|
|
148
|
+
</label>
|
|
149
|
+
<button className={btnSecondary} onClick={handleSave} disabled={saving}>
|
|
150
|
+
{saving ? 'Saving…' : 'Save settings'}
|
|
151
|
+
</button>
|
|
152
|
+
</div>
|
|
153
|
+
</SectionCard>
|
|
154
|
+
)
|
|
155
|
+
}
|
|
156
|
+
|
|
69
157
|
function Ai404RecoveryCard({ onApplied }: { onApplied: () => void }) {
|
|
70
158
|
const { data, loading, error, refetch } = useSeoResource(fetchRedirectSuggestions, [])
|
|
71
159
|
const [generating, setGenerating] = useState(false)
|
|
@@ -78,7 +166,11 @@ function Ai404RecoveryCard({ onApplied }: { onApplied: () => void }) {
|
|
|
78
166
|
toast.error(res.error)
|
|
79
167
|
return
|
|
80
168
|
}
|
|
81
|
-
|
|
169
|
+
const autoMsg =
|
|
170
|
+
res.autoApplied && res.autoApplied > 0
|
|
171
|
+
? ` ${res.autoApplied} high-confidence redirect${res.autoApplied === 1 ? '' : 's'} applied automatically.`
|
|
172
|
+
: ''
|
|
173
|
+
toast.success(`Generated 404 recovery suggestions.${autoMsg}`)
|
|
82
174
|
refetch()
|
|
83
175
|
}
|
|
84
176
|
|
|
@@ -120,7 +212,7 @@ function Ai404RecoveryCard({ onApplied }: { onApplied: () => void }) {
|
|
|
120
212
|
) : (
|
|
121
213
|
<ul className="divide-border divide-y">
|
|
122
214
|
{data!.map((s) => (
|
|
123
|
-
<li key={s.id} className="flex items-center justify-between gap-3 py-3
|
|
215
|
+
<li key={s.id} className="flex items-center justify-between gap-3 py-3">
|
|
124
216
|
<div className="min-w-0">
|
|
125
217
|
<p className="text-foreground flex items-center gap-2 text-sm">
|
|
126
218
|
<span className="truncate font-medium">{s.fromPath}</span>
|
|
@@ -181,7 +273,7 @@ function ChainMapCard({ onFlattened }: { onFlattened: () => void }) {
|
|
|
181
273
|
{data.map((chain) => (
|
|
182
274
|
<li
|
|
183
275
|
key={chain.id}
|
|
184
|
-
className="border-border flex items-center justify-between gap-3 rounded-md border p-
|
|
276
|
+
className="border-border flex items-center justify-between gap-3 rounded-md border p-4"
|
|
185
277
|
>
|
|
186
278
|
<div className="min-w-0">
|
|
187
279
|
<div className="mb-1 flex items-center gap-2">
|
|
@@ -272,6 +364,7 @@ export function RedirectsTab() {
|
|
|
272
364
|
<OverviewCards onRefetchKey={refetchKey} />
|
|
273
365
|
|
|
274
366
|
<div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
|
|
367
|
+
<RecoverySettingsCard />
|
|
275
368
|
<Ai404RecoveryCard onApplied={refetchAll} />
|
|
276
369
|
<ChainMapCard onFlattened={refetchAll} />
|
|
277
370
|
</div>
|
|
@@ -73,7 +73,7 @@ function Toggle({
|
|
|
73
73
|
const labelId = useId()
|
|
74
74
|
const helpId = useId()
|
|
75
75
|
return (
|
|
76
|
-
<div className="flex items-center justify-between gap-3 py-
|
|
76
|
+
<div className="flex items-center justify-between gap-3 py-3.5">
|
|
77
77
|
<span className="min-w-0">
|
|
78
78
|
<span id={labelId} className="text-foreground block text-sm font-medium">
|
|
79
79
|
{label}
|
|
@@ -259,7 +259,7 @@ function RobotsCard() {
|
|
|
259
259
|
<div className="space-y-3">
|
|
260
260
|
{validation.blocksEntireSite && (
|
|
261
261
|
<div
|
|
262
|
-
className="border-destructive/30 bg-destructive/10 flex items-start gap-2 rounded-md border p-
|
|
262
|
+
className="border-destructive/30 bg-destructive/10 flex items-start gap-2 rounded-md border p-4"
|
|
263
263
|
role="alert"
|
|
264
264
|
>
|
|
265
265
|
<AlertTriangle className="text-destructive mt-0.5 h-4 w-4 shrink-0" aria-hidden />
|
|
@@ -92,7 +92,7 @@ export function AISettingsTab({ role, config }: AISettingsTabProps) {
|
|
|
92
92
|
{ai.loadError && (
|
|
93
93
|
<div
|
|
94
94
|
role="alert"
|
|
95
|
-
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-
|
|
95
|
+
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-4 text-sm"
|
|
96
96
|
>
|
|
97
97
|
<AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
|
|
98
98
|
<span className="flex-1">{ai.loadError}</span>
|
|
@@ -107,7 +107,7 @@ export function AISettingsTab({ role, config }: AISettingsTabProps) {
|
|
|
107
107
|
)}
|
|
108
108
|
|
|
109
109
|
{!canEdit && (
|
|
110
|
-
<div className="border-border bg-muted text-muted-foreground flex items-center gap-2 rounded-lg border p-
|
|
110
|
+
<div className="border-border bg-muted text-muted-foreground flex items-center gap-2 rounded-lg border p-4 text-sm">
|
|
111
111
|
<Info size={16} className="shrink-0" aria-hidden="true" />
|
|
112
112
|
You have read-only access to AI settings. Only administrators can make changes.
|
|
113
113
|
</div>
|
|
@@ -145,7 +145,7 @@ export function AISettingsTab({ role, config }: AISettingsTabProps) {
|
|
|
145
145
|
{ai.saveState === 'error' && ai.saveError && (
|
|
146
146
|
<div
|
|
147
147
|
role="alert"
|
|
148
|
-
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-
|
|
148
|
+
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-4 text-sm"
|
|
149
149
|
>
|
|
150
150
|
<AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
|
|
151
151
|
<span className="flex-1">{ai.saveError}</span>
|
|
@@ -56,7 +56,7 @@ export function AppearanceTab({ role, config }: AppearanceTabProps) {
|
|
|
56
56
|
return (
|
|
57
57
|
<div className="space-y-4">
|
|
58
58
|
{!canEdit && (
|
|
59
|
-
<p className="text-muted-foreground border-border bg-muted rounded-lg border p-
|
|
59
|
+
<p className="text-muted-foreground border-border bg-muted rounded-lg border p-4 text-sm">
|
|
60
60
|
You have read-only access to appearance settings.
|
|
61
61
|
</p>
|
|
62
62
|
)}
|
|
@@ -341,7 +341,7 @@ export function BrandVoiceCard({
|
|
|
341
341
|
{aiReadiness && !aiReadiness.ready && aiReadiness.message && (
|
|
342
342
|
<div
|
|
343
343
|
role="status"
|
|
344
|
-
className="border-warning/40 bg-warning/10 text-foreground flex items-start gap-3 rounded-lg border p-
|
|
344
|
+
className="border-warning/40 bg-warning/10 text-foreground flex items-start gap-3 rounded-lg border p-4 text-sm"
|
|
345
345
|
>
|
|
346
346
|
<AlertTriangle size={16} className="text-warning mt-0.5 shrink-0" aria-hidden="true" />
|
|
347
347
|
<p>{aiReadiness.message}</p>
|
|
@@ -400,7 +400,7 @@ export function BrandVoiceCard({
|
|
|
400
400
|
{importError && (
|
|
401
401
|
<div
|
|
402
402
|
role="alert"
|
|
403
|
-
className="border-destructive/30 bg-destructive/10 text-destructive rounded-md border p-
|
|
403
|
+
className="border-destructive/30 bg-destructive/10 text-destructive rounded-md border p-4 text-sm"
|
|
404
404
|
>
|
|
405
405
|
{importError}
|
|
406
406
|
</div>
|
|
@@ -115,7 +115,7 @@ function Notice({
|
|
|
115
115
|
<div
|
|
116
116
|
role="status"
|
|
117
117
|
aria-live="polite"
|
|
118
|
-
className={`flex items-start gap-2.5 rounded-lg border p-
|
|
118
|
+
className={`flex items-start gap-2.5 rounded-lg border p-4 text-sm ${toneClass}`}
|
|
119
119
|
>
|
|
120
120
|
<Icon size={16} className="mt-0.5 shrink-0" aria-hidden="true" />
|
|
121
121
|
<div className="min-w-0">{children}</div>
|
|
@@ -294,7 +294,7 @@ export function EmailSettingsTab({ role }: { role?: string }) {
|
|
|
294
294
|
return (
|
|
295
295
|
<div
|
|
296
296
|
role="alert"
|
|
297
|
-
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-
|
|
297
|
+
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-4 text-sm"
|
|
298
298
|
>
|
|
299
299
|
<AlertTriangle size={20} className="shrink-0" aria-hidden="true" />
|
|
300
300
|
<span className="flex-1">{s.loadError}</span>
|
|
@@ -42,7 +42,7 @@ export function GeneralSettingsTab({ onNavigate, role }: GeneralSettingsTabProps
|
|
|
42
42
|
{settings.loadError && (
|
|
43
43
|
<div
|
|
44
44
|
role="alert"
|
|
45
|
-
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-
|
|
45
|
+
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-4 text-sm"
|
|
46
46
|
>
|
|
47
47
|
<AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
|
|
48
48
|
<span className="flex-1">{settings.loadError}</span>
|
|
@@ -57,7 +57,7 @@ export function GeneralSettingsTab({ onNavigate, role }: GeneralSettingsTabProps
|
|
|
57
57
|
)}
|
|
58
58
|
|
|
59
59
|
{!canEdit && (
|
|
60
|
-
<div className="border-border bg-muted text-muted-foreground flex items-center gap-2 rounded-lg border p-
|
|
60
|
+
<div className="border-border bg-muted text-muted-foreground flex items-center gap-2 rounded-lg border p-4 text-sm">
|
|
61
61
|
<Info size={16} className="shrink-0" aria-hidden="true" />
|
|
62
62
|
You have read-only access to settings. Only administrators can make changes.
|
|
63
63
|
</div>
|
|
@@ -99,7 +99,7 @@ export function GeneralSettingsTab({ onNavigate, role }: GeneralSettingsTabProps
|
|
|
99
99
|
{settings.saveState === 'error' && settings.saveError && (
|
|
100
100
|
<div
|
|
101
101
|
role="alert"
|
|
102
|
-
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-
|
|
102
|
+
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-4 text-sm"
|
|
103
103
|
>
|
|
104
104
|
<AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
|
|
105
105
|
<span className="flex-1">{settings.saveError}</span>
|
|
@@ -83,7 +83,7 @@ export function SecurityStatusCard({
|
|
|
83
83
|
<div
|
|
84
84
|
key={w.id}
|
|
85
85
|
role="note"
|
|
86
|
-
className={`flex items-start justify-between gap-3 rounded-lg border p-
|
|
86
|
+
className={`flex items-start justify-between gap-3 rounded-lg border p-4 text-sm ${SEVERITY_STYLES[w.severity]}`}
|
|
87
87
|
>
|
|
88
88
|
<div>
|
|
89
89
|
<p className="font-medium">{w.title}</p>
|
|
@@ -102,7 +102,7 @@ export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
|
|
|
102
102
|
{seo.loadError && (
|
|
103
103
|
<div
|
|
104
104
|
role="alert"
|
|
105
|
-
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-
|
|
105
|
+
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-4 text-sm"
|
|
106
106
|
>
|
|
107
107
|
<AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
|
|
108
108
|
<span className="flex-1">{seo.loadError}</span>
|
|
@@ -117,7 +117,7 @@ export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
|
|
|
117
117
|
)}
|
|
118
118
|
|
|
119
119
|
{!canEdit && (
|
|
120
|
-
<div className="border-border bg-muted text-muted-foreground flex items-center gap-2 rounded-lg border p-
|
|
120
|
+
<div className="border-border bg-muted text-muted-foreground flex items-center gap-2 rounded-lg border p-4 text-sm">
|
|
121
121
|
<Info size={16} className="shrink-0" aria-hidden="true" />
|
|
122
122
|
You have read-only access to SEO defaults. Only administrators can make changes.
|
|
123
123
|
</div>
|
|
@@ -150,7 +150,7 @@ export function SeoSettingsTab({ onNavigate, role }: SeoSettingsTabProps) {
|
|
|
150
150
|
{seo.saveState === 'error' && seo.saveError && (
|
|
151
151
|
<div
|
|
152
152
|
role="alert"
|
|
153
|
-
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-
|
|
153
|
+
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-4 text-sm"
|
|
154
154
|
>
|
|
155
155
|
<AlertTriangle size={16} className="shrink-0" aria-hidden="true" />
|
|
156
156
|
<span className="flex-1">{seo.saveError}</span>
|
|
@@ -381,7 +381,7 @@ function SeoPreviewCard({
|
|
|
381
381
|
}) {
|
|
382
382
|
return (
|
|
383
383
|
<div className="border-border mt-4 grid gap-4 border-t pt-4 sm:grid-cols-2">
|
|
384
|
-
<div className="border-border rounded-lg border p-
|
|
384
|
+
<div className="border-border rounded-lg border p-4">
|
|
385
385
|
<p className="text-muted-foreground mb-2 text-xs font-medium tracking-wide uppercase">
|
|
386
386
|
Search preview
|
|
387
387
|
</p>
|
|
@@ -398,7 +398,7 @@ function SeoPreviewCard({
|
|
|
398
398
|
<ImageIcon size={24} className="text-muted-foreground" aria-hidden="true" />
|
|
399
399
|
)}
|
|
400
400
|
</div>
|
|
401
|
-
<div className="p-
|
|
401
|
+
<div className="p-4">
|
|
402
402
|
<p className="text-muted-foreground truncate text-xs uppercase">
|
|
403
403
|
{siteName || new URL(url).hostname}
|
|
404
404
|
</p>
|
|
@@ -700,7 +700,7 @@ function SitemapDefaultsCard({
|
|
|
700
700
|
description="Control XML sitemap generation and whether search engines are pinged on publish."
|
|
701
701
|
>
|
|
702
702
|
{!siteUrl && (
|
|
703
|
-
<div className="border-warning/30 bg-warning/10 text-warning mb-4 flex items-start gap-2 rounded-md border p-
|
|
703
|
+
<div className="border-warning/30 bg-warning/10 text-warning mb-4 flex items-start gap-2 rounded-md border p-4 text-sm">
|
|
704
704
|
<AlertTriangle size={16} className="mt-0.5 shrink-0" aria-hidden="true" />
|
|
705
705
|
Site URL is not set — sitemap URLs may be incorrect. Set it in Settings → General.
|
|
706
706
|
</div>
|
|
@@ -109,7 +109,7 @@ function Notice({
|
|
|
109
109
|
? 'border-destructive/30 bg-destructive/10 text-destructive'
|
|
110
110
|
: 'border-warning/30 bg-warning/10 text-warning'
|
|
111
111
|
return (
|
|
112
|
-
<div className={`mt-3 flex items-start gap-2.5 rounded-md border p-
|
|
112
|
+
<div className={`mt-3 flex items-start gap-2.5 rounded-md border p-4 ${toneClass}`}>
|
|
113
113
|
<span className="mt-0.5 shrink-0" aria-hidden="true">
|
|
114
114
|
{icon}
|
|
115
115
|
</span>
|
|
@@ -180,7 +180,7 @@ export function UpdatesTab({ role }: UpdatesTabProps) {
|
|
|
180
180
|
{error && (
|
|
181
181
|
<div
|
|
182
182
|
role="alert"
|
|
183
|
-
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-
|
|
183
|
+
className="border-destructive/30 bg-destructive/10 text-destructive flex items-center gap-3 rounded-lg border p-4 text-sm"
|
|
184
184
|
>
|
|
185
185
|
<AlertTriangle size={20} className="shrink-0" aria-hidden="true" />
|
|
186
186
|
<span className="flex-1">{error}</span>
|
|
@@ -309,7 +309,7 @@ export function UpdatesTab({ role }: UpdatesTabProps) {
|
|
|
309
309
|
</div>
|
|
310
310
|
|
|
311
311
|
{info.updateCommand && (
|
|
312
|
-
<div className="border-border bg-card mt-3 rounded-md border p-
|
|
312
|
+
<div className="border-border bg-card mt-3 rounded-md border p-4">
|
|
313
313
|
<p className="text-muted-foreground mb-1 text-xs">Or update manually:</p>
|
|
314
314
|
<code className="bg-muted text-foreground block rounded px-2 py-1.5 font-mono text-xs select-all">
|
|
315
315
|
{info.updateCommand}
|
|
@@ -49,7 +49,7 @@ export function SettingsCard({
|
|
|
49
49
|
</div>
|
|
50
50
|
{actions && <div className="flex shrink-0 items-center gap-2">{actions}</div>}
|
|
51
51
|
</CardHeader>
|
|
52
|
-
<CardContent className="
|
|
52
|
+
<CardContent className="text-[var(--txt)]">{children}</CardContent>
|
|
53
53
|
</Card>
|
|
54
54
|
)
|
|
55
55
|
}
|
|
@@ -74,7 +74,7 @@ export function SettingsSubsection({
|
|
|
74
74
|
<div className={`border-border border-t pt-4 ${className ?? ''}`}>
|
|
75
75
|
<div className="text-foreground text-base font-medium">{title}</div>
|
|
76
76
|
{description && <p className="text-muted-foreground mt-0.5 text-sm">{description}</p>}
|
|
77
|
-
{children}
|
|
77
|
+
{children ? <div className="mt-4">{children}</div> : null}
|
|
78
78
|
</div>
|
|
79
79
|
)
|
|
80
80
|
}
|
|
@@ -200,7 +200,7 @@ export function SettingsValidationSummary({ issues }: { issues: ValidationIssue[
|
|
|
200
200
|
<div
|
|
201
201
|
role="alert"
|
|
202
202
|
aria-live="polite"
|
|
203
|
-
className={`flex items-start gap-3 rounded-lg border p-
|
|
203
|
+
className={`flex items-start gap-3 rounded-lg border p-4 text-sm ${
|
|
204
204
|
isError
|
|
205
205
|
? 'border-destructive/30 bg-destructive/10 text-destructive'
|
|
206
206
|
: 'border-warning/30 bg-warning/10 text-warning'
|