@actuate-media/cms-admin 0.9.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.d.ts +18 -0
- package/dist/components/SchedulePublishDialog.d.ts.map +1 -0
- package/dist/components/SchedulePublishDialog.js +106 -0
- package/dist/components/SchedulePublishDialog.js.map +1 -0
- package/dist/components/SharePreviewLinkDialog.d.ts +17 -0
- package/dist/components/SharePreviewLinkDialog.d.ts.map +1 -0
- package/dist/components/SharePreviewLinkDialog.js +83 -0
- package/dist/components/SharePreviewLinkDialog.js.map +1 -0
- 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 +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -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.d.ts.map +1 -1
- package/dist/views/ApiKeys.js +13 -11
- package/dist/views/ApiKeys.js.map +1 -1
- 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.d.ts.map +1 -1
- package/dist/views/DocumentEdit.js +17 -5
- package/dist/views/DocumentEdit.js.map +1 -1
- 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 +241 -0
- package/src/components/SharePreviewLinkDialog.tsx +227 -0
- 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 +32 -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 +90 -10
- 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
|
@@ -189,9 +189,9 @@ export function FolderTree({
|
|
|
189
189
|
return (
|
|
190
190
|
<div key={folder.id}>
|
|
191
191
|
<div
|
|
192
|
-
className={`group flex items-center gap-1 px-2 py-1.5
|
|
192
|
+
className={`group flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-sm transition-colors ${
|
|
193
193
|
isActive
|
|
194
|
-
? 'bg-blue-50 text-blue-700
|
|
194
|
+
? 'bg-blue-50 font-medium text-blue-700'
|
|
195
195
|
: isDragOver
|
|
196
196
|
? 'bg-blue-100 ring-2 ring-blue-300'
|
|
197
197
|
: 'text-gray-700 hover:bg-gray-100'
|
|
@@ -208,23 +208,23 @@ export function FolderTree({
|
|
|
208
208
|
>
|
|
209
209
|
<button
|
|
210
210
|
type="button"
|
|
211
|
-
className={`p-0.5
|
|
211
|
+
className={`rounded p-0.5 transition-colors hover:bg-gray-200 ${hasChildren ? '' : 'invisible'}`}
|
|
212
212
|
onClick={(e) => {
|
|
213
213
|
e.stopPropagation()
|
|
214
214
|
toggleExpand(folder.id)
|
|
215
215
|
}}
|
|
216
216
|
>
|
|
217
217
|
{isExpanded ? (
|
|
218
|
-
<ChevronDown className="
|
|
218
|
+
<ChevronDown className="h-3.5 w-3.5" />
|
|
219
219
|
) : (
|
|
220
|
-
<ChevronRight className="
|
|
220
|
+
<ChevronRight className="h-3.5 w-3.5" />
|
|
221
221
|
)}
|
|
222
222
|
</button>
|
|
223
223
|
|
|
224
224
|
{isExpanded ? (
|
|
225
|
-
<FolderOpen className="
|
|
225
|
+
<FolderOpen className="h-4 w-4 shrink-0 text-blue-500" />
|
|
226
226
|
) : (
|
|
227
|
-
<FolderIcon className="
|
|
227
|
+
<FolderIcon className="h-4 w-4 shrink-0 text-gray-400" />
|
|
228
228
|
)}
|
|
229
229
|
|
|
230
230
|
{editingId === folder.id ? (
|
|
@@ -238,11 +238,11 @@ export function FolderTree({
|
|
|
238
238
|
if (e.key === 'Enter') handleRename(folder.id)
|
|
239
239
|
if (e.key === 'Escape') setEditingId(null)
|
|
240
240
|
}}
|
|
241
|
-
className="
|
|
241
|
+
className="min-w-0 flex-1 rounded border border-blue-300 px-1 py-0 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none"
|
|
242
242
|
onClick={(e) => e.stopPropagation()}
|
|
243
243
|
/>
|
|
244
244
|
) : (
|
|
245
|
-
<span className="
|
|
245
|
+
<span className="min-w-0 flex-1 truncate">{folder.name}</span>
|
|
246
246
|
)}
|
|
247
247
|
|
|
248
248
|
{count !== undefined && !editingId && (
|
|
@@ -251,13 +251,13 @@ export function FolderTree({
|
|
|
251
251
|
|
|
252
252
|
<button
|
|
253
253
|
type="button"
|
|
254
|
-
className="p-0.5
|
|
254
|
+
className="rounded p-0.5 opacity-0 transition-all group-hover:opacity-100 hover:bg-gray-200"
|
|
255
255
|
onClick={(e) => {
|
|
256
256
|
e.stopPropagation()
|
|
257
257
|
setContextMenu({ id: folder.id, x: e.clientX, y: e.clientY })
|
|
258
258
|
}}
|
|
259
259
|
>
|
|
260
|
-
<MoreHorizontal className="
|
|
260
|
+
<MoreHorizontal className="h-3.5 w-3.5 text-gray-500" />
|
|
261
261
|
</button>
|
|
262
262
|
</div>
|
|
263
263
|
|
|
@@ -269,7 +269,7 @@ export function FolderTree({
|
|
|
269
269
|
className="flex items-center gap-1 px-2 py-1"
|
|
270
270
|
style={{ paddingLeft: `${24 + (depth + 1) * 16}px` }}
|
|
271
271
|
>
|
|
272
|
-
<FolderIcon className="
|
|
272
|
+
<FolderIcon className="h-4 w-4 shrink-0 text-gray-400" />
|
|
273
273
|
<input
|
|
274
274
|
ref={newFolderInputRef}
|
|
275
275
|
type="text"
|
|
@@ -284,7 +284,7 @@ export function FolderTree({
|
|
|
284
284
|
}
|
|
285
285
|
}}
|
|
286
286
|
placeholder="Folder name..."
|
|
287
|
-
className="
|
|
287
|
+
className="min-w-0 flex-1 rounded border border-blue-300 px-1 py-0 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none"
|
|
288
288
|
/>
|
|
289
289
|
</div>
|
|
290
290
|
)}
|
|
@@ -297,19 +297,19 @@ export function FolderTree({
|
|
|
297
297
|
if (loading) {
|
|
298
298
|
return (
|
|
299
299
|
<div className="flex items-center justify-center py-8">
|
|
300
|
-
<Loader2 className="
|
|
300
|
+
<Loader2 className="h-5 w-5 animate-spin text-gray-400" />
|
|
301
301
|
</div>
|
|
302
302
|
)
|
|
303
303
|
}
|
|
304
304
|
|
|
305
305
|
return (
|
|
306
|
-
<div className="flex flex-col
|
|
306
|
+
<div className="flex h-full flex-col">
|
|
307
307
|
<div className="space-y-0.5 px-1 py-2">
|
|
308
308
|
<button
|
|
309
309
|
type="button"
|
|
310
|
-
className={`w-full
|
|
310
|
+
className={`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${
|
|
311
311
|
isSelected({ type: 'smart', smart: 'all' })
|
|
312
|
-
? 'bg-blue-50 text-blue-700
|
|
312
|
+
? 'bg-blue-50 font-medium text-blue-700'
|
|
313
313
|
: 'text-gray-700 hover:bg-gray-100'
|
|
314
314
|
}`}
|
|
315
315
|
onClick={() => onSelect({ type: 'smart', smart: 'all' })}
|
|
@@ -317,7 +317,7 @@ export function FolderTree({
|
|
|
317
317
|
onDragLeave={handleDragLeave}
|
|
318
318
|
onDrop={(e) => handleDrop(e, null)}
|
|
319
319
|
>
|
|
320
|
-
<LayoutGrid className="
|
|
320
|
+
<LayoutGrid className="h-4 w-4 shrink-0" />
|
|
321
321
|
<span className="flex-1 text-left">All</span>
|
|
322
322
|
{totalCount !== undefined && (
|
|
323
323
|
<span className="text-xs text-gray-400 tabular-nums">{totalCount}</span>
|
|
@@ -326,14 +326,14 @@ export function FolderTree({
|
|
|
326
326
|
|
|
327
327
|
<button
|
|
328
328
|
type="button"
|
|
329
|
-
className={`w-full
|
|
329
|
+
className={`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${
|
|
330
330
|
isSelected({ type: 'smart', smart: 'recent' })
|
|
331
|
-
? 'bg-blue-50 text-blue-700
|
|
331
|
+
? 'bg-blue-50 font-medium text-blue-700'
|
|
332
332
|
: 'text-gray-700 hover:bg-gray-100'
|
|
333
333
|
}`}
|
|
334
334
|
onClick={() => onSelect({ type: 'smart', smart: 'recent' })}
|
|
335
335
|
>
|
|
336
|
-
<Clock className="
|
|
336
|
+
<Clock className="h-4 w-4 shrink-0" />
|
|
337
337
|
<span className="flex-1 text-left">Recent</span>
|
|
338
338
|
{recentCount !== undefined && (
|
|
339
339
|
<span className="text-xs text-gray-400 tabular-nums">{recentCount}</span>
|
|
@@ -342,14 +342,14 @@ export function FolderTree({
|
|
|
342
342
|
|
|
343
343
|
<button
|
|
344
344
|
type="button"
|
|
345
|
-
className={`w-full
|
|
345
|
+
className={`flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm transition-colors ${
|
|
346
346
|
isSelected({ type: 'smart', smart: 'uncategorized' })
|
|
347
|
-
? 'bg-blue-50 text-blue-700
|
|
347
|
+
? 'bg-blue-50 font-medium text-blue-700'
|
|
348
348
|
: 'text-gray-700 hover:bg-gray-100'
|
|
349
349
|
}`}
|
|
350
350
|
onClick={() => onSelect({ type: 'smart', smart: 'uncategorized' })}
|
|
351
351
|
>
|
|
352
|
-
<Inbox className="
|
|
352
|
+
<Inbox className="h-4 w-4 shrink-0" />
|
|
353
353
|
<span className="flex-1 text-left">Uncategorized</span>
|
|
354
354
|
{uncategorizedCount !== undefined && (
|
|
355
355
|
<span className="text-xs text-gray-400 tabular-nums">{uncategorizedCount}</span>
|
|
@@ -357,14 +357,14 @@ export function FolderTree({
|
|
|
357
357
|
</button>
|
|
358
358
|
</div>
|
|
359
359
|
|
|
360
|
-
<div className="border-t border-gray-200
|
|
360
|
+
<div className="my-1 border-t border-gray-200" />
|
|
361
361
|
|
|
362
|
-
<div className="flex-1 overflow-y-auto px-1 py-1
|
|
362
|
+
<div className="flex-1 space-y-0.5 overflow-y-auto px-1 py-1">
|
|
363
363
|
{folders.map((folder) => renderFolder(folder, 0))}
|
|
364
364
|
|
|
365
365
|
{creatingIn === null && (
|
|
366
366
|
<div className="flex items-center gap-1 px-2 py-1">
|
|
367
|
-
<FolderIcon className="
|
|
367
|
+
<FolderIcon className="ml-5 h-4 w-4 shrink-0 text-gray-400" />
|
|
368
368
|
<input
|
|
369
369
|
ref={newFolderInputRef}
|
|
370
370
|
type="text"
|
|
@@ -379,7 +379,7 @@ export function FolderTree({
|
|
|
379
379
|
}
|
|
380
380
|
}}
|
|
381
381
|
placeholder="Folder name..."
|
|
382
|
-
className="
|
|
382
|
+
className="min-w-0 flex-1 rounded border border-blue-300 px-1 py-0 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none"
|
|
383
383
|
/>
|
|
384
384
|
</div>
|
|
385
385
|
)}
|
|
@@ -392,21 +392,21 @@ export function FolderTree({
|
|
|
392
392
|
setCreatingIn(null)
|
|
393
393
|
setNewFolderName('')
|
|
394
394
|
}}
|
|
395
|
-
className="w-full
|
|
395
|
+
className="flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-sm text-gray-600 transition-colors hover:bg-gray-100"
|
|
396
396
|
>
|
|
397
|
-
<Plus className="
|
|
397
|
+
<Plus className="h-4 w-4" />
|
|
398
398
|
New Folder
|
|
399
399
|
</button>
|
|
400
400
|
</div>
|
|
401
401
|
|
|
402
402
|
{contextMenu && (
|
|
403
403
|
<div
|
|
404
|
-
className="fixed z-50
|
|
404
|
+
className="fixed z-50 min-w-[160px] rounded-lg border border-gray-200 bg-white py-1 shadow-lg"
|
|
405
405
|
style={{ left: contextMenu.x, top: contextMenu.y }}
|
|
406
406
|
>
|
|
407
407
|
<button
|
|
408
408
|
type="button"
|
|
409
|
-
className="w-full
|
|
409
|
+
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-gray-700 transition-colors hover:bg-gray-100"
|
|
410
410
|
onClick={() => {
|
|
411
411
|
const folder = findFolder(folders, contextMenu.id)
|
|
412
412
|
if (folder) {
|
|
@@ -416,12 +416,12 @@ export function FolderTree({
|
|
|
416
416
|
setContextMenu(null)
|
|
417
417
|
}}
|
|
418
418
|
>
|
|
419
|
-
<Pencil className="
|
|
419
|
+
<Pencil className="h-3.5 w-3.5" />
|
|
420
420
|
Rename
|
|
421
421
|
</button>
|
|
422
422
|
<button
|
|
423
423
|
type="button"
|
|
424
|
-
className="w-full
|
|
424
|
+
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-gray-700 transition-colors hover:bg-gray-100"
|
|
425
425
|
onClick={() => {
|
|
426
426
|
setCreatingIn(contextMenu.id)
|
|
427
427
|
setNewFolderName('')
|
|
@@ -429,19 +429,19 @@ export function FolderTree({
|
|
|
429
429
|
setContextMenu(null)
|
|
430
430
|
}}
|
|
431
431
|
>
|
|
432
|
-
<FolderPlus className="
|
|
432
|
+
<FolderPlus className="h-3.5 w-3.5" />
|
|
433
433
|
New Subfolder
|
|
434
434
|
</button>
|
|
435
|
-
<div className="border-t border-gray-200
|
|
435
|
+
<div className="my-1 border-t border-gray-200" />
|
|
436
436
|
<button
|
|
437
437
|
type="button"
|
|
438
|
-
className="w-full
|
|
438
|
+
className="flex w-full items-center gap-2 px-3 py-1.5 text-sm text-red-600 transition-colors hover:bg-red-50"
|
|
439
439
|
onClick={() => {
|
|
440
440
|
handleDelete(contextMenu.id)
|
|
441
441
|
setContextMenu(null)
|
|
442
442
|
}}
|
|
443
443
|
>
|
|
444
|
-
<Trash2 className="
|
|
444
|
+
<Trash2 className="h-3.5 w-3.5" />
|
|
445
445
|
Delete
|
|
446
446
|
</button>
|
|
447
447
|
</div>
|
|
@@ -79,8 +79,8 @@ export function LivePreview({
|
|
|
79
79
|
|
|
80
80
|
if (!previewSrc) {
|
|
81
81
|
return (
|
|
82
|
-
<div className="flex flex-col items-center justify-center
|
|
83
|
-
<p className="text-sm text-gray-500
|
|
82
|
+
<div className="flex h-full flex-col items-center justify-center rounded-lg border border-dashed border-gray-300 bg-gray-50 p-8">
|
|
83
|
+
<p className="text-center text-sm text-gray-500">
|
|
84
84
|
{!documentId
|
|
85
85
|
? 'Save the document first to enable preview'
|
|
86
86
|
: 'Configure a preview URL in the collection settings to enable live preview'}
|
|
@@ -93,8 +93,8 @@ export function LivePreview({
|
|
|
93
93
|
}
|
|
94
94
|
|
|
95
95
|
return (
|
|
96
|
-
<div className="flex flex-col
|
|
97
|
-
<div className="flex items-center justify-between
|
|
96
|
+
<div className="flex h-full flex-col border-l border-gray-200 bg-white">
|
|
97
|
+
<div className="flex items-center justify-between border-b border-gray-200 bg-gray-50 px-3 py-2">
|
|
98
98
|
<div className="flex items-center gap-1">
|
|
99
99
|
{(
|
|
100
100
|
[
|
|
@@ -106,52 +106,52 @@ export function LivePreview({
|
|
|
106
106
|
<button
|
|
107
107
|
key={vp}
|
|
108
108
|
onClick={() => setViewport(vp)}
|
|
109
|
-
className={`p-1.5
|
|
109
|
+
className={`rounded p-1.5 ${viewport === vp ? 'bg-white text-blue-600 shadow-sm' : 'text-gray-400 hover:text-gray-600'}`}
|
|
110
110
|
title={vp}
|
|
111
111
|
>
|
|
112
|
-
<Icon className="
|
|
112
|
+
<Icon className="h-4 w-4" />
|
|
113
113
|
</button>
|
|
114
114
|
))}
|
|
115
115
|
</div>
|
|
116
116
|
<div className="flex items-center gap-1">
|
|
117
117
|
<button
|
|
118
118
|
onClick={handleRefresh}
|
|
119
|
-
className="p-1.5
|
|
119
|
+
className="rounded p-1.5 text-gray-400 hover:text-gray-600"
|
|
120
120
|
title="Refresh"
|
|
121
121
|
>
|
|
122
|
-
<RefreshCw className="
|
|
122
|
+
<RefreshCw className="h-4 w-4" />
|
|
123
123
|
</button>
|
|
124
124
|
<button
|
|
125
125
|
onClick={handleOpenExternal}
|
|
126
|
-
className="p-1.5
|
|
126
|
+
className="rounded p-1.5 text-gray-400 hover:text-gray-600"
|
|
127
127
|
title="Open in new tab"
|
|
128
128
|
>
|
|
129
|
-
<ExternalLink className="
|
|
129
|
+
<ExternalLink className="h-4 w-4" />
|
|
130
130
|
</button>
|
|
131
131
|
<button
|
|
132
132
|
onClick={onClose}
|
|
133
|
-
className="p-1.5
|
|
133
|
+
className="rounded p-1.5 text-gray-400 hover:text-gray-600"
|
|
134
134
|
title="Close"
|
|
135
135
|
>
|
|
136
|
-
<X className="
|
|
136
|
+
<X className="h-4 w-4" />
|
|
137
137
|
</button>
|
|
138
138
|
</div>
|
|
139
139
|
</div>
|
|
140
140
|
|
|
141
|
-
<div className="flex-1 overflow-auto
|
|
141
|
+
<div className="flex flex-1 justify-center overflow-auto bg-gray-100 p-4">
|
|
142
142
|
<div
|
|
143
143
|
style={{ width: VIEWPORT_WIDTHS[viewport], maxWidth: '100%', transition: 'width 0.3s' }}
|
|
144
144
|
className="relative"
|
|
145
145
|
>
|
|
146
146
|
{loading && (
|
|
147
|
-
<div className="absolute inset-0 flex items-center justify-center bg-white/80
|
|
148
|
-
<div className="animate-spin rounded-full
|
|
147
|
+
<div className="absolute inset-0 z-10 flex items-center justify-center rounded-lg bg-white/80">
|
|
148
|
+
<div className="h-8 w-8 animate-spin rounded-full border-b-2 border-blue-600" />
|
|
149
149
|
</div>
|
|
150
150
|
)}
|
|
151
151
|
<iframe
|
|
152
152
|
ref={iframeRef}
|
|
153
153
|
src={previewSrc}
|
|
154
|
-
className="
|
|
154
|
+
className="h-full w-full rounded-lg border border-gray-200 bg-white shadow-lg"
|
|
155
155
|
style={{ minHeight: '600px' }}
|
|
156
156
|
onLoad={() => setLoading(false)}
|
|
157
157
|
title="Page Preview"
|
|
@@ -15,20 +15,20 @@ export function LocaleSwitcher() {
|
|
|
15
15
|
<DropdownMenu.Root>
|
|
16
16
|
<DropdownMenu.Trigger asChild>
|
|
17
17
|
<button
|
|
18
|
-
className="flex items-center gap-1.5 px-2 py-1.5 text-sm hover:bg-[var(--accent)]
|
|
18
|
+
className="flex items-center gap-1.5 rounded-lg px-2 py-1.5 text-sm transition-colors hover:bg-[var(--accent)]"
|
|
19
19
|
aria-label="Switch locale"
|
|
20
20
|
>
|
|
21
|
-
<Globe className="
|
|
22
|
-
<span className="hidden sm
|
|
21
|
+
<Globe className="h-4 w-4 text-[var(--muted-foreground)]" />
|
|
22
|
+
<span className="hidden text-sm font-medium text-[var(--foreground)] sm:inline">
|
|
23
23
|
{activeLabel}
|
|
24
24
|
</span>
|
|
25
|
-
<ChevronDown className="
|
|
25
|
+
<ChevronDown className="h-3 w-3 text-[var(--muted-foreground)]" />
|
|
26
26
|
</button>
|
|
27
27
|
</DropdownMenu.Trigger>
|
|
28
28
|
|
|
29
29
|
<DropdownMenu.Portal>
|
|
30
30
|
<DropdownMenu.Content
|
|
31
|
-
className="min-w-[160px]
|
|
31
|
+
className="z-50 min-w-[160px] rounded-lg border border-[var(--border)] bg-[var(--popover)] p-1 text-[var(--popover-foreground)] shadow-lg"
|
|
32
32
|
align="end"
|
|
33
33
|
sideOffset={5}
|
|
34
34
|
>
|
|
@@ -36,10 +36,10 @@ export function LocaleSwitcher() {
|
|
|
36
36
|
<DropdownMenu.Item
|
|
37
37
|
key={locale.code}
|
|
38
38
|
onSelect={() => setLocale(locale.code)}
|
|
39
|
-
className="flex items-center justify-between gap-2 px-3 py-2 text-sm hover:bg-[var(--accent)]
|
|
39
|
+
className="flex cursor-pointer items-center justify-between gap-2 rounded px-3 py-2 text-sm outline-none hover:bg-[var(--accent)]"
|
|
40
40
|
>
|
|
41
41
|
<span>{locale.label}</span>
|
|
42
|
-
{locale.code === activeLocale && <Check className="
|
|
42
|
+
{locale.code === activeLocale && <Check className="h-4 w-4 text-[var(--primary)]" />}
|
|
43
43
|
</DropdownMenu.Item>
|
|
44
44
|
))}
|
|
45
45
|
</DropdownMenu.Content>
|
|
@@ -73,14 +73,14 @@ export function MediaPickerModal({ open, onClose, onSelect, accept }: MediaPicke
|
|
|
73
73
|
return (
|
|
74
74
|
<div className="fixed inset-0 z-50 flex items-center justify-center">
|
|
75
75
|
<div className="fixed inset-0 bg-black/40" onClick={onClose} />
|
|
76
|
-
<div className="relative
|
|
77
|
-
<div className="flex items-center justify-between
|
|
76
|
+
<div className="relative mx-4 flex max-h-[80vh] w-full max-w-2xl flex-col rounded-xl bg-white shadow-2xl">
|
|
77
|
+
<div className="flex items-center justify-between border-b border-gray-200 px-4 py-3">
|
|
78
78
|
<h2 className="text-lg font-semibold text-gray-900">Insert Image</h2>
|
|
79
79
|
<button
|
|
80
80
|
onClick={onClose}
|
|
81
|
-
className="p-1.5 hover:bg-gray-100
|
|
81
|
+
className="rounded-lg p-1.5 transition-colors hover:bg-gray-100"
|
|
82
82
|
>
|
|
83
|
-
<X className="
|
|
83
|
+
<X className="h-5 w-5 text-gray-500" />
|
|
84
84
|
</button>
|
|
85
85
|
</div>
|
|
86
86
|
|
|
@@ -89,7 +89,7 @@ export function MediaPickerModal({ open, onClose, onSelect, accept }: MediaPicke
|
|
|
89
89
|
onClick={() => setTab('library')}
|
|
90
90
|
className={`flex-1 px-4 py-2.5 text-sm font-medium transition-colors ${
|
|
91
91
|
tab === 'library'
|
|
92
|
-
? '
|
|
92
|
+
? 'border-b-2 border-blue-600 text-blue-600'
|
|
93
93
|
: 'text-gray-500 hover:text-gray-700'
|
|
94
94
|
}`}
|
|
95
95
|
>
|
|
@@ -99,7 +99,7 @@ export function MediaPickerModal({ open, onClose, onSelect, accept }: MediaPicke
|
|
|
99
99
|
onClick={() => setTab('upload')}
|
|
100
100
|
className={`flex-1 px-4 py-2.5 text-sm font-medium transition-colors ${
|
|
101
101
|
tab === 'upload'
|
|
102
|
-
? '
|
|
102
|
+
? 'border-b-2 border-blue-600 text-blue-600'
|
|
103
103
|
: 'text-gray-500 hover:text-gray-700'
|
|
104
104
|
}`}
|
|
105
105
|
>
|
|
@@ -111,37 +111,37 @@ export function MediaPickerModal({ open, onClose, onSelect, accept }: MediaPicke
|
|
|
111
111
|
{tab === 'library' ? (
|
|
112
112
|
<>
|
|
113
113
|
<div className="relative mb-4">
|
|
114
|
-
<Search className="absolute
|
|
114
|
+
<Search className="absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
|
|
115
115
|
<input
|
|
116
116
|
type="text"
|
|
117
117
|
value={search}
|
|
118
118
|
onChange={(e) => setSearch(e.target.value)}
|
|
119
119
|
placeholder="Search images..."
|
|
120
|
-
className="w-full
|
|
120
|
+
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"
|
|
121
121
|
/>
|
|
122
122
|
</div>
|
|
123
123
|
|
|
124
124
|
{loading ? (
|
|
125
125
|
<div className="flex items-center justify-center py-12">
|
|
126
|
-
<Loader2 className="
|
|
126
|
+
<Loader2 className="h-6 w-6 animate-spin text-gray-400" />
|
|
127
127
|
</div>
|
|
128
128
|
) : imageItems.length === 0 ? (
|
|
129
|
-
<div className="
|
|
129
|
+
<div className="py-12 text-center text-sm text-gray-500">
|
|
130
130
|
No images found. Try uploading one.
|
|
131
131
|
</div>
|
|
132
132
|
) : (
|
|
133
|
-
<div className="grid grid-cols-3 sm:grid-cols-4
|
|
133
|
+
<div className="grid grid-cols-3 gap-3 sm:grid-cols-4">
|
|
134
134
|
{imageItems.map((item: MediaItem) => (
|
|
135
135
|
<button
|
|
136
136
|
key={item.id}
|
|
137
137
|
onClick={() => handleSelectItem(item)}
|
|
138
|
-
className="group relative aspect-square rounded-lg border-2 border-gray-200
|
|
138
|
+
className="group relative aspect-square overflow-hidden rounded-lg border-2 border-gray-200 bg-gray-100 transition-colors hover:border-blue-500"
|
|
139
139
|
>
|
|
140
|
-
<div className="
|
|
141
|
-
<ImageIcon className="
|
|
140
|
+
<div className="flex h-full w-full items-center justify-center">
|
|
141
|
+
<ImageIcon className="h-8 w-8 text-gray-300" />
|
|
142
142
|
</div>
|
|
143
|
-
<div className="absolute inset-x-0 bottom-0 bg-black/60 p-1.5 opacity-0 group-hover:opacity-100
|
|
144
|
-
<p className="text-
|
|
143
|
+
<div className="absolute inset-x-0 bottom-0 bg-black/60 p-1.5 opacity-0 transition-opacity group-hover:opacity-100">
|
|
144
|
+
<p className="truncate text-xs text-white">{item.filename}</p>
|
|
145
145
|
</div>
|
|
146
146
|
</button>
|
|
147
147
|
))}
|
|
@@ -157,20 +157,20 @@ export function MediaPickerModal({ open, onClose, onSelect, accept }: MediaPicke
|
|
|
157
157
|
className="hidden"
|
|
158
158
|
onChange={(e) => handleUpload(e.target.files)}
|
|
159
159
|
/>
|
|
160
|
-
<div className="
|
|
160
|
+
<div className="mb-4 flex h-16 w-16 items-center justify-center rounded-full bg-blue-50">
|
|
161
161
|
{uploading ? (
|
|
162
|
-
<Loader2 className="
|
|
162
|
+
<Loader2 className="h-8 w-8 animate-spin text-blue-600" />
|
|
163
163
|
) : (
|
|
164
|
-
<Upload className="
|
|
164
|
+
<Upload className="h-8 w-8 text-blue-600" />
|
|
165
165
|
)}
|
|
166
166
|
</div>
|
|
167
|
-
<p className="text-sm text-gray-600
|
|
167
|
+
<p className="mb-4 text-sm text-gray-600">
|
|
168
168
|
{uploading ? 'Uploading...' : 'Select an image file to upload'}
|
|
169
169
|
</p>
|
|
170
170
|
{!uploading && (
|
|
171
171
|
<button
|
|
172
172
|
onClick={() => fileInputRef.current?.click()}
|
|
173
|
-
className="px-4 py-2 text-sm
|
|
173
|
+
className="rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700"
|
|
174
174
|
>
|
|
175
175
|
Choose File
|
|
176
176
|
</button>
|
|
@@ -57,7 +57,7 @@ export function PresenceIndicator({ documentId, currentUserId }: PresenceIndicat
|
|
|
57
57
|
{users.slice(0, 5).map((user, i) => (
|
|
58
58
|
<div
|
|
59
59
|
key={user.userId}
|
|
60
|
-
className="
|
|
60
|
+
className="flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium text-white ring-2 ring-white"
|
|
61
61
|
style={{ backgroundColor: COLORS[i % COLORS.length] }}
|
|
62
62
|
title={user.name}
|
|
63
63
|
>
|
|
@@ -65,7 +65,7 @@ export function PresenceIndicator({ documentId, currentUserId }: PresenceIndicat
|
|
|
65
65
|
</div>
|
|
66
66
|
))}
|
|
67
67
|
{users.length > 5 && (
|
|
68
|
-
<div className="
|
|
68
|
+
<div className="bg-muted text-muted-foreground flex h-7 w-7 items-center justify-center rounded-full text-xs font-medium ring-2 ring-white">
|
|
69
69
|
+{users.length - 5}
|
|
70
70
|
</div>
|
|
71
71
|
)}
|