flagon-io/g1t

public

Git for AI scale: a forge for thousands of agents working on the same code at once.

Commit

The balance shows what was spent this month and in total

syntaqxcommitted Parent66440ccBrowse files
2 files+41−60/2 viewed
+4−0
325325
326326 ## The statement
327327
328+Beside the balance, the **Billing** page shows what the workspace has
329+spent this month and in total, and what it has paid and been credited in
330+total: every agent run, sandbox, build and app, at what was charged.
331+
328332 The **Billing** page ends with the workspace's statement, a month at a
329333 time. Every member can see it.
330334
+37−6
5252 throw redirect(`/${slug}/-/billing?added=1`);
5353 }
5454 const group: "day" | "project" = url.searchParams.get("group") === "project" ? "project" : "day";
55− const [account, statement, features, deployUsage, limit, invoices] = await Promise.all([
55+ const now = new Date();
56+ const monthStart = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)).toISOString();
57+ const [account, statement, features, deployUsage, limit, invoices, thisMonth, allTime] = await Promise.all([
5658 billing.account(slug, viewer),
5759 billing.statement(slug, viewer, url.searchParams.get("month"), group),
5860 billing.features(slug, viewer),
5961 deployments.usage(slug, viewer),
6062 billing.limit(slug, viewer),
6163 billing.invoices(slug, viewer).catch(() => null),
64+ billing.usage(slug, viewer, monthStart).catch(() => null),
65+ billing.usage(slug, viewer, "1970-01-01T00:00:00.000Z").catch(() => null),
6266 ]);
6367 return {
6468 slug,
7074 deployUsage: deployUsage.ok ? deployUsage.value : null,
7175 limit: limit.ok ? limit.value : null,
7276 invoices: invoices?.ok ? invoices.value : [],
77+ spent: {
78+ month: thisMonth?.ok ? thisMonth.value.spentMicros : null,
79+ total: allTime?.ok ? allTime.value.spentMicros : null,
80+ added: allTime?.ok ? allTime.value.addedMicros : null,
81+ },
7382 added: url.searchParams.has("added"),
7483 subscribed: url.searchParams.has("subscribed"),
7584 };
131140 }
132141
133142 export default function WorkspaceBilling({ loaderData, actionData }: Route.ComponentProps) {
134− const { slug, role, account, statement, group, features, deployUsage, limit, invoices, added, subscribed } = loaderData;
143+ const { slug, role, account, statement, group, spent, features, deployUsage, limit, invoices, added, subscribed } = loaderData;
135144 const { status } = account;
136145 const paying = useNavigation().state === "submitting";
137146 const empty = account.balanceMicros <= 0;
267276 empty && status.enabled ? "border-warn/40 bg-warn/5" : "border-line bg-surface"
268277 }`}
269278 >
270− <p className="text-xs text-muted">Balance</p>
271− <p className="mt-1 text-3xl font-semibold tabular-nums tracking-tight">
272− {dollars(account.balanceMicros)}
273− </p>
279+ <dl className="flex flex-wrap items-end gap-x-10 gap-y-4">
280+ <div>
281+ <dt className="text-xs text-muted">Balance</dt>
282+ <dd className="mt-1 text-3xl font-semibold tabular-nums tracking-tight">
283+ {dollars(account.balanceMicros)}
284+ </dd>
285+ </div>
286+ {spent.month !== null && (
287+ <div>
288+ <dt className="text-xs text-muted">Spent this month</dt>
289+ <dd className="mt-1 text-xl font-medium tabular-nums">{dollars(spent.month)}</dd>
290+ </div>
291+ )}
292+ {spent.total !== null && (
293+ <div>
294+ <dt className="text-xs text-muted">Spent in total</dt>
295+ <dd className="mt-1 text-xl font-medium tabular-nums">{dollars(spent.total)}</dd>
296+ </div>
297+ )}
298+ {spent.added !== null && spent.added !== 0 && (
299+ <div>
300+ <dt className="text-xs text-muted">Paid and credited in total</dt>
301+ <dd className="mt-1 text-xl font-medium tabular-nums text-muted">{dollars(spent.added)}</dd>
302+ </div>
303+ )}
304+ </dl>
274305 {added && (
275306 <p className="mt-2 text-sm text-accent">Payment received. Credit added.</p>
276307 )}