@caprionlinesrl/puck-plugin-media 0.1.4

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/index.js ADDED
@@ -0,0 +1,3029 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ DEFAULT_LANGUAGES: () => DEFAULT_LANGUAGES,
25
+ DocumentField: () => DocumentField,
26
+ DocumentPickerModal: () => DocumentPickerModal,
27
+ GalleryField: () => GalleryField,
28
+ GalleryPickerModal: () => GalleryPickerModal,
29
+ ImageField: () => ImageField,
30
+ ImageGrid: () => ImageGrid,
31
+ ImagePickerModal: () => ImagePickerModal,
32
+ MediaPanel: () => MediaPanel,
33
+ UploadDropzone: () => UploadDropzone,
34
+ UploadQueue: () => UploadQueue,
35
+ createMediaPlugin: () => createMediaPlugin,
36
+ formatFileSize: () => formatFileSize,
37
+ useUpload: () => useUpload
38
+ });
39
+ module.exports = __toCommonJS(index_exports);
40
+
41
+ // src/createMediaPlugin.tsx
42
+ var import_lucide_react16 = require("lucide-react");
43
+
44
+ // src/components/ImageField/ImageField.tsx
45
+ var import_react7 = require("react");
46
+ var import_react_dom = require("react-dom");
47
+ var import_core = require("@puckeditor/core");
48
+ var import_lucide_react10 = require("lucide-react");
49
+
50
+ // src/components/ImagePickerModal/ImagePickerModal.tsx
51
+ var import_react6 = require("react");
52
+ var import_lucide_react9 = require("lucide-react");
53
+
54
+ // src/components/Modal/Modal.tsx
55
+ var import_react = require("react");
56
+ var import_lucide_react = require("lucide-react");
57
+
58
+ // src/components/Modal/Modal.module.css
59
+ var Modal_default = {
60
+ backdrop: "Modal_backdrop",
61
+ fadeIn: "Modal_fadeIn",
62
+ modal: "Modal_modal",
63
+ slideUp: "Modal_slideUp",
64
+ small: "Modal_small",
65
+ header: "Modal_header",
66
+ title: "Modal_title",
67
+ headerActions: "Modal_headerActions",
68
+ closeButton: "Modal_closeButton",
69
+ toolbar: "Modal_toolbar",
70
+ content: "Modal_content",
71
+ loading: "Modal_loading",
72
+ spinner: "Modal_spinner",
73
+ spin: "Modal_spin",
74
+ empty: "Modal_empty",
75
+ footer: "Modal_footer"
76
+ };
77
+
78
+ // src/components/Modal/Modal.tsx
79
+ var import_jsx_runtime = require("react/jsx-runtime");
80
+ function Modal({
81
+ title,
82
+ onClose,
83
+ size = "default",
84
+ headerLeft,
85
+ headerActions,
86
+ toolbar,
87
+ children,
88
+ footer,
89
+ overlay,
90
+ loading = false,
91
+ empty = false,
92
+ emptyMessage = "No items found"
93
+ }) {
94
+ (0, import_react.useEffect)(() => {
95
+ const handleEscape = (e) => {
96
+ if (e.key === "Escape") {
97
+ onClose();
98
+ }
99
+ };
100
+ window.addEventListener("keydown", handleEscape);
101
+ return () => window.removeEventListener("keydown", handleEscape);
102
+ }, [onClose]);
103
+ (0, import_react.useEffect)(() => {
104
+ const originalOverflow = document.body.style.overflow;
105
+ document.body.style.overflow = "hidden";
106
+ return () => {
107
+ document.body.style.overflow = originalOverflow;
108
+ };
109
+ }, []);
110
+ const handleBackdropClick = (e) => {
111
+ if (e.target === e.currentTarget) {
112
+ onClose();
113
+ }
114
+ };
115
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: Modal_default.backdrop, onClick: handleBackdropClick, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
116
+ "div",
117
+ {
118
+ className: `${Modal_default.modal} ${size === "small" ? Modal_default.small : ""}`,
119
+ role: "dialog",
120
+ "aria-modal": "true",
121
+ "aria-labelledby": "modal-title",
122
+ onClick: (e) => e.stopPropagation(),
123
+ children: [
124
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Modal_default.header, children: [
125
+ headerLeft,
126
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { id: "modal-title", className: Modal_default.title, children: title }),
127
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Modal_default.headerActions, children: [
128
+ headerActions,
129
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
130
+ "button",
131
+ {
132
+ type: "button",
133
+ onClick: (e) => {
134
+ e.stopPropagation();
135
+ onClose();
136
+ },
137
+ className: Modal_default.closeButton,
138
+ "aria-label": "Close",
139
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.X, { size: 20 })
140
+ }
141
+ )
142
+ ] })
143
+ ] }),
144
+ toolbar && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: Modal_default.toolbar, children: toolbar }),
145
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: Modal_default.content, children: loading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Modal_default.loading, children: [
146
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.Loader2, { size: 32, className: Modal_default.spinner }),
147
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: "Loading..." })
148
+ ] }) : empty ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: Modal_default.empty, children: emptyMessage }) : children }),
149
+ footer && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: Modal_default.footer, children: footer }),
150
+ overlay
151
+ ]
152
+ }
153
+ ) });
154
+ }
155
+
156
+ // src/components/SearchBar/SearchBar.tsx
157
+ var import_react2 = require("react");
158
+ var import_lucide_react2 = require("lucide-react");
159
+
160
+ // src/components/SearchBar/SearchBar.module.css
161
+ var SearchBar_default = {
162
+ container: "SearchBar_container",
163
+ icon: "SearchBar_icon",
164
+ input: "SearchBar_input",
165
+ clearButton: "SearchBar_clearButton"
166
+ };
167
+
168
+ // src/components/SearchBar/SearchBar.tsx
169
+ var import_jsx_runtime2 = require("react/jsx-runtime");
170
+ function SearchBar({
171
+ value,
172
+ onChange,
173
+ placeholder = "Search...",
174
+ autoFocus = false
175
+ }) {
176
+ const inputRef = (0, import_react2.useRef)(null);
177
+ (0, import_react2.useEffect)(() => {
178
+ if (autoFocus && inputRef.current) {
179
+ inputRef.current.focus();
180
+ }
181
+ }, [autoFocus]);
182
+ const handleClear = () => {
183
+ onChange("");
184
+ inputRef.current?.focus();
185
+ };
186
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: SearchBar_default.container, children: [
187
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Search, { size: 18, className: SearchBar_default.icon }),
188
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
189
+ "input",
190
+ {
191
+ ref: inputRef,
192
+ type: "search",
193
+ value,
194
+ onChange: (e) => onChange(e.target.value),
195
+ placeholder,
196
+ className: SearchBar_default.input
197
+ }
198
+ ),
199
+ value && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
200
+ "button",
201
+ {
202
+ type: "button",
203
+ onClick: handleClear,
204
+ className: SearchBar_default.clearButton,
205
+ "aria-label": "Clear search",
206
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.X, { size: 16 })
207
+ }
208
+ )
209
+ ] });
210
+ }
211
+
212
+ // src/components/LoadMoreButton/LoadMoreButton.tsx
213
+ var import_lucide_react3 = require("lucide-react");
214
+
215
+ // src/components/LoadMoreButton/LoadMoreButton.module.css
216
+ var LoadMoreButton_default = {
217
+ container: "LoadMoreButton_container",
218
+ button: "LoadMoreButton_button",
219
+ spinner: "LoadMoreButton_spinner",
220
+ spin: "LoadMoreButton_spin"
221
+ };
222
+
223
+ // src/components/LoadMoreButton/LoadMoreButton.tsx
224
+ var import_jsx_runtime3 = require("react/jsx-runtime");
225
+ function LoadMoreButton({ onClick, loading = false }) {
226
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: LoadMoreButton_default.container, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
227
+ "button",
228
+ {
229
+ type: "button",
230
+ onClick,
231
+ disabled: loading,
232
+ className: LoadMoreButton_default.button,
233
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
234
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.Loader2, { size: 16, className: LoadMoreButton_default.spinner }),
235
+ "Loading..."
236
+ ] }) : "Load more"
237
+ }
238
+ ) });
239
+ }
240
+
241
+ // src/components/ConfirmDialog/ConfirmDialog.tsx
242
+ var import_react3 = require("react");
243
+ var import_lucide_react4 = require("lucide-react");
244
+
245
+ // src/components/ConfirmDialog/ConfirmDialog.module.css
246
+ var ConfirmDialog_default = {
247
+ overlay: "ConfirmDialog_overlay",
248
+ fadeIn: "ConfirmDialog_fadeIn",
249
+ dialog: "ConfirmDialog_dialog",
250
+ slideUp: "ConfirmDialog_slideUp",
251
+ title: "ConfirmDialog_title",
252
+ message: "ConfirmDialog_message",
253
+ actions: "ConfirmDialog_actions",
254
+ cancelButton: "ConfirmDialog_cancelButton",
255
+ confirmButton: "ConfirmDialog_confirmButton",
256
+ danger: "ConfirmDialog_danger",
257
+ spinner: "ConfirmDialog_spinner",
258
+ spin: "ConfirmDialog_spin"
259
+ };
260
+
261
+ // src/components/ConfirmDialog/ConfirmDialog.tsx
262
+ var import_jsx_runtime4 = require("react/jsx-runtime");
263
+ function ConfirmDialog({
264
+ title,
265
+ message,
266
+ confirmLabel,
267
+ onConfirm,
268
+ onCancel,
269
+ loading = false,
270
+ variant = "danger"
271
+ }) {
272
+ (0, import_react3.useEffect)(() => {
273
+ const handleEscape = (e) => {
274
+ if (e.key === "Escape" && !loading) {
275
+ e.stopPropagation();
276
+ onCancel();
277
+ }
278
+ };
279
+ window.addEventListener("keydown", handleEscape);
280
+ return () => window.removeEventListener("keydown", handleEscape);
281
+ }, [onCancel, loading]);
282
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: ConfirmDialog_default.overlay, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: ConfirmDialog_default.dialog, children: [
283
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: ConfirmDialog_default.title, children: title }),
284
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: ConfirmDialog_default.message, children: message }),
285
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: ConfirmDialog_default.actions, children: [
286
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
287
+ "button",
288
+ {
289
+ type: "button",
290
+ onClick: onCancel,
291
+ className: ConfirmDialog_default.cancelButton,
292
+ disabled: loading,
293
+ children: "Cancel"
294
+ }
295
+ ),
296
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
297
+ "button",
298
+ {
299
+ type: "button",
300
+ onClick: onConfirm,
301
+ className: `${ConfirmDialog_default.confirmButton} ${variant === "danger" ? ConfirmDialog_default.danger : ""}`,
302
+ disabled: loading,
303
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
304
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.Loader2, { size: 16, className: ConfirmDialog_default.spinner }),
305
+ confirmLabel
306
+ ] }) : confirmLabel
307
+ }
308
+ )
309
+ ] })
310
+ ] }) });
311
+ }
312
+
313
+ // src/components/SelectionToolbar/SelectionToolbar.tsx
314
+ var import_lucide_react5 = require("lucide-react");
315
+
316
+ // src/components/SelectionToolbar/SelectionToolbar.module.css
317
+ var SelectionToolbar_default = {
318
+ toolbar: "SelectionToolbar_toolbar",
319
+ selectAllButton: "SelectionToolbar_selectAllButton",
320
+ checkbox: "SelectionToolbar_checkbox",
321
+ checked: "SelectionToolbar_checked",
322
+ indeterminate: "SelectionToolbar_indeterminate",
323
+ indeterminateLine: "SelectionToolbar_indeterminateLine",
324
+ actions: "SelectionToolbar_actions",
325
+ cancelButton: "SelectionToolbar_cancelButton",
326
+ deleteButton: "SelectionToolbar_deleteButton"
327
+ };
328
+
329
+ // src/components/SelectionToolbar/SelectionToolbar.tsx
330
+ var import_jsx_runtime5 = require("react/jsx-runtime");
331
+ function SelectionToolbar({
332
+ selectedCount,
333
+ totalCount: _totalCount,
334
+ onSelectAll,
335
+ onCancel,
336
+ onDelete,
337
+ isAllSelected,
338
+ isIndeterminate,
339
+ deleteLabel = "Delete"
340
+ }) {
341
+ void _totalCount;
342
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: SelectionToolbar_default.toolbar, children: [
343
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
344
+ "button",
345
+ {
346
+ type: "button",
347
+ onClick: onSelectAll,
348
+ className: `${SelectionToolbar_default.selectAllButton} ${isAllSelected ? SelectionToolbar_default.checked : ""} ${isIndeterminate ? SelectionToolbar_default.indeterminate : ""}`,
349
+ "aria-label": isAllSelected ? "Deselect all" : "Select all",
350
+ children: [
351
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: SelectionToolbar_default.checkbox, children: [
352
+ isAllSelected && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Check, { size: 14, strokeWidth: 3 }),
353
+ isIndeterminate && !isAllSelected && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: SelectionToolbar_default.indeterminateLine })
354
+ ] }),
355
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Select All" })
356
+ ]
357
+ }
358
+ ),
359
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: SelectionToolbar_default.actions, children: [
360
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
361
+ "button",
362
+ {
363
+ type: "button",
364
+ onClick: onCancel,
365
+ className: SelectionToolbar_default.cancelButton,
366
+ children: "Cancel"
367
+ }
368
+ ),
369
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
370
+ "button",
371
+ {
372
+ type: "button",
373
+ onClick: onDelete,
374
+ className: SelectionToolbar_default.deleteButton,
375
+ disabled: selectedCount === 0,
376
+ children: [
377
+ deleteLabel,
378
+ " (",
379
+ selectedCount,
380
+ ")"
381
+ ]
382
+ }
383
+ )
384
+ ] })
385
+ ] });
386
+ }
387
+
388
+ // src/components/ImageGrid/ImageGrid.tsx
389
+ var import_lucide_react6 = require("lucide-react");
390
+
391
+ // src/components/ImageGrid/ImageGrid.module.css
392
+ var ImageGrid_default = {
393
+ grid: "ImageGrid_grid",
394
+ itemContainer: "ImageGrid_itemContainer",
395
+ item: "ImageGrid_item",
396
+ selected: "ImageGrid_selected",
397
+ imageWrapper: "ImageGrid_imageWrapper",
398
+ image: "ImageGrid_image",
399
+ checkmark: "ImageGrid_checkmark",
400
+ checkbox: "ImageGrid_checkbox",
401
+ checkboxChecked: "ImageGrid_checkboxChecked",
402
+ info: "ImageGrid_info",
403
+ infoRow: "ImageGrid_infoRow",
404
+ infoText: "ImageGrid_infoText",
405
+ filename: "ImageGrid_filename",
406
+ meta: "ImageGrid_meta",
407
+ editButton: "ImageGrid_editButton"
408
+ };
409
+
410
+ // src/components/ImageGrid/ImageGrid.tsx
411
+ var import_jsx_runtime6 = require("react/jsx-runtime");
412
+ function ImageGrid({
413
+ items,
414
+ onSelect,
415
+ selectedId,
416
+ onEditAlt,
417
+ manageMode = false,
418
+ selectedIds,
419
+ onToggleSelect
420
+ }) {
421
+ const formatFileSize2 = (bytes) => {
422
+ if (!bytes) return "";
423
+ if (bytes < 1024) return `${bytes} B`;
424
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
425
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
426
+ };
427
+ const handleItemClick = (item) => {
428
+ if (manageMode && onToggleSelect) {
429
+ onToggleSelect(item);
430
+ } else {
431
+ onSelect(item);
432
+ }
433
+ };
434
+ const handleEditClick = (e, item) => {
435
+ e.stopPropagation();
436
+ onEditAlt?.(item);
437
+ };
438
+ const isSelected = (item) => {
439
+ if (manageMode) {
440
+ return selectedIds?.has(item.id) ?? false;
441
+ }
442
+ return selectedId === item.id;
443
+ };
444
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: ImageGrid_default.grid, children: items.map((item) => {
445
+ const selected = isSelected(item);
446
+ const isSelectedForInsert = !manageMode && selectedId === item.id;
447
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: ImageGrid_default.itemContainer, children: [
448
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
449
+ "button",
450
+ {
451
+ type: "button",
452
+ onClick: () => handleItemClick(item),
453
+ className: `${ImageGrid_default.item} ${isSelectedForInsert ? ImageGrid_default.selected : ""}`,
454
+ title: item.filename,
455
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: ImageGrid_default.imageWrapper, children: [
456
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
457
+ "img",
458
+ {
459
+ src: item.thumbnailUrl || item.url,
460
+ alt: item.filename || "",
461
+ className: ImageGrid_default.image,
462
+ loading: "lazy"
463
+ }
464
+ ),
465
+ manageMode && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: `${ImageGrid_default.checkbox} ${selected ? ImageGrid_default.checkboxChecked : ""}`, children: selected && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Check, { size: 14, strokeWidth: 3 }) }),
466
+ isSelectedForInsert && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: ImageGrid_default.checkmark, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
467
+ "svg",
468
+ {
469
+ width: "16",
470
+ height: "16",
471
+ viewBox: "0 0 16 16",
472
+ fill: "none",
473
+ xmlns: "http://www.w3.org/2000/svg",
474
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
475
+ "path",
476
+ {
477
+ d: "M13.5 4.5L6 12L2.5 8.5",
478
+ stroke: "currentColor",
479
+ strokeWidth: "2",
480
+ strokeLinecap: "round",
481
+ strokeLinejoin: "round"
482
+ }
483
+ )
484
+ }
485
+ ) })
486
+ ] })
487
+ }
488
+ ),
489
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: ImageGrid_default.info, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: ImageGrid_default.infoRow, children: [
490
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: ImageGrid_default.infoText, children: [
491
+ item.filename && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: ImageGrid_default.filename, children: item.filename }),
492
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: ImageGrid_default.meta, children: [
493
+ item.width && item.height && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
494
+ item.width,
495
+ "\xD7",
496
+ item.height
497
+ ] }),
498
+ item.size && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: formatFileSize2(item.size) })
499
+ ] })
500
+ ] }),
501
+ !manageMode && onEditAlt && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
502
+ "button",
503
+ {
504
+ type: "button",
505
+ onClick: (e) => handleEditClick(e, item),
506
+ className: ImageGrid_default.editButton,
507
+ "aria-label": "Edit alt",
508
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.Pencil, { size: 14 })
509
+ }
510
+ )
511
+ ] }) })
512
+ ] }, item.id);
513
+ }) });
514
+ }
515
+
516
+ // src/components/UploadDropzone/UploadDropzone.tsx
517
+ var import_react5 = require("react");
518
+ var import_lucide_react7 = require("lucide-react");
519
+
520
+ // src/hooks/useUpload.ts
521
+ var import_react4 = require("react");
522
+ var DEFAULT_CONFIG = {
523
+ accept: "image/*",
524
+ maxSize: 10 * 1024 * 1024,
525
+ // 10MB
526
+ multiple: true
527
+ };
528
+ var MAX_CONCURRENT_UPLOADS = 3;
529
+ var generateId = () => `upload-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
530
+ var formatFileSize = (bytes) => {
531
+ if (bytes < 1024) return `${bytes} B`;
532
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
533
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
534
+ };
535
+ var validateFile = (file, config) => {
536
+ if (file.size > config.maxSize) {
537
+ return {
538
+ valid: false,
539
+ error: `File too large. Maximum size is ${formatFileSize(config.maxSize)}`
540
+ };
541
+ }
542
+ const acceptedTypes = config.accept.split(",").map((t) => t.trim());
543
+ const isAccepted = acceptedTypes.some((type) => {
544
+ if (type === "*/*" || type === "*") return true;
545
+ if (type.endsWith("/*")) {
546
+ const category = type.slice(0, -2);
547
+ return file.type.startsWith(category);
548
+ }
549
+ if (type.startsWith(".")) {
550
+ return file.name.toLowerCase().endsWith(type.toLowerCase());
551
+ }
552
+ return file.type === type;
553
+ });
554
+ if (!isAccepted) {
555
+ return {
556
+ valid: false,
557
+ error: `File type not accepted. Accepted types: ${config.accept}`
558
+ };
559
+ }
560
+ return { valid: true };
561
+ };
562
+ var createPreviewUrl = (file) => {
563
+ if (file.type.startsWith("image/")) {
564
+ return URL.createObjectURL(file);
565
+ }
566
+ return void 0;
567
+ };
568
+ function useUpload({
569
+ upload,
570
+ config,
571
+ onUploadComplete
572
+ }) {
573
+ const [uploading, setUploading] = (0, import_react4.useState)([]);
574
+ const activeUploadsRef = (0, import_react4.useRef)(/* @__PURE__ */ new Set());
575
+ const uploadConfig = { ...DEFAULT_CONFIG, ...config };
576
+ const startUpload = (0, import_react4.useCallback)(
577
+ async (id, file) => {
578
+ try {
579
+ const result = await upload(file, {
580
+ onProgress: (percent) => {
581
+ setUploading(
582
+ (current) => current.map((f) => f.id === id ? { ...f, progress: percent } : f)
583
+ );
584
+ }
585
+ });
586
+ const singleResult = Array.isArray(result) ? result[0] : result;
587
+ setUploading(
588
+ (current) => current.map(
589
+ (f) => f.id === id ? { ...f, status: "completed", progress: 100, result: singleResult } : f
590
+ )
591
+ );
592
+ onUploadComplete?.(singleResult);
593
+ } catch (error) {
594
+ const errorMessage = error instanceof Error ? error.message : "Upload failed";
595
+ setUploading(
596
+ (current) => current.map(
597
+ (f) => f.id === id ? { ...f, status: "error", error: errorMessage } : f
598
+ )
599
+ );
600
+ } finally {
601
+ activeUploadsRef.current.delete(id);
602
+ processQueue();
603
+ }
604
+ },
605
+ [upload, onUploadComplete]
606
+ );
607
+ const processQueue = (0, import_react4.useCallback)(() => {
608
+ setUploading((current) => {
609
+ const pending = current.filter(
610
+ (f) => f.status === "pending" && !activeUploadsRef.current.has(f.id)
611
+ );
612
+ const activeCount = activeUploadsRef.current.size;
613
+ const slotsAvailable = MAX_CONCURRENT_UPLOADS - activeCount;
614
+ if (slotsAvailable <= 0 || pending.length === 0) {
615
+ return current;
616
+ }
617
+ const toStart = pending.slice(0, slotsAvailable);
618
+ toStart.forEach((file) => {
619
+ activeUploadsRef.current.add(file.id);
620
+ startUpload(file.id, file.file);
621
+ });
622
+ return current.map(
623
+ (f) => toStart.some((t) => t.id === f.id) ? { ...f, status: "uploading" } : f
624
+ );
625
+ });
626
+ }, [startUpload]);
627
+ const addFiles = (0, import_react4.useCallback)(
628
+ (files) => {
629
+ const fileArray = Array.from(files);
630
+ const filesToAdd = uploadConfig.multiple ? fileArray : fileArray.slice(0, 1);
631
+ const newUploads = filesToAdd.map((file) => {
632
+ const validation = validateFile(file, uploadConfig);
633
+ const previewUrl = createPreviewUrl(file);
634
+ return {
635
+ id: generateId(),
636
+ file,
637
+ progress: 0,
638
+ status: validation.valid ? "pending" : "error",
639
+ error: validation.error,
640
+ previewUrl
641
+ };
642
+ });
643
+ setUploading((current) => [...newUploads, ...current]);
644
+ setTimeout(processQueue, 0);
645
+ },
646
+ [uploadConfig, processQueue]
647
+ );
648
+ const cancelUpload = (0, import_react4.useCallback)((id) => {
649
+ setUploading((current) => {
650
+ const file = current.find((f) => f.id === id);
651
+ if (file?.previewUrl) {
652
+ URL.revokeObjectURL(file.previewUrl);
653
+ }
654
+ return current.filter((f) => f.id !== id);
655
+ });
656
+ activeUploadsRef.current.delete(id);
657
+ }, []);
658
+ const clearCompleted = (0, import_react4.useCallback)(() => {
659
+ setUploading((current) => {
660
+ current.filter((f) => f.status === "completed" || f.status === "error").forEach((f) => {
661
+ if (f.previewUrl) {
662
+ URL.revokeObjectURL(f.previewUrl);
663
+ }
664
+ });
665
+ return current.filter((f) => f.status === "pending" || f.status === "uploading");
666
+ });
667
+ }, []);
668
+ const isUploading = uploading.some(
669
+ (f) => f.status === "pending" || f.status === "uploading"
670
+ );
671
+ return {
672
+ uploading,
673
+ isUploading,
674
+ addFiles,
675
+ cancelUpload,
676
+ clearCompleted,
677
+ uploadConfig
678
+ };
679
+ }
680
+
681
+ // src/components/UploadDropzone/UploadDropzone.module.css
682
+ var UploadDropzone_default = {
683
+ dropzone: "UploadDropzone_dropzone",
684
+ disabled: "UploadDropzone_disabled",
685
+ dragging: "UploadDropzone_dragging",
686
+ input: "UploadDropzone_input",
687
+ icon: "UploadDropzone_icon",
688
+ text: "UploadDropzone_text",
689
+ hint: "UploadDropzone_hint"
690
+ };
691
+
692
+ // src/components/UploadDropzone/UploadDropzone.tsx
693
+ var import_jsx_runtime7 = require("react/jsx-runtime");
694
+ function UploadDropzone({
695
+ onFilesSelected,
696
+ config,
697
+ disabled = false
698
+ }) {
699
+ const [isDragging, setIsDragging] = (0, import_react5.useState)(false);
700
+ const inputRef = (0, import_react5.useRef)(null);
701
+ const dragCounterRef = (0, import_react5.useRef)(0);
702
+ const handleDragEnter = (0, import_react5.useCallback)((e) => {
703
+ e.preventDefault();
704
+ e.stopPropagation();
705
+ dragCounterRef.current++;
706
+ if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
707
+ setIsDragging(true);
708
+ }
709
+ }, []);
710
+ const handleDragLeave = (0, import_react5.useCallback)((e) => {
711
+ e.preventDefault();
712
+ e.stopPropagation();
713
+ dragCounterRef.current--;
714
+ if (dragCounterRef.current === 0) {
715
+ setIsDragging(false);
716
+ }
717
+ }, []);
718
+ const handleDragOver = (0, import_react5.useCallback)((e) => {
719
+ e.preventDefault();
720
+ e.stopPropagation();
721
+ }, []);
722
+ const handleDrop = (0, import_react5.useCallback)(
723
+ (e) => {
724
+ e.preventDefault();
725
+ e.stopPropagation();
726
+ setIsDragging(false);
727
+ dragCounterRef.current = 0;
728
+ if (disabled) return;
729
+ const { files } = e.dataTransfer;
730
+ if (files && files.length > 0) {
731
+ onFilesSelected(files);
732
+ }
733
+ },
734
+ [disabled, onFilesSelected]
735
+ );
736
+ const handleClick = (0, import_react5.useCallback)(() => {
737
+ if (!disabled && inputRef.current) {
738
+ inputRef.current.click();
739
+ }
740
+ }, [disabled]);
741
+ const handleInputChange = (0, import_react5.useCallback)(
742
+ (e) => {
743
+ const { files } = e.target;
744
+ if (files && files.length > 0) {
745
+ onFilesSelected(files);
746
+ e.target.value = "";
747
+ }
748
+ },
749
+ [onFilesSelected]
750
+ );
751
+ const formatAcceptedTypes = (accept) => {
752
+ const types = accept.split(",").map((t) => t.trim());
753
+ const formatted = types.map((type) => {
754
+ if (type === "image/*") return "Images";
755
+ if (type === "image/jpeg") return "JPG";
756
+ if (type === "image/png") return "PNG";
757
+ if (type === "image/gif") return "GIF";
758
+ if (type === "image/webp") return "WebP";
759
+ if (type === "image/svg+xml") return "SVG";
760
+ return type.replace("image/", "").toUpperCase();
761
+ });
762
+ return formatted.join(", ");
763
+ };
764
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
765
+ "div",
766
+ {
767
+ className: `${UploadDropzone_default.dropzone} ${isDragging ? UploadDropzone_default.dragging : ""} ${disabled ? UploadDropzone_default.disabled : ""}`,
768
+ onDragEnter: handleDragEnter,
769
+ onDragLeave: handleDragLeave,
770
+ onDragOver: handleDragOver,
771
+ onDrop: handleDrop,
772
+ onClick: handleClick,
773
+ role: "button",
774
+ tabIndex: disabled ? -1 : 0,
775
+ onKeyDown: (e) => {
776
+ if (e.key === "Enter" || e.key === " ") {
777
+ e.preventDefault();
778
+ handleClick();
779
+ }
780
+ },
781
+ children: [
782
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
783
+ "input",
784
+ {
785
+ ref: inputRef,
786
+ type: "file",
787
+ accept: config.accept,
788
+ multiple: config.multiple,
789
+ onChange: handleInputChange,
790
+ className: UploadDropzone_default.input,
791
+ disabled
792
+ }
793
+ ),
794
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_lucide_react7.Upload, { size: 24, className: UploadDropzone_default.icon }),
795
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: UploadDropzone_default.text, children: isDragging ? "Drop files here" : "Drop files here or click to upload" }),
796
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: UploadDropzone_default.hint, children: [
797
+ formatAcceptedTypes(config.accept),
798
+ " (max ",
799
+ formatFileSize(config.maxSize),
800
+ ")"
801
+ ] })
802
+ ]
803
+ }
804
+ );
805
+ }
806
+
807
+ // src/components/UploadQueue/UploadQueue.tsx
808
+ var import_lucide_react8 = require("lucide-react");
809
+
810
+ // src/components/UploadQueue/UploadQueue.module.css
811
+ var UploadQueue_default = {
812
+ container: "UploadQueue_container",
813
+ header: "UploadQueue_header",
814
+ title: "UploadQueue_title",
815
+ clearButton: "UploadQueue_clearButton",
816
+ list: "UploadQueue_list",
817
+ item: "UploadQueue_item",
818
+ preview: "UploadQueue_preview",
819
+ previewImage: "UploadQueue_previewImage",
820
+ previewPlaceholder: "UploadQueue_previewPlaceholder",
821
+ progressOverlay: "UploadQueue_progressOverlay",
822
+ progressBar: "UploadQueue_progressBar",
823
+ progressText: "UploadQueue_progressText",
824
+ info: "UploadQueue_info",
825
+ filename: "UploadQueue_filename",
826
+ size: "UploadQueue_size",
827
+ error: "UploadQueue_error",
828
+ actions: "UploadQueue_actions",
829
+ cancelButton: "UploadQueue_cancelButton",
830
+ spinner: "UploadQueue_spinner",
831
+ spin: "UploadQueue_spin",
832
+ successIcon: "UploadQueue_successIcon",
833
+ errorIcon: "UploadQueue_errorIcon",
834
+ completed: "UploadQueue_completed"
835
+ };
836
+
837
+ // src/components/UploadQueue/UploadQueue.tsx
838
+ var import_jsx_runtime8 = require("react/jsx-runtime");
839
+ function UploadQueue({ files, onCancel, onClearCompleted }) {
840
+ if (files.length === 0) return null;
841
+ const hasCompleted = files.some((f) => f.status === "completed" || f.status === "error");
842
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: UploadQueue_default.container, children: [
843
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: UploadQueue_default.header, children: [
844
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: UploadQueue_default.title, children: [
845
+ "Uploading (",
846
+ files.filter((f) => f.status === "uploading" || f.status === "pending").length,
847
+ ")"
848
+ ] }),
849
+ hasCompleted && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
850
+ "button",
851
+ {
852
+ type: "button",
853
+ onClick: onClearCompleted,
854
+ className: UploadQueue_default.clearButton,
855
+ children: "Clear completed"
856
+ }
857
+ )
858
+ ] }),
859
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: UploadQueue_default.list, children: files.map((file) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(UploadItem, { file, onCancel: () => onCancel(file.id) }, file.id)) })
860
+ ] });
861
+ }
862
+ function UploadItem({ file, onCancel }) {
863
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: `${UploadQueue_default.item} ${UploadQueue_default[file.status]}`, children: [
864
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: UploadQueue_default.preview, children: [
865
+ file.previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("img", { src: file.previewUrl, alt: "", className: UploadQueue_default.previewImage }) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("div", { className: UploadQueue_default.previewPlaceholder }),
866
+ file.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: UploadQueue_default.progressOverlay, children: [
867
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
868
+ "div",
869
+ {
870
+ className: UploadQueue_default.progressBar,
871
+ style: { height: `${100 - file.progress}%` }
872
+ }
873
+ ),
874
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("span", { className: UploadQueue_default.progressText, children: [
875
+ file.progress,
876
+ "%"
877
+ ] })
878
+ ] })
879
+ ] }),
880
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: UploadQueue_default.info, children: [
881
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: UploadQueue_default.filename, title: file.file.name, children: file.file.name }),
882
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: UploadQueue_default.size, children: formatFileSize(file.file.size) }),
883
+ file.error && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: UploadQueue_default.error, children: file.error })
884
+ ] }),
885
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: UploadQueue_default.actions, children: [
886
+ file.status === "pending" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
887
+ "button",
888
+ {
889
+ type: "button",
890
+ onClick: onCancel,
891
+ className: UploadQueue_default.cancelButton,
892
+ "aria-label": "Cancel upload",
893
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react8.X, { size: 16 })
894
+ }
895
+ ),
896
+ file.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react8.Loader2, { size: 18, className: UploadQueue_default.spinner }),
897
+ file.status === "completed" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react8.CheckCircle, { size: 18, className: UploadQueue_default.successIcon }),
898
+ file.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_lucide_react8.AlertCircle, { size: 18, className: UploadQueue_default.errorIcon })
899
+ ] })
900
+ ] });
901
+ }
902
+
903
+ // src/components/ImagePickerModal/ImagePickerModal.module.css
904
+ var ImagePickerModal_default = {
905
+ backButton: "ImagePickerModal_backButton",
906
+ selectModeButton: "ImagePickerModal_selectModeButton",
907
+ toolbar: "ImagePickerModal_toolbar",
908
+ uploadSection: "ImagePickerModal_uploadSection",
909
+ footer: "ImagePickerModal_footer",
910
+ footerInfo: "ImagePickerModal_footerInfo",
911
+ footerImage: "ImagePickerModal_footerImage",
912
+ footerFilename: "ImagePickerModal_footerFilename",
913
+ footerMeta: "ImagePickerModal_footerMeta",
914
+ selectButton: "ImagePickerModal_selectButton",
915
+ editContent: "ImagePickerModal_editContent",
916
+ editPreview: "ImagePickerModal_editPreview",
917
+ editImage: "ImagePickerModal_editImage",
918
+ editInfo: "ImagePickerModal_editInfo",
919
+ editInfoRow: "ImagePickerModal_editInfoRow",
920
+ editInfoLabel: "ImagePickerModal_editInfoLabel",
921
+ editInfoValue: "ImagePickerModal_editInfoValue",
922
+ editField: "ImagePickerModal_editField",
923
+ editFieldHeader: "ImagePickerModal_editFieldHeader",
924
+ editFieldLabel: "ImagePickerModal_editFieldLabel",
925
+ langTabs: "ImagePickerModal_langTabs",
926
+ langTab: "ImagePickerModal_langTab",
927
+ langTabActive: "ImagePickerModal_langTabActive",
928
+ editInput: "ImagePickerModal_editInput",
929
+ editFooter: "ImagePickerModal_editFooter",
930
+ saveButton: "ImagePickerModal_saveButton",
931
+ spinner: "ImagePickerModal_spinner",
932
+ spin: "ImagePickerModal_spin"
933
+ };
934
+
935
+ // src/components/ImagePickerModal/ImagePickerModal.tsx
936
+ var import_jsx_runtime9 = require("react/jsx-runtime");
937
+ var DEFAULT_UPLOAD_CONFIG = {
938
+ accept: "image/*",
939
+ maxSize: 10 * 1024 * 1024,
940
+ multiple: true
941
+ };
942
+ var PAGE_SIZE = 20;
943
+ function ImagePickerModal({
944
+ languages,
945
+ imageOptions,
946
+ title = "Select Image",
947
+ selectedImage,
948
+ onSelect,
949
+ onClose,
950
+ selectable = true
951
+ }) {
952
+ const { fetchList, upload, update, delete: deleteImage, uploadConfig } = imageOptions;
953
+ const [view, setView] = (0, import_react6.useState)("picker");
954
+ const [editingItem, setEditingItem] = (0, import_react6.useState)(null);
955
+ const [selectMode, setSelectMode] = (0, import_react6.useState)(false);
956
+ const [selectedForDelete, setSelectedForDelete] = (0, import_react6.useState)(/* @__PURE__ */ new Set());
957
+ const [items, setItems] = (0, import_react6.useState)([]);
958
+ const [search, setSearch] = (0, import_react6.useState)("");
959
+ const [loading, setLoading] = (0, import_react6.useState)(true);
960
+ const [page, setPage] = (0, import_react6.useState)(1);
961
+ const [hasMore, setHasMore] = (0, import_react6.useState)(false);
962
+ const [selectedItem, setSelectedItem] = (0, import_react6.useState)(null);
963
+ const [altValues, setAltValues] = (0, import_react6.useState)({});
964
+ const [activeLang, setActiveLang] = (0, import_react6.useState)(languages[0]?.code || "it");
965
+ const [isSaving, setIsSaving] = (0, import_react6.useState)(false);
966
+ const [showDeleteConfirm, setShowDeleteConfirm] = (0, import_react6.useState)(false);
967
+ const [isDeleting, setIsDeleting] = (0, import_react6.useState)(false);
968
+ const canUpload = !!upload;
969
+ const {
970
+ uploading,
971
+ isUploading,
972
+ addFiles,
973
+ cancelUpload,
974
+ clearCompleted,
975
+ uploadConfig: mergedUploadConfig
976
+ } = useUpload({
977
+ upload: upload || (async () => {
978
+ throw new Error("Upload not configured");
979
+ }),
980
+ config: uploadConfig || DEFAULT_UPLOAD_CONFIG,
981
+ onUploadComplete: (newItem) => {
982
+ setItems((prev) => [newItem, ...prev]);
983
+ }
984
+ });
985
+ const loadItems = (0, import_react6.useCallback)(
986
+ async (searchQuery, pageNum, append = false) => {
987
+ setLoading(true);
988
+ try {
989
+ const result = await fetchList({
990
+ query: searchQuery || void 0,
991
+ page: pageNum,
992
+ pageSize: PAGE_SIZE
993
+ });
994
+ const newItems = Array.isArray(result) ? result : result.items;
995
+ const more = Array.isArray(result) ? newItems.length === PAGE_SIZE : result.hasMore ?? false;
996
+ setItems((prev) => append ? [...prev, ...newItems] : newItems);
997
+ setHasMore(more);
998
+ } catch (error) {
999
+ console.error("Failed to fetch images:", error);
1000
+ setItems([]);
1001
+ setHasMore(false);
1002
+ } finally {
1003
+ setLoading(false);
1004
+ }
1005
+ },
1006
+ [fetchList]
1007
+ );
1008
+ (0, import_react6.useEffect)(() => {
1009
+ const timer = setTimeout(() => {
1010
+ setPage(1);
1011
+ loadItems(search, 1);
1012
+ }, 300);
1013
+ return () => clearTimeout(timer);
1014
+ }, [search, loadItems]);
1015
+ (0, import_react6.useEffect)(() => {
1016
+ if (selectedImage) {
1017
+ const existingItem = items.find((item) => item.id === selectedImage.id);
1018
+ if (existingItem) {
1019
+ setSelectedItem(existingItem);
1020
+ }
1021
+ }
1022
+ }, [selectedImage, items]);
1023
+ const handleClose = (0, import_react6.useCallback)(() => {
1024
+ onClose();
1025
+ }, [onClose]);
1026
+ const handleLoadMore = () => {
1027
+ const nextPage = page + 1;
1028
+ setPage(nextPage);
1029
+ loadItems(search, nextPage, true);
1030
+ };
1031
+ const handleImageClick = (item) => {
1032
+ if (selectedItem?.id === item.id) {
1033
+ setSelectedItem(null);
1034
+ } else {
1035
+ setSelectedItem(item);
1036
+ }
1037
+ };
1038
+ const handleConfirmSelection = () => {
1039
+ if (!selectedItem || !onSelect) return;
1040
+ onSelect(selectedItem);
1041
+ };
1042
+ const handleEditAlt = (item) => {
1043
+ setEditingItem(item);
1044
+ setAltValues(item.alt || {});
1045
+ setActiveLang(languages[0]?.code || "it");
1046
+ setView("edit");
1047
+ };
1048
+ const handleAltChange = (langCode, value) => {
1049
+ setAltValues((prev) => ({
1050
+ ...prev,
1051
+ [langCode]: value
1052
+ }));
1053
+ };
1054
+ const handleSaveAlt = async () => {
1055
+ if (!editingItem || !update) return;
1056
+ setIsSaving(true);
1057
+ try {
1058
+ await update(editingItem.id, { alt: altValues });
1059
+ setItems(
1060
+ (prev) => prev.map(
1061
+ (item) => item.id === editingItem.id ? { ...item, alt: altValues } : item
1062
+ )
1063
+ );
1064
+ if (selectedItem?.id === editingItem.id) {
1065
+ setSelectedItem((prev) => prev ? { ...prev, alt: altValues } : null);
1066
+ }
1067
+ setView("picker");
1068
+ setEditingItem(null);
1069
+ setAltValues({});
1070
+ } catch (error) {
1071
+ console.error("Failed to update alt text:", error);
1072
+ } finally {
1073
+ setIsSaving(false);
1074
+ }
1075
+ };
1076
+ const handleToggleSelect = (item) => {
1077
+ setSelectedForDelete((prev) => {
1078
+ const newSet = new Set(prev);
1079
+ if (newSet.has(item.id)) {
1080
+ newSet.delete(item.id);
1081
+ } else {
1082
+ newSet.add(item.id);
1083
+ }
1084
+ return newSet;
1085
+ });
1086
+ };
1087
+ const handleSelectAll = () => {
1088
+ if (selectedForDelete.size === items.length) {
1089
+ setSelectedForDelete(/* @__PURE__ */ new Set());
1090
+ } else {
1091
+ setSelectedForDelete(new Set(items.map((item) => item.id)));
1092
+ }
1093
+ };
1094
+ const handleConfirmDelete = async () => {
1095
+ if (!deleteImage || selectedForDelete.size === 0) return;
1096
+ setIsDeleting(true);
1097
+ try {
1098
+ const deletePromises = Array.from(selectedForDelete).map((id) => deleteImage(id));
1099
+ await Promise.all(deletePromises);
1100
+ setItems((prev) => prev.filter((item) => !selectedForDelete.has(item.id)));
1101
+ if (selectedItem && selectedForDelete.has(selectedItem.id)) {
1102
+ setSelectedItem(null);
1103
+ }
1104
+ setShowDeleteConfirm(false);
1105
+ setSelectedForDelete(/* @__PURE__ */ new Set());
1106
+ setSelectMode(false);
1107
+ } catch (error) {
1108
+ console.error("Failed to delete images:", error);
1109
+ } finally {
1110
+ setIsDeleting(false);
1111
+ }
1112
+ };
1113
+ const formatFileSize2 = (bytes) => {
1114
+ if (!bytes) return "";
1115
+ if (bytes < 1024) return `${bytes} B`;
1116
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
1117
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1118
+ };
1119
+ const isAllSelected = items.length > 0 && selectedForDelete.size === items.length;
1120
+ const isSomeSelected = selectedForDelete.size > 0 && selectedForDelete.size < items.length;
1121
+ if (view === "edit" && editingItem) {
1122
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1123
+ Modal,
1124
+ {
1125
+ title: "Edit Image Details",
1126
+ onClose: handleClose,
1127
+ headerLeft: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1128
+ "button",
1129
+ {
1130
+ type: "button",
1131
+ onClick: () => {
1132
+ setView("picker");
1133
+ setEditingItem(null);
1134
+ setAltValues({});
1135
+ },
1136
+ className: ImagePickerModal_default.backButton,
1137
+ "aria-label": "Back to grid",
1138
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react9.ArrowLeft, { size: 20 })
1139
+ }
1140
+ ),
1141
+ footer: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.editFooter, children: [
1142
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", {}),
1143
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1144
+ "button",
1145
+ {
1146
+ type: "button",
1147
+ onClick: handleSaveAlt,
1148
+ className: ImagePickerModal_default.saveButton,
1149
+ disabled: isSaving || !update,
1150
+ children: isSaving ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
1151
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_lucide_react9.Loader2, { size: 16, className: ImagePickerModal_default.spinner }),
1152
+ "Saving..."
1153
+ ] }) : "Save"
1154
+ }
1155
+ )
1156
+ ] }),
1157
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.editContent, children: [
1158
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: ImagePickerModal_default.editPreview, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1159
+ "img",
1160
+ {
1161
+ src: editingItem.url,
1162
+ alt: editingItem.filename || "",
1163
+ className: ImagePickerModal_default.editImage
1164
+ }
1165
+ ) }),
1166
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.editInfo, children: [
1167
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.editInfoRow, children: [
1168
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: ImagePickerModal_default.editInfoLabel, children: "Filename" }),
1169
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: ImagePickerModal_default.editInfoValue, children: editingItem.filename })
1170
+ ] }),
1171
+ editingItem.width && editingItem.height && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.editInfoRow, children: [
1172
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: ImagePickerModal_default.editInfoLabel, children: "Dimensions" }),
1173
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: ImagePickerModal_default.editInfoValue, children: [
1174
+ editingItem.width,
1175
+ "\xD7",
1176
+ editingItem.height
1177
+ ] })
1178
+ ] }),
1179
+ editingItem.size && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.editInfoRow, children: [
1180
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: ImagePickerModal_default.editInfoLabel, children: "Size" }),
1181
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: ImagePickerModal_default.editInfoValue, children: formatFileSize2(editingItem.size) })
1182
+ ] })
1183
+ ] }),
1184
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.editField, children: [
1185
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.editFieldHeader, children: [
1186
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("label", { className: ImagePickerModal_default.editFieldLabel, children: "Alt" }),
1187
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: ImagePickerModal_default.langTabs, children: languages.map((lang) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1188
+ "button",
1189
+ {
1190
+ type: "button",
1191
+ onClick: () => setActiveLang(lang.code),
1192
+ className: `${ImagePickerModal_default.langTab} ${activeLang === lang.code ? ImagePickerModal_default.langTabActive : ""}`,
1193
+ children: lang.code.toUpperCase()
1194
+ },
1195
+ lang.code
1196
+ )) })
1197
+ ] }),
1198
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1199
+ "input",
1200
+ {
1201
+ type: "text",
1202
+ value: altValues[activeLang] || "",
1203
+ onChange: (e) => handleAltChange(activeLang, e.target.value),
1204
+ placeholder: `Alt text in ${languages.find((l) => l.code === activeLang)?.label || activeLang}...`,
1205
+ className: ImagePickerModal_default.editInput
1206
+ }
1207
+ )
1208
+ ] })
1209
+ ] })
1210
+ }
1211
+ );
1212
+ }
1213
+ const renderFooter = () => {
1214
+ if (selectMode) {
1215
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1216
+ SelectionToolbar,
1217
+ {
1218
+ selectedCount: selectedForDelete.size,
1219
+ totalCount: items.length,
1220
+ onSelectAll: handleSelectAll,
1221
+ onCancel: () => {
1222
+ setSelectMode(false);
1223
+ setSelectedForDelete(/* @__PURE__ */ new Set());
1224
+ },
1225
+ onDelete: () => setShowDeleteConfirm(true),
1226
+ isAllSelected,
1227
+ isIndeterminate: isSomeSelected
1228
+ }
1229
+ );
1230
+ }
1231
+ if (selectedItem && selectable) {
1232
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.footer, children: [
1233
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.footerInfo, children: [
1234
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1235
+ "img",
1236
+ {
1237
+ src: selectedItem.thumbnailUrl || selectedItem.url,
1238
+ alt: "",
1239
+ className: ImagePickerModal_default.footerImage
1240
+ }
1241
+ ),
1242
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: ImagePickerModal_default.footerFilename, children: selectedItem.filename }),
1243
+ selectedItem.width && selectedItem.height && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: ImagePickerModal_default.footerMeta, children: [
1244
+ selectedItem.width,
1245
+ "\xD7",
1246
+ selectedItem.height
1247
+ ] })
1248
+ ] }),
1249
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1250
+ "button",
1251
+ {
1252
+ type: "button",
1253
+ onClick: handleConfirmSelection,
1254
+ className: ImagePickerModal_default.selectButton,
1255
+ children: "Select Image"
1256
+ }
1257
+ )
1258
+ ] });
1259
+ }
1260
+ return void 0;
1261
+ };
1262
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1263
+ Modal,
1264
+ {
1265
+ title,
1266
+ onClose: handleClose,
1267
+ headerActions: !selectMode && deleteImage ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1268
+ "button",
1269
+ {
1270
+ type: "button",
1271
+ onClick: () => setSelectMode(true),
1272
+ className: ImagePickerModal_default.selectModeButton,
1273
+ children: "Select Items"
1274
+ }
1275
+ ) : void 0,
1276
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("div", { className: ImagePickerModal_default.toolbar, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1277
+ SearchBar,
1278
+ {
1279
+ value: search,
1280
+ onChange: setSearch,
1281
+ placeholder: "Search images...",
1282
+ autoFocus: !selectMode
1283
+ }
1284
+ ) }),
1285
+ footer: renderFooter(),
1286
+ overlay: showDeleteConfirm ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1287
+ ConfirmDialog,
1288
+ {
1289
+ title: "Delete Images",
1290
+ message: `Are you sure you want to delete ${selectedForDelete.size} image${selectedForDelete.size > 1 ? "s" : ""}? This action cannot be undone.`,
1291
+ confirmLabel: isDeleting ? "Deleting..." : `Delete ${selectedForDelete.size} image${selectedForDelete.size > 1 ? "s" : ""}`,
1292
+ onConfirm: handleConfirmDelete,
1293
+ onCancel: () => setShowDeleteConfirm(false),
1294
+ loading: isDeleting,
1295
+ variant: "danger"
1296
+ }
1297
+ ) : void 0,
1298
+ loading: loading && items.length === 0,
1299
+ empty: !loading && items.length === 0,
1300
+ emptyMessage: "No images found",
1301
+ children: [
1302
+ canUpload && !selectMode && /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: ImagePickerModal_default.uploadSection, children: [
1303
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1304
+ UploadDropzone,
1305
+ {
1306
+ onFilesSelected: addFiles,
1307
+ config: mergedUploadConfig,
1308
+ disabled: isUploading && uploading.length >= 10
1309
+ }
1310
+ ),
1311
+ uploading.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1312
+ UploadQueue,
1313
+ {
1314
+ files: uploading,
1315
+ onCancel: cancelUpload,
1316
+ onClearCompleted: clearCompleted
1317
+ }
1318
+ )
1319
+ ] }),
1320
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1321
+ ImageGrid,
1322
+ {
1323
+ items,
1324
+ onSelect: handleImageClick,
1325
+ selectedId: selectedItem?.id,
1326
+ onEditAlt: update ? handleEditAlt : void 0,
1327
+ manageMode: selectMode,
1328
+ selectedIds: selectedForDelete,
1329
+ onToggleSelect: handleToggleSelect
1330
+ }
1331
+ ),
1332
+ hasMore && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(LoadMoreButton, { onClick: handleLoadMore, loading })
1333
+ ]
1334
+ }
1335
+ );
1336
+ }
1337
+
1338
+ // src/components/ImageField/ImageField.module.css
1339
+ var ImageField_default = {
1340
+ container: "ImageField_container",
1341
+ preview: "ImageField_preview",
1342
+ image: "ImageField_image",
1343
+ overlay: "ImageField_overlay",
1344
+ changeButton: "ImageField_changeButton",
1345
+ removeButton: "ImageField_removeButton",
1346
+ selectButton: "ImageField_selectButton"
1347
+ };
1348
+
1349
+ // src/components/ImageField/ImageField.tsx
1350
+ var import_jsx_runtime10 = require("react/jsx-runtime");
1351
+ function ImageField({
1352
+ value,
1353
+ onChange,
1354
+ field,
1355
+ languages,
1356
+ imageOptions
1357
+ }) {
1358
+ const [isModalOpen, setIsModalOpen] = (0, import_react7.useState)(false);
1359
+ const handleSelect = (item) => {
1360
+ onChange(item);
1361
+ setIsModalOpen(false);
1362
+ };
1363
+ const handleRemove = (e) => {
1364
+ e.stopPropagation();
1365
+ onChange(null);
1366
+ };
1367
+ const handleOpenModal = () => {
1368
+ setIsModalOpen(true);
1369
+ };
1370
+ const getAltDisplay = () => {
1371
+ if (!value?.alt) return "";
1372
+ for (const lang of languages) {
1373
+ if (value.alt[lang.code]) {
1374
+ return value.alt[lang.code];
1375
+ }
1376
+ }
1377
+ return "";
1378
+ };
1379
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_core.FieldLabel, { label: field.label || "Image", children: [
1380
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { className: ImageField_default.container, children: value ? /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: ImageField_default.preview, children: [
1381
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1382
+ "img",
1383
+ {
1384
+ src: value.url,
1385
+ alt: getAltDisplay(),
1386
+ className: ImageField_default.image
1387
+ }
1388
+ ),
1389
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("div", { className: ImageField_default.overlay, children: [
1390
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1391
+ "button",
1392
+ {
1393
+ type: "button",
1394
+ onClick: handleOpenModal,
1395
+ className: ImageField_default.changeButton,
1396
+ children: "Change"
1397
+ }
1398
+ ),
1399
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1400
+ "button",
1401
+ {
1402
+ type: "button",
1403
+ onClick: handleRemove,
1404
+ className: ImageField_default.removeButton,
1405
+ "aria-label": "Remove image",
1406
+ children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react10.X, { size: 16 })
1407
+ }
1408
+ )
1409
+ ] })
1410
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
1411
+ "button",
1412
+ {
1413
+ type: "button",
1414
+ onClick: handleOpenModal,
1415
+ className: ImageField_default.selectButton,
1416
+ children: [
1417
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_lucide_react10.ImagePlus, { size: 24 }),
1418
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { children: "Select image" })
1419
+ ]
1420
+ }
1421
+ ) }),
1422
+ isModalOpen && (0, import_react_dom.createPortal)(
1423
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1424
+ ImagePickerModal,
1425
+ {
1426
+ languages,
1427
+ imageOptions,
1428
+ title: "Select Image",
1429
+ selectedImage: value,
1430
+ onSelect: handleSelect,
1431
+ onClose: () => setIsModalOpen(false)
1432
+ }
1433
+ ),
1434
+ document.body
1435
+ )
1436
+ ] });
1437
+ }
1438
+
1439
+ // src/components/GalleryField/GalleryField.tsx
1440
+ var import_react9 = require("react");
1441
+ var import_react_dom2 = require("react-dom");
1442
+ var import_core2 = require("@puckeditor/core");
1443
+ var import_lucide_react12 = require("lucide-react");
1444
+
1445
+ // src/components/GalleryPickerModal/GalleryPickerModal.tsx
1446
+ var import_react8 = require("react");
1447
+ var import_lucide_react11 = require("lucide-react");
1448
+
1449
+ // src/components/GalleryPickerModal/GalleryPickerModal.module.css
1450
+ var GalleryPickerModal_default = {
1451
+ backButton: "GalleryPickerModal_backButton",
1452
+ selectModeButton: "GalleryPickerModal_selectModeButton",
1453
+ toolbar: "GalleryPickerModal_toolbar",
1454
+ createButton: "GalleryPickerModal_createButton",
1455
+ createForm: "GalleryPickerModal_createForm",
1456
+ createInput: "GalleryPickerModal_createInput",
1457
+ createSubmitButton: "GalleryPickerModal_createSubmitButton",
1458
+ createCancelButton: "GalleryPickerModal_createCancelButton",
1459
+ uploadSection: "GalleryPickerModal_uploadSection",
1460
+ galleryGrid: "GalleryPickerModal_galleryGrid",
1461
+ galleryCard: "GalleryPickerModal_galleryCard",
1462
+ galleryCardButton: "GalleryPickerModal_galleryCardButton",
1463
+ selected: "GalleryPickerModal_selected",
1464
+ checkbox: "GalleryPickerModal_checkbox",
1465
+ checkboxChecked: "GalleryPickerModal_checkboxChecked",
1466
+ galleryCover: "GalleryPickerModal_galleryCover",
1467
+ galleryCoverPlaceholder: "GalleryPickerModal_galleryCoverPlaceholder",
1468
+ galleryInfo: "GalleryPickerModal_galleryInfo",
1469
+ galleryName: "GalleryPickerModal_galleryName",
1470
+ galleryCount: "GalleryPickerModal_galleryCount",
1471
+ footer: "GalleryPickerModal_footer",
1472
+ footerInfo: "GalleryPickerModal_footerInfo",
1473
+ footerText: "GalleryPickerModal_footerText",
1474
+ selectButton: "GalleryPickerModal_selectButton",
1475
+ editContent: "GalleryPickerModal_editContent",
1476
+ editPreview: "GalleryPickerModal_editPreview",
1477
+ editImage: "GalleryPickerModal_editImage",
1478
+ editInfo: "GalleryPickerModal_editInfo",
1479
+ editInfoRow: "GalleryPickerModal_editInfoRow",
1480
+ editInfoLabel: "GalleryPickerModal_editInfoLabel",
1481
+ editInfoValue: "GalleryPickerModal_editInfoValue",
1482
+ editField: "GalleryPickerModal_editField",
1483
+ editFieldHeader: "GalleryPickerModal_editFieldHeader",
1484
+ editFieldLabel: "GalleryPickerModal_editFieldLabel",
1485
+ langTabs: "GalleryPickerModal_langTabs",
1486
+ langTab: "GalleryPickerModal_langTab",
1487
+ langTabActive: "GalleryPickerModal_langTabActive",
1488
+ editInput: "GalleryPickerModal_editInput",
1489
+ editFooter: "GalleryPickerModal_editFooter",
1490
+ saveButton: "GalleryPickerModal_saveButton",
1491
+ spinner: "GalleryPickerModal_spinner",
1492
+ spin: "GalleryPickerModal_spin"
1493
+ };
1494
+
1495
+ // src/components/GalleryPickerModal/GalleryPickerModal.tsx
1496
+ var import_jsx_runtime11 = require("react/jsx-runtime");
1497
+ var DEFAULT_UPLOAD_CONFIG2 = {
1498
+ accept: "image/*",
1499
+ maxSize: 10 * 1024 * 1024,
1500
+ multiple: true
1501
+ };
1502
+ var PAGE_SIZE2 = 20;
1503
+ function GalleryPickerModal({
1504
+ languages,
1505
+ galleryOptions,
1506
+ title = "Select Gallery",
1507
+ selectedGallery: _initialSelectedGallery,
1508
+ onSelect,
1509
+ onClose,
1510
+ selectable = true
1511
+ }) {
1512
+ void _initialSelectedGallery;
1513
+ const { fetchList, fetch, create, delete: deleteGallery, upload, removeImage, updateImage } = galleryOptions;
1514
+ const [viewMode, setViewMode] = (0, import_react8.useState)("list");
1515
+ const [editingImage, setEditingImage] = (0, import_react8.useState)(null);
1516
+ const [galleries, setGalleries] = (0, import_react8.useState)([]);
1517
+ const [selectedGalleryItem, setSelectedGalleryItem] = (0, import_react8.useState)(null);
1518
+ const [search, setSearch] = (0, import_react8.useState)("");
1519
+ const [loading, setLoading] = (0, import_react8.useState)(true);
1520
+ const [page, setPage] = (0, import_react8.useState)(1);
1521
+ const [hasMore, setHasMore] = (0, import_react8.useState)(false);
1522
+ const [gallerySelectMode, setGallerySelectMode] = (0, import_react8.useState)(false);
1523
+ const [selectedGalleryIds, setSelectedGalleryIds] = (0, import_react8.useState)(/* @__PURE__ */ new Set());
1524
+ const [imageSelectMode, setImageSelectMode] = (0, import_react8.useState)(false);
1525
+ const [selectedImageIds, setSelectedImageIds] = (0, import_react8.useState)(/* @__PURE__ */ new Set());
1526
+ const [showDeleteConfirm, setShowDeleteConfirm] = (0, import_react8.useState)(false);
1527
+ const [deleteTarget, setDeleteTarget] = (0, import_react8.useState)("gallery");
1528
+ const [isDeleting, setIsDeleting] = (0, import_react8.useState)(false);
1529
+ const [isCreating, setIsCreating] = (0, import_react8.useState)(false);
1530
+ const [newGalleryName, setNewGalleryName] = (0, import_react8.useState)("");
1531
+ const [createLoading, setCreateLoading] = (0, import_react8.useState)(false);
1532
+ const [altValues, setAltValues] = (0, import_react8.useState)({});
1533
+ const [activeLang, setActiveLang] = (0, import_react8.useState)(languages[0]?.code || "it");
1534
+ const [isSaving, setIsSaving] = (0, import_react8.useState)(false);
1535
+ const newGalleryInputRef = (0, import_react8.useRef)(null);
1536
+ const {
1537
+ uploading,
1538
+ isUploading,
1539
+ addFiles,
1540
+ cancelUpload,
1541
+ clearCompleted,
1542
+ uploadConfig: mergedUploadConfig
1543
+ } = useUpload({
1544
+ upload: async (file, callbacks) => {
1545
+ if (!selectedGalleryItem) throw new Error("No gallery selected");
1546
+ const result = await upload(selectedGalleryItem.id, file, callbacks);
1547
+ return Array.isArray(result) ? result[0] : result;
1548
+ },
1549
+ config: DEFAULT_UPLOAD_CONFIG2,
1550
+ onUploadComplete: (newItem) => {
1551
+ if (selectedGalleryItem) {
1552
+ setSelectedGalleryItem((prev) => {
1553
+ if (!prev) return prev;
1554
+ return {
1555
+ ...prev,
1556
+ images: [newItem, ...prev.images],
1557
+ imageCount: (prev.imageCount || 0) + 1
1558
+ };
1559
+ });
1560
+ }
1561
+ }
1562
+ });
1563
+ const loadGalleries = (0, import_react8.useCallback)(
1564
+ async (searchQuery, pageNum, append = false) => {
1565
+ setLoading(true);
1566
+ try {
1567
+ const result = await fetchList({
1568
+ query: searchQuery || void 0,
1569
+ page: pageNum,
1570
+ pageSize: PAGE_SIZE2
1571
+ });
1572
+ const newItems = Array.isArray(result) ? result : result.items;
1573
+ const more = Array.isArray(result) ? newItems.length === PAGE_SIZE2 : result.hasMore ?? false;
1574
+ setGalleries((prev) => append ? [...prev, ...newItems] : newItems);
1575
+ setHasMore(more);
1576
+ } catch (error) {
1577
+ console.error("Failed to fetch galleries:", error);
1578
+ setGalleries([]);
1579
+ setHasMore(false);
1580
+ } finally {
1581
+ setLoading(false);
1582
+ }
1583
+ },
1584
+ [fetchList]
1585
+ );
1586
+ const loadGalleryDetail = (0, import_react8.useCallback)(
1587
+ async (id) => {
1588
+ setLoading(true);
1589
+ try {
1590
+ const gallery = await fetch(id);
1591
+ setSelectedGalleryItem(gallery);
1592
+ } catch (error) {
1593
+ console.error("Failed to fetch gallery:", error);
1594
+ } finally {
1595
+ setLoading(false);
1596
+ }
1597
+ },
1598
+ [fetch]
1599
+ );
1600
+ (0, import_react8.useEffect)(() => {
1601
+ if (viewMode === "list") {
1602
+ const timer = setTimeout(() => {
1603
+ setPage(1);
1604
+ loadGalleries(search, 1);
1605
+ }, 300);
1606
+ return () => clearTimeout(timer);
1607
+ }
1608
+ }, [search, loadGalleries, viewMode]);
1609
+ (0, import_react8.useEffect)(() => {
1610
+ if (isCreating && newGalleryInputRef.current) {
1611
+ newGalleryInputRef.current.focus();
1612
+ }
1613
+ }, [isCreating]);
1614
+ const handleClose = (0, import_react8.useCallback)(() => {
1615
+ onClose();
1616
+ }, [onClose]);
1617
+ const handleLoadMore = () => {
1618
+ const nextPage = page + 1;
1619
+ setPage(nextPage);
1620
+ loadGalleries(search, nextPage, true);
1621
+ };
1622
+ const handleGalleryClick = (gallery) => {
1623
+ if (gallerySelectMode) {
1624
+ setSelectedGalleryIds((prev) => {
1625
+ const newSet = new Set(prev);
1626
+ if (newSet.has(gallery.id)) {
1627
+ newSet.delete(gallery.id);
1628
+ } else {
1629
+ newSet.add(gallery.id);
1630
+ }
1631
+ return newSet;
1632
+ });
1633
+ } else {
1634
+ setViewMode("detail");
1635
+ loadGalleryDetail(gallery.id);
1636
+ }
1637
+ };
1638
+ const handleCreateGallery = async () => {
1639
+ if (!newGalleryName.trim()) return;
1640
+ setCreateLoading(true);
1641
+ try {
1642
+ const newGallery = await create(newGalleryName.trim());
1643
+ setGalleries((prev) => [newGallery, ...prev]);
1644
+ setIsCreating(false);
1645
+ setNewGalleryName("");
1646
+ } catch (error) {
1647
+ console.error("Failed to create gallery:", error);
1648
+ } finally {
1649
+ setCreateLoading(false);
1650
+ }
1651
+ };
1652
+ const handleSelectAllGalleries = () => {
1653
+ if (selectedGalleryIds.size === galleries.length) {
1654
+ setSelectedGalleryIds(/* @__PURE__ */ new Set());
1655
+ } else {
1656
+ setSelectedGalleryIds(new Set(galleries.map((g) => g.id)));
1657
+ }
1658
+ };
1659
+ const handleSelectAllImages = () => {
1660
+ if (!selectedGalleryItem) return;
1661
+ if (selectedImageIds.size === selectedGalleryItem.images.length) {
1662
+ setSelectedImageIds(/* @__PURE__ */ new Set());
1663
+ } else {
1664
+ setSelectedImageIds(new Set(selectedGalleryItem.images.map((img) => img.id)));
1665
+ }
1666
+ };
1667
+ const handleToggleImageSelect = (image) => {
1668
+ setSelectedImageIds((prev) => {
1669
+ const newSet = new Set(prev);
1670
+ if (newSet.has(image.id)) {
1671
+ newSet.delete(image.id);
1672
+ } else {
1673
+ newSet.add(image.id);
1674
+ }
1675
+ return newSet;
1676
+ });
1677
+ };
1678
+ const handleConfirmDelete = async () => {
1679
+ setIsDeleting(true);
1680
+ try {
1681
+ if (deleteTarget === "gallery") {
1682
+ const deletePromises = Array.from(selectedGalleryIds).map((id) => deleteGallery(id));
1683
+ await Promise.all(deletePromises);
1684
+ setGalleries((prev) => prev.filter((g) => !selectedGalleryIds.has(g.id)));
1685
+ setSelectedGalleryIds(/* @__PURE__ */ new Set());
1686
+ setGallerySelectMode(false);
1687
+ } else {
1688
+ if (!selectedGalleryItem) return;
1689
+ const removePromises = Array.from(selectedImageIds).map(
1690
+ (imageId) => removeImage(selectedGalleryItem.id, imageId)
1691
+ );
1692
+ await Promise.all(removePromises);
1693
+ setSelectedGalleryItem((prev) => {
1694
+ if (!prev) return prev;
1695
+ return {
1696
+ ...prev,
1697
+ images: prev.images.filter((img) => !selectedImageIds.has(img.id)),
1698
+ imageCount: (prev.imageCount || prev.images.length) - selectedImageIds.size
1699
+ };
1700
+ });
1701
+ setSelectedImageIds(/* @__PURE__ */ new Set());
1702
+ setImageSelectMode(false);
1703
+ }
1704
+ setShowDeleteConfirm(false);
1705
+ } catch (error) {
1706
+ console.error("Failed to delete:", error);
1707
+ } finally {
1708
+ setIsDeleting(false);
1709
+ }
1710
+ };
1711
+ const handleEditAlt = (image) => {
1712
+ setEditingImage(image);
1713
+ setAltValues(image.alt || {});
1714
+ setActiveLang(languages[0]?.code || "it");
1715
+ setViewMode("editImage");
1716
+ };
1717
+ const handleAltChange = (langCode, value) => {
1718
+ setAltValues((prev) => ({
1719
+ ...prev,
1720
+ [langCode]: value
1721
+ }));
1722
+ };
1723
+ const handleSaveAlt = async () => {
1724
+ if (!selectedGalleryItem || !editingImage || !updateImage) return;
1725
+ setIsSaving(true);
1726
+ try {
1727
+ await updateImage(selectedGalleryItem.id, editingImage.id, { alt: altValues });
1728
+ setSelectedGalleryItem((prev) => {
1729
+ if (!prev) return prev;
1730
+ return {
1731
+ ...prev,
1732
+ images: prev.images.map(
1733
+ (img) => img.id === editingImage.id ? { ...img, alt: altValues } : img
1734
+ )
1735
+ };
1736
+ });
1737
+ setViewMode("detail");
1738
+ setEditingImage(null);
1739
+ setAltValues({});
1740
+ } catch (error) {
1741
+ console.error("Failed to update alt text:", error);
1742
+ } finally {
1743
+ setIsSaving(false);
1744
+ }
1745
+ };
1746
+ const handleSelectGallery = () => {
1747
+ if (selectedGalleryItem && onSelect) {
1748
+ onSelect(selectedGalleryItem);
1749
+ }
1750
+ };
1751
+ const formatFileSize2 = (bytes) => {
1752
+ if (!bytes) return "";
1753
+ if (bytes < 1024) return `${bytes} B`;
1754
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
1755
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1756
+ };
1757
+ const isAllGalleriesSelected = galleries.length > 0 && selectedGalleryIds.size === galleries.length;
1758
+ const isSomeGalleriesSelected = selectedGalleryIds.size > 0 && selectedGalleryIds.size < galleries.length;
1759
+ const isAllImagesSelected = selectedGalleryItem && selectedGalleryItem.images.length > 0 && selectedImageIds.size === selectedGalleryItem.images.length;
1760
+ const isSomeImagesSelected = selectedImageIds.size > 0 && selectedGalleryItem && selectedImageIds.size < selectedGalleryItem.images.length;
1761
+ if (viewMode === "editImage" && editingImage) {
1762
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1763
+ Modal,
1764
+ {
1765
+ title: "Edit Image Details",
1766
+ onClose: handleClose,
1767
+ headerLeft: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1768
+ "button",
1769
+ {
1770
+ type: "button",
1771
+ onClick: () => {
1772
+ setViewMode("detail");
1773
+ setEditingImage(null);
1774
+ setAltValues({});
1775
+ },
1776
+ className: GalleryPickerModal_default.backButton,
1777
+ "aria-label": "Back to gallery",
1778
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react11.ArrowLeft, { size: 20 })
1779
+ }
1780
+ ),
1781
+ footer: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.editFooter, children: [
1782
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", {}),
1783
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1784
+ "button",
1785
+ {
1786
+ type: "button",
1787
+ onClick: handleSaveAlt,
1788
+ className: GalleryPickerModal_default.saveButton,
1789
+ disabled: isSaving || !updateImage,
1790
+ children: isSaving ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1791
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react11.Loader2, { size: 16, className: GalleryPickerModal_default.spinner }),
1792
+ "Saving..."
1793
+ ] }) : "Save"
1794
+ }
1795
+ )
1796
+ ] }),
1797
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.editContent, children: [
1798
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: GalleryPickerModal_default.editPreview, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1799
+ "img",
1800
+ {
1801
+ src: editingImage.url,
1802
+ alt: editingImage.filename || "",
1803
+ className: GalleryPickerModal_default.editImage
1804
+ }
1805
+ ) }),
1806
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.editInfo, children: [
1807
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.editInfoRow, children: [
1808
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: GalleryPickerModal_default.editInfoLabel, children: "Filename" }),
1809
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: GalleryPickerModal_default.editInfoValue, children: editingImage.filename })
1810
+ ] }),
1811
+ editingImage.width && editingImage.height && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.editInfoRow, children: [
1812
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: GalleryPickerModal_default.editInfoLabel, children: "Dimensions" }),
1813
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: GalleryPickerModal_default.editInfoValue, children: [
1814
+ editingImage.width,
1815
+ "\xD7",
1816
+ editingImage.height
1817
+ ] })
1818
+ ] }),
1819
+ editingImage.size && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.editInfoRow, children: [
1820
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: GalleryPickerModal_default.editInfoLabel, children: "Size" }),
1821
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: GalleryPickerModal_default.editInfoValue, children: formatFileSize2(editingImage.size) })
1822
+ ] })
1823
+ ] }),
1824
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.editField, children: [
1825
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.editFieldHeader, children: [
1826
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("label", { className: GalleryPickerModal_default.editFieldLabel, children: "Alt" }),
1827
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: GalleryPickerModal_default.langTabs, children: languages.map((lang) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1828
+ "button",
1829
+ {
1830
+ type: "button",
1831
+ onClick: () => setActiveLang(lang.code),
1832
+ className: `${GalleryPickerModal_default.langTab} ${activeLang === lang.code ? GalleryPickerModal_default.langTabActive : ""}`,
1833
+ children: lang.code.toUpperCase()
1834
+ },
1835
+ lang.code
1836
+ )) })
1837
+ ] }),
1838
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1839
+ "input",
1840
+ {
1841
+ type: "text",
1842
+ value: altValues[activeLang] || "",
1843
+ onChange: (e) => handleAltChange(activeLang, e.target.value),
1844
+ placeholder: `Alt text in ${languages.find((l) => l.code === activeLang)?.label || activeLang}...`,
1845
+ className: GalleryPickerModal_default.editInput
1846
+ }
1847
+ )
1848
+ ] })
1849
+ ] })
1850
+ }
1851
+ );
1852
+ }
1853
+ if (viewMode === "detail" && selectedGalleryItem) {
1854
+ const renderDetailFooter = () => {
1855
+ if (imageSelectMode) {
1856
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1857
+ SelectionToolbar,
1858
+ {
1859
+ selectedCount: selectedImageIds.size,
1860
+ totalCount: selectedGalleryItem.images.length,
1861
+ onSelectAll: handleSelectAllImages,
1862
+ onCancel: () => {
1863
+ setImageSelectMode(false);
1864
+ setSelectedImageIds(/* @__PURE__ */ new Set());
1865
+ },
1866
+ onDelete: () => {
1867
+ setDeleteTarget("image");
1868
+ setShowDeleteConfirm(true);
1869
+ },
1870
+ isAllSelected: !!isAllImagesSelected,
1871
+ isIndeterminate: !!isSomeImagesSelected,
1872
+ deleteLabel: "Remove"
1873
+ }
1874
+ );
1875
+ }
1876
+ if (selectable) {
1877
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.footer, children: [
1878
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: GalleryPickerModal_default.footerInfo, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: GalleryPickerModal_default.footerText, children: [
1879
+ selectedGalleryItem.images.length,
1880
+ " ",
1881
+ selectedGalleryItem.images.length === 1 ? "image" : "images"
1882
+ ] }) }),
1883
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1884
+ "button",
1885
+ {
1886
+ type: "button",
1887
+ onClick: handleSelectGallery,
1888
+ className: GalleryPickerModal_default.selectButton,
1889
+ children: "Select this Gallery"
1890
+ }
1891
+ )
1892
+ ] });
1893
+ }
1894
+ return void 0;
1895
+ };
1896
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1897
+ Modal,
1898
+ {
1899
+ title: selectedGalleryItem.name,
1900
+ onClose: handleClose,
1901
+ headerLeft: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1902
+ "button",
1903
+ {
1904
+ type: "button",
1905
+ onClick: () => {
1906
+ setViewMode("list");
1907
+ setSelectedGalleryItem(null);
1908
+ },
1909
+ className: GalleryPickerModal_default.backButton,
1910
+ "aria-label": "Back to galleries",
1911
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react11.ArrowLeft, { size: 20 })
1912
+ }
1913
+ ),
1914
+ headerActions: !imageSelectMode && typeof removeImage === "function" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1915
+ "button",
1916
+ {
1917
+ type: "button",
1918
+ onClick: () => setImageSelectMode(true),
1919
+ className: GalleryPickerModal_default.selectModeButton,
1920
+ children: "Select Items"
1921
+ }
1922
+ ) : void 0,
1923
+ toolbar: !imageSelectMode ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.uploadSection, children: [
1924
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1925
+ UploadDropzone,
1926
+ {
1927
+ onFilesSelected: addFiles,
1928
+ config: mergedUploadConfig,
1929
+ disabled: isUploading && uploading.length >= 10
1930
+ }
1931
+ ),
1932
+ uploading.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1933
+ UploadQueue,
1934
+ {
1935
+ files: uploading,
1936
+ onCancel: cancelUpload,
1937
+ onClearCompleted: clearCompleted
1938
+ }
1939
+ )
1940
+ ] }) : void 0,
1941
+ footer: renderDetailFooter(),
1942
+ overlay: showDeleteConfirm ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1943
+ ConfirmDialog,
1944
+ {
1945
+ title: "Remove Images",
1946
+ message: `Are you sure you want to remove ${selectedImageIds.size} ${selectedImageIds.size > 1 ? "images" : "image"} from this gallery?`,
1947
+ confirmLabel: isDeleting ? "Removing..." : `Remove ${selectedImageIds.size} ${selectedImageIds.size > 1 ? "images" : "image"}`,
1948
+ onConfirm: handleConfirmDelete,
1949
+ onCancel: () => setShowDeleteConfirm(false),
1950
+ loading: isDeleting,
1951
+ variant: "danger"
1952
+ }
1953
+ ) : void 0,
1954
+ loading,
1955
+ empty: !loading && selectedGalleryItem.images.length === 0,
1956
+ emptyMessage: "No images in this gallery. Upload some images above.",
1957
+ children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1958
+ ImageGrid,
1959
+ {
1960
+ items: selectedGalleryItem.images,
1961
+ onSelect: () => {
1962
+ },
1963
+ onEditAlt: updateImage ? handleEditAlt : void 0,
1964
+ manageMode: imageSelectMode,
1965
+ selectedIds: selectedImageIds,
1966
+ onToggleSelect: handleToggleImageSelect
1967
+ }
1968
+ )
1969
+ }
1970
+ );
1971
+ }
1972
+ const renderListFooter = () => {
1973
+ if (gallerySelectMode) {
1974
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1975
+ SelectionToolbar,
1976
+ {
1977
+ selectedCount: selectedGalleryIds.size,
1978
+ totalCount: galleries.length,
1979
+ onSelectAll: handleSelectAllGalleries,
1980
+ onCancel: () => {
1981
+ setGallerySelectMode(false);
1982
+ setSelectedGalleryIds(/* @__PURE__ */ new Set());
1983
+ },
1984
+ onDelete: () => {
1985
+ setDeleteTarget("gallery");
1986
+ setShowDeleteConfirm(true);
1987
+ },
1988
+ isAllSelected: isAllGalleriesSelected,
1989
+ isIndeterminate: isSomeGalleriesSelected
1990
+ }
1991
+ );
1992
+ }
1993
+ return void 0;
1994
+ };
1995
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
1996
+ Modal,
1997
+ {
1998
+ title,
1999
+ onClose: handleClose,
2000
+ headerActions: !gallerySelectMode && typeof deleteGallery === "function" ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2001
+ "button",
2002
+ {
2003
+ type: "button",
2004
+ onClick: () => setGallerySelectMode(true),
2005
+ className: GalleryPickerModal_default.selectModeButton,
2006
+ children: "Select Items"
2007
+ }
2008
+ ) : void 0,
2009
+ toolbar: !gallerySelectMode ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.toolbar, children: [
2010
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2011
+ SearchBar,
2012
+ {
2013
+ value: search,
2014
+ onChange: setSearch,
2015
+ placeholder: "Search galleries...",
2016
+ autoFocus: true
2017
+ }
2018
+ ),
2019
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2020
+ "button",
2021
+ {
2022
+ type: "button",
2023
+ onClick: () => setIsCreating(true),
2024
+ className: GalleryPickerModal_default.createButton,
2025
+ children: [
2026
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react11.Plus, { size: 18 }),
2027
+ "New Gallery"
2028
+ ]
2029
+ }
2030
+ )
2031
+ ] }) : void 0,
2032
+ footer: renderListFooter(),
2033
+ overlay: showDeleteConfirm ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2034
+ ConfirmDialog,
2035
+ {
2036
+ title: "Delete Galleries",
2037
+ message: `Are you sure you want to delete ${selectedGalleryIds.size} ${selectedGalleryIds.size > 1 ? "galleries" : "gallery"}? This action cannot be undone.`,
2038
+ confirmLabel: isDeleting ? "Deleting..." : `Delete ${selectedGalleryIds.size} ${selectedGalleryIds.size > 1 ? "galleries" : "gallery"}`,
2039
+ onConfirm: handleConfirmDelete,
2040
+ onCancel: () => setShowDeleteConfirm(false),
2041
+ loading: isDeleting,
2042
+ variant: "danger"
2043
+ }
2044
+ ) : void 0,
2045
+ loading: loading && galleries.length === 0,
2046
+ empty: !loading && galleries.length === 0,
2047
+ emptyMessage: "No galleries found",
2048
+ children: [
2049
+ isCreating && /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.createForm, children: [
2050
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2051
+ "input",
2052
+ {
2053
+ ref: newGalleryInputRef,
2054
+ type: "text",
2055
+ value: newGalleryName,
2056
+ onChange: (e) => setNewGalleryName(e.target.value),
2057
+ placeholder: "Gallery name...",
2058
+ className: GalleryPickerModal_default.createInput,
2059
+ onKeyDown: (e) => {
2060
+ if (e.key === "Enter") handleCreateGallery();
2061
+ if (e.key === "Escape") {
2062
+ setIsCreating(false);
2063
+ setNewGalleryName("");
2064
+ }
2065
+ }
2066
+ }
2067
+ ),
2068
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2069
+ "button",
2070
+ {
2071
+ type: "button",
2072
+ onClick: handleCreateGallery,
2073
+ disabled: !newGalleryName.trim() || createLoading,
2074
+ className: GalleryPickerModal_default.createSubmitButton,
2075
+ children: createLoading ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react11.Loader2, { size: 16, className: GalleryPickerModal_default.spinner }) : "Create"
2076
+ }
2077
+ ),
2078
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2079
+ "button",
2080
+ {
2081
+ type: "button",
2082
+ onClick: () => {
2083
+ setIsCreating(false);
2084
+ setNewGalleryName("");
2085
+ },
2086
+ className: GalleryPickerModal_default.createCancelButton,
2087
+ children: "Cancel"
2088
+ }
2089
+ )
2090
+ ] }),
2091
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: GalleryPickerModal_default.galleryGrid, children: galleries.map((gallery) => {
2092
+ const isSelected = selectedGalleryIds.has(gallery.id);
2093
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: GalleryPickerModal_default.galleryCard, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
2094
+ "button",
2095
+ {
2096
+ type: "button",
2097
+ onClick: () => handleGalleryClick(gallery),
2098
+ className: `${GalleryPickerModal_default.galleryCardButton} ${gallerySelectMode && isSelected ? GalleryPickerModal_default.selected : ""}`,
2099
+ children: [
2100
+ gallerySelectMode && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: `${GalleryPickerModal_default.checkbox} ${isSelected ? GalleryPickerModal_default.checkboxChecked : ""}`, children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_lucide_react11.Check, { size: 14, strokeWidth: 3 }) }),
2101
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: GalleryPickerModal_default.galleryCover, children: gallery.coverImage ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2102
+ "img",
2103
+ {
2104
+ src: gallery.coverImage.thumbnailUrl || gallery.coverImage.url,
2105
+ alt: ""
2106
+ }
2107
+ ) : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { className: GalleryPickerModal_default.galleryCoverPlaceholder }) }),
2108
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("div", { className: GalleryPickerModal_default.galleryInfo, children: [
2109
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: GalleryPickerModal_default.galleryName, children: gallery.name }),
2110
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)("span", { className: GalleryPickerModal_default.galleryCount, children: [
2111
+ gallery.imageCount ?? gallery.images.length,
2112
+ " ",
2113
+ (gallery.imageCount ?? gallery.images.length) === 1 ? "image" : "images"
2114
+ ] })
2115
+ ] })
2116
+ ]
2117
+ }
2118
+ ) }, gallery.id);
2119
+ }) }),
2120
+ hasMore && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LoadMoreButton, { onClick: handleLoadMore, loading })
2121
+ ]
2122
+ }
2123
+ );
2124
+ }
2125
+
2126
+ // src/components/GalleryField/GalleryField.module.css
2127
+ var GalleryField_default = {
2128
+ container: "GalleryField_container",
2129
+ preview: "GalleryField_preview",
2130
+ header: "GalleryField_header",
2131
+ name: "GalleryField_name",
2132
+ count: "GalleryField_count",
2133
+ thumbnails: "GalleryField_thumbnails",
2134
+ thumbnail: "GalleryField_thumbnail",
2135
+ more: "GalleryField_more",
2136
+ actions: "GalleryField_actions",
2137
+ changeButton: "GalleryField_changeButton",
2138
+ removeButton: "GalleryField_removeButton",
2139
+ selectButton: "GalleryField_selectButton"
2140
+ };
2141
+
2142
+ // src/components/GalleryField/GalleryField.tsx
2143
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2144
+ function GalleryField({
2145
+ value,
2146
+ onChange,
2147
+ field,
2148
+ languages,
2149
+ galleryOptions
2150
+ }) {
2151
+ const [isModalOpen, setIsModalOpen] = (0, import_react9.useState)(false);
2152
+ const handleSelect = (gallery) => {
2153
+ onChange(gallery);
2154
+ setIsModalOpen(false);
2155
+ };
2156
+ const handleRemove = (e) => {
2157
+ e.stopPropagation();
2158
+ onChange(null);
2159
+ };
2160
+ const handleOpenModal = () => {
2161
+ setIsModalOpen(true);
2162
+ };
2163
+ const previewImages = value?.images?.slice(0, 4) || [];
2164
+ const remainingCount = (value?.images?.length || 0) - 4;
2165
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_core2.FieldLabel, { label: field.label || "Gallery", children: [
2166
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: GalleryField_default.container, children: value ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: GalleryField_default.preview, children: [
2167
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: GalleryField_default.header, children: [
2168
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: GalleryField_default.name, children: value.name }),
2169
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("span", { className: GalleryField_default.count, children: [
2170
+ value.images.length,
2171
+ " ",
2172
+ value.images.length === 1 ? "image" : "images"
2173
+ ] })
2174
+ ] }),
2175
+ previewImages.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: GalleryField_default.thumbnails, children: [
2176
+ previewImages.map((img) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: GalleryField_default.thumbnail, children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("img", { src: img.url, alt: "" }) }, img.id)),
2177
+ remainingCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: GalleryField_default.more, children: [
2178
+ "+",
2179
+ remainingCount
2180
+ ] })
2181
+ ] }),
2182
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { className: GalleryField_default.actions, children: [
2183
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2184
+ "button",
2185
+ {
2186
+ type: "button",
2187
+ onClick: handleOpenModal,
2188
+ className: GalleryField_default.changeButton,
2189
+ children: "Change Gallery"
2190
+ }
2191
+ ),
2192
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2193
+ "button",
2194
+ {
2195
+ type: "button",
2196
+ onClick: handleRemove,
2197
+ className: GalleryField_default.removeButton,
2198
+ "aria-label": "Remove gallery",
2199
+ children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react12.X, { size: 16 })
2200
+ }
2201
+ )
2202
+ ] })
2203
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2204
+ "button",
2205
+ {
2206
+ type: "button",
2207
+ onClick: handleOpenModal,
2208
+ className: GalleryField_default.selectButton,
2209
+ children: [
2210
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_lucide_react12.Images, { size: 24 }),
2211
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { children: "Select gallery" })
2212
+ ]
2213
+ }
2214
+ ) }),
2215
+ isModalOpen && (0, import_react_dom2.createPortal)(
2216
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2217
+ GalleryPickerModal,
2218
+ {
2219
+ languages,
2220
+ galleryOptions,
2221
+ title: "Select Gallery",
2222
+ onSelect: handleSelect,
2223
+ onClose: () => setIsModalOpen(false)
2224
+ }
2225
+ ),
2226
+ document.body
2227
+ )
2228
+ ] });
2229
+ }
2230
+
2231
+ // src/components/DocumentField/DocumentField.tsx
2232
+ var import_react11 = require("react");
2233
+ var import_react_dom3 = require("react-dom");
2234
+ var import_core3 = require("@puckeditor/core");
2235
+ var import_lucide_react14 = require("lucide-react");
2236
+
2237
+ // src/components/DocumentPickerModal/DocumentPickerModal.tsx
2238
+ var import_react10 = require("react");
2239
+ var import_lucide_react13 = require("lucide-react");
2240
+
2241
+ // src/components/DocumentPickerModal/DocumentPickerModal.module.css
2242
+ var DocumentPickerModal_default = {
2243
+ backButton: "DocumentPickerModal_backButton",
2244
+ selectModeButton: "DocumentPickerModal_selectModeButton",
2245
+ toolbar: "DocumentPickerModal_toolbar",
2246
+ uploadSection: "DocumentPickerModal_uploadSection",
2247
+ documentList: "DocumentPickerModal_documentList",
2248
+ documentItemContainer: "DocumentPickerModal_documentItemContainer",
2249
+ documentItem: "DocumentPickerModal_documentItem",
2250
+ selected: "DocumentPickerModal_selected",
2251
+ checkbox: "DocumentPickerModal_checkbox",
2252
+ checkboxChecked: "DocumentPickerModal_checkboxChecked",
2253
+ documentIcon: "DocumentPickerModal_documentIcon",
2254
+ pdfIcon: "DocumentPickerModal_pdfIcon",
2255
+ fileIcon: "DocumentPickerModal_fileIcon",
2256
+ documentInfo: "DocumentPickerModal_documentInfo",
2257
+ documentName: "DocumentPickerModal_documentName",
2258
+ documentMeta: "DocumentPickerModal_documentMeta",
2259
+ checkmark: "DocumentPickerModal_checkmark",
2260
+ editButton: "DocumentPickerModal_editButton",
2261
+ footer: "DocumentPickerModal_footer",
2262
+ footerInfo: "DocumentPickerModal_footerInfo",
2263
+ footerIcon: "DocumentPickerModal_footerIcon",
2264
+ footerFilename: "DocumentPickerModal_footerFilename",
2265
+ footerMeta: "DocumentPickerModal_footerMeta",
2266
+ selectButton: "DocumentPickerModal_selectButton",
2267
+ editContent: "DocumentPickerModal_editContent",
2268
+ editPreview: "DocumentPickerModal_editPreview",
2269
+ editIcon: "DocumentPickerModal_editIcon",
2270
+ editInfo: "DocumentPickerModal_editInfo",
2271
+ editInfoRow: "DocumentPickerModal_editInfoRow",
2272
+ editInfoLabel: "DocumentPickerModal_editInfoLabel",
2273
+ editInfoValue: "DocumentPickerModal_editInfoValue",
2274
+ editField: "DocumentPickerModal_editField",
2275
+ editFieldHeader: "DocumentPickerModal_editFieldHeader",
2276
+ editFieldLabel: "DocumentPickerModal_editFieldLabel",
2277
+ langTabs: "DocumentPickerModal_langTabs",
2278
+ langTab: "DocumentPickerModal_langTab",
2279
+ langTabActive: "DocumentPickerModal_langTabActive",
2280
+ editInput: "DocumentPickerModal_editInput",
2281
+ editFooter: "DocumentPickerModal_editFooter",
2282
+ saveButton: "DocumentPickerModal_saveButton",
2283
+ spinner: "DocumentPickerModal_spinner",
2284
+ spin: "DocumentPickerModal_spin"
2285
+ };
2286
+
2287
+ // src/components/DocumentPickerModal/DocumentPickerModal.tsx
2288
+ var import_jsx_runtime13 = require("react/jsx-runtime");
2289
+ var DEFAULT_UPLOAD_CONFIG3 = {
2290
+ accept: ".pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.txt",
2291
+ maxSize: 20 * 1024 * 1024,
2292
+ multiple: true
2293
+ };
2294
+ var PAGE_SIZE3 = 20;
2295
+ function DocumentPickerModal({
2296
+ languages,
2297
+ documentOptions,
2298
+ title = "Select Document",
2299
+ selectedDocument,
2300
+ onSelect,
2301
+ onClose,
2302
+ selectable = true
2303
+ }) {
2304
+ const { fetchList, upload, update, delete: deleteDocument, uploadConfig } = documentOptions;
2305
+ const [view, setView] = (0, import_react10.useState)("picker");
2306
+ const [editingItem, setEditingItem] = (0, import_react10.useState)(null);
2307
+ const [selectMode, setSelectMode] = (0, import_react10.useState)(false);
2308
+ const [selectedForDelete, setSelectedForDelete] = (0, import_react10.useState)(/* @__PURE__ */ new Set());
2309
+ const [items, setItems] = (0, import_react10.useState)([]);
2310
+ const [search, setSearch] = (0, import_react10.useState)("");
2311
+ const [loading, setLoading] = (0, import_react10.useState)(true);
2312
+ const [page, setPage] = (0, import_react10.useState)(1);
2313
+ const [hasMore, setHasMore] = (0, import_react10.useState)(false);
2314
+ const [selectedItem, setSelectedItem] = (0, import_react10.useState)(null);
2315
+ const [titleValues, setTitleValues] = (0, import_react10.useState)({});
2316
+ const [activeLang, setActiveLang] = (0, import_react10.useState)(languages[0]?.code || "it");
2317
+ const [isSaving, setIsSaving] = (0, import_react10.useState)(false);
2318
+ const [showDeleteConfirm, setShowDeleteConfirm] = (0, import_react10.useState)(false);
2319
+ const [isDeleting, setIsDeleting] = (0, import_react10.useState)(false);
2320
+ const canUpload = !!upload;
2321
+ const {
2322
+ uploading,
2323
+ isUploading,
2324
+ addFiles,
2325
+ cancelUpload,
2326
+ clearCompleted,
2327
+ uploadConfig: mergedUploadConfig
2328
+ } = useUpload({
2329
+ upload: upload || (async () => {
2330
+ throw new Error("Upload not configured");
2331
+ }),
2332
+ config: uploadConfig || DEFAULT_UPLOAD_CONFIG3,
2333
+ onUploadComplete: (newItem) => {
2334
+ setItems((prev) => [newItem, ...prev]);
2335
+ }
2336
+ });
2337
+ const loadItems = (0, import_react10.useCallback)(
2338
+ async (searchQuery, pageNum, append = false) => {
2339
+ setLoading(true);
2340
+ try {
2341
+ const result = await fetchList({
2342
+ query: searchQuery || void 0,
2343
+ page: pageNum,
2344
+ pageSize: PAGE_SIZE3
2345
+ });
2346
+ const newItems = Array.isArray(result) ? result : result.items;
2347
+ const more = Array.isArray(result) ? newItems.length === PAGE_SIZE3 : result.hasMore ?? false;
2348
+ setItems((prev) => append ? [...prev, ...newItems] : newItems);
2349
+ setHasMore(more);
2350
+ } catch (error) {
2351
+ console.error("Failed to fetch documents:", error);
2352
+ setItems([]);
2353
+ setHasMore(false);
2354
+ } finally {
2355
+ setLoading(false);
2356
+ }
2357
+ },
2358
+ [fetchList]
2359
+ );
2360
+ (0, import_react10.useEffect)(() => {
2361
+ const timer = setTimeout(() => {
2362
+ setPage(1);
2363
+ loadItems(search, 1);
2364
+ }, 300);
2365
+ return () => clearTimeout(timer);
2366
+ }, [search, loadItems]);
2367
+ (0, import_react10.useEffect)(() => {
2368
+ if (selectedDocument) {
2369
+ const existingItem = items.find((item) => item.id === selectedDocument.id);
2370
+ if (existingItem) {
2371
+ setSelectedItem(existingItem);
2372
+ }
2373
+ }
2374
+ }, [selectedDocument, items]);
2375
+ const handleClose = (0, import_react10.useCallback)(() => {
2376
+ onClose();
2377
+ }, [onClose]);
2378
+ const handleLoadMore = () => {
2379
+ const nextPage = page + 1;
2380
+ setPage(nextPage);
2381
+ loadItems(search, nextPage, true);
2382
+ };
2383
+ const handleDocumentClick = (item) => {
2384
+ if (selectMode) {
2385
+ setSelectedForDelete((prev) => {
2386
+ const newSet = new Set(prev);
2387
+ if (newSet.has(item.id)) {
2388
+ newSet.delete(item.id);
2389
+ } else {
2390
+ newSet.add(item.id);
2391
+ }
2392
+ return newSet;
2393
+ });
2394
+ } else {
2395
+ if (selectedItem?.id === item.id) {
2396
+ setSelectedItem(null);
2397
+ } else {
2398
+ setSelectedItem(item);
2399
+ }
2400
+ }
2401
+ };
2402
+ const handleConfirmSelection = () => {
2403
+ if (!selectedItem || !onSelect) return;
2404
+ onSelect(selectedItem);
2405
+ };
2406
+ const handleEditTitle = (item) => {
2407
+ setEditingItem(item);
2408
+ setTitleValues(item.title || {});
2409
+ setActiveLang(languages[0]?.code || "it");
2410
+ setView("edit");
2411
+ };
2412
+ const handleTitleChange = (langCode, value) => {
2413
+ setTitleValues((prev) => ({
2414
+ ...prev,
2415
+ [langCode]: value
2416
+ }));
2417
+ };
2418
+ const handleSaveTitle = async () => {
2419
+ if (!editingItem || !update) return;
2420
+ setIsSaving(true);
2421
+ try {
2422
+ await update(editingItem.id, { title: titleValues });
2423
+ setItems(
2424
+ (prev) => prev.map(
2425
+ (item) => item.id === editingItem.id ? { ...item, title: titleValues } : item
2426
+ )
2427
+ );
2428
+ if (selectedItem?.id === editingItem.id) {
2429
+ setSelectedItem((prev) => prev ? { ...prev, title: titleValues } : null);
2430
+ }
2431
+ setView("picker");
2432
+ setEditingItem(null);
2433
+ setTitleValues({});
2434
+ } catch (error) {
2435
+ console.error("Failed to update title:", error);
2436
+ } finally {
2437
+ setIsSaving(false);
2438
+ }
2439
+ };
2440
+ const handleSelectAll = () => {
2441
+ if (selectedForDelete.size === items.length) {
2442
+ setSelectedForDelete(/* @__PURE__ */ new Set());
2443
+ } else {
2444
+ setSelectedForDelete(new Set(items.map((item) => item.id)));
2445
+ }
2446
+ };
2447
+ const handleConfirmDelete = async () => {
2448
+ if (!deleteDocument || selectedForDelete.size === 0) return;
2449
+ setIsDeleting(true);
2450
+ try {
2451
+ const deletePromises = Array.from(selectedForDelete).map((id) => deleteDocument(id));
2452
+ await Promise.all(deletePromises);
2453
+ setItems((prev) => prev.filter((item) => !selectedForDelete.has(item.id)));
2454
+ if (selectedItem && selectedForDelete.has(selectedItem.id)) {
2455
+ setSelectedItem(null);
2456
+ }
2457
+ setShowDeleteConfirm(false);
2458
+ setSelectedForDelete(/* @__PURE__ */ new Set());
2459
+ setSelectMode(false);
2460
+ } catch (error) {
2461
+ console.error("Failed to delete documents:", error);
2462
+ } finally {
2463
+ setIsDeleting(false);
2464
+ }
2465
+ };
2466
+ const getIcon = (mimeType) => {
2467
+ if (mimeType === "application/pdf") {
2468
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react13.FileText, { size: 20, className: DocumentPickerModal_default.pdfIcon });
2469
+ }
2470
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react13.File, { size: 20, className: DocumentPickerModal_default.fileIcon });
2471
+ };
2472
+ const isAllSelected = items.length > 0 && selectedForDelete.size === items.length;
2473
+ const isSomeSelected = selectedForDelete.size > 0 && selectedForDelete.size < items.length;
2474
+ if (view === "edit" && editingItem) {
2475
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2476
+ Modal,
2477
+ {
2478
+ title: "Edit Document Details",
2479
+ onClose: handleClose,
2480
+ size: "small",
2481
+ headerLeft: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2482
+ "button",
2483
+ {
2484
+ type: "button",
2485
+ onClick: () => {
2486
+ setView("picker");
2487
+ setEditingItem(null);
2488
+ setTitleValues({});
2489
+ },
2490
+ className: DocumentPickerModal_default.backButton,
2491
+ "aria-label": "Back to list",
2492
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react13.ArrowLeft, { size: 20 })
2493
+ }
2494
+ ),
2495
+ footer: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.editFooter, children: [
2496
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", {}),
2497
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2498
+ "button",
2499
+ {
2500
+ type: "button",
2501
+ onClick: handleSaveTitle,
2502
+ className: DocumentPickerModal_default.saveButton,
2503
+ disabled: isSaving || !update,
2504
+ children: isSaving ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
2505
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react13.Loader2, { size: 16, className: DocumentPickerModal_default.spinner }),
2506
+ "Saving..."
2507
+ ] }) : "Save"
2508
+ }
2509
+ )
2510
+ ] }),
2511
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.editContent, children: [
2512
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: DocumentPickerModal_default.editPreview, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: DocumentPickerModal_default.editIcon, children: getIcon(editingItem.mimeType) }) }),
2513
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.editInfo, children: [
2514
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.editInfoRow, children: [
2515
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: DocumentPickerModal_default.editInfoLabel, children: "Filename" }),
2516
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: DocumentPickerModal_default.editInfoValue, children: editingItem.filename })
2517
+ ] }),
2518
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.editInfoRow, children: [
2519
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: DocumentPickerModal_default.editInfoLabel, children: "Type" }),
2520
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: DocumentPickerModal_default.editInfoValue, children: editingItem.extension?.toUpperCase() })
2521
+ ] }),
2522
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.editInfoRow, children: [
2523
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: DocumentPickerModal_default.editInfoLabel, children: "Size" }),
2524
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: DocumentPickerModal_default.editInfoValue, children: formatFileSize(editingItem.size) })
2525
+ ] })
2526
+ ] }),
2527
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.editField, children: [
2528
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.editFieldHeader, children: [
2529
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("label", { className: DocumentPickerModal_default.editFieldLabel, children: "Title" }),
2530
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: DocumentPickerModal_default.langTabs, children: languages.map((lang) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2531
+ "button",
2532
+ {
2533
+ type: "button",
2534
+ onClick: () => setActiveLang(lang.code),
2535
+ className: `${DocumentPickerModal_default.langTab} ${activeLang === lang.code ? DocumentPickerModal_default.langTabActive : ""}`,
2536
+ children: lang.code.toUpperCase()
2537
+ },
2538
+ lang.code
2539
+ )) })
2540
+ ] }),
2541
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2542
+ "input",
2543
+ {
2544
+ type: "text",
2545
+ value: titleValues[activeLang] || "",
2546
+ onChange: (e) => handleTitleChange(activeLang, e.target.value),
2547
+ placeholder: `Title in ${languages.find((l) => l.code === activeLang)?.label || activeLang}...`,
2548
+ className: DocumentPickerModal_default.editInput
2549
+ }
2550
+ )
2551
+ ] })
2552
+ ] })
2553
+ }
2554
+ );
2555
+ }
2556
+ const renderFooter = () => {
2557
+ if (selectMode) {
2558
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2559
+ SelectionToolbar,
2560
+ {
2561
+ selectedCount: selectedForDelete.size,
2562
+ totalCount: items.length,
2563
+ onSelectAll: handleSelectAll,
2564
+ onCancel: () => {
2565
+ setSelectMode(false);
2566
+ setSelectedForDelete(/* @__PURE__ */ new Set());
2567
+ },
2568
+ onDelete: () => setShowDeleteConfirm(true),
2569
+ isAllSelected,
2570
+ isIndeterminate: isSomeSelected
2571
+ }
2572
+ );
2573
+ }
2574
+ if (selectedItem && selectable) {
2575
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.footer, children: [
2576
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.footerInfo, children: [
2577
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: DocumentPickerModal_default.footerIcon, children: getIcon(selectedItem.mimeType) }),
2578
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: DocumentPickerModal_default.footerFilename, children: selectedItem.filename }),
2579
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: DocumentPickerModal_default.footerMeta, children: [
2580
+ selectedItem.extension?.toUpperCase(),
2581
+ " - ",
2582
+ formatFileSize(selectedItem.size)
2583
+ ] })
2584
+ ] }),
2585
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2586
+ "button",
2587
+ {
2588
+ type: "button",
2589
+ onClick: handleConfirmSelection,
2590
+ className: DocumentPickerModal_default.selectButton,
2591
+ children: "Select Document"
2592
+ }
2593
+ )
2594
+ ] });
2595
+ }
2596
+ return void 0;
2597
+ };
2598
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2599
+ Modal,
2600
+ {
2601
+ title,
2602
+ onClose: handleClose,
2603
+ size: "small",
2604
+ headerActions: !selectMode && deleteDocument ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2605
+ "button",
2606
+ {
2607
+ type: "button",
2608
+ onClick: () => setSelectMode(true),
2609
+ className: DocumentPickerModal_default.selectModeButton,
2610
+ children: "Select Items"
2611
+ }
2612
+ ) : void 0,
2613
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: DocumentPickerModal_default.toolbar, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2614
+ SearchBar,
2615
+ {
2616
+ value: search,
2617
+ onChange: setSearch,
2618
+ placeholder: "Search documents...",
2619
+ autoFocus: !selectMode
2620
+ }
2621
+ ) }),
2622
+ footer: renderFooter(),
2623
+ overlay: showDeleteConfirm ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2624
+ ConfirmDialog,
2625
+ {
2626
+ title: "Delete Documents",
2627
+ message: `Are you sure you want to delete ${selectedForDelete.size} document${selectedForDelete.size > 1 ? "s" : ""}? This action cannot be undone.`,
2628
+ confirmLabel: isDeleting ? "Deleting..." : `Delete ${selectedForDelete.size} document${selectedForDelete.size > 1 ? "s" : ""}`,
2629
+ onConfirm: handleConfirmDelete,
2630
+ onCancel: () => setShowDeleteConfirm(false),
2631
+ loading: isDeleting,
2632
+ variant: "danger"
2633
+ }
2634
+ ) : void 0,
2635
+ loading: loading && items.length === 0,
2636
+ empty: !loading && items.length === 0,
2637
+ emptyMessage: "No documents found",
2638
+ children: [
2639
+ canUpload && !selectMode && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.uploadSection, children: [
2640
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2641
+ UploadDropzone,
2642
+ {
2643
+ onFilesSelected: addFiles,
2644
+ config: mergedUploadConfig,
2645
+ disabled: isUploading && uploading.length >= 10
2646
+ }
2647
+ ),
2648
+ uploading.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2649
+ UploadQueue,
2650
+ {
2651
+ files: uploading,
2652
+ onCancel: cancelUpload,
2653
+ onClearCompleted: clearCompleted
2654
+ }
2655
+ )
2656
+ ] }),
2657
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: DocumentPickerModal_default.documentList, children: items.map((item) => {
2658
+ const isSelected = selectMode ? selectedForDelete.has(item.id) : selectedItem?.id === item.id;
2659
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.documentItemContainer, children: [
2660
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2661
+ "button",
2662
+ {
2663
+ type: "button",
2664
+ onClick: () => handleDocumentClick(item),
2665
+ className: `${DocumentPickerModal_default.documentItem} ${isSelected ? DocumentPickerModal_default.selected : ""}`,
2666
+ children: [
2667
+ selectMode && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: `${DocumentPickerModal_default.checkbox} ${isSelected ? DocumentPickerModal_default.checkboxChecked : ""}`, children: isSelected && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react13.Check, { size: 14, strokeWidth: 3 }) }),
2668
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: DocumentPickerModal_default.documentIcon, children: getIcon(item.mimeType) }),
2669
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: DocumentPickerModal_default.documentInfo, children: [
2670
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: DocumentPickerModal_default.documentName, children: item.title?.[languages[0]?.code] || item.filename }),
2671
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("span", { className: DocumentPickerModal_default.documentMeta, children: [
2672
+ item.extension?.toUpperCase(),
2673
+ " - ",
2674
+ formatFileSize(item.size)
2675
+ ] })
2676
+ ] }),
2677
+ !selectMode && selectedItem?.id === item.id && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: DocumentPickerModal_default.checkmark, children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2678
+ "svg",
2679
+ {
2680
+ width: "16",
2681
+ height: "16",
2682
+ viewBox: "0 0 16 16",
2683
+ fill: "none",
2684
+ xmlns: "http://www.w3.org/2000/svg",
2685
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2686
+ "path",
2687
+ {
2688
+ d: "M13.5 4.5L6 12L2.5 8.5",
2689
+ stroke: "currentColor",
2690
+ strokeWidth: "2",
2691
+ strokeLinecap: "round",
2692
+ strokeLinejoin: "round"
2693
+ }
2694
+ )
2695
+ }
2696
+ ) })
2697
+ ]
2698
+ }
2699
+ ),
2700
+ !selectMode && update && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2701
+ "button",
2702
+ {
2703
+ type: "button",
2704
+ onClick: (e) => {
2705
+ e.stopPropagation();
2706
+ handleEditTitle(item);
2707
+ },
2708
+ className: DocumentPickerModal_default.editButton,
2709
+ "aria-label": "Edit title",
2710
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react13.Pencil, { size: 14 })
2711
+ }
2712
+ )
2713
+ ] }, item.id);
2714
+ }) }),
2715
+ hasMore && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LoadMoreButton, { onClick: handleLoadMore, loading })
2716
+ ]
2717
+ }
2718
+ );
2719
+ }
2720
+
2721
+ // src/components/DocumentField/DocumentField.module.css
2722
+ var DocumentField_default = {
2723
+ container: "DocumentField_container",
2724
+ preview: "DocumentField_preview",
2725
+ iconWrapper: "DocumentField_iconWrapper",
2726
+ pdfIcon: "DocumentField_pdfIcon",
2727
+ fileIcon: "DocumentField_fileIcon",
2728
+ info: "DocumentField_info",
2729
+ title: "DocumentField_title",
2730
+ meta: "DocumentField_meta",
2731
+ actions: "DocumentField_actions",
2732
+ changeButton: "DocumentField_changeButton",
2733
+ removeButton: "DocumentField_removeButton",
2734
+ selectButton: "DocumentField_selectButton"
2735
+ };
2736
+
2737
+ // src/components/DocumentField/DocumentField.tsx
2738
+ var import_jsx_runtime14 = require("react/jsx-runtime");
2739
+ function DocumentField({
2740
+ value,
2741
+ onChange,
2742
+ field,
2743
+ languages,
2744
+ documentOptions
2745
+ }) {
2746
+ const [isModalOpen, setIsModalOpen] = (0, import_react11.useState)(false);
2747
+ const handleSelect = (item) => {
2748
+ onChange(item);
2749
+ setIsModalOpen(false);
2750
+ };
2751
+ const handleRemove = (e) => {
2752
+ e.stopPropagation();
2753
+ onChange(null);
2754
+ };
2755
+ const handleOpenModal = () => {
2756
+ setIsModalOpen(true);
2757
+ };
2758
+ const getTitleDisplay = () => {
2759
+ if (value?.title) {
2760
+ for (const lang of languages) {
2761
+ if (value.title[lang.code]) {
2762
+ return value.title[lang.code];
2763
+ }
2764
+ }
2765
+ }
2766
+ return value?.filename || "";
2767
+ };
2768
+ const getIcon = () => {
2769
+ if (value?.mimeType === "application/pdf") {
2770
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react14.FileText, { size: 24, className: DocumentField_default.pdfIcon });
2771
+ }
2772
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react14.File, { size: 24, className: DocumentField_default.fileIcon });
2773
+ };
2774
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_core3.FieldLabel, { label: field.label || "Document", children: [
2775
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: DocumentField_default.container, children: value ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: DocumentField_default.preview, children: [
2776
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { className: DocumentField_default.iconWrapper, children: getIcon() }),
2777
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: DocumentField_default.info, children: [
2778
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { className: DocumentField_default.title, children: getTitleDisplay() }),
2779
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("span", { className: DocumentField_default.meta, children: [
2780
+ value.extension?.toUpperCase(),
2781
+ " \u2022 ",
2782
+ formatFileSize(value.size)
2783
+ ] })
2784
+ ] }),
2785
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: DocumentField_default.actions, children: [
2786
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2787
+ "button",
2788
+ {
2789
+ type: "button",
2790
+ onClick: handleOpenModal,
2791
+ className: DocumentField_default.changeButton,
2792
+ children: "Change"
2793
+ }
2794
+ ),
2795
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2796
+ "button",
2797
+ {
2798
+ type: "button",
2799
+ onClick: handleRemove,
2800
+ className: DocumentField_default.removeButton,
2801
+ "aria-label": "Remove document",
2802
+ children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react14.X, { size: 16 })
2803
+ }
2804
+ )
2805
+ ] })
2806
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
2807
+ "button",
2808
+ {
2809
+ type: "button",
2810
+ onClick: handleOpenModal,
2811
+ className: DocumentField_default.selectButton,
2812
+ children: [
2813
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_lucide_react14.FileText, { size: 24 }),
2814
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("span", { children: "Select document" })
2815
+ ]
2816
+ }
2817
+ ) }),
2818
+ isModalOpen && (0, import_react_dom3.createPortal)(
2819
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2820
+ DocumentPickerModal,
2821
+ {
2822
+ languages,
2823
+ documentOptions,
2824
+ title: "Select Document",
2825
+ onSelect: handleSelect,
2826
+ onClose: () => setIsModalOpen(false)
2827
+ }
2828
+ ),
2829
+ document.body
2830
+ )
2831
+ ] });
2832
+ }
2833
+
2834
+ // src/components/MediaPanel/MediaPanel.tsx
2835
+ var import_react12 = require("react");
2836
+ var import_react_dom4 = require("react-dom");
2837
+ var import_lucide_react15 = require("lucide-react");
2838
+
2839
+ // src/components/MediaPanel/MediaPanel.module.css
2840
+ var MediaPanel_default = {
2841
+ panel: "MediaPanel_panel",
2842
+ item: "MediaPanel_item"
2843
+ };
2844
+
2845
+ // src/components/MediaPanel/MediaPanel.tsx
2846
+ var import_jsx_runtime15 = require("react/jsx-runtime");
2847
+ function MediaPanel({
2848
+ languages,
2849
+ imageOptions,
2850
+ galleryOptions,
2851
+ documentOptions
2852
+ }) {
2853
+ const [openModal, setOpenModal] = (0, import_react12.useState)(null);
2854
+ const handleCloseModal = () => {
2855
+ setOpenModal(null);
2856
+ };
2857
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: MediaPanel_default.panel, children: [
2858
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2859
+ "button",
2860
+ {
2861
+ type: "button",
2862
+ className: MediaPanel_default.item,
2863
+ onClick: () => setOpenModal("image"),
2864
+ children: [
2865
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react15.Image, { size: 20 }),
2866
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Images" })
2867
+ ]
2868
+ }
2869
+ ),
2870
+ galleryOptions && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2871
+ "button",
2872
+ {
2873
+ type: "button",
2874
+ className: MediaPanel_default.item,
2875
+ onClick: () => setOpenModal("gallery"),
2876
+ children: [
2877
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react15.Images, { size: 20 }),
2878
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Gallery" })
2879
+ ]
2880
+ }
2881
+ ),
2882
+ documentOptions && /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
2883
+ "button",
2884
+ {
2885
+ type: "button",
2886
+ className: MediaPanel_default.item,
2887
+ onClick: () => setOpenModal("document"),
2888
+ children: [
2889
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_lucide_react15.FileText, { size: 20 }),
2890
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("span", { children: "Documents" })
2891
+ ]
2892
+ }
2893
+ ),
2894
+ openModal === "image" && (0, import_react_dom4.createPortal)(
2895
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2896
+ ImagePickerModal,
2897
+ {
2898
+ languages,
2899
+ imageOptions,
2900
+ title: "Media Library",
2901
+ selectable: false,
2902
+ onClose: handleCloseModal
2903
+ }
2904
+ ),
2905
+ document.body
2906
+ ),
2907
+ openModal === "gallery" && galleryOptions && (0, import_react_dom4.createPortal)(
2908
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2909
+ GalleryPickerModal,
2910
+ {
2911
+ languages,
2912
+ galleryOptions,
2913
+ title: "Gallery Library",
2914
+ selectable: false,
2915
+ onClose: handleCloseModal
2916
+ }
2917
+ ),
2918
+ document.body
2919
+ ),
2920
+ openModal === "document" && documentOptions && (0, import_react_dom4.createPortal)(
2921
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2922
+ DocumentPickerModal,
2923
+ {
2924
+ languages,
2925
+ documentOptions,
2926
+ title: "Document Library",
2927
+ selectable: false,
2928
+ onClose: handleCloseModal
2929
+ }
2930
+ ),
2931
+ document.body
2932
+ )
2933
+ ] });
2934
+ }
2935
+
2936
+ // src/createMediaPlugin.tsx
2937
+ var import_jsx_runtime16 = require("react/jsx-runtime");
2938
+ function createMediaPlugin(options) {
2939
+ const {
2940
+ languages = [
2941
+ { code: "en", label: "English" },
2942
+ { code: "it", label: "Italiano" }
2943
+ ],
2944
+ image,
2945
+ gallery,
2946
+ document: document2
2947
+ } = options;
2948
+ const fieldTypes = {
2949
+ // Image field type (always available)
2950
+ image: (props) => {
2951
+ const fieldProps = props;
2952
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2953
+ ImageField,
2954
+ {
2955
+ ...fieldProps,
2956
+ languages,
2957
+ imageOptions: image
2958
+ }
2959
+ );
2960
+ }
2961
+ };
2962
+ if (gallery) {
2963
+ fieldTypes.gallery = (props) => {
2964
+ const fieldProps = props;
2965
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2966
+ GalleryField,
2967
+ {
2968
+ ...fieldProps,
2969
+ languages,
2970
+ galleryOptions: gallery
2971
+ }
2972
+ );
2973
+ };
2974
+ }
2975
+ if (document2) {
2976
+ fieldTypes.document = (props) => {
2977
+ const fieldProps = props;
2978
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2979
+ DocumentField,
2980
+ {
2981
+ ...fieldProps,
2982
+ languages,
2983
+ documentOptions: document2
2984
+ }
2985
+ );
2986
+ };
2987
+ }
2988
+ return {
2989
+ name: "puck-media",
2990
+ label: "Media",
2991
+ icon: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_lucide_react16.Image, { size: 20 }),
2992
+ render: () => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
2993
+ MediaPanel,
2994
+ {
2995
+ languages,
2996
+ imageOptions: image,
2997
+ galleryOptions: gallery,
2998
+ documentOptions: document2
2999
+ }
3000
+ ),
3001
+ overrides: {
3002
+ fieldTypes
3003
+ }
3004
+ };
3005
+ }
3006
+
3007
+ // src/types.ts
3008
+ var DEFAULT_LANGUAGES = [
3009
+ { code: "en", label: "English" },
3010
+ { code: "it", label: "Italiano" }
3011
+ ];
3012
+ // Annotate the CommonJS export names for ESM import in node:
3013
+ 0 && (module.exports = {
3014
+ DEFAULT_LANGUAGES,
3015
+ DocumentField,
3016
+ DocumentPickerModal,
3017
+ GalleryField,
3018
+ GalleryPickerModal,
3019
+ ImageField,
3020
+ ImageGrid,
3021
+ ImagePickerModal,
3022
+ MediaPanel,
3023
+ UploadDropzone,
3024
+ UploadQueue,
3025
+ createMediaPlugin,
3026
+ formatFileSize,
3027
+ useUpload
3028
+ });
3029
+ //# sourceMappingURL=index.js.map