@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.
@@ -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,15 @@ 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;
674
+
675
+ &:hover {
676
+ border-color: #a855f7;
677
+ }
497
678
  `,
498
- checkbox: css3`
679
+ checkbox: css4`
499
680
  position: absolute;
500
681
  top: 8px;
501
682
  left: 8px;
@@ -504,7 +685,7 @@ var styles3 = {
504
685
  height: 16px;
505
686
  accent-color: #9333ea;
506
687
  `,
507
- cdnBadge: css3`
688
+ cdnBadge: css4`
508
689
  position: absolute;
509
690
  top: 8px;
510
691
  right: 8px;
@@ -515,30 +696,30 @@ var styles3 = {
515
696
  padding: 2px 6px;
516
697
  border-radius: 9999px;
517
698
  `,
518
- content: css3`
699
+ content: css4`
519
700
  aspect-ratio: 1;
520
701
  display: flex;
521
702
  align-items: center;
522
703
  justify-content: center;
523
704
  padding: 16px;
524
705
  `,
525
- folderIcon: css3`
706
+ folderIcon: css4`
526
707
  width: 64px;
527
708
  height: 64px;
528
709
  color: #facc15;
529
710
  `,
530
- image: css3`
711
+ image: css4`
531
712
  max-width: 100%;
532
713
  max-height: 100%;
533
714
  object-fit: contain;
534
715
  border-radius: 4px;
535
716
  `,
536
- label: css3`
717
+ label: css4`
537
718
  padding: 6px 8px;
538
719
  background-color: white;
539
720
  border-top: 1px solid #e5e7eb;
540
721
  `,
541
- name: css3`
722
+ name: css4`
542
723
  font-size: 12px;
543
724
  color: #374151;
544
725
  white-space: nowrap;
@@ -546,19 +727,19 @@ var styles3 = {
546
727
  text-overflow: ellipsis;
547
728
  margin: 0;
548
729
  `,
549
- size: css3`
730
+ size: css4`
550
731
  font-size: 12px;
551
732
  color: #9ca3af;
552
733
  margin: 0;
553
734
  `,
554
- selectAllRow: css3`
735
+ selectAllRow: css4`
555
736
  display: flex;
556
737
  align-items: center;
557
738
  margin-bottom: 12px;
558
739
  padding-bottom: 12px;
559
740
  border-bottom: 1px solid #e5e7eb;
560
741
  `,
561
- selectAllLabel: css3`
742
+ selectAllLabel: css4`
562
743
  display: flex;
563
744
  align-items: center;
564
745
  gap: 8px;
@@ -570,7 +751,7 @@ var styles3 = {
570
751
  color: #374151;
571
752
  }
572
753
  `,
573
- selectAllCheckbox: css3`
754
+ selectAllCheckbox: css4`
574
755
  width: 16px;
575
756
  height: 16px;
576
757
  accent-color: #9333ea;
@@ -597,13 +778,13 @@ function StudioFileGrid() {
597
778
  loadItems();
598
779
  }, [currentPath, refreshKey]);
599
780
  if (loading) {
600
- return /* @__PURE__ */ jsx3("div", { css: styles3.loading, children: /* @__PURE__ */ jsx3("div", { css: styles3.spinner }) });
781
+ return /* @__PURE__ */ jsx4("div", { css: styles4.loading, children: /* @__PURE__ */ jsx4("div", { css: styles4.spinner }) });
601
782
  }
602
783
  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" })
784
+ return /* @__PURE__ */ jsxs4("div", { css: styles4.empty, children: [
785
+ /* @__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" }) }),
786
+ /* @__PURE__ */ jsx4("p", { css: styles4.emptyText, children: "No files in this folder" }),
787
+ /* @__PURE__ */ jsx4("p", { css: styles4.emptyText, children: "Upload images to get started" })
607
788
  ] });
608
789
  }
609
790
  const sortedItems = [...items].sort((a, b) => {
@@ -632,13 +813,13 @@ function StudioFileGrid() {
632
813
  toggleSelection(item.path);
633
814
  }
634
815
  };
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(
816
+ return /* @__PURE__ */ jsxs4("div", { children: [
817
+ files.length > 0 && /* @__PURE__ */ jsx4("div", { css: styles4.selectAllRow, children: /* @__PURE__ */ jsxs4("label", { css: styles4.selectAllLabel, children: [
818
+ /* @__PURE__ */ jsx4(
638
819
  "input",
639
820
  {
640
821
  type: "checkbox",
641
- css: styles3.selectAllCheckbox,
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__ */ jsx3("div", { css: styles3.grid, children: sortedItems.map((item) => /* @__PURE__ */ jsx3(
834
+ /* @__PURE__ */ jsx4("div", { css: styles4.grid, children: sortedItems.map((item) => /* @__PURE__ */ jsx4(
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__ */ jsxs3("div", { css: [styles3.item, isSelected && styles3.itemSelected], onClick, children: [
667
- !isFolder && /* @__PURE__ */ jsx3(
847
+ return /* @__PURE__ */ jsxs4("div", { css: [styles4.item, isSelected && styles4.itemSelected], onClick, children: [
848
+ !isFolder && /* @__PURE__ */ jsx4(
668
849
  "input",
669
850
  {
670
851
  type: "checkbox",
671
- css: styles3.checkbox,
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__ */ 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(
859
+ item.cdnSynced && /* @__PURE__ */ jsx4("span", { css: styles4.cdnBadge, children: "CDN" }),
860
+ /* @__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
861
  "img",
681
862
  {
682
- css: styles3.image,
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__ */ 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) })
869
+ /* @__PURE__ */ jsxs4("div", { css: styles4.label, children: [
870
+ /* @__PURE__ */ jsx4("p", { css: styles4.name, title: item.name, children: item.name }),
871
+ item.size && /* @__PURE__ */ jsx4("p", { css: styles4.size, children: formatFileSize(item.size) })
691
872
  ] })
692
873
  ] });
693
874
  }
@@ -699,19 +880,19 @@ function formatFileSize(bytes) {
699
880
 
700
881
  // src/components/StudioFileList.tsx
701
882
  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`
883
+ import { css as css5, keyframes as keyframes3 } from "@emotion/react";
884
+ import { jsx as jsx5, jsxs as jsxs5 } from "@emotion/react/jsx-runtime";
885
+ var spin2 = keyframes3`
705
886
  to { transform: rotate(360deg); }
706
887
  `;
707
- var styles4 = {
708
- loading: css4`
888
+ var styles5 = {
889
+ loading: css5`
709
890
  display: flex;
710
891
  align-items: center;
711
892
  justify-content: center;
712
893
  height: 256px;
713
894
  `,
714
- spinner: css4`
895
+ spinner: css5`
715
896
  width: 32px;
716
897
  height: 32px;
717
898
  border-radius: 50%;
@@ -719,7 +900,7 @@ var styles4 = {
719
900
  border-bottom-color: #9333ea;
720
901
  animation: ${spin2} 1s linear infinite;
721
902
  `,
722
- empty: css4`
903
+ empty: css5`
723
904
  display: flex;
724
905
  flex-direction: column;
725
906
  align-items: center;
@@ -727,11 +908,11 @@ var styles4 = {
727
908
  height: 256px;
728
909
  color: #6b7280;
729
910
  `,
730
- table: css4`
911
+ table: css5`
731
912
  width: 100%;
732
913
  border-collapse: collapse;
733
914
  `,
734
- th: css4`
915
+ th: css5`
735
916
  text-align: left;
736
917
  font-size: 12px;
737
918
  color: #6b7280;
@@ -740,22 +921,22 @@ var styles4 = {
740
921
  padding-bottom: 8px;
741
922
  font-weight: normal;
742
923
  `,
743
- thCheckbox: css4`
924
+ thCheckbox: css5`
744
925
  width: 32px;
745
926
  `,
746
- thSize: css4`
927
+ thSize: css5`
747
928
  width: 96px;
748
929
  `,
749
- thDimensions: css4`
930
+ thDimensions: css5`
750
931
  width: 128px;
751
932
  `,
752
- thCdn: css4`
933
+ thCdn: css5`
753
934
  width: 96px;
754
935
  `,
755
- tbody: css4`
936
+ tbody: css5`
756
937
  border-top: 1px solid #f3f4f6;
757
938
  `,
758
- row: css4`
939
+ row: css5`
759
940
  cursor: pointer;
760
941
  transition: background-color 0.15s;
761
942
 
@@ -763,53 +944,57 @@ var styles4 = {
763
944
  background-color: #f9fafb;
764
945
  }
765
946
  `,
766
- rowSelected: css4`
947
+ rowSelected: css5`
767
948
  background-color: #faf5ff;
949
+
950
+ &:hover {
951
+ background-color: #faf5ff;
952
+ }
768
953
  `,
769
- td: css4`
954
+ td: css5`
770
955
  padding: 8px 0;
771
956
  border-bottom: 1px solid #f3f4f6;
772
957
  `,
773
- checkbox: css4`
958
+ checkbox: css5`
774
959
  width: 16px;
775
960
  height: 16px;
776
961
  accent-color: #9333ea;
777
962
  `,
778
- nameCell: css4`
963
+ nameCell: css5`
779
964
  display: flex;
780
965
  align-items: center;
781
966
  gap: 8px;
782
967
  `,
783
- folderIcon: css4`
968
+ folderIcon: css5`
784
969
  width: 20px;
785
970
  height: 20px;
786
971
  color: #facc15;
787
972
  `,
788
- fileIcon: css4`
973
+ fileIcon: css5`
789
974
  width: 20px;
790
975
  height: 20px;
791
976
  color: #9ca3af;
792
977
  `,
793
- name: css4`
978
+ name: css5`
794
979
  font-size: 14px;
795
980
  color: #111827;
796
981
  `,
797
- meta: css4`
982
+ meta: css5`
798
983
  font-size: 14px;
799
984
  color: #6b7280;
800
985
  `,
801
- cdnBadge: css4`
986
+ cdnBadge: css5`
802
987
  display: inline-flex;
803
988
  align-items: center;
804
989
  gap: 4px;
805
990
  font-size: 12px;
806
991
  color: #15803d;
807
992
  `,
808
- cdnIcon: css4`
993
+ cdnIcon: css5`
809
994
  width: 12px;
810
995
  height: 12px;
811
996
  `,
812
- cdnEmpty: css4`
997
+ cdnEmpty: css5`
813
998
  font-size: 12px;
814
999
  color: #9ca3af;
815
1000
  `
@@ -835,10 +1020,10 @@ function StudioFileList() {
835
1020
  loadItems();
836
1021
  }, [currentPath, refreshKey]);
837
1022
  if (loading) {
838
- return /* @__PURE__ */ jsx4("div", { css: styles4.loading, children: /* @__PURE__ */ jsx4("div", { css: styles4.spinner }) });
1023
+ return /* @__PURE__ */ jsx5("div", { css: styles5.loading, children: /* @__PURE__ */ jsx5("div", { css: styles5.spinner }) });
839
1024
  }
840
1025
  if (items.length === 0) {
841
- return /* @__PURE__ */ jsx4("div", { css: styles4.empty, children: /* @__PURE__ */ jsx4("p", { children: "No files in this folder" }) });
1026
+ return /* @__PURE__ */ jsx5("div", { css: styles5.empty, children: /* @__PURE__ */ jsx5("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__ */ 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(
1054
+ return /* @__PURE__ */ jsxs5("table", { css: styles5.table, children: [
1055
+ /* @__PURE__ */ jsx5("thead", { children: /* @__PURE__ */ jsxs5("tr", { children: [
1056
+ /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thCheckbox], children: files.length > 0 && /* @__PURE__ */ jsx5(
872
1057
  "input",
873
1058
  {
874
1059
  type: "checkbox",
875
- css: styles4.checkbox,
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__ */ 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" })
1068
+ /* @__PURE__ */ jsx5("th", { css: styles5.th, children: "Name" }),
1069
+ /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thSize], children: "Size" }),
1070
+ /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thDimensions], children: "Dimensions" }),
1071
+ /* @__PURE__ */ jsx5("th", { css: [styles5.th, styles5.thCdn], children: "CDN" })
887
1072
  ] }) }),
888
- /* @__PURE__ */ jsx4("tbody", { css: styles4.tbody, children: sortedItems.map((item) => /* @__PURE__ */ jsx4(
1073
+ /* @__PURE__ */ jsx5("tbody", { css: styles5.tbody, children: sortedItems.map((item) => /* @__PURE__ */ jsx5(
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__ */ jsxs4("tr", { css: [styles4.row, isSelected && styles4.rowSelected], onClick, children: [
902
- /* @__PURE__ */ jsx4("td", { css: styles4.td, children: !isFolder && /* @__PURE__ */ jsx4(
1086
+ return /* @__PURE__ */ jsxs5("tr", { css: [styles5.row, isSelected && styles5.rowSelected], onClick, children: [
1087
+ /* @__PURE__ */ jsx5("td", { css: styles5.td, children: !isFolder && /* @__PURE__ */ jsx5(
903
1088
  "input",
904
1089
  {
905
1090
  type: "checkbox",
906
- css: styles4.checkbox,
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__ */ 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 })
1098
+ /* @__PURE__ */ jsx5("td", { css: styles5.td, children: /* @__PURE__ */ jsxs5("div", { css: styles5.nameCell, children: [
1099
+ 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" }) }),
1100
+ /* @__PURE__ */ jsx5("span", { css: styles5.name, children: item.name })
916
1101
  ] }) }),
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" }) }),
1102
+ /* @__PURE__ */ jsx5("td", { css: [styles5.td, styles5.meta], children: item.size ? formatFileSize2(item.size) : "--" }),
1103
+ /* @__PURE__ */ jsx5("td", { css: [styles5.td, styles5.meta], children: item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
1104
+ /* @__PURE__ */ jsx5("td", { css: styles5.td, children: item.cdnSynced ? /* @__PURE__ */ jsxs5("span", { css: styles5.cdnBadge, children: [
1105
+ /* @__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
1106
  "Synced"
922
- ] }) : /* @__PURE__ */ jsx4("span", { css: styles4.cdnEmpty, children: "--" }) })
1107
+ ] }) : /* @__PURE__ */ jsx5("span", { css: styles5.cdnEmpty, children: "--" }) })
923
1108
  ] });
924
1109
  }
925
1110
  function formatFileSize2(bytes) {
@@ -929,78 +1114,79 @@ function formatFileSize2(bytes) {
929
1114
  }
930
1115
 
931
1116
  // 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`
1117
+ import { useState as useState4 } from "react";
1118
+ import { css as css6 } from "@emotion/react";
1119
+ import { Fragment as Fragment2, jsx as jsx6, jsxs as jsxs6 } from "@emotion/react/jsx-runtime";
1120
+ var styles6 = {
1121
+ panel: css6`
936
1122
  width: 320px;
937
1123
  border-left: 1px solid #e5e7eb;
938
1124
  background-color: #f9fafb;
939
1125
  padding: 16px;
940
1126
  overflow: auto;
941
1127
  `,
942
- title: css5`
1128
+ title: css6`
943
1129
  font-size: 14px;
944
1130
  font-weight: 500;
945
1131
  color: #111827;
946
1132
  margin: 0 0 16px 0;
947
1133
  `,
948
- imageContainer: css5`
1134
+ imageContainer: css6`
949
1135
  background-color: white;
950
1136
  border-radius: 8px;
951
1137
  border: 1px solid #e5e7eb;
952
1138
  padding: 8px;
953
1139
  margin-bottom: 16px;
954
1140
  `,
955
- image: css5`
1141
+ image: css6`
956
1142
  width: 100%;
957
1143
  height: auto;
958
1144
  border-radius: 4px;
959
1145
  `,
960
- info: css5`
1146
+ info: css6`
961
1147
  display: flex;
962
1148
  flex-direction: column;
963
1149
  gap: 12px;
964
1150
  `,
965
- row: css5`
1151
+ row: css6`
966
1152
  display: flex;
967
1153
  justify-content: space-between;
968
1154
  font-size: 12px;
969
1155
  `,
970
- label: css5`
1156
+ label: css6`
971
1157
  color: #6b7280;
972
1158
  `,
973
- value: css5`
1159
+ value: css6`
974
1160
  color: #111827;
975
1161
  `,
976
- valueTruncate: css5`
1162
+ valueTruncate: css6`
977
1163
  max-width: 128px;
978
1164
  white-space: nowrap;
979
1165
  overflow: hidden;
980
1166
  text-overflow: ellipsis;
981
1167
  `,
982
- section: css5`
1168
+ section: css6`
983
1169
  padding-top: 8px;
984
1170
  border-top: 1px solid #e5e7eb;
985
1171
  `,
986
- sectionTitle: css5`
1172
+ sectionTitle: css6`
987
1173
  font-size: 12px;
988
1174
  font-weight: 500;
989
1175
  color: #6b7280;
990
1176
  margin: 0 0 8px 0;
991
1177
  `,
992
- cdnStatus: css5`
1178
+ cdnStatus: css6`
993
1179
  display: flex;
994
1180
  align-items: center;
995
1181
  gap: 8px;
996
1182
  font-size: 12px;
997
1183
  color: #16a34a;
998
1184
  `,
999
- cdnIcon: css5`
1185
+ cdnIcon: css6`
1000
1186
  width: 16px;
1001
1187
  height: 16px;
1002
1188
  `,
1003
- copyBtn: css5`
1189
+ copyBtn: css6`
1004
1190
  margin-top: 8px;
1005
1191
  font-size: 12px;
1006
1192
  color: #9333ea;
@@ -1013,23 +1199,23 @@ var styles5 = {
1013
1199
  text-decoration: underline;
1014
1200
  }
1015
1201
  `,
1016
- colorSwatch: css5`
1202
+ colorSwatch: css6`
1017
1203
  margin-top: 8px;
1018
1204
  height: 32px;
1019
1205
  border-radius: 4px;
1020
1206
  `,
1021
- emptyState: css5`
1207
+ emptyState: css6`
1022
1208
  display: flex;
1023
1209
  align-items: center;
1024
1210
  justify-content: center;
1025
1211
  height: 200px;
1026
1212
  `,
1027
- emptyText: css5`
1213
+ emptyText: css6`
1028
1214
  font-size: 14px;
1029
1215
  color: #9ca3af;
1030
1216
  margin: 0;
1031
1217
  `,
1032
- actions: css5`
1218
+ actions: css6`
1033
1219
  margin-top: 16px;
1034
1220
  padding-top: 16px;
1035
1221
  border-top: 1px solid #e5e7eb;
@@ -1037,7 +1223,7 @@ var styles5 = {
1037
1223
  flex-direction: column;
1038
1224
  gap: 8px;
1039
1225
  `,
1040
- actionBtn: css5`
1226
+ actionBtn: css6`
1041
1227
  width: 100%;
1042
1228
  padding: 8px 12px;
1043
1229
  font-size: 14px;
@@ -1052,7 +1238,7 @@ var styles5 = {
1052
1238
  background-color: #f9fafb;
1053
1239
  }
1054
1240
  `,
1055
- actionBtnDanger: css5`
1241
+ actionBtnDanger: css6`
1056
1242
  color: #dc2626;
1057
1243
 
1058
1244
  &:hover {
@@ -1062,9 +1248,14 @@ var styles5 = {
1062
1248
  };
1063
1249
  function StudioPreview() {
1064
1250
  const { selectedItems, meta, triggerRefresh, clearSelection } = useStudio();
1065
- const handleDelete = async () => {
1251
+ const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
1252
+ const [alertMessage, setAlertMessage] = useState4(null);
1253
+ const handleDeleteClick = () => {
1066
1254
  if (selectedItems.size === 0) return;
1067
- if (!confirm(`Delete ${selectedItems.size} item(s)?`)) return;
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
- alert(`Delete failed: ${error.error || "Unknown error"}`);
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
- alert("Delete failed. Check console for details.");
1277
+ setAlertMessage({
1278
+ title: "Delete Failed",
1279
+ message: "Delete failed. Check console for details."
1280
+ });
1084
1281
  }
1085
1282
  };
1283
+ const modals = /* @__PURE__ */ jsxs6(Fragment2, { children: [
1284
+ showDeleteConfirm && /* @__PURE__ */ jsx6(
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__ */ jsx6(
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__ */ 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" }) })
1305
+ return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1306
+ modals,
1307
+ /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1308
+ /* @__PURE__ */ jsx6("h3", { css: styles6.title, children: "Preview" }),
1309
+ /* @__PURE__ */ jsx6("div", { css: styles6.emptyState, children: /* @__PURE__ */ jsx6("p", { css: styles6.emptyText, children: "Select an image to preview" }) })
1310
+ ] })
1090
1311
  ] });
1091
1312
  }
1092
1313
  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
- ] }) })
1314
+ return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1315
+ modals,
1316
+ /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1317
+ /* @__PURE__ */ jsxs6("h3", { css: styles6.title, children: [
1318
+ selectedItems.size,
1319
+ " items selected"
1320
+ ] }),
1321
+ /* @__PURE__ */ jsx6("div", { css: styles6.actions, children: /* @__PURE__ */ jsxs6("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 = 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",
1332
+ return /* @__PURE__ */ jsxs6(Fragment2, { children: [
1333
+ modals,
1334
+ /* @__PURE__ */ jsxs6("div", { css: styles6.panel, children: [
1335
+ /* @__PURE__ */ jsx6("h3", { css: styles6.title, children: "Preview" }),
1336
+ /* @__PURE__ */ jsx6("div", { css: styles6.imageContainer, children: /* @__PURE__ */ jsx6(
1337
+ "img",
1338
+ {
1339
+ css: styles6.image,
1340
+ src: selectedPath.replace("public", ""),
1341
+ alt: "Preview"
1342
+ }
1343
+ ) }),
1344
+ /* @__PURE__ */ jsxs6("div", { css: styles6.info, children: [
1345
+ /* @__PURE__ */ jsx6(InfoRow, { label: "Filename", value: selectedPath.split("/").pop() || "" }),
1346
+ imageData && /* @__PURE__ */ jsxs6(Fragment2, { children: [
1347
+ /* @__PURE__ */ jsx6(
1348
+ InfoRow,
1147
1349
  {
1148
- css: styles5.copyBtn,
1149
- onClick: () => {
1150
- navigator.clipboard.writeText(`${imageData.cdn?.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__ */ jsxs5("div", { css: styles5.section, children: [
1157
- /* @__PURE__ */ jsx5(InfoRow, { label: "Blurhash", value: imageData.blurhash, truncate: true }),
1158
- /* @__PURE__ */ jsx5(
1159
- "div",
1353
+ ),
1354
+ /* @__PURE__ */ jsx6(
1355
+ InfoRow,
1160
1356
  {
1161
- css: styles5.colorSwatch,
1162
- style: { backgroundColor: imageData.dominantColor },
1163
- title: `Dominant color: ${imageData.dominantColor}`
1357
+ label: "File size",
1358
+ value: formatFileSize3(imageData.original.fileSize)
1164
1359
  }
1165
- )
1360
+ ),
1361
+ /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1362
+ /* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "Generated sizes" }),
1363
+ Object.entries(imageData.sizes).map(([size, data]) => /* @__PURE__ */ jsx6(InfoRow, { label: size, value: `${data.width}x${data.height}` }, size))
1364
+ ] }),
1365
+ imageData.cdn?.synced && /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1366
+ /* @__PURE__ */ jsx6("p", { css: styles6.sectionTitle, children: "CDN" }),
1367
+ /* @__PURE__ */ jsxs6("div", { css: styles6.cdnStatus, children: [
1368
+ /* @__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" }) }),
1369
+ "Synced to CDN"
1370
+ ] }),
1371
+ /* @__PURE__ */ jsx6(
1372
+ "button",
1373
+ {
1374
+ css: styles6.copyBtn,
1375
+ onClick: () => {
1376
+ navigator.clipboard.writeText(`${imageData.cdn?.baseUrl}${imageData.sizes.full.path}`);
1377
+ },
1378
+ children: "Copy CDN URL"
1379
+ }
1380
+ )
1381
+ ] }),
1382
+ imageData.blurhash && /* @__PURE__ */ jsxs6("div", { css: styles6.section, children: [
1383
+ /* @__PURE__ */ jsx6(InfoRow, { label: "Blurhash", value: imageData.blurhash, truncate: true }),
1384
+ /* @__PURE__ */ jsx6(
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__ */ jsxs6("div", { css: styles6.actions, children: [
1396
+ /* @__PURE__ */ jsx6("button", { css: styles6.actionBtn, children: "Rename" }),
1397
+ /* @__PURE__ */ jsx6("button", { css: [styles6.actionBtn, styles6.actionBtnDanger], onClick: handleDeleteClick, children: "Delete" })
1167
1398
  ] })
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
1399
  ] })
1173
1400
  ] });
1174
1401
  }
1175
1402
  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 })
1403
+ return /* @__PURE__ */ jsxs6("div", { css: styles6.row, children: [
1404
+ /* @__PURE__ */ jsx6("span", { css: styles6.label, children: label }),
1405
+ /* @__PURE__ */ jsx6("span", { css: [styles6.value, truncate && styles6.valueTruncate], title: truncate ? value : void 0, children: value })
1179
1406
  ] });
1180
1407
  }
1181
1408
  function formatFileSize3(bytes) {
@@ -1185,11 +1412,11 @@ function formatFileSize3(bytes) {
1185
1412
  }
1186
1413
 
1187
1414
  // 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`
1415
+ import { useState as useState5 } from "react";
1416
+ import { css as css7 } from "@emotion/react";
1417
+ import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
1418
+ var styles7 = {
1419
+ btn: css7`
1193
1420
  padding: 8px;
1194
1421
  background: none;
1195
1422
  border: none;
@@ -1201,12 +1428,12 @@ var styles6 = {
1201
1428
  background-color: #f3f4f6;
1202
1429
  }
1203
1430
  `,
1204
- icon: css6`
1431
+ icon: css7`
1205
1432
  width: 20px;
1206
1433
  height: 20px;
1207
1434
  color: #6b7280;
1208
1435
  `,
1209
- overlay: css6`
1436
+ overlay: css7`
1210
1437
  position: fixed;
1211
1438
  top: 0;
1212
1439
  right: 0;
@@ -1217,7 +1444,7 @@ var styles6 = {
1217
1444
  align-items: center;
1218
1445
  justify-content: center;
1219
1446
  `,
1220
- backdrop: css6`
1447
+ backdrop: css7`
1221
1448
  position: absolute;
1222
1449
  top: 0;
1223
1450
  right: 0;
@@ -1225,7 +1452,7 @@ var styles6 = {
1225
1452
  left: 0;
1226
1453
  background-color: rgba(0, 0, 0, 0.3);
1227
1454
  `,
1228
- panel: css6`
1455
+ panel: css7`
1229
1456
  position: relative;
1230
1457
  background-color: white;
1231
1458
  border-radius: 12px;
@@ -1234,18 +1461,18 @@ var styles6 = {
1234
1461
  max-width: 512px;
1235
1462
  padding: 24px;
1236
1463
  `,
1237
- header: css6`
1464
+ header: css7`
1238
1465
  display: flex;
1239
1466
  align-items: center;
1240
1467
  justify-content: space-between;
1241
1468
  margin-bottom: 24px;
1242
1469
  `,
1243
- title: css6`
1470
+ title: css7`
1244
1471
  font-size: 18px;
1245
1472
  font-weight: 600;
1246
1473
  margin: 0;
1247
1474
  `,
1248
- closeBtn: css6`
1475
+ closeBtn: css7`
1249
1476
  padding: 4px;
1250
1477
  background: none;
1251
1478
  border: none;
@@ -1256,23 +1483,23 @@ var styles6 = {
1256
1483
  background-color: #f3f4f6;
1257
1484
  }
1258
1485
  `,
1259
- sections: css6`
1486
+ sections: css7`
1260
1487
  display: flex;
1261
1488
  flex-direction: column;
1262
1489
  gap: 24px;
1263
1490
  `,
1264
- sectionTitle: css6`
1491
+ sectionTitle: css7`
1265
1492
  font-size: 14px;
1266
1493
  font-weight: 500;
1267
1494
  color: #111827;
1268
1495
  margin: 0 0 12px 0;
1269
1496
  `,
1270
- description: css6`
1497
+ description: css7`
1271
1498
  font-size: 12px;
1272
1499
  color: #6b7280;
1273
1500
  margin: 0 0 12px 0;
1274
1501
  `,
1275
- code: css6`
1502
+ code: css7`
1276
1503
  background-color: #f9fafb;
1277
1504
  border-radius: 8px;
1278
1505
  padding: 12px;
@@ -1280,14 +1507,14 @@ var styles6 = {
1280
1507
  font-size: 12px;
1281
1508
  color: #4b5563;
1282
1509
  `,
1283
- codeLine: css6`
1510
+ codeLine: css7`
1284
1511
  margin: 0 0 4px 0;
1285
1512
 
1286
1513
  &:last-child {
1287
1514
  margin: 0;
1288
1515
  }
1289
1516
  `,
1290
- input: css6`
1517
+ input: css7`
1291
1518
  width: 100%;
1292
1519
  padding: 8px 12px;
1293
1520
  border: 1px solid #e5e7eb;
@@ -1299,24 +1526,24 @@ var styles6 = {
1299
1526
  box-shadow: 0 0 0 2px #a855f7;
1300
1527
  }
1301
1528
  `,
1302
- grid: css6`
1529
+ grid: css7`
1303
1530
  display: grid;
1304
1531
  grid-template-columns: repeat(3, 1fr);
1305
1532
  gap: 12px;
1306
1533
  `,
1307
- label: css6`
1534
+ label: css7`
1308
1535
  font-size: 12px;
1309
1536
  color: #6b7280;
1310
1537
  display: block;
1311
1538
  margin-bottom: 4px;
1312
1539
  `,
1313
- footer: css6`
1540
+ footer: css7`
1314
1541
  margin-top: 24px;
1315
1542
  display: flex;
1316
1543
  justify-content: flex-end;
1317
1544
  gap: 12px;
1318
1545
  `,
1319
- cancelBtn: css6`
1546
+ cancelBtn: css7`
1320
1547
  padding: 8px 16px;
1321
1548
  font-size: 14px;
1322
1549
  color: #4b5563;
@@ -1329,7 +1556,7 @@ var styles6 = {
1329
1556
  background-color: #f3f4f6;
1330
1557
  }
1331
1558
  `,
1332
- saveBtn: css6`
1559
+ saveBtn: css7`
1333
1560
  padding: 8px 16px;
1334
1561
  font-size: 14px;
1335
1562
  color: white;
@@ -1344,12 +1571,12 @@ var styles6 = {
1344
1571
  `
1345
1572
  };
1346
1573
  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(
1574
+ const [isOpen, setIsOpen] = useState5(false);
1575
+ return /* @__PURE__ */ jsxs7(Fragment3, { children: [
1576
+ /* @__PURE__ */ jsx7("button", { css: styles7.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ jsxs7(
1350
1577
  "svg",
1351
1578
  {
1352
- css: styles6.icon,
1579
+ css: styles7.icon,
1353
1580
  xmlns: "http://www.w3.org/2000/svg",
1354
1581
  viewBox: "0 0 24 24",
1355
1582
  fill: "none",
@@ -1358,93 +1585,93 @@ function StudioSettings() {
1358
1585
  strokeLinecap: "round",
1359
1586
  strokeLinejoin: "round",
1360
1587
  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" })
1588
+ /* @__PURE__ */ jsx7("circle", { cx: "12", cy: "12", r: "3" }),
1589
+ /* @__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
1590
  ]
1364
1591
  }
1365
1592
  ) }),
1366
- isOpen && /* @__PURE__ */ jsx6(SettingsPanel, { onClose: () => setIsOpen(false) })
1593
+ isOpen && /* @__PURE__ */ jsx7(SettingsPanel, { onClose: () => setIsOpen(false) })
1367
1594
  ] });
1368
1595
  }
1369
1596
  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" }) }) })
1597
+ return /* @__PURE__ */ jsxs7("div", { css: styles7.overlay, children: [
1598
+ /* @__PURE__ */ jsx7("div", { css: styles7.backdrop, onClick: onClose }),
1599
+ /* @__PURE__ */ jsxs7("div", { css: styles7.panel, children: [
1600
+ /* @__PURE__ */ jsxs7("div", { css: styles7.header, children: [
1601
+ /* @__PURE__ */ jsx7("h2", { css: styles7.title, children: "Settings" }),
1602
+ /* @__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
1603
  ] }),
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" })
1604
+ /* @__PURE__ */ jsxs7("div", { css: styles7.sections, children: [
1605
+ /* @__PURE__ */ jsxs7("section", { children: [
1606
+ /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Cloudflare R2" }),
1607
+ /* @__PURE__ */ jsx7("p", { css: styles7.description, children: "Configure in .env.local file:" }),
1608
+ /* @__PURE__ */ jsxs7("div", { css: styles7.code, children: [
1609
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID" }),
1610
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID" }),
1611
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY" }),
1612
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME" }),
1613
+ /* @__PURE__ */ jsx7("p", { css: styles7.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL" })
1387
1614
  ] })
1388
1615
  ] }),
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" })
1616
+ /* @__PURE__ */ jsxs7("section", { children: [
1617
+ /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Custom CDN URL" }),
1618
+ /* @__PURE__ */ jsx7("p", { css: styles7.description, children: "Override the default R2 URL with a custom domain:" }),
1619
+ /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "text", placeholder: "https://cdn.yourdomain.com" })
1393
1620
  ] }),
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 })
1621
+ /* @__PURE__ */ jsxs7("section", { children: [
1622
+ /* @__PURE__ */ jsx7("h3", { css: styles7.sectionTitle, children: "Thumbnail Sizes" }),
1623
+ /* @__PURE__ */ jsxs7("div", { css: styles7.grid, children: [
1624
+ /* @__PURE__ */ jsxs7("div", { children: [
1625
+ /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Small" }),
1626
+ /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 300 })
1400
1627
  ] }),
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 })
1628
+ /* @__PURE__ */ jsxs7("div", { children: [
1629
+ /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Medium" }),
1630
+ /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 700 })
1404
1631
  ] }),
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 })
1632
+ /* @__PURE__ */ jsxs7("div", { children: [
1633
+ /* @__PURE__ */ jsx7("label", { css: styles7.label, children: "Large" }),
1634
+ /* @__PURE__ */ jsx7("input", { css: styles7.input, type: "number", defaultValue: 1400 })
1408
1635
  ] })
1409
1636
  ] })
1410
1637
  ] })
1411
1638
  ] }),
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" })
1639
+ /* @__PURE__ */ jsxs7("div", { css: styles7.footer, children: [
1640
+ /* @__PURE__ */ jsx7("button", { css: styles7.cancelBtn, onClick: onClose, children: "Cancel" }),
1641
+ /* @__PURE__ */ jsx7("button", { css: styles7.saveBtn, children: "Save Changes" })
1415
1642
  ] })
1416
1643
  ] })
1417
1644
  ] });
1418
1645
  }
1419
1646
 
1420
1647
  // src/components/StudioUI.tsx
1421
- import { jsx as jsx7, jsxs as jsxs7 } from "@emotion/react/jsx-runtime";
1422
- var styles7 = {
1423
- container: css7`
1648
+ import { jsx as jsx8, jsxs as jsxs8 } from "@emotion/react/jsx-runtime";
1649
+ var styles8 = {
1650
+ container: css8`
1424
1651
  display: flex;
1425
1652
  flex-direction: column;
1426
1653
  height: 100%;
1427
1654
  font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
1428
1655
  `,
1429
- header: css7`
1656
+ header: css8`
1430
1657
  display: flex;
1431
1658
  align-items: center;
1432
1659
  justify-content: space-between;
1433
1660
  padding: 16px 24px;
1434
1661
  border-bottom: 1px solid #e5e7eb;
1435
1662
  `,
1436
- title: css7`
1663
+ title: css8`
1437
1664
  font-size: 20px;
1438
1665
  font-weight: 600;
1439
1666
  color: #111827;
1440
1667
  margin: 0;
1441
1668
  `,
1442
- headerActions: css7`
1669
+ headerActions: css8`
1443
1670
  display: flex;
1444
1671
  align-items: center;
1445
1672
  gap: 8px;
1446
1673
  `,
1447
- closeBtn: css7`
1674
+ closeBtn: css8`
1448
1675
  padding: 8px;
1449
1676
  background: none;
1450
1677
  border: none;
@@ -1456,17 +1683,17 @@ var styles7 = {
1456
1683
  background-color: #f3f4f6;
1457
1684
  }
1458
1685
  `,
1459
- closeIcon: css7`
1686
+ closeIcon: css8`
1460
1687
  width: 20px;
1461
1688
  height: 20px;
1462
1689
  color: #6b7280;
1463
1690
  `,
1464
- content: css7`
1691
+ content: css8`
1465
1692
  flex: 1;
1466
1693
  display: flex;
1467
1694
  overflow: hidden;
1468
1695
  `,
1469
- fileBrowser: css7`
1696
+ fileBrowser: css8`
1470
1697
  flex: 1;
1471
1698
  min-width: 0;
1472
1699
  overflow: auto;
@@ -1474,13 +1701,13 @@ var styles7 = {
1474
1701
  `
1475
1702
  };
1476
1703
  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);
1704
+ const [currentPath, setCurrentPathInternal] = useState6("public");
1705
+ const [selectedItems, setSelectedItems] = useState6(/* @__PURE__ */ new Set());
1706
+ const [lastSelectedPath, setLastSelectedPath] = useState6(null);
1707
+ const [viewMode, setViewMode] = useState6("grid");
1708
+ const [meta, setMeta] = useState6(null);
1709
+ const [isLoading, setIsLoading] = useState6(false);
1710
+ const [refreshKey, setRefreshKey] = useState6(0);
1484
1711
  const triggerRefresh = useCallback2(() => {
1485
1712
  setRefreshKey((k) => k + 1);
1486
1713
  }, []);
@@ -1569,35 +1796,35 @@ function StudioUI({ onClose }) {
1569
1796
  refreshKey,
1570
1797
  triggerRefresh
1571
1798
  };
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(
1799
+ return /* @__PURE__ */ jsx8(StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxs8("div", { css: styles8.container, children: [
1800
+ /* @__PURE__ */ jsxs8("div", { css: styles8.header, children: [
1801
+ /* @__PURE__ */ jsx8("h1", { css: styles8.title, children: "Studio" }),
1802
+ /* @__PURE__ */ jsxs8("div", { css: styles8.headerActions, children: [
1803
+ /* @__PURE__ */ jsx8(StudioSettings, {}),
1804
+ /* @__PURE__ */ jsx8(
1578
1805
  "button",
1579
1806
  {
1580
- css: styles7.closeBtn,
1807
+ css: styles8.closeBtn,
1581
1808
  onClick: onClose,
1582
1809
  "aria-label": "Close Studio",
1583
- children: /* @__PURE__ */ jsx7(CloseIcon, {})
1810
+ children: /* @__PURE__ */ jsx8(CloseIcon, {})
1584
1811
  }
1585
1812
  )
1586
1813
  ] })
1587
1814
  ] }),
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, {})
1815
+ /* @__PURE__ */ jsx8(StudioToolbar, {}),
1816
+ /* @__PURE__ */ jsx8(StudioBreadcrumb, {}),
1817
+ /* @__PURE__ */ jsxs8("div", { css: styles8.content, children: [
1818
+ /* @__PURE__ */ jsx8("div", { css: styles8.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ jsx8(StudioFileGrid, {}) : /* @__PURE__ */ jsx8(StudioFileList, {}) }),
1819
+ /* @__PURE__ */ jsx8(StudioPreview, {})
1593
1820
  ] })
1594
1821
  ] }) });
1595
1822
  }
1596
1823
  function CloseIcon() {
1597
- return /* @__PURE__ */ jsxs7(
1824
+ return /* @__PURE__ */ jsxs8(
1598
1825
  "svg",
1599
1826
  {
1600
- css: styles7.closeIcon,
1827
+ css: styles8.closeIcon,
1601
1828
  xmlns: "http://www.w3.org/2000/svg",
1602
1829
  viewBox: "0 0 24 24",
1603
1830
  fill: "none",
@@ -1606,8 +1833,8 @@ function CloseIcon() {
1606
1833
  strokeLinecap: "round",
1607
1834
  strokeLinejoin: "round",
1608
1835
  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" })
1836
+ /* @__PURE__ */ jsx8("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
1837
+ /* @__PURE__ */ jsx8("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
1611
1838
  ]
1612
1839
  }
1613
1840
  );
@@ -1617,4 +1844,4 @@ export {
1617
1844
  StudioUI,
1618
1845
  StudioUI_default as default
1619
1846
  };
1620
- //# sourceMappingURL=StudioUI-2CBIV4Q5.mjs.map
1847
+ //# sourceMappingURL=StudioUI-RS5UCUIN.mjs.map