@actuate-media/cms-admin 0.10.0 → 0.11.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/dist/AdminRoot.d.ts.map +1 -1
- package/dist/AdminRoot.js +8 -5
- package/dist/AdminRoot.js.map +1 -1
- package/dist/__tests__/layout/primitives.test.d.ts +2 -0
- package/dist/__tests__/layout/primitives.test.d.ts.map +1 -0
- package/dist/__tests__/layout/primitives.test.js +34 -0
- package/dist/__tests__/layout/primitives.test.js.map +1 -0
- package/dist/__tests__/lib/cv.test.d.ts +2 -0
- package/dist/__tests__/lib/cv.test.d.ts.map +1 -0
- package/dist/__tests__/lib/cv.test.js +66 -0
- package/dist/__tests__/lib/cv.test.js.map +1 -0
- package/dist/actuate-admin.css +1 -1
- package/dist/assets/actuate-logo.d.ts +36 -0
- package/dist/assets/actuate-logo.d.ts.map +1 -0
- package/dist/assets/actuate-logo.js +15 -0
- package/dist/assets/actuate-logo.js.map +1 -0
- package/dist/components/Breadcrumbs.js +2 -2
- package/dist/components/CommandPalette.js +10 -10
- package/dist/components/ContentOverviewChart.js +3 -3
- package/dist/components/ErrorBoundary.js +1 -1
- package/dist/components/FocalPointPicker.js +2 -2
- package/dist/components/FolderTree.js +20 -20
- package/dist/components/LivePreview.js +3 -3
- package/dist/components/LocaleSwitcher.js +1 -1
- package/dist/components/MediaPickerModal.js +4 -4
- package/dist/components/PresenceIndicator.js +1 -1
- package/dist/components/SEOConfigPanel.d.ts +2 -0
- package/dist/components/SEOConfigPanel.d.ts.map +1 -0
- package/dist/components/SEOConfigPanel.js +174 -0
- package/dist/components/SEOConfigPanel.js.map +1 -0
- package/dist/components/SEOPanel.js +9 -9
- package/dist/components/SEOPerformance.js +2 -2
- package/dist/components/SchedulePublishDialog.js +1 -1
- package/dist/components/SharePreviewLinkDialog.js +1 -1
- package/dist/components/TipTapEditor.js +5 -5
- package/dist/components/VersionHistory.js +2 -2
- package/dist/components/ui/Badge.d.ts +33 -3
- package/dist/components/ui/Badge.d.ts.map +1 -1
- package/dist/components/ui/Badge.js +42 -8
- package/dist/components/ui/Badge.js.map +1 -1
- package/dist/components/ui/Button.d.ts +19 -8
- package/dist/components/ui/Button.d.ts.map +1 -1
- package/dist/components/ui/Button.js +35 -14
- package/dist/components/ui/Button.js.map +1 -1
- package/dist/components/ui/Card.d.ts +26 -0
- package/dist/components/ui/Card.d.ts.map +1 -0
- package/dist/components/ui/Card.js +45 -0
- package/dist/components/ui/Card.js.map +1 -0
- package/dist/components/ui/DataTable.js +1 -1
- package/dist/components/ui/Input.d.ts +15 -0
- package/dist/components/ui/Input.d.ts.map +1 -0
- package/dist/components/ui/Input.js +23 -0
- package/dist/components/ui/Input.js.map +1 -0
- package/dist/components/ui/SearchInput.js +1 -1
- package/dist/components/ui/Select.d.ts +16 -0
- package/dist/components/ui/Select.d.ts.map +1 -0
- package/dist/components/ui/Select.js +25 -0
- package/dist/components/ui/Select.js.map +1 -0
- package/dist/components/ui/Toast.js +1 -1
- package/dist/components/ui/index.d.ts +10 -4
- package/dist/components/ui/index.d.ts.map +1 -1
- package/dist/components/ui/index.js +5 -2
- package/dist/components/ui/index.js.map +1 -1
- package/dist/fields/BlockBuilderField.js +3 -3
- package/dist/fields/DateField.js +1 -1
- package/dist/fields/RelationshipField.js +3 -3
- package/dist/fields/TextField.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/layout/Header.js +1 -1
- package/dist/layout/Layout.d.ts +14 -0
- package/dist/layout/Layout.d.ts.map +1 -1
- package/dist/layout/Layout.js +17 -11
- package/dist/layout/Layout.js.map +1 -1
- package/dist/layout/Sidebar.d.ts.map +1 -1
- package/dist/layout/Sidebar.js +21 -11
- package/dist/layout/Sidebar.js.map +1 -1
- package/dist/layout/primitives/AdminShell.d.ts +43 -0
- package/dist/layout/primitives/AdminShell.d.ts.map +1 -0
- package/dist/layout/primitives/AdminShell.js +51 -0
- package/dist/layout/primitives/AdminShell.js.map +1 -0
- package/dist/layout/primitives/Box.d.ts +19 -0
- package/dist/layout/primitives/Box.d.ts.map +1 -0
- package/dist/layout/primitives/Box.js +12 -0
- package/dist/layout/primitives/Box.js.map +1 -0
- package/dist/layout/primitives/Cluster.d.ts +27 -0
- package/dist/layout/primitives/Cluster.d.ts.map +1 -0
- package/dist/layout/primitives/Cluster.js +37 -0
- package/dist/layout/primitives/Cluster.js.map +1 -0
- package/dist/layout/primitives/Grid.d.ts +45 -0
- package/dist/layout/primitives/Grid.d.ts.map +1 -0
- package/dist/layout/primitives/Grid.js +59 -0
- package/dist/layout/primitives/Grid.js.map +1 -0
- package/dist/layout/primitives/PageContainer.d.ts +36 -0
- package/dist/layout/primitives/PageContainer.d.ts.map +1 -0
- package/dist/layout/primitives/PageContainer.js +41 -0
- package/dist/layout/primitives/PageContainer.js.map +1 -0
- package/dist/layout/primitives/Split.d.ts +34 -0
- package/dist/layout/primitives/Split.d.ts.map +1 -0
- package/dist/layout/primitives/Split.js +27 -0
- package/dist/layout/primitives/Split.js.map +1 -0
- package/dist/layout/primitives/Stack.d.ts +23 -0
- package/dist/layout/primitives/Stack.d.ts.map +1 -0
- package/dist/layout/primitives/Stack.js +34 -0
- package/dist/layout/primitives/Stack.js.map +1 -0
- package/dist/layout/primitives/index.d.ts +30 -0
- package/dist/layout/primitives/index.d.ts.map +1 -0
- package/dist/layout/primitives/index.js +22 -0
- package/dist/layout/primitives/index.js.map +1 -0
- package/dist/layout/primitives/tokens.d.ts +48 -0
- package/dist/layout/primitives/tokens.d.ts.map +1 -0
- package/dist/layout/primitives/tokens.js +54 -0
- package/dist/layout/primitives/tokens.js.map +1 -0
- package/dist/lib/cv.d.ts +53 -0
- package/dist/lib/cv.d.ts.map +1 -0
- package/dist/lib/cv.js +39 -0
- package/dist/lib/cv.js.map +1 -0
- package/dist/views/ApiKeys.js +7 -7
- package/dist/views/CollectionList.js +8 -8
- package/dist/views/Dashboard.d.ts.map +1 -1
- package/dist/views/Dashboard.js +333 -78
- package/dist/views/Dashboard.js.map +1 -1
- package/dist/views/DocumentEdit.js +3 -3
- package/dist/views/ForgotPassword.js +2 -2
- package/dist/views/FormEditor.js +5 -5
- package/dist/views/FormSubmissions.js +6 -6
- package/dist/views/Forms.js +2 -2
- package/dist/views/Login.d.ts +16 -1
- package/dist/views/Login.d.ts.map +1 -1
- package/dist/views/Login.js +17 -7
- package/dist/views/Login.js.map +1 -1
- package/dist/views/MediaBrowser.js +16 -16
- package/dist/views/PageEditor.js +2 -2
- package/dist/views/Pages.js +10 -10
- package/dist/views/PostEditor.js +2 -2
- package/dist/views/Posts.js +4 -4
- package/dist/views/Redirects.js +4 -4
- package/dist/views/ResetPassword.js +2 -2
- package/dist/views/SEO.js +6 -6
- package/dist/views/ScriptTagEditor.js +4 -4
- package/dist/views/ScriptTags.js +2 -2
- package/dist/views/Settings.d.ts.map +1 -1
- package/dist/views/Settings.js +9 -8
- package/dist/views/Settings.js.map +1 -1
- package/dist/views/SetupWizard.js +2 -2
- package/dist/views/Users.js +4 -4
- package/dist/views/page-builder/AIBlockAssist.js +1 -1
- package/dist/views/page-builder/AIGenerateDialog.js +10 -10
- package/dist/views/page-builder/BlockEditor.js +10 -10
- package/dist/views/page-builder/BlockPicker.js +4 -4
- package/dist/views/page-builder/BottomBar.js +1 -1
- package/dist/views/page-builder/BuilderToolbar.js +2 -2
- package/dist/views/page-builder/ContextPanel.js +2 -2
- package/dist/views/page-builder/DesignScore.js +9 -9
- package/dist/views/page-builder/NodeSettings.js +8 -8
- package/dist/views/page-builder/PageBuilder.js +3 -3
- package/dist/views/page-builder/PageSettings.js +1 -1
- package/dist/views/page-builder/PageTemplates.js +2 -2
- package/dist/views/page-builder/SEOPanel.js +13 -13
- package/dist/views/page-builder/SavedSections.js +5 -5
- package/dist/views/page-builder/TemplatePicker.js +2 -2
- package/dist/views/page-builder/block-renderers/CTAPreview.js +5 -5
- package/dist/views/page-builder/block-renderers/CardsPreview.js +1 -1
- package/dist/views/page-builder/block-renderers/CodePreview.js +1 -1
- package/dist/views/page-builder/block-renderers/FAQPreview.js +3 -3
- package/dist/views/page-builder/block-renderers/FallbackPreview.js +1 -1
- package/dist/views/page-builder/block-renderers/FormPreview.js +3 -3
- package/dist/views/page-builder/block-renderers/GalleryPreview.js +5 -5
- package/dist/views/page-builder/block-renderers/HeroPreview.js +3 -3
- package/dist/views/page-builder/block-renderers/ImagePreview.js +3 -3
- package/dist/views/page-builder/block-renderers/TextPreview.js +3 -3
- package/dist/views/page-builder/block-renderers/VideoPreview.js +4 -4
- package/dist/views/page-builder/canvas/BlockRenderer.js +1 -1
- package/dist/views/page-builder/canvas/BuilderCanvas.js +3 -3
- package/dist/views/page-builder/canvas/ColumnRenderer.js +2 -2
- package/dist/views/page-builder/canvas/ContainerRenderer.js +2 -2
- package/dist/views/page-builder/canvas/RowRenderer.js +2 -2
- package/dist/views/page-builder/canvas/SectionRenderer.js +2 -2
- package/package.json +6 -2
- package/src/AdminRoot.tsx +21 -11
- package/src/__tests__/layout/primitives.test.ts +37 -0
- package/src/__tests__/lib/cv.test.ts +74 -0
- package/src/assets/actuate-logo.tsx +72 -0
- package/src/components/Breadcrumbs.tsx +6 -6
- package/src/components/CommandPalette.tsx +34 -34
- package/src/components/ContentOverviewChart.tsx +3 -3
- package/src/components/ErrorBoundary.tsx +3 -3
- package/src/components/FocalPointPicker.tsx +4 -4
- package/src/components/FolderTree.tsx +38 -38
- package/src/components/LivePreview.tsx +16 -16
- package/src/components/LocaleSwitcher.tsx +7 -7
- package/src/components/MediaPickerModal.tsx +21 -21
- package/src/components/PresenceIndicator.tsx +2 -2
- package/src/components/SEOConfigPanel.tsx +582 -0
- package/src/components/SEOPanel.tsx +46 -46
- package/src/components/SEOPerformance.tsx +21 -21
- package/src/components/SchedulePublishDialog.tsx +4 -4
- package/src/components/SharePreviewLinkDialog.tsx +1 -1
- package/src/components/TipTapEditor.tsx +33 -33
- package/src/components/VersionHistory.tsx +16 -16
- package/src/components/ui/Badge.tsx +66 -14
- package/src/components/ui/Button.tsx +70 -33
- package/src/components/ui/Card.tsx +101 -0
- package/src/components/ui/DataTable.tsx +1 -1
- package/src/components/ui/Input.tsx +35 -0
- package/src/components/ui/SearchInput.tsx +4 -4
- package/src/components/ui/Select.tsx +56 -0
- package/src/components/ui/Toast.tsx +1 -1
- package/src/components/ui/index.ts +18 -4
- package/src/fields/BlockBuilderField.tsx +3 -3
- package/src/fields/DateField.tsx +1 -1
- package/src/fields/RelationshipField.tsx +10 -10
- package/src/fields/TextField.tsx +1 -1
- package/src/index.ts +28 -0
- package/src/layout/Header.tsx +28 -28
- package/src/layout/Layout.tsx +39 -46
- package/src/layout/Sidebar.tsx +37 -64
- package/src/layout/primitives/AdminShell.tsx +118 -0
- package/src/layout/primitives/Box.tsx +30 -0
- package/src/layout/primitives/Cluster.tsx +74 -0
- package/src/layout/primitives/Grid.tsx +120 -0
- package/src/layout/primitives/PageContainer.tsx +96 -0
- package/src/layout/primitives/Split.tsx +73 -0
- package/src/layout/primitives/Stack.tsx +67 -0
- package/src/layout/primitives/index.ts +36 -0
- package/src/layout/primitives/tokens.ts +76 -0
- package/src/lib/cv.ts +96 -0
- package/src/styles/build-input.css +1 -1
- package/src/views/ApiKeys.tsx +57 -57
- package/src/views/CollectionList.tsx +30 -30
- package/src/views/Dashboard.tsx +737 -186
- package/src/views/DocumentEdit.tsx +9 -9
- package/src/views/ForgotPassword.tsx +18 -18
- package/src/views/FormEditor.tsx +75 -75
- package/src/views/FormSubmissions.tsx +76 -76
- package/src/views/Forms.tsx +27 -27
- package/src/views/Login.tsx +65 -25
- package/src/views/MediaBrowser.tsx +127 -127
- package/src/views/PageEditor.tsx +25 -25
- package/src/views/Pages.tsx +59 -59
- package/src/views/PostEditor.tsx +37 -37
- package/src/views/Posts.tsx +48 -48
- package/src/views/Redirects.tsx +21 -21
- package/src/views/ResetPassword.tsx +28 -28
- package/src/views/SEO.tsx +144 -144
- package/src/views/ScriptTagEditor.tsx +24 -24
- package/src/views/ScriptTags.tsx +10 -10
- package/src/views/Settings.tsx +88 -80
- package/src/views/SetupWizard.tsx +28 -28
- package/src/views/Users.tsx +20 -20
- package/src/views/page-builder/AIBlockAssist.tsx +1 -1
- package/src/views/page-builder/AIGenerateDialog.tsx +63 -63
- package/src/views/page-builder/BlockEditor.tsx +26 -26
- package/src/views/page-builder/BlockPicker.tsx +22 -22
- package/src/views/page-builder/BottomBar.tsx +8 -8
- package/src/views/page-builder/BuilderToolbar.tsx +17 -17
- package/src/views/page-builder/ContextPanel.tsx +3 -3
- package/src/views/page-builder/DesignScore.tsx +21 -21
- package/src/views/page-builder/NodeSettings.tsx +27 -27
- package/src/views/page-builder/PageBuilder.tsx +11 -11
- package/src/views/page-builder/PageSettings.tsx +4 -4
- package/src/views/page-builder/PageTemplates.tsx +18 -18
- package/src/views/page-builder/SEOPanel.tsx +53 -53
- package/src/views/page-builder/SavedSections.tsx +37 -37
- package/src/views/page-builder/TemplatePicker.tsx +17 -17
- package/src/views/page-builder/block-renderers/CTAPreview.tsx +13 -13
- package/src/views/page-builder/block-renderers/CardsPreview.tsx +5 -5
- package/src/views/page-builder/block-renderers/CodePreview.tsx +6 -6
- package/src/views/page-builder/block-renderers/FAQPreview.tsx +13 -13
- package/src/views/page-builder/block-renderers/FallbackPreview.tsx +3 -3
- package/src/views/page-builder/block-renderers/FormPreview.tsx +20 -20
- package/src/views/page-builder/block-renderers/GalleryPreview.tsx +8 -8
- package/src/views/page-builder/block-renderers/HeroPreview.tsx +16 -16
- package/src/views/page-builder/block-renderers/ImagePreview.tsx +4 -4
- package/src/views/page-builder/block-renderers/TextPreview.tsx +14 -14
- package/src/views/page-builder/block-renderers/VideoPreview.tsx +12 -12
- package/src/views/page-builder/canvas/BlockRenderer.tsx +4 -4
- package/src/views/page-builder/canvas/BuilderCanvas.tsx +6 -6
- package/src/views/page-builder/canvas/ColumnRenderer.tsx +3 -3
- package/src/views/page-builder/canvas/ContainerRenderer.tsx +2 -2
- package/src/views/page-builder/canvas/RowRenderer.tsx +2 -2
- package/src/views/page-builder/canvas/SectionRenderer.tsx +2 -2
package/src/views/PageEditor.tsx
CHANGED
|
@@ -81,18 +81,18 @@ export function PageEditor({ id, onNavigate }: PageEditorProps) {
|
|
|
81
81
|
|
|
82
82
|
if (!isNew && loading) {
|
|
83
83
|
return (
|
|
84
|
-
<div className="h-full
|
|
85
|
-
<Loader2 className="
|
|
84
|
+
<div className="flex h-full items-center justify-center">
|
|
85
|
+
<Loader2 className="h-6 w-6 animate-spin text-blue-600" />
|
|
86
86
|
</div>
|
|
87
87
|
)
|
|
88
88
|
}
|
|
89
89
|
|
|
90
90
|
return (
|
|
91
|
-
<div className="h-full flex
|
|
91
|
+
<div className="flex h-full flex-col bg-white">
|
|
92
92
|
{error && (
|
|
93
93
|
<div className="mx-4 mt-3 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
|
|
94
|
-
<AlertTriangle className="
|
|
95
|
-
<span className="text-sm text-red-800
|
|
94
|
+
<AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
|
|
95
|
+
<span className="flex-1 text-sm text-red-800">{error}</span>
|
|
96
96
|
</div>
|
|
97
97
|
)}
|
|
98
98
|
|
|
@@ -100,63 +100,63 @@ export function PageEditor({ id, onNavigate }: PageEditorProps) {
|
|
|
100
100
|
<div className="flex items-center justify-between">
|
|
101
101
|
<button
|
|
102
102
|
onClick={() => onNavigate?.('/pages')}
|
|
103
|
-
className="inline-flex items-center gap-2 text-sm text-gray-600 hover:text-gray-900
|
|
103
|
+
className="inline-flex items-center gap-2 text-sm text-gray-600 transition-colors hover:text-gray-900"
|
|
104
104
|
>
|
|
105
|
-
<ArrowLeft className="
|
|
105
|
+
<ArrowLeft className="h-4 w-4" />
|
|
106
106
|
Back to Pages
|
|
107
107
|
</button>
|
|
108
108
|
<div className="flex items-center gap-3">
|
|
109
|
-
<button className="
|
|
110
|
-
<Eye className="
|
|
109
|
+
<button className="flex items-center gap-2 rounded-lg border border-gray-300 px-3 py-1.5 text-sm transition-colors hover:bg-gray-50">
|
|
110
|
+
<Eye className="h-4 w-4" />
|
|
111
111
|
Preview
|
|
112
112
|
</button>
|
|
113
113
|
</div>
|
|
114
114
|
</div>
|
|
115
115
|
</div>
|
|
116
116
|
|
|
117
|
-
<div className="flex-1 overflow-hidden
|
|
117
|
+
<div className="flex flex-1 overflow-hidden">
|
|
118
118
|
<div className="flex-1 overflow-y-auto">
|
|
119
|
-
<div className="max-w-4xl
|
|
119
|
+
<div className="mx-auto max-w-4xl p-3 pr-6 sm:p-4 sm:pr-8">
|
|
120
120
|
<input
|
|
121
121
|
type="text"
|
|
122
122
|
value={title}
|
|
123
123
|
onChange={(e) => setTitle(e.target.value)}
|
|
124
124
|
placeholder="Page title"
|
|
125
|
-
className="w-full
|
|
125
|
+
className="mb-4 w-full border-none px-0 text-2xl font-bold placeholder:text-gray-300 focus:ring-0 focus:outline-none sm:text-3xl"
|
|
126
126
|
/>
|
|
127
127
|
|
|
128
128
|
<div className="mb-4">
|
|
129
|
-
<label className="block text-xs font-medium text-gray-600
|
|
129
|
+
<label className="mb-1 block text-xs font-medium text-gray-600">URL Slug</label>
|
|
130
130
|
<input
|
|
131
131
|
type="text"
|
|
132
132
|
value={slug}
|
|
133
133
|
onChange={(e) => setSlug(e.target.value)}
|
|
134
134
|
placeholder="url-slug"
|
|
135
|
-
className="w-full px-3 py-1.5 text-sm
|
|
135
|
+
className="w-full rounded-lg border border-gray-300 px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
|
136
136
|
/>
|
|
137
137
|
</div>
|
|
138
138
|
|
|
139
|
-
<div className="border-2 border-dashed border-gray-300
|
|
140
|
-
<p className="text-gray-500
|
|
139
|
+
<div className="rounded-lg border-2 border-dashed border-gray-300 p-8 text-center">
|
|
140
|
+
<p className="mb-2 text-gray-500">No blocks added yet</p>
|
|
141
141
|
<p className="text-sm text-gray-400">Click "Add Block" to start building your page</p>
|
|
142
|
-
<button className="mt-4 px-4 py-2 text-sm
|
|
142
|
+
<button className="mt-4 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700">
|
|
143
143
|
Add Block
|
|
144
144
|
</button>
|
|
145
145
|
</div>
|
|
146
146
|
</div>
|
|
147
147
|
</div>
|
|
148
148
|
|
|
149
|
-
<div className="w-[30%] border-l border-gray-200
|
|
150
|
-
<div className="
|
|
151
|
-
<div className="
|
|
152
|
-
<h3 className="font-semibold text-gray-900
|
|
149
|
+
<div className="w-[30%] overflow-y-auto border-l border-gray-200 bg-gray-50">
|
|
150
|
+
<div className="space-y-4 p-4">
|
|
151
|
+
<div className="rounded-lg border border-gray-200 bg-white p-4">
|
|
152
|
+
<h3 className="mb-3 text-sm font-semibold text-gray-900">Publish</h3>
|
|
153
153
|
<div className="space-y-3">
|
|
154
154
|
<div>
|
|
155
|
-
<label className="block text-xs font-medium text-gray-700
|
|
155
|
+
<label className="mb-1 block text-xs font-medium text-gray-700">Status</label>
|
|
156
156
|
<select
|
|
157
157
|
value={status}
|
|
158
158
|
onChange={(e) => setStatus(e.target.value as 'draft' | 'published')}
|
|
159
|
-
className="w-full px-3 py-1.5 text-sm
|
|
159
|
+
className="w-full rounded-lg border border-gray-300 px-3 py-1.5 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
|
160
160
|
>
|
|
161
161
|
<option value="draft">Draft</option>
|
|
162
162
|
<option value="published">Published</option>
|
|
@@ -165,7 +165,7 @@ export function PageEditor({ id, onNavigate }: PageEditorProps) {
|
|
|
165
165
|
<button
|
|
166
166
|
onClick={savePage}
|
|
167
167
|
disabled={saving}
|
|
168
|
-
className="w-full
|
|
168
|
+
className="w-full rounded-lg bg-blue-600 py-2 text-sm font-medium text-white transition-colors hover:bg-blue-700 disabled:opacity-50"
|
|
169
169
|
>
|
|
170
170
|
{saving ? 'Saving...' : 'Save Page'}
|
|
171
171
|
</button>
|
|
@@ -173,7 +173,7 @@ export function PageEditor({ id, onNavigate }: PageEditorProps) {
|
|
|
173
173
|
<button
|
|
174
174
|
onClick={publishPage}
|
|
175
175
|
disabled={saving}
|
|
176
|
-
className="w-full
|
|
176
|
+
className="w-full rounded-lg bg-green-600 py-2 text-sm font-medium text-white transition-colors hover:bg-green-700 disabled:opacity-50"
|
|
177
177
|
>
|
|
178
178
|
{saving ? 'Publishing...' : 'Publish'}
|
|
179
179
|
</button>
|
package/src/views/Pages.tsx
CHANGED
|
@@ -73,7 +73,7 @@ function SeoScoreBadge({ score }: { score: number }) {
|
|
|
73
73
|
const color = score >= 80 ? 'bg-green-500' : score >= 60 ? 'bg-amber-500' : 'bg-red-500'
|
|
74
74
|
return (
|
|
75
75
|
<div className="flex items-center gap-1.5">
|
|
76
|
-
<span className={`
|
|
76
|
+
<span className={`h-2.5 w-2.5 rounded-full ${color}`} />
|
|
77
77
|
<span className="text-xs text-gray-600">{score}</span>
|
|
78
78
|
</div>
|
|
79
79
|
)
|
|
@@ -83,7 +83,7 @@ function FolderBadge({ name }: { name: string }) {
|
|
|
83
83
|
const colors = getFolderColor(name)
|
|
84
84
|
return (
|
|
85
85
|
<span
|
|
86
|
-
className={`inline-flex px-2 py-0.5
|
|
86
|
+
className={`inline-flex rounded px-2 py-0.5 text-xs font-medium ${colors.bg} ${colors.text}`}
|
|
87
87
|
>
|
|
88
88
|
{name}
|
|
89
89
|
</span>
|
|
@@ -229,17 +229,17 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
229
229
|
<button
|
|
230
230
|
type="button"
|
|
231
231
|
onClick={() => setSortConfig(toggleSort(sortConfig, sortKey))}
|
|
232
|
-
className="flex items-center gap-1 text-xs font-medium text-gray-700 hover:text-gray-900
|
|
232
|
+
className="flex items-center gap-1 text-xs font-medium text-gray-700 transition-colors hover:text-gray-900"
|
|
233
233
|
>
|
|
234
234
|
{label}
|
|
235
235
|
{active ? (
|
|
236
236
|
sortConfig!.direction === 'asc' ? (
|
|
237
|
-
<ArrowUp className="
|
|
237
|
+
<ArrowUp className="h-3 w-3" />
|
|
238
238
|
) : (
|
|
239
|
-
<ArrowDown className="
|
|
239
|
+
<ArrowDown className="h-3 w-3" />
|
|
240
240
|
)
|
|
241
241
|
) : (
|
|
242
|
-
<ArrowUpDown className="
|
|
242
|
+
<ArrowUpDown className="h-3 w-3 text-gray-400" />
|
|
243
243
|
)}
|
|
244
244
|
</button>
|
|
245
245
|
)
|
|
@@ -247,39 +247,39 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
247
247
|
|
|
248
248
|
if (loading) {
|
|
249
249
|
return (
|
|
250
|
-
<div className="p-3 pr-6 sm:p-4 sm:pr-8
|
|
251
|
-
<Loader2 className="
|
|
250
|
+
<div className="flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8">
|
|
251
|
+
<Loader2 className="h-6 w-6 animate-spin text-blue-600" />
|
|
252
252
|
</div>
|
|
253
253
|
)
|
|
254
254
|
}
|
|
255
255
|
|
|
256
256
|
return (
|
|
257
|
-
<div className="p-3 pr-6 sm:p-4 sm:pr-8
|
|
257
|
+
<div className="flex h-full flex-col p-3 pr-6 sm:p-4 sm:pr-8">
|
|
258
258
|
{error && (
|
|
259
259
|
<div className="mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3">
|
|
260
|
-
<AlertTriangle className="
|
|
261
|
-
<span className="text-sm text-red-800
|
|
260
|
+
<AlertTriangle className="h-5 w-5 shrink-0 text-red-600" />
|
|
261
|
+
<span className="flex-1 text-sm text-red-800">{error}</span>
|
|
262
262
|
<button
|
|
263
263
|
onClick={refetch}
|
|
264
|
-
className="px-3 py-1 text-sm text-red-700
|
|
264
|
+
className="rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100"
|
|
265
265
|
>
|
|
266
266
|
Retry
|
|
267
267
|
</button>
|
|
268
268
|
</div>
|
|
269
269
|
)}
|
|
270
270
|
|
|
271
|
-
<div className="flex flex-col sm:flex-row sm:items-center
|
|
271
|
+
<div className="mb-4 flex flex-col justify-between gap-3 sm:flex-row sm:items-center">
|
|
272
272
|
<div className="flex items-center gap-3">
|
|
273
273
|
<button
|
|
274
274
|
type="button"
|
|
275
275
|
onClick={() => setSidebarOpen((prev) => !prev)}
|
|
276
|
-
className="p-1.5
|
|
276
|
+
className="rounded-lg p-1.5 transition-colors hover:bg-gray-100"
|
|
277
277
|
title={sidebarOpen ? 'Hide folders' : 'Show folders'}
|
|
278
278
|
>
|
|
279
|
-
<FolderInput className="
|
|
279
|
+
<FolderInput className="h-5 w-5 text-gray-600" />
|
|
280
280
|
</button>
|
|
281
281
|
<div>
|
|
282
|
-
<h1 className="text-xl
|
|
282
|
+
<h1 className="text-xl font-semibold text-gray-900 sm:text-2xl">Pages</h1>
|
|
283
283
|
<p className="text-sm text-gray-500">
|
|
284
284
|
{totalCount} page{totalCount !== 1 ? 's' : ''}
|
|
285
285
|
</p>
|
|
@@ -287,17 +287,17 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
287
287
|
</div>
|
|
288
288
|
<button
|
|
289
289
|
onClick={() => onNavigate?.('/pages/new')}
|
|
290
|
-
className="flex items-center justify-center gap-2 px-4 py-2
|
|
290
|
+
className="flex items-center justify-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700"
|
|
291
291
|
>
|
|
292
|
-
<Plus className="
|
|
292
|
+
<Plus className="h-4 w-4" />
|
|
293
293
|
<span className="hidden sm:inline">New Page</span>
|
|
294
294
|
<span className="sm:hidden">New</span>
|
|
295
295
|
</button>
|
|
296
296
|
</div>
|
|
297
297
|
|
|
298
|
-
<div className="flex
|
|
298
|
+
<div className="flex min-h-0 flex-1 gap-4 overflow-hidden">
|
|
299
299
|
{sidebarOpen && (
|
|
300
|
-
<div className="w-56 shrink-0
|
|
300
|
+
<div className="flex w-56 shrink-0 flex-col overflow-hidden rounded-lg border border-gray-200 bg-white">
|
|
301
301
|
<FolderTree
|
|
302
302
|
scope="pages"
|
|
303
303
|
selected={folderSel}
|
|
@@ -312,24 +312,24 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
312
312
|
</div>
|
|
313
313
|
)}
|
|
314
314
|
|
|
315
|
-
<div className="flex-
|
|
316
|
-
<div className="
|
|
317
|
-
<div className="
|
|
315
|
+
<div className="flex min-w-0 flex-1 flex-col">
|
|
316
|
+
<div className="mb-4 rounded-lg border border-gray-200 bg-white">
|
|
317
|
+
<div className="flex flex-col gap-3 p-3">
|
|
318
318
|
<div className="relative">
|
|
319
|
-
<Search className="absolute
|
|
319
|
+
<Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
|
|
320
320
|
<input
|
|
321
321
|
type="text"
|
|
322
322
|
placeholder="Search pages..."
|
|
323
323
|
value={searchQuery}
|
|
324
324
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
325
|
-
className="w-full
|
|
325
|
+
className="w-full rounded-lg border border-gray-300 py-2 pr-3 pl-9 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
|
326
326
|
/>
|
|
327
327
|
</div>
|
|
328
|
-
<div className="flex flex-col sm:flex-row
|
|
328
|
+
<div className="flex flex-col gap-2 sm:flex-row">
|
|
329
329
|
<select
|
|
330
330
|
value={filterStatus}
|
|
331
331
|
onChange={(e) => setFilterStatus(e.target.value)}
|
|
332
|
-
className="flex-1
|
|
332
|
+
className="flex-1 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
|
333
333
|
>
|
|
334
334
|
<option value="all">All Status</option>
|
|
335
335
|
<option value="published">Published</option>
|
|
@@ -338,7 +338,7 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
338
338
|
<select
|
|
339
339
|
value={filterTemplate}
|
|
340
340
|
onChange={(e) => setFilterTemplate(e.target.value)}
|
|
341
|
-
className="flex-1
|
|
341
|
+
className="flex-1 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none"
|
|
342
342
|
>
|
|
343
343
|
<option value="all">All Templates</option>
|
|
344
344
|
<option value="landing">Landing</option>
|
|
@@ -348,9 +348,9 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
348
348
|
</select>
|
|
349
349
|
<button
|
|
350
350
|
type="button"
|
|
351
|
-
className="flex items-center justify-center gap-2 px-3 py-2 text-sm
|
|
351
|
+
className="flex items-center justify-center gap-2 rounded-lg border border-gray-300 px-3 py-2 text-sm transition-colors hover:bg-gray-50"
|
|
352
352
|
>
|
|
353
|
-
<SlidersHorizontal className="
|
|
353
|
+
<SlidersHorizontal className="h-4 w-4" />
|
|
354
354
|
<span className="hidden sm:inline">More Filters</span>
|
|
355
355
|
</button>
|
|
356
356
|
</div>
|
|
@@ -358,8 +358,8 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
358
358
|
</div>
|
|
359
359
|
|
|
360
360
|
{selectedPages.length > 0 && (
|
|
361
|
-
<div className="
|
|
362
|
-
<div className="flex flex-col sm:flex-row sm:items-center
|
|
361
|
+
<div className="mb-4 rounded-lg border border-blue-200 bg-blue-50 p-3">
|
|
362
|
+
<div className="flex flex-col justify-between gap-2 sm:flex-row sm:items-center">
|
|
363
363
|
<span className="text-sm text-blue-900">
|
|
364
364
|
{selectedPages.length} page{selectedPages.length !== 1 ? 's' : ''} selected
|
|
365
365
|
</span>
|
|
@@ -367,28 +367,28 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
367
367
|
<button
|
|
368
368
|
type="button"
|
|
369
369
|
onClick={handleBulkPublish}
|
|
370
|
-
className="flex-1
|
|
370
|
+
className="flex-1 rounded-lg bg-green-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-green-700 sm:flex-none"
|
|
371
371
|
>
|
|
372
372
|
Publish
|
|
373
373
|
</button>
|
|
374
374
|
<button
|
|
375
375
|
type="button"
|
|
376
376
|
onClick={handleBulkUnpublish}
|
|
377
|
-
className="flex-1
|
|
377
|
+
className="flex-1 rounded-lg bg-yellow-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-yellow-700 sm:flex-none"
|
|
378
378
|
>
|
|
379
379
|
Unpublish
|
|
380
380
|
</button>
|
|
381
381
|
<button
|
|
382
382
|
type="button"
|
|
383
383
|
onClick={handleBulkDelete}
|
|
384
|
-
className="flex-1
|
|
384
|
+
className="flex-1 rounded-lg bg-red-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-red-700 sm:flex-none"
|
|
385
385
|
>
|
|
386
386
|
Delete
|
|
387
387
|
</button>
|
|
388
388
|
<button
|
|
389
389
|
type="button"
|
|
390
390
|
onClick={() => setSelectedPages([])}
|
|
391
|
-
className="flex-1
|
|
391
|
+
className="flex-1 rounded-lg border border-gray-300 bg-white px-3 py-1.5 text-sm transition-colors hover:bg-gray-50 sm:flex-none"
|
|
392
392
|
>
|
|
393
393
|
Cancel
|
|
394
394
|
</button>
|
|
@@ -398,8 +398,8 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
398
398
|
)}
|
|
399
399
|
|
|
400
400
|
{filteredAndSorted.length === 0 && !error ? (
|
|
401
|
-
<div className="
|
|
402
|
-
<p className="text-sm text-gray-500
|
|
401
|
+
<div className="flex flex-1 flex-col items-center justify-center rounded-lg border border-gray-200 bg-white p-8 text-center">
|
|
402
|
+
<p className="mb-2 text-sm text-gray-500">
|
|
403
403
|
{folderSel.type === 'smart' && folderSel.smart === 'uncategorized'
|
|
404
404
|
? 'No uncategorized pages'
|
|
405
405
|
: folderSel.type === 'folder'
|
|
@@ -408,17 +408,17 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
408
408
|
</p>
|
|
409
409
|
<button
|
|
410
410
|
onClick={() => onNavigate?.('/pages/new')}
|
|
411
|
-
className="px-4 py-2 text-sm
|
|
411
|
+
className="rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700"
|
|
412
412
|
>
|
|
413
413
|
Create your first page
|
|
414
414
|
</button>
|
|
415
415
|
</div>
|
|
416
416
|
) : (
|
|
417
417
|
<>
|
|
418
|
-
<div className="hidden
|
|
419
|
-
<div className="overflow-x-auto
|
|
418
|
+
<div className="hidden flex-1 overflow-hidden rounded-lg border border-gray-200 bg-white md:block">
|
|
419
|
+
<div className="h-full overflow-x-auto">
|
|
420
420
|
<table className="w-full">
|
|
421
|
-
<thead className="
|
|
421
|
+
<thead className="sticky top-0 border-b border-gray-200 bg-gray-50">
|
|
422
422
|
<tr>
|
|
423
423
|
<th className="w-8 px-3 py-2 text-left">
|
|
424
424
|
<input
|
|
@@ -462,7 +462,7 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
462
462
|
return (
|
|
463
463
|
<tr
|
|
464
464
|
key={page.id}
|
|
465
|
-
className="hover:bg-gray-50
|
|
465
|
+
className="transition-colors hover:bg-gray-50"
|
|
466
466
|
draggable
|
|
467
467
|
onDragStart={(e) => handleDragStart(e, page.id)}
|
|
468
468
|
>
|
|
@@ -474,14 +474,14 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
474
474
|
className="rounded border-gray-300"
|
|
475
475
|
/>
|
|
476
476
|
</td>
|
|
477
|
-
<td className="px-1 py-2
|
|
478
|
-
<GripVertical className="
|
|
477
|
+
<td className="cursor-grab px-1 py-2">
|
|
478
|
+
<GripVertical className="h-4 w-4 text-gray-300" />
|
|
479
479
|
</td>
|
|
480
480
|
<td className="px-3 py-2">
|
|
481
481
|
<button
|
|
482
482
|
type="button"
|
|
483
483
|
onClick={() => onNavigate?.(`/pages/${page.id}`)}
|
|
484
|
-
className="font-medium text-gray-900 hover:text-blue-600
|
|
484
|
+
className="text-left text-sm font-medium text-gray-900 hover:text-blue-600"
|
|
485
485
|
>
|
|
486
486
|
{page.title}
|
|
487
487
|
</button>
|
|
@@ -499,7 +499,7 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
499
499
|
</td>
|
|
500
500
|
<td className="px-3 py-2">
|
|
501
501
|
<span
|
|
502
|
-
className={`inline-flex items-center px-2 py-0.5
|
|
502
|
+
className={`inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${page.status === 'Published' || page.status === 'PUBLISHED' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}
|
|
503
503
|
>
|
|
504
504
|
{page.status}
|
|
505
505
|
</span>
|
|
@@ -510,18 +510,18 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
510
510
|
<button
|
|
511
511
|
type="button"
|
|
512
512
|
onClick={() => onNavigate?.(`/pages/${page.id}`)}
|
|
513
|
-
className="p-1.5 hover:bg-gray-100
|
|
513
|
+
className="rounded p-1.5 transition-colors hover:bg-gray-100"
|
|
514
514
|
title="Edit"
|
|
515
515
|
>
|
|
516
|
-
<Pencil className="
|
|
516
|
+
<Pencil className="h-4 w-4 text-gray-600" />
|
|
517
517
|
</button>
|
|
518
518
|
<button
|
|
519
519
|
type="button"
|
|
520
520
|
onClick={() => handleDelete(page.id)}
|
|
521
|
-
className="p-1.5 hover:bg-gray-100
|
|
521
|
+
className="rounded p-1.5 transition-colors hover:bg-gray-100"
|
|
522
522
|
title="Delete"
|
|
523
523
|
>
|
|
524
|
-
<Trash2 className="
|
|
524
|
+
<Trash2 className="h-4 w-4 text-red-600" />
|
|
525
525
|
</button>
|
|
526
526
|
</div>
|
|
527
527
|
</td>
|
|
@@ -533,7 +533,7 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
533
533
|
</div>
|
|
534
534
|
</div>
|
|
535
535
|
|
|
536
|
-
<div className="
|
|
536
|
+
<div className="flex-1 overflow-auto rounded-lg border border-gray-200 bg-white md:hidden">
|
|
537
537
|
<div className="divide-y divide-gray-200">
|
|
538
538
|
{filteredAndSorted.map((page: any) => {
|
|
539
539
|
const seoScore = computeSeoScore(page.data)
|
|
@@ -550,24 +550,24 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
550
550
|
type="checkbox"
|
|
551
551
|
checked={selectedPages.includes(page.id)}
|
|
552
552
|
onChange={() => handleSelectPage(page.id)}
|
|
553
|
-
className="rounded border-gray-300
|
|
553
|
+
className="mt-1 rounded border-gray-300"
|
|
554
554
|
/>
|
|
555
|
-
<div className="
|
|
555
|
+
<div className="min-w-0 flex-1">
|
|
556
556
|
<button
|
|
557
557
|
type="button"
|
|
558
558
|
onClick={() => onNavigate?.(`/pages/${page.id}`)}
|
|
559
|
-
className="
|
|
559
|
+
className="mb-1 block text-left text-sm font-medium text-gray-900 hover:text-blue-600"
|
|
560
560
|
>
|
|
561
561
|
{page.title}
|
|
562
562
|
</button>
|
|
563
|
-
<div className="flex flex-wrap items-center gap-2 text-xs text-gray-600
|
|
563
|
+
<div className="mb-2 flex flex-wrap items-center gap-2 text-xs text-gray-600">
|
|
564
564
|
{folderName && <FolderBadge name={folderName} />}
|
|
565
565
|
<span>{page.author}</span>
|
|
566
566
|
<span>·</span>
|
|
567
567
|
<span>{page.date}</span>
|
|
568
568
|
<SeoScoreBadge score={seoScore} />
|
|
569
569
|
<span
|
|
570
|
-
className={`px-2 py-0.5
|
|
570
|
+
className={`rounded-full px-2 py-0.5 text-xs font-medium ${page.status === 'Published' || page.status === 'PUBLISHED' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`}
|
|
571
571
|
>
|
|
572
572
|
{page.status}
|
|
573
573
|
</span>
|
|
@@ -576,9 +576,9 @@ export function Pages({ onNavigate }: PagesProps) {
|
|
|
576
576
|
<button
|
|
577
577
|
type="button"
|
|
578
578
|
onClick={() => handleDelete(page.id)}
|
|
579
|
-
className="p-1.5 hover:bg-gray-100
|
|
579
|
+
className="rounded p-1.5 transition-colors hover:bg-gray-100"
|
|
580
580
|
>
|
|
581
|
-
<Trash2 className="
|
|
581
|
+
<Trash2 className="h-4 w-4 text-red-600" />
|
|
582
582
|
</button>
|
|
583
583
|
</div>
|
|
584
584
|
</div>
|