@burdenoff/microfe-admin 2026.805.1 → 2026.829.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,128 +4,127 @@ import { PageLayout as n } from "../components/PageLayout.js";
4
4
  import { MetricCard as r, MetricsGrid as i } from "../components/MetricCard.js";
5
5
  import { ActivityFeed as a } from "../components/ActivityFeed.js";
6
6
  import { QuickLinks as o } from "../components/Charts.js";
7
- import { tWithFallback as s } from "../utils/i18n.js";
8
- import { PermissionGuard as c } from "../components/PermissionGuard.js";
7
+ import { PermissionGuard as s } from "../components/PermissionGuard.js";
9
8
  import "../components/index.js";
10
- import { joinPath as l } from "../utils/navigation.js";
11
- import { mapActivityLogToUi as u } from "../utils/mappers.js";
12
- import { useGetDashboardActiveWorkspaceCountQuery as d, useGetDashboardOrganizationCountQuery as f, useGetDashboardTenantCountQuery as p, useGetDashboardUserCountQuery as m, useGetRecentActivityLogsQuery as h } from "../../generated/global-operations.js";
9
+ import { joinPath as c } from "../utils/navigation.js";
10
+ import { mapActivityLogToUi as l } from "../utils/mappers.js";
11
+ import { useGetDashboardActiveWorkspaceCountQuery as u, useGetDashboardOrganizationCountQuery as d, useGetDashboardTenantCountQuery as f, useGetDashboardUserCountQuery as p, useGetRecentActivityLogsQuery as m } from "../../generated/global-operations.js";
12
+ import { useTr as h } from "../hooks/useTr.js";
13
13
  import { useMemo as g } from "react";
14
14
  import { Briefcase as _, Building2 as v, FileText as y, HelpCircle as b, Layout as x, Plus as S, UserPlus as C, Users as w } from "lucide-react";
15
15
  import { useNavigate as T } from "react-router";
16
16
  import { jsx as E, jsxs as D } from "react/jsx-runtime";
17
- import { useI18n as O } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
18
- import { NextSteps as k, PagePurpose as A } from "@burdenoff/fe-libs/ui";
17
+ import { NextSteps as O, PagePurpose as k } from "@burdenoff/fe-libs/ui";
19
18
  //#region src/admin/pages/DashboardPage.tsx
20
- function j() {
21
- let { canViewDashboard: j, isLoading: M } = t(), { basePath: N = "" } = e(), P = T(), { t: F } = O(), I = (e, t, n) => s(F, e, t, n), L = M || !j, { data: R, loading: z } = p({
19
+ function A() {
20
+ let { canViewDashboard: A, isLoading: j } = t(), { basePath: M = "" } = e(), N = T(), P = h(), F = j || !A, { data: I, loading: L } = f({
22
21
  fetchPolicy: "cache-and-network",
23
- skip: L
24
- }), { data: B, loading: V } = f({
22
+ skip: F
23
+ }), { data: R, loading: z } = d({
25
24
  fetchPolicy: "cache-and-network",
26
- skip: L
27
- }), { data: H, loading: U } = d({
25
+ skip: F
26
+ }), { data: B, loading: V } = u({
28
27
  fetchPolicy: "cache-and-network",
29
- skip: L
30
- }), { data: W, loading: G } = m({
28
+ skip: F
29
+ }), { data: H, loading: U } = p({
31
30
  fetchPolicy: "cache-and-network",
32
- skip: L
33
- }), { data: K, loading: q } = h({
31
+ skip: F
32
+ }), { data: W, loading: G } = m({
34
33
  variables: { limit: 10 },
35
34
  fetchPolicy: "cache-and-network",
36
- skip: L
37
- }), J = {
38
- tenants: R?.tenants?.total ?? 0,
39
- organizations: B?.allOrganizations?.total ?? 0,
40
- workspaces: H?.allWorkspaces?.total ?? 0,
41
- users: W?.userCount ?? 0
42
- }, Y = g(() => (K?.activityLogs?.nodes ?? []).map(u), [K]), X = [
35
+ skip: F
36
+ }), K = {
37
+ tenants: I?.tenants?.total ?? 0,
38
+ organizations: R?.allOrganizations?.total ?? 0,
39
+ workspaces: B?.allWorkspaces?.total ?? 0,
40
+ users: H?.userCount ?? 0
41
+ }, q = g(() => (W?.activityLogs?.nodes ?? []).map(l), [W]), J = [
43
42
  {
44
- to: l(N, "tenants"),
45
- label: I("admin.dashboard.quickLinks.addTenant", "Add Tenant"),
43
+ to: c(M, "tenants"),
44
+ label: P("admin.dashboard.quickLinks.addTenant", "Add Tenant"),
46
45
  icon: /* @__PURE__ */ E(S, { className: "h-4 w-4" }),
47
- description: I("admin.dashboard.quickLinks.addTenantDescription", "Create a new tenant")
46
+ description: P("admin.dashboard.quickLinks.addTenantDescription", "Create a new tenant")
48
47
  },
49
48
  {
50
- to: l(N, "users"),
51
- label: I("admin.dashboard.quickLinks.inviteUser", "Invite User"),
49
+ to: c(M, "users"),
50
+ label: P("admin.dashboard.quickLinks.inviteUser", "Invite User"),
52
51
  icon: /* @__PURE__ */ E(C, { className: "h-4 w-4" }),
53
- description: I("admin.dashboard.quickLinks.inviteUserDescription", "Invite a new user")
52
+ description: P("admin.dashboard.quickLinks.inviteUserDescription", "Invite a new user")
54
53
  },
55
54
  {
56
- to: l(N, "audit"),
57
- label: I("admin.dashboard.quickLinks.auditLogs", "Audit Logs"),
55
+ to: c(M, "audit"),
56
+ label: P("admin.dashboard.quickLinks.auditLogs", "Audit Logs"),
58
57
  icon: /* @__PURE__ */ E(y, { className: "h-4 w-4" }),
59
- description: I("admin.dashboard.quickLinks.auditLogsDescription", "View security audit trail")
58
+ description: P("admin.dashboard.quickLinks.auditLogsDescription", "View security audit trail")
60
59
  },
61
60
  {
62
- to: l(N, "support"),
63
- label: I("admin.dashboard.quickLinks.support", "Support"),
61
+ to: c(M, "support"),
62
+ label: P("admin.dashboard.quickLinks.support", "Support"),
64
63
  icon: /* @__PURE__ */ E(b, { className: "h-4 w-4" }),
65
- description: I("admin.dashboard.quickLinks.supportDescription", "Manage support tickets")
64
+ description: P("admin.dashboard.quickLinks.supportDescription", "Manage support tickets")
66
65
  }
67
- ], Z = z || V || U || G;
68
- return /* @__PURE__ */ E(c, {
69
- allowed: j,
70
- isLoading: M,
71
- pageTitle: I("admin.dashboard.title", "Dashboard"),
72
- denyMessage: I("admin.dashboard.denyMessage", "You don't have permission to view the admin dashboard."),
66
+ ], Y = L || z || V || U;
67
+ return /* @__PURE__ */ E(s, {
68
+ allowed: A,
69
+ isLoading: j,
70
+ pageTitle: P("admin.dashboard.title", "Dashboard"),
71
+ denyMessage: P("admin.dashboard.denyMessage", "You don't have permission to view the admin dashboard."),
73
72
  children: /* @__PURE__ */ E(n, {
74
- title: I("admin.dashboard.title", "Dashboard"),
75
- description: I("admin.dashboard.description", "Platform overview and key metrics"),
76
- gradientWord: I("admin.dashboard.title", "Dashboard"),
73
+ title: P("admin.dashboard.title", "Dashboard"),
74
+ description: P("admin.dashboard.description", "Platform overview and key metrics"),
75
+ gradientWord: P("admin.dashboard.title", "Dashboard"),
77
76
  aurora: !0,
78
77
  children: /* @__PURE__ */ D("div", {
79
78
  className: "space-y-6",
80
79
  children: [
81
- /* @__PURE__ */ E(A, { children: I("admin.dashboard.purpose", "Your control tower for the whole platform. See live tenant, organization, workspace and user counts at a glance, watch the most recent administrative activity, and jump straight into the day-to-day jobs — onboarding a tenant, inviting a user, or reviewing the audit trail.") }),
82
- /* @__PURE__ */ E(k, {
80
+ /* @__PURE__ */ E(k, { children: P("admin.dashboard.purpose", "Your control tower for the whole platform. See live tenant, organization, workspace and user counts at a glance, watch the most recent administrative activity, and jump straight into the day-to-day jobs — onboarding a tenant, inviting a user, or reviewing the audit trail.") }),
81
+ /* @__PURE__ */ E(O, {
83
82
  storageKey: "admin-dashboard",
84
83
  steps: [
85
84
  {
86
85
  id: "add-tenant",
87
- label: I("admin.dashboard.nextSteps.addTenant", "Onboard a tenant"),
88
- description: I("admin.dashboard.nextSteps.addTenantDesc", "Provision a new customer tenant to start serving them."),
89
- onClick: () => P(l(N, "tenants/new"))
86
+ label: P("admin.dashboard.nextSteps.addTenant", "Onboard a tenant"),
87
+ description: P("admin.dashboard.nextSteps.addTenantDesc", "Provision a new customer tenant to start serving them."),
88
+ onClick: () => N(c(M, "tenants/new"))
90
89
  },
91
90
  {
92
91
  id: "invite-user",
93
- label: I("admin.dashboard.nextSteps.inviteUser", "Invite a teammate"),
94
- description: I("admin.dashboard.nextSteps.inviteUserDesc", "Bring another operator into the admin console."),
95
- onClick: () => P(l(N, "users"))
92
+ label: P("admin.dashboard.nextSteps.inviteUser", "Invite a teammate"),
93
+ description: P("admin.dashboard.nextSteps.inviteUserDesc", "Bring another operator into the admin console."),
94
+ onClick: () => N(c(M, "users"))
96
95
  },
97
96
  {
98
97
  id: "review-audit",
99
- label: I("admin.dashboard.nextSteps.reviewAudit", "Review the audit trail"),
100
- description: I("admin.dashboard.nextSteps.reviewAuditDesc", "Check who changed what across the platform."),
101
- onClick: () => P(l(N, "audit"))
98
+ label: P("admin.dashboard.nextSteps.reviewAudit", "Review the audit trail"),
99
+ description: P("admin.dashboard.nextSteps.reviewAuditDesc", "Check who changed what across the platform."),
100
+ onClick: () => N(c(M, "audit"))
102
101
  }
103
102
  ]
104
103
  }),
105
104
  /* @__PURE__ */ D(i, { children: [
106
105
  /* @__PURE__ */ E(r, {
107
- title: I("admin.dashboard.metrics.totalTenants", "Total Tenants"),
108
- value: J.tenants,
109
- loading: Z,
106
+ title: P("admin.dashboard.metrics.totalTenants", "Total Tenants"),
107
+ value: K.tenants,
108
+ loading: Y,
110
109
  hero: !0,
111
110
  icon: /* @__PURE__ */ E(v, { className: "h-5 w-5 text-action-primary-bg" })
112
111
  }),
113
112
  /* @__PURE__ */ E(r, {
114
- title: I("admin.dashboard.metrics.organizations", "Organizations"),
115
- value: J.organizations,
116
- loading: Z,
113
+ title: P("admin.dashboard.metrics.organizations", "Organizations"),
114
+ value: K.organizations,
115
+ loading: Y,
117
116
  icon: /* @__PURE__ */ E(_, { className: "h-5 w-5 text-text-secondary" })
118
117
  }),
119
118
  /* @__PURE__ */ E(r, {
120
- title: I("admin.dashboard.metrics.activeWorkspaces", "Active Workspaces"),
121
- value: J.workspaces,
122
- loading: Z,
119
+ title: P("admin.dashboard.metrics.activeWorkspaces", "Active Workspaces"),
120
+ value: K.workspaces,
121
+ loading: Y,
123
122
  icon: /* @__PURE__ */ E(x, { className: "h-5 w-5 text-status-success-text" })
124
123
  }),
125
124
  /* @__PURE__ */ E(r, {
126
- title: I("admin.dashboard.metrics.totalUsers", "Total Users"),
127
- value: J.users,
128
- loading: Z,
125
+ title: P("admin.dashboard.metrics.totalUsers", "Total Users"),
126
+ value: K.users,
127
+ loading: Y,
129
128
  icon: /* @__PURE__ */ E(w, { className: "h-5 w-5 text-text-secondary" })
130
129
  })
131
130
  ] }),
@@ -134,12 +133,12 @@ function j() {
134
133
  children: [/* @__PURE__ */ E("div", {
135
134
  className: "lg:col-span-2",
136
135
  children: /* @__PURE__ */ E(a, {
137
- activities: Y,
138
- loading: q
136
+ activities: q,
137
+ loading: G
139
138
  })
140
139
  }), /* @__PURE__ */ E("div", {
141
140
  className: "space-y-4",
142
- children: /* @__PURE__ */ E(o, { links: X })
141
+ children: /* @__PURE__ */ E(o, { links: J })
143
142
  })]
144
143
  })
145
144
  ]
@@ -148,6 +147,6 @@ function j() {
148
147
  });
149
148
  }
150
149
  //#endregion
151
- export { j as DashboardPage };
150
+ export { A as DashboardPage };
152
151
 
153
152
  //# sourceMappingURL=DashboardPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/admin/pages/DashboardPage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Building2,\n Users,\n Layout,\n Briefcase,\n Plus,\n UserPlus,\n FileText,\n HelpCircle,\n} from 'lucide-react';\nimport { useAdmin } from '../providers/AdminProvider';\nimport { useAdminPermissions } from '../hooks/useAdminPermissions';\nimport {\n PageLayout,\n MetricCard,\n MetricsGrid,\n ActivityFeed,\n QuickLinks,\n PermissionGuard,\n} from '../components';\nimport { useNavigate } from 'react-router';\nimport { PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { joinPath } from '../utils/navigation';\nimport { mapActivityLogToUi } from '../utils/mappers';\nimport type { Activity } from '../types';\nimport {\n useGetDashboardTenantCountQuery,\n useGetDashboardOrganizationCountQuery,\n useGetDashboardActiveWorkspaceCountQuery,\n useGetDashboardUserCountQuery,\n useGetRecentActivityLogsQuery,\n} from '../../generated/global-operations';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { tWithFallback } from '../utils/i18n';\n\n/**\n * Dashboard page — platform overview with real-time metrics\n */\nexport function DashboardPage() {\n const { canViewDashboard, isLoading: permissionsLoading } = useAdminPermissions();\n const { basePath = '' } = useAdmin();\n const navigate = useNavigate();\n const { t } = useI18n();\n const tr = (key: string, fallback: string, params?: Record<string, string | number>): string =>\n tWithFallback(t, key, fallback, params);\n\n const skipQueries = permissionsLoading || !canViewDashboard;\n\n const { data: tenantData, loading: tenantLoading } = useGetDashboardTenantCountQuery({\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n const { data: orgData, loading: orgLoading } = useGetDashboardOrganizationCountQuery({\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n const { data: workspaceData, loading: workspaceLoading } =\n useGetDashboardActiveWorkspaceCountQuery({\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n const { data: userData, loading: userLoading } = useGetDashboardUserCountQuery({\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n const { data: activityData, loading: activityLoading } = useGetRecentActivityLogsQuery({\n variables: { limit: 10 },\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n\n const metrics = {\n tenants: tenantData?.tenants?.total ?? 0,\n organizations: orgData?.allOrganizations?.total ?? 0,\n workspaces: workspaceData?.allWorkspaces?.total ?? 0,\n users: userData?.userCount ?? 0,\n };\n\n const recentActivity: Activity[] = useMemo(\n () => (activityData?.activityLogs?.nodes ?? []).map(mapActivityLogToUi),\n [activityData]\n );\n\n const quickLinks = [\n {\n to: joinPath(basePath, 'tenants'),\n label: tr('admin.dashboard.quickLinks.addTenant', 'Add Tenant'),\n icon: <Plus className=\"h-4 w-4\" />,\n description: tr('admin.dashboard.quickLinks.addTenantDescription', 'Create a new tenant'),\n },\n {\n to: joinPath(basePath, 'users'),\n label: tr('admin.dashboard.quickLinks.inviteUser', 'Invite User'),\n icon: <UserPlus className=\"h-4 w-4\" />,\n description: tr('admin.dashboard.quickLinks.inviteUserDescription', 'Invite a new user'),\n },\n {\n to: joinPath(basePath, 'audit'),\n label: tr('admin.dashboard.quickLinks.auditLogs', 'Audit Logs'),\n icon: <FileText className=\"h-4 w-4\" />,\n description: tr(\n 'admin.dashboard.quickLinks.auditLogsDescription',\n 'View security audit trail'\n ),\n },\n {\n to: joinPath(basePath, 'support'),\n label: tr('admin.dashboard.quickLinks.support', 'Support'),\n icon: <HelpCircle className=\"h-4 w-4\" />,\n description: tr('admin.dashboard.quickLinks.supportDescription', 'Manage support tickets'),\n },\n ];\n\n const isLoading = tenantLoading || orgLoading || workspaceLoading || userLoading;\n\n return (\n <PermissionGuard\n allowed={canViewDashboard}\n isLoading={permissionsLoading}\n pageTitle={tr('admin.dashboard.title', 'Dashboard')}\n denyMessage={tr(\n 'admin.dashboard.denyMessage',\n \"You don't have permission to view the admin dashboard.\"\n )}\n >\n <PageLayout\n title={tr('admin.dashboard.title', 'Dashboard')}\n description={tr('admin.dashboard.description', 'Platform overview and key metrics')}\n gradientWord={tr('admin.dashboard.title', 'Dashboard')}\n aurora\n >\n <div className=\"space-y-6\">\n <PagePurpose>\n {tr(\n 'admin.dashboard.purpose',\n 'Your control tower for the whole platform. See live tenant, organization, workspace and user counts at a glance, watch the most recent administrative activity, and jump straight into the day-to-day jobs — onboarding a tenant, inviting a user, or reviewing the audit trail.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"admin-dashboard\"\n steps={[\n {\n id: 'add-tenant',\n label: tr('admin.dashboard.nextSteps.addTenant', 'Onboard a tenant'),\n description: tr(\n 'admin.dashboard.nextSteps.addTenantDesc',\n 'Provision a new customer tenant to start serving them.'\n ),\n onClick: () => navigate(joinPath(basePath, 'tenants/new')),\n },\n {\n id: 'invite-user',\n label: tr('admin.dashboard.nextSteps.inviteUser', 'Invite a teammate'),\n description: tr(\n 'admin.dashboard.nextSteps.inviteUserDesc',\n 'Bring another operator into the admin console.'\n ),\n onClick: () => navigate(joinPath(basePath, 'users')),\n },\n {\n id: 'review-audit',\n label: tr('admin.dashboard.nextSteps.reviewAudit', 'Review the audit trail'),\n description: tr(\n 'admin.dashboard.nextSteps.reviewAuditDesc',\n 'Check who changed what across the platform.'\n ),\n onClick: () => navigate(joinPath(basePath, 'audit')),\n },\n ]}\n />\n\n {/* Metrics Grid */}\n <MetricsGrid>\n <MetricCard\n title={tr('admin.dashboard.metrics.totalTenants', 'Total Tenants')}\n value={metrics.tenants}\n loading={isLoading}\n hero\n icon={<Building2 className=\"h-5 w-5 text-action-primary-bg\" />}\n />\n <MetricCard\n title={tr('admin.dashboard.metrics.organizations', 'Organizations')}\n value={metrics.organizations}\n loading={isLoading}\n icon={<Briefcase className=\"h-5 w-5 text-text-secondary\" />}\n />\n <MetricCard\n title={tr('admin.dashboard.metrics.activeWorkspaces', 'Active Workspaces')}\n value={metrics.workspaces}\n loading={isLoading}\n icon={<Layout className=\"h-5 w-5 text-status-success-text\" />}\n />\n <MetricCard\n title={tr('admin.dashboard.metrics.totalUsers', 'Total Users')}\n value={metrics.users}\n loading={isLoading}\n icon={<Users className=\"h-5 w-5 text-text-secondary\" />}\n />\n </MetricsGrid>\n\n {/* Content Area */}\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2\">\n <ActivityFeed activities={recentActivity} loading={activityLoading} />\n </div>\n <div className=\"space-y-4\">\n <QuickLinks links={quickLinks} />\n </div>\n </div>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/admin/pages/DashboardPage.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport {\n Building2,\n Users,\n Layout,\n Briefcase,\n Plus,\n UserPlus,\n FileText,\n HelpCircle,\n} from 'lucide-react';\nimport { useAdmin } from '../providers/AdminProvider';\nimport { useAdminPermissions } from '../hooks/useAdminPermissions';\nimport {\n PageLayout,\n MetricCard,\n MetricsGrid,\n ActivityFeed,\n QuickLinks,\n PermissionGuard,\n} from '../components';\nimport { useNavigate } from 'react-router';\nimport { PagePurpose, NextSteps } from '@burdenoff/fe-libs/ui';\nimport { joinPath } from '../utils/navigation';\nimport { mapActivityLogToUi } from '../utils/mappers';\nimport type { Activity } from '../types';\nimport {\n useGetDashboardTenantCountQuery,\n useGetDashboardOrganizationCountQuery,\n useGetDashboardActiveWorkspaceCountQuery,\n useGetDashboardUserCountQuery,\n useGetRecentActivityLogsQuery,\n} from '../../generated/global-operations';\nimport { useTr } from '../hooks/useTr';\n\n/**\n * Dashboard page — platform overview with real-time metrics\n */\nexport function DashboardPage() {\n const { canViewDashboard, isLoading: permissionsLoading } = useAdminPermissions();\n const { basePath = '' } = useAdmin();\n const navigate = useNavigate();\n const tr = useTr();\n\n const skipQueries = permissionsLoading || !canViewDashboard;\n\n const { data: tenantData, loading: tenantLoading } = useGetDashboardTenantCountQuery({\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n const { data: orgData, loading: orgLoading } = useGetDashboardOrganizationCountQuery({\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n const { data: workspaceData, loading: workspaceLoading } =\n useGetDashboardActiveWorkspaceCountQuery({\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n const { data: userData, loading: userLoading } = useGetDashboardUserCountQuery({\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n const { data: activityData, loading: activityLoading } = useGetRecentActivityLogsQuery({\n variables: { limit: 10 },\n fetchPolicy: 'cache-and-network',\n skip: skipQueries,\n });\n\n const metrics = {\n tenants: tenantData?.tenants?.total ?? 0,\n organizations: orgData?.allOrganizations?.total ?? 0,\n workspaces: workspaceData?.allWorkspaces?.total ?? 0,\n users: userData?.userCount ?? 0,\n };\n\n const recentActivity: Activity[] = useMemo(\n () => (activityData?.activityLogs?.nodes ?? []).map(mapActivityLogToUi),\n [activityData]\n );\n\n const quickLinks = [\n {\n to: joinPath(basePath, 'tenants'),\n label: tr('admin.dashboard.quickLinks.addTenant', 'Add Tenant'),\n icon: <Plus className=\"h-4 w-4\" />,\n description: tr('admin.dashboard.quickLinks.addTenantDescription', 'Create a new tenant'),\n },\n {\n to: joinPath(basePath, 'users'),\n label: tr('admin.dashboard.quickLinks.inviteUser', 'Invite User'),\n icon: <UserPlus className=\"h-4 w-4\" />,\n description: tr('admin.dashboard.quickLinks.inviteUserDescription', 'Invite a new user'),\n },\n {\n to: joinPath(basePath, 'audit'),\n label: tr('admin.dashboard.quickLinks.auditLogs', 'Audit Logs'),\n icon: <FileText className=\"h-4 w-4\" />,\n description: tr(\n 'admin.dashboard.quickLinks.auditLogsDescription',\n 'View security audit trail'\n ),\n },\n {\n to: joinPath(basePath, 'support'),\n label: tr('admin.dashboard.quickLinks.support', 'Support'),\n icon: <HelpCircle className=\"h-4 w-4\" />,\n description: tr('admin.dashboard.quickLinks.supportDescription', 'Manage support tickets'),\n },\n ];\n\n const isLoading = tenantLoading || orgLoading || workspaceLoading || userLoading;\n\n return (\n <PermissionGuard\n allowed={canViewDashboard}\n isLoading={permissionsLoading}\n pageTitle={tr('admin.dashboard.title', 'Dashboard')}\n denyMessage={tr(\n 'admin.dashboard.denyMessage',\n \"You don't have permission to view the admin dashboard.\"\n )}\n >\n <PageLayout\n title={tr('admin.dashboard.title', 'Dashboard')}\n description={tr('admin.dashboard.description', 'Platform overview and key metrics')}\n gradientWord={tr('admin.dashboard.title', 'Dashboard')}\n aurora\n >\n <div className=\"space-y-6\">\n <PagePurpose>\n {tr(\n 'admin.dashboard.purpose',\n 'Your control tower for the whole platform. See live tenant, organization, workspace and user counts at a glance, watch the most recent administrative activity, and jump straight into the day-to-day jobs — onboarding a tenant, inviting a user, or reviewing the audit trail.'\n )}\n </PagePurpose>\n\n <NextSteps\n storageKey=\"admin-dashboard\"\n steps={[\n {\n id: 'add-tenant',\n label: tr('admin.dashboard.nextSteps.addTenant', 'Onboard a tenant'),\n description: tr(\n 'admin.dashboard.nextSteps.addTenantDesc',\n 'Provision a new customer tenant to start serving them.'\n ),\n onClick: () => navigate(joinPath(basePath, 'tenants/new')),\n },\n {\n id: 'invite-user',\n label: tr('admin.dashboard.nextSteps.inviteUser', 'Invite a teammate'),\n description: tr(\n 'admin.dashboard.nextSteps.inviteUserDesc',\n 'Bring another operator into the admin console.'\n ),\n onClick: () => navigate(joinPath(basePath, 'users')),\n },\n {\n id: 'review-audit',\n label: tr('admin.dashboard.nextSteps.reviewAudit', 'Review the audit trail'),\n description: tr(\n 'admin.dashboard.nextSteps.reviewAuditDesc',\n 'Check who changed what across the platform.'\n ),\n onClick: () => navigate(joinPath(basePath, 'audit')),\n },\n ]}\n />\n\n {/* Metrics Grid */}\n <MetricsGrid>\n <MetricCard\n title={tr('admin.dashboard.metrics.totalTenants', 'Total Tenants')}\n value={metrics.tenants}\n loading={isLoading}\n hero\n icon={<Building2 className=\"h-5 w-5 text-action-primary-bg\" />}\n />\n <MetricCard\n title={tr('admin.dashboard.metrics.organizations', 'Organizations')}\n value={metrics.organizations}\n loading={isLoading}\n icon={<Briefcase className=\"h-5 w-5 text-text-secondary\" />}\n />\n <MetricCard\n title={tr('admin.dashboard.metrics.activeWorkspaces', 'Active Workspaces')}\n value={metrics.workspaces}\n loading={isLoading}\n icon={<Layout className=\"h-5 w-5 text-status-success-text\" />}\n />\n <MetricCard\n title={tr('admin.dashboard.metrics.totalUsers', 'Total Users')}\n value={metrics.users}\n loading={isLoading}\n icon={<Users className=\"h-5 w-5 text-text-secondary\" />}\n />\n </MetricsGrid>\n\n {/* Content Area */}\n <div className=\"grid gap-6 lg:grid-cols-3\">\n <div className=\"lg:col-span-2\">\n <ActivityFeed activities={recentActivity} loading={activityLoading} />\n </div>\n <div className=\"space-y-4\">\n <QuickLinks links={quickLinks} />\n </div>\n </div>\n </div>\n </PageLayout>\n </PermissionGuard>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAsCA,SAAgB,IAAgB;CAC9B,IAAM,EAAE,qBAAkB,WAAW,MAAuB,GAAqB,EAC3E,EAAE,cAAW,OAAO,GAAU,EAC9B,IAAW,GAAa,EACxB,IAAK,GAAO,EAEZ,IAAc,KAAsB,CAAC,GAErC,EAAE,MAAM,GAAY,SAAS,MAAkB,EAAgC;EACnF,aAAa;EACb,MAAM;EACP,CAAC,EACI,EAAE,MAAM,GAAS,SAAS,MAAe,EAAsC;EACnF,aAAa;EACb,MAAM;EACP,CAAC,EACI,EAAE,MAAM,GAAe,SAAS,MACpC,EAAyC;EACvC,aAAa;EACb,MAAM;EACP,CAAC,EACE,EAAE,MAAM,GAAU,SAAS,MAAgB,EAA8B;EAC7E,aAAa;EACb,MAAM;EACP,CAAC,EACI,EAAE,MAAM,GAAc,SAAS,MAAoB,EAA8B;EACrF,WAAW,EAAE,OAAO,IAAI;EACxB,aAAa;EACb,MAAM;EACP,CAAC,EAEI,IAAU;EACd,SAAS,GAAY,SAAS,SAAS;EACvC,eAAe,GAAS,kBAAkB,SAAS;EACnD,YAAY,GAAe,eAAe,SAAS;EACnD,OAAO,GAAU,aAAa;EAC/B,EAEK,IAA6B,SAC1B,GAAc,cAAc,SAAS,EAAE,EAAE,IAAI,EAAmB,EACvE,CAAC,EAAa,CACf,EAEK,IAAa;EACjB;GACE,IAAI,EAAS,GAAU,UAAU;GACjC,OAAO,EAAG,wCAAwC,aAAa;GAC/D,MAAM,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;GAClC,aAAa,EAAG,mDAAmD,sBAAsB;GAC1F;EACD;GACE,IAAI,EAAS,GAAU,QAAQ;GAC/B,OAAO,EAAG,yCAAyC,cAAc;GACjE,MAAM,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;GACtC,aAAa,EAAG,oDAAoD,oBAAoB;GACzF;EACD;GACE,IAAI,EAAS,GAAU,QAAQ;GAC/B,OAAO,EAAG,wCAAwC,aAAa;GAC/D,MAAM,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA;GACtC,aAAa,EACX,mDACA,4BACD;GACF;EACD;GACE,IAAI,EAAS,GAAU,UAAU;GACjC,OAAO,EAAG,sCAAsC,UAAU;GAC1D,MAAM,kBAAC,GAAD,EAAY,WAAU,WAAY,CAAA;GACxC,aAAa,EAAG,iDAAiD,yBAAyB;GAC3F;EACF,EAEK,IAAY,KAAiB,KAAc,KAAoB;AAErE,QACE,kBAAC,GAAD;EACE,SAAS;EACT,WAAW;EACX,WAAW,EAAG,yBAAyB,YAAY;EACnD,aAAa,EACX,+BACA,yDACD;YAED,kBAAC,GAAD;GACE,OAAO,EAAG,yBAAyB,YAAY;GAC/C,aAAa,EAAG,+BAA+B,oCAAoC;GACnF,cAAc,EAAG,yBAAyB,YAAY;GACtD,QAAA;aAEA,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,GAAD,EAAA,UACG,EACC,2BACA,mRACD,EACW,CAAA;KAEd,kBAAC,GAAD;MACE,YAAW;MACX,OAAO;OACL;QACE,IAAI;QACJ,OAAO,EAAG,uCAAuC,mBAAmB;QACpE,aAAa,EACX,2CACA,yDACD;QACD,eAAe,EAAS,EAAS,GAAU,cAAc,CAAC;QAC3D;OACD;QACE,IAAI;QACJ,OAAO,EAAG,wCAAwC,oBAAoB;QACtE,aAAa,EACX,4CACA,iDACD;QACD,eAAe,EAAS,EAAS,GAAU,QAAQ,CAAC;QACrD;OACD;QACE,IAAI;QACJ,OAAO,EAAG,yCAAyC,yBAAyB;QAC5E,aAAa,EACX,6CACA,8CACD;QACD,eAAe,EAAS,EAAS,GAAU,QAAQ,CAAC;QACrD;OACF;MACD,CAAA;KAGF,kBAAC,GAAD,EAAA,UAAA;MACE,kBAAC,GAAD;OACE,OAAO,EAAG,wCAAwC,gBAAgB;OAClE,OAAO,EAAQ;OACf,SAAS;OACT,MAAA;OACA,MAAM,kBAAC,GAAD,EAAW,WAAU,kCAAmC,CAAA;OAC9D,CAAA;MACF,kBAAC,GAAD;OACE,OAAO,EAAG,yCAAyC,gBAAgB;OACnE,OAAO,EAAQ;OACf,SAAS;OACT,MAAM,kBAAC,GAAD,EAAW,WAAU,+BAAgC,CAAA;OAC3D,CAAA;MACF,kBAAC,GAAD;OACE,OAAO,EAAG,4CAA4C,oBAAoB;OAC1E,OAAO,EAAQ;OACf,SAAS;OACT,MAAM,kBAAC,GAAD,EAAQ,WAAU,oCAAqC,CAAA;OAC7D,CAAA;MACF,kBAAC,GAAD;OACE,OAAO,EAAG,sCAAsC,cAAc;OAC9D,OAAO,EAAQ;OACf,SAAS;OACT,MAAM,kBAAC,GAAD,EAAO,WAAU,+BAAgC,CAAA;OACvD,CAAA;MACU,EAAA,CAAA;KAGd,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD;QAAc,YAAY;QAAgB,SAAS;QAAmB,CAAA;OAClE,CAAA,EACN,kBAAC,OAAD;OAAK,WAAU;iBACb,kBAAC,GAAD,EAAY,OAAO,GAAc,CAAA;OAC7B,CAAA,CACF;;KACF;;GACK,CAAA;EACG,CAAA"}