Skip to content

Commit c429337

Browse files
committed
feat(usage-analytics): add profile hero with stats and token heat map
Add UsageProfileHero component above existing Usage page contents for personal context only. Includes: - ProfileHeader: centered circular avatar with initials, display name, and "Personal usage" handle - UsageProfileStats: 4-KPI grid showing lifetime tokens, peak tokens, current streak, and longest streak - TokenActivityHeatmap: GitHub-style daily grid with 30d/90d/1y range toggle, intensity-based tile coloring, and tooltips on all days Adds getProfile tRPC procedure querying MICRODOLLAR_USAGE_DAILY for lifetime totals (SUM/MAX) and last 365 days of daily activity. Streaks are computed client-side from daily activity with GitHub-style semantics (current streak = consecutive active days ending today).
1 parent 703f847 commit c429337

5 files changed

Lines changed: 636 additions & 0 deletions

File tree

apps/web/src/components/usage-analytics/UsageAnalyticsDashboard.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import {
2828
UsageAnalyticsSidebar,
2929
type PersonalView,
3030
} from './UsageAnalyticsSidebar';
31+
import { UsageProfileHero } from './UsageProfileHero';
3132
import {
3233
EMPTY_FILTERS,
3334
defaultGranularityForPeriod,
@@ -38,6 +39,7 @@ import {
3839
useUsageSummary,
3940
useUsageTable,
4041
useUsageTimeseries,
42+
useUsageProfile,
4143
type UsageFilters,
4244
type ViewAs,
4345
} from './hooks';
@@ -274,6 +276,13 @@ export function UsageAnalyticsDashboard({
274276
limit: 500,
275277
});
276278

279+
// Profile hook - only enabled for personal context
280+
const {
281+
data: usageProfile,
282+
isLoading: usageProfileLoading,
283+
error: usageProfileError,
284+
} = useUsageProfile(context === 'personal');
285+
277286
// Resolve user ID -> email for labels whenever there is an effective org
278287
// scope. Key off `effectiveOrgId` (not the prop `organizationId`) so that
279288
// future paths which surface user-dimension data in personal-with-org mode
@@ -536,6 +545,13 @@ export function UsageAnalyticsDashboard({
536545

537546
<div className="flex-1 overflow-y-auto">
538547
<div className="m-auto flex w-full max-w-[1140px] flex-col gap-6 p-4 md:p-6">
548+
{context === 'personal' && (
549+
<UsageProfileHero
550+
profile={usageProfile}
551+
loading={usageProfileLoading}
552+
error={usageProfileError}
553+
/>
554+
)}
539555
<UsageWarning />
540556

541557
{isOrgContext && organizationId && (

0 commit comments

Comments
 (0)