@withpotter/pages-admin 0.13.0-next.81 → 0.13.0-next.84
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/_overview/control-room.js +1 -19
- package/dist/admin/_overview/control-room.js.map +1 -1
- package/dist/admin/accounts/account-sessions.js +7 -3
- package/dist/admin/accounts/account-sessions.js.map +1 -1
- package/dist/admin/revenue/platform-fees.js +9 -0
- package/dist/admin/revenue/platform-fees.js.map +1 -0
- package/dist/admin/revenue/revenue-overview.js +20 -1
- package/dist/admin/revenue/revenue-overview.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 +18 -3
- package/dist/admin/tenants/[id]/page.js.map +1 -1
- package/dist/admin/tenants/[id]/tenant-overview.js +3 -2
- package/dist/admin/tenants/[id]/tenant-overview.js.map +1 -1
- package/dist/admin/tenants/[id]/tenant-wallet-card.js +3 -2
- package/dist/admin/tenants/[id]/tenant-wallet-card.js.map +1 -1
- package/dist/admin/tenants/[id]/use-tenant-wallet.js +23 -0
- package/dist/admin/tenants/[id]/use-tenant-wallet.js.map +1 -0
- package/package.json +5 -5
|
@@ -46,7 +46,8 @@ function TenantOverview({
|
|
|
46
46
|
recentOrders,
|
|
47
47
|
onTab,
|
|
48
48
|
currency = "",
|
|
49
|
-
currencyControl
|
|
49
|
+
currencyControl,
|
|
50
|
+
walletNote
|
|
50
51
|
}) {
|
|
51
52
|
const balances = byCurrency(
|
|
52
53
|
data.wallet?.balances ?? [],
|
|
@@ -77,7 +78,7 @@ function TenantOverview({
|
|
|
77
78
|
StatCard,
|
|
78
79
|
{
|
|
79
80
|
label: "Wallet available",
|
|
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",
|
|
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` : walletNote ? walletNote : "No wallet",
|
|
81
82
|
sub: balances.length ? `Pending ${balances.map((b) => formatMinor(b.pendingMinor, b.currency)).join(" \xB7 ")}` : void 0,
|
|
82
83
|
hint: "Money in the merchant's Potter wallet that can be paid out now."
|
|
83
84
|
}
|
|
@@ -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}: {\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":";AAqCQ,SAqDJ,UAnDM,KAFF;AAlCR,SAAS,aAAa;AAEtB,SAAS,mBAAmB;AAC5B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,MAAM,uBAAuB;AACtC,SAAS,qBAAqB;AAE9B,OAAO,YAAY;AAEnB,SAAS,UAAU,EAAE,KAAK,GAA2B;AACnD,QAAM,aAAa,KAAK;AAExB,MAAI,CAAC,cAAc,WAAW,WAAW,IAAK,QAAO;AAGrD,QAAM,QAAQ,CAAC,GAAG,WAAW,KAAK,EAAE;AAAA,IAClC,CAAC,GAAG,MACF,OAAO,EAAE,WAAW,WAAW,IAAI,OAAO,EAAE,WAAW,WAAW;AAAA,EACtE;AAEA,SACE,qBAAC,aAAQ,IAAI,KAAK,OAAO,WAAW,aAAa,OAAO,UAAU,IAChE;AAAA,yBAAC,SAAI,WAAW,OAAO,UACrB;AAAA,2BAAC,QAAG,WAAW,OAAO,OAAO;AAAA;AAAA,QAAS,WAAW;AAAA,QAAQ;AAAA,SAAM;AAAA,MAC9D,WAAW,aACV,oBAAC,SAAM,SAAQ,aAAY,iCAAmB;AAAA,OAElD;AAAA,IACA,oBAAC,SAAI,WAAW,OAAO,UAAU,eAAW,MAC1C,8BAAC,UAAK,OAAO,EAAE,OAAO,GAAG,WAAW,OAAO,IAAI,GAAG,GACpD;AAAA,IACA,oBAAC,QAAG,WAAW,OAAO,OACnB,gBAAM,IAAI,CAAC,MACV,qBAAC,QAAe,aAAW,EAAE,WAAW,aACrC;AAAA,QAAE;AAAA,MACH,oBAAC,UAAM,YAAE,OAAO,WAAW,KAAK,GAAG,GAAE;AAAA,SAF9B,EAAE,GAGX,CACD,GACH;AAAA,KACF;AAEJ;AAGO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AACF,GASG;AAED,QAAM,WAAW;AAAA,IACf,KAAK,QAAQ,YAAY,CAAC;AAAA,IAC1B;AAAA,IACA,CAAC,MAAM,EAAE;AAAA,EACX;AACA,QAAM,SAAS,KAAK,QAAQ;AAE5B,QAAM,QAAQ,KAAK,QAAQ;AAC3B,QAAM,WAAW,WAAW,OAAO,UAAU,CAAC,MAAM,EAAE,GAAG;AACzD,QAAM,QAAQ,cAAc,KAAK,cAAc,CAAC,GAAG,QAAQ;AAC3D,QAAM,SAAS,OAAO,KAAK,yBAAyB,KAAK,GAAG;AAE5D,SACE,iCACE;AAAA,wBAAC,mBAAgB,MAAY,OAAc;AAAA,IAC3C,qBAAC,SAAI,WAAW,OAAO,QACrB;AAAA,2BAAC,SAAI,WAAW,OAAO,MACrB;AAAA,6BAAC,SAAI,WAAW,OAAO,QACrB;AAAA,+BAAC,UAAK;AAAA;AAAA,YAAa;AAAA,aAAY;AAAA,UAC/B,qBAAC,SAAI,WAAU,eACZ;AAAA;AAAA,YACA;AAAA,aACH;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAW,OAAO,MACrB;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,OACE,SAAS,SACP,oBAAC,UAAK,WAAW,OAAO,YACrB,mBAAS,IAAI,CAAC,MACb,oBAAC,UACE,sBAAY,EAAE,gBAAgB,EAAE,QAAQ,KADhC,EAAE,QAEb,CACD,GACH,IACE,KAAK,QAAQ,SAAS,SACxB,MAAM,QAAQ,aAEd;AAAA,cAGJ,KACE,SAAS,SACL,WAAW,SACR,IAAI,CAAC,MAAM,YAAY,EAAE,cAAc,EAAE,QAAQ,CAAC,EAClD,KAAK,QAAK,CAAC,KACd;AAAA,cAEN,MAAK;AAAA;AAAA,UACP;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,OACE;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM;AAAA,kBACN;AAAA,kBACA,QAAQ,CAAC,MAAM,EAAE,OAAO;AAAA;AAAA,cAC1B;AAAA,cAEF,KAAK,YAAY,SAAS,SAAS,SAAS,KAAK,QAAK,IAAI,SAAS,QAAQ,CAAC;AAAA,cAC5E,MAAK;AAAA;AAAA,UACP;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,OAAO,OAAO,OAAO,MAAM;AAAA,cAC3B,KAAK,GAAG,OAAO,UAAU;AAAA,cACzB,MAAK;AAAA;AAAA,UACP;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,OAAO,OAAO,OAAO,SAAS;AAAA,cAC9B,KAAK,GAAG,KAAK,QAAQ,cAAc;AAAA,cACnC,MAAK;AAAA;AAAA,UACP;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,OAAM;AAAA,cACN,OACE;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAM;AAAA,kBACN;AAAA,kBACA,QAAQ,CAAC,MAAM,EAAE,OAAO;AAAA;AAAA,cAC1B;AAAA,cAEF,KAAK,iBAAiB,KAAK,QAAQ,sBAAsB,MAAM;AAAA,cAC/D,MAAK;AAAA;AAAA,UACP;AAAA,WACF;AAAA,QACA,qBAAC,aAAQ,WAAU,aACjB;AAAA,+BAAC,QAAG,WAAW,OAAO,OAAO;AAAA;AAAA,YACJ,QAAQ,SAAM,KAAK,KAAK;AAAA,aACjD;AAAA,UACC,SAAS,CAAC,KAAK,YAAY,SAC1B;AAAA,YAAC;AAAA;AAAA,cACC,OAAO,UAAU,CAAC,GAAG,IAAI,CAAC,OAAO;AAAA,gBAC/B,MAAM,EAAE;AAAA,gBACR,OAAO,EAAE;AAAA,cACX,EAAE;AAAA,cACF,YAAW;AAAA;AAAA,UACb,IAEA,oBAAC,OAAE,WAAU,wCACV,yBACH;AAAA,WAEJ;AAAA,QACA,oBAAC,aAAU,MAAY;AAAA,QACvB,qBAAC,aAAQ,WAAU,aACjB;AAAA,8BAAC,QAAG,WAAW,OAAO,OAAO,6BAAe;AAAA,UAC5C;AAAA,YAAC;AAAA;AAAA,cACC,SAAS,KAAK,YAAY,CAAC;AAAA,cAC3B,WAAW,MAAM,MAAM,OAAO;AAAA;AAAA,UAChC;AAAA,WACF;AAAA,QACA,qBAAC,aACC;AAAA,8BAAC,QAAG,WAAW,OAAO,OAAO,2BAAa;AAAA,UACzC;AAAA,WACH;AAAA,SACF;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,QAAQ,MACN,SACG,eAAe,aAAa,GAC3B,eAAe,EAAE,UAAU,UAAU,OAAO,QAAQ,CAAC;AAAA;AAAA,MAE7D;AAAA,OACF;AAAA,KACF;AAEJ;","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 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":[]}
|
|
@@ -6,7 +6,8 @@ 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 = ""
|
|
9
|
+
currency = "",
|
|
10
|
+
walletNote
|
|
10
11
|
}) {
|
|
11
12
|
const wallet = data.wallet;
|
|
12
13
|
const balances = byCurrency(
|
|
@@ -25,7 +26,7 @@ function TenantWalletCard({
|
|
|
25
26
|
}
|
|
26
27
|
)
|
|
27
28
|
] }),
|
|
28
|
-
!wallet ? /* @__PURE__ */ jsx("p", { children: "No wallet yet
|
|
29
|
+
!wallet && walletNote ? /* @__PURE__ */ jsx("p", { children: walletNote }) : !wallet ? /* @__PURE__ */ jsx("p", { children: "No wallet yet. It is created when the merchant activates payments." }) : balances.length === 0 ? /* @__PURE__ */ jsxs("p", { children: [
|
|
29
30
|
"The wallet holds no ",
|
|
30
31
|
currency,
|
|
31
32
|
" 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}: {\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
|
|
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 walletNote,\n}: {\n data: TenantDetail;\n /** The currency filter's choice; '' shows every currency. */\n currency?: string;\n /** Said in place of \"No wallet yet\" while the ledger loads or cannot be read. */\n walletNote?: 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 && walletNote ? (\n <p>{walletNote}</p>\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":";AA6BM,SAGI,KAHJ;AA3BN,SAAS,aAAa;AAEtB,SAAS,aAAa,kBAAkB;AACxC,SAAS,kBAAkB;AAC3B,OAAO,YAAY;AAGZ,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA,WAAW;AAAA,EACX;AACF,GAMG;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,UAAU,aACV,oBAAC,OAAG,sBAAW,IACb,CAAC,SACH,oBAAC,OAAE,gFAEH,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":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useLedgerWallet } from "../../_money/use-ledger";
|
|
3
|
+
import { isNoWallet } from "../../_money/ledger";
|
|
4
|
+
function useTenantWallet(tenantId, enabled, fallback) {
|
|
5
|
+
const ledger = useLedgerWallet(enabled ? tenantId : "");
|
|
6
|
+
if (ledger.data)
|
|
7
|
+
return {
|
|
8
|
+
wallet: { status: ledger.data.status, balances: ledger.data.balances }
|
|
9
|
+
};
|
|
10
|
+
if (ledger.isError)
|
|
11
|
+
return {
|
|
12
|
+
wallet: isNoWallet(ledger.error) ? null : fallback,
|
|
13
|
+
walletNote: !isNoWallet(ledger.error) && !fallback ? "The wallet did not load." : void 0
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
wallet: fallback,
|
|
17
|
+
walletNote: enabled && !fallback ? "Loading" : void 0
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
useTenantWallet
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=use-tenant-wallet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/admin/tenants/%5Bid%5D/use-tenant-wallet.ts"],"sourcesContent":["'use client';\n\nimport type { TenantDetail } from '@withpotter/lib/admin-api';\nimport { useLedgerWallet } from '../../_money/use-ledger';\nimport { isNoWallet } from '../../_money/ledger';\n\ntype TenantWallet = TenantDetail['wallet'];\n\n/**\n * The wallet the Overview and Wallet cards show. The tenant detail does not\n * carry one, so it is read from the money ledger, the same read the Money\n * pages use. `null` only when the ledger says the business has none.\n */\nexport function useTenantWallet(\n tenantId: string,\n enabled: boolean,\n fallback: TenantWallet,\n): { wallet: TenantWallet; walletNote?: string } {\n const ledger = useLedgerWallet(enabled ? tenantId : '');\n\n if (ledger.data)\n return {\n wallet: { status: ledger.data.status, balances: ledger.data.balances },\n };\n\n if (ledger.isError)\n return {\n wallet: isNoWallet(ledger.error) ? null : fallback,\n walletNote:\n !isNoWallet(ledger.error) && !fallback\n ? 'The wallet did not load.'\n : undefined,\n };\n\n // Loading says so rather than \"No wallet\"; with the ledger off, nothing to add.\n return {\n wallet: fallback,\n walletNote: enabled && !fallback ? 'Loading' : undefined,\n };\n}\n"],"mappings":";AAGA,SAAS,uBAAuB;AAChC,SAAS,kBAAkB;AASpB,SAAS,gBACd,UACA,SACA,UAC+C;AAC/C,QAAM,SAAS,gBAAgB,UAAU,WAAW,EAAE;AAEtD,MAAI,OAAO;AACT,WAAO;AAAA,MACL,QAAQ,EAAE,QAAQ,OAAO,KAAK,QAAQ,UAAU,OAAO,KAAK,SAAS;AAAA,IACvE;AAEF,MAAI,OAAO;AACT,WAAO;AAAA,MACL,QAAQ,WAAW,OAAO,KAAK,IAAI,OAAO;AAAA,MAC1C,YACE,CAAC,WAAW,OAAO,KAAK,KAAK,CAAC,WAC1B,6BACA;AAAA,IACR;AAGF,SAAO;AAAA,IACL,QAAQ;AAAA,IACR,YAAY,WAAW,CAAC,WAAW,YAAY;AAAA,EACjD;AACF;","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.84",
|
|
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.84",
|
|
35
|
+
"@withpotter/platform-admin": "^0.13.0-next.84",
|
|
36
|
+
"@withpotter/ui-kit": "^0.13.0-next.84",
|
|
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
|
}
|