@burdenoff/microfe-files 2026.527.5 → 2026.528.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,87 +1,50 @@
1
- import { useEffect as e, useEffectEvent as t, useId as n, useRef as r } from "react";
2
- import { AlertTriangle as i, Loader2 as a, X as o } from "lucide-react";
3
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
1
+ import { AlertTriangle as e, Loader2 as t } from "lucide-react";
2
+ import { jsx as n, jsxs as r } from "react/jsx-runtime";
3
+ import { Button as i, ResponsiveDialog as a, ResponsiveDialogContent as o, ResponsiveDialogDescription as s, ResponsiveDialogFooter as c, ResponsiveDialogHeader as l, ResponsiveDialogTitle as u } from "@burdenoff/fe-libs/ui";
4
4
  //#region src/files/components/ConfirmDialog.tsx
5
- function l({ title: l, description: u, confirmLabel: d, cancelLabel: f, variant: p = "default", loading: m = !1, onConfirm: h, onCancel: g }) {
6
- let _ = n(), v = n(), y = r(null), b = t(() => {
7
- m || g();
8
- });
9
- return e(() => {
10
- y.current?.focus();
11
- let e = (e) => {
12
- e.key === "Escape" && b();
13
- };
14
- return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
15
- }, []), /* @__PURE__ */ s("div", {
16
- className: "fixed inset-0 z-[140] flex items-center justify-center bg-bg-overlay p-4",
17
- role: "presentation",
18
- onMouseDown: (e) => {
19
- e.target === e.currentTarget && !m && g();
5
+ function d({ title: d, description: f, confirmLabel: p, cancelLabel: m, variant: h = "default", loading: g = !1, onConfirm: _, onCancel: v }) {
6
+ return /* @__PURE__ */ n(a, {
7
+ open: !0,
8
+ onOpenChange: (e) => {
9
+ !e && !g && v();
20
10
  },
21
- children: /* @__PURE__ */ c("section", {
22
- role: "alertdialog",
23
- "aria-modal": "true",
24
- "aria-labelledby": _,
25
- "aria-describedby": v,
26
- className: "w-full max-w-md rounded-2xl border border-border-default bg-bg-surface p-5 shadow-elevation-3",
27
- children: [/* @__PURE__ */ c("div", {
28
- className: "flex items-start gap-3",
29
- children: [
30
- /* @__PURE__ */ s("div", {
31
- className: "rounded-full bg-status-warning-bg-subtle p-2 text-status-warning-text",
32
- children: /* @__PURE__ */ s(i, {
33
- className: "size-5",
34
- "aria-hidden": "true"
35
- })
36
- }),
37
- /* @__PURE__ */ c("div", {
38
- className: "min-w-0 flex-1",
39
- children: [/* @__PURE__ */ s("h2", {
40
- id: _,
41
- className: "text-base font-semibold text-text-primary",
42
- children: l
43
- }), /* @__PURE__ */ s("div", {
44
- id: v,
45
- className: "mt-2 text-sm leading-6 text-text-secondary",
46
- children: u
47
- })]
48
- }),
49
- /* @__PURE__ */ s("button", {
50
- type: "button",
51
- onClick: g,
52
- disabled: m,
53
- className: "rounded-lg p-1 text-text-tertiary transition-colors hover:bg-bg-muted hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border disabled:cursor-not-allowed disabled:opacity-50",
54
- "aria-label": f,
55
- children: /* @__PURE__ */ s(o, {
56
- className: "size-4",
57
- "aria-hidden": "true"
58
- })
11
+ children: /* @__PURE__ */ r(o, { children: [/* @__PURE__ */ n(l, { children: /* @__PURE__ */ r("div", {
12
+ className: "flex items-start gap-3",
13
+ children: [/* @__PURE__ */ n("div", {
14
+ className: "rounded-full bg-status-warning-bg-subtle p-2 text-status-warning-text",
15
+ children: /* @__PURE__ */ n(e, {
16
+ className: "size-5",
17
+ "aria-hidden": "true"
18
+ })
19
+ }), /* @__PURE__ */ r("div", {
20
+ className: "min-w-0 flex-1",
21
+ children: [/* @__PURE__ */ n(u, { children: d }), /* @__PURE__ */ n(s, {
22
+ asChild: !0,
23
+ children: /* @__PURE__ */ n("div", {
24
+ className: "mt-2 text-sm leading-6 text-text-secondary",
25
+ children: f
59
26
  })
60
- ]
61
- }), /* @__PURE__ */ c("div", {
62
- className: "mt-6 flex flex-col-reverse gap-3 sm:flex-row sm:justify-end",
63
- children: [/* @__PURE__ */ s("button", {
64
- ref: y,
65
- type: "button",
66
- onClick: g,
67
- disabled: m,
68
- className: "inline-flex items-center justify-center rounded-lg border border-border-default bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border disabled:cursor-not-allowed disabled:opacity-50",
69
- children: f
70
- }), /* @__PURE__ */ c("button", {
71
- type: "button",
72
- onClick: h,
73
- disabled: m,
74
- className: `inline-flex items-center justify-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-60 ${p === "danger" ? "bg-status-error-bg text-text-inverse hover:bg-status-error-bg focus-visible:ring-status-error-border" : "bg-action-primary-bg text-text-inverse hover:bg-action-primary-bg-hover focus-visible:ring-action-primary-border"}`,
75
- children: [m && /* @__PURE__ */ s(a, {
76
- className: "size-4 animate-spin",
77
- "aria-hidden": "true"
78
- }), d]
79
27
  })]
80
28
  })]
81
- })
29
+ }) }), /* @__PURE__ */ r(c, { children: [/* @__PURE__ */ n(i, {
30
+ type: "button",
31
+ variant: "outline",
32
+ onClick: v,
33
+ disabled: g,
34
+ children: m
35
+ }), /* @__PURE__ */ r(i, {
36
+ type: "button",
37
+ onClick: _,
38
+ disabled: g,
39
+ variant: h === "danger" ? "destructive" : "default",
40
+ children: [g && /* @__PURE__ */ n(t, {
41
+ className: "size-4 animate-spin",
42
+ "aria-hidden": "true"
43
+ }), p]
44
+ })] })] })
82
45
  });
83
46
  }
84
47
  //#endregion
85
- export { l as ConfirmDialog };
48
+ export { d as ConfirmDialog };
86
49
 
87
50
  //# sourceMappingURL=ConfirmDialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmDialog.js","names":[],"sources":["../../../src/files/components/ConfirmDialog.tsx"],"sourcesContent":["import {\n type ReactNode,\n useEffect,\n useEffectEvent,\n useId,\n useRef,\n} from \"react\";\nimport { AlertTriangle, Loader2, X } from \"lucide-react\";\n\ninterface ConfirmDialogProps {\n title: string;\n description: ReactNode;\n confirmLabel: string;\n cancelLabel: string;\n variant?: \"danger\" | \"default\";\n loading?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\nexport function ConfirmDialog({\n title,\n description,\n confirmLabel,\n cancelLabel,\n variant = \"default\",\n loading = false,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n const titleId = useId();\n const descriptionId = useId();\n const cancelButtonRef = useRef<HTMLButtonElement>(null);\n\n const onEscape = useEffectEvent(() => {\n if (!loading) {\n onCancel();\n }\n });\n\n useEffect(() => {\n cancelButtonRef.current?.focus();\n\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onEscape();\n }\n };\n\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => document.removeEventListener(\"keydown\", handleKeyDown);\n }, []);\n\n const confirmClassName =\n variant === \"danger\"\n ? \"bg-status-error-bg text-text-inverse hover:bg-status-error-bg focus-visible:ring-status-error-border\"\n : \"bg-action-primary-bg text-text-inverse hover:bg-action-primary-bg-hover focus-visible:ring-action-primary-border\";\n\n return (\n <div\n className=\"fixed inset-0 z-[140] flex items-center justify-center bg-bg-overlay p-4\"\n role=\"presentation\"\n onMouseDown={(event) => {\n if (event.target === event.currentTarget && !loading) {\n onCancel();\n }\n }}\n >\n <section\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n aria-describedby={descriptionId}\n className=\"w-full max-w-md rounded-2xl border border-border-default bg-bg-surface p-5 shadow-elevation-3\"\n >\n <div className=\"flex items-start gap-3\">\n <div className=\"rounded-full bg-status-warning-bg-subtle p-2 text-status-warning-text\">\n <AlertTriangle className=\"size-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <h2\n id={titleId}\n className=\"text-base font-semibold text-text-primary\"\n >\n {title}\n </h2>\n <div\n id={descriptionId}\n className=\"mt-2 text-sm leading-6 text-text-secondary\"\n >\n {description}\n </div>\n </div>\n <button\n type=\"button\"\n onClick={onCancel}\n disabled={loading}\n className=\"rounded-lg p-1 text-text-tertiary transition-colors hover:bg-bg-muted hover:text-text-primary focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border disabled:cursor-not-allowed disabled:opacity-50\"\n aria-label={cancelLabel}\n >\n <X className=\"size-4\" aria-hidden=\"true\" />\n </button>\n </div>\n\n <div className=\"mt-6 flex flex-col-reverse gap-3 sm:flex-row sm:justify-end\">\n <button\n ref={cancelButtonRef}\n type=\"button\"\n onClick={onCancel}\n disabled={loading}\n className=\"inline-flex items-center justify-center rounded-lg border border-border-default bg-bg-surface px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-action-primary-border disabled:cursor-not-allowed disabled:opacity-50\"\n >\n {cancelLabel}\n </button>\n <button\n type=\"button\"\n onClick={onConfirm}\n disabled={loading}\n className={`inline-flex items-center justify-center gap-2 rounded-lg px-4 py-2 text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 disabled:cursor-not-allowed disabled:opacity-60 ${confirmClassName}`}\n >\n {loading && (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n )}\n {confirmLabel}\n </button>\n </div>\n </section>\n </div>\n );\n}\n"],"mappings":";;;;AAoBA,SAAgB,EAAc,EAC5B,UACA,gBACA,iBACA,gBACA,aAAU,WACV,aAAU,IACV,cACA,eACqB;CACrB,IAAM,IAAU,GAAO,EACjB,IAAgB,GAAO,EACvB,IAAkB,EAA0B,KAAK,EAEjD,IAAW,QAAqB;AACpC,EAAK,KACH,GAAU;GAEZ;AAoBF,QAlBA,QAAgB;AACd,IAAgB,SAAS,OAAO;EAEhC,IAAM,KAAiB,MAAyB;AAC9C,GAAI,EAAM,QAAQ,YAChB,GAAU;;AAKd,SADA,SAAS,iBAAiB,WAAW,EAAc,QACtC,SAAS,oBAAoB,WAAW,EAAc;IAClE,EAAE,CAAC,EAQJ,kBAAC,OAAD;EACE,WAAU;EACV,MAAK;EACL,cAAc,MAAU;AACtB,GAAI,EAAM,WAAW,EAAM,iBAAiB,CAAC,KAC3C,GAAU;;YAId,kBAAC,WAAD;GACE,MAAK;GACL,cAAW;GACX,mBAAiB;GACjB,oBAAkB;GAClB,WAAU;aALZ,CAOE,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,OAAD;MAAK,WAAU;gBACb,kBAAC,GAAD;OAAe,WAAU;OAAS,eAAY;OAAS,CAAA;MACnD,CAAA;KACN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,MAAD;OACE,IAAI;OACJ,WAAU;iBAET;OACE,CAAA,EACL,kBAAC,OAAD;OACE,IAAI;OACJ,WAAU;iBAET;OACG,CAAA,CACF;;KACN,kBAAC,UAAD;MACE,MAAK;MACL,SAAS;MACT,UAAU;MACV,WAAU;MACV,cAAY;gBAEZ,kBAAC,GAAD;OAAG,WAAU;OAAS,eAAY;OAAS,CAAA;MACpC,CAAA;KACL;OAEN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,UAAD;KACE,KAAK;KACL,MAAK;KACL,SAAS;KACT,UAAU;KACV,WAAU;eAET;KACM,CAAA,EACT,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,UAAU;KACV,WAAW,4MAhEnB,MAAY,WACR,yGACA;eA0DE,CAMG,KACC,kBAAC,GAAD;MAAS,WAAU;MAAsB,eAAY;MAAS,CAAA,EAE/D,EACM;OACL;MACE;;EACN,CAAA"}
1
+ {"version":3,"file":"ConfirmDialog.js","names":[],"sources":["../../../src/files/components/ConfirmDialog.tsx"],"sourcesContent":["import { type ReactNode } from \"react\";\nimport { AlertTriangle, Loader2 } from \"lucide-react\";\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n Button,\n} from \"@burdenoff/fe-libs/ui\";\n\ninterface ConfirmDialogProps {\n title: string;\n description: ReactNode;\n confirmLabel: string;\n cancelLabel: string;\n variant?: \"danger\" | \"default\";\n loading?: boolean;\n onConfirm: () => void;\n onCancel: () => void;\n}\n\n/**\n * Confirm/alert dialog. Delegates layout + dismissal to\n * `<ResponsiveDialog>` from `@burdenoff/fe-libs/ui` (bottom-sheet on\n * mobile, centred modal on tablet/desktop). Existing call sites that\n * mount this conditionally (`{open && <ConfirmDialog ... />}`) continue\n * to work because we drive `open={true}` and forward dismissal via\n * `onOpenChange` → `onCancel`.\n */\nexport function ConfirmDialog({\n title,\n description,\n confirmLabel,\n cancelLabel,\n variant = \"default\",\n loading = false,\n onConfirm,\n onCancel,\n}: ConfirmDialogProps) {\n return (\n <ResponsiveDialog\n open\n onOpenChange={(next: boolean) => {\n if (!next && !loading) {\n onCancel();\n }\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <div className=\"flex items-start gap-3\">\n <div className=\"rounded-full bg-status-warning-bg-subtle p-2 text-status-warning-text\">\n <AlertTriangle className=\"size-5\" aria-hidden=\"true\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <ResponsiveDialogTitle>{title}</ResponsiveDialogTitle>\n <ResponsiveDialogDescription asChild>\n <div className=\"mt-2 text-sm leading-6 text-text-secondary\">\n {description}\n </div>\n </ResponsiveDialogDescription>\n </div>\n </div>\n </ResponsiveDialogHeader>\n\n <ResponsiveDialogFooter>\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onCancel}\n disabled={loading}\n >\n {cancelLabel}\n </Button>\n <Button\n type=\"button\"\n onClick={onConfirm}\n disabled={loading}\n variant={variant === \"danger\" ? \"destructive\" : \"default\"}\n >\n {loading && (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n )}\n {confirmLabel}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":";;;;AA+BA,SAAgB,EAAc,EAC5B,UACA,gBACA,iBACA,gBACA,aAAU,WACV,aAAU,IACV,cACA,eACqB;AACrB,QACE,kBAAC,GAAD;EACE,MAAA;EACA,eAAe,MAAkB;AAC/B,GAAI,CAAC,KAAQ,CAAC,KACZ,GAAU;;YAId,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KAAe,WAAU;KAAS,eAAY;KAAS,CAAA;IACnD,CAAA,EACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD,EAAA,UAAwB,GAA8B,CAAA,EACtD,kBAAC,GAAD;KAA6B,SAAA;eAC3B,kBAAC,OAAD;MAAK,WAAU;gBACZ;MACG,CAAA;KACsB,CAAA,CAC1B;MACF;MACiB,CAAA,EAEzB,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD;GACE,MAAK;GACL,SAAQ;GACR,SAAS;GACT,UAAU;aAET;GACM,CAAA,EACT,kBAAC,GAAD;GACE,MAAK;GACL,SAAS;GACT,UAAU;GACV,SAAS,MAAY,WAAW,gBAAgB;aAJlD,CAMG,KACC,kBAAC,GAAD;IAAS,WAAU;IAAsB,eAAY;IAAS,CAAA,EAE/D,EACM;KACc,EAAA,CAAA,CACD,EAAA,CAAA;EACT,CAAA"}
@@ -1,68 +1,54 @@
1
1
  import { tWithFallback as e } from "../utils/i18n.js";
2
2
  import { Clock as t, FolderOpen as n, Star as r, Trash2 as i } from "lucide-react";
3
- import { jsx as a, jsxs as o } from "react/jsx-runtime";
4
- import { useI18n as s } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
3
+ import { jsx as a } from "react/jsx-runtime";
4
+ import { useI18n as o } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
5
+ import { Button as s, EmptyState as c } from "@burdenoff/fe-libs/ui";
5
6
  //#region src/files/components/EmptyState.tsx
6
- function c({ type: c, onUpload: l, onNewFolder: u }) {
7
- let { t: d } = s(), f = {
7
+ function l({ type: l, onUpload: u, onNewFolder: d }) {
8
+ let { t: f } = o(), p = {
8
9
  all: {
9
- icon: /* @__PURE__ */ a(n, { className: "size-16 text-text-tertiary" }),
10
- title: e(d, "files.empty.all.title", "No files or folders yet"),
11
- description: e(d, "files.empty.all.description", "Upload files or create folders to get started"),
10
+ icon: /* @__PURE__ */ a(n, { className: "size-12 text-text-tertiary" }),
11
+ title: e(f, "files.empty.all.title", "No files or folders yet"),
12
+ description: e(f, "files.empty.all.description", "Upload files or create folders to get started"),
12
13
  showActions: !0
13
14
  },
14
15
  recent: {
15
- icon: /* @__PURE__ */ a(t, { className: "size-16 text-text-tertiary" }),
16
- title: e(d, "files.empty.recent.title", "No recent files"),
17
- description: e(d, "files.empty.recent.description", "Files you recently opened will appear here"),
16
+ icon: /* @__PURE__ */ a(t, { className: "size-12 text-text-tertiary" }),
17
+ title: e(f, "files.empty.recent.title", "No recent files"),
18
+ description: e(f, "files.empty.recent.description", "Files you recently opened will appear here"),
18
19
  showActions: !1
19
20
  },
20
21
  starred: {
21
- icon: /* @__PURE__ */ a(r, { className: "size-16 text-text-tertiary" }),
22
- title: e(d, "files.empty.starred.title", "No starred items"),
23
- description: e(d, "files.empty.starred.description", "Star files and folders to find them easily"),
22
+ icon: /* @__PURE__ */ a(r, { className: "size-12 text-text-tertiary" }),
23
+ title: e(f, "files.empty.starred.title", "No starred items"),
24
+ description: e(f, "files.empty.starred.description", "Star files and folders to find them easily"),
24
25
  showActions: !1
25
26
  },
26
27
  bin: {
27
- icon: /* @__PURE__ */ a(i, { className: "size-16 text-text-tertiary" }),
28
- title: e(d, "files.empty.bin.title", "Bin is empty"),
29
- description: e(d, "files.empty.bin.description", "Deleted files and folders will appear here"),
28
+ icon: /* @__PURE__ */ a(i, { className: "size-12 text-text-tertiary" }),
29
+ title: e(f, "files.empty.bin.title", "Bin is empty"),
30
+ description: e(f, "files.empty.bin.description", "Deleted files and folders will appear here"),
30
31
  showActions: !1
31
32
  }
32
- }[c];
33
- return /* @__PURE__ */ o("div", {
34
- className: "flex flex-col items-center justify-center py-20 px-4 animate-in fade-in duration-500",
35
- children: [
36
- /* @__PURE__ */ a("div", {
37
- className: "mb-4 animate-in zoom-in duration-300 delay-100",
38
- children: f.icon
39
- }),
40
- /* @__PURE__ */ a("h3", {
41
- className: "text-lg font-semibold text-text-primary mb-2",
42
- children: f.title
43
- }),
44
- /* @__PURE__ */ a("p", {
45
- className: "text-sm text-text-secondary mb-6 text-center max-w-md",
46
- children: f.description
47
- }),
48
- f.showActions && /* @__PURE__ */ o("div", {
49
- className: "flex gap-3 animate-in fade-in slide-in-from-bottom-2 duration-300 delay-200",
50
- children: [u && /* @__PURE__ */ a("button", {
51
- type: "button",
52
- onClick: u,
53
- className: "px-4 py-2 text-sm font-medium text-text-primary bg-bg-surface border border-border-default rounded-lg hover:bg-action-ghost-bg-hover transition-all duration-200",
54
- children: e(d, "files.empty.newFolder", "New Folder")
55
- }), l && /* @__PURE__ */ a("button", {
56
- type: "button",
57
- onClick: l,
58
- className: "px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-all duration-200",
59
- children: e(d, "files.empty.uploadFiles", "Upload Files")
60
- })]
61
- })
62
- ]
33
+ }[l], m = p.showActions && u ? /* @__PURE__ */ a(s, {
34
+ type: "button",
35
+ onClick: u,
36
+ children: e(f, "files.empty.uploadFiles", "Upload Files")
37
+ }) : void 0, h = p.showActions && d ? /* @__PURE__ */ a(s, {
38
+ type: "button",
39
+ variant: "outline",
40
+ onClick: d,
41
+ children: e(f, "files.empty.newFolder", "New Folder")
42
+ }) : void 0;
43
+ return /* @__PURE__ */ a(c, {
44
+ icon: p.icon,
45
+ title: p.title,
46
+ description: p.description,
47
+ action: m,
48
+ secondaryAction: h
63
49
  });
64
50
  }
65
51
  //#endregion
66
- export { c as EmptyState };
52
+ export { l as EmptyState };
67
53
 
68
54
  //# sourceMappingURL=EmptyState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"EmptyState.js","names":[],"sources":["../../../src/files/components/EmptyState.tsx"],"sourcesContent":["import { FolderOpen, Star, Trash2, Clock } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface EmptyStateProps {\n type: \"all\" | \"recent\" | \"starred\" | \"bin\";\n onUpload?: () => void;\n onNewFolder?: () => void;\n}\n\nexport function EmptyState({ type, onUpload, onNewFolder }: EmptyStateProps) {\n const { t } = useI18n();\n const configs = {\n all: {\n icon: <FolderOpen className=\"size-16 text-text-tertiary\" />,\n title: tWithFallback(\n t,\n \"files.empty.all.title\",\n \"No files or folders yet\",\n ),\n description: tWithFallback(\n t,\n \"files.empty.all.description\",\n \"Upload files or create folders to get started\",\n ),\n showActions: true,\n },\n recent: {\n icon: <Clock className=\"size-16 text-text-tertiary\" />,\n title: tWithFallback(t, \"files.empty.recent.title\", \"No recent files\"),\n description: tWithFallback(\n t,\n \"files.empty.recent.description\",\n \"Files you recently opened will appear here\",\n ),\n showActions: false,\n },\n starred: {\n icon: <Star className=\"size-16 text-text-tertiary\" />,\n title: tWithFallback(t, \"files.empty.starred.title\", \"No starred items\"),\n description: tWithFallback(\n t,\n \"files.empty.starred.description\",\n \"Star files and folders to find them easily\",\n ),\n showActions: false,\n },\n bin: {\n icon: <Trash2 className=\"size-16 text-text-tertiary\" />,\n title: tWithFallback(t, \"files.empty.bin.title\", \"Bin is empty\"),\n description: tWithFallback(\n t,\n \"files.empty.bin.description\",\n \"Deleted files and folders will appear here\",\n ),\n showActions: false,\n },\n };\n\n const config = configs[type];\n\n return (\n <div className=\"flex flex-col items-center justify-center py-20 px-4 animate-in fade-in duration-500\">\n <div className=\"mb-4 animate-in zoom-in duration-300 delay-100\">\n {config.icon}\n </div>\n <h3 className=\"text-lg font-semibold text-text-primary mb-2\">\n {config.title}\n </h3>\n <p className=\"text-sm text-text-secondary mb-6 text-center max-w-md\">\n {config.description}\n </p>\n\n {config.showActions && (\n <div className=\"flex gap-3 animate-in fade-in slide-in-from-bottom-2 duration-300 delay-200\">\n {onNewFolder && (\n <button\n type=\"button\"\n onClick={onNewFolder}\n className=\"px-4 py-2 text-sm font-medium text-text-primary bg-bg-surface border border-border-default rounded-lg hover:bg-action-ghost-bg-hover transition-all duration-200\"\n >\n {tWithFallback(t, \"files.empty.newFolder\", \"New Folder\")}\n </button>\n )}\n {onUpload && (\n <button\n type=\"button\"\n onClick={onUpload}\n className=\"px-4 py-2 text-sm font-medium text-action-primary-text bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-all duration-200\"\n >\n {tWithFallback(t, \"files.empty.uploadFiles\", \"Upload Files\")}\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n"],"mappings":";;;;;AAUA,SAAgB,EAAW,EAAE,SAAM,aAAU,kBAAgC;CAC3E,IAAM,EAAE,SAAM,GAAS,EAgDjB,IA/CU;EACd,KAAK;GACH,MAAM,kBAAC,GAAD,EAAY,WAAU,8BAA+B,CAAA;GAC3D,OAAO,EACL,GACA,yBACA,0BACD;GACD,aAAa,EACX,GACA,+BACA,gDACD;GACD,aAAa;GACd;EACD,QAAQ;GACN,MAAM,kBAAC,GAAD,EAAO,WAAU,8BAA+B,CAAA;GACtD,OAAO,EAAc,GAAG,4BAA4B,kBAAkB;GACtE,aAAa,EACX,GACA,kCACA,6CACD;GACD,aAAa;GACd;EACD,SAAS;GACP,MAAM,kBAAC,GAAD,EAAM,WAAU,8BAA+B,CAAA;GACrD,OAAO,EAAc,GAAG,6BAA6B,mBAAmB;GACxE,aAAa,EACX,GACA,mCACA,6CACD;GACD,aAAa;GACd;EACD,KAAK;GACH,MAAM,kBAAC,GAAD,EAAQ,WAAU,8BAA+B,CAAA;GACvD,OAAO,EAAc,GAAG,yBAAyB,eAAe;GAChE,aAAa,EACX,GACA,+BACA,6CACD;GACD,aAAa;GACd;EACF,CAEsB;AAEvB,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAO;IACJ,CAAA;GACN,kBAAC,MAAD;IAAI,WAAU;cACX,EAAO;IACL,CAAA;GACL,kBAAC,KAAD;IAAG,WAAU;cACV,EAAO;IACN,CAAA;GAEH,EAAO,eACN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACG,KACC,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,WAAU;eAET,EAAc,GAAG,yBAAyB,aAAa;KACjD,CAAA,EAEV,KACC,kBAAC,UAAD;KACE,MAAK;KACL,SAAS;KACT,WAAU;eAET,EAAc,GAAG,2BAA2B,eAAe;KACrD,CAAA,CAEP;;GAEJ"}
1
+ {"version":3,"file":"EmptyState.js","names":[],"sources":["../../../src/files/components/EmptyState.tsx"],"sourcesContent":["import { FolderOpen, Star, Trash2, Clock } from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n EmptyState as CanonicalEmptyState,\n Button,\n} from \"@burdenoff/fe-libs/ui\";\nimport { tWithFallback } from \"../utils/i18n\";\n\ninterface EmptyStateProps {\n type: \"all\" | \"recent\" | \"starred\" | \"bin\";\n onUpload?: () => void;\n onNewFolder?: () => void;\n}\n\n/**\n * Local wrapper that delegates to the canonical `<EmptyState>` from\n * `@burdenoff/fe-libs/ui`. Keeps the microfe-files-specific `type`-keyed\n * config (icon + i18n keys + per-type action visibility) at the call site.\n */\nexport function EmptyState({ type, onUpload, onNewFolder }: EmptyStateProps) {\n const { t } = useI18n();\n const configs = {\n all: {\n icon: <FolderOpen className=\"size-12 text-text-tertiary\" />,\n title: tWithFallback(\n t,\n \"files.empty.all.title\",\n \"No files or folders yet\",\n ),\n description: tWithFallback(\n t,\n \"files.empty.all.description\",\n \"Upload files or create folders to get started\",\n ),\n showActions: true,\n },\n recent: {\n icon: <Clock className=\"size-12 text-text-tertiary\" />,\n title: tWithFallback(t, \"files.empty.recent.title\", \"No recent files\"),\n description: tWithFallback(\n t,\n \"files.empty.recent.description\",\n \"Files you recently opened will appear here\",\n ),\n showActions: false,\n },\n starred: {\n icon: <Star className=\"size-12 text-text-tertiary\" />,\n title: tWithFallback(t, \"files.empty.starred.title\", \"No starred items\"),\n description: tWithFallback(\n t,\n \"files.empty.starred.description\",\n \"Star files and folders to find them easily\",\n ),\n showActions: false,\n },\n bin: {\n icon: <Trash2 className=\"size-12 text-text-tertiary\" />,\n title: tWithFallback(t, \"files.empty.bin.title\", \"Bin is empty\"),\n description: tWithFallback(\n t,\n \"files.empty.bin.description\",\n \"Deleted files and folders will appear here\",\n ),\n showActions: false,\n },\n };\n\n const config = configs[type];\n\n const action =\n config.showActions && onUpload ? (\n <Button type=\"button\" onClick={onUpload}>\n {tWithFallback(t, \"files.empty.uploadFiles\", \"Upload Files\")}\n </Button>\n ) : undefined;\n\n const secondaryAction =\n config.showActions && onNewFolder ? (\n <Button type=\"button\" variant=\"outline\" onClick={onNewFolder}>\n {tWithFallback(t, \"files.empty.newFolder\", \"New Folder\")}\n </Button>\n ) : undefined;\n\n return (\n <CanonicalEmptyState\n icon={config.icon}\n title={config.title}\n description={config.description}\n action={action}\n secondaryAction={secondaryAction}\n />\n );\n}\n"],"mappings":";;;;;;AAmBA,SAAgB,EAAW,EAAE,SAAM,aAAU,kBAAgC;CAC3E,IAAM,EAAE,SAAM,GAAS,EAgDjB,IA/CU;EACd,KAAK;GACH,MAAM,kBAAC,GAAD,EAAY,WAAU,8BAA+B,CAAA;GAC3D,OAAO,EACL,GACA,yBACA,0BACD;GACD,aAAa,EACX,GACA,+BACA,gDACD;GACD,aAAa;GACd;EACD,QAAQ;GACN,MAAM,kBAAC,GAAD,EAAO,WAAU,8BAA+B,CAAA;GACtD,OAAO,EAAc,GAAG,4BAA4B,kBAAkB;GACtE,aAAa,EACX,GACA,kCACA,6CACD;GACD,aAAa;GACd;EACD,SAAS;GACP,MAAM,kBAAC,GAAD,EAAM,WAAU,8BAA+B,CAAA;GACrD,OAAO,EAAc,GAAG,6BAA6B,mBAAmB;GACxE,aAAa,EACX,GACA,mCACA,6CACD;GACD,aAAa;GACd;EACD,KAAK;GACH,MAAM,kBAAC,GAAD,EAAQ,WAAU,8BAA+B,CAAA;GACvD,OAAO,EAAc,GAAG,yBAAyB,eAAe;GAChE,aAAa,EACX,GACA,+BACA,6CACD;GACD,aAAa;GACd;EACF,CAEsB,IAEjB,IACJ,EAAO,eAAe,IACpB,kBAAC,GAAD;EAAQ,MAAK;EAAS,SAAS;YAC5B,EAAc,GAAG,2BAA2B,eAAe;EACrD,CAAA,GACP,KAAA,GAEA,IACJ,EAAO,eAAe,IACpB,kBAAC,GAAD;EAAQ,MAAK;EAAS,SAAQ;EAAU,SAAS;YAC9C,EAAc,GAAG,yBAAyB,aAAa;EACjD,CAAA,GACP,KAAA;AAEN,QACE,kBAAC,GAAD;EACE,MAAM,EAAO;EACb,OAAO,EAAO;EACd,aAAa,EAAO;EACZ;EACS;EACjB,CAAA"}
@@ -1,216 +1,197 @@
1
1
  import { tWithFallback as e } from "../utils/i18n.js";
2
2
  import { useEffect as t, useState as n } from "react";
3
- import { Calendar as r, Check as i, Copy as a, Download as o, Link as s, Loader2 as c, Lock as l, Mail as u, X as d } from "lucide-react";
4
- import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
5
- import { useI18n as h } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
3
+ import { Calendar as r, Check as i, Copy as a, Download as o, Link as s, Loader2 as c, Lock as l, Mail as u } from "lucide-react";
4
+ import { Fragment as d, jsx as f, jsxs as p } from "react/jsx-runtime";
5
+ import { useI18n as m } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
6
+ import { Button as h, OptionalFields as g, ResponsiveDialog as _, ResponsiveDialogContent as v, ResponsiveDialogFooter as y, ResponsiveDialogHeader as b, ResponsiveDialogTitle as x } from "@burdenoff/fe-libs/ui";
6
7
  //#region src/files/components/ShareDialog.tsx
7
- function g({ item: g, itemType: _, onClose: v, onCreateShare: y, isLoading: b }) {
8
- let { t: x } = h(), [S, C] = n(null), [w, T] = n(null), [E, D] = n(!1), [O, k] = n(7), [A, j] = n(0), [M, N] = n(!1), [P, F] = n(""), [I, L] = n(""), [R, z] = n(null), B = `share-dialog-title-${g.id}`;
8
+ function S({ item: S, itemType: C, onClose: w, onCreateShare: T, isLoading: E }) {
9
+ let { t: D } = m(), [O, k] = n(null), [A, j] = n(null), [M, N] = n(!1), [P, F] = n(7), [I, L] = n(0), [R, z] = n(!1), [B, V] = n(""), [H, U] = n(""), [W, G] = n(null);
9
10
  return t(() => {
10
- let e = (e) => {
11
- e.key === "Escape" && v();
12
- };
13
- return document.addEventListener("keydown", e), () => document.removeEventListener("keydown", e);
14
- }, [v]), t(() => {
15
- if (E) {
16
- let e = setTimeout(() => D(!1), 2e3);
11
+ if (M) {
12
+ let e = setTimeout(() => N(!1), 2e3);
17
13
  return () => clearTimeout(e);
18
14
  }
19
- }, [E]), /* @__PURE__ */ p("div", {
20
- className: "fixed inset-0 bg-bg-overlay flex items-center justify-center z-[100] animate-in fade-in duration-200",
21
- role: "dialog",
22
- "aria-modal": "true",
23
- "aria-labelledby": B,
24
- children: /* @__PURE__ */ m("div", {
25
- className: "bg-bg-surface rounded-lg shadow-xl p-6 w-full max-w-md mx-4 animate-in zoom-in-95 duration-200",
26
- children: [/* @__PURE__ */ m("div", {
27
- className: "flex items-center justify-between mb-4",
28
- children: [/* @__PURE__ */ p("h2", {
29
- id: B,
30
- className: "text-lg font-semibold text-text-primary",
31
- children: e(x, "files.shareDialog.title", "Share {{itemType}} \"{{name}}\"", {
32
- itemType: e(x, _ === "folder" ? "files.shareDialog.itemType.folder" : "files.shareDialog.itemType.file", _ === "folder" ? "folder" : "file"),
33
- name: g.name
34
- })
35
- }), /* @__PURE__ */ p("button", {
36
- type: "button",
37
- onClick: v,
38
- className: "text-text-tertiary hover:text-text-secondary transition-colors duration-200",
39
- "aria-label": e(x, "files.shareDialog.actions.close", "Close share dialog"),
40
- children: /* @__PURE__ */ p(d, { className: "size-5" })
41
- })]
42
- }), w === null ? /* @__PURE__ */ m(f, { children: [
43
- R && /* @__PURE__ */ p("div", {
44
- className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
45
- children: R
46
- }),
47
- /* @__PURE__ */ m("div", {
48
- className: "space-y-4",
49
- children: [
50
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ m("label", {
51
- className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
52
- children: [/* @__PURE__ */ p(r, { className: "size-4" }), e(x, "files.shareDialog.expiry.label", "Link expires in")]
53
- }), /* @__PURE__ */ m("select", {
54
- value: O,
55
- onChange: (e) => k(Number(e.target.value)),
56
- className: "w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200",
57
- children: [
58
- /* @__PURE__ */ p("option", {
59
- value: 0,
60
- children: e(x, "files.shareDialog.expiry.options.never", "Never")
61
- }),
62
- /* @__PURE__ */ p("option", {
63
- value: 1,
64
- children: e(x, "files.shareDialog.expiry.options.oneDay", "1 day")
65
- }),
66
- /* @__PURE__ */ p("option", {
67
- value: 7,
68
- children: e(x, "files.shareDialog.expiry.options.sevenDays", "7 days")
69
- }),
70
- /* @__PURE__ */ p("option", {
71
- value: 30,
72
- children: e(x, "files.shareDialog.expiry.options.thirtyDays", "30 days")
73
- }),
74
- /* @__PURE__ */ p("option", {
75
- value: 90,
76
- children: e(x, "files.shareDialog.expiry.options.ninetyDays", "90 days")
77
- })
78
- ]
79
- })] }),
80
- /* @__PURE__ */ m("div", { children: [/* @__PURE__ */ m("label", {
81
- className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
82
- children: [/* @__PURE__ */ p(o, { className: "size-4" }), e(x, "files.shareDialog.downloads.label", "Maximum downloads")]
83
- }), /* @__PURE__ */ p("input", {
84
- type: "number",
85
- min: "0",
86
- value: A,
87
- onChange: (e) => j(Number(e.target.value)),
88
- "aria-label": e(x, "files.shareDialog.downloads.label", "Maximum downloads"),
89
- placeholder: e(x, "files.shareDialog.downloads.placeholder", "Unlimited"),
90
- className: "w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
91
- })] }),
92
- /* @__PURE__ */ m("div", { children: [
93
- /* @__PURE__ */ m("label", {
94
- className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
95
- children: [/* @__PURE__ */ p(l, { className: "size-4" }), e(x, "files.shareDialog.password.label", "Password protection")]
15
+ }, [M]), /* @__PURE__ */ f(_, {
16
+ open: !0,
17
+ onOpenChange: (e) => {
18
+ e || w();
19
+ },
20
+ children: /* @__PURE__ */ p(v, { children: [/* @__PURE__ */ f(b, { children: /* @__PURE__ */ f(x, { children: e(D, "files.shareDialog.title", "Share {{itemType}} \"{{name}}\"", {
21
+ itemType: e(D, C === "folder" ? "files.shareDialog.itemType.folder" : "files.shareDialog.itemType.file", C === "folder" ? "folder" : "file"),
22
+ name: S.name
23
+ }) }) }), A === null ? /* @__PURE__ */ p(d, { children: [
24
+ W && /* @__PURE__ */ f("div", {
25
+ className: "mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text",
26
+ children: W
27
+ }),
28
+ /* @__PURE__ */ p("div", {
29
+ className: "space-y-4",
30
+ children: [
31
+ /* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("label", {
32
+ className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
33
+ children: [/* @__PURE__ */ f(r, { className: "size-4" }), e(D, "files.shareDialog.expiry.label", "Link expires in")]
34
+ }), /* @__PURE__ */ p("select", {
35
+ value: P,
36
+ onChange: (e) => F(Number(e.target.value)),
37
+ className: "w-full min-h-11 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200",
38
+ children: [
39
+ /* @__PURE__ */ f("option", {
40
+ value: 0,
41
+ children: e(D, "files.shareDialog.expiry.options.never", "Never")
96
42
  }),
97
- /* @__PURE__ */ m("div", {
98
- className: "flex items-center gap-2",
99
- children: [/* @__PURE__ */ p("input", {
100
- type: "checkbox",
101
- checked: M,
102
- onChange: (e) => N(e.target.checked),
103
- "aria-label": e(x, "files.shareDialog.password.require", "Require password"),
104
- className: "rounded transition-colors duration-200"
105
- }), /* @__PURE__ */ p("span", {
106
- className: "text-sm text-text-secondary",
107
- children: e(x, "files.shareDialog.password.require", "Require password")
108
- })]
43
+ /* @__PURE__ */ f("option", {
44
+ value: 1,
45
+ children: e(D, "files.shareDialog.expiry.options.oneDay", "1 day")
109
46
  }),
110
- M && /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("input", {
111
- type: "password",
112
- value: P,
113
- onChange: (e) => F(e.target.value),
114
- "aria-label": e(x, "files.shareDialog.password.label", "Password protection"),
115
- placeholder: e(x, "files.shareDialog.password.placeholder", "Enter password"),
116
- className: "w-full mt-2 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
117
- }), /* @__PURE__ */ p("p", {
118
- className: "mt-1 text-xs text-text-tertiary",
119
- children: e(x, "files.shareDialog.password.help", "Password must be at least 8 characters and contain uppercase, lowercase, and number")
120
- })] })
121
- ] }),
122
- /* @__PURE__ */ m("div", { children: [
123
- /* @__PURE__ */ m("label", {
124
- className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
125
- children: [/* @__PURE__ */ p(u, { className: "size-4" }), e(x, "files.shareDialog.invite.label", "Invite specific person (optional)")]
47
+ /* @__PURE__ */ f("option", {
48
+ value: 7,
49
+ children: e(D, "files.shareDialog.expiry.options.sevenDays", "7 days")
126
50
  }),
127
- /* @__PURE__ */ p("input", {
128
- type: "email",
129
- value: I,
130
- onChange: (e) => L(e.target.value),
131
- "aria-label": e(x, "files.shareDialog.invite.label", "Invite specific person (optional)"),
132
- placeholder: "user@example.com",
133
- className: "w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
51
+ /* @__PURE__ */ f("option", {
52
+ value: 30,
53
+ children: e(D, "files.shareDialog.expiry.options.thirtyDays", "30 days")
134
54
  }),
135
- /* @__PURE__ */ p("p", {
136
- className: "mt-1 text-xs text-text-secondary",
137
- children: e(x, "files.shareDialog.invite.help", "Leave empty for public link")
55
+ /* @__PURE__ */ f("option", {
56
+ value: 90,
57
+ children: e(D, "files.shareDialog.expiry.options.ninetyDays", "90 days")
138
58
  })
139
- ] })
140
- ]
141
- }),
142
- /* @__PURE__ */ m("div", {
143
- className: "flex justify-end gap-2 mt-6",
144
- children: [/* @__PURE__ */ p("button", {
145
- type: "button",
146
- onClick: v,
147
- className: "px-4 py-2 text-sm font-medium text-text-primary hover:bg-action-ghost-bg-hover rounded-lg transition-colors duration-200",
148
- children: e(x, "files.common.actions.cancel", "Cancel")
149
- }), /* @__PURE__ */ p("button", {
59
+ ]
60
+ })] }),
61
+ /* @__PURE__ */ p("div", { children: [
62
+ /* @__PURE__ */ p("label", {
63
+ className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
64
+ children: [/* @__PURE__ */ f(u, { className: "size-4" }), e(D, "files.shareDialog.invite.label", "Invite specific person (optional)")]
65
+ }),
66
+ /* @__PURE__ */ f("input", {
67
+ type: "email",
68
+ value: H,
69
+ onChange: (e) => U(e.target.value),
70
+ "aria-label": e(D, "files.shareDialog.invite.label", "Invite specific person (optional)"),
71
+ placeholder: "user@example.com",
72
+ className: "w-full min-h-11 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
73
+ }),
74
+ /* @__PURE__ */ f("p", {
75
+ className: "mt-1 text-xs text-text-secondary",
76
+ children: e(D, "files.shareDialog.invite.help", "Leave empty for public link")
77
+ })
78
+ ] }),
79
+ /* @__PURE__ */ f(g, {
80
+ title: e(D, "files.shareDialog.advanced.title", "Advanced"),
81
+ description: e(D, "files.shareDialog.advanced.description", "Download limits and password protection"),
82
+ children: /* @__PURE__ */ p("div", {
83
+ className: "space-y-4",
84
+ children: [/* @__PURE__ */ p("div", { children: [/* @__PURE__ */ p("label", {
85
+ className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
86
+ children: [/* @__PURE__ */ f(o, { className: "size-4" }), e(D, "files.shareDialog.downloads.label", "Maximum downloads")]
87
+ }), /* @__PURE__ */ f("input", {
88
+ type: "number",
89
+ min: "0",
90
+ value: I,
91
+ onChange: (e) => L(Number(e.target.value)),
92
+ "aria-label": e(D, "files.shareDialog.downloads.label", "Maximum downloads"),
93
+ placeholder: e(D, "files.shareDialog.downloads.placeholder", "Unlimited"),
94
+ className: "w-full min-h-11 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
95
+ })] }), /* @__PURE__ */ p("div", { children: [
96
+ /* @__PURE__ */ p("label", {
97
+ className: "flex items-center gap-2 text-sm font-medium text-text-primary mb-2",
98
+ children: [/* @__PURE__ */ f(l, { className: "size-4" }), e(D, "files.shareDialog.password.label", "Password protection")]
99
+ }),
100
+ /* @__PURE__ */ p("div", {
101
+ className: "flex items-center gap-2",
102
+ children: [/* @__PURE__ */ f("input", {
103
+ type: "checkbox",
104
+ checked: R,
105
+ onChange: (e) => z(e.target.checked),
106
+ "aria-label": e(D, "files.shareDialog.password.require", "Require password"),
107
+ className: "rounded transition-colors duration-200"
108
+ }), /* @__PURE__ */ f("span", {
109
+ className: "text-sm text-text-secondary",
110
+ children: e(D, "files.shareDialog.password.require", "Require password")
111
+ })]
112
+ }),
113
+ R && /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f("input", {
114
+ type: "password",
115
+ value: B,
116
+ onChange: (e) => V(e.target.value),
117
+ "aria-label": e(D, "files.shareDialog.password.label", "Password protection"),
118
+ placeholder: e(D, "files.shareDialog.password.placeholder", "Enter password"),
119
+ className: "w-full min-h-11 mt-2 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200"
120
+ }), /* @__PURE__ */ f("p", {
121
+ className: "mt-1 text-xs text-text-tertiary",
122
+ children: e(D, "files.shareDialog.password.help", "Password must be at least 8 characters and contain uppercase, lowercase, and number")
123
+ })] })
124
+ ] })]
125
+ })
126
+ })
127
+ ]
128
+ }),
129
+ /* @__PURE__ */ p(y, { children: [/* @__PURE__ */ f(h, {
130
+ type: "button",
131
+ variant: "outline",
132
+ onClick: w,
133
+ children: e(D, "files.common.actions.cancel", "Cancel")
134
+ }), /* @__PURE__ */ f(h, {
135
+ type: "button",
136
+ onClick: async () => {
137
+ try {
138
+ G(null);
139
+ let e = P > 0 ? new Date(Date.now() + P * 24 * 60 * 60 * 1e3).toISOString() : void 0, t = H ? "EMAIL_INVITE" : "PUBLIC_LINK", n = await T({
140
+ ...C === "file" ? { fileId: S.id } : { folderId: S.id },
141
+ shareType: t,
142
+ accessLevel: "DOWNLOAD",
143
+ expiresAt: e,
144
+ maxDownloads: I > 0 ? I : void 0,
145
+ password: R && B ? B : void 0,
146
+ invitedEmail: H || void 0
147
+ });
148
+ j(t), k(n.publicUrl || "");
149
+ } catch (e) {
150
+ G(e instanceof Error ? e.message : "Failed to create share");
151
+ }
152
+ },
153
+ disabled: E || R && !B,
154
+ children: E ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(c, { className: "size-4 animate-spin" }), e(D, "files.shareDialog.actions.creating", "Creating...")] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(s, { className: "size-4" }), e(D, "files.shareDialog.actions.createLink", "Create share link")] })
155
+ })] })
156
+ ] }) : /* @__PURE__ */ f(d, { children: /* @__PURE__ */ p("div", {
157
+ className: "space-y-4",
158
+ children: [/* @__PURE__ */ f("div", {
159
+ className: "bg-status-success-bg-subtle border border-status-success-border rounded-lg p-4",
160
+ children: A === "EMAIL_INVITE" ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f("p", {
161
+ className: "text-sm font-medium text-status-success-text mb-2",
162
+ children: e(D, "files.shareDialog.success.invitationSent", "Invitation sent successfully!")
163
+ }), /* @__PURE__ */ f("p", {
164
+ className: "text-sm text-text-secondary",
165
+ children: e(D, "files.shareDialog.success.invitationSentTo", "An invitation has been sent to {{email}}", { email: H })
166
+ })] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f("p", {
167
+ className: "text-sm font-medium text-status-success-text mb-2",
168
+ children: e(D, "files.shareDialog.success.linkCreated", "Share link created successfully!")
169
+ }), /* @__PURE__ */ p("div", {
170
+ className: "flex flex-col sm:flex-row items-stretch sm:items-center gap-2",
171
+ children: [/* @__PURE__ */ f("input", {
172
+ type: "text",
173
+ value: O || "",
174
+ readOnly: !0,
175
+ "aria-label": e(D, "files.shareDialog.success.linkCreated", "Share link"),
176
+ className: "flex-1 min-h-11 px-3 py-2 bg-bg-surface border border-status-success-border rounded-lg text-sm"
177
+ }), /* @__PURE__ */ f(h, {
150
178
  type: "button",
151
179
  onClick: async () => {
152
- try {
153
- z(null);
154
- let e = O > 0 ? new Date(Date.now() + O * 24 * 60 * 60 * 1e3).toISOString() : void 0, t = I ? "EMAIL_INVITE" : "PUBLIC_LINK", n = await y({
155
- ..._ === "file" ? { fileId: g.id } : { folderId: g.id },
156
- shareType: t,
157
- accessLevel: "DOWNLOAD",
158
- expiresAt: e,
159
- maxDownloads: A > 0 ? A : void 0,
160
- password: M && P ? P : void 0,
161
- invitedEmail: I || void 0
162
- });
163
- T(t), C(n.publicUrl || "");
164
- } catch (e) {
165
- z(e instanceof Error ? e.message : "Failed to create share");
166
- }
180
+ O && (await navigator.clipboard.writeText(O), N(!0));
167
181
  },
168
- disabled: b || M && !P,
169
- className: "flex items-center gap-2 px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover disabled:bg-bg-muted disabled:text-text-tertiary disabled:cursor-not-allowed transition-colors duration-200",
170
- children: b ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(c, { className: "size-4 animate-spin" }), e(x, "files.shareDialog.actions.creating", "Creating...")] }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(s, { className: "size-4" }), e(x, "files.shareDialog.actions.createLink", "Create share link")] })
182
+ children: M ? /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(i, { className: "size-4" }), e(D, "files.shareDialog.actions.copied", "Copied!")] }) : /* @__PURE__ */ p(d, { children: [/* @__PURE__ */ f(a, { className: "size-4" }), e(D, "files.common.actions.copy", "Copy")] })
171
183
  })]
172
- })
173
- ] }) : /* @__PURE__ */ p(f, { children: /* @__PURE__ */ m("div", {
174
- className: "space-y-4",
175
- children: [/* @__PURE__ */ p("div", {
176
- className: "bg-status-success-bg-subtle border border-status-success-border rounded-lg p-4",
177
- children: w === "EMAIL_INVITE" ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("p", {
178
- className: "text-sm font-medium text-status-success-text mb-2",
179
- children: e(x, "files.shareDialog.success.invitationSent", "Invitation sent successfully!")
180
- }), /* @__PURE__ */ p("p", {
181
- className: "text-sm text-text-secondary",
182
- children: e(x, "files.shareDialog.success.invitationSentTo", "An invitation has been sent to {{email}}", { email: I })
183
- })] }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("p", {
184
- className: "text-sm font-medium text-status-success-text mb-2",
185
- children: e(x, "files.shareDialog.success.linkCreated", "Share link created successfully!")
186
- }), /* @__PURE__ */ m("div", {
187
- className: "flex items-center gap-2",
188
- children: [/* @__PURE__ */ p("input", {
189
- type: "text",
190
- value: S || "",
191
- readOnly: !0,
192
- "aria-label": e(x, "files.shareDialog.success.linkCreated", "Share link"),
193
- className: "flex-1 px-3 py-2 bg-bg-surface border border-status-success-border rounded-lg text-sm"
194
- }), /* @__PURE__ */ p("button", {
195
- type: "button",
196
- onClick: async () => {
197
- S && (await navigator.clipboard.writeText(S), D(!0));
198
- },
199
- className: "flex items-center gap-2 px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-colors duration-200",
200
- children: E ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(i, { className: "size-4" }), e(x, "files.shareDialog.actions.copied", "Copied!")] }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p(a, { className: "size-4" }), e(x, "files.common.actions.copy", "Copy")] })
201
- })]
202
- })] })
203
- }), /* @__PURE__ */ p("button", {
204
- type: "button",
205
- onClick: v,
206
- className: "w-full px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-colors duration-200",
207
- children: e(x, "files.common.actions.done", "Done")
208
- })]
184
+ })] })
185
+ }), /* @__PURE__ */ f(y, { children: /* @__PURE__ */ f(h, {
186
+ type: "button",
187
+ onClick: w,
188
+ className: "w-full",
189
+ children: e(D, "files.common.actions.done", "Done")
209
190
  }) })]
210
- })
191
+ }) })] })
211
192
  });
