@withpotter/pages-admin 0.13.0-next.101 → 0.13.0-next.103

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.
Files changed (60) hide show
  1. package/dist/admin/_pos/tenant-operators.js +73 -0
  2. package/dist/admin/_pos/tenant-operators.js.map +1 -0
  3. package/dist/admin/_pos/tenant-pos-figures.js +82 -0
  4. package/dist/admin/_pos/tenant-pos-figures.js.map +1 -0
  5. package/dist/admin/_pos/use-pos.js +12 -0
  6. package/dist/admin/_pos/use-pos.js.map +1 -1
  7. package/dist/admin/hooks.js +19 -0
  8. package/dist/admin/hooks.js.map +1 -1
  9. package/dist/admin/pos/shifts-tab.js +15 -8
  10. package/dist/admin/pos/shifts-tab.js.map +1 -1
  11. package/dist/admin/revenue/cohort-panel.js +5 -5
  12. package/dist/admin/revenue/cohort-panel.js.map +1 -1
  13. package/dist/admin/revenue/health-panel.js +17 -17
  14. package/dist/admin/revenue/health-panel.js.map +1 -1
  15. package/dist/admin/revenue/ledger-model.js +7 -0
  16. package/dist/admin/revenue/ledger-model.js.map +1 -1
  17. package/dist/admin/revenue/ledger.module.css +43 -0
  18. package/dist/admin/revenue/merchant-headline.js +37 -0
  19. package/dist/admin/revenue/merchant-headline.js.map +1 -0
  20. package/dist/admin/revenue/merchant-payments-view.js +46 -22
  21. package/dist/admin/revenue/merchant-payments-view.js.map +1 -1
  22. package/dist/admin/revenue/merchants-view.js +99 -0
  23. package/dist/admin/revenue/merchants-view.js.map +1 -0
  24. package/dist/admin/revenue/payment-drawer.js +53 -0
  25. package/dist/admin/revenue/payment-drawer.js.map +1 -0
  26. package/dist/admin/revenue/plan-mix-panel.js +1 -1
  27. package/dist/admin/revenue/plan-mix-panel.js.map +1 -1
  28. package/dist/admin/revenue/plan-payment-drawer.js +42 -0
  29. package/dist/admin/revenue/plan-payment-drawer.js.map +1 -0
  30. package/dist/admin/revenue/print-summary-button.js +34 -0
  31. package/dist/admin/revenue/print-summary-button.js.map +1 -0
  32. package/dist/admin/revenue/quality-panel.js +19 -19
  33. package/dist/admin/revenue/quality-panel.js.map +1 -1
  34. package/dist/admin/revenue/revenue-kpis.js +64 -50
  35. package/dist/admin/revenue/revenue-kpis.js.map +1 -1
  36. package/dist/admin/revenue/revenue-overview.js +68 -50
  37. package/dist/admin/revenue/revenue-overview.js.map +1 -1
  38. package/dist/admin/revenue/revenue-retention.js +17 -13
  39. package/dist/admin/revenue/revenue-retention.js.map +1 -1
  40. package/dist/admin/revenue/revenue-workspace.js +16 -0
  41. package/dist/admin/revenue/revenue-workspace.js.map +1 -1
  42. package/dist/admin/revenue/subscriptions-panel.js +14 -14
  43. package/dist/admin/revenue/subscriptions-panel.js.map +1 -1
  44. package/dist/admin/revenue/subscriptions-view.js +20 -20
  45. package/dist/admin/revenue/subscriptions-view.js.map +1 -1
  46. package/dist/admin/revenue/summary-download.js +34 -0
  47. package/dist/admin/revenue/summary-download.js.map +1 -0
  48. package/dist/admin/revenue/summary-print.js +82 -0
  49. package/dist/admin/revenue/summary-print.js.map +1 -0
  50. package/dist/admin/revenue/summary-rows.js +44 -0
  51. package/dist/admin/revenue/summary-rows.js.map +1 -0
  52. package/dist/admin/revenue/top-tenants-panel.js +1 -1
  53. package/dist/admin/revenue/top-tenants-panel.js.map +1 -1
  54. package/dist/admin/revenue/url-filters.js +36 -0
  55. package/dist/admin/revenue/url-filters.js.map +1 -0
  56. package/dist/admin/revenue/use-url-filters.js +24 -0
  57. package/dist/admin/revenue/use-url-filters.js.map +1 -0
  58. package/dist/admin/tenants/[id]/tenant-pos.js +53 -16
  59. package/dist/admin/tenants/[id]/tenant-pos.js.map +1 -1
  60. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/admin/revenue/top-tenants-panel.tsx"],"sourcesContent":["import Link from 'next/link';\nimport { useRouter } from 'next/navigation';\nimport { EmptyNote, TableRow, TableShell, Th } from '@withpotter/ui-kit';\nimport type { PlatformRevenue } from '@withpotter/lib/admin-api';\nimport { EntityAvatar } from '../_fx';\nimport { PICK_CURRENCY, Panel, moneyIn } from '../_ui';\nimport { logoOf } from '../tenants/tenants-logo';\nimport styles from './revenue.module.css';\n\nconst integer = new Intl.NumberFormat('en-US');\n\n/**\n * Merchants ranked by GMV within one currency, with order count, AOV and\n * share of that currency's lifetime GMV.\n */\nexport function TopTenantsPanel({\n tenants,\n lifetime,\n focus,\n}: {\n tenants: PlatformRevenue['gmv']['topTenants'];\n /** Lifetime GMV in `focus`, the base for each share. */\n lifetime: number;\n /** The one currency ranked, or null when there are several and none is chosen. */\n focus: string | null;\n}) {\n const router = useRouter();\n const money = moneyIn(focus ?? '');\n\n return (\n <Panel\n title=\"Top merchants by GMV\"\n count={tenants.length || undefined}\n caption={focus ?? undefined}\n action={<Link href=\"/admin/tenants\">View all</Link>}\n flush\n >\n {tenants.length === 0 ? (\n <EmptyNote className={styles.empty}>\n {focus ? `No ${focus} merchant revenue recorded yet.` : PICK_CURRENCY}\n </EmptyNote>\n ) : (\n <TableShell\n bare\n minWidth={520}\n density=\"compact\"\n head={\n <tr>\n <Th>Merchant</Th>\n <Th align=\"right\">Orders</Th>\n <Th align=\"right\">AOV</Th>\n <Th align=\"right\">GMV</Th>\n <Th align=\"right\">% of GMV</Th>\n </tr>\n }\n >\n {tenants.map((t) => {\n const aov = t.orders > 0 ? t.gmv / t.orders : 0;\n const share = lifetime > 0 ? (t.gmv / lifetime) * 100 : 0;\n const logo = logoOf(t);\n return (\n <TableRow\n key={t.id}\n onClick={() => router.push(`/admin/tenants/${t.id}`)}\n >\n <td className={styles.name}>\n <span className={styles.tenant}>\n {logo && (\n <EntityAvatar\n name={t.businessName}\n src={logo}\n size={28}\n />\n )}\n <span className={styles.tenantText}>\n <Link\n href={`/admin/tenants/${t.id}`}\n title={t.businessName}\n onClick={(e) => e.stopPropagation()}\n >\n {t.businessName}\n </Link>\n {t.slug && (\n <span className={styles.slug} title={t.slug}>\n {t.slug}\n </span>\n )}\n </span>\n </span>\n </td>\n <td className={styles.num}>{integer.format(t.orders)}</td>\n <td className={styles.num}>{money(aov)}</td>\n <td className={styles.numStrong}>{money(t.gmv)}</td>\n <td className={styles.num}>\n <span className={styles.share}>\n <span className={styles.shareTrack} aria-hidden>\n <span\n className={styles.shareFill}\n style={{ width: `${Math.min(share, 100)}%` }}\n />\n </span>\n {share.toFixed(1)}%\n </span>\n </td>\n </TableRow>\n );\n })}\n </TableShell>\n )}\n </Panel>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/admin/revenue/top-tenants-panel.tsx"],"sourcesContent":["import Link from 'next/link';\nimport { useRouter } from 'next/navigation';\nimport { EmptyNote, TableRow, TableShell, Th } from '@withpotter/ui-kit';\nimport type { PlatformRevenue } from '@withpotter/lib/admin-api';\nimport { EntityAvatar } from '../_fx';\nimport { PICK_CURRENCY, Panel, moneyIn } from '../_ui';\nimport { logoOf } from '../tenants/tenants-logo';\nimport styles from './revenue.module.css';\n\nconst integer = new Intl.NumberFormat('en-US');\n\n/**\n * Merchants ranked by GMV within one currency, with order count, AOV and\n * share of that currency's lifetime GMV.\n */\nexport function TopTenantsPanel({\n tenants,\n lifetime,\n focus,\n}: {\n tenants: PlatformRevenue['gmv']['topTenants'];\n /** Lifetime GMV in `focus`, the base for each share. */\n lifetime: number;\n /** The one currency ranked, or null when there are several and none is chosen. */\n focus: string | null;\n}) {\n const router = useRouter();\n const money = moneyIn(focus ?? '');\n\n return (\n <Panel\n title=\"Biggest merchants by sales\"\n count={tenants.length || undefined}\n caption={focus ?? undefined}\n action={<Link href=\"/admin/tenants\">View all</Link>}\n flush\n >\n {tenants.length === 0 ? (\n <EmptyNote className={styles.empty}>\n {focus ? `No ${focus} merchant revenue recorded yet.` : PICK_CURRENCY}\n </EmptyNote>\n ) : (\n <TableShell\n bare\n minWidth={520}\n density=\"compact\"\n head={\n <tr>\n <Th>Merchant</Th>\n <Th align=\"right\">Orders</Th>\n <Th align=\"right\">AOV</Th>\n <Th align=\"right\">GMV</Th>\n <Th align=\"right\">% of GMV</Th>\n </tr>\n }\n >\n {tenants.map((t) => {\n const aov = t.orders > 0 ? t.gmv / t.orders : 0;\n const share = lifetime > 0 ? (t.gmv / lifetime) * 100 : 0;\n const logo = logoOf(t);\n return (\n <TableRow\n key={t.id}\n onClick={() => router.push(`/admin/tenants/${t.id}`)}\n >\n <td className={styles.name}>\n <span className={styles.tenant}>\n {logo && (\n <EntityAvatar\n name={t.businessName}\n src={logo}\n size={28}\n />\n )}\n <span className={styles.tenantText}>\n <Link\n href={`/admin/tenants/${t.id}`}\n title={t.businessName}\n onClick={(e) => e.stopPropagation()}\n >\n {t.businessName}\n </Link>\n {t.slug && (\n <span className={styles.slug} title={t.slug}>\n {t.slug}\n </span>\n )}\n </span>\n </span>\n </td>\n <td className={styles.num}>{integer.format(t.orders)}</td>\n <td className={styles.num}>{money(aov)}</td>\n <td className={styles.numStrong}>{money(t.gmv)}</td>\n <td className={styles.num}>\n <span className={styles.share}>\n <span className={styles.shareTrack} aria-hidden>\n <span\n className={styles.shareFill}\n style={{ width: `${Math.min(share, 100)}%` }}\n />\n </span>\n {share.toFixed(1)}%\n </span>\n </td>\n </TableRow>\n );\n })}\n </TableShell>\n )}\n </Panel>\n );\n}\n"],"mappings":"AAkCc,cAaF,YAbE;AAlCd,OAAO,UAAU;AACjB,SAAS,iBAAiB;AAC1B,SAAS,WAAW,UAAU,YAAY,UAAU;AAEpD,SAAS,oBAAoB;AAC7B,SAAS,eAAe,OAAO,eAAe;AAC9C,SAAS,cAAc;AACvB,OAAO,YAAY;AAEnB,MAAM,UAAU,IAAI,KAAK,aAAa,OAAO;AAMtC,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AACF,GAMG;AACD,QAAM,SAAS,UAAU;AACzB,QAAM,QAAQ,QAAQ,SAAS,EAAE;AAEjC,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,OAAO,QAAQ,UAAU;AAAA,MACzB,SAAS,SAAS;AAAA,MAClB,QAAQ,oBAAC,QAAK,MAAK,kBAAiB,sBAAQ;AAAA,MAC5C,OAAK;AAAA,MAEJ,kBAAQ,WAAW,IAClB,oBAAC,aAAU,WAAW,OAAO,OAC1B,kBAAQ,MAAM,KAAK,oCAAoC,eAC1D,IAEA;AAAA,QAAC;AAAA;AAAA,UACC,MAAI;AAAA,UACJ,UAAU;AAAA,UACV,SAAQ;AAAA,UACR,MACE,qBAAC,QACC;AAAA,gCAAC,MAAG,sBAAQ;AAAA,YACZ,oBAAC,MAAG,OAAM,SAAQ,oBAAM;AAAA,YACxB,oBAAC,MAAG,OAAM,SAAQ,iBAAG;AAAA,YACrB,oBAAC,MAAG,OAAM,SAAQ,iBAAG;AAAA,YACrB,oBAAC,MAAG,OAAM,SAAQ,sBAAQ;AAAA,aAC5B;AAAA,UAGD,kBAAQ,IAAI,CAAC,MAAM;AAClB,kBAAM,MAAM,EAAE,SAAS,IAAI,EAAE,MAAM,EAAE,SAAS;AAC9C,kBAAM,QAAQ,WAAW,IAAK,EAAE,MAAM,WAAY,MAAM;AACxD,kBAAM,OAAO,OAAO,CAAC;AACrB,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,SAAS,MAAM,OAAO,KAAK,kBAAkB,EAAE,EAAE,EAAE;AAAA,gBAEnD;AAAA,sCAAC,QAAG,WAAW,OAAO,MACpB,+BAAC,UAAK,WAAW,OAAO,QACrB;AAAA,4BACC;AAAA,sBAAC;AAAA;AAAA,wBACC,MAAM,EAAE;AAAA,wBACR,KAAK;AAAA,wBACL,MAAM;AAAA;AAAA,oBACR;AAAA,oBAEF,qBAAC,UAAK,WAAW,OAAO,YACtB;AAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAM,kBAAkB,EAAE,EAAE;AAAA,0BAC5B,OAAO,EAAE;AAAA,0BACT,SAAS,CAAC,MAAM,EAAE,gBAAgB;AAAA,0BAEjC,YAAE;AAAA;AAAA,sBACL;AAAA,sBACC,EAAE,QACD,oBAAC,UAAK,WAAW,OAAO,MAAM,OAAO,EAAE,MACpC,YAAE,MACL;AAAA,uBAEJ;AAAA,qBACF,GACF;AAAA,kBACA,oBAAC,QAAG,WAAW,OAAO,KAAM,kBAAQ,OAAO,EAAE,MAAM,GAAE;AAAA,kBACrD,oBAAC,QAAG,WAAW,OAAO,KAAM,gBAAM,GAAG,GAAE;AAAA,kBACvC,oBAAC,QAAG,WAAW,OAAO,WAAY,gBAAM,EAAE,GAAG,GAAE;AAAA,kBAC/C,oBAAC,QAAG,WAAW,OAAO,KACpB,+BAAC,UAAK,WAAW,OAAO,OACtB;AAAA,wCAAC,UAAK,WAAW,OAAO,YAAY,eAAW,MAC7C;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAW,OAAO;AAAA,wBAClB,OAAO,EAAE,OAAO,GAAG,KAAK,IAAI,OAAO,GAAG,CAAC,IAAI;AAAA;AAAA,oBAC7C,GACF;AAAA,oBACC,MAAM,QAAQ,CAAC;AAAA,oBAAE;AAAA,qBACpB,GACF;AAAA;AAAA;AAAA,cAzCK,EAAE;AAAA,YA0CT;AAAA,UAEJ,CAAC;AAAA;AAAA,MACH;AAAA;AAAA,EAEJ;AAEJ;","names":[]}
