@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.
Files changed (295) hide show
  1. package/dist/AdminRoot.d.ts +21 -0
  2. package/dist/AdminRoot.d.ts.map +1 -0
  3. package/dist/AdminRoot.js +136 -0
  4. package/dist/AdminRoot.js.map +1 -0
  5. package/dist/components/Breadcrumbs.d.ts +6 -0
  6. package/dist/components/Breadcrumbs.d.ts.map +1 -0
  7. package/dist/components/Breadcrumbs.js +52 -0
  8. package/dist/components/Breadcrumbs.js.map +1 -0
  9. package/dist/components/CommandPalette.d.ts +7 -0
  10. package/dist/components/CommandPalette.d.ts.map +1 -0
  11. package/dist/components/CommandPalette.js +152 -0
  12. package/dist/components/CommandPalette.js.map +1 -0
  13. package/dist/components/ErrorBoundary.d.ts +17 -0
  14. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  15. package/dist/components/ErrorBoundary.js +24 -0
  16. package/dist/components/ErrorBoundary.js.map +1 -0
  17. package/dist/components/FocalPointPicker.d.ts +9 -0
  18. package/dist/components/FocalPointPicker.d.ts.map +1 -0
  19. package/dist/components/FocalPointPicker.js +19 -0
  20. package/dist/components/FocalPointPicker.js.map +1 -0
  21. package/dist/components/FolderTree.d.ts +28 -0
  22. package/dist/components/FolderTree.d.ts.map +1 -0
  23. package/dist/components/FolderTree.js +198 -0
  24. package/dist/components/FolderTree.js.map +1 -0
  25. package/dist/components/LivePreview.d.ts +10 -0
  26. package/dist/components/LivePreview.d.ts.map +1 -0
  27. package/dist/components/LivePreview.js +62 -0
  28. package/dist/components/LivePreview.js.map +1 -0
  29. package/dist/components/LocaleProvider.d.ts +28 -0
  30. package/dist/components/LocaleProvider.d.ts.map +1 -0
  31. package/dist/components/LocaleProvider.js +29 -0
  32. package/dist/components/LocaleProvider.js.map +1 -0
  33. package/dist/components/LocaleSwitcher.d.ts +2 -0
  34. package/dist/components/LocaleSwitcher.d.ts.map +1 -0
  35. package/dist/components/LocaleSwitcher.js +13 -0
  36. package/dist/components/LocaleSwitcher.js.map +1 -0
  37. package/dist/components/MediaPickerModal.d.ts +8 -0
  38. package/dist/components/MediaPickerModal.d.ts.map +1 -0
  39. package/dist/components/MediaPickerModal.js +53 -0
  40. package/dist/components/MediaPickerModal.js.map +1 -0
  41. package/dist/components/PresenceIndicator.d.ts +7 -0
  42. package/dist/components/PresenceIndicator.d.ts.map +1 -0
  43. package/dist/components/PresenceIndicator.js +37 -0
  44. package/dist/components/PresenceIndicator.js.map +1 -0
  45. package/dist/components/SEOPanel.d.ts +26 -0
  46. package/dist/components/SEOPanel.d.ts.map +1 -0
  47. package/dist/components/SEOPanel.js +249 -0
  48. package/dist/components/SEOPanel.js.map +1 -0
  49. package/dist/components/ThemeProvider.d.ts +13 -0
  50. package/dist/components/ThemeProvider.d.ts.map +1 -0
  51. package/dist/components/ThemeProvider.js +62 -0
  52. package/dist/components/ThemeProvider.js.map +1 -0
  53. package/dist/components/TipTapEditor.d.ts +9 -0
  54. package/dist/components/TipTapEditor.d.ts.map +1 -0
  55. package/dist/components/TipTapEditor.js +167 -0
  56. package/dist/components/TipTapEditor.js.map +1 -0
  57. package/dist/components/VersionHistory.d.ts +9 -0
  58. package/dist/components/VersionHistory.d.ts.map +1 -0
  59. package/dist/components/VersionHistory.js +70 -0
  60. package/dist/components/VersionHistory.js.map +1 -0
  61. package/dist/components/ui/Avatar.d.ts +9 -0
  62. package/dist/components/ui/Avatar.d.ts.map +1 -0
  63. package/dist/components/ui/Avatar.js +21 -0
  64. package/dist/components/ui/Avatar.js.map +1 -0
  65. package/dist/components/ui/Badge.d.ts +5 -0
  66. package/dist/components/ui/Badge.d.ts.map +1 -0
  67. package/dist/components/ui/Badge.js +17 -0
  68. package/dist/components/ui/Badge.js.map +1 -0
  69. package/dist/components/ui/Button.d.ts +12 -0
  70. package/dist/components/ui/Button.d.ts.map +1 -0
  71. package/dist/components/ui/Button.js +17 -0
  72. package/dist/components/ui/Button.js.map +1 -0
  73. package/dist/components/ui/CommandPalette.d.ts +14 -0
  74. package/dist/components/ui/CommandPalette.d.ts.map +1 -0
  75. package/dist/components/ui/CommandPalette.js +52 -0
  76. package/dist/components/ui/CommandPalette.js.map +1 -0
  77. package/dist/components/ui/ConfirmDialog.d.ts +12 -0
  78. package/dist/components/ui/ConfirmDialog.d.ts.map +1 -0
  79. package/dist/components/ui/ConfirmDialog.js +11 -0
  80. package/dist/components/ui/ConfirmDialog.js.map +1 -0
  81. package/dist/components/ui/DataTable.d.ts +30 -0
  82. package/dist/components/ui/DataTable.d.ts.map +1 -0
  83. package/dist/components/ui/DataTable.js +40 -0
  84. package/dist/components/ui/DataTable.js.map +1 -0
  85. package/dist/components/ui/EmptyState.d.ts +10 -0
  86. package/dist/components/ui/EmptyState.d.ts.map +1 -0
  87. package/dist/components/ui/EmptyState.js +6 -0
  88. package/dist/components/ui/EmptyState.js.map +1 -0
  89. package/dist/components/ui/Modal.d.ts +10 -0
  90. package/dist/components/ui/Modal.d.ts.map +1 -0
  91. package/dist/components/ui/Modal.js +19 -0
  92. package/dist/components/ui/Modal.js.map +1 -0
  93. package/dist/components/ui/Pagination.d.ts +9 -0
  94. package/dist/components/ui/Pagination.d.ts.map +1 -0
  95. package/dist/components/ui/Pagination.js +21 -0
  96. package/dist/components/ui/Pagination.js.map +1 -0
  97. package/dist/components/ui/SearchInput.d.ts +7 -0
  98. package/dist/components/ui/SearchInput.d.ts.map +1 -0
  99. package/dist/components/ui/SearchInput.js +6 -0
  100. package/dist/components/ui/SearchInput.js.map +1 -0
  101. package/dist/components/ui/Skeleton.d.ts +9 -0
  102. package/dist/components/ui/Skeleton.d.ts.map +1 -0
  103. package/dist/components/ui/Skeleton.js +11 -0
  104. package/dist/components/ui/Skeleton.js.map +1 -0
  105. package/dist/components/ui/Toast.d.ts +18 -0
  106. package/dist/components/ui/Toast.d.ts.map +1 -0
  107. package/dist/components/ui/Toast.js +29 -0
  108. package/dist/components/ui/Toast.js.map +1 -0
  109. package/dist/components/ui/index.d.ts +25 -0
  110. package/dist/components/ui/index.d.ts.map +1 -0
  111. package/dist/components/ui/index.js +13 -0
  112. package/dist/components/ui/index.js.map +1 -0
  113. package/dist/fields/ArrayField.d.ts +9 -0
  114. package/dist/fields/ArrayField.d.ts.map +1 -0
  115. package/dist/fields/ArrayField.js +21 -0
  116. package/dist/fields/ArrayField.js.map +1 -0
  117. package/dist/fields/BlockBuilderField.d.ts +16 -0
  118. package/dist/fields/BlockBuilderField.d.ts.map +1 -0
  119. package/dist/fields/BlockBuilderField.js +110 -0
  120. package/dist/fields/BlockBuilderField.js.map +1 -0
  121. package/dist/fields/DateField.d.ts +9 -0
  122. package/dist/fields/DateField.d.ts.map +1 -0
  123. package/dist/fields/DateField.js +6 -0
  124. package/dist/fields/DateField.js.map +1 -0
  125. package/dist/fields/FieldRenderer.d.ts +22 -0
  126. package/dist/fields/FieldRenderer.d.ts.map +1 -0
  127. package/dist/fields/FieldRenderer.js +38 -0
  128. package/dist/fields/FieldRenderer.js.map +1 -0
  129. package/dist/fields/GroupField.d.ts +8 -0
  130. package/dist/fields/GroupField.d.ts.map +1 -0
  131. package/dist/fields/GroupField.js +8 -0
  132. package/dist/fields/GroupField.js.map +1 -0
  133. package/dist/fields/MediaField.d.ts +13 -0
  134. package/dist/fields/MediaField.d.ts.map +1 -0
  135. package/dist/fields/MediaField.js +6 -0
  136. package/dist/fields/MediaField.js.map +1 -0
  137. package/dist/fields/NavBuilderField.d.ts +15 -0
  138. package/dist/fields/NavBuilderField.d.ts.map +1 -0
  139. package/dist/fields/NavBuilderField.js +19 -0
  140. package/dist/fields/NavBuilderField.js.map +1 -0
  141. package/dist/fields/NumberField.d.ts +12 -0
  142. package/dist/fields/NumberField.d.ts.map +1 -0
  143. package/dist/fields/NumberField.js +6 -0
  144. package/dist/fields/NumberField.js.map +1 -0
  145. package/dist/fields/RelationshipField.d.ts +13 -0
  146. package/dist/fields/RelationshipField.d.ts.map +1 -0
  147. package/dist/fields/RelationshipField.js +119 -0
  148. package/dist/fields/RelationshipField.js.map +1 -0
  149. package/dist/fields/RichTextField.d.ts +9 -0
  150. package/dist/fields/RichTextField.d.ts.map +1 -0
  151. package/dist/fields/RichTextField.js +7 -0
  152. package/dist/fields/RichTextField.js.map +1 -0
  153. package/dist/fields/SelectField.d.ts +11 -0
  154. package/dist/fields/SelectField.d.ts.map +1 -0
  155. package/dist/fields/SelectField.js +31 -0
  156. package/dist/fields/SelectField.js.map +1 -0
  157. package/dist/fields/SlugField.d.ts +10 -0
  158. package/dist/fields/SlugField.d.ts.map +1 -0
  159. package/dist/fields/SlugField.js +15 -0
  160. package/dist/fields/SlugField.js.map +1 -0
  161. package/dist/fields/TextField.d.ts +11 -0
  162. package/dist/fields/TextField.d.ts.map +1 -0
  163. package/dist/fields/TextField.js +8 -0
  164. package/dist/fields/TextField.js.map +1 -0
  165. package/dist/fields/ToggleField.d.ts +8 -0
  166. package/dist/fields/ToggleField.d.ts.map +1 -0
  167. package/dist/fields/ToggleField.js +6 -0
  168. package/dist/fields/ToggleField.js.map +1 -0
  169. package/dist/fields/block-types.d.ts +18 -0
  170. package/dist/fields/block-types.d.ts.map +1 -0
  171. package/dist/fields/block-types.js +88 -0
  172. package/dist/fields/block-types.js.map +1 -0
  173. package/dist/fields/index.d.ts +18 -0
  174. package/dist/fields/index.d.ts.map +1 -0
  175. package/dist/fields/index.js +16 -0
  176. package/dist/fields/index.js.map +1 -0
  177. package/dist/hooks/useContentLock.d.ts +12 -0
  178. package/dist/hooks/useContentLock.d.ts.map +1 -0
  179. package/dist/hooks/useContentLock.js +38 -0
  180. package/dist/hooks/useContentLock.js.map +1 -0
  181. package/dist/hooks/useDebounce.d.ts +2 -0
  182. package/dist/hooks/useDebounce.d.ts.map +1 -0
  183. package/dist/hooks/useDebounce.js +11 -0
  184. package/dist/hooks/useDebounce.js.map +1 -0
  185. package/dist/hooks/useKeyboardShortcuts.d.ts +6 -0
  186. package/dist/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  187. package/dist/hooks/useKeyboardShortcuts.js +26 -0
  188. package/dist/hooks/useKeyboardShortcuts.js.map +1 -0
  189. package/dist/index.d.ts +52 -0
  190. package/dist/index.d.ts.map +1 -0
  191. package/dist/index.js +39 -0
  192. package/dist/index.js.map +1 -0
  193. package/dist/layout/Header.d.ts +7 -0
  194. package/dist/layout/Header.d.ts.map +1 -0
  195. package/dist/layout/Header.js +18 -0
  196. package/dist/layout/Header.js.map +1 -0
  197. package/dist/layout/Layout.d.ts +10 -0
  198. package/dist/layout/Layout.d.ts.map +1 -0
  199. package/dist/layout/Layout.js +25 -0
  200. package/dist/layout/Layout.js.map +1 -0
  201. package/dist/layout/Sidebar.d.ts +9 -0
  202. package/dist/layout/Sidebar.d.ts.map +1 -0
  203. package/dist/layout/Sidebar.js +63 -0
  204. package/dist/layout/Sidebar.js.map +1 -0
  205. package/dist/lib/api.d.ts +8 -0
  206. package/dist/lib/api.d.ts.map +1 -0
  207. package/dist/lib/api.js +59 -0
  208. package/dist/lib/api.js.map +1 -0
  209. package/dist/lib/search.d.ts +11 -0
  210. package/dist/lib/search.d.ts.map +1 -0
  211. package/dist/lib/search.js +46 -0
  212. package/dist/lib/search.js.map +1 -0
  213. package/dist/lib/useApiData.d.ts +8 -0
  214. package/dist/lib/useApiData.d.ts.map +1 -0
  215. package/dist/lib/useApiData.js +36 -0
  216. package/dist/lib/useApiData.js.map +1 -0
  217. package/dist/lib/utils.d.ts +3 -0
  218. package/dist/lib/utils.d.ts.map +1 -0
  219. package/dist/lib/utils.js +6 -0
  220. package/dist/lib/utils.js.map +1 -0
  221. package/dist/router/index.d.ts +10 -0
  222. package/dist/router/index.d.ts.map +1 -0
  223. package/dist/router/index.js +61 -0
  224. package/dist/router/index.js.map +1 -0
  225. package/dist/views/CollectionList.d.ts +7 -0
  226. package/dist/views/CollectionList.d.ts.map +1 -0
  227. package/dist/views/CollectionList.js +107 -0
  228. package/dist/views/CollectionList.js.map +1 -0
  229. package/dist/views/Dashboard.d.ts +5 -0
  230. package/dist/views/Dashboard.d.ts.map +1 -0
  231. package/dist/views/Dashboard.js +17 -0
  232. package/dist/views/Dashboard.js.map +1 -0
  233. package/dist/views/DocumentEdit.d.ts +8 -0
  234. package/dist/views/DocumentEdit.d.ts.map +1 -0
  235. package/dist/views/DocumentEdit.js +210 -0
  236. package/dist/views/DocumentEdit.js.map +1 -0
  237. package/dist/views/FormEditor.d.ts +6 -0
  238. package/dist/views/FormEditor.d.ts.map +1 -0
  239. package/dist/views/FormEditor.js +126 -0
  240. package/dist/views/FormEditor.js.map +1 -0
  241. package/dist/views/FormSubmissions.d.ts +6 -0
  242. package/dist/views/FormSubmissions.d.ts.map +1 -0
  243. package/dist/views/FormSubmissions.js +88 -0
  244. package/dist/views/FormSubmissions.js.map +1 -0
  245. package/dist/views/Forms.d.ts +5 -0
  246. package/dist/views/Forms.d.ts.map +1 -0
  247. package/dist/views/Forms.js +24 -0
  248. package/dist/views/Forms.js.map +1 -0
  249. package/dist/views/Login.d.ts +10 -0
  250. package/dist/views/Login.d.ts.map +1 -0
  251. package/dist/views/Login.js +83 -0
  252. package/dist/views/Login.js.map +1 -0
  253. package/dist/views/MediaBrowser.d.ts +5 -0
  254. package/dist/views/MediaBrowser.d.ts.map +1 -0
  255. package/dist/views/MediaBrowser.js +245 -0
  256. package/dist/views/MediaBrowser.js.map +1 -0
  257. package/dist/views/PageEditor.d.ts +6 -0
  258. package/dist/views/PageEditor.d.ts.map +1 -0
  259. package/dist/views/PageEditor.js +74 -0
  260. package/dist/views/PageEditor.js.map +1 -0
  261. package/dist/views/Pages.d.ts +5 -0
  262. package/dist/views/Pages.d.ts.map +1 -0
  263. package/dist/views/Pages.js +127 -0
  264. package/dist/views/Pages.js.map +1 -0
  265. package/dist/views/PostEditor.d.ts +6 -0
  266. package/dist/views/PostEditor.d.ts.map +1 -0
  267. package/dist/views/PostEditor.js +79 -0
  268. package/dist/views/PostEditor.js.map +1 -0
  269. package/dist/views/Posts.d.ts +5 -0
  270. package/dist/views/Posts.d.ts.map +1 -0
  271. package/dist/views/Posts.js +67 -0
  272. package/dist/views/Posts.js.map +1 -0
  273. package/dist/views/Redirects.d.ts +5 -0
  274. package/dist/views/Redirects.d.ts.map +1 -0
  275. package/dist/views/Redirects.js +79 -0
  276. package/dist/views/Redirects.js.map +1 -0
  277. package/dist/views/SEO.d.ts +6 -0
  278. package/dist/views/SEO.d.ts.map +1 -0
  279. package/dist/views/SEO.js +120 -0
  280. package/dist/views/SEO.js.map +1 -0
  281. package/dist/views/Settings.d.ts +5 -0
  282. package/dist/views/Settings.d.ts.map +1 -0
  283. package/dist/views/Settings.js +95 -0
  284. package/dist/views/Settings.js.map +1 -0
  285. package/dist/views/SetupWizard.d.ts +13 -0
  286. package/dist/views/SetupWizard.d.ts.map +1 -0
  287. package/dist/views/SetupWizard.js +68 -0
  288. package/dist/views/SetupWizard.js.map +1 -0
  289. package/dist/views/Users.d.ts +5 -0
  290. package/dist/views/Users.d.ts.map +1 -0
  291. package/dist/views/Users.js +69 -0
  292. package/dist/views/Users.js.map +1 -0
  293. package/package.json +71 -0
  294. package/src/styles/tailwind.css +2 -0
  295. 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,6 @@
1
+ export interface PageEditorProps {
2
+ id?: string;
3
+ onNavigate?: (path: string) => void;
4
+ }
5
+ export declare function PageEditor({ id, onNavigate }: PageEditorProps): import("react/jsx-runtime").JSX.Element;
6
+ //# sourceMappingURL=PageEditor.d.ts.map
@@ -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,5 @@
1
+ export interface PagesProps {
2
+ onNavigate?: (path: string) => void;
3
+ }
4
+ export declare function Pages({ onNavigate }: PagesProps): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=Pages.d.ts.map
@@ -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