@gallop.software/studio 0.1.7 → 0.1.9
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/{StudioUI-ZAD65UPD.js → StudioUI-QG2NJQTM.js} +468 -241
- package/dist/StudioUI-QG2NJQTM.js.map +1 -0
- package/dist/{StudioUI-2CBIV4Q5.mjs → StudioUI-RS5UCUIN.mjs} +633 -406
- package/dist/StudioUI-RS5UCUIN.mjs.map +1 -0
- package/dist/index.js +14 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +14 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/StudioUI-2CBIV4Q5.mjs.map +0 -1
- package/dist/StudioUI-ZAD65UPD.js.map +0 -1
|
@@ -50,8 +50,147 @@ function useStudio() {
|
|
|
50
50
|
// src/components/StudioToolbar.tsx
|
|
51
51
|
|
|
52
52
|
|
|
53
|
+
|
|
54
|
+
// src/components/StudioModal.tsx
|
|
55
|
+
|
|
53
56
|
var _jsxruntime = require('@emotion/react/jsx-runtime');
|
|
57
|
+
var fadeIn = _react3.keyframes`
|
|
58
|
+
from { opacity: 0; }
|
|
59
|
+
to { opacity: 1; }
|
|
60
|
+
`;
|
|
61
|
+
var slideIn = _react3.keyframes`
|
|
62
|
+
from {
|
|
63
|
+
opacity: 0;
|
|
64
|
+
transform: scale(0.95);
|
|
65
|
+
}
|
|
66
|
+
to {
|
|
67
|
+
opacity: 1;
|
|
68
|
+
transform: scale(1);
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
54
71
|
var styles = {
|
|
72
|
+
overlay: _react3.css`
|
|
73
|
+
position: fixed;
|
|
74
|
+
inset: 0;
|
|
75
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
76
|
+
display: flex;
|
|
77
|
+
align-items: center;
|
|
78
|
+
justify-content: center;
|
|
79
|
+
z-index: 10000;
|
|
80
|
+
animation: ${fadeIn} 0.15s ease-out;
|
|
81
|
+
`,
|
|
82
|
+
modal: _react3.css`
|
|
83
|
+
background-color: white;
|
|
84
|
+
border-radius: 12px;
|
|
85
|
+
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
86
|
+
max-width: 400px;
|
|
87
|
+
width: 90%;
|
|
88
|
+
animation: ${slideIn} 0.15s ease-out;
|
|
89
|
+
`,
|
|
90
|
+
header: _react3.css`
|
|
91
|
+
padding: 20px 24px 0;
|
|
92
|
+
`,
|
|
93
|
+
title: _react3.css`
|
|
94
|
+
font-size: 18px;
|
|
95
|
+
font-weight: 600;
|
|
96
|
+
color: #111827;
|
|
97
|
+
margin: 0;
|
|
98
|
+
`,
|
|
99
|
+
body: _react3.css`
|
|
100
|
+
padding: 12px 24px 24px;
|
|
101
|
+
`,
|
|
102
|
+
message: _react3.css`
|
|
103
|
+
font-size: 14px;
|
|
104
|
+
color: #6b7280;
|
|
105
|
+
margin: 0;
|
|
106
|
+
line-height: 1.5;
|
|
107
|
+
`,
|
|
108
|
+
footer: _react3.css`
|
|
109
|
+
display: flex;
|
|
110
|
+
justify-content: flex-end;
|
|
111
|
+
gap: 12px;
|
|
112
|
+
padding: 16px 24px;
|
|
113
|
+
border-top: 1px solid #e5e7eb;
|
|
114
|
+
background-color: #f9fafb;
|
|
115
|
+
border-radius: 0 0 12px 12px;
|
|
116
|
+
`,
|
|
117
|
+
btn: _react3.css`
|
|
118
|
+
padding: 8px 16px;
|
|
119
|
+
font-size: 14px;
|
|
120
|
+
font-weight: 500;
|
|
121
|
+
border-radius: 8px;
|
|
122
|
+
cursor: pointer;
|
|
123
|
+
transition: all 0.15s;
|
|
124
|
+
`,
|
|
125
|
+
btnCancel: _react3.css`
|
|
126
|
+
background-color: white;
|
|
127
|
+
border: 1px solid #d1d5db;
|
|
128
|
+
color: #374151;
|
|
129
|
+
|
|
130
|
+
&:hover {
|
|
131
|
+
background-color: #f9fafb;
|
|
132
|
+
}
|
|
133
|
+
`,
|
|
134
|
+
btnConfirm: _react3.css`
|
|
135
|
+
background-color: #9333ea;
|
|
136
|
+
border: 1px solid #9333ea;
|
|
137
|
+
color: white;
|
|
138
|
+
|
|
139
|
+
&:hover {
|
|
140
|
+
background-color: #7c3aed;
|
|
141
|
+
}
|
|
142
|
+
`,
|
|
143
|
+
btnDanger: _react3.css`
|
|
144
|
+
background-color: #dc2626;
|
|
145
|
+
border: 1px solid #dc2626;
|
|
146
|
+
color: white;
|
|
147
|
+
|
|
148
|
+
&:hover {
|
|
149
|
+
background-color: #b91c1c;
|
|
150
|
+
}
|
|
151
|
+
`
|
|
152
|
+
};
|
|
153
|
+
function ConfirmModal({
|
|
154
|
+
title,
|
|
155
|
+
message,
|
|
156
|
+
confirmLabel = "Confirm",
|
|
157
|
+
cancelLabel = "Cancel",
|
|
158
|
+
variant = "default",
|
|
159
|
+
onConfirm,
|
|
160
|
+
onCancel
|
|
161
|
+
}) {
|
|
162
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles.overlay, onClick: onCancel, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles.modal, onClick: (e) => e.stopPropagation(), children: [
|
|
163
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles.header, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles.title, children: title }) }),
|
|
164
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles.body, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles.message, children: message }) }),
|
|
165
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles.footer, children: [
|
|
166
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: [styles.btn, styles.btnCancel], onClick: onCancel, children: cancelLabel }),
|
|
167
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
168
|
+
"button",
|
|
169
|
+
{
|
|
170
|
+
css: [styles.btn, variant === "danger" ? styles.btnDanger : styles.btnConfirm],
|
|
171
|
+
onClick: onConfirm,
|
|
172
|
+
children: confirmLabel
|
|
173
|
+
}
|
|
174
|
+
)
|
|
175
|
+
] })
|
|
176
|
+
] }) });
|
|
177
|
+
}
|
|
178
|
+
function AlertModal({
|
|
179
|
+
title,
|
|
180
|
+
message,
|
|
181
|
+
buttonLabel = "OK",
|
|
182
|
+
onClose
|
|
183
|
+
}) {
|
|
184
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles.overlay, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles.modal, onClick: (e) => e.stopPropagation(), children: [
|
|
185
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles.header, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles.title, children: title }) }),
|
|
186
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles.body, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles.message, children: message }) }),
|
|
187
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles.footer, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: [styles.btn, styles.btnConfirm], onClick: onClose, children: buttonLabel }) })
|
|
188
|
+
] }) });
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/components/StudioToolbar.tsx
|
|
192
|
+
|
|
193
|
+
var styles2 = {
|
|
55
194
|
toolbar: _react3.css`
|
|
56
195
|
display: flex;
|
|
57
196
|
align-items: center;
|
|
@@ -151,6 +290,8 @@ function StudioToolbar() {
|
|
|
151
290
|
const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh } = useStudio();
|
|
152
291
|
const fileInputRef = _react.useRef.call(void 0, null);
|
|
153
292
|
const [uploading, setUploading] = _react.useState.call(void 0, false);
|
|
293
|
+
const [showDeleteConfirm, setShowDeleteConfirm] = _react.useState.call(void 0, false);
|
|
294
|
+
const [alertMessage, setAlertMessage] = _react.useState.call(void 0, null);
|
|
154
295
|
const handleUpload = _react.useCallback.call(void 0, () => {
|
|
155
296
|
_optionalChain([fileInputRef, 'access', _ => _.current, 'optionalAccess', _2 => _2.click, 'call', _3 => _3()]);
|
|
156
297
|
}, []);
|
|
@@ -170,13 +311,19 @@ function StudioToolbar() {
|
|
|
170
311
|
if (!response.ok) {
|
|
171
312
|
const error = await response.json();
|
|
172
313
|
console.error("Upload failed:", error);
|
|
173
|
-
|
|
314
|
+
setAlertMessage({
|
|
315
|
+
title: "Upload Failed",
|
|
316
|
+
message: `Failed to upload ${file.name}: ${error.error || "Unknown error"}`
|
|
317
|
+
});
|
|
174
318
|
}
|
|
175
319
|
}
|
|
176
320
|
triggerRefresh();
|
|
177
321
|
} catch (error) {
|
|
178
322
|
console.error("Upload error:", error);
|
|
179
|
-
|
|
323
|
+
setAlertMessage({
|
|
324
|
+
title: "Upload Failed",
|
|
325
|
+
message: "Upload failed. Check console for details."
|
|
326
|
+
});
|
|
180
327
|
} finally {
|
|
181
328
|
setUploading(false);
|
|
182
329
|
if (fileInputRef.current) {
|
|
@@ -187,9 +334,12 @@ function StudioToolbar() {
|
|
|
187
334
|
const handleReprocess = _react.useCallback.call(void 0, () => {
|
|
188
335
|
console.log("Reprocess clicked", selectedItems);
|
|
189
336
|
}, [selectedItems]);
|
|
190
|
-
const
|
|
337
|
+
const handleDeleteClick = _react.useCallback.call(void 0, () => {
|
|
191
338
|
if (selectedItems.size === 0) return;
|
|
192
|
-
|
|
339
|
+
setShowDeleteConfirm(true);
|
|
340
|
+
}, [selectedItems]);
|
|
341
|
+
const handleDeleteConfirm = _react.useCallback.call(void 0, async () => {
|
|
342
|
+
setShowDeleteConfirm(false);
|
|
193
343
|
try {
|
|
194
344
|
const response = await fetch("/api/studio/delete", {
|
|
195
345
|
method: "POST",
|
|
@@ -201,11 +351,17 @@ function StudioToolbar() {
|
|
|
201
351
|
triggerRefresh();
|
|
202
352
|
} else {
|
|
203
353
|
const error = await response.json();
|
|
204
|
-
|
|
354
|
+
setAlertMessage({
|
|
355
|
+
title: "Delete Failed",
|
|
356
|
+
message: error.error || "Unknown error"
|
|
357
|
+
});
|
|
205
358
|
}
|
|
206
359
|
} catch (error) {
|
|
207
360
|
console.error("Delete error:", error);
|
|
208
|
-
|
|
361
|
+
setAlertMessage({
|
|
362
|
+
title: "Delete Failed",
|
|
363
|
+
message: "Delete failed. Check console for details."
|
|
364
|
+
});
|
|
209
365
|
}
|
|
210
366
|
}, [selectedItems, clearSelection, triggerRefresh]);
|
|
211
367
|
const handleSyncCdn = _react.useCallback.call(void 0, () => {
|
|
@@ -215,83 +371,104 @@ function StudioToolbar() {
|
|
|
215
371
|
console.log("Scan clicked");
|
|
216
372
|
}, []);
|
|
217
373
|
const hasSelection = selectedItems.size > 0;
|
|
218
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
219
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
220
|
-
|
|
374
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
375
|
+
showDeleteConfirm && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
376
|
+
ConfirmModal,
|
|
221
377
|
{
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
378
|
+
title: "Delete Items",
|
|
379
|
+
message: `Are you sure you want to delete ${selectedItems.size} item(s)? This action cannot be undone.`,
|
|
380
|
+
confirmLabel: "Delete",
|
|
381
|
+
variant: "danger",
|
|
382
|
+
onConfirm: handleDeleteConfirm,
|
|
383
|
+
onCancel: () => setShowDeleteConfirm(false)
|
|
228
384
|
}
|
|
229
385
|
),
|
|
230
|
-
/* @__PURE__ */ _jsxruntime.
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
),
|
|
240
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
241
|
-
ToolbarButton,
|
|
242
|
-
{
|
|
243
|
-
onClick: handleReprocess,
|
|
244
|
-
icon: "refresh",
|
|
245
|
-
label: "Reprocess",
|
|
246
|
-
disabled: !hasSelection
|
|
247
|
-
}
|
|
248
|
-
),
|
|
249
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
250
|
-
ToolbarButton,
|
|
251
|
-
{
|
|
252
|
-
onClick: handleDelete,
|
|
253
|
-
icon: "trash",
|
|
254
|
-
label: "Delete",
|
|
255
|
-
disabled: !hasSelection,
|
|
256
|
-
variant: "danger"
|
|
257
|
-
}
|
|
258
|
-
),
|
|
386
|
+
alertMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
387
|
+
AlertModal,
|
|
388
|
+
{
|
|
389
|
+
title: alertMessage.title,
|
|
390
|
+
message: alertMessage.message,
|
|
391
|
+
onClose: () => setAlertMessage(null)
|
|
392
|
+
}
|
|
393
|
+
),
|
|
394
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.toolbar, children: [
|
|
259
395
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
260
|
-
|
|
396
|
+
"input",
|
|
261
397
|
{
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
398
|
+
ref: fileInputRef,
|
|
399
|
+
type: "file",
|
|
400
|
+
multiple: true,
|
|
401
|
+
accept: "image/*",
|
|
402
|
+
onChange: handleFileChange,
|
|
403
|
+
style: { display: "none" }
|
|
266
404
|
}
|
|
267
405
|
),
|
|
268
|
-
/* @__PURE__ */ _jsxruntime.
|
|
269
|
-
] }),
|
|
270
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles.right, children: [
|
|
271
|
-
hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles.selectionCount, children: [
|
|
272
|
-
selectedItems.size,
|
|
273
|
-
" selected",
|
|
274
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles.clearBtn, onClick: clearSelection, children: "Clear" })
|
|
275
|
-
] }),
|
|
276
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles.viewToggle, children: [
|
|
406
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.left, children: [
|
|
277
407
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
278
|
-
|
|
408
|
+
ToolbarButton,
|
|
279
409
|
{
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
410
|
+
onClick: handleUpload,
|
|
411
|
+
icon: "upload",
|
|
412
|
+
label: uploading ? "Uploading..." : "Upload",
|
|
413
|
+
disabled: uploading
|
|
284
414
|
}
|
|
285
415
|
),
|
|
286
416
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
287
|
-
|
|
417
|
+
ToolbarButton,
|
|
288
418
|
{
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
419
|
+
onClick: handleReprocess,
|
|
420
|
+
icon: "refresh",
|
|
421
|
+
label: "Reprocess",
|
|
422
|
+
disabled: !hasSelection
|
|
293
423
|
}
|
|
294
|
-
)
|
|
424
|
+
),
|
|
425
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
426
|
+
ToolbarButton,
|
|
427
|
+
{
|
|
428
|
+
onClick: handleDeleteClick,
|
|
429
|
+
icon: "trash",
|
|
430
|
+
label: "Delete",
|
|
431
|
+
disabled: !hasSelection,
|
|
432
|
+
variant: "danger"
|
|
433
|
+
}
|
|
434
|
+
),
|
|
435
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
436
|
+
ToolbarButton,
|
|
437
|
+
{
|
|
438
|
+
onClick: handleSyncCdn,
|
|
439
|
+
icon: "cloud",
|
|
440
|
+
label: "Sync CDN",
|
|
441
|
+
disabled: !hasSelection
|
|
442
|
+
}
|
|
443
|
+
),
|
|
444
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, ToolbarButton, { onClick: handleScan, icon: "scan", label: "Scan" })
|
|
445
|
+
] }),
|
|
446
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.right, children: [
|
|
447
|
+
hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles2.selectionCount, children: [
|
|
448
|
+
selectedItems.size,
|
|
449
|
+
" selected",
|
|
450
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles2.clearBtn, onClick: clearSelection, children: "Clear" })
|
|
451
|
+
] }),
|
|
452
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles2.viewToggle, children: [
|
|
453
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
454
|
+
"button",
|
|
455
|
+
{
|
|
456
|
+
css: [styles2.viewBtn, viewMode === "grid" && styles2.viewBtnActive],
|
|
457
|
+
onClick: () => setViewMode("grid"),
|
|
458
|
+
"aria-label": "Grid view",
|
|
459
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, GridIcon, {})
|
|
460
|
+
}
|
|
461
|
+
),
|
|
462
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
463
|
+
"button",
|
|
464
|
+
{
|
|
465
|
+
css: [styles2.viewBtn, viewMode === "list" && styles2.viewBtnActive],
|
|
466
|
+
onClick: () => setViewMode("list"),
|
|
467
|
+
"aria-label": "List view",
|
|
468
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListIcon, {})
|
|
469
|
+
}
|
|
470
|
+
)
|
|
471
|
+
] })
|
|
295
472
|
] })
|
|
296
473
|
] })
|
|
297
474
|
] });
|
|
@@ -306,7 +483,7 @@ function ToolbarButton({
|
|
|
306
483
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
307
484
|
"button",
|
|
308
485
|
{
|
|
309
|
-
css: [
|
|
486
|
+
css: [styles2.btn, variant === "danger" ? styles2.btnDanger : styles2.btnDefault],
|
|
310
487
|
onClick,
|
|
311
488
|
disabled,
|
|
312
489
|
children: [
|
|
@@ -319,30 +496,30 @@ function ToolbarButton({
|
|
|
319
496
|
function IconComponent({ icon }) {
|
|
320
497
|
switch (icon) {
|
|
321
498
|
case "upload":
|
|
322
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
499
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) });
|
|
323
500
|
case "refresh":
|
|
324
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
501
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) });
|
|
325
502
|
case "trash":
|
|
326
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
503
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) });
|
|
327
504
|
case "cloud":
|
|
328
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
505
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) });
|
|
329
506
|
case "scan":
|
|
330
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
507
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) });
|
|
331
508
|
default:
|
|
332
509
|
return null;
|
|
333
510
|
}
|
|
334
511
|
}
|
|
335
512
|
function GridIcon() {
|
|
336
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
513
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
|
|
337
514
|
}
|
|
338
515
|
function ListIcon() {
|
|
339
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
516
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
|
|
340
517
|
}
|
|
341
518
|
|
|
342
519
|
// src/components/StudioBreadcrumb.tsx
|
|
343
520
|
|
|
344
521
|
|
|
345
|
-
var
|
|
522
|
+
var styles3 = {
|
|
346
523
|
container: _react3.css`
|
|
347
524
|
display: flex;
|
|
348
525
|
align-items: center;
|
|
@@ -413,14 +590,14 @@ function StudioBreadcrumb() {
|
|
|
413
590
|
const newPath = parts.slice(0, index + 1).join("/");
|
|
414
591
|
setCurrentPath(newPath);
|
|
415
592
|
};
|
|
416
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
417
|
-
currentPath !== "public" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
418
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "nav", { css:
|
|
419
|
-
index > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
593
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.container, children: [
|
|
594
|
+
currentPath !== "public" && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles3.backBtn, onClick: navigateUp, "aria-label": "Go back", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.backIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) }),
|
|
595
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "nav", { css: styles3.nav, children: parts.map((part, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles3.item, children: [
|
|
596
|
+
index > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.separator, children: "/" }),
|
|
420
597
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
421
598
|
"button",
|
|
422
599
|
{
|
|
423
|
-
css: [
|
|
600
|
+
css: [styles3.btn, index === parts.length - 1 ? styles3.btnActive : styles3.btnInactive],
|
|
424
601
|
onClick: () => handleClick(index),
|
|
425
602
|
children: part
|
|
426
603
|
}
|
|
@@ -436,7 +613,7 @@ function StudioBreadcrumb() {
|
|
|
436
613
|
var spin = _react3.keyframes`
|
|
437
614
|
to { transform: rotate(360deg); }
|
|
438
615
|
`;
|
|
439
|
-
var
|
|
616
|
+
var styles4 = {
|
|
440
617
|
loading: _react3.css`
|
|
441
618
|
display: flex;
|
|
442
619
|
align-items: center;
|
|
@@ -494,6 +671,10 @@ var styles3 = {
|
|
|
494
671
|
itemSelected: _react3.css`
|
|
495
672
|
border-color: #a855f7;
|
|
496
673
|
background-color: #faf5ff;
|
|
674
|
+
|
|
675
|
+
&:hover {
|
|
676
|
+
border-color: #a855f7;
|
|
677
|
+
}
|
|
497
678
|
`,
|
|
498
679
|
checkbox: _react3.css`
|
|
499
680
|
position: absolute;
|
|
@@ -597,13 +778,13 @@ function StudioFileGrid() {
|
|
|
597
778
|
loadItems();
|
|
598
779
|
}, [currentPath, refreshKey]);
|
|
599
780
|
if (loading) {
|
|
600
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
781
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.spinner }) });
|
|
601
782
|
}
|
|
602
783
|
if (items.length === 0) {
|
|
603
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
604
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
605
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
606
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
784
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.empty, children: [
|
|
785
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
786
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.emptyText, children: "No files in this folder" }),
|
|
787
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.emptyText, children: "Upload images to get started" })
|
|
607
788
|
] });
|
|
608
789
|
}
|
|
609
790
|
const sortedItems = [...items].sort((a, b) => {
|
|
@@ -633,12 +814,12 @@ function StudioFileGrid() {
|
|
|
633
814
|
}
|
|
634
815
|
};
|
|
635
816
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
636
|
-
files.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
817
|
+
files.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.selectAllRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { css: styles4.selectAllLabel, children: [
|
|
637
818
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
638
819
|
"input",
|
|
639
820
|
{
|
|
640
821
|
type: "checkbox",
|
|
641
|
-
css:
|
|
822
|
+
css: styles4.selectAllCheckbox,
|
|
642
823
|
checked: allFilesSelected,
|
|
643
824
|
ref: (el) => {
|
|
644
825
|
if (el) el.indeterminate = someFilesSelected && !allFilesSelected;
|
|
@@ -650,7 +831,7 @@ function StudioFileGrid() {
|
|
|
650
831
|
files.length,
|
|
651
832
|
")"
|
|
652
833
|
] }) }),
|
|
653
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
834
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.grid, children: sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
654
835
|
GridItem,
|
|
655
836
|
{
|
|
656
837
|
item,
|
|
@@ -663,31 +844,31 @@ function StudioFileGrid() {
|
|
|
663
844
|
}
|
|
664
845
|
function GridItem({ item, isSelected, onClick }) {
|
|
665
846
|
const isFolder = item.type === "folder";
|
|
666
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: [
|
|
847
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: [styles4.item, isSelected && styles4.itemSelected], onClick, children: [
|
|
667
848
|
!isFolder && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
668
849
|
"input",
|
|
669
850
|
{
|
|
670
851
|
type: "checkbox",
|
|
671
|
-
css:
|
|
852
|
+
css: styles4.checkbox,
|
|
672
853
|
checked: isSelected,
|
|
673
854
|
onChange: () => {
|
|
674
855
|
},
|
|
675
856
|
onClick: (e) => e.stopPropagation()
|
|
676
857
|
}
|
|
677
858
|
),
|
|
678
|
-
item.cdnSynced && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
679
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
859
|
+
item.cdnSynced && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles4.cdnBadge, children: "CDN" }),
|
|
860
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.content, children: isFolder ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
680
861
|
"img",
|
|
681
862
|
{
|
|
682
|
-
css:
|
|
863
|
+
css: styles4.image,
|
|
683
864
|
src: item.path.replace("public", ""),
|
|
684
865
|
alt: item.name,
|
|
685
866
|
loading: "lazy"
|
|
686
867
|
}
|
|
687
868
|
) }),
|
|
688
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
689
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
690
|
-
item.size && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
869
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.label, children: [
|
|
870
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.name, title: item.name, children: item.name }),
|
|
871
|
+
item.size && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles4.size, children: formatFileSize(item.size) })
|
|
691
872
|
] })
|
|
692
873
|
] });
|
|
693
874
|
}
|
|
@@ -704,7 +885,7 @@ function formatFileSize(bytes) {
|
|
|
704
885
|
var spin2 = _react3.keyframes`
|
|
705
886
|
to { transform: rotate(360deg); }
|
|
706
887
|
`;
|
|
707
|
-
var
|
|
888
|
+
var styles5 = {
|
|
708
889
|
loading: _react3.css`
|
|
709
890
|
display: flex;
|
|
710
891
|
align-items: center;
|
|
@@ -765,6 +946,10 @@ var styles4 = {
|
|
|
765
946
|
`,
|
|
766
947
|
rowSelected: _react3.css`
|
|
767
948
|
background-color: #faf5ff;
|
|
949
|
+
|
|
950
|
+
&:hover {
|
|
951
|
+
background-color: #faf5ff;
|
|
952
|
+
}
|
|
768
953
|
`,
|
|
769
954
|
td: _react3.css`
|
|
770
955
|
padding: 8px 0;
|
|
@@ -835,10 +1020,10 @@ function StudioFileList() {
|
|
|
835
1020
|
loadItems();
|
|
836
1021
|
}, [currentPath, refreshKey]);
|
|
837
1022
|
if (loading) {
|
|
838
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
1023
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.spinner }) });
|
|
839
1024
|
}
|
|
840
1025
|
if (items.length === 0) {
|
|
841
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
1026
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.empty, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files in this folder" }) });
|
|
842
1027
|
}
|
|
843
1028
|
const sortedItems = [...items].sort((a, b) => {
|
|
844
1029
|
if (a.type === "folder" && b.type !== "folder") return -1;
|
|
@@ -866,13 +1051,13 @@ function StudioFileList() {
|
|
|
866
1051
|
toggleSelection(item.path);
|
|
867
1052
|
}
|
|
868
1053
|
};
|
|
869
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css:
|
|
1054
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles5.table, children: [
|
|
870
1055
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
|
|
871
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [
|
|
1056
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCheckbox], children: files.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
872
1057
|
"input",
|
|
873
1058
|
{
|
|
874
1059
|
type: "checkbox",
|
|
875
|
-
css:
|
|
1060
|
+
css: styles5.checkbox,
|
|
876
1061
|
checked: allFilesSelected,
|
|
877
1062
|
ref: (el) => {
|
|
878
1063
|
if (el) el.indeterminate = someFilesSelected && !allFilesSelected;
|
|
@@ -880,12 +1065,12 @@ function StudioFileList() {
|
|
|
880
1065
|
onChange: handleSelectAll
|
|
881
1066
|
}
|
|
882
1067
|
) }),
|
|
883
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css:
|
|
884
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [
|
|
885
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [
|
|
886
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [
|
|
1068
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles5.th, children: "Name" }),
|
|
1069
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thSize], children: "Size" }),
|
|
1070
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thDimensions], children: "Dimensions" }),
|
|
1071
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles5.th, styles5.thCdn], children: "CDN" })
|
|
887
1072
|
] }) }),
|
|
888
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tbody", { css:
|
|
1073
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "tbody", { css: styles5.tbody, children: sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
889
1074
|
ListRow,
|
|
890
1075
|
{
|
|
891
1076
|
item,
|
|
@@ -898,28 +1083,28 @@ function StudioFileList() {
|
|
|
898
1083
|
}
|
|
899
1084
|
function ListRow({ item, isSelected, onClick }) {
|
|
900
1085
|
const isFolder = item.type === "folder";
|
|
901
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: [
|
|
902
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css:
|
|
1086
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: [styles5.row, isSelected && styles5.rowSelected], onClick, children: [
|
|
1087
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: !isFolder && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
903
1088
|
"input",
|
|
904
1089
|
{
|
|
905
1090
|
type: "checkbox",
|
|
906
|
-
css:
|
|
1091
|
+
css: styles5.checkbox,
|
|
907
1092
|
checked: isSelected,
|
|
908
1093
|
onChange: () => {
|
|
909
1094
|
},
|
|
910
1095
|
onClick: (e) => e.stopPropagation()
|
|
911
1096
|
}
|
|
912
1097
|
) }),
|
|
913
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css:
|
|
914
|
-
isFolder ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
915
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
1098
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.nameCell, children: [
|
|
1099
|
+
isFolder ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
1100
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.name, children: item.name })
|
|
916
1101
|
] }) }),
|
|
917
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [
|
|
918
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [
|
|
919
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css:
|
|
920
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1102
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: item.size ? formatFileSize2(item.size) : "--" }),
|
|
1103
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles5.td, styles5.meta], children: item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
|
|
1104
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles5.td, children: item.cdnSynced ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles5.cdnBadge, children: [
|
|
1105
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
|
|
921
1106
|
"Synced"
|
|
922
|
-
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
1107
|
+
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.cdnEmpty, children: "--" }) })
|
|
923
1108
|
] });
|
|
924
1109
|
}
|
|
925
1110
|
function formatFileSize2(bytes) {
|
|
@@ -931,7 +1116,8 @@ function formatFileSize2(bytes) {
|
|
|
931
1116
|
// src/components/StudioPreview.tsx
|
|
932
1117
|
|
|
933
1118
|
|
|
934
|
-
|
|
1119
|
+
|
|
1120
|
+
var styles6 = {
|
|
935
1121
|
panel: _react3.css`
|
|
936
1122
|
width: 320px;
|
|
937
1123
|
border-left: 1px solid #e5e7eb;
|
|
@@ -1062,9 +1248,14 @@ var styles5 = {
|
|
|
1062
1248
|
};
|
|
1063
1249
|
function StudioPreview() {
|
|
1064
1250
|
const { selectedItems, meta, triggerRefresh, clearSelection } = useStudio();
|
|
1065
|
-
const
|
|
1251
|
+
const [showDeleteConfirm, setShowDeleteConfirm] = _react.useState.call(void 0, false);
|
|
1252
|
+
const [alertMessage, setAlertMessage] = _react.useState.call(void 0, null);
|
|
1253
|
+
const handleDeleteClick = () => {
|
|
1066
1254
|
if (selectedItems.size === 0) return;
|
|
1067
|
-
|
|
1255
|
+
setShowDeleteConfirm(true);
|
|
1256
|
+
};
|
|
1257
|
+
const handleDeleteConfirm = async () => {
|
|
1258
|
+
setShowDeleteConfirm(false);
|
|
1068
1259
|
try {
|
|
1069
1260
|
const response = await fetch("/api/studio/delete", {
|
|
1070
1261
|
method: "POST",
|
|
@@ -1076,106 +1267,142 @@ function StudioPreview() {
|
|
|
1076
1267
|
triggerRefresh();
|
|
1077
1268
|
} else {
|
|
1078
1269
|
const error = await response.json();
|
|
1079
|
-
|
|
1270
|
+
setAlertMessage({
|
|
1271
|
+
title: "Delete Failed",
|
|
1272
|
+
message: error.error || "Unknown error"
|
|
1273
|
+
});
|
|
1080
1274
|
}
|
|
1081
1275
|
} catch (error) {
|
|
1082
1276
|
console.error("Delete error:", error);
|
|
1083
|
-
|
|
1277
|
+
setAlertMessage({
|
|
1278
|
+
title: "Delete Failed",
|
|
1279
|
+
message: "Delete failed. Check console for details."
|
|
1280
|
+
});
|
|
1084
1281
|
}
|
|
1085
1282
|
};
|
|
1283
|
+
const modals = /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1284
|
+
showDeleteConfirm && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1285
|
+
ConfirmModal,
|
|
1286
|
+
{
|
|
1287
|
+
title: "Delete Items",
|
|
1288
|
+
message: `Are you sure you want to delete ${selectedItems.size} item(s)? This action cannot be undone.`,
|
|
1289
|
+
confirmLabel: "Delete",
|
|
1290
|
+
variant: "danger",
|
|
1291
|
+
onConfirm: handleDeleteConfirm,
|
|
1292
|
+
onCancel: () => setShowDeleteConfirm(false)
|
|
1293
|
+
}
|
|
1294
|
+
),
|
|
1295
|
+
alertMessage && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1296
|
+
AlertModal,
|
|
1297
|
+
{
|
|
1298
|
+
title: alertMessage.title,
|
|
1299
|
+
message: alertMessage.message,
|
|
1300
|
+
onClose: () => setAlertMessage(null)
|
|
1301
|
+
}
|
|
1302
|
+
)
|
|
1303
|
+
] });
|
|
1086
1304
|
if (selectedItems.size === 0) {
|
|
1087
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1088
|
-
|
|
1089
|
-
/* @__PURE__ */ _jsxruntime.
|
|
1305
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1306
|
+
modals,
|
|
1307
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.panel, children: [
|
|
1308
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles6.title, children: "Preview" }),
|
|
1309
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.emptyState, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.emptyText, children: "Select an image to preview" }) })
|
|
1310
|
+
] })
|
|
1090
1311
|
] });
|
|
1091
1312
|
}
|
|
1092
1313
|
if (selectedItems.size > 1) {
|
|
1093
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
"
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1314
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1315
|
+
modals,
|
|
1316
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.panel, children: [
|
|
1317
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "h3", { css: styles6.title, children: [
|
|
1318
|
+
selectedItems.size,
|
|
1319
|
+
" items selected"
|
|
1320
|
+
] }),
|
|
1321
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.actions, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: [
|
|
1322
|
+
"Delete ",
|
|
1323
|
+
selectedItems.size,
|
|
1324
|
+
" items"
|
|
1325
|
+
] }) })
|
|
1326
|
+
] })
|
|
1103
1327
|
] });
|
|
1104
1328
|
}
|
|
1105
1329
|
const selectedPath = Array.from(selectedItems)[0];
|
|
1106
1330
|
const imageKey = selectedPath.replace(/^public\/images\//, "").replace(/^public\/originals\//, "");
|
|
1107
1331
|
const imageData = _optionalChain([meta, 'optionalAccess', _4 => _4.images, 'optionalAccess', _5 => _5[imageKey]]);
|
|
1108
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1109
|
-
|
|
1110
|
-
/* @__PURE__ */ _jsxruntime.
|
|
1111
|
-
"
|
|
1112
|
-
{
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1122
|
-
|
|
1123
|
-
{
|
|
1124
|
-
label: "Original",
|
|
1125
|
-
value: `${imageData.original.width}x${imageData.original.height}`
|
|
1126
|
-
}
|
|
1127
|
-
),
|
|
1128
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1129
|
-
InfoRow,
|
|
1130
|
-
{
|
|
1131
|
-
label: "File size",
|
|
1132
|
-
value: formatFileSize3(imageData.original.fileSize)
|
|
1133
|
-
}
|
|
1134
|
-
),
|
|
1135
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.section, children: [
|
|
1136
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.sectionTitle, children: "Generated sizes" }),
|
|
1137
|
-
Object.entries(imageData.sizes).map(([size, data]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InfoRow, { label: size, value: `${data.width}x${data.height}` }, size))
|
|
1138
|
-
] }),
|
|
1139
|
-
_optionalChain([imageData, 'access', _6 => _6.cdn, 'optionalAccess', _7 => _7.synced]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.section, children: [
|
|
1140
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.sectionTitle, children: "CDN" }),
|
|
1141
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.cdnStatus, children: [
|
|
1142
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
|
|
1143
|
-
"Synced to CDN"
|
|
1144
|
-
] }),
|
|
1332
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1333
|
+
modals,
|
|
1334
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.panel, children: [
|
|
1335
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles6.title, children: "Preview" }),
|
|
1336
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.imageContainer, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1337
|
+
"img",
|
|
1338
|
+
{
|
|
1339
|
+
css: styles6.image,
|
|
1340
|
+
src: selectedPath.replace("public", ""),
|
|
1341
|
+
alt: "Preview"
|
|
1342
|
+
}
|
|
1343
|
+
) }),
|
|
1344
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.info, children: [
|
|
1345
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, InfoRow, { label: "Filename", value: selectedPath.split("/").pop() || "" }),
|
|
1346
|
+
imageData && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1145
1347
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1146
|
-
|
|
1348
|
+
InfoRow,
|
|
1147
1349
|
{
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
navigator.clipboard.writeText(`${_optionalChain([imageData, 'access', _8 => _8.cdn, 'optionalAccess', _9 => _9.baseUrl])}${imageData.sizes.full.path}`);
|
|
1151
|
-
},
|
|
1152
|
-
children: "Copy CDN URL"
|
|
1350
|
+
label: "Original",
|
|
1351
|
+
value: `${imageData.original.width}x${imageData.original.height}`
|
|
1153
1352
|
}
|
|
1154
|
-
)
|
|
1155
|
-
] }),
|
|
1156
|
-
imageData.blurhash && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.section, children: [
|
|
1157
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, InfoRow, { label: "Blurhash", value: imageData.blurhash, truncate: true }),
|
|
1353
|
+
),
|
|
1158
1354
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1159
|
-
|
|
1355
|
+
InfoRow,
|
|
1160
1356
|
{
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
title: `Dominant color: ${imageData.dominantColor}`
|
|
1357
|
+
label: "File size",
|
|
1358
|
+
value: formatFileSize3(imageData.original.fileSize)
|
|
1164
1359
|
}
|
|
1165
|
-
)
|
|
1360
|
+
),
|
|
1361
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.section, children: [
|
|
1362
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.sectionTitle, children: "Generated sizes" }),
|
|
1363
|
+
Object.entries(imageData.sizes).map(([size, data]) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, InfoRow, { label: size, value: `${data.width}x${data.height}` }, size))
|
|
1364
|
+
] }),
|
|
1365
|
+
_optionalChain([imageData, 'access', _6 => _6.cdn, 'optionalAccess', _7 => _7.synced]) && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.section, children: [
|
|
1366
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles6.sectionTitle, children: "CDN" }),
|
|
1367
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.cdnStatus, children: [
|
|
1368
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
|
|
1369
|
+
"Synced to CDN"
|
|
1370
|
+
] }),
|
|
1371
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1372
|
+
"button",
|
|
1373
|
+
{
|
|
1374
|
+
css: styles6.copyBtn,
|
|
1375
|
+
onClick: () => {
|
|
1376
|
+
navigator.clipboard.writeText(`${_optionalChain([imageData, 'access', _8 => _8.cdn, 'optionalAccess', _9 => _9.baseUrl])}${imageData.sizes.full.path}`);
|
|
1377
|
+
},
|
|
1378
|
+
children: "Copy CDN URL"
|
|
1379
|
+
}
|
|
1380
|
+
)
|
|
1381
|
+
] }),
|
|
1382
|
+
imageData.blurhash && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.section, children: [
|
|
1383
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, InfoRow, { label: "Blurhash", value: imageData.blurhash, truncate: true }),
|
|
1384
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1385
|
+
"div",
|
|
1386
|
+
{
|
|
1387
|
+
css: styles6.colorSwatch,
|
|
1388
|
+
style: { backgroundColor: imageData.dominantColor },
|
|
1389
|
+
title: `Dominant color: ${imageData.dominantColor}`
|
|
1390
|
+
}
|
|
1391
|
+
)
|
|
1392
|
+
] })
|
|
1166
1393
|
] })
|
|
1394
|
+
] }),
|
|
1395
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.actions, children: [
|
|
1396
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles6.actionBtn, children: "Rename" }),
|
|
1397
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: "Delete" })
|
|
1167
1398
|
] })
|
|
1168
|
-
] }),
|
|
1169
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.actions, children: [
|
|
1170
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles5.actionBtn, children: "Rename" }),
|
|
1171
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: [styles5.actionBtn, styles5.actionBtnDanger], onClick: handleDelete, children: "Delete" })
|
|
1172
1399
|
] })
|
|
1173
1400
|
] });
|
|
1174
1401
|
}
|
|
1175
1402
|
function InfoRow({ label, value, truncate }) {
|
|
1176
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1177
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
1178
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: [
|
|
1403
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.row, children: [
|
|
1404
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.label, children: label }),
|
|
1405
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: [styles6.value, truncate && styles6.valueTruncate], title: truncate ? value : void 0, children: value })
|
|
1179
1406
|
] });
|
|
1180
1407
|
}
|
|
1181
1408
|
function formatFileSize3(bytes) {
|
|
@@ -1188,7 +1415,7 @@ function formatFileSize3(bytes) {
|
|
|
1188
1415
|
|
|
1189
1416
|
|
|
1190
1417
|
|
|
1191
|
-
var
|
|
1418
|
+
var styles7 = {
|
|
1192
1419
|
btn: _react3.css`
|
|
1193
1420
|
padding: 8px;
|
|
1194
1421
|
background: none;
|
|
@@ -1346,10 +1573,10 @@ var styles6 = {
|
|
|
1346
1573
|
function StudioSettings() {
|
|
1347
1574
|
const [isOpen, setIsOpen] = _react.useState.call(void 0, false);
|
|
1348
1575
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
1349
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
1576
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1350
1577
|
"svg",
|
|
1351
1578
|
{
|
|
1352
|
-
css:
|
|
1579
|
+
css: styles7.icon,
|
|
1353
1580
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1354
1581
|
viewBox: "0 0 24 24",
|
|
1355
1582
|
fill: "none",
|
|
@@ -1367,51 +1594,51 @@ function StudioSettings() {
|
|
|
1367
1594
|
] });
|
|
1368
1595
|
}
|
|
1369
1596
|
function SettingsPanel({ onClose }) {
|
|
1370
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1371
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
1372
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1373
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1374
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css:
|
|
1375
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
1597
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.overlay, children: [
|
|
1598
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.backdrop, onClick: onClose }),
|
|
1599
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.panel, children: [
|
|
1600
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.header, children: [
|
|
1601
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles7.title, children: "Settings" }),
|
|
1602
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.closeBtn, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
1376
1603
|
] }),
|
|
1377
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1604
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.sections, children: [
|
|
1378
1605
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
|
|
1379
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css:
|
|
1380
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
1381
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1382
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
1383
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
1384
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
1385
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
1386
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
1606
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sectionTitle, children: "Cloudflare R2" }),
|
|
1607
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.description, children: "Configure in .env.local file:" }),
|
|
1608
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.code, children: [
|
|
1609
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID" }),
|
|
1610
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID" }),
|
|
1611
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY" }),
|
|
1612
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME" }),
|
|
1613
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL" })
|
|
1387
1614
|
] })
|
|
1388
1615
|
] }),
|
|
1389
1616
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
|
|
1390
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css:
|
|
1391
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
1392
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css:
|
|
1617
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sectionTitle, children: "Custom CDN URL" }),
|
|
1618
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.description, children: "Override the default R2 URL with a custom domain:" }),
|
|
1619
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "text", placeholder: "https://cdn.yourdomain.com" })
|
|
1393
1620
|
] }),
|
|
1394
1621
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
|
|
1395
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css:
|
|
1396
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1622
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sectionTitle, children: "Thumbnail Sizes" }),
|
|
1623
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.grid, children: [
|
|
1397
1624
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
1398
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css:
|
|
1399
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css:
|
|
1625
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Small" }),
|
|
1626
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 300 })
|
|
1400
1627
|
] }),
|
|
1401
1628
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
1402
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css:
|
|
1403
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css:
|
|
1629
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Medium" }),
|
|
1630
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 700 })
|
|
1404
1631
|
] }),
|
|
1405
1632
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
1406
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css:
|
|
1407
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css:
|
|
1633
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles7.label, children: "Large" }),
|
|
1634
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles7.input, type: "number", defaultValue: 1400 })
|
|
1408
1635
|
] })
|
|
1409
1636
|
] })
|
|
1410
1637
|
] })
|
|
1411
1638
|
] }),
|
|
1412
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1413
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
1414
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
1639
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.footer, children: [
|
|
1640
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.cancelBtn, onClick: onClose, children: "Cancel" }),
|
|
1641
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.saveBtn, children: "Save Changes" })
|
|
1415
1642
|
] })
|
|
1416
1643
|
] })
|
|
1417
1644
|
] });
|
|
@@ -1419,7 +1646,7 @@ function SettingsPanel({ onClose }) {
|
|
|
1419
1646
|
|
|
1420
1647
|
// src/components/StudioUI.tsx
|
|
1421
1648
|
|
|
1422
|
-
var
|
|
1649
|
+
var styles8 = {
|
|
1423
1650
|
container: _react3.css`
|
|
1424
1651
|
display: flex;
|
|
1425
1652
|
flex-direction: column;
|
|
@@ -1569,15 +1796,15 @@ function StudioUI({ onClose }) {
|
|
|
1569
1796
|
refreshKey,
|
|
1570
1797
|
triggerRefresh
|
|
1571
1798
|
};
|
|
1572
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1573
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1574
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css:
|
|
1575
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1799
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.container, children: [
|
|
1800
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.header, children: [
|
|
1801
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css: styles8.title, children: "Studio" }),
|
|
1802
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.headerActions, children: [
|
|
1576
1803
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioSettings, {}),
|
|
1577
1804
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1578
1805
|
"button",
|
|
1579
1806
|
{
|
|
1580
|
-
css:
|
|
1807
|
+
css: styles8.closeBtn,
|
|
1581
1808
|
onClick: onClose,
|
|
1582
1809
|
"aria-label": "Close Studio",
|
|
1583
1810
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloseIcon, {})
|
|
@@ -1587,8 +1814,8 @@ function StudioUI({ onClose }) {
|
|
|
1587
1814
|
] }),
|
|
1588
1815
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioToolbar, {}),
|
|
1589
1816
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioBreadcrumb, {}),
|
|
1590
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1591
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
1817
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.content, children: [
|
|
1818
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileGrid, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileList, {}) }),
|
|
1592
1819
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioPreview, {})
|
|
1593
1820
|
] })
|
|
1594
1821
|
] }) });
|
|
@@ -1597,7 +1824,7 @@ function CloseIcon() {
|
|
|
1597
1824
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1598
1825
|
"svg",
|
|
1599
1826
|
{
|
|
1600
|
-
css:
|
|
1827
|
+
css: styles8.closeIcon,
|
|
1601
1828
|
xmlns: "http://www.w3.org/2000/svg",
|
|
1602
1829
|
viewBox: "0 0 24 24",
|
|
1603
1830
|
fill: "none",
|
|
@@ -1617,4 +1844,4 @@ var StudioUI_default = StudioUI;
|
|
|
1617
1844
|
|
|
1618
1845
|
|
|
1619
1846
|
exports.StudioUI = StudioUI; exports.default = StudioUI_default;
|
|
1620
|
-
//# sourceMappingURL=StudioUI-
|
|
1847
|
+
//# sourceMappingURL=StudioUI-QG2NJQTM.js.map
|