@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
|
@@ -250,9 +250,9 @@ export function DocumentEdit({ collectionSlug, documentId, config, onNavigate, }
|
|
|
250
250
|
? 'bg-blue-100 text-blue-800'
|
|
251
251
|
: 'bg-yellow-100 text-yellow-800';
|
|
252
252
|
if (loading) {
|
|
253
|
-
return (_jsx("div", { className: "flex items-center justify-center
|
|
253
|
+
return (_jsx("div", { className: "flex min-h-[300px] items-center justify-center", children: _jsx(Loader2, { className: "h-8 w-8 animate-spin text-gray-400" }) }));
|
|
254
254
|
}
|
|
255
|
-
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("h1", { className: "text-2xl font-bold", children: displayTitle }), _jsx("span", { className: `inline-flex items-center px-2.5 py-0.5
|
|
255
|
+
return (_jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("h1", { className: "text-2xl font-bold", children: displayTitle }), _jsx("span", { className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${statusColor}`, children: docStatus }), documentId && _jsx(PresenceIndicator, { documentId: documentId }), isDirty && _jsx("span", { className: "text-xs font-medium text-amber-600", children: "Unsaved changes" })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("button", { onClick: () => setShowPreview((v) => !v), className: "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-[var(--muted-foreground)] hover:bg-[var(--muted)] hover:text-[var(--foreground)]", title: showPreview ? 'Hide preview' : 'Show preview', children: [showPreview ? _jsx(EyeOff, { className: "h-4 w-4" }) : _jsx(Eye, { className: "h-4 w-4" }), "Preview"] }), !isNew && (_jsxs(_Fragment, { children: [_jsxs("button", { onClick: () => setShowShareLink(true), className: "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-[var(--muted-foreground)] hover:bg-[var(--muted)] hover:text-[var(--foreground)]", title: "Share a signed preview link for the current draft", children: [_jsx(Share2, { className: "h-4 w-4" }), "Share preview"] }), _jsxs("button", { onClick: () => setShowVersions(true), className: "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-[var(--muted-foreground)] hover:bg-[var(--muted)] hover:text-[var(--foreground)]", title: "Version history", children: [_jsx(Clock, { className: "h-4 w-4" }), "History"] }), _jsxs("button", { onClick: handleDuplicate, className: "inline-flex items-center gap-1.5 rounded-md px-3 py-1.5 text-sm text-[var(--muted-foreground)] hover:bg-[var(--muted)] hover:text-[var(--foreground)]", title: "Duplicate this document", children: [_jsx(Copy, { className: "h-4 w-4" }), "Duplicate"] })] }))] })] }), _jsxs("div", { className: showPreview ? 'grid grid-cols-2 gap-6' : '', children: [_jsxs("div", { className: "space-y-6", children: [fields.length === 0 ? (_jsxs("div", { className: "flex flex-col items-center justify-center rounded-lg border border-[var(--border)] py-16 text-center", children: [_jsx("div", { className: "mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-gray-100", children: _jsx(AlertTriangle, { className: "h-6 w-6 text-gray-400" }) }), _jsx("h3", { className: "mb-1 text-sm font-medium text-gray-900", children: "Collection schema not found" }), _jsx("p", { className: "text-sm text-gray-500", children: "No fields are defined for this collection." })] })) : (_jsxs("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-3", children: [_jsx("div", { className: "space-y-6 lg:col-span-2", children: mainFields.map((field) => (_jsx(FieldRenderer, { field: field, value: values[field.name], onChange: (val) => handleFieldChange(field.name, val) }, field.name))) }), _jsxs("div", { className: "space-y-6", children: [_jsxs("div", { className: "rounded-lg border border-[var(--border)] bg-[var(--card)] p-4", children: [_jsx("h3", { className: "mb-4 font-semibold", children: "Status" }), _jsxs("div", { className: "space-y-3", children: [!isNew && docStatus === 'DRAFT' && (_jsx(Button, { variant: "primary", className: "w-full", onClick: handlePublish, loading: saving, children: "Publish" })), !isNew && docStatus === 'PUBLISHED' && (_jsx(Button, { variant: "secondary", className: "w-full", onClick: handleUnpublish, loading: saving, children: "Unpublish" })), !isNew && (_jsxs("button", { onClick: () => setShowSchedule(true), className: "inline-flex w-full items-center justify-center gap-1.5 rounded-md border border-[var(--border)] bg-white px-3 py-1.5 text-sm font-medium text-gray-700 hover:bg-gray-50", children: [_jsx(Calendar, { className: "h-4 w-4" }), scheduledAt || scheduledUnpublishAt ? 'Reschedule' : 'Schedule'] })), !isNew && (scheduledAt || scheduledUnpublishAt) && (_jsxs("div", { className: "space-y-1 rounded-md border border-blue-100 bg-blue-50 px-3 py-2 text-xs text-blue-900", children: [scheduledAt && (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(Calendar, { className: "h-3.5 w-3.5" }), "Publishes ", new Date(scheduledAt).toLocaleString()] })), scheduledUnpublishAt && (_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx(XCircle, { className: "h-3.5 w-3.5" }), "Unpublishes ", new Date(scheduledUnpublishAt).toLocaleString()] }))] }))] })] }), sidebarFields.length > 0 && (_jsxs("div", { className: "rounded-lg border border-[var(--border)] bg-[var(--card)] p-4", children: [_jsx("h3", { className: "mb-4 font-semibold", children: "Metadata" }), sidebarFields.map((field) => (_jsx("div", { className: "mb-4", children: _jsx(FieldRenderer, { field: field, value: values[field.name], onChange: (val) => handleFieldChange(field.name, val) }) }, field.name)))] })), _jsx(SEOPanel, { title: values[useAsTitleField] ?? values.title ?? '', slug: docSlug, content: htmlContent, seoData: seoData, onChange: setSeoData, siteUrl: config?.siteUrl }), hasLayout && (_jsxs("div", { className: "rounded-lg border border-[var(--border)] bg-[var(--card)] p-4", children: [_jsx("h3", { className: "mb-1 font-semibold", children: "Layout" }), _jsx("p", { className: "mb-4 text-xs text-[var(--muted-foreground)]", children: "Assign header/footer variants. Child pages inherit from ancestors." }), _jsx("div", { className: "space-y-4", children: layoutRegions.map((region) => (_jsxs("div", { children: [_jsx(RelationshipField, { label: region.label, value: layoutAssignments[region.name] ?? '', onChange: (val) => {
|
|
256
256
|
setLayoutAssignments((prev) => {
|
|
257
257
|
const next = { ...prev };
|
|
258
258
|
if (val && typeof val === 'string') {
|
|
@@ -271,7 +271,7 @@ export function DocumentEdit({ collectionSlug, documentId, config, onNavigate, }
|
|
|
271
271
|
delete next[region.name];
|
|
272
272
|
return next;
|
|
273
273
|
});
|
|
274
|
-
}, className: "mt-1 text-xs text-[var(--primary)] hover:underline", children: "Clear override (inherit from parent)" }))] }, region.name))) })] }))] })] })), _jsxs("div", { className: "sticky bottom-0 flex items-center justify-end gap-3 border-t border-[var(--border)] bg-[var(--background)] px-4 py-3", children: [_jsx(Button, { variant: "secondary", onClick: () => onNavigate?.(`/${collectionSlug}`), children: "Cancel" }), _jsxs(Button, { variant: "primary", loading: saving, onClick: handleSave, "data-shortcut": "save", children: [_jsx(Save, { className: "h-4 w-4
|
|
274
|
+
}, className: "mt-1 text-xs text-[var(--primary)] hover:underline", children: "Clear override (inherit from parent)" }))] }, region.name))) })] }))] })] })), _jsxs("div", { className: "sticky bottom-0 flex items-center justify-end gap-3 border-t border-[var(--border)] bg-[var(--background)] px-4 py-3", children: [_jsx(Button, { variant: "secondary", onClick: () => onNavigate?.(`/${collectionSlug}`), children: "Cancel" }), _jsxs(Button, { variant: "primary", loading: saving, onClick: handleSave, "data-shortcut": "save", children: [_jsx(Save, { className: "mr-1.5 h-4 w-4" }), isNew ? 'Create' : 'Save Changes'] })] })] }), showPreview && (_jsx(LivePreview, { collection: collectionSlug, documentId: documentId, previewUrl: previewUrl, values: values, onClose: () => setShowPreview(false) }))] }), !isNew && documentId && (_jsx(VersionHistory, { collectionSlug: collectionSlug, documentId: documentId, open: showVersions, onClose: () => setShowVersions(false), onRestore: (data) => {
|
|
275
275
|
const restoredData = data;
|
|
276
276
|
setValues(restoredData);
|
|
277
277
|
setInitialValues(restoredData);
|
|
@@ -34,8 +34,8 @@ export function ForgotPassword({ onNavigate }) {
|
|
|
34
34
|
setSubmitting(false);
|
|
35
35
|
}
|
|
36
36
|
};
|
|
37
|
-
return (_jsx("div", { className: "min-h-screen
|
|
37
|
+
return (_jsx("div", { className: "flex min-h-screen items-center justify-center bg-gray-50 px-4", children: _jsxs("div", { className: "w-full max-w-md", children: [_jsxs("div", { className: "mb-8 text-center", children: [_jsx("div", { className: "mx-auto mb-4 flex h-14 w-14 items-center justify-center rounded-xl bg-blue-600", children: _jsx(Shield, { className: "h-7 w-7 text-white" }) }), _jsx("h1", { className: "text-2xl font-bold text-gray-900", children: "Reset Password" }), _jsx("p", { className: "mt-2 text-gray-600", children: sent
|
|
38
38
|
? 'Check your inbox for a reset link'
|
|
39
|
-
: "Enter your email and we'll send you a reset link" })] }), _jsxs("div", { className: "
|
|
39
|
+
: "Enter your email and we'll send you a reset link" })] }), _jsxs("div", { className: "space-y-5 rounded-xl border border-gray-200 bg-white p-6 shadow-sm", children: [sent ? (_jsxs("div", { className: "space-y-4 text-center", children: [_jsx("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100", children: _jsx(CheckCircle2, { className: "h-6 w-6 text-green-600" }) }), _jsxs("p", { className: "text-sm text-gray-600", children: ["If an account exists for ", _jsx("strong", { children: email }), ", you will receive a password reset email shortly."] }), _jsx("p", { className: "text-xs text-gray-500", children: "The link expires in 1 hour. Check your spam folder if you don't see it." }), _jsx("button", { type: "button", onClick: () => onNavigate('/login'), className: "w-full rounded-lg bg-blue-600 py-2.5 font-medium text-white transition-colors hover:bg-blue-700", children: "Back to Sign In" })] })) : (_jsxs("form", { onSubmit: handleSubmit, className: "space-y-5", children: [error && (_jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0 text-red-600" }), _jsx("p", { className: "text-sm text-red-800", children: error })] })), _jsxs("div", { children: [_jsx("label", { htmlFor: "forgot-email", className: "mb-1.5 block text-sm font-medium text-gray-700", children: "Email Address" }), _jsx("input", { id: "forgot-email", type: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "admin@example.com", className: "w-full rounded-lg border border-gray-300 px-3 py-2.5 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none", required: true, autoFocus: true, autoComplete: "email" })] }), _jsx("button", { type: "submit", disabled: !canSubmit, className: "flex w-full items-center justify-center gap-2 rounded-lg bg-blue-600 py-2.5 font-medium text-white transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50", children: submitting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), "Sending..."] })) : ('Send Reset Link') })] })), !sent && (_jsxs("button", { type: "button", onClick: () => onNavigate('/login'), className: "flex w-full items-center justify-center gap-2 text-sm text-gray-600 transition-colors hover:text-gray-800", children: [_jsx(ArrowLeft, { className: "h-4 w-4" }), "Back to Sign In"] }))] })] }) }));
|
|
40
40
|
}
|
|
41
41
|
//# sourceMappingURL=ForgotPassword.js.map
|
package/dist/views/FormEditor.js
CHANGED
|
@@ -116,17 +116,17 @@ export function FormEditor({ formId, onNavigate }) {
|
|
|
116
116
|
setExpandedSection(expandedSection === section ? null : section);
|
|
117
117
|
};
|
|
118
118
|
if (loading) {
|
|
119
|
-
return (_jsx("div", { className: "
|
|
119
|
+
return (_jsx("div", { className: "flex h-64 items-center justify-center p-4", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-blue-600" }) }));
|
|
120
120
|
}
|
|
121
|
-
return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8
|
|
121
|
+
return (_jsxs("div", { className: "max-w-4xl p-3 pr-6 sm:p-4 sm:pr-8", children: [_jsxs("div", { className: "mb-6 flex items-center gap-3", children: [_jsx("button", { onClick: () => onNavigate?.('/forms'), className: "rounded-lg p-2 transition-colors hover:bg-gray-100", children: _jsx(ArrowLeft, { className: "h-5 w-5 text-gray-600" }) }), _jsx("div", { className: "flex-1", children: _jsx("h1", { className: "text-xl font-semibold text-gray-900", children: isNew ? 'New Form' : 'Edit Form' }) }), _jsxs("button", { onClick: handleSave, disabled: saving || !name.trim(), className: "flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700 disabled:opacity-50", children: [saving ? _jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : _jsx(Save, { className: "h-4 w-4" }), saving ? 'Saving...' : 'Save'] })] }), _jsx("div", { className: "mb-4 rounded-lg border border-gray-200 bg-white p-4", children: _jsxs("div", { className: "grid gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Form Name" }), _jsx("input", { type: "text", value: name, onChange: (e) => setName(e.target.value), placeholder: "e.g. Contact Form", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Description" }), _jsx("input", { type: "text", value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Brief description of this form", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Status" }), _jsxs("select", { value: status, onChange: (e) => setStatus(e.target.value), className: "rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none", children: [_jsx("option", { value: "active", children: "Active" }), _jsx("option", { value: "inactive", children: "Inactive" })] })] })] }) }), _jsxs("div", { className: "mb-4 rounded-lg border border-gray-200 bg-white", children: [_jsx("button", { onClick: () => toggleSection('fields'), className: "flex w-full items-center justify-between p-4 transition-colors hover:bg-gray-50", children: _jsxs("div", { className: "flex items-center gap-2", children: [expandedSection === 'fields' ? (_jsx(ChevronDown, { className: "h-4 w-4" })) : (_jsx(ChevronRight, { className: "h-4 w-4" })), _jsx("span", { className: "font-medium text-gray-900", children: "Form Fields" }), _jsxs("span", { className: "text-sm text-gray-500", children: ["(", fields.length, ")"] })] }) }), expandedSection === 'fields' && (_jsxs("div", { className: "border-t border-gray-200 p-4", children: [_jsx("div", { className: "mb-4 flex flex-wrap gap-2", children: FIELD_TYPES.map((ft) => (_jsxs("button", { onClick: () => addField(ft.value), className: "flex items-center gap-1 rounded-lg border border-gray-300 px-3 py-1.5 text-xs transition-colors hover:bg-gray-50", children: [_jsx(Plus, { className: "h-3 w-3" }), " ", ft.label] }, ft.value))) }), fields.length === 0 ? (_jsx("p", { className: "py-6 text-center text-sm text-gray-500", children: "Click a field type above to add it to your form." })) : (_jsx("div", { className: "flex flex-col gap-2", children: fields.map((field, index) => (_jsxs("div", { draggable: true, onDragStart: (e) => e.dataTransfer.setData('text/plain', String(index)), onDragOver: (e) => e.preventDefault(), onDrop: (e) => {
|
|
122
122
|
const from = Number(e.dataTransfer.getData('text/plain'));
|
|
123
123
|
moveField(from, index);
|
|
124
|
-
}, className: "flex items-center gap-3
|
|
124
|
+
}, className: "flex items-center gap-3 rounded-lg border border-gray-200 bg-gray-50 p-3 transition-colors hover:bg-white", children: [_jsx(GripVertical, { className: "h-4 w-4 shrink-0 cursor-grab text-gray-400" }), _jsx("input", { type: "text", value: field.label, onChange: (e) => updateField(field.id, { label: e.target.value }), className: "flex-1 rounded border border-gray-300 px-2 py-1 text-sm focus:ring-1 focus:ring-blue-500 focus:outline-none" }), _jsx("span", { className: "shrink-0 rounded bg-gray-100 px-2 py-0.5 text-xs text-gray-500", children: field.type }), _jsxs("label", { className: "flex shrink-0 items-center gap-1 text-xs text-gray-600", children: [_jsx("input", { type: "checkbox", checked: field.required, onChange: (e) => updateField(field.id, { required: e.target.checked }), className: "rounded" }), "Required"] }), _jsx("button", { onClick: () => removeField(field.id), className: "shrink-0 rounded p-1 text-red-500 transition-colors hover:bg-red-50", children: _jsx(Trash2, { className: "h-4 w-4" }) })] }, field.id))) }))] }))] }), _jsxs("div", { className: "mb-4 rounded-lg border border-gray-200 bg-white", children: [_jsx("button", { onClick: () => toggleSection('confirmation'), className: "flex w-full items-center justify-between p-4 transition-colors hover:bg-gray-50", children: _jsxs("div", { className: "flex items-center gap-2", children: [expandedSection === 'confirmation' ? (_jsx(ChevronDown, { className: "h-4 w-4" })) : (_jsx(ChevronRight, { className: "h-4 w-4" })), _jsx(MessageSquare, { className: "h-4 w-4 text-green-600" }), _jsx("span", { className: "font-medium text-gray-900", children: "Confirmation" }), _jsx("span", { className: "rounded bg-gray-100 px-2 py-0.5 text-xs text-gray-500", children: confirmation.type === 'message' ? 'Show Message' : 'Redirect' })] }) }), expandedSection === 'confirmation' && (_jsxs("div", { className: "border-t border-gray-200 p-4", children: [_jsxs("div", { className: "mb-4", children: [_jsx("label", { className: "mb-2 block text-sm font-medium text-gray-700", children: "After submission" }), _jsxs("div", { className: "flex gap-3", children: [_jsxs("label", { className: "flex cursor-pointer items-center gap-2 rounded-lg border px-4 py-2 transition-colors hover:bg-gray-50", style: {
|
|
125
125
|
borderColor: confirmation.type === 'message' ? '#2563eb' : '#d1d5db',
|
|
126
126
|
backgroundColor: confirmation.type === 'message' ? '#eff6ff' : 'transparent',
|
|
127
|
-
}, children: [_jsx("input", { type: "radio", name: "confirmationType", value: "message", checked: confirmation.type === 'message', onChange: () => setConfirmation((c) => ({ ...c, type: 'message' })), className: "text-blue-600" }), _jsx(MessageSquare, { className: "
|
|
127
|
+
}, children: [_jsx("input", { type: "radio", name: "confirmationType", value: "message", checked: confirmation.type === 'message', onChange: () => setConfirmation((c) => ({ ...c, type: 'message' })), className: "text-blue-600" }), _jsx(MessageSquare, { className: "h-4 w-4" }), _jsx("span", { className: "text-sm", children: "Show Message" })] }), _jsxs("label", { className: "flex cursor-pointer items-center gap-2 rounded-lg border px-4 py-2 transition-colors hover:bg-gray-50", style: {
|
|
128
128
|
borderColor: confirmation.type === 'redirect' ? '#2563eb' : '#d1d5db',
|
|
129
129
|
backgroundColor: confirmation.type === 'redirect' ? '#eff6ff' : 'transparent',
|
|
130
|
-
}, children: [_jsx("input", { type: "radio", name: "confirmationType", value: "redirect", checked: confirmation.type === 'redirect', onChange: () => setConfirmation((c) => ({ ...c, type: 'redirect' })), className: "text-blue-600" }), _jsx(ExternalLink, { className: "
|
|
130
|
+
}, children: [_jsx("input", { type: "radio", name: "confirmationType", value: "redirect", checked: confirmation.type === 'redirect', onChange: () => setConfirmation((c) => ({ ...c, type: 'redirect' })), className: "text-blue-600" }), _jsx(ExternalLink, { className: "h-4 w-4" }), _jsx("span", { className: "text-sm", children: "Redirect to Page" })] })] })] }), confirmation.type === 'message' ? (_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Success Message" }), _jsx("textarea", { value: confirmation.message, onChange: (e) => setConfirmation((c) => ({ ...c, message: e.target.value })), rows: 3, className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none", placeholder: "Thank you! Your submission has been received." })] })) : (_jsxs("div", { className: "grid gap-3", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Redirect URL" }), _jsx("input", { type: "url", value: confirmation.redirectUrl, onChange: (e) => setConfirmation((c) => ({ ...c, redirectUrl: e.target.value })), placeholder: "https://example.com/thank-you", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Redirect Delay (ms)" }), _jsx("input", { type: "number", value: confirmation.redirectDelay, onChange: (e) => setConfirmation((c) => ({ ...c, redirectDelay: Number(e.target.value) })), min: 0, step: 500, className: "w-32 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "0 = instant redirect" })] })] }))] }))] }), _jsxs("div", { className: "mb-4 rounded-lg border border-gray-200 bg-white", children: [_jsx("button", { onClick: () => toggleSection('analytics'), className: "flex w-full items-center justify-between p-4 transition-colors hover:bg-gray-50", children: _jsxs("div", { className: "flex items-center gap-2", children: [expandedSection === 'analytics' ? (_jsx(ChevronDown, { className: "h-4 w-4" })) : (_jsx(ChevronRight, { className: "h-4 w-4" })), _jsx(BarChart3, { className: "h-4 w-4 text-purple-600" }), _jsx("span", { className: "font-medium text-gray-900", children: "GA4 Analytics" }), _jsx("span", { className: `rounded px-2 py-0.5 text-xs ${analytics.enabled ? 'bg-green-100 text-green-700' : 'bg-gray-100 text-gray-500'}`, children: analytics.enabled ? 'Enabled' : 'Disabled' })] }) }), expandedSection === 'analytics' && (_jsxs("div", { className: "border-t border-gray-200 p-4", children: [_jsxs("div", { className: "mb-4 flex items-center gap-3", children: [_jsxs("label", { className: "relative inline-flex cursor-pointer items-center", children: [_jsx("input", { type: "checkbox", checked: analytics.enabled, onChange: (e) => setAnalytics((a) => ({ ...a, enabled: e.target.checked })), className: "peer sr-only" }), _jsx("div", { className: "peer h-5 w-9 rounded-full bg-gray-200 peer-checked:bg-blue-600 peer-focus:ring-2 peer-focus:ring-blue-300 peer-focus:outline-none after:absolute after:top-[2px] after:left-[2px] after:h-4 after:w-4 after:rounded-full after:border after:border-gray-300 after:bg-white after:transition-all after:content-[''] peer-checked:after:translate-x-full peer-checked:after:border-white" })] }), _jsx("span", { className: "text-sm font-medium text-gray-700", children: "Push events to Google Analytics 4" })] }), analytics.enabled && (_jsxs("div", { className: "grid gap-4 pl-12", children: [_jsxs("div", { children: [_jsxs("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: ["GA4 Measurement ID", _jsx("span", { className: "font-normal text-gray-400", children: " (optional)" })] }), _jsx("input", { type: "text", value: analytics.measurementId, onChange: (e) => setAnalytics((a) => ({ ...a, measurementId: e.target.value })), placeholder: "G-XXXXXXXXXX", className: "w-64 rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" }), _jsx("p", { className: "mt-1 text-xs text-gray-500", children: "Leave blank to use your site's default GA4 tag" })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Submit Event Name" }), _jsx("input", { type: "text", value: analytics.submitEventName, onChange: (e) => setAnalytics((a) => ({ ...a, submitEventName: e.target.value })), className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Start Event Name" }), _jsx("input", { type: "text", value: analytics.startEventName, onChange: (e) => setAnalytics((a) => ({ ...a, startEventName: e.target.value })), className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" })] })] }), _jsxs("div", { className: "border-t border-gray-200 pt-4", children: [_jsxs("div", { className: "mb-3 flex items-center gap-3", children: [_jsx("input", { type: "checkbox", id: "trackConversion", checked: analytics.trackAsConversion, onChange: (e) => setAnalytics((a) => ({ ...a, trackAsConversion: e.target.checked })), className: "rounded" }), _jsx("label", { htmlFor: "trackConversion", className: "text-sm font-medium text-gray-700", children: "Track as conversion event" })] }), analytics.trackAsConversion && (_jsxs("div", { className: "ml-6 grid grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Conversion Value" }), _jsx("input", { type: "number", value: analytics.conversionValue, onChange: (e) => setAnalytics((a) => ({ ...a, conversionValue: Number(e.target.value) })), min: 0, step: 0.01, className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Currency" }), _jsxs("select", { value: analytics.conversionCurrency, onChange: (e) => setAnalytics((a) => ({ ...a, conversionCurrency: e.target.value })), className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none", children: [_jsx("option", { value: "USD", children: "USD" }), _jsx("option", { value: "EUR", children: "EUR" }), _jsx("option", { value: "GBP", children: "GBP" }), _jsx("option", { value: "CAD", children: "CAD" }), _jsx("option", { value: "AUD", children: "AUD" })] })] })] }))] }), _jsx("div", { className: "rounded-lg border border-blue-200 bg-blue-50 p-3", children: _jsxs("p", { className: "text-xs text-blue-800", children: [_jsx("strong", { children: "Note:" }), " Your site must have the GA4 snippet or GTM container installed. Actuate pushes events via", ' ', _jsx("code", { className: "rounded bg-blue-100 px-1", children: "gtag()" }), " /", _jsx("code", { className: "rounded bg-blue-100 px-1", children: "dataLayer" }), " \u2014 it does not load the GA4 script."] }) })] }))] }))] })] }));
|
|
131
131
|
}
|
|
132
132
|
//# sourceMappingURL=FormEditor.js.map
|
|
@@ -35,10 +35,10 @@ function mediumColor(medium) {
|
|
|
35
35
|
}
|
|
36
36
|
function DeviceIcon({ type }) {
|
|
37
37
|
if (type === 'Mobile')
|
|
38
|
-
return _jsx(Smartphone, { className: "
|
|
38
|
+
return _jsx(Smartphone, { className: "h-3.5 w-3.5" });
|
|
39
39
|
if (type === 'Tablet')
|
|
40
|
-
return _jsx(Tablet, { className: "
|
|
41
|
-
return _jsx(Monitor, { className: "
|
|
40
|
+
return _jsx(Tablet, { className: "h-3.5 w-3.5" });
|
|
41
|
+
return _jsx(Monitor, { className: "h-3.5 w-3.5" });
|
|
42
42
|
}
|
|
43
43
|
export function FormSubmissions({ formId, onNavigate }) {
|
|
44
44
|
const { data, loading, error, refetch } = useApiData(`/forms/${formId}/submissions`);
|
|
@@ -76,13 +76,13 @@ export function FormSubmissions({ formId, onNavigate }) {
|
|
|
76
76
|
toast.success('Submissions exported to CSV (includes attribution data)');
|
|
77
77
|
};
|
|
78
78
|
if (loading) {
|
|
79
|
-
return (_jsx("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8
|
|
79
|
+
return (_jsx("div", { className: "flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-blue-600" }) }));
|
|
80
80
|
}
|
|
81
|
-
return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8", children: [error && (_jsxs("div", { className: "mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "
|
|
81
|
+
return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8", children: [error && (_jsxs("div", { className: "mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "h-5 w-5 shrink-0 text-red-600" }), _jsx("span", { className: "flex-1 text-sm text-red-800", children: error }), _jsx("button", { onClick: refetch, className: "rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100", children: "Retry" })] })), _jsxs("div", { className: "mb-4", children: [_jsxs("button", { onClick: () => onNavigate?.('/forms'), className: "mb-3 inline-flex items-center gap-2 text-sm text-gray-600 transition-colors hover:text-gray-900", children: [_jsx(ArrowLeft, { className: "h-4 w-4" }), "Back to Forms"] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "mb-1 text-2xl font-semibold text-gray-900", children: "Contact Form - Submissions" }), _jsxs("p", { className: "text-sm text-gray-600", children: [filteredSubmissions.length, " submission", filteredSubmissions.length !== 1 ? 's' : ''] })] }), _jsxs("button", { onClick: handleExport, className: "flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700", children: [_jsx(Download, { className: "h-4 w-4" }), "Export CSV"] })] })] }), _jsxs("div", { className: "mb-4 grid grid-cols-2 gap-3 md:grid-cols-5", children: [_jsxs("div", { className: "rounded-lg border border-gray-200 bg-white p-4", children: [_jsx("div", { className: "mb-1 text-xs text-gray-600", children: "Total" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: submissions.length })] }), _jsxs("div", { className: "rounded-lg border border-gray-200 bg-white p-4", children: [_jsx("div", { className: "mb-1 text-xs text-gray-600", children: "New" }), _jsx("div", { className: "text-2xl font-semibold text-blue-600", children: submissions.filter((s) => s.status === 'new').length })] }), _jsxs("div", { className: "rounded-lg border border-gray-200 bg-white p-4", children: [_jsx("div", { className: "mb-1 text-xs text-gray-600", children: "Paid Traffic" }), _jsx("div", { className: "text-2xl font-semibold text-orange-600", children: paidCount })] }), _jsxs("div", { className: "rounded-lg border border-gray-200 bg-white p-4", children: [_jsx("div", { className: "mb-1 text-xs text-gray-600", children: "Organic" }), _jsx("div", { className: "text-2xl font-semibold text-green-600", children: organicCount })] }), _jsxs("div", { className: "rounded-lg border border-gray-200 bg-white p-4", children: [_jsx("div", { className: "mb-1 text-xs text-gray-600", children: "Top Source" }), _jsx("div", { className: "text-lg font-semibold text-gray-900", children: sourceSummary[0]?.[0] ?? '—' })] })] }), _jsxs("div", { className: "mb-4 rounded-lg border border-gray-200 bg-white p-4", children: [_jsxs("h3", { className: "mb-3 flex items-center gap-2 text-sm font-semibold text-gray-900", children: [_jsx(Globe, { className: "h-4 w-4 text-blue-600" }), "Lead Source Breakdown"] }), _jsx("div", { className: "flex flex-wrap gap-2", children: sourceSummary.map(([label, count]) => (_jsxs("div", { className: "flex items-center gap-2 rounded-lg bg-gray-50 px-3 py-1.5", children: [_jsx("span", { className: "text-sm font-medium text-gray-800", children: label }), _jsx("span", { className: "rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-800", children: count })] }, label))) })] }), _jsx("div", { className: "mb-4 rounded-lg border border-gray-200 bg-white", children: _jsxs("div", { className: "flex flex-col gap-3 p-3 sm:flex-row", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search submissions...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), 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" })] }), _jsxs("select", { value: filterStatus, onChange: (e) => setFilterStatus(e.target.value), className: "rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none", children: [_jsx("option", { value: "all", children: "All Status" }), _jsx("option", { value: "new", children: "New" }), _jsx("option", { value: "read", children: "Read" }), _jsx("option", { value: "replied", children: "Replied" })] }), _jsxs("select", { value: filterSource, onChange: (e) => setFilterSource(e.target.value), className: "rounded-lg border border-gray-300 px-3 py-2 text-sm focus:ring-2 focus:ring-blue-500 focus:outline-none", children: [_jsx("option", { value: "all", children: "All Sources" }), uniqueSources.map((src) => (_jsx("option", { value: src, children: src }, src)))] })] }) }), filteredSubmissions.length === 0 ? (_jsx("div", { className: "rounded-lg border border-gray-200 bg-white p-8 text-center", children: _jsx("p", { className: "text-sm text-gray-500", children: "No submissions yet" }) })) : (_jsx("div", { className: "space-y-3", children: filteredSubmissions.map((submission) => {
|
|
82
82
|
const expanded = expandedId === submission.id;
|
|
83
83
|
const attr = submission.attribution;
|
|
84
84
|
const activeClickIds = Object.entries(attr.clickIds).filter(([, v]) => v);
|
|
85
|
-
return (_jsxs("div", { className: "
|
|
85
|
+
return (_jsxs("div", { className: "rounded-lg border border-gray-200 bg-white transition-shadow hover:shadow-md", children: [_jsxs("div", { className: "p-4", children: [_jsxs("div", { className: "mb-3 flex items-start justify-between", children: [_jsxs("div", { className: "flex flex-1 items-start gap-3", children: [_jsx("div", { className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-linear-to-br from-blue-500 to-purple-600 text-sm font-medium text-white", children: submission.name.charAt(0) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "mb-1 flex items-center gap-2", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900", children: submission.name }), _jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${submission.status === 'new' ? 'bg-blue-100 text-blue-800' : submission.status === 'read' ? 'bg-gray-100 text-gray-800' : 'bg-green-100 text-green-800'}`, children: submission.status })] }), _jsxs("div", { className: "mb-2 text-xs text-gray-600", children: [submission.email, submission.phone ? ` · ${submission.phone}` : ''] }), _jsx("p", { className: "text-sm text-gray-700", children: submission.message }), _jsxs("div", { className: "mt-2 text-xs text-gray-500", children: ["Submitted ", submission.submittedAt] })] })] }), _jsx("button", { onClick: () => toast.success('Submission deleted'), className: "rounded p-1.5 transition-colors hover:bg-gray-100", title: "Delete", children: _jsx(Trash2, { className: "h-4 w-4 text-red-600" }) })] }), _jsxs("div", { className: "mt-3 flex flex-wrap items-center gap-2 border-t border-gray-100 pt-3", children: [_jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${sourceColor(attr.source)}`, children: attr.source }), _jsx("span", { className: "text-xs text-gray-400", children: "/" }), _jsx("span", { className: `rounded-full px-2 py-0.5 text-xs font-medium ${mediumColor(attr.medium)}`, children: attr.medium }), attr.campaign && (_jsx("span", { className: "rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-800", children: attr.campaign })), _jsxs("span", { className: "flex items-center gap-1 text-xs text-gray-500", children: [_jsx(DeviceIcon, { type: attr.deviceType }), attr.deviceType] }), activeClickIds.length > 0 && (_jsxs("span", { className: "flex items-center gap-1 text-xs text-gray-500", children: [_jsx(MousePointerClick, { className: "h-3.5 w-3.5" }), activeClickIds.map(([k]) => k).join(', ')] })), _jsxs("button", { onClick: () => setExpandedId(expanded ? null : submission.id), className: "ml-auto flex items-center gap-1 text-xs text-blue-600 transition-colors hover:text-blue-800", children: [expanded ? (_jsx(ChevronUp, { className: "h-3.5 w-3.5" })) : (_jsx(ChevronDown, { className: "h-3.5 w-3.5" })), expanded ? 'Hide' : 'Attribution'] })] }), expanded && (_jsxs("div", { className: "mt-3 space-y-4 rounded-lg border-t border-gray-100 bg-gray-50 p-4 pt-3 text-sm", children: [_jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [_jsxs("div", { children: [_jsx("h4", { className: "mb-2 text-xs font-semibold tracking-wider text-gray-600 uppercase", children: "Traffic Source" }), _jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-500", children: "Source" }), _jsx("span", { className: "font-medium text-gray-900", children: attr.source })] }), _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-500", children: "Medium" }), _jsx("span", { className: "font-medium text-gray-900", children: attr.medium })] }), attr.campaign && (_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-500", children: "Campaign" }), _jsx("span", { className: "font-medium text-gray-900", children: attr.campaign })] })), attr.term && (_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-500", children: "Keyword" }), _jsx("span", { className: "font-medium text-gray-900", children: attr.term })] })), attr.content && (_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-500", children: "Content" }), _jsx("span", { className: "font-medium text-gray-900", children: attr.content })] }))] })] }), _jsxs("div", { children: [_jsx("h4", { className: "mb-2 text-xs font-semibold tracking-wider text-gray-600 uppercase", children: "Page Context" }), _jsxs("div", { className: "space-y-1.5", children: [_jsxs("div", { children: [_jsx("span", { className: "text-xs text-gray-500", children: "Landing Page" }), _jsxs("div", { className: "mt-0.5 flex items-center gap-1", children: [_jsx(MapPin, { className: "h-3 w-3 shrink-0 text-gray-400" }), _jsx("span", { className: "text-xs font-medium break-all text-gray-900", children: attr.landingPage })] })] }), attr.referrer && (_jsxs("div", { children: [_jsx("span", { className: "text-xs text-gray-500", children: "Referrer" }), _jsxs("div", { className: "mt-0.5 flex items-center gap-1", children: [_jsx(ExternalLink, { className: "h-3 w-3 shrink-0 text-gray-400" }), _jsx("span", { className: "text-xs font-medium break-all text-gray-900", children: attr.referrer })] })] })), _jsxs("div", { className: "flex justify-between", children: [_jsx("span", { className: "text-gray-500", children: "Device" }), _jsxs("span", { className: "flex items-center gap-1 font-medium text-gray-900", children: [_jsx(DeviceIcon, { type: attr.deviceType }), attr.deviceType] })] })] })] })] }), activeClickIds.length > 0 && (_jsxs("div", { children: [_jsx("h4", { className: "mb-2 text-xs font-semibold tracking-wider text-gray-600 uppercase", children: "Click IDs" }), _jsx("div", { className: "flex flex-wrap gap-2", children: activeClickIds.map(([key, val]) => (_jsxs("div", { className: "rounded-lg border border-gray-200 bg-white px-2.5 py-1", children: [_jsxs("span", { className: "text-xs text-gray-500", children: [key, ": "] }), _jsxs("span", { className: "font-mono text-xs text-gray-800", children: [String(val).slice(0, 20), "..."] })] }, key))) })] })), _jsxs("div", { className: "text-xs text-gray-500", children: ["Attribution captured ", attr.capturedAt] })] }))] }), _jsxs("div", { className: "flex items-center gap-2 border-t border-gray-200 px-4 py-3", children: [_jsx("button", { className: "rounded-lg bg-blue-600 px-3 py-1.5 text-sm text-white transition-colors hover:bg-blue-700", children: "Reply" }), _jsx("button", { className: "rounded-lg border border-gray-300 px-3 py-1.5 text-sm transition-colors hover:bg-gray-50", children: "Mark as Read" })] })] }, submission.id));
|
|
86
86
|
}) }))] }));
|
|
87
87
|
}
|
|
88
88
|
//# sourceMappingURL=FormSubmissions.js.map
|
package/dist/views/Forms.js
CHANGED
|
@@ -17,8 +17,8 @@ export function Forms({ onNavigate }) {
|
|
|
17
17
|
return results;
|
|
18
18
|
}, [forms, searchQuery]);
|
|
19
19
|
if (loading) {
|
|
20
|
-
return (_jsx("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8
|
|
20
|
+
return (_jsx("div", { className: "flex h-64 items-center justify-center p-3 pr-6 sm:p-4 sm:pr-8", children: _jsx(Loader2, { className: "h-6 w-6 animate-spin text-blue-600" }) }));
|
|
21
21
|
}
|
|
22
|
-
return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8", children: [error && (_jsxs("div", { className: "mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "
|
|
22
|
+
return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8", children: [error && (_jsxs("div", { className: "mb-4 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "h-5 w-5 shrink-0 text-red-600" }), _jsx("span", { className: "flex-1 text-sm text-red-800", children: error }), _jsx("button", { onClick: refetch, className: "rounded-lg border border-red-300 px-3 py-1 text-sm text-red-700 transition-colors hover:bg-red-100", children: "Retry" })] })), _jsxs("div", { className: "mb-4 flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("h1", { className: "mb-1 text-xl font-semibold text-gray-900 sm:text-2xl", children: "Forms" }), _jsxs("p", { className: "text-sm text-gray-600", children: [filteredAndSorted.length, " total forms"] })] }), _jsxs("button", { onClick: () => onNavigate?.('/forms/new'), className: "flex items-center gap-2 rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700", children: [_jsx(Plus, { className: "h-4 w-4" }), "New Form"] })] }), _jsx("div", { className: "mb-4 rounded-lg border border-gray-200 bg-white", children: _jsx("div", { className: "p-3", children: _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search forms...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), 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" })] }) }) }), filteredAndSorted.length === 0 ? (_jsxs("div", { className: "rounded-lg border border-gray-200 bg-white p-8 text-center", children: [_jsx("p", { className: "mb-2 text-sm text-gray-500", children: "No forms yet" }), _jsx("button", { className: "rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700", children: "Create your first form" })] })) : (_jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3", children: filteredAndSorted.map((form) => (_jsxs("div", { className: "rounded-lg border border-gray-200 bg-white p-4 transition-shadow hover:shadow-md", children: [_jsxs("div", { className: "mb-3 flex items-start justify-between", children: [_jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "mb-1 font-semibold text-gray-900", children: form.name }), _jsx("p", { className: "mb-2 text-sm text-gray-600", children: form.description })] }), _jsx("button", { className: "rounded p-1.5 transition-colors hover:bg-gray-100", children: _jsx(MoreVertical, { className: "h-4 w-4 text-gray-600" }) })] }), _jsxs("div", { className: "mb-3 flex items-center gap-4 text-sm text-gray-600", children: [_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(FileText, { className: "h-4 w-4" }), form.fields, " fields"] }), _jsxs("span", { className: "flex items-center gap-1", children: [_jsx(Send, { className: "h-4 w-4" }), form.submissions, " submissions"] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: () => onNavigate?.(`/forms/${form.id}/submissions`), className: "flex-1 rounded-lg bg-blue-600 px-3 py-1.5 text-center text-sm text-white transition-colors hover:bg-blue-700", children: "View Submissions" }), _jsx("button", { onClick: () => onNavigate?.(`/forms/${form.id}/edit`), className: "rounded-lg border border-gray-300 px-3 py-1.5 text-sm transition-colors hover:bg-gray-50", children: "Edit" })] })] }, form.id))) }))] }));
|
|
23
23
|
}
|
|
24
24
|
//# sourceMappingURL=Forms.js.map
|
package/dist/views/Login.d.ts
CHANGED
|
@@ -2,6 +2,16 @@ export interface CaptchaConfig {
|
|
|
2
2
|
provider: 'recaptcha' | 'turnstile' | 'none';
|
|
3
3
|
siteKey: string | null;
|
|
4
4
|
}
|
|
5
|
+
/**
|
|
6
|
+
* Branding shown on the login screen. Mirrors `config.admin.branding` from the
|
|
7
|
+
* sidebar so integrators only need to set it once. `logo` should be a URL or
|
|
8
|
+
* data URL; pass `null` to opt out of any logo entirely.
|
|
9
|
+
*/
|
|
10
|
+
export interface LoginBrandingConfig {
|
|
11
|
+
logo?: string | null;
|
|
12
|
+
name?: string;
|
|
13
|
+
tagline?: string;
|
|
14
|
+
}
|
|
5
15
|
export interface LoginProps {
|
|
6
16
|
onLogin: (email: string, password: string, captchaToken?: string) => Promise<{
|
|
7
17
|
success: boolean;
|
|
@@ -10,6 +20,11 @@ export interface LoginProps {
|
|
|
10
20
|
onNavigate?: (path: string) => void;
|
|
11
21
|
oauthProviders?: string[];
|
|
12
22
|
captchaConfig?: CaptchaConfig;
|
|
23
|
+
/**
|
|
24
|
+
* Custom branding for the login screen. Falls back to the bundled Actuate
|
|
25
|
+
* Media wordmark + "Actuate CMS" headline when omitted.
|
|
26
|
+
*/
|
|
27
|
+
branding?: LoginBrandingConfig;
|
|
13
28
|
}
|
|
14
|
-
export declare function Login({ onLogin, onNavigate, oauthProviders, captchaConfig }: LoginProps): import("react/jsx-runtime").JSX.Element;
|
|
29
|
+
export declare function Login({ onLogin, onNavigate, oauthProviders, captchaConfig, branding, }: LoginProps): import("react/jsx-runtime").JSX.Element;
|
|
15
30
|
//# sourceMappingURL=Login.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Login.d.ts","sourceRoot":"","sources":["../../src/views/Login.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Login.d.ts","sourceRoot":"","sources":["../../src/views/Login.tsx"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,CAAA;IAC5C,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CACvB;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,CACP,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,YAAY,CAAC,EAAE,MAAM,KAClB,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAClD,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;IACzB,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;OAGG;IACH,QAAQ,CAAC,EAAE,mBAAmB,CAAA;CAC/B;AAyJD,wBAAgB,KAAK,CAAC,EACpB,OAAO,EACP,UAAU,EACV,cAAc,EACd,aAAa,EACb,QAAQ,GACT,EAAE,UAAU,2CA6LZ"}
|
package/dist/views/Login.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from 'react';
|
|
4
|
-
import {
|
|
4
|
+
import { Eye, EyeOff, AlertTriangle, Loader2 } from 'lucide-react';
|
|
5
|
+
import { ActuateBrandLogo } from '../assets/actuate-logo.js';
|
|
5
6
|
const OAUTH_LABELS = {
|
|
6
7
|
google: 'Google',
|
|
7
8
|
github: 'GitHub',
|
|
@@ -28,17 +29,17 @@ const OAUTH_COLORS = {
|
|
|
28
29
|
},
|
|
29
30
|
};
|
|
30
31
|
function GoogleIcon() {
|
|
31
|
-
return (_jsxs("svg", { className: "
|
|
32
|
+
return (_jsxs("svg", { className: "h-5 w-5", viewBox: "0 0 24 24", "aria-hidden": "true", children: [_jsx("path", { d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 01-2.2 3.32v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.1z", fill: "#4285F4" }), _jsx("path", { d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z", fill: "#34A853" }), _jsx("path", { d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z", fill: "#FBBC05" }), _jsx("path", { d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z", fill: "#EA4335" })] }));
|
|
32
33
|
}
|
|
33
34
|
function MicrosoftIcon() {
|
|
34
|
-
return (_jsxs("svg", { className: "
|
|
35
|
+
return (_jsxs("svg", { className: "h-5 w-5", viewBox: "0 0 21 21", "aria-hidden": "true", children: [_jsx("rect", { x: "1", y: "1", width: "9", height: "9", fill: "#F25022" }), _jsx("rect", { x: "1", y: "11", width: "9", height: "9", fill: "#00A4EF" }), _jsx("rect", { x: "11", y: "1", width: "9", height: "9", fill: "#7FBA00" }), _jsx("rect", { x: "11", y: "11", width: "9", height: "9", fill: "#FFB900" })] }));
|
|
35
36
|
}
|
|
36
37
|
function OAuthIcon({ provider }) {
|
|
37
38
|
switch (provider) {
|
|
38
39
|
case 'google':
|
|
39
40
|
return _jsx(GoogleIcon, {});
|
|
40
41
|
case 'github':
|
|
41
|
-
return (_jsx("svg", { className: "
|
|
42
|
+
return (_jsx("svg", { className: "h-5 w-5", viewBox: "0 0 24 24", fill: "currentColor", children: _jsx("path", { d: "M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0024 12c0-6.63-5.37-12-12-12z" }) }));
|
|
42
43
|
case 'microsoft':
|
|
43
44
|
return _jsx(MicrosoftIcon, {});
|
|
44
45
|
default:
|
|
@@ -115,7 +116,7 @@ async function getCaptchaToken(provider, siteKey, action) {
|
|
|
115
116
|
}
|
|
116
117
|
return '';
|
|
117
118
|
}
|
|
118
|
-
export function Login({ onLogin, onNavigate, oauthProviders, captchaConfig }) {
|
|
119
|
+
export function Login({ onLogin, onNavigate, oauthProviders, captchaConfig, branding, }) {
|
|
119
120
|
const [email, setEmail] = useState('');
|
|
120
121
|
const [password, setPassword] = useState('');
|
|
121
122
|
const [showPassword, setShowPassword] = useState(false);
|
|
@@ -155,9 +156,18 @@ export function Login({ onLogin, onNavigate, oauthProviders, captchaConfig }) {
|
|
|
155
156
|
window.location.href = `/api/cms/auth/oauth/${provider}`;
|
|
156
157
|
};
|
|
157
158
|
const enabledProviders = oauthProviders?.filter((p) => ['google', 'github', 'microsoft'].includes(p)) ?? [];
|
|
158
|
-
|
|
159
|
+
// Branding fallbacks: when an integrator doesn't pass `branding`, render the
|
|
160
|
+
// Actuate Media wordmark inline (transparent SVG, no surrounding pill needed).
|
|
161
|
+
// When `branding.logo` is explicitly `null`, render no logo at all (just the
|
|
162
|
+
// headline + tagline) so whitelabel deployments can hide it entirely.
|
|
163
|
+
const customLogo = branding?.logo;
|
|
164
|
+
const brandName = branding?.name ?? 'Actuate CMS';
|
|
165
|
+
const brandTagline = branding?.tagline ?? 'Sign in to your account';
|
|
166
|
+
const showLogo = customLogo !== null;
|
|
167
|
+
return (_jsx("div", { className: "flex min-h-screen items-center justify-center bg-gray-50 px-4", children: _jsxs("div", { className: "w-full max-w-md", children: [_jsxs("div", { className: "mb-8 text-center", children: [showLogo &&
|
|
168
|
+
(customLogo ? (_jsx("img", { src: customLogo, alt: brandName, className: "mx-auto mb-4 max-h-16 w-auto object-contain", draggable: false })) : (_jsx(ActuateBrandLogo, { className: "mx-auto mb-4 h-14 w-auto" }))), _jsx("h1", { className: "text-2xl font-bold text-gray-900", children: brandName }), _jsx("p", { className: "mt-2 text-gray-600", children: brandTagline })] }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-5 rounded-xl border border-gray-200 bg-white p-6 shadow-sm", children: [error && (_jsxs("div", { className: "flex items-start gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "mt-0.5 h-5 w-5 shrink-0 text-red-600" }), _jsx("p", { className: "text-sm text-red-800", children: error })] })), _jsxs("div", { children: [_jsx("label", { htmlFor: "login-email", className: "mb-1.5 block text-sm font-medium text-gray-700", children: "Email Address" }), _jsx("input", { id: "login-email", type: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "admin@example.com", className: "w-full rounded-lg border border-gray-300 px-3 py-2.5 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none", required: true, autoFocus: true, autoComplete: "email" })] }), _jsxs("div", { children: [_jsxs("div", { className: "mb-1.5 flex items-center justify-between", children: [_jsx("label", { htmlFor: "login-password", className: "block text-sm font-medium text-gray-700", children: "Password" }), onNavigate && (_jsx("button", { type: "button", onClick: () => onNavigate('/forgot-password'), className: "text-xs font-medium text-blue-600 hover:text-blue-700", children: "Forgot Password?" }))] }), _jsxs("div", { className: "relative", children: [_jsx("input", { id: "login-password", type: showPassword ? 'text' : 'password', value: password, onChange: (e) => setPassword(e.target.value), placeholder: "Enter your password", className: "w-full rounded-lg border border-gray-300 px-3 py-2.5 pr-10 text-sm focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none", required: true, autoComplete: "current-password" }), _jsx("button", { type: "button", onClick: () => setShowPassword(!showPassword), className: "absolute top-1/2 right-3 -translate-y-1/2 text-gray-400 hover:text-gray-600", tabIndex: -1, children: showPassword ? _jsx(EyeOff, { className: "h-4 w-4" }) : _jsx(Eye, { className: "h-4 w-4" }) })] })] }), _jsx("button", { type: "submit", disabled: !canSubmit, className: "flex w-full items-center justify-center gap-2 rounded-lg bg-blue-600 py-2.5 font-medium text-white transition-colors hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50", children: submitting ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { className: "h-4 w-4 animate-spin" }), "Signing in..."] })) : ('Sign In') }), enabledProviders.length > 0 && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "relative", children: [_jsx("div", { className: "absolute inset-0 flex items-center", children: _jsx("div", { className: "w-full border-t border-gray-200" }) }), _jsx("div", { className: "relative flex justify-center text-sm", children: _jsx("span", { className: "bg-white px-3 text-gray-500", children: "Or continue with" }) })] }), _jsx("div", { className: "grid gap-3", children: enabledProviders.map((provider) => {
|
|
159
169
|
const colors = OAUTH_COLORS[provider] ?? OAUTH_COLORS.google;
|
|
160
|
-
return (_jsxs("button", { type: "button", onClick: () => handleOAuthClick(provider), className: `w-full
|
|
170
|
+
return (_jsxs("button", { type: "button", onClick: () => handleOAuthClick(provider), className: `flex w-full items-center justify-center gap-3 border px-4 py-2.5 ${colors?.border ?? ''} ${colors?.bg ?? ''} ${colors?.text ?? ''} rounded-lg text-sm font-medium ${colors?.hover ?? ''} transition-colors`, children: [_jsx(OAuthIcon, { provider: provider }), OAUTH_LABELS[provider] ?? provider] }, provider));
|
|
161
171
|
}) })] }))] })] }) }));
|
|
162
172
|
}
|
|
163
173
|
//# sourceMappingURL=Login.js.map
|
package/dist/views/Login.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Login.js","sourceRoot":"","sources":["../../src/views/Login.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAA;AAChD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"Login.js","sourceRoot":"","sources":["../../src/views/Login.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAA;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAClE,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAkC5D,MAAM,YAAY,GAA2B;IAC3C,MAAM,EAAE,QAAQ;IAChB,MAAM,EAAE,QAAQ;IAChB,SAAS,EAAE,WAAW;CACvB,CAAA;AAED,MAAM,YAAY,GAAgF;IAChG,MAAM,EAAE;QACN,MAAM,EAAE,iBAAiB;QACzB,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,kBAAkB;KAC1B;IACD,MAAM,EAAE;QACN,MAAM,EAAE,iBAAiB;QACzB,EAAE,EAAE,aAAa;QACjB,IAAI,EAAE,YAAY;QAClB,KAAK,EAAE,mBAAmB;KAC3B;IACD,SAAS,EAAE;QACT,MAAM,EAAE,iBAAiB;QACzB,EAAE,EAAE,UAAU;QACd,IAAI,EAAE,eAAe;QACrB,KAAK,EAAE,kBAAkB;KAC1B;CACF,CAAA;AAED,SAAS,UAAU;IACjB,OAAO,CACL,eAAK,SAAS,EAAC,SAAS,EAAC,OAAO,EAAC,WAAW,iBAAa,MAAM,aAC7D,eACE,CAAC,EAAC,kHAAkH,EACpH,IAAI,EAAC,SAAS,GACd,EACF,eACE,CAAC,EAAC,uIAAuI,EACzI,IAAI,EAAC,SAAS,GACd,EACF,eACE,CAAC,EAAC,+HAA+H,EACjI,IAAI,EAAC,SAAS,GACd,EACF,eACE,CAAC,EAAC,qIAAqI,EACvI,IAAI,EAAC,SAAS,GACd,IACE,CACP,CAAA;AACH,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,CACL,eAAK,SAAS,EAAC,SAAS,EAAC,OAAO,EAAC,WAAW,iBAAa,MAAM,aAC7D,eAAM,CAAC,EAAC,GAAG,EAAC,CAAC,EAAC,GAAG,EAAC,KAAK,EAAC,GAAG,EAAC,MAAM,EAAC,GAAG,EAAC,IAAI,EAAC,SAAS,GAAG,EACxD,eAAM,CAAC,EAAC,GAAG,EAAC,CAAC,EAAC,IAAI,EAAC,KAAK,EAAC,GAAG,EAAC,MAAM,EAAC,GAAG,EAAC,IAAI,EAAC,SAAS,GAAG,EACzD,eAAM,CAAC,EAAC,IAAI,EAAC,CAAC,EAAC,GAAG,EAAC,KAAK,EAAC,GAAG,EAAC,MAAM,EAAC,GAAG,EAAC,IAAI,EAAC,SAAS,GAAG,EACzD,eAAM,CAAC,EAAC,IAAI,EAAC,CAAC,EAAC,IAAI,EAAC,KAAK,EAAC,GAAG,EAAC,MAAM,EAAC,GAAG,EAAC,IAAI,EAAC,SAAS,GAAG,IACtD,CACP,CAAA;AACH,CAAC;AAED,SAAS,SAAS,CAAC,EAAE,QAAQ,EAAwB;IACnD,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,QAAQ;YACX,OAAO,KAAC,UAAU,KAAG,CAAA;QACvB,KAAK,QAAQ;YACX,OAAO,CACL,cAAK,SAAS,EAAC,SAAS,EAAC,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,cAAc,YAC9D,eAAM,CAAC,EAAC,ypBAAypB,GAAG,GAChqB,CACP,CAAA;QACH,KAAK,WAAW;YACd,OAAO,KAAC,aAAa,KAAG,CAAA;QAC1B;YACE,OAAO,IAAI,CAAA;IACf,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,QAA4B,EAAE,OAAkC;IACxF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAE3C,QAAQ,CAAC,GAAG,EAAE;QACZ,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,CAAC,OAAO;YAAE,OAAM;QAErD,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YAC7B,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAA;YACnE,IAAI,QAAQ,EAAE,CAAC;gBACb,SAAS,CAAC,IAAI,CAAC,CAAA;gBACf,OAAM;YACR,CAAC;YACD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;YAC/C,MAAM,CAAC,GAAG,GAAG,kDAAkD,OAAO,EAAE,CAAA;YACxE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAA;YACnB,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YACrC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;aAAM,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,QAAQ,CAAC,aAAa,CAAC,0BAA0B,CAAC,CAAA;YACnE,IAAI,QAAQ,EAAE,CAAC;gBACb,SAAS,CAAC,IAAI,CAAC,CAAA;gBACf,OAAM;YACR,CAAC;YACD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAA;YAC/C,MAAM,CAAC,GAAG,GAAG,uDAAuD,CAAA;YACpE,MAAM,CAAC,KAAK,GAAG,IAAI,CAAA;YACnB,MAAM,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAA;YACrC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAA;QACnC,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,QAAgB,EAAE,OAAe,EAAE,MAAc;IAC9E,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAI,MAAc,CAAC,UAAU,CAAA;QAC7C,IAAI,CAAC,UAAU;YAAE,OAAO,EAAE,CAAA;QAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,UAAU,CAAC,KAAK,CAAC,GAAG,EAAE;gBACpB,UAAU;qBACP,OAAO,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC;qBAC5B,IAAI,CAAC,OAAO,CAAC;qBACb,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;YAC7B,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC7B,MAAM,SAAS,GAAI,MAAc,CAAC,SAAS,CAAA;QAC3C,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAA;QACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,MAAM,SAAS,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;YAC/C,SAAS,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAA;YAChC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;YACpC,SAAS,CAAC,MAAM,CAAC,SAAS,EAAE;gBAC1B,OAAO,EAAE,OAAO;gBAChB,MAAM;gBACN,QAAQ,EAAE,CAAC,KAAa,EAAE,EAAE;oBAC1B,SAAS,CAAC,MAAM,EAAE,CAAA;oBAClB,OAAO,CAAC,KAAK,CAAC,CAAA;gBAChB,CAAC;gBACD,gBAAgB,EAAE,GAAG,EAAE;oBACrB,SAAS,CAAC,MAAM,EAAE,CAAA;oBAClB,OAAO,CAAC,EAAE,CAAC,CAAA;gBACb,CAAC;aACF,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,EAAE,CAAA;AACX,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,EACpB,OAAO,EACP,UAAU,EACV,cAAc,EACd,aAAa,EACb,QAAQ,GACG;IACX,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACtC,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAC5C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACvD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IAEtC,gBAAgB,CAAC,aAAa,EAAE,QAAQ,EAAE,aAAa,EAAE,OAAO,CAAC,CAAA;IAEjE,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,EAAE,IAAI,QAAQ,IAAI,CAAC,UAAU,CAAA;IAEzD,MAAM,YAAY,GAAG,KAAK,EAAE,CAAY,EAAE,EAAE;QAC1C,CAAC,CAAC,cAAc,EAAE,CAAA;QAClB,IAAI,CAAC,SAAS;YAAE,OAAM;QAEtB,QAAQ,CAAC,EAAE,CAAC,CAAA;QACZ,aAAa,CAAC,IAAI,CAAC,CAAA;QAEnB,IAAI,CAAC;YACH,IAAI,YAAgC,CAAA;YACpC,IAAI,aAAa,EAAE,QAAQ,IAAI,aAAa,CAAC,QAAQ,KAAK,MAAM,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;gBAC1F,YAAY,GAAG,MAAM,eAAe,CAAC,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;gBAC5F,IAAI,CAAC,YAAY,EAAE,CAAC;oBAClB,QAAQ,CAAC,gDAAgD,CAAC,CAAA;oBAC1D,aAAa,CAAC,KAAK,CAAC,CAAA;oBACpB,OAAM;gBACR,CAAC;YACH,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAA;YAElE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,QAAQ,CAAC,MAAM,CAAC,KAAK,IAAI,2BAA2B,CAAC,CAAA;YACvD,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,8BAA8B,CAAC,CAAA;QAC/E,CAAC;gBAAS,CAAC;YACT,aAAa,CAAC,KAAK,CAAC,CAAA;QACtB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,gBAAgB,GAAG,CAAC,QAAgB,EAAE,EAAE;QAC5C,MAAM,CAAC,QAAQ,CAAC,IAAI,GAAG,uBAAuB,QAAQ,EAAE,CAAA;IAC1D,CAAC,CAAA;IAED,MAAM,gBAAgB,GACpB,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAEpF,6EAA6E;IAC7E,+EAA+E;IAC/E,6EAA6E;IAC7E,sEAAsE;IACtE,MAAM,UAAU,GAAG,QAAQ,EAAE,IAAI,CAAA;IACjC,MAAM,SAAS,GAAG,QAAQ,EAAE,IAAI,IAAI,aAAa,CAAA;IACjD,MAAM,YAAY,GAAG,QAAQ,EAAE,OAAO,IAAI,yBAAyB,CAAA;IACnE,MAAM,QAAQ,GAAG,UAAU,KAAK,IAAI,CAAA;IAEpC,OAAO,CACL,cAAK,SAAS,EAAC,+DAA+D,YAC5E,eAAK,SAAS,EAAC,iBAAiB,aAC9B,eAAK,SAAS,EAAC,kBAAkB,aAC9B,QAAQ;4BACP,CAAC,UAAU,CAAC,CAAC,CAAC,CACZ,cACE,GAAG,EAAE,UAAU,EACf,GAAG,EAAE,SAAS,EACd,SAAS,EAAC,6CAA6C,EACvD,SAAS,EAAE,KAAK,GAChB,CACH,CAAC,CAAC,CAAC,CACF,KAAC,gBAAgB,IAAC,SAAS,EAAC,0BAA0B,GAAG,CAC1D,CAAC,EACJ,aAAI,SAAS,EAAC,kCAAkC,YAAE,SAAS,GAAM,EACjE,YAAG,SAAS,EAAC,oBAAoB,YAAE,YAAY,GAAK,IAChD,EAEN,gBACE,QAAQ,EAAE,YAAY,EACtB,SAAS,EAAC,oEAAoE,aAE7E,KAAK,IAAI,CACR,eAAK,SAAS,EAAC,uEAAuE,aACpF,KAAC,aAAa,IAAC,SAAS,EAAC,sCAAsC,GAAG,EAClE,YAAG,SAAS,EAAC,sBAAsB,YAAE,KAAK,GAAK,IAC3C,CACP,EAED,0BACE,gBAAO,OAAO,EAAC,aAAa,EAAC,SAAS,EAAC,gDAAgD,8BAE/E,EACR,gBACE,EAAE,EAAC,aAAa,EAChB,IAAI,EAAC,OAAO,EACZ,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EACzC,WAAW,EAAC,mBAAmB,EAC/B,SAAS,EAAC,wIAAwI,EAClJ,QAAQ,QACR,SAAS,QACT,YAAY,EAAC,OAAO,GACpB,IACE,EAEN,0BACE,eAAK,SAAS,EAAC,0CAA0C,aACvD,gBAAO,OAAO,EAAC,gBAAgB,EAAC,SAAS,EAAC,yCAAyC,yBAE3E,EACP,UAAU,IAAI,CACb,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,kBAAkB,CAAC,EAC7C,SAAS,EAAC,uDAAuD,iCAG1D,CACV,IACG,EACN,eAAK,SAAS,EAAC,UAAU,aACvB,gBACE,EAAE,EAAC,gBAAgB,EACnB,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,UAAU,EACxC,KAAK,EAAE,QAAQ,EACf,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5C,WAAW,EAAC,qBAAqB,EACjC,SAAS,EAAC,8IAA8I,EACxJ,QAAQ,QACR,YAAY,EAAC,kBAAkB,GAC/B,EACF,iBACE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC,YAAY,CAAC,EAC7C,SAAS,EAAC,6EAA6E,EACvF,QAAQ,EAAE,CAAC,CAAC,YAEX,YAAY,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,SAAS,EAAC,SAAS,GAAG,CAAC,CAAC,CAAC,KAAC,GAAG,IAAC,SAAS,EAAC,SAAS,GAAG,GACrE,IACL,IACF,EAEN,iBACE,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,CAAC,SAAS,EACpB,SAAS,EAAC,wLAAwL,YAEjM,UAAU,CAAC,CAAC,CAAC,CACZ,8BACE,KAAC,OAAO,IAAC,SAAS,EAAC,sBAAsB,GAAG,qBAE3C,CACJ,CAAC,CAAC,CAAC,CACF,SAAS,CACV,GACM,EAER,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,CAC9B,8BACE,eAAK,SAAS,EAAC,UAAU,aACvB,cAAK,SAAS,EAAC,oCAAoC,YACjD,cAAK,SAAS,EAAC,iCAAiC,GAAG,GAC/C,EACN,cAAK,SAAS,EAAC,sCAAsC,YACnD,eAAM,SAAS,EAAC,6BAA6B,iCAAwB,GACjE,IACF,EAEN,cAAK,SAAS,EAAC,YAAY,YACxB,gBAAgB,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE;wCACjC,MAAM,MAAM,GAAG,YAAY,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC,MAAM,CAAA;wCAC5D,OAAO,CACL,kBAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EACzC,SAAS,EAAE,oEAAoE,MAAM,EAAE,MAAM,IAAI,EAAE,IAAI,MAAM,EAAE,EAAE,IAAI,EAAE,IAAI,MAAM,EAAE,IAAI,IAAI,EAAE,mCAAmC,MAAM,EAAE,KAAK,IAAI,EAAE,oBAAoB,aAEvN,KAAC,SAAS,IAAC,QAAQ,EAAE,QAAQ,GAAI,EAChC,YAAY,CAAC,QAAQ,CAAC,IAAI,QAAQ,KAN9B,QAAQ,CAON,CACV,CAAA;oCACH,CAAC,CAAC,GACE,IACL,CACJ,IACI,IACH,GACF,CACP,CAAA;AACH,CAAC"}
|