212
193
  }
213
194
  //#endregion
214
- export { g as ShareDialog };
195
+ export { S as ShareDialog };
215
196
 
216
197
  //# sourceMappingURL=ShareDialog.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ShareDialog.js","names":[],"sources":["../../../src/files/components/ShareDialog.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport {\n X,\n Link,\n Mail,\n Calendar,\n Download,\n Lock,\n Copy,\n Check,\n Loader2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FileItem, FolderItem } from \"../types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\nexport interface ShareDialogInput {\n fileId?: string;\n folderId?: string;\n shareType: \"PUBLIC_LINK\" | \"EMAIL_INVITE\";\n accessLevel: \"VIEW\" | \"DOWNLOAD\" | \"EDIT\";\n expiresAt?: string;\n maxDownloads?: number;\n password?: string;\n invitedEmail?: string;\n}\n\ninterface ShareDialogProps {\n item: FileItem | FolderItem;\n itemType: \"file\" | \"folder\";\n onClose: () => void;\n onCreateShare: (\n input: ShareDialogInput,\n ) => Promise<{ publicUrl: string; token: string }>;\n isLoading?: boolean;\n}\n\nexport function ShareDialog({\n item,\n itemType,\n onClose,\n onCreateShare,\n isLoading,\n}: ShareDialogProps) {\n const { t } = useI18n();\n const [shareUrl, setShareUrl] = useState<string | null>(null);\n const [shareType, setShareType] = useState<\n \"PUBLIC_LINK\" | \"EMAIL_INVITE\" | null\n >(null);\n const [copied, setCopied] = useState(false);\n const [expiryDays, setExpiryDays] = useState<number>(7);\n const [maxDownloads, setMaxDownloads] = useState<number>(0);\n const [hasPassword, setHasPassword] = useState(false);\n const [password, setPassword] = useState(\"\");\n const [invitedEmail, setInvitedEmail] = useState(\"\");\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n const titleId = `share-dialog-title-${item.id}`;\n\n useEffect(() => {\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n onClose();\n }\n };\n\n document.addEventListener(\"keydown\", handleEscape);\n return () => document.removeEventListener(\"keydown\", handleEscape);\n }, [onClose]);\n\n const handleCreateShare = async () => {\n try {\n setErrorMessage(null);\n const expiresAt =\n expiryDays > 0\n ? new Date(\n Date.now() + expiryDays * 24 * 60 * 60 * 1000,\n ).toISOString()\n : undefined;\n\n const type: ShareDialogInput[\"shareType\"] = invitedEmail\n ? \"EMAIL_INVITE\"\n : \"PUBLIC_LINK\";\n\n const shareInput: ShareDialogInput = {\n ...(itemType === \"file\" ? { fileId: item.id } : { folderId: item.id }),\n shareType: type,\n accessLevel: \"DOWNLOAD\",\n expiresAt,\n maxDownloads: maxDownloads > 0 ? maxDownloads : undefined,\n password: hasPassword && password ? password : undefined,\n invitedEmail: invitedEmail || undefined,\n };\n\n const result = await onCreateShare(shareInput);\n\n setShareType(type);\n setShareUrl(result.publicUrl || \"\");\n } catch (error) {\n setErrorMessage(\n error instanceof Error ? error.message : \"Failed to create share\",\n );\n }\n };\n\n const handleCopyLink = async () => {\n if (shareUrl) {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n }\n };\n\n // Cleanup timeout on unmount to prevent React state update warning\n useEffect(() => {\n if (copied) {\n const timer = setTimeout(() => setCopied(false), 2000);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [copied]);\n\n return (\n <div\n className=\"fixed inset-0 bg-bg-overlay flex items-center justify-center z-[100] animate-in fade-in duration-200\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby={titleId}\n >\n <div className=\"bg-bg-surface rounded-lg shadow-xl p-6 w-full max-w-md mx-4 animate-in zoom-in-95 duration-200\">\n <div className=\"flex items-center justify-between mb-4\">\n <h2 id={titleId} className=\"text-lg font-semibold text-text-primary\">\n {tWithFallback(\n t,\n \"files.shareDialog.title\",\n 'Share {{itemType}} \"{{name}}\"',\n {\n itemType: tWithFallback(\n t,\n itemType === \"folder\"\n ? \"files.shareDialog.itemType.folder\"\n : \"files.shareDialog.itemType.file\",\n itemType === \"folder\" ? \"folder\" : \"file\",\n ),\n name: item.name,\n },\n )}\n </h2>\n <button\n type=\"button\"\n onClick={onClose}\n className=\"text-text-tertiary hover:text-text-secondary transition-colors duration-200\"\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.actions.close\",\n \"Close share dialog\",\n )}\n >\n <X className=\"size-5\" />\n </button>\n </div>\n\n {shareType === null ? (\n <>\n {errorMessage && (\n <div className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {errorMessage}\n </div>\n )}\n\n {/* Share Settings */}\n <div className=\"space-y-4\">\n {/* Expiry */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Calendar className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.label\",\n \"Link expires in\",\n )}\n </label>\n <select\n value={expiryDays}\n onChange={(e) => setExpiryDays(Number(e.target.value))}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n >\n <option value={0}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.never\",\n \"Never\",\n )}\n </option>\n <option value={1}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.oneDay\",\n \"1 day\",\n )}\n </option>\n <option value={7}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.sevenDays\",\n \"7 days\",\n )}\n </option>\n <option value={30}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.thirtyDays\",\n \"30 days\",\n )}\n </option>\n <option value={90}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.ninetyDays\",\n \"90 days\",\n )}\n </option>\n </select>\n </div>\n\n {/* Max Downloads */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Download className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.downloads.label\",\n \"Maximum downloads\",\n )}\n </label>\n <input\n type=\"number\"\n min=\"0\"\n value={maxDownloads}\n onChange={(e) => setMaxDownloads(Number(e.target.value))}\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.downloads.label\",\n \"Maximum downloads\",\n )}\n placeholder={tWithFallback(\n t,\n \"files.shareDialog.downloads.placeholder\",\n \"Unlimited\",\n )}\n className=\"w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n </div>\n\n {/* Password Protection */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Lock className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.password.label\",\n \"Password protection\",\n )}\n </label>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n checked={hasPassword}\n onChange={(e) => setHasPassword(e.target.checked)}\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.password.require\",\n \"Require password\",\n )}\n className=\"rounded transition-colors duration-200\"\n />\n <span className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.password.require\",\n \"Require password\",\n )}\n </span>\n </div>\n {hasPassword && (\n <>\n <input\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.password.label\",\n \"Password protection\",\n )}\n placeholder={tWithFallback(\n t,\n \"files.shareDialog.password.placeholder\",\n \"Enter password\",\n )}\n className=\"w-full mt-2 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n <p className=\"mt-1 text-xs text-text-tertiary\">\n {tWithFallback(\n t,\n \"files.shareDialog.password.help\",\n \"Password must be at least 8 characters and contain uppercase, lowercase, and number\",\n )}\n </p>\n </>\n )}\n </div>\n\n {/* Invited Email */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Mail className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.invite.label\",\n \"Invite specific person (optional)\",\n )}\n </label>\n <input\n type=\"email\"\n value={invitedEmail}\n onChange={(e) => setInvitedEmail(e.target.value)}\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.invite.label\",\n \"Invite specific person (optional)\",\n )}\n placeholder=\"user@example.com\"\n className=\"w-full px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n <p className=\"mt-1 text-xs text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.invite.help\",\n \"Leave empty for public link\",\n )}\n </p>\n </div>\n </div>\n\n {/* Create Button */}\n <div className=\"flex justify-end gap-2 mt-6\">\n <button\n type=\"button\"\n onClick={onClose}\n className=\"px-4 py-2 text-sm font-medium text-text-primary hover:bg-action-ghost-bg-hover rounded-lg transition-colors duration-200\"\n >\n {tWithFallback(t, \"files.common.actions.cancel\", \"Cancel\")}\n </button>\n <button\n type=\"button\"\n onClick={handleCreateShare}\n disabled={isLoading || (hasPassword && !password)}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover disabled:bg-bg-muted disabled:text-text-tertiary disabled:cursor-not-allowed transition-colors duration-200\"\n >\n {isLoading ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.creating\",\n \"Creating...\",\n )}\n </>\n ) : (\n <>\n <Link className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.createLink\",\n \"Create share link\",\n )}\n </>\n )}\n </button>\n </div>\n </>\n ) : (\n <>\n {/* Share Created Success */}\n <div className=\"space-y-4\">\n <div className=\"bg-status-success-bg-subtle border border-status-success-border rounded-lg p-4\">\n {shareType === \"EMAIL_INVITE\" ? (\n <>\n <p className=\"text-sm font-medium text-status-success-text mb-2\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.invitationSent\",\n \"Invitation sent successfully!\",\n )}\n </p>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.invitationSentTo\",\n \"An invitation has been sent to {{email}}\",\n { email: invitedEmail },\n )}\n </p>\n </>\n ) : (\n <>\n <p className=\"text-sm font-medium text-status-success-text mb-2\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.linkCreated\",\n \"Share link created successfully!\",\n )}\n </p>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"text\"\n value={shareUrl || \"\"}\n readOnly\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.success.linkCreated\",\n \"Share link\",\n )}\n className=\"flex-1 px-3 py-2 bg-bg-surface border border-status-success-border rounded-lg text-sm\"\n />\n <button\n type=\"button\"\n onClick={handleCopyLink}\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-colors duration-200\"\n >\n {copied ? (\n <>\n <Check className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.copied\",\n \"Copied!\",\n )}\n </>\n ) : (\n <>\n <Copy className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.common.actions.copy\",\n \"Copy\",\n )}\n </>\n )}\n </button>\n </div>\n </>\n )}\n </div>\n\n <button\n type=\"button\"\n onClick={onClose}\n className=\"w-full px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover transition-colors duration-200\"\n >\n {tWithFallback(t, \"files.common.actions.done\", \"Done\")}\n </button>\n </div>\n </>\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ShareDialog.js","names":[],"sources":["../../../src/files/components/ShareDialog.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport {\n Link,\n Mail,\n Calendar,\n Download,\n Lock,\n Copy,\n Check,\n Loader2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogFooter,\n OptionalFields,\n Button,\n} from \"@burdenoff/fe-libs/ui\";\nimport type { FileItem, FolderItem } from \"../types\";\nimport { tWithFallback } from \"../utils/i18n\";\n\nexport interface ShareDialogInput {\n fileId?: string;\n folderId?: string;\n shareType: \"PUBLIC_LINK\" | \"EMAIL_INVITE\";\n accessLevel: \"VIEW\" | \"DOWNLOAD\" | \"EDIT\";\n expiresAt?: string;\n maxDownloads?: number;\n password?: string;\n invitedEmail?: string;\n}\n\ninterface ShareDialogProps {\n item: FileItem | FolderItem;\n itemType: \"file\" | \"folder\";\n onClose: () => void;\n onCreateShare: (\n input: ShareDialogInput,\n ) => Promise<{ publicUrl: string; token: string }>;\n isLoading?: boolean;\n}\n\nexport function ShareDialog({\n item,\n itemType,\n onClose,\n onCreateShare,\n isLoading,\n}: ShareDialogProps) {\n const { t } = useI18n();\n const [shareUrl, setShareUrl] = useState<string | null>(null);\n const [shareType, setShareType] = useState<\n \"PUBLIC_LINK\" | \"EMAIL_INVITE\" | null\n >(null);\n const [copied, setCopied] = useState(false);\n const [expiryDays, setExpiryDays] = useState<number>(7);\n const [maxDownloads, setMaxDownloads] = useState<number>(0);\n const [hasPassword, setHasPassword] = useState(false);\n const [password, setPassword] = useState(\"\");\n const [invitedEmail, setInvitedEmail] = useState(\"\");\n const [errorMessage, setErrorMessage] = useState<string | null>(null);\n\n const handleCreateShare = async () => {\n try {\n setErrorMessage(null);\n const expiresAt =\n expiryDays > 0\n ? new Date(\n Date.now() + expiryDays * 24 * 60 * 60 * 1000,\n ).toISOString()\n : undefined;\n\n const type: ShareDialogInput[\"shareType\"] = invitedEmail\n ? \"EMAIL_INVITE\"\n : \"PUBLIC_LINK\";\n\n const shareInput: ShareDialogInput = {\n ...(itemType === \"file\" ? { fileId: item.id } : { folderId: item.id }),\n shareType: type,\n accessLevel: \"DOWNLOAD\",\n expiresAt,\n maxDownloads: maxDownloads > 0 ? maxDownloads : undefined,\n password: hasPassword && password ? password : undefined,\n invitedEmail: invitedEmail || undefined,\n };\n\n const result = await onCreateShare(shareInput);\n\n setShareType(type);\n setShareUrl(result.publicUrl || \"\");\n } catch (error) {\n setErrorMessage(\n error instanceof Error ? error.message : \"Failed to create share\",\n );\n }\n };\n\n const handleCopyLink = async () => {\n if (shareUrl) {\n await navigator.clipboard.writeText(shareUrl);\n setCopied(true);\n }\n };\n\n useEffect(() => {\n if (copied) {\n const timer = setTimeout(() => setCopied(false), 2000);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [copied]);\n\n return (\n <ResponsiveDialog\n open\n onOpenChange={(next: boolean) => {\n if (!next) onClose();\n }}\n >\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>\n {tWithFallback(\n t,\n \"files.shareDialog.title\",\n 'Share {{itemType}} \"{{name}}\"',\n {\n itemType: tWithFallback(\n t,\n itemType === \"folder\"\n ? \"files.shareDialog.itemType.folder\"\n : \"files.shareDialog.itemType.file\",\n itemType === \"folder\" ? \"folder\" : \"file\",\n ),\n name: item.name,\n },\n )}\n </ResponsiveDialogTitle>\n </ResponsiveDialogHeader>\n\n {shareType === null ? (\n <>\n {errorMessage && (\n <div className=\"mb-4 rounded-lg border border-status-error-border bg-status-error-bg-subtle px-3 py-2 text-sm text-status-error-text\">\n {errorMessage}\n </div>\n )}\n\n <div className=\"space-y-4\">\n {/* Expiry — smart-default field, visible above the fold */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Calendar className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.label\",\n \"Link expires in\",\n )}\n </label>\n <select\n value={expiryDays}\n onChange={(e) => setExpiryDays(Number(e.target.value))}\n className=\"w-full min-h-11 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n >\n <option value={0}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.never\",\n \"Never\",\n )}\n </option>\n <option value={1}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.oneDay\",\n \"1 day\",\n )}\n </option>\n <option value={7}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.sevenDays\",\n \"7 days\",\n )}\n </option>\n <option value={30}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.thirtyDays\",\n \"30 days\",\n )}\n </option>\n <option value={90}>\n {tWithFallback(\n t,\n \"files.shareDialog.expiry.options.ninetyDays\",\n \"90 days\",\n )}\n </option>\n </select>\n </div>\n\n {/* Invited Email — smart-default; \"leave empty for public link\" */}\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Mail className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.invite.label\",\n \"Invite specific person (optional)\",\n )}\n </label>\n <input\n type=\"email\"\n value={invitedEmail}\n onChange={(e) => setInvitedEmail(e.target.value)}\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.invite.label\",\n \"Invite specific person (optional)\",\n )}\n placeholder=\"user@example.com\"\n className=\"w-full min-h-11 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n <p className=\"mt-1 text-xs text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.invite.help\",\n \"Leave empty for public link\",\n )}\n </p>\n </div>\n\n {/* Advanced: ACL overrides + retention */}\n <OptionalFields\n title={tWithFallback(\n t,\n \"files.shareDialog.advanced.title\",\n \"Advanced\",\n )}\n description={tWithFallback(\n t,\n \"files.shareDialog.advanced.description\",\n \"Download limits and password protection\",\n )}\n >\n <div className=\"space-y-4\">\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Download className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.downloads.label\",\n \"Maximum downloads\",\n )}\n </label>\n <input\n type=\"number\"\n min=\"0\"\n value={maxDownloads}\n onChange={(e) => setMaxDownloads(Number(e.target.value))}\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.downloads.label\",\n \"Maximum downloads\",\n )}\n placeholder={tWithFallback(\n t,\n \"files.shareDialog.downloads.placeholder\",\n \"Unlimited\",\n )}\n className=\"w-full min-h-11 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n </div>\n\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-text-primary mb-2\">\n <Lock className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.password.label\",\n \"Password protection\",\n )}\n </label>\n <div className=\"flex items-center gap-2\">\n <input\n type=\"checkbox\"\n checked={hasPassword}\n onChange={(e) => setHasPassword(e.target.checked)}\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.password.require\",\n \"Require password\",\n )}\n className=\"rounded transition-colors duration-200\"\n />\n <span className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.password.require\",\n \"Require password\",\n )}\n </span>\n </div>\n {hasPassword && (\n <>\n <input\n type=\"password\"\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.password.label\",\n \"Password protection\",\n )}\n placeholder={tWithFallback(\n t,\n \"files.shareDialog.password.placeholder\",\n \"Enter password\",\n )}\n className=\"w-full min-h-11 mt-2 px-3 py-2 border border-border-default rounded-lg focus:outline-none focus:border-action-primary-border text-sm transition-colors duration-200\"\n />\n <p className=\"mt-1 text-xs text-text-tertiary\">\n {tWithFallback(\n t,\n \"files.shareDialog.password.help\",\n \"Password must be at least 8 characters and contain uppercase, lowercase, and number\",\n )}\n </p>\n </>\n )}\n </div>\n </div>\n </OptionalFields>\n </div>\n\n <ResponsiveDialogFooter>\n <Button type=\"button\" variant=\"outline\" onClick={onClose}>\n {tWithFallback(t, \"files.common.actions.cancel\", \"Cancel\")}\n </Button>\n <Button\n type=\"button\"\n onClick={handleCreateShare}\n disabled={isLoading || (hasPassword && !password)}\n >\n {isLoading ? (\n <>\n <Loader2 className=\"size-4 animate-spin\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.creating\",\n \"Creating...\",\n )}\n </>\n ) : (\n <>\n <Link className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.createLink\",\n \"Create share link\",\n )}\n </>\n )}\n </Button>\n </ResponsiveDialogFooter>\n </>\n ) : (\n <>\n <div className=\"space-y-4\">\n <div className=\"bg-status-success-bg-subtle border border-status-success-border rounded-lg p-4\">\n {shareType === \"EMAIL_INVITE\" ? (\n <>\n <p className=\"text-sm font-medium text-status-success-text mb-2\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.invitationSent\",\n \"Invitation sent successfully!\",\n )}\n </p>\n <p className=\"text-sm text-text-secondary\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.invitationSentTo\",\n \"An invitation has been sent to {{email}}\",\n { email: invitedEmail },\n )}\n </p>\n </>\n ) : (\n <>\n <p className=\"text-sm font-medium text-status-success-text mb-2\">\n {tWithFallback(\n t,\n \"files.shareDialog.success.linkCreated\",\n \"Share link created successfully!\",\n )}\n </p>\n <div className=\"flex flex-col sm:flex-row items-stretch sm:items-center gap-2\">\n <input\n type=\"text\"\n value={shareUrl || \"\"}\n readOnly\n aria-label={tWithFallback(\n t,\n \"files.shareDialog.success.linkCreated\",\n \"Share link\",\n )}\n className=\"flex-1 min-h-11 px-3 py-2 bg-bg-surface border border-status-success-border rounded-lg text-sm\"\n />\n <Button type=\"button\" onClick={handleCopyLink}>\n {copied ? (\n <>\n <Check className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.shareDialog.actions.copied\",\n \"Copied!\",\n )}\n </>\n ) : (\n <>\n <Copy className=\"size-4\" />\n {tWithFallback(\n t,\n \"files.common.actions.copy\",\n \"Copy\",\n )}\n </>\n )}\n </Button>\n </div>\n </>\n )}\n </div>\n\n <ResponsiveDialogFooter>\n <Button type=\"button\" onClick={onClose} className=\"w-full\">\n {tWithFallback(t, \"files.common.actions.done\", \"Done\")}\n </Button>\n </ResponsiveDialogFooter>\n </div>\n </>\n )}\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/microfe-files",
3
- "version": "2026.527.5",
3
+ "version": "2026.528.2",
4
4
  "description": "Burdenoff Files Microfrontend - Standalone file management module",
5
5
  "type": "module",
6
6
  "imports": {
@@ -45,7 +45,7 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "@apollo/client": "^4.0.13",
48
- "@burdenoff/fe-libs": "2026.524.1",
48
+ "@burdenoff/fe-libs": "2026.528.2",
49
49
  "@tanstack/react-query": "^5.90.17",
50
50
  "graphql": "^16.12.0",
51
51
  "lucide-react": "^0.468.0",