@withpotter/pages-admin 0.13.0-next.124 → 0.13.0-next.58
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/_ui/workspace-tab.js +1 -11
- package/dist/admin/_ui/workspace-tab.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 +17 -40
- package/dist/admin/payout-tiers/tiers-table.js.map +1 -1
- package/dist/admin/payout-tiers/tiers-workspace.js +17 -20
- 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 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/revenue/summary-rows.ts"],"sourcesContent":["import type { MerchantPaymentsPage, PlatformRevenue } from '@withpotter/lib/admin-api';\nimport { methodCards, pctChange, plainAmount } from './ledger-model';\n\nexport const SUMMARY_HEAD = ['Section', 'Figure', 'This period', 'Period before', 'Change (%)'];\n\nconst naira = (kobo: number): string => plainAmount(Math.round(kobo * 100));\n\n/**\n * The Revenue figures as rows for a spreadsheet: what customers paid merchants (with the period before), the ways\n * of paying, and Olive's plan income. Amounts are plain numbers in one currency.\n */\nexport function summaryRows(\n ledger: MerchantPaymentsPage | undefined,\n revenue: PlatformRevenue | undefined,\n currency: string,\n): string[][] {\n const rows: string[][] = [];\n const now = ledger?.cards.current.find((c) => c.currency === currency);\n const before = ledger?.cards.previous?.find((c) => c.currency === currency);\n\n if (now) {\n const money = (label: string, a: string, b?: string) =>\n rows.push(['Merchant payments', label, plainAmount(a), b === undefined ? '' : plainAmount(b), String(pctChange(a, b) ?? '')]);\n\n money('Money received', now.grossMinor, before?.grossMinor);\n money('Fees taken', now.feeMinor, before?.feeMinor);\n money('Merchants keep', now.netMinor, before?.netMinor);\n money('Refunded', now.refundsMinor, before?.refundsMinor);\n rows.push(['Merchant payments', 'Payments that went through', String(now.payments), before ? String(before.payments) : '', String(pctChange(now.payments, before?.payments) ?? '')]);\n rows.push(['Merchant payments', 'Payments that worked (%)', String(now.successRate ?? ''), String(before?.successRate ?? ''), '']);\n }\n\n if (ledger) {\n for (const card of methodCards(ledger.byChannel.current, ledger.byChannel.previous, currency)) {\n const prior = ledger.byChannel.previous?.find((r) => r.currency === currency && r.channel.key === card.key);\n\n rows.push([\n 'How customers paid',\n card.label,\n plainAmount(card.amountMinor),\n ledger.byChannel.previous ? plainAmount(prior?.amountMinor ?? '0') : '',\n String(card.change ?? ''),\n ]);\n }\n }\n\n const plan = revenue?.recurring;\n\n if (plan && plan.tracked !== false) {\n rows.push(['Plan income', 'Income each month', naira(plan.mrr), '', '']);\n rows.push(['Plan income', 'Income over a year', naira(plan.arr), '', '']);\n rows.push(['Plan income', 'Average per paying merchant', naira(plan.arpa), '', '']);\n rows.push(['Plan income', 'Merchants paying', String(plan.payingMerchants ?? plan.activeSubscriptions), '', '']);\n rows.push(['Plan income', 'Joined in this period', String(plan.newInRange), '', '']);\n rows.push(['Plan income', 'Left in this period', String(plan.churnedInRange), '', '']);\n }\n\n return rows;\n}\n"],"mappings":"AACA,SAAS,aAAa,WAAW,mBAAmB;AAE7C,MAAM,eAAe,CAAC,WAAW,UAAU,eAAe,iBAAiB,YAAY;AAE9F,MAAM,QAAQ,CAAC,SAAyB,YAAY,KAAK,MAAM,OAAO,GAAG,CAAC;AAMnE,SAAS,YACd,QACA,SACA,UACY;AACZ,QAAM,OAAmB,CAAC;AAC1B,QAAM,MAAM,QAAQ,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,aAAa,QAAQ;AACrE,QAAM,SAAS,QAAQ,MAAM,UAAU,KAAK,CAAC,MAAM,EAAE,aAAa,QAAQ;AAE1E,MAAI,KAAK;AACP,UAAM,QAAQ,CAAC,OAAe,GAAW,MACvC,KAAK,KAAK,CAAC,qBAAqB,OAAO,YAAY,CAAC,GAAG,MAAM,SAAY,KAAK,YAAY,CAAC,GAAG,OAAO,UAAU,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC;AAE9H,UAAM,kBAAkB,IAAI,YAAY,QAAQ,UAAU;AAC1D,UAAM,cAAc,IAAI,UAAU,QAAQ,QAAQ;AAClD,UAAM,kBAAkB,IAAI,UAAU,QAAQ,QAAQ;AACtD,UAAM,YAAY,IAAI,cAAc,QAAQ,YAAY;AACxD,SAAK,KAAK,CAAC,qBAAqB,8BAA8B,OAAO,IAAI,QAAQ,GAAG,SAAS,OAAO,OAAO,QAAQ,IAAI,IAAI,OAAO,UAAU,IAAI,UAAU,QAAQ,QAAQ,KAAK,EAAE,CAAC,CAAC;AACnL,SAAK,KAAK,CAAC,qBAAqB,4BAA4B,OAAO,IAAI,eAAe,EAAE,GAAG,OAAO,QAAQ,eAAe,EAAE,GAAG,EAAE,CAAC;AAAA,EACnI;AAEA,MAAI,QAAQ;AACV,eAAW,QAAQ,YAAY,OAAO,UAAU,SAAS,OAAO,UAAU,UAAU,QAAQ,GAAG;AAC7F,YAAM,QAAQ,OAAO,UAAU,UAAU,KAAK,CAAC,MAAM,EAAE,aAAa,YAAY,EAAE,QAAQ,QAAQ,KAAK,GAAG;AAE1G,WAAK,KAAK;AAAA,QACR;AAAA,QACA,KAAK;AAAA,QACL,YAAY,KAAK,WAAW;AAAA,QAC5B,OAAO,UAAU,WAAW,YAAY,OAAO,eAAe,GAAG,IAAI;AAAA,QACrE,OAAO,KAAK,UAAU,EAAE;AAAA,MAC1B,CAAC;AAAA,IACH;AAAA,EACF;AAEA,QAAM,OAAO,SAAS;AAEtB,MAAI,QAAQ,KAAK,YAAY,OAAO;AAClC,SAAK,KAAK,CAAC,eAAe,qBAAqB,MAAM,KAAK,GAAG,GAAG,IAAI,EAAE,CAAC;AACvE,SAAK,KAAK,CAAC,eAAe,sBAAsB,MAAM,KAAK,GAAG,GAAG,IAAI,EAAE,CAAC;AACxE,SAAK,KAAK,CAAC,eAAe,+BAA+B,MAAM,KAAK,IAAI,GAAG,IAAI,EAAE,CAAC;AAClF,SAAK,KAAK,CAAC,eAAe,oBAAoB,OAAO,KAAK,mBAAmB,KAAK,mBAAmB,GAAG,IAAI,EAAE,CAAC;AAC/G,SAAK,KAAK,CAAC,eAAe,yBAAyB,OAAO,KAAK,UAAU,GAAG,IAAI,EAAE,CAAC;AACnF,SAAK,KAAK,CAAC,eAAe,uBAAuB,OAAO,KAAK,cAAc,GAAG,IAAI,EAAE,CAAC;AAAA,EACvF;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
const key = (prefix, name) => `${prefix}_${name}`;
|
|
2
|
-
function readFilters(search, prefix, defaults) {
|
|
3
|
-
const params = new URLSearchParams(search);
|
|
4
|
-
const out = {};
|
|
5
|
-
for (const name of Object.keys(defaults)) {
|
|
6
|
-
out[name] = params.get(key(prefix, name)) ?? defaults[name];
|
|
7
|
-
}
|
|
8
|
-
return out;
|
|
9
|
-
}
|
|
10
|
-
function readPage(search, prefix) {
|
|
11
|
-
const page = Number.parseInt(new URLSearchParams(search).get(key(prefix, "page")) ?? "", 10);
|
|
12
|
-
return Number.isFinite(page) && page > 0 ? page : 1;
|
|
13
|
-
}
|
|
14
|
-
function applyFilters(search, prefix, patch, defaults) {
|
|
15
|
-
const params = new URLSearchParams(search);
|
|
16
|
-
const changesPage = "page" in patch;
|
|
17
|
-
for (const [name, value] of Object.entries(patch)) {
|
|
18
|
-
const text = String(value);
|
|
19
|
-
const unchanged = name === "page" ? text === "1" : text === (defaults[name] ?? "");
|
|
20
|
-
if (unchanged) {
|
|
21
|
-
params.delete(key(prefix, name));
|
|
22
|
-
} else {
|
|
23
|
-
params.set(key(prefix, name), text);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
if (!changesPage) {
|
|
27
|
-
params.delete(key(prefix, "page"));
|
|
28
|
-
}
|
|
29
|
-
return params.toString();
|
|
30
|
-
}
|
|
31
|
-
export {
|
|
32
|
-
applyFilters,
|
|
33
|
-
readFilters,
|
|
34
|
-
readPage
|
|
35
|
-
};
|
|
36
|
-
//# sourceMappingURL=url-filters.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/revenue/url-filters.ts"],"sourcesContent":["/**\n * Filters that live in the page address, so a view can be bookmarked or sent to someone. Each view has its own\n * prefix (`mp_`, `sp_`, `mr_`), so a filter of one view never leaks into another when the tab changes.\n */\n\n/** One filter's name in the address. */\nconst key = (prefix: string, name: string): string => `${prefix}_${name}`;\n\n/** The values of a view's filters, read from the address; a missing one is its default. */\nexport function readFilters<T extends Record<string, string>>(\n search: string,\n prefix: string,\n defaults: T,\n): T {\n const params = new URLSearchParams(search);\n const out: Record<string, string> = {};\n\n for (const name of Object.keys(defaults)) {\n out[name] = params.get(key(prefix, name)) ?? defaults[name];\n }\n\n return out as T;\n}\n\n/** The page number, at least 1. */\nexport function readPage(search: string, prefix: string): number {\n const page = Number.parseInt(new URLSearchParams(search).get(key(prefix, 'page')) ?? '', 10);\n\n return Number.isFinite(page) && page > 0 ? page : 1;\n}\n\n/**\n * The address after a change. A filter set back to its default is removed, so the address stays short. Changing\n * any filter but the page sends the view back to its first page.\n */\nexport function applyFilters(\n search: string,\n prefix: string,\n patch: Record<string, string | number>,\n defaults: Record<string, string>,\n): string {\n const params = new URLSearchParams(search);\n const changesPage = 'page' in patch;\n\n for (const [name, value] of Object.entries(patch)) {\n const text = String(value);\n const unchanged = name === 'page' ? text === '1' : text === (defaults[name] ?? '');\n\n if (unchanged) {\n params.delete(key(prefix, name));\n } else {\n params.set(key(prefix, name), text);\n }\n }\n\n if (!changesPage) {\n params.delete(key(prefix, 'page'));\n }\n\n return params.toString();\n}\n"],"mappings":"AAMA,MAAM,MAAM,CAAC,QAAgB,SAAyB,GAAG,MAAM,IAAI,IAAI;AAGhE,SAAS,YACd,QACA,QACA,UACG;AACH,QAAM,SAAS,IAAI,gBAAgB,MAAM;AACzC,QAAM,MAA8B,CAAC;AAErC,aAAW,QAAQ,OAAO,KAAK,QAAQ,GAAG;AACxC,QAAI,IAAI,IAAI,OAAO,IAAI,IAAI,QAAQ,IAAI,CAAC,KAAK,SAAS,IAAI;AAAA,EAC5D;AAEA,SAAO;AACT;AAGO,SAAS,SAAS,QAAgB,QAAwB;AAC/D,QAAM,OAAO,OAAO,SAAS,IAAI,gBAAgB,MAAM,EAAE,IAAI,IAAI,QAAQ,MAAM,CAAC,KAAK,IAAI,EAAE;AAE3F,SAAO,OAAO,SAAS,IAAI,KAAK,OAAO,IAAI,OAAO;AACpD;AAMO,SAAS,aACd,QACA,QACA,OACA,UACQ;AACR,QAAM,SAAS,IAAI,gBAAgB,MAAM;AACzC,QAAM,cAAc,UAAU;AAE9B,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,UAAM,OAAO,OAAO,KAAK;AACzB,UAAM,YAAY,SAAS,SAAS,SAAS,MAAM,UAAU,SAAS,IAAI,KAAK;AAE/E,QAAI,WAAW;AACb,aAAO,OAAO,IAAI,QAAQ,IAAI,CAAC;AAAA,IACjC,OAAO;AACL,aAAO,IAAI,IAAI,QAAQ,IAAI,GAAG,IAAI;AAAA,IACpC;AAAA,EACF;AAEA,MAAI,CAAC,aAAa;AAChB,WAAO,OAAO,IAAI,QAAQ,MAAM,CAAC;AAAA,EACnC;AAEA,SAAO,OAAO,SAAS;AACzB;","names":[]}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { useCallback, useMemo } from "react";
|
|
3
|
-
import { usePathname, useRouter, useSearchParams } from "next/navigation";
|
|
4
|
-
import { applyFilters, readFilters, readPage } from "./url-filters";
|
|
5
|
-
function useUrlFilters(prefix, defaults) {
|
|
6
|
-
const router = useRouter();
|
|
7
|
-
const pathname = usePathname();
|
|
8
|
-
const search = useSearchParams().toString();
|
|
9
|
-
const values = useMemo(() => readFilters(search, prefix, defaults), [search, prefix, defaults]);
|
|
10
|
-
const page = readPage(search, prefix);
|
|
11
|
-
const set = useCallback(
|
|
12
|
-
(patch) => {
|
|
13
|
-
const now = window.location.search.replace(/^\?/, "");
|
|
14
|
-
const next = applyFilters(now, prefix, patch, defaults);
|
|
15
|
-
router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false });
|
|
16
|
-
},
|
|
17
|
-
[router, pathname, prefix, defaults]
|
|
18
|
-
);
|
|
19
|
-
return { values, page, set };
|
|
20
|
-
}
|
|
21
|
-
export {
|
|
22
|
-
useUrlFilters
|
|
23
|
-
};
|
|
24
|
-
//# sourceMappingURL=use-url-filters.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/revenue/use-url-filters.ts"],"sourcesContent":["'use client';\n\nimport { useCallback, useMemo } from 'react';\nimport { usePathname, useRouter, useSearchParams } from 'next/navigation';\nimport { applyFilters, readFilters, readPage } from './url-filters';\n\n/**\n * A view's filters and page, kept in the page address. `set` changes some of them and sends the view back to its\n * first page; `set({ page })` only moves the page. The address is replaced, not added to, so Back leaves the view.\n */\nexport function useUrlFilters<T extends Record<string, string>>(prefix: string, defaults: T) {\n const router = useRouter();\n const pathname = usePathname();\n const search = useSearchParams().toString();\n const values = useMemo(() => readFilters(search, prefix, defaults), [search, prefix, defaults]);\n const page = readPage(search, prefix);\n\n const set = useCallback(\n (patch: Partial<Record<keyof T | 'page', string | number>>) => {\n // Read the address as it is now, so two changes in a row do not undo each other.\n const now = window.location.search.replace(/^\\?/, '');\n const next = applyFilters(now, prefix, patch as Record<string, string | number>, defaults);\n\n router.replace(next ? `${pathname}?${next}` : pathname, { scroll: false });\n },\n [router, pathname, prefix, defaults],\n );\n\n return { values, page, set };\n}\n"],"mappings":";AAEA,SAAS,aAAa,eAAe;AACrC,SAAS,aAAa,WAAW,uBAAuB;AACxD,SAAS,cAAc,aAAa,gBAAgB;AAM7C,SAAS,cAAgD,QAAgB,UAAa;AAC3F,QAAM,SAAS,UAAU;AACzB,QAAM,WAAW,YAAY;AAC7B,QAAM,SAAS,gBAAgB,EAAE,SAAS;AAC1C,QAAM,SAAS,QAAQ,MAAM,YAAY,QAAQ,QAAQ,QAAQ,GAAG,CAAC,QAAQ,QAAQ,QAAQ,CAAC;AAC9F,QAAM,OAAO,SAAS,QAAQ,MAAM;AAEpC,QAAM,MAAM;AAAA,IACV,CAAC,UAA8D;AAE7D,YAAM,MAAM,OAAO,SAAS,OAAO,QAAQ,OAAO,EAAE;AACpD,YAAM,OAAO,aAAa,KAAK,QAAQ,OAA0C,QAAQ;AAEzF,aAAO,QAAQ,OAAO,GAAG,QAAQ,IAAI,IAAI,KAAK,UAAU,EAAE,QAAQ,MAAM,CAAC;AAAA,IAC3E;AAAA,IACA,CAAC,QAAQ,UAAU,QAAQ,QAAQ;AAAA,EACrC;AAEA,SAAO,EAAE,QAAQ,MAAM,IAAI;AAC7B;","names":[]}
|
|
@@ -1,23 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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":[]}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import { useQuery } from "@tanstack/react-query";
|
|
5
|
-
import { adminCaseApi } from "@withpotter/lib/admin-case-api";
|
|
6
|
-
import { AdmLoading } from "../../../_ui";
|
|
7
|
-
import { documentWord } from "./case-checks";
|
|
8
|
-
import { caseErrorText } from "./case-rules";
|
|
9
|
-
import { documentLinkKey, pdfSource, viewerKind } from "./document-view";
|
|
10
|
-
import styles from "./document-viewer.module.css";
|
|
11
|
-
function DocumentFile({
|
|
12
|
-
tenantId,
|
|
13
|
-
document,
|
|
14
|
-
size = "full"
|
|
15
|
-
}) {
|
|
16
|
-
const link = useQuery({
|
|
17
|
-
queryKey: [...documentLinkKey(tenantId, document.id), size],
|
|
18
|
-
queryFn: () => adminCaseApi.viewDocument(tenantId, document.id),
|
|
19
|
-
retry: false,
|
|
20
|
-
staleTime: Infinity,
|
|
21
|
-
gcTime: 0,
|
|
22
|
-
refetchOnWindowFocus: false,
|
|
23
|
-
refetchOnReconnect: false
|
|
24
|
-
});
|
|
25
|
-
const name = documentWord(document);
|
|
26
|
-
const thumb = size === "thumb";
|
|
27
|
-
if (link.isLoading)
|
|
28
|
-
return thumb ? /* @__PURE__ */ jsx("div", { className: styles.thumbFrame, children: /* @__PURE__ */ jsx("span", { className: styles.note, children: "Loading\u2026" }) }) : /* @__PURE__ */ jsx(AdmLoading, { label: "Opening document\u2026" });
|
|
29
|
-
if (link.isError || !link.data)
|
|
30
|
-
return /* @__PURE__ */ jsx("p", { className: styles.note, role: "alert", children: caseErrorText(link.error, "document") });
|
|
31
|
-
const kind = viewerKind(link.data.mimeType);
|
|
32
|
-
if (kind === "image")
|
|
33
|
-
return /* @__PURE__ */ jsx(Photo, { url: link.data.url, name, thumb });
|
|
34
|
-
if (kind === "pdf" && thumb)
|
|
35
|
-
return /* @__PURE__ */ jsx("div", { className: styles.thumbFrame, children: /* @__PURE__ */ jsx("span", { className: styles.note, children: "PDF. Open it to read." }) });
|
|
36
|
-
if (kind === "pdf")
|
|
37
|
-
return /* @__PURE__ */ jsx("div", { className: styles.frame, children: /* @__PURE__ */ jsx(
|
|
38
|
-
"iframe",
|
|
39
|
-
{
|
|
40
|
-
className: styles.pdf,
|
|
41
|
-
src: pdfSource(link.data.url),
|
|
42
|
-
title: name,
|
|
43
|
-
referrerPolicy: "no-referrer"
|
|
44
|
-
}
|
|
45
|
-
) });
|
|
46
|
-
return /* @__PURE__ */ jsx("p", { className: styles.note, children: "This file type can't be shown here." });
|
|
47
|
-
}
|
|
48
|
-
function Photo({
|
|
49
|
-
url,
|
|
50
|
-
name,
|
|
51
|
-
thumb
|
|
52
|
-
}) {
|
|
53
|
-
const [state, setState] = useState(
|
|
54
|
-
"loading"
|
|
55
|
-
);
|
|
56
|
-
return /* @__PURE__ */ jsxs("div", { className: thumb ? styles.thumbFrame : styles.frame, children: [
|
|
57
|
-
state === "loading" && /* @__PURE__ */ jsx("span", { className: styles.note, children: "Loading photo\u2026" }),
|
|
58
|
-
state === "failed" && /* @__PURE__ */ jsx("span", { className: styles.note, role: "alert", children: "The photo did not load. Close it and open it again." }),
|
|
59
|
-
/* @__PURE__ */ jsx(
|
|
60
|
-
"img",
|
|
61
|
-
{
|
|
62
|
-
className: thumb ? styles.thumbImage : styles.image,
|
|
63
|
-
src: url,
|
|
64
|
-
alt: name,
|
|
65
|
-
style: state === "shown" ? void 0 : { display: "none" },
|
|
66
|
-
referrerPolicy: "no-referrer",
|
|
67
|
-
draggable: false,
|
|
68
|
-
onLoad: () => setState("shown"),
|
|
69
|
-
onError: () => setState("failed"),
|
|
70
|
-
onContextMenu: (e) => e.preventDefault()
|
|
71
|
-
}
|
|
72
|
-
)
|
|
73
|
-
] });
|
|
74
|
-
}
|
|
75
|
-
export {
|
|
76
|
-
DocumentFile
|
|
77
|
-
};
|
|
78
|
-
//# sourceMappingURL=document-file.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/admin/tenants/%5Bid%5D/verification/document-file.tsx"],"sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { useQuery } from '@tanstack/react-query';\nimport { adminCaseApi } from '@withpotter/lib/admin-case-api';\nimport type { CaseDocument } from '@withpotter/lib/admin-case-types';\nimport { AdmLoading } from '../../../_ui';\nimport { documentWord } from './case-checks';\nimport { caseErrorText } from './case-rules';\nimport { documentLinkKey, pdfSource, viewerKind } from './document-view';\nimport styles from './document-viewer.module.css';\n\n/**\n * One file a business sent, drawn from a fresh short-lived link: full size in\n * the document panel, or small on the case itself so the admin sees it before\n * deciding. The two sizes ask for their own link, so the panel never opens on\n * one that has run out while the small copy sat on the page.\n */\nexport function DocumentFile({\n tenantId,\n document,\n size = 'full',\n}: {\n tenantId: string;\n document: CaseDocument;\n size?: 'full' | 'thumb';\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), size],\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 const thumb = size === 'thumb';\n\n if (link.isLoading)\n return thumb ? (\n <div className={styles.thumbFrame}>\n <span className={styles.note}>Loading…</span>\n </div>\n ) : (\n <AdmLoading label=\"Opening document…\" />\n );\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 <Photo url={link.data.url} name={name} thumb={thumb} />;\n\n if (kind === 'pdf' && thumb)\n return (\n <div className={styles.thumbFrame}>\n <span className={styles.note}>PDF. Open it to read.</span>\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\n/** The photo, with a word while it downloads and if it never arrives. */\nfunction Photo({\n url,\n name,\n thumb,\n}: {\n url: string;\n name: string;\n thumb: boolean;\n}) {\n const [state, setState] = useState<'loading' | 'shown' | 'failed'>(\n 'loading',\n );\n\n return (\n <div className={thumb ? styles.thumbFrame : styles.frame}>\n {state === 'loading' && (\n <span className={styles.note}>Loading photo…</span>\n )}\n {state === 'failed' && (\n <span className={styles.note} role=\"alert\">\n The photo did not load. Close it and open it again.\n </span>\n )}\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n className={thumb ? styles.thumbImage : styles.image}\n src={url}\n alt={name}\n // The class sets display, which would beat `hidden`.\n style={state === 'shown' ? undefined : { display: 'none' }}\n referrerPolicy=\"no-referrer\"\n draggable={false}\n onLoad={() => setState('shown')}\n onError={() => setState('failed')}\n onContextMenu={(e) => e.preventDefault()}\n />\n </div>\n );\n}\n"],"mappings":";AA2CQ,cAuDJ,YAvDI;AAzCR,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,oBAAoB;AAE7B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB,WAAW,kBAAkB;AACvD,OAAO,YAAY;AAQZ,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA,OAAO;AACT,GAIG;AAED,QAAM,OAAO,SAAS;AAAA,IACpB,UAAU,CAAC,GAAG,gBAAgB,UAAU,SAAS,EAAE,GAAG,IAAI;AAAA,IAC1D,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;AAClC,QAAM,QAAQ,SAAS;AAEvB,MAAI,KAAK;AACP,WAAO,QACL,oBAAC,SAAI,WAAW,OAAO,YACrB,8BAAC,UAAK,WAAW,OAAO,MAAM,2BAAQ,GACxC,IAEA,oBAAC,cAAW,OAAM,0BAAoB;AAG1C,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,WAAO,oBAAC,SAAM,KAAK,KAAK,KAAK,KAAK,MAAY,OAAc;AAE9D,MAAI,SAAS,SAAS;AACpB,WACE,oBAAC,SAAI,WAAW,OAAO,YACrB,8BAAC,UAAK,WAAW,OAAO,MAAM,mCAAqB,GACrD;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;AAGA,SAAS,MAAM;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,CAAC,OAAO,QAAQ,IAAI;AAAA,IACxB;AAAA,EACF;AAEA,SACE,qBAAC,SAAI,WAAW,QAAQ,OAAO,aAAa,OAAO,OAChD;AAAA,cAAU,aACT,oBAAC,UAAK,WAAW,OAAO,MAAM,iCAAc;AAAA,IAE7C,UAAU,YACT,oBAAC,UAAK,WAAW,OAAO,MAAM,MAAK,SAAQ,iEAE3C;AAAA,IAGF;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,QAAQ,OAAO,aAAa,OAAO;AAAA,QAC9C,KAAK;AAAA,QACL,KAAK;AAAA,QAEL,OAAO,UAAU,UAAU,SAAY,EAAE,SAAS,OAAO;AAAA,QACzD,gBAAe;AAAA,QACf,WAAW;AAAA,QACX,QAAQ,MAAM,SAAS,OAAO;AAAA,QAC9B,SAAS,MAAM,SAAS,QAAQ;AAAA,QAChC,eAAe,CAAC,MAAM,EAAE,eAAe;AAAA;AAAA,IACzC;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { Panel } from "../../../_ui";
|
|
4
|
-
import { documentWord } from "./case-checks";
|
|
5
|
-
import { DocumentFile } from "./document-file";
|
|
6
|
-
import { ownerName } from "./document-view";
|
|
7
|
-
import styles from "./document-viewer.module.css";
|
|
8
|
-
function SentFiles({
|
|
9
|
-
tenantId,
|
|
10
|
-
documents,
|
|
11
|
-
people,
|
|
12
|
-
onOpen
|
|
13
|
-
}) {
|
|
14
|
-
const files = documents ?? [];
|
|
15
|
-
return /* @__PURE__ */ jsx(Panel, { title: "What the merchant sent", count: files.length, children: files.length === 0 ? /* @__PURE__ */ jsx("p", { className: styles.note, children: "No photos or documents sent." }) : /* @__PURE__ */ jsx("ul", { className: styles.thumbs, children: files.map((d) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(
|
|
16
|
-
"button",
|
|
17
|
-
{
|
|
18
|
-
type: "button",
|
|
19
|
-
className: styles.thumb,
|
|
20
|
-
onClick: () => onOpen(d),
|
|
21
|
-
"aria-label": `Open ${documentWord(d)} full size`,
|
|
22
|
-
children: [
|
|
23
|
-
/* @__PURE__ */ jsx(DocumentFile, { tenantId, document: d, size: "thumb" }),
|
|
24
|
-
/* @__PURE__ */ jsx("span", { className: styles.thumbLabel, children: documentWord(d) }),
|
|
25
|
-
/* @__PURE__ */ jsx("span", { className: styles.note, children: ownerName(d, people) })
|
|
26
|
-
]
|
|
27
|
-
}
|
|
28
|
-
) }, d.id)) }) });
|
|
29
|
-
}
|
|
30
|
-
export {
|
|
31
|
-
SentFiles
|
|
32
|
-
};
|
|
33
|
-
//# sourceMappingURL=sent-files.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../src/admin/tenants/%5Bid%5D/verification/sent-files.tsx"],"sourcesContent":["'use client';\n\nimport type {\n CaseDocument,\n CasePerson,\n} from '@withpotter/lib/admin-case-types';\nimport { Panel } from '../../../_ui';\nimport { documentWord } from './case-checks';\nimport { DocumentFile } from './document-file';\nimport { ownerName } from './document-view';\nimport styles from './document-viewer.module.css';\n\n/**\n * Every photo and document the business sent, shown on the case itself, so\n * the admin looks at them before Approve or Deny. A press opens one full size\n * in the document panel.\n */\nexport function SentFiles({\n tenantId,\n documents,\n people,\n onOpen,\n}: {\n tenantId: string;\n documents: CaseDocument[] | undefined;\n people: CasePerson[];\n onOpen: (document: CaseDocument) => void;\n}) {\n const files = documents ?? [];\n\n return (\n <Panel title=\"What the merchant sent\" count={files.length}>\n {files.length === 0 ? (\n <p className={styles.note}>No photos or documents sent.</p>\n ) : (\n <ul className={styles.thumbs}>\n {files.map((d) => (\n <li key={d.id}>\n <button\n type=\"button\"\n className={styles.thumb}\n onClick={() => onOpen(d)}\n aria-label={`Open ${documentWord(d)} full size`}\n >\n <DocumentFile tenantId={tenantId} document={d} size=\"thumb\" />\n <span className={styles.thumbLabel}>{documentWord(d)}</span>\n <span className={styles.note}>{ownerName(d, people)}</span>\n </button>\n </li>\n ))}\n </ul>\n )}\n </Panel>\n );\n}\n"],"mappings":";AAiCQ,cAKM,YALN;AA3BR,SAAS,aAAa;AACtB,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,OAAO,YAAY;AAOZ,SAAS,UAAU;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,QAAQ,aAAa,CAAC;AAE5B,SACE,oBAAC,SAAM,OAAM,0BAAyB,OAAO,MAAM,QAChD,gBAAM,WAAW,IAChB,oBAAC,OAAE,WAAW,OAAO,MAAM,0CAA4B,IAEvD,oBAAC,QAAG,WAAW,OAAO,QACnB,gBAAM,IAAI,CAAC,MACV,oBAAC,QACC;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAW,OAAO;AAAA,MAClB,SAAS,MAAM,OAAO,CAAC;AAAA,MACvB,cAAY,QAAQ,aAAa,CAAC,CAAC;AAAA,MAEnC;AAAA,4BAAC,gBAAa,UAAoB,UAAU,GAAG,MAAK,SAAQ;AAAA,QAC5D,oBAAC,UAAK,WAAW,OAAO,YAAa,uBAAa,CAAC,GAAE;AAAA,QACrD,oBAAC,UAAK,WAAW,OAAO,MAAO,oBAAU,GAAG,MAAM,GAAE;AAAA;AAAA;AAAA,EACtD,KAVO,EAAE,EAWX,CACD,GACH,GAEJ;AAEJ;","names":[]}
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useRef, useState } from "react";
|
|
4
|
-
import {
|
|
5
|
-
Button,
|
|
6
|
-
ErrorBanner,
|
|
7
|
-
FormDialog,
|
|
8
|
-
useConfirm,
|
|
9
|
-
useToast
|
|
10
|
-
} from "@withpotter/ui-kit";
|
|
11
|
-
import { AdmLoading } from "../_ui";
|
|
12
|
-
import { useMoneyPermissions } from "../_money/permissions";
|
|
13
|
-
import { documentWord } from "../tenants/[id]/verification/case-checks";
|
|
14
|
-
import {
|
|
15
|
-
barMode,
|
|
16
|
-
caseErrorText
|
|
17
|
-
} from "../tenants/[id]/verification/case-rules";
|
|
18
|
-
import { DenyDialog } from "../tenants/[id]/verification/decision-dialogs";
|
|
19
|
-
import { DocumentFile } from "../tenants/[id]/verification/document-file";
|
|
20
|
-
import { ownerName } from "../tenants/[id]/verification/document-view";
|
|
21
|
-
import { useCase, useDecideCase } from "../tenants/[id]/verification/use-case";
|
|
22
|
-
import styles from "../tenants/[id]/verification/verification.module.css";
|
|
23
|
-
import viewer from "../tenants/[id]/verification/document-viewer.module.css";
|
|
24
|
-
function PreviewDialog({
|
|
25
|
-
tenantId,
|
|
26
|
-
business,
|
|
27
|
-
onClose
|
|
28
|
-
}) {
|
|
29
|
-
const { toast } = useToast();
|
|
30
|
-
const confirm = useConfirm();
|
|
31
|
-
const { manageComplianceHint } = useMoneyPermissions();
|
|
32
|
-
const query = useCase(tenantId);
|
|
33
|
-
const decide = useDecideCase(tenantId);
|
|
34
|
-
const [denying, setDenying] = useState(false);
|
|
35
|
-
const data = query.data;
|
|
36
|
-
const mode = data ? barMode(data.status) : null;
|
|
37
|
-
const wasDeciding = useRef(false);
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
if (mode === "decide") wasDeciding.current = true;
|
|
40
|
-
else if (wasDeciding.current) onClose();
|
|
41
|
-
}, [mode, onClose]);
|
|
42
|
-
async function approve() {
|
|
43
|
-
const ok = await confirm({
|
|
44
|
-
title: `Approve ${business}?`,
|
|
45
|
-
description: "Everyone listed is marked verified.",
|
|
46
|
-
confirmLabel: "Approve"
|
|
47
|
-
});
|
|
48
|
-
if (!ok) return;
|
|
49
|
-
decide.mutate(
|
|
50
|
-
{ decision: "APPROVE" },
|
|
51
|
-
{
|
|
52
|
-
onSuccess: () => toast({ title: `${business} approved` }),
|
|
53
|
-
onError: (e) => toast({ title: caseErrorText(e, "decide"), variant: "destructive" })
|
|
54
|
-
}
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
const files = data?.documents ?? [];
|
|
58
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
59
|
-
/* @__PURE__ */ jsxs(
|
|
60
|
-
FormDialog,
|
|
61
|
-
{
|
|
62
|
-
open: !denying,
|
|
63
|
-
onClose,
|
|
64
|
-
title: business,
|
|
65
|
-
description: "What the merchant sent",
|
|
66
|
-
size: "lg",
|
|
67
|
-
footer: /* @__PURE__ */ jsxs("div", { className: styles.footer, children: [
|
|
68
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, children: "Close" }),
|
|
69
|
-
mode === "decide" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
70
|
-
/* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: () => setDenying(true), children: "Deny" }),
|
|
71
|
-
/* @__PURE__ */ jsx(
|
|
72
|
-
Button,
|
|
73
|
-
{
|
|
74
|
-
loading: decide.isPending,
|
|
75
|
-
onClick: () => void approve(),
|
|
76
|
-
children: "Approve"
|
|
77
|
-
}
|
|
78
|
-
)
|
|
79
|
-
] })
|
|
80
|
-
] }),
|
|
81
|
-
children: [
|
|
82
|
-
query.isLoading && /* @__PURE__ */ jsx(AdmLoading, { label: "Loading what was sent\u2026" }),
|
|
83
|
-
(query.isError || !query.isLoading && !data) && /* @__PURE__ */ jsx(ErrorBanner, { children: caseErrorText(query.error, "load") }),
|
|
84
|
-
data && files.length === 0 && /* @__PURE__ */ jsx("p", { className: viewer.note, children: "No photos or documents sent." }),
|
|
85
|
-
data && files.map((d) => /* @__PURE__ */ jsxs("div", { className: styles.stack, children: [
|
|
86
|
-
/* @__PURE__ */ jsxs("span", { className: viewer.note, children: [
|
|
87
|
-
documentWord(d),
|
|
88
|
-
" \xB7 ",
|
|
89
|
-
ownerName(d, data.people)
|
|
90
|
-
] }),
|
|
91
|
-
/* @__PURE__ */ jsx(DocumentFile, { tenantId, document: d })
|
|
92
|
-
] }, d.id)),
|
|
93
|
-
manageComplianceHint && /* @__PURE__ */ jsx("span", { className: "adm-caption", children: manageComplianceHint })
|
|
94
|
-
]
|
|
95
|
-
}
|
|
96
|
-
),
|
|
97
|
-
/* @__PURE__ */ jsx(
|
|
98
|
-
DenyDialog,
|
|
99
|
-
{
|
|
100
|
-
tenantId,
|
|
101
|
-
business,
|
|
102
|
-
open: denying,
|
|
103
|
-
onClose: () => setDenying(false)
|
|
104
|
-
}
|
|
105
|
-
)
|
|
106
|
-
] });
|
|
107
|
-
}
|
|
108
|
-
export {
|
|
109
|
-
PreviewDialog
|
|
110
|
-
};
|
|
111
|
-
//# sourceMappingURL=preview-dialog.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/admin/verification/preview-dialog.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport {\n Button,\n ErrorBanner,\n FormDialog,\n useConfirm,\n useToast,\n} from \"@withpotter/ui-kit\";\nimport { AdmLoading } from \"../_ui\";\nimport { useMoneyPermissions } from \"../_money/permissions\";\nimport { documentWord } from \"../tenants/[id]/verification/case-checks\";\nimport {\n barMode,\n caseErrorText,\n} from \"../tenants/[id]/verification/case-rules\";\nimport { DenyDialog } from \"../tenants/[id]/verification/decision-dialogs\";\nimport { DocumentFile } from \"../tenants/[id]/verification/document-file\";\nimport { ownerName } from \"../tenants/[id]/verification/document-view\";\nimport { useCase, useDecideCase } from \"../tenants/[id]/verification/use-case\";\nimport styles from \"../tenants/[id]/verification/verification.module.css\";\nimport viewer from \"../tenants/[id]/verification/document-viewer.module.css\";\n\n/**\n * A popup over the Verification list: every photo and document the business\n * sent, full size, with Approve and Deny at the foot, so the admin decides\n * without leaving the list. It closes once the case is no longer waiting.\n */\nexport function PreviewDialog({\n tenantId,\n business,\n onClose,\n}: {\n tenantId: string;\n business: string;\n onClose: () => void;\n}) {\n const { toast } = useToast();\n const confirm = useConfirm();\n const { manageComplianceHint } = useMoneyPermissions();\n const query = useCase(tenantId);\n const decide = useDecideCase(tenantId);\n const [denying, setDenying] = useState(false);\n const data = query.data;\n const mode = data ? barMode(data.status) : null;\n const wasDeciding = useRef(false);\n\n useEffect(() => {\n if (mode === \"decide\") wasDeciding.current = true;\n else if (wasDeciding.current) onClose();\n }, [mode, onClose]);\n\n async function approve() {\n const ok = await confirm({\n title: `Approve ${business}?`,\n description: \"Everyone listed is marked verified.\",\n confirmLabel: \"Approve\",\n });\n\n if (!ok) return;\n\n decide.mutate(\n { decision: \"APPROVE\" },\n {\n onSuccess: () => toast({ title: `${business} approved` }),\n onError: (e) =>\n toast({ title: caseErrorText(e, \"decide\"), variant: \"destructive\" }),\n }\n );\n }\n\n const files = data?.documents ?? [];\n\n return (\n <>\n <FormDialog\n open={!denying}\n onClose={onClose}\n title={business}\n description=\"What the merchant sent\"\n size=\"lg\"\n footer={\n <div className={styles.footer}>\n <Button variant=\"secondary\" onClick={onClose}>\n Close\n </Button>\n {mode === \"decide\" && (\n <>\n <Button variant=\"secondary\" onClick={() => setDenying(true)}>\n Deny\n </Button>\n <Button\n loading={decide.isPending}\n onClick={() => void approve()}\n >\n Approve\n </Button>\n </>\n )}\n </div>\n }\n >\n {query.isLoading && <AdmLoading label=\"Loading what was sent…\" />}\n {(query.isError || (!query.isLoading && !data)) && (\n <ErrorBanner>{caseErrorText(query.error, \"load\")}</ErrorBanner>\n )}\n {data && files.length === 0 && (\n <p className={viewer.note}>No photos or documents sent.</p>\n )}\n {data &&\n files.map((d) => (\n <div key={d.id} className={styles.stack}>\n <span className={viewer.note}>\n {documentWord(d)} · {ownerName(d, data.people)}\n </span>\n <DocumentFile tenantId={tenantId} document={d} />\n </div>\n ))}\n {manageComplianceHint && (\n <span className=\"adm-caption\">{manageComplianceHint}</span>\n )}\n </FormDialog>\n <DenyDialog\n tenantId={tenantId}\n business={business}\n open={denying}\n onClose={() => setDenying(false)}\n />\n </>\n );\n}\n"],"mappings":";AAoFY,SAIE,UAJF,KAIE,YAJF;AAlFZ,SAAS,WAAW,QAAQ,gBAAgB;AAC5C;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,oBAAoB;AAC7B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,SAAS,qBAAqB;AACvC,OAAO,YAAY;AACnB,OAAO,YAAY;AAOZ,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,QAAM,EAAE,MAAM,IAAI,SAAS;AAC3B,QAAM,UAAU,WAAW;AAC3B,QAAM,EAAE,qBAAqB,IAAI,oBAAoB;AACrD,QAAM,QAAQ,QAAQ,QAAQ;AAC9B,QAAM,SAAS,cAAc,QAAQ;AACrC,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,KAAK;AAC5C,QAAM,OAAO,MAAM;AACnB,QAAM,OAAO,OAAO,QAAQ,KAAK,MAAM,IAAI;AAC3C,QAAM,cAAc,OAAO,KAAK;AAEhC,YAAU,MAAM;AACd,QAAI,SAAS,SAAU,aAAY,UAAU;AAAA,aACpC,YAAY,QAAS,SAAQ;AAAA,EACxC,GAAG,CAAC,MAAM,OAAO,CAAC;AAElB,iBAAe,UAAU;AACvB,UAAM,KAAK,MAAM,QAAQ;AAAA,MACvB,OAAO,WAAW,QAAQ;AAAA,MAC1B,aAAa;AAAA,MACb,cAAc;AAAA,IAChB,CAAC;AAED,QAAI,CAAC,GAAI;AAET,WAAO;AAAA,MACL,EAAE,UAAU,UAAU;AAAA,MACtB;AAAA,QACE,WAAW,MAAM,MAAM,EAAE,OAAO,GAAG,QAAQ,YAAY,CAAC;AAAA,QACxD,SAAS,CAAC,MACR,MAAM,EAAE,OAAO,cAAc,GAAG,QAAQ,GAAG,SAAS,cAAc,CAAC;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AAEA,QAAM,QAAQ,MAAM,aAAa,CAAC;AAElC,SACE,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,CAAC;AAAA,QACP;AAAA,QACA,OAAO;AAAA,QACP,aAAY;AAAA,QACZ,MAAK;AAAA,QACL,QACE,qBAAC,SAAI,WAAW,OAAO,QACrB;AAAA,8BAAC,UAAO,SAAQ,aAAY,SAAS,SAAS,mBAE9C;AAAA,UACC,SAAS,YACR,iCACE;AAAA,gCAAC,UAAO,SAAQ,aAAY,SAAS,MAAM,WAAW,IAAI,GAAG,kBAE7D;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,SAAS,OAAO;AAAA,gBAChB,SAAS,MAAM,KAAK,QAAQ;AAAA,gBAC7B;AAAA;AAAA,YAED;AAAA,aACF;AAAA,WAEJ;AAAA,QAGD;AAAA,gBAAM,aAAa,oBAAC,cAAW,OAAM,+BAAyB;AAAA,WAC7D,MAAM,WAAY,CAAC,MAAM,aAAa,CAAC,SACvC,oBAAC,eAAa,wBAAc,MAAM,OAAO,MAAM,GAAE;AAAA,UAElD,QAAQ,MAAM,WAAW,KACxB,oBAAC,OAAE,WAAW,OAAO,MAAM,0CAA4B;AAAA,UAExD,QACC,MAAM,IAAI,CAAC,MACT,qBAAC,SAAe,WAAW,OAAO,OAChC;AAAA,iCAAC,UAAK,WAAW,OAAO,MACrB;AAAA,2BAAa,CAAC;AAAA,cAAE;AAAA,cAAI,UAAU,GAAG,KAAK,MAAM;AAAA,eAC/C;AAAA,YACA,oBAAC,gBAAa,UAAoB,UAAU,GAAG;AAAA,eAJvC,EAAE,EAKZ,CACD;AAAA,UACF,wBACC,oBAAC,UAAK,WAAU,eAAe,gCAAqB;AAAA;AAAA;AAAA,IAExD;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN,SAAS,MAAM,WAAW,KAAK;AAAA;AAAA,IACjC;AAAA,KACF;AAEJ;","names":[]}
|