fix(analytics): tighten top-bar layout (single-line trigger, grouped cluster, compact timestamp)

Three design taste fixes that ride on top of the disclaimer collapse:

- Single-line profile trigger: render only `option.label` in the
  Select trigger; keep label+description in the open menu where the
  description earns its keep. Removes the two-line trigger that broke
  the row baseline (taller pill, vertical-center cascade).
- Group Select + Info icon in an `inline-flex … shrink-0` cluster so
  they wrap as a single unit and the icon never orphans onto a second
  row under the refresh button.
- Compact timestamp: "Updated less than a minute ago" → "1m ago"
  rendered in font-mono. Full phrase preserved via `title`
  attribute. Drops the localized prefix into a tooltip-only context.
- Trigger width trimmed 190px → 170px since it no longer needs to fit
  a description line.
This commit is contained in:
Tam Nhu Tran
2026-05-24 11:34:57 -04:00
parent 9130c7d869
commit bfa4c704eb
2 changed files with 24 additions and 8 deletions
@@ -54,10 +54,12 @@ export function AnalyticsHeader({
<p className="text-sm text-muted-foreground">{t('analytics.subtitle')}</p>
</div>
<div className="flex flex-wrap items-center gap-2 xl:justify-end">
<div className="flex items-center gap-1">
<div className="inline-flex items-center gap-1 shrink-0">
<Select value={selectedProfile} onValueChange={onProfileChange}>
<SelectTrigger className="h-8 w-[190px]" aria-label="Analytics profile">
<SelectValue placeholder="All profiles" />
<SelectTrigger className="h-8 w-[170px]" aria-label="Analytics profile">
<SelectValue placeholder="All profiles">
{profileOptions.find((o) => o.value === selectedProfile)?.label ?? 'All profiles'}
</SelectValue>
</SelectTrigger>
<SelectContent>
{profileOptions.map((option) => (
@@ -114,8 +116,11 @@ export function AnalyticsHeader({
/>
{lastUpdatedText && (
<span className="text-xs text-muted-foreground whitespace-nowrap">
{t('analytics.updated', { value: lastUpdatedText })}
<span
className="text-xs text-muted-foreground whitespace-nowrap font-mono"
title={t('analytics.updated', { value: lastUpdatedText })}
>
{lastUpdatedText}
</span>
)}
<Button
+14 -3
View File
@@ -6,7 +6,18 @@
import { useState, useMemo, useCallback } from 'react';
import type { DateRange } from 'react-day-picker';
import { subDays, formatDistanceToNow } from 'date-fns';
import { subDays } from 'date-fns';
function formatCompactRelativeTime(date: Date): string {
const seconds = Math.max(1, Math.floor((Date.now() - date.getTime()) / 1000));
if (seconds < 60) return `${seconds}s ago`;
const minutes = Math.floor(seconds / 60);
if (minutes < 60) return `${minutes}m ago`;
const hours = Math.floor(minutes / 60);
if (hours < 24) return `${hours}h ago`;
const days = Math.floor(hours / 24);
return `${days}d ago`;
}
import {
useUsageSummary,
useUsageTrends,
@@ -151,10 +162,10 @@ export function useAnalyticsPage() {
persistSelectedProfile(profile);
}, []);
// Format "Last updated" text
// Compact "Last updated" text (e.g. "1m ago", "2h ago")
const lastUpdatedText = useMemo(() => {
if (!status?.lastFetch) return null;
return formatDistanceToNow(new Date(status.lastFetch), { addSuffix: true });
return formatCompactRelativeTime(new Date(status.lastFetch));
}, [status?.lastFetch]);
// Handle model click for popover