Files
anonymous_github/public/script/templates.js
T
Thomas DurieuxandClaude Opus 5.5 511dcd7067 feat(admin): billing tab to monitor subscriptions and sales (#952)
* 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>
2026-11-13 14:37:29 +01:00

65 lines
3.3 KiB
JavaScript

import { render as reviewConsentTemplate } from "../partials/reviewConsent.htm";
import { render as connectionsTemplate } from "../partials/connections.htm";
import { render as signinTemplate } from "../partials/signin.htm";
import { render as template0 } from "../partials/404.htm";
import { render as template1 } from "../partials/admin/conferences.htm";
import { render as template2 } from "../partials/admin/errors.htm";
import { render as template3 } from "../partials/admin/overview.htm";
import { render as template4 } from "../partials/admin/queues.htm";
import { render as template5 } from "../partials/admin/repositories.htm";
import { render as template6 } from "../partials/admin/user.htm";
import { render as template7 } from "../partials/admin/users.htm";
import { render as template8 } from "../partials/anonymize.htm";
import { render as template9 } from "../partials/anonymizePullRequest.htm";
import { render as template10 } from "../partials/claim.htm";
import { render as template11 } from "../partials/conference.htm";
import { render as template12 } from "../partials/conferences.htm";
import { render as template13 } from "../partials/dashboard.htm";
import { render as template14 } from "../partials/explorer.htm";
import { render as template15 } from "../partials/faq.htm";
import { render as template16 } from "../partials/gist.htm";
import { render as template17 } from "../partials/header.htm";
import { render as template18 } from "../partials/home.htm";
import { render as template19 } from "../partials/loading.htm";
import { render as template20 } from "../partials/newConference.htm";
import { render as template21 } from "../partials/pageView.htm";
import { render as template22 } from "../partials/pr-dashboard.htm";
import { render as template23 } from "../partials/profile.htm";
import { render as template24 } from "../partials/pullRequest.htm";
import { render as template25 } from "../partials/status.htm";
import { render as adminBillingTemplate } from "../partials/admin/billing.htm";
import { render as footerTemplate } from "../partials/footer.htm";
export const templates = {
"partials/reviewConsent.htm": reviewConsentTemplate,
"partials/connections.htm": connectionsTemplate,
"partials/signin.htm": signinTemplate,
"partials/404.htm": template0,
"partials/admin/billing.htm": adminBillingTemplate,
"partials/admin/conferences.htm": template1,
"partials/admin/errors.htm": template2,
"partials/admin/overview.htm": template3,
"partials/admin/queues.htm": template4,
"partials/admin/repositories.htm": template5,
"partials/admin/user.htm": template6,
"partials/admin/users.htm": template7,
"partials/anonymize.htm": template8,
"partials/anonymizePullRequest.htm": template9,
"partials/claim.htm": template10,
"partials/conference.htm": template11,
"partials/conferences.htm": template12,
"partials/dashboard.htm": template13,
"partials/explorer.htm": template14,
"partials/faq.htm": template15,
"partials/gist.htm": template16,
"partials/header.htm": template17,
"partials/home.htm": template18,
"partials/loading.htm": template19,
"partials/newConference.htm": template20,
"partials/pageView.htm": template21,
"partials/pr-dashboard.htm": template22,
"partials/profile.htm": template23,
"partials/pullRequest.htm": template24,
"partials/status.htm": template25,
"partials/footer.htm": footerTemplate
};