@thetechfossil/upfiles 1.0.11 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,64 +1,42 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __export = (target, all) => {
9
- for (var name in all)
10
- __defProp(target, name, { get: all[name], enumerable: true });
11
- };
12
- var __copyProps = (to, from, except, desc) => {
13
- if (from && typeof from === "object" || typeof from === "function") {
14
- for (let key of __getOwnPropNames(from))
15
- if (!__hasOwnProp.call(to, key) && key !== except)
16
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
1
+ 'use strict';
2
+
3
+ var React4 = require('react');
4
+ var jsxRuntime = require('react/jsx-runtime');
5
+ var Dialog2 = require('@radix-ui/react-dialog');
6
+
7
+ function _interopNamespace(e) {
8
+ if (e && e.__esModule) return e;
9
+ var n = Object.create(null);
10
+ if (e) {
11
+ Object.keys(e).forEach(function (k) {
12
+ if (k !== 'default') {
13
+ var d = Object.getOwnPropertyDescriptor(e, k);
14
+ Object.defineProperty(n, k, d.get ? d : {
15
+ enumerable: true,
16
+ get: function () { return e[k]; }
17
+ });
18
+ }
19
+ });
17
20
  }
18
- return to;
19
- };
20
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
- // If the importer is in node compatibility mode or this is not an ESM
22
- // file that has been converted to a CommonJS file using a Babel-
23
- // compatible transform (i.e. "__esModule" has not been set), then set
24
- // "default" to the CommonJS "module.exports" for node compatibility.
25
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
- mod
27
- ));
28
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
21
+ n.default = e;
22
+ return Object.freeze(n);
23
+ }
29
24
 
30
- // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- ConnectProjectDialog: () => ConnectProjectDialog,
34
- ImageManager: () => ImageManager,
35
- ProjectFilesWidget: () => ProjectFilesWidget,
36
- UpfilesClient: () => UpfilesClient,
37
- Uploader: () => Uploader,
38
- addApiKeyManually: () => addApiKeyManually,
39
- connectProject: () => connectProject,
40
- connectUsingApiKey: () => connectUsingApiKey,
41
- createClientWithKey: () => createClientWithKey,
42
- createProject: () => createProject,
43
- fetchFileThumbnails: () => fetchFileThumbnails,
44
- fetchProjectFiles: () => fetchProjectFiles,
45
- fetchProjectImagesWithThumbs: () => fetchProjectImagesWithThumbs,
46
- listProjects: () => listProjects
47
- });
48
- module.exports = __toCommonJS(index_exports);
25
+ var React4__namespace = /*#__PURE__*/_interopNamespace(React4);
26
+ var Dialog2__namespace = /*#__PURE__*/_interopNamespace(Dialog2);
49
27
 
50
28
  // src/client.ts
51
29
  var UpfilesClient = class {
52
30
  constructor(opts) {
53
31
  this.baseUrl = opts.baseUrl?.replace(/\/$/, "");
54
- this.presignPath = opts.presignPath ?? "/api/plugin/upload/presigned-url";
32
+ this.presignPath = opts.presignPath ?? "/api/plugin/upload";
55
33
  this.presignUrl = opts.presignUrl;
56
34
  this.headers = opts.headers;
57
35
  this.withCredentials = opts.withCredentials;
58
36
  this.apiKey = opts.apiKey;
59
37
  this.apiKeyHeader = opts.apiKeyHeader ?? "authorization";
60
38
  this.thumbnailsPath = opts.thumbnailsPath ?? "/api/plugin/thumbnails";
61
- this.completionPath = opts.completionPath ?? "/api/plugin/upload/complete";
39
+ this.completionPath = opts.completionPath ?? "/api/plugin/files";
62
40
  this.foldersPath = opts.foldersPath ?? "/api/plugin/folders";
63
41
  this.callCompletionEndpoint = opts.callCompletionEndpoint ?? false;
64
42
  }
@@ -334,8 +312,7 @@ var UpfilesClient = class {
334
312
  };
335
313
  }
336
314
  getEventsUrl(projectId) {
337
- const basePath = this.thumbnailsPath.replace(/\/thumbnails$/, "");
338
- const eventsPath = `${basePath}/events`;
315
+ this.thumbnailsPath.replace(/\/thumbnails$/, "");
339
316
  const target = this.baseUrl ? `${this.baseUrl}/api/events` : "/api/events";
340
317
  const url = new URL(target, window.location.href);
341
318
  if (this.apiKey) {
@@ -347,10 +324,6 @@ var UpfilesClient = class {
347
324
  return url.toString();
348
325
  }
349
326
  };
350
-
351
- // src/Uploader.tsx
352
- var import_react = __toESM(require("react"));
353
- var import_jsx_runtime = require("react/jsx-runtime");
354
327
  var Uploader = ({
355
328
  clientOptions,
356
329
  multiple = true,
@@ -373,12 +346,12 @@ var Uploader = ({
373
346
  recordUrl = "/api/files",
374
347
  autoUpload = false
375
348
  }) => {
376
- const inputRef = (0, import_react.useRef)(null);
377
- const client = (0, import_react.useMemo)(() => new UpfilesClient(clientOptions ?? {}), [clientOptions]);
378
- const [files, setFiles] = (0, import_react.useState)([]);
379
- const [isUploading, setIsUploading] = (0, import_react.useState)(false);
380
- const [isDragOver, setIsDragOver] = (0, import_react.useState)(false);
381
- const addFiles = (0, import_react.useCallback)((incoming) => {
349
+ const inputRef = React4.useRef(null);
350
+ const client = React4.useMemo(() => new UpfilesClient(clientOptions ?? {}), [clientOptions]);
351
+ const [files, setFiles] = React4.useState([]);
352
+ const [isUploading, setIsUploading] = React4.useState(false);
353
+ const [isDragOver, setIsDragOver] = React4.useState(false);
354
+ const addFiles = React4.useCallback((incoming) => {
382
355
  const filtered = incoming.filter((f2) => {
383
356
  if (f2.size > maxFileSize) {
384
357
  return false;
@@ -397,18 +370,18 @@ var Uploader = ({
397
370
  }));
398
371
  setFiles((prev) => [...prev, ...mapped]);
399
372
  }, [files.length, maxFileSize, maxFiles]);
400
- const onInputChange = (0, import_react.useCallback)((e) => {
373
+ const onInputChange = React4.useCallback((e) => {
401
374
  const fs = Array.from(e.target.files || []);
402
375
  addFiles(fs);
403
376
  if (inputRef.current) inputRef.current.value = "";
404
377
  }, [addFiles]);
405
- const handleDrop = (0, import_react.useCallback)((e) => {
378
+ const handleDrop = React4.useCallback((e) => {
406
379
  e.preventDefault();
407
380
  e.stopPropagation();
408
381
  setIsDragOver(false);
409
382
  addFiles(Array.from(e.dataTransfer.files || []));
410
383
  }, [addFiles]);
411
- const uploadOne = (0, import_react.useCallback)(async (item) => {
384
+ const uploadOne = React4.useCallback(async (item) => {
412
385
  const update = (patch) => {
413
386
  setFiles((prev) => prev.map((f2) => f2.id === item.id ? { ...f2, ...patch } : f2));
414
387
  };
@@ -497,7 +470,7 @@ var Uploader = ({
497
470
  throw err;
498
471
  }
499
472
  }, [client, projectId, folderPath, fetchThumbnails, autoRecordToDb, recordUrl, clientOptions, onUploadBegin, onUploadProgress, onClientUploadComplete]);
500
- const uploadAll = (0, import_react.useCallback)(async () => {
473
+ const uploadAll = React4.useCallback(async () => {
501
474
  const targets = files.filter((f2) => f2.status === "pending");
502
475
  if (!targets.length) return;
503
476
  setIsUploading(true);
@@ -517,7 +490,7 @@ var Uploader = ({
517
490
  setIsUploading(false);
518
491
  }
519
492
  }, [files, onComplete, onError, uploadOne]);
520
- import_react.default.useEffect(() => {
493
+ React4__namespace.default.useEffect(() => {
521
494
  if (autoUpload && files.some((f2) => f2.status === "pending") && !isUploading) {
522
495
  const timer = setTimeout(() => {
523
496
  uploadAll();
@@ -525,8 +498,8 @@ var Uploader = ({
525
498
  return () => clearTimeout(timer);
526
499
  }
527
500
  }, [autoUpload, files, isUploading, uploadAll]);
528
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className, children: [
529
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
501
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
502
+ /* @__PURE__ */ jsxRuntime.jsx(
530
503
  "input",
531
504
  {
532
505
  ref: inputRef,
@@ -537,7 +510,7 @@ var Uploader = ({
537
510
  onChange: onInputChange
538
511
  }
539
512
  ),
540
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
513
+ /* @__PURE__ */ jsxRuntime.jsxs(
541
514
  "div",
542
515
  {
543
516
  className: `${dropzoneClassName} border-2 border-dashed rounded-xl transition-all duration-200 cursor-pointer p-10 flex flex-col items-center justify-center gap-4 ${isDragOver ? "border-blue-500 bg-blue-50 dark:bg-blue-900/20" : "border-gray-200 dark:border-gray-800 hover:border-gray-300 dark:hover:border-gray-700 bg-gray-50/50 dark:bg-gray-900/50"}`,
@@ -556,14 +529,14 @@ var Uploader = ({
556
529
  role: "button",
557
530
  "aria-label": "Upload files",
558
531
  children: [
559
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-16 h-16 rounded-full bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center text-blue-600 dark:text-blue-400", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
560
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
561
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "17 8 12 3 7 8" }),
562
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
532
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 rounded-full bg-blue-100 dark:bg-blue-900/30 flex items-center justify-center text-blue-600 dark:text-blue-400", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "32", height: "32", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
533
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
534
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "17 8 12 3 7 8" }),
535
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", y1: "3", x2: "12", y2: "15" })
563
536
  ] }) }),
564
- children ?? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-center", children: [
565
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: "Drop files here or click to browse" }),
566
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-sm text-gray-500 dark:text-gray-400 mt-1", children: [
537
+ children ?? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-center", children: [
538
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-lg font-semibold text-gray-900 dark:text-gray-100", children: "Drop files here or click to browse" }),
539
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-sm text-gray-500 dark:text-gray-400 mt-1", children: [
567
540
  multiple ? `Up to ${maxFiles} files` : "Single file",
568
541
  " \u2022 Max ",
569
542
  (maxFileSize / (1024 * 1024)).toFixed(0),
@@ -573,26 +546,26 @@ var Uploader = ({
573
546
  ]
574
547
  }
575
548
  ),
576
- files.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "mt-8 space-y-4", children: [
577
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between border-b border-gray-100 dark:border-gray-800 pb-4", children: [
578
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h4", { className: "font-semibold text-gray-900 dark:text-gray-100", children: "Selected Files" }),
579
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex gap-3", children: [
580
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
549
+ files.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-8 space-y-4", children: [
550
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between border-b border-gray-100 dark:border-gray-800 pb-4", children: [
551
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "font-semibold text-gray-900 dark:text-gray-100", children: "Selected Files" }),
552
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3", children: [
553
+ /* @__PURE__ */ jsxRuntime.jsx(
581
554
  "button",
582
555
  {
583
556
  className: "px-4 py-2 bg-blue-600 text-white text-sm font-semibold rounded-lg hover:bg-blue-500 disabled:opacity-50 disabled:cursor-not-allowed transition-colors shadow-sm",
584
557
  disabled: isUploading || files.every((f2) => f2.status !== "pending"),
585
558
  onClick: uploadAll,
586
- children: isUploading ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center gap-2", children: [
587
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { className: "animate-spin h-4 w-4 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
588
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
589
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
559
+ children: isUploading ? /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex items-center gap-2", children: [
560
+ /* @__PURE__ */ jsxRuntime.jsxs("svg", { className: "animate-spin h-4 w-4 text-white", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24", children: [
561
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
562
+ /* @__PURE__ */ jsxRuntime.jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" })
590
563
  ] }),
591
564
  "Uploading..."
592
565
  ] }) : "Upload All"
593
566
  }
594
567
  ),
595
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
568
+ /* @__PURE__ */ jsxRuntime.jsx(
596
569
  "button",
597
570
  {
598
571
  className: "px-4 py-2 bg-gray-100 dark:bg-gray-800 text-gray-700 dark:text-gray-300 text-sm font-semibold rounded-lg hover:bg-gray-200 dark:hover:bg-gray-700 disabled:opacity-50 transition-colors",
@@ -603,24 +576,24 @@ var Uploader = ({
603
576
  )
604
577
  ] })
605
578
  ] }),
606
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "grid gap-3", children: files.map((f2) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "group relative bg-white dark:bg-gray-900 border border-gray-100 dark:border-gray-800 rounded-xl p-4 transition-all hover:shadow-md", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-4", children: [
607
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "w-10 h-10 rounded-lg bg-gray-50 dark:bg-gray-800 flex items-center justify-center flex-shrink-0", children: f2.type.startsWith("image/") ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "text-indigo-500", children: [
608
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
609
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
610
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "21 15 16 10 5 21" })
611
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "text-blue-500", children: [
612
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
613
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "14 2 14 8 20 8" })
579
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid gap-3", children: files.map((f2) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "group relative bg-white dark:bg-gray-900 border border-gray-100 dark:border-gray-800 rounded-xl p-4 transition-all hover:shadow-md", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-4", children: [
580
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-10 h-10 rounded-lg bg-gray-50 dark:bg-gray-800 flex items-center justify-center flex-shrink-0", children: f2.type.startsWith("image/") ? /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "text-indigo-500", children: [
581
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
582
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
583
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "21 15 16 10 5 21" })
584
+ ] }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "text-blue-500", children: [
585
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14.5 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7.5L14.5 2z" }),
586
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "14 2 14 8 20 8" })
614
587
  ] }) }),
615
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex-1 min-w-0", children: [
616
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center justify-between mb-1", children: [
617
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 truncate pr-4", children: f2.name }),
618
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-xs text-gray-500 font-medium whitespace-nowrap", children: [
588
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 min-w-0", children: [
589
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between mb-1", children: [
590
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-sm font-medium text-gray-900 dark:text-gray-100 truncate pr-4", children: f2.name }),
591
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-gray-500 font-medium whitespace-nowrap", children: [
619
592
  (f2.size / (1024 * 1024)).toFixed(2),
620
593
  " MB"
621
594
  ] })
