@withpotter/pages-admin 0.13.0-next.74 → 0.13.0-next.77
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/_shell/nav-fold.js +1 -1
- package/dist/admin/_shell/nav-fold.js.map +1 -1
- package/dist/admin/_shell/nav-group.js +2 -2
- package/dist/admin/_shell/nav-group.js.map +1 -1
- package/dist/admin/_shell/sidebar.js +6 -3
- package/dist/admin/_shell/sidebar.js.map +1 -1
- package/dist/admin/_shell/use-open-groups.js +20 -0
- package/dist/admin/_shell/use-open-groups.js.map +1 -0
- package/dist/admin/accounts/account-panel.js +15 -4
- package/dist/admin/accounts/account-panel.js.map +1 -1
- package/dist/admin/accounts/account-panel.module.css +21 -0
- package/dist/admin/accounts/account-row.js +11 -2
- package/dist/admin/accounts/account-row.js.map +1 -1
- package/dist/admin/accounts/account-sessions.js +51 -0
- package/dist/admin/accounts/account-sessions.js.map +1 -0
- package/dist/admin/accounts/account-sessions.module.css +53 -0
- package/dist/admin/accounts/account-stage-filter.js +29 -0
- package/dist/admin/accounts/account-stage-filter.js.map +1 -0
- package/dist/admin/accounts/account-stage.js +47 -0
- package/dist/admin/accounts/account-stage.js.map +1 -0
- package/dist/admin/accounts/accounts-table.js +39 -8
- package/dist/admin/accounts/accounts-table.js.map +1 -1
- package/dist/admin/accounts/hint.js +12 -0
- package/dist/admin/accounts/hint.js.map +1 -0
- package/dist/admin/accounts/rows.module.css +17 -0
- package/dist/admin/hooks.js +8 -0
- package/dist/admin/hooks.js.map +1 -1
- package/dist/admin/settings/account-tab.js +1 -25
- package/dist/admin/settings/account-tab.js.map +1 -1
- package/dist/admin/tenants/tenant-list-row.js +2 -1
- package/dist/admin/tenants/tenant-list-row.js.map +1 -1
- package/dist/admin/tenants/tenants-table.js +2 -1
- package/dist/admin/tenants/tenants-table.js.map +1 -1
- package/package.json +5 -5
- package/dist/admin/_shell/use-open-group.js +0 -16
- package/dist/admin/_shell/use-open-group.js.map +0 -1
- package/dist/admin/settings/system-status-card.js +0 -30
- package/dist/admin/settings/system-status-card.js.map +0 -1
|
@@ -3,7 +3,9 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { Button, OverflowItem, OverflowMenu, Th } from "@withpotter/ui-kit";
|
|
5
5
|
import { toCsv } from "@withpotter/lib/csv";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
platformAdminApi
|
|
8
|
+
} from "@withpotter/lib/admin-api";
|
|
7
9
|
import {
|
|
8
10
|
ColumnPicker,
|
|
9
11
|
FilterDates,
|
|
@@ -13,20 +15,27 @@ import {
|
|
|
13
15
|
import { usePlatformAccounts } from "../hooks";
|
|
14
16
|
import { AccountPanel } from "./account-panel";
|
|
15
17
|
import { ListCard, ListPager } from "../_ui/list-card";
|
|
18
|
+
import { ACTIVE_HINT, kycLabel, STAGE_LABELS } from "./account-stage";
|
|
19
|
+
import { AccountStageFilter } from "./account-stage-filter";
|
|
20
|
+
import { Hint } from "./hint";
|
|
16
21
|
import { AccountListRow, PROVIDER_LABELS } from "./account-row";
|
|
17
22
|
import { PROVIDER_LABELS as PROVIDER_LABELS2 } from "./account-row";
|
|
18
23
|
const OPTIONAL_COLUMNS = [
|
|
19
24
|
{ key: "provider", label: "Provider" },
|
|
25
|
+
{ key: "kyc", label: "KYC / KYB" },
|
|
26
|
+
{ key: "stage", label: "Stage" },
|
|
20
27
|
{ key: "emailVerified", label: "Email verified" },
|
|
21
28
|
{ key: "workspaces", label: "Workspaces" },
|
|
22
29
|
{ key: "lastLogin", label: "Last login" },
|
|
23
30
|
{ key: "joined", label: "Joined" },
|
|
24
|
-
{ key: "
|
|
31
|
+
{ key: "firstSale", label: "First sale" },
|
|
25
32
|
{ key: "activeSessions", label: "Active sessions" },
|
|
26
33
|
{ key: "lastSeen", label: "Last seen" }
|
|
27
34
|
];
|
|
28
35
|
const DEFAULT_VISIBLE = [
|
|
29
36
|
"provider",
|
|
37
|
+
"kyc",
|
|
38
|
+
"stage",
|
|
30
39
|
"emailVerified",
|
|
31
40
|
"workspaces",
|
|
32
41
|
"lastLogin",
|
|
@@ -55,13 +64,15 @@ function toCsvRow(a, visible) {
|
|
|
55
64
|
cells.push(PROVIDER_LABELS[a.authProvider] ?? a.authProvider);
|
|
56
65
|
}
|
|
57
66
|
cells.push(a.status);
|
|
67
|
+
if (visible.has("kyc")) cells.push(kycLabel(a.kycStatus) ?? "");
|
|
68
|
+
if (visible.has("stage")) cells.push(a.stage ? STAGE_LABELS[a.stage] : "");
|
|
58
69
|
if (visible.has("emailVerified")) {
|
|
59
70
|
cells.push(a.emailVerified ? "Verified" : "Unverified");
|
|
60
71
|
}
|
|
61
72
|
if (visible.has("workspaces")) cells.push(String(a.workspaceCount ?? 0));
|
|
62
73
|
if (visible.has("lastLogin")) cells.push(day(a.lastLoginAt) || "Never");
|
|
63
74
|
if (visible.has("joined")) cells.push(day(a.createdAt));
|
|
64
|
-
if (visible.has("
|
|
75
|
+
if (visible.has("firstSale")) cells.push(day(a.firstSaleAt) || "None yet");
|
|
65
76
|
if (visible.has("activeSessions")) cells.push(String(a.activeSessions ?? 0));
|
|
66
77
|
if (visible.has("lastSeen")) cells.push(day(a.lastSeenAt) || "Never");
|
|
67
78
|
return cells;
|
|
@@ -73,6 +84,7 @@ function AccountsTable({
|
|
|
73
84
|
const [search, setSearch] = useState("");
|
|
74
85
|
const [joinedFrom, setJoinedFrom] = useState("");
|
|
75
86
|
const [joinedTo, setJoinedTo] = useState("");
|
|
87
|
+
const [stage, setStage] = useState("");
|
|
76
88
|
const [page, setPage] = useState(1);
|
|
77
89
|
const [visible, setVisible] = useState(readVisibleColumns);
|
|
78
90
|
const [exporting, setExporting] = useState(false);
|
|
@@ -81,7 +93,8 @@ function AccountsTable({
|
|
|
81
93
|
pageSize: 20,
|
|
82
94
|
search: search || void 0,
|
|
83
95
|
joinedFrom: joinedFrom || void 0,
|
|
84
|
-
joinedTo: joinedTo || void 0
|
|
96
|
+
joinedTo: joinedTo || void 0,
|
|
97
|
+
stage: stage || void 0
|
|
85
98
|
});
|
|
86
99
|
const current = data?.rows.find((row) => row.id === selected?.id) ?? selected;
|
|
87
100
|
const totalPages = data ? Math.max(1, Math.ceil(data.total / data.pageSize)) : 1;
|
|
@@ -100,16 +113,19 @@ function AccountsTable({
|
|
|
100
113
|
pageSize: 5e3,
|
|
101
114
|
search: search || void 0,
|
|
102
115
|
joinedFrom: joinedFrom || void 0,
|
|
103
|
-
joinedTo: joinedTo || void 0
|
|
116
|
+
joinedTo: joinedTo || void 0,
|
|
117
|
+
stage: stage || void 0
|
|
104
118
|
});
|
|
105
119
|
const header = ["Name", "Email"];
|
|
106
120
|
if (visible.has("provider")) header.push("Provider");
|
|
107
121
|
header.push("Status");
|
|
122
|
+
if (visible.has("kyc")) header.push("KYC / KYB");
|
|
123
|
+
if (visible.has("stage")) header.push("Stage");
|
|
108
124
|
if (visible.has("emailVerified")) header.push("Email verified");
|
|
109
125
|
if (visible.has("workspaces")) header.push("Workspaces");
|
|
110
126
|
if (visible.has("lastLogin")) header.push("Last login");
|
|
111
127
|
if (visible.has("joined")) header.push("Joined");
|
|
112
|
-
if (visible.has("
|
|
128
|
+
if (visible.has("firstSale")) header.push("First sale");
|
|
113
129
|
if (visible.has("activeSessions")) header.push("Active sessions");
|
|
114
130
|
if (visible.has("lastSeen")) header.push("Last seen");
|
|
115
131
|
const rows = [header, ...page2.rows.map((a2) => toCsvRow(a2, visible))];
|
|
@@ -139,7 +155,7 @@ function AccountsTable({
|
|
|
139
155
|
onRetry: () => void refetch(),
|
|
140
156
|
errorTitle: "Failed to load accounts.",
|
|
141
157
|
isEmpty: data?.rows.length === 0,
|
|
142
|
-
emptyTitle: "No accounts match
|
|
158
|
+
emptyTitle: "No accounts match these filters.",
|
|
143
159
|
controls: /* @__PURE__ */ jsxs(Filters, { label: "Filter accounts", children: [
|
|
144
160
|
/* @__PURE__ */ jsx(
|
|
145
161
|
FilterSearch,
|
|
@@ -149,6 +165,16 @@ function AccountsTable({
|
|
|
149
165
|
placeholder: "Search by email or name\u2026"
|
|
150
166
|
}
|
|
151
167
|
),
|
|
168
|
+
/* @__PURE__ */ jsx(
|
|
169
|
+
AccountStageFilter,
|
|
170
|
+
{
|
|
171
|
+
value: stage,
|
|
172
|
+
onChange: (v) => {
|
|
173
|
+
setStage(v);
|
|
174
|
+
setPage(1);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
),
|
|
152
178
|
/* @__PURE__ */ jsx(
|
|
153
179
|
FilterDates,
|
|
154
180
|
{
|
|
@@ -194,11 +220,16 @@ function AccountsTable({
|
|
|
194
220
|
/* @__PURE__ */ jsx(Th, { children: "Account" }),
|
|
195
221
|
visible.has("provider") && /* @__PURE__ */ jsx(Th, { children: "Provider" }),
|
|
196
222
|
/* @__PURE__ */ jsx(Th, { children: "Status" }),
|
|
223
|
+
visible.has("kyc") && /* @__PURE__ */ jsx(Th, { children: "KYC / KYB" }),
|
|
224
|
+
visible.has("stage") && /* @__PURE__ */ jsxs(Th, { children: [
|
|
225
|
+
"Stage",
|
|
226
|
+
/* @__PURE__ */ jsx(Hint, { label: ACTIVE_HINT })
|
|
227
|
+
] }),
|
|
197
228
|
visible.has("emailVerified") && /* @__PURE__ */ jsx(Th, { children: "Email" }),
|
|
198
229
|
visible.has("workspaces") && /* @__PURE__ */ jsx(Th, { align: "right", children: "Workspaces" }),
|
|
199
230
|
visible.has("lastLogin") && /* @__PURE__ */ jsx(Th, { children: "Last login" }),
|
|
200
231
|
visible.has("joined") && /* @__PURE__ */ jsx(Th, { children: "Joined" }),
|
|
201
|
-
visible.has("
|
|
232
|
+
visible.has("firstSale") && /* @__PURE__ */ jsx(Th, { children: "First sale" }),
|
|
202
233
|
visible.has("activeSessions") && /* @__PURE__ */ jsx(Th, { align: "right", children: "Sessions" }),
|
|
203
234
|
visible.has("lastSeen") && /* @__PURE__ */ jsx(Th, { children: "Last seen" }),
|
|
204
235
|
/* @__PURE__ */ jsx(Th, { align: "right", children: /* @__PURE__ */ jsx("span", { className: "sr-only", children: "Actions" }) })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/accounts/accounts-table.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Button, OverflowItem, OverflowMenu, Th } from '@withpotter/ui-kit';\nimport { toCsv } from '@withpotter/lib/csv';\nimport { platformAdminApi, type AccountRow } from '@withpotter/lib/admin-api';\nimport {\n ColumnPicker,\n FilterDates,\n FilterSearch,\n Filters,\n type ColumnOption,\n} from '../_ui';\nimport { usePlatformAccounts } from '../hooks';\nimport { AccountPanel, type AccountSummary } from './account-panel';\nimport { ListCard, ListPager } from '../_ui/list-card';\nimport { AccountListRow, PROVIDER_LABELS } from './account-row';\n\nexport { PROVIDER_LABELS } from './account-row';\n\nconst OPTIONAL_COLUMNS: ColumnOption[] = [\n { key: 'provider', label: 'Provider' },\n { key: 'emailVerified', label: 'Email verified' },\n { key: 'workspaces', label: 'Workspaces' },\n { key: 'lastLogin', label: 'Last login' },\n { key: 'joined', label: 'Joined' },\n { key: 'mfa', label: 'MFA enabled' },\n { key: 'activeSessions', label: 'Active sessions' },\n { key: 'lastSeen', label: 'Last seen' },\n];\nconst DEFAULT_VISIBLE = [\n 'provider',\n 'emailVerified',\n 'workspaces',\n 'lastLogin',\n 'joined',\n];\nconst COLUMNS_KEY = 'adm-accounts-columns';\n\nfunction readVisibleColumns(): Set<string> {\n if (typeof window === 'undefined') return new Set(DEFAULT_VISIBLE);\n try {\n const raw = window.localStorage.getItem(COLUMNS_KEY);\n return raw\n ? new Set(raw.split(',').filter(Boolean))\n : new Set(DEFAULT_VISIBLE);\n } catch {\n return new Set(DEFAULT_VISIBLE);\n }\n}\n\nfunction writeVisibleColumns(cols: Set<string>): void {\n try {\n window.localStorage.setItem(COLUMNS_KEY, [...cols].join(','));\n } catch {\n /* storage unavailable (private mode / quota) — non-fatal */\n }\n}\n\nconst day = (iso?: string | null) =>\n iso ? new Date(iso).toLocaleDateString() : '';\n\n/** One row's values, in the same column order the table renders. */\nfunction toCsvRow(a: AccountRow, visible: Set<string>): string[] {\n const cells: string[] = [a.name ?? '', a.email];\n if (visible.has('provider')) {\n cells.push(PROVIDER_LABELS[a.authProvider] ?? a.authProvider);\n }\n cells.push(a.status);\n if (visible.has('emailVerified')) {\n cells.push(a.emailVerified ? 'Verified' : 'Unverified');\n }\n if (visible.has('workspaces')) cells.push(String(a.workspaceCount ?? 0));\n if (visible.has('lastLogin')) cells.push(day(a.lastLoginAt) || 'Never');\n if (visible.has('joined')) cells.push(day(a.createdAt));\n if (visible.has('mfa')) cells.push(a.mfaEnabled ? 'Yes' : 'No');\n if (visible.has('activeSessions')) cells.push(String(a.activeSessions ?? 0));\n if (visible.has('lastSeen')) cells.push(day(a.lastSeenAt) || 'Never');\n return cells;\n}\n\n/** Every account, searchable and filterable by join date. */\nexport function AccountsTable({\n selected,\n onSelect,\n}: {\n selected: AccountSummary | null;\n onSelect: (account: AccountSummary | null) => void;\n}) {\n const [search, setSearch] = useState('');\n const [joinedFrom, setJoinedFrom] = useState('');\n const [joinedTo, setJoinedTo] = useState('');\n const [page, setPage] = useState(1);\n const [visible, setVisible] = useState<Set<string>>(readVisibleColumns);\n const [exporting, setExporting] = useState(false);\n const { data, isLoading, isError, refetch } = usePlatformAccounts({\n page,\n pageSize: 20,\n search: search || undefined,\n joinedFrom: joinedFrom || undefined,\n joinedTo: joinedTo || undefined,\n });\n // Show the freshest copy of the selected account after an action refetches.\n const current = data?.rows.find((row) => row.id === selected?.id) ?? selected;\n const totalPages = data\n ? Math.max(1, Math.ceil(data.total / data.pageSize))\n : 1;\n const filter = (set: (v: string) => void) => (v: string) => {\n set(v);\n setPage(1);\n };\n\n const changeColumns = (next: Set<string>) => {\n setVisible(next);\n writeVisibleColumns(next);\n };\n\n // Every account matching the current search/join-date filter, not just\n // this page — a export of \"what I'm looking at\" that stops at 20 rows\n // because of pagination would just be confusing.\n const exportCsv = async () => {\n setExporting(true);\n try {\n const page = await platformAdminApi.accounts({\n pageSize: 5000,\n search: search || undefined,\n joinedFrom: joinedFrom || undefined,\n joinedTo: joinedTo || undefined,\n });\n const header = ['Name', 'Email'];\n if (visible.has('provider')) header.push('Provider');\n header.push('Status');\n if (visible.has('emailVerified')) header.push('Email verified');\n if (visible.has('workspaces')) header.push('Workspaces');\n if (visible.has('lastLogin')) header.push('Last login');\n if (visible.has('joined')) header.push('Joined');\n if (visible.has('mfa')) header.push('MFA enabled');\n if (visible.has('activeSessions')) header.push('Active sessions');\n if (visible.has('lastSeen')) header.push('Last seen');\n const rows = [header, ...page.rows.map((a) => toCsvRow(a, visible))];\n const url = URL.createObjectURL(\n new Blob([toCsv(rows)], { type: 'text/csv' }),\n );\n const a = document.createElement('a');\n a.href = url;\n a.download = 'accounts.csv';\n a.click();\n URL.revokeObjectURL(url);\n } finally {\n setExporting(false);\n }\n };\n\n const columns = 3 + visible.size; // Account + Status + Actions, plus optional\n\n return (\n <>\n <ListCard\n title=\"All accounts\"\n count={data?.total}\n columns={columns}\n minWidth={880}\n isLoading={isLoading}\n isError={isError}\n onRetry={() => void refetch()}\n errorTitle=\"Failed to load accounts.\"\n isEmpty={data?.rows.length === 0}\n emptyTitle=\"No accounts match this search or join date.\"\n controls={\n <Filters label=\"Filter accounts\">\n <FilterSearch\n value={search}\n onChange={filter(setSearch)}\n placeholder=\"Search by email or name…\"\n />\n <FilterDates\n label=\"Joined\"\n fromLabel=\"Joined from\"\n toLabel=\"Joined to\"\n from={joinedFrom}\n to={joinedTo}\n onFrom={filter(setJoinedFrom)}\n onTo={filter(setJoinedTo)}\n />\n {(joinedFrom || joinedTo) && (\n <Button\n variant=\"ghost\"\n onClick={() => {\n setJoinedFrom('');\n setJoinedTo('');\n setPage(1);\n }}\n >\n Clear\n </Button>\n )}\n <ColumnPicker\n options={OPTIONAL_COLUMNS}\n visible={visible}\n onChange={changeColumns}\n />\n <OverflowMenu label=\"Export\">\n <OverflowItem\n onClick={() => void exportCsv()}\n disabled={exporting || !data?.total}\n >\n {exporting ? 'Exporting…' : 'Export CSV'}\n </OverflowItem>\n </OverflowMenu>\n </Filters>\n }\n head={\n <tr>\n <Th>Account</Th>\n {visible.has('provider') && <Th>Provider</Th>}\n <Th>Status</Th>\n {visible.has('emailVerified') && <Th>Email</Th>}\n {visible.has('workspaces') && <Th align=\"right\">Workspaces</Th>}\n {visible.has('lastLogin') && <Th>Last login</Th>}\n {visible.has('joined') && <Th>Joined</Th>}\n {visible.has('mfa') && <Th>MFA</Th>}\n {visible.has('activeSessions') && <Th align=\"right\">Sessions</Th>}\n {visible.has('lastSeen') && <Th>Last seen</Th>}\n <Th align=\"right\">\n <span className=\"sr-only\">Actions</span>\n </Th>\n </tr>\n }\n footer={\n <ListPager\n page={page}\n totalPages={totalPages}\n total={data?.total}\n noun=\"accounts\"\n onPage={setPage}\n />\n }\n >\n {data?.rows.map((a) => (\n <AccountListRow\n key={a.id}\n a={a}\n active={a.id === selected?.id}\n onOpen={() => onSelect(a)}\n visible={visible}\n />\n ))}\n </ListCard>\n <AccountPanel account={current} onClose={() => onSelect(null)} />\n </>\n );\n}\n"],"mappings":"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","names":["PROVIDER_LABELS","page","a"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/accounts/accounts-table.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Button, OverflowItem, OverflowMenu, Th } from '@withpotter/ui-kit';\nimport { toCsv } from '@withpotter/lib/csv';\nimport {\n platformAdminApi,\n type AccountRow,\n type AccountStage,\n} from '@withpotter/lib/admin-api';\nimport {\n ColumnPicker,\n FilterDates,\n FilterSearch,\n Filters,\n type ColumnOption,\n} from '../_ui';\nimport { usePlatformAccounts } from '../hooks';\nimport { AccountPanel, type AccountSummary } from './account-panel';\nimport { ListCard, ListPager } from '../_ui/list-card';\nimport { ACTIVE_HINT, kycLabel, STAGE_LABELS } from './account-stage';\nimport { AccountStageFilter } from './account-stage-filter';\nimport { Hint } from './hint';\nimport { AccountListRow, PROVIDER_LABELS } from './account-row';\n\nexport { PROVIDER_LABELS } from './account-row';\n\nconst OPTIONAL_COLUMNS: ColumnOption[] = [\n { key: 'provider', label: 'Provider' },\n { key: 'kyc', label: 'KYC / KYB' },\n { key: 'stage', label: 'Stage' },\n { key: 'emailVerified', label: 'Email verified' },\n { key: 'workspaces', label: 'Workspaces' },\n { key: 'lastLogin', label: 'Last login' },\n { key: 'joined', label: 'Joined' },\n { key: 'firstSale', label: 'First sale' },\n { key: 'activeSessions', label: 'Active sessions' },\n { key: 'lastSeen', label: 'Last seen' },\n];\nconst DEFAULT_VISIBLE = [\n 'provider',\n 'kyc',\n 'stage',\n 'emailVerified',\n 'workspaces',\n 'lastLogin',\n 'joined',\n];\nconst COLUMNS_KEY = 'adm-accounts-columns';\n\nfunction readVisibleColumns(): Set<string> {\n if (typeof window === 'undefined') return new Set(DEFAULT_VISIBLE);\n try {\n const raw = window.localStorage.getItem(COLUMNS_KEY);\n return raw\n ? new Set(raw.split(',').filter(Boolean))\n : new Set(DEFAULT_VISIBLE);\n } catch {\n return new Set(DEFAULT_VISIBLE);\n }\n}\n\nfunction writeVisibleColumns(cols: Set<string>): void {\n try {\n window.localStorage.setItem(COLUMNS_KEY, [...cols].join(','));\n } catch {\n /* storage unavailable (private mode / quota) — non-fatal */\n }\n}\n\nconst day = (iso?: string | null) =>\n iso ? new Date(iso).toLocaleDateString() : '';\n\n/** One row's values, in the same column order the table renders. */\nfunction toCsvRow(a: AccountRow, visible: Set<string>): string[] {\n const cells: string[] = [a.name ?? '', a.email];\n if (visible.has('provider')) {\n cells.push(PROVIDER_LABELS[a.authProvider] ?? a.authProvider);\n }\n cells.push(a.status);\n if (visible.has('kyc')) cells.push(kycLabel(a.kycStatus) ?? '');\n if (visible.has('stage')) cells.push(a.stage ? STAGE_LABELS[a.stage] : '');\n if (visible.has('emailVerified')) {\n cells.push(a.emailVerified ? 'Verified' : 'Unverified');\n }\n if (visible.has('workspaces')) cells.push(String(a.workspaceCount ?? 0));\n if (visible.has('lastLogin')) cells.push(day(a.lastLoginAt) || 'Never');\n if (visible.has('joined')) cells.push(day(a.createdAt));\n if (visible.has('firstSale')) cells.push(day(a.firstSaleAt) || 'None yet');\n if (visible.has('activeSessions')) cells.push(String(a.activeSessions ?? 0));\n if (visible.has('lastSeen')) cells.push(day(a.lastSeenAt) || 'Never');\n return cells;\n}\n\n/** Every account, searchable and filterable by stage and join date. */\nexport function AccountsTable({\n selected,\n onSelect,\n}: {\n selected: AccountSummary | null;\n onSelect: (account: AccountSummary | null) => void;\n}) {\n const [search, setSearch] = useState('');\n const [joinedFrom, setJoinedFrom] = useState('');\n const [joinedTo, setJoinedTo] = useState('');\n const [stage, setStage] = useState<AccountStage | ''>('');\n const [page, setPage] = useState(1);\n const [visible, setVisible] = useState<Set<string>>(readVisibleColumns);\n const [exporting, setExporting] = useState(false);\n const { data, isLoading, isError, refetch } = usePlatformAccounts({\n page,\n pageSize: 20,\n search: search || undefined,\n joinedFrom: joinedFrom || undefined,\n joinedTo: joinedTo || undefined,\n stage: stage || undefined,\n });\n // Show the freshest copy of the selected account after an action refetches.\n const current = data?.rows.find((row) => row.id === selected?.id) ?? selected;\n const totalPages = data\n ? Math.max(1, Math.ceil(data.total / data.pageSize))\n : 1;\n const filter = (set: (v: string) => void) => (v: string) => {\n set(v);\n setPage(1);\n };\n\n const changeColumns = (next: Set<string>) => {\n setVisible(next);\n writeVisibleColumns(next);\n };\n\n // Every account matching the current search/join-date filter, not just\n // this page — a export of \"what I'm looking at\" that stops at 20 rows\n // because of pagination would just be confusing.\n const exportCsv = async () => {\n setExporting(true);\n try {\n const page = await platformAdminApi.accounts({\n pageSize: 5000,\n search: search || undefined,\n joinedFrom: joinedFrom || undefined,\n joinedTo: joinedTo || undefined,\n stage: stage || undefined,\n });\n const header = ['Name', 'Email'];\n if (visible.has('provider')) header.push('Provider');\n header.push('Status');\n if (visible.has('kyc')) header.push('KYC / KYB');\n if (visible.has('stage')) header.push('Stage');\n if (visible.has('emailVerified')) header.push('Email verified');\n if (visible.has('workspaces')) header.push('Workspaces');\n if (visible.has('lastLogin')) header.push('Last login');\n if (visible.has('joined')) header.push('Joined');\n if (visible.has('firstSale')) header.push('First sale');\n if (visible.has('activeSessions')) header.push('Active sessions');\n if (visible.has('lastSeen')) header.push('Last seen');\n const rows = [header, ...page.rows.map((a) => toCsvRow(a, visible))];\n const url = URL.createObjectURL(\n new Blob([toCsv(rows)], { type: 'text/csv' }),\n );\n const a = document.createElement('a');\n a.href = url;\n a.download = 'accounts.csv';\n a.click();\n URL.revokeObjectURL(url);\n } finally {\n setExporting(false);\n }\n };\n\n const columns = 3 + visible.size; // Account + Status + Actions, plus optional\n\n return (\n <>\n <ListCard\n title=\"All accounts\"\n count={data?.total}\n columns={columns}\n minWidth={880}\n isLoading={isLoading}\n isError={isError}\n onRetry={() => void refetch()}\n errorTitle=\"Failed to load accounts.\"\n isEmpty={data?.rows.length === 0}\n emptyTitle=\"No accounts match these filters.\"\n controls={\n <Filters label=\"Filter accounts\">\n <FilterSearch\n value={search}\n onChange={filter(setSearch)}\n placeholder=\"Search by email or name…\"\n />\n <AccountStageFilter\n value={stage}\n onChange={(v: AccountStage | '') => {\n setStage(v);\n setPage(1);\n }}\n />\n <FilterDates\n label=\"Joined\"\n fromLabel=\"Joined from\"\n toLabel=\"Joined to\"\n from={joinedFrom}\n to={joinedTo}\n onFrom={filter(setJoinedFrom)}\n onTo={filter(setJoinedTo)}\n />\n {(joinedFrom || joinedTo) && (\n <Button\n variant=\"ghost\"\n onClick={() => {\n setJoinedFrom('');\n setJoinedTo('');\n setPage(1);\n }}\n >\n Clear\n </Button>\n )}\n <ColumnPicker\n options={OPTIONAL_COLUMNS}\n visible={visible}\n onChange={changeColumns}\n />\n <OverflowMenu label=\"Export\">\n <OverflowItem\n onClick={() => void exportCsv()}\n disabled={exporting || !data?.total}\n >\n {exporting ? 'Exporting…' : 'Export CSV'}\n </OverflowItem>\n </OverflowMenu>\n </Filters>\n }\n head={\n <tr>\n <Th>Account</Th>\n {visible.has('provider') && <Th>Provider</Th>}\n <Th>Status</Th>\n {visible.has('kyc') && <Th>KYC / KYB</Th>}\n {visible.has('stage') && (\n <Th>\n Stage\n <Hint label={ACTIVE_HINT} />\n </Th>\n )}\n {visible.has('emailVerified') && <Th>Email</Th>}\n {visible.has('workspaces') && <Th align=\"right\">Workspaces</Th>}\n {visible.has('lastLogin') && <Th>Last login</Th>}\n {visible.has('joined') && <Th>Joined</Th>}\n {visible.has('firstSale') && <Th>First sale</Th>}\n {visible.has('activeSessions') && <Th align=\"right\">Sessions</Th>}\n {visible.has('lastSeen') && <Th>Last seen</Th>}\n <Th align=\"right\">\n <span className=\"sr-only\">Actions</span>\n </Th>\n </tr>\n }\n footer={\n <ListPager\n page={page}\n totalPages={totalPages}\n total={data?.total}\n noun=\"accounts\"\n onPage={setPage}\n />\n }\n >\n {data?.rows.map((a) => (\n <AccountListRow\n key={a.id}\n a={a}\n active={a.id === selected?.id}\n onOpen={() => onSelect(a)}\n visible={visible}\n />\n ))}\n </ListCard>\n <AccountPanel account={current} onClose={() => onSelect(null)} />\n </>\n );\n}\n"],"mappings":"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","names":["PROVIDER_LABELS","page","a"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Info } from "lucide-react";
|
|
4
|
+
import { Tooltip } from "@withpotter/ui-kit";
|
|
5
|
+
import styles from "./rows.module.css";
|
|
6
|
+
function Hint({ label }) {
|
|
7
|
+
return /* @__PURE__ */ jsx(Tooltip, { label, children: /* @__PURE__ */ jsx("button", { type: "button", className: styles.hint, "aria-label": label, children: /* @__PURE__ */ jsx(Info, { size: 13, "aria-hidden": true }) }) });
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
Hint
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=hint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/accounts/hint.tsx"],"sourcesContent":["'use client';\n\nimport { Info } from 'lucide-react';\nimport { Tooltip } from '@withpotter/ui-kit';\nimport styles from './rows.module.css';\n\n/** A small info icon that explains a term on hover or focus. */\nexport function Hint({ label }: { label: string }) {\n return (\n <Tooltip label={label}>\n <button type=\"button\" className={styles.hint} aria-label={label}>\n <Info size={13} aria-hidden />\n </button>\n </Tooltip>\n );\n}\n"],"mappings":";AAWQ;AATR,SAAS,YAAY;AACrB,SAAS,eAAe;AACxB,OAAO,YAAY;AAGZ,SAAS,KAAK,EAAE,MAAM,GAAsB;AACjD,SACE,oBAAC,WAAQ,OACP,8BAAC,YAAO,MAAK,UAAS,WAAW,OAAO,MAAM,cAAY,OACxD,8BAAC,QAAK,MAAM,IAAI,eAAW,MAAC,GAC9B,GACF;AAEJ;","names":[]}
|
|
@@ -65,3 +65,20 @@
|
|
|
65
65
|
font-variant-numeric: tabular-nums;
|
|
66
66
|
cursor: default;
|
|
67
67
|
}
|
|
68
|
+
|
|
69
|
+
.hint {
|
|
70
|
+
display: inline-flex;
|
|
71
|
+
align-items: center;
|
|
72
|
+
margin-left: 4px;
|
|
73
|
+
padding: 0;
|
|
74
|
+
border: 0;
|
|
75
|
+
background: none;
|
|
76
|
+
vertical-align: middle;
|
|
77
|
+
color: var(--text-tertiary);
|
|
78
|
+
cursor: help;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.hint:hover,
|
|
82
|
+
.hint:focus-visible {
|
|
83
|
+
color: var(--text-primary);
|
|
84
|
+
}
|
package/dist/admin/hooks.js
CHANGED
|
@@ -168,6 +168,13 @@ function useAdminRoles() {
|
|
|
168
168
|
queryFn: () => platformAdminApi.roles()
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
|
+
function useAccountSessions(id) {
|
|
172
|
+
return useQuery({
|
|
173
|
+
queryKey: ["platform-admin", "account-sessions", id],
|
|
174
|
+
queryFn: () => platformAdminApi.accountSessions(id),
|
|
175
|
+
enabled: !!id
|
|
176
|
+
});
|
|
177
|
+
}
|
|
171
178
|
function useAccountTenants(id) {
|
|
172
179
|
return useQuery({
|
|
173
180
|
queryKey: ["platform-admin", "account-tenants", id],
|
|
@@ -188,6 +195,7 @@ function usePlatformAuditAnalytics(range = {}) {
|
|
|
188
195
|
});
|
|
189
196
|
}
|
|
190
197
|
export {
|
|
198
|
+
useAccountSessions,
|
|
191
199
|
useAccountTenants,
|
|
192
200
|
useAdminPermissions,
|
|
193
201
|
useAdminRoles,
|
package/dist/admin/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/admin/hooks.ts"],"sourcesContent":["'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { platformAdminApi } from '@withpotter/lib/admin-api';\nimport type { TenantListParams } from '@withpotter/lib/admin-tenants-query';\n\nexport function useAdminSession(enabled = true) {\n return useQuery({\n queryKey: ['platform-admin', 'session'],\n queryFn: () => platformAdminApi.me(),\n enabled,\n retry: false,\n staleTime: 60_000,\n });\n}\n\nexport function usePlatformOverview() {\n return useQuery({\n queryKey: ['platform-admin', 'overview'],\n queryFn: () => platformAdminApi.overview(),\n });\n}\n\nexport function usePlatformCockpit(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'cockpit', range],\n queryFn: () => platformAdminApi.cockpit(range),\n });\n}\n\nexport function usePlatformRevenue(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'revenue', range],\n queryFn: () => platformAdminApi.revenue(range),\n });\n}\n\nexport function usePlatformTenantsAnalytics(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenants-analytics', range],\n queryFn: () => platformAdminApi.tenantsAnalytics(range),\n });\n}\n\nexport function usePlatformTenants(params: TenantListParams) {\n return useQuery({\n queryKey: ['platform-admin', 'tenants', params],\n queryFn: () => platformAdminApi.tenants(params),\n });\n}\n\nexport function usePlatformTenant(\n id: string,\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant', id, range],\n queryFn: () => platformAdminApi.tenant(id, range),\n enabled: !!id,\n });\n}\n\nexport function useTenantAnalytics(\n id: string,\n range: { startDate?: string; endDate?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-analytics', id, range],\n queryFn: () => platformAdminApi.tenantAnalytics(id, range),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantFinance(\n id: string,\n range: { startDate?: string; endDate?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-finance', id, range],\n queryFn: () => platformAdminApi.tenantFinance(id, range),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantTransactions(\n id: string,\n params: {\n status?: string;\n type?: string;\n search?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-transactions', id, params],\n queryFn: () => platformAdminApi.tenantTransactions(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantCustomers(\n id: string,\n params: {\n search?: string;\n type?: string;\n status?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-customers', id, params],\n queryFn: () => platformAdminApi.tenantCustomers(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantProducts(\n id: string,\n params: { type?: string; search?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-products', id, params],\n queryFn: () => platformAdminApi.tenantProducts(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantProductInsights(\n id: string,\n range: { startDate?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-product-insights', id, range],\n queryFn: () => platformAdminApi.tenantProductInsights(id, range),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantCustomerInsights(\n id: string,\n range: { startDate?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-customer-insights', id, range],\n queryFn: () => platformAdminApi.tenantCustomerInsights(id, range),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantInvoices(\n id: string,\n params: {\n status?: string;\n search?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-invoices', id, params],\n queryFn: () => platformAdminApi.tenantInvoices(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantLoyalty(id: string, enabled = true) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-loyalty', id],\n queryFn: () => platformAdminApi.tenantLoyalty(id),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantDiscounts(\n id: string,\n params: {\n status?: string;\n discountType?: string;\n search?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-discounts', id, params],\n queryFn: () => platformAdminApi.tenantDiscounts(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantSettlements(\n id: string,\n params: {\n page?: number;\n limit?: number;\n startDate?: string;\n endDate?: string;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-settlements', id, params],\n queryFn: () => platformAdminApi.tenantSettlements(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantSubscriptions(\n id: string,\n params: {\n status?: string;\n planId?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-subscriptions', id, params],\n queryFn: () => platformAdminApi.tenantSubscriptions(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function usePlatformAccounts(params: {\n page?: number;\n pageSize?: number;\n search?: string;\n joinedFrom?: string;\n joinedTo?: string;\n}) {\n return useQuery({\n queryKey: ['platform-admin', 'accounts', params],\n queryFn: () => platformAdminApi.accounts(params),\n });\n}\n\nexport function usePlatformAccountsAnalytics(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'accounts-analytics', range],\n queryFn: () => platformAdminApi.accountsAnalytics(range),\n });\n}\n\nexport function usePlatformAdmins() {\n return useQuery({\n queryKey: ['platform-admin', 'admins'],\n queryFn: () => platformAdminApi.admins(),\n });\n}\n\nexport function usePlatformAdminsAnalytics(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'admins-analytics', range],\n queryFn: () => platformAdminApi.adminsAnalytics(range),\n });\n}\n\nexport function useAdminPermissions() {\n return useQuery({\n queryKey: ['platform-admin', 'admin-permissions'],\n queryFn: () => platformAdminApi.adminPermissions(),\n staleTime: 5 * 60_000,\n });\n}\n\nexport function useAdminRoles() {\n return useQuery({\n queryKey: ['platform-admin', 'roles'],\n queryFn: () => platformAdminApi.roles(),\n });\n}\n\nexport function useAccountTenants(id: string | null) {\n return useQuery({\n queryKey: ['platform-admin', 'account-tenants', id],\n queryFn: () => platformAdminApi.accountTenants(id!),\n enabled: !!id,\n });\n}\n\nexport function usePlatformAudit(\n params: {\n page?: number;\n pageSize?: number;\n search?: string;\n action?: string;\n adminEmail?: string;\n from?: string;\n to?: string;\n } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'audit', params],\n queryFn: () => platformAdminApi.audit(params),\n });\n}\n\nexport function usePlatformAuditAnalytics(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'audit-analytics', range],\n queryFn: () => platformAdminApi.auditAnalytics(range),\n });\n}\n"],"mappings":";AAEA,SAAS,gBAAgB;AACzB,SAAS,wBAAwB;AAG1B,SAAS,gBAAgB,UAAU,MAAM;AAC9C,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,SAAS;AAAA,IACtC,SAAS,MAAM,iBAAiB,GAAG;AAAA,IACnC;AAAA,IACA,OAAO;AAAA,IACP,WAAW;AAAA,EACb,CAAC;AACH;AAEO,SAAS,sBAAsB;AACpC,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,UAAU;AAAA,IACvC,SAAS,MAAM,iBAAiB,SAAS;AAAA,EAC3C,CAAC;AACH;AAEO,SAAS,mBACd,QAAkD,CAAC,GACnD;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,WAAW,KAAK;AAAA,IAC7C,SAAS,MAAM,iBAAiB,QAAQ,KAAK;AAAA,EAC/C,CAAC;AACH;AAEO,SAAS,mBACd,QAAkD,CAAC,GACnD;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,WAAW,KAAK;AAAA,IAC7C,SAAS,MAAM,iBAAiB,QAAQ,KAAK;AAAA,EAC/C,CAAC;AACH;AAEO,SAAS,4BACd,QAAkD,CAAC,GACnD;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,qBAAqB,KAAK;AAAA,IACvD,SAAS,MAAM,iBAAiB,iBAAiB,KAAK;AAAA,EACxD,CAAC;AACH;AAEO,SAAS,mBAAmB,QAA0B;AAC3D,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,WAAW,MAAM;AAAA,IAC9C,SAAS,MAAM,iBAAiB,QAAQ,MAAM;AAAA,EAChD,CAAC;AACH;AAEO,SAAS,kBACd,IACA,QAAkD,CAAC,GACnD;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,UAAU,IAAI,KAAK;AAAA,IAChD,SAAS,MAAM,iBAAiB,OAAO,IAAI,KAAK;AAAA,IAChD,SAAS,CAAC,CAAC;AAAA,EACb,CAAC;AACH;AAEO,SAAS,mBACd,IACA,QAAkD,CAAC,GACnD,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,oBAAoB,IAAI,KAAK;AAAA,IAC1D,SAAS,MAAM,iBAAiB,gBAAgB,IAAI,KAAK;AAAA,IACzD,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,iBACd,IACA,QAAkD,CAAC,GACnD,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,kBAAkB,IAAI,KAAK;AAAA,IACxD,SAAS,MAAM,iBAAiB,cAAc,IAAI,KAAK;AAAA,IACvD,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,sBACd,IACA,SAMI,CAAC,GACL,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,uBAAuB,IAAI,MAAM;AAAA,IAC9D,SAAS,MAAM,iBAAiB,mBAAmB,IAAI,MAAM;AAAA,IAC7D,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,mBACd,IACA,SAMI,CAAC,GACL,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,oBAAoB,IAAI,MAAM;AAAA,IAC3D,SAAS,MAAM,iBAAiB,gBAAgB,IAAI,MAAM;AAAA,IAC1D,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,kBACd,IACA,SAA6C,CAAC,GAC9C,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,mBAAmB,IAAI,MAAM;AAAA,IAC1D,SAAS,MAAM,iBAAiB,eAAe,IAAI,MAAM;AAAA,IACzD,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,yBACd,IACA,QAAgC,CAAC,GACjC,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,2BAA2B,IAAI,KAAK;AAAA,IACjE,SAAS,MAAM,iBAAiB,sBAAsB,IAAI,KAAK;AAAA,IAC/D,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,0BACd,IACA,QAAgC,CAAC,GACjC,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,4BAA4B,IAAI,KAAK;AAAA,IAClE,SAAS,MAAM,iBAAiB,uBAAuB,IAAI,KAAK;AAAA,IAChE,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,kBACd,IACA,SAKI,CAAC,GACL,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,mBAAmB,IAAI,MAAM;AAAA,IAC1D,SAAS,MAAM,iBAAiB,eAAe,IAAI,MAAM;AAAA,IACzD,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,iBAAiB,IAAY,UAAU,MAAM;AAC3D,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,kBAAkB,EAAE;AAAA,IACjD,SAAS,MAAM,iBAAiB,cAAc,EAAE;AAAA,IAChD,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,mBACd,IACA,SAMI,CAAC,GACL,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,oBAAoB,IAAI,MAAM;AAAA,IAC3D,SAAS,MAAM,iBAAiB,gBAAgB,IAAI,MAAM;AAAA,IAC1D,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,qBACd,IACA,SAKI,CAAC,GACL,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,sBAAsB,IAAI,MAAM;AAAA,IAC7D,SAAS,MAAM,iBAAiB,kBAAkB,IAAI,MAAM;AAAA,IAC5D,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,uBACd,IACA,SAKI,CAAC,GACL,UAAU,MACV;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,wBAAwB,IAAI,MAAM;AAAA,IAC/D,SAAS,MAAM,iBAAiB,oBAAoB,IAAI,MAAM;AAAA,IAC9D,SAAS,CAAC,CAAC,MAAM;AAAA,EACnB,CAAC;AACH;AAEO,SAAS,oBAAoB,QAMjC;AACD,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,YAAY,MAAM;AAAA,IAC/C,SAAS,MAAM,iBAAiB,SAAS,MAAM;AAAA,EACjD,CAAC;AACH;AAEO,SAAS,6BACd,QAAkD,CAAC,GACnD;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,sBAAsB,KAAK;AAAA,IACxD,SAAS,MAAM,iBAAiB,kBAAkB,KAAK;AAAA,EACzD,CAAC;AACH;AAEO,SAAS,oBAAoB;AAClC,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,QAAQ;AAAA,IACrC,SAAS,MAAM,iBAAiB,OAAO;AAAA,EACzC,CAAC;AACH;AAEO,SAAS,2BACd,QAAkD,CAAC,GACnD;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,oBAAoB,KAAK;AAAA,IACtD,SAAS,MAAM,iBAAiB,gBAAgB,KAAK;AAAA,EACvD,CAAC;AACH;AAEO,SAAS,sBAAsB;AACpC,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,mBAAmB;AAAA,IAChD,SAAS,MAAM,iBAAiB,iBAAiB;AAAA,IACjD,WAAW,IAAI;AAAA,EACjB,CAAC;AACH;AAEO,SAAS,gBAAgB;AAC9B,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,OAAO;AAAA,IACpC,SAAS,MAAM,iBAAiB,MAAM;AAAA,EACxC,CAAC;AACH;AAEO,SAAS,kBAAkB,IAAmB;AACnD,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,mBAAmB,EAAE;AAAA,IAClD,SAAS,MAAM,iBAAiB,eAAe,EAAG;AAAA,IAClD,SAAS,CAAC,CAAC;AAAA,EACb,CAAC;AACH;AAEO,SAAS,iBACd,SAQI,CAAC,GACL;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,SAAS,MAAM;AAAA,IAC5C,SAAS,MAAM,iBAAiB,MAAM,MAAM;AAAA,EAC9C,CAAC;AACH;AAEO,SAAS,0BACd,QAAkD,CAAC,GACnD;AACA,SAAO,SAAS;AAAA,IACd,UAAU,CAAC,kBAAkB,mBAAmB,KAAK;AAAA,IACrD,SAAS,MAAM,iBAAiB,eAAe,KAAK;AAAA,EACtD,CAAC;AACH;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/admin/hooks.ts"],"sourcesContent":["'use client';\n\nimport { useQuery } from '@tanstack/react-query';\nimport { platformAdminApi } from '@withpotter/lib/admin-api';\nimport type { TenantListParams } from '@withpotter/lib/admin-tenants-query';\nimport type { AccountStage } from '@withpotter/lib/admin-account-types';\n\nexport function useAdminSession(enabled = true) {\n return useQuery({\n queryKey: ['platform-admin', 'session'],\n queryFn: () => platformAdminApi.me(),\n enabled,\n retry: false,\n staleTime: 60_000,\n });\n}\n\nexport function usePlatformOverview() {\n return useQuery({\n queryKey: ['platform-admin', 'overview'],\n queryFn: () => platformAdminApi.overview(),\n });\n}\n\nexport function usePlatformCockpit(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'cockpit', range],\n queryFn: () => platformAdminApi.cockpit(range),\n });\n}\n\nexport function usePlatformRevenue(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'revenue', range],\n queryFn: () => platformAdminApi.revenue(range),\n });\n}\n\nexport function usePlatformTenantsAnalytics(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenants-analytics', range],\n queryFn: () => platformAdminApi.tenantsAnalytics(range),\n });\n}\n\nexport function usePlatformTenants(params: TenantListParams) {\n return useQuery({\n queryKey: ['platform-admin', 'tenants', params],\n queryFn: () => platformAdminApi.tenants(params),\n });\n}\n\nexport function usePlatformTenant(\n id: string,\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant', id, range],\n queryFn: () => platformAdminApi.tenant(id, range),\n enabled: !!id,\n });\n}\n\nexport function useTenantAnalytics(\n id: string,\n range: { startDate?: string; endDate?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-analytics', id, range],\n queryFn: () => platformAdminApi.tenantAnalytics(id, range),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantFinance(\n id: string,\n range: { startDate?: string; endDate?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-finance', id, range],\n queryFn: () => platformAdminApi.tenantFinance(id, range),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantTransactions(\n id: string,\n params: {\n status?: string;\n type?: string;\n search?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-transactions', id, params],\n queryFn: () => platformAdminApi.tenantTransactions(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantCustomers(\n id: string,\n params: {\n search?: string;\n type?: string;\n status?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-customers', id, params],\n queryFn: () => platformAdminApi.tenantCustomers(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantProducts(\n id: string,\n params: { type?: string; search?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-products', id, params],\n queryFn: () => platformAdminApi.tenantProducts(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantProductInsights(\n id: string,\n range: { startDate?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-product-insights', id, range],\n queryFn: () => platformAdminApi.tenantProductInsights(id, range),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantCustomerInsights(\n id: string,\n range: { startDate?: string } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-customer-insights', id, range],\n queryFn: () => platformAdminApi.tenantCustomerInsights(id, range),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantInvoices(\n id: string,\n params: {\n status?: string;\n search?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-invoices', id, params],\n queryFn: () => platformAdminApi.tenantInvoices(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantLoyalty(id: string, enabled = true) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-loyalty', id],\n queryFn: () => platformAdminApi.tenantLoyalty(id),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantDiscounts(\n id: string,\n params: {\n status?: string;\n discountType?: string;\n search?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-discounts', id, params],\n queryFn: () => platformAdminApi.tenantDiscounts(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantSettlements(\n id: string,\n params: {\n page?: number;\n limit?: number;\n startDate?: string;\n endDate?: string;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-settlements', id, params],\n queryFn: () => platformAdminApi.tenantSettlements(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function useTenantSubscriptions(\n id: string,\n params: {\n status?: string;\n planId?: string;\n page?: number;\n limit?: number;\n } = {},\n enabled = true,\n) {\n return useQuery({\n queryKey: ['platform-admin', 'tenant-subscriptions', id, params],\n queryFn: () => platformAdminApi.tenantSubscriptions(id, params),\n enabled: !!id && enabled,\n });\n}\n\nexport function usePlatformAccounts(params: {\n page?: number;\n pageSize?: number;\n search?: string;\n joinedFrom?: string;\n joinedTo?: string;\n stage?: AccountStage;\n}) {\n return useQuery({\n queryKey: ['platform-admin', 'accounts', params],\n queryFn: () => platformAdminApi.accounts(params),\n });\n}\n\nexport function usePlatformAccountsAnalytics(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'accounts-analytics', range],\n queryFn: () => platformAdminApi.accountsAnalytics(range),\n });\n}\n\nexport function usePlatformAdmins() {\n return useQuery({\n queryKey: ['platform-admin', 'admins'],\n queryFn: () => platformAdminApi.admins(),\n });\n}\n\nexport function usePlatformAdminsAnalytics(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'admins-analytics', range],\n queryFn: () => platformAdminApi.adminsAnalytics(range),\n });\n}\n\nexport function useAdminPermissions() {\n return useQuery({\n queryKey: ['platform-admin', 'admin-permissions'],\n queryFn: () => platformAdminApi.adminPermissions(),\n staleTime: 5 * 60_000,\n });\n}\n\nexport function useAdminRoles() {\n return useQuery({\n queryKey: ['platform-admin', 'roles'],\n queryFn: () => platformAdminApi.roles(),\n });\n}\n\nexport function useAccountSessions(id: string | null) {\n return useQuery({\n queryKey: ['platform-admin', 'account-sessions', id],\n queryFn: () => platformAdminApi.accountSessions(id!),\n enabled: !!id,\n });\n}\n\nexport function useAccountTenants(id: string | null) {\n return useQuery({\n queryKey: ['platform-admin', 'account-tenants', id],\n queryFn: () => platformAdminApi.accountTenants(id!),\n enabled: !!id,\n });\n}\n\nexport function usePlatformAudit(\n params: {\n page?: number;\n pageSize?: number;\n search?: string;\n action?: string;\n adminEmail?: string;\n from?: string;\n to?: string;\n } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'audit', params],\n queryFn: () => platformAdminApi.audit(params),\n });\n}\n\nexport function usePlatformAuditAnalytics(\n range: { startDate?: string; endDate?: string } = {},\n) {\n return useQuery({\n queryKey: ['platform-admin', 'audit-analytics', range],\n queryFn: () => platformAdminApi.auditAnalytics(range),\n });\n}\n"],"mappings":"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","names":[]}
|
|
@@ -2,21 +2,17 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
4
|
import { useRouter } from "next/navigation";
|
|
5
|
-
import { Button
|
|
5
|
+
import { Button } from "@withpotter/ui-kit";
|
|
6
6
|
import { SUPPORT_INBOX_EMAIL } from "@withpotter/lib/support-inbox";
|
|
7
7
|
import { useAdminSession } from "../hooks";
|
|
8
|
-
import { settingsStore } from "../_settings";
|
|
9
8
|
import { useModuleOn } from "../_shell/modules-context";
|
|
10
9
|
import { signOutAdmin } from "../_shell/sign-out";
|
|
11
10
|
import { ChangePasswordDialog } from "./change-password-dialog";
|
|
12
11
|
import { ProfileCard } from "./profile-card";
|
|
13
12
|
import { SettingRow, SettingsCard } from "./setting-row";
|
|
14
|
-
import { SystemStatusCard } from "./system-status-card";
|
|
15
13
|
import styles from "./settings.module.css";
|
|
16
14
|
function AccountTab() {
|
|
17
15
|
const router = useRouter();
|
|
18
|
-
const confirm = useConfirm();
|
|
19
|
-
const { toast } = useToast();
|
|
20
16
|
const { data: session } = useAdminSession();
|
|
21
17
|
const [changing, setChanging] = useState(false);
|
|
22
18
|
const [leaving, setLeaving] = useState(false);
|
|
@@ -26,17 +22,6 @@ function AccountTab() {
|
|
|
26
22
|
await signOutAdmin();
|
|
27
23
|
router.replace("/admin/login");
|
|
28
24
|
};
|
|
29
|
-
const reset = async () => {
|
|
30
|
-
const ok = await confirm({
|
|
31
|
-
title: "Reset settings on this device?",
|
|
32
|
-
description: "Density, accessibility, notification and shortcut choices go back to their defaults. Your account is not affected.",
|
|
33
|
-
confirmLabel: "Reset settings",
|
|
34
|
-
tone: "danger"
|
|
35
|
-
});
|
|
36
|
-
if (!ok) return;
|
|
37
|
-
settingsStore.reset();
|
|
38
|
-
toast({ title: "Settings reset on this device" });
|
|
39
|
-
};
|
|
40
25
|
return /* @__PURE__ */ jsxs("div", { className: styles.stack, children: [
|
|
41
26
|
session && /* @__PURE__ */ jsx(ProfileCard, { session }),
|
|
42
27
|
/* @__PURE__ */ jsxs(SettingsCard, { title: "Security", children: [
|
|
@@ -57,14 +42,6 @@ function AccountTab() {
|
|
|
57
42
|
}
|
|
58
43
|
)
|
|
59
44
|
] }),
|
|
60
|
-
/* @__PURE__ */ jsx(SettingsCard, { title: "This device", children: /* @__PURE__ */ jsx(
|
|
61
|
-
SettingRow,
|
|
62
|
-
{
|
|
63
|
-
label: "Reset all settings on this device",
|
|
64
|
-
description: "Every preference on this page returns to its default.",
|
|
65
|
-
children: /* @__PURE__ */ jsx(Button, { variant: "danger", onClick: reset, children: "Reset" })
|
|
66
|
-
}
|
|
67
|
-
) }),
|
|
68
45
|
supportOn && /* @__PURE__ */ jsx(SettingsCard, { title: "Support inbox", children: /* @__PURE__ */ jsx(
|
|
69
46
|
SettingRow,
|
|
70
47
|
{
|
|
@@ -73,7 +50,6 @@ function AccountTab() {
|
|
|
73
50
|
children: /* @__PURE__ */ jsx("span", { className: styles.value, title: SUPPORT_INBOX_EMAIL, children: SUPPORT_INBOX_EMAIL })
|
|
74
51
|
}
|
|
75
52
|
) }),
|
|
76
|
-
/* @__PURE__ */ jsx(SystemStatusCard, {}),
|
|
77
53
|
changing && /* @__PURE__ */ jsx(ChangePasswordDialog, { onClose: () => setChanging(false) })
|
|
78
54
|
] });
|
|
79
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/settings/account-tab.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { Button
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/settings/account-tab.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { Button } from '@withpotter/ui-kit';\nimport { SUPPORT_INBOX_EMAIL } from '@withpotter/lib/support-inbox';\nimport { useAdminSession } from '../hooks';\nimport { useModuleOn } from '../_shell/modules-context';\nimport { signOutAdmin } from '../_shell/sign-out';\nimport { ChangePasswordDialog } from './change-password-dialog';\nimport { ProfileCard } from './profile-card';\nimport { SettingRow, SettingsCard } from './setting-row';\nimport styles from './settings.module.css';\n\n/**\n * Who you are and how you sign in. The support inbox\n * address shows only where this box serves Support.\n */\nexport function AccountTab() {\n const router = useRouter();\n const { data: session } = useAdminSession();\n const [changing, setChanging] = useState(false);\n const [leaving, setLeaving] = useState(false);\n const supportOn = useModuleOn('support');\n\n const signOut = async () => {\n setLeaving(true);\n await signOutAdmin();\n router.replace('/admin/login');\n };\n\n return (\n <div className={styles.stack}>\n {session && <ProfileCard session={session} />}\n <SettingsCard title=\"Security\">\n <SettingRow\n label=\"Password\"\n description=\"At least 12 characters. You stay signed in here.\"\n >\n <Button variant=\"secondary\" onClick={() => setChanging(true)}>\n Change password\n </Button>\n </SettingRow>\n <SettingRow\n label=\"Sign out\"\n description=\"Also ends any View as owner session.\"\n >\n <Button variant=\"secondary\" loading={leaving} onClick={signOut}>\n Sign out\n </Button>\n </SettingRow>\n </SettingsCard>\n {supportOn && (\n <SettingsCard title=\"Support inbox\">\n <SettingRow\n label=\"Inbound address\"\n description=\"Merchants write here; each email opens a case in Support.\"\n >\n <span className={styles.value} title={SUPPORT_INBOX_EMAIL}>\n {SUPPORT_INBOX_EMAIL}\n </span>\n </SettingRow>\n </SettingsCard>\n )}\n {changing && <ChangePasswordDialog onClose={() => setChanging(false)} />}\n </div>\n );\n}\n"],"mappings":";AAiCkB,cACZ,YADY;AA/BlB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,cAAc;AACvB,SAAS,2BAA2B;AACpC,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,4BAA4B;AACrC,SAAS,mBAAmB;AAC5B,SAAS,YAAY,oBAAoB;AACzC,OAAO,YAAY;AAMZ,SAAS,aAAa;AAC3B,QAAM,SAAS,UAAU;AACzB,QAAM,EAAE,MAAM,QAAQ,IAAI,gBAAgB;AAC1C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,YAAY,YAAY,SAAS;AAEvC,QAAM,UAAU,YAAY;AAC1B,eAAW,IAAI;AACf,UAAM,aAAa;AACnB,WAAO,QAAQ,cAAc;AAAA,EAC/B;AAEA,SACE,qBAAC,SAAI,WAAW,OAAO,OACpB;AAAA,eAAW,oBAAC,eAAY,SAAkB;AAAA,IAC3C,qBAAC,gBAAa,OAAM,YAClB;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAM;AAAA,UACN,aAAY;AAAA,UAEZ,8BAAC,UAAO,SAAQ,aAAY,SAAS,MAAM,YAAY,IAAI,GAAG,6BAE9D;AAAA;AAAA,MACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,OAAM;AAAA,UACN,aAAY;AAAA,UAEZ,8BAAC,UAAO,SAAQ,aAAY,SAAS,SAAS,SAAS,SAAS,sBAEhE;AAAA;AAAA,MACF;AAAA,OACF;AAAA,IACC,aACC,oBAAC,gBAAa,OAAM,iBAClB;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,aAAY;AAAA,QAEZ,8BAAC,UAAK,WAAW,OAAO,OAAO,OAAO,qBACnC,+BACH;AAAA;AAAA,IACF,GACF;AAAA,IAED,YAAY,oBAAC,wBAAqB,SAAS,MAAM,YAAY,KAAK,GAAG;AAAA,KACxE;AAEJ;","names":[]}
|
|
@@ -95,9 +95,10 @@ function TenantListRow({
|
|
|
95
95
|
children: t.businessName
|
|
96
96
|
}
|
|
97
97
|
),
|
|
98
|
-
/* @__PURE__ */ jsx("span", { className: rows.secondary, title: t.slug, children: t.slug })
|
|
98
|
+
/* @__PURE__ */ jsx("span", { className: rows.secondary, title: t.slug, children: [t.slug, t.phone].filter(Boolean).join(" \xB7 ") })
|
|
99
99
|
] })
|
|
100
100
|
] }) }),
|
|
101
|
+
/* @__PURE__ */ jsx("td", { className: `${list.clip} ${list.muted}`, children: /* @__PURE__ */ jsx("span", { title: t.email ?? t.ownerEmail ?? void 0, children: t.email ?? t.ownerEmail ?? EMPTY }) }),
|
|
101
102
|
/* @__PURE__ */ jsx("td", { className: `${list.clip} ${list.muted}`, children: countryText(t.country, t.countryCode) ? /* @__PURE__ */ jsx(CountryLabel, { country: t.country, code: t.countryCode }) : EMPTY }),
|
|
102
103
|
/* @__PURE__ */ jsx("td", { className: `${list.clip} ${list.muted}`, children: t.industryKey ?? EMPTY }),
|
|
103
104
|
/* @__PURE__ */ jsx("td", { className: list.num, children: /* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/tenants/tenant-list-row.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport Link from 'next/link';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport {\n OverflowItem,\n OverflowMenu,\n TableRow,\n useConfirm,\n useToast,\n} from '@withpotter/ui-kit';\nimport { platformAdminApi, type TenantRow } from '@withpotter/lib/admin-api';\nimport { EntityAvatar } from '../_fx';\nimport { CountryLabel } from '../_ui/country-label';\nimport { countryText } from '../_ui/country-text';\nimport { EMPTY } from '../_ui/list-card';\nimport { MoneyLines } from '../_ui/money-lines';\nimport { useAccountActions } from '../accounts/use-account-actions';\nimport { useModuleOn } from '../_shell/modules-context';\nimport { useAdminSession } from '../hooks';\nimport { StatusPill } from '../audit/status-pill';\nimport { AccountOfficerDialog } from './[id]/account-officer-dialog';\nimport { officerAction } from './account-officer-action';\nimport { logoOf } from './tenants-logo';\nimport list from '../_ui/list-card.module.css';\nimport rows from '../accounts/rows.module.css';\n\n/** One business: identity, money, status and a ••• menu. */\nexport function TenantListRow({\n t,\n onOpen,\n}: {\n t: TenantRow;\n onOpen: () => void;\n}) {\n const queryClient = useQueryClient();\n const confirm = useConfirm();\n const { toast } = useToast();\n const { impersonate } = useAccountActions();\n const ownerView = useModuleOn('ownerView');\n const { data: session } = useAdminSession();\n const officerChoice = officerAction(\n t.accountOfficer,\n session?.role === 'superadmin',\n t.status,\n );\n const [picking, setPicking] = useState(false);\n const href = `/admin/tenants/${t.id}`;\n const suspended = t.status === 'suspended';\n const logo = logoOf(t);\n const fail = (title: string) => (e: Error) =>\n toast({ title, description: e.message, variant: 'destructive' });\n\n const status = useMutation({\n mutationFn: () =>\n platformAdminApi.setTenantStatus(\n t.id,\n suspended ? 'active' : 'suspended',\n ),\n onSuccess: () => {\n toast({\n title: `${t.businessName} ${suspended ? 'restored' : 'suspended'}`,\n });\n void queryClient.invalidateQueries({\n queryKey: ['platform-admin', 'tenants'],\n });\n },\n onError: fail('The status was not changed'),\n });\n\n // The owner is looked up first, so the tab is reserved inside the click\n // (before the await); opened afterwards it would be blocked as a pop-up.\n const viewAsOwner = useMutation({\n mutationFn: async (tab: Window | null) => {\n const detail = await platformAdminApi.tenant(t.id);\n const owner = detail.owner?.accountId;\n\n if (!owner) throw new Error('This business has no owner account.');\n\n impersonate.mutate(owner, tab);\n },\n onError: (error, tab) => {\n tab?.close();\n fail('Could not open the owner’s view')(error);\n },\n });\n\n const toggle = async () => {\n const ok = await confirm({\n title: suspended\n ? `Restore ${t.businessName}?`\n : `Suspend ${t.businessName}?`,\n description: suspended\n ? 'Their store and dashboard come back online straight away.'\n : 'Their store goes offline and their team loses access until restored.',\n confirmLabel: suspended ? 'Restore' : 'Suspend',\n tone: suspended ? 'default' : 'danger',\n });\n if (ok) status.mutate();\n };\n\n return (\n <TableRow onClick={onOpen}>\n <td>\n <span className={rows.identity}>\n {logo && <EntityAvatar name={t.businessName} src={logo} size={32} />}\n <span className={rows.identityText}>\n <Link\n href={href}\n className={rows.primary}\n title={t.businessName}\n onClick={(e) => e.stopPropagation()}\n >\n {t.businessName}\n </Link>\n <span className={rows.secondary} title={t.slug}>\n {t.slug}\n </span>\n </span>\n </span>\n </td>\n <td className={`${list.clip} ${list.muted}`}>\n {countryText(t.country, t.countryCode) ? (\n <CountryLabel country={t.country} code={t.countryCode} />\n ) : (\n EMPTY\n )}\n </td>\n <td className={`${list.clip} ${list.muted}`}>{t.industryKey ?? EMPTY}</td>\n <td className={list.num}>\n {/* One line per currency the business sells in; never added up. */}\n <MoneyLines\n rows={t.gmvByCurrency}\n currency=\"\"\n amount={(r) => r.amount}\n empty={EMPTY}\n />\n </td>\n <td className={list.nowrap}>\n <StatusPill status={t.status} />\n </td>\n <td\n className={`${list.clip} ${list.muted}`}\n onClick={(e) => e.stopPropagation()}\n >\n {officerChoice ? (\n <button\n type=\"button\"\n className={rows.nameButton}\n title={\n t.accountOfficer\n ? `${t.accountOfficer.name}. Change the account officer`\n : 'Assign an account officer'\n }\n onClick={() => setPicking(true)}\n >\n {t.accountOfficer?.name ?? 'Assign'}\n </button>\n ) : (\n (t.accountOfficer?.name ?? EMPTY)\n )}\n </td>\n <td className={`${list.nowrap} ${list.muted}`}>\n {new Date(t.createdAt).toLocaleDateString()}\n </td>\n <td className={rows.menuCell} onClick={(e) => e.stopPropagation()}>\n <OverflowMenu label={`Actions for ${t.businessName}`}>\n <OverflowItem onClick={onOpen}>View merchant</OverflowItem>\n {ownerView && (\n <OverflowItem\n disabled={viewAsOwner.isPending}\n onClick={() => viewAsOwner.mutate(impersonate.reserveTab())}\n >\n View as owner\n </OverflowItem>\n )}\n {officerChoice && (\n <OverflowItem onClick={() => setPicking(true)}>\n {officerChoice === 'assign'\n ? 'Assign account officer'\n : 'Change account officer'}\n </OverflowItem>\n )}\n {t.status !== 'deleted' && (\n <OverflowItem\n onClick={() => void toggle()}\n destructive={!suspended}\n >\n {suspended ? 'Restore' : 'Suspend'}\n </OverflowItem>\n )}\n </OverflowMenu>\n {picking && (\n <AccountOfficerDialog\n open\n tenantId={t.id}\n name={t.businessName}\n currentId={t.accountOfficer?.id ?? null}\n onClose={() => setPicking(false)}\n />\n )}\n </td>\n </TableRow>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/tenants/tenant-list-row.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport Link from 'next/link';\nimport { useMutation, useQueryClient } from '@tanstack/react-query';\nimport {\n OverflowItem,\n OverflowMenu,\n TableRow,\n useConfirm,\n useToast,\n} from '@withpotter/ui-kit';\nimport { platformAdminApi, type TenantRow } from '@withpotter/lib/admin-api';\nimport { EntityAvatar } from '../_fx';\nimport { CountryLabel } from '../_ui/country-label';\nimport { countryText } from '../_ui/country-text';\nimport { EMPTY } from '../_ui/list-card';\nimport { MoneyLines } from '../_ui/money-lines';\nimport { useAccountActions } from '../accounts/use-account-actions';\nimport { useModuleOn } from '../_shell/modules-context';\nimport { useAdminSession } from '../hooks';\nimport { StatusPill } from '../audit/status-pill';\nimport { AccountOfficerDialog } from './[id]/account-officer-dialog';\nimport { officerAction } from './account-officer-action';\nimport { logoOf } from './tenants-logo';\nimport list from '../_ui/list-card.module.css';\nimport rows from '../accounts/rows.module.css';\n\n/** One business: identity, money, status and a ••• menu. */\nexport function TenantListRow({\n t,\n onOpen,\n}: {\n t: TenantRow;\n onOpen: () => void;\n}) {\n const queryClient = useQueryClient();\n const confirm = useConfirm();\n const { toast } = useToast();\n const { impersonate } = useAccountActions();\n const ownerView = useModuleOn('ownerView');\n const { data: session } = useAdminSession();\n const officerChoice = officerAction(\n t.accountOfficer,\n session?.role === 'superadmin',\n t.status,\n );\n const [picking, setPicking] = useState(false);\n const href = `/admin/tenants/${t.id}`;\n const suspended = t.status === 'suspended';\n const logo = logoOf(t);\n const fail = (title: string) => (e: Error) =>\n toast({ title, description: e.message, variant: 'destructive' });\n\n const status = useMutation({\n mutationFn: () =>\n platformAdminApi.setTenantStatus(\n t.id,\n suspended ? 'active' : 'suspended',\n ),\n onSuccess: () => {\n toast({\n title: `${t.businessName} ${suspended ? 'restored' : 'suspended'}`,\n });\n void queryClient.invalidateQueries({\n queryKey: ['platform-admin', 'tenants'],\n });\n },\n onError: fail('The status was not changed'),\n });\n\n // The owner is looked up first, so the tab is reserved inside the click\n // (before the await); opened afterwards it would be blocked as a pop-up.\n const viewAsOwner = useMutation({\n mutationFn: async (tab: Window | null) => {\n const detail = await platformAdminApi.tenant(t.id);\n const owner = detail.owner?.accountId;\n\n if (!owner) throw new Error('This business has no owner account.');\n\n impersonate.mutate(owner, tab);\n },\n onError: (error, tab) => {\n tab?.close();\n fail('Could not open the owner’s view')(error);\n },\n });\n\n const toggle = async () => {\n const ok = await confirm({\n title: suspended\n ? `Restore ${t.businessName}?`\n : `Suspend ${t.businessName}?`,\n description: suspended\n ? 'Their store and dashboard come back online straight away.'\n : 'Their store goes offline and their team loses access until restored.',\n confirmLabel: suspended ? 'Restore' : 'Suspend',\n tone: suspended ? 'default' : 'danger',\n });\n if (ok) status.mutate();\n };\n\n return (\n <TableRow onClick={onOpen}>\n <td>\n <span className={rows.identity}>\n {logo && <EntityAvatar name={t.businessName} src={logo} size={32} />}\n <span className={rows.identityText}>\n <Link\n href={href}\n className={rows.primary}\n title={t.businessName}\n onClick={(e) => e.stopPropagation()}\n >\n {t.businessName}\n </Link>\n <span className={rows.secondary} title={t.slug}>\n {[t.slug, t.phone].filter(Boolean).join(' · ')}\n </span>\n </span>\n </span>\n </td>\n <td className={`${list.clip} ${list.muted}`}>\n <span title={t.email ?? t.ownerEmail ?? undefined}>\n {t.email ?? t.ownerEmail ?? EMPTY}\n </span>\n </td>\n <td className={`${list.clip} ${list.muted}`}>\n {countryText(t.country, t.countryCode) ? (\n <CountryLabel country={t.country} code={t.countryCode} />\n ) : (\n EMPTY\n )}\n </td>\n <td className={`${list.clip} ${list.muted}`}>{t.industryKey ?? EMPTY}</td>\n <td className={list.num}>\n {/* One line per currency the business sells in; never added up. */}\n <MoneyLines\n rows={t.gmvByCurrency}\n currency=\"\"\n amount={(r) => r.amount}\n empty={EMPTY}\n />\n </td>\n <td className={list.nowrap}>\n <StatusPill status={t.status} />\n </td>\n <td\n className={`${list.clip} ${list.muted}`}\n onClick={(e) => e.stopPropagation()}\n >\n {officerChoice ? (\n <button\n type=\"button\"\n className={rows.nameButton}\n title={\n t.accountOfficer\n ? `${t.accountOfficer.name}. Change the account officer`\n : 'Assign an account officer'\n }\n onClick={() => setPicking(true)}\n >\n {t.accountOfficer?.name ?? 'Assign'}\n </button>\n ) : (\n (t.accountOfficer?.name ?? EMPTY)\n )}\n </td>\n <td className={`${list.nowrap} ${list.muted}`}>\n {new Date(t.createdAt).toLocaleDateString()}\n </td>\n <td className={rows.menuCell} onClick={(e) => e.stopPropagation()}>\n <OverflowMenu label={`Actions for ${t.businessName}`}>\n <OverflowItem onClick={onOpen}>View merchant</OverflowItem>\n {ownerView && (\n <OverflowItem\n disabled={viewAsOwner.isPending}\n onClick={() => viewAsOwner.mutate(impersonate.reserveTab())}\n >\n View as owner\n </OverflowItem>\n )}\n {officerChoice && (\n <OverflowItem onClick={() => setPicking(true)}>\n {officerChoice === 'assign'\n ? 'Assign account officer'\n : 'Change account officer'}\n </OverflowItem>\n )}\n {t.status !== 'deleted' && (\n <OverflowItem\n onClick={() => void toggle()}\n destructive={!suspended}\n >\n {suspended ? 'Restore' : 'Suspend'}\n </OverflowItem>\n )}\n </OverflowMenu>\n {picking && (\n <AccountOfficerDialog\n open\n tenantId={t.id}\n name={t.businessName}\n currentId={t.accountOfficer?.id ?? null}\n onClose={() => setPicking(false)}\n />\n )}\n </td>\n </TableRow>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -37,7 +37,7 @@ function TenantsTable() {
|
|
|
37
37
|
{
|
|
38
38
|
title: "All merchants",
|
|
39
39
|
count: data?.total,
|
|
40
|
-
columns:
|
|
40
|
+
columns: 9,
|
|
41
41
|
minWidth: 1e3,
|
|
42
42
|
isLoading,
|
|
43
43
|
isError,
|
|
@@ -99,6 +99,7 @@ function TenantsTable() {
|
|
|
99
99
|
] }),
|
|
100
100
|
head: /* @__PURE__ */ jsxs("tr", { children: [
|
|
101
101
|
/* @__PURE__ */ jsx(Th, { children: "Business" }),
|
|
102
|
+
/* @__PURE__ */ jsx(Th, { children: "Email" }),
|
|
102
103
|
/* @__PURE__ */ jsx(Th, { children: "Country" }),
|
|
103
104
|
/* @__PURE__ */ jsx(Th, { children: "Industry" }),
|
|
104
105
|
/* @__PURE__ */ jsx(Th, { align: "right", children: "GMV (USD)" }),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/tenants/tenants-table.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { Th } from '@withpotter/ui-kit';\nimport type { TenantStatus } from '@withpotter/lib/admin-api';\nimport { usePlatformTenants } from '../hooks';\nimport { ListCard, ListPager } from '../_ui/list-card';\nimport { TenantListRow } from './tenant-list-row';\nimport { FilterSearch, FilterSelect, Filters } from '../_ui';\nimport { CountryFilter, useCountryParam } from './country-filter';\nimport { AccountOfficerFilter, useOfficerParam } from './account-officer-filter';\n\nconst STATUS_OPTIONS: TenantStatus[] = [\n 'active',\n 'pending',\n 'suspended',\n 'deleted',\n];\n\nconst sentence = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\n/** Every business, searchable by name or slug, narrowed by status, country or officer. */\nexport function TenantsTable() {\n const router = useRouter();\n const [search, setSearch] = useState('');\n const [status, setStatus] = useState<TenantStatus | ''>('');\n const [country, setCountry] = useCountryParam();\n const [officer, setOfficer] = useOfficerParam();\n const [page, setPage] = useState(1);\n const { data, isLoading, isError, refetch } = usePlatformTenants({\n page,\n pageSize: 20,\n search: search || undefined,\n status: status || undefined,\n country: country || undefined,\n accountOfficerId: officer || undefined,\n });\n const totalPages = data\n ? Math.max(1, Math.ceil(data.total / data.pageSize))\n : 1;\n\n return (\n <ListCard\n title=\"All merchants\"\n count={data?.total}\n columns={
|
|
1
|
+
{"version":3,"sources":["../../../src/admin/tenants/tenants-table.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { useRouter } from 'next/navigation';\nimport { Th } from '@withpotter/ui-kit';\nimport type { TenantStatus } from '@withpotter/lib/admin-api';\nimport { usePlatformTenants } from '../hooks';\nimport { ListCard, ListPager } from '../_ui/list-card';\nimport { TenantListRow } from './tenant-list-row';\nimport { FilterSearch, FilterSelect, Filters } from '../_ui';\nimport { CountryFilter, useCountryParam } from './country-filter';\nimport { AccountOfficerFilter, useOfficerParam } from './account-officer-filter';\n\nconst STATUS_OPTIONS: TenantStatus[] = [\n 'active',\n 'pending',\n 'suspended',\n 'deleted',\n];\n\nconst sentence = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);\n\n/** Every business, searchable by name or slug, narrowed by status, country or officer. */\nexport function TenantsTable() {\n const router = useRouter();\n const [search, setSearch] = useState('');\n const [status, setStatus] = useState<TenantStatus | ''>('');\n const [country, setCountry] = useCountryParam();\n const [officer, setOfficer] = useOfficerParam();\n const [page, setPage] = useState(1);\n const { data, isLoading, isError, refetch } = usePlatformTenants({\n page,\n pageSize: 20,\n search: search || undefined,\n status: status || undefined,\n country: country || undefined,\n accountOfficerId: officer || undefined,\n });\n const totalPages = data\n ? Math.max(1, Math.ceil(data.total / data.pageSize))\n : 1;\n\n return (\n <ListCard\n title=\"All merchants\"\n count={data?.total}\n columns={9}\n minWidth={1000}\n isLoading={isLoading}\n isError={isError}\n onRetry={() => void refetch()}\n errorTitle=\"Failed to load merchants.\"\n isEmpty={data?.rows.length === 0}\n emptyTitle=\"No merchants found\"\n emptyDescription=\"Try a different search, status, country or officer.\"\n controls={\n <Filters label=\"Filter merchants\">\n <FilterSearch\n value={search}\n onChange={(v) => {\n setSearch(v);\n setPage(1);\n }}\n placeholder=\"Search by name or slug…\"\n />\n <FilterSelect\n label=\"Status\"\n value={status}\n onChange={(v) => {\n setStatus(v as TenantStatus | '');\n setPage(1);\n }}\n options={[\n { value: '', label: 'All statuses' },\n ...STATUS_OPTIONS.map((s) => ({\n value: s,\n label: sentence(s),\n })),\n ]}\n />\n <CountryFilter\n value={country}\n onChange={(v) => {\n setCountry(v);\n setPage(1);\n }}\n />\n <AccountOfficerFilter\n value={officer}\n onChange={(v) => {\n setOfficer(v);\n setPage(1);\n }}\n />\n </Filters>\n }\n head={\n <tr>\n <Th>Business</Th>\n <Th>Email</Th>\n <Th>Country</Th>\n <Th>Industry</Th>\n <Th align=\"right\">GMV (USD)</Th>\n <Th>Status</Th>\n <Th>Account officer</Th>\n <Th>Joined</Th>\n <Th align=\"right\">\n <span className=\"sr-only\">Actions</span>\n </Th>\n </tr>\n }\n footer={\n <ListPager\n page={page}\n totalPages={totalPages}\n total={data?.total}\n noun=\"merchants\"\n onPage={setPage}\n />\n }\n >\n {data?.rows.map((t) => (\n <TenantListRow\n key={t.id}\n t={t}\n onOpen={() => router.push(`/admin/tenants/${t.id}`)}\n />\n ))}\n </ListCard>\n );\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@withpotter/pages-admin",
|
|
3
|
-
"version": "0.13.0-next.
|
|
3
|
+
"version": "0.13.0-next.77",
|
|
4
4
|
"description": "Box console platform-admin routes: overview, revenue, accounts, tenants, admins, roles, audit.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@radix-ui/react-popover": "^1.1.23",
|
|
33
33
|
"@tanstack/react-query": "^5.90.20",
|
|
34
|
-
"@withpotter/lib": "^0.13.0-next.
|
|
35
|
-
"@withpotter/platform-admin": "^0.13.0-next.
|
|
36
|
-
"@withpotter/ui-kit": "^0.13.0-next.
|
|
34
|
+
"@withpotter/lib": "^0.13.0-next.77",
|
|
35
|
+
"@withpotter/platform-admin": "^0.13.0-next.77",
|
|
36
|
+
"@withpotter/ui-kit": "^0.13.0-next.77",
|
|
37
37
|
"lucide-react": "^0.562.0",
|
|
38
38
|
"motion": "^12.42.2"
|
|
39
39
|
},
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"typescript": "^5"
|
|
51
51
|
},
|
|
52
52
|
"publishConfig": {
|
|
53
|
-
"registry": "https://registry.npmjs.org",
|
|
53
|
+
"registry": "https://registry.npmjs.org/",
|
|
54
54
|
"access": "restricted"
|
|
55
55
|
}
|
|
56
56
|
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useState } from "react";
|
|
3
|
-
function useOpenGroup(pathname) {
|
|
4
|
-
const [choice, setChoice] = useState(void 0);
|
|
5
|
-
const setGroupOpen = (label, next) => setChoice(next ? label : null);
|
|
6
|
-
const [choiceRoute, setChoiceRoute] = useState(pathname);
|
|
7
|
-
if (choiceRoute !== pathname) {
|
|
8
|
-
setChoiceRoute(pathname);
|
|
9
|
-
setChoice(void 0);
|
|
10
|
-
}
|
|
11
|
-
return { choice, setGroupOpen };
|
|
12
|
-
}
|
|
13
|
-
export {
|
|
14
|
-
useOpenGroup
|
|
15
|
-
};
|
|
16
|
-
//# sourceMappingURL=use-open-group.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/_shell/use-open-group.ts"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport type { GroupChoice } from './nav-fold';\n\n/**\n * Which sidebar group is showing its rows: ONE, none, or \"not said yet\"\n * (`undefined`, which leaves the group owning the current page open). The\n * merchant rail's useOpenHub, for the admin's groups.\n */\nexport function useOpenGroup(pathname: string) {\n const [choice, setChoice] = useState<GroupChoice>(undefined);\n const setGroupOpen = (label: string, next: boolean) =>\n setChoice(next ? label : null);\n // A new route retires the choice, or arriving from inside the page would\n // leave the rail on the last group pressed, with the current row hidden.\n // Adjusted during render, not in an effect, so no stale frame paints first.\n const [choiceRoute, setChoiceRoute] = useState(pathname);\n\n if (choiceRoute !== pathname) {\n setChoiceRoute(pathname);\n setChoice(undefined);\n }\n\n return { choice, setGroupOpen };\n}\n"],"mappings":";AAEA,SAAS,gBAAgB;AAQlB,SAAS,aAAa,UAAkB;AAC7C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAsB,MAAS;AAC3D,QAAM,eAAe,CAAC,OAAe,SACnC,UAAU,OAAO,QAAQ,IAAI;AAI/B,QAAM,CAAC,aAAa,cAAc,IAAI,SAAS,QAAQ;AAEvD,MAAI,gBAAgB,UAAU;AAC5B,mBAAe,QAAQ;AACvB,cAAU,MAAS;AAAA,EACrB;AAEA,SAAO,EAAE,QAAQ,aAAa;AAChC;","names":[]}
|