@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,245 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Upload, Grid3x3, List, Search, Trash2, Download, ArrowUpDown, ArrowUp, ArrowDown, X, Bot, Sparkles, Link2, AlertTriangle, Copy, ExternalLink, ImageIcon, FileImage, Loader2, FolderInput, GripVertical, } from 'lucide-react';
|
|
4
|
+
import { useState, useMemo, useRef, useCallback } 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
|
+
import { FolderTree } from '../components/FolderTree';
|
|
10
|
+
import { FocalPointPicker } from '../components/FocalPointPicker';
|
|
11
|
+
function buildMediaApiUrl(folderSel) {
|
|
12
|
+
const base = '/media?pageSize=100';
|
|
13
|
+
if (folderSel.type === 'smart') {
|
|
14
|
+
if (folderSel.smart === 'recent')
|
|
15
|
+
return `${base}&sort=updatedAt&order=desc&pageSize=20`;
|
|
16
|
+
if (folderSel.smart === 'uncategorized')
|
|
17
|
+
return `${base}&folderId=none`;
|
|
18
|
+
return base;
|
|
19
|
+
}
|
|
20
|
+
return `${base}&folderId=${folderSel.folderId}`;
|
|
21
|
+
}
|
|
22
|
+
export function MediaBrowser({ onNavigate }) {
|
|
23
|
+
const [folderSel, setFolderSel] = useState({ type: 'smart', smart: 'all' });
|
|
24
|
+
const [sidebarOpen, setSidebarOpen] = useState(true);
|
|
25
|
+
const apiUrl = useMemo(() => buildMediaApiUrl(folderSel), [folderSel]);
|
|
26
|
+
const { data, loading, error, refetch } = useApiData(apiUrl);
|
|
27
|
+
const allData = useApiData('/media?pageSize=1');
|
|
28
|
+
const uncatData = useApiData('/media?pageSize=1&folderId=none');
|
|
29
|
+
const [viewMode, setViewMode] = useState('grid');
|
|
30
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
31
|
+
const [filterType, setFilterType] = useState('all');
|
|
32
|
+
const [selectedMedia, setSelectedMedia] = useState([]);
|
|
33
|
+
const [sortConfig, setSortConfig] = useState(null);
|
|
34
|
+
const [activeItem, setActiveItem] = useState(null);
|
|
35
|
+
const [editAlt, setEditAlt] = useState('');
|
|
36
|
+
const [editTitle, setEditTitle] = useState('');
|
|
37
|
+
const [editFilename, setEditFilename] = useState('');
|
|
38
|
+
const [focalX, setFocalX] = useState(0.5);
|
|
39
|
+
const [focalY, setFocalY] = useState(0.5);
|
|
40
|
+
const [saving, setSaving] = useState(false);
|
|
41
|
+
const [aiGenerating, setAiGenerating] = useState(null);
|
|
42
|
+
const [uploading, setUploading] = useState(false);
|
|
43
|
+
const fileInputRef = useRef(null);
|
|
44
|
+
const mediaItems = data?.data ?? [];
|
|
45
|
+
const filteredAndSorted = useMemo(() => {
|
|
46
|
+
let results = mediaItems.filter((item) => {
|
|
47
|
+
const matchesSearch = item.name.toLowerCase().includes(searchQuery.toLowerCase());
|
|
48
|
+
const matchesType = filterType === 'all' || item.type === filterType;
|
|
49
|
+
return matchesSearch && matchesType;
|
|
50
|
+
});
|
|
51
|
+
if (searchQuery.trim()) {
|
|
52
|
+
results = sortByRelevance(results, searchQuery, (m) => [m.name]);
|
|
53
|
+
}
|
|
54
|
+
else if (sortConfig) {
|
|
55
|
+
results = [...results].sort((a, b) => {
|
|
56
|
+
let cmp;
|
|
57
|
+
if (sortConfig.key === 'size') {
|
|
58
|
+
cmp = a.sizeBytes - b.sizeBytes;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
cmp = String(a[sortConfig.key]).localeCompare(String(b[sortConfig.key]));
|
|
62
|
+
}
|
|
63
|
+
return sortConfig.direction === 'asc' ? cmp : -cmp;
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
return results;
|
|
67
|
+
}, [mediaItems, searchQuery, filterType, sortConfig]);
|
|
68
|
+
const openDetail = (item) => {
|
|
69
|
+
setActiveItem(item);
|
|
70
|
+
setEditAlt(item.altTag ?? '');
|
|
71
|
+
setEditTitle(item.title ?? '');
|
|
72
|
+
setEditFilename(item.name);
|
|
73
|
+
setFocalX(item.focalPointX ?? 0.5);
|
|
74
|
+
setFocalY(item.focalPointY ?? 0.5);
|
|
75
|
+
};
|
|
76
|
+
const closeDetail = () => {
|
|
77
|
+
setActiveItem(null);
|
|
78
|
+
};
|
|
79
|
+
const handleCheckbox = (e, id) => {
|
|
80
|
+
e.stopPropagation();
|
|
81
|
+
setSelectedMedia(prev => prev.includes(id) ? prev.filter(item => item !== id) : [...prev, id]);
|
|
82
|
+
};
|
|
83
|
+
const handleSelectAll = () => {
|
|
84
|
+
setSelectedMedia(prev => prev.length === filteredAndSorted.length ? [] : filteredAndSorted.map(item => item.id));
|
|
85
|
+
};
|
|
86
|
+
const handleSaveDetails = async () => {
|
|
87
|
+
if (!activeItem)
|
|
88
|
+
return;
|
|
89
|
+
setSaving(true);
|
|
90
|
+
const res = await cmsApi(`/media/${activeItem.id}`, {
|
|
91
|
+
method: 'PUT',
|
|
92
|
+
body: JSON.stringify({
|
|
93
|
+
alt: editAlt,
|
|
94
|
+
title: editTitle,
|
|
95
|
+
filename: editFilename,
|
|
96
|
+
focalX,
|
|
97
|
+
focalY,
|
|
98
|
+
}),
|
|
99
|
+
});
|
|
100
|
+
setSaving(false);
|
|
101
|
+
if (res.error) {
|
|
102
|
+
toast.error(res.error);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
toast.success('Media details saved');
|
|
106
|
+
refetch();
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
const deleteMedia = async (id) => {
|
|
110
|
+
const res = await cmsApi(`/media/${id}`, { method: 'DELETE' });
|
|
111
|
+
if (res.error) {
|
|
112
|
+
toast.error(res.error);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
toast.success('Media deleted');
|
|
116
|
+
if (activeItem?.id === id)
|
|
117
|
+
closeDetail();
|
|
118
|
+
refetch();
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
const handleAiGenerate = async (field) => {
|
|
122
|
+
setAiGenerating(field);
|
|
123
|
+
if (field === 'optimize' && activeItem) {
|
|
124
|
+
const res = await cmsApi(`/media/${activeItem.id}/optimize`, { method: 'POST' });
|
|
125
|
+
if (res.error) {
|
|
126
|
+
toast.error(res.error);
|
|
127
|
+
}
|
|
128
|
+
else if (res.data?.optimization?.alreadyOptimized) {
|
|
129
|
+
toast.info('Image is already in WebP format — no further optimization needed');
|
|
130
|
+
}
|
|
131
|
+
else if (res.data?.optimization) {
|
|
132
|
+
const opt = res.data.optimization;
|
|
133
|
+
toast.success(`Optimized: ${opt.originalSizeFormatted} → ${opt.optimizedSizeFormatted} (${opt.savings}% smaller)`);
|
|
134
|
+
refetch();
|
|
135
|
+
}
|
|
136
|
+
setAiGenerating(null);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
await new Promise(r => setTimeout(r, 1500));
|
|
140
|
+
if (field === 'alt') {
|
|
141
|
+
const generated = `A ${activeItem?.format?.toLowerCase()} image showing ${activeItem?.name.replace(/[-_]/g, ' ').replace(/\.\w+$/, '')} content`;
|
|
142
|
+
setEditAlt(generated);
|
|
143
|
+
toast.success('Alt tag generated by AI');
|
|
144
|
+
}
|
|
145
|
+
else if (field === 'title') {
|
|
146
|
+
const generated = activeItem?.name.replace(/[-_]/g, ' ').replace(/\.\w+$/, '').replace(/\b\w/g, c => c.toUpperCase()) ?? '';
|
|
147
|
+
setEditTitle(generated);
|
|
148
|
+
toast.success('Title generated by AI');
|
|
149
|
+
}
|
|
150
|
+
setAiGenerating(null);
|
|
151
|
+
};
|
|
152
|
+
const handleCopyUrl = () => {
|
|
153
|
+
if (activeItem?.url) {
|
|
154
|
+
navigator.clipboard.writeText(activeItem.url);
|
|
155
|
+
toast.success('URL copied to clipboard');
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
const handleUploadFiles = async (files) => {
|
|
159
|
+
if (!files || files.length === 0)
|
|
160
|
+
return;
|
|
161
|
+
setUploading(true);
|
|
162
|
+
let successCount = 0;
|
|
163
|
+
for (let i = 0; i < files.length; i++) {
|
|
164
|
+
const file = files[i];
|
|
165
|
+
const formData = new FormData();
|
|
166
|
+
formData.append('file', file);
|
|
167
|
+
const res = await cmsApi('/media/upload', { method: 'POST', body: formData });
|
|
168
|
+
if (res.error) {
|
|
169
|
+
toast.error(`Failed to upload ${file.name}: ${res.error}`);
|
|
170
|
+
}
|
|
171
|
+
else {
|
|
172
|
+
const opt = res.data?.optimization;
|
|
173
|
+
if (opt && opt.savings > 0) {
|
|
174
|
+
toast.success(`${file.name} → WebP (${opt.originalSizeFormatted} → ${opt.optimizedSizeFormatted}, ${opt.savings}% saved)`);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
toast.success(`Uploaded ${file.name}`);
|
|
178
|
+
}
|
|
179
|
+
successCount++;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
if (successCount > 0)
|
|
183
|
+
refetch();
|
|
184
|
+
if (fileInputRef.current)
|
|
185
|
+
fileInputRef.current.value = '';
|
|
186
|
+
setUploading(false);
|
|
187
|
+
};
|
|
188
|
+
const handleDropItem = useCallback(async (itemId, folderId) => {
|
|
189
|
+
const res = await cmsApi(`/media/${itemId}/folder`, {
|
|
190
|
+
method: 'PUT',
|
|
191
|
+
body: JSON.stringify({ folderId }),
|
|
192
|
+
});
|
|
193
|
+
if (res.error) {
|
|
194
|
+
toast.error(res.error);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
toast.success(folderId ? 'Moved to folder' : 'Removed from folder');
|
|
198
|
+
refetch();
|
|
199
|
+
}
|
|
200
|
+
}, [refetch]);
|
|
201
|
+
const handleDragStart = (e, id) => {
|
|
202
|
+
e.dataTransfer.setData('text/actuate-item-id', String(id));
|
|
203
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
204
|
+
};
|
|
205
|
+
const panelOpen = activeItem !== null;
|
|
206
|
+
const issues = activeItem ? [
|
|
207
|
+
...(!activeItem.altTag ? ['Missing alt tag'] : []),
|
|
208
|
+
...(!activeItem.title ? ['Missing title'] : []),
|
|
209
|
+
...(activeItem.sizeBytes > 2000000 ? ['File size over 2 MB — consider optimizing'] : []),
|
|
210
|
+
...(activeItem.usedOn?.length === 0 ? ['Not used on any page'] : []),
|
|
211
|
+
] : [];
|
|
212
|
+
function SortHeader({ label, sortKey }) {
|
|
213
|
+
const active = sortConfig?.key === sortKey;
|
|
214
|
+
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" }))] }));
|
|
215
|
+
}
|
|
216
|
+
if (loading) {
|
|
217
|
+
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" }) }));
|
|
218
|
+
}
|
|
219
|
+
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 items-center justify-between mb-4", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("button", { type: "button", onClick: () => setSidebarOpen(prev => !prev), className: "p-1.5 rounded-lg hover:bg-gray-100 transition-colors", title: sidebarOpen ? 'Hide folders' : 'Show folders', children: _jsx(FolderInput, { className: "w-5 h-5 text-gray-600" }) }), _jsxs("div", { children: [_jsx("h1", { className: "text-xl sm:text-2xl font-semibold text-gray-900 mb-1", children: "Media Library" }), _jsxs("p", { className: "text-sm text-gray-600", children: [filteredAndSorted.length, " files"] })] })] }), _jsxs("div", { children: [_jsx("input", { ref: fileInputRef, type: "file", multiple: true, accept: "image/*,video/*,application/pdf,.doc,.docx,.xls,.xlsx", className: "hidden", onChange: (e) => handleUploadFiles(e.target.files) }), _jsxs("button", { onClick: () => fileInputRef.current?.click(), disabled: uploading, 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 disabled:opacity-50", children: [uploading ? _jsx(Loader2, { className: "w-4 h-4 animate-spin" }) : _jsx(Upload, { className: "w-4 h-4" }), uploading ? 'Uploading...' : 'Upload Files'] })] })] }), _jsxs("div", { className: "flex gap-4 flex-1 min-h-0 overflow-hidden", children: [sidebarOpen && (_jsx("div", { className: "w-56 shrink-0 bg-white rounded-lg border border-gray-200 overflow-hidden flex flex-col", children: _jsx(FolderTree, { scope: "media", selected: folderSel, onSelect: (sel) => { setFolderSel(sel); setSelectedMedia([]); }, totalCount: allData.data?.total, uncategorizedCount: uncatData.data?.total, onDropItem: handleDropItem }) })), _jsxs("div", { className: "flex-1 flex flex-col min-w-0", children: [_jsx("div", { className: "bg-white rounded-lg border border-gray-200 mb-4", children: _jsxs("div", { className: "p-3 flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3 flex-1", children: [_jsxs("div", { className: "flex-1 max-w-md 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 media...", 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: "image", children: "Images" }), _jsx("option", { value: "video", children: "Videos" }), _jsx("option", { value: "document", children: "Documents" })] })] }), _jsxs("div", { className: "flex items-center gap-1 bg-gray-100 p-1 rounded-lg", children: [_jsx("button", { onClick: () => setViewMode('grid'), className: `p-1.5 rounded transition-colors ${viewMode === 'grid' ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-600 hover:text-gray-900'}`, children: _jsx(Grid3x3, { className: "w-4 h-4" }) }), _jsx("button", { onClick: () => setViewMode('list'), className: `p-1.5 rounded transition-colors ${viewMode === 'list' ? 'bg-white text-gray-900 shadow-sm' : 'text-gray-600 hover:text-gray-900'}`, children: _jsx(List, { className: "w-4 h-4" }) })] })] }) }), selectedMedia.length > 0 && (_jsx("div", { className: "bg-blue-50 border border-blue-200 rounded-lg p-3 mb-4", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-sm text-blue-900", children: [selectedMedia.length, " file", selectedMedia.length !== 1 ? 's' : '', " selected"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { onClick: async () => { for (const id of selectedMedia)
|
|
220
|
+
await deleteMedia(id); setSelectedMedia([]); }, className: "px-3 py-1.5 text-sm bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors", children: "Delete Selected" }), _jsx("button", { onClick: () => setSelectedMedia([]), className: "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 && !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(ImageIcon, { className: "w-6 h-6 text-gray-400" }) }), _jsx("h3", { className: "text-sm font-medium text-gray-900 mb-1", children: folderSel.type === 'smart' && folderSel.smart === 'uncategorized'
|
|
221
|
+
? 'No uncategorized media'
|
|
222
|
+
: folderSel.type === 'folder'
|
|
223
|
+
? 'No media in this folder'
|
|
224
|
+
: 'No media yet' }), _jsx("p", { className: "text-sm text-gray-500", children: "Upload your first file to get started." })] })) : (_jsxs("div", { className: "flex gap-4 flex-1 overflow-hidden min-h-0", children: [_jsx("div", { className: `bg-white rounded-lg border border-gray-200 overflow-hidden transition-all duration-200 ${panelOpen ? 'flex-1 min-w-0' : 'w-full'}`, children: viewMode === 'grid' ? (_jsx("div", { className: `grid gap-2 sm:gap-3 p-2 sm:p-3 overflow-y-auto h-full ${panelOpen
|
|
225
|
+
? 'grid-cols-2 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4'
|
|
226
|
+
: 'grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 2xl:grid-cols-8'}`, children: filteredAndSorted.map((item) => {
|
|
227
|
+
const isActive = activeItem?.id === item.id;
|
|
228
|
+
const hasIssues = !item.altTag || !item.title || item.usedOn?.length === 0;
|
|
229
|
+
return (_jsxs("div", { className: `group relative aspect-square rounded-lg border-2 overflow-hidden cursor-pointer transition-all ${isActive ? 'border-blue-500 ring-2 ring-blue-200' :
|
|
230
|
+
selectedMedia.includes(item.id) ? 'border-blue-400 ring-1 ring-blue-100' :
|
|
231
|
+
'border-gray-200 hover:border-gray-300'}`, onClick: () => openDetail(item), draggable: true, onDragStart: (e) => handleDragStart(e, item.id), children: [_jsx("div", { className: "w-full h-full bg-gray-100 flex items-center justify-center", children: _jsx(FileImage, { className: "w-6 h-6 sm:w-8 sm:h-8 text-gray-400" }) }), _jsx("div", { className: "absolute inset-0 bg-linear-to-t from-black/60 to-transparent opacity-0 group-hover:opacity-100 transition-opacity", children: _jsxs("div", { className: "absolute bottom-0 left-0 right-0 p-2", children: [_jsx("p", { className: "text-white text-xs font-medium truncate", children: item.name }), _jsx("p", { className: "text-white/80 text-xs", children: item.size })] }) }), hasIssues && (_jsx("div", { className: "absolute top-1.5 left-1.5 w-5 h-5 bg-yellow-500 rounded-full flex items-center justify-center", title: "Needs attention", children: _jsx(AlertTriangle, { className: "w-3 h-3 text-white" }) })), _jsx("div", { className: "absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 transition-opacity", onClick: (e) => handleCheckbox(e, item.id), children: _jsx("div", { className: `w-5 h-5 rounded border-2 flex items-center justify-center transition-colors ${selectedMedia.includes(item.id) ? 'bg-blue-600 border-blue-600' : 'bg-white/80 border-gray-400'}`, children: selectedMedia.includes(item.id) && (_jsx("svg", { className: "w-3 h-3 text-white", fill: "none", viewBox: "0 0 12 12", children: _jsx("path", { d: "M10 3L4.5 8.5L2 6", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })) }) })] }, item.id));
|
|
232
|
+
}) })) : (_jsx("div", { className: "overflow-y-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: selectedMedia.length === filteredAndSorted.length && filteredAndSorted.length > 0, onChange: handleSelectAll, className: "rounded border-gray-300" }) }), _jsx("th", { className: "w-6 px-1 py-2" }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Name", sortKey: "name" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Type", sortKey: "type" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Size", sortKey: "size" }) }), _jsx("th", { className: "px-3 py-2 text-left", children: _jsx(SortHeader, { label: "Uploaded", sortKey: "date" }) }), _jsx("th", { className: "px-3 py-2 text-left text-xs font-medium text-gray-700", children: "Status" })] }) }), _jsx("tbody", { className: "divide-y divide-gray-200", children: filteredAndSorted.map((item) => {
|
|
233
|
+
const isActive = activeItem?.id === item.id;
|
|
234
|
+
const hasIssues = !item.altTag || !item.title || item.usedOn?.length === 0;
|
|
235
|
+
return (_jsxs("tr", { className: `transition-colors cursor-pointer ${isActive ? 'bg-blue-50' : 'hover:bg-gray-50'}`, onClick: () => openDetail(item), draggable: true, onDragStart: (e) => handleDragStart(e, item.id), children: [_jsx("td", { className: "px-3 py-2", onClick: (e) => e.stopPropagation(), children: _jsx("input", { type: "checkbox", checked: selectedMedia.includes(item.id), onChange: () => handleCheckbox({ stopPropagation: () => { } }, item.id), className: "rounded border-gray-300" }) }), _jsx("td", { className: "px-1 py-2 cursor-grab", children: _jsx(GripVertical, { className: "w-4 h-4 text-gray-300" }) }), _jsx("td", { className: "px-3 py-2", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "w-10 h-10 bg-gray-100 rounded flex items-center justify-center", children: _jsx(FileImage, { className: "w-5 h-5 text-gray-400" }) }), _jsx("span", { className: "text-sm font-medium text-gray-900", children: item.name })] }) }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: item.format ?? item.type }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: item.size }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: item.date }), _jsx("td", { className: "px-3 py-2", children: hasIssues ? (_jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800", children: [_jsx(AlertTriangle, { className: "w-3 h-3" }), " Needs attention"] })) : (_jsx("span", { className: "inline-flex items-center px-2 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800", children: "Complete" })) })] }, item.id));
|
|
236
|
+
}) })] }) })) }), panelOpen && activeItem && (_jsxs("div", { className: "w-80 lg:w-96 bg-white rounded-lg border border-gray-200 overflow-y-auto shrink-0 flex flex-col", children: [_jsxs("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 sticky top-0 bg-white z-10", children: [_jsx("h3", { className: "text-sm font-semibold text-gray-900 truncate", children: activeItem.name }), _jsx("button", { onClick: closeDetail, className: "p-1 hover:bg-gray-100 rounded transition-colors", "aria-label": "Close panel", children: _jsx(X, { className: "w-4 h-4 text-gray-500" }) })] }), _jsxs("div", { className: "flex-1 overflow-y-auto", children: [_jsx("div", { className: "p-4 border-b border-gray-200", children: _jsx("div", { className: "aspect-video bg-gray-100 rounded-lg flex items-center justify-center", children: _jsx(ImageIcon, { className: "w-12 h-12 text-gray-300" }) }) }), issues.length > 0 && (_jsxs("div", { className: "mx-4 mt-4 p-3 bg-yellow-50 border border-yellow-200 rounded-lg", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertTriangle, { className: "w-4 h-4 text-yellow-600 mt-0.5 shrink-0" }), _jsxs("div", { children: [_jsxs("p", { className: "text-xs font-semibold text-yellow-900 mb-1", children: [issues.length, " issue", issues.length !== 1 ? 's' : '', " found"] }), _jsx("ul", { className: "space-y-0.5", children: issues.map((issue, i) => (_jsxs("li", { className: "text-xs text-yellow-800", children: ["\u2022 ", issue] }, i))) })] })] }), _jsxs("button", { type: "button", onClick: async () => {
|
|
237
|
+
if (!activeItem.altTag)
|
|
238
|
+
await handleAiGenerate('alt');
|
|
239
|
+
if (!activeItem.title)
|
|
240
|
+
await handleAiGenerate('title');
|
|
241
|
+
if (activeItem.sizeBytes > 2000000)
|
|
242
|
+
await handleAiGenerate('optimize');
|
|
243
|
+
}, className: "mt-2 w-full flex items-center justify-center gap-1.5 px-3 py-1.5 text-xs bg-yellow-600 text-white rounded-lg hover:bg-yellow-700 transition-colors", children: [_jsx(Sparkles, { className: "w-3.5 h-3.5" }), "AI Fix All Issues"] })] })), _jsxs("div", { className: "p-4 border-b border-gray-200 space-y-3", children: [_jsx("h4", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide", children: "File Information" }), _jsxs("div", { className: "grid grid-cols-2 gap-3", children: [_jsxs("div", { children: [_jsx("div", { className: "text-xs text-gray-500 mb-0.5", children: "Format" }), _jsx("div", { className: "text-sm text-gray-900", children: activeItem.format ?? 'Unknown' })] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs text-gray-500 mb-0.5", children: "File Size" }), _jsxs("div", { className: "text-sm text-gray-900 flex items-center gap-1", children: [activeItem.size, activeItem.sizeBytes > 2000000 && (_jsx("span", { className: "text-yellow-600 text-xs", children: "(large)" }))] })] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs text-gray-500 mb-0.5", children: "Dimensions" }), _jsx("div", { className: "text-sm text-gray-900", children: activeItem.dimensions ?? '—' })] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs text-gray-500 mb-0.5", children: "Uploaded" }), _jsx("div", { className: "text-sm text-gray-900", children: activeItem.date })] })] }), _jsxs("div", { children: [_jsx("div", { className: "text-xs text-gray-500 mb-1", children: "URL" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("code", { className: "flex-1 text-xs bg-gray-50 border border-gray-200 px-2 py-1.5 rounded text-gray-700 truncate", children: activeItem.url }), _jsx("button", { onClick: handleCopyUrl, className: "p-1.5 hover:bg-gray-100 rounded transition-colors shrink-0", title: "Copy URL", children: _jsx(Copy, { className: "w-3.5 h-3.5 text-gray-500" }) })] })] })] }), _jsxs("div", { className: "p-4 border-b border-gray-200 space-y-4", children: [_jsx("h4", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide", children: "SEO & Accessibility" }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-1", children: [_jsx("label", { className: "text-sm font-medium text-gray-700", children: "Alt Tag" }), _jsxs("button", { type: "button", onClick: () => handleAiGenerate('alt'), disabled: aiGenerating === 'alt', className: "flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-700 disabled:opacity-50 transition-colors", children: [_jsx(Bot, { className: "w-3.5 h-3.5" }), aiGenerating === 'alt' ? 'Generating...' : 'AI Generate'] })] }), _jsx("textarea", { value: editAlt, onChange: (e) => setEditAlt(e.target.value), placeholder: "Describe this image for accessibility...", rows: 2, className: "w-full text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none" }), !editAlt && (_jsx("p", { className: "text-xs text-red-500 mt-1", children: "Required for accessibility and SEO" }))] }), _jsxs("div", { children: [_jsxs("div", { className: "flex items-center justify-between mb-1", children: [_jsx("label", { className: "text-sm font-medium text-gray-700", children: "Title" }), _jsxs("button", { type: "button", onClick: () => handleAiGenerate('title'), disabled: aiGenerating === 'title', className: "flex items-center gap-1 text-xs text-indigo-600 hover:text-indigo-700 disabled:opacity-50 transition-colors", children: [_jsx(Bot, { className: "w-3.5 h-3.5" }), aiGenerating === 'title' ? 'Generating...' : 'AI Generate'] })] }), _jsx("input", { type: "text", value: editTitle, onChange: (e) => setEditTitle(e.target.value), placeholder: "Image title...", className: "w-full text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" })] }), _jsxs("div", { children: [_jsx("label", { className: "text-sm font-medium text-gray-700 mb-1 block", children: "File Name" }), _jsx("input", { type: "text", value: editFilename, onChange: (e) => setEditFilename(e.target.value), className: "w-full text-sm border border-gray-300 rounded-lg px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" })] })] }), activeItem.type === 'image' && activeItem.url && (_jsx("div", { className: "p-4 border-b border-gray-200", children: _jsx(FocalPointPicker, { imageUrl: activeItem.url, focalX: focalX, focalY: focalY, onChange: (x, y) => { setFocalX(x); setFocalY(y); } }) })), _jsxs("div", { className: "p-4 border-b border-gray-200", children: [_jsxs("h4", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide mb-3", children: ["Used On ", activeItem.usedOn && `(${activeItem.usedOn.length})`] }), activeItem.usedOn && activeItem.usedOn.length > 0 ? (_jsx("div", { className: "space-y-2", children: activeItem.usedOn.map((usage, i) => (_jsxs("button", { type: "button", onClick: () => onNavigate?.(usage.path), className: "w-full flex items-center gap-2 p-2 rounded-lg border border-gray-200 hover:bg-gray-50 transition-colors text-left", children: [_jsx(Link2, { className: "w-4 h-4 text-gray-400 shrink-0" }), _jsx("span", { className: "text-sm text-gray-900 flex-1 truncate", children: usage.page }), _jsx(ExternalLink, { className: "w-3.5 h-3.5 text-gray-400 shrink-0" })] }, i))) })) : (_jsx("div", { className: "p-3 bg-orange-50 border border-orange-200 rounded-lg", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(AlertTriangle, { className: "w-4 h-4 text-orange-600 mt-0.5 shrink-0" }), _jsxs("div", { children: [_jsx("p", { className: "text-xs font-medium text-orange-900", children: "Orphaned media" }), _jsx("p", { className: "text-xs text-orange-700 mt-0.5", children: "This file isn't used on any page. Consider deleting it to save storage." })] })] }) }))] }), _jsxs("div", { className: "p-4 space-y-3", children: [_jsx("h4", { className: "text-xs font-semibold text-gray-500 uppercase tracking-wide", children: "AI Optimization" }), _jsxs("button", { type: "button", onClick: () => handleAiGenerate('optimize'), disabled: aiGenerating === 'optimize', className: "w-full flex items-center gap-2 p-3 rounded-lg border border-indigo-200 bg-indigo-50 hover:bg-indigo-100 transition-colors text-left disabled:opacity-50", children: [_jsx(Sparkles, { className: `w-5 h-5 text-indigo-600 shrink-0 ${aiGenerating === 'optimize' ? 'animate-spin' : ''}` }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "text-sm font-medium text-indigo-900", children: aiGenerating === 'optimize' ? 'Optimizing...' : 'Optimize Image' }), _jsx("div", { className: "text-xs text-indigo-700 mt-0.5", children: "Compress and convert to modern format (WebP/AVIF)" })] })] }), _jsxs("button", { type: "button", className: "w-full flex items-center gap-2 p-3 rounded-lg border border-gray-200 hover:bg-gray-50 transition-colors text-left", children: [_jsx(Bot, { className: "w-5 h-5 text-gray-500 shrink-0" }), _jsxs("div", { className: "flex-1", children: [_jsx("div", { className: "text-sm font-medium text-gray-900", children: "AI Content Analysis" }), _jsx("div", { className: "text-xs text-gray-600 mt-0.5", children: "Detect objects, faces, text, and suggest categories" })] })] })] })] }), _jsxs("div", { className: "p-4 border-t border-gray-200 bg-white sticky bottom-0 flex items-center gap-2", children: [_jsxs("button", { type: "button", onClick: handleSaveDetails, disabled: saving, className: "flex-1 px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors disabled:opacity-50 flex items-center justify-center gap-2", children: [saving && _jsx(Loader2, { className: "w-4 h-4 animate-spin" }), saving ? 'Saving...' : 'Save Changes'] }), _jsx("button", { type: "button", className: "p-2 hover:bg-gray-100 rounded-lg transition-colors", title: "Download", children: _jsx(Download, { className: "w-4 h-4 text-gray-600" }) }), _jsx("button", { type: "button", onClick: () => deleteMedia(activeItem.id), className: "p-2 hover:bg-gray-100 rounded-lg transition-colors", title: "Delete", children: _jsx(Trash2, { className: "w-4 h-4 text-red-600" }) })] })] }))] }))] })] })] }));
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=MediaBrowser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MediaBrowser.js","sourceRoot":"","sources":["../../src/views/MediaBrowser.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageEditor.d.ts","sourceRoot":"","sources":["../../src/views/PageEditor.tsx"],"names":[],"mappings":"AASA,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,2CAiL7D"}
|
|
@@ -0,0 +1,74 @@
|
|
|
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 { SEOPanel } from '../components/SEOPanel';
|
|
7
|
+
import { useApiData } from '../lib/useApiData';
|
|
8
|
+
import { cmsApi } from '../lib/api';
|
|
9
|
+
export function PageEditor({ id, onNavigate }) {
|
|
10
|
+
const isNew = !id;
|
|
11
|
+
const { data, loading, error } = useApiData(isNew ? '' : `/collections/pages/${id}`);
|
|
12
|
+
const [title, setTitle] = useState('');
|
|
13
|
+
const [slug, setSlug] = useState('');
|
|
14
|
+
const [status, setStatus] = useState('draft');
|
|
15
|
+
const [saving, setSaving] = useState(false);
|
|
16
|
+
const [initialized, setInitialized] = useState(isNew);
|
|
17
|
+
const [seoData, setSeoData] = useState({});
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
if (data && !initialized) {
|
|
20
|
+
setTitle(data.title ?? '');
|
|
21
|
+
setSlug(data.slug ?? '');
|
|
22
|
+
setStatus(data.status === 'PUBLISHED' ? 'published' : 'draft');
|
|
23
|
+
setInitialized(true);
|
|
24
|
+
}
|
|
25
|
+
}, [data, initialized]);
|
|
26
|
+
const savePage = async () => {
|
|
27
|
+
setSaving(true);
|
|
28
|
+
const body = JSON.stringify({
|
|
29
|
+
title,
|
|
30
|
+
slug,
|
|
31
|
+
status: status === 'published' ? 'PUBLISHED' : 'DRAFT',
|
|
32
|
+
});
|
|
33
|
+
const res = isNew
|
|
34
|
+
? await cmsApi('/collections/pages', { method: 'POST', body })
|
|
35
|
+
: await cmsApi(`/collections/pages/${id}`, { method: 'PUT', body });
|
|
36
|
+
setSaving(false);
|
|
37
|
+
if (res.error) {
|
|
38
|
+
toast.error(res.error);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
toast.success('Page saved successfully!');
|
|
42
|
+
if (isNew && res.data?.id) {
|
|
43
|
+
onNavigate?.(`/pages/${res.data.id}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const publishPage = async () => {
|
|
48
|
+
setSaving(true);
|
|
49
|
+
const body = JSON.stringify({
|
|
50
|
+
title,
|
|
51
|
+
slug,
|
|
52
|
+
status: 'PUBLISHED',
|
|
53
|
+
});
|
|
54
|
+
const endpoint = isNew ? '/collections/pages' : `/collections/pages/${id}`;
|
|
55
|
+
const method = isNew ? 'POST' : 'PUT';
|
|
56
|
+
const res = await cmsApi(endpoint, { method, body });
|
|
57
|
+
setSaving(false);
|
|
58
|
+
if (res.error) {
|
|
59
|
+
toast.error(res.error);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
setStatus('published');
|
|
63
|
+
toast.success('Page published!');
|
|
64
|
+
if (isNew && res.data?.id) {
|
|
65
|
+
onNavigate?.(`/pages/${res.data.id}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
if (!isNew && loading) {
|
|
70
|
+
return (_jsx("div", { className: "h-full flex items-center justify-center", children: _jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }) }));
|
|
71
|
+
}
|
|
72
|
+
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-4 py-3", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("button", { onClick: () => onNavigate?.('/pages'), 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" }), "Back to Pages"] }), _jsx("div", { className: "flex items-center gap-3", 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" }), "Preview"] }) })] }) }), _jsxs("div", { className: "flex-1 overflow-hidden flex", 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: "Page 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" })] }), _jsxs("div", { className: "border-2 border-dashed border-gray-300 rounded-lg p-8 text-center", children: [_jsx("p", { className: "text-gray-500 mb-2", children: "No blocks added yet" }), _jsx("p", { className: "text-sm text-gray-400", children: "Click \"Add Block\" to start building your page" }), _jsx("button", { className: "mt-4 px-4 py-2 text-sm bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors", children: "Add Block" })] })] }) }), _jsx("div", { className: "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" })] })] }), _jsx("button", { onClick: savePage, 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 Page' }), status === 'draft' && (_jsx("button", { onClick: publishPage, 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' }))] })] }), _jsx(SEOPanel, { title: title, slug: slug, seoData: seoData, onChange: setSeoData })] }) })] })] }));
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=PageEditor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageEditor.js","sourceRoot":"","sources":["../../src/views/PageEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Pages.d.ts","sourceRoot":"","sources":["../../src/views/Pages.tsx"],"names":[],"mappings":"AAYA,MAAM,WAAW,UAAU;IACzB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAYD,wBAAgB,KAAK,CAAC,EAAE,UAAU,EAAE,EAAE,UAAU,2CAuU/C"}
|
|
@@ -0,0 +1,127 @@
|
|
|
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, GripVertical, FolderInput } from 'lucide-react';
|
|
4
|
+
import { useState, useMemo, useCallback } 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
|
+
import { FolderTree } from '../components/FolderTree';
|
|
10
|
+
function buildApiUrl(folderSel) {
|
|
11
|
+
const base = '/collections/pages?pageSize=100';
|
|
12
|
+
if (folderSel.type === 'smart') {
|
|
13
|
+
if (folderSel.smart === 'recent')
|
|
14
|
+
return `${base}&sort=updatedAt&order=desc&pageSize=20`;
|
|
15
|
+
if (folderSel.smart === 'uncategorized')
|
|
16
|
+
return `${base}&folderId=none`;
|
|
17
|
+
return base;
|
|
18
|
+
}
|
|
19
|
+
return `${base}&folderId=${folderSel.folderId}`;
|
|
20
|
+
}
|
|
21
|
+
export function Pages({ onNavigate }) {
|
|
22
|
+
const [folderSel, setFolderSel] = useState({ type: 'smart', smart: 'all' });
|
|
23
|
+
const [sidebarOpen, setSidebarOpen] = useState(true);
|
|
24
|
+
const apiUrl = useMemo(() => buildApiUrl(folderSel), [folderSel]);
|
|
25
|
+
const { data, loading, error, refetch } = useApiData(apiUrl);
|
|
26
|
+
const allData = useApiData('/collections/pages?pageSize=1');
|
|
27
|
+
const uncatData = useApiData('/collections/pages?pageSize=1&folderId=none');
|
|
28
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
29
|
+
const [filterStatus, setFilterStatus] = useState('all');
|
|
30
|
+
const [filterTemplate, setFilterTemplate] = useState('all');
|
|
31
|
+
const [selectedPages, setSelectedPages] = useState([]);
|
|
32
|
+
const [sortConfig, setSortConfig] = useState(null);
|
|
33
|
+
const pages = data?.docs ?? [];
|
|
34
|
+
const filteredAndSorted = useMemo(() => {
|
|
35
|
+
let results = pages.filter((page) => {
|
|
36
|
+
const matchesSearch = (page.title ?? '').toLowerCase().includes(searchQuery.toLowerCase()) ||
|
|
37
|
+
(page.author ?? '').toLowerCase().includes(searchQuery.toLowerCase());
|
|
38
|
+
const matchesStatus = filterStatus === 'all' || (page.status ?? '').toLowerCase() === filterStatus.toLowerCase();
|
|
39
|
+
const matchesTemplate = filterTemplate === 'all' || (page.template ?? '').toLowerCase() === filterTemplate.toLowerCase();
|
|
40
|
+
return matchesSearch && matchesStatus && matchesTemplate;
|
|
41
|
+
});
|
|
42
|
+
if (searchQuery.trim()) {
|
|
43
|
+
results = sortByRelevance(results, searchQuery, (p) => [p.title, p.author ?? '', p.template ?? '']);
|
|
44
|
+
}
|
|
45
|
+
else if (sortConfig) {
|
|
46
|
+
results = [...results].sort((a, b) => {
|
|
47
|
+
const aVal = a[sortConfig.key] ?? '';
|
|
48
|
+
const bVal = b[sortConfig.key] ?? '';
|
|
49
|
+
const cmp = String(aVal).localeCompare(String(bVal));
|
|
50
|
+
return sortConfig.direction === 'asc' ? cmp : -cmp;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return results;
|
|
54
|
+
}, [pages, searchQuery, filterStatus, filterTemplate, sortConfig]);
|
|
55
|
+
const handleSelectAll = (checked) => {
|
|
56
|
+
setSelectedPages(checked ? filteredAndSorted.map((p) => p.id) : []);
|
|
57
|
+
};
|
|
58
|
+
const handleSelectPage = (id) => {
|
|
59
|
+
setSelectedPages(prev => prev.includes(id) ? prev.filter(pid => pid !== id) : [...prev, id]);
|
|
60
|
+
};
|
|
61
|
+
const handleBulkDelete = async () => {
|
|
62
|
+
for (const id of selectedPages) {
|
|
63
|
+
await cmsApi(`/collections/pages/${id}`, { method: 'DELETE' });
|
|
64
|
+
}
|
|
65
|
+
toast.success(`${selectedPages.length} pages deleted`);
|
|
66
|
+
setSelectedPages([]);
|
|
67
|
+
refetch();
|
|
68
|
+
};
|
|
69
|
+
const handleBulkPublish = async () => {
|
|
70
|
+
for (const id of selectedPages) {
|
|
71
|
+
await cmsApi(`/collections/pages/${id}`, {
|
|
72
|
+
method: 'PUT',
|
|
73
|
+
body: JSON.stringify({ status: 'PUBLISHED' }),
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
toast.success(`${selectedPages.length} pages published`);
|
|
77
|
+
setSelectedPages([]);
|
|
78
|
+
refetch();
|
|
79
|
+
};
|
|
80
|
+
const handleBulkUnpublish = async () => {
|
|
81
|
+
for (const id of selectedPages) {
|
|
82
|
+
await cmsApi(`/collections/pages/${id}`, {
|
|
83
|
+
method: 'PUT',
|
|
84
|
+
body: JSON.stringify({ status: 'DRAFT' }),
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
toast.success(`${selectedPages.length} pages unpublished`);
|
|
88
|
+
setSelectedPages([]);
|
|
89
|
+
refetch();
|
|
90
|
+
};
|
|
91
|
+
const handleDelete = async (id) => {
|
|
92
|
+
await cmsApi(`/collections/pages/${id}`, { method: 'DELETE' });
|
|
93
|
+
toast.success('Page deleted');
|
|
94
|
+
setSelectedPages(prev => prev.filter(pid => pid !== id));
|
|
95
|
+
refetch();
|
|
96
|
+
};
|
|
97
|
+
const handleDropItem = useCallback(async (itemId, folderId) => {
|
|
98
|
+
const res = await cmsApi(`/documents/${itemId}/folder`, {
|
|
99
|
+
method: 'PUT',
|
|
100
|
+
body: JSON.stringify({ folderId }),
|
|
101
|
+
});
|
|
102
|
+
if (res.error) {
|
|
103
|
+
toast.error(res.error);
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
toast.success(folderId ? 'Moved to folder' : 'Removed from folder');
|
|
107
|
+
refetch();
|
|
108
|
+
}
|
|
109
|
+
}, [refetch]);
|
|
110
|
+
const handleDragStart = (e, id) => {
|
|
111
|
+
e.dataTransfer.setData('text/actuate-item-id', id);
|
|
112
|
+
e.dataTransfer.effectAllowed = 'move';
|
|
113
|
+
};
|
|
114
|
+
function SortHeader({ label, sortKey }) {
|
|
115
|
+
const active = sortConfig?.key === sortKey;
|
|
116
|
+
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" }))] }));
|
|
117
|
+
}
|
|
118
|
+
if (loading) {
|
|
119
|
+
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" }) }));
|
|
120
|
+
}
|
|
121
|
+
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", { className: "flex items-center gap-3", children: [_jsx("button", { type: "button", onClick: () => setSidebarOpen(prev => !prev), className: "p-1.5 rounded-lg hover:bg-gray-100 transition-colors", title: sidebarOpen ? 'Hide folders' : 'Show folders', children: _jsx(FolderInput, { className: "w-5 h-5 text-gray-600" }) }), _jsxs("div", { children: [_jsx("h1", { className: "text-xl sm:text-2xl font-semibold text-gray-900 mb-1", children: "Pages" }), _jsxs("p", { className: "text-sm text-gray-600", children: [filteredAndSorted.length, " total pages"] })] })] }), _jsxs("button", { onClick: () => onNavigate?.('/pages/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 Page" }), _jsx("span", { className: "sm:hidden", children: "New" })] })] }), _jsxs("div", { className: "flex gap-4 flex-1 min-h-0 overflow-hidden", children: [sidebarOpen && (_jsx("div", { className: "w-56 shrink-0 bg-white rounded-lg border border-gray-200 overflow-hidden flex flex-col", children: _jsx(FolderTree, { scope: "pages", selected: folderSel, onSelect: (sel) => { setFolderSel(sel); setSelectedPages([]); }, totalCount: allData.data?.total, uncategorizedCount: uncatData.data?.total, onDropItem: handleDropItem }) })), _jsxs("div", { className: "flex-1 flex flex-col min-w-0", children: [_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 pages...", 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: filterTemplate, onChange: (e) => setFilterTemplate(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 Templates" }), _jsx("option", { value: "landing", children: "Landing" }), _jsx("option", { value: "standard", children: "Standard" }), _jsx("option", { value: "marketing", children: "Marketing" }), _jsx("option", { value: "blog", children: "Blog" })] }), _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" })] })] })] }) }), selectedPages.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: [selectedPages.length, " page", selectedPages.length !== 1 ? 's' : '', " selected"] }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "button", onClick: handleBulkPublish, className: "flex-1 sm:flex-none px-3 py-1.5 text-sm bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors", children: "Publish" }), _jsx("button", { type: "button", onClick: handleBulkUnpublish, className: "flex-1 sm:flex-none px-3 py-1.5 text-sm bg-yellow-600 text-white rounded-lg hover:bg-yellow-700 transition-colors", children: "Unpublish" }), _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: () => setSelectedPages([]), 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: folderSel.type === 'smart' && folderSel.smart === 'uncategorized'
|
|
122
|
+
? 'No uncategorized pages'
|
|
123
|
+
: folderSel.type === 'folder'
|
|
124
|
+
? 'No pages in this folder'
|
|
125
|
+
: 'No pages yet' }), _jsx("button", { onClick: () => onNavigate?.('/pages/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 page" })] })) : (_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: selectedPages.length === filteredAndSorted.length && filteredAndSorted.length > 0, onChange: (e) => handleSelectAll(e.target.checked), className: "rounded border-gray-300" }) }), _jsx("th", { className: "w-6 px-1 py-2" }), _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: "Template", sortKey: "template" }) }), _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((page) => (_jsxs("tr", { className: "hover:bg-gray-50 transition-colors", draggable: true, onDragStart: (e) => handleDragStart(e, page.id), children: [_jsx("td", { className: "px-3 py-2", children: _jsx("input", { type: "checkbox", checked: selectedPages.includes(page.id), onChange: () => handleSelectPage(page.id), className: "rounded border-gray-300" }) }), _jsx("td", { className: "px-1 py-2 cursor-grab", children: _jsx(GripVertical, { className: "w-4 h-4 text-gray-300" }) }), _jsx("td", { className: "px-3 py-2", children: _jsx("button", { type: "button", onClick: () => onNavigate?.(`/pages/${page.id}`), className: "font-medium text-gray-900 hover:text-blue-600 text-sm text-left", children: page.title }) }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: page.author }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: page.template }), _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 ${page.status === 'Published' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: page.status }) }), _jsx("td", { className: "px-3 py-2 text-sm text-gray-600", children: page.date }), _jsx("td", { className: "px-3 py-2", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("button", { type: "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" }) }), _jsx("button", { type: "button", onClick: () => handleDelete(page.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" }) })] }) })] }, page.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((page) => (_jsx("div", { className: "p-3", draggable: true, onDragStart: (e) => handleDragStart(e, page.id), children: _jsxs("div", { className: "flex items-start gap-3", children: [_jsx("input", { type: "checkbox", checked: selectedPages.includes(page.id), onChange: () => handleSelectPage(page.id), className: "rounded border-gray-300 mt-1" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("button", { type: "button", onClick: () => onNavigate?.(`/pages/${page.id}`), className: "font-medium text-sm text-gray-900 hover:text-blue-600 block mb-1 text-left", children: page.title }), _jsxs("div", { className: "flex flex-wrap items-center gap-2 text-xs text-gray-600 mb-2", children: [_jsx("span", { children: page.author }), _jsx("span", { children: "\u2022" }), _jsx("span", { children: page.date }), _jsx("span", { className: `px-2 py-0.5 rounded-full text-xs font-medium ${page.status === 'Published' ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800'}`, children: page.status })] })] }), _jsx("button", { type: "button", onClick: () => handleDelete(page.id), className: "p-1.5 hover:bg-gray-100 rounded transition-colors", children: _jsx(Trash2, { className: "w-4 h-4 text-red-600" }) })] }) }, page.id))) }) })] }))] })] })] }));
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=Pages.js.map
|