@withpotter/pages-admin 0.13.0-next.124 → 0.13.0-next.59
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/_money/cash-postings.js +3 -20
- package/dist/admin/_money/cash-postings.js.map +1 -1
- package/dist/admin/_money/cash.module.css +0 -10
- package/dist/admin/_money/finder-format.js +0 -1
- package/dist/admin/_money/finder-format.js.map +1 -1
- package/dist/admin/_money/format.js +0 -1
- package/dist/admin/_money/format.js.map +1 -1
- package/dist/admin/_overview/activation-panel.js +6 -6
- package/dist/admin/_overview/activation-panel.js.map +1 -1
- package/dist/admin/_overview/attention-groups.js +8 -8
- package/dist/admin/_overview/attention-groups.js.map +1 -1
- package/dist/admin/_overview/attention-panel.js +33 -37
- package/dist/admin/_overview/attention-panel.js.map +1 -1
- package/dist/admin/_overview/attention.module.css +3 -0
- package/dist/admin/_overview/control-room.js +13 -41
- package/dist/admin/_overview/control-room.js.map +1 -1
- package/dist/admin/_overview/kpi-row.js +7 -7
- package/dist/admin/_overview/kpi-row.js.map +1 -1
- package/dist/admin/_overview/leaders-panel.js +1 -1
- package/dist/admin/_overview/leaders-panel.js.map +1 -1
- package/dist/admin/_overview/overdue-outstanding.js +1 -2
- package/dist/admin/_overview/overdue-outstanding.js.map +1 -1
- package/dist/admin/_overview/portfolio-panel.js +5 -5
- package/dist/admin/_overview/portfolio-panel.js.map +1 -1
- package/dist/admin/_overview/position-panel.js +12 -8
- package/dist/admin/_overview/position-panel.js.map +1 -1
- package/dist/admin/_pos/pos-figures.js +5 -18
- package/dist/admin/_pos/pos-figures.js.map +1 -1
- package/dist/admin/_pos/pos-rules.js +0 -2
- package/dist/admin/_pos/pos-rules.js.map +1 -1
- package/dist/admin/_pos/pos-words.js +1 -6
- package/dist/admin/_pos/pos-words.js.map +1 -1
- package/dist/admin/_pos/use-pos.js +1 -70
- package/dist/admin/_pos/use-pos.js.map +1 -1
- package/dist/admin/_shell/nav-config.js +3 -3
- package/dist/admin/_shell/nav-config.js.map +1 -1
- package/dist/admin/_shell/nav-filter.js +2 -4
- package/dist/admin/_shell/nav-filter.js.map +1 -1
- package/dist/admin/_shell/nav-row.js +2 -5
- package/dist/admin/_shell/nav-row.js.map +1 -1
- package/dist/admin/_shell/sidebar-footer.js +0 -20
- package/dist/admin/_shell/sidebar-footer.js.map +1 -1
- package/dist/admin/_shell/sidebar-footer.module.css +0 -17
- package/dist/admin/_shell/sidebar.js +15 -25
- package/dist/admin/_shell/sidebar.js.map +1 -1
- package/dist/admin/_shell/sidebar.module.css +0 -69
- package/dist/admin/_shell/use-fluid-hover.js +6 -37
- package/dist/admin/_shell/use-fluid-hover.js.map +1 -1
- package/dist/admin/_ui/admin.css +0 -7
- package/dist/admin/_ui/data-table.js +1 -1
- package/dist/admin/_ui/data-table.js.map +1 -1
- package/dist/admin/_ui/list-card.js +1 -1
- package/dist/admin/_ui/list-card.js.map +1 -1
- package/dist/admin/_ui/list-card.module.css +16 -2
- package/dist/admin/_ui/money-view.js +0 -1
- package/dist/admin/_ui/money-view.js.map +1 -1
- package/dist/admin/_ui/page-header.js +4 -31
- package/dist/admin/_ui/page-header.js.map +1 -1
- package/dist/admin/_ui/panel.module.css +10 -0
- package/dist/admin/_ui/stat-card.js +2 -11
- package/dist/admin/_ui/stat-card.js.map +1 -1
- package/dist/admin/_ui/trend.js +2 -2
- package/dist/admin/_ui/trend.js.map +1 -1
- package/dist/admin/accounts/account-panel.js +6 -49
- package/dist/admin/accounts/account-panel.js.map +1 -1
- package/dist/admin/accounts/account-panel.module.css +0 -73
- package/dist/admin/accounts/account-row.js +2 -11
- package/dist/admin/accounts/account-row.js.map +1 -1
- package/dist/admin/accounts/account-vitals.js +13 -15
- package/dist/admin/accounts/account-vitals.js.map +1 -1
- package/dist/admin/accounts/accounts-table.js +8 -39
- package/dist/admin/accounts/accounts-table.js.map +1 -1
- package/dist/admin/accounts/accounts-workspace.js +2 -2
- package/dist/admin/accounts/accounts-workspace.js.map +1 -1
- package/dist/admin/accounts/owner-session.js +6 -0
- package/dist/admin/accounts/owner-session.js.map +1 -1
- package/dist/admin/accounts/rows.module.css +0 -17
- package/dist/admin/audit/status-pill.js +0 -6
- package/dist/admin/audit/status-pill.js.map +1 -1
- package/dist/admin/audit/status-pill.module.css +0 -4
- package/dist/admin/commerce/commerce-overview.js +2 -2
- package/dist/admin/commerce/commerce-overview.js.map +1 -1
- package/dist/admin/commerce/merchant-meta.js +0 -1
- package/dist/admin/commerce/merchant-meta.js.map +1 -1
- package/dist/admin/commerce/merchant-view.js +2 -2
- package/dist/admin/commerce/merchant-view.js.map +1 -1
- package/dist/admin/feedback/prompt-operations.module.css +2 -0
- package/dist/admin/feedback/prompt-preview.module.css +2 -0
- package/dist/admin/hooks.js +1 -57
- package/dist/admin/hooks.js.map +1 -1
- package/dist/admin/layout.js +2 -8
- package/dist/admin/layout.js.map +1 -1
- package/dist/admin/page.js +8 -28
- package/dist/admin/page.js.map +1 -1
- package/dist/admin/payout-tiers/_tier-dialog.js +21 -31
- package/dist/admin/payout-tiers/_tier-dialog.js.map +1 -1
- package/dist/admin/payout-tiers/tier-preview-result.js +9 -10
- package/dist/admin/payout-tiers/tier-preview-result.js.map +1 -1
- package/dist/admin/payout-tiers/tiers-table.js +7 -6
- package/dist/admin/payout-tiers/tiers-table.js.map +1 -1
- package/dist/admin/payout-tiers/tiers-workspace.js +2 -2
- package/dist/admin/payout-tiers/tiers-workspace.js.map +1 -1
- package/dist/admin/pos/pos-workspace.js +2 -6
- package/dist/admin/pos/pos-workspace.js.map +1 -1
- package/dist/admin/pos/shifts-tab.js +9 -16
- package/dist/admin/pos/shifts-tab.js.map +1 -1
- package/dist/admin/revenue/cohort-panel.js +6 -6
- package/dist/admin/revenue/cohort-panel.js.map +1 -1
- package/dist/admin/revenue/health-panel.js +21 -22
- package/dist/admin/revenue/health-panel.js.map +1 -1
- package/dist/admin/revenue/plan-mix-panel.js +3 -3
- package/dist/admin/revenue/plan-mix-panel.js.map +1 -1
- package/dist/admin/revenue/quality-panel.js +19 -19
- package/dist/admin/revenue/quality-panel.js.map +1 -1
- package/dist/admin/revenue/revenue-kpis.js +50 -111
- package/dist/admin/revenue/revenue-kpis.js.map +1 -1
- package/dist/admin/revenue/revenue-overview.js +46 -39
- package/dist/admin/revenue/revenue-overview.js.map +1 -1
- package/dist/admin/revenue/revenue-retention.js +13 -17
- package/dist/admin/revenue/revenue-retention.js.map +1 -1
- package/dist/admin/revenue/revenue-workspace.js +6 -53
- package/dist/admin/revenue/revenue-workspace.js.map +1 -1
- package/dist/admin/revenue/subscriptions-panel.js +14 -14
- package/dist/admin/revenue/subscriptions-panel.js.map +1 -1
- package/dist/admin/revenue/top-tenants-panel.js +4 -4
- package/dist/admin/revenue/top-tenants-panel.js.map +1 -1
- package/dist/admin/settings/account-tab.js +25 -1
- package/dist/admin/settings/account-tab.js.map +1 -1
- package/dist/admin/settings/general-tab.js +2 -2
- package/dist/admin/settings/general-tab.js.map +1 -1
- package/dist/admin/settings/system-status-card.js +30 -0
- package/dist/admin/settings/system-status-card.js.map +1 -0
- package/dist/admin/support/queue-card.module.css +4 -1
- package/dist/admin/tenants/[id]/commerce/format.js +1 -2
- package/dist/admin/tenants/[id]/commerce/format.js.map +1 -1
- package/dist/admin/tenants/[id]/commerce/recent-orders.js +1 -1
- package/dist/admin/tenants/[id]/commerce/recent-orders.js.map +1 -1
- package/dist/admin/tenants/[id]/page.js +10 -37
- package/dist/admin/tenants/[id]/page.js.map +1 -1
- package/dist/admin/tenants/[id]/tenant-layout.module.css +4 -1
- package/dist/admin/tenants/[id]/tenant-overview.js +2 -3
- package/dist/admin/tenants/[id]/tenant-overview.js.map +1 -1
- package/dist/admin/tenants/[id]/tenant-overview.module.css +1 -1
- package/dist/admin/tenants/[id]/tenant-pos.js +16 -64
- package/dist/admin/tenants/[id]/tenant-pos.js.map +1 -1
- package/dist/admin/tenants/[id]/tenant-wallet-card.js +2 -3
- package/dist/admin/tenants/[id]/tenant-wallet-card.js.map +1 -1
- package/dist/admin/tenants/[id]/verification/document-viewer.js +52 -3
- package/dist/admin/tenants/[id]/verification/document-viewer.js.map +1 -1
- package/dist/admin/tenants/[id]/verification/document-viewer.module.css +0 -51
- package/dist/admin/tenants/[id]/verification/tenant-verification.js +0 -10
- package/dist/admin/tenants/[id]/verification/tenant-verification.js.map +1 -1
- package/dist/admin/tenants/tenant-list-row.js +1 -2
- package/dist/admin/tenants/tenant-list-row.js.map +1 -1
- package/dist/admin/tenants/tenants-table.js +2 -3
- package/dist/admin/tenants/tenants-table.js.map +1 -1
- package/dist/admin/tenants/tenants-workspace.js +2 -2
- package/dist/admin/tenants/tenants-workspace.js.map +1 -1
- package/dist/admin/verification/verification-page.js +3 -19
- package/dist/admin/verification/verification-page.js.map +1 -1
- package/dist/admin/verification/verification.module.css +0 -10
- package/dist/admin/verification/waiting-case-actions.js +68 -0
- package/dist/admin/verification/waiting-case-actions.js.map +1 -0
- package/dist/admin/verification/waiting-cases.js +48 -66
- package/dist/admin/verification/waiting-cases.js.map +1 -1
- package/package.json +5 -5
- package/dist/admin/_pos/olive-balance.js +0 -40
- package/dist/admin/_pos/olive-balance.js.map +0 -1
- package/dist/admin/_pos/olive-state.js +0 -23
- package/dist/admin/_pos/olive-state.js.map +0 -1
- package/dist/admin/_pos/payments-model.js +0 -55
- package/dist/admin/_pos/payments-model.js.map +0 -1
- package/dist/admin/_pos/tenant-operators.js +0 -63
- package/dist/admin/_pos/tenant-operators.js.map +0 -1
- package/dist/admin/_pos/tenant-outlets.js +0 -77
- package/dist/admin/_pos/tenant-outlets.js.map +0 -1
- package/dist/admin/_pos/tenant-pos-figures.js +0 -82
- package/dist/admin/_pos/tenant-pos-figures.js.map +0 -1
- package/dist/admin/_pos/tenant-requests.js +0 -64
- package/dist/admin/_pos/tenant-requests.js.map +0 -1
- package/dist/admin/_pos/tenant-transactions.js +0 -145
- package/dist/admin/_pos/tenant-transactions.js.map +0 -1
- package/dist/admin/_shell/nav-fold.js +0 -14
- package/dist/admin/_shell/nav-fold.js.map +0 -1
- package/dist/admin/_shell/nav-group.js +0 -78
- package/dist/admin/_shell/nav-group.js.map +0 -1
- package/dist/admin/_shell/use-open-groups.js +0 -64
- package/dist/admin/_shell/use-open-groups.js.map +0 -1
- package/dist/admin/_ui/page-header.module.css +0 -45
- package/dist/admin/accounts/account-sessions.js +0 -70
- package/dist/admin/accounts/account-sessions.js.map +0 -1
- package/dist/admin/accounts/account-sessions.module.css +0 -55
- package/dist/admin/accounts/account-stage-filter.js +0 -29
- package/dist/admin/accounts/account-stage-filter.js.map +0 -1
- package/dist/admin/accounts/account-stage.js +0 -81
- package/dist/admin/accounts/account-stage.js.map +0 -1
- package/dist/admin/accounts/hint.js +0 -12
- package/dist/admin/accounts/hint.js.map +0 -1
- package/dist/admin/payout-tiers/requirement-labels.js +0 -70
- package/dist/admin/payout-tiers/requirement-labels.js.map +0 -1
- package/dist/admin/pos/transactions-tab.js +0 -214
- package/dist/admin/pos/transactions-tab.js.map +0 -1
- package/dist/admin/revenue/channel-panel.js +0 -49
- package/dist/admin/revenue/channel-panel.js.map +0 -1
- package/dist/admin/revenue/channel-rows.js +0 -17
- package/dist/admin/revenue/channel-rows.js.map +0 -1
- package/dist/admin/revenue/download-button.js +0 -40
- package/dist/admin/revenue/download-button.js.map +0 -1
- package/dist/admin/revenue/earnings/earnings-colors.js +0 -25
- package/dist/admin/revenue/earnings/earnings-colors.js.map +0 -1
- package/dist/admin/revenue/earnings/earnings-legend.js +0 -75
- package/dist/admin/revenue/earnings/earnings-legend.js.map +0 -1
- package/dist/admin/revenue/earnings/earnings-summary.js +0 -308
- package/dist/admin/revenue/earnings/earnings-summary.js.map +0 -1
- package/dist/admin/revenue/earnings/earnings-table.js +0 -143
- package/dist/admin/revenue/earnings/earnings-table.js.map +0 -1
- package/dist/admin/revenue/earnings/earnings.module.css +0 -201
- package/dist/admin/revenue/earnings/use-earnings.js +0 -27
- package/dist/admin/revenue/earnings/use-earnings.js.map +0 -1
- package/dist/admin/revenue/ledger-model.js +0 -104
- package/dist/admin/revenue/ledger-model.js.map +0 -1
- package/dist/admin/revenue/ledger.module.css +0 -144
- package/dist/admin/revenue/merchant-headline.js +0 -37
- package/dist/admin/revenue/merchant-headline.js.map +0 -1
- package/dist/admin/revenue/merchant-payments-view.js +0 -234
- package/dist/admin/revenue/merchant-payments-view.js.map +0 -1
- package/dist/admin/revenue/method-cards.js +0 -40
- package/dist/admin/revenue/method-cards.js.map +0 -1
- package/dist/admin/revenue/payment-drawer.js +0 -53
- package/dist/admin/revenue/payment-drawer.js.map +0 -1
- package/dist/admin/revenue/plan-lines.js +0 -36
- package/dist/admin/revenue/plan-lines.js.map +0 -1
- package/dist/admin/revenue/plan-payment-drawer.js +0 -42
- package/dist/admin/revenue/plan-payment-drawer.js.map +0 -1
- package/dist/admin/revenue/plans-panel.js +0 -48
- package/dist/admin/revenue/plans-panel.js.map +0 -1
- package/dist/admin/revenue/platform-fees.js +0 -9
- package/dist/admin/revenue/platform-fees.js.map +0 -1
- package/dist/admin/revenue/print-summary-button.js +0 -27
- package/dist/admin/revenue/print-summary-button.js.map +0 -1
- package/dist/admin/revenue/subscriptions-view.js +0 -213
- package/dist/admin/revenue/subscriptions-view.js.map +0 -1
- package/dist/admin/revenue/summary-download.js +0 -38
- package/dist/admin/revenue/summary-download.js.map +0 -1
- package/dist/admin/revenue/summary-print.js +0 -82
- package/dist/admin/revenue/summary-print.js.map +0 -1
- package/dist/admin/revenue/summary-rows.js +0 -44
- package/dist/admin/revenue/summary-rows.js.map +0 -1
- package/dist/admin/revenue/url-filters.js +0 -36
- package/dist/admin/revenue/url-filters.js.map +0 -1
- package/dist/admin/revenue/use-url-filters.js +0 -24
- package/dist/admin/revenue/use-url-filters.js.map +0 -1
- package/dist/admin/tenants/[id]/use-tenant-wallet.js +0 -23
- package/dist/admin/tenants/[id]/use-tenant-wallet.js.map +0 -1
- package/dist/admin/tenants/[id]/verification/document-file.js +0 -78
- package/dist/admin/tenants/[id]/verification/document-file.js.map +0 -1
- package/dist/admin/tenants/[id]/verification/sent-files.js +0 -33
- package/dist/admin/tenants/[id]/verification/sent-files.js.map +0 -1
- package/dist/admin/verification/preview-dialog.js +0 -111
- package/dist/admin/verification/preview-dialog.js.map +0 -1
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
/*
|
|
1
|
+
/* Sticky identity + tabs, pinned under the 58px admin bar. */
|
|
2
2
|
.header {
|
|
3
|
+
position: sticky;
|
|
4
|
+
top: var(--adm-topbar-h);
|
|
5
|
+
z-index: 15;
|
|
3
6
|
margin: -32px -40px 20px;
|
|
4
7
|
padding: 16px 40px 0;
|
|
5
8
|
border-bottom: 1px solid var(--border-subtle);
|
|
@@ -46,8 +46,7 @@ function TenantOverview({
|
|
|
46
46
|
recentOrders,
|
|
47
47
|
onTab,
|
|
48
48
|
currency = "",
|
|
49
|
-
currencyControl
|
|
50
|
-
walletNote
|
|
49
|
+
currencyControl
|
|
51
50
|
}) {
|
|
52
51
|
const balances = byCurrency(
|
|
53
52
|
data.wallet?.balances ?? [],
|
|
@@ -78,7 +77,7 @@ function TenantOverview({
|
|
|
78
77
|
StatCard,
|
|
79
78
|
{
|
|
80
79
|
label: "Wallet available",
|
|
81
|
-
value: balances.length ? /* @__PURE__ */ jsx("span", { className: styles.moneyLines, children: balances.map((b) => /* @__PURE__ */ jsx("span", { children: formatMinor(b.availableMinor, b.currency) }, b.currency)) }) : data.wallet?.balances.length ? `No ${currency} balance` :
|
|
80
|
+
value: balances.length ? /* @__PURE__ */ jsx("span", { className: styles.moneyLines, children: balances.map((b) => /* @__PURE__ */ jsx("span", { children: formatMinor(b.availableMinor, b.currency) }, b.currency)) }) : data.wallet?.balances.length ? `No ${currency} balance` : "No wallet",
|
|
82
81
|
sub: balances.length ? `Pending ${balances.map((b) => formatMinor(b.pendingMinor, b.currency)).join(" \xB7 ")}` : void 0,
|
|
83
82
|
hint: "Money in the merchant's Potter wallet that can be paid out now."
|
|
84
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/admin/tenants/%5Bid%5D/tenant-overview.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { Badge } from '@withpotter/ui-kit';\nimport type { TenantDetail } from '@withpotter/lib/admin-api';\nimport { formatMinor } from '@withpotter/lib/wallet-format';\nimport {\n MoneyLines,\n PICK_CURRENCY,\n StatCard,\n byCurrency,\n focusCurrency,\n moneyLines,\n noneText,\n rowFor,\n} from '../../_ui';\nimport { GrowthChart } from '../../growth-chart';\nimport { ActivityFeed } from './tenant-activity-feed';\nimport { JUMP, TenantAttention } from './tenant-attention';\nimport { TenantSidebar } from './tenant-sidebar';\nimport type { TenantTab } from './tenant-header';\nimport styles from './tenant-overview.module.css';\n\nfunction SetupCard({ data }: { data: TenantDetail }) {\n const onboarding = data.onboarding;\n\n if (!onboarding || onboarding.percent >= 100) return null;\n\n // Unfinished steps first: that's what the admin can help with.\n const steps = [...onboarding.steps].sort(\n (a, b) =>\n Number(a.status === 'completed') - Number(b.status === 'completed'),\n );\n\n return (\n <section id={JUMP.setup} className={`adm-panel ${styles.jumpTarget}`}>\n <div className={styles.cardHead}>\n <h2 className={styles.title}>Setup · {onboarding.percent}% done</h2>\n {onboarding.dismissed && (\n <Badge variant=\"secondary\">checklist dismissed</Badge>\n )}\n </div>\n <div className={styles.progress} aria-hidden>\n <span style={{ width: `${onboarding.percent}%` }} />\n </div>\n <ul className={styles.steps}>\n {steps.map((s) => (\n <li key={s.key} data-done={s.status === 'completed'}>\n {s.label}\n <span>{s.status.replaceAll('_', ' ')}</span>\n </li>\n ))}\n </ul>\n </section>\n );\n}\n\n/** The first tab: health and money first, facts on the side. */\nexport function TenantOverview({\n data,\n periodLabel,\n periodControl,\n recentOrders,\n onTab,\n currency = '',\n currencyControl,\n walletNote,\n}: {\n data: TenantDetail;\n periodLabel: string;\n periodControl: ReactNode;\n recentOrders: ReactNode;\n onTab: (tab: TenantTab) => void;\n /** The currency filter's choice; narrows the wallet and recent orders. */\n currency?: string;\n currencyControl?: ReactNode;\n /** Said in place of \"No wallet\" while the ledger loads or cannot be read. */\n walletNote?: string;\n}) {\n // Every currency the wallet holds, one line each; it showed only the first.\n const balances = byCurrency(\n data.wallet?.balances ?? [],\n currency,\n (b) => b.currency,\n );\n const period = data.metrics.window;\n // Sales come back once per currency; the chart draws one of them.\n const sales = data.metrics.byCurrency;\n const lifetime = moneyLines(sales, currency, (r) => r.gmv);\n const focus = focusCurrency(data.currencies ?? [], currency);\n const series = rowFor(data.revenueSeriesByCurrency, focus)?.series;\n\n return (\n <>\n <TenantAttention data={data} onTab={onTab} />\n <div className={styles.layout}>\n <div className={styles.main}>\n <div className={styles.period}>\n <span>Numbers for {periodLabel}</span>\n <div className=\"adm-toolbar\">\n {currencyControl}\n {periodControl}\n </div>\n </div>\n <div className={styles.kpis}>\n <StatCard\n label=\"Wallet available\"\n value={\n balances.length ? (\n <span className={styles.moneyLines}>\n {balances.map((b) => (\n <span key={b.currency}>\n {formatMinor(b.availableMinor, b.currency)}\n </span>\n ))}\n </span>\n ) : data.wallet?.balances.length ? (\n `No ${currency} balance`\n ) : walletNote ? (\n walletNote\n ) : (\n 'No wallet'\n )\n }\n sub={\n balances.length\n ? `Pending ${balances\n .map((b) => formatMinor(b.pendingMinor, b.currency))\n .join(' · ')}`\n : undefined\n }\n hint=\"Money in the merchant's Potter wallet that can be paid out now.\"\n />\n <StatCard\n label=\"Sales\"\n value={\n <MoneyLines\n rows={sales}\n currency={currency}\n amount={(r) => r.window.gmv}\n />\n }\n sub={`Lifetime ${lifetime.length ? lifetime.join(' · ') : noneText(currency)}`}\n hint=\"Gross sales in the selected period; lifetime underneath.\"\n />\n <StatCard\n label=\"Orders\"\n value={String(period.orders)}\n sub={`${period.paidOrders} paid`}\n hint=\"Orders placed in the selected period.\"\n />\n <StatCard\n label=\"Customers\"\n value={String(period.customers)}\n sub={`${data.metrics.totalCustomers} all time`}\n hint=\"Distinct customers who ordered in the selected period.\"\n />\n <StatCard\n label=\"Avg order\"\n value={\n <MoneyLines\n rows={sales}\n currency={currency}\n amount={(r) => r.window.aov}\n />\n }\n sub={`Subscription: ${data.metrics.subscriptionStatus ?? 'none'}`}\n hint=\"Average order value in the selected period, and the plan status.\"\n />\n </div>\n <section className=\"adm-panel\">\n <h2 className={styles.title}>\n Revenue · last 30 days{focus ? ` · ${focus}` : ''}\n </h2>\n {focus || !data.currencies?.length ? (\n <GrowthChart\n data={(series ?? []).map((p) => ({\n date: p.date,\n count: p.amount,\n }))}\n emptyLabel=\"No revenue in the last 30 days\"\n />\n ) : (\n <p className=\"text-sm text-[var(--text-secondary)]\">\n {PICK_CURRENCY}\n </p>\n )}\n </section>\n <SetupCard data={data} />\n <section className=\"adm-panel\">\n <h2 className={styles.title}>Recent activity</h2>\n <ActivityFeed\n entries={data.activity ?? []}\n onViewAll={() => onTab('audit')}\n />\n </section>\n <section>\n <h2 className={styles.title}>Recent orders</h2>\n {recentOrders}\n </section>\n </div>\n <TenantSidebar\n data={data}\n onTeam={() =>\n document\n .getElementById('tenant-team')\n ?.scrollIntoView({ behavior: 'smooth', block: 'start' })\n }\n />\n </div>\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../src/admin/tenants/%5Bid%5D/tenant-overview.tsx"],"sourcesContent":["'use client';\n\nimport type { ReactNode } from 'react';\nimport { Badge } from '@withpotter/ui-kit';\nimport type { TenantDetail } from '@withpotter/lib/admin-api';\nimport { formatMinor } from '@withpotter/lib/wallet-format';\nimport {\n MoneyLines,\n PICK_CURRENCY,\n StatCard,\n byCurrency,\n focusCurrency,\n moneyLines,\n noneText,\n rowFor,\n} from '../../_ui';\nimport { GrowthChart } from '../../growth-chart';\nimport { ActivityFeed } from './tenant-activity-feed';\nimport { JUMP, TenantAttention } from './tenant-attention';\nimport { TenantSidebar } from './tenant-sidebar';\nimport type { TenantTab } from './tenant-header';\nimport styles from './tenant-overview.module.css';\n\nfunction SetupCard({ data }: { data: TenantDetail }) {\n const onboarding = data.onboarding;\n\n if (!onboarding || onboarding.percent >= 100) return null;\n\n // Unfinished steps first: that's what the admin can help with.\n const steps = [...onboarding.steps].sort(\n (a, b) =>\n Number(a.status === 'completed') - Number(b.status === 'completed'),\n );\n\n return (\n <section id={JUMP.setup} className={`adm-panel ${styles.jumpTarget}`}>\n <div className={styles.cardHead}>\n <h2 className={styles.title}>Setup · {onboarding.percent}% done</h2>\n {onboarding.dismissed && (\n <Badge variant=\"secondary\">checklist dismissed</Badge>\n )}\n </div>\n <div className={styles.progress} aria-hidden>\n <span style={{ width: `${onboarding.percent}%` }} />\n </div>\n <ul className={styles.steps}>\n {steps.map((s) => (\n <li key={s.key} data-done={s.status === 'completed'}>\n {s.label}\n <span>{s.status.replaceAll('_', ' ')}</span>\n </li>\n ))}\n </ul>\n </section>\n );\n}\n\n/** The first tab: health and money first, facts on the side. */\nexport function TenantOverview({\n data,\n periodLabel,\n periodControl,\n recentOrders,\n onTab,\n currency = '',\n currencyControl,\n}: {\n data: TenantDetail;\n periodLabel: string;\n periodControl: ReactNode;\n recentOrders: ReactNode;\n onTab: (tab: TenantTab) => void;\n /** The currency filter's choice; narrows the wallet and recent orders. */\n currency?: string;\n currencyControl?: ReactNode;\n}) {\n // Every currency the wallet holds, one line each; it showed only the first.\n const balances = byCurrency(\n data.wallet?.balances ?? [],\n currency,\n (b) => b.currency,\n );\n const period = data.metrics.window;\n // Sales come back once per currency; the chart draws one of them.\n const sales = data.metrics.byCurrency;\n const lifetime = moneyLines(sales, currency, (r) => r.gmv);\n const focus = focusCurrency(data.currencies ?? [], currency);\n const series = rowFor(data.revenueSeriesByCurrency, focus)?.series;\n\n return (\n <>\n <TenantAttention data={data} onTab={onTab} />\n <div className={styles.layout}>\n <div className={styles.main}>\n <div className={styles.period}>\n <span>Numbers for {periodLabel}</span>\n <div className=\"adm-toolbar\">\n {currencyControl}\n {periodControl}\n </div>\n </div>\n <div className={styles.kpis}>\n <StatCard\n label=\"Wallet available\"\n value={\n balances.length ? (\n <span className={styles.moneyLines}>\n {balances.map((b) => (\n <span key={b.currency}>\n {formatMinor(b.availableMinor, b.currency)}\n </span>\n ))}\n </span>\n ) : data.wallet?.balances.length ? (\n `No ${currency} balance`\n ) : (\n 'No wallet'\n )\n }\n sub={\n balances.length\n ? `Pending ${balances\n .map((b) => formatMinor(b.pendingMinor, b.currency))\n .join(' · ')}`\n : undefined\n }\n hint=\"Money in the merchant's Potter wallet that can be paid out now.\"\n />\n <StatCard\n label=\"Sales\"\n value={\n <MoneyLines\n rows={sales}\n currency={currency}\n amount={(r) => r.window.gmv}\n />\n }\n sub={`Lifetime ${lifetime.length ? lifetime.join(' · ') : noneText(currency)}`}\n hint=\"Gross sales in the selected period; lifetime underneath.\"\n />\n <StatCard\n label=\"Orders\"\n value={String(period.orders)}\n sub={`${period.paidOrders} paid`}\n hint=\"Orders placed in the selected period.\"\n />\n <StatCard\n label=\"Customers\"\n value={String(period.customers)}\n sub={`${data.metrics.totalCustomers} all time`}\n hint=\"Distinct customers who ordered in the selected period.\"\n />\n <StatCard\n label=\"Avg order\"\n value={\n <MoneyLines\n rows={sales}\n currency={currency}\n amount={(r) => r.window.aov}\n />\n }\n sub={`Subscription: ${data.metrics.subscriptionStatus ?? 'none'}`}\n hint=\"Average order value in the selected period, and the plan status.\"\n />\n </div>\n <section className=\"adm-panel\">\n <h2 className={styles.title}>\n Revenue · last 30 days{focus ? ` · ${focus}` : ''}\n </h2>\n {focus || !data.currencies?.length ? (\n <GrowthChart\n data={(series ?? []).map((p) => ({\n date: p.date,\n count: p.amount,\n }))}\n emptyLabel=\"No revenue in the last 30 days\"\n />\n ) : (\n <p className=\"text-sm text-[var(--text-secondary)]\">\n {PICK_CURRENCY}\n </p>\n )}\n </section>\n <SetupCard data={data} />\n <section className=\"adm-panel\">\n <h2 className={styles.title}>Recent activity</h2>\n <ActivityFeed\n entries={data.activity ?? []}\n onViewAll={() => onTab('audit')}\n />\n </section>\n <section>\n <h2 className={styles.title}>Recent orders</h2>\n {recentOrders}\n </section>\n </div>\n <TenantSidebar\n data={data}\n onTeam={() =>\n document\n .getElementById('tenant-team')\n ?.scrollIntoView({ behavior: 'smooth', block: 'start' })\n }\n />\n </div>\n </>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
.attentionAction:hover {
|
|
124
124
|
background: color-mix(in srgb, var(--accent-primary) 10%, transparent);
|
|
125
125
|
}
|
|
126
|
-
/* Where the banner jumps to: then flash once. */
|
|
126
|
+
/* Where the banner jumps to: clear the sticky header, then flash once. */
|
|
127
127
|
.jumpTarget {
|
|
128
128
|
scroll-margin-top: 200px;
|
|
129
129
|
}
|
|
@@ -3,14 +3,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import Link from "next/link";
|
|
4
4
|
import { useRouter } from "next/navigation";
|
|
5
5
|
import { EmptyNote } from "@withpotter/ui-kit";
|
|
6
|
-
import {
|
|
7
|
-
AdmLoading,
|
|
8
|
-
CurrencyFilter,
|
|
9
|
-
PageTabs,
|
|
10
|
-
currenciesIn,
|
|
11
|
-
useCurrencyParam,
|
|
12
|
-
useTabParam
|
|
13
|
-
} from "../../_ui";
|
|
6
|
+
import { AdmLoading, CurrencyFilter, currenciesIn, useCurrencyParam } from "../../_ui";
|
|
14
7
|
import { ListCard } from "../../_ui/list-card";
|
|
15
8
|
import { LoadError, MoneyLines } from "../../_pos/pos-parts";
|
|
16
9
|
import { count } from "../../_pos/pos-words";
|
|
@@ -20,32 +13,10 @@ import { usePosAccess } from "../../_pos/use-pos-access";
|
|
|
20
13
|
import { usePosPeriod } from "../../_pos/use-pos-period";
|
|
21
14
|
import { useTenantPos } from "../../_pos/use-pos";
|
|
22
15
|
import pos from "../../_pos/pos.module.css";
|
|
23
|
-
import {
|
|
24
|
-
import { TenantOperators } from "../../_pos/tenant-operators";
|
|
25
|
-
import { TenantOutlets } from "../../_pos/tenant-outlets";
|
|
26
|
-
import { TenantRequests } from "../../_pos/tenant-requests";
|
|
27
|
-
import { TenantTransactions } from "../../_pos/tenant-transactions";
|
|
28
|
-
import { TenantPosFigures } from "../../_pos/tenant-pos-figures";
|
|
29
|
-
import { ShiftsTab } from "../../pos/shifts-tab";
|
|
30
|
-
import {
|
|
31
|
-
TerminalHead,
|
|
32
|
-
TerminalRow,
|
|
33
|
-
terminalColumns
|
|
34
|
-
} from "../../pos/terminal-row";
|
|
35
|
-
const VIEWS = [
|
|
36
|
-
{ id: "overview", label: "Overview" },
|
|
37
|
-
{ id: "terminals", label: "Terminals" },
|
|
38
|
-
{ id: "sessions", label: "Sessions" },
|
|
39
|
-
{ id: "operators", label: "Operators" },
|
|
40
|
-
{ id: "outlets", label: "Outlets" },
|
|
41
|
-
{ id: "transactions", label: "Transactions" },
|
|
42
|
-
{ id: "requests", label: "Requests" }
|
|
43
|
-
];
|
|
44
|
-
const VIEW_KEYS = VIEWS.map((v) => v.id);
|
|
16
|
+
import { TerminalHead, TerminalRow, terminalColumns } from "../../pos/terminal-row";
|
|
45
17
|
function TenantPos({ tenantId }) {
|
|
46
18
|
const router = useRouter();
|
|
47
19
|
const { isLoading: accessLoading, canRead } = usePosAccess();
|
|
48
|
-
const [view, setView] = useTabParam(VIEW_KEYS, "view");
|
|
49
20
|
const { period, phrase, control } = usePosPeriod();
|
|
50
21
|
const [currency, setCurrency] = useCurrencyParam();
|
|
51
22
|
const query = useTenantPos(tenantId, period, canRead);
|
|
@@ -75,14 +46,7 @@ function TenantPos({ tenantId }) {
|
|
|
75
46
|
/* @__PURE__ */ jsx(MoneyLines, { amounts: data.takings.amounts, currency }),
|
|
76
47
|
` taken, ${phrase} \xB7 `
|
|
77
48
|
] }) : null,
|
|
78
|
-
/* @__PURE__ */ jsx(
|
|
79
|
-
Link,
|
|
80
|
-
{
|
|
81
|
-
href: `/admin/pos?tenant=${tenantId}`,
|
|
82
|
-
className: "text-brand-500 hover:underline",
|
|
83
|
-
children: "Open in POS"
|
|
84
|
-
}
|
|
85
|
-
)
|
|
49
|
+
/* @__PURE__ */ jsx(Link, { href: `/admin/pos?tenant=${tenantId}`, className: "text-brand-500 hover:underline", children: "Open in POS" })
|
|
86
50
|
] }),
|
|
87
51
|
/* @__PURE__ */ jsxs("div", { className: "adm-toolbar", children: [
|
|
88
52
|
/* @__PURE__ */ jsx(
|
|
@@ -90,31 +54,13 @@ function TenantPos({ tenantId }) {
|
|
|
90
54
|
{
|
|
91
55
|
value: currency,
|
|
92
56
|
onChange: setCurrency,
|
|
93
|
-
currencies: currenciesIn(
|
|
94
|
-
data.takings.amounts.map((a) => a.currency)
|
|
95
|
-
)
|
|
57
|
+
currencies: currenciesIn(data.takings.amounts.map((a) => a.currency))
|
|
96
58
|
}
|
|
97
59
|
),
|
|
98
60
|
control
|
|
99
61
|
] })
|
|
100
62
|
] }),
|
|
101
|
-
/* @__PURE__ */ jsx(
|
|
102
|
-
view === "overview" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
103
|
-
/* @__PURE__ */ jsx(TenantPosFigures, { data, phrase, currency }),
|
|
104
|
-
/* @__PURE__ */ jsx(OliveBalance, { tenantId }),
|
|
105
|
-
/* @__PURE__ */ jsx(
|
|
106
|
-
ShiftsTable,
|
|
107
|
-
{
|
|
108
|
-
title: "Open shifts",
|
|
109
|
-
rows: data.openShifts,
|
|
110
|
-
total: data.openShifts.length,
|
|
111
|
-
withBusiness: false,
|
|
112
|
-
currency,
|
|
113
|
-
emptyTitle: "No till is open right now."
|
|
114
|
-
}
|
|
115
|
-
)
|
|
116
|
-
] }),
|
|
117
|
-
view === "terminals" && /* @__PURE__ */ jsx(
|
|
63
|
+
/* @__PURE__ */ jsx(
|
|
118
64
|
ListCard,
|
|
119
65
|
{
|
|
120
66
|
title: "Terminals",
|
|
@@ -136,11 +82,17 @@ function TenantPos({ tenantId }) {
|
|
|
136
82
|
))
|
|
137
83
|
}
|
|
138
84
|
),
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
85
|
+
/* @__PURE__ */ jsx(
|
|
86
|
+
ShiftsTable,
|
|
87
|
+
{
|
|
88
|
+
title: "Open shifts",
|
|
89
|
+
rows: data.openShifts,
|
|
90
|
+
total: data.openShifts.length,
|
|
91
|
+
withBusiness: false,
|
|
92
|
+
currency,
|
|
93
|
+
emptyTitle: "No till is open right now."
|
|
94
|
+
}
|
|
95
|
+
)
|
|
144
96
|
] });
|
|
145
97
|
}
|
|
146
98
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/admin/tenants/%5Bid%5D/tenant-pos.tsx"],"sourcesContent":["'use client';\n\nimport Link from 'next/link';\nimport { useRouter } from 'next/navigation';\nimport { EmptyNote } from '@withpotter/ui-kit';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../src/admin/tenants/%5Bid%5D/tenant-pos.tsx"],"sourcesContent":["'use client';\n\nimport Link from 'next/link';\nimport { useRouter } from 'next/navigation';\nimport { EmptyNote } from '@withpotter/ui-kit';\nimport { AdmLoading, CurrencyFilter, currenciesIn, useCurrencyParam } from '../../_ui';\nimport { ListCard } from '../../_ui/list-card';\nimport { LoadError, MoneyLines } from '../../_pos/pos-parts';\nimport { count } from '../../_pos/pos-words';\nimport { terminalHref } from '../../_pos/shift-row';\nimport { ShiftsTable } from '../../_pos/shifts-table';\nimport { usePosAccess } from '../../_pos/use-pos-access';\nimport { usePosPeriod } from '../../_pos/use-pos-period';\nimport { useTenantPos } from '../../_pos/use-pos';\nimport pos from '../../_pos/pos.module.css';\nimport { TerminalHead, TerminalRow, terminalColumns } from '../../pos/terminal-row';\n\n/**\n * Merchant 360 → POS: the business's terminals, the shifts open now, and\n * what its terminals took in the period, per currency.\n */\nexport function TenantPos({ tenantId }: { tenantId: string }) {\n const router = useRouter();\n const { isLoading: accessLoading, canRead } = usePosAccess();\n const { period, phrase, control } = usePosPeriod();\n const [currency, setCurrency] = useCurrencyParam();\n const query = useTenantPos(tenantId, period, canRead);\n const data = query.data;\n\n if (accessLoading || (canRead && query.isLoading))\n return <AdmLoading label=\"Loading POS…\" />;\n\n if (!canRead)\n return (\n <EmptyNote well>{\"You don't have permission to see this business's POS.\"}</EmptyNote>\n );\n\n if (query.isError || !data)\n return (\n <LoadError\n error={query.error}\n what=\"this business's POS\"\n onRetry={() => void query.refetch()}\n />\n );\n\n const live = data.terminals.filter((t) => t.status !== 'revoked').length;\n const revoked = data.terminals.length - live;\n\n return (\n <div className={pos.stack}>\n <div className={pos.toolbarRow}>\n <span className=\"adm-caption\">\n {`${count(live, 'terminal')} in use`}\n {revoked ? `, ${revoked} revoked` : ''}\n {' · '}\n {data.takings.count > 0 ? (\n <>\n <MoneyLines amounts={data.takings.amounts} currency={currency} />\n {` taken, ${phrase} · `}\n </>\n ) : null}\n <Link href={`/admin/pos?tenant=${tenantId}`} className=\"text-brand-500 hover:underline\">\n Open in POS\n </Link>\n </span>\n <div className=\"adm-toolbar\">\n <CurrencyFilter\n value={currency}\n onChange={setCurrency}\n currencies={currenciesIn(data.takings.amounts.map((a) => a.currency))}\n />\n {control}\n </div>\n </div>\n\n <ListCard\n title=\"Terminals\"\n count={data.terminals.length}\n columns={terminalColumns(false)}\n minWidth={860}\n errorTitle=\"\"\n isEmpty={data.terminals.length === 0}\n emptyTitle=\"This business has no terminals.\"\n head={<TerminalHead withBusiness={false} />}\n >\n {data.terminals.map((t) => (\n <TerminalRow\n key={t.id}\n t={t}\n currency={currency}\n onOpen={() => router.push(terminalHref(t.id))}\n />\n ))}\n </ListCard>\n\n <ShiftsTable\n title=\"Open shifts\"\n rows={data.openShifts}\n total={data.openShifts.length}\n withBusiness={false}\n currency={currency}\n emptyTitle=\"No till is open right now.\"\n />\n </div>\n );\n}\n"],"mappings":";AA8BW,SA2BC,UA3BD,KA2BC,YA3BD;AA5BX,OAAO,UAAU;AACjB,SAAS,iBAAiB;AAC1B,SAAS,iBAAiB;AAC1B,SAAS,YAAY,gBAAgB,cAAc,wBAAwB;AAC3E,SAAS,gBAAgB;AACzB,SAAS,WAAW,kBAAkB;AACtC,SAAS,aAAa;AACtB,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,OAAO,SAAS;AAChB,SAAS,cAAc,aAAa,uBAAuB;AAMpD,SAAS,UAAU,EAAE,SAAS,GAAyB;AAC5D,QAAM,SAAS,UAAU;AACzB,QAAM,EAAE,WAAW,eAAe,QAAQ,IAAI,aAAa;AAC3D,QAAM,EAAE,QAAQ,QAAQ,QAAQ,IAAI,aAAa;AACjD,QAAM,CAAC,UAAU,WAAW,IAAI,iBAAiB;AACjD,QAAM,QAAQ,aAAa,UAAU,QAAQ,OAAO;AACpD,QAAM,OAAO,MAAM;AAEnB,MAAI,iBAAkB,WAAW,MAAM;AACrC,WAAO,oBAAC,cAAW,OAAM,qBAAe;AAE1C,MAAI,CAAC;AACH,WACE,oBAAC,aAAU,MAAI,MAAE,mEAAwD;AAG7E,MAAI,MAAM,WAAW,CAAC;AACpB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,OAAO,MAAM;AAAA,QACb,MAAK;AAAA,QACL,SAAS,MAAM,KAAK,MAAM,QAAQ;AAAA;AAAA,IACpC;AAGJ,QAAM,OAAO,KAAK,UAAU,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE;AAClE,QAAM,UAAU,KAAK,UAAU,SAAS;AAExC,SACE,qBAAC,SAAI,WAAW,IAAI,OAClB;AAAA,yBAAC,SAAI,WAAW,IAAI,YAClB;AAAA,2BAAC,UAAK,WAAU,eACb;AAAA,WAAG,MAAM,MAAM,UAAU,CAAC;AAAA,QAC1B,UAAU,KAAK,OAAO,aAAa;AAAA,QACnC;AAAA,QACA,KAAK,QAAQ,QAAQ,IACpB,iCACE;AAAA,8BAAC,cAAW,SAAS,KAAK,QAAQ,SAAS,UAAoB;AAAA,UAC9D,WAAW,MAAM;AAAA,WACpB,IACE;AAAA,QACJ,oBAAC,QAAK,MAAM,qBAAqB,QAAQ,IAAI,WAAU,kCAAiC,yBAExF;AAAA,SACF;AAAA,MACA,qBAAC,SAAI,WAAU,eACb;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU;AAAA,YACV,YAAY,aAAa,KAAK,QAAQ,QAAQ,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC;AAAA;AAAA,QACtE;AAAA,QACC;AAAA,SACH;AAAA,OACF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAO,KAAK,UAAU;AAAA,QACtB,SAAS,gBAAgB,KAAK;AAAA,QAC9B,UAAU;AAAA,QACV,YAAW;AAAA,QACX,SAAS,KAAK,UAAU,WAAW;AAAA,QACnC,YAAW;AAAA,QACX,MAAM,oBAAC,gBAAa,cAAc,OAAO;AAAA,QAExC,eAAK,UAAU,IAAI,CAAC,MACnB;AAAA,UAAC;AAAA;AAAA,YAEC;AAAA,YACA;AAAA,YACA,QAAQ,MAAM,OAAO,KAAK,aAAa,EAAE,EAAE,CAAC;AAAA;AAAA,UAHvC,EAAE;AAAA,QAIT,CACD;AAAA;AAAA,IACH;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,MAAM,KAAK;AAAA,QACX,OAAO,KAAK,WAAW;AAAA,QACvB,cAAc;AAAA,QACd;AAAA,QACA,YAAW;AAAA;AAAA,IACb;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -6,8 +6,7 @@ import { byCurrency } from "../../_ui/currency-filter-model";
|
|
|
6
6
|
import styles from "./tenant-overview.module.css";
|
|
7
7
|
function TenantWalletCard({
|
|
8
8
|
data,
|
|
9
|
-
currency = ""
|
|
10
|
-
walletNote
|
|
9
|
+
currency = ""
|
|
11
10
|
}) {
|
|
12
11
|
const wallet = data.wallet;
|
|
13
12
|
const balances = byCurrency(
|
|
@@ -26,7 +25,7 @@ function TenantWalletCard({
|
|
|
26
25
|
}
|
|
27
26
|
)
|
|
28
27
|
] }),
|
|
29
|
-
!wallet
|
|
28
|
+
!wallet ? /* @__PURE__ */ jsx("p", { children: "No wallet yet \u2014 it is created when the merchant activates payments." }) : balances.length === 0 ? /* @__PURE__ */ jsxs("p", { children: [
|
|
30
29
|
"The wallet holds no ",
|
|
31
30
|
currency,
|
|
32
31
|
" balance."
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/admin/tenants/%5Bid%5D/tenant-wallet-card.tsx"],"sourcesContent":["'use client';\n\nimport { Badge } from '@withpotter/ui-kit';\nimport type { TenantDetail } from '@withpotter/lib/admin-api';\nimport { formatMinor, sameStatus } from '@withpotter/lib/wallet-format';\nimport { byCurrency } from '../../_ui/currency-filter-model';\nimport styles from './tenant-overview.module.css';\n\n/** Every balance the merchant's Potter wallet holds, per currency. */\nexport function TenantWalletCard({\n data,\n currency = '',\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/admin/tenants/%5Bid%5D/tenant-wallet-card.tsx"],"sourcesContent":["'use client';\n\nimport { Badge } from '@withpotter/ui-kit';\nimport type { TenantDetail } from '@withpotter/lib/admin-api';\nimport { formatMinor, sameStatus } from '@withpotter/lib/wallet-format';\nimport { byCurrency } from '../../_ui/currency-filter-model';\nimport styles from './tenant-overview.module.css';\n\n/** Every balance the merchant's Potter wallet holds, per currency. */\nexport function TenantWalletCard({\n data,\n currency = '',\n}: {\n data: TenantDetail;\n /** The currency filter's choice; '' shows every currency. */\n currency?: string;\n}) {\n const wallet = data.wallet;\n const balances = byCurrency(\n wallet?.balances ?? [],\n currency,\n (b) => b.currency,\n );\n\n return (\n <section className=\"adm-panel\" style={{ marginBottom: 16 }}>\n <h2 className={styles.title}>\n Wallet\n {wallet && (\n <Badge\n variant={\n sameStatus(wallet.status) === 'active' ? 'success' : 'warning'\n }\n >\n {sameStatus(wallet.status).replaceAll('_', ' ')}\n </Badge>\n )}\n </h2>\n {!wallet ? (\n <p>\n No wallet yet — it is created when the merchant activates payments.\n </p>\n ) : balances.length === 0 ? (\n <p>The wallet holds no {currency} balance.</p>\n ) : (\n <div className={styles.kpis}>\n {balances.flatMap((b) =>\n [\n ['Available', b.availableMinor],\n ['Pending', b.pendingMinor],\n ['Paying out', b.payoutPendingMinor],\n ['Restricted', b.restrictedMinor],\n ].map(([label, minor]) => (\n <div key={`${b.currency}-${label}`}>\n <div className={styles.title}>\n {b.currency} {label}\n </div>\n <strong>{formatMinor(minor, b.currency)}</strong>\n </div>\n )),\n )}\n </div>\n )}\n </section>\n );\n}\n"],"mappings":";AA0BM,SAGI,KAHJ;AAxBN,SAAS,aAAa;AAEtB,SAAS,aAAa,kBAAkB;AACxC,SAAS,kBAAkB;AAC3B,OAAO,YAAY;AAGZ,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,WAAW;AACb,GAIG;AACD,QAAM,SAAS,KAAK;AACpB,QAAM,WAAW;AAAA,IACf,QAAQ,YAAY,CAAC;AAAA,IACrB;AAAA,IACA,CAAC,MAAM,EAAE;AAAA,EACX;AAEA,SACE,qBAAC,aAAQ,WAAU,aAAY,OAAO,EAAE,cAAc,GAAG,GACvD;AAAA,yBAAC,QAAG,WAAW,OAAO,OAAO;AAAA;AAAA,MAE1B,UACC;AAAA,QAAC;AAAA;AAAA,UACC,SACE,WAAW,OAAO,MAAM,MAAM,WAAW,YAAY;AAAA,UAGtD,qBAAW,OAAO,MAAM,EAAE,WAAW,KAAK,GAAG;AAAA;AAAA,MAChD;AAAA,OAEJ;AAAA,IACC,CAAC,SACA,oBAAC,OAAE,sFAEH,IACE,SAAS,WAAW,IACtB,qBAAC,OAAE;AAAA;AAAA,MAAqB;AAAA,MAAS;AAAA,OAAS,IAE1C,oBAAC,SAAI,WAAW,OAAO,MACpB,mBAAS;AAAA,MAAQ,CAAC,MACjB;AAAA,QACE,CAAC,aAAa,EAAE,cAAc;AAAA,QAC9B,CAAC,WAAW,EAAE,YAAY;AAAA,QAC1B,CAAC,cAAc,EAAE,kBAAkB;AAAA,QACnC,CAAC,cAAc,EAAE,eAAe;AAAA,MAClC,EAAE,IAAI,CAAC,CAAC,OAAO,KAAK,MAClB,qBAAC,SACC;AAAA,6BAAC,SAAI,WAAW,OAAO,OACpB;AAAA,YAAE;AAAA,UAAS;AAAA,UAAE;AAAA,WAChB;AAAA,QACA,oBAAC,YAAQ,sBAAY,OAAO,EAAE,QAAQ,GAAE;AAAA,WAJhC,GAAG,EAAE,QAAQ,IAAI,KAAK,EAKhC,CACD;AAAA,IACH,GACF;AAAA,KAEJ;AAEJ;","names":[]}
|
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useState } from "react";
|
|
4
|
+
import { useQuery } from "@tanstack/react-query";
|
|
4
5
|
import { Button } from "@withpotter/ui-kit";
|
|
5
|
-
import {
|
|
6
|
+
import { adminCaseApi } from "@withpotter/lib/admin-case-api";
|
|
7
|
+
import { AdmLoading, Drawer } from "../../../_ui";
|
|
6
8
|
import { documentWord } from "./case-checks";
|
|
9
|
+
import { caseErrorText } from "./case-rules";
|
|
7
10
|
import { checkTone, checkWord, shortDate } from "./case-words";
|
|
8
|
-
import {
|
|
9
|
-
|
|
11
|
+
import {
|
|
12
|
+
documentLinkKey,
|
|
13
|
+
ownerName,
|
|
14
|
+
pdfSource,
|
|
15
|
+
viewerKind
|
|
16
|
+
} from "./document-view";
|
|
10
17
|
import styles from "./document-viewer.module.css";
|
|
11
18
|
function DocumentViewer({
|
|
12
19
|
tenantId,
|
|
@@ -40,6 +47,48 @@ function DocumentViewer({
|
|
|
40
47
|
}
|
|
41
48
|
);
|
|
42
49
|
}
|
|
50
|
+
function DocumentFile({
|
|
51
|
+
tenantId,
|
|
52
|
+
document
|
|
53
|
+
}) {
|
|
54
|
+
const link = useQuery({
|
|
55
|
+
queryKey: documentLinkKey(tenantId, document.id),
|
|
56
|
+
queryFn: () => adminCaseApi.viewDocument(tenantId, document.id),
|
|
57
|
+
retry: false,
|
|
58
|
+
staleTime: Infinity,
|
|
59
|
+
gcTime: 0,
|
|
60
|
+
refetchOnWindowFocus: false,
|
|
61
|
+
refetchOnReconnect: false
|
|
62
|
+
});
|
|
63
|
+
const name = documentWord(document);
|
|
64
|
+
if (link.isLoading) return /* @__PURE__ */ jsx(AdmLoading, { label: "Opening document\u2026" });
|
|
65
|
+
if (link.isError || !link.data)
|
|
66
|
+
return /* @__PURE__ */ jsx("p", { className: styles.note, role: "alert", children: caseErrorText(link.error, "document") });
|
|
67
|
+
const kind = viewerKind(link.data.mimeType);
|
|
68
|
+
if (kind === "image")
|
|
69
|
+
return /* @__PURE__ */ jsx("div", { className: styles.frame, children: /* @__PURE__ */ jsx(
|
|
70
|
+
"img",
|
|
71
|
+
{
|
|
72
|
+
className: styles.image,
|
|
73
|
+
src: link.data.url,
|
|
74
|
+
alt: name,
|
|
75
|
+
referrerPolicy: "no-referrer",
|
|
76
|
+
draggable: false,
|
|
77
|
+
onContextMenu: (e) => e.preventDefault()
|
|
78
|
+
}
|
|
79
|
+
) });
|
|
80
|
+
if (kind === "pdf")
|
|
81
|
+
return /* @__PURE__ */ jsx("div", { className: styles.frame, children: /* @__PURE__ */ jsx(
|
|
82
|
+
"iframe",
|
|
83
|
+
{
|
|
84
|
+
className: styles.pdf,
|
|
85
|
+
src: pdfSource(link.data.url),
|
|
86
|
+
title: name,
|
|
87
|
+
referrerPolicy: "no-referrer"
|
|
88
|
+
}
|
|
89
|
+
) });
|
|
90
|
+
return /* @__PURE__ */ jsx("p", { className: styles.note, children: "This file type can't be shown here." });
|
|
91
|
+
}
|
|
43
92
|
export {
|
|
44
93
|
DocumentViewer
|
|
45
94
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/admin/tenants/%5Bid%5D/verification/document-viewer.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { Button } from '@withpotter/ui-kit';\nimport type {\n CaseDocument,\n CasePerson,\n} from '@withpotter/lib/admin-case-types';\nimport { Drawer } from '../../../_ui';\nimport { documentWord } from './case-checks';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../src/admin/tenants/%5Bid%5D/verification/document-viewer.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { Button } from '@withpotter/ui-kit';\nimport { adminCaseApi } from '@withpotter/lib/admin-case-api';\nimport type {\n CaseDocument,\n CasePerson,\n} from '@withpotter/lib/admin-case-types';\nimport { AdmLoading, Drawer } from '../../../_ui';\nimport { documentWord } from './case-checks';\nimport { caseErrorText } from './case-rules';\nimport { checkTone, checkWord, shortDate } from './case-words';\nimport {\n documentLinkKey,\n ownerName,\n pdfSource,\n viewerKind,\n} from './document-view';\nimport styles from './document-viewer.module.css';\n\n/**\n * One document a business sent, in a side panel beside the case (Square):\n * the photo or PDF, whose it is and what its check said. Close is the only\n * action; the file is shown, never offered as a download. Each opening asks\n * the server for a fresh 60-second link, and the server logs it.\n */\nexport function DocumentViewer({\n tenantId,\n document,\n people,\n onClose,\n}: {\n tenantId: string;\n document: CaseDocument | null;\n people: CasePerson[];\n onClose: () => void;\n}) {\n // Keep the last document on screen while the panel slides out.\n const [shown, setShown] = useState(document);\n\n if (document && document !== shown) setShown(document);\n\n return (\n <Drawer\n open={Boolean(document)}\n onClose={onClose}\n width={640}\n title={shown ? documentWord(shown) : 'Document'}\n subtitle={shown ? ownerName(shown, people) : undefined}\n meta={\n shown ? (\n <span\n className={styles.tone}\n data-tone={checkTone(shown.checkStatus)}\n >\n {checkWord(shown.checkStatus, null)}\n {shown.sentAt ? ` · Sent ${shortDate(shown.sentAt)}` : ''}\n </span>\n ) : undefined\n }\n footer={\n <Button variant=\"secondary\" onClick={onClose}>\n Close\n </Button>\n }\n >\n {shown && document && (\n <DocumentFile tenantId={tenantId} document={shown} />\n )}\n </Drawer>\n );\n}\n\nfunction DocumentFile({\n tenantId,\n document,\n}: {\n tenantId: string;\n document: CaseDocument;\n}) {\n // One link per opening: no retries or refetches, each would be another logged view.\n const link = useQuery({\n queryKey: documentLinkKey(tenantId, document.id),\n queryFn: () => adminCaseApi.viewDocument(tenantId, document.id),\n retry: false,\n staleTime: Infinity,\n gcTime: 0,\n refetchOnWindowFocus: false,\n refetchOnReconnect: false,\n });\n const name = documentWord(document);\n\n if (link.isLoading) return <AdmLoading label=\"Opening document…\" />;\n\n if (link.isError || !link.data)\n return (\n <p className={styles.note} role=\"alert\">\n {caseErrorText(link.error, 'document')}\n </p>\n );\n\n const kind = viewerKind(link.data.mimeType);\n\n if (kind === 'image')\n return (\n <div className={styles.frame}>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n className={styles.image}\n src={link.data.url}\n alt={name}\n referrerPolicy=\"no-referrer\"\n draggable={false}\n onContextMenu={(e) => e.preventDefault()}\n />\n </div>\n );\n\n if (kind === 'pdf')\n return (\n <div className={styles.frame}>\n <iframe\n className={styles.pdf}\n src={pdfSource(link.data.url)}\n title={name}\n referrerPolicy=\"no-referrer\"\n />\n </div>\n );\n\n return <p className={styles.note}>This file type can't be shown here.</p>;\n}\n"],"mappings":";AAqDU,SAUF,KAVE;AAnDV,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,cAAc;AACvB,SAAS,oBAAoB;AAK7B,SAAS,YAAY,cAAc;AACnC,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,WAAW,WAAW,iBAAiB;AAChD;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,OAAO,YAAY;AAQZ,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AAED,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,QAAQ;AAE3C,MAAI,YAAY,aAAa,MAAO,UAAS,QAAQ;AAErD,SACE;AAAA,IAAC;AAAA;AAAA,MACC,MAAM,QAAQ,QAAQ;AAAA,MACtB;AAAA,MACA,OAAO;AAAA,MACP,OAAO,QAAQ,aAAa,KAAK,IAAI;AAAA,MACrC,UAAU,QAAQ,UAAU,OAAO,MAAM,IAAI;AAAA,MAC7C,MACE,QACE;AAAA,QAAC;AAAA;AAAA,UACC,WAAW,OAAO;AAAA,UAClB,aAAW,UAAU,MAAM,WAAW;AAAA,UAErC;AAAA,sBAAU,MAAM,aAAa,IAAI;AAAA,YACjC,MAAM,SAAS,cAAW,UAAU,MAAM,MAAM,CAAC,KAAK;AAAA;AAAA;AAAA,MACzD,IACE;AAAA,MAEN,QACE,oBAAC,UAAO,SAAQ,aAAY,SAAS,SAAS,mBAE9C;AAAA,MAGD,mBAAS,YACR,oBAAC,gBAAa,UAAoB,UAAU,OAAO;AAAA;AAAA,EAEvD;AAEJ;AAEA,SAAS,aAAa;AAAA,EACpB;AAAA,EACA;AACF,GAGG;AAED,QAAM,OAAO,SAAS;AAAA,IACpB,UAAU,gBAAgB,UAAU,SAAS,EAAE;AAAA,IAC/C,SAAS,MAAM,aAAa,aAAa,UAAU,SAAS,EAAE;AAAA,IAC9D,OAAO;AAAA,IACP,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,sBAAsB;AAAA,IACtB,oBAAoB;AAAA,EACtB,CAAC;AACD,QAAM,OAAO,aAAa,QAAQ;AAElC,MAAI,KAAK,UAAW,QAAO,oBAAC,cAAW,OAAM,0BAAoB;AAEjE,MAAI,KAAK,WAAW,CAAC,KAAK;AACxB,WACE,oBAAC,OAAE,WAAW,OAAO,MAAM,MAAK,SAC7B,wBAAc,KAAK,OAAO,UAAU,GACvC;AAGJ,QAAM,OAAO,WAAW,KAAK,KAAK,QAAQ;AAE1C,MAAI,SAAS;AACX,WACE,oBAAC,SAAI,WAAW,OAAO,OAErB;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,OAAO;AAAA,QAClB,KAAK,KAAK,KAAK;AAAA,QACf,KAAK;AAAA,QACL,gBAAe;AAAA,QACf,WAAW;AAAA,QACX,eAAe,CAAC,MAAM,EAAE,eAAe;AAAA;AAAA,IACzC,GACF;AAGJ,MAAI,SAAS;AACX,WACE,oBAAC,SAAI,WAAW,OAAO,OACrB;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,OAAO;AAAA,QAClB,KAAK,UAAU,KAAK,KAAK,GAAG;AAAA,QAC5B,OAAO;AAAA,QACP,gBAAe;AAAA;AAAA,IACjB,GACF;AAGJ,SAAO,oBAAC,OAAE,WAAW,OAAO,MAAM,iDAAmC;AACvE;","names":[]}
|
|
@@ -45,54 +45,3 @@
|
|
|
45
45
|
.tone[data-tone='bad'] {
|
|
46
46
|
color: var(--error);
|
|
47
47
|
}
|
|
48
|
-
|
|
49
|
-
/* What the merchant sent, on the case: a row of small copies to press. */
|
|
50
|
-
.thumbs {
|
|
51
|
-
display: grid;
|
|
52
|
-
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
|
|
53
|
-
gap: 12px;
|
|
54
|
-
margin: 0;
|
|
55
|
-
padding: 0;
|
|
56
|
-
list-style: none;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
.thumb {
|
|
60
|
-
display: grid;
|
|
61
|
-
gap: 4px;
|
|
62
|
-
width: 100%;
|
|
63
|
-
padding: 0;
|
|
64
|
-
border: 0;
|
|
65
|
-
background: none;
|
|
66
|
-
text-align: left;
|
|
67
|
-
cursor: pointer;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
.thumbFrame {
|
|
71
|
-
display: grid;
|
|
72
|
-
place-items: center;
|
|
73
|
-
height: 180px;
|
|
74
|
-
border: 1px solid var(--border-default);
|
|
75
|
-
border-radius: var(--adm-card-radius);
|
|
76
|
-
background: var(--adm-canvas);
|
|
77
|
-
overflow: hidden;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
.thumb:hover .thumbFrame,
|
|
81
|
-
.thumb:focus-visible .thumbFrame {
|
|
82
|
-
border-color: var(--border-strong);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
.thumbImage {
|
|
86
|
-
display: block;
|
|
87
|
-
width: 100%;
|
|
88
|
-
height: 100%;
|
|
89
|
-
object-fit: contain;
|
|
90
|
-
user-select: none;
|
|
91
|
-
-webkit-user-drag: none;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
.thumbLabel {
|
|
95
|
-
font-size: 13px;
|
|
96
|
-
line-height: 20px;
|
|
97
|
-
color: var(--text-primary);
|
|
98
|
-
}
|
|
@@ -12,7 +12,6 @@ import { DecisionBar } from "./decision-bar";
|
|
|
12
12
|
import { photoOf } from "./document-view";
|
|
13
13
|
import { DocumentViewer } from "./document-viewer";
|
|
14
14
|
import { PersonCard } from "./person-card";
|
|
15
|
-
import { SentFiles } from "./sent-files";
|
|
16
15
|
import { useAdminNames, useCase } from "./use-case";
|
|
17
16
|
import styles from "./verification.module.css";
|
|
18
17
|
function TenantVerification({ tenantId }) {
|
|
@@ -54,15 +53,6 @@ function TenantVerification({ tenantId }) {
|
|
|
54
53
|
] });
|
|
55
54
|
return /* @__PURE__ */ jsxs("div", { className: styles.stack, children: [
|
|
56
55
|
/* @__PURE__ */ jsx(CaseStatus, { data, nameOf }),
|
|
57
|
-
/* @__PURE__ */ jsx(
|
|
58
|
-
SentFiles,
|
|
59
|
-
{
|
|
60
|
-
tenantId,
|
|
61
|
-
documents: data.documents,
|
|
62
|
-
people: data.people,
|
|
63
|
-
onOpen: setViewing
|
|
64
|
-
}
|
|
65
|
-
),
|
|
66
56
|
data.people.length > 0 ? /* @__PURE__ */ jsx("div", { className: styles.people, children: data.people.map((p) => {
|
|
67
57
|
const photo = photoOf(data.documents, p.id);
|
|
68
58
|
return /* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/admin/tenants/%5Bid%5D/verification/tenant-verification.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport type { CaseDocument } from '@withpotter/lib/admin-case-types';\nimport { Button, EmptyNote, ErrorBanner } from '@withpotter/ui-kit';\nimport { AdmLoading } from '../../../_ui';\nimport { useMoneyPermissions } from '../../../_money/permissions';\nimport { caseErrorText, isNoCase } from './case-rules';\nimport { BusinessRecord, ControlChecks } from './business-records';\nimport { CaseHistory } from './case-history';\nimport { CaseStatus } from './case-status';\nimport { DecisionBar } from './decision-bar';\nimport { photoOf } from './document-view';\nimport { DocumentViewer } from './document-viewer';\nimport { PersonCard } from './person-card';\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../../../src/admin/tenants/%5Bid%5D/verification/tenant-verification.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport type { CaseDocument } from '@withpotter/lib/admin-case-types';\nimport { Button, EmptyNote, ErrorBanner } from '@withpotter/ui-kit';\nimport { AdmLoading } from '../../../_ui';\nimport { useMoneyPermissions } from '../../../_money/permissions';\nimport { caseErrorText, isNoCase } from './case-rules';\nimport { BusinessRecord, ControlChecks } from './business-records';\nimport { CaseHistory } from './case-history';\nimport { CaseStatus } from './case-status';\nimport { DecisionBar } from './decision-bar';\nimport { photoOf } from './document-view';\nimport { DocumentViewer } from './document-viewer';\nimport { PersonCard } from './person-card';\nimport { useAdminNames, useCase } from './use-case';\nimport styles from './verification.module.css';\n\n/**\n * Merchant 360 → Verification, laid out as a record: where the case stands\n * at the top, one card per person, what the business sent and the checks\n * run on it, the history, and the decision pinned to the bottom while there\n * is one to make. A document opens in a side panel beside the record.\n */\nexport function TenantVerification({ tenantId }: { tenantId: string }) {\n const query = useCase(tenantId);\n const nameOf = useAdminNames();\n const { readComplianceHint, revealComplianceHint } = useMoneyPermissions();\n const [viewing, setViewing] = useState<CaseDocument | null>(null);\n const data = query.data;\n const viewButton = (document: CaseDocument) => (\n <Button\n size=\"sm\"\n variant=\"ghost\"\n title={revealComplianceHint}\n aria-label={\n document.kind === 'ID_PHOTO' ? 'View ID photo' : 'View certificate'\n }\n onClick={() => setViewing(document)}\n >\n View\n </Button>\n );\n\n if (query.isLoading) return <AdmLoading label=\"Loading verification…\" />;\n\n if (query.isError && isNoCase(query.error))\n return (\n <EmptyNote well>This business has not started verification.</EmptyNote>\n );\n\n if (query.isError || !data)\n return (\n <div className={styles.stack}>\n <ErrorBanner>\n {caseErrorText(query.error, 'load')}{' '}\n <Button\n size=\"sm\"\n variant=\"secondary\"\n onClick={() => void query.refetch()}\n >\n Try again\n </Button>\n </ErrorBanner>\n {readComplianceHint && (\n <span className=\"adm-caption\">{readComplianceHint}</span>\n )}\n </div>\n );\n\n return (\n <div className={styles.stack}>\n <CaseStatus data={data} nameOf={nameOf} />\n {data.people.length > 0 ? (\n <div className={styles.people}>\n {data.people.map((p) => {\n const photo = photoOf(data.documents, p.id);\n\n return (\n <PersonCard\n key={p.id}\n tenantId={tenantId}\n person={p}\n photoButton={photo ? viewButton(photo) : null}\n />\n );\n })}\n </div>\n ) : (\n <EmptyNote well>No directors or owners added yet.</EmptyNote>\n )}\n {data.documents && (\n <BusinessRecord\n profile={data.profile}\n documents={data.documents}\n viewButton={viewButton}\n />\n )}\n <ControlChecks checks={data.checks} />\n <CaseHistory events={data.history} nameOf={nameOf} />\n <DecisionBar data={data} />\n <DocumentViewer\n tenantId={tenantId}\n document={viewing}\n people={data.people}\n onClose={() => setViewing(null)}\n />\n </div>\n );\n}\n"],"mappings":";AA+BI,cAuBI,YAvBJ;AA7BJ,SAAS,gBAAgB;AAEzB,SAAS,QAAQ,WAAW,mBAAmB;AAC/C,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,eAAe,gBAAgB;AACxC,SAAS,gBAAgB,qBAAqB;AAC9C,SAAS,mBAAmB;AAC5B,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,eAAe,eAAe;AACvC,OAAO,YAAY;AAQZ,SAAS,mBAAmB,EAAE,SAAS,GAAyB;AACrE,QAAM,QAAQ,QAAQ,QAAQ;AAC9B,QAAM,SAAS,cAAc;AAC7B,QAAM,EAAE,oBAAoB,qBAAqB,IAAI,oBAAoB;AACzE,QAAM,CAAC,SAAS,UAAU,IAAI,SAA8B,IAAI;AAChE,QAAM,OAAO,MAAM;AACnB,QAAM,aAAa,CAAC,aAClB;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAQ;AAAA,MACR,OAAO;AAAA,MACP,cACE,SAAS,SAAS,aAAa,kBAAkB;AAAA,MAEnD,SAAS,MAAM,WAAW,QAAQ;AAAA,MACnC;AAAA;AAAA,EAED;AAGF,MAAI,MAAM,UAAW,QAAO,oBAAC,cAAW,OAAM,8BAAwB;AAEtE,MAAI,MAAM,WAAW,SAAS,MAAM,KAAK;AACvC,WACE,oBAAC,aAAU,MAAI,MAAC,yDAA2C;AAG/D,MAAI,MAAM,WAAW,CAAC;AACpB,WACE,qBAAC,SAAI,WAAW,OAAO,OACrB;AAAA,2BAAC,eACE;AAAA,sBAAc,MAAM,OAAO,MAAM;AAAA,QAAG;AAAA,QACrC;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,SAAS,MAAM,KAAK,MAAM,QAAQ;AAAA,YACnC;AAAA;AAAA,QAED;AAAA,SACF;AAAA,MACC,sBACC,oBAAC,UAAK,WAAU,eAAe,8BAAmB;AAAA,OAEtD;AAGJ,SACE,qBAAC,SAAI,WAAW,OAAO,OACrB;AAAA,wBAAC,cAAW,MAAY,QAAgB;AAAA,IACvC,KAAK,OAAO,SAAS,IACpB,oBAAC,SAAI,WAAW,OAAO,QACpB,eAAK,OAAO,IAAI,CAAC,MAAM;AACtB,YAAM,QAAQ,QAAQ,KAAK,WAAW,EAAE,EAAE;AAE1C,aACE;AAAA,QAAC;AAAA;AAAA,UAEC;AAAA,UACA,QAAQ;AAAA,UACR,aAAa,QAAQ,WAAW,KAAK,IAAI;AAAA;AAAA,QAHpC,EAAE;AAAA,MAIT;AAAA,IAEJ,CAAC,GACH,IAEA,oBAAC,aAAU,MAAI,MAAC,+CAAiC;AAAA,IAElD,KAAK,aACJ;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,KAAK;AAAA,QACd,WAAW,KAAK;AAAA,QAChB;AAAA;AAAA,IACF;AAAA,IAEF,oBAAC,iBAAc,QAAQ,KAAK,QAAQ;AAAA,IACpC,oBAAC,eAAY,QAAQ,KAAK,SAAS,QAAgB;AAAA,IACnD,oBAAC,eAAY,MAAY;AAAA,IACzB;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,UAAU;AAAA,QACV,QAAQ,KAAK;AAAA,QACb,SAAS,MAAM,WAAW,IAAI;AAAA;AAAA,IAChC;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -95,10 +95,9 @@ function TenantListRow({
|
|
|
95
95
|
children: t.businessName
|
|
96
96
|
}
|
|
97
97
|
),
|
|
98
|
-
/* @__PURE__ */ jsx("span", { className: rows.secondary, title: t.slug, children:
|
|
98
|
+
/* @__PURE__ */ jsx("span", { className: rows.secondary, title: t.slug, children: t.slug })
|
|
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 }) }),
|
|
102
101
|
/* @__PURE__ */ jsx("td", { className: `${list.clip} ${list.muted}`, children: countryText(t.country, t.countryCode) ? /* @__PURE__ */ jsx(CountryLabel, { country: t.country, code: t.countryCode }) : EMPTY }),
|
|
103
102
|
/* @__PURE__ */ jsx("td", { className: `${list.clip} ${list.muted}`, children: t.industryKey ?? EMPTY }),
|
|
104
103
|
/* @__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, 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":[]}
|
|
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":[]}
|
|
@@ -37,7 +37,7 @@ function TenantsTable() {
|
|
|
37
37
|
{
|
|
38
38
|
title: "All merchants",
|
|
39
39
|
count: data?.total,
|
|
40
|
-
columns:
|
|
40
|
+
columns: 8,
|
|
41
41
|
minWidth: 1e3,
|
|
42
42
|
isLoading,
|
|
43
43
|
isError,
|
|
@@ -99,10 +99,9 @@ function TenantsTable() {
|
|
|
99
99
|
] }),
|
|
100
100
|
head: /* @__PURE__ */ jsxs("tr", { children: [
|
|
101
101
|
/* @__PURE__ */ jsx(Th, { children: "Business" }),
|
|
102
|
-
/* @__PURE__ */ jsx(Th, { children: "Email" }),
|
|
103
102
|
/* @__PURE__ */ jsx(Th, { children: "Country" }),
|
|
104
103
|
/* @__PURE__ */ jsx(Th, { children: "Industry" }),
|
|
105
|
-
/* @__PURE__ */ jsx(Th, { align: "right", children: "GMV" }),
|
|
104
|
+
/* @__PURE__ */ jsx(Th, { align: "right", children: "GMV (USD)" }),
|
|
106
105
|
/* @__PURE__ */ jsx(Th, { children: "Status" }),
|
|
107
106
|
/* @__PURE__ */ jsx(Th, { children: "Account officer" }),
|
|
108
107
|
/* @__PURE__ */ jsx(Th, { children: "Joined" }),
|