@actuate-media/cms-admin 0.1.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 +21 -0
- package/dist/AdminRoot.d.ts.map +1 -0
- package/dist/AdminRoot.js +136 -0
- package/dist/AdminRoot.js.map +1 -0
- package/dist/components/Breadcrumbs.d.ts +6 -0
- package/dist/components/Breadcrumbs.d.ts.map +1 -0
- package/dist/components/Breadcrumbs.js +52 -0
- package/dist/components/Breadcrumbs.js.map +1 -0
- package/dist/components/CommandPalette.d.ts +7 -0
- package/dist/components/CommandPalette.d.ts.map +1 -0
- package/dist/components/CommandPalette.js +152 -0
- package/dist/components/CommandPalette.js.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +17 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.js +24 -0
- package/dist/components/ErrorBoundary.js.map +1 -0
- package/dist/components/FocalPointPicker.d.ts +9 -0
- package/dist/components/FocalPointPicker.d.ts.map +1 -0
- package/dist/components/FocalPointPicker.js +19 -0
- package/dist/components/FocalPointPicker.js.map +1 -0
- package/dist/components/FolderTree.d.ts +28 -0
- package/dist/components/FolderTree.d.ts.map +1 -0
- package/dist/components/FolderTree.js +198 -0
- package/dist/components/FolderTree.js.map +1 -0
- package/dist/components/LivePreview.d.ts +10 -0
- package/dist/components/LivePreview.d.ts.map +1 -0
- package/dist/components/LivePreview.js +62 -0
- package/dist/components/LivePreview.js.map +1 -0
- package/dist/components/LocaleProvider.d.ts +28 -0
- package/dist/components/LocaleProvider.d.ts.map +1 -0
- package/dist/components/LocaleProvider.js +29 -0
- package/dist/components/LocaleProvider.js.map +1 -0
- package/dist/components/LocaleSwitcher.d.ts +2 -0
- package/dist/components/LocaleSwitcher.d.ts.map +1 -0
- package/dist/components/LocaleSwitcher.js +13 -0
- package/dist/components/LocaleSwitcher.js.map +1 -0
- package/dist/components/MediaPickerModal.d.ts +8 -0
- package/dist/components/MediaPickerModal.d.ts.map +1 -0
- package/dist/components/MediaPickerModal.js +53 -0
- package/dist/components/MediaPickerModal.js.map +1 -0
- package/dist/components/PresenceIndicator.d.ts +7 -0
- package/dist/components/PresenceIndicator.d.ts.map +1 -0
- package/dist/components/PresenceIndicator.js +37 -0
- package/dist/components/PresenceIndicator.js.map +1 -0
- package/dist/components/SEOPanel.d.ts +26 -0
- package/dist/components/SEOPanel.d.ts.map +1 -0
- package/dist/components/SEOPanel.js +249 -0
- package/dist/components/SEOPanel.js.map +1 -0
- package/dist/components/ThemeProvider.d.ts +13 -0
- package/dist/components/ThemeProvider.d.ts.map +1 -0
- package/dist/components/ThemeProvider.js +62 -0
- package/dist/components/ThemeProvider.js.map +1 -0
- package/dist/components/TipTapEditor.d.ts +9 -0
- package/dist/components/TipTapEditor.d.ts.map +1 -0
- package/dist/components/TipTapEditor.js +167 -0
- package/dist/components/TipTapEditor.js.map +1 -0
- package/dist/components/VersionHistory.d.ts +9 -0
- package/dist/components/VersionHistory.d.ts.map +1 -0
- package/dist/components/VersionHistory.js +70 -0
- package/dist/components/VersionHistory.js.map +1 -0
- package/dist/components/ui/Avatar.d.ts +9 -0
- package/dist/components/ui/Avatar.d.ts.map +1 -0
- package/dist/components/ui/Avatar.js +21 -0
- package/dist/components/ui/Avatar.js.map +1 -0
- package/dist/components/ui/Badge.d.ts +5 -0
- package/dist/components/ui/Badge.d.ts.map +1 -0
- package/dist/components/ui/Badge.js +17 -0
- package/dist/components/ui/Badge.js.map +1 -0
- package/dist/components/ui/Button.d.ts +12 -0
- package/dist/components/ui/Button.d.ts.map +1 -0
- package/dist/components/ui/Button.js +17 -0
- package/dist/components/ui/Button.js.map +1 -0
- package/dist/components/ui/CommandPalette.d.ts +14 -0
- package/dist/components/ui/CommandPalette.d.ts.map +1 -0
- package/dist/components/ui/CommandPalette.js +52 -0
- package/dist/components/ui/CommandPalette.js.map +1 -0
- package/dist/components/ui/ConfirmDialog.d.ts +12 -0
- package/dist/components/ui/ConfirmDialog.d.ts.map +1 -0
- package/dist/components/ui/ConfirmDialog.js +11 -0
- package/dist/components/ui/ConfirmDialog.js.map +1 -0
- package/dist/components/ui/DataTable.d.ts +30 -0
- package/dist/components/ui/DataTable.d.ts.map +1 -0
- package/dist/components/ui/DataTable.js +40 -0
- package/dist/components/ui/DataTable.js.map +1 -0
- package/dist/components/ui/EmptyState.d.ts +10 -0
- package/dist/components/ui/EmptyState.d.ts.map +1 -0
- package/dist/components/ui/EmptyState.js +6 -0
- package/dist/components/ui/EmptyState.js.map +1 -0
- package/dist/components/ui/Modal.d.ts +10 -0
- package/dist/components/ui/Modal.d.ts.map +1 -0
- package/dist/components/ui/Modal.js +19 -0
- package/dist/components/ui/Modal.js.map +1 -0
- package/dist/components/ui/Pagination.d.ts +9 -0
- package/dist/components/ui/Pagination.d.ts.map +1 -0
- package/dist/components/ui/Pagination.js +21 -0
- package/dist/components/ui/Pagination.js.map +1 -0
- package/dist/components/ui/SearchInput.d.ts +7 -0
- package/dist/components/ui/SearchInput.d.ts.map +1 -0
- package/dist/components/ui/SearchInput.js +6 -0
- package/dist/components/ui/SearchInput.js.map +1 -0
- package/dist/components/ui/Skeleton.d.ts +9 -0
- package/dist/components/ui/Skeleton.d.ts.map +1 -0
- package/dist/components/ui/Skeleton.js +11 -0
- package/dist/components/ui/Skeleton.js.map +1 -0
- package/dist/components/ui/Toast.d.ts +18 -0
- package/dist/components/ui/Toast.d.ts.map +1 -0
- package/dist/components/ui/Toast.js +29 -0
- package/dist/components/ui/Toast.js.map +1 -0
- package/dist/components/ui/index.d.ts +25 -0
- package/dist/components/ui/index.d.ts.map +1 -0
- package/dist/components/ui/index.js +13 -0
- package/dist/components/ui/index.js.map +1 -0
- package/dist/fields/ArrayField.d.ts +9 -0
- package/dist/fields/ArrayField.d.ts.map +1 -0
- package/dist/fields/ArrayField.js +21 -0
- package/dist/fields/ArrayField.js.map +1 -0
- package/dist/fields/BlockBuilderField.d.ts +16 -0
- package/dist/fields/BlockBuilderField.d.ts.map +1 -0
- package/dist/fields/BlockBuilderField.js +110 -0
- package/dist/fields/BlockBuilderField.js.map +1 -0
- package/dist/fields/DateField.d.ts +9 -0
- package/dist/fields/DateField.d.ts.map +1 -0
- package/dist/fields/DateField.js +6 -0
- package/dist/fields/DateField.js.map +1 -0
- package/dist/fields/FieldRenderer.d.ts +22 -0
- package/dist/fields/FieldRenderer.d.ts.map +1 -0
- package/dist/fields/FieldRenderer.js +38 -0
- package/dist/fields/FieldRenderer.js.map +1 -0
- package/dist/fields/GroupField.d.ts +8 -0
- package/dist/fields/GroupField.d.ts.map +1 -0
- package/dist/fields/GroupField.js +8 -0
- package/dist/fields/GroupField.js.map +1 -0
- package/dist/fields/MediaField.d.ts +13 -0
- package/dist/fields/MediaField.d.ts.map +1 -0
- package/dist/fields/MediaField.js +6 -0
- package/dist/fields/MediaField.js.map +1 -0
- package/dist/fields/NavBuilderField.d.ts +15 -0
- package/dist/fields/NavBuilderField.d.ts.map +1 -0
- package/dist/fields/NavBuilderField.js +19 -0
- package/dist/fields/NavBuilderField.js.map +1 -0
- package/dist/fields/NumberField.d.ts +12 -0
- package/dist/fields/NumberField.d.ts.map +1 -0
- package/dist/fields/NumberField.js +6 -0
- package/dist/fields/NumberField.js.map +1 -0
- package/dist/fields/RelationshipField.d.ts +13 -0
- package/dist/fields/RelationshipField.d.ts.map +1 -0
- package/dist/fields/RelationshipField.js +119 -0
- package/dist/fields/RelationshipField.js.map +1 -0
- package/dist/fields/RichTextField.d.ts +9 -0
- package/dist/fields/RichTextField.d.ts.map +1 -0
- package/dist/fields/RichTextField.js +7 -0
- package/dist/fields/RichTextField.js.map +1 -0
- package/dist/fields/SelectField.d.ts +11 -0
- package/dist/fields/SelectField.d.ts.map +1 -0
- package/dist/fields/SelectField.js +31 -0
- package/dist/fields/SelectField.js.map +1 -0
- package/dist/fields/SlugField.d.ts +10 -0
- package/dist/fields/SlugField.d.ts.map +1 -0
- package/dist/fields/SlugField.js +15 -0
- package/dist/fields/SlugField.js.map +1 -0
- package/dist/fields/TextField.d.ts +11 -0
- package/dist/fields/TextField.d.ts.map +1 -0
- package/dist/fields/TextField.js +8 -0
- package/dist/fields/TextField.js.map +1 -0
- package/dist/fields/ToggleField.d.ts +8 -0
- package/dist/fields/ToggleField.d.ts.map +1 -0
- package/dist/fields/ToggleField.js +6 -0
- package/dist/fields/ToggleField.js.map +1 -0
- package/dist/fields/block-types.d.ts +18 -0
- package/dist/fields/block-types.d.ts.map +1 -0
- package/dist/fields/block-types.js +88 -0
- package/dist/fields/block-types.js.map +1 -0
- package/dist/fields/index.d.ts +18 -0
- package/dist/fields/index.d.ts.map +1 -0
- package/dist/fields/index.js +16 -0
- package/dist/fields/index.js.map +1 -0
- package/dist/hooks/useContentLock.d.ts +12 -0
- package/dist/hooks/useContentLock.d.ts.map +1 -0
- package/dist/hooks/useContentLock.js +38 -0
- package/dist/hooks/useContentLock.js.map +1 -0
- package/dist/hooks/useDebounce.d.ts +2 -0
- package/dist/hooks/useDebounce.d.ts.map +1 -0
- package/dist/hooks/useDebounce.js +11 -0
- package/dist/hooks/useDebounce.js.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts +6 -0
- package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/dist/hooks/useKeyboardShortcuts.js +26 -0
- package/dist/hooks/useKeyboardShortcuts.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +39 -0
- package/dist/index.js.map +1 -0
- package/dist/layout/Header.d.ts +7 -0
- package/dist/layout/Header.d.ts.map +1 -0
- package/dist/layout/Header.js +18 -0
- package/dist/layout/Header.js.map +1 -0
- package/dist/layout/Layout.d.ts +10 -0
- package/dist/layout/Layout.d.ts.map +1 -0
- package/dist/layout/Layout.js +25 -0
- package/dist/layout/Layout.js.map +1 -0
- package/dist/layout/Sidebar.d.ts +9 -0
- package/dist/layout/Sidebar.d.ts.map +1 -0
- package/dist/layout/Sidebar.js +63 -0
- package/dist/layout/Sidebar.js.map +1 -0
- package/dist/lib/api.d.ts +8 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +59 -0
- package/dist/lib/api.js.map +1 -0
- package/dist/lib/search.d.ts +11 -0
- package/dist/lib/search.d.ts.map +1 -0
- package/dist/lib/search.js +46 -0
- package/dist/lib/search.js.map +1 -0
- package/dist/lib/useApiData.d.ts +8 -0
- package/dist/lib/useApiData.d.ts.map +1 -0
- package/dist/lib/useApiData.js +36 -0
- package/dist/lib/useApiData.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/utils.js +6 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/router/index.d.ts +10 -0
- package/dist/router/index.d.ts.map +1 -0
- package/dist/router/index.js +61 -0
- package/dist/router/index.js.map +1 -0
- package/dist/views/CollectionList.d.ts +7 -0
- package/dist/views/CollectionList.d.ts.map +1 -0
- package/dist/views/CollectionList.js +107 -0
- package/dist/views/CollectionList.js.map +1 -0
- package/dist/views/Dashboard.d.ts +5 -0
- package/dist/views/Dashboard.d.ts.map +1 -0
- package/dist/views/Dashboard.js +17 -0
- package/dist/views/Dashboard.js.map +1 -0
- package/dist/views/DocumentEdit.d.ts +8 -0
- package/dist/views/DocumentEdit.d.ts.map +1 -0
- package/dist/views/DocumentEdit.js +210 -0
- package/dist/views/DocumentEdit.js.map +1 -0
- package/dist/views/FormEditor.d.ts +6 -0
- package/dist/views/FormEditor.d.ts.map +1 -0
- package/dist/views/FormEditor.js +126 -0
- package/dist/views/FormEditor.js.map +1 -0
- package/dist/views/FormSubmissions.d.ts +6 -0
- package/dist/views/FormSubmissions.d.ts.map +1 -0
- package/dist/views/FormSubmissions.js +88 -0
- package/dist/views/FormSubmissions.js.map +1 -0
- package/dist/views/Forms.d.ts +5 -0
- package/dist/views/Forms.d.ts.map +1 -0
- package/dist/views/Forms.js +24 -0
- package/dist/views/Forms.js.map +1 -0
- package/dist/views/Login.d.ts +10 -0
- package/dist/views/Login.d.ts.map +1 -0
- package/dist/views/Login.js +83 -0
- package/dist/views/Login.js.map +1 -0
- package/dist/views/MediaBrowser.d.ts +5 -0
- package/dist/views/MediaBrowser.d.ts.map +1 -0
- package/dist/views/MediaBrowser.js +245 -0
- package/dist/views/MediaBrowser.js.map +1 -0
- package/dist/views/PageEditor.d.ts +6 -0
- package/dist/views/PageEditor.d.ts.map +1 -0
- package/dist/views/PageEditor.js +74 -0
- package/dist/views/PageEditor.js.map +1 -0
- package/dist/views/Pages.d.ts +5 -0
- package/dist/views/Pages.d.ts.map +1 -0
- package/dist/views/Pages.js +127 -0
- package/dist/views/Pages.js.map +1 -0
- package/dist/views/PostEditor.d.ts +6 -0
- package/dist/views/PostEditor.d.ts.map +1 -0
- package/dist/views/PostEditor.js +79 -0
- package/dist/views/PostEditor.js.map +1 -0
- package/dist/views/Posts.d.ts +5 -0
- package/dist/views/Posts.d.ts.map +1 -0
- package/dist/views/Posts.js +67 -0
- package/dist/views/Posts.js.map +1 -0
- package/dist/views/Redirects.d.ts +5 -0
- package/dist/views/Redirects.d.ts.map +1 -0
- package/dist/views/Redirects.js +79 -0
- package/dist/views/Redirects.js.map +1 -0
- package/dist/views/SEO.d.ts +6 -0
- package/dist/views/SEO.d.ts.map +1 -0
- package/dist/views/SEO.js +120 -0
- package/dist/views/SEO.js.map +1 -0
- package/dist/views/Settings.d.ts +5 -0
- package/dist/views/Settings.d.ts.map +1 -0
- package/dist/views/Settings.js +95 -0
- package/dist/views/Settings.js.map +1 -0
- package/dist/views/SetupWizard.d.ts +13 -0
- package/dist/views/SetupWizard.d.ts.map +1 -0
- package/dist/views/SetupWizard.js +68 -0
- package/dist/views/SetupWizard.js.map +1 -0
- package/dist/views/Users.d.ts +5 -0
- package/dist/views/Users.d.ts.map +1 -0
- package/dist/views/Users.js +69 -0
- package/dist/views/Users.js.map +1 -0
- package/package.json +71 -0
- package/src/styles/tailwind.css +2 -0
- package/src/styles/theme.css +175 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pages.js","sourceRoot":"","sources":["../../src/views/Pages.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostEditor.d.ts","sourceRoot":"","sources":["../../src/views/PostEditor.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,eAAe;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,EAAE,eAAe,2CA2O7D"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
|
+
import { ArrowLeft, Eye, Loader2, AlertTriangle } from 'lucide-react';
|
|
5
|
+
import { toast } from 'sonner';
|
|
6
|
+
import { TipTapEditor } from '../components/TipTapEditor';
|
|
7
|
+
import { SEOPanel } from '../components/SEOPanel';
|
|
8
|
+
import { useApiData } from '../lib/useApiData';
|
|
9
|
+
import { cmsApi } from '../lib/api';
|
|
10
|
+
export function PostEditor({ id, onNavigate }) {
|
|
11
|
+
const isNew = !id;
|
|
12
|
+
const { data, loading, error } = useApiData(isNew ? '' : `/collections/posts/${id}`);
|
|
13
|
+
const [title, setTitle] = useState('');
|
|
14
|
+
const [content, setContent] = useState('');
|
|
15
|
+
const [status, setStatus] = useState('draft');
|
|
16
|
+
const [slug, setSlug] = useState('');
|
|
17
|
+
const [saving, setSaving] = useState(false);
|
|
18
|
+
const [initialized, setInitialized] = useState(isNew);
|
|
19
|
+
const [seoData, setSeoData] = useState({});
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (data && !initialized) {
|
|
22
|
+
setTitle(data.title ?? '');
|
|
23
|
+
setContent(data.content ?? data.data?.content ?? '');
|
|
24
|
+
setStatus(data.status === 'PUBLISHED' ? 'published' : 'draft');
|
|
25
|
+
setSlug(data.slug ?? '');
|
|
26
|
+
setInitialized(true);
|
|
27
|
+
}
|
|
28
|
+
}, [data, initialized]);
|
|
29
|
+
const savePost = async () => {
|
|
30
|
+
setSaving(true);
|
|
31
|
+
const body = JSON.stringify({
|
|
32
|
+
title,
|
|
33
|
+
content,
|
|
34
|
+
slug,
|
|
35
|
+
status: status === 'published' ? 'PUBLISHED' : 'DRAFT',
|
|
36
|
+
});
|
|
37
|
+
const res = isNew
|
|
38
|
+
? await cmsApi('/collections/posts', { method: 'POST', body })
|
|
39
|
+
: await cmsApi(`/collections/posts/${id}`, { method: 'PUT', body });
|
|
40
|
+
setSaving(false);
|
|
41
|
+
if (res.error) {
|
|
42
|
+
toast.error(res.error);
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
toast.success('Post saved successfully!');
|
|
46
|
+
if (isNew && res.data?.id) {
|
|
47
|
+
onNavigate?.(`/posts/${res.data.id}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const publishPost = async () => {
|
|
52
|
+
setSaving(true);
|
|
53
|
+
const body = JSON.stringify({
|
|
54
|
+
title,
|
|
55
|
+
content,
|
|
56
|
+
slug,
|
|
57
|
+
status: 'PUBLISHED',
|
|
58
|
+
});
|
|
59
|
+
const endpoint = isNew ? '/collections/posts' : `/collections/posts/${id}`;
|
|
60
|
+
const method = isNew ? 'POST' : 'PUT';
|
|
61
|
+
const res = await cmsApi(endpoint, { method, body });
|
|
62
|
+
setSaving(false);
|
|
63
|
+
if (res.error) {
|
|
64
|
+
toast.error(res.error);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
setStatus('published');
|
|
68
|
+
toast.success('Post published!');
|
|
69
|
+
if (isNew && res.data?.id) {
|
|
70
|
+
onNavigate?.(`/posts/${res.data.id}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
if (!isNew && loading) {
|
|
75
|
+
return (_jsx("div", { className: "h-full flex items-center justify-center", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
|
|
76
|
+
}
|
|
77
|
+
return (_jsxs("div", { className: "h-full flex flex-col bg-white", children: [error && (_jsxs("div", { className: "mx-4 mt-3 flex items-center gap-3 rounded-lg border border-red-200 bg-red-50 p-3", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-red-600 shrink-0" }), _jsx("span", { className: "text-sm text-red-800 flex-1", children: error })] })), _jsx("div", { className: "border-b border-gray-200 px-3 sm:px-4 py-3", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("button", { onClick: () => onNavigate?.('/posts'), className: "inline-flex items-center gap-2 text-sm text-gray-600 hover:text-gray-900 transition-colors", children: [_jsx(ArrowLeft, { className: "w-4 h-4" }), _jsx("span", { className: "hidden sm:inline", children: "Back to Posts" }), _jsx("span", { className: "sm:hidden", children: "Back" })] }), _jsx("div", { className: "flex items-center gap-2", children: _jsxs("button", { className: "px-3 py-1.5 text-sm border border-gray-300 rounded-lg flex items-center gap-2 hover:bg-gray-50 transition-colors", children: [_jsx(Eye, { className: "w-4 h-4" }), _jsx("span", { className: "hidden sm:inline", children: "Preview" })] }) })] }) }), _jsxs("div", { className: "flex-1 overflow-hidden flex flex-col lg:flex-row", children: [_jsx("div", { className: "flex-1 overflow-y-auto", children: _jsxs("div", { className: "max-w-4xl mx-auto p-3 pr-6 sm:p-4 sm:pr-8", children: [_jsx("input", { type: "text", value: title, onChange: (e) => setTitle(e.target.value), placeholder: "Post title", className: "w-full text-2xl sm:text-3xl font-bold mb-4 px-0 border-none focus:outline-none focus:ring-0 placeholder:text-gray-300" }), _jsxs("div", { className: "mb-4", children: [_jsx("label", { className: "block text-xs font-medium text-gray-600 mb-1", children: "URL Slug" }), _jsx("input", { type: "text", value: slug, onChange: (e) => setSlug(e.target.value), placeholder: "url-slug", className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsx("div", { className: "mb-4", children: _jsx(TipTapEditor, { content: content, onChange: setContent }) })] }) }), _jsx("div", { className: "hidden lg:block w-[30%] border-l border-gray-200 overflow-y-auto bg-gray-50", children: _jsxs("div", { className: "p-4 space-y-4", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("h3", { className: "font-semibold text-gray-900 mb-3 text-sm", children: "Publish" }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Status" }), _jsxs("select", { value: status, onChange: (e) => setStatus(e.target.value), className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "draft", children: "Draft" }), _jsx("option", { value: "published", children: "Published" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Publish Date" }), _jsx("input", { type: "datetime-local", className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsx("button", { onClick: savePost, disabled: saving, className: "w-full py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium disabled:opacity-50", children: saving ? 'Saving...' : 'Save Post' }), status === 'draft' && (_jsx("button", { onClick: publishPost, disabled: saving, className: "w-full py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors text-sm font-medium disabled:opacity-50", children: saving ? 'Publishing...' : 'Publish' }))] })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("h3", { className: "font-semibold text-gray-900 mb-3 text-sm", children: "Categories & Tags" }), _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Category" }), _jsxs("select", { className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { children: "Technology" }), _jsx("option", { children: "Design" }), _jsx("option", { children: "Business" })] })] }), _jsxs("div", { children: [_jsx("label", { className: "block text-xs font-medium text-gray-700 mb-1", children: "Tags" }), _jsx("input", { type: "text", placeholder: "Add tags...", className: "w-full px-3 py-1.5 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] })] })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("h3", { className: "font-semibold text-gray-900 mb-3 text-sm", children: "Featured Image" }), _jsx("button", { className: "w-full py-2 border-2 border-dashed border-gray-300 rounded-lg hover:border-gray-400 transition-colors text-sm text-gray-600", children: "Upload Image" })] }), _jsx(SEOPanel, { title: title, slug: slug, content: content, seoData: seoData, onChange: setSeoData })] }) }), _jsx("div", { className: "lg:hidden border-t border-gray-200 p-3 bg-white", children: _jsxs("div", { className: "flex gap-2", children: [_jsx("button", { onClick: savePost, disabled: saving, className: "flex-1 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm font-medium disabled:opacity-50", children: saving ? 'Saving...' : 'Save Post' }), status === 'draft' && (_jsx("button", { onClick: publishPost, disabled: saving, className: "flex-1 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors text-sm font-medium disabled:opacity-50", children: "Publish" }))] }) })] })] }));
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=PostEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PostEditor.js","sourceRoot":"","sources":["../../src/views/PostEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Posts.d.ts","sourceRoot":"","sources":["../../src/views/Posts.tsx"],"names":[],"mappings":"AAWA,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,2CAmO/C"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { Plus, Search, Trash2, SlidersHorizontal, Pencil, ArrowUpDown, ArrowUp, ArrowDown, Loader2, AlertTriangle } from 'lucide-react';
|
|
4
|
+
import { useState, useMemo } from 'react';
|
|
5
|
+
import { toast } from 'sonner';
|
|
6
|
+
import { sortByRelevance, toggleSort } from '../lib/search';
|
|
7
|
+
import { useApiData } from '../lib/useApiData';
|
|
8
|
+
import { cmsApi } from '../lib/api';
|
|
9
|
+
export function Posts({ onNavigate }) {
|
|
10
|
+
const { data, loading, error, refetch } = useApiData('/collections/posts?pageSize=100');
|
|
11
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
12
|
+
const [filterStatus, setFilterStatus] = useState('all');
|
|
13
|
+
const [filterCategory, setFilterCategory] = useState('all');
|
|
14
|
+
const [selectedPosts, setSelectedPosts] = useState([]);
|
|
15
|
+
const [sortConfig, setSortConfig] = useState(null);
|
|
16
|
+
const posts = data?.docs ?? [];
|
|
17
|
+
const filteredAndSorted = useMemo(() => {
|
|
18
|
+
let results = posts.filter((post) => {
|
|
19
|
+
const matchesSearch = post.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
20
|
+
(post.author ?? '').toLowerCase().includes(searchQuery.toLowerCase());
|
|
21
|
+
const matchesStatus = filterStatus === 'all' || (post.status ?? '').toLowerCase() === filterStatus.toLowerCase();
|
|
22
|
+
const matchesCategory = filterCategory === 'all' || (post.category ?? '').toLowerCase() === filterCategory.toLowerCase();
|
|
23
|
+
return matchesSearch && matchesStatus && matchesCategory;
|
|
24
|
+
});
|
|
25
|
+
if (searchQuery.trim()) {
|
|
26
|
+
results = sortByRelevance(results, searchQuery, (p) => [p.title, p.author ?? '', p.category ?? '']);
|
|
27
|
+
}
|
|
28
|
+
else if (sortConfig) {
|
|
29
|
+
results = [...results].sort((a, b) => {
|
|
30
|
+
const aVal = a[sortConfig.key] ?? '';
|
|
31
|
+
const bVal = b[sortConfig.key] ?? '';
|
|
32
|
+
const cmp = String(aVal).localeCompare(String(bVal));
|
|
33
|
+
return sortConfig.direction === 'asc' ? cmp : -cmp;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return results;
|
|
37
|
+
}, [posts, searchQuery, filterStatus, filterCategory, sortConfig]);
|
|
38
|
+
const handleSelectAll = (checked) => {
|
|
39
|
+
setSelectedPosts(checked ? filteredAndSorted.map((p) => p.id) : []);
|
|
40
|
+
};
|
|
41
|
+
const handleSelectPost = (id) => {
|
|
42
|
+
setSelectedPosts(prev => prev.includes(id) ? prev.filter(pid => pid !== id) : [...prev, id]);
|
|
43
|
+
};
|
|
44
|
+
const handleBulkDelete = async () => {
|
|
45
|
+
for (const id of selectedPosts) {
|
|
46
|
+
await cmsApi(`/collections/posts/${id}`, { method: 'DELETE' });
|
|
47
|
+
}
|
|
48
|
+
toast.success(`${selectedPosts.length} posts deleted`);
|
|
49
|
+
setSelectedPosts([]);
|
|
50
|
+
refetch();
|
|
51
|
+
};
|
|
52
|
+
const handleDelete = async (id) => {
|
|
53
|
+
await cmsApi(`/collections/posts/${id}`, { method: 'DELETE' });
|
|
54
|
+
toast.success('Post deleted');
|
|
55
|
+
setSelectedPosts(prev => prev.filter(pid => pid !== id));
|
|
56
|
+
refetch();
|
|
57
|
+
};
|
|
58
|
+
function SortHeader({ label, sortKey }) {
|
|
59
|
+
const active = sortConfig?.key === sortKey;
|
|
60
|
+
return (_jsxs("button", { type: "button", onClick: () => setSortConfig(toggleSort(sortConfig, sortKey)), className: "flex items-center gap-1 text-xs font-medium text-gray-700 hover:text-gray-900 transition-colors", children: [label, active ? (sortConfig.direction === 'asc' ? _jsx(ArrowUp, { className: "w-3 h-3" }) : _jsx(ArrowDown, { className: "w-3 h-3" })) : (_jsx(ArrowUpDown, { className: "w-3 h-3 text-gray-400" }))] }));
|
|
61
|
+
}
|
|
62
|
+
if (loading) {
|
|
63
|
+
return (_jsx("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
|
|
64
|
+
}
|
|
65
|
+
return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 h-full flex flex-col", 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: "w-5 h-5 text-red-600 shrink-0" }), _jsx("span", { className: "text-sm text-red-800 flex-1", children: error }), _jsx("button", { onClick: refetch, className: "px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors", children: "Retry" })] })), _jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between mb-4 gap-3", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl sm:text-2xl font-semibold text-gray-900 mb-1", children: "Posts" }), _jsxs("p", { className: "text-sm text-gray-600", children: [filteredAndSorted.length, " total posts"] })] }), _jsxs("button", { onClick: () => onNavigate?.('/posts/new'), className: "flex items-center justify-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm", children: [_jsx(Plus, { className: "w-4 h-4" }), _jsx("span", { className: "hidden sm:inline", children: "New Post" }), _jsx("span", { className: "sm:hidden", children: "New" })] })] }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 mb-4", children: _jsxs("div", { className: "p-3 flex flex-col gap-3", children: [_jsxs("div", { className: "relative", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search posts...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("div", { className: "flex flex-col sm:flex-row gap-2", children: [_jsxs("select", { value: filterStatus, onChange: (e) => setFilterStatus(e.target.value), className: "flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "all", children: "All Status" }), _jsx("option", { value: "published", children: "Published" }), _jsx("option", { value: "draft", children: "Draft" })] }), _jsxs("select", { value: filterCategory, onChange: (e) => setFilterCategory(e.target.value), className: "flex-1 px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "all", children: "All Categories" }), _jsx("option", { value: "technology", children: "Technology" }), _jsx("option", { value: "design", children: "Design" }), _jsx("option", { value: "business", children: "Business" })] }), _jsxs("button", { type: "button", className: "flex items-center justify-center gap-2 px-3 py-2 text-sm border border-gray-300 rounded-lg hover:bg-gray-50 transition-colors", children: [_jsx(SlidersHorizontal, { className: "w-4 h-4" }), _jsx("span", { className: "hidden sm:inline", children: "More Filters" })] })] })] }) }), selectedPosts.length > 0 && (_jsx("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 mb-4", children: _jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-2", children: [_jsxs("span", { className: "text-sm text-blue-900", children: [selectedPosts.length, " post", selectedPosts.length !== 1 ? 's' : '', " selected"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: handleBulkDelete, className: "flex-1 sm:flex-none px-3 py-1.5 text-sm bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors", children: "Delete" }), _jsx("button", { type: "button", onClick: () => setSelectedPosts([]), className: "flex-1 sm:flex-none px-3 py-1.5 text-sm border border-gray-300 bg-white rounded-lg hover:bg-gray-50 transition-colors", children: "Cancel" })] })] }) })), filteredAndSorted.length === 0 && !error ? (_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-8 text-center flex-1 flex flex-col items-center justify-center", children: [_jsx("p", { className: "text-sm text-gray-500 mb-2", children: "No posts yet" }), _jsx("button", { onClick: () => onNavigate?.('/posts/new'), className: "px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors", children: "Create your first post" })] })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "hidden md:block bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "w-8 px-3 py-2 text-left", children: _jsx("input", { type: "checkbox", checked: selectedPosts.length === filteredAndSorted.length && filteredAndSorted.length > 0, onChange: (e) => handleSelectAll(e.target.checked), className: "rounded border-gray-300" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Title", sortKey: "title" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Author", sortKey: "author" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Category", sortKey: "category" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Status", sortKey: "status" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Date", sortKey: "date" }) }), _jsx("th", { className: "px-3 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filteredAndSorted.map((post) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsx("td", { className: "px-3 py-2", children: _jsx("input", { type: "checkbox", checked: selectedPosts.includes(post.id), onChange: () => handleSelectPost(post.id), className: "rounded border-gray-300" }) }), _jsx("td", { className: "px-3 py-2", children: _jsx("button", { type: "button", onClick: () => onNavigate?.(`/posts/${post.id}`), className: "font-medium text-gray-900 hover:text-blue-600 text-sm text-left", children: post.title }) }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: post.author }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: post.category }), _jsx("td", { className: "px-3 py-2", children: _jsx("span", { className: `inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium ${post.status === 'Published' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: post.status }) }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: post.date }), _jsx("td", { className: "px-3 py-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/posts/${post.id}`), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Edit", children: _jsx(Pencil, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { type: "button", onClick: () => handleDelete(post.id), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Delete", children: _jsx(Trash2, { className: "w-4 h-4 text-red-600" }) })] }) })] }, post.id))) })] }) }) }), _jsx("div", { className: "md:hidden bg-white rounded-lg border border-gray-200 flex-1 overflow-auto", children: _jsx("div", { className: "divide-y divide-gray-200", children: filteredAndSorted.map((post) => (_jsx("div", { className: "p-3", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("input", { type: "checkbox", checked: selectedPosts.includes(post.id), onChange: () => handleSelectPost(post.id), className: "rounded border-gray-300 mt-1" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/posts/${post.id}`), className: "font-medium text-sm text-gray-900 hover:text-blue-600 block mb-1 text-left", children: post.title }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-gray-600 mb-2", children: [_jsx("span", { children: post.author }), _jsx("span", { children: "\u2022" }), _jsx("span", { children: post.date }), _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${post.status === 'Published' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: post.status })] })] }), _jsx("button", { type: "button", onClick: () => handleDelete(post.id), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", children: _jsx(Trash2, { className: "w-4 h-4 text-red-600" }) })] }) }, post.id))) }) })] }))] }));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=Posts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Posts.js","sourceRoot":"","sources":["../../src/views/Posts.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Redirects.d.ts","sourceRoot":"","sources":["../../src/views/Redirects.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,SAAS,CAAC,EAAE,UAAU,EAAE,EAAE,cAAc,2CAoRvD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as Dialog from '@radix-ui/react-dialog';
|
|
4
|
+
import { Pencil, Plus, Trash2, Search, ArrowUpDown, ArrowUp, ArrowDown, ArrowRightLeft, Loader2, AlertTriangle } from 'lucide-react';
|
|
5
|
+
import { useState, useMemo } from 'react';
|
|
6
|
+
import { toast } from 'sonner';
|
|
7
|
+
import { sortByRelevance, toggleSort } from '../lib/search';
|
|
8
|
+
import { useApiData } from '../lib/useApiData';
|
|
9
|
+
import { cmsApi } from '../lib/api';
|
|
10
|
+
export function Redirects({ onNavigate }) {
|
|
11
|
+
const { data, loading, error, refetch } = useApiData('/redirects');
|
|
12
|
+
const [showAddDialog, setShowAddDialog] = useState(false);
|
|
13
|
+
const [newRedirect, setNewRedirect] = useState({ source: '', destination: '', type: '301' });
|
|
14
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
15
|
+
const [filterType, setFilterType] = useState('all');
|
|
16
|
+
const [sortConfig, setSortConfig] = useState(null);
|
|
17
|
+
const redirects = data ?? [];
|
|
18
|
+
const filteredAndSorted = useMemo(() => {
|
|
19
|
+
let results = redirects.filter((r) => {
|
|
20
|
+
const matchesSearch = r.from.toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
21
|
+
r.to.toLowerCase().includes(searchQuery.toLowerCase());
|
|
22
|
+
const matchesType = filterType === 'all' || r.type === filterType;
|
|
23
|
+
return matchesSearch && matchesType;
|
|
24
|
+
});
|
|
25
|
+
if (searchQuery.trim()) {
|
|
26
|
+
results = sortByRelevance(results, searchQuery, (r) => [r.from, r.to]);
|
|
27
|
+
}
|
|
28
|
+
else if (sortConfig) {
|
|
29
|
+
results = [...results].sort((a, b) => {
|
|
30
|
+
let cmp;
|
|
31
|
+
if (sortConfig.key === 'hits') {
|
|
32
|
+
cmp = a.hits - b.hits;
|
|
33
|
+
}
|
|
34
|
+
else if (sortConfig.key === 'active') {
|
|
35
|
+
cmp = Number(a.active) - Number(b.active);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
cmp = String(a[sortConfig.key]).localeCompare(String(b[sortConfig.key]));
|
|
39
|
+
}
|
|
40
|
+
return sortConfig.direction === 'asc' ? cmp : -cmp;
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
return results;
|
|
44
|
+
}, [redirects, searchQuery, filterType, sortConfig]);
|
|
45
|
+
const handleSubmit = async (e) => {
|
|
46
|
+
e.preventDefault();
|
|
47
|
+
const res = await cmsApi('/redirects', {
|
|
48
|
+
method: 'POST',
|
|
49
|
+
body: JSON.stringify({ from: newRedirect.source, to: newRedirect.destination, type: newRedirect.type }),
|
|
50
|
+
});
|
|
51
|
+
if (res.error) {
|
|
52
|
+
toast.error(res.error);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
toast.success('Redirect added');
|
|
56
|
+
refetch();
|
|
57
|
+
}
|
|
58
|
+
setShowAddDialog(false);
|
|
59
|
+
};
|
|
60
|
+
const handleDelete = async (id) => {
|
|
61
|
+
const res = await cmsApi(`/redirects/${id}`, { method: 'DELETE' });
|
|
62
|
+
if (res.error) {
|
|
63
|
+
toast.error(res.error);
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
toast.success('Redirect deleted');
|
|
67
|
+
refetch();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
function SortHeader({ label, sortKey }) {
|
|
71
|
+
const active = sortConfig?.key === sortKey;
|
|
72
|
+
return (_jsxs("button", { type: "button", onClick: () => setSortConfig(toggleSort(sortConfig, sortKey)), className: "flex items-center gap-1 text-xs font-medium text-gray-700 hover:text-gray-900 transition-colors", children: [label, active ? (sortConfig.direction === 'asc' ? _jsx(ArrowUp, { className: "w-3 h-3" }) : _jsx(ArrowDown, { className: "w-3 h-3" })) : (_jsx(ArrowUpDown, { className: "w-3 h-3 text-gray-400" }))] }));
|
|
73
|
+
}
|
|
74
|
+
if (loading) {
|
|
75
|
+
return (_jsx("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
|
|
76
|
+
}
|
|
77
|
+
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: "w-5 h-5 text-red-600 shrink-0" }), _jsx("span", { className: "text-sm text-red-800 flex-1", children: error }), _jsx("button", { onClick: refetch, className: "px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors", 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: "Redirects" }), _jsxs("p", { className: "text-sm text-gray-600", children: [filteredAndSorted.length, " total redirects"] })] }), _jsxs("button", { type: "button", onClick: () => setShowAddDialog(true), 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" }), "Add Redirect"] })] }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 mb-4", children: _jsxs("div", { className: "p-3 flex flex-col sm:flex-row gap-3", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search by source or destination URL...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("select", { value: filterType, onChange: (e) => setFilterType(e.target.value), className: "px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "all", children: "All Types" }), _jsx("option", { value: "301", children: "301 (Permanent)" }), _jsx("option", { value: "302", children: "302 (Temporary)" })] })] }) }), filteredAndSorted.length === 0 && !loading ? (_jsxs("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [_jsx("div", { className: "w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mb-4", children: _jsx(ArrowRightLeft, { className: "w-6 h-6 text-gray-400" }) }), _jsx("h3", { className: "text-sm font-medium text-gray-900 mb-1", children: "No redirects yet" }), _jsx("p", { className: "text-sm text-gray-500", children: "Add your first redirect to get started." })] })) : (_jsx("div", { className: "rounded-lg border border-gray-200 bg-white", children: _jsx("div", { className: "overflow-x-auto", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "border-b border-gray-200 bg-gray-50", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Source URL", sortKey: "from" }) }), _jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Destination URL", sortKey: "to" }) }), _jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Type", sortKey: "type" }) }), _jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Hits", sortKey: "hits" }) }), _jsx("th", { className: "px-4 py-2 text-left", children: _jsx(SortHeader, { label: "Status", sortKey: "active" }) }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filteredAndSorted.map((redirect) => (_jsxs("tr", { className: "transition-colors hover:bg-gray-50", children: [_jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "rounded bg-gray-100 px-2 py-1 text-xs text-gray-900", children: redirect.from }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "rounded bg-gray-100 px-2 py-1 text-xs text-gray-900", children: redirect.to }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${redirect.type === '301' ? 'bg-blue-100 text-blue-800' : 'bg-purple-100 text-purple-800'}`, children: redirect.type }) }), _jsx("td", { className: "px-4 py-3 text-sm text-gray-600", children: redirect.hits.toLocaleString() }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${redirect.active ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: redirect.active ? 'Active' : 'Inactive' }) }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/redirects/${redirect.id}/edit`), className: "rounded p-1.5 transition-colors hover:bg-gray-100", "aria-label": "Edit redirect", children: _jsx(Pencil, { className: "h-4 w-4 text-gray-600" }) }), _jsx("button", { type: "button", onClick: () => handleDelete(redirect.id), className: "rounded p-1.5 transition-colors hover:bg-gray-100", "aria-label": "Delete redirect", children: _jsx(Trash2, { className: "h-4 w-4 text-red-600" }) })] }) })] }, redirect.id))) })] }) }) })), _jsx(Dialog.Root, { open: showAddDialog, onOpenChange: setShowAddDialog, children: _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/50" }), _jsxs(Dialog.Content, { className: "fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg", children: [_jsx(Dialog.Title, { className: "mb-4 text-lg font-semibold text-gray-900", children: "Add Redirect" }), _jsxs("form", { onSubmit: handleSubmit, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Source URL" }), _jsx("input", { type: "text", value: newRedirect.source, onChange: (e) => setNewRedirect({ ...newRedirect, source: e.target.value }), placeholder: "/old-page", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", required: true })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Destination URL" }), _jsx("input", { type: "text", value: newRedirect.destination, onChange: (e) => setNewRedirect({ ...newRedirect, destination: e.target.value }), placeholder: "/new-page", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", required: true })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Redirect Type" }), _jsxs("select", { value: newRedirect.type, onChange: (e) => setNewRedirect({ ...newRedirect, type: e.target.value }), className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "301", children: "301 (Permanent)" }), _jsx("option", { value: "302", children: "302 (Temporary)" })] })] }), _jsxs("div", { className: "flex items-center justify-end gap-3 pt-4", children: [_jsx(Dialog.Close, { asChild: true, children: _jsx("button", { type: "button", className: "rounded-lg border border-gray-300 px-4 py-2 text-sm transition-colors hover:bg-gray-50", children: "Cancel" }) }), _jsx("button", { type: "submit", className: "rounded-lg bg-blue-600 px-4 py-2 text-sm text-white transition-colors hover:bg-blue-700", children: "Add Redirect" })] })] })] })] }) })] }));
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=Redirects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Redirects.js","sourceRoot":"","sources":["../../src/views/Redirects.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SEO.d.ts","sourceRoot":"","sources":["../../src/views/SEO.tsx"],"names":[],"mappings":"AAcA,MAAM,WAAW,QAAQ;IACvB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,GAAG,CAAC,EAAE,UAAU,EAAE,UAAoB,EAAE,EAAE,QAAQ,2CAsbjE"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import * as Tabs from '@radix-ui/react-tabs';
|
|
4
|
+
import { Search, Globe, FileCode2, BarChart3, AlertTriangle, CheckCircle2, XCircle, ArrowUpRight, RefreshCw, BookOpen, Link2, Bot, Plus, Pencil, Trash2, ExternalLink, ArrowRightLeft, Copy, ShieldCheck, Loader2, } from 'lucide-react';
|
|
5
|
+
import { useState } from 'react';
|
|
6
|
+
import { toast } from 'sonner';
|
|
7
|
+
import * as Dialog from '@radix-ui/react-dialog';
|
|
8
|
+
import { useApiData } from '../lib/useApiData';
|
|
9
|
+
import { cmsApi } from '../lib/api';
|
|
10
|
+
export function SEO({ onNavigate, initialTab = 'pages' }) {
|
|
11
|
+
const { data: seoData, loading: seoLoading, error: seoError, refetch: seoRefetch } = useApiData('/seo/pages');
|
|
12
|
+
const { data: redirectsData, loading: redirectsLoading, error: redirectsError, refetch: redirectsRefetch } = useApiData('/redirects');
|
|
13
|
+
const { data: linkHealthData, loading: linkHealthLoading } = useApiData('/seo/link-health');
|
|
14
|
+
const [activeTab, setActiveTab] = useState(initialTab);
|
|
15
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
16
|
+
const [filterScore, setFilterScore] = useState('all');
|
|
17
|
+
const [scanning, setScanning] = useState(false);
|
|
18
|
+
const [showAddRedirect, setShowAddRedirect] = useState(false);
|
|
19
|
+
const [newRedirect, setNewRedirect] = useState({ source: '', destination: '', type: '301' });
|
|
20
|
+
const [redirectSearch, setRedirectSearch] = useState('');
|
|
21
|
+
const seoPages = seoData ?? [];
|
|
22
|
+
const redirects = redirectsData ?? [];
|
|
23
|
+
const linkHealth = linkHealthData ?? [];
|
|
24
|
+
const handleTabChange = (tab) => {
|
|
25
|
+
setActiveTab(tab);
|
|
26
|
+
const path = tab === 'pages' ? '/seo' : `/seo/${tab}`;
|
|
27
|
+
onNavigate?.(path);
|
|
28
|
+
};
|
|
29
|
+
// --- Pages tab data ---
|
|
30
|
+
const filtered = seoPages
|
|
31
|
+
.filter((page) => {
|
|
32
|
+
const matchesSearch = page.url.toLowerCase().includes(searchQuery.toLowerCase()) || page.title.toLowerCase().includes(searchQuery.toLowerCase());
|
|
33
|
+
const matchesScore = filterScore === 'all' || (filterScore === 'good' && page.score >= 80) || (filterScore === 'warning' && page.score >= 50 && page.score < 80) || (filterScore === 'critical' && page.score < 50);
|
|
34
|
+
return matchesSearch && matchesScore;
|
|
35
|
+
})
|
|
36
|
+
.sort((a, b) => !searchQuery ? b.issues - a.issues : 0);
|
|
37
|
+
const totalIssues = seoPages.reduce((sum, p) => sum + p.issues, 0);
|
|
38
|
+
const avgScore = seoPages.length > 0 ? Math.round(seoPages.reduce((sum, p) => sum + p.score, 0) / seoPages.length) : 0;
|
|
39
|
+
const missingMeta = seoPages.filter((p) => !p.metaTitle || !p.metaDescription).length;
|
|
40
|
+
const missingSchema = seoPages.filter((p) => !p.schemaType).length;
|
|
41
|
+
// --- Canonical data ---
|
|
42
|
+
const missingCanonical = seoPages.filter((p) => !p.canonical);
|
|
43
|
+
const allCanonicals = seoPages.filter((p) => p.canonical);
|
|
44
|
+
const canonicalDomains = [...new Set(allCanonicals.map((p) => { try {
|
|
45
|
+
return new URL(p.canonical).hostname;
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return '';
|
|
49
|
+
} }).filter(Boolean))];
|
|
50
|
+
// --- Redirects data ---
|
|
51
|
+
const filteredRedirects = redirects.filter((r) => r.from.toLowerCase().includes(redirectSearch.toLowerCase()) ||
|
|
52
|
+
r.to.toLowerCase().includes(redirectSearch.toLowerCase()));
|
|
53
|
+
const handleScan = async () => {
|
|
54
|
+
setScanning(true);
|
|
55
|
+
try {
|
|
56
|
+
const res = await cmsApi('/seo/scan', { method: 'POST' });
|
|
57
|
+
if (res.error) {
|
|
58
|
+
toast.error(res.error);
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
const d = res.data;
|
|
62
|
+
toast.success(`SEO scan complete — ${d.totalProblems} issues found across ${d.pagesWithIssues} of ${d.total} pages`);
|
|
63
|
+
seoRefetch();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
toast.error('SEO scan failed');
|
|
68
|
+
}
|
|
69
|
+
finally {
|
|
70
|
+
setScanning(false);
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const handleAddRedirect = async (e) => {
|
|
74
|
+
e.preventDefault();
|
|
75
|
+
const res = await cmsApi('/redirects', {
|
|
76
|
+
method: 'POST',
|
|
77
|
+
body: JSON.stringify({ from: newRedirect.source, to: newRedirect.destination, type: newRedirect.type }),
|
|
78
|
+
});
|
|
79
|
+
if (res.error) {
|
|
80
|
+
toast.error(res.error);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
toast.success('Redirect added');
|
|
84
|
+
redirectsRefetch();
|
|
85
|
+
}
|
|
86
|
+
setShowAddRedirect(false);
|
|
87
|
+
setNewRedirect({ source: '', destination: '', type: '301' });
|
|
88
|
+
};
|
|
89
|
+
const handleDeleteRedirect = async (id) => {
|
|
90
|
+
const res = await cmsApi(`/redirects/${id}`, { method: 'DELETE' });
|
|
91
|
+
if (res.error) {
|
|
92
|
+
toast.error(res.error);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
toast.success('Redirect deleted');
|
|
96
|
+
redirectsRefetch();
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
function scoreBadge(score) {
|
|
100
|
+
if (score >= 80)
|
|
101
|
+
return 'bg-green-100 text-green-800';
|
|
102
|
+
if (score >= 50)
|
|
103
|
+
return 'bg-yellow-100 text-yellow-800';
|
|
104
|
+
return 'bg-red-100 text-red-800';
|
|
105
|
+
}
|
|
106
|
+
function scoreIcon(score) {
|
|
107
|
+
if (score >= 80)
|
|
108
|
+
return _jsx(CheckCircle2, { className: "w-4 h-4 text-green-600" });
|
|
109
|
+
if (score >= 50)
|
|
110
|
+
return _jsx(AlertTriangle, { className: "w-4 h-4 text-yellow-600" });
|
|
111
|
+
return _jsx(XCircle, { className: "w-4 h-4 text-red-600" });
|
|
112
|
+
}
|
|
113
|
+
const tabClass = "px-4 py-2 text-sm font-medium text-gray-600 transition-colors hover:text-gray-900 data-[state=active]:border-b-2 data-[state=active]:border-blue-600 data-[state=active]:text-blue-600 shrink-0";
|
|
114
|
+
const isLoading = seoLoading || redirectsLoading || linkHealthLoading;
|
|
115
|
+
if (isLoading) {
|
|
116
|
+
return (_jsx("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 flex items-center justify-center h-64", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
|
|
117
|
+
}
|
|
118
|
+
return (_jsxs("div", { className: "p-3 pr-6 sm:p-4 sm:pr-8 h-full flex flex-col", children: [(seoError || redirectsError) && (_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: "w-5 h-5 text-red-600 shrink-0" }), _jsx("span", { className: "text-sm text-red-800 flex-1", children: seoError || redirectsError }), _jsx("button", { onClick: () => { seoRefetch(); redirectsRefetch(); }, className: "px-3 py-1 text-sm text-red-700 border border-red-300 rounded-lg hover:bg-red-100 transition-colors", children: "Retry" })] })), _jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between mb-4 gap-3", children: [_jsxs("div", { children: [_jsx("h1", { className: "text-xl sm:text-2xl font-semibold text-gray-900 mb-1", children: "SEO & Redirects" }), _jsx("p", { className: "text-sm text-gray-600", children: "Search optimization, redirects, canonicalization, and link health" })] }), _jsxs("button", { onClick: handleScan, disabled: scanning, className: "flex items-center justify-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm disabled:opacity-60", children: [_jsx(RefreshCw, { className: `w-4 h-4 ${scanning ? 'animate-spin' : ''}` }), scanning ? 'Scanning...' : 'Run SEO Scan'] })] }), _jsxs(Tabs.Root, { value: activeTab, onValueChange: handleTabChange, children: [_jsxs(Tabs.List, { className: "mb-4 flex gap-1 border-b border-gray-200 overflow-x-auto", children: [_jsx(Tabs.Trigger, { value: "pages", className: tabClass, children: _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(BarChart3, { className: "w-4 h-4" }), "Pages"] }) }), _jsx(Tabs.Trigger, { value: "redirects", className: tabClass, children: _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(ArrowRightLeft, { className: "w-4 h-4" }), "Redirects"] }) }), _jsx(Tabs.Trigger, { value: "canonicals", className: tabClass, children: _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Copy, { className: "w-4 h-4" }), "Canonicalization"] }) }), _jsx(Tabs.Trigger, { value: "links", className: tabClass, children: _jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Link2, { className: "w-4 h-4" }), "Link Health"] }) })] }), _jsxs(Tabs.Content, { value: "pages", className: "flex flex-col flex-1 min-h-0", children: [_jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3 mb-4", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(BarChart3, { className: "w-4 h-4 text-blue-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Avg SEO Score" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: avgScore }), _jsx("div", { className: `text-xs mt-1 ${avgScore >= 80 ? 'text-green-600' : avgScore >= 50 ? 'text-yellow-600' : 'text-red-600'}`, children: avgScore >= 80 ? 'Good' : avgScore >= 50 ? 'Needs improvement' : 'Critical' })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(AlertTriangle, { className: "w-4 h-4 text-yellow-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Total Issues" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: totalIssues }), _jsxs("div", { className: "text-xs text-gray-500 mt-1", children: ["Across ", seoPages.filter((p) => p.issues > 0).length, " pages"] })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(FileCode2, { className: "w-4 h-4 text-purple-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Missing Meta" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: missingMeta }), _jsx("div", { className: "text-xs text-gray-500 mt-1", children: "Title or description" })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(Globe, { className: "w-4 h-4 text-green-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Missing Schema" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: missingSchema }), _jsx("div", { className: "text-xs text-gray-500 mt-1", children: "No Schema.org markup" })] })] }), _jsx("div", { className: "bg-linear-to-r from-indigo-50 to-purple-50 border border-indigo-200 rounded-lg p-4 mb-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(Bot, { className: "w-5 h-5 text-indigo-600 mt-0.5 shrink-0" }), _jsxs("div", { className: "flex-1", children: [_jsx("h3", { className: "text-sm font-semibold text-indigo-900 mb-1", children: "AI SEO Recommendations" }), _jsxs("p", { className: "text-sm text-indigo-700 mb-2", children: [missingMeta, " pages missing meta descriptions. ", missingCanonical.length, " pages without canonical URLs. AI can auto-generate these from page content."] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: () => onNavigate?.('/settings'), className: "px-3 py-1.5 text-xs bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors", children: "Configure AI" }), _jsx("button", { className: "px-3 py-1.5 text-xs border border-indigo-300 text-indigo-700 rounded-lg hover:bg-indigo-50 transition-colors", children: "Auto-fix All" })] })] })] }) }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 mb-4", children: _jsxs("div", { className: "p-3 flex flex-col sm:flex-row gap-3", children: [_jsxs("div", { className: "relative flex-1", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search pages by URL or title...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("select", { value: filterScore, onChange: (e) => setFilterScore(e.target.value), className: "px-3 py-2 text-sm border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "all", children: "All Scores" }), _jsx("option", { value: "good", children: "Good (80+)" }), _jsx("option", { value: "warning", children: "Needs Work (50-79)" }), _jsx("option", { value: "critical", children: "Critical (<50)" })] })] }) }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Page" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Score" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Readability" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Schema" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Meta" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Issues" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filtered.map((page) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsxs("td", { className: "px-4 py-3", children: [_jsx("div", { className: "text-sm font-medium text-gray-900", children: page.title }), _jsx("div", { className: "text-xs text-gray-500", children: page.url })] }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [scoreIcon(page.score), _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${scoreBadge(page.score)}`, children: page.score })] }) }), _jsx("td", { className: "px-4 py-3", children: page.readability > 0 ? _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(BookOpen, { className: "w-3.5 h-3.5 text-gray-400" }), _jsx("span", { className: `text-sm ${page.readability >= 80 ? 'text-green-700' : page.readability >= 60 ? 'text-yellow-700' : 'text-red-700'}`, children: page.readability })] }) : _jsx("span", { className: "text-xs text-gray-400", children: "\u2014" }) }), _jsx("td", { className: "px-4 py-3", children: page.schemaType ? _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-purple-100 text-purple-800", children: page.schemaType }) : _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800", children: "Missing" }) }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex flex-col gap-0.5", children: [_jsx("span", { className: `text-xs ${page.metaTitle ? 'text-green-700' : 'text-red-600'}`, children: page.metaTitle ? '✓ Title' : '✗ Title' }), _jsx("span", { className: `text-xs ${page.metaDescription ? 'text-green-700' : 'text-red-600'}`, children: page.metaDescription ? '✓ Desc' : '✗ Desc' })] }) }), _jsx("td", { className: "px-4 py-3", children: page.issues > 0 ? _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800", children: page.issues }) : _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800", children: "\u2713" }) }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: () => onNavigate?.(`/pages/${page.id}`), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Edit", children: _jsx(ArrowUpRight, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "AI analyze", children: _jsx(Bot, { className: "w-4 h-4 text-indigo-600" }) })] }) })] }, page.id))) })] }) }) })] }), _jsxs(Tabs.Content, { value: "redirects", className: "flex flex-col flex-1 min-h-0", children: [_jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3 mb-4", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Total Redirects" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: redirects.length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Active" }), _jsx("div", { className: "text-2xl font-semibold text-green-600", children: redirects.filter((r) => r.active).length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Total Hits" }), _jsx("div", { className: "text-2xl font-semibold text-blue-600", children: redirects.reduce((s, r) => s + r.hits, 0).toLocaleString() })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "301 Permanent" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: redirects.filter((r) => r.type === '301').length })] })] }), _jsxs("div", { className: "flex items-center gap-3 mb-4", children: [_jsxs("div", { className: "relative flex-1 max-w-md", children: [_jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400" }), _jsx("input", { type: "text", placeholder: "Search redirects...", value: redirectSearch, onChange: (e) => setRedirectSearch(e.target.value), className: "w-full pl-9 pr-3 py-2 text-sm border border-gray-300 rounded-lg bg-white focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("button", { onClick: () => setShowAddRedirect(true), className: "flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors text-sm shrink-0", children: [_jsx(Plus, { className: "w-4 h-4" }), "Add Redirect"] })] }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Source" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Destination" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Type" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Hits" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Status" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filteredRedirects.map((r) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "rounded bg-gray-100 px-2 py-1 text-xs text-gray-900", children: r.from }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "rounded bg-gray-100 px-2 py-1 text-xs text-gray-900", children: r.to }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${r.type === '301' ? 'bg-blue-100 text-blue-800' : 'bg-purple-100 text-purple-800'}`, children: r.type }) }), _jsx("td", { className: "px-4 py-3 text-sm text-gray-600", children: r.hits.toLocaleString() }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${r.active ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: r.active ? 'Active' : 'Inactive' }) }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { className: "p-1.5 hover:bg-gray-100 rounded transition-colors", children: _jsx(Pencil, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { onClick: () => handleDeleteRedirect(r.id), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", children: _jsx(Trash2, { className: "w-4 h-4 text-red-600" }) })] }) })] }, r.id))) })] }) }) }), _jsx(Dialog.Root, { open: showAddRedirect, onOpenChange: setShowAddRedirect, children: _jsxs(Dialog.Portal, { children: [_jsx(Dialog.Overlay, { className: "fixed inset-0 z-50 bg-black/50" }), _jsxs(Dialog.Content, { className: "fixed left-1/2 top-1/2 z-50 w-full max-w-md -translate-x-1/2 -translate-y-1/2 rounded-lg bg-white p-6 shadow-lg", children: [_jsx(Dialog.Title, { className: "mb-4 text-lg font-semibold text-gray-900", children: "Add Redirect" }), _jsxs("form", { onSubmit: handleAddRedirect, className: "space-y-4", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Source URL" }), _jsx("input", { type: "text", value: newRedirect.source, onChange: (e) => setNewRedirect({ ...newRedirect, source: e.target.value }), placeholder: "/old-page", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", required: true })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Destination URL" }), _jsx("input", { type: "text", value: newRedirect.destination, onChange: (e) => setNewRedirect({ ...newRedirect, destination: e.target.value }), placeholder: "/new-page", className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", required: true })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-1 block text-sm font-medium text-gray-700", children: "Type" }), _jsxs("select", { value: newRedirect.type, onChange: (e) => setNewRedirect({ ...newRedirect, type: e.target.value }), className: "w-full rounded-lg border border-gray-300 px-3 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-500", children: [_jsx("option", { value: "301", children: "301 (Permanent)" }), _jsx("option", { value: "302", children: "302 (Temporary)" })] })] }), _jsxs("div", { className: "flex justify-end gap-3 pt-4", children: [_jsx(Dialog.Close, { asChild: true, children: _jsx("button", { type: "button", className: "rounded-lg border border-gray-300 px-4 py-2 text-sm hover:bg-gray-50", children: "Cancel" }) }), _jsx("button", { type: "submit", className: "rounded-lg bg-blue-600 px-4 py-2 text-sm text-white hover:bg-blue-700", children: "Add Redirect" })] })] })] })] }) })] }), _jsxs(Tabs.Content, { value: "canonicals", className: "flex flex-col flex-1 min-h-0 space-y-4", children: [_jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(ShieldCheck, { className: "w-4 h-4 text-green-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "With Canonical" })] }), _jsx("div", { className: "text-2xl font-semibold text-green-700", children: allCanonicals.length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(AlertTriangle, { className: "w-4 h-4 text-red-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Missing Canonical" })] }), _jsx("div", { className: "text-2xl font-semibold text-red-700", children: missingCanonical.length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(Globe, { className: "w-4 h-4 text-blue-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Canonical Domains" })] }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: canonicalDomains.length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsxs("div", { className: "flex items-center gap-2 mb-2", children: [_jsx(CheckCircle2, { className: "w-4 h-4 text-green-600" }), _jsx("span", { className: "text-xs font-medium text-gray-600", children: "Self-Referencing" })] }), _jsx("div", { className: "text-2xl font-semibold text-green-700", children: allCanonicals.length }), _jsx("div", { className: "text-xs text-gray-500 mt-1", children: "Correct pattern" })] })] }), missingCanonical.length > 0 && (_jsx("div", { className: "bg-yellow-50 border border-yellow-200 rounded-lg p-4", children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx(AlertTriangle, { className: "w-5 h-5 text-yellow-600 mt-0.5 shrink-0" }), _jsxs("div", { className: "flex-1", children: [_jsxs("h3", { className: "text-sm font-semibold text-yellow-900 mb-1", children: [missingCanonical.length, " page", missingCanonical.length !== 1 ? 's' : '', " missing canonical URLs"] }), _jsx("p", { className: "text-sm text-yellow-700 mb-2", children: "Without canonical tags, search engines may index duplicate versions of these pages, diluting your ranking signals." }), _jsx("div", { className: "flex flex-wrap gap-2", children: missingCanonical.map((p) => (_jsxs("button", { onClick: () => onNavigate?.(`/pages/${p.id}`), className: "px-2.5 py-1 text-xs bg-yellow-100 text-yellow-900 rounded-lg hover:bg-yellow-200 transition-colors", children: [p.title, " (", p.url, ")"] }, p.id))) })] })] }) })), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Page" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "URL" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Canonical URL" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Status" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: seoPages.map((page) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsx("td", { className: "px-4 py-3 text-sm font-medium text-gray-900", children: page.title }), _jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "text-xs bg-gray-100 px-2 py-1 rounded text-gray-700", children: page.url }) }), _jsx("td", { className: "px-4 py-3", children: page.canonical ? _jsx("code", { className: "text-xs bg-gray-100 px-2 py-1 rounded text-gray-700 truncate max-w-[200px] block", children: page.canonical }) : _jsx("span", { className: "text-xs text-red-600 font-medium", children: "Not set" }) }), _jsx("td", { className: "px-4 py-3", children: page.canonical ? _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800", children: "\u2713 Set" }) : _jsx("span", { className: "px-2 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800", children: "Missing" }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("button", { onClick: () => onNavigate?.(`/pages/${page.id}`), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Edit", children: _jsx(Pencil, { className: "w-4 h-4 text-gray-600" }) }) })] }, page.id))) })] }) }) })] }), _jsxs(Tabs.Content, { value: "links", className: "flex flex-col flex-1 min-h-0 space-y-4", children: [_jsxs("div", { className: "grid grid-cols-2 lg:grid-cols-4 gap-3", children: [_jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Broken Links" }), _jsx("div", { className: "text-2xl font-semibold text-red-600", children: linkHealth.filter((l) => l.status === 404).length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Redirect Chains" }), _jsx("div", { className: "text-2xl font-semibold text-yellow-600", children: linkHealth.filter((l) => l.status === 301).length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "Internal Issues" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: linkHealth.filter((l) => l.type === 'internal').length })] }), _jsxs("div", { className: "bg-white rounded-lg border border-gray-200 p-4", children: [_jsx("div", { className: "text-xs text-gray-600 mb-1", children: "External Issues" }), _jsx("div", { className: "text-2xl font-semibold text-gray-900", children: linkHealth.filter((l) => l.type === 'external').length })] })] }), _jsx("div", { className: "bg-white rounded-lg border border-gray-200 flex-1 overflow-hidden", children: _jsx("div", { className: "overflow-x-auto h-full", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-gray-50 border-b border-gray-200 sticky top-0", children: _jsxs("tr", { children: [_jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Found On" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Broken URL" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Status" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Type" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Last Checked" }), _jsx("th", { className: "px-4 py-2 text-left text-xs font-medium text-gray-700", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: linkHealth.map((link) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", children: [_jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "text-xs bg-gray-100 px-2 py-1 rounded text-gray-700", children: link.page }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("code", { className: "text-xs bg-red-50 px-2 py-1 rounded text-red-800 truncate max-w-[200px] block", children: link.url }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${link.status === 404 ? 'bg-red-100 text-red-800' : 'bg-yellow-100 text-yellow-800'}`, children: link.status }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${link.type === 'internal' ? 'bg-blue-100 text-blue-800' : 'bg-gray-100 text-gray-800'}`, children: link.type }) }), _jsx("td", { className: "px-4 py-3 text-sm text-gray-600", children: link.lastChecked }), _jsx("td", { className: "px-4 py-3", children: _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Create redirect", children: _jsx(ArrowRightLeft, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { className: "p-1.5 hover:bg-gray-100 rounded transition-colors", title: "Open URL", children: _jsx(ExternalLink, { className: "w-4 h-4 text-gray-600" }) })] }) })] }, link.id))) })] }) }) })] })] })] }));
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=SEO.js.map
|