@burdenoff/microfe-admin 2026.626.1 → 2026.712.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.
@@ -7,7 +7,7 @@ import { jsx as b } from "react/jsx-runtime";
7
7
  import { FeatureFlagProvider as x } from "@burdenoff/fe-libs/shared/feature-flags";
8
8
  //#region src/admin/AdminRoot.tsx
9
9
  var S = (S) => {
10
- let { registerNavItems: C, registerFooterItems: w, basePath: T = "" } = S;
10
+ let { registerNavItems: C, registerFooterItems: w, basePath: T = "", workspaceId: E } = S;
11
11
  return r(() => {
12
12
  if (C) return C([
13
13
  {
@@ -168,7 +168,7 @@ var S = (S) => {
168
168
  section: "left"
169
169
  }]);
170
170
  }, [w]), /* @__PURE__ */ b(x, {
171
- workspaceId: null,
171
+ workspaceId: E || null,
172
172
  gateway: "global",
173
173
  defaultEnabled: !0,
174
174
  children: /* @__PURE__ */ b(e, {
@@ -1 +1 @@
1
- {"version":3,"file":"AdminRoot.js","names":[],"sources":["../../src/admin/AdminRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect } from 'react';\nimport {\n LayoutDashboard,\n Building2,\n Users,\n CreditCard,\n Settings,\n Server,\n Mail,\n FileText,\n Box,\n Building,\n Layout,\n ToggleLeft,\n ShieldCheck,\n GitBranch,\n Link2,\n AlertOctagon,\n} from 'lucide-react';\nimport { AdminProvider } from './providers/AdminProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport type { NavItem, AdminRootProps } from './types';\nimport { AdminRoutes } from './AdminRoutes';\nimport { joinPath } from './utils/navigation';\n\n/**\n * Root component for the Admin microfrontend.\n *\n * This is the main entry point that host applications import and render.\n * It sets up the necessary providers and renders the internal routing.\n * Automatically registers navigation items with the shell if registration functions are provided.\n *\n * @example\n * ```tsx\n * import { AdminRoot, type AdminRootProps } from '@burdenoff/microfe-admin';\n *\n * function App() {\n * const props: AdminRootProps = {\n * basePath: '/admin',\n * navigate: (path) => router.push(path),\n * currentUser: { id: '1', email: 'admin@example.com', role: 'PLATFORM_SUPERADMIN' },\n * tenantId: 'tenant-123',\n * apiGatewayUrl: 'https://api.example.com',\n * authToken: 'token',\n * registerNavItems: (items) => { return () => {}; },\n * };\n *\n * return <AdminRoot {...props} />;\n * }\n * ```\n */\nexport const AdminRoot: FC<AdminRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '' } = props;\n\n // Register navigation items with the shell\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'admin-dashboard',\n label: 'Dashboard',\n path: joinPath(basePath, 'dashboard'),\n icon: <LayoutDashboard size={20} />,\n order: 10,\n group: 'admin',\n },\n {\n id: 'admin-tenants',\n label: 'Tenants',\n path: joinPath(basePath, 'tenants'),\n icon: <Building2 size={20} />,\n order: 20,\n group: 'admin',\n },\n {\n id: 'admin-organizations',\n label: 'Organizations',\n path: joinPath(basePath, 'organizations'),\n icon: <Building size={20} />,\n order: 25,\n group: 'admin',\n },\n {\n id: 'admin-workspaces',\n label: 'Workspaces',\n path: joinPath(basePath, 'workspaces'),\n icon: <Layout size={20} />,\n order: 26,\n group: 'admin',\n },\n {\n id: 'admin-users',\n label: 'Users',\n path: joinPath(basePath, 'users'),\n icon: <Users size={20} />,\n order: 30,\n group: 'admin',\n },\n {\n id: 'admin-roles',\n label: 'Roles & Permissions',\n path: joinPath(basePath, 'roles'),\n icon: <ShieldCheck size={20} />,\n order: 35,\n group: 'admin',\n },\n {\n id: 'admin-billing',\n label: 'Billing',\n path: joinPath(basePath, 'billing'),\n icon: <CreditCard size={20} />,\n order: 40,\n group: 'admin',\n children: [\n {\n id: 'admin-billing-subscriptions',\n label: 'Subscriptions',\n path: joinPath(basePath, 'billing/subscriptions'),\n order: 1,\n },\n {\n id: 'admin-billing-invoices',\n label: 'Invoices',\n path: joinPath(basePath, 'billing/invoices'),\n order: 2,\n },\n {\n id: 'admin-billing-plans',\n label: 'Plans',\n path: joinPath(basePath, 'billing/plans'),\n order: 3,\n },\n ],\n },\n {\n id: 'admin-communications',\n label: 'Communications',\n path: joinPath(basePath, 'communications'),\n icon: <Mail size={20} />,\n order: 50,\n group: 'admin',\n },\n {\n id: 'admin-feature-flags',\n label: 'Feature Flags',\n path: joinPath(basePath, 'feature-flags'),\n icon: <ToggleLeft size={20} />,\n order: 60,\n group: 'admin',\n },\n {\n id: 'admin-workflows',\n label: 'Workflows',\n path: joinPath(basePath, 'workflows'),\n icon: <GitBranch size={20} />,\n order: 70,\n group: 'admin',\n },\n {\n id: 'admin-sre',\n label: 'SRE',\n path: joinPath(basePath, 'sre'),\n icon: <Server size={20} />,\n order: 80,\n group: 'admin',\n },\n {\n id: 'admin-sync-failures',\n label: 'Sync Failures',\n path: joinPath(basePath, 'sync-failures'),\n icon: <AlertOctagon size={20} />,\n order: 82,\n group: 'admin',\n },\n {\n id: 'admin-audit',\n label: 'Audit Logs',\n path: joinPath(basePath, 'audit'),\n icon: <FileText size={20} />,\n order: 85,\n group: 'admin',\n },\n {\n id: 'admin-referrals',\n label: 'Referrals',\n path: joinPath(basePath, 'referrals'),\n icon: <Link2 size={20} />,\n order: 86,\n group: 'admin',\n },\n {\n id: 'admin-sandbox',\n label: 'Sandbox',\n path: joinPath(basePath, 'sandbox'),\n icon: <Box size={20} />,\n order: 87,\n group: 'admin',\n },\n {\n id: 'admin-settings',\n label: 'Settings',\n path: joinPath(basePath, 'settings'),\n icon: <Settings size={20} />,\n order: 90,\n group: 'admin',\n },\n ];\n\n // Register and get cleanup function\n const cleanup = registerNavItems(navItems);\n\n // Return cleanup function to unregister on unmount\n return cleanup;\n }, [registerNavItems, basePath]);\n\n // Register footer items\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'admin-status',\n label: 'Admin Console Ready',\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems]);\n\n return (\n <FeatureFlagProvider workspaceId={null} gateway=\"global\" defaultEnabled={true}>\n <AdminProvider {...props}>\n <AdminRoutes />\n </AdminProvider>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminRoot.js","names":[],"sources":["../../src/admin/AdminRoot.tsx"],"sourcesContent":["import type { FC } from 'react';\nimport { useEffect } from 'react';\nimport {\n LayoutDashboard,\n Building2,\n Users,\n CreditCard,\n Settings,\n Server,\n Mail,\n FileText,\n Box,\n Building,\n Layout,\n ToggleLeft,\n ShieldCheck,\n GitBranch,\n Link2,\n AlertOctagon,\n} from 'lucide-react';\nimport { AdminProvider } from './providers/AdminProvider';\nimport { FeatureFlagProvider } from '@burdenoff/fe-libs/shared/feature-flags';\nimport type { NavItem, AdminRootProps } from './types';\nimport { AdminRoutes } from './AdminRoutes';\nimport { joinPath } from './utils/navigation';\n\n/**\n * Root component for the Admin microfrontend.\n *\n * This is the main entry point that host applications import and render.\n * It sets up the necessary providers and renders the internal routing.\n * Automatically registers navigation items with the shell if registration functions are provided.\n *\n * @example\n * ```tsx\n * import { AdminRoot, type AdminRootProps } from '@burdenoff/microfe-admin';\n *\n * function App() {\n * const props: AdminRootProps = {\n * basePath: '/admin',\n * navigate: (path) => router.push(path),\n * currentUser: { id: '1', email: 'admin@example.com', role: 'PLATFORM_SUPERADMIN' },\n * tenantId: 'tenant-123',\n * apiGatewayUrl: 'https://api.example.com',\n * authToken: 'token',\n * registerNavItems: (items) => { return () => {}; },\n * };\n *\n * return <AdminRoot {...props} />;\n * }\n * ```\n */\nexport const AdminRoot: FC<AdminRootProps> = (props) => {\n const { registerNavItems, registerFooterItems, basePath = '', workspaceId } = props;\n\n // Register navigation items with the shell\n useEffect(() => {\n if (!registerNavItems) return;\n\n const navItems: NavItem[] = [\n {\n id: 'admin-dashboard',\n label: 'Dashboard',\n path: joinPath(basePath, 'dashboard'),\n icon: <LayoutDashboard size={20} />,\n order: 10,\n group: 'admin',\n },\n {\n id: 'admin-tenants',\n label: 'Tenants',\n path: joinPath(basePath, 'tenants'),\n icon: <Building2 size={20} />,\n order: 20,\n group: 'admin',\n },\n {\n id: 'admin-organizations',\n label: 'Organizations',\n path: joinPath(basePath, 'organizations'),\n icon: <Building size={20} />,\n order: 25,\n group: 'admin',\n },\n {\n id: 'admin-workspaces',\n label: 'Workspaces',\n path: joinPath(basePath, 'workspaces'),\n icon: <Layout size={20} />,\n order: 26,\n group: 'admin',\n },\n {\n id: 'admin-users',\n label: 'Users',\n path: joinPath(basePath, 'users'),\n icon: <Users size={20} />,\n order: 30,\n group: 'admin',\n },\n {\n id: 'admin-roles',\n label: 'Roles & Permissions',\n path: joinPath(basePath, 'roles'),\n icon: <ShieldCheck size={20} />,\n order: 35,\n group: 'admin',\n },\n {\n id: 'admin-billing',\n label: 'Billing',\n path: joinPath(basePath, 'billing'),\n icon: <CreditCard size={20} />,\n order: 40,\n group: 'admin',\n children: [\n {\n id: 'admin-billing-subscriptions',\n label: 'Subscriptions',\n path: joinPath(basePath, 'billing/subscriptions'),\n order: 1,\n },\n {\n id: 'admin-billing-invoices',\n label: 'Invoices',\n path: joinPath(basePath, 'billing/invoices'),\n order: 2,\n },\n {\n id: 'admin-billing-plans',\n label: 'Plans',\n path: joinPath(basePath, 'billing/plans'),\n order: 3,\n },\n ],\n },\n {\n id: 'admin-communications',\n label: 'Communications',\n path: joinPath(basePath, 'communications'),\n icon: <Mail size={20} />,\n order: 50,\n group: 'admin',\n },\n {\n id: 'admin-feature-flags',\n label: 'Feature Flags',\n path: joinPath(basePath, 'feature-flags'),\n icon: <ToggleLeft size={20} />,\n order: 60,\n group: 'admin',\n },\n {\n id: 'admin-workflows',\n label: 'Workflows',\n path: joinPath(basePath, 'workflows'),\n icon: <GitBranch size={20} />,\n order: 70,\n group: 'admin',\n },\n {\n id: 'admin-sre',\n label: 'SRE',\n path: joinPath(basePath, 'sre'),\n icon: <Server size={20} />,\n order: 80,\n group: 'admin',\n },\n {\n id: 'admin-sync-failures',\n label: 'Sync Failures',\n path: joinPath(basePath, 'sync-failures'),\n icon: <AlertOctagon size={20} />,\n order: 82,\n group: 'admin',\n },\n {\n id: 'admin-audit',\n label: 'Audit Logs',\n path: joinPath(basePath, 'audit'),\n icon: <FileText size={20} />,\n order: 85,\n group: 'admin',\n },\n {\n id: 'admin-referrals',\n label: 'Referrals',\n path: joinPath(basePath, 'referrals'),\n icon: <Link2 size={20} />,\n order: 86,\n group: 'admin',\n },\n {\n id: 'admin-sandbox',\n label: 'Sandbox',\n path: joinPath(basePath, 'sandbox'),\n icon: <Box size={20} />,\n order: 87,\n group: 'admin',\n },\n {\n id: 'admin-settings',\n label: 'Settings',\n path: joinPath(basePath, 'settings'),\n icon: <Settings size={20} />,\n order: 90,\n group: 'admin',\n },\n ];\n\n // Register and get cleanup function\n const cleanup = registerNavItems(navItems);\n\n // Return cleanup function to unregister on unmount\n return cleanup;\n }, [registerNavItems, basePath]);\n\n // Register footer items\n useEffect(() => {\n if (!registerFooterItems) return;\n\n const footerItems = [\n {\n id: 'admin-status',\n label: 'Admin Console Ready',\n type: 'status' as const,\n order: 10,\n section: 'left' as const,\n },\n ];\n\n const cleanup = registerFooterItems(footerItems);\n return cleanup;\n }, [registerFooterItems]);\n\n return (\n <FeatureFlagProvider workspaceId={workspaceId || null} gateway=\"global\" defaultEnabled={true}>\n <AdminProvider {...props}>\n <AdminRoutes />\n </AdminProvider>\n </FeatureFlagProvider>\n );\n};\n"],"mappings":"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"}
@@ -1,144 +1,196 @@
1
1
  import { useAdmin as e } from "./providers/AdminProvider.js";
2
- import { DashboardPage as t } from "./pages/DashboardPage.js";
2
+ import { tWithFallback as t } from "./utils/i18n.js";
3
+ import { DashboardPage as n } from "./pages/DashboardPage.js";
4
+ import { TENANT_FEATURE_FLAGS as r } from "./constants/featureFlags.js";
3
5
  import "./pages/index.js";
4
- import { Suspense as n, lazy as r } from "react";
5
- import { Navigate as i, Route as a, Routes as o } from "react-router-dom";
6
- import { jsx as s, jsxs as c } from "react/jsx-runtime";
6
+ import { Suspense as i, lazy as a } from "react";
7
+ import { Navigate as o, Route as s, Routes as c } from "react-router-dom";
8
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
9
+ import { FeatureGate as d } from "@burdenoff/fe-libs/shared/feature-flags";
10
+ import { useI18n as f } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
7
11
  //#region src/admin/AdminRoutes.tsx
8
- var l = r(() => import("./pages/TenantsListPage.js").then((e) => ({ default: e.TenantsListPage }))), u = r(() => import("./pages/TenantDetailPage.js").then((e) => ({ default: e.TenantDetailPage }))), d = r(() => import("./pages/TenantFormRoutePage.js").then((e) => ({ default: e.TenantFormRoutePage }))), f = r(() => import("./pages/UsersListPage.js").then((e) => ({ default: e.UsersListPage }))), p = r(() => import("./pages/BillingPage.js").then((e) => ({ default: e.BillingPage }))), m = r(() => import("./pages/SettingsPage.js").then((e) => ({ default: e.SettingsPage }))), h = r(() => import("./pages/CommunicationsPage.js").then((e) => ({ default: e.CommunicationsPage }))), g = r(() => import("./pages/SREPage.js").then((e) => ({ default: e.SREPage }))), _ = r(() => import("./pages/SyncFailuresPage.js").then((e) => ({ default: e.SyncFailuresPage }))), v = r(() => import("./pages/AuditLogsPage.js").then((e) => ({ default: e.AuditLogsPage }))), y = r(() => import("./pages/SandboxSettingsPage.js").then((e) => ({ default: e.SandboxSettingsPage }))), b = r(() => import("./pages/OrganizationsListPage.js").then((e) => ({ default: e.OrganizationsListPage }))), x = r(() => import("./pages/WorkspacesListPage.js").then((e) => ({ default: e.WorkspacesListPage }))), S = r(() => import("./pages/FeatureFlagsPage.js").then((e) => ({ default: e.FeatureFlagsPage }))), C = r(() => import("./pages/RolesPermissionsPage.js").then((e) => ({ default: e.RolesPermissionsPage }))), w = r(() => import("./pages/WorkflowsPage.js").then((e) => ({ default: e.WorkflowsPage }))), T = r(() => import("./pages/ProductsPage.js").then((e) => ({ default: e.ProductsPage }))), E = r(() => import("./pages/ContentPagesPage.js").then((e) => ({ default: e.ContentPagesPage }))), D = r(() => import("./pages/WaitlistPage.js").then((e) => ({ default: e.WaitlistPage }))), O = r(() => import("./pages/ReferralsPage.js").then((e) => ({ default: e.ReferralsPage })));
9
- function k() {
10
- return /* @__PURE__ */ s("div", {
12
+ var p = a(() => import("./pages/TenantsListPage.js").then((e) => ({ default: e.TenantsListPage }))), m = a(() => import("./pages/TenantDetailPage.js").then((e) => ({ default: e.TenantDetailPage }))), h = a(() => import("./pages/TenantFormRoutePage.js").then((e) => ({ default: e.TenantFormRoutePage }))), g = a(() => import("./pages/UsersListPage.js").then((e) => ({ default: e.UsersListPage }))), _ = a(() => import("./pages/BillingPage.js").then((e) => ({ default: e.BillingPage }))), v = a(() => import("./pages/SettingsPage.js").then((e) => ({ default: e.SettingsPage }))), y = a(() => import("./pages/CommunicationsPage.js").then((e) => ({ default: e.CommunicationsPage }))), b = a(() => import("./pages/SREPage.js").then((e) => ({ default: e.SREPage }))), x = a(() => import("./pages/SyncFailuresPage.js").then((e) => ({ default: e.SyncFailuresPage }))), S = a(() => import("./pages/AuditLogsPage.js").then((e) => ({ default: e.AuditLogsPage }))), C = a(() => import("./pages/SandboxSettingsPage.js").then((e) => ({ default: e.SandboxSettingsPage }))), w = a(() => import("./pages/OrganizationsListPage.js").then((e) => ({ default: e.OrganizationsListPage }))), T = a(() => import("./pages/WorkspacesListPage.js").then((e) => ({ default: e.WorkspacesListPage }))), E = a(() => import("./pages/FeatureFlagsPage.js").then((e) => ({ default: e.FeatureFlagsPage }))), D = a(() => import("./pages/RolesPermissionsPage.js").then((e) => ({ default: e.RolesPermissionsPage }))), O = a(() => import("./pages/WorkflowsPage.js").then((e) => ({ default: e.WorkflowsPage }))), k = a(() => import("./pages/ProductsPage.js").then((e) => ({ default: e.ProductsPage }))), A = a(() => import("./pages/ContentPagesPage.js").then((e) => ({ default: e.ContentPagesPage }))), j = a(() => import("./pages/WaitlistPage.js").then((e) => ({ default: e.WaitlistPage }))), M = a(() => import("./pages/ReferralsPage.js").then((e) => ({ default: e.ReferralsPage })));
13
+ function N() {
14
+ return /* @__PURE__ */ l("div", {
11
15
  className: "flex h-64 items-center justify-center",
12
- children: /* @__PURE__ */ s("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" })
16
+ children: /* @__PURE__ */ l("div", { className: "h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent" })
13
17
  });
14
18
  }
15
- function A() {
16
- let { basePath: r } = e(), A = r || "/admin";
17
- return /* @__PURE__ */ s(n, {
18
- fallback: /* @__PURE__ */ s(k, {}),
19
- children: /* @__PURE__ */ c(o, { children: [
20
- /* @__PURE__ */ s(a, {
19
+ function P() {
20
+ let { t: e } = f();
21
+ return /* @__PURE__ */ l("div", {
22
+ className: "flex min-h-[400px] items-center justify-center p-8 text-center",
23
+ children: /* @__PURE__ */ u("div", { children: [/* @__PURE__ */ l("h2", {
24
+ className: "mb-2 text-lg font-semibold text-foreground",
25
+ children: t(e, "admin.routes.tenantFeatureDisabledTitle", "Tenant management unavailable")
26
+ }), /* @__PURE__ */ l("p", {
27
+ className: "text-sm text-muted-foreground",
28
+ children: t(e, "admin.routes.tenantFeatureDisabled", "This feature is currently disabled.")
29
+ })] })
30
+ });
31
+ }
32
+ function F(e, t, n) {
33
+ return /* @__PURE__ */ l(d, {
34
+ flag: e,
35
+ defaultValue: n,
36
+ fallback: /* @__PURE__ */ l(P, {}),
37
+ children: t
38
+ });
39
+ }
40
+ function I(e, t) {
41
+ return e.reduceRight((e, t) => F(t.flag, e, t.defaultValue), t);
42
+ }
43
+ function L() {
44
+ let { basePath: t } = e(), a = t || "/admin";
45
+ return /* @__PURE__ */ l(i, {
46
+ fallback: /* @__PURE__ */ l(N, {}),
47
+ children: /* @__PURE__ */ u(c, { children: [
48
+ /* @__PURE__ */ l(s, {
21
49
  index: !0,
22
- element: /* @__PURE__ */ s(i, {
23
- to: `${A}/dashboard`,
50
+ element: /* @__PURE__ */ l(o, {
51
+ to: `${a}/dashboard`,
24
52
  replace: !0
25
53
  })
26
54
  }),
27
- /* @__PURE__ */ s(a, {
55
+ /* @__PURE__ */ l(s, {
28
56
  path: "dashboard",
29
- element: /* @__PURE__ */ s(t, {})
57
+ element: /* @__PURE__ */ l(n, {})
30
58
  }),
31
- /* @__PURE__ */ s(a, {
59
+ /* @__PURE__ */ l(s, {
32
60
  path: "tenants",
33
- element: /* @__PURE__ */ s(l, {})
34
- }),
35
- /* @__PURE__ */ s(a, {
61
+ element: I([{
62
+ flag: r.management,
63
+ defaultValue: !0
64
+ }, {
65
+ flag: r.list,
66
+ defaultValue: !0
67
+ }], /* @__PURE__ */ l(p, {}))
68
+ }),
69
+ /* @__PURE__ */ l(s, {
36
70
  path: "tenants/new",
37
- element: /* @__PURE__ */ s(d, { mode: "create" })
38
- }),
39
- /* @__PURE__ */ s(a, {
71
+ element: I([{
72
+ flag: r.management,
73
+ defaultValue: !0
74
+ }, {
75
+ flag: r.create,
76
+ defaultValue: !0
77
+ }], /* @__PURE__ */ l(h, { mode: "create" }))
78
+ }),
79
+ /* @__PURE__ */ l(s, {
40
80
  path: "tenants/:tenantId",
41
- element: /* @__PURE__ */ s(u, {})
42
- }),
43
- /* @__PURE__ */ s(a, {
81
+ element: I([{
82
+ flag: r.management,
83
+ defaultValue: !0
84
+ }, {
85
+ flag: r.detail,
86
+ defaultValue: !0
87
+ }], /* @__PURE__ */ l(m, {}))
88
+ }),
89
+ /* @__PURE__ */ l(s, {
44
90
  path: "tenants/:tenantId/edit",
45
- element: /* @__PURE__ */ s(d, { mode: "edit" })
46
- }),
47
- /* @__PURE__ */ s(a, {
91
+ element: I([{
92
+ flag: r.management,
93
+ defaultValue: !0
94
+ }, {
95
+ flag: r.edit,
96
+ defaultValue: !0
97
+ }], /* @__PURE__ */ l(h, { mode: "edit" }))
98
+ }),
99
+ /* @__PURE__ */ l(s, {
48
100
  path: "organizations",
49
- element: /* @__PURE__ */ s(b, {})
101
+ element: /* @__PURE__ */ l(w, {})
50
102
  }),
51
- /* @__PURE__ */ s(a, {
103
+ /* @__PURE__ */ l(s, {
52
104
  path: "workspaces",
53
- element: /* @__PURE__ */ s(x, {})
105
+ element: /* @__PURE__ */ l(T, {})
54
106
  }),
55
- /* @__PURE__ */ s(a, {
107
+ /* @__PURE__ */ l(s, {
56
108
  path: "users",
57
- element: /* @__PURE__ */ s(f, {})
109
+ element: /* @__PURE__ */ l(g, {})
58
110
  }),
59
- /* @__PURE__ */ s(a, {
111
+ /* @__PURE__ */ l(s, {
60
112
  path: "users/:userId",
61
- element: /* @__PURE__ */ s(f, {})
113
+ element: /* @__PURE__ */ l(g, {})
62
114
  }),
63
- /* @__PURE__ */ s(a, {
115
+ /* @__PURE__ */ l(s, {
64
116
  path: "roles",
65
- element: /* @__PURE__ */ s(C, {})
117
+ element: /* @__PURE__ */ l(D, {})
66
118
  }),
67
- /* @__PURE__ */ s(a, {
119
+ /* @__PURE__ */ l(s, {
68
120
  path: "feature-flags",
69
- element: /* @__PURE__ */ s(S, {})
121
+ element: /* @__PURE__ */ l(E, {})
70
122
  }),
71
- /* @__PURE__ */ s(a, {
123
+ /* @__PURE__ */ l(s, {
72
124
  path: "workflows",
73
- element: /* @__PURE__ */ s(w, {})
125
+ element: /* @__PURE__ */ l(O, {})
74
126
  }),
75
- /* @__PURE__ */ s(a, {
127
+ /* @__PURE__ */ l(s, {
76
128
  path: "billing",
77
- element: /* @__PURE__ */ s(p, {})
129
+ element: /* @__PURE__ */ l(_, {})
78
130
  }),
79
- /* @__PURE__ */ s(a, {
131
+ /* @__PURE__ */ l(s, {
80
132
  path: "billing/subscriptions",
81
- element: /* @__PURE__ */ s(p, {})
133
+ element: /* @__PURE__ */ l(_, {})
82
134
  }),
83
- /* @__PURE__ */ s(a, {
135
+ /* @__PURE__ */ l(s, {
84
136
  path: "billing/invoices",
85
- element: /* @__PURE__ */ s(p, {})
137
+ element: /* @__PURE__ */ l(_, {})
86
138
  }),
87
- /* @__PURE__ */ s(a, {
139
+ /* @__PURE__ */ l(s, {
88
140
  path: "billing/plans",
89
- element: /* @__PURE__ */ s(p, {})
141
+ element: /* @__PURE__ */ l(_, {})
90
142
  }),
91
- /* @__PURE__ */ s(a, {
143
+ /* @__PURE__ */ l(s, {
92
144
  path: "support/*",
93
- element: /* @__PURE__ */ s(i, {
145
+ element: /* @__PURE__ */ l(o, {
94
146
  to: "/support",
95
147
  replace: !0
96
148
  })
97
149
  }),
98
- /* @__PURE__ */ s(a, {
150
+ /* @__PURE__ */ l(s, {
99
151
  path: "communications",
100
- element: /* @__PURE__ */ s(h, {})
152
+ element: /* @__PURE__ */ l(y, {})
101
153
  }),
102
- /* @__PURE__ */ s(a, {
154
+ /* @__PURE__ */ l(s, {
103
155
  path: "sre",
104
- element: /* @__PURE__ */ s(g, {})
156
+ element: /* @__PURE__ */ l(b, {})
105
157
  }),
106
- /* @__PURE__ */ s(a, {
158
+ /* @__PURE__ */ l(s, {
107
159
  path: "sync-failures",
108
- element: /* @__PURE__ */ s(_, {})
160
+ element: /* @__PURE__ */ l(x, {})
109
161
  }),
110
- /* @__PURE__ */ s(a, {
162
+ /* @__PURE__ */ l(s, {
111
163
  path: "audit",
112
- element: /* @__PURE__ */ s(v, {})
164
+ element: /* @__PURE__ */ l(S, {})
113
165
  }),
114
- /* @__PURE__ */ s(a, {
166
+ /* @__PURE__ */ l(s, {
115
167
  path: "referrals",
116
- element: /* @__PURE__ */ s(O, {})
168
+ element: /* @__PURE__ */ l(M, {})
117
169
  }),
118
- /* @__PURE__ */ s(a, {
170
+ /* @__PURE__ */ l(s, {
119
171
  path: "sandbox",
120
- element: /* @__PURE__ */ s(y, {})
172
+ element: /* @__PURE__ */ l(C, {})
121
173
  }),
122
- /* @__PURE__ */ s(a, {
174
+ /* @__PURE__ */ l(s, {
123
175
  path: "products",
124
- element: /* @__PURE__ */ s(T, {})
176
+ element: /* @__PURE__ */ l(k, {})
125
177
  }),
126
- /* @__PURE__ */ s(a, {
178
+ /* @__PURE__ */ l(s, {
127
179
  path: "content",
128
- element: /* @__PURE__ */ s(E, {})
180
+ element: /* @__PURE__ */ l(A, {})
129
181
  }),
130
- /* @__PURE__ */ s(a, {
182
+ /* @__PURE__ */ l(s, {
131
183
  path: "waitlist",
132
- element: /* @__PURE__ */ s(D, {})
184
+ element: /* @__PURE__ */ l(j, {})
133
185
  }),
134
- /* @__PURE__ */ s(a, {
186
+ /* @__PURE__ */ l(s, {
135
187
  path: "settings",
136
- element: /* @__PURE__ */ s(m, {})
188
+ element: /* @__PURE__ */ l(v, {})
137
189
  }),
138
- /* @__PURE__ */ s(a, {
190
+ /* @__PURE__ */ l(s, {
139
191
  path: "*",
140
- element: /* @__PURE__ */ s(i, {
141
- to: `${A}/dashboard`,
192
+ element: /* @__PURE__ */ l(o, {
193
+ to: `${a}/dashboard`,
142
194
  replace: !0
143
195
  })
144
196
  })
@@ -146,6 +198,6 @@ function A() {
146
198
  });
147
199
  }
148
200
  //#endregion
149
- export { A as AdminRoutes };
201
+ export { L as AdminRoutes };
150
202
 
151
203
  //# sourceMappingURL=AdminRoutes.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminRoutes.js","names":[],"sources":["../../src/admin/AdminRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport { Navigate, Route, Routes } from 'react-router-dom';\nimport { DashboardPage } from './pages';\nimport { useAdmin } from './providers/AdminProvider';\n\n// Lazy loaded pages\nconst TenantsListPage = lazy(() =>\n import('./pages/TenantsListPage').then((m) => ({ default: m.TenantsListPage }))\n);\nconst TenantDetailPage = lazy(() =>\n import('./pages/TenantDetailPage').then((m) => ({ default: m.TenantDetailPage }))\n);\nconst TenantFormRoutePage = lazy(() =>\n import('./pages/TenantFormRoutePage').then((m) => ({ default: m.TenantFormRoutePage }))\n);\nconst UsersListPage = lazy(() =>\n import('./pages/UsersListPage').then((m) => ({ default: m.UsersListPage }))\n);\nconst BillingPage = lazy(() =>\n import('./pages/BillingPage').then((m) => ({ default: m.BillingPage }))\n);\nconst SettingsPage = lazy(() =>\n import('./pages/SettingsPage').then((m) => ({ default: m.SettingsPage }))\n);\nconst CommunicationsPage = lazy(() =>\n import('./pages/CommunicationsPage').then((m) => ({ default: m.CommunicationsPage }))\n);\nconst SREPage = lazy(() => import('./pages/SREPage').then((m) => ({ default: m.SREPage })));\nconst SyncFailuresPage = lazy(() =>\n import('./pages/SyncFailuresPage').then((m) => ({ default: m.SyncFailuresPage }))\n);\nconst AuditLogsPage = lazy(() =>\n import('./pages/AuditLogsPage').then((m) => ({ default: m.AuditLogsPage }))\n);\nconst SandboxSettingsPage = lazy(() =>\n import('./pages/SandboxSettingsPage').then((m) => ({ default: m.SandboxSettingsPage }))\n);\nconst OrganizationsListPage = lazy(() =>\n import('./pages/OrganizationsListPage').then((m) => ({ default: m.OrganizationsListPage }))\n);\nconst WorkspacesListPage = lazy(() =>\n import('./pages/WorkspacesListPage').then((m) => ({ default: m.WorkspacesListPage }))\n);\nconst FeatureFlagsPage = lazy(() =>\n import('./pages/FeatureFlagsPage').then((m) => ({ default: m.FeatureFlagsPage }))\n);\nconst RolesPermissionsPage = lazy(() =>\n import('./pages/RolesPermissionsPage').then((m) => ({ default: m.RolesPermissionsPage }))\n);\nconst WorkflowsPage = lazy(() =>\n import('./pages/WorkflowsPage').then((m) => ({ default: m.WorkflowsPage }))\n);\nconst ProductsPage = lazy(() =>\n import('./pages/ProductsPage').then((m) => ({ default: m.ProductsPage }))\n);\nconst ContentPagesPage = lazy(() =>\n import('./pages/ContentPagesPage').then((m) => ({ default: m.ContentPagesPage }))\n);\nconst WaitlistPage = lazy(() =>\n import('./pages/WaitlistPage').then((m) => ({ default: m.WaitlistPage }))\n);\nconst ReferralsPage = lazy(() =>\n import('./pages/ReferralsPage').then((m) => ({ default: m.ReferralsPage }))\n);\n\n// Loading fallback component\nfunction PageLoader() {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent\" />\n </div>\n );\n}\n\n/**\n * Internal router for the Admin microfrontend.\n * This component handles routing within the microfrontend using React Router v7.\n *\n * Routes:\n * - / → Dashboard (redirect)\n * - /dashboard → Dashboard\n * - /tenants → Tenants list\n * - /tenants/new → Create new tenant\n * - /tenants/:tenantId → Tenant detail\n * - /tenants/:tenantId/edit → Edit tenant\n * - /users → Users list\n * - /users/:userId → User detail\n * - /billing → Billing overview\n * - /billing/subscriptions → Subscriptions list\n * - /billing/invoices → Invoices list\n * - /billing/plans → Plans management\n * - /support → Support overview\n * - /support/tickets → Tickets list\n * - /support/tickets/:ticketId → Ticket detail\n * - /products → Products management\n * - /communications → Communications center\n * - /sre → SRE Monitoring\n * - /audit → Audit logs\n * - /sandbox → Sandbox settings\n * - /settings → Settings\n */\nexport function AdminRoutes() {\n const { basePath } = useAdmin();\n const base = basePath || '/admin';\n\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Default redirect to dashboard */}\n <Route index element={<Navigate to={`${base}/dashboard`} replace />} />\n\n {/* Dashboard - eager loaded for fast initial render */}\n <Route path=\"dashboard\" element={<DashboardPage />} />\n\n {/* Tenants */}\n <Route path=\"tenants\" element={<TenantsListPage />} />\n <Route path=\"tenants/new\" element={<TenantFormRoutePage mode=\"create\" />} />\n <Route path=\"tenants/:tenantId\" element={<TenantDetailPage />} />\n <Route path=\"tenants/:tenantId/edit\" element={<TenantFormRoutePage mode=\"edit\" />} />\n\n {/* Organizations */}\n <Route path=\"organizations\" element={<OrganizationsListPage />} />\n\n {/* Workspaces */}\n <Route path=\"workspaces\" element={<WorkspacesListPage />} />\n\n {/* Users */}\n <Route path=\"users\" element={<UsersListPage />} />\n <Route path=\"users/:userId\" element={<UsersListPage />} />\n\n {/* Roles & Permissions */}\n <Route path=\"roles\" element={<RolesPermissionsPage />} />\n\n {/* Feature Flags */}\n <Route path=\"feature-flags\" element={<FeatureFlagsPage />} />\n\n {/* Workflows */}\n <Route path=\"workflows\" element={<WorkflowsPage />} />\n\n {/* Billing */}\n <Route path=\"billing\" element={<BillingPage />} />\n <Route path=\"billing/subscriptions\" element={<BillingPage />} />\n <Route path=\"billing/invoices\" element={<BillingPage />} />\n <Route path=\"billing/plans\" element={<BillingPage />} />\n\n {/* Support — redirects to shell-level /support/* route (microfe-support MFE) */}\n <Route path=\"support/*\" element={<Navigate to=\"/support\" replace />} />\n\n {/* Communications */}\n <Route path=\"communications\" element={<CommunicationsPage />} />\n\n {/* SRE Monitoring */}\n <Route path=\"sre\" element={<SREPage />} />\n\n {/* Sync Failures (cross-layer sync outbox) */}\n <Route path=\"sync-failures\" element={<SyncFailuresPage />} />\n\n {/* Audit Logs */}\n <Route path=\"audit\" element={<AuditLogsPage />} />\n\n {/* Referrals */}\n <Route path=\"referrals\" element={<ReferralsPage />} />\n\n {/* Sandbox */}\n <Route path=\"sandbox\" element={<SandboxSettingsPage />} />\n\n {/* Products */}\n <Route path=\"products\" element={<ProductsPage />} />\n\n {/* Content (blog / case studies / changelog) */}\n <Route path=\"content\" element={<ContentPagesPage />} />\n\n {/* Waitlist */}\n <Route path=\"waitlist\" element={<WaitlistPage />} />\n\n {/* Settings */}\n <Route path=\"settings\" element={<SettingsPage />} />\n\n {/* Catch-all route - redirect to dashboard (absolute path to prevent infinite loops) */}\n <Route path=\"*\" element={<Navigate to={`${base}/dashboard`} replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"AdminRoutes.js","names":[],"sources":["../../src/admin/AdminRoutes.tsx"],"sourcesContent":["import { lazy, Suspense } from 'react';\nimport type { ReactElement, ReactNode } from 'react';\nimport { Navigate, Route, Routes } from 'react-router-dom';\nimport { FeatureGate } from '@burdenoff/fe-libs/shared/feature-flags';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { DashboardPage } from './pages';\nimport { useAdmin } from './providers/AdminProvider';\nimport { TENANT_FEATURE_FLAGS } from './constants/featureFlags';\nimport { tWithFallback } from './utils/i18n';\n\n// Lazy loaded pages\nconst TenantsListPage = lazy(() =>\n import('./pages/TenantsListPage').then((m) => ({ default: m.TenantsListPage }))\n);\nconst TenantDetailPage = lazy(() =>\n import('./pages/TenantDetailPage').then((m) => ({ default: m.TenantDetailPage }))\n);\nconst TenantFormRoutePage = lazy(() =>\n import('./pages/TenantFormRoutePage').then((m) => ({ default: m.TenantFormRoutePage }))\n);\nconst UsersListPage = lazy(() =>\n import('./pages/UsersListPage').then((m) => ({ default: m.UsersListPage }))\n);\nconst BillingPage = lazy(() =>\n import('./pages/BillingPage').then((m) => ({ default: m.BillingPage }))\n);\nconst SettingsPage = lazy(() =>\n import('./pages/SettingsPage').then((m) => ({ default: m.SettingsPage }))\n);\nconst CommunicationsPage = lazy(() =>\n import('./pages/CommunicationsPage').then((m) => ({ default: m.CommunicationsPage }))\n);\nconst SREPage = lazy(() => import('./pages/SREPage').then((m) => ({ default: m.SREPage })));\nconst SyncFailuresPage = lazy(() =>\n import('./pages/SyncFailuresPage').then((m) => ({ default: m.SyncFailuresPage }))\n);\nconst AuditLogsPage = lazy(() =>\n import('./pages/AuditLogsPage').then((m) => ({ default: m.AuditLogsPage }))\n);\nconst SandboxSettingsPage = lazy(() =>\n import('./pages/SandboxSettingsPage').then((m) => ({ default: m.SandboxSettingsPage }))\n);\nconst OrganizationsListPage = lazy(() =>\n import('./pages/OrganizationsListPage').then((m) => ({ default: m.OrganizationsListPage }))\n);\nconst WorkspacesListPage = lazy(() =>\n import('./pages/WorkspacesListPage').then((m) => ({ default: m.WorkspacesListPage }))\n);\nconst FeatureFlagsPage = lazy(() =>\n import('./pages/FeatureFlagsPage').then((m) => ({ default: m.FeatureFlagsPage }))\n);\nconst RolesPermissionsPage = lazy(() =>\n import('./pages/RolesPermissionsPage').then((m) => ({ default: m.RolesPermissionsPage }))\n);\nconst WorkflowsPage = lazy(() =>\n import('./pages/WorkflowsPage').then((m) => ({ default: m.WorkflowsPage }))\n);\nconst ProductsPage = lazy(() =>\n import('./pages/ProductsPage').then((m) => ({ default: m.ProductsPage }))\n);\nconst ContentPagesPage = lazy(() =>\n import('./pages/ContentPagesPage').then((m) => ({ default: m.ContentPagesPage }))\n);\nconst WaitlistPage = lazy(() =>\n import('./pages/WaitlistPage').then((m) => ({ default: m.WaitlistPage }))\n);\nconst ReferralsPage = lazy(() =>\n import('./pages/ReferralsPage').then((m) => ({ default: m.ReferralsPage }))\n);\n\n// Loading fallback component\nfunction PageLoader() {\n return (\n <div className=\"flex h-64 items-center justify-center\">\n <div className=\"h-8 w-8 animate-spin rounded-full border-4 border-primary border-t-transparent\" />\n </div>\n );\n}\n\nfunction FeatureDisabledFallback() {\n const { t } = useI18n();\n\n return (\n <div className=\"flex min-h-[400px] items-center justify-center p-8 text-center\">\n <div>\n <h2 className=\"mb-2 text-lg font-semibold text-foreground\">\n {tWithFallback(\n t,\n 'admin.routes.tenantFeatureDisabledTitle',\n 'Tenant management unavailable'\n )}\n </h2>\n <p className=\"text-sm text-muted-foreground\">\n {tWithFallback(\n t,\n 'admin.routes.tenantFeatureDisabled',\n 'This feature is currently disabled.'\n )}\n </p>\n </div>\n </div>\n );\n}\n\nfunction gated(flag: string, element: ReactNode, defaultValue: boolean): ReactElement {\n return (\n <FeatureGate flag={flag} defaultValue={defaultValue} fallback={<FeatureDisabledFallback />}>\n {element}\n </FeatureGate>\n );\n}\n\nfunction gatedAll(\n gates: Array<{ flag: string; defaultValue: boolean }>,\n element: ReactElement\n): ReactElement {\n return gates.reduceRight((child, gate) => gated(gate.flag, child, gate.defaultValue), element);\n}\n\n/**\n * Internal router for the Admin microfrontend.\n * This component handles routing within the microfrontend using React Router v7.\n *\n * Routes:\n * - / → Dashboard (redirect)\n * - /dashboard → Dashboard\n * - /tenants → Tenants list\n * - /tenants/new → Create new tenant\n * - /tenants/:tenantId → Tenant detail\n * - /tenants/:tenantId/edit → Edit tenant\n * - /users → Users list\n * - /users/:userId → User detail\n * - /billing → Billing overview\n * - /billing/subscriptions → Subscriptions list\n * - /billing/invoices → Invoices list\n * - /billing/plans → Plans management\n * - /support → Support overview\n * - /support/tickets → Tickets list\n * - /support/tickets/:ticketId → Ticket detail\n * - /products → Products management\n * - /communications → Communications center\n * - /sre → SRE Monitoring\n * - /audit → Audit logs\n * - /sandbox → Sandbox settings\n * - /settings → Settings\n */\nexport function AdminRoutes() {\n const { basePath } = useAdmin();\n const base = basePath || '/admin';\n\n return (\n <Suspense fallback={<PageLoader />}>\n <Routes>\n {/* Default redirect to dashboard */}\n <Route index element={<Navigate to={`${base}/dashboard`} replace />} />\n\n {/* Dashboard - eager loaded for fast initial render */}\n <Route path=\"dashboard\" element={<DashboardPage />} />\n\n {/* Tenants */}\n <Route\n path=\"tenants\"\n element={gatedAll(\n [\n { flag: TENANT_FEATURE_FLAGS.management, defaultValue: true },\n { flag: TENANT_FEATURE_FLAGS.list, defaultValue: true },\n ],\n <TenantsListPage />\n )}\n />\n <Route\n path=\"tenants/new\"\n element={gatedAll(\n [\n { flag: TENANT_FEATURE_FLAGS.management, defaultValue: true },\n { flag: TENANT_FEATURE_FLAGS.create, defaultValue: true },\n ],\n <TenantFormRoutePage mode=\"create\" />\n )}\n />\n <Route\n path=\"tenants/:tenantId\"\n element={gatedAll(\n [\n { flag: TENANT_FEATURE_FLAGS.management, defaultValue: true },\n { flag: TENANT_FEATURE_FLAGS.detail, defaultValue: true },\n ],\n <TenantDetailPage />\n )}\n />\n <Route\n path=\"tenants/:tenantId/edit\"\n element={gatedAll(\n [\n { flag: TENANT_FEATURE_FLAGS.management, defaultValue: true },\n { flag: TENANT_FEATURE_FLAGS.edit, defaultValue: true },\n ],\n <TenantFormRoutePage mode=\"edit\" />\n )}\n />\n\n {/* Organizations */}\n <Route path=\"organizations\" element={<OrganizationsListPage />} />\n\n {/* Workspaces */}\n <Route path=\"workspaces\" element={<WorkspacesListPage />} />\n\n {/* Users */}\n <Route path=\"users\" element={<UsersListPage />} />\n <Route path=\"users/:userId\" element={<UsersListPage />} />\n\n {/* Roles & Permissions */}\n <Route path=\"roles\" element={<RolesPermissionsPage />} />\n\n {/* Feature Flags */}\n <Route path=\"feature-flags\" element={<FeatureFlagsPage />} />\n\n {/* Workflows */}\n <Route path=\"workflows\" element={<WorkflowsPage />} />\n\n {/* Billing */}\n <Route path=\"billing\" element={<BillingPage />} />\n <Route path=\"billing/subscriptions\" element={<BillingPage />} />\n <Route path=\"billing/invoices\" element={<BillingPage />} />\n <Route path=\"billing/plans\" element={<BillingPage />} />\n\n {/* Support — redirects to shell-level /support/* route (microfe-support MFE) */}\n <Route path=\"support/*\" element={<Navigate to=\"/support\" replace />} />\n\n {/* Communications */}\n <Route path=\"communications\" element={<CommunicationsPage />} />\n\n {/* SRE Monitoring */}\n <Route path=\"sre\" element={<SREPage />} />\n\n {/* Sync Failures (cross-layer sync outbox) */}\n <Route path=\"sync-failures\" element={<SyncFailuresPage />} />\n\n {/* Audit Logs */}\n <Route path=\"audit\" element={<AuditLogsPage />} />\n\n {/* Referrals */}\n <Route path=\"referrals\" element={<ReferralsPage />} />\n\n {/* Sandbox */}\n <Route path=\"sandbox\" element={<SandboxSettingsPage />} />\n\n {/* Products */}\n <Route path=\"products\" element={<ProductsPage />} />\n\n {/* Content (blog / case studies / changelog) */}\n <Route path=\"content\" element={<ContentPagesPage />} />\n\n {/* Waitlist */}\n <Route path=\"waitlist\" element={<WaitlistPage />} />\n\n {/* Settings */}\n <Route path=\"settings\" element={<SettingsPage />} />\n\n {/* Catch-all route - redirect to dashboard (absolute path to prevent infinite loops) */}\n <Route path=\"*\" element={<Navigate to={`${base}/dashboard`} replace />} />\n </Routes>\n </Suspense>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ConfirmDialog.js","names":[],"sources":["../../../src/admin/components/ConfirmDialog.tsx"],"sourcesContent":["import { useEffect, useRef, type ReactNode } from 'react';\nimport { AlertTriangle, Loader2 } from 'lucide-react';\nimport { Button } from './ui';\nimport { cn } from '../utils/cn';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ConfirmDialogProps {\n /** Whether the dialog is open */\n open: boolean;\n /** Callback when the dialog should close */\n onClose: () => void;\n /** Callback when confirmed */\n onConfirm: () => void | Promise<void>;\n /** Dialog title */\n title: string;\n /** Dialog description */\n description: ReactNode;\n /** Confirm button text */\n confirmLabel?: string;\n /** Cancel button text */\n cancelLabel?: string;\n /** Variant for styling */\n variant?: 'default' | 'destructive';\n /** Loading state */\n loading?: boolean;\n /** Icon to display */\n icon?: ReactNode;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * ConfirmDialog - Modal dialog for confirming actions\n *\n * Use for destructive actions like deleting, or important state changes.\n */\nexport function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n description,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n variant = 'default',\n loading = false,\n icon,\n}: ConfirmDialogProps) {\n const confirmRef = useRef<HTMLButtonElement>(null);\n\n // Handle escape key\n useEffect(() => {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && open && !loading) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [open, onClose, loading]);\n\n // Focus confirm button when opened\n useEffect(() => {\n if (open) {\n // Small delay to ensure dialog is rendered\n const timer = setTimeout(() => {\n confirmRef.current?.focus();\n }, 50);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n // Prevent body scroll when open\n useEffect(() => {\n if (open) {\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = '';\n }\n return () => {\n document.body.style.overflow = '';\n };\n }, [open]);\n\n if (!open) return null;\n\n const handleConfirm = async () => {\n await onConfirm();\n };\n\n const isDestructive = variant === 'destructive';\n const defaultIcon = isDestructive ? <AlertTriangle className=\"h-6 w-6 text-status-error-text\" /> : null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <div\n className=\"fixed inset-0 bg-overlay transition-opacity\"\n onClick={loading ? undefined : onClose}\n aria-hidden=\"true\"\n />\n\n {/* Dialog */}\n <div\n className={cn(\n 'relative z-10 w-full max-w-md rounded-lg bg-bg-surface p-6 shadow-xl',\n 'animate-in zoom-in-95 fade-in duration-200'\n )}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby=\"confirm-dialog-title\"\n aria-describedby=\"confirm-dialog-description\"\n >\n {/* Icon & Content */}\n <div className=\"flex gap-4\">\n {(icon || defaultIcon) && (\n <div\n className={cn(\n 'flex h-12 w-12 shrink-0 items-center justify-center rounded-full',\n isDestructive ? 'bg-status-error-bg/10' : 'bg-action-primary-bg/10'\n )}\n >\n {icon || defaultIcon}\n </div>\n )}\n <div className=\"flex-1\">\n <h3 id=\"confirm-dialog-title\" className=\"text-lg font-semibold text-text-primary\">\n {title}\n </h3>\n <div id=\"confirm-dialog-description\" className=\"mt-2 text-sm text-text-secondary\">\n {description}\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"mt-6 flex justify-end gap-3\">\n <Button variant=\"outline\" onClick={onClose} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button\n ref={confirmRef}\n variant={isDestructive ? 'destructive' : 'default'}\n onClick={handleConfirm}\n disabled={loading}\n >\n {loading && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />}\n {confirmLabel}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Delete Confirmation Helper\n// ============================================================================\n\nexport interface DeleteConfirmDialogProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void | Promise<void>;\n /** Name of item being deleted */\n itemName: string;\n /** Type of item (e.g., \"tenant\", \"user\") */\n itemType: string;\n loading?: boolean;\n}\n\n/**\n * DeleteConfirmDialog - Pre-configured dialog for delete confirmations\n */\nexport function DeleteConfirmDialog({\n open,\n onClose,\n onConfirm,\n itemName,\n itemType,\n loading,\n}: DeleteConfirmDialogProps) {\n return (\n <ConfirmDialog\n open={open}\n onClose={onClose}\n onConfirm={onConfirm}\n title={`Delete ${itemType}?`}\n description={\n <>\n Are you sure you want to delete <strong className=\"text-text-primary\">{itemName}</strong>?\n This action cannot be undone.\n </>\n }\n confirmLabel=\"Delete\"\n variant=\"destructive\"\n loading={loading}\n />\n );\n}\n"],"mappings":";;;;;;AAyCA,SAAgB,EAAc,EAC5B,SACA,YACA,cACA,UACA,gBACA,kBAAe,WACf,iBAAc,UACd,aAAU,WACV,aAAU,IACV,WACqB;CACrB,IAAM,IAAa,EAA0B,KAAK;AAoClD,KAjCA,QAAgB;EACd,IAAM,KAAgB,MAAqB;AACzC,GAAI,EAAE,QAAQ,YAAY,KAAQ,CAAC,KACjC,GAAS;;AAIb,SADA,SAAS,iBAAiB,WAAW,EAAa,QACrC,SAAS,oBAAoB,WAAW,EAAa;IACjE;EAAC;EAAM;EAAS;EAAQ,CAAC,EAG5B,QAAgB;AACd,MAAI,GAAM;GAER,IAAM,IAAQ,iBAAiB;AAC7B,MAAW,SAAS,OAAO;MAC1B,GAAG;AACN,gBAAa,aAAa,EAAM;;IAEjC,CAAC,EAAK,CAAC,EAGV,SACM,IACF,SAAS,KAAK,MAAM,WAAW,WAE/B,SAAS,KAAK,MAAM,WAAW,UAEpB;AACX,WAAS,KAAK,MAAM,WAAW;KAEhC,CAAC,EAAK,CAAC,EAEN,CAAC,EAAM,QAAO;CAElB,IAAM,IAAgB,YAAY;AAChC,QAAM,GAAW;IAGb,IAAgB,MAAY,eAC5B,IAAc,IAAgB,kBAAC,GAAD,EAAe,WAAU,kCAAmC,CAAA,GAAG;AAEnG,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GACE,WAAU;GACV,SAAS,IAAU,KAAA,IAAY;GAC/B,eAAY;GACZ,CAAA,EAGF,kBAAC,OAAD;GACE,WAAW,EACT,wEACA,6CACD;GACD,MAAK;GACL,cAAW;GACX,mBAAgB;GAChB,oBAAiB;aARnB,CAWE,kBAAC,OAAD;IAAK,WAAU;cAAf,EACI,KAAQ,MACR,kBAAC,OAAD;KACE,WAAW,EACT,oEACA,IAAgB,0BAA0B,0BAC3C;eAEA,KAAQ;KACL,CAAA,EAER,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,IAAG;MAAuB,WAAU;gBACrC;MACE,CAAA,EACL,kBAAC,OAAD;MAAK,IAAG;MAA6B,WAAU;gBAC5C;MACG,CAAA,CACF;OACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAQ,SAAQ;KAAU,SAAS;KAAS,UAAU;eACnD;KACM,CAAA,EACT,kBAAC,GAAD;KACE,KAAK;KACL,SAAS,IAAgB,gBAAgB;KACzC,SAAS;KACT,UAAU;eAJZ,CAMG,KAAW,kBAAC,GAAD,EAAS,WAAU,6BAA8B,CAAA,EAC5D,EACM;OACL;MACF;KACF;;;AAsBV,SAAgB,EAAoB,EAClC,SACA,YACA,cACA,aACA,aACA,cAC2B;AAC3B,QACE,kBAAC,GAAD;EACQ;EACG;EACE;EACX,OAAO,UAAU,EAAS;EAC1B,aACE,kBAAA,GAAA,EAAA,UAAA;GAAE;GACgC,kBAAC,UAAD;IAAQ,WAAU;cAAqB;IAAkB,CAAA;;GAExF,EAAA,CAAA;EAEL,cAAa;EACb,SAAQ;EACC;EACT,CAAA"}
1
+ {"version":3,"file":"ConfirmDialog.js","names":[],"sources":["../../../src/admin/components/ConfirmDialog.tsx"],"sourcesContent":["import { useEffect, useRef, type ReactNode } from 'react';\nimport { AlertTriangle, Loader2 } from 'lucide-react';\nimport { Button } from './ui';\nimport { cn } from '../utils/cn';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ConfirmDialogProps {\n /** Whether the dialog is open */\n open: boolean;\n /** Callback when the dialog should close */\n onClose: () => void;\n /** Callback when confirmed */\n onConfirm: () => void | Promise<void>;\n /** Dialog title */\n title: string;\n /** Dialog description */\n description: ReactNode;\n /** Confirm button text */\n confirmLabel?: string;\n /** Cancel button text */\n cancelLabel?: string;\n /** Variant for styling */\n variant?: 'default' | 'destructive';\n /** Loading state */\n loading?: boolean;\n /** Icon to display */\n icon?: ReactNode;\n}\n\n// ============================================================================\n// Component\n// ============================================================================\n\n/**\n * ConfirmDialog - Modal dialog for confirming actions\n *\n * Use for destructive actions like deleting, or important state changes.\n */\nexport function ConfirmDialog({\n open,\n onClose,\n onConfirm,\n title,\n description,\n confirmLabel = 'Confirm',\n cancelLabel = 'Cancel',\n variant = 'default',\n loading = false,\n icon,\n}: ConfirmDialogProps) {\n const confirmRef = useRef<HTMLButtonElement>(null);\n\n // Handle escape key\n useEffect(() => {\n const handleEscape = (e: KeyboardEvent) => {\n if (e.key === 'Escape' && open && !loading) {\n onClose();\n }\n };\n document.addEventListener('keydown', handleEscape);\n return () => document.removeEventListener('keydown', handleEscape);\n }, [open, onClose, loading]);\n\n // Focus confirm button when opened\n useEffect(() => {\n if (open) {\n // Small delay to ensure dialog is rendered\n const timer = setTimeout(() => {\n confirmRef.current?.focus();\n }, 50);\n return () => clearTimeout(timer);\n }\n }, [open]);\n\n // Prevent body scroll when open\n useEffect(() => {\n if (open) {\n document.body.style.overflow = 'hidden';\n } else {\n document.body.style.overflow = '';\n }\n return () => {\n document.body.style.overflow = '';\n };\n }, [open]);\n\n if (!open) return null;\n\n const handleConfirm = async () => {\n await onConfirm();\n };\n\n const isDestructive = variant === 'destructive';\n const defaultIcon = isDestructive ? (\n <AlertTriangle className=\"h-6 w-6 text-status-error-text\" />\n ) : null;\n\n return (\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\n {/* Backdrop */}\n <div\n className=\"fixed inset-0 bg-overlay transition-opacity\"\n onClick={loading ? undefined : onClose}\n aria-hidden=\"true\"\n />\n\n {/* Dialog */}\n <div\n className={cn(\n 'relative z-10 w-full max-w-md rounded-lg bg-bg-surface p-6 shadow-xl',\n 'animate-in zoom-in-95 fade-in duration-200'\n )}\n role=\"alertdialog\"\n aria-modal=\"true\"\n aria-labelledby=\"confirm-dialog-title\"\n aria-describedby=\"confirm-dialog-description\"\n >\n {/* Icon & Content */}\n <div className=\"flex gap-4\">\n {(icon || defaultIcon) && (\n <div\n className={cn(\n 'flex h-12 w-12 shrink-0 items-center justify-center rounded-full',\n isDestructive ? 'bg-status-error-bg/10' : 'bg-action-primary-bg/10'\n )}\n >\n {icon || defaultIcon}\n </div>\n )}\n <div className=\"flex-1\">\n <h3 id=\"confirm-dialog-title\" className=\"text-lg font-semibold text-text-primary\">\n {title}\n </h3>\n <div id=\"confirm-dialog-description\" className=\"mt-2 text-sm text-text-secondary\">\n {description}\n </div>\n </div>\n </div>\n\n {/* Actions */}\n <div className=\"mt-6 flex justify-end gap-3\">\n <Button variant=\"outline\" onClick={onClose} disabled={loading}>\n {cancelLabel}\n </Button>\n <Button\n ref={confirmRef}\n variant={isDestructive ? 'destructive' : 'default'}\n onClick={handleConfirm}\n disabled={loading}\n >\n {loading && <Loader2 className=\"mr-2 h-4 w-4 animate-spin\" />}\n {confirmLabel}\n </Button>\n </div>\n </div>\n </div>\n );\n}\n\n// ============================================================================\n// Delete Confirmation Helper\n// ============================================================================\n\nexport interface DeleteConfirmDialogProps {\n open: boolean;\n onClose: () => void;\n onConfirm: () => void | Promise<void>;\n /** Name of item being deleted */\n itemName: string;\n /** Type of item (e.g., \"tenant\", \"user\") */\n itemType: string;\n loading?: boolean;\n}\n\n/**\n * DeleteConfirmDialog - Pre-configured dialog for delete confirmations\n */\nexport function DeleteConfirmDialog({\n open,\n onClose,\n onConfirm,\n itemName,\n itemType,\n loading,\n}: DeleteConfirmDialogProps) {\n return (\n <ConfirmDialog\n open={open}\n onClose={onClose}\n onConfirm={onConfirm}\n title={`Delete ${itemType}?`}\n description={\n <>\n Are you sure you want to delete <strong className=\"text-text-primary\">{itemName}</strong>?\n This action cannot be undone.\n </>\n }\n confirmLabel=\"Delete\"\n variant=\"destructive\"\n loading={loading}\n />\n );\n}\n"],"mappings":";;;;;;AAyCA,SAAgB,EAAc,EAC5B,SACA,YACA,cACA,UACA,gBACA,kBAAe,WACf,iBAAc,UACd,aAAU,WACV,aAAU,IACV,WACqB;CACrB,IAAM,IAAa,EAA0B,KAAK;AAoClD,KAjCA,QAAgB;EACd,IAAM,KAAgB,MAAqB;AACzC,GAAI,EAAE,QAAQ,YAAY,KAAQ,CAAC,KACjC,GAAS;;AAIb,SADA,SAAS,iBAAiB,WAAW,EAAa,QACrC,SAAS,oBAAoB,WAAW,EAAa;IACjE;EAAC;EAAM;EAAS;EAAQ,CAAC,EAG5B,QAAgB;AACd,MAAI,GAAM;GAER,IAAM,IAAQ,iBAAiB;AAC7B,MAAW,SAAS,OAAO;MAC1B,GAAG;AACN,gBAAa,aAAa,EAAM;;IAEjC,CAAC,EAAK,CAAC,EAGV,SACM,IACF,SAAS,KAAK,MAAM,WAAW,WAE/B,SAAS,KAAK,MAAM,WAAW,UAEpB;AACX,WAAS,KAAK,MAAM,WAAW;KAEhC,CAAC,EAAK,CAAC,EAEN,CAAC,EAAM,QAAO;CAElB,IAAM,IAAgB,YAAY;AAChC,QAAM,GAAW;IAGb,IAAgB,MAAY,eAC5B,IAAc,IAClB,kBAAC,GAAD,EAAe,WAAU,kCAAmC,CAAA,GAC1D;AAEJ,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf,CAEE,kBAAC,OAAD;GACE,WAAU;GACV,SAAS,IAAU,KAAA,IAAY;GAC/B,eAAY;GACZ,CAAA,EAGF,kBAAC,OAAD;GACE,WAAW,EACT,wEACA,6CACD;GACD,MAAK;GACL,cAAW;GACX,mBAAgB;GAChB,oBAAiB;aARnB,CAWE,kBAAC,OAAD;IAAK,WAAU;cAAf,EACI,KAAQ,MACR,kBAAC,OAAD;KACE,WAAW,EACT,oEACA,IAAgB,0BAA0B,0BAC3C;eAEA,KAAQ;KACL,CAAA,EAER,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,IAAG;MAAuB,WAAU;gBACrC;MACE,CAAA,EACL,kBAAC,OAAD;MAAK,IAAG;MAA6B,WAAU;gBAC5C;MACG,CAAA,CACF;OACF;OAGN,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAQ,SAAQ;KAAU,SAAS;KAAS,UAAU;eACnD;KACM,CAAA,EACT,kBAAC,GAAD;KACE,KAAK;KACL,SAAS,IAAgB,gBAAgB;KACzC,SAAS;KACT,UAAU;eAJZ,CAMG,KAAW,kBAAC,GAAD,EAAS,WAAU,6BAA8B,CAAA,EAC5D,EACM;OACL;MACF;KACF;;;AAsBV,SAAgB,EAAoB,EAClC,SACA,YACA,cACA,aACA,aACA,cAC2B;AAC3B,QACE,kBAAC,GAAD;EACQ;EACG;EACE;EACX,OAAO,UAAU,EAAS;EAC1B,aACE,kBAAA,GAAA,EAAA,UAAA;GAAE;GACgC,kBAAC,UAAD;IAAQ,WAAU;cAAqB;IAAkB,CAAA;;GAExF,EAAA,CAAA;EAEL,cAAa;EACb,SAAQ;EACC;EACT,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"DataTable.js","names":[],"sources":["../../../src/admin/components/DataTable.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';\nimport { Button, Skeleton } from './ui';\nimport { cn } from '../utils/cn';\n\ninterface Column<T> {\n /** Column key (used for accessing data) */\n key: string;\n /** Column header */\n header: string;\n /** Custom render function */\n render?: (item: T, index: number) => ReactNode;\n /** Column width */\n width?: string;\n /** Align content */\n align?: 'left' | 'center' | 'right';\n /** Sortable */\n sortable?: boolean;\n}\n\ninterface DataTableProps<T> {\n /** Column definitions */\n columns: Column<T>[];\n /** Data to display */\n data: T[];\n /** Key extractor for rows */\n keyExtractor: (item: T) => string;\n /** Loading state */\n loading?: boolean;\n /** Number of skeleton rows when loading */\n skeletonRows?: number;\n /** Empty state content */\n emptyState?: ReactNode;\n /** On row click handler */\n onRowClick?: (item: T) => void;\n /** Current sort column */\n sortBy?: string;\n /** Sort direction */\n sortOrder?: 'asc' | 'desc';\n /** On sort change */\n onSort?: (column: string, order: 'asc' | 'desc') => void;\n /** Additional class name */\n className?: string;\n}\n\n/**\n * Reusable data table component\n */\nexport function DataTable<T>({\n columns,\n data,\n keyExtractor,\n loading,\n skeletonRows = 5,\n emptyState,\n onRowClick,\n sortBy,\n sortOrder,\n onSort,\n className,\n}: DataTableProps<T>) {\n const handleSort = (column: Column<T>) => {\n if (!column.sortable || !onSort) return;\n const newOrder = sortBy === column.key && sortOrder === 'asc' ? 'desc' : 'asc';\n onSort(column.key, newOrder);\n };\n\n const alignClasses = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n };\n\n return (\n <div className={cn('overflow-hidden rounded-card border border-border-seam', className)}>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse\">\n <thead>\n <tr className=\"border-b border-border-seam bg-bg-sunken/40\">\n {columns.map((column) => (\n <th\n key={column.key}\n className={cn(\n 'px-4 py-3 text-sm font-medium text-text-secondary',\n alignClasses[column.align || 'left'],\n column.sortable && 'cursor-pointer select-none hover:text-text-primary',\n column.width\n )}\n style={column.width ? { width: column.width } : undefined}\n onClick={() => handleSort(column)}\n >\n <div className=\"flex items-center gap-2\">\n {column.header}\n {column.sortable && sortBy === column.key && (\n <span className=\"text-xs\">{sortOrder === 'asc' ? '↑' : '↓'}</span>\n )}\n </div>\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {loading ? (\n Array.from({ length: skeletonRows }).map((_, rowIndex) => (\n <tr key={rowIndex} className=\"border-b border-border-seam last:border-0\">\n {columns.map((column) => (\n <td key={column.key} className=\"px-4 py-3\">\n <Skeleton className=\"h-5 w-full motion-safe:animate-vc-shimmer\" />\n </td>\n ))}\n </tr>\n ))\n ) : data.length === 0 ? (\n <tr>\n <td colSpan={columns.length} className=\"px-4 py-8\">\n {emptyState || (\n <div className=\"text-center text-sm text-text-secondary\">\n No data available\n </div>\n )}\n </td>\n </tr>\n ) : (\n data.map((item, index) => (\n <tr\n key={keyExtractor(item)}\n className={cn(\n 'border-b border-border-seam last:border-0 transition-colors',\n onRowClick && 'cursor-pointer hover:bg-bg-sunken/40'\n )}\n onClick={() => onRowClick?.(item)}\n >\n {columns.map((column) => (\n <td\n key={column.key}\n className={cn('px-4 py-3 text-sm', alignClasses[column.align || 'left'])}\n >\n {column.render\n ? column.render(item, index)\n : String((item as Record<string, unknown>)[column.key] ?? '')}\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n\ninterface PaginationProps {\n /** Current page (1-indexed) */\n page: number;\n /** Total pages */\n totalPages: number;\n /** Total items */\n totalItems: number;\n /** Items per page */\n pageSize: number;\n /** On page change */\n onPageChange: (page: number) => void;\n /** Additional class name */\n className?: string;\n}\n\n/**\n * Pagination controls\n */\nexport function Pagination({\n page,\n totalPages,\n totalItems,\n pageSize,\n onPageChange,\n className,\n}: PaginationProps) {\n const startItem = (page - 1) * pageSize + 1;\n const endItem = Math.min(page * pageSize, totalItems);\n\n return (\n <div className={cn('flex items-center justify-between px-4 py-3', className)}>\n <div className=\"text-sm text-text-secondary\">\n Showing {startItem} to {endItem} of {totalItems} results\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => onPageChange(1)}\n disabled={page === 1}\n aria-label=\"First page\"\n >\n <ChevronsLeft className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => onPageChange(page - 1)}\n disabled={page === 1}\n aria-label=\"Previous page\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </Button>\n <span className=\"px-3 text-sm\">\n Page {page} of {totalPages}\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => onPageChange(page + 1)}\n disabled={page === totalPages}\n aria-label=\"Next page\"\n >\n <ChevronRight className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => onPageChange(totalPages)}\n disabled={page === totalPages}\n aria-label=\"Last page\"\n >\n <ChevronsRight className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DataTable.js","names":[],"sources":["../../../src/admin/components/DataTable.tsx"],"sourcesContent":["import type { ReactNode } from 'react';\nimport { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-react';\nimport { Button, Skeleton } from './ui';\nimport { cn } from '../utils/cn';\n\ninterface Column<T> {\n /** Column key (used for accessing data) */\n key: string;\n /** Column header */\n header: string;\n /** Custom render function */\n render?: (item: T, index: number) => ReactNode;\n /** Column width */\n width?: string;\n /** Align content */\n align?: 'left' | 'center' | 'right';\n /** Sortable */\n sortable?: boolean;\n}\n\ninterface DataTableProps<T> {\n /** Column definitions */\n columns: Column<T>[];\n /** Data to display */\n data: T[];\n /** Key extractor for rows */\n keyExtractor: (item: T) => string;\n /** Loading state */\n loading?: boolean;\n /** Number of skeleton rows when loading */\n skeletonRows?: number;\n /** Empty state content */\n emptyState?: ReactNode;\n /** On row click handler */\n onRowClick?: (item: T) => void;\n /** Current sort column */\n sortBy?: string;\n /** Sort direction */\n sortOrder?: 'asc' | 'desc';\n /** On sort change */\n onSort?: (column: string, order: 'asc' | 'desc') => void;\n /** Additional class name */\n className?: string;\n}\n\n/**\n * Reusable data table component\n */\nexport function DataTable<T>({\n columns,\n data,\n keyExtractor,\n loading,\n skeletonRows = 5,\n emptyState,\n onRowClick,\n sortBy,\n sortOrder,\n onSort,\n className,\n}: DataTableProps<T>) {\n const handleSort = (column: Column<T>) => {\n if (!column.sortable || !onSort) return;\n const newOrder = sortBy === column.key && sortOrder === 'asc' ? 'desc' : 'asc';\n onSort(column.key, newOrder);\n };\n\n const alignClasses = {\n left: 'text-left',\n center: 'text-center',\n right: 'text-right',\n };\n\n return (\n <div className={cn('overflow-hidden rounded-card border border-border-seam', className)}>\n <div className=\"overflow-x-auto\">\n <table className=\"w-full border-collapse\">\n <thead>\n <tr className=\"border-b border-border-seam bg-bg-sunken/40\">\n {columns.map((column) => (\n <th\n key={column.key}\n className={cn(\n 'px-4 py-3 text-sm font-medium text-text-secondary',\n alignClasses[column.align || 'left'],\n column.sortable && 'cursor-pointer select-none hover:text-text-primary',\n column.width\n )}\n style={column.width ? { width: column.width } : undefined}\n onClick={() => handleSort(column)}\n >\n <div className=\"flex items-center gap-2\">\n {column.header}\n {column.sortable && sortBy === column.key && (\n <span className=\"text-xs\">{sortOrder === 'asc' ? '↑' : '↓'}</span>\n )}\n </div>\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {loading ? (\n Array.from({ length: skeletonRows }).map((_, rowIndex) => (\n <tr key={rowIndex} className=\"border-b border-border-seam last:border-0\">\n {columns.map((column) => (\n <td key={column.key} className=\"px-4 py-3\">\n <Skeleton className=\"h-5 w-full motion-safe:animate-vc-shimmer\" />\n </td>\n ))}\n </tr>\n ))\n ) : data.length === 0 ? (\n <tr>\n <td colSpan={columns.length} className=\"px-4 py-8\">\n {emptyState || (\n <div className=\"text-center text-sm text-text-secondary\">No data available</div>\n )}\n </td>\n </tr>\n ) : (\n data.map((item, index) => (\n <tr\n key={keyExtractor(item)}\n className={cn(\n 'border-b border-border-seam last:border-0 transition-colors',\n onRowClick && 'cursor-pointer hover:bg-bg-sunken/40'\n )}\n onClick={() => onRowClick?.(item)}\n >\n {columns.map((column) => (\n <td\n key={column.key}\n className={cn('px-4 py-3 text-sm', alignClasses[column.align || 'left'])}\n >\n {column.render\n ? column.render(item, index)\n : String((item as Record<string, unknown>)[column.key] ?? '')}\n </td>\n ))}\n </tr>\n ))\n )}\n </tbody>\n </table>\n </div>\n </div>\n );\n}\n\ninterface PaginationProps {\n /** Current page (1-indexed) */\n page: number;\n /** Total pages */\n totalPages: number;\n /** Total items */\n totalItems: number;\n /** Items per page */\n pageSize: number;\n /** On page change */\n onPageChange: (page: number) => void;\n /** Additional class name */\n className?: string;\n}\n\n/**\n * Pagination controls\n */\nexport function Pagination({\n page,\n totalPages,\n totalItems,\n pageSize,\n onPageChange,\n className,\n}: PaginationProps) {\n const startItem = (page - 1) * pageSize + 1;\n const endItem = Math.min(page * pageSize, totalItems);\n\n return (\n <div className={cn('flex items-center justify-between px-4 py-3', className)}>\n <div className=\"text-sm text-text-secondary\">\n Showing {startItem} to {endItem} of {totalItems} results\n </div>\n <div className=\"flex items-center gap-1\">\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => onPageChange(1)}\n disabled={page === 1}\n aria-label=\"First page\"\n >\n <ChevronsLeft className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => onPageChange(page - 1)}\n disabled={page === 1}\n aria-label=\"Previous page\"\n >\n <ChevronLeft className=\"h-4 w-4\" />\n </Button>\n <span className=\"px-3 text-sm\">\n Page {page} of {totalPages}\n </span>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => onPageChange(page + 1)}\n disabled={page === totalPages}\n aria-label=\"Next page\"\n >\n <ChevronRight className=\"h-4 w-4\" />\n </Button>\n <Button\n variant=\"outline\"\n size=\"icon\"\n onClick={() => onPageChange(totalPages)}\n disabled={page === totalPages}\n aria-label=\"Last page\"\n >\n <ChevronsRight className=\"h-4 w-4\" />\n </Button>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ //#region src/admin/constants/featureFlags.ts
2
+ var e = {
3
+ management: "tenant.management",
4
+ list: "tenant.list",
5
+ detail: "tenant.detail",
6
+ create: "tenant.create",
7
+ edit: "tenant.edit"
8
+ };
9
+ //#endregion
10
+ export { e as TENANT_FEATURE_FLAGS };
11
+
12
+ //# sourceMappingURL=featureFlags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"featureFlags.js","names":[],"sources":["../../../src/admin/constants/featureFlags.ts"],"sourcesContent":["export const TENANT_FEATURE_FLAGS = {\n management: 'tenant.management',\n list: 'tenant.list',\n detail: 'tenant.detail',\n create: 'tenant.create',\n edit: 'tenant.edit',\n} as const;\n\nexport type TenantFeatureFlag = (typeof TENANT_FEATURE_FLAGS)[keyof typeof TENANT_FEATURE_FLAGS];\n"],"mappings":";AAAA,IAAa,IAAuB;CAClC,YAAY;CACZ,MAAM;CACN,QAAQ;CACR,QAAQ;CACR,MAAM;CACP"}