@gallop.software/studio 0.1.7 → 0.1.8

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.
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
 
3
3
  // src/components/StudioUI.tsx
4
- import { useEffect as useEffect3, useCallback as useCallback2, useState as useState5 } from "react";
5
- import { css as css7 } from "@emotion/react";
4
+ import { useEffect as useEffect3, useCallback as useCallback2, useState as useState6 } from "react";
5
+ import { css as css8 } from "@emotion/react";
6
6
 
7
7
  // src/components/StudioContext.tsx
8
8
  import { createContext, useContext } from "react";
@@ -49,10 +49,149 @@ function useStudio() {
49
49
 
50
50
  // src/components/StudioToolbar.tsx
51
51
  import { useCallback, useRef, useState } from "react";
52
- import { css } from "@emotion/react";
52
+ import { css as css2 } from "@emotion/react";
53
+
54
+ // src/components/StudioModal.tsx
55
+ import { css, keyframes } from "@emotion/react";
53
56
  import { jsx, jsxs } from "@emotion/react/jsx-runtime";
57
+ var fadeIn = keyframes`
58
+ from { opacity: 0; }
59
+ to { opacity: 1; }
60
+ `;
61
+ var slideIn = 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 = {
55
- toolbar: css`
72
+ overlay: 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: 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: css`
91
+ padding: 20px 24px 0;
92
+ `,
93
+ title: css`
94
+ font-size: 18px;
95
+ font-weight: 600;
96
+ color: #111827;
97
+ margin: 0;
98
+ `,
99
+ body: css`
100
+ padding: 12px 24px 24px;
101
+ `,
102
+ message: css`
103
+ font-size: 14px;
104
+ color: #6b7280;
105
+ margin: 0;
106
+ line-height: 1.5;
107
+ `,
108
+ footer: 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: 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: css`
126
+ background-color: white;
127
+ border: 1px solid #d1d5db;
128
+ color: #374151;
129
+
130
+ &:hover {
131
+ background-color: #f9fafb;
132
+ }
133
+ `,
134
+ btnConfirm: css`
135
+ background-color: #9333ea;
136
+ border: 1px solid #9333ea;
137
+ color: white;
138
+
139
+ &:hover {
140
+ background-color: #7c3aed;
141
+ }
142
+ `,
143
+ btnDanger: 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__ */ jsx("div", { css: styles.overlay, onClick: onCancel, children: /* @__PURE__ */ jsxs("div", { css: styles.modal, onClick: (e) => e.stopPropagation(), children: [
163
+ /* @__PURE__ */ jsx("div", { css: styles.header, children: /* @__PURE__ */ jsx("h3", { css: styles.title, children: title }) }),
164
+ /* @__PURE__ */ jsx("div", { css: styles.body, children: /* @__PURE__ */ jsx("p", { css: styles.message, children: message }) }),
165
+ /* @__PURE__ */ jsxs("div", { css: styles.footer, children: [
166
+ /* @__PURE__ */ jsx("button", { css: [styles.btn, styles.btnCancel], onClick: onCancel, children: cancelLabel }),
167
+ /* @__PURE__ */ jsx(
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__ */ jsx("div", { css: styles.overlay, onClick: onClose, children: /* @__PURE__ */ jsxs("div", { css: styles.modal, onClick: (e) => e.stopPropagation(), children: [
185
+ /* @__PURE__ */ jsx("div", { css: styles.header, children: /* @__PURE__ */ jsx("h3", { css: styles.title, children: title }) }),
186
+ /* @__PURE__ */ jsx("div", { css: styles.body, children: /* @__PURE__ */ jsx("p", { css: styles.message, children: message }) }),
187
+ /* @__PURE__ */ jsx("div", { css: styles.footer, children: /* @__PURE__ */ jsx("button", { css: [styles.btn, styles.btnConfirm], onClick: onClose, children: buttonLabel }) })
188
+ ] }) });
189
+ }
190
+
191
+ // src/components/StudioToolbar.tsx
192
+ import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "@emotion/react/jsx-runtime";
193
+ var styles2 = {
194
+ toolbar: css2`
56
195
  display: flex;
57
196
  align-items: center;
58
197
  justify-content: space-between;
@@ -60,17 +199,17 @@ var styles = {
60
199
  background-color: #f9fafb;
61
200
  border-bottom: 1px solid #e5e7eb;
62
201
  `,
63
- left: css`
202
+ left: css2`
64
203
  display: flex;
65
204
  align-items: center;
66
205
  gap: 8px;
67
206
  `,
68
- right: css`
207
+ right: css2`
69
208
  display: flex;
70
209
  align-items: center;
71
210
  gap: 16px;
72
211
  `,
73
- btn: css`
212
+ btn: css2`
74
213
  display: flex;
75
214
  align-items: center;
76
215
  gap: 8px;
@@ -88,29 +227,29 @@ var styles = {
88
227
  opacity: 0.5;
89
228
  }
90
229
  `,
91
- btnDefault: css`
230
+ btnDefault: css2`
92
231
  color: #374151;
93
232
 
94
233
  &:hover:not(:disabled) {
95
234
  background-color: white;
96
235
  }
97
236
  `,
98
- btnDanger: css`
237
+ btnDanger: css2`
99
238
  color: #dc2626;
100
239
 
101
240
  &:hover:not(:disabled) {
102
241
  background-color: #fef2f2;
103
242
  }
104
243
  `,
105
- icon: css`
244
+ icon: css2`
106
245
  width: 16px;
107
246
  height: 16px;
108
247
  `,
109
- selectionCount: css`
248
+ selectionCount: css2`
110
249
  font-size: 14px;
111
250
  color: #4b5563;
112
251
  `,
113
- clearBtn: css`
252
+ clearBtn: css2`
114
253
  margin-left: 8px;
115
254
  color: #9333ea;
116
255
  background: none;
@@ -122,7 +261,7 @@ var styles = {
122
261
  text-decoration: underline;
123
262
  }
124
263
  `,
125
- viewToggle: css`
264
+ viewToggle: css2`
126
265
  display: flex;
127
266
  align-items: center;
128
267
  background-color: white;
@@ -130,7 +269,7 @@ var styles = {
130
269
  border-radius: 8px;
131
270
  overflow: hidden;
132
271
  `,
133
- viewBtn: css`
272
+ viewBtn: css2`
134
273
  padding: 8px;
135
274
  background: none;
136
275
  border: none;
@@ -142,7 +281,7 @@ var styles = {
142
281
  background-color: #f9fafb;
143
282
  }
144
283
  `,
145
- viewBtnActive: css`
284
+ viewBtnActive: css2`
146
285
  background-color: #f3e8ff;
147
286
  color: #7c3aed;
148
287
  `
@@ -151,6 +290,8 @@ function StudioToolbar() {
151
290
  const { selectedItems, viewMode, setViewMode, clearSelection, currentPath, triggerRefresh } = useStudio();
152
291
  const fileInputRef = useRef(null);
153
292
  const [uploading, setUploading] = useState(false);
293
+ const [showDeleteConfirm, setShowDeleteConfirm] = useState(false);
294
+ const [alertMessage, setAlertMessage] = useState(null);
154
295
  const handleUpload = useCallback(() => {
155
296
  fileInputRef.current?.click();
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
- alert(`Failed to upload ${file.name}: ${error.error || "Unknown error"}`);
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
- alert("Upload failed. Check console for details.");
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 = useCallback(() => {
188
335
  console.log("Reprocess clicked", selectedItems);
189
336
  }, [selectedItems]);
190
- const handleDelete = useCallback(async () => {
337
+ const handleDeleteClick = useCallback(() => {
191
338
  if (selectedItems.size === 0) return;
192
- if (!confirm(`Delete ${selectedItems.size} item(s)?`)) return;
339
+ setShowDeleteConfirm(true);
340
+ }, [selectedItems]);
341
+ const handleDeleteConfirm = useCallback(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
- alert(`Delete failed: ${error.error || "Unknown error"}`);
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
- alert("Delete failed. Check console for details.");
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 = useCallback(() => {
@@ -215,83 +371,104 @@ function StudioToolbar() {
215
371
  console.log("Scan clicked");
216
372
  }, []);
217
373
  const hasSelection = selectedItems.size > 0;
218
- return /* @__PURE__ */ jsxs("div", { css: styles.toolbar, children: [
219
- /* @__PURE__ */ jsx(
220
- "input",
374
+ return /* @__PURE__ */ jsxs2(Fragment, { children: [
375
+ showDeleteConfirm && /* @__PURE__ */ jsx2(
376
+ ConfirmModal,
221
377
  {
222
- ref: fileInputRef,
223
- type: "file",
224
- multiple: true,
225
- accept: "image/*",
226
- onChange: handleFileChange,
227
- style: { display: "none" }
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__ */ jsxs("div", { css: styles.left, children: [
231
- /* @__PURE__ */ jsx(
232
- ToolbarButton,
233
- {
234
- onClick: handleUpload,
235
- icon: "upload",
236
- label: uploading ? "Uploading..." : "Upload",
237
- disabled: uploading
238
- }
239
- ),
240
- /* @__PURE__ */ jsx(
241
- ToolbarButton,
242
- {
243
- onClick: handleReprocess,
244
- icon: "refresh",
245
- label: "Reprocess",
246
- disabled: !hasSelection
247
- }
248
- ),
249
- /* @__PURE__ */ jsx(
250
- ToolbarButton,
251
- {
252
- onClick: handleDelete,
253
- icon: "trash",
254
- label: "Delete",
255
- disabled: !hasSelection,
256
- variant: "danger"
257
- }
258
- ),
259
- /* @__PURE__ */ jsx(
260
- ToolbarButton,
386
+ alertMessage && /* @__PURE__ */ jsx2(
387
+ AlertModal,
388
+ {
389
+ title: alertMessage.title,
390
+ message: alertMessage.message,
391
+ onClose: () => setAlertMessage(null)
392
+ }
393
+ ),
394
+ /* @__PURE__ */ jsxs2("div", { css: styles2.toolbar, children: [
395
+ /* @__PURE__ */ jsx2(
396
+ "input",
261
397
  {
262
- onClick: handleSyncCdn,
263
- icon: "cloud",
264
- label: "Sync CDN",
265
- disabled: !hasSelection
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__ */ jsx(ToolbarButton, { onClick: handleScan, icon: "scan", label: "Scan" })
269
- ] }),
270
- /* @__PURE__ */ jsxs("div", { css: styles.right, children: [
271
- hasSelection && /* @__PURE__ */ jsxs("span", { css: styles.selectionCount, children: [
272
- selectedItems.size,
273
- " selected",
274
- /* @__PURE__ */ jsx("button", { css: styles.clearBtn, onClick: clearSelection, children: "Clear" })
275
- ] }),
276
- /* @__PURE__ */ jsxs("div", { css: styles.viewToggle, children: [
277
- /* @__PURE__ */ jsx(
278
- "button",
406
+ /* @__PURE__ */ jsxs2("div", { css: styles2.left, children: [
407
+ /* @__PURE__ */ jsx2(
408
+ ToolbarButton,
279
409
  {
280
- css: [styles.viewBtn, viewMode === "grid" && styles.viewBtnActive],
281
- onClick: () => setViewMode("grid"),
282
- "aria-label": "Grid view",
283
- children: /* @__PURE__ */ jsx(GridIcon, {})
410
+ onClick: handleUpload,
411
+ icon: "upload",
412
+ label: uploading ? "Uploading..." : "Upload",
413
+ disabled: uploading
284
414
  }
285
415
  ),
286
- /* @__PURE__ */ jsx(
287
- "button",
416
+ /* @__PURE__ */ jsx2(
417
+ ToolbarButton,
288
418
  {
289
- css: [styles.viewBtn, viewMode === "list" && styles.viewBtnActive],
290
- onClick: () => setViewMode("list"),
291
- "aria-label": "List view",
292
- children: /* @__PURE__ */ jsx(ListIcon, {})
419
+ onClick: handleReprocess,
420
+ icon: "refresh",
421
+ label: "Reprocess",
422
+ disabled: !hasSelection
293
423
  }
294
- )
424
+ ),
425
+ /* @__PURE__ */ jsx2(
426
+ ToolbarButton,
427
+ {
428
+ onClick: handleDeleteClick,
429
+ icon: "trash",
430
+ label: "Delete",
431
+ disabled: !hasSelection,
432
+ variant: "danger"
433
+ }
434
+ ),
435
+ /* @__PURE__ */ jsx2(
436
+ ToolbarButton,
437
+ {
438
+ onClick: handleSyncCdn,
439
+ icon: "cloud",
440
+ label: "Sync CDN",
441
+ disabled: !hasSelection
442
+ }
443
+ ),
444
+ /* @__PURE__ */ jsx2(ToolbarButton, { onClick: handleScan, icon: "scan", label: "Scan" })
445
+ ] }),
446
+ /* @__PURE__ */ jsxs2("div", { css: styles2.right, children: [
447
+ hasSelection && /* @__PURE__ */ jsxs2("span", { css: styles2.selectionCount, children: [
448
+ selectedItems.size,
449
+ " selected",
450
+ /* @__PURE__ */ jsx2("button", { css: styles2.clearBtn, onClick: clearSelection, children: "Clear" })
451
+ ] }),
452
+ /* @__PURE__ */ jsxs2("div", { css: styles2.viewToggle, children: [
453
+ /* @__PURE__ */ jsx2(
454
+ "button",
455
+ {
456
+ css: [styles2.viewBtn, viewMode === "grid" && styles2.viewBtnActive],
457
+ onClick: () => setViewMode("grid"),
458
+ "aria-label": "Grid view",
459
+ children: /* @__PURE__ */ jsx2(GridIcon, {})
460
+ }
461
+ ),
462
+ /* @__PURE__ */ jsx2(
463
+ "button",
464
+ {
465
+ css: [styles2.viewBtn, viewMode === "list" && styles2.viewBtnActive],
466
+ onClick: () => setViewMode("list"),
467
+ "aria-label": "List view",
468
+ children: /* @__PURE__ */ jsx2(ListIcon, {})
469
+ }
470
+ )
471
+ ] })
295
472
  ] })
296
473
  ] })
297
474
  ] });
@@ -303,14 +480,14 @@ function ToolbarButton({
303
480
  disabled,
304
481
  variant = "default"
305
482
  }) {
306
- return /* @__PURE__ */ jsxs(
483
+ return /* @__PURE__ */ jsxs2(
307
484
  "button",
308
485
  {
309
- css: [styles.btn, variant === "danger" ? styles.btnDanger : styles.btnDefault],
486
+ css: [styles2.btn, variant === "danger" ? styles2.btnDanger : styles2.btnDefault],
310
487
  onClick,
311
488
  disabled,
312
489
  children: [
313
- /* @__PURE__ */ jsx(IconComponent, { icon }),
490
+ /* @__PURE__ */ jsx2(IconComponent, { icon }),
314
491
  label
315
492
  ]
316
493
  }
@@ -319,31 +496,31 @@ function ToolbarButton({
319
496
  function IconComponent({ icon }) {
320
497
  switch (icon) {
321
498
  case "upload":
322
- return /* @__PURE__ */ jsx("svg", { css: styles.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("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" }) });
499
+ return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("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__ */ jsx("svg", { css: styles.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("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" }) });
501
+ return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("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__ */ jsx("svg", { css: styles.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("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" }) });
503
+ return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("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__ */ jsx("svg", { css: styles.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("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" }) });
505
+ return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("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__ */ jsx("svg", { css: styles.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z" }) });
507
+ return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("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__ */ jsx("svg", { css: styles.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("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" }) });
513
+ return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("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__ */ jsx("svg", { css: styles.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
516
+ return /* @__PURE__ */ jsx2("svg", { css: styles2.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
340
517
  }
341
518
 
342
519
  // src/components/StudioBreadcrumb.tsx
343
- import { css as css2 } from "@emotion/react";
344
- import { jsx as jsx2, jsxs as jsxs2 } from "@emotion/react/jsx-runtime";
345
- var styles2 = {
346
- container: css2`
520
+ import { css as css3 } from "@emotion/react";
521
+ import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
522
+ var styles3 = {
523
+ container: css3`
347
524
  display: flex;
348
525
  align-items: center;
349
526
  gap: 8px;
@@ -351,7 +528,7 @@ var styles2 = {
351
528
  background-color: white;
352
529
  border-bottom: 1px solid #f3f4f6;
353
530
  `,
354
- backBtn: css2`
531
+ backBtn: css3`
355
532
  padding: 4px;
356
533
  background: none;
357
534
  border: none;
@@ -363,26 +540,26 @@ var styles2 = {
363
540
  background-color: #f3f4f6;
364
541
  }
365
542
  `,
366
- backIcon: css2`
543
+ backIcon: css3`
367
544
  width: 16px;
368
545
  height: 16px;
369
546
  color: #6b7280;
370
547
  `,
371
- nav: css2`
548
+ nav: css3`
372
549
  display: flex;
373
550
  align-items: center;
374
551
  gap: 4px;
375
552
  font-size: 14px;
376
553
  `,
377
- item: css2`
554
+ item: css3`
378
555
  display: flex;
379
556
  align-items: center;
380
557
  gap: 4px;
381
558
  `,
382
- separator: css2`
559
+ separator: css3`
383
560
  color: #d1d5db;
384
561
  `,
385
- btn: css2`
562
+ btn: css3`
386
563
  padding: 2px 4px;
387
564
  background: none;
388
565
  border: none;
@@ -394,11 +571,11 @@ var styles2 = {
394
571
  background-color: #f3f4f6;
395
572
  }
396
573
  `,
397
- btnActive: css2`
574
+ btnActive: css3`
398
575
  color: #111827;
399
576
  font-weight: 500;
400
577
  `,
401
- btnInactive: css2`
578
+ btnInactive: css3`
402
579
  color: #6b7280;
403
580
 
404
581
  &:hover {
@@ -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__ */ jsxs2("div", { css: styles2.container, children: [
417
- currentPath !== "public" && /* @__PURE__ */ jsx2("button", { css: styles2.backBtn, onClick: navigateUp, "aria-label": "Go back", children: /* @__PURE__ */ jsx2("svg", { css: styles2.backIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx2("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) }),
418
- /* @__PURE__ */ jsx2("nav", { css: styles2.nav, children: parts.map((part, index) => /* @__PURE__ */ jsxs2("span", { css: styles2.item, children: [
419
- index > 0 && /* @__PURE__ */ jsx2("span", { css: styles2.separator, children: "/" }),
420
- /* @__PURE__ */ jsx2(
593
+ return /* @__PURE__ */ jsxs3("div", { css: styles3.container, children: [
594
+ currentPath !== "public" && /* @__PURE__ */ jsx3("button", { css: styles3.backBtn, onClick: navigateUp, "aria-label": "Go back", children: /* @__PURE__ */ jsx3("svg", { css: styles3.backIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M15 19l-7-7 7-7" }) }) }),
595
+ /* @__PURE__ */ jsx3("nav", { css: styles3.nav, children: parts.map((part, index) => /* @__PURE__ */ jsxs3("span", { css: styles3.item, children: [
596
+ index > 0 && /* @__PURE__ */ jsx3("span", { css: styles3.separator, children: "/" }),
597
+ /* @__PURE__ */ jsx3(
421
598
  "button",
422
599
  {
423
- css: [styles2.btn, index === parts.length - 1 ? styles2.btnActive : styles2.btnInactive],
600
+ css: [styles3.btn, index === parts.length - 1 ? styles3.btnActive : styles3.btnInactive],
424
601
  onClick: () => handleClick(index),
425
602
  children: part
426
603
  }
@@ -431,19 +608,19 @@ function StudioBreadcrumb() {
431
608
 
432
609
  // src/components/StudioFileGrid.tsx
433
610
  import { useEffect, useState as useState2 } from "react";
434
- import { css as css3, keyframes } from "@emotion/react";
435
- import { jsx as jsx3, jsxs as jsxs3 } from "@emotion/react/jsx-runtime";
436
- var spin = keyframes`
611
+ import { css as css4, keyframes as keyframes2 } from "@emotion/react";
612
+ import { jsx as jsx4, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
613
+ var spin = keyframes2`
437
614
  to { transform: rotate(360deg); }
438
615
  `;
439
- var styles3 = {
440
- loading: css3`
616
+ var styles4 = {
617
+ loading: css4`
441
618
  display: flex;
442
619
  align-items: center;
443
620
  justify-content: center;
444
621
  height: 256px;
445
622
  `,
446
- spinner: css3`
623
+ spinner: css4`
447
624
  width: 32px;
448
625
  height: 32px;
449
626
  border-radius: 50%;
@@ -451,7 +628,7 @@ var styles3 = {
451
628
  border-bottom-color: #9333ea;
452
629
  animation: ${spin} 1s linear infinite;
453
630
  `,
454
- empty: css3`
631
+ empty: css4`
455
632
  display: flex;
456
633
  flex-direction: column;
457
634
  align-items: center;
@@ -459,16 +636,16 @@ var styles3 = {
459
636
  height: 256px;
460
637
  color: #6b7280;
461
638
  `,
462
- emptyIcon: css3`
639
+ emptyIcon: css4`
463
640
  width: 48px;
464
641
  height: 48px;
465
642
  margin-bottom: 16px;
466
643
  `,
467
- emptyText: css3`
644
+ emptyText: css4`
468
645
  font-size: 14px;
469
646
  margin: 0;
470
647
  `,
471
- grid: css3`
648
+ grid: css4`
472
649
  display: grid;
473
650
  grid-template-columns: repeat(2, 1fr);
474
651
  gap: 16px;
@@ -478,7 +655,7 @@ var styles3 = {
478
655
  @media (min-width: 1024px) { grid-template-columns: repeat(5, 1fr); }
479
656
  @media (min-width: 1280px) { grid-template-columns: repeat(6, 1fr); }
480
657
  `,
481
- item: css3`
658
+ item: css4`
482
659
  position: relative;
483
660
  border-radius: 8px;
484
661
  border: 2px solid transparent;
@@ -491,11 +668,11 @@ var styles3 = {
491
668
  border-color: #e5e7eb;
492
669
  }
493
670
  `,
494
- itemSelected: css3`
671
+ itemSelected: css4`
495
672
  border-color: #a855f7;
496
673
  background-color: #faf5ff;
497
674
  `,
498
- checkbox: css3`
675
+ checkbox: css4`
499
676
  position: absolute;
500
677
  top: 8px;
501
678
  left: 8px;
@@ -504,7 +681,7 @@ var styles3 = {
504
681
  height: 16px;
505
682
  accent-color: #9333ea;
506
683
  `,
507
- cdnBadge: css3`
684
+ cdnBadge: css4`
508
685
  position: absolute;
509
686
  top: 8px;
510
687
  right: 8px;
@@ -515,30 +692,30 @@ var styles3 = {
515
692
  padding: 2px 6px;
516
693
  border-radius: 9999px;
517
694
  `,
518
- content: css3`
695
+ content: css4`
519
696
  aspect-ratio: 1;
520
697
  display: flex;
521
698
  align-items: center;
522
699
  justify-content: center;
523
700
  padding: 16px;
524
701
  `,
525
- folderIcon: css3`
702
+ folderIcon: css4`
526
703
  width: 64px;
527
704
  height: 64px;
528
705
  color: #facc15;
529
706
  `,
530
- image: css3`
707
+ image: css4`
531
708
  max-width: 100%;
532
709
  max-height: 100%;
533
710
  object-fit: contain;
534
711
  border-radius: 4px;
535
712
  `,
536
- label: css3`
713
+ label: css4`
537
714
  padding: 6px 8px;
538
715
  background-color: white;
539
716
  border-top: 1px solid #e5e7eb;
540
717
  `,
541
- name: css3`
718
+ name: css4`
542
719
  font-size: 12px;
543
720
  color: #374151;
544
721
  white-space: nowrap;
@@ -546,19 +723,19 @@ var styles3 = {
546
723
  text-overflow: ellipsis;
547
724
  margin: 0;
548
725
  `,
549
- size: css3`
726
+ size: css4`
550
727
  font-size: 12px;
551
728
  color: #9ca3af;
552
729
  margin: 0;
553
730
  `,
554
- selectAllRow: css3`
731
+ selectAllRow: css4`
555
732
  display: flex;
556
733
  align-items: center;
557
734
  margin-bottom: 12px;
558
735
  padding-bottom: 12px;
559
736
  border-bottom: 1px solid #e5e7eb;
560
737
  `,
561
- selectAllLabel: css3`
738
+ selectAllLabel: css4`
562
739
  display: flex;
563
740
  align-items: center;
564
741
  gap: 8px;
@@ -570,7 +747,7 @@ var styles3 = {
570
747
  color: #374151;
571
748
  }
572
749
  `,
573
- selectAllCheckbox: css3`
750
+ selectAllCheckbox: css4`
574
751
  width: 16px;
575
752
  height: 16px;
576
753
  accent-color: #9333ea;
@@ -597,13 +774,13 @@ function StudioFileGrid() {
597
774
  loadItems();
598
775
  }, [currentPath, refreshKey]);
599
776
  if (loading) {
600
- return /* @__PURE__ */ jsx3("div", { css: styles3.loading, children: /* @__PURE__ */ jsx3("div", { css: styles3.spinner }) });
777
+ return /* @__PURE__ */ jsx4("div", { css: styles4.loading, children: /* @__PURE__ */ jsx4("div", { css: styles4.spinner }) });
601
778
  }
602
779
  if (items.length === 0) {
603
- return /* @__PURE__ */ jsxs3("div", { css: styles3.empty, children: [
604
- /* @__PURE__ */ jsx3("svg", { css: styles3.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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" }) }),
605
- /* @__PURE__ */ jsx3("p", { css: styles3.emptyText, children: "No files in this folder" }),
606
- /* @__PURE__ */ jsx3("p", { css: styles3.emptyText, children: "Upload images to get started" })
780
+ return /* @__PURE__ */ jsxs4("div", { css: styles4.empty, children: [
781
+ /* @__PURE__ */ jsx4("svg", { css: styles4.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }),
782
+ /* @__PURE__ */ jsx4("p", { css: styles4.emptyText, children: "No files in this folder" }),
783
+ /* @__PURE__ */ jsx4("p", { css: styles4.emptyText, children: "Upload images to get started" })
607
784
  ] });
608
785
  }
609
786
  const sortedItems = [...items].sort((a, b) => {
@@ -632,13 +809,13 @@ function StudioFileGrid() {
632
809
  toggleSelection(item.path);
633
810
  }
634
811
  };
635
- return /* @__PURE__ */ jsxs3("div", { children: [
636
- files.length > 0 && /* @__PURE__ */ jsx3("div", { css: styles3.selectAllRow, children: /* @__PURE__ */ jsxs3("label", { css: styles3.selectAllLabel, children: [
637
- /* @__PURE__ */ jsx3(
812
+ return /* @__PURE__ */ jsxs4("div", { children: [
813
+ files.length > 0 && /* @__PURE__ */ jsx4("div", { css: styles4.selectAllRow, children: /* @__PURE__ */ jsxs4("label", { css: styles4.selectAllLabel, children: [
814
+ /* @__PURE__ */ jsx4(
638
815
  "input",
639
816
  {
640
817
  type: "checkbox",
641
- css: styles3.selectAllCheckbox,
818
+ css: styles4.selectAllCheckbox,
642
819
  checked: allFilesSelected,
643
820
  ref: (el) => {
644
821
  if (el) el.indeterminate = someFilesSelected && !allFilesSelected;
@@ -650,7 +827,7 @@ function StudioFileGrid() {
650
827
  files.length,
651
828
  ")"
652
829
  ] }) }),
653
- /* @__PURE__ */ jsx3("div", { css: styles3.grid, children: sortedItems.map((item) => /* @__PURE__ */ jsx3(
830
+ /* @__PURE__ */ jsx4("div", { css: styles4.grid, children: sortedItems.map((item) => /* @__PURE__ */ jsx4(
654
831
  GridItem,
655
832
  {
656
833
  item,
@@ -663,31 +840,31 @@ function StudioFileGrid() {
663
840
  }
664
841
  function GridItem({ item, isSelected, onClick }) {
665
842
  const isFolder = item.type === "folder";
666
- return /* @__PURE__ */ jsxs3("div", { css: [styles3.item, isSelected && styles3.itemSelected], onClick, children: [
667
- !isFolder && /* @__PURE__ */ jsx3(
843
+ return /* @__PURE__ */ jsxs4("div", { css: [styles4.item, isSelected && styles4.itemSelected], onClick, children: [
844
+ !isFolder && /* @__PURE__ */ jsx4(
668
845
  "input",
669
846
  {
670
847
  type: "checkbox",
671
- css: styles3.checkbox,
848
+ css: styles4.checkbox,
672
849
  checked: isSelected,
673
850
  onChange: () => {
674
851
  },
675
852
  onClick: (e) => e.stopPropagation()
676
853
  }
677
854
  ),
678
- item.cdnSynced && /* @__PURE__ */ jsx3("span", { css: styles3.cdnBadge, children: "CDN" }),
679
- /* @__PURE__ */ jsx3("div", { css: styles3.content, children: isFolder ? /* @__PURE__ */ jsx3("svg", { css: styles3.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx3("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__ */ jsx3(
855
+ item.cdnSynced && /* @__PURE__ */ jsx4("span", { css: styles4.cdnBadge, children: "CDN" }),
856
+ /* @__PURE__ */ jsx4("div", { css: styles4.content, children: isFolder ? /* @__PURE__ */ jsx4("svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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__ */ jsx4(
680
857
  "img",
681
858
  {
682
- css: styles3.image,
859
+ css: styles4.image,
683
860
  src: item.path.replace("public", ""),
684
861
  alt: item.name,
685
862
  loading: "lazy"
686
863
  }
687
864
  ) }),
688
- /* @__PURE__ */ jsxs3("div", { css: styles3.label, children: [
689
- /* @__PURE__ */ jsx3("p", { css: styles3.name, title: item.name, children: item.name }),
690
- item.size && /* @__PURE__ */ jsx3("p", { css: styles3.size, children: formatFileSize(item.size) })
865
+ /* @__PURE__ */ jsxs4("div", { css: styles4.label, children: [
866
+ /* @__PURE__ */ jsx4("p", { css: styles4.name, title: item.name, children: item.name }),
867
+ item.size && /* @__PURE__ */ jsx4("p", { css: styles4.size, children: formatFileSize(item.size) })
691
868
  ] })
692
869
  ] });
693
870
  }
@@ -699,19 +876,19 @@ function formatFileSize(bytes) {
699
876
 
700
877
  // src/components/StudioFileList.tsx
701
878
  import { useEffect as useEffect2, useState as useState3 } from "react";
702
- import { css as css4, keyframes as keyframes2 } from "@emotion/react";
703
- import { jsx as jsx4, jsxs as jsxs4 } from "@emotion/react/jsx-runtime";
704
- var spin2 = keyframes2`
879
+ import { css as css5, keyframes as keyframes3 } from "@emotion/react";
880
+ import { jsx as jsx5, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
881
+ var spin2 = keyframes3`
705
882
  to { transform: rotate(360deg); }
706
883
  `;
707
- var styles4 = {
708
- loading: css4`
884
+ var styles5 = {
885
+ loading: css5`
709
886
  display: flex;
710
887
  align-items: center;
711
888
  justify-content: center;
712
889
  height: 256px;
713
890
  `,
714
- spinner: css4`
891
+ spinner: css5`
715
892
  width: 32px;
716
893
  height: 32px;
717
894
  border-radius: 50%;
@@ -719,7 +896,7 @@ var styles4 = {
719
896
  border-bottom-color: #9333ea;
720
897
  animation: ${spin2} 1s linear infinite;
721
898
  `,
722
- empty: css4`
899
+ empty: css5`
723
900
  display: flex;
724
901
  flex-direction: column;
725
902
  align-items: center;
@@ -727,11 +904,11 @@ var styles4 = {
727
904
  height: 256px;
728
905
  color: #6b7280;
729
906
  `,
730
- table: css4`
907
+ table: css5`
731
908
  width: 100%;
732
909
  border-collapse: collapse;
733
910
  `,
734
- th: css4`
911
+ th: css5`
735
912
  text-align: left;
736
913
  font-size: 12px;
737
914
  color: #6b7280;
@@ -740,22 +917,22 @@ var styles4 = {
740
917
  padding-bottom: 8px;
741
918
  font-weight: normal;
742
919
  `,
743
- thCheckbox: css4`
920
+ thCheckbox: css5`
744
921
  width: 32px;
745
922
  `,
746
- thSize: css4`
923
+ thSize: css5`
747
924
  width: 96px;
748
925
  `,
749
- thDimensions: css4`
926
+ thDimensions: css5`
750
927
  width: 128px;
751
928
  `,
752
- thCdn: css4`
929
+ thCdn: css5`
753
930
  width: 96px;
754
931
  `,
755
- tbody: css4`
932
+ tbody: css5`
756
933
  border-top: 1px solid #f3f4f6;
757
934
  `,
758
- row: css4`
935
+ row: css5`
759
936
  cursor: pointer;
760
937
  transition: background-color 0.15s;
761
938
 
@@ -763,53 +940,53 @@ var styles4 = {
763
940
  background-color: #f9fafb;
764
941
  }
765
942
  `,
766
- rowSelected: css4`
943
+ rowSelected: css5`
767
944
  background-color: #faf5ff;
768
945
  `,
769
- td: css4`
946
+ td: css5`
770
947
  padding: 8px 0;
771
948
  border-bottom: 1px solid #f3f4f6;
772
949
  `,
773
- checkbox: css4`
950
+ checkbox: css5`
774
951
  width: 16px;
775
952
  height: 16px;
776
953
  accent-color: #9333ea;
777
954
  `,
778
- nameCell: css4`
955
+ nameCell: css5`
779
956
  display: flex;
780
957
  align-items: center;
781
958
  gap: 8px;
782
959
  `,
783
- folderIcon: css4`
960
+ folderIcon: css5`
784
961
  width: 20px;
785
962
  height: 20px;
786
963
  color: #facc15;
787
964
  `,
788
- fileIcon: css4`
965
+ fileIcon: css5`
789
966
  width: 20px;
790
967
  height: 20px;
791
968
  color: #9ca3af;
792
969
  `,
793
- name: css4`
970
+ name: css5`
794
971
  font-size: 14px;
795
972
  color: #111827;
796
973
  `,
797
- meta: css4`
974
+ meta: css5`
798
975
  font-size: 14px;
799
976
  color: #6b7280;
800
977
  `,
801
- cdnBadge: css4`
978
+ cdnBadge: css5`
802
979
  display: inline-flex;
803
980
  align-items: center;
804
981
  gap: 4px;
805
982
  font-size: 12px;
806
983
  color: #15803d;
807
984
  `,
808
- cdnIcon: css4`
985
+ cdnIcon: css5`
809
986
  width: 12px;
810
987
  height: 12px;
811
988
  `,
812
- cdnEmpty: css4`
989
+ cdnEmpty: css5`
813
990
  font-size: 12px;
814
991
  color: #9ca3af;
815
992
  `
@@ -835,10 +1012,10 @@ function StudioFileList() {
835
1012
  loadItems();
836
1013
  }, [currentPath, refreshKey]);
837
1014
  if (loading) {
838
- return /* @__PURE__ */ jsx4("div", { css: styles4.loading, children: /* @__PURE__ */ jsx4("div", { css: styles4.spinner }) });
1015
+ return /* @__PURE__ */ jsx5("div", { css: styles5.loading, children: /* @__PURE__ */ jsx5("div", { css: styles5.spinner }) });
839
1016
  }
840
1017
  if (items.length === 0) {
841
- return /* @__PURE__ */ jsx4("div", { css: styles4.empty, children: /* @__PURE__ */ jsx4("p", { children: "No files in this folder" }) });
1018
+ return /* @__PURE__ */ jsx5("div", { css: styles5.empty, children: /* @__PURE__ */ jsx5("p", { children: "No files in this folder" }) });
842
1019
  }
843
1020
  const sortedItems = [...items].sort((a, b) => {
844
1021
  if (a.type === "folder" && b.type !== "folder") return -1;
@@ -866,13 +1043,13 @@ function StudioFileList() {
866
1043
  toggleSelection(item.path);
867
1044
  }
868
1045
  };
869
- return /* @__PURE__ */ jsxs4("table", { css: styles4.table, children: [
870
- /* @__PURE__ */ jsx4("thead", { children: /* @__PURE__ */ jsxs4("tr", { children: [
871
- /* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thCheckbox], children: files.length > 0 && /* @__PURE__ */ jsx4(
1046
+ return /* @__PURE__ */ jsxs5("table", { css: styles5.table, children: [
1047
+ /* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
1048
+ /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thCheckbox], children: files.length > 0 && /* @__PURE__ */ jsx5(
872
1049
  "input",
873
1050
  {
874
1051
  type: "checkbox",
875
- css: styles4.checkbox,
1052
+ css: styles5.checkbox,
876
1053
  checked: allFilesSelected,
877
1054
  ref: (el) => {
878
1055
  if (el) el.indeterminate = someFilesSelected && !allFilesSelected;
@@ -880,12 +1057,12 @@ function StudioFileList() {
880
1057
  onChange: handleSelectAll
881
1058
  }
882
1059
  ) }),
883
- /* @__PURE__ */ jsx4("th", { css: styles4.th, children: "Name" }),
884
- /* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thSize], children: "Size" }),
885
- /* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thDimensions], children: "Dimensions" }),
886
- /* @__PURE__ */ jsx4("th", { css: [styles4.th, styles4.thCdn], children: "CDN" })
1060
+ /* @__PURE__ */ jsx5("th", { css: styles5.th, children: "Name" }),
1061
+ /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thSize], children: "Size" }),
1062
+ /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thDimensions], children: "Dimensions" }),
1063
+ /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thCdn], children: "CDN" })
887
1064
  ] }) }),
888
- /* @__PURE__ */ jsx4("tbody", { css: styles4.tbody, children: sortedItems.map((item) => /* @__PURE__ */ jsx4(
1065
+ /* @__PURE__ */ jsx5("tbody", { css: styles5.tbody, children: sortedItems.map((item) => /* @__PURE__ */ jsx5(
889
1066
  ListRow,
890
1067
  {
891
1068
  item,
@@ -898,28 +1075,28 @@ function StudioFileList() {
898
1075
  }
899
1076
  function ListRow({ item, isSelected, onClick }) {
900
1077
  const isFolder = item.type === "folder";
901
- return /* @__PURE__ */ jsxs4("tr", { css: [styles4.row, isSelected && styles4.rowSelected], onClick, children: [
902
- /* @__PURE__ */ jsx4("td", { css: styles4.td, children: !isFolder && /* @__PURE__ */ jsx4(
1078
+ return /* @__PURE__ */ jsxs5("tr", { css: [styles5.row, isSelected && styles5.rowSelected], onClick, children: [
1079
+ /* @__PURE__ */ jsx5("td", { css: styles5.td, children: !isFolder && /* @__PURE__ */ jsx5(
903
1080
  "input",
904
1081
  {
905
1082
  type: "checkbox",
906
- css: styles4.checkbox,
1083
+ css: styles5.checkbox,
907
1084
  checked: isSelected,
908
1085
  onChange: () => {
909
1086
  },
910
1087
  onClick: (e) => e.stopPropagation()
911
1088
  }
912
1089
  ) }),
913
- /* @__PURE__ */ jsx4("td", { css: styles4.td, children: /* @__PURE__ */ jsxs4("div", { css: styles4.nameCell, children: [
914
- isFolder ? /* @__PURE__ */ jsx4("svg", { css: styles4.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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__ */ jsx4("svg", { css: styles4.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx4("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" }) }),
915
- /* @__PURE__ */ jsx4("span", { css: styles4.name, children: item.name })
1090
+ /* @__PURE__ */ jsx5("td", { css: styles5.td, children: /* @__PURE__ */ jsxs5("div", { css: styles5.nameCell, children: [
1091
+ isFolder ? /* @__PURE__ */ jsx5("svg", { css: styles5.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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__ */ jsx5("svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx5("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" }) }),
1092
+ /* @__PURE__ */ jsx5("span", { css: styles5.name, children: item.name })
916
1093
  ] }) }),
917
- /* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: item.size ? formatFileSize2(item.size) : "--" }),
918
- /* @__PURE__ */ jsx4("td", { css: [styles4.td, styles4.meta], children: item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
919
- /* @__PURE__ */ jsx4("td", { css: styles4.td, children: item.cdnSynced ? /* @__PURE__ */ jsxs4("span", { css: styles4.cdnBadge, children: [
920
- /* @__PURE__ */ jsx4("svg", { css: styles4.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx4("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" }) }),
1094
+ /* @__PURE__ */ jsx5("td", { css: [styles5.td, styles5.meta], children: item.size ? formatFileSize2(item.size) : "--" }),
1095
+ /* @__PURE__ */ jsx5("td", { css: [styles5.td, styles5.meta], children: item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
1096
+ /* @__PURE__ */ jsx5("td", { css: styles5.td, children: item.cdnSynced ? /* @__PURE__ */ jsxs5("span", { css: styles5.cdnBadge, children: [
1097
+ /* @__PURE__ */ jsx5("svg", { css: styles5.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx5("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
1098
  "Synced"
922
- ] }) : /* @__PURE__ */ jsx4("span", { css: styles4.cdnEmpty, children: "--" }) })
1099
+ ] }) : /* @__PURE__ */ jsx5("span", { css: styles5.cdnEmpty, children: "--" }) })
923
1100
  ] });
924
1101
  }
925
1102
  function formatFileSize2(bytes) {
@@ -929,78 +1106,79 @@ function formatFileSize2(bytes) {
929
1106
  }
930
1107
 
931
1108
  // src/components/StudioPreview.tsx
932
- import { css as css5 } from "@emotion/react";
933
- import { Fragment, jsx as jsx5, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
934
- var styles5 = {
935
- panel: css5`
1109
+ import { useState as useState4 } from "react";
1110
+ import { css as css6 } from "@emotion/react";
1111
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
1112
+ var styles6 = {
1113
+ panel: css6`
936
1114
  width: 320px;
937
1115
  border-left: 1px solid #e5e7eb;
938
1116
  background-color: #f9fafb;
939
1117
  padding: 16px;
940
1118
  overflow: auto;
941
1119
  `,
942
- title: css5`
1120
+ title: css6`
943
1121
  font-size: 14px;
944
1122
  font-weight: 500;
945
1123
  color: #111827;
946
1124
  margin: 0 0 16px 0;
947
1125
  `,
948
- imageContainer: css5`
1126
+ imageContainer: css6`
949
1127
  background-color: white;
950
1128
  border-radius: 8px;
951
1129
  border: 1px solid #e5e7eb;
952
1130
  padding: 8px;
953
1131
  margin-bottom: 16px;
954
1132
  `,
955
- image: css5`
1133
+ image: css6`
956
1134
  width: 100%;
957
1135
  height: auto;
958
1136
  border-radius: 4px;
959
1137
  `,
960
- info: css5`
1138
+ info: css6`
961
1139
  display: flex;
962
1140
  flex-direction: column;
963
1141
  gap: 12px;
964
1142
  `,
965
- row: css5`
1143
+ row: css6`
966
1144
  display: flex;
967
1145
  justify-content: space-between;
968
1146
  font-size: 12px;
969
1147
  `,
970
- label: css5`
1148
+ label: css6`
971
1149
  color: #6b7280;
972
1150
  `,
973
- value: css5`
1151
+ value: css6`
974
1152
  color: #111827;
975
1153
  `,
976
- valueTruncate: css5`
1154
+ valueTruncate: css6`
977
1155
  max-width: 128px;
978
1156
  white-space: nowrap;
979
1157
  overflow: hidden;
980
1158
  text-overflow: ellipsis;
981
1159
  `,
982
- section: css5`
1160
+ section: css6`
983
1161
  padding-top: 8px;
984
1162
  border-top: 1px solid #e5e7eb;
985
1163
  `,
986
- sectionTitle: css5`
1164
+ sectionTitle: css6`
987
1165
  font-size: 12px;
988
1166
  font-weight: 500;
989
1167
  color: #6b7280;
990
1168
  margin: 0 0 8px 0;
991
1169
  `,
992
- cdnStatus: css5`
1170
+ cdnStatus: css6`
993
1171
  display: flex;
994
1172
  align-items: center;
995
1173
  gap: 8px;
996
1174
  font-size: 12px;
997
1175
  color: #16a34a;
998
1176
  `,
999
- cdnIcon: css5`
1177
+ cdnIcon: css6`
1000
1178
  width: 16px;
1001
1179
  height: 16px;
1002
1180
  `,
1003
- copyBtn: css5`
1181
+ copyBtn: css6`
1004
1182
  margin-top: 8px;
1005
1183
  font-size: 12px;
1006
1184
  color: #9333ea;
@@ -1013,23 +1191,23 @@ var styles5 = {
1013
1191
  text-decoration: underline;
1014
1192
  }
1015
1193
  `,
1016
- colorSwatch: css5`
1194
+ colorSwatch: css6`
1017
1195
  margin-top: 8px;
1018
1196
  height: 32px;
1019
1197
  border-radius: 4px;
1020
1198
  `,
1021
- emptyState: css5`
1199
+ emptyState: css6`
1022
1200
  display: flex;
1023
1201
  align-items: center;
1024
1202
  justify-content: center;
1025
1203
  height: 200px;
1026
1204
  `,
1027
- emptyText: css5`
1205
+ emptyText: css6`
1028
1206
  font-size: 14px;
1029
1207
  color: #9ca3af;
1030
1208
  margin: 0;
1031
1209
  `,
1032
- actions: css5`
1210
+ actions: css6`
1033
1211
  margin-top: 16px;
1034
1212
  padding-top: 16px;
1035
1213
  border-top: 1px solid #e5e7eb;
@@ -1037,7 +1215,7 @@ var styles5 = {
1037
1215
  flex-direction: column;
1038
1216
  gap: 8px;
1039
1217
  `,
1040
- actionBtn: css5`
1218
+ actionBtn: css6`
1041
1219
  width: 100%;
1042
1220
  padding: 8px 12px;
1043
1221
  font-size: 14px;
@@ -1052,7 +1230,7 @@ var styles5 = {
1052
1230
  background-color: #f9fafb;
1053
1231
  }
1054
1232
  `,
1055
- actionBtnDanger: css5`
1233
+ actionBtnDanger: css6`
1056
1234
  color: #dc2626;
1057
1235
 
1058
1236
  &:hover {
@@ -1062,9 +1240,14 @@ var styles5 = {
1062
1240
  };
1063
1241
  function StudioPreview() {
1064
1242
  const { selectedItems, meta, triggerRefresh, clearSelection } = useStudio();
1065
- const handleDelete = async () => {
1243
+ const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
1244
+ const [alertMessage, setAlertMessage] = useState4(null);
1245
+ const handleDeleteClick = () => {
1066
1246
  if (selectedItems.size === 0) return;
1067
- if (!confirm(`Delete ${selectedItems.size} item(s)?`)) return;
1247
+ setShowDeleteConfirm(true);
1248
+ };
1249
+ const handleDeleteConfirm = async () => {
1250
+ setShowDeleteConfirm(false);
1068
1251
  try {
1069
1252
  const response = await fetch("/api/studio/delete", {
1070
1253
  method: "POST",
@@ -1076,106 +1259,142 @@ function StudioPreview() {
1076
1259
  triggerRefresh();
1077
1260
  } else {
1078
1261
  const error = await response.json();
1079
- alert(`Delete failed: ${error.error || "Unknown error"}`);
1262
+ setAlertMessage({
1263
+ title: "Delete Failed",
1264
+ message: error.error || "Unknown error"
1265
+ });
1080
1266
  }
1081
1267
  } catch (error) {
1082
1268
  console.error("Delete error:", error);
1083
- alert("Delete failed. Check console for details.");
1269
+ setAlertMessage({
1270
+ title: "Delete Failed",
1271
+ message: "Delete failed. Check console for details."
1272
+ });
1084
1273
  }
1085
1274
  };
1275
+ const modals = /* @__PURE__ */ jsxs6(Fragment2, { children: [
1276
+ showDeleteConfirm && /* @__PURE__ */ jsx6(
1277
+ ConfirmModal,
1278
+ {
1279
+ title: "Delete Items",
1280
+ message: `Are you sure you want to delete ${selectedItems.size} item(s)? This action cannot be undone.`,
1281
+ confirmLabel: "Delete",
1282
+ variant: "danger",
1283
+ onConfirm: handleDeleteConfirm,
1284
+ onCancel: () => setShowDeleteConfirm(false)
1285
+ }
1286
+ ),
1287
+ alertMessage && /* @__PURE__ */ jsx6(
1288
+ AlertModal,
1289
+ {
1290
+ title: alertMessage.title,
1291
+ message: alertMessage.message,
1292
+ onClose: () => setAlertMessage(null)
1293
+ }
1294
+ )
1295
+ ] });
1086
1296
  if (selectedItems.size === 0) {
1087
- return /* @__PURE__ */ jsxs5("div", { css: styles5.panel, children: [
1088
- /* @__PURE__ */ jsx5("h3", { css: styles5.title, children: "Preview" }),
1089
- /* @__PURE__ */ jsx5("div", { css: styles5.emptyState, children: /* @__PURE__ */ jsx5("p", { css: styles5.emptyText, children: "Select an image to preview" }) })
1297
+ return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1298
+ modals,
1299
+ /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1300
+ /* @__PURE__ */ jsx6("h3", { css: styles6.title, children: "Preview" }),
1301
+ /* @__PURE__ */ jsx6("div", { css: styles6.emptyState, children: /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "Select an image to preview" }) })
1302
+ ] })
1090
1303
  ] });
1091
1304
  }
1092
1305
  if (selectedItems.size > 1) {
1093
- return /* @__PURE__ */ jsxs5("div", { css: styles5.panel, children: [
1094
- /* @__PURE__ */ jsxs5("h3", { css: styles5.title, children: [
1095
- selectedItems.size,
1096
- " items selected"
1097
- ] }),
1098
- /* @__PURE__ */ jsx5("div", { css: styles5.actions, children: /* @__PURE__ */ jsxs5("button", { css: [styles5.actionBtn, styles5.actionBtnDanger], onClick: handleDelete, children: [
1099
- "Delete ",
1100
- selectedItems.size,
1101
- " items"
1102
- ] }) })
1306
+ return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1307
+ modals,
1308
+ /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1309
+ /* @__PURE__ */ jsxs6("h3", { css: styles6.title, children: [
1310
+ selectedItems.size,
1311
+ " items selected"
1312
+ ] }),
1313
+ /* @__PURE__ */ jsx6("div", { css: styles6.actions, children: /* @__PURE__ */ jsxs6("button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: [
1314
+ "Delete ",
1315
+ selectedItems.size,
1316
+ " items"
1317
+ ] }) })
1318
+ ] })
1103
1319
  ] });
1104
1320
  }
1105
1321
  const selectedPath = Array.from(selectedItems)[0];
1106
1322
  const imageKey = selectedPath.replace(/^public\/images\//, "").replace(/^public\/originals\//, "");
1107
1323
  const imageData = meta?.images?.[imageKey];
1108
- return /* @__PURE__ */ jsxs5("div", { css: styles5.panel, children: [
1109
- /* @__PURE__ */ jsx5("h3", { css: styles5.title, children: "Preview" }),
1110
- /* @__PURE__ */ jsx5("div", { css: styles5.imageContainer, children: /* @__PURE__ */ jsx5(
1111
- "img",
1112
- {
1113
- css: styles5.image,
1114
- src: selectedPath.replace("public", ""),
1115
- alt: "Preview"
1116
- }
1117
- ) }),
1118
- /* @__PURE__ */ jsxs5("div", { css: styles5.info, children: [
1119
- /* @__PURE__ */ jsx5(InfoRow, { label: "Filename", value: selectedPath.split("/").pop() || "" }),
1120
- imageData && /* @__PURE__ */ jsxs5(Fragment, { children: [
1121
- /* @__PURE__ */ jsx5(
1122
- InfoRow,
1123
- {
1124
- label: "Original",
1125
- value: `${imageData.original.width}x${imageData.original.height}`
1126
- }
1127
- ),
1128
- /* @__PURE__ */ jsx5(
1129
- InfoRow,
1130
- {
1131
- label: "File size",
1132
- value: formatFileSize3(imageData.original.fileSize)
1133
- }
1134
- ),
1135
- /* @__PURE__ */ jsxs5("div", { css: styles5.section, children: [
1136
- /* @__PURE__ */ jsx5("p", { css: styles5.sectionTitle, children: "Generated sizes" }),
1137
- Object.entries(imageData.sizes).map(([size, data]) => /* @__PURE__ */ jsx5(InfoRow, { label: size, value: `${data.width}x${data.height}` }, size))
1138
- ] }),
1139
- imageData.cdn?.synced && /* @__PURE__ */ jsxs5("div", { css: styles5.section, children: [
1140
- /* @__PURE__ */ jsx5("p", { css: styles5.sectionTitle, children: "CDN" }),
1141
- /* @__PURE__ */ jsxs5("div", { css: styles5.cdnStatus, children: [
1142
- /* @__PURE__ */ jsx5("svg", { css: styles5.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx5("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
- ] }),
1145
- /* @__PURE__ */ jsx5(
1146
- "button",
1324
+ return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1325
+ modals,
1326
+ /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1327
+ /* @__PURE__ */ jsx6("h3", { css: styles6.title, children: "Preview" }),
1328
+ /* @__PURE__ */ jsx6("div", { css: styles6.imageContainer, children: /* @__PURE__ */ jsx6(
1329
+ "img",
1330
+ {
1331
+ css: styles6.image,
1332
+ src: selectedPath.replace("public", ""),
1333
+ alt: "Preview"
1334
+ }
1335
+ ) }),
1336
+ /* @__PURE__ */ jsxs6("div", { css: styles6.info, children: [
1337
+ /* @__PURE__ */ jsx6(InfoRow, { label: "Filename", value: selectedPath.split("/").pop() || "" }),
1338
+ imageData && /* @__PURE__ */ jsxs6(Fragment2, { children: [
1339
+ /* @__PURE__ */ jsx6(
1340
+ InfoRow,
1147
1341
  {
1148
- css: styles5.copyBtn,
1149
- onClick: () => {
1150
- navigator.clipboard.writeText(`${imageData.cdn?.baseUrl}${imageData.sizes.full.path}`);
1151
- },
1152
- children: "Copy CDN URL"
1342
+ label: "Original",
1343
+ value: `${imageData.original.width}x${imageData.original.height}`
1153
1344
  }
1154
- )
1155
- ] }),
1156
- imageData.blurhash && /* @__PURE__ */ jsxs5("div", { css: styles5.section, children: [
1157
- /* @__PURE__ */ jsx5(InfoRow, { label: "Blurhash", value: imageData.blurhash, truncate: true }),
1158
- /* @__PURE__ */ jsx5(
1159
- "div",
1345
+ ),
1346
+ /* @__PURE__ */ jsx6(
1347
+ InfoRow,
1160
1348
  {
1161
- css: styles5.colorSwatch,
1162
- style: { backgroundColor: imageData.dominantColor },
1163
- title: `Dominant color: ${imageData.dominantColor}`
1349
+ label: "File size",
1350
+ value: formatFileSize3(imageData.original.fileSize)
1164
1351
  }
1165
- )
1352
+ ),
1353
+ /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1354
+ /* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "Generated sizes" }),
1355
+ Object.entries(imageData.sizes).map(([size, data]) => /* @__PURE__ */ jsx6(InfoRow, { label: size, value: `${data.width}x${data.height}` }, size))
1356
+ ] }),
1357
+ imageData.cdn?.synced && /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1358
+ /* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "CDN" }),
1359
+ /* @__PURE__ */ jsxs6("div", { css: styles6.cdnStatus, children: [
1360
+ /* @__PURE__ */ jsx6("svg", { css: styles6.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx6("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" }) }),
1361
+ "Synced to CDN"
1362
+ ] }),
1363
+ /* @__PURE__ */ jsx6(
1364
+ "button",
1365
+ {
1366
+ css: styles6.copyBtn,
1367
+ onClick: () => {
1368
+ navigator.clipboard.writeText(`${imageData.cdn?.baseUrl}${imageData.sizes.full.path}`);
1369
+ },
1370
+ children: "Copy CDN URL"
1371
+ }
1372
+ )
1373
+ ] }),
1374
+ imageData.blurhash && /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1375
+ /* @__PURE__ */ jsx6(InfoRow, { label: "Blurhash", value: imageData.blurhash, truncate: true }),
1376
+ /* @__PURE__ */ jsx6(
1377
+ "div",
1378
+ {
1379
+ css: styles6.colorSwatch,
1380
+ style: { backgroundColor: imageData.dominantColor },
1381
+ title: `Dominant color: ${imageData.dominantColor}`
1382
+ }
1383
+ )
1384
+ ] })
1166
1385
  ] })
1386
+ ] }),
1387
+ /* @__PURE__ */ jsxs6("div", { css: styles6.actions, children: [
1388
+ /* @__PURE__ */ jsx6("button", { css: styles6.actionBtn, children: "Rename" }),
1389
+ /* @__PURE__ */ jsx6("button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: "Delete" })
1167
1390
  ] })
1168
- ] }),
1169
- /* @__PURE__ */ jsxs5("div", { css: styles5.actions, children: [
1170
- /* @__PURE__ */ jsx5("button", { css: styles5.actionBtn, children: "Rename" }),
1171
- /* @__PURE__ */ jsx5("button", { css: [styles5.actionBtn, styles5.actionBtnDanger], onClick: handleDelete, children: "Delete" })
1172
1391
  ] })
1173
1392
  ] });
1174
1393
  }
1175
1394
  function InfoRow({ label, value, truncate }) {
1176
- return /* @__PURE__ */ jsxs5("div", { css: styles5.row, children: [
1177
- /* @__PURE__ */ jsx5("span", { css: styles5.label, children: label }),
1178
- /* @__PURE__ */ jsx5("span", { css: [styles5.value, truncate && styles5.valueTruncate], title: truncate ? value : void 0, children: value })
1395
+ return /* @__PURE__ */ jsxs6("div", { css: styles6.row, children: [
1396
+ /* @__PURE__ */ jsx6("span", { css: styles6.label, children: label }),
1397
+ /* @__PURE__ */ jsx6("span", { css: [styles6.value, truncate && styles6.valueTruncate], title: truncate ? value : void 0, children: value })
1179
1398
  ] });
1180
1399
  }
1181
1400
  function formatFileSize3(bytes) {
@@ -1185,11 +1404,11 @@ function formatFileSize3(bytes) {
1185
1404
  }
1186
1405
 
1187
1406
  // src/components/StudioSettings.tsx
1188
- import { useState as useState4 } from "react";
1189
- import { css as css6 } from "@emotion/react";
1190
- import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
1191
- var styles6 = {
1192
- btn: css6`
1407
+ import { useState as useState5 } from "react";
1408
+ import { css as css7 } from "@emotion/react";
1409
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
1410
+ var styles7 = {
1411
+ btn: css7`
1193
1412
  padding: 8px;
1194
1413
  background: none;
1195
1414
  border: none;
@@ -1201,12 +1420,12 @@ var styles6 = {
1201
1420
  background-color: #f3f4f6;
1202
1421
  }
1203
1422
  `,
1204
- icon: css6`
1423
+ icon: css7`
1205
1424
  width: 20px;
1206
1425
  height: 20px;
1207
1426
  color: #6b7280;
1208
1427
  `,
1209
- overlay: css6`
1428
+ overlay: css7`
1210
1429
  position: fixed;
1211
1430
  top: 0;
1212
1431
  right: 0;
@@ -1217,7 +1436,7 @@ var styles6 = {
1217
1436
  align-items: center;
1218
1437
  justify-content: center;
1219
1438
  `,
1220
- backdrop: css6`
1439
+ backdrop: css7`
1221
1440
  position: absolute;
1222
1441
  top: 0;
1223
1442
  right: 0;
@@ -1225,7 +1444,7 @@ var styles6 = {
1225
1444
  left: 0;
1226
1445
  background-color: rgba(0, 0, 0, 0.3);
1227
1446
  `,
1228
- panel: css6`
1447
+ panel: css7`
1229
1448
  position: relative;
1230
1449
  background-color: white;
1231
1450
  border-radius: 12px;
@@ -1234,18 +1453,18 @@ var styles6 = {
1234
1453
  max-width: 512px;
1235
1454
  padding: 24px;
1236
1455
  `,
1237
- header: css6`
1456
+ header: css7`
1238
1457
  display: flex;
1239
1458
  align-items: center;
1240
1459
  justify-content: space-between;
1241
1460
  margin-bottom: 24px;
1242
1461
  `,
1243
- title: css6`
1462
+ title: css7`
1244
1463
  font-size: 18px;
1245
1464
  font-weight: 600;
1246
1465
  margin: 0;
1247
1466
  `,
1248
- closeBtn: css6`
1467
+ closeBtn: css7`
1249
1468
  padding: 4px;
1250
1469
  background: none;
1251
1470
  border: none;
@@ -1256,23 +1475,23 @@ var styles6 = {
1256
1475
  background-color: #f3f4f6;
1257
1476
  }
1258
1477
  `,
1259
- sections: css6`
1478
+ sections: css7`
1260
1479
  display: flex;
1261
1480
  flex-direction: column;
1262
1481
  gap: 24px;
1263
1482
  `,
1264
- sectionTitle: css6`
1483
+ sectionTitle: css7`
1265
1484
  font-size: 14px;
1266
1485
  font-weight: 500;
1267
1486
  color: #111827;
1268
1487
  margin: 0 0 12px 0;
1269
1488
  `,
1270
- description: css6`
1489
+ description: css7`
1271
1490
  font-size: 12px;
1272
1491
  color: #6b7280;
1273
1492
  margin: 0 0 12px 0;
1274
1493
  `,
1275
- code: css6`
1494
+ code: css7`
1276
1495
  background-color: #f9fafb;
1277
1496
  border-radius: 8px;
1278
1497
  padding: 12px;
@@ -1280,14 +1499,14 @@ var styles6 = {
1280
1499
  font-size: 12px;
1281
1500
  color: #4b5563;
1282
1501
  `,
1283
- codeLine: css6`
1502
+ codeLine: css7`
1284
1503
  margin: 0 0 4px 0;
1285
1504
 
1286
1505
  &:last-child {
1287
1506
  margin: 0;
1288
1507
  }
1289
1508
  `,
1290
- input: css6`
1509
+ input: css7`
1291
1510
  width: 100%;
1292
1511
  padding: 8px 12px;
1293
1512
  border: 1px solid #e5e7eb;
@@ -1299,24 +1518,24 @@ var styles6 = {
1299
1518
  box-shadow: 0 0 0 2px #a855f7;
1300
1519
  }
1301
1520
  `,
1302
- grid: css6`
1521
+ grid: css7`
1303
1522
  display: grid;
1304
1523
  grid-template-columns: repeat(3, 1fr);
1305
1524
  gap: 12px;
1306
1525
  `,
1307
- label: css6`
1526
+ label: css7`
1308
1527
  font-size: 12px;
1309
1528
  color: #6b7280;
1310
1529
  display: block;
1311
1530
  margin-bottom: 4px;
1312
1531
  `,
1313
- footer: css6`
1532
+ footer: css7`
1314
1533
  margin-top: 24px;
1315
1534
  display: flex;
1316
1535
  justify-content: flex-end;
1317
1536
  gap: 12px;
1318
1537
  `,
1319
- cancelBtn: css6`
1538
+ cancelBtn: css7`
1320
1539
  padding: 8px 16px;
1321
1540
  font-size: 14px;
1322
1541
  color: #4b5563;
@@ -1329,7 +1548,7 @@ var styles6 = {
1329
1548
  background-color: #f3f4f6;
1330
1549
  }
1331
1550
  `,
1332
- saveBtn: css6`
1551
+ saveBtn: css7`
1333
1552
  padding: 8px 16px;
1334
1553
  font-size: 14px;
1335
1554
  color: white;
@@ -1344,12 +1563,12 @@ var styles6 = {
1344
1563
  `
1345
1564
  };
1346
1565
  function StudioSettings() {
1347
- const [isOpen, setIsOpen] = useState4(false);
1348
- return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1349
- /* @__PURE__ */ jsx6("button", { css: styles6.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs6(
1566
+ const [isOpen, setIsOpen] = useState5(false);
1567
+ return /* @__PURE__ */ jsxs7(Fragment3, { children: [
1568
+ /* @__PURE__ */ jsx7("button", { css: styles7.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs7(
1350
1569
  "svg",
1351
1570
  {
1352
- css: styles6.icon,
1571
+ css: styles7.icon,
1353
1572
  xmlns: "http://www.w3.org/2000/svg",
1354
1573
  viewBox: "0 0 24 24",
1355
1574
  fill: "none",
@@ -1358,93 +1577,93 @@ function StudioSettings() {
1358
1577
  strokeLinecap: "round",
1359
1578
  strokeLinejoin: "round",
1360
1579
  children: [
1361
- /* @__PURE__ */ jsx6("circle", { cx: "12", cy: "12", r: "3" }),
1362
- /* @__PURE__ */ jsx6("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" })
1580
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" }),
1581
+ /* @__PURE__ */ jsx7("path", { d: "M19.4 15a1.65 1.65 0 00.33 1.82l.06.06a2 2 0 010 2.83 2 2 0 01-2.83 0l-.06-.06a1.65 1.65 0 00-1.82-.33 1.65 1.65 0 00-1 1.51V21a2 2 0 01-2 2 2 2 0 01-2-2v-.09A1.65 1.65 0 009 19.4a1.65 1.65 0 00-1.82.33l-.06.06a2 2 0 01-2.83 0 2 2 0 010-2.83l.06-.06a1.65 1.65 0 00.33-1.82 1.65 1.65 0 00-1.51-1H3a2 2 0 01-2-2 2 2 0 012-2h.09A1.65 1.65 0 004.6 9a1.65 1.65 0 00-.33-1.82l-.06-.06a2 2 0 010-2.83 2 2 0 012.83 0l.06.06a1.65 1.65 0 001.82.33H9a1.65 1.65 0 001-1.51V3a2 2 0 012-2 2 2 0 012 2v.09a1.65 1.65 0 001 1.51 1.65 1.65 0 001.82-.33l.06-.06a2 2 0 012.83 0 2 2 0 010 2.83l-.06.06a1.65 1.65 0 00-.33 1.82V9a1.65 1.65 0 001.51 1H21a2 2 0 012 2 2 2 0 01-2 2h-.09a1.65 1.65 0 00-1.51 1z" })
1363
1582
  ]
1364
1583
  }
1365
1584
  ) }),
1366
- isOpen && /* @__PURE__ */ jsx6(SettingsPanel, { onClose: () => setIsOpen(false) })
1585
+ isOpen && /* @__PURE__ */ jsx7(SettingsPanel, { onClose: () => setIsOpen(false) })
1367
1586
  ] });
1368
1587
  }
1369
1588
  function SettingsPanel({ onClose }) {
1370
- return /* @__PURE__ */ jsxs6("div", { css: styles6.overlay, children: [
1371
- /* @__PURE__ */ jsx6("div", { css: styles6.backdrop, onClick: onClose }),
1372
- /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1373
- /* @__PURE__ */ jsxs6("div", { css: styles6.header, children: [
1374
- /* @__PURE__ */ jsx6("h2", { css: styles6.title, children: "Settings" }),
1375
- /* @__PURE__ */ jsx6("button", { css: styles6.closeBtn, onClick: onClose, children: /* @__PURE__ */ jsx6("svg", { css: styles6.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx6("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
1589
+ return /* @__PURE__ */ jsxs7("div", { css: styles7.overlay, children: [
1590
+ /* @__PURE__ */ jsx7("div", { css: styles7.backdrop, onClick: onClose }),
1591
+ /* @__PURE__ */ jsxs7("div", { css: styles7.panel, children: [
1592
+ /* @__PURE__ */ jsxs7("div", { css: styles7.header, children: [
1593
+ /* @__PURE__ */ jsx7("h2", { css: styles7.title, children: "Settings" }),
1594
+ /* @__PURE__ */ jsx7("button", { css: styles7.closeBtn, onClick: onClose, children: /* @__PURE__ */ jsx7("svg", { css: styles7.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ jsx7("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
1376
1595
  ] }),
1377
- /* @__PURE__ */ jsxs6("div", { css: styles6.sections, children: [
1378
- /* @__PURE__ */ jsxs6("section", { children: [
1379
- /* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Cloudflare R2" }),
1380
- /* @__PURE__ */ jsx6("p", { css: styles6.description, children: "Configure in .env.local file:" }),
1381
- /* @__PURE__ */ jsxs6("div", { css: styles6.code, children: [
1382
- /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID" }),
1383
- /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID" }),
1384
- /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY" }),
1385
- /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME" }),
1386
- /* @__PURE__ */ jsx6("p", { css: styles6.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL" })
1596
+ /* @__PURE__ */ jsxs7("div", { css: styles7.sections, children: [
1597
+ /* @__PURE__ */ jsxs7("section", { children: [
1598
+ /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Cloudflare R2" }),
1599
+ /* @__PURE__ */ jsx7("p", { css: styles7.description, children: "Configure in .env.local file:" }),
1600
+ /* @__PURE__ */ jsxs7("div", { css: styles7.code, children: [
1601
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID" }),
1602
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID" }),
1603
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY" }),
1604
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME" }),
1605
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL" })
1387
1606
  ] })
1388
1607
  ] }),
1389
- /* @__PURE__ */ jsxs6("section", { children: [
1390
- /* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Custom CDN URL" }),
1391
- /* @__PURE__ */ jsx6("p", { css: styles6.description, children: "Override the default R2 URL with a custom domain:" }),
1392
- /* @__PURE__ */ jsx6("input", { css: styles6.input, type: "text", placeholder: "https://cdn.yourdomain.com" })
1608
+ /* @__PURE__ */ jsxs7("section", { children: [
1609
+ /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Custom CDN URL" }),
1610
+ /* @__PURE__ */ jsx7("p", { css: styles7.description, children: "Override the default R2 URL with a custom domain:" }),
1611
+ /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "text", placeholder: "https://cdn.yourdomain.com" })
1393
1612
  ] }),
1394
- /* @__PURE__ */ jsxs6("section", { children: [
1395
- /* @__PURE__ */ jsx6("h3", { css: styles6.sectionTitle, children: "Thumbnail Sizes" }),
1396
- /* @__PURE__ */ jsxs6("div", { css: styles6.grid, children: [
1397
- /* @__PURE__ */ jsxs6("div", { children: [
1398
- /* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Small" }),
1399
- /* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 300 })
1613
+ /* @__PURE__ */ jsxs7("section", { children: [
1614
+ /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Thumbnail Sizes" }),
1615
+ /* @__PURE__ */ jsxs7("div", { css: styles7.grid, children: [
1616
+ /* @__PURE__ */ jsxs7("div", { children: [
1617
+ /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Small" }),
1618
+ /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 300 })
1400
1619
  ] }),
1401
- /* @__PURE__ */ jsxs6("div", { children: [
1402
- /* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Medium" }),
1403
- /* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 700 })
1620
+ /* @__PURE__ */ jsxs7("div", { children: [
1621
+ /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Medium" }),
1622
+ /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 700 })
1404
1623
  ] }),
1405
- /* @__PURE__ */ jsxs6("div", { children: [
1406
- /* @__PURE__ */ jsx6("label", { css: styles6.label, children: "Large" }),
1407
- /* @__PURE__ */ jsx6("input", { css: styles6.input, type: "number", defaultValue: 1400 })
1624
+ /* @__PURE__ */ jsxs7("div", { children: [
1625
+ /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Large" }),
1626
+ /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 1400 })
1408
1627
  ] })
1409
1628
  ] })
1410
1629
  ] })
1411
1630
  ] }),
1412
- /* @__PURE__ */ jsxs6("div", { css: styles6.footer, children: [
1413
- /* @__PURE__ */ jsx6("button", { css: styles6.cancelBtn, onClick: onClose, children: "Cancel" }),
1414
- /* @__PURE__ */ jsx6("button", { css: styles6.saveBtn, children: "Save Changes" })
1631
+ /* @__PURE__ */ jsxs7("div", { css: styles7.footer, children: [
1632
+ /* @__PURE__ */ jsx7("button", { css: styles7.cancelBtn, onClick: onClose, children: "Cancel" }),
1633
+ /* @__PURE__ */ jsx7("button", { css: styles7.saveBtn, children: "Save Changes" })
1415
1634
  ] })
1416
1635
  ] })
1417
1636
  ] });
1418
1637
  }
1419
1638
 
1420
1639
  // src/components/StudioUI.tsx
1421
- import { jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
1422
- var styles7 = {
1423
- container: css7`
1640
+ import { jsx as jsx8, jsxs as jsxs8 } from "@emotion/react/jsx-runtime";
1641
+ var styles8 = {
1642
+ container: css8`
1424
1643
  display: flex;
1425
1644
  flex-direction: column;
1426
1645
  height: 100%;
1427
1646
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1428
1647
  `,
1429
- header: css7`
1648
+ header: css8`
1430
1649
  display: flex;
1431
1650
  align-items: center;
1432
1651
  justify-content: space-between;
1433
1652
  padding: 16px 24px;
1434
1653
  border-bottom: 1px solid #e5e7eb;
1435
1654
  `,
1436
- title: css7`
1655
+ title: css8`
1437
1656
  font-size: 20px;
1438
1657
  font-weight: 600;
1439
1658
  color: #111827;
1440
1659
  margin: 0;
1441
1660
  `,
1442
- headerActions: css7`
1661
+ headerActions: css8`
1443
1662
  display: flex;
1444
1663
  align-items: center;
1445
1664
  gap: 8px;
1446
1665
  `,
1447
- closeBtn: css7`
1666
+ closeBtn: css8`
1448
1667
  padding: 8px;
1449
1668
  background: none;
1450
1669
  border: none;
@@ -1456,17 +1675,17 @@ var styles7 = {
1456
1675
  background-color: #f3f4f6;
1457
1676
  }
1458
1677
  `,
1459
- closeIcon: css7`
1678
+ closeIcon: css8`
1460
1679
  width: 20px;
1461
1680
  height: 20px;
1462
1681
  color: #6b7280;
1463
1682
  `,
1464
- content: css7`
1683
+ content: css8`
1465
1684
  flex: 1;
1466
1685
  display: flex;
1467
1686
  overflow: hidden;
1468
1687
  `,
1469
- fileBrowser: css7`
1688
+ fileBrowser: css8`
1470
1689
  flex: 1;
1471
1690
  min-width: 0;
1472
1691
  overflow: auto;
@@ -1474,13 +1693,13 @@ var styles7 = {
1474
1693
  `
1475
1694
  };
1476
1695
  function StudioUI({ onClose }) {
1477
- const [currentPath, setCurrentPathInternal] = useState5("public");
1478
- const [selectedItems, setSelectedItems] = useState5(/* @__PURE__ */ new Set());
1479
- const [lastSelectedPath, setLastSelectedPath] = useState5(null);
1480
- const [viewMode, setViewMode] = useState5("grid");
1481
- const [meta, setMeta] = useState5(null);
1482
- const [isLoading, setIsLoading] = useState5(false);
1483
- const [refreshKey, setRefreshKey] = useState5(0);
1696
+ const [currentPath, setCurrentPathInternal] = useState6("public");
1697
+ const [selectedItems, setSelectedItems] = useState6(/* @__PURE__ */ new Set());
1698
+ const [lastSelectedPath, setLastSelectedPath] = useState6(null);
1699
+ const [viewMode, setViewMode] = useState6("grid");
1700
+ const [meta, setMeta] = useState6(null);
1701
+ const [isLoading, setIsLoading] = useState6(false);
1702
+ const [refreshKey, setRefreshKey] = useState6(0);
1484
1703
  const triggerRefresh = useCallback2(() => {
1485
1704
  setRefreshKey((k) => k + 1);
1486
1705
  }, []);
@@ -1569,35 +1788,35 @@ function StudioUI({ onClose }) {
1569
1788
  refreshKey,
1570
1789
  triggerRefresh
1571
1790
  };
1572
- return /* @__PURE__ */ jsx7(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs7("div", { css: styles7.container, children: [
1573
- /* @__PURE__ */ jsxs7("div", { css: styles7.header, children: [
1574
- /* @__PURE__ */ jsx7("h1", { css: styles7.title, children: "Studio" }),
1575
- /* @__PURE__ */ jsxs7("div", { css: styles7.headerActions, children: [
1576
- /* @__PURE__ */ jsx7(StudioSettings, {}),
1577
- /* @__PURE__ */ jsx7(
1791
+ return /* @__PURE__ */ jsx8(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs8("div", { css: styles8.container, children: [
1792
+ /* @__PURE__ */ jsxs8("div", { css: styles8.header, children: [
1793
+ /* @__PURE__ */ jsx8("h1", { css: styles8.title, children: "Studio" }),
1794
+ /* @__PURE__ */ jsxs8("div", { css: styles8.headerActions, children: [
1795
+ /* @__PURE__ */ jsx8(StudioSettings, {}),
1796
+ /* @__PURE__ */ jsx8(
1578
1797
  "button",
1579
1798
  {
1580
- css: styles7.closeBtn,
1799
+ css: styles8.closeBtn,
1581
1800
  onClick: onClose,
1582
1801
  "aria-label": "Close Studio",
1583
- children: /* @__PURE__ */ jsx7(CloseIcon, {})
1802
+ children: /* @__PURE__ */ jsx8(CloseIcon, {})
1584
1803
  }
1585
1804
  )
1586
1805
  ] })
1587
1806
  ] }),
1588
- /* @__PURE__ */ jsx7(StudioToolbar, {}),
1589
- /* @__PURE__ */ jsx7(StudioBreadcrumb, {}),
1590
- /* @__PURE__ */ jsxs7("div", { css: styles7.content, children: [
1591
- /* @__PURE__ */ jsx7("div", { css: styles7.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx7(StudioFileGrid, {}) : /* @__PURE__ */ jsx7(StudioFileList, {}) }),
1592
- /* @__PURE__ */ jsx7(StudioPreview, {})
1807
+ /* @__PURE__ */ jsx8(StudioToolbar, {}),
1808
+ /* @__PURE__ */ jsx8(StudioBreadcrumb, {}),
1809
+ /* @__PURE__ */ jsxs8("div", { css: styles8.content, children: [
1810
+ /* @__PURE__ */ jsx8("div", { css: styles8.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx8(StudioFileGrid, {}) : /* @__PURE__ */ jsx8(StudioFileList, {}) }),
1811
+ /* @__PURE__ */ jsx8(StudioPreview, {})
1593
1812
  ] })
1594
1813
  ] }) });
1595
1814
  }
1596
1815
  function CloseIcon() {
1597
- return /* @__PURE__ */ jsxs7(
1816
+ return /* @__PURE__ */ jsxs8(
1598
1817
  "svg",
1599
1818
  {
1600
- css: styles7.closeIcon,
1819
+ css: styles8.closeIcon,
1601
1820
  xmlns: "http://www.w3.org/2000/svg",
1602
1821
  viewBox: "0 0 24 24",
1603
1822
  fill: "none",
@@ -1606,8 +1825,8 @@ function CloseIcon() {
1606
1825
  strokeLinecap: "round",
1607
1826
  strokeLinejoin: "round",
1608
1827
  children: [
1609
- /* @__PURE__ */ jsx7("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1610
- /* @__PURE__ */ jsx7("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1828
+ /* @__PURE__ */ jsx8("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1829
+ /* @__PURE__ */ jsx8("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1611
1830
  ]
1612
1831
  }
1613
1832
  );
@@ -1617,4 +1836,4 @@ export {
1617
1836
  StudioUI,
1618
1837
  StudioUI_default as default
1619
1838
  };
1620
- //# sourceMappingURL=StudioUI-2CBIV4Q5.mjs.map
1839
+ //# sourceMappingURL=StudioUI-5I7VRE4F.mjs.map