Files
2026-09-08 07:21:34 -04:00

120 lines
5.4 KiB
TypeScript

"use client";
import React from "react";
import { BarChart3, Cpu, Clock, DollarSign, Users, Zap } from "lucide-react";
import { Card, CardBody, CardHeader, CardTitle } from "@/components/ui/Card";
import { Badge } from "@/components/ui/Badge";
import { MetricCard } from "@/components/ui/MetricCard";
const MONTHS = ["Jul", "Aug", "Sep", "Oct", "Nov"];
const SERIES = [
{ label: "AI tokens (M)", data: [0.1, 0.8, 1.4, 2.9, 4.2], tone: "bg-violet-400" },
{ label: "Jobs executed", data: [120, 280, 412, 688, 904], tone: "bg-brand-400" },
];
function Bar({ label, values, tone }: { label: string; values: number[]; tone: string }) {
const max = Math.max(...values, 1);
return (
<div>
<div className="text-xs text-slate-500 mb-2 font-medium">{label}</div>
<div className="flex items-end gap-2 h-32">
{values.map((v, i) => (
<div key={i} className="flex-1 flex flex-col items-center gap-1">
<div
className={["w-full rounded-t-md transition-all", tone].join(" ")}
style={{ height: `${(v / max) * 100}%`, minHeight: "4px" }}
title={`${v}`}
/>
<div className="text-[10px] text-slate-500">{MONTHS[i]}</div>
</div>
))}
</div>
</div>
);
}
const ROWS = [
{ name: "Tenant default", projects: 6, users: 14, jobs_7d: 412, tokens_7d: 2.1, cost_7d: 128.4 },
{ name: "Tenant acme-corp", projects: 2, users: 6, jobs_7d: 88, tokens_7d: 0.6, cost_7d: 24.1 },
{ name: "Tenant contoso-labs", projects: 3, users: 9, jobs_7d: 180, tokens_7d: 1.1, cost_7d: 52.7 },
];
export default function UsagePage() {
return (
<div className="p-6 lg:p-8 max-w-[1400px] mx-auto">
<header className="mb-6 flex flex-wrap items-start justify-between gap-3">
<div>
<h1 className="text-2xl font-semibold tracking-tight text-slate-900 flex items-center gap-2">
<BarChart3 className="w-6 h-6 text-brand-600" />
Usage
</h1>
<p className="mt-1 text-sm text-slate-500">
Tenant-level metering: AI tokens, background jobs, projects, seats and estimated cost.
</p>
</div>
<Badge tone="neutral">Monthly view</Badge>
</header>
<section className="grid grid-cols-2 md:grid-cols-5 gap-4 mb-6">
<MetricCard label="Projects" value={11} tone="brand" icon={<BarChart3 className="w-5 h-5" />} />
<MetricCard label="Active users" value={29} tone="blue" icon={<Users className="w-5 h-5" />} />
<MetricCard label="Jobs (7d)" value={680} tone="green" icon={<Clock className="w-5 h-5" />} delta={12.4} />
<MetricCard label="AI tokens (7d, M)" value={3.8} tone="violet" icon={<Zap className="w-5 h-5" />} delta={18.7} />
<MetricCard label="Est. cost (7d, $)" value={205.2} tone="amber" icon={<DollarSign className="w-5 h-5" />} delta={9.2} />
</section>
<section className="grid grid-cols-1 lg:grid-cols-2 gap-4 mb-6">
<Card>
<CardHeader><CardTitle>Trend · AI tokens</CardTitle><Badge tone="violet">millions</Badge></CardHeader>
<CardBody>
<Bar label="" values={SERIES[0].data} tone={SERIES[0].tone} />
</CardBody>
</Card>
<Card>
<CardHeader><CardTitle>Trend · Jobs executed</CardTitle><Badge tone="brand">count</Badge></CardHeader>
<CardBody>
<Bar label="" values={SERIES[1].data} tone={SERIES[1].tone} />
</CardBody>
</Card>
</section>
<Card>
<CardHeader>
<CardTitle>Per-tenant breakdown</CardTitle>
<Badge tone="neutral">{ROWS.length} tenants</Badge>
</CardHeader>
<CardBody className="p-0">
<table className="w-full text-sm">
<thead className="bg-slate-50 text-xs uppercase tracking-wide text-slate-500 border-b border-slate-200">
<tr>
<th className="text-left px-4 py-2">Tenant</th>
<th className="text-right px-4 py-2">Projects</th>
<th className="text-right px-4 py-2">Users</th>
<th className="text-right px-4 py-2">Jobs (7d)</th>
<th className="text-right px-4 py-2">Tokens (7d, M)</th>
<th className="text-right px-4 py-2">Cost (7d)</th>
</tr>
</thead>
<tbody className="divide-y divide-slate-100">
{ROWS.map((r) => (
<tr key={r.name} className="hover:bg-slate-50">
<td className="px-4 py-2.5 font-medium text-slate-800">{r.name}</td>
<td className="px-4 py-2.5 text-right tabular-nums">{r.projects}</td>
<td className="px-4 py-2.5 text-right tabular-nums">{r.users}</td>
<td className="px-4 py-2.5 text-right tabular-nums">{r.jobs_7d}</td>
<td className="px-4 py-2.5 text-right tabular-nums">{r.tokens_7d.toFixed(2)}</td>
<td className="px-4 py-2.5 text-right tabular-nums">${r.cost_7d.toFixed(2)}</td>
</tr>
))}
</tbody>
</table>
</CardBody>
</Card>
<div className="mt-4 flex items-center justify-end gap-3 text-xs text-slate-500">
<Badge tone="neutral"><Cpu className="w-3 h-3" /> GPU-s metered</Badge>
<Badge tone="neutral"><DollarSign className="w-3 h-3" /> Cost tables configurable per-tenant</Badge>
</div>
</div>
);
}