mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-11-14 00:07:00 +01:00
* feat(admin): add a Billing tab for subscriptions and sales
The admin can now follow subscriptions and sales without opening Stripe:
- Summary tiles: active subscriptions (monthly/annual), MRR with annual
plans counted as 1/12, sales and revenue for 7d/30d/90d/12m/all time,
all-time sales, subscriptions cancelling at period end, and refunds
and disputes.
- A stacked chart of sales per day, week or month by plan family.
- A by-plan table: active grants, period and all-time sales and revenue.
- A paginated list of grants with plan, Stripe status, active/expired/
revoked and user filters, linked to the admin user, repository or
conference.
- One row of webhook health: pending, failed, oldest pending event, last
error and unreviewed payment reversals.
A sale is one checkout or subscription, so a paper pack's three grants
count once. Revenue is each sale's Stripe list price, resolved once per
price and cached in memory. Currencies are never added together. Without
Stripe the page shows counts and marks revenue as unavailable.
GET /api/admin/billing/summary and /grants sit behind the admin check.
Grants get a { purchasedAt, _id } index for the list.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* fix: preserve payment history in admin billing totals
* fix: scope billing history and preserve original sale prices
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
79 lines
9.0 KiB
HTML
79 lines
9.0 KiB
HTML
<svg class="ui-icon-definitions" aria-hidden="true" focusable="false">
|
|
<defs>
|
|
<symbol id="project-type-repo" viewBox="0 0 24 24">
|
|
<path d="M6 3h13v18H6a3 3 0 0 1 0-6h13M3 18V6a3 3 0 0 1 3-3M8 7h6"></path>
|
|
</symbol>
|
|
<symbol id="project-type-pr" viewBox="0 0 24 24">
|
|
<circle cx="6" cy="5" r="2.5"></circle><circle cx="6" cy="19" r="2.5"></circle><circle cx="18" cy="19" r="2.5"></circle>
|
|
<path d="M6 7.5v9M18 16.5V9a4 4 0 0 0-4-4h-3m3-3-3 3 3 3"></path>
|
|
</symbol>
|
|
<symbol id="project-type-gist" viewBox="0 0 24 24">
|
|
<path d="M14 3H5v18h14V8l-5-5v5h5M9 12l-2 2 2 2m6-4 2 2-2 2"></path>
|
|
</symbol>
|
|
<symbol id="project-icon-copy" viewBox="0 0 24 24"><rect x="8" y="8" width="12" height="13" rx="2"></rect><path d="M15 8V3H3v13h5"></path></symbol>
|
|
<symbol id="project-icon-more" viewBox="0 0 24 24"><circle cx="5" cy="12" r="1"></circle><circle cx="12" cy="12" r="1"></circle><circle cx="19" cy="12" r="1"></circle></symbol>
|
|
<symbol id="project-icon-eye" viewBox="0 0 24 24"><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12Z"></path><circle cx="12" cy="12" r="3"></circle></symbol>
|
|
<symbol id="project-icon-clock" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"></circle><path d="M12 7v5l3 2"></path></symbol>
|
|
<symbol id="project-icon-conference" viewBox="0 0 24 24"><path d="m3 8 9-5 9 5H3Zm2 3v7m5-7v7m4-7v7m5-7v7M3 21h18"></path></symbol>
|
|
<symbol id="project-icon-plus" viewBox="0 0 24 24"><path d="M12 5v14M5 12h14"></path></symbol>
|
|
<symbol id="project-icon-filter" viewBox="0 0 24 24"><path d="M3 6h18M3 12h18M3 18h18"></path><circle cx="8" cy="6" r="2"></circle><circle cx="16" cy="12" r="2"></circle><circle cx="9" cy="18" r="2"></circle></symbol>
|
|
<symbol id="project-icon-arrow" viewBox="0 0 24 24"><path d="M12 4v16m-5-5 5 5 5-5"></path></symbol>
|
|
<symbol id="project-icon-close" viewBox="0 0 24 24"><path d="m6 6 12 12M6 18 18 6"></path></symbol>
|
|
<symbol id="project-icon-chevron" viewBox="0 0 24 24"><path d="m6 9 6 6 6-6"></path></symbol>
|
|
<symbol id="project-icon-storage" viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="7" rx="2"></rect><rect x="3" y="13" width="18" height="7" rx="2"></rect><path d="M7 7.5h.01M7 16.5h.01M11 7.5h6M11 16.5h6"></path></symbol>
|
|
<symbol id="project-icon-file" viewBox="0 0 24 24"><path d="M14 3H5v18h14V8l-5-5v5h5M9 12h6M9 16h6"></path></symbol>
|
|
<symbol id="project-icon-inbox" viewBox="0 0 24 24"><path d="m3 14 3-9h12l3 9v6H3v-6h5l2 3h4l2-3h5"></path></symbol>
|
|
<symbol id="ui-icon-arrow-left" viewBox="0 0 24 24"><path d="M20 12H4m6-6-6 6 6 6"/></symbol>
|
|
<symbol id="ui-icon-arrow-right" viewBox="0 0 24 24"><path d="M4 12h16m-6-6 6 6-6 6"/></symbol>
|
|
<symbol id="ui-icon-check" viewBox="0 0 24 24"><path d="m5 12 4 4L19 6"/></symbol>
|
|
<symbol id="ui-icon-check-circle" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="m7 12 3 3 7-7"/></symbol>
|
|
<symbol id="ui-icon-edit" viewBox="0 0 24 24"><path d="m15 4 5 5M4 20l5-1L21 7l-5-5L4 14v6Z"/></symbol>
|
|
<symbol id="ui-icon-external-link" viewBox="0 0 24 24"><path d="M14 3h7v7m0-7L10 14M10 3H3v18h18v-7"/></symbol>
|
|
<symbol id="ui-icon-key" viewBox="0 0 24 24"><circle cx="8" cy="8" r="5"/><path d="m12 12 9 9m-6-6 3-3m0 6 3-3"/></symbol>
|
|
<symbol id="ui-icon-refresh" viewBox="0 0 24 24"><path d="M20 8a8 8 0 0 0-14-3L3 8m0-5v5h5M4 16a8 8 0 0 0 14 3l3-3m0 5v-5h-5"/></symbol>
|
|
<symbol id="ui-icon-info" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M12 11v6M12 7h.01"/></symbol>
|
|
<symbol id="ui-icon-warning" viewBox="0 0 24 24"><path d="m12 3 10 18H2L12 3Zm0 6v5m0 3h.01"/></symbol>
|
|
<symbol id="ui-icon-help" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="M9 9a3 3 0 0 1 6 0c0 2-3 2-3 4m0 4h.01"/></symbol>
|
|
<symbol id="ui-icon-user" viewBox="0 0 24 24"><circle cx="12" cy="7" r="4"/><path d="M4 21v-3a8 8 0 0 1 16 0v3"/></symbol>
|
|
<symbol id="ui-icon-users" viewBox="0 0 24 24"><circle cx="9" cy="7" r="4"/><path d="M2 21v-3a7 7 0 0 1 14 0v3M16 3a4 4 0 0 1 0 8m3 3a6 6 0 0 1 3 5v2"/></symbol>
|
|
<symbol id="ui-icon-shield" viewBox="0 0 24 24"><path d="m12 3 9 4v6c0 4-9 9-9 9S3 17 3 13V7l9-4Z"/></symbol>
|
|
<symbol id="ui-icon-code" viewBox="0 0 24 24"><path d="m7 6-6 6 6 6m10-12 6 6-6 6m-4-14-2 16"/></symbol>
|
|
<symbol id="ui-icon-comment" viewBox="0 0 24 24"><path d="M21 3H3v14h5l4 4v-4h9V3Z"/><path d="M7 8h10M7 12h6"/></symbol>
|
|
<symbol id="ui-icon-save" viewBox="0 0 24 24"><path d="M3 3h14l4 4v14H3V3Zm4 0v7h10V3M7 21v-7h10v7"/></symbol>
|
|
<symbol id="ui-icon-heart" viewBox="0 0 24 24"><path d="M12 21 3 12C-2 6 7-1 12 6c5-7 14 0 9 6l-9 9Z"/></symbol>
|
|
<symbol id="ui-icon-globe" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><ellipse cx="12" cy="12" rx="4" ry="9"/><path d="M3 12h18"/></symbol>
|
|
<symbol id="ui-icon-hourglass" viewBox="0 0 24 24"><path d="M5 3h14M5 21h14M6 3v4l6 5 6-5V3M6 21v-4l6-5 6 5v4"/></symbol>
|
|
<symbol id="ui-icon-moon" viewBox="0 0 24 24"><path d="M20 14A9 9 0 0 1 10 3a9 9 0 1 0 10 11Z"/></symbol>
|
|
<symbol id="ui-icon-sun" viewBox="0 0 24 24"><circle cx="12" cy="12" r="4"/><path d="M12 1v2m0 18v2M1 12h2m18 0h2M4 4l2 2m12 12 2 2M4 20l2-2M18 6l2-2"/></symbol>
|
|
<symbol id="ui-icon-home" viewBox="0 0 24 24"><path d="M3 11 12 3l9 8M5 9.5V21h5v-6h4v6h5V9.5"/></symbol>
|
|
<symbol id="ui-icon-grid" viewBox="0 0 24 24"><rect x="3" y="3" width="7" height="7" rx="1"/><rect x="14" y="3" width="7" height="7" rx="1"/><rect x="3" y="14" width="7" height="7" rx="1"/><rect x="14" y="14" width="7" height="7" rx="1"/></symbol>
|
|
<symbol id="ui-icon-logout" viewBox="0 0 24 24"><path d="M9 3H3v18h6M9 12h12m-4-4 4 4-4 4"/></symbol>
|
|
<symbol id="ui-icon-link" viewBox="0 0 24 24"><path d="m10 7 3-3a5 5 0 0 1 7 7l-3 3M7 10l-3 3a5 5 0 0 0 7 7l3-3M8 16l8-8"/></symbol>
|
|
<symbol id="ui-icon-card" viewBox="0 0 24 24"><path d="M3 7a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2zM3 10h18M7 15h3"/></symbol>
|
|
<symbol id="ui-icon-chart" viewBox="0 0 24 24"><path d="M3 3v18h18M7 16V9m5 7V5m5 11v-5"/></symbol>
|
|
<symbol id="ui-icon-sidebar" viewBox="0 0 24 24"><path d="M4 5h16v14H4zM9.5 5v14M6 8.5h1.5M6 11h1.5"/></symbol>
|
|
<symbol id="ui-icon-zip" viewBox="0 0 24 24"><path d="M3 7a2 2 0 0 1 2-2h4l2 2h8a2 2 0 0 1 2 2v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"/><path d="M12 10v6m-2.5-2.5L12 16l2.5-2.5"/></symbol>
|
|
<symbol id="ui-icon-goto" viewBox="0 0 24 24"><path d="M9 4 7 20M17 4l-2 16M4 9h16M3 15h16"/></symbol>
|
|
<symbol id="ui-icon-wrap" viewBox="0 0 24 24"><path d="M3 6h18M3 12h14.5a3.5 3.5 0 0 1 0 7H13m2-2.5L12.5 19l2.5 2.5M3 18h6"/></symbol>
|
|
<symbol id="ui-icon-outline" viewBox="0 0 24 24"><path d="M4 6h16M8 12h12M8 18h12M4 12h.01M4 18h.01"/></symbol>
|
|
<symbol id="ui-icon-list" viewBox="0 0 24 24"><path d="M9 5h12M9 12h12M9 19h12m-18-14 1 1 2-2m-3 8 1 1 2-2m-3 8 1 1 2-2"/></symbol>
|
|
<symbol id="ui-icon-bug" viewBox="0 0 24 24"><rect x="7" y="7" width="10" height="14" rx="5"/><path d="M9 7V5a3 3 0 0 1 6 0v2M12 7v14M3 8l4 2m-4 5h4m-4 7 4-4M21 8l-4 2m4 5h-4m4 7-4-4"/></symbol>
|
|
<symbol id="ui-icon-chevron-left" viewBox="0 0 24 24"><path d="m15 5-7 7 7 7"/></symbol>
|
|
<symbol id="ui-icon-chevron-right" viewBox="0 0 24 24"><path d="m9 5 7 7-7 7"/></symbol>
|
|
<symbol id="ui-icon-download" viewBox="0 0 24 24"><path d="M12 3v12m-5-5 5 5 5-5M3 16v5h18v-5"/></symbol>
|
|
<symbol id="ui-icon-export" viewBox="0 0 24 24"><path d="M13 3H3v18h14v-6M12 9h9m-4-4 4 4-4 4"/></symbol>
|
|
<symbol id="ui-icon-clipboard" viewBox="0 0 24 24"><path d="M8 5H4v16h16V5h-4"/><rect x="8" y="2" width="8" height="6" rx="2"/></symbol>
|
|
<symbol id="ui-icon-ban" viewBox="0 0 24 24"><circle cx="12" cy="12" r="9"/><path d="m6 6 12 12"/></symbol>
|
|
<symbol id="ui-icon-trash" viewBox="0 0 24 24"><path d="M3 6h18M9 6V3h6v3M5 6l1 15h12l1-15M10 10v7m4-7v7"/></symbol>
|
|
<symbol id="ui-icon-broom" viewBox="0 0 24 24"><path d="m16 3-5 8m-7 5 6-6 6 4-3 7H3l1-5Zm1 5 4-6"/></symbol>
|
|
<symbol id="ui-icon-database" viewBox="0 0 24 24"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5v14c0 4 18 4 18 0V5M3 12c0 4 18 4 18 0"/></symbol>
|
|
<symbol id="ui-icon-user-minus" viewBox="0 0 24 24"><circle cx="9" cy="7" r="4"/><path d="M2 21v-3a7 7 0 0 1 14 0v3m0-11h7"/></symbol>
|
|
<symbol id="ui-icon-user-shield" viewBox="0 0 24 24"><circle cx="8" cy="6" r="4"/><path d="M1 21v-4a7 7 0 0 1 10-6m7 0 5 2v4c0 3-5 6-5 6s-5-3-5-6v-4l5-2Z"/></symbol>
|
|
<symbol id="ui-icon-spinner" viewBox="0 0 24 24"><path d="M21 12a9 9 0 1 1-9-9"/></symbol>
|
|
<symbol id="ui-icon-archive" viewBox="0 0 24 24"><path d="M3 3h18v5H3V3Zm2 5v13h14V8M10 3v3m4 3v3m-4 3v3m4 0v3"/></symbol>
|
|
<symbol id="ui-icon-calendar" viewBox="0 0 24 24"><rect x="3" y="5" width="18" height="16" rx="2"/><path d="M7 2v6m10-6v6M3 11h18"/></symbol>
|
|
<symbol id="ui-icon-search" viewBox="0 0 24 24"><circle cx="10" cy="10" r="7"></circle><path d="m15 15 7 7"></path></symbol>
|
|
<symbol id="ui-icon-folder" viewBox="0 0 24 24"><path d="M3 20V4h6l2 3h10v13H3Z"/></symbol>
|
|
</defs>
|
|
</svg>
|