622
595
  ] }),
623
- f2.status === "error" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "text-xs text-red-500 font-medium mt-1", children: f2.error }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-1.5 w-full bg-gray-100 dark:bg-gray-800 rounded-full overflow-hidden mt-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
596
+ f2.status === "error" ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-red-500 font-medium mt-1", children: f2.error }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-1.5 w-full bg-gray-100 dark:bg-gray-800 rounded-full overflow-hidden mt-2", children: /* @__PURE__ */ jsxRuntime.jsx(
624
597
  "div",
625
598
  {
626
599
  className: `h-full transition-all duration-300 ${f2.status === "success" ? "bg-green-500" : "bg-blue-500"}`,
@@ -628,10 +601,10 @@ var Uploader = ({
628
601
  }
629
602
  ) })
630
603
  ] }),
631
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex-shrink-0 ml-4", children: [
632
- f2.status === "success" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-center gap-2", children: [
633
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "20 6 9 17 4 12" }) }) }),
634
- f2.publicUrl && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
604
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-shrink-0 ml-4", children: [
605
+ f2.status === "success" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
606
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) }) }),
607
+ f2.publicUrl && /* @__PURE__ */ jsxRuntime.jsx(
635
608
  "a",
636
609
  {
637
610
  href: f2.publicUrl,
@@ -639,23 +612,23 @@ var Uploader = ({
639
612
  rel: "noreferrer",
640
613
  className: "p-1.5 text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-md transition-colors",
641
614
  title: "View online",
642
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
643
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
644
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("polyline", { points: "15 3 21 3 21 9" }),
645
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
615
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
616
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
617
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "15 3 21 3 21 9" }),
618
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", y1: "14", x2: "21", y2: "3" })
646
619
  ] })
647
620
  }
648
621
  )
649
622
  ] }),
650
- f2.status === "error" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: [
651
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
652
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
623
+ f2.status === "error" && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-red-100 dark:bg-red-900/30 text-red-600 dark:text-red-400", children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", children: [
624
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
625
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
653
626
  ] }) }),
654
- f2.status === "uploading" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "text-xs font-semibold text-blue-600 dark:text-blue-400", children: [
627
+ f2.status === "uploading" && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "text-xs font-semibold text-blue-600 dark:text-blue-400", children: [
655
628
  f2.progress,
656
629
  "%"
657
630
  ] }),
658
- f2.status === "pending" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
631
+ f2.status === "pending" && /* @__PURE__ */ jsxRuntime.jsx(
659
632
  "button",
660
633
  {
661
634
  onClick: (e) => {
@@ -664,9 +637,9 @@ var Uploader = ({
664
637
  },
665
638
  className: "p-1.5 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/20 rounded-md transition-colors",
666
639
  title: "Remove",
667
- children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
668
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
669
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
640
+ children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
641
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }),
642
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })
670
643
  ] })
671
644
  }
672
645
  )
@@ -675,10 +648,6 @@ var Uploader = ({
675
648
  ] })
676
649
  ] });
677
650
  };
678
-
679
- // src/ProjectFilesWidget.tsx
680
- var import_react2 = __toESM(require("react"));
681
- var import_jsx_runtime2 = require("react/jsx-runtime");
682
651
  var ProjectFilesWidget = ({
683
652
  clientOptions,
684
653
  folderPath,
@@ -694,16 +663,16 @@ var ProjectFilesWidget = ({
694
663
  showDelete = false,
695
664
  refreshInterval = 5e3
696
665
  }) => {
697
- const client = (0, import_react2.useMemo)(() => new UpfilesClient(clientOptions ?? {}), [clientOptions]);
698
- const [files, setFiles] = (0, import_react2.useState)([]);
699
- const [loading, setLoading] = (0, import_react2.useState)(false);
700
- const [error, setError] = (0, import_react2.useState)(null);
701
- const [query, setQuery] = (0, import_react2.useState)("");
702
- const [savingKey, setSavingKey] = (0, import_react2.useState)(null);
703
- const [deletingKey, setDeletingKey] = (0, import_react2.useState)(null);
704
- const lastUpdatedRef = import_react2.default.useRef(null);
705
- const isFetchingRef = import_react2.default.useRef(false);
706
- const fetchFiles = import_react2.default.useCallback(async (isPolling = false) => {
666
+ const client = React4.useMemo(() => new UpfilesClient(clientOptions ?? {}), [clientOptions]);
667
+ const [files, setFiles] = React4.useState([]);
668
+ const [loading, setLoading] = React4.useState(false);
669
+ const [error, setError] = React4.useState(null);
670
+ const [query, setQuery] = React4.useState("");
671
+ const [savingKey, setSavingKey] = React4.useState(null);
672
+ const [deletingKey, setDeletingKey] = React4.useState(null);
673
+ const lastUpdatedRef = React4__namespace.default.useRef(null);
674
+ const isFetchingRef = React4__namespace.default.useRef(false);
675
+ const fetchFiles = React4__namespace.default.useCallback(async (isPolling = false) => {
707
676
  if (isFetchingRef.current) return;
708
677
  isFetchingRef.current = true;
709
678
  if (!isPolling) setLoading(true);
@@ -722,10 +691,10 @@ var ProjectFilesWidget = ({
722
691
  isFetchingRef.current = false;
723
692
  }
724
693
  }, [client, folderPath]);
725
- (0, import_react2.useEffect)(() => {
694
+ React4.useEffect(() => {
726
695
  fetchFiles();
727
696
  }, [fetchFiles]);
728
- (0, import_react2.useEffect)(() => {
697
+ React4.useEffect(() => {
729
698
  if (!refreshInterval || refreshInterval <= 0) return;
730
699
  const timer = setInterval(() => {
731
700
  fetchFiles(true);
@@ -771,9 +740,9 @@ var ProjectFilesWidget = ({
771
740
  setDeletingKey(null);
772
741
  }
773
742
  };
774
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className, children: [
775
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 8, alignItems: "center", marginBottom: 8 }, children: [
776
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
743
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className, children: [
744
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 8, alignItems: "center", marginBottom: 8 }, children: [
745
+ /* @__PURE__ */ jsxRuntime.jsx(
777
746
  "input",
778
747
  {
779
748
  type: "text",
@@ -783,7 +752,7 @@ var ProjectFilesWidget = ({
783
752
  style: { flex: 1, padding: 8, border: "1px solid #e5e7eb", borderRadius: 6 }
784
753
  }
785
754
  ),
786
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
755
+ /* @__PURE__ */ jsxRuntime.jsx(
787
756
  "button",
788
757
  {
789
758
  onClick: () => {
@@ -795,26 +764,26 @@ var ProjectFilesWidget = ({
795
764
  }
796
765
  )
797
766
  ] }),
798
- loading && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontSize: 12, color: "#666" }, children: "Loading files\u2026" }),
799
- error && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontSize: 12, color: "#b91c1c" }, children: error }),
800
- !loading && !error && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("ul", { className: listClassName, style: { listStyle: "none", padding: 0, margin: 0, display: "grid", gap: 8 }, children: [
801
- visible.map((f2) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
767
+ loading && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: "#666" }, children: "Loading files\u2026" }),
768
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontSize: 12, color: "#b91c1c" }, children: error }),
769
+ !loading && !error && /* @__PURE__ */ jsxRuntime.jsxs("ul", { className: listClassName, style: { listStyle: "none", padding: 0, margin: 0, display: "grid", gap: 8 }, children: [
770
+ visible.map((f2) => /* @__PURE__ */ jsxRuntime.jsxs(
802
771
  "li",
803
772
  {
804
773
  className: itemClassName,
805
774
  style: { border: "1px solid #e5e7eb", borderRadius: 8, padding: 10, display: "flex", justifyContent: "space-between", alignItems: "center" },
806
775
  children: [
807
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { minWidth: 0 }, children: [
808
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontWeight: 500, overflow: "hidden", textOverflow: "ellipsis" }, children: f2.originalName }),
809
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: 12, color: "#666" }, children: [
776
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { minWidth: 0 }, children: [
777
+ /* @__PURE__ */ jsxRuntime.jsx("div", { style: { fontWeight: 500, overflow: "hidden", textOverflow: "ellipsis" }, children: f2.originalName }),
778
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { fontSize: 12, color: "#666" }, children: [
810
779
  (f2.size / (1024 * 1024)).toFixed(2),
811
780
  " MB \u2022 ",
812
781
  f2.contentType
813
782
  ] })
814
783
  ] }),
815
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
816
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: f2.url, target: "_blank", rel: "noreferrer", style: { fontSize: 12, color: "#2563eb" }, children: "View" }),
817
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
784
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", gap: 8, alignItems: "center" }, children: [
785
+ /* @__PURE__ */ jsxRuntime.jsx("a", { href: f2.url, target: "_blank", rel: "noreferrer", style: { fontSize: 12, color: "#2563eb" }, children: "View" }),
786
+ /* @__PURE__ */ jsxRuntime.jsx(
818
787
  "button",
819
788
  {
820
789
  onClick: async () => {
@@ -851,7 +820,7 @@ var ProjectFilesWidget = ({
851
820
  children: savingKey === f2.key ? "Saving\u2026" : "Use"
852
821
  }
853
822
  ),
854
- showDelete && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
823
+ showDelete && /* @__PURE__ */ jsxRuntime.jsx(
855
824
  "button",
856
825
  {
857
826
  onClick: () => handleDelete(f2.key),
@@ -865,15 +834,11 @@ var ProjectFilesWidget = ({
865
834
  },
866
835
  f2.key
867
836
  )),
868
- visible.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("li", { style: { fontSize: 12, color: "#666" }, children: "No files found" })
837
+ visible.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("li", { style: { fontSize: 12, color: "#666" }, children: "No files found" })
869
838
  ] })
870
839
  ] });
871
840
  };
872
841
 
873
- // src/ConnectProjectDialog.tsx
874
- var React3 = __toESM(require("react"));
875
- var Dialog = __toESM(require("@radix-ui/react-dialog"));
876
-
877
842
  // src/projectConnect.ts
878
843
  var f = (globalThis.fetch || fetch).bind(globalThis);
879
844
  async function httpJson(input, init, useFetch) {
@@ -963,19 +928,16 @@ function connectUsingApiKey(opts) {
963
928
  const client = new UpfilesClient({ baseUrl, apiKey, apiKeyHeader: opts.apiKeyHeader ?? "authorization" });
964
929
  return { apiKey, client };
965
930
  }
966
-
967
- // src/ConnectProjectDialog.tsx
968
- var import_jsx_runtime3 = require("react/jsx-runtime");
969
931
  function ConnectProjectDialog(props) {
970
932
  const { baseUrl, open, onOpenChange, onConnected, fetchImpl, title, description, className } = props;
971
- const [mode, setMode] = React3.useState("existing");
972
- const [loading, setLoading] = React3.useState(false);
973
- const [error, setError] = React3.useState(null);
974
- const [projects, setProjects] = React3.useState([]);
975
- const [selectedProjectId, setSelectedProjectId] = React3.useState("");
976
- const [manualKey, setManualKey] = React3.useState("");
977
- const [newProjectName, setNewProjectName] = React3.useState("");
978
- const resetState = React3.useCallback(() => {
933
+ const [mode, setMode] = React4__namespace.useState("existing");
934
+ const [loading, setLoading] = React4__namespace.useState(false);
935
+ const [error, setError] = React4__namespace.useState(null);
936
+ const [projects, setProjects] = React4__namespace.useState([]);
937
+ const [selectedProjectId, setSelectedProjectId] = React4__namespace.useState("");
938
+ const [manualKey, setManualKey] = React4__namespace.useState("");
939
+ const [newProjectName, setNewProjectName] = React4__namespace.useState("");
940
+ const resetState = React4__namespace.useCallback(() => {
979
941
  setMode("existing");
980
942
  setLoading(false);
981
943
  setError(null);
@@ -984,7 +946,7 @@ function ConnectProjectDialog(props) {
984
946
  setManualKey("");
985
947
  setNewProjectName("");
986
948
  }, []);
987
- React3.useEffect(() => {
949
+ React4__namespace.useEffect(() => {
988
950
  const run = async () => {
989
951
  if (!open || mode !== "existing") return;
990
952
  try {
@@ -1046,8 +1008,8 @@ function ConnectProjectDialog(props) {
1046
1008
  setLoading(false);
1047
1009
  }
1048
1010
  };
1049
- const ModeSwitcher = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "grid grid-cols-3 gap-2", children: [
1050
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1011
+ const ModeSwitcher = /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-3 gap-2", children: [
1012
+ /* @__PURE__ */ jsxRuntime.jsx(
1051
1013
  "button",
1052
1014
  {
1053
1015
  type: "button",
@@ -1056,7 +1018,7 @@ function ConnectProjectDialog(props) {
1056
1018
  children: "Connect existing"
1057
1019
  }
1058
1020
  ),
1059
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1021
+ /* @__PURE__ */ jsxRuntime.jsx(
1060
1022
  "button",
1061
1023
  {
1062
1024
  type: "button",
@@ -1065,7 +1027,7 @@ function ConnectProjectDialog(props) {
1065
1027
  children: "Add API key"
1066
1028
  }
1067
1029
  ),
1068
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1030
+ /* @__PURE__ */ jsxRuntime.jsx(
1069
1031
  "button",
1070
1032
  {
1071
1033
  type: "button",
@@ -1075,19 +1037,19 @@ function ConnectProjectDialog(props) {
1075
1037
  }
1076
1038
  )
1077
1039
  ] });
1078
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog.Root, { open, onOpenChange: (o) => {
1040
+ return /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Root, { open, onOpenChange: (o) => {
1079
1041
  if (!o) resetState();
1080
1042
  onOpenChange(o);
1081
- }, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Dialog.Portal, { children: [
1082
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog.Overlay, { className: "fixed inset-0 bg-black/40" }),
1083
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog.Content, { className: `fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[95vw] max-w-md rounded-lg border bg-white p-4 shadow-lg ${className ?? ""}`, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-3", children: [
1084
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog.Title, { className: "text-lg font-semibold", children: title ?? "Connect to Upfiles" }),
1085
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog.Description, { className: "text-sm text-muted-foreground", children: description ?? "Choose how to connect your project to retrieve an API key." }),
1043
+ }, children: /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Portal, { children: [
1044
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Overlay, { className: "fixed inset-0 bg-black/40" }),
1045
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Content, { className: `fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[95vw] max-w-md rounded-lg border bg-white p-4 shadow-lg ${className ?? ""}`, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", children: [
1046
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Title, { className: "text-lg font-semibold", children: title ?? "Connect to Upfiles" }),
1047
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Description, { className: "text-sm text-muted-foreground", children: description ?? "Choose how to connect your project to retrieve an API key." }),
1086
1048
  ModeSwitcher,
1087
- error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "rounded border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700", children: error }),
1088
- mode === "existing" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-2", children: [
1089
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "text-sm font-medium", children: "Project" }),
1090
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
1049
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "rounded border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700", children: error }),
1050
+ mode === "existing" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
1051
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Project" }),
1052
+ /* @__PURE__ */ jsxRuntime.jsxs(
1091
1053
  "select",
1092
1054
  {
1093
1055
  className: "w-full rounded border px-3 py-2 text-sm",
@@ -1095,14 +1057,14 @@ function ConnectProjectDialog(props) {
1095
1057
  onChange: (e) => setSelectedProjectId(e.target.value),
1096
1058
  disabled: loading,
1097
1059
  children: [
1098
- projects.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: loading ? "Loading..." : "No projects found" }),
1099
- projects.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: p.id, children: p.name }, p.id))
1060
+ projects.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: loading ? "Loading..." : "No projects found" }),
1061
+ projects.map((p) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: p.id, children: p.name }, p.id))
1100
1062
  ]
1101
1063
  }
1102
1064
  ),
1103
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex justify-end gap-2 pt-2", children: [
1104
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "px-3 py-2 text-sm rounded border", children: "Cancel" }) }),
1105
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1065
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 pt-2", children: [
1066
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "px-3 py-2 text-sm rounded border", children: "Cancel" }) }),
1067
+ /* @__PURE__ */ jsxRuntime.jsx(
1106
1068
  "button",
1107
1069
  {
1108
1070
  type: "button",
@@ -1114,9 +1076,9 @@ function ConnectProjectDialog(props) {
1114
1076
  )
1115
1077
  ] })
1116
1078
  ] }),
1117
- mode === "manual" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-2", children: [
1118
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "text-sm font-medium", children: "API key" }),
1119
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1079
+ mode === "manual" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
1080
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "API key" }),
1081
+ /* @__PURE__ */ jsxRuntime.jsx(
1120
1082
  "input",
1121
1083
  {
1122
1084
  className: "w-full rounded border px-3 py-2 text-sm",
@@ -1126,9 +1088,9 @@ function ConnectProjectDialog(props) {
1126
1088
  disabled: loading
1127
1089
  }
1128
1090
  ),
1129
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex justify-end gap-2 pt-2", children: [
1130
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "px-3 py-2 text-sm rounded border", children: "Cancel" }) }),
1131
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1091
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 pt-2", children: [
1092
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "px-3 py-2 text-sm rounded border", children: "Cancel" }) }),
1093
+ /* @__PURE__ */ jsxRuntime.jsx(
1132
1094
  "button",
1133
1095
  {
1134
1096
  type: "button",
@@ -1140,9 +1102,9 @@ function ConnectProjectDialog(props) {
1140
1102
  )
1141
1103
  ] })
1142
1104
  ] }),
1143
- mode === "new" && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "space-y-2", children: [
1144
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { className: "text-sm font-medium", children: "Project name" }),
1145
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1105
+ mode === "new" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-2", children: [
1106
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "text-sm font-medium", children: "Project name" }),
1107
+ /* @__PURE__ */ jsxRuntime.jsx(
1146
1108
  "input",
1147
1109
  {
1148
1110
  className: "w-full rounded border px-3 py-2 text-sm",
@@ -1152,10 +1114,10 @@ function ConnectProjectDialog(props) {
1152
1114
  disabled: loading
1153
1115
  }
1154
1116
  ),
1155
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-muted-foreground", children: "A project will be created in your Upfiles account and an API key generated." }),
1156
- /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex justify-end gap-2 pt-2", children: [
1157
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "button", className: "px-3 py-2 text-sm rounded border", children: "Cancel" }) }),
1158
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1117
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-muted-foreground", children: "A project will be created in your Upfiles account and an API key generated." }),
1118
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-2 pt-2", children: [
1119
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { type: "button", className: "px-3 py-2 text-sm rounded border", children: "Cancel" }) }),
1120
+ /* @__PURE__ */ jsxRuntime.jsx(
1159
1121
  "button",
1160
1122
  {
1161
1123
  type: "button",
@@ -1205,60 +1167,60 @@ async function fetchProjectImagesWithThumbs(clientOptions, opts) {
1205
1167
  results.sort((a, b) => (keyToIndex.get(a.key) ?? 0) - (keyToIndex.get(b.key) ?? 0));
1206
1168
  return { items: results, updatedAt };
1207
1169
  }
1208
-
1209
- // src/ImageManager.tsx
1210
- var React4 = __toESM(require("react"));
1211
- var Dialog2 = __toESM(require("@radix-ui/react-dialog"));
1212
- var import_jsx_runtime4 = require("react/jsx-runtime");
1213
- var IconGrid = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1214
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { width: "7", height: "7", x: "3", y: "3", rx: "1" }),
1215
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
1216
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" }),
1217
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { width: "7", height: "7", x: "3", y: "14", rx: "1" })
1170
+ var IconGrid = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1171
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "7", height: "7", x: "3", y: "3", rx: "1" }),
1172
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "7", height: "7", x: "14", y: "3", rx: "1" }),
1173
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "7", height: "7", x: "14", y: "14", rx: "1" }),
1174
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "7", height: "7", x: "3", y: "14", rx: "1" })
1218
1175
  ] });
1219
- var IconUploadCloud = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1220
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242" }),
1221
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M12 12v9" }),
1222
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m16 16-4-4-4 4" })
1176
+ var IconUploadCloud = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1177
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 14.899A7 7 0 1 1 15.71 8h1.79a4.5 4.5 0 0 1 2.5 8.242" }),
1178
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M12 12v9" }),
1179
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m16 16-4-4-4 4" })
1223
1180
  ] });
1224
- var IconFolder = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", stroke: "currentColor", strokeWidth: "0", className, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M19.5 21a3 3 0 0 0 3-3v-4.5a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3V18a3 3 0 0 0 3 3h15ZM1.5 10.146V6a3 3 0 0 1 3-3h5.379a2.25 2.25 0 0 1 1.59.659l2.122 2.121c.14.141.331.22.53.22H19.5a3 3 0 0 1 3 3v1.146A4.483 4.483 0 0 0 19.5 9h-15a4.483 4.483 0 0 0-3 1.146Z" }) });
1225
- var IconFolderPlus = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1226
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2Z" }),
1227
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "12", x2: "12", y1: "10", y2: "16" }),
1228
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "9", x2: "15", y1: "13", y2: "13" })
1181
+ var IconFolder = ({ className }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "currentColor", stroke: "currentColor", strokeWidth: "0", className, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19.5 21a3 3 0 0 0 3-3v-4.5a3 3 0 0 0-3-3h-15a3 3 0 0 0-3 3V18a3 3 0 0 0 3 3h15ZM1.5 10.146V6a3 3 0 0 1 3-3h5.379a2.25 2.25 0 0 1 1.59.659l2.122 2.121c.14.141.331.22.53.22H19.5a3 3 0 0 1 3 3v1.146A4.483 4.483 0 0 0 19.5 9h-15a4.483 4.483 0 0 0-3 1.146Z" }) });
1182
+ var IconFolderPlus = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1183
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M4 20h16a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.93a2 2 0 0 1-1.66-.9l-.82-1.2A2 2 0 0 0 7.93 2H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2Z" }),
1184
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "12", x2: "12", y1: "10", y2: "16" }),
1185
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "9", x2: "15", y1: "13", y2: "13" })
1229
1186
  ] });
1230
- var IconSearch = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1231
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
1232
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m21 21-4.3-4.3" })
1187
+ var IconSearch = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1188
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "11", cy: "11", r: "8" }),
1189
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m21 21-4.3-4.3" })
1233
1190
  ] });
1234
- var IconRefresh = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1235
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
1236
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 3v5h-5" }),
1237
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
1238
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M8 16H3v5" })
1191
+ var IconRefresh = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1192
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8" }),
1193
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 3v5h-5" }),
1194
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16" }),
1195
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 16H3v5" })
1239
1196
  ] });
1240
- var IconChevronRight = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m9 18 6-6-6-6" }) });
1241
- var IconTrash = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1242
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M3 6h18" }),
1243
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }),
1244
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" }),
1245
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "10", x2: "10", y1: "11", y2: "17" }),
1246
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("line", { x1: "14", x2: "14", y1: "11", y2: "17" })
1197
+ var IconChevronRight = ({ className }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m9 18 6-6-6-6" }) });
1198
+ var IconTrash = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1199
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 6h18" }),
1200
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6" }),
1201
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2" }),
1202
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "10", x2: "10", y1: "11", y2: "17" }),
1203
+ /* @__PURE__ */ jsxRuntime.jsx("line", { x1: "14", x2: "14", y1: "11", y2: "17" })
1247
1204
  ] });
1248
- var IconX = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1249
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M18 6 6 18" }),
1250
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m6 6 12 12" })
1205
+ var IconX = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1206
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M18 6 6 18" }),
1207
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m6 6 12 12" })
1251
1208
  ] });
1252
- var IconHome = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1253
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }),
1254
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("polyline", { points: "9 22 9 12 15 12 15 22" })
1209
+ var IconHome = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1210
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" }),
1211
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "9 22 9 12 15 12 15 22" })
1255
1212
  ] });
1256
- var IconImage = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1257
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
1258
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("circle", { cx: "9", cy: "9", r: "2" }),
1259
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
1213
+ var IconImage = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1214
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2" }),
1215
+ /* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "9", cy: "9", r: "2" }),
1216
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21" })
1217
+ ] });
1218
+ var IconLoader = ({ className }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
1219
+ var IconLayers = ({ className }) => /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: [
1220
+ /* @__PURE__ */ jsxRuntime.jsx("polygon", { points: "12 2 2 7 12 12 22 7 12 2" }),
1221
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "2 17 12 22 22 17" }),
1222
+ /* @__PURE__ */ jsxRuntime.jsx("polyline", { points: "2 12 12 17 22 12" })
1260
1223
  ] });
1261
- var IconLoader = ({ className }) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("svg", { xmlns: "http://www.w3.org/2000/svg", width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) });
1262
1224
  function ImageManager(props) {
1263
1225
  const {
1264
1226
  open,
@@ -1281,23 +1243,35 @@ function ImageManager(props) {
1281
1243
  showDelete = true,
1282
1244
  refreshInterval = 5e3
1283
1245
  } = props;
1284
- const [activeView, setActiveView] = React4.useState(mode === "upload" ? "upload" : "browse");
1285
- const [loading, setLoading] = React4.useState(false);
1286
- const [error, setError] = React4.useState(null);
1287
- const [currentFolderId, setCurrentFolderId] = React4.useState(void 0);
1288
- const [breadcrumbs, setBreadcrumbs] = React4.useState([{ id: void 0, name: "Home" }]);
1289
- const [files, setFiles] = React4.useState([]);
1290
- const [folders, setFolders] = React4.useState([]);
1291
- const [query, setQuery] = React4.useState("");
1292
- const [deleting, setDeleting] = React4.useState(null);
1293
- const [showCreateFolder, setShowCreateFolder] = React4.useState(false);
1294
- const [newFolderName, setNewFolderName] = React4.useState("");
1295
- const [creatingFolder, setCreatingFolder] = React4.useState(false);
1296
- const [fileToDelete, setFileToDelete] = React4.useState(null);
1297
- const [thumbnailSelectorFile, setThumbnailSelectorFile] = React4.useState(null);
1298
- const lastUpdatedRef = React4.useRef(null);
1299
- const isFetchingRef = React4.useRef(false);
1300
- const load = React4.useCallback(async (isPolling = false) => {
1246
+ const [activeView, setActiveView] = React4__namespace.useState(mode === "upload" ? "upload" : "browse");
1247
+ const [loading, setLoading] = React4__namespace.useState(false);
1248
+ const [error, setError] = React4__namespace.useState(null);
1249
+ const [currentFolderId, setCurrentFolderId] = React4__namespace.useState(void 0);
1250
+ const [breadcrumbs, setBreadcrumbs] = React4__namespace.useState([{ id: void 0, name: "Home" }]);
1251
+ const [files, setFiles] = React4__namespace.useState([]);
1252
+ const [folders, setFolders] = React4__namespace.useState([]);
1253
+ const [query, setQuery] = React4__namespace.useState("");
1254
+ const [deleting, setDeleting] = React4__namespace.useState(null);
1255
+ const [showCreateFolder, setShowCreateFolder] = React4__namespace.useState(false);
1256
+ const [newFolderName, setNewFolderName] = React4__namespace.useState("");
1257
+ const [creatingFolder, setCreatingFolder] = React4__namespace.useState(false);
1258
+ const [fileToDelete, setFileToDelete] = React4__namespace.useState(null);
1259
+ const [thumbnailSelectorFile, setThumbnailSelectorFile] = React4__namespace.useState(null);
1260
+ const [selectedThumbnailForFile, setSelectedThumbnailForFile] = React4__namespace.useState(null);
1261
+ const [previewFile, setPreviewFile] = React4__namespace.useState(null);
1262
+ const lastUpdatedRef = React4__namespace.useRef(null);
1263
+ const isFetchingRef = React4__namespace.useRef(false);
1264
+ const deduplicateFiles = React4__namespace.useCallback((files2) => {
1265
+ const seen = /* @__PURE__ */ new Set();
1266
+ return files2.filter((file) => {
1267
+ if (seen.has(file.key)) {
1268
+ return false;
1269
+ }
1270
+ seen.add(file.key);
1271
+ return true;
1272
+ });
1273
+ }, []);
1274
+ const load = React4__namespace.useCallback(async (isPolling = false) => {
1301
1275
  if (isFetchingRef.current) return;
1302
1276
  isFetchingRef.current = true;
1303
1277
  try {
@@ -1313,7 +1287,7 @@ function ImageManager(props) {
1313
1287
  const { items: list, updatedAt } = filesData;
1314
1288
  if (isPolling && updatedAt && updatedAt === lastUpdatedRef.current) {
1315
1289
  }
1316
- setFiles(list);
1290
+ setFiles(deduplicateFiles(list));
1317
1291
  setFolders(foldersData);
1318
1292
  lastUpdatedRef.current = updatedAt;
1319
1293
  } catch (e) {
@@ -1323,7 +1297,7 @@ function ImageManager(props) {
1323
1297
  isFetchingRef.current = false;
1324
1298
  }
1325
1299
  }, [clientOptions, folderPath, currentFolderId, breadcrumbs]);
1326
- React4.useEffect(() => {
1300
+ React4__namespace.useEffect(() => {
1327
1301
  if (!open) {
1328
1302
  setFiles([]);
1329
1303
  setFolders([]);
@@ -1336,7 +1310,7 @@ function ImageManager(props) {
1336
1310
  load();
1337
1311
  }
1338
1312
  }, [open, activeView, load, mode]);
1339
- React4.useEffect(() => {
1313
+ React4__namespace.useEffect(() => {
1340
1314
  if (!open) return;
1341
1315
  const client = new UpfilesClient(clientOptions);
1342
1316
  const url = client.getEventsUrl(projectId);
@@ -1348,7 +1322,7 @@ function ImageManager(props) {
1348
1322
  const newFile = payload.data.file;
1349
1323
  setFiles((prev) => {
1350
1324
  if (prev.find((f2) => f2.key === newFile.key)) return prev;
1351
- return [newFile, ...prev];
1325
+ return deduplicateFiles([newFile, ...prev]);
1352
1326
  });
1353
1327
  } else if (payload.type === "file:deleted") {
1354
1328
  const deletedKey = payload.data.fileKey || payload.data.file?.key;
@@ -1360,11 +1334,11 @@ function ImageManager(props) {
1360
1334
  };
1361
1335
  return () => eventSource.close();
1362
1336
  }, [open, clientOptions, projectId]);
1363
- const visibleFiles = React4.useMemo(() => {
1337
+ const visibleFiles = React4__namespace.useMemo(() => {
1364
1338
  const q = query.trim().toLowerCase();
1365
1339
  return !q ? files : files.filter((i) => (i.originalName || "").toLowerCase().includes(q));
1366
1340
  }, [files, query]);
1367
- const visibleFolders = React4.useMemo(() => {
1341
+ const visibleFolders = React4__namespace.useMemo(() => {
1368
1342
  const q = query.trim().toLowerCase();
1369
1343
  return !q ? folders : folders.filter((f2) => (f2.name || "").toLowerCase().includes(q));
1370
1344
  }, [folders, query]);
@@ -1433,7 +1407,7 @@ function ImageManager(props) {
1433
1407
  setCurrentFolderId(target.id);
1434
1408
  setQuery("");
1435
1409
  };
1436
- const uploadFoldersList = React4.useMemo(() => {
1410
+ const uploadFoldersList = React4__namespace.useMemo(() => {
1437
1411
  const options = [];
1438
1412
  options.push({ id: "root", name: "Root ( / )", path: void 0 });
1439
1413
  if (currentFolderId) {
@@ -1446,65 +1420,82 @@ function ImageManager(props) {
1446
1420
  });
1447
1421
  return options;
1448
1422
  }, [breadcrumbs, currentFolderId, folders]);
1449
- const [selectedUploadFolder, setSelectedUploadFolder] = React4.useState("current");
1450
- const activeBreadcrumbPath = React4.useMemo(() => {
1423
+ const [selectedUploadFolder, setSelectedUploadFolder] = React4__namespace.useState("current");
1424
+ const activeBreadcrumbPath = React4__namespace.useMemo(() => {
1451
1425
  return breadcrumbs.length > 1 ? breadcrumbs.slice(1).map((b) => b.name).join("/") + "/" : void 0;
1452
1426
  }, [breadcrumbs]);
1453
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Dialog2.Root, { open, onOpenChange, children: [
1454
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Dialog2.Portal, { children: [
1455
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog2.Overlay, { className: "fixed inset-0 bg-gray-900/50 backdrop-blur-sm z-50 transition-all duration-300" }),
1456
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1457
- Dialog2.Content,
1427
+ return /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Root, { open, onOpenChange, children: [
1428
+ /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Portal, { children: [
1429
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Overlay, { className: "fixed inset-0 bg-black/60 backdrop-blur-sm z-50 transition-all duration-300 flex items-center justify-center" }),
1430
+ /* @__PURE__ */ jsxRuntime.jsxs(
1431
+ Dialog2__namespace.Content,
1458
1432
  {
1459
- className: `fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[90vw] h-[85vh] max-w-6xl rounded-2xl bg-white dark:bg-gray-950 shadow-2xl z-50 overflow-hidden flex flex-row ${className ?? ""}`,
1433
+ className: `fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[95vw] h-[90vh] max-w-7xl min-w-[800px] min-h-[600px] rounded-2xl bg-white dark:bg-gray-950 shadow-2xl z-[51] overflow-hidden flex flex-row ${className ?? ""}`,
1460
1434
  children: [
1461
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "w-64 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-800 flex flex-col flex-shrink-0", children: [
1462
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "p-6", children: [
1463
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("h2", { className: "text-lg font-bold text-gray-900 dark:text-white flex items-center gap-2", children: [
1464
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconImage, { className: "text-blue-600" }),
1435
+ /* @__PURE__ */ jsxRuntime.jsx(
1436
+ Dialog2__namespace.Title,
1437
+ {
1438
+ style: {
1439
+ position: "absolute",
1440
+ width: "1px",
1441
+ height: "1px",
1442
+ padding: "0",
1443
+ margin: "-1px",
1444
+ overflow: "hidden",
1445
+ clip: "rect(0, 0, 0, 0)",
1446
+ whiteSpace: "nowrap",
1447
+ border: "0"
1448
+ },
1449
+ children: title ?? "Media Library"
1450
+ }
1451
+ ),
1452
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-64 min-w-[256px] bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-800 flex flex-col flex-shrink-0", children: [
1453
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6", children: [
1454
+ /* @__PURE__ */ jsxRuntime.jsxs("h2", { className: "text-lg font-bold text-gray-900 dark:text-white flex items-center gap-2", children: [
1455
+ /* @__PURE__ */ jsxRuntime.jsx(IconImage, { className: "text-blue-600" }),
1465
1456
  title ?? "Media Library"
1466
1457
  ] }),
1467
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-xs text-gray-500 mt-1", children: description ?? "Manage your assets" })
1458
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-xs text-gray-500 mt-1", children: description ?? "Manage your assets" })
1468
1459
  ] }),
1469
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("nav", { className: "flex-1 px-3 space-y-1", children: [
1470
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1460
+ /* @__PURE__ */ jsxRuntime.jsxs("nav", { className: "flex-1 px-3 space-y-1", children: [
1461
+ /* @__PURE__ */ jsxRuntime.jsxs(
1471
1462
  "button",
1472
1463
  {
1473
1464
  onClick: () => setActiveView("browse"),
1474
1465
  className: `w-full flex items-center gap-3 px-3 py-2.5 text-sm font-medium rounded-lg transition-colors ${activeView === "browse" ? "bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-400 shadow-sm" : "text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800"}`,
1475
1466
  children: [
1476
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconGrid, { className: "w-4 h-4" }),
1467
+ /* @__PURE__ */ jsxRuntime.jsx(IconGrid, { className: "w-4 h-4" }),
1477
1468
  "All Files"
1478
1469
  ]
1479
1470
  }
1480
1471
  ),
1481
- mode === "full" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1472
+ mode === "full" && /* @__PURE__ */ jsxRuntime.jsxs(
1482
1473
  "button",
1483
1474
  {
1484
1475
  onClick: () => setActiveView("upload"),
1485
1476
  className: `w-full flex items-center gap-3 px-3 py-2.5 text-sm font-medium rounded-lg transition-colors ${activeView === "upload" ? "bg-white dark:bg-gray-800 text-blue-600 dark:text-blue-400 shadow-sm" : "text-gray-600 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800"}`,
1486
1477
  children: [
1487
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconUploadCloud, { className: "w-4 h-4" }),
1478
+ /* @__PURE__ */ jsxRuntime.jsx(IconUploadCloud, { className: "w-4 h-4" }),
1488
1479
  "Upload New"
1489
1480
  ]
1490
1481
  }
1491
1482
  )
1492
1483
  ] }),
1493
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "p-4 border-t border-gray-200 dark:border-gray-800", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "text-xs text-center text-gray-400", children: [
1484
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-4 border-t border-gray-200 dark:border-gray-800", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-xs text-center text-gray-400", children: [
1494
1485
  files.length,
1495
1486
  " files \u2022 ",
1496
1487
  folders.length,
1497
1488
  " folders"
1498
1489
  ] }) })
1499
1490
  ] }),
1500
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex-1 flex flex-col bg-white dark:bg-gray-950 relative", children: [
1501
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "h-16 border-b border-gray-100 dark:border-gray-800 flex items-center justify-between px-6 gap-4", children: [
1502
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex items-center gap-4 flex-1", children: activeView === "browse" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1503
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center text-sm text-gray-500 overflow-hidden whitespace-nowrap", children: [
1504
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: () => handleBreadcrumbClick(0), className: "hover:text-blue-600 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconHome, { className: "w-4 h-4" }) }),
1505
- breadcrumbs.slice(1).map((b, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(React4.Fragment, { children: [
1506
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconChevronRight, { className: "w-4 h-4 text-gray-300 mx-1" }),
1507
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1491
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 flex flex-col bg-white dark:bg-gray-950 relative", children: [
1492
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-16 border-b border-gray-100 dark:border-gray-800 flex items-center justify-between px-6 gap-4", children: [
1493
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-4 flex-1", children: activeView === "browse" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1494
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center text-sm text-gray-500 overflow-hidden whitespace-nowrap", children: [
1495
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => handleBreadcrumbClick(0), className: "hover:text-blue-600 transition-colors", children: /* @__PURE__ */ jsxRuntime.jsx(IconHome, { className: "w-4 h-4" }) }),
1496
+ breadcrumbs.slice(1).map((b, i) => /* @__PURE__ */ jsxRuntime.jsxs(React4__namespace.Fragment, { children: [
1497
+ /* @__PURE__ */ jsxRuntime.jsx(IconChevronRight, { className: "w-4 h-4 text-gray-300 mx-1" }),
1498
+ /* @__PURE__ */ jsxRuntime.jsx(
1508
1499
  "button",
1509
1500
  {
1510
1501
  onClick: () => handleBreadcrumbClick(i + 1),
@@ -1512,23 +1503,23 @@ function ImageManager(props) {
1512
1503
  children: b.name
1513
1504
  }
1514
1505
  )
1515
- ] }, b.id || i))
1506
+ ] }, `${b.id || "breadcrumb"}-${i}`))
1516
1507
  ] }),
1517
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-4 w-px bg-gray-200 dark:bg-gray-700 mx-2" }),
1518
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1508
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-px bg-gray-200 dark:bg-gray-700 mx-2" }),
1509
+ /* @__PURE__ */ jsxRuntime.jsx(
1519
1510
  "button",
1520
1511
  {
1521
1512
  onClick: () => load(),
1522
1513
  disabled: loading,
1523
1514
  className: "p-1.5 text-gray-400 hover:text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-md transition-all disabled:opacity-50",
1524
1515
  title: "Refresh",
1525
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconRefresh, { className: `w-4 h-4 ${loading ? "animate-spin" : ""}` })
1516
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconRefresh, { className: `w-4 h-4 ${loading ? "animate-spin" : ""}` })
1526
1517
  }
1527
1518
  ),
1528
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-4 w-px bg-gray-200 dark:bg-gray-700 mx-2" }),
1529
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "relative flex-1 max-w-sm group", children: [
1530
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconSearch, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 group-focus-within:text-blue-500 transition-colors" }),
1531
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1519
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-px bg-gray-200 dark:bg-gray-700 mx-2" }),
1520
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative flex-1 max-w-sm group", children: [
1521
+ /* @__PURE__ */ jsxRuntime.jsx(IconSearch, { className: "absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 group-focus-within:text-blue-500 transition-colors" }),
1522
+ /* @__PURE__ */ jsxRuntime.jsx(
1532
1523
  "input",
1533
1524
  {
1534
1525
  value: query,
@@ -1539,26 +1530,26 @@ function ImageManager(props) {
1539
1530
  )
1540
1531
  ] })
1541
1532
  ] }) }),
1542
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2", children: [
1543
- activeView === "browse" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1544
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: () => setShowCreateFolder(true), className: "p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/10 rounded-lg transition-colors", title: "New Folder", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconFolderPlus, { className: "w-5 h-5" }) }),
1545
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: () => load(), className: `p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/10 rounded-lg transition-colors ${loading ? "animate-spin text-blue-600" : ""}`, title: "Refresh", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconLoader, { className: "w-5 h-5" }) })
1533
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1534
+ activeView === "browse" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1535
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setShowCreateFolder(true), className: "p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/10 rounded-lg transition-colors", title: "New Folder", children: /* @__PURE__ */ jsxRuntime.jsx(IconFolderPlus, { className: "w-5 h-5" }) }),
1536
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => load(), className: `p-2 text-gray-400 hover:text-blue-600 hover:bg-blue-50 dark:hover:bg-blue-900/10 rounded-lg transition-colors ${loading ? "animate-spin text-blue-600" : ""}`, title: "Refresh", children: /* @__PURE__ */ jsxRuntime.jsx(IconLoader, { className: "w-5 h-5" }) })
1546
1537
  ] }),
1547
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog2.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { className: "ml-2 p-2 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/10 rounded-lg transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconX, { className: "w-5 h-5" }) }) })
1538
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Close, { asChild: true, children: /* @__PURE__ */ jsxRuntime.jsx("button", { className: "ml-2 p-2 text-gray-400 hover:text-red-500 hover:bg-red-50 dark:hover:bg-red-900/10 rounded-lg transition-colors", children: /* @__PURE__ */ jsxRuntime.jsx(IconX, { className: "w-5 h-5" }) }) })
1548
1539
  ] })
1549
1540
  ] }),
1550
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex-1 overflow-y-auto p-6 bg-gray-50/30 dark:bg-gray-900/30", children: [
1551
- activeView === "browse" && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
1552
- error && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "mb-6 bg-red-50 text-red-600 p-4 rounded-lg text-sm border border-red-100 flex items-center gap-2", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: error }) }),
1553
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: gridClassName ?? "grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-6", children: [
1554
- visibleFolders.map((folder) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1541
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex-1 overflow-y-auto p-6 bg-gray-50/30 dark:bg-gray-900/30", children: [
1542
+ activeView === "browse" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
1543
+ error && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-6 bg-red-50 text-red-600 p-4 rounded-lg text-sm border border-red-100 flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx("span", { children: error }) }),
1544
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: gridClassName ?? "grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-6", children: [
1545
+ visibleFolders.map((folder) => /* @__PURE__ */ jsxRuntime.jsxs(
1555
1546
  "div",
1556
1547
  {
1557
1548
  onClick: () => handleNavigate(folder),
1558
1549
  className: "group flex flex-col items-center gap-3 p-4 rounded-xl border border-gray-200/60 bg-white hover:border-blue-200 hover:shadow-lg hover:shadow-blue-500/5 hover:-translate-y-1 transition-all cursor-pointer",
1559
1550
  children: [
1560
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w-16 h-12 bg-blue-50 rounded-lg flex items-center justify-center text-blue-500 group-hover:scale-110 transition-transform", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconFolder, { className: "w-8 h-8 drop-shadow-sm" }) }),
1561
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "text-sm font-medium text-gray-700 truncate w-full text-center", children: folder.name })
1551
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-12 bg-blue-50 rounded-lg flex items-center justify-center text-blue-500 group-hover:scale-110 transition-transform", children: /* @__PURE__ */ jsxRuntime.jsx(IconFolder, { className: "w-8 h-8 drop-shadow-sm" }) }),
1552
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm font-medium text-gray-700 truncate w-full text-center", children: folder.name })
1562
1553
  ]
1563
1554
  },
1564
1555
  folder.id
@@ -1567,17 +1558,19 @@ function ImageManager(props) {
1567
1558
  const fWithThumbs = f2;
1568
1559
  const bestThumb = fWithThumbs.thumbnails?.sort((a, b) => a.size - b.size).find((t) => t.size >= 300) || fWithThumbs.thumbnails?.[fWithThumbs.thumbnails?.length - 1];
1569
1560
  const thumbUrl = bestThumb?.url || f2.url;
1570
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
1561
+ return /* @__PURE__ */ jsxRuntime.jsxs(
1571
1562
  "div",
1572
1563
  {
1573
- className: "group relative aspect-[4/3] bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm hover:shadow-xl hover:shadow-gray-200/50 hover:border-blue-300 transition-all duration-300",
1564
+ onClick: () => setPreviewFile(f2),
1565
+ className: "group relative aspect-[4/3] bg-white rounded-xl border border-gray-200 overflow-hidden shadow-sm hover:shadow-xl hover:shadow-gray-200/50 hover:border-blue-300 transition-all duration-300 cursor-pointer",
1574
1566
  children: [
1575
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("img", { src: thumbUrl, alt: "", className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-105" }),
1576
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex flex-col justify-end p-3", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex gap-2 justify-center transform translate-y-2 group-hover:translate-y-0 transition-transform duration-300", children: [
1577
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1567
+ /* @__PURE__ */ jsxRuntime.jsx("img", { src: thumbUrl, alt: f2.originalName, className: "w-full h-full object-cover transition-transform duration-700 group-hover:scale-105" }),
1568
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity duration-200 flex flex-col justify-end p-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2 justify-center transform translate-y-2 group-hover:translate-y-0 transition-transform duration-300", children: [
1569
+ /* @__PURE__ */ jsxRuntime.jsx(
1578
1570
  "button",
1579
1571
  {
1580
- onClick: () => {
1572
+ onClick: (e) => {
1573
+ e.stopPropagation();
1581
1574
  onSelect({
1582
1575
  url: f2.url,
1583
1576
  key: f2.key,
@@ -1592,7 +1585,20 @@ function ImageManager(props) {
1592
1585
  children: "Select"
1593
1586
  }
1594
1587
  ),
1595
- showDelete && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1588
+ fWithThumbs.thumbnails && fWithThumbs.thumbnails.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
1589
+ "button",
1590
+ {
1591
+ onClick: (e) => {
1592
+ e.stopPropagation();
1593
+ setThumbnailSelectorFile(f2);
1594
+ setSelectedThumbnailForFile(null);
1595
+ },
1596
+ className: "p-1.5 bg-white/20 text-white text-xs font-semibold rounded-md hover:bg-purple-500 backdrop-blur-md transition-colors",
1597
+ title: "Select Thumbnail",
1598
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconLayers, { className: "w-4 h-4" })
1599
+ }
1600
+ ),
1601
+ showDelete && /* @__PURE__ */ jsxRuntime.jsx(
1596
1602
  "button",
1597
1603
  {
1598
1604
  onClick: (e) => {
@@ -1600,44 +1606,44 @@ function ImageManager(props) {
1600
1606
  setFileToDelete(f2);
1601
1607
  },
1602
1608
  className: "p-1.5 bg-white/20 text-white text-xs font-semibold rounded-md hover:bg-red-500 backdrop-blur-md transition-colors",
1603
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconTrash, { className: "w-4 h-4" })
1609
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconTrash, { className: "w-4 h-4" })
1604
1610
  }
1605
1611
  )
1606
1612
  ] }) }),
1607
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "absolute top-2 right-2 bg-black/50 backdrop-blur-md text-white text-[10px] px-1.5 py-0.5 rounded opacity-0 group-hover:opacity-100 transition-opacity", children: f2.originalName.split(".").pop()?.toUpperCase() })
1613
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-2 right-2 bg-black/50 backdrop-blur-md text-white text-[10px] px-1.5 py-0.5 rounded opacity-0 group-hover:opacity-100 transition-opacity", children: f2.originalName.split(".").pop()?.toUpperCase() })
1608
1614
  ]
1609
1615
  },
1610
1616
  f2.key
1611
1617
  );
1612
1618
  })
1613
1619
  ] }),
1614
- !loading && visibleFolders.length === 0 && visibleFiles.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "h-full flex flex-col items-center justify-center text-gray-400", children: [
1615
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w-16 h-16 bg-gray-100 rounded-2xl flex items-center justify-center mb-4", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconSearch, { className: "w-8 h-8 opacity-40" }) }),
1616
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("h3", { className: "text-gray-900 font-medium mb-1", children: "No Assets Found" }),
1617
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-sm", children: "Try uploading a file or creating a new folder." })
1620
+ !loading && visibleFolders.length === 0 && visibleFiles.length === 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "h-full flex flex-col items-center justify-center text-gray-400", children: [
1621
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-16 h-16 bg-gray-100 rounded-2xl flex items-center justify-center mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(IconSearch, { className: "w-8 h-8 opacity-40" }) }),
1622
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { className: "text-gray-900 font-medium mb-1", children: "No Assets Found" }),
1623
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm", children: "Try uploading a file or creating a new folder." })
1618
1624
  ] })
1619
1625
  ] }),
1620
- activeView === "upload" && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "h-full flex flex-col items-center justify-center max-w-2xl mx-auto", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "w-full bg-white rounded-2xl border border-gray-200 p-8 shadow-sm", children: [
1621
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("h3", { className: "text-lg font-semibold text-gray-900 mb-6 flex items-center gap-2", children: [
1622
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconUploadCloud, { className: "text-blue-500" }),
1626
+ activeView === "upload" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-full flex flex-col items-center justify-center max-w-2xl mx-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full bg-white rounded-2xl border border-gray-200 p-8 shadow-sm", children: [
1627
+ /* @__PURE__ */ jsxRuntime.jsxs("h3", { className: "text-lg font-semibold text-gray-900 mb-6 flex items-center gap-2", children: [
1628
+ /* @__PURE__ */ jsxRuntime.jsx(IconUploadCloud, { className: "text-blue-500" }),
1623
1629
  "Upload Files"
1624
1630
  ] }),
1625
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "mb-6", children: [
1626
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Target Folder" }),
1627
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex gap-2", children: [
1628
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1631
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mb-6", children: [
1632
+ /* @__PURE__ */ jsxRuntime.jsx("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Target Folder" }),
1633
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-2", children: [
1634
+ /* @__PURE__ */ jsxRuntime.jsx(
1629
1635
  "select",
1630
1636
  {
1631
1637
  value: selectedUploadFolder,
1632
1638
  onChange: (e) => setSelectedUploadFolder(e.target.value),
1633
1639
  className: "block w-full rounded-lg border-gray-200 bg-gray-50 text-gray-900 text-sm focus:ring-blue-500 focus:border-blue-500 p-2.5",
1634
- children: uploadFoldersList.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("option", { value: opt.id, children: opt.name }, opt.id))
1640
+ children: uploadFoldersList.map((opt) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: opt.id, children: opt.name }, opt.id))
1635
1641
  }
1636
1642
  ),
1637
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: () => setShowCreateFolder(true), className: "px-3 bg-gray-100 hover:bg-gray-200 rounded-lg text-gray-600 transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconFolderPlus, { className: "w-5 h-5" }) })
1643
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setShowCreateFolder(true), className: "px-3 bg-gray-100 hover:bg-gray-200 rounded-lg text-gray-600 transition-colors", children: /* @__PURE__ */ jsxRuntime.jsx(IconFolderPlus, { className: "w-5 h-5" }) })
1638
1644
  ] })
1639
1645
  ] }),
1640
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1646
+ /* @__PURE__ */ jsxRuntime.jsx(
1641
1647
  Uploader,
1642
1648
  {
1643
1649
  clientOptions,
@@ -1660,7 +1666,10 @@ function ImageManager(props) {
1660
1666
  url: file.publicUrl,
1661
1667
  thumbnails: file.thumbnails
1662
1668
  };
1663
- setFiles((prev) => [newItem, ...prev]);
1669
+ setFiles((prev) => {
1670
+ if (prev.find((f2) => f2.key === newItem.key)) return prev;
1671
+ return deduplicateFiles([newItem, ...prev]);
1672
+ });
1664
1673
  }
1665
1674
  },
1666
1675
  onComplete: () => {
@@ -1673,11 +1682,11 @@ function ImageManager(props) {
1673
1682
  },
1674
1683
  dropzoneClassName: "border-2 border-dashed border-gray-300 bg-gray-50 rounded-xl p-12 text-center cursor-pointer hover:border-blue-500 hover:bg-blue-50/50 transition-all",
1675
1684
  buttonClassName: "hidden",
1676
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex flex-col items-center gap-4", children: [
1677
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "w-12 h-12 bg-blue-100 text-blue-600 rounded-full flex items-center justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(IconUploadCloud, { className: "w-6 h-6" }) }),
1678
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { children: [
1679
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-gray-900 font-medium", children: "Click to upload or drag and drop" }),
1680
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "text-xs text-gray-500 mt-1", children: [
1685
+ children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center gap-4", children: [
1686
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-12 h-12 bg-blue-100 text-blue-600 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx(IconUploadCloud, { className: "w-6 h-6" }) }),
1687
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1688
+ /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-gray-900 font-medium", children: "Click to upload or drag and drop" }),
1689
+ /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-xs text-gray-500 mt-1", children: [
1681
1690
  "Supports PNG, JPG, GIF up to ",
1682
1691
  Math.round(maxFileSize / 1024 / 1024),
1683
1692
  "MB"
@@ -1693,11 +1702,12 @@ function ImageManager(props) {
1693
1702
  }
1694
1703
  )
1695
1704
  ] }),
1696
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog2.Root, { open: showCreateFolder, onOpenChange: setShowCreateFolder, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Dialog2.Portal, { children: [
1697
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog2.Overlay, { className: "fixed inset-0 bg-black/40 z-[60]" }),
1698
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Dialog2.Content, { className: "fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-sm rounded-xl bg-white p-6 shadow-2xl z-[61] outline-none", children: [
1699
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog2.Title, { className: "text-lg font-semibold text-gray-900 mb-4", children: "New Folder" }),
1700
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1705
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Root, { open: showCreateFolder, onOpenChange: setShowCreateFolder, children: /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Portal, { children: [
1706
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Overlay, { className: "fixed inset-0 bg-black/40 z-[60]" }),
1707
+ /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Content, { className: "fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-sm rounded-xl bg-white p-6 shadow-2xl z-[61] outline-none", "aria-describedby": "new-folder-description", children: [
1708
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Title, { className: "text-lg font-semibold text-gray-900 mb-4", children: "New Folder" }),
1709
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Description, { id: "new-folder-description", className: "sr-only", children: "Create a new folder to organize your files" }),
1710
+ /* @__PURE__ */ jsxRuntime.jsx(
1701
1711
  "input",
1702
1712
  {
1703
1713
  autoFocus: true,
@@ -1708,9 +1718,9 @@ function ImageManager(props) {
1708
1718
  onKeyDown: (e) => e.key === "Enter" && handleCreateFolder()
1709
1719
  }
1710
1720
  ),
1711
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex justify-end gap-3", children: [
1712
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("button", { onClick: () => setShowCreateFolder(false), className: "px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 rounded-lg", children: "Cancel" }),
1713
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1721
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-3", children: [
1722
+ /* @__PURE__ */ jsxRuntime.jsx("button", { onClick: () => setShowCreateFolder(false), className: "px-4 py-2 text-sm font-medium text-gray-600 hover:bg-gray-100 rounded-lg", children: "Cancel" }),
1723
+ /* @__PURE__ */ jsxRuntime.jsx(
1714
1724
  "button",
1715
1725
  {
1716
1726
  onClick: handleCreateFolder,
@@ -1722,21 +1732,21 @@ function ImageManager(props) {
1722
1732
  ] })
1723
1733
  ] })
1724
1734
  ] }) }),
1725
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog2.Root, { open: !!fileToDelete, onOpenChange: (open2) => !open2 && setFileToDelete(null), children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Dialog2.Portal, { children: [
1726
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog2.Overlay, { className: "fixed inset-0 bg-black/40 z-[80]" }),
1727
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Dialog2.Content, { className: "fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md rounded-xl bg-white p-6 shadow-2xl z-[81]", children: [
1728
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog2.Title, { className: "text-xl font-semibold text-gray-900 mb-2", children: "Delete File" }),
1729
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(Dialog2.Description, { className: "text-gray-600 mb-6", children: [
1735
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Root, { open: !!fileToDelete, onOpenChange: (open2) => !open2 && setFileToDelete(null), children: /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Portal, { children: [
1736
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Overlay, { className: "fixed inset-0 bg-black/40 z-[80]" }),
1737
+ /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Content, { className: "fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md rounded-xl bg-white p-6 shadow-2xl z-[81]", "aria-describedby": "delete-file-description", children: [
1738
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Title, { className: "text-xl font-semibold text-gray-900 mb-2", children: "Delete File" }),
1739
+ /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Description, { id: "delete-file-description", className: "text-gray-600 mb-6", children: [
1730
1740
  "Are you sure you want to delete ",
1731
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("span", { className: "font-semibold text-gray-900", children: [
1741
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-gray-900", children: [
1732
1742
  '"',
1733
1743
  fileToDelete?.originalName,
1734
1744
  '"'
1735
1745
  ] }),
1736
1746
  "?"
1737
1747
  ] }),
1738
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex justify-end gap-3", children: [
1739
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1748
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex justify-end gap-3", children: [
1749
+ /* @__PURE__ */ jsxRuntime.jsx(
1740
1750
  "button",
1741
1751
  {
1742
1752
  onClick: () => setFileToDelete(null),
@@ -1744,7 +1754,7 @@ function ImageManager(props) {
1744
1754
  children: "Cancel"
1745
1755
  }
1746
1756
  ),
1747
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1757
+ /* @__PURE__ */ jsxRuntime.jsx(
1748
1758
  "button",
1749
1759
  {
1750
1760
  onClick: handleDelete,
@@ -1755,23 +1765,221 @@ function ImageManager(props) {
1755
1765
  )
1756
1766
  ] })
1757
1767
  ] })
1768
+ ] }) }),
1769
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Root, { open: !!thumbnailSelectorFile, onOpenChange: (open2) => !open2 && setThumbnailSelectorFile(null), children: /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Portal, { children: [
1770
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Overlay, { className: "fixed inset-0 bg-black/50 z-[90]" }),
1771
+ /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Content, { className: "fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-4xl max-h-[80vh] rounded-xl bg-white shadow-2xl z-[91] overflow-hidden", "aria-describedby": "thumbnail-selector-description", children: [
1772
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 border-b border-gray-200", children: [
1773
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Title, { className: "text-xl font-semibold text-gray-900 mb-2", children: "Select Thumbnail" }),
1774
+ /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Description, { id: "thumbnail-selector-description", className: "text-gray-600", children: [
1775
+ "Choose a thumbnail size for ",
1776
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "font-semibold text-gray-900", children: [
1777
+ '"',
1778
+ thumbnailSelectorFile?.originalName,
1779
+ '"'
1780
+ ] })
1781
+ ] })
1782
+ ] }),
1783
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "p-6 overflow-y-auto max-h-[60vh]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4", children: [
1784
+ /* @__PURE__ */ jsxRuntime.jsxs(
1785
+ "div",
1786
+ {
1787
+ onClick: () => setSelectedThumbnailForFile(null),
1788
+ className: `group cursor-pointer rounded-lg border-2 overflow-hidden transition-all ${selectedThumbnailForFile === null ? "border-blue-500 ring-2 ring-blue-200" : "border-gray-200 hover:border-blue-300"}`,
1789
+ children: [
1790
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aspect-square bg-gray-100 flex items-center justify-center relative", children: [
1791
+ /* @__PURE__ */ jsxRuntime.jsx(
1792
+ "img",
1793
+ {
1794
+ src: thumbnailSelectorFile?.url,
1795
+ alt: "Original",
1796
+ className: "w-full h-full object-cover"
1797
+ }
1798
+ ),
1799
+ selectedThumbnailForFile === null && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-blue-500/20 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-6 h-6 bg-blue-500 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4 text-white", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx("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" }) }) }) })
1800
+ ] }),
1801
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 bg-white", children: [
1802
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "font-medium text-sm text-gray-900", children: "Original" }),
1803
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-gray-500", children: "Full size" })
1804
+ ] })
1805
+ ]
1806
+ }
1807
+ ),
1808
+ thumbnailSelectorFile?.thumbnails?.map((thumbnail) => /* @__PURE__ */ jsxRuntime.jsxs(
1809
+ "div",
1810
+ {
1811
+ onClick: () => setSelectedThumbnailForFile(thumbnail),
1812
+ className: `group cursor-pointer rounded-lg border-2 overflow-hidden transition-all ${selectedThumbnailForFile?.id === thumbnail.id ? "border-blue-500 ring-2 ring-blue-200" : "border-gray-200 hover:border-blue-300"}`,
1813
+ children: [
1814
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "aspect-square bg-gray-100 flex items-center justify-center relative", children: [
1815
+ /* @__PURE__ */ jsxRuntime.jsx(
1816
+ "img",
1817
+ {
1818
+ src: thumbnail.url,
1819
+ alt: `${thumbnail.size}px thumbnail`,
1820
+ className: "w-full h-full object-cover"
1821
+ }
1822
+ ),
1823
+ selectedThumbnailForFile?.id === thumbnail.id && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute inset-0 bg-blue-500/20 flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "w-6 h-6 bg-blue-500 rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsxRuntime.jsx("svg", { className: "w-4 h-4 text-white", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntime.jsx("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" }) }) }) })
1824
+ ] }),
1825
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-3 bg-white", children: [
1826
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "font-medium text-sm text-gray-900", children: [
1827
+ thumbnail.size,
1828
+ "px"
1829
+ ] }),
1830
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-xs text-gray-500", children: thumbnail.sizeType || "Thumbnail" })
1831
+ ] })
1832
+ ]
1833
+ },
1834
+ thumbnail.id
1835
+ ))
1836
+ ] }) }),
1837
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "p-6 border-t border-gray-200 flex justify-end gap-3", children: [
1838
+ /* @__PURE__ */ jsxRuntime.jsx(
1839
+ "button",
1840
+ {
1841
+ onClick: () => setThumbnailSelectorFile(null),
1842
+ className: "px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-lg",
1843
+ children: "Cancel"
1844
+ }
1845
+ ),
1846
+ /* @__PURE__ */ jsxRuntime.jsxs(
1847
+ "button",
1848
+ {
1849
+ onClick: () => {
1850
+ if (thumbnailSelectorFile) {
1851
+ onSelect({
1852
+ url: selectedThumbnailForFile?.url || thumbnailSelectorFile.url,
1853
+ key: thumbnailSelectorFile.key,
1854
+ originalName: thumbnailSelectorFile.originalName,
1855
+ size: thumbnailSelectorFile.size,
1856
+ contentType: thumbnailSelectorFile.contentType,
1857
+ thumbnails: thumbnailSelectorFile.thumbnails,
1858
+ selectedThumbnail: selectedThumbnailForFile || void 0
1859
+ });
1860
+ onOpenChange(false);
1861
+ setThumbnailSelectorFile(null);
1862
+ }
1863
+ },
1864
+ className: "px-4 py-2 text-sm font-medium rounded-lg bg-blue-600 text-white hover:bg-blue-700",
1865
+ children: [
1866
+ "Select ",
1867
+ selectedThumbnailForFile ? `${selectedThumbnailForFile.size}px Thumbnail` : "Original"
1868
+ ]
1869
+ }
1870
+ )
1871
+ ] })
1872
+ ] })
1873
+ ] }) }),
1874
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Root, { open: !!previewFile, onOpenChange: (open2) => !open2 && setPreviewFile(null), children: /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Portal, { children: [
1875
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Overlay, { className: "fixed inset-0 bg-black/90 z-[100]", onClick: () => setPreviewFile(null) }),
1876
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Content, { className: "fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[90vw] h-[90vh] z-[101] outline-none", "aria-describedby": "image-preview-description", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative w-full h-full flex flex-col", children: [
1877
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute top-0 left-0 right-0 z-10 bg-gradient-to-b from-black/70 to-transparent p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-start justify-between", children: [
1878
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-white", children: [
1879
+ /* @__PURE__ */ jsxRuntime.jsx(Dialog2__namespace.Title, { className: "text-xl font-semibold mb-1", children: previewFile?.originalName }),
1880
+ /* @__PURE__ */ jsxRuntime.jsxs(Dialog2__namespace.Description, { id: "image-preview-description", className: "text-sm text-gray-300", children: [
1881
+ previewFile?.size ? `${(previewFile.size / 1024).toFixed(1)} KB` : "",
1882
+ " \u2022 ",
1883
+ previewFile?.contentType
1884
+ ] })
1885
+ ] }),
1886
+ /* @__PURE__ */ jsxRuntime.jsx(
1887
+ "button",
1888
+ {
1889
+ onClick: () => setPreviewFile(null),
1890
+ className: "p-2 bg-white/10 hover:bg-white/20 rounded-lg backdrop-blur-md transition-colors",
1891
+ children: /* @__PURE__ */ jsxRuntime.jsx(IconX, { className: "w-6 h-6 text-white" })
1892
+ }
1893
+ )
1894
+ ] }) }),
1895
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 flex items-center justify-center p-6", children: /* @__PURE__ */ jsxRuntime.jsx(
1896
+ "img",
1897
+ {
1898
+ src: previewFile?.url,
1899
+ alt: previewFile?.originalName,
1900
+ className: "max-w-full max-h-full object-contain",
1901
+ onError: (e) => {
1902
+ const target = e.target;
1903
+ target.style.display = "none";
1904
+ const errorDiv = document.createElement("div");
1905
+ errorDiv.className = "text-white text-center";
1906
+ errorDiv.innerHTML = `
1907
+ <div class="text-red-400 mb-2">Failed to load image</div>
1908
+ <div class="text-sm text-gray-400">URL: ${previewFile?.url}</div>
1909
+ `;
1910
+ target.parentElement?.appendChild(errorDiv);
1911
+ }
1912
+ }
1913
+ ) }),
1914
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "absolute bottom-0 left-0 right-0 z-10 bg-gradient-to-t from-black/70 to-transparent p-6", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex gap-3 justify-center", children: [
1915
+ /* @__PURE__ */ jsxRuntime.jsx(
1916
+ "button",
1917
+ {
1918
+ onClick: (e) => {
1919
+ e.stopPropagation();
1920
+ if (previewFile) {
1921
+ onSelect({
1922
+ url: previewFile.url,
1923
+ key: previewFile.key,
1924
+ originalName: previewFile.originalName,
1925
+ size: previewFile.size,
1926
+ contentType: previewFile.contentType,
1927
+ thumbnails: previewFile.thumbnails
1928
+ });
1929
+ onOpenChange(false);
1930
+ setPreviewFile(null);
1931
+ }
1932
+ },
1933
+ className: "px-6 py-2.5 bg-blue-600 text-white font-semibold rounded-lg hover:bg-blue-500 shadow-lg",
1934
+ children: "Select Image"
1935
+ }
1936
+ ),
1937
+ /* @__PURE__ */ jsxRuntime.jsx(
1938
+ "a",
1939
+ {
1940
+ href: previewFile?.url,
1941
+ target: "_blank",
1942
+ rel: "noopener noreferrer",
1943
+ onClick: (e) => e.stopPropagation(),
1944
+ className: "px-6 py-2.5 bg-white/10 text-white font-semibold rounded-lg hover:bg-white/20 backdrop-blur-md transition-colors",
1945
+ children: "Open in New Tab"
1946
+ }
1947
+ ),
1948
+ previewFile?.thumbnails && previewFile.thumbnails.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(
1949
+ "button",
1950
+ {
1951
+ onClick: (e) => {
1952
+ e.stopPropagation();
1953
+ setThumbnailSelectorFile(previewFile);
1954
+ setSelectedThumbnailForFile(null);
1955
+ setPreviewFile(null);
1956
+ },
1957
+ className: "px-6 py-2.5 bg-purple-600 text-white font-semibold rounded-lg hover:bg-purple-500 shadow-lg flex items-center gap-2",
1958
+ children: [
1959
+ /* @__PURE__ */ jsxRuntime.jsx(IconLayers, { className: "w-5 h-5" }),
1960
+ "Select Thumbnail"
1961
+ ]
1962
+ }
1963
+ )
1964
+ ] }) })
1965
+ ] }) })
1758
1966
  ] }) })
1759
1967
  ] });
1760
1968
  }
1761
- // Annotate the CommonJS export names for ESM import in node:
1762
- 0 && (module.exports = {
1763
- ConnectProjectDialog,
1764
- ImageManager,
1765
- ProjectFilesWidget,
1766
- UpfilesClient,
1767
- Uploader,
1768
- addApiKeyManually,
1769
- connectProject,
1770
- connectUsingApiKey,
1771
- createClientWithKey,
1772
- createProject,
1773
- fetchFileThumbnails,
1774
- fetchProjectFiles,
1775
- fetchProjectImagesWithThumbs,
1776
- listProjects
1777
- });
1969
+
1970
+ exports.ConnectProjectDialog = ConnectProjectDialog;
1971
+ exports.ImageManager = ImageManager;
1972
+ exports.ProjectFilesWidget = ProjectFilesWidget;
1973
+ exports.UpfilesClient = UpfilesClient;
1974
+ exports.Uploader = Uploader;
1975
+ exports.addApiKeyManually = addApiKeyManually;
1976
+ exports.connectProject = connectProject;
1977
+ exports.connectUsingApiKey = connectUsingApiKey;
1978
+ exports.createClientWithKey = createClientWithKey;
1979
+ exports.createProject = createProject;
1980
+ exports.fetchFileThumbnails = fetchFileThumbnails;
1981
+ exports.fetchProjectFiles = fetchProjectFiles;
1982
+ exports.fetchProjectImagesWithThumbs = fetchProjectImagesWithThumbs;
1983
+ exports.listProjects = listProjects;
1984
+ //# sourceMappingURL=index.js.map
1985
+ //# sourceMappingURL=index.js.map