@burdenoff/microfe-export 2026.623.2 → 2026.625.1

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 +1 @@
1
- {"version":3,"file":"ExportDashboardPage.js","names":[],"sources":["../../../src/export/pages/ExportDashboardPage.tsx"],"sourcesContent":["import {\n Plus,\n Download,\n Clock,\n FileBox,\n ArrowRight,\n Activity,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport { useExportJobs } from \"../hooks/useExportQueries\";\nimport { ExportStatusBadge } from \"../components/ExportStatusBadge\";\nimport { ExportProgressBar } from \"../components/ExportProgressBar\";\nimport { PageLayout, PageSection, EmptyState } from \"../components/PageLayout\";\nimport { cn } from \"../utils/cn\";\nimport { tWithFallback } from \"../utils/i18n\";\n\n/**\n * Helper to join paths correctly, avoiding double slashes\n */\nconst joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return cleanBase + cleanPath;\n};\n\n/**\n * Export Dashboard Page\n * Overview with recent exports, quick actions, and status summary\n */\nexport function ExportDashboardPage() {\n const { basePath = \"/\", navigate } = useExport();\n const { t } = useI18n();\n const tr = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>,\n ) => tWithFallback(t, key, fallback, params);\n const { data: jobs, isLoading } = useExportJobs({});\n\n const recentJobs = jobs.slice(0, 5);\n const activeJobs = jobs.filter(\n (j) => j.status === \"RUNNING\" || j.status === \"QUEUED\",\n );\n\n const handleNavigate = (path: string) => {\n if (!navigate) return;\n navigate(joinPath(basePath, path));\n };\n\n return (\n <PageLayout\n title={tr(\"export.dashboard.title\", \"Export\")}\n subtitle={tr(\n \"export.dashboard.subtitle\",\n \"Export your workspace data in multiple formats\",\n )}\n icon={<Download size={24} />}\n >\n {/* Quick Actions */}\n <div\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\"\n data-tour=\"export-dashboard-quick-actions\"\n >\n {[\n {\n icon: <Plus size={20} />,\n label: tr(\"export.dashboard.actions.newExport.label\", \"New Export\"),\n description: tr(\n \"export.dashboard.actions.newExport.description\",\n \"Create a new data export\",\n ),\n path: \"new\",\n color: \"bg-primary/10 text-primary\",\n },\n {\n icon: <Clock size={20} />,\n label: tr(\"export.dashboard.actions.history.label\", \"History\"),\n description: tr(\n \"export.dashboard.actions.history.description\",\n \"View past exports\",\n ),\n path: \"history\",\n color: \"bg-status-info-bg-subtle text-status-info-text\",\n },\n {\n icon: <FileBox size={20} />,\n label: tr(\"export.dashboard.actions.templates.label\", \"Templates\"),\n description: tr(\n \"export.dashboard.actions.templates.description\",\n \"Reusable export configs\",\n ),\n path: \"templates\",\n color: \"bg-accent-purple-subtle text-accent-purple\",\n },\n {\n icon: <Activity size={20} />,\n label: tr(\n \"export.dashboard.actions.activeJobs.label\",\n \"Active Jobs\",\n ),\n description: tr(\n \"export.dashboard.actions.activeJobs.description\",\n \"{count} running\",\n { count: activeJobs.length },\n ),\n path: \"history?status=RUNNING\",\n color: \"bg-status-success-bg-subtle text-status-success-text\",\n },\n ].map((action) => (\n <button\n type=\"button\"\n key={action.path + action.label}\n onClick={() => handleNavigate(action.path)}\n className={cn(\n \"group relative overflow-hidden border-2 border-border/50 rounded-xl p-5\",\n \"bg-gradient-to-br from-card/50 to-background shadow-sm\",\n \"hover:shadow-md hover:border-primary/30 transition-all duration-200\",\n \"text-left\",\n )}\n >\n <div className={cn(\"p-2.5 rounded-lg w-fit mb-3\", action.color)}>\n {action.icon}\n </div>\n <h3 className=\"font-semibold text-foreground mb-1\">\n {action.label}\n </h3>\n <p className=\"text-sm text-muted-foreground\">\n {action.description}\n </p>\n <ArrowRight\n size={16}\n className=\"absolute top-5 right-5 text-muted-foreground opacity-0 group-hover:opacity-100 transition-opacity\"\n />\n </button>\n ))}\n </div>\n\n {/* Active Exports */}\n {activeJobs.length > 0 && (\n <PageSection\n data-tour=\"export-dashboard-active-section\"\n title={tr(\"export.dashboard.active.title\", \"Active Exports\")}\n description={tr(\n \"export.dashboard.active.description\",\n \"Currently running export jobs\",\n )}\n >\n <div className=\"space-y-3\">\n {activeJobs.map((job) => (\n <button\n type=\"button\"\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border-2 border-border/50 rounded-xl p-4\",\n \"hover:shadow-md hover:border-primary/30 transition-all duration-200\",\n \"bg-gradient-to-r from-card/50 to-background\",\n )}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"font-semibold text-foreground\">{job.name}</h4>\n <ExportStatusBadge status={job.status} />\n </div>\n <ExportProgressBar progress={job.progress} size=\"sm\" />\n </button>\n ))}\n </div>\n </PageSection>\n )}\n\n {/* Recent Exports */}\n <PageSection\n data-tour=\"export-dashboard-recent-section\"\n title={tr(\"export.dashboard.recent.title\", \"Recent Exports\")}\n description={tr(\n \"export.dashboard.recent.description\",\n \"Your latest export jobs\",\n )}\n actions={\n recentJobs.length > 0 ? (\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"history\")}\n className=\"text-sm text-primary hover:underline font-medium\"\n >\n {tr(\"export.dashboard.recent.actions.viewAll\", \"View All\")}\n </button>\n ) : undefined\n }\n >\n {isLoading ? (\n <div className=\"space-y-3\">\n {[...Array(3)].map((_, i) => (\n <div\n key={i}\n className=\"border-2 border-border/50 rounded-xl p-4 animate-pulse\"\n >\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"h-4 w-48 bg-muted rounded\" />\n <div className=\"h-5 w-20 bg-muted rounded-full\" />\n </div>\n <div className=\"h-3 w-32 bg-muted rounded mt-2\" />\n </div>\n ))}\n </div>\n ) : recentJobs.length > 0 ? (\n <div className=\"space-y-3\">\n {recentJobs.map((job, index) => (\n <button\n type=\"button\"\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border-2 border-border/50 rounded-xl p-4\",\n \"hover:shadow-md hover:border-primary/30 transition-all duration-200\",\n \"bg-gradient-to-r from-card/50 to-background\",\n \"animate-in fade-in-0 slide-in-from-bottom-2\",\n )}\n style={{ animationDelay: `${index * 50}ms` }}\n >\n <div className=\"flex items-start sm:items-center justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-semibold text-foreground truncate\">\n {job.name}\n </h4>\n <p className=\"text-sm text-muted-foreground mt-1 line-clamp-2\">\n {job.entityTypes.join(\", \")} &middot; {job.format}\n {job.totalEntities != null &&\n ` · ${tr(\n \"export.dashboard.recent.entitiesCount\",\n \"{count} entities\",\n { count: job.totalEntities.toLocaleString() },\n )}`}\n </p>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n <ExportStatusBadge status={job.status} />\n <ArrowRight\n size={16}\n className=\"text-muted-foreground hidden sm:block\"\n />\n </div>\n </div>\n </button>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<Download size={48} />}\n title={tr(\"export.dashboard.empty.title\", \"No exports yet\")}\n description={tr(\n \"export.dashboard.empty.description\",\n \"Create your first export to start downloading your workspace data.\",\n )}\n action={\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"new\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium\"\n >\n <Plus size={16} />\n {tr(\n \"export.dashboard.empty.actions.createFirst\",\n \"Create First Export\",\n )}\n </button>\n }\n />\n )}\n </PageSection>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ExportDashboardPage.js","names":[],"sources":["../../../src/export/pages/ExportDashboardPage.tsx"],"sourcesContent":["import {\n Plus,\n Download,\n Clock,\n FileBox,\n ArrowRight,\n Activity,\n CheckCircle2,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport { GlassCard, EmphasisPanel } from \"@burdenoff/fe-libs/ui\";\nimport { useExport } from \"../providers/ExportProvider\";\nimport { useExportJobs } from \"../hooks/useExportQueries\";\nimport { ExportStatusBadge } from \"../components/ExportStatusBadge\";\nimport { ExportProgressBar } from \"../components/ExportProgressBar\";\nimport { PageLayout, PageSection, EmptyState } from \"../components/PageLayout\";\nimport { cn } from \"../utils/cn\";\nimport { tWithFallback } from \"../utils/i18n\";\n\n/**\n * Helper to join paths correctly, avoiding double slashes\n */\nconst joinPath = (base: string, path: string): string => {\n const cleanBase = base.endsWith(\"/\") ? base.slice(0, -1) : base;\n const cleanPath = path.startsWith(\"/\") ? path : `/${path}`;\n return cleanBase + cleanPath;\n};\n\n/**\n * Export Dashboard Page\n * Overview with recent exports, quick actions, and status summary\n */\nexport function ExportDashboardPage() {\n const { basePath = \"/\", navigate } = useExport();\n const { t } = useI18n();\n const tr = (\n key: string,\n fallback: string,\n params?: Record<string, string | number>,\n ) => tWithFallback(t, key, fallback, params);\n const { data: jobs, isLoading } = useExportJobs({});\n\n const recentJobs = jobs.slice(0, 5);\n const activeJobs = jobs.filter(\n (j) => j.status === \"RUNNING\" || j.status === \"QUEUED\",\n );\n const completedJobs = jobs.filter((j) => j.status === \"COMPLETED\");\n\n const metrics = [\n {\n icon: <Download size={18} />,\n label: tr(\"export.dashboard.metrics.total\", \"Total Exports\"),\n value: jobs.length,\n treatment: \"glass\" as const,\n },\n {\n icon: <Activity size={18} />,\n label: tr(\"export.dashboard.metrics.active\", \"Active\"),\n value: activeJobs.length,\n treatment: \"metric\" as const,\n },\n {\n icon: <CheckCircle2 size={18} />,\n label: tr(\"export.dashboard.metrics.completed\", \"Completed\"),\n value: completedJobs.length,\n treatment: \"metric\" as const,\n },\n ];\n\n const handleNavigate = (path: string) => {\n if (!navigate) return;\n navigate(joinPath(basePath, path));\n };\n\n return (\n <PageLayout\n title={tr(\"export.dashboard.title\", \"Export\")}\n subtitle={tr(\n \"export.dashboard.subtitle\",\n \"Export your workspace data in multiple formats\",\n )}\n icon={<Download size={24} />}\n >\n {/* Metric strip */}\n {!isLoading && jobs.length > 0 && (\n <div className=\"grid grid-cols-1 sm:grid-cols-3 gap-4\">\n {metrics.map((m) => (\n <GlassCard\n key={m.label}\n treatment={m.treatment}\n className=\"p-5 border-border-seam\"\n >\n <div className=\"flex items-center gap-2 text-text-secondary mb-2\">\n {m.icon}\n <span className=\"text-xs font-medium\">{m.label}</span>\n </div>\n <p className=\"text-3xl font-bold tabular-nums text-text-primary\">\n {m.value.toLocaleString()}\n </p>\n </GlassCard>\n ))}\n </div>\n )}\n\n {/* Quick Actions */}\n <div\n className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4\"\n data-tour=\"export-dashboard-quick-actions\"\n >\n {[\n {\n icon: <Plus size={20} />,\n label: tr(\"export.dashboard.actions.newExport.label\", \"New Export\"),\n description: tr(\n \"export.dashboard.actions.newExport.description\",\n \"Create a new data export\",\n ),\n path: \"new\",\n color: \"bg-action-primary-bg/10 text-primary\",\n },\n {\n icon: <Clock size={20} />,\n label: tr(\"export.dashboard.actions.history.label\", \"History\"),\n description: tr(\n \"export.dashboard.actions.history.description\",\n \"View past exports\",\n ),\n path: \"history\",\n color: \"bg-status-info-bg-subtle text-status-info-text\",\n },\n {\n icon: <FileBox size={20} />,\n label: tr(\"export.dashboard.actions.templates.label\", \"Templates\"),\n description: tr(\n \"export.dashboard.actions.templates.description\",\n \"Reusable export configs\",\n ),\n path: \"templates\",\n color: \"bg-accent-purple-subtle text-accent-purple\",\n },\n {\n icon: <Activity size={20} />,\n label: tr(\n \"export.dashboard.actions.activeJobs.label\",\n \"Active Jobs\",\n ),\n description: tr(\n \"export.dashboard.actions.activeJobs.description\",\n \"{count} running\",\n { count: activeJobs.length },\n ),\n path: \"history?status=RUNNING\",\n color: \"bg-status-success-bg-subtle text-status-success-text\",\n },\n ].map((action) => (\n <button\n type=\"button\"\n key={action.path + action.label}\n onClick={() => handleNavigate(action.path)}\n className={cn(\n \"group relative overflow-hidden border border-border-seam rounded-xl p-5\",\n \"bg-bg-surface shadow-[var(--shadow-pop)]\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n )}\n >\n <div className={cn(\"p-2.5 rounded-lg w-fit mb-3\", action.color)}>\n {action.icon}\n </div>\n <h3 className=\"font-semibold text-text-primary mb-1\">\n {action.label}\n </h3>\n <p className=\"text-sm text-text-secondary\">\n {action.description}\n </p>\n <ArrowRight\n size={16}\n className=\"absolute top-5 right-5 text-text-secondary opacity-0 group-hover:opacity-100 transition-opacity\"\n />\n </button>\n ))}\n </div>\n\n {/* Active Exports — the single emphasised zone on this page */}\n {activeJobs.length > 0 && (\n <EmphasisPanel\n data-tour=\"export-dashboard-active-section\"\n className=\"p-5 sm:p-6\"\n >\n <div className=\"mb-4\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr(\"export.dashboard.active.title\", \"Active Exports\")}\n </h2>\n <p className=\"text-sm text-text-secondary\">\n {tr(\n \"export.dashboard.active.description\",\n \"Currently running export jobs\",\n )}\n </p>\n </div>\n <div className=\"space-y-3\">\n {activeJobs.map((job) => (\n <button\n type=\"button\"\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border border-border-seam rounded-xl p-4 bg-bg-surface/70\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n )}\n >\n <div className=\"flex items-center justify-between mb-2\">\n <h4 className=\"font-semibold text-text-primary\">{job.name}</h4>\n <ExportStatusBadge status={job.status} />\n </div>\n <ExportProgressBar progress={job.progress} size=\"sm\" />\n </button>\n ))}\n </div>\n </EmphasisPanel>\n )}\n\n {/* Recent Exports */}\n <PageSection\n data-tour=\"export-dashboard-recent-section\"\n title={tr(\"export.dashboard.recent.title\", \"Recent Exports\")}\n description={tr(\n \"export.dashboard.recent.description\",\n \"Your latest export jobs\",\n )}\n actions={\n recentJobs.length > 0 ? (\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"history\")}\n className=\"text-sm text-primary hover:underline font-medium\"\n >\n {tr(\"export.dashboard.recent.actions.viewAll\", \"View All\")}\n </button>\n ) : undefined\n }\n >\n {isLoading ? (\n <div className=\"space-y-3\">\n {[...Array(3)].map((_, i) => (\n <div\n key={i}\n className=\"border border-border-seam rounded-xl p-4 animate-pulse\"\n >\n <div className=\"flex items-center justify-between mb-2\">\n <div className=\"h-4 w-48 bg-bg-sunken rounded\" />\n <div className=\"h-5 w-20 bg-bg-sunken rounded-full\" />\n </div>\n <div className=\"h-3 w-32 bg-bg-sunken rounded mt-2\" />\n </div>\n ))}\n </div>\n ) : recentJobs.length > 0 ? (\n <div className=\"space-y-3\">\n {recentJobs.map((job, index) => (\n <button\n type=\"button\"\n key={job.id}\n onClick={() => handleNavigate(job.id)}\n className={cn(\n \"w-full text-left border border-border-seam rounded-xl p-4 bg-bg-surface\",\n \"hover:border-primary/40 transition-colors duration-200\",\n \"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40\",\n \"animate-in fade-in-0\",\n )}\n style={{ animationDelay: `${index * 50}ms` }}\n >\n <div className=\"flex items-start sm:items-center justify-between gap-3\">\n <div className=\"flex-1 min-w-0\">\n <h4 className=\"font-semibold text-text-primary truncate\">\n {job.name}\n </h4>\n <p className=\"text-sm text-text-secondary mt-1 line-clamp-2\">\n {job.entityTypes.join(\", \")} &middot; {job.format}\n {job.totalEntities != null &&\n ` · ${tr(\n \"export.dashboard.recent.entitiesCount\",\n \"{count} entities\",\n { count: job.totalEntities.toLocaleString() },\n )}`}\n </p>\n </div>\n <div className=\"flex items-center gap-2 flex-shrink-0\">\n <ExportStatusBadge status={job.status} />\n <ArrowRight\n size={16}\n className=\"text-text-secondary hidden sm:block\"\n />\n </div>\n </div>\n </button>\n ))}\n </div>\n ) : (\n <EmptyState\n icon={<Download size={48} />}\n title={tr(\"export.dashboard.empty.title\", \"No exports yet\")}\n description={tr(\n \"export.dashboard.empty.description\",\n \"Create your first export to start downloading your workspace data.\",\n )}\n action={\n <button\n type=\"button\"\n onClick={() => handleNavigate(\"new\")}\n className=\"inline-flex items-center gap-2 px-4 py-2 bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors font-medium\"\n >\n <Plus size={16} />\n {tr(\n \"export.dashboard.empty.actions.createFirst\",\n \"Create First Export\",\n )}\n </button>\n }\n />\n )}\n </PageSection>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -4,14 +4,15 @@ import { cn as o } from "../utils/cn.js";
4
4
  import { getArchiveFormatDisplayName as s, getFormatDisplayName as c } from "../constants/enums.js";
5
5
  import { ExportStatusBadge as l } from "../components/ExportStatusBadge.js";
6
6
  import { ExportProgressBar as u } from "../components/ExportProgressBar.js";
7
- import { PageLayout as d, PageSection as f } from "../components/PageLayout.js";
8
- import { nativeImpact as p, nativeNotify as m } from "../../utils/nativeBridge.js";
9
- import { useState as h } from "react";
10
- import { AlertCircle as g, ArrowLeft as _, CheckCircle2 as v, Clock as y, Download as b, FileDown as x, FileText as S, HardDrive as C, Loader2 as w, RotateCcw as T, Trash2 as E, XCircle as D } from "lucide-react";
11
- import { useNavigate as O, useParams as k } from "react-router-dom";
12
- import { jsx as A, jsxs as j } from "react/jsx-runtime";
7
+ import { PageLayout as d, PageSection as ee } from "../components/PageLayout.js";
8
+ import { nativeImpact as te, nativeNotify as f } from "../../utils/nativeBridge.js";
9
+ import { useState as p } from "react";
10
+ import { AlertCircle as m, ArrowLeft as h, CheckCircle2 as g, Clock as _, Download as v, FileDown as y, FileText as b, HardDrive as x, Loader2 as S, RotateCcw as C, Trash2 as w, XCircle as ne } from "lucide-react";
11
+ import { useNavigate as re, useParams as ie } from "react-router-dom";
12
+ import { jsx as T, jsxs as E } from "react/jsx-runtime";
13
+ import { CTAOverflowMenu as D, GlassCard as O } from "@burdenoff/fe-libs/ui";
13
14
  //#region src/export/pages/ExportDetailPage.tsx
14
- function M(e) {
15
+ function k(e) {
15
16
  if (e === 0) return "0 B";
16
17
  let t = 1024, n = [
17
18
  "B",
@@ -22,312 +23,327 @@ function M(e) {
22
23
  ], r = Math.floor(Math.log(e) / Math.log(t));
23
24
  return `${parseFloat((e / t ** +r).toFixed(2))} ${n[r]}`;
24
25
  }
25
- var N = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
26
- function P() {
27
- let { jobId: P } = k(), { basePath: F = "/", navigate: I } = e(), L = O(), R = () => {
28
- window.history.length > 1 ? L(-1) : I?.(F);
29
- }, { data: z, isLoading: B } = r(P), { data: V } = i(P), [H, U] = h(null), { cancelJob: W, isPending: G } = t(), { deleteJob: K, isPending: q } = n(), { retryJob: J, isPending: Y } = a(), X = V ?? z ?? null, Z = X?.status === "CREATED" || X?.status === "QUEUED" || X?.status === "RUNNING", Q = X?.status === "COMPLETED", $ = X?.status === "FAILED", ee = X?.status === "FAILED" || X?.status === "CANCELLED" || X?.status === "EXPIRED";
30
- return B ? /* @__PURE__ */ j("div", {
26
+ var A = (e, t) => (e.endsWith("/") ? e.slice(0, -1) : e) + (t.startsWith("/") ? t : `/${t}`);
27
+ function j() {
28
+ let { jobId: j } = ie(), { basePath: M = "/", navigate: N } = e(), P = re(), F = () => {
29
+ window.history.length > 1 ? P(-1) : N?.(M);
30
+ }, { data: I, isLoading: L } = r(j), { data: R } = i(j), [z, B] = p(null), { cancelJob: V, isPending: H } = t(), { deleteJob: U, isPending: W } = n(), { retryJob: G, isPending: K } = a(), q = R ?? I ?? null, J = q?.status === "CREATED" || q?.status === "QUEUED" || q?.status === "RUNNING", ae = q?.status === "COMPLETED", oe = q?.status === "FAILED", Y = q?.status === "FAILED" || q?.status === "CANCELLED" || q?.status === "EXPIRED", se = async () => {
31
+ j && B("cancel");
32
+ }, ce = async () => {
33
+ j && (te("medium"), B("delete"));
34
+ }, le = async () => {
35
+ if (!(!j || !z)) {
36
+ try {
37
+ z === "cancel" ? await V(j) : (await U(j), N?.(M)), f("success");
38
+ } catch {
39
+ f("error");
40
+ }
41
+ B(null);
42
+ }
43
+ }, X = async () => {
44
+ if (!j) return;
45
+ let e = await G(j);
46
+ e?.id && N?.(A(M, e.id));
47
+ }, Z = q?.parts.find((e) => e.downloadUrl);
48
+ if (L) return /* @__PURE__ */ E("div", {
31
49
  className: "flex flex-col items-center justify-center py-20",
32
- children: [/* @__PURE__ */ A(w, {
50
+ children: [/* @__PURE__ */ T(S, {
33
51
  size: 48,
34
52
  className: "animate-spin text-primary"
35
- }), /* @__PURE__ */ A("span", {
36
- className: "mt-6 text-sm font-medium text-muted-foreground",
53
+ }), /* @__PURE__ */ T("span", {
54
+ className: "mt-6 text-sm font-medium text-text-secondary",
37
55
  children: "Loading export details…"
38
56
  })]
39
- }) : X ? /* @__PURE__ */ j(d, {
57
+ });
58
+ if (!q) return /* @__PURE__ */ E(d, {
59
+ showHeader: !1,
60
+ children: [/* @__PURE__ */ E("div", {
61
+ className: "flex items-center gap-3 mb-6",
62
+ children: [/* @__PURE__ */ T("button", {
63
+ type: "button",
64
+ onClick: F,
65
+ className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200",
66
+ children: /* @__PURE__ */ T(h, { size: 20 })
67
+ }), /* @__PURE__ */ T("h1", {
68
+ className: "text-xl font-bold",
69
+ children: "Export Not Found"
70
+ })]
71
+ }), /* @__PURE__ */ E("div", {
72
+ className: "border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-12 text-center",
73
+ children: [
74
+ /* @__PURE__ */ T(m, {
75
+ size: 48,
76
+ className: "text-status-error-text mx-auto mb-4"
77
+ }),
78
+ /* @__PURE__ */ T("h3", {
79
+ className: "text-lg font-bold text-status-error-text mb-2",
80
+ children: "Export Not Found"
81
+ }),
82
+ /* @__PURE__ */ T("p", {
83
+ className: "text-status-error-text mb-6",
84
+ children: "The export job you are looking for does not exist or has been deleted."
85
+ }),
86
+ /* @__PURE__ */ E("button", {
87
+ type: "button",
88
+ onClick: F,
89
+ className: "inline-flex items-center gap-2 px-6 py-3 bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors font-medium",
90
+ children: [/* @__PURE__ */ T(h, { size: 18 }), "Back to Dashboard"]
91
+ })
92
+ ]
93
+ })]
94
+ });
95
+ let Q = Z ? {
96
+ label: "Download",
97
+ icon: /* @__PURE__ */ T(v, { size: 16 }),
98
+ onSelect: () => {
99
+ Z.downloadUrl && window.location.assign(Z.downloadUrl);
100
+ }
101
+ } : Y ? {
102
+ label: "Retry Export",
103
+ icon: /* @__PURE__ */ T(C, { size: 16 }),
104
+ disabled: K,
105
+ onSelect: () => {
106
+ X();
107
+ }
108
+ } : void 0, $ = [];
109
+ return Y && Z && $.push({
110
+ label: "Retry Export",
111
+ icon: /* @__PURE__ */ T(C, { size: 16 }),
112
+ disabled: K,
113
+ onSelect: () => {
114
+ X();
115
+ }
116
+ }), J && $.push({
117
+ label: "Cancel Export",
118
+ icon: /* @__PURE__ */ T(ne, { size: 16 }),
119
+ disabled: H,
120
+ onSelect: () => {
121
+ se();
122
+ }
123
+ }), J || $.push({
124
+ label: "Delete Export",
125
+ icon: /* @__PURE__ */ T(w, { size: 16 }),
126
+ intent: "destructive",
127
+ disabled: W,
128
+ onSelect: () => {
129
+ ce();
130
+ }
131
+ }), /* @__PURE__ */ E(d, {
40
132
  showHeader: !1,
41
133
  children: [
42
- /* @__PURE__ */ A("div", {
43
- className: "relative overflow-hidden rounded-xl bg-gradient-to-br from-primary/5 via-primary/3 to-background border border-border/50 p-6 shadow-sm",
44
- children: /* @__PURE__ */ j("div", {
45
- className: "relative z-10 flex items-center gap-4",
46
- children: [/* @__PURE__ */ A("button", {
47
- type: "button",
48
- onClick: R,
49
- className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200",
50
- children: /* @__PURE__ */ A(_, { size: 20 })
51
- }), /* @__PURE__ */ j("div", {
52
- className: "flex items-center gap-3 flex-1",
53
- children: [
54
- /* @__PURE__ */ A("div", {
55
- className: "p-2.5 rounded-lg bg-primary/10",
56
- children: /* @__PURE__ */ A(b, {
57
- size: 24,
58
- className: "text-primary"
59
- })
60
- }),
61
- /* @__PURE__ */ j("div", {
62
- className: "flex-1 min-w-0",
63
- children: [/* @__PURE__ */ A("h1", {
64
- className: "text-xl sm:text-2xl font-bold truncate",
65
- children: X.name
66
- }), /* @__PURE__ */ A("p", {
67
- className: "text-sm text-muted-foreground mt-1",
68
- children: X.entityTypes.join(", ")
69
- })]
70
- }),
71
- /* @__PURE__ */ A(l, { status: X.status })
72
- ]
73
- })]
134
+ /* @__PURE__ */ T("div", {
135
+ className: "relative overflow-hidden rounded-xl bg-accent-wash border border-border-seam p-6 shadow-[var(--shadow-pop)]",
136
+ children: /* @__PURE__ */ E("div", {
137
+ className: "relative z-10 flex flex-col sm:flex-row sm:items-center gap-4",
138
+ children: [
139
+ /* @__PURE__ */ T("button", {
140
+ type: "button",
141
+ onClick: F,
142
+ "aria-label": "Go back",
143
+ className: "p-2.5 hover:bg-accent rounded-lg transition-colors duration-200 self-start focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/40",
144
+ children: /* @__PURE__ */ T(h, { size: 20 })
145
+ }),
146
+ /* @__PURE__ */ E("div", {
147
+ className: "flex items-center gap-3 flex-1 min-w-0",
148
+ children: [
149
+ /* @__PURE__ */ T("div", {
150
+ className: "p-2.5 rounded-lg bg-action-primary-bg/10",
151
+ children: /* @__PURE__ */ T(v, {
152
+ size: 24,
153
+ className: "text-primary"
154
+ })
155
+ }),
156
+ /* @__PURE__ */ E("div", {
157
+ className: "flex-1 min-w-0",
158
+ children: [/* @__PURE__ */ T("h1", {
159
+ className: "text-xl sm:text-2xl font-bold truncate",
160
+ children: q.name
161
+ }), /* @__PURE__ */ T("p", {
162
+ className: "text-sm text-text-secondary mt-1",
163
+ children: q.entityTypes.join(", ")
164
+ })]
165
+ }),
166
+ /* @__PURE__ */ T(l, { status: q.status })
167
+ ]
168
+ }),
169
+ (Q || $.length > 0) && /* @__PURE__ */ T("div", {
170
+ className: "flex-shrink-0",
171
+ children: /* @__PURE__ */ T(D, {
172
+ primary: Q,
173
+ actions: $
174
+ })
175
+ })
176
+ ]
74
177
  })
75
178
  }),
76
- (X.status === "RUNNING" || X.status === "QUEUED") && /* @__PURE__ */ j("div", {
77
- className: "border-2 border-border-default rounded-xl bg-status-info-bg-subtle p-6",
78
- children: [/* @__PURE__ */ A(u, {
79
- progress: X.progress,
179
+ (q.status === "RUNNING" || q.status === "QUEUED") && /* @__PURE__ */ E("div", {
180
+ className: "border border-border-seam rounded-xl bg-status-info-bg-subtle p-6",
181
+ children: [/* @__PURE__ */ T(u, {
182
+ progress: q.progress,
80
183
  size: "lg"
81
- }), X.processedEntities != null && X.totalEntities != null && /* @__PURE__ */ j("p", {
82
- className: "text-sm text-muted-foreground mt-2",
184
+ }), q.processedEntities != null && q.totalEntities != null && /* @__PURE__ */ E("p", {
185
+ className: "text-sm text-text-secondary mt-2",
83
186
  children: [
84
- X.processedEntities.toLocaleString(),
187
+ q.processedEntities.toLocaleString(),
85
188
  " /",
86
189
  " ",
87
- X.totalEntities.toLocaleString(),
190
+ q.totalEntities.toLocaleString(),
88
191
  " entities processed"
89
192
  ]
90
193
  })]
91
194
  }),
92
- $ && X.errorMessage && /* @__PURE__ */ j("div", {
195
+ oe && q.errorMessage && /* @__PURE__ */ E("div", {
93
196
  className: "border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-6 flex items-start gap-4",
94
- children: [/* @__PURE__ */ A(g, {
197
+ children: [/* @__PURE__ */ T(m, {
95
198
  size: 24,
96
199
  className: "text-status-error-text flex-shrink-0 mt-0.5"
97
- }), /* @__PURE__ */ j("div", { children: [/* @__PURE__ */ A("h3", {
200
+ }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("h3", {
98
201
  className: "font-semibold text-status-error-text mb-1",
99
202
  children: "Export Failed"
100
- }), /* @__PURE__ */ A("p", {
203
+ }), /* @__PURE__ */ T("p", {
101
204
  className: "text-sm text-status-error-text",
102
- children: X.errorMessage
205
+ children: q.errorMessage
103
206
  })] })]
104
207
  }),
105
- /* @__PURE__ */ A("div", {
208
+ /* @__PURE__ */ T("div", {
106
209
  className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4",
107
210
  children: [
108
211
  {
109
- icon: /* @__PURE__ */ A(S, { size: 18 }),
212
+ icon: /* @__PURE__ */ T(b, { size: 18 }),
110
213
  label: "Format",
111
- value: c(X.format)
214
+ value: c(q.format)
112
215
  },
113
216
  {
114
- icon: /* @__PURE__ */ A(C, { size: 18 }),
217
+ icon: /* @__PURE__ */ T(x, { size: 18 }),
115
218
  label: "Archive",
116
- value: s(X.archiveFormat)
219
+ value: s(q.archiveFormat)
117
220
  },
118
221
  {
119
- icon: /* @__PURE__ */ A(b, { size: 18 }),
222
+ icon: /* @__PURE__ */ T(v, { size: 18 }),
120
223
  label: "Total Size",
121
- value: X.totalSizeBytes == null ? "-" : M(X.totalSizeBytes)
224
+ value: q.totalSizeBytes == null ? "-" : k(q.totalSizeBytes)
122
225
  },
123
226
  {
124
- icon: /* @__PURE__ */ A(y, { size: 18 }),
227
+ icon: /* @__PURE__ */ T(_, { size: 18 }),
125
228
  label: "Created",
126
- value: new Date(X.createdAt).toLocaleDateString()
229
+ value: new Date(q.createdAt).toLocaleDateString()
127
230
  }
128
- ].map((e) => /* @__PURE__ */ j("div", {
129
- className: "border-2 border-border/50 rounded-xl p-4 bg-gradient-to-br from-card/50 to-background",
130
- children: [/* @__PURE__ */ j("div", {
131
- className: "flex items-center gap-2 text-muted-foreground mb-1",
132
- children: [e.icon, /* @__PURE__ */ A("span", {
231
+ ].map((e) => /* @__PURE__ */ E(O, {
232
+ treatment: "metric",
233
+ className: "p-4 border-border-seam",
234
+ children: [/* @__PURE__ */ E("div", {
235
+ className: "flex items-center gap-2 text-text-secondary mb-1",
236
+ children: [e.icon, /* @__PURE__ */ T("span", {
133
237
  className: "text-xs font-medium",
134
238
  children: e.label
135
239
  })]
136
- }), /* @__PURE__ */ A("p", {
137
- className: "font-bold text-lg",
240
+ }), /* @__PURE__ */ T("p", {
241
+ className: "font-bold text-lg tabular-nums",
138
242
  children: e.value
139
243
  })]
140
244
  }, e.label))
141
245
  }),
142
- X.parts.length > 0 && /* @__PURE__ */ A(f, {
246
+ q.parts.length > 0 && /* @__PURE__ */ T(ee, {
143
247
  title: "Export Parts",
144
- description: `${X.parts.length} file(s) generated`,
145
- children: /* @__PURE__ */ A("div", {
248
+ description: `${q.parts.length} file(s) generated`,
249
+ children: /* @__PURE__ */ T("div", {
146
250
  className: "space-y-2",
147
- children: X.parts.map((e) => /* @__PURE__ */ j("div", {
148
- className: o("border-2 border-border/50 rounded-xl p-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3", "hover:border-primary/30 transition-all duration-200"),
149
- children: [/* @__PURE__ */ j("div", {
251
+ children: q.parts.map((e) => /* @__PURE__ */ E("div", {
252
+ className: o("border border-border-seam rounded-xl p-4 flex flex-col sm:flex-row sm:items-center sm:justify-between gap-3 bg-bg-surface", "hover:border-primary/40 transition-colors duration-200"),
253
+ children: [/* @__PURE__ */ E("div", {
150
254
  className: "flex items-center gap-3 min-w-0",
151
- children: [/* @__PURE__ */ A(x, {
255
+ children: [/* @__PURE__ */ T(y, {
152
256
  size: 20,
153
257
  className: "text-primary flex-shrink-0"
154
- }), /* @__PURE__ */ j("div", {
258
+ }), /* @__PURE__ */ E("div", {
155
259
  className: "min-w-0",
156
- children: [/* @__PURE__ */ A("p", {
260
+ children: [/* @__PURE__ */ T("p", {
157
261
  className: "font-medium truncate",
158
262
  children: e.fileName
159
- }), /* @__PURE__ */ j("p", {
160
- className: "text-sm text-muted-foreground",
263
+ }), /* @__PURE__ */ E("p", {
264
+ className: "text-sm text-text-secondary",
161
265
  children: [
162
266
  e.entityTypes.join(", "),
163
267
  " ·",
164
268
  " ",
165
- M(e.sizeBytes),
269
+ k(e.sizeBytes),
166
270
  e.downloadExpiresAt && ` · expires ${new Date(e.downloadExpiresAt).toLocaleDateString()}`
167
271
  ]
168
272
  })]
169
273
  })]
170
- }), /* @__PURE__ */ A("div", {
274
+ }), /* @__PURE__ */ T("div", {
171
275
  className: "flex items-center gap-2 flex-shrink-0",
172
- children: e.downloadUrl ? /* @__PURE__ */ j("a", {
276
+ children: e.downloadUrl ? /* @__PURE__ */ E("a", {
173
277
  href: e.downloadUrl,
174
- className: "inline-flex items-center gap-2 px-3 py-1.5 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors text-sm font-medium",
175
- children: [/* @__PURE__ */ A(b, { size: 14 }), "Download"]
176
- }) : /* @__PURE__ */ j("span", {
177
- className: "inline-flex items-center gap-1.5 text-sm text-muted-foreground",
178
- children: [/* @__PURE__ */ A(y, { size: 14 }), "Pending"]
278
+ className: "inline-flex items-center gap-2 px-3 py-1.5 bg-action-primary-bg text-action-primary-text rounded-lg hover:bg-action-primary-bg/90 transition-colors text-sm font-medium",
279
+ children: [/* @__PURE__ */ T(v, { size: 14 }), "Download"]
280
+ }) : /* @__PURE__ */ E("span", {
281
+ className: "inline-flex items-center gap-1.5 text-sm text-text-secondary",
282
+ children: [/* @__PURE__ */ T(_, { size: 14 }), "Pending"]
179
283
  })
180
284
  })]
181
285
  }, e.id))
182
286
  })
183
287
  }),
184
- Q && X.parts.length === 0 && /* @__PURE__ */ j("div", {
288
+ ae && q.parts.length === 0 && /* @__PURE__ */ E("div", {
185
289
  className: "border-2 border-border-default rounded-xl bg-status-success-bg-subtle p-6 text-center",
186
290
  children: [
187
- /* @__PURE__ */ A(v, {
291
+ /* @__PURE__ */ T(g, {
188
292
  size: 48,
189
293
  className: "text-status-success-text mx-auto mb-3"
190
294
  }),
191
- /* @__PURE__ */ A("h3", {
295
+ /* @__PURE__ */ T("h3", {
192
296
  className: "text-lg font-bold text-status-success-text mb-1",
193
297
  children: "Export Complete"
194
298
  }),
195
- /* @__PURE__ */ A("p", {
299
+ /* @__PURE__ */ T("p", {
196
300
  className: "text-sm text-status-success-text",
197
301
  children: "Your export has completed but no download parts are available yet."
198
302
  })
199
303
  ]
200
304
  }),
201
- /* @__PURE__ */ j("div", {
202
- className: "flex flex-col sm:flex-row gap-3 pt-2",
203
- children: [
204
- Z && /* @__PURE__ */ j("button", {
205
- type: "button",
206
- onClick: async () => {
207
- P && U("cancel");
208
- },
209
- disabled: G,
210
- className: "inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-warning-bg/50 text-status-warning-text rounded-lg hover:bg-status-warning-bg-subtle transition-all duration-200 font-medium disabled:opacity-50",
211
- children: [G ? /* @__PURE__ */ A(w, {
212
- size: 18,
213
- className: "animate-spin"
214
- }) : /* @__PURE__ */ A(D, { size: 18 }), "Cancel Export"]
215
- }),
216
- ee && /* @__PURE__ */ j("button", {
217
- type: "button",
218
- onClick: async () => {
219
- if (!P) return;
220
- let e = await J(P);
221
- e?.id && I?.(N(F, e.id));
222
- },
223
- disabled: Y,
224
- className: "inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-primary/50 text-primary rounded-lg hover:bg-primary/5 transition-all duration-200 font-medium disabled:opacity-50",
225
- children: [Y ? /* @__PURE__ */ A(w, {
226
- size: 18,
227
- className: "animate-spin"
228
- }) : /* @__PURE__ */ A(T, { size: 18 }), "Retry Export"]
229
- }),
230
- !Z && /* @__PURE__ */ j("button", {
231
- type: "button",
232
- onClick: async () => {
233
- P && (p("medium"), U("delete"));
234
- },
235
- disabled: q,
236
- className: "inline-flex items-center justify-center gap-2 px-6 py-3 border-2 border-status-error-bg/50 text-status-error-text rounded-lg hover:bg-status-error-bg-subtle transition-all duration-200 font-medium disabled:opacity-50",
237
- children: [q ? /* @__PURE__ */ A(w, {
238
- size: 18,
239
- className: "animate-spin"
240
- }) : /* @__PURE__ */ A(E, { size: 18 }), "Delete Export"]
241
- })
242
- ]
243
- }),
244
- H && /* @__PURE__ */ A("div", {
305
+ z && /* @__PURE__ */ T("div", {
245
306
  role: "dialog",
246
307
  "aria-modal": "true",
247
308
  "aria-labelledby": "export-confirm-title",
248
- className: "fixed inset-0 z-50 flex items-center justify-center bg-background/80 backdrop-blur-sm p-4",
249
- children: /* @__PURE__ */ j("div", {
250
- className: "w-full max-w-md rounded-xl border-2 border-border bg-card p-6 shadow-xl",
309
+ className: "fixed inset-0 z-50 flex items-center justify-center bg-bg-surface/80 backdrop-blur-sm p-4",
310
+ children: /* @__PURE__ */ E("div", {
311
+ className: "w-full max-w-md rounded-xl border-2 border-border-subtle bg-bg-surface p-6 shadow-xl",
251
312
  children: [
252
- /* @__PURE__ */ A("h2", {
313
+ /* @__PURE__ */ T("h2", {
253
314
  id: "export-confirm-title",
254
315
  className: "text-lg font-bold",
255
- children: H === "cancel" ? "Cancel export?" : "Delete export?"
316
+ children: z === "cancel" ? "Cancel export?" : "Delete export?"
256
317
  }),
257
- /* @__PURE__ */ A("p", {
258
- className: "mt-2 text-sm text-muted-foreground",
259
- children: H === "cancel" ? "This stops the running export job. You can retry it later if needed." : "This removes the export job from history. This action cannot be undone."
318
+ /* @__PURE__ */ T("p", {
319
+ className: "mt-2 text-sm text-text-secondary",
320
+ children: z === "cancel" ? "This stops the running export job. You can retry it later if needed." : "This removes the export job from history. This action cannot be undone."
260
321
  }),
261
- /* @__PURE__ */ j("div", {
322
+ /* @__PURE__ */ E("div", {
262
323
  className: "mt-6 flex flex-col-reverse sm:flex-row sm:justify-end gap-3",
263
- children: [/* @__PURE__ */ A("button", {
324
+ children: [/* @__PURE__ */ T("button", {
264
325
  type: "button",
265
- onClick: () => U(null),
266
- className: "px-4 py-2 rounded-lg border-2 border-border hover:bg-accent transition-colors font-medium",
326
+ onClick: () => B(null),
327
+ className: "px-4 py-2 rounded-lg border-2 border-border-subtle hover:bg-accent transition-colors font-medium",
267
328
  children: "Keep Export"
268
- }), /* @__PURE__ */ j("button", {
329
+ }), /* @__PURE__ */ E("button", {
269
330
  type: "button",
270
- onClick: async () => {
271
- if (!(!P || !H)) {
272
- try {
273
- H === "cancel" ? await W(P) : (await K(P), I?.(F)), m("success");
274
- } catch {
275
- m("error");
276
- }
277
- U(null);
278
- }
279
- },
280
- disabled: G || q,
281
- className: "inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-destructive text-destructive-foreground hover:bg-destructive/90 transition-colors font-medium disabled:opacity-50",
282
- children: [G || q ? /* @__PURE__ */ A(w, {
331
+ onClick: le,
332
+ disabled: H || W,
333
+ className: "inline-flex items-center justify-center gap-2 px-4 py-2 rounded-lg bg-status-error-bg text-status-error-text hover:bg-status-error-bg/90 transition-colors font-medium disabled:opacity-50",
334
+ children: [H || W ? /* @__PURE__ */ T(S, {
283
335
  size: 16,
284
336
  className: "animate-spin"
285
- }) : null, H === "cancel" ? "Cancel Export" : "Delete Export"]
337
+ }) : null, z === "cancel" ? "Cancel Export" : "Delete Export"]
286
338
  })]
287
339
  })
288
340
  ]
289
341
  })
290
342
  })
291
343
  ]
292
- }) : /* @__PURE__ */ j(d, {
293
- showHeader: !1,
294
- children: [/* @__PURE__ */ j("div", {
295
- className: "flex items-center gap-3 mb-6",
296
- children: [/* @__PURE__ */ A("button", {
297
- type: "button",
298
- onClick: R,
299
- className: "p-2.5 hover:bg-accent rounded-lg transition-all duration-200",
300
- children: /* @__PURE__ */ A(_, { size: 20 })
301
- }), /* @__PURE__ */ A("h1", {
302
- className: "text-xl font-bold",
303
- children: "Export Not Found"
304
- })]
305
- }), /* @__PURE__ */ j("div", {
306
- className: "border-2 border-border-default rounded-xl bg-status-error-bg-subtle p-12 text-center",
307
- children: [
308
- /* @__PURE__ */ A(g, {
309
- size: 48,
310
- className: "text-status-error-text mx-auto mb-4"
311
- }),
312
- /* @__PURE__ */ A("h3", {
313
- className: "text-lg font-bold text-status-error-text mb-2",
314
- children: "Export Not Found"
315
- }),
316
- /* @__PURE__ */ A("p", {
317
- className: "text-status-error-text mb-6",
318
- children: "The export job you are looking for does not exist or has been deleted."
319
- }),
320
- /* @__PURE__ */ j("button", {
321
- type: "button",
322
- onClick: R,
323
- className: "inline-flex items-center gap-2 px-6 py-3 bg-primary text-primary-foreground rounded-lg hover:bg-primary/90 transition-colors font-medium",
324
- children: [/* @__PURE__ */ A(_, { size: 18 }), "Back to Dashboard"]
325
- })
326
- ]
327
- })]
328
344
  });
329
345
  }
330
346
  //#endregion
331
- export { P as ExportDetailPage };
347
+ export { j as ExportDetailPage };
332
348
 
333
349
  //# sourceMappingURL=ExportDetailPage.js.map