@jhits/plugin-images 0.0.14 → 0.0.15
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/components/Image.d.ts +1 -6
- package/dist/components/Image.d.ts.map +1 -1
- package/dist/components/Image.js +86 -202
- package/dist/components/ImageEditor.d.ts.map +1 -1
- package/dist/components/ImageEditor.js +21 -125
- package/dist/components/ImagePicker.d.ts.map +1 -1
- package/dist/components/ImagePicker.js +6 -59
- package/dist/utils/fallback.d.ts +9 -4
- package/dist/utils/fallback.d.ts.map +1 -1
- package/dist/utils/fallback.js +40 -12
- package/dist/utils/transforms.d.ts.map +1 -1
- package/dist/utils/transforms.js +7 -10
- package/dist/views/ImageManager/components/CleanupLibraryModal.d.ts +12 -0
- package/dist/views/ImageManager/components/CleanupLibraryModal.d.ts.map +1 -0
- package/dist/views/ImageManager/components/CleanupLibraryModal.js +7 -0
- package/dist/views/ImageManager/components/DeleteImageModal.d.ts +15 -0
- package/dist/views/ImageManager/components/DeleteImageModal.d.ts.map +1 -0
- package/dist/views/ImageManager/components/DeleteImageModal.js +8 -0
- package/dist/views/ImageManager/components/ImageGrid.d.ts +12 -0
- package/dist/views/ImageManager/components/ImageGrid.d.ts.map +1 -0
- package/dist/views/ImageManager/components/ImageGrid.js +15 -0
- package/dist/views/ImageManager/components/ImageManagerHeader.d.ts +11 -0
- package/dist/views/ImageManager/components/ImageManagerHeader.d.ts.map +1 -0
- package/dist/views/ImageManager/components/ImageManagerHeader.js +6 -0
- package/dist/views/ImageManager/components/ImageManagerStats.d.ts +8 -0
- package/dist/views/ImageManager/components/ImageManagerStats.d.ts.map +1 -0
- package/dist/views/ImageManager/components/ImageManagerStats.js +6 -0
- package/dist/views/ImageManager/components/ImageManagerToolbar.d.ts +9 -0
- package/dist/views/ImageManager/components/ImageManagerToolbar.d.ts.map +1 -0
- package/dist/views/ImageManager/components/ImageManagerToolbar.js +10 -0
- package/dist/views/ImageManager/components/ImageTable.d.ts +13 -0
- package/dist/views/ImageManager/components/ImageTable.d.ts.map +1 -0
- package/dist/views/ImageManager/components/ImageTable.js +13 -0
- package/dist/views/ImageManager/types.d.ts +26 -0
- package/dist/views/ImageManager/types.d.ts.map +1 -0
- package/dist/views/ImageManager/types.js +1 -0
- package/dist/views/ImageManager.d.ts +1 -1
- package/dist/views/ImageManager.d.ts.map +1 -1
- package/dist/views/ImageManager.js +28 -52
- package/package.json +10 -9
- package/src/components/Image.tsx +107 -262
- package/src/components/ImageEditor.tsx +31 -193
- package/src/components/ImagePicker.tsx +22 -107
- package/src/utils/fallback.ts +46 -13
- package/src/utils/transforms.ts +9 -12
- package/src/views/ImageManager/components/CleanupLibraryModal.tsx +96 -0
- package/src/views/ImageManager/components/DeleteImageModal.tsx +144 -0
- package/src/views/ImageManager/components/ImageGrid.tsx +119 -0
- package/src/views/ImageManager/components/ImageManagerHeader.tsx +72 -0
- package/src/views/ImageManager/components/ImageManagerStats.tsx +60 -0
- package/src/views/ImageManager/components/ImageManagerToolbar.tsx +60 -0
- package/src/views/ImageManager/components/ImageTable.tsx +120 -0
- package/src/views/ImageManager/types.ts +27 -0
- package/src/views/ImageManager.tsx +103 -571
- package/src/components/BackgroundImage.d.ts +0 -11
- package/src/components/BackgroundImage.d.ts.map +0 -1
- package/src/components/GlobalImageEditor/config.d.ts +0 -9
- package/src/components/GlobalImageEditor/config.d.ts.map +0 -1
- package/src/components/GlobalImageEditor/eventHandlers.d.ts +0 -20
- package/src/components/GlobalImageEditor/eventHandlers.d.ts.map +0 -1
- package/src/components/GlobalImageEditor/imageDetection.d.ts +0 -16
- package/src/components/GlobalImageEditor/imageDetection.d.ts.map +0 -1
- package/src/components/GlobalImageEditor/imageSetup.d.ts +0 -9
- package/src/components/GlobalImageEditor/imageSetup.d.ts.map +0 -1
- package/src/components/GlobalImageEditor/saveLogic.d.ts +0 -26
- package/src/components/GlobalImageEditor/saveLogic.d.ts.map +0 -1
- package/src/components/GlobalImageEditor/stylingDetection.d.ts +0 -9
- package/src/components/GlobalImageEditor/stylingDetection.d.ts.map +0 -1
- package/src/components/GlobalImageEditor/transformParsing.d.ts +0 -16
- package/src/components/GlobalImageEditor/transformParsing.d.ts.map +0 -1
- package/src/components/GlobalImageEditor/types.d.ts +0 -36
- package/src/components/GlobalImageEditor/types.d.ts.map +0 -1
- package/src/components/GlobalImageEditor.d.ts +0 -8
- package/src/components/GlobalImageEditor.d.ts.map +0 -1
- package/src/components/Image.d.ts +0 -22
- package/src/components/Image.d.ts.map +0 -1
- package/src/components/ImageBrowserModal.d.ts +0 -13
- package/src/components/ImageBrowserModal.d.ts.map +0 -1
- package/src/components/ImageEditor.d.ts +0 -27
- package/src/components/ImageEditor.d.ts.map +0 -1
- package/src/components/ImagePicker.d.ts +0 -3
- package/src/components/ImagePicker.d.ts.map +0 -1
- package/src/components/ImagesPluginInit.d.ts +0 -24
- package/src/components/ImagesPluginInit.d.ts.map +0 -1
- package/src/hooks/useImagePicker.d.ts +0 -20
- package/src/hooks/useImagePicker.d.ts.map +0 -1
- package/src/types/index.d.ts +0 -80
- package/src/types/index.d.ts.map +0 -1
- package/src/utils/fallback.d.ts +0 -27
- package/src/utils/fallback.d.ts.map +0 -1
- package/src/utils/transforms.d.ts +0 -26
- package/src/utils/transforms.d.ts.map +0 -1
- package/src/views/ImageManager.d.ts +0 -10
- package/src/views/ImageManager.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ImageManager.d.ts","sourceRoot":"","sources":["../../src/views/ImageManager.tsx"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"ImageManager.d.ts","sourceRoot":"","sources":["../../src/views/ImageManager.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAsBH,MAAM,WAAW,qBAAqB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAClB;AAmBD,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,qBAAqB,2CAqRzE"}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Image Manager View
|
|
3
|
-
*
|
|
3
|
+
* Refactored modular interface for media management
|
|
4
4
|
*/
|
|
5
5
|
'use client';
|
|
6
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
6
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
7
7
|
import { useState, useEffect, useMemo, useCallback } from 'react';
|
|
8
|
-
import {
|
|
9
|
-
|
|
8
|
+
import { ImageIcon, Loader2 } from 'lucide-react';
|
|
9
|
+
// Components
|
|
10
|
+
import { ImageManagerHeader } from './ImageManager/components/ImageManagerHeader';
|
|
11
|
+
import { ImageManagerStats } from './ImageManager/components/ImageManagerStats';
|
|
12
|
+
import { ImageManagerToolbar } from './ImageManager/components/ImageManagerToolbar';
|
|
13
|
+
import { ImageGrid } from './ImageManager/components/ImageGrid';
|
|
14
|
+
import { ImageTable } from './ImageManager/components/ImageTable';
|
|
15
|
+
import { DeleteImageModal } from './ImageManager/components/DeleteImageModal';
|
|
16
|
+
import { CleanupLibraryModal } from './ImageManager/components/CleanupLibraryModal';
|
|
10
17
|
function formatFileSize(bytes) {
|
|
11
18
|
if (bytes === 0)
|
|
12
19
|
return '0 B';
|
|
@@ -17,12 +24,10 @@ function formatFileSize(bytes) {
|
|
|
17
24
|
}
|
|
18
25
|
function formatDate(dateString) {
|
|
19
26
|
const date = new Date(dateString);
|
|
20
|
-
return date.toLocaleDateString(
|
|
27
|
+
return date.toLocaleDateString(undefined, {
|
|
21
28
|
year: 'numeric',
|
|
22
29
|
month: 'short',
|
|
23
|
-
day: 'numeric'
|
|
24
|
-
hour: '2-digit',
|
|
25
|
-
minute: '2-digit'
|
|
30
|
+
day: 'numeric'
|
|
26
31
|
});
|
|
27
32
|
}
|
|
28
33
|
export function ImageManagerView({ siteId, locale }) {
|
|
@@ -96,6 +101,7 @@ export function ImageManagerView({ siteId, locale }) {
|
|
|
96
101
|
setImages(prev => [data.image, ...prev]);
|
|
97
102
|
}
|
|
98
103
|
}
|
|
104
|
+
handleRefresh();
|
|
99
105
|
}
|
|
100
106
|
catch (error) {
|
|
101
107
|
console.error('Upload failed:', error);
|
|
@@ -118,6 +124,7 @@ export function ImageManagerView({ siteId, locale }) {
|
|
|
118
124
|
setImages(prev => prev.filter(img => img.id !== selectedImage.id));
|
|
119
125
|
setShowDeleteModal(false);
|
|
120
126
|
setSelectedImage(null);
|
|
127
|
+
handleRefresh();
|
|
121
128
|
}
|
|
122
129
|
else {
|
|
123
130
|
const error = await response.json();
|
|
@@ -156,18 +163,19 @@ export function ImageManagerView({ siteId, locale }) {
|
|
|
156
163
|
}
|
|
157
164
|
if (deletedCount > 0) {
|
|
158
165
|
setImages(prev => prev.filter(img => isImageInUse(img.filename)));
|
|
166
|
+
handleRefresh();
|
|
159
167
|
}
|
|
160
168
|
setShowCleanupModal(false);
|
|
161
169
|
if (failedCount > 0) {
|
|
162
170
|
alert(`Deleted ${deletedCount} images. ${failedCount} failed.`);
|
|
163
171
|
}
|
|
164
172
|
else {
|
|
165
|
-
alert(`Successfully deleted ${deletedCount} unused
|
|
173
|
+
alert(`Successfully deleted ${deletedCount} unused assets.`);
|
|
166
174
|
}
|
|
167
175
|
}
|
|
168
176
|
catch (error) {
|
|
169
177
|
console.error('Cleanup failed:', error);
|
|
170
|
-
alert('Failed to cleanup
|
|
178
|
+
alert('Failed to cleanup assets');
|
|
171
179
|
}
|
|
172
180
|
finally {
|
|
173
181
|
setCleaning(false);
|
|
@@ -192,46 +200,14 @@ export function ImageManagerView({ siteId, locale }) {
|
|
|
192
200
|
const isImageInUse = (filename) => {
|
|
193
201
|
return isImageMapped(filename) || getImageUsage(filename).length > 0;
|
|
194
202
|
};
|
|
195
|
-
return (_jsxs("div", { className: "
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
setSelectedImage(image);
|
|
206
|
-
setShowDeleteModal(true);
|
|
207
|
-
}, className: `p-2 bg-white dark:bg-neutral-900 rounded-full transition-colors ${inUse
|
|
208
|
-
? 'text-neutral-400 cursor-not-allowed'
|
|
209
|
-
: 'text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20'}`, title: inUse ? 'Cannot delete - image is in use' : 'Delete', disabled: inUse, children: _jsx(Trash2, { size: 16 }) })] }), inUse && (_jsxs("div", { className: "absolute top-2 right-2 px-2 py-1 bg-red-500 text-white text-[10px] font-bold uppercase rounded-full flex items-center gap-1 shadow-lg", children: [_jsx(CheckCircle, { size: 10 }), "In Use"] }))] }), _jsxs("div", { className: "p-3", children: [_jsx("p", { className: "text-xs font-medium text-neutral-700 dark:text-neutral-300 truncate", title: image.filename, children: image.filename }), _jsxs("div", { className: "flex items-center justify-between mt-1", children: [_jsx("p", { className: "text-[10px] text-neutral-500", children: formatFileSize(image.size) }), inUse ? (_jsx("p", { className: "text-[10px] text-red-500 dark:text-red-400 font-bold", children: usage.length > 0 ? `${usage.length} ref${usage.length > 1 ? 's' : ''}` : 'mapped' })) : (_jsx("p", { className: "text-[10px] text-green-500 dark:text-green-400 font-bold", children: "available" }))] })] })] }, image.id));
|
|
210
|
-
}) })) : (_jsx("div", { className: "bg-neutral-100 dark:bg-neutral-800 rounded-2xl overflow-hidden border border-neutral-200 dark:border-neutral-700", children: _jsxs("table", { className: "w-full", children: [_jsx("thead", { className: "bg-neutral-200 dark:bg-neutral-700/50", children: _jsxs("tr", { children: [_jsx("th", { className: "text-left px-4 py-3 text-xs font-bold text-neutral-600 dark:text-neutral-400 uppercase", children: "Preview" }), _jsx("th", { className: "text-left px-4 py-3 text-xs font-bold text-neutral-600 dark:text-neutral-400 uppercase", children: "Filename" }), _jsx("th", { className: "text-left px-4 py-3 text-xs font-bold text-neutral-600 dark:text-neutral-400 uppercase", children: "Size" }), _jsx("th", { className: "text-left px-4 py-3 text-xs font-bold text-neutral-600 dark:text-neutral-400 uppercase", children: "Uploaded" }), _jsx("th", { className: "text-left px-4 py-3 text-xs font-bold text-neutral-600 dark:text-neutral-400 uppercase", children: "Status" }), _jsx("th", { className: "text-right px-4 py-3 text-xs font-bold text-neutral-600 dark:text-neutral-400 uppercase", children: "Actions" })] }) }), _jsx("tbody", { className: "divide-y divide-neutral-200 dark:divide-neutral-700", children: filteredImages.map((image) => {
|
|
211
|
-
const usage = getImageUsage(image.filename);
|
|
212
|
-
const inUse = isImageInUse(image.filename);
|
|
213
|
-
return (_jsxs("tr", { className: `transition-colors ${inUse
|
|
214
|
-
? 'bg-amber-50/30 dark:bg-amber-900/5 hover:bg-amber-50/50 dark:hover:bg-amber-900/10'
|
|
215
|
-
: 'hover:bg-neutral-200/50 dark:hover:bg-neutral-700/30'}`, children: [_jsx("td", { className: "px-4 py-3", children: _jsx("div", { className: `w-12 h-12 relative bg-neutral-200 dark:bg-neutral-700 rounded-lg overflow-hidden ring-2 ${inUse ? 'ring-red-400 dark:ring-red-600' : 'ring-transparent'}`, children: _jsx(Image, { src: image.url, alt: image.filename, fill: true, className: "object-cover", unoptimized: true }) }) }), _jsx("td", { className: "px-4 py-3", children: _jsx("p", { className: "text-sm font-medium text-neutral-700 dark:text-neutral-300 truncate max-w-[200px]", title: image.filename, children: image.filename }) }), _jsx("td", { className: "px-4 py-3 text-sm text-neutral-600 dark:text-neutral-400", children: formatFileSize(image.size) }), _jsx("td", { className: "px-4 py-3 text-sm text-neutral-600 dark:text-neutral-400", children: formatDate(image.uploadedAt) }), _jsx("td", { className: "px-4 py-3", children: inUse ? (_jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-1 bg-red-500/10 text-red-600 dark:text-red-400 text-xs font-bold rounded-full", children: [_jsx(CheckCircle, { size: 12 }), "In Use", usage.length > 0 ? ` (${usage.length})` : ''] })) : (_jsxs("span", { className: "inline-flex items-center gap-1 px-2 py-1 bg-green-500/10 text-green-600 dark:text-green-400 text-xs font-medium rounded-full", children: [_jsx(Circle, { size: 12 }), "Available"] })) }), _jsx("td", { className: "px-4 py-3 text-right", children: _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx("button", { onClick: () => window.open(image.url, '_blank'), className: "p-2 text-neutral-500 hover:text-primary hover:bg-neutral-200 dark:hover:bg-neutral-700 rounded-lg transition-colors", title: "View", children: _jsx(Eye, { size: 16 }) }), _jsx("button", { onClick: () => {
|
|
216
|
-
setSelectedImage(image);
|
|
217
|
-
setShowDeleteModal(true);
|
|
218
|
-
}, className: `p-2 rounded-lg transition-colors ${inUse
|
|
219
|
-
? 'text-neutral-400 cursor-not-allowed'
|
|
220
|
-
: 'text-neutral-500 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20'}`, title: inUse ? 'Cannot delete - image is in use' : 'Delete', disabled: inUse, children: _jsx(Trash2, { size: 16 }) })] }) })] }, image.id));
|
|
221
|
-
}) })] }) })), showDeleteModal && selectedImage && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm", children: _jsxs("div", { className: "bg-white dark:bg-neutral-900 rounded-2xl p-6 max-w-md w-full mx-4 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx("h3", { className: "text-xl font-bold text-neutral-900 dark:text-white", children: "Delete Image" }), _jsx("button", { onClick: () => {
|
|
222
|
-
setShowDeleteModal(false);
|
|
223
|
-
setSelectedImage(null);
|
|
224
|
-
}, className: "p-2 text-neutral-500 hover:text-neutral-700 dark:hover:text-neutral-300 rounded-lg", children: _jsx(X, { size: 20 }) })] }), (() => {
|
|
225
|
-
const usage = getImageUsage(selectedImage.filename);
|
|
226
|
-
const inUse = isImageInUse(selectedImage.filename);
|
|
227
|
-
const isMapped = isImageMapped(selectedImage.filename);
|
|
228
|
-
return (_jsxs(_Fragment, { children: [inUse ? (_jsxs("div", { className: "mb-6", children: [_jsxs("div", { className: "flex items-center gap-2 p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-xl mb-4", children: [_jsx(AlertTriangle, { className: "text-red-500 shrink-0", size: 24 }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-red-800 dark:text-red-200", children: isMapped && usage.length === 0
|
|
229
|
-
? 'This image is mapped to content'
|
|
230
|
-
: 'This image is currently in use' }), _jsx("p", { className: "text-xs text-red-600 dark:text-red-400 mt-1", children: isMapped && usage.length === 0
|
|
231
|
-
? 'The image is linked via semantic ID mapping.'
|
|
232
|
-
: 'Please remove the image from all content before deleting.' })] })] }), (usage.length > 0) && (_jsxs("div", { className: "space-y-2 max-h-[200px] overflow-y-auto", children: [_jsx("p", { className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: "Used in:" }), usage.map((item, idx) => (_jsxs("div", { className: "flex items-center justify-between p-3 bg-neutral-100 dark:bg-neutral-800 rounded-lg", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-neutral-700 dark:text-neutral-300", children: item.title }), _jsxs("p", { className: "text-xs text-neutral-500", children: [item.plugin, " - ", item.type] })] }), item.url && (_jsx("a", { href: item.url, target: "_blank", rel: "noopener noreferrer", className: "p-2 text-primary hover:bg-primary/10 rounded-lg transition-colors", children: _jsx(ExternalLink, { size: 16 }) }))] }, idx)))] })), isMapped && usage.length === 0 && (_jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 mt-2", children: "This image is being used through semantic ID mappings. Delete the mapping first." }))] })) : (_jsxs("div", { className: "mb-6", children: [_jsxs("div", { className: "flex items-center gap-4 mb-4", children: [_jsx("div", { className: "w-20 h-20 relative bg-neutral-200 dark:bg-neutral-700 rounded-lg overflow-hidden shrink-0", children: _jsx(Image, { src: selectedImage.url, alt: selectedImage.filename, fill: true, className: "object-cover", unoptimized: true }) }), _jsxs("div", { children: [_jsx("p", { className: "font-medium text-neutral-900 dark:text-white", children: selectedImage.filename }), _jsx("p", { className: "text-sm text-neutral-500", children: formatFileSize(selectedImage.size) }), _jsx("p", { className: "text-sm text-neutral-500", children: formatDate(selectedImage.uploadedAt) })] })] }), _jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400", children: "Are you sure you want to delete this image? This action cannot be undone." })] })), _jsxs("div", { className: "flex justify-end gap-3", children: [_jsx("button", { onClick: () => {
|
|
233
|
-
setShowDeleteModal(false);
|
|
234
|
-
setSelectedImage(null);
|
|
235
|
-
}, className: "px-4 py-2 text-neutral-600 dark:text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-lg transition-colors", children: "Cancel" }), !inUse && (_jsxs("button", { onClick: handleDelete, disabled: deleting, className: "px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors disabled:opacity-50 flex items-center gap-2", children: [deleting && _jsx(Loader2, { size: 16, className: "animate-spin" }), "Delete"] }))] })] }));
|
|
236
|
-
})()] }) })), showCleanupModal && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm", children: _jsxs("div", { className: "bg-white dark:bg-neutral-900 rounded-2xl p-6 max-w-md w-full mx-4 shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between mb-4", children: [_jsx("h3", { className: "text-xl font-bold text-neutral-900 dark:text-white", children: "Clean Up Unused Images" }), _jsx("button", { onClick: () => setShowCleanupModal(false), className: "p-2 text-neutral-500 hover:text-neutral-700 dark:hover:text-neutral-300 rounded-lg", children: _jsx(X, { size: 20 }) })] }), _jsxs("div", { className: "mb-6", children: [_jsxs("div", { className: "flex items-center gap-2 p-4 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-xl mb-4", children: [_jsx(AlertTriangle, { className: "text-amber-500 shrink-0", size: 24 }), _jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-amber-800 dark:text-amber-200", children: "Warning: This action cannot be undone" }), _jsxs("p", { className: "text-xs text-amber-600 dark:text-amber-400 mt-1", children: [getUnusedImagesCount(), " unused image", getUnusedImagesCount() !== 1 ? 's' : '', " will be permanently deleted."] })] })] }), _jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 mb-4", children: "This will delete all images that are not currently in use by any content (blogs, newsletters, or user avatars)." }), _jsxs("div", { className: "p-3 bg-neutral-100 dark:bg-neutral-800 rounded-lg", children: [_jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("span", { className: "text-neutral-600 dark:text-neutral-400", children: "Total images:" }), _jsx("span", { className: "font-bold text-neutral-900 dark:text-white", children: stats?.totalImages || 0 })] }), _jsxs("div", { className: "flex items-center justify-between text-sm mt-2", children: [_jsx("span", { className: "text-neutral-600 dark:text-neutral-400", children: "In use:" }), _jsx("span", { className: "font-bold text-red-500", children: stats?.usedImages || 0 })] }), _jsxs("div", { className: "flex items-center justify-between text-sm mt-2", children: [_jsx("span", { className: "text-neutral-600 dark:text-neutral-400", children: "Will be deleted:" }), _jsx("span", { className: "font-bold text-red-500", children: getUnusedImagesCount() })] })] })] }), _jsxs("div", { className: "flex justify-end gap-3", children: [_jsx("button", { onClick: () => setShowCleanupModal(false), className: "px-4 py-2 text-neutral-600 dark:text-neutral-400 hover:bg-neutral-100 dark:hover:bg-neutral-800 rounded-lg transition-colors", children: "Cancel" }), _jsxs("button", { onClick: handleCleanup, disabled: cleaning, className: "px-4 py-2 bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors disabled:opacity-50 flex items-center gap-2", children: [cleaning && _jsx(Loader2, { size: 16, className: "animate-spin" }), cleaning ? 'Deleting...' : `Delete ${getUnusedImagesCount()} Images`] })] })] }) }))] }));
|
|
203
|
+
return (_jsxs("div", { className: "w-full flex flex-col space-y-8 px-6 lg:px-10 py-6 lg:py-10 pb-10 bg-transparent", children: [_jsx(ImageManagerHeader, { uploading: uploading, unusedCount: getUnusedImagesCount(), onUpload: handleUpload, onRefresh: handleRefresh, onShowCleanup: () => setShowCleanupModal(true) }), stats && _jsx(ImageManagerStats, { stats: stats, formatFileSize: formatFileSize }), _jsx(ImageManagerToolbar, { search: search, setSearch: setSearch, viewMode: viewMode, setViewMode: setViewMode }), _jsx("div", { className: "flex-1 px-4 min-h-[400px]", children: loading ? (_jsx("div", { className: "h-full flex items-center justify-center py-20", children: _jsxs("div", { className: "flex flex-col items-center gap-4", children: [_jsx(Loader2, { size: 40, className: "animate-spin text-primary opacity-40" }), _jsx("p", { className: "text-[10px] font-bold text-primary uppercase tracking-widest animate-pulse", children: "Syncing Library" })] }) })) : filteredImages.length === 0 ? (_jsxs("div", { className: "h-full flex flex-col items-center justify-center py-32 text-center", children: [_jsxs("div", { className: "size-24 bg-dashboard-card/40 rounded-3xl border border-dashed border-dashboard-border/50 flex items-center justify-center mb-6 relative", children: [_jsx(ImageIcon, { size: 40, className: "text-dashboard-text-secondary opacity-20" }), _jsx("div", { className: "absolute inset-0 bg-primary/5 rounded-3xl animate-pulse" })] }), _jsx("h3", { className: "text-xl font-bold text-dashboard-text tracking-tight opacity-40 mb-1.5", children: search ? 'Reference Not Found' : 'Repository Empty' }), _jsx("p", { className: "text-xs text-dashboard-text-secondary font-medium opacity-60", children: search ? 'Try refining your search parameters' : 'Upload your first image to begin building your library' })] })) : viewMode === 'grid' ? (_jsx(ImageGrid, { images: filteredImages, isImageInUse: isImageInUse, getImageUsage: getImageUsage, formatFileSize: formatFileSize, onViewFull: (url) => window.open(url, '_blank'), onDelete: (img) => {
|
|
204
|
+
setSelectedImage(img);
|
|
205
|
+
setShowDeleteModal(true);
|
|
206
|
+
} })) : (_jsx(ImageTable, { images: filteredImages, isImageInUse: isImageInUse, getImageUsage: getImageUsage, formatFileSize: formatFileSize, formatDate: formatDate, onViewFull: (url) => window.open(url, '_blank'), onDelete: (img) => {
|
|
207
|
+
setSelectedImage(img);
|
|
208
|
+
setShowDeleteModal(true);
|
|
209
|
+
} })) }), _jsx(DeleteImageModal, { isOpen: showDeleteModal, image: selectedImage, inUse: selectedImage ? isImageInUse(selectedImage.filename) : false, usage: selectedImage ? getImageUsage(selectedImage.filename) : [], isDeleting: deleting, formatFileSize: formatFileSize, formatDate: formatDate, onClose: () => {
|
|
210
|
+
setShowDeleteModal(false);
|
|
211
|
+
setSelectedImage(null);
|
|
212
|
+
}, onConfirm: handleDelete }), _jsx(CleanupLibraryModal, { isOpen: showCleanupModal, stats: stats, unusedCount: getUnusedImagesCount(), isCleaning: cleaning, onClose: () => setShowCleanupModal(false), onConfirm: handleCleanup })] }));
|
|
237
213
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jhits/plugin-images",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
4
4
|
"description": "Image management and storage plugin for the JHITS ecosystem",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"main": "./
|
|
9
|
-
"types": "./
|
|
8
|
+
"main": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": {
|
|
12
|
-
"types": "./
|
|
13
|
-
"import": "./
|
|
14
|
-
"default": "./
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
15
|
},
|
|
16
16
|
"./src": {
|
|
17
17
|
"types": "./src/index.tsx",
|
|
@@ -19,12 +19,13 @@
|
|
|
19
19
|
"default": "./src/index.tsx"
|
|
20
20
|
},
|
|
21
21
|
"./server": {
|
|
22
|
-
"types": "./
|
|
23
|
-
"import": "./
|
|
24
|
-
"default": "./
|
|
22
|
+
"types": "./dist/index.server.d.ts",
|
|
23
|
+
"import": "./dist/index.server.js",
|
|
24
|
+
"default": "./dist/index.server.js"
|
|
25
25
|
}
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
+
"framer-motion": "^12.36.0",
|
|
28
29
|
"lucide-react": "^0.564.0",
|
|
29
30
|
"mongodb": "^7.1.0",
|
|
30
31
|
"@jhits/plugin-core": "0.0.10"
|