@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.
- package/dist/{StudioUI-2CBIV4Q5.mjs → StudioUI-5I7VRE4F.mjs} +625 -406
- package/dist/StudioUI-5I7VRE4F.mjs.map +1 -0
- package/dist/{StudioUI-ZAD65UPD.js → StudioUI-ELH3QOUT.js} +460 -241
- package/dist/StudioUI-ELH3QOUT.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/StudioUI-2CBIV4Q5.mjs.map +0 -1
- package/dist/StudioUI-ZAD65UPD.js.map +0 -1
|
@@ -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
|
|
5
|
-
import { css as
|
|
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
|
-
|
|
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:
|
|
202
|
+
left: css2`
|
|
64
203
|
display: flex;
|
|
65
204
|
align-items: center;
|
|
66
205
|
gap: 8px;
|
|
67
206
|
`,
|
|
68
|
-
right:
|
|
207
|
+
right: css2`
|
|
69
208
|
display: flex;
|
|
70
209
|
align-items: center;
|
|
71
210
|
gap: 16px;
|
|
72
211
|
`,
|
|
73
|
-
btn:
|
|
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:
|
|
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:
|
|
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:
|
|
244
|
+
icon: css2`
|
|
106
245
|
width: 16px;
|
|
107
246
|
height: 16px;
|
|
108
247
|
`,
|
|
109
|
-
selectionCount:
|
|
248
|
+
selectionCount: css2`
|
|
110
249
|
font-size: 14px;
|
|
111
250
|
color: #4b5563;
|
|
112
251
|
`,
|
|
113
|
-
clearBtn:
|
|
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:
|
|
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:
|
|
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:
|
|
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
|
-
|
|
314
|
+
setAlertMessage({
|
|
315
|
+
title: "Upload Failed",
|
|
316
|
+
message: `Failed to upload ${file.name}: ${error.error || "Unknown error"}`
|
|
317
|
+
});
|
|
174
318
|
}
|
|
175
319
|
}
|
|
176
320
|
triggerRefresh();
|
|
177
321
|
} catch (error) {
|
|
178
322
|
console.error("Upload error:", error);
|
|
179
|
-
|
|
323
|
+
setAlertMessage({
|
|
324
|
+
title: "Upload Failed",
|
|
325
|
+
message: "Upload failed. Check console for details."
|
|
326
|
+
});
|
|
180
327
|
} finally {
|
|
181
328
|
setUploading(false);
|
|
182
329
|
if (fileInputRef.current) {
|
|
@@ -187,9 +334,12 @@ function StudioToolbar() {
|
|
|
187
334
|
const handleReprocess = useCallback(() => {
|
|
188
335
|
console.log("Reprocess clicked", selectedItems);
|
|
189
336
|
}, [selectedItems]);
|
|
190
|
-
const
|
|
337
|
+
const handleDeleteClick = useCallback(() => {
|
|
191
338
|
if (selectedItems.size === 0) return;
|
|
192
|
-
|
|
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
|
-
|
|
354
|
+
setAlertMessage({
|
|
355
|
+
title: "Delete Failed",
|
|
356
|
+
message: error.error || "Unknown error"
|
|
357
|
+
});
|
|
205
358
|
}
|
|
206
359
|
} catch (error) {
|
|
207
360
|
console.error("Delete error:", error);
|
|
208
|
-
|
|
361
|
+
setAlertMessage({
|
|
362
|
+
title: "Delete Failed",
|
|
363
|
+
message: "Delete failed. Check console for details."
|
|
364
|
+
});
|
|
209
365
|
}
|
|
210
366
|
}, [selectedItems, clearSelection, triggerRefresh]);
|
|
211
367
|
const handleSyncCdn = 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__ */
|
|
219
|
-
/* @__PURE__ */
|
|
220
|
-
|
|
374
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
375
|
+
showDeleteConfirm && /* @__PURE__ */ jsx2(
|
|
376
|
+
ConfirmModal,
|
|
221
377
|
{
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
378
|
+
title: "Delete Items",
|
|
379
|
+
message: `Are you sure you want to delete ${selectedItems.size} item(s)? This action cannot be undone.`,
|
|
380
|
+
confirmLabel: "Delete",
|
|
381
|
+
variant: "danger",
|
|
382
|
+
onConfirm: handleDeleteConfirm,
|
|
383
|
+
onCancel: () => setShowDeleteConfirm(false)
|
|
228
384
|
}
|
|
229
385
|
),
|
|
230
|
-
/* @__PURE__ */
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
398
|
+
ref: fileInputRef,
|
|
399
|
+
type: "file",
|
|
400
|
+
multiple: true,
|
|
401
|
+
accept: "image/*",
|
|
402
|
+
onChange: handleFileChange,
|
|
403
|
+
style: { display: "none" }
|
|
266
404
|
}
|
|
267
405
|
),
|
|
268
|
-
/* @__PURE__ */
|
|
269
|
-
|
|
270
|
-
|
|
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
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
410
|
+
onClick: handleUpload,
|
|
411
|
+
icon: "upload",
|
|
412
|
+
label: uploading ? "Uploading..." : "Upload",
|
|
413
|
+
disabled: uploading
|
|
284
414
|
}
|
|
285
415
|
),
|
|
286
|
-
/* @__PURE__ */
|
|
287
|
-
|
|
416
|
+
/* @__PURE__ */ jsx2(
|
|
417
|
+
ToolbarButton,
|
|
288
418
|
{
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
419
|
+
onClick: handleReprocess,
|
|
420
|
+
icon: "refresh",
|
|
421
|
+
label: "Reprocess",
|
|
422
|
+
disabled: !hasSelection
|
|
293
423
|
}
|
|
294
|
-
)
|
|
424
|
+
),
|
|
425
|
+
/* @__PURE__ */ 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__ */
|
|
483
|
+
return /* @__PURE__ */ jsxs2(
|
|
307
484
|
"button",
|
|
308
485
|
{
|
|
309
|
-
css: [
|
|
486
|
+
css: [styles2.btn, variant === "danger" ? styles2.btnDanger : styles2.btnDefault],
|
|
310
487
|
onClick,
|
|
311
488
|
disabled,
|
|
312
489
|
children: [
|
|
313
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
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
|
|
344
|
-
import { jsx as
|
|
345
|
-
var
|
|
346
|
-
container:
|
|
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:
|
|
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:
|
|
543
|
+
backIcon: css3`
|
|
367
544
|
width: 16px;
|
|
368
545
|
height: 16px;
|
|
369
546
|
color: #6b7280;
|
|
370
547
|
`,
|
|
371
|
-
nav:
|
|
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:
|
|
554
|
+
item: css3`
|
|
378
555
|
display: flex;
|
|
379
556
|
align-items: center;
|
|
380
557
|
gap: 4px;
|
|
381
558
|
`,
|
|
382
|
-
separator:
|
|
559
|
+
separator: css3`
|
|
383
560
|
color: #d1d5db;
|
|
384
561
|
`,
|
|
385
|
-
btn:
|
|
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:
|
|
574
|
+
btnActive: css3`
|
|
398
575
|
color: #111827;
|
|
399
576
|
font-weight: 500;
|
|
400
577
|
`,
|
|
401
|
-
btnInactive:
|
|
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__ */
|
|
417
|
-
currentPath !== "public" && /* @__PURE__ */
|
|
418
|
-
/* @__PURE__ */
|
|
419
|
-
index > 0 && /* @__PURE__ */
|
|
420
|
-
/* @__PURE__ */
|
|
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: [
|
|
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
|
|
435
|
-
import { jsx as
|
|
436
|
-
var spin =
|
|
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
|
|
440
|
-
loading:
|
|
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:
|
|
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:
|
|
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:
|
|
639
|
+
emptyIcon: css4`
|
|
463
640
|
width: 48px;
|
|
464
641
|
height: 48px;
|
|
465
642
|
margin-bottom: 16px;
|
|
466
643
|
`,
|
|
467
|
-
emptyText:
|
|
644
|
+
emptyText: css4`
|
|
468
645
|
font-size: 14px;
|
|
469
646
|
margin: 0;
|
|
470
647
|
`,
|
|
471
|
-
grid:
|
|
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:
|
|
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:
|
|
671
|
+
itemSelected: css4`
|
|
495
672
|
border-color: #a855f7;
|
|
496
673
|
background-color: #faf5ff;
|
|
497
674
|
`,
|
|
498
|
-
checkbox:
|
|
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:
|
|
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:
|
|
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:
|
|
702
|
+
folderIcon: css4`
|
|
526
703
|
width: 64px;
|
|
527
704
|
height: 64px;
|
|
528
705
|
color: #facc15;
|
|
529
706
|
`,
|
|
530
|
-
image:
|
|
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:
|
|
713
|
+
label: css4`
|
|
537
714
|
padding: 6px 8px;
|
|
538
715
|
background-color: white;
|
|
539
716
|
border-top: 1px solid #e5e7eb;
|
|
540
717
|
`,
|
|
541
|
-
name:
|
|
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:
|
|
726
|
+
size: css4`
|
|
550
727
|
font-size: 12px;
|
|
551
728
|
color: #9ca3af;
|
|
552
729
|
margin: 0;
|
|
553
730
|
`,
|
|
554
|
-
selectAllRow:
|
|
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:
|
|
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:
|
|
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__ */
|
|
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__ */
|
|
604
|
-
/* @__PURE__ */
|
|
605
|
-
/* @__PURE__ */
|
|
606
|
-
/* @__PURE__ */
|
|
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__ */
|
|
636
|
-
files.length > 0 && /* @__PURE__ */
|
|
637
|
-
/* @__PURE__ */
|
|
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:
|
|
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__ */
|
|
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__ */
|
|
667
|
-
!isFolder && /* @__PURE__ */
|
|
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:
|
|
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__ */
|
|
679
|
-
/* @__PURE__ */
|
|
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:
|
|
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__ */
|
|
689
|
-
/* @__PURE__ */
|
|
690
|
-
item.size && /* @__PURE__ */
|
|
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
|
|
703
|
-
import { jsx as
|
|
704
|
-
var spin2 =
|
|
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
|
|
708
|
-
loading:
|
|
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:
|
|
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:
|
|
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:
|
|
907
|
+
table: css5`
|
|
731
908
|
width: 100%;
|
|
732
909
|
border-collapse: collapse;
|
|
733
910
|
`,
|
|
734
|
-
th:
|
|
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:
|
|
920
|
+
thCheckbox: css5`
|
|
744
921
|
width: 32px;
|
|
745
922
|
`,
|
|
746
|
-
thSize:
|
|
923
|
+
thSize: css5`
|
|
747
924
|
width: 96px;
|
|
748
925
|
`,
|
|
749
|
-
thDimensions:
|
|
926
|
+
thDimensions: css5`
|
|
750
927
|
width: 128px;
|
|
751
928
|
`,
|
|
752
|
-
thCdn:
|
|
929
|
+
thCdn: css5`
|
|
753
930
|
width: 96px;
|
|
754
931
|
`,
|
|
755
|
-
tbody:
|
|
932
|
+
tbody: css5`
|
|
756
933
|
border-top: 1px solid #f3f4f6;
|
|
757
934
|
`,
|
|
758
|
-
row:
|
|
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:
|
|
943
|
+
rowSelected: css5`
|
|
767
944
|
background-color: #faf5ff;
|
|
768
945
|
`,
|
|
769
|
-
td:
|
|
946
|
+
td: css5`
|
|
770
947
|
padding: 8px 0;
|
|
771
948
|
border-bottom: 1px solid #f3f4f6;
|
|
772
949
|
`,
|
|
773
|
-
checkbox:
|
|
950
|
+
checkbox: css5`
|
|
774
951
|
width: 16px;
|
|
775
952
|
height: 16px;
|
|
776
953
|
accent-color: #9333ea;
|
|
777
954
|
`,
|
|
778
|
-
nameCell:
|
|
955
|
+
nameCell: css5`
|
|
779
956
|
display: flex;
|
|
780
957
|
align-items: center;
|
|
781
958
|
gap: 8px;
|
|
782
959
|
`,
|
|
783
|
-
folderIcon:
|
|
960
|
+
folderIcon: css5`
|
|
784
961
|
width: 20px;
|
|
785
962
|
height: 20px;
|
|
786
963
|
color: #facc15;
|
|
787
964
|
`,
|
|
788
|
-
fileIcon:
|
|
965
|
+
fileIcon: css5`
|
|
789
966
|
width: 20px;
|
|
790
967
|
height: 20px;
|
|
791
968
|
color: #9ca3af;
|
|
792
969
|
`,
|
|
793
|
-
name:
|
|
970
|
+
name: css5`
|
|
794
971
|
font-size: 14px;
|
|
795
972
|
color: #111827;
|
|
796
973
|
`,
|
|
797
|
-
meta:
|
|
974
|
+
meta: css5`
|
|
798
975
|
font-size: 14px;
|
|
799
976
|
color: #6b7280;
|
|
800
977
|
`,
|
|
801
|
-
cdnBadge:
|
|
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:
|
|
985
|
+
cdnIcon: css5`
|
|
809
986
|
width: 12px;
|
|
810
987
|
height: 12px;
|
|
811
988
|
`,
|
|
812
|
-
cdnEmpty:
|
|
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__ */
|
|
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__ */
|
|
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__ */
|
|
870
|
-
/* @__PURE__ */
|
|
871
|
-
/* @__PURE__ */
|
|
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:
|
|
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__ */
|
|
884
|
-
/* @__PURE__ */
|
|
885
|
-
/* @__PURE__ */
|
|
886
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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__ */
|
|
902
|
-
/* @__PURE__ */
|
|
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:
|
|
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__ */
|
|
914
|
-
isFolder ? /* @__PURE__ */
|
|
915
|
-
/* @__PURE__ */
|
|
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__ */
|
|
918
|
-
/* @__PURE__ */
|
|
919
|
-
/* @__PURE__ */
|
|
920
|
-
/* @__PURE__ */
|
|
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__ */
|
|
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 {
|
|
933
|
-
import {
|
|
934
|
-
|
|
935
|
-
|
|
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:
|
|
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:
|
|
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:
|
|
1133
|
+
image: css6`
|
|
956
1134
|
width: 100%;
|
|
957
1135
|
height: auto;
|
|
958
1136
|
border-radius: 4px;
|
|
959
1137
|
`,
|
|
960
|
-
info:
|
|
1138
|
+
info: css6`
|
|
961
1139
|
display: flex;
|
|
962
1140
|
flex-direction: column;
|
|
963
1141
|
gap: 12px;
|
|
964
1142
|
`,
|
|
965
|
-
row:
|
|
1143
|
+
row: css6`
|
|
966
1144
|
display: flex;
|
|
967
1145
|
justify-content: space-between;
|
|
968
1146
|
font-size: 12px;
|
|
969
1147
|
`,
|
|
970
|
-
label:
|
|
1148
|
+
label: css6`
|
|
971
1149
|
color: #6b7280;
|
|
972
1150
|
`,
|
|
973
|
-
value:
|
|
1151
|
+
value: css6`
|
|
974
1152
|
color: #111827;
|
|
975
1153
|
`,
|
|
976
|
-
valueTruncate:
|
|
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:
|
|
1160
|
+
section: css6`
|
|
983
1161
|
padding-top: 8px;
|
|
984
1162
|
border-top: 1px solid #e5e7eb;
|
|
985
1163
|
`,
|
|
986
|
-
sectionTitle:
|
|
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:
|
|
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:
|
|
1177
|
+
cdnIcon: css6`
|
|
1000
1178
|
width: 16px;
|
|
1001
1179
|
height: 16px;
|
|
1002
1180
|
`,
|
|
1003
|
-
copyBtn:
|
|
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:
|
|
1194
|
+
colorSwatch: css6`
|
|
1017
1195
|
margin-top: 8px;
|
|
1018
1196
|
height: 32px;
|
|
1019
1197
|
border-radius: 4px;
|
|
1020
1198
|
`,
|
|
1021
|
-
emptyState:
|
|
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:
|
|
1205
|
+
emptyText: css6`
|
|
1028
1206
|
font-size: 14px;
|
|
1029
1207
|
color: #9ca3af;
|
|
1030
1208
|
margin: 0;
|
|
1031
1209
|
`,
|
|
1032
|
-
actions:
|
|
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:
|
|
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:
|
|
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
|
|
1243
|
+
const [showDeleteConfirm, setShowDeleteConfirm] = useState4(false);
|
|
1244
|
+
const [alertMessage, setAlertMessage] = useState4(null);
|
|
1245
|
+
const handleDeleteClick = () => {
|
|
1066
1246
|
if (selectedItems.size === 0) return;
|
|
1067
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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__ */
|
|
1088
|
-
|
|
1089
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
"
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
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__ */
|
|
1109
|
-
|
|
1110
|
-
/* @__PURE__ */
|
|
1111
|
-
"
|
|
1112
|
-
{
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
/* @__PURE__ */
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
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
|
-
|
|
1149
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1162
|
-
|
|
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__ */
|
|
1177
|
-
/* @__PURE__ */
|
|
1178
|
-
/* @__PURE__ */
|
|
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
|
|
1189
|
-
import { css as
|
|
1190
|
-
import { Fragment as
|
|
1191
|
-
var
|
|
1192
|
-
btn:
|
|
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:
|
|
1423
|
+
icon: css7`
|
|
1205
1424
|
width: 20px;
|
|
1206
1425
|
height: 20px;
|
|
1207
1426
|
color: #6b7280;
|
|
1208
1427
|
`,
|
|
1209
|
-
overlay:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
1462
|
+
title: css7`
|
|
1244
1463
|
font-size: 18px;
|
|
1245
1464
|
font-weight: 600;
|
|
1246
1465
|
margin: 0;
|
|
1247
1466
|
`,
|
|
1248
|
-
closeBtn:
|
|
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:
|
|
1478
|
+
sections: css7`
|
|
1260
1479
|
display: flex;
|
|
1261
1480
|
flex-direction: column;
|
|
1262
1481
|
gap: 24px;
|
|
1263
1482
|
`,
|
|
1264
|
-
sectionTitle:
|
|
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:
|
|
1489
|
+
description: css7`
|
|
1271
1490
|
font-size: 12px;
|
|
1272
1491
|
color: #6b7280;
|
|
1273
1492
|
margin: 0 0 12px 0;
|
|
1274
1493
|
`,
|
|
1275
|
-
code:
|
|
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:
|
|
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:
|
|
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:
|
|
1521
|
+
grid: css7`
|
|
1303
1522
|
display: grid;
|
|
1304
1523
|
grid-template-columns: repeat(3, 1fr);
|
|
1305
1524
|
gap: 12px;
|
|
1306
1525
|
`,
|
|
1307
|
-
label:
|
|
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:
|
|
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:
|
|
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:
|
|
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] =
|
|
1348
|
-
return /* @__PURE__ */
|
|
1349
|
-
/* @__PURE__ */
|
|
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:
|
|
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__ */
|
|
1362
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1585
|
+
isOpen && /* @__PURE__ */ jsx7(SettingsPanel, { onClose: () => setIsOpen(false) })
|
|
1367
1586
|
] });
|
|
1368
1587
|
}
|
|
1369
1588
|
function SettingsPanel({ onClose }) {
|
|
1370
|
-
return /* @__PURE__ */
|
|
1371
|
-
/* @__PURE__ */
|
|
1372
|
-
/* @__PURE__ */
|
|
1373
|
-
/* @__PURE__ */
|
|
1374
|
-
/* @__PURE__ */
|
|
1375
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1378
|
-
/* @__PURE__ */
|
|
1379
|
-
/* @__PURE__ */
|
|
1380
|
-
/* @__PURE__ */
|
|
1381
|
-
/* @__PURE__ */
|
|
1382
|
-
/* @__PURE__ */
|
|
1383
|
-
/* @__PURE__ */
|
|
1384
|
-
/* @__PURE__ */
|
|
1385
|
-
/* @__PURE__ */
|
|
1386
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1390
|
-
/* @__PURE__ */
|
|
1391
|
-
/* @__PURE__ */
|
|
1392
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1395
|
-
/* @__PURE__ */
|
|
1396
|
-
/* @__PURE__ */
|
|
1397
|
-
/* @__PURE__ */
|
|
1398
|
-
/* @__PURE__ */
|
|
1399
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1402
|
-
/* @__PURE__ */
|
|
1403
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1406
|
-
/* @__PURE__ */
|
|
1407
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1413
|
-
/* @__PURE__ */
|
|
1414
|
-
/* @__PURE__ */
|
|
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
|
|
1422
|
-
var
|
|
1423
|
-
container:
|
|
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:
|
|
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:
|
|
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:
|
|
1661
|
+
headerActions: css8`
|
|
1443
1662
|
display: flex;
|
|
1444
1663
|
align-items: center;
|
|
1445
1664
|
gap: 8px;
|
|
1446
1665
|
`,
|
|
1447
|
-
closeBtn:
|
|
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:
|
|
1678
|
+
closeIcon: css8`
|
|
1460
1679
|
width: 20px;
|
|
1461
1680
|
height: 20px;
|
|
1462
1681
|
color: #6b7280;
|
|
1463
1682
|
`,
|
|
1464
|
-
content:
|
|
1683
|
+
content: css8`
|
|
1465
1684
|
flex: 1;
|
|
1466
1685
|
display: flex;
|
|
1467
1686
|
overflow: hidden;
|
|
1468
1687
|
`,
|
|
1469
|
-
fileBrowser:
|
|
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] =
|
|
1478
|
-
const [selectedItems, setSelectedItems] =
|
|
1479
|
-
const [lastSelectedPath, setLastSelectedPath] =
|
|
1480
|
-
const [viewMode, setViewMode] =
|
|
1481
|
-
const [meta, setMeta] =
|
|
1482
|
-
const [isLoading, setIsLoading] =
|
|
1483
|
-
const [refreshKey, setRefreshKey] =
|
|
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__ */
|
|
1573
|
-
/* @__PURE__ */
|
|
1574
|
-
/* @__PURE__ */
|
|
1575
|
-
/* @__PURE__ */
|
|
1576
|
-
/* @__PURE__ */
|
|
1577
|
-
/* @__PURE__ */
|
|
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:
|
|
1799
|
+
css: styles8.closeBtn,
|
|
1581
1800
|
onClick: onClose,
|
|
1582
1801
|
"aria-label": "Close Studio",
|
|
1583
|
-
children: /* @__PURE__ */
|
|
1802
|
+
children: /* @__PURE__ */ jsx8(CloseIcon, {})
|
|
1584
1803
|
}
|
|
1585
1804
|
)
|
|
1586
1805
|
] })
|
|
1587
1806
|
] }),
|
|
1588
|
-
/* @__PURE__ */
|
|
1589
|
-
/* @__PURE__ */
|
|
1590
|
-
/* @__PURE__ */
|
|
1591
|
-
/* @__PURE__ */
|
|
1592
|
-
/* @__PURE__ */
|
|
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__ */
|
|
1816
|
+
return /* @__PURE__ */ jsxs8(
|
|
1598
1817
|
"svg",
|
|
1599
1818
|
{
|
|
1600
|
-
css:
|
|
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__ */
|
|
1610
|
-
/* @__PURE__ */
|
|
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-
|
|
1839
|
+
//# sourceMappingURL=StudioUI-5I7VRE4F.mjs.map
|