@@ -0,0 +1,36 @@
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
@@ -0,0 +1 @@
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":[]}
@@ -0,0 +1,24 @@
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
@@ -0,0 +1 @@
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":[]}
@@ -3,7 +3,14 @@ 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 { AdmLoading, CurrencyFilter, currenciesIn, useCurrencyParam } from "../../_ui";
6
+ import {
7
+ AdmLoading,
8
+ CurrencyFilter,
9
+ PageTabs,
10
+ currenciesIn,
11
+ useCurrencyParam,
12
+ useTabParam
13
+ } from "../../_ui";
7
14
  import { ListCard } from "../../_ui/list-card";
8
15
  import { LoadError, MoneyLines } from "../../_pos/pos-parts";
9
16
  import { count } from "../../_pos/pos-words";
@@ -13,10 +20,25 @@ import { usePosAccess } from "../../_pos/use-pos-access";
13
20
  import { usePosPeriod } from "../../_pos/use-pos-period";
14
21
  import { useTenantPos } from "../../_pos/use-pos";
15
22
  import pos from "../../_pos/pos.module.css";
16
- import { TerminalHead, TerminalRow, terminalColumns } from "../../pos/terminal-row";
23
+ import { TenantOperators } from "../../_pos/tenant-operators";
24
+ import { TenantPosFigures } from "../../_pos/tenant-pos-figures";
25
+ import { ShiftsTab } from "../../pos/shifts-tab";
26
+ import {
27
+ TerminalHead,
28
+ TerminalRow,
29
+ terminalColumns
30
+ } from "../../pos/terminal-row";
31
+ const VIEWS = [
32
+ { id: "overview", label: "Overview" },
33
+ { id: "terminals", label: "Terminals" },
34
+ { id: "sessions", label: "Sessions" },
35
+ { id: "operators", label: "Operators" }
36
+ ];
37
+ const VIEW_KEYS = VIEWS.map((v) => v.id);
17
38
  function TenantPos({ tenantId }) {
18
39
  const router = useRouter();
19
40
  const { isLoading: accessLoading, canRead } = usePosAccess();
41
+ const [view, setView] = useTabParam(VIEW_KEYS, "view");
20
42
  const { period, phrase, control } = usePosPeriod();
21
43
  const [currency, setCurrency] = useCurrencyParam();
22
44
  const query = useTenantPos(tenantId, period, canRead);
@@ -46,7 +68,14 @@ function TenantPos({ tenantId }) {
46
68
  /* @__PURE__ */ jsx(MoneyLines, { amounts: data.takings.amounts, currency }),
47
69
  ` taken, ${phrase} \xB7 `
48
70
  ] }) : null,
49
- /* @__PURE__ */ jsx(Link, { href: `/admin/pos?tenant=${tenantId}`, className: "text-brand-500 hover:underline", children: "Open in POS" })
71
+ /* @__PURE__ */ jsx(
72
+ Link,
73
+ {
74
+ href: `/admin/pos?tenant=${tenantId}`,
75
+ className: "text-brand-500 hover:underline",
76
+ children: "Open in POS"
77
+ }
78
+ )
50
79
  ] }),
51
80
  /* @__PURE__ */ jsxs("div", { className: "adm-toolbar", children: [
52
81
  /* @__PURE__ */ jsx(
@@ -54,13 +83,30 @@ function TenantPos({ tenantId }) {
54
83
  {
55
84
  value: currency,
56
85
  onChange: setCurrency,
57
- currencies: currenciesIn(data.takings.amounts.map((a) => a.currency))
86
+ currencies: currenciesIn(
87
+ data.takings.amounts.map((a) => a.currency)
88
+ )
58
89
  }
59
90
  ),
60
91
  control
61
92
  ] })
62
93
  ] }),
63
- /* @__PURE__ */ jsx(
94
+ /* @__PURE__ */ jsx(PageTabs, { tabs: VIEWS, active: view, onChange: setView }),
95
+ view === "overview" && /* @__PURE__ */ jsxs(Fragment, { children: [
96
+ /* @__PURE__ */ jsx(TenantPosFigures, { data, phrase, currency }),
97
+ /* @__PURE__ */ jsx(
98
+ ShiftsTable,
99
+ {
100
+ title: "Open shifts",
101
+ rows: data.openShifts,
102
+ total: data.openShifts.length,
103
+ withBusiness: false,
104
+ currency,
105
+ emptyTitle: "No till is open right now."
106
+ }
107
+ )
108
+ ] }),
109
+ view === "terminals" && /* @__PURE__ */ jsx(
64
110
  ListCard,
65
111
  {
66
112
  title: "Terminals",
@@ -82,17 +128,8 @@ function TenantPos({ tenantId }) {
82
128
  ))
83
129
  }
84
130
  ),
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
- )
131
+ view === "sessions" && /* @__PURE__ */ jsx(ShiftsTab, { tenantId, currency, title: "Sessions" }),
132
+ view === "operators" && /* @__PURE__ */ jsx(TenantOperators, { terminals: data.terminals, period })
96
133
  ] });
97
134
  }
98
135
  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 { 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":[]}
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 {\n AdmLoading,\n CurrencyFilter,\n PageTabs,\n currenciesIn,\n useCurrencyParam,\n useTabParam,\n} 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 { TenantOperators } from '../../_pos/tenant-operators';\nimport { TenantPosFigures } from '../../_pos/tenant-pos-figures';\nimport { ShiftsTab } from '../../pos/shifts-tab';\nimport {\n TerminalHead,\n TerminalRow,\n terminalColumns,\n} from '../../pos/terminal-row';\n\nconst VIEWS = [\n { id: 'overview', label: 'Overview' },\n { id: 'terminals', label: 'Terminals' },\n { id: 'sessions', label: 'Sessions' },\n { id: 'operators', label: 'Operators' },\n] as const;\n\nconst VIEW_KEYS = VIEWS.map((v) => v.id);\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 [view, setView] = useTabParam(VIEW_KEYS, 'view');\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>\n {\"You don't have permission to see this business's POS.\"}\n </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\n href={`/admin/pos?tenant=${tenantId}`}\n className=\"text-brand-500 hover:underline\"\n >\n Open in POS\n </Link>\n </span>\n <div className=\"adm-toolbar\">\n <CurrencyFilter\n value={currency}\n onChange={setCurrency}\n currencies={currenciesIn(\n data.takings.amounts.map((a) => a.currency),\n )}\n />\n {control}\n </div>\n </div>\n\n <PageTabs tabs={VIEWS} active={view} onChange={setView} />\n\n {view === 'overview' && (\n <>\n <TenantPosFigures data={data} phrase={phrase} currency={currency} />\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 </>\n )}\n\n {view === 'terminals' && (\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\n {view === 'sessions' && (\n <ShiftsTab tenantId={tenantId} currency={currency} title=\"Sessions\" />\n )}\n\n {view === 'operators' && (\n <TenantOperators terminals={data.terminals} period={period} />\n )}\n </div>\n );\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@withpotter/pages-admin",
3
- "version": "0.13.0-next.101",
3
+ "version": "0.13.0-next.103",
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.101",
35
- "@withpotter/platform-admin": "^0.13.0-next.101",
36
- "@withpotter/ui-kit": "^0.13.0-next.101",
34
+ "@withpotter/lib": "^0.13.0-next.103",
35
+ "@withpotter/platform-admin": "^0.13.0-next.103",
36
+ "@withpotter/ui-kit": "^0.13.0-next.103",
37
37
  "lucide-react": "^0.562.0",
38
38
  "motion": "^12.42.2"
39
39
  },