@actuate-media/cms-admin 0.56.0 → 0.56.2
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 +12 -0
- package/dist/__tests__/components/posts-badges.test.js +3 -3
- package/dist/__tests__/components/posts-badges.test.js.map +1 -1
- package/dist/actuate-admin.css +1 -1
- package/dist/components/AICoauthorBubbleMenu.js +2 -2
- package/dist/components/AICoauthorBubbleMenu.js.map +1 -1
- package/dist/components/Breadcrumbs.js +2 -2
- package/dist/components/Breadcrumbs.js.map +1 -1
- package/dist/components/CoauthorResultPopover.d.ts.map +1 -1
- package/dist/components/CoauthorResultPopover.js +1 -1
- package/dist/components/CoauthorResultPopover.js.map +1 -1
- package/dist/components/CommandPalette.d.ts.map +1 -1
- package/dist/components/CommandPalette.js +11 -11
- package/dist/components/CommandPalette.js.map +1 -1
- package/dist/components/CommentSidePanel.js +11 -11
- package/dist/components/CommentSidePanel.js.map +1 -1
- package/dist/components/ContentOverviewChart.js +2 -2
- package/dist/components/ContentOverviewChart.js.map +1 -1
- package/dist/components/FocalPointPicker.js +1 -1
- package/dist/components/FocalPointPicker.js.map +1 -1
- package/dist/components/LivePreview.d.ts.map +1 -1
- package/dist/components/LivePreview.js +5 -5
- package/dist/components/LivePreview.js.map +1 -1
- package/dist/components/LogoPlaceholder.js +1 -1
- package/dist/components/LogoPlaceholder.js.map +1 -1
- package/dist/components/MentionableTextarea.js +3 -3
- package/dist/components/MentionableTextarea.js.map +1 -1
- package/dist/components/NotificationBell.js +1 -1
- package/dist/components/NotificationBell.js.map +1 -1
- package/dist/components/OfflineStatus.js +8 -8
- package/dist/components/OfflineStatus.js.map +1 -1
- package/dist/components/PresenceChips.d.ts.map +1 -1
- package/dist/components/PresenceChips.js +10 -6
- package/dist/components/PresenceChips.js.map +1 -1
- package/dist/components/SEOConfigPanel.d.ts.map +1 -1
- package/dist/components/SEOConfigPanel.js +10 -10
- package/dist/components/SEOConfigPanel.js.map +1 -1
- package/dist/components/SEOPanel.js +12 -12
- package/dist/components/SEOPanel.js.map +1 -1
- package/dist/components/SEOPerformance.d.ts.map +1 -1
- package/dist/components/SEOPerformance.js +3 -3
- package/dist/components/SEOPerformance.js.map +1 -1
- package/dist/components/TipTapEditor.js +6 -6
- package/dist/components/TipTapEditor.js.map +1 -1
- package/dist/components/pages/tag-badges.js +6 -6
- package/dist/components/pages/tag-badges.js.map +1 -1
- package/dist/components/posts/badges.d.ts +0 -4
- package/dist/components/posts/badges.d.ts.map +1 -1
- package/dist/components/posts/badges.js +28 -42
- package/dist/components/posts/badges.js.map +1 -1
- package/dist/components/ui/Badge.js +5 -5
- package/dist/components/ui/Badge.js.map +1 -1
- package/dist/components/ui/Toast.d.ts.map +1 -1
- package/dist/components/ui/Toast.js +4 -4
- package/dist/components/ui/Toast.js.map +1 -1
- package/dist/fields/ComponentBlockField.js +2 -2
- package/dist/fields/ComponentBlockField.js.map +1 -1
- package/dist/fields/FieldRenderer.js +1 -1
- package/dist/fields/FieldRenderer.js.map +1 -1
- package/dist/fields/PropInput.js +1 -1
- package/dist/fields/PropInput.js.map +1 -1
- package/dist/fields/RelationshipField.js +5 -5
- package/dist/fields/RelationshipField.js.map +1 -1
- package/dist/fields/ToggleField.js +1 -1
- package/dist/fields/ToggleField.js.map +1 -1
- package/dist/views/Dashboard.js +5 -5
- package/dist/views/Dashboard.js.map +1 -1
- package/dist/views/DocumentEdit.d.ts.map +1 -1
- package/dist/views/DocumentEdit.js +5 -5
- package/dist/views/DocumentEdit.js.map +1 -1
- package/dist/views/ForgotPassword.d.ts.map +1 -1
- package/dist/views/ForgotPassword.js +3 -2
- package/dist/views/ForgotPassword.js.map +1 -1
- package/dist/views/FormEditor.d.ts.map +1 -1
- package/dist/views/FormEditor.js +5 -5
- package/dist/views/FormEditor.js.map +1 -1
- package/dist/views/Login.d.ts.map +1 -1
- package/dist/views/Login.js +17 -17
- package/dist/views/Login.js.map +1 -1
- package/dist/views/PageEditor.d.ts.map +1 -1
- package/dist/views/PageEditor.js +2 -2
- package/dist/views/PageEditor.js.map +1 -1
- package/dist/views/Pages/PagesListView.js +6 -6
- package/dist/views/Pages/PagesListView.js.map +1 -1
- package/dist/views/Pages.d.ts.map +1 -1
- package/dist/views/Pages.js +16 -19
- package/dist/views/Pages.js.map +1 -1
- package/dist/views/ResetPassword.d.ts.map +1 -1
- package/dist/views/ResetPassword.js +3 -2
- package/dist/views/ResetPassword.js.map +1 -1
- package/dist/views/Settings.js +2 -2
- package/dist/views/Settings.js.map +1 -1
- package/dist/views/SetupWizard.d.ts.map +1 -1
- package/dist/views/SetupWizard.js +6 -5
- package/dist/views/SetupWizard.js.map +1 -1
- package/dist/views/page-builder/DesignScore.js +12 -12
- package/dist/views/page-builder/DesignScore.js.map +1 -1
- package/dist/views/page-builder/SEOPanel.js +9 -9
- package/dist/views/page-builder/SEOPanel.js.map +1 -1
- package/dist/views/page-editor/EditorCanvas.js +1 -1
- package/dist/views/page-editor/EditorCanvas.js.map +1 -1
- package/dist/views/page-editor/EditorTopBar.js +2 -2
- package/dist/views/page-editor/EditorTopBar.js.map +1 -1
- package/dist/views/page-editor/PagePreview.js +1 -1
- package/dist/views/page-editor/PagePreview.js.map +1 -1
- package/dist/views/page-editor/SectionInspector.js +1 -1
- package/dist/views/page-editor/SectionInspector.js.map +1 -1
- package/dist/views/page-editor/SitePreviewFrame.js +1 -1
- package/dist/views/page-editor/SitePreviewFrame.js.map +1 -1
- package/dist/views/page-editor/sections/ArticleBodySection.js +1 -1
- package/dist/views/page-editor/sections/ArticleBodySection.js.map +1 -1
- package/dist/views/page-editor/sections/AuthorBioSection.js +2 -2
- package/dist/views/page-editor/sections/AuthorBioSection.js.map +1 -1
- package/dist/views/page-editor/sections/ByTheNumbersSection.js +1 -1
- package/dist/views/page-editor/sections/ByTheNumbersSection.js.map +1 -1
- package/dist/views/page-editor/sections/CtaBannerSection.js +1 -1
- package/dist/views/page-editor/sections/CtaBannerSection.js.map +1 -1
- package/dist/views/page-editor/sections/EmbedSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/EmbedSection.js +1 -1
- package/dist/views/page-editor/sections/EmbedSection.js.map +1 -1
- package/dist/views/page-editor/sections/FeatureHighlightSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/FeatureHighlightSection.js +2 -2
- package/dist/views/page-editor/sections/FeatureHighlightSection.js.map +1 -1
- package/dist/views/page-editor/sections/GallerySection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/GallerySection.js +1 -1
- package/dist/views/page-editor/sections/GallerySection.js.map +1 -1
- package/dist/views/page-editor/sections/HeroBannerSection.js +1 -1
- package/dist/views/page-editor/sections/HeroBannerSection.js.map +1 -1
- package/dist/views/page-editor/sections/MissionSection.d.ts.map +1 -1
- package/dist/views/page-editor/sections/MissionSection.js +1 -1
- package/dist/views/page-editor/sections/MissionSection.js.map +1 -1
- package/dist/views/page-editor/sections/PullQuoteSection.js +1 -1
- package/dist/views/page-editor/sections/PullQuoteSection.js.map +1 -1
- package/dist/views/page-editor/sections/RelatedPostsSection.js +1 -1
- package/dist/views/page-editor/sections/RelatedPostsSection.js.map +1 -1
- package/dist/views/page-editor/sections/SectionRenderer.js +1 -1
- package/dist/views/page-editor/sections/SectionRenderer.js.map +1 -1
- package/dist/views/page-editor/sections/parts.js +6 -6
- package/dist/views/page-editor/sections/parts.js.map +1 -1
- package/dist/views/post-editor/PostEditorCanvas.js +2 -2
- package/dist/views/post-editor/PostEditorCanvas.js.map +1 -1
- package/dist/views/post-editor/PostHeader.js +2 -2
- package/dist/views/post-editor/PostHeader.js.map +1 -1
- package/dist/views/post-editor/PostHeaderPanel.js +1 -1
- package/dist/views/post-editor/PostHeaderPanel.js.map +1 -1
- package/dist/views/post-editor/PostPreview.js +1 -1
- package/dist/views/post-editor/PostPreview.js.map +1 -1
- package/dist/views/profile/AccountSecurity.js +1 -1
- package/dist/views/profile/AccountSecurity.js.map +1 -1
- package/dist/views/settings/components.js +1 -1
- package/dist/views/settings/components.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/components/posts-badges.test.tsx +3 -3
- package/src/components/AICoauthorBubbleMenu.tsx +4 -4
- package/src/components/Breadcrumbs.tsx +5 -5
- package/src/components/CoauthorResultPopover.tsx +26 -23
- package/src/components/CommandPalette.tsx +41 -39
- package/src/components/CommentSidePanel.tsx +20 -20
- package/src/components/ContentOverviewChart.tsx +4 -4
- package/src/components/FocalPointPicker.tsx +2 -2
- package/src/components/LivePreview.tsx +20 -17
- package/src/components/LogoPlaceholder.tsx +1 -1
- package/src/components/MentionableTextarea.tsx +5 -5
- package/src/components/NotificationBell.tsx +10 -10
- package/src/components/OfflineStatus.tsx +8 -8
- package/src/components/PresenceChips.tsx +12 -8
- package/src/components/SEOConfigPanel.tsx +40 -38
- package/src/components/SEOPanel.tsx +15 -15
- package/src/components/SEOPerformance.tsx +25 -23
- package/src/components/TipTapEditor.tsx +7 -7
- package/src/components/pages/tag-badges.tsx +6 -6
- package/src/components/posts/badges.tsx +28 -46
- package/src/components/ui/Badge.tsx +5 -5
- package/src/components/ui/Toast.tsx +4 -5
- package/src/fields/ComponentBlockField.tsx +2 -2
- package/src/fields/FieldRenderer.tsx +1 -1
- package/src/fields/PropInput.tsx +1 -1
- package/src/fields/RelationshipField.tsx +5 -5
- package/src/fields/ToggleField.tsx +1 -1
- package/src/views/Dashboard.tsx +5 -5
- package/src/views/DocumentEdit.tsx +13 -11
- package/src/views/ForgotPassword.tsx +21 -18
- package/src/views/FormEditor.tsx +74 -69
- package/src/views/Login.tsx +45 -39
- package/src/views/PageEditor.tsx +26 -22
- package/src/views/Pages/PagesListView.tsx +6 -6
- package/src/views/Pages.tsx +64 -65
- package/src/views/ResetPassword.tsx +32 -29
- package/src/views/Settings.tsx +2 -2
- package/src/views/SetupWizard.tsx +42 -33
- package/src/views/page-builder/DesignScore.tsx +12 -12
- package/src/views/page-builder/SEOPanel.tsx +12 -12
- package/src/views/page-editor/EditorCanvas.tsx +1 -1
- package/src/views/page-editor/EditorTopBar.tsx +2 -2
- package/src/views/page-editor/PagePreview.tsx +1 -1
- package/src/views/page-editor/SectionInspector.tsx +1 -1
- package/src/views/page-editor/SitePreviewFrame.tsx +1 -1
- package/src/views/page-editor/sections/ArticleBodySection.tsx +5 -5
- package/src/views/page-editor/sections/AuthorBioSection.tsx +6 -6
- package/src/views/page-editor/sections/ByTheNumbersSection.tsx +5 -5
- package/src/views/page-editor/sections/CtaBannerSection.tsx +1 -1
- package/src/views/page-editor/sections/EmbedSection.tsx +6 -4
- package/src/views/page-editor/sections/FeatureHighlightSection.tsx +7 -5
- package/src/views/page-editor/sections/GallerySection.tsx +6 -4
- package/src/views/page-editor/sections/HeroBannerSection.tsx +2 -2
- package/src/views/page-editor/sections/MissionSection.tsx +4 -2
- package/src/views/page-editor/sections/PullQuoteSection.tsx +4 -4
- package/src/views/page-editor/sections/RelatedPostsSection.tsx +5 -5
- package/src/views/page-editor/sections/SectionRenderer.tsx +2 -2
- package/src/views/page-editor/sections/parts.tsx +6 -6
- package/src/views/post-editor/PostEditorCanvas.tsx +4 -4
- package/src/views/post-editor/PostHeader.tsx +5 -5
- package/src/views/post-editor/PostHeaderPanel.tsx +1 -1
- package/src/views/post-editor/PostPreview.tsx +1 -1
- package/src/views/profile/AccountSecurity.tsx +1 -1
- package/src/views/settings/components.tsx +1 -1
|
@@ -23,8 +23,8 @@ interface SEOSummary {
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
function ScoreBadge({ score }: { score: number }) {
|
|
26
|
-
const color = score >= 80 ? 'text-
|
|
27
|
-
const bg = score >= 80 ? 'bg-
|
|
26
|
+
const color = score >= 80 ? 'text-success' : score >= 60 ? 'text-warning' : 'text-destructive'
|
|
27
|
+
const bg = score >= 80 ? 'bg-success/10' : score >= 60 ? 'bg-warning/10' : 'bg-destructive/10'
|
|
28
28
|
return (
|
|
29
29
|
<span
|
|
30
30
|
className={`inline-flex h-9 w-9 items-center justify-center rounded-full text-sm font-medium ${color} ${bg}`}
|
|
@@ -53,38 +53,40 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
53
53
|
const visible = topContent.slice(page * perPage, (page + 1) * perPage)
|
|
54
54
|
|
|
55
55
|
return (
|
|
56
|
-
<div className="
|
|
57
|
-
<div className="flex items-center justify-between border-b
|
|
56
|
+
<div className="border-border bg-card rounded-lg border">
|
|
57
|
+
<div className="border-border flex items-center justify-between border-b p-4">
|
|
58
58
|
<div className="flex items-center gap-2">
|
|
59
|
-
<Search className="h-4 w-4
|
|
60
|
-
<h2 className="text-sm font-medium
|
|
59
|
+
<Search className="text-muted-foreground h-4 w-4" />
|
|
60
|
+
<h2 className="text-foreground text-sm font-medium">SEO Performance</h2>
|
|
61
61
|
</div>
|
|
62
62
|
{totalIssues > 0 && (
|
|
63
|
-
<span className="text-
|
|
63
|
+
<span className="text-muted-foreground text-xs">
|
|
64
64
|
{totalIssues} issue{totalIssues !== 1 ? 's' : ''} found
|
|
65
65
|
</span>
|
|
66
66
|
)}
|
|
67
67
|
</div>
|
|
68
68
|
|
|
69
|
-
<div className="grid grid-cols-1 divide-y
|
|
69
|
+
<div className="divide-border grid grid-cols-1 divide-y lg:grid-cols-12 lg:divide-x lg:divide-y-0">
|
|
70
70
|
<div className="p-4 lg:col-span-7">
|
|
71
|
-
<h3 className="mb-3 text-sm font-medium
|
|
71
|
+
<h3 className="text-foreground mb-3 text-sm font-medium">Top Performing Content</h3>
|
|
72
72
|
<div className="space-y-2">
|
|
73
73
|
{visible.map((item) => (
|
|
74
74
|
<div key={item.id} className="flex items-center justify-between py-2">
|
|
75
75
|
<div className="mr-3 min-w-0 flex-1">
|
|
76
|
-
<p className="truncate text-sm font-medium
|
|
77
|
-
<p className="text-
|
|
76
|
+
<p className="text-foreground truncate text-sm font-medium">{item.title}</p>
|
|
77
|
+
<p className="text-muted-foreground text-xs capitalize">{item.collection}</p>
|
|
78
78
|
</div>
|
|
79
79
|
<ScoreBadge score={item.score} />
|
|
80
80
|
</div>
|
|
81
81
|
))}
|
|
82
82
|
{visible.length === 0 && (
|
|
83
|
-
<p className="py-4 text-center text-sm
|
|
83
|
+
<p className="text-muted-foreground py-4 text-center text-sm">
|
|
84
|
+
No published content yet
|
|
85
|
+
</p>
|
|
84
86
|
)}
|
|
85
87
|
</div>
|
|
86
88
|
{topContent.length > perPage && (
|
|
87
|
-
<div className="mt-3 flex items-center justify-between border-t border-gray-100 pt-3 text-xs
|
|
89
|
+
<div className="text-muted-foreground mt-3 flex items-center justify-between border-t border-gray-100 pt-3 text-xs">
|
|
88
90
|
<span>
|
|
89
91
|
Showing {page * perPage + 1}-{Math.min((page + 1) * perPage, topContent.length)} of{' '}
|
|
90
92
|
{topContent.length}
|
|
@@ -93,7 +95,7 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
93
95
|
<button
|
|
94
96
|
onClick={() => setPage(Math.max(0, page - 1))}
|
|
95
97
|
disabled={page === 0}
|
|
96
|
-
className="rounded p-1
|
|
98
|
+
className="hover:bg-accent rounded p-1 disabled:opacity-30"
|
|
97
99
|
>
|
|
98
100
|
<ChevronLeft className="h-3.5 w-3.5" />
|
|
99
101
|
</button>
|
|
@@ -103,7 +105,7 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
103
105
|
<button
|
|
104
106
|
onClick={() => setPage(Math.min(totalPages - 1, page + 1))}
|
|
105
107
|
disabled={page >= totalPages - 1}
|
|
106
|
-
className="rounded p-1
|
|
108
|
+
className="hover:bg-accent rounded p-1 disabled:opacity-30"
|
|
107
109
|
>
|
|
108
110
|
<ChevronRight className="h-3.5 w-3.5" />
|
|
109
111
|
</button>
|
|
@@ -113,38 +115,38 @@ export function SEOPerformance({ onNavigate }: SEOPerformanceProps) {
|
|
|
113
115
|
</div>
|
|
114
116
|
|
|
115
117
|
<div className="p-4 lg:col-span-5">
|
|
116
|
-
<h3 className="mb-3 text-sm font-medium
|
|
118
|
+
<h3 className="text-foreground mb-3 text-sm font-medium">SEO Issues</h3>
|
|
117
119
|
<div className="space-y-3">
|
|
118
120
|
<div className="flex items-center justify-between">
|
|
119
121
|
<div className="flex items-center gap-2">
|
|
120
122
|
<FileWarning className="h-4 w-4 text-red-400" />
|
|
121
|
-
<span className="text-
|
|
123
|
+
<span className="text-foreground text-sm">Missing meta descriptions</span>
|
|
122
124
|
</div>
|
|
123
|
-
<span className="text-sm font-medium
|
|
125
|
+
<span className="text-foreground text-sm font-medium">
|
|
124
126
|
{issues.missingMetaDescriptions}
|
|
125
127
|
</span>
|
|
126
128
|
</div>
|
|
127
129
|
<div className="flex items-center justify-between">
|
|
128
130
|
<div className="flex items-center gap-2">
|
|
129
131
|
<LinkIcon className="h-4 w-4 text-red-400" />
|
|
130
|
-
<span className="text-
|
|
132
|
+
<span className="text-foreground text-sm">Broken internal links</span>
|
|
131
133
|
</div>
|
|
132
|
-
<span className="text-sm font-medium
|
|
134
|
+
<span className="text-foreground text-sm font-medium">
|
|
133
135
|
{issues.brokenInternalLinks}
|
|
134
136
|
</span>
|
|
135
137
|
</div>
|
|
136
138
|
<div className="flex items-center justify-between">
|
|
137
139
|
<div className="flex items-center gap-2">
|
|
138
140
|
<ImageOff className="h-4 w-4 text-red-400" />
|
|
139
|
-
<span className="text-
|
|
141
|
+
<span className="text-foreground text-sm">Missing alt text</span>
|
|
140
142
|
</div>
|
|
141
|
-
<span className="text-sm font-medium
|
|
143
|
+
<span className="text-foreground text-sm font-medium">{issues.missingAltText}</span>
|
|
142
144
|
</div>
|
|
143
145
|
</div>
|
|
144
146
|
{totalIssues > 0 && (
|
|
145
147
|
<button
|
|
146
148
|
onClick={() => onNavigate?.('/seo')}
|
|
147
|
-
className="mt-4 text-sm font-medium
|
|
149
|
+
className="text-primary hover:text-primary/80 mt-4 text-sm font-medium"
|
|
148
150
|
>
|
|
149
151
|
View All Issues
|
|
150
152
|
</button>
|
|
@@ -233,8 +233,8 @@ function ToolbarButton({
|
|
|
233
233
|
title={title}
|
|
234
234
|
className={`rounded p-1.5 transition-colors ${
|
|
235
235
|
isActive
|
|
236
|
-
? 'bg-
|
|
237
|
-
: 'text-
|
|
236
|
+
? 'bg-info/10 text-info'
|
|
237
|
+
: 'text-muted-foreground hover:bg-accent hover:text-foreground'
|
|
238
238
|
} ${disabled ? 'cursor-not-allowed opacity-40' : ''}`}
|
|
239
239
|
>
|
|
240
240
|
{children}
|
|
@@ -243,7 +243,7 @@ function ToolbarButton({
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
function Divider() {
|
|
246
|
-
return <div className="mx-1 h-6 w-px
|
|
246
|
+
return <div className="bg-muted mx-1 h-6 w-px" />
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
function Toolbar({ editor, onOpenMediaPicker }: { editor: Editor; onOpenMediaPicker: () => void }) {
|
|
@@ -265,7 +265,7 @@ function Toolbar({ editor, onOpenMediaPicker }: { editor: Editor; onOpenMediaPic
|
|
|
265
265
|
const isInTable = editor.isActive('table')
|
|
266
266
|
|
|
267
267
|
return (
|
|
268
|
-
<div className="sticky top-0 z-10 flex flex-wrap items-center gap-0.5 border-b
|
|
268
|
+
<div className="border-border bg-muted sticky top-0 z-10 flex flex-wrap items-center gap-0.5 border-b p-2">
|
|
269
269
|
{/* Group 1: Text formatting */}
|
|
270
270
|
<ToolbarButton
|
|
271
271
|
onClick={() => editor.chain().focus().toggleBold().run()}
|
|
@@ -544,7 +544,7 @@ export function TipTapEditor({
|
|
|
544
544
|
UnderlineExt,
|
|
545
545
|
Link.configure({
|
|
546
546
|
openOnClick: false,
|
|
547
|
-
HTMLAttributes: { class: 'text-
|
|
547
|
+
HTMLAttributes: { class: 'text-primary underline' },
|
|
548
548
|
}),
|
|
549
549
|
Image.configure({
|
|
550
550
|
inline: true,
|
|
@@ -656,10 +656,10 @@ export function TipTapEditor({
|
|
|
656
656
|
|
|
657
657
|
const editorPane = (
|
|
658
658
|
<div
|
|
659
|
-
className={`flex-1 overflow-hidden rounded-lg border
|
|
659
|
+
className={`border-border bg-card flex-1 overflow-hidden rounded-lg border ${className ?? ''}`}
|
|
660
660
|
>
|
|
661
661
|
{collaboration && awareness && (
|
|
662
|
-
<div className="flex items-center justify-between gap-2 border-b border-gray-100
|
|
662
|
+
<div className="bg-card flex items-center justify-between gap-2 border-b border-gray-100 px-2 py-1.5">
|
|
663
663
|
<PresenceChips awareness={awareness} status={collabStatus} />
|
|
664
664
|
<OfflineStatus connection={collabStatus} offline={offlineStatus} />
|
|
665
665
|
</div>
|
|
@@ -14,12 +14,12 @@ import { paletteFor } from '../posts/badges.js'
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
const DOT_COLOR: Record<string, string> = {
|
|
17
|
-
purple: 'bg-
|
|
18
|
-
green: 'bg-
|
|
19
|
-
orange: 'bg-
|
|
20
|
-
red: 'bg-
|
|
21
|
-
blue: 'bg-
|
|
22
|
-
pink: 'bg-
|
|
17
|
+
purple: 'bg-brand',
|
|
18
|
+
green: 'bg-success',
|
|
19
|
+
orange: 'bg-warning',
|
|
20
|
+
red: 'bg-destructive',
|
|
21
|
+
blue: 'bg-info',
|
|
22
|
+
pink: 'bg-chart-4',
|
|
23
23
|
gray: 'bg-muted-foreground',
|
|
24
24
|
}
|
|
25
25
|
|
|
@@ -5,53 +5,45 @@ import type { PostStatus } from '../../lib/posts-service.js'
|
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Shared status / type / SEO indicators for the Posts admin area.
|
|
8
|
-
*
|
|
9
|
-
* Colors are restricted to the theme tokens already used elsewhere in
|
|
10
|
-
* the admin (`success`, `warning`, `destructive`, `primary`, `muted`)
|
|
11
|
-
* plus a small named-color palette (`purple`, `green`, `orange`, ...)
|
|
12
|
-
* that maps to fixed Tailwind utilities. This keeps the badges working
|
|
13
|
-
* in both light and dark mode and avoids leaking `bg-[#...]` arbitrary
|
|
14
|
-
* values into components.
|
|
8
|
+
* Colors use semantic theme tokens only.
|
|
15
9
|
*/
|
|
16
10
|
|
|
17
|
-
// ─── Named color palette ─────────────────────────────────────────────
|
|
18
|
-
|
|
19
11
|
const PALETTE: Record<string, { bg: string; text: string; ring: string; border: string }> = {
|
|
20
12
|
purple: {
|
|
21
|
-
bg: 'bg-
|
|
22
|
-
text: 'text-
|
|
23
|
-
ring: 'ring-
|
|
24
|
-
border: 'border-
|
|
13
|
+
bg: 'bg-brand/10',
|
|
14
|
+
text: 'text-brand',
|
|
15
|
+
ring: 'ring-brand/20',
|
|
16
|
+
border: 'border-brand',
|
|
25
17
|
},
|
|
26
18
|
green: {
|
|
27
|
-
bg: 'bg-
|
|
28
|
-
text: 'text-
|
|
29
|
-
ring: 'ring-
|
|
30
|
-
border: 'border-
|
|
19
|
+
bg: 'bg-success/10',
|
|
20
|
+
text: 'text-success',
|
|
21
|
+
ring: 'ring-success/20',
|
|
22
|
+
border: 'border-success',
|
|
31
23
|
},
|
|
32
24
|
orange: {
|
|
33
|
-
bg: 'bg-
|
|
34
|
-
text: 'text-
|
|
35
|
-
ring: 'ring-
|
|
36
|
-
border: 'border-
|
|
25
|
+
bg: 'bg-warning/10',
|
|
26
|
+
text: 'text-warning',
|
|
27
|
+
ring: 'ring-warning/20',
|
|
28
|
+
border: 'border-warning',
|
|
37
29
|
},
|
|
38
30
|
red: {
|
|
39
|
-
bg: 'bg-
|
|
40
|
-
text: 'text-
|
|
41
|
-
ring: 'ring-
|
|
42
|
-
border: 'border-
|
|
31
|
+
bg: 'bg-destructive/10',
|
|
32
|
+
text: 'text-destructive',
|
|
33
|
+
ring: 'ring-destructive/20',
|
|
34
|
+
border: 'border-destructive',
|
|
43
35
|
},
|
|
44
36
|
blue: {
|
|
45
|
-
bg: 'bg-
|
|
46
|
-
text: 'text-
|
|
47
|
-
ring: 'ring-
|
|
48
|
-
border: 'border-
|
|
37
|
+
bg: 'bg-info/10',
|
|
38
|
+
text: 'text-info',
|
|
39
|
+
ring: 'ring-info/20',
|
|
40
|
+
border: 'border-info',
|
|
49
41
|
},
|
|
50
42
|
pink: {
|
|
51
|
-
bg: 'bg-
|
|
52
|
-
text: 'text-
|
|
53
|
-
ring: 'ring-
|
|
54
|
-
border: 'border-
|
|
43
|
+
bg: 'bg-chart-4/15',
|
|
44
|
+
text: 'text-chart-4',
|
|
45
|
+
ring: 'ring-chart-4/20',
|
|
46
|
+
border: 'border-chart-4',
|
|
55
47
|
},
|
|
56
48
|
gray: {
|
|
57
49
|
bg: 'bg-muted',
|
|
@@ -66,8 +58,6 @@ export function paletteFor(color: string | null | undefined) {
|
|
|
66
58
|
return PALETTE[color] ?? PALETTE.gray!
|
|
67
59
|
}
|
|
68
60
|
|
|
69
|
-
// ─── PostStatusBadge ─────────────────────────────────────────────────
|
|
70
|
-
|
|
71
61
|
const STATUS_LABEL: Record<PostStatus, string> = {
|
|
72
62
|
PUBLISHED: 'Published',
|
|
73
63
|
DRAFT: 'Draft',
|
|
@@ -104,8 +94,6 @@ export function PostStatusBadge({ status }: { status: PostStatus }) {
|
|
|
104
94
|
)
|
|
105
95
|
}
|
|
106
96
|
|
|
107
|
-
// ─── PostTypeBadge ───────────────────────────────────────────────────
|
|
108
|
-
|
|
109
97
|
export function PostTypeBadge({
|
|
110
98
|
label,
|
|
111
99
|
color,
|
|
@@ -127,12 +115,6 @@ export function PostTypeBadge({
|
|
|
127
115
|
return <span className={className}>{label}</span>
|
|
128
116
|
}
|
|
129
117
|
|
|
130
|
-
// ─── SeoScoreIndicator ───────────────────────────────────────────────
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Returns the palette key for an SEO score so callers can match the
|
|
134
|
-
* colored dot. 80+ green, 60–79 orange, 1–59 red, missing = gray.
|
|
135
|
-
*/
|
|
136
118
|
export function seoScorePalette(score: number | null): string {
|
|
137
119
|
if (score === null || Number.isNaN(score)) return 'gray'
|
|
138
120
|
if (score >= 80) return 'green'
|
|
@@ -158,10 +140,10 @@ export function SeoScoreIndicator({ score }: { score: number | null }) {
|
|
|
158
140
|
aria-hidden
|
|
159
141
|
className={`h-2 w-2 rounded-full ${
|
|
160
142
|
colorKey === 'green'
|
|
161
|
-
? 'bg-
|
|
143
|
+
? 'bg-success'
|
|
162
144
|
: colorKey === 'orange'
|
|
163
|
-
? 'bg-
|
|
164
|
-
: 'bg-
|
|
145
|
+
? 'bg-warning'
|
|
146
|
+
: 'bg-destructive'
|
|
165
147
|
}`}
|
|
166
148
|
/>
|
|
167
149
|
<span className="tabular-nums">{score}</span>
|
|
@@ -4,11 +4,11 @@ import { cv, type VariantProps } from '../../lib/cv.js'
|
|
|
4
4
|
const badge = cv('inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium', {
|
|
5
5
|
variants: {
|
|
6
6
|
tone: {
|
|
7
|
-
neutral: 'bg-
|
|
8
|
-
success: 'bg-
|
|
9
|
-
warning: 'bg-
|
|
10
|
-
danger: 'bg-
|
|
11
|
-
info: 'bg-
|
|
7
|
+
neutral: 'bg-muted text-muted-foreground',
|
|
8
|
+
success: 'bg-success/10 text-success',
|
|
9
|
+
warning: 'bg-warning/10 text-warning',
|
|
10
|
+
danger: 'bg-destructive/10 text-destructive',
|
|
11
|
+
info: 'bg-info/10 text-info',
|
|
12
12
|
primary: 'bg-[var(--primary)]/15 text-[var(--primary)] dark:bg-[var(--primary)]/25',
|
|
13
13
|
},
|
|
14
14
|
size: {
|
|
@@ -11,11 +11,10 @@ interface Toast {
|
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
const typeClasses: Record<ToastType, string> = {
|
|
14
|
-
success:
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
info: 'border-blue-500 bg-blue-50 text-blue-900 dark:bg-blue-900/20 dark:text-blue-300',
|
|
14
|
+
success: 'border-success bg-success/10 text-success',
|
|
15
|
+
error: 'border-destructive bg-destructive/10 text-destructive',
|
|
16
|
+
warning: 'border-warning bg-warning/10 text-warning',
|
|
17
|
+
info: 'border-info bg-info/10 text-info',
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
export function useToast() {
|
|
@@ -117,7 +117,7 @@ export function ComponentBlockField({
|
|
|
117
117
|
|
|
118
118
|
if (!currentSpec) {
|
|
119
119
|
return (
|
|
120
|
-
<div className="rounded-md border border-[var(--destructive)]
|
|
120
|
+
<div className="bg-destructive/10 rounded-md border border-[var(--destructive)] p-3 text-sm text-[var(--destructive)]">
|
|
121
121
|
Component block has no components to choose from.
|
|
122
122
|
</div>
|
|
123
123
|
)
|
|
@@ -147,7 +147,7 @@ export function ComponentBlockField({
|
|
|
147
147
|
) : null}
|
|
148
148
|
|
|
149
149
|
{errorMessage ? (
|
|
150
|
-
<div className="rounded-md border border-[var(--destructive)]
|
|
150
|
+
<div className="bg-destructive/10 rounded-md border border-[var(--destructive)] px-3 py-2 text-xs text-[var(--destructive)]">
|
|
151
151
|
{errorMessage}
|
|
152
152
|
</div>
|
|
153
153
|
) : null}
|
|
@@ -62,7 +62,7 @@ export function FieldRenderer({ field, value, onChange }: FieldRendererProps) {
|
|
|
62
62
|
|
|
63
63
|
if (!Component) {
|
|
64
64
|
return (
|
|
65
|
-
<div className="rounded-md border border-[var(--destructive)]
|
|
65
|
+
<div className="bg-destructive/10 rounded-md border border-[var(--destructive)] p-3 text-sm text-[var(--destructive)]">
|
|
66
66
|
Unknown field type: <code>{field.type}</code>
|
|
67
67
|
</div>
|
|
68
68
|
)
|
package/src/fields/PropInput.tsx
CHANGED
|
@@ -259,7 +259,7 @@ function BooleanInput({
|
|
|
259
259
|
}`}
|
|
260
260
|
>
|
|
261
261
|
<span
|
|
262
|
-
className={`pointer-events-none inline-block h-5 w-5 rounded-full
|
|
262
|
+
className={`bg-card pointer-events-none inline-block h-5 w-5 rounded-full shadow-sm ring-0 transition-transform ${
|
|
263
263
|
boolVal ? 'translate-x-5' : 'translate-x-0'
|
|
264
264
|
}`}
|
|
265
265
|
/>
|
|
@@ -26,10 +26,10 @@ interface RelatedDoc {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
const STATUS_STYLES: Record<string, string> = {
|
|
29
|
-
PUBLISHED: 'bg-
|
|
30
|
-
DRAFT: 'bg-
|
|
31
|
-
ARCHIVED: 'bg-
|
|
32
|
-
SCHEDULED: 'bg-
|
|
29
|
+
PUBLISHED: 'bg-success/10 text-success',
|
|
30
|
+
DRAFT: 'bg-warning/10 text-warning',
|
|
31
|
+
ARCHIVED: 'bg-muted text-muted-foreground',
|
|
32
|
+
SCHEDULED: 'bg-info/10 text-info',
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
function relativeTime(dateStr: string | undefined): string {
|
|
@@ -150,7 +150,7 @@ export function RelationshipField({
|
|
|
150
150
|
function renderOption(opt: RelatedDoc, isSelected: boolean) {
|
|
151
151
|
const status = opt.status ?? (opt.data as any)?.status
|
|
152
152
|
const collection = opt.collection ?? relationTo
|
|
153
|
-
const statusClass = STATUS_STYLES[status] ?? 'bg-
|
|
153
|
+
const statusClass = STATUS_STYLES[status] ?? 'bg-muted text-muted-foreground'
|
|
154
154
|
|
|
155
155
|
return (
|
|
156
156
|
<button
|
|
@@ -24,7 +24,7 @@ export function ToggleField({ label, value = false, onChange, helpText }: Toggle
|
|
|
24
24
|
}`}
|
|
25
25
|
>
|
|
26
26
|
<span
|
|
27
|
-
className={`pointer-events-none inline-block h-5 w-5 rounded-full
|
|
27
|
+
className={`bg-card pointer-events-none inline-block h-5 w-5 rounded-full shadow-sm ring-0 transition-transform ${
|
|
28
28
|
value ? 'translate-x-5' : 'translate-x-0'
|
|
29
29
|
}`}
|
|
30
30
|
/>
|
package/src/views/Dashboard.tsx
CHANGED
|
@@ -795,7 +795,7 @@ export function Dashboard({ config, session, onNavigate }: DashboardProps) {
|
|
|
795
795
|
: contentHealth.tone === 'warn'
|
|
796
796
|
? 'text-warning'
|
|
797
797
|
: contentHealth.tone === 'err'
|
|
798
|
-
? 'text-
|
|
798
|
+
? 'text-destructive dark:text-red-400'
|
|
799
799
|
: 'text-muted-foreground'
|
|
800
800
|
}`}
|
|
801
801
|
>
|
|
@@ -810,7 +810,7 @@ export function Dashboard({ config, session, onNavigate }: DashboardProps) {
|
|
|
810
810
|
: contentHealth.tone === 'warn'
|
|
811
811
|
? 'bg-warning'
|
|
812
812
|
: contentHealth.tone === 'err'
|
|
813
|
-
? 'bg-
|
|
813
|
+
? 'bg-destructive'
|
|
814
814
|
: 'bg-muted-foreground/40'
|
|
815
815
|
}`}
|
|
816
816
|
style={{ width: `${Math.max(0, Math.min(100, contentHealth.score))}%` }}
|
|
@@ -833,7 +833,7 @@ export function Dashboard({ config, session, onNavigate }: DashboardProps) {
|
|
|
833
833
|
<span
|
|
834
834
|
className={`h-1.5 w-1.5 shrink-0 rounded-full ${
|
|
835
835
|
iss.tone === 'err'
|
|
836
|
-
? 'bg-
|
|
836
|
+
? 'bg-destructive'
|
|
837
837
|
: iss.tone === 'warn'
|
|
838
838
|
? 'bg-warning'
|
|
839
839
|
: 'bg-muted-foreground'
|
|
@@ -846,7 +846,7 @@ export function Dashboard({ config, session, onNavigate }: DashboardProps) {
|
|
|
846
846
|
<span
|
|
847
847
|
className={`shrink-0 text-sm font-medium ${
|
|
848
848
|
iss.tone === 'err'
|
|
849
|
-
? 'text-
|
|
849
|
+
? 'text-destructive dark:text-red-400'
|
|
850
850
|
: iss.tone === 'warn'
|
|
851
851
|
? 'text-warning'
|
|
852
852
|
: 'text-muted-foreground'
|
|
@@ -1040,7 +1040,7 @@ function DeliveryTile({
|
|
|
1040
1040
|
: tone === 'warn'
|
|
1041
1041
|
? 'text-warning'
|
|
1042
1042
|
: tone === 'err'
|
|
1043
|
-
? 'text-
|
|
1043
|
+
? 'text-destructive dark:text-red-400'
|
|
1044
1044
|
: 'text-muted-foreground'
|
|
1045
1045
|
return (
|
|
1046
1046
|
<div className="px-4 py-3.5">
|
|
@@ -292,15 +292,15 @@ export function DocumentEdit({
|
|
|
292
292
|
|
|
293
293
|
const statusColor =
|
|
294
294
|
docStatus === 'PUBLISHED'
|
|
295
|
-
? 'bg-
|
|
295
|
+
? 'bg-success/10 text-success'
|
|
296
296
|
: docStatus === 'SCHEDULED'
|
|
297
|
-
? 'bg-
|
|
298
|
-
: 'bg-
|
|
297
|
+
? 'bg-info/10 text-info'
|
|
298
|
+
: 'bg-warning/10 text-warning'
|
|
299
299
|
|
|
300
300
|
if (loading) {
|
|
301
301
|
return (
|
|
302
302
|
<div className="flex min-h-[300px] items-center justify-center">
|
|
303
|
-
<Loader2 className="h-8 w-8 animate-spin
|
|
303
|
+
<Loader2 className="text-muted-foreground h-8 w-8 animate-spin" />
|
|
304
304
|
</div>
|
|
305
305
|
)
|
|
306
306
|
}
|
|
@@ -316,7 +316,7 @@ export function DocumentEdit({
|
|
|
316
316
|
{docStatus}
|
|
317
317
|
</span>
|
|
318
318
|
{documentId && <PresenceIndicator documentId={documentId} />}
|
|
319
|
-
{isDirty && <span className="text-xs font-medium
|
|
319
|
+
{isDirty && <span className="text-warning text-xs font-medium">Unsaved changes</span>}
|
|
320
320
|
</div>
|
|
321
321
|
<div className="flex items-center gap-2">
|
|
322
322
|
<button
|
|
@@ -362,13 +362,15 @@ export function DocumentEdit({
|
|
|
362
362
|
<div className="space-y-6">
|
|
363
363
|
{fields.length === 0 ? (
|
|
364
364
|
<div className="flex flex-col items-center justify-center rounded-lg border border-[var(--border)] py-16 text-center">
|
|
365
|
-
<div className="mb-4 flex h-12 w-12 items-center justify-center rounded-full
|
|
366
|
-
<AlertTriangle className="h-6 w-6
|
|
365
|
+
<div className="bg-muted mb-4 flex h-12 w-12 items-center justify-center rounded-full">
|
|
366
|
+
<AlertTriangle className="text-muted-foreground h-6 w-6" />
|
|
367
367
|
</div>
|
|
368
|
-
<h3 className="mb-1 text-sm font-medium
|
|
368
|
+
<h3 className="text-foreground mb-1 text-sm font-medium">
|
|
369
369
|
Collection schema not found
|
|
370
370
|
</h3>
|
|
371
|
-
<p className="text-
|
|
371
|
+
<p className="text-muted-foreground text-sm">
|
|
372
|
+
No fields are defined for this collection.
|
|
373
|
+
</p>
|
|
372
374
|
</div>
|
|
373
375
|
) : (
|
|
374
376
|
<div className="grid grid-cols-1 gap-6 lg:grid-cols-3">
|
|
@@ -410,14 +412,14 @@ export function DocumentEdit({
|
|
|
410
412
|
{!isNew && (
|
|
411
413
|
<button
|
|
412
414
|
onClick={() => setShowSchedule(true)}
|
|
413
|
-
className="inline-flex w-full items-center justify-center gap-1.5 rounded-md border
|
|
415
|
+
className="border-border bg-card text-foreground hover:bg-accent inline-flex w-full items-center justify-center gap-1.5 rounded-md border px-3 py-1.5 text-sm font-medium"
|
|
414
416
|
>
|
|
415
417
|
<Calendar className="h-4 w-4" />
|
|
416
418
|
{scheduledAt || scheduledUnpublishAt ? 'Reschedule' : 'Schedule'}
|
|
417
419
|
</button>
|
|
418
420
|
)}
|
|
419
421
|
{!isNew && (scheduledAt || scheduledUnpublishAt) && (
|
|
420
|
-
<div className="space-y-1 rounded-md border
|
|
422
|
+
<div className="border-info/30 bg-info/10 text-foreground space-y-1 rounded-md border px-3 py-2 text-xs">
|
|
421
423
|
{scheduledAt && (
|
|
422
424
|
<div className="flex items-center gap-1.5">
|
|
423
425
|
<Calendar className="h-3.5 w-3.5" />
|