feat(frontend): collapse Dashboard period switcher to icons on mobile

On screens narrower than the `sm` breakpoint (640 px) the
Week / Month / Quarter triggers were forcing the period switcher to
crowd the Analytics / Overview tabs into the next line. Replaced
the labels with lucide calendar icons (CalendarDays / Calendar /
CalendarRange) that swap in below `sm` while the full text comes
back above it.

Accessibility preserved — each TabsTrigger keeps an explicit
aria-label and the icons are aria-hidden so screen readers still
announce "Week" / "Month" / "Quarter" instead of duplicate icon
descriptions.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergey Kozyrenko
2026-05-19 09:39:23 +07:00
co-authored by Claude Opus 4.7
parent 58d01e0a67
commit e02da42f39
+12 -7
View File
@@ -1,4 +1,4 @@
import { LayoutDashboard } from 'lucide-react';
import { Calendar, CalendarDays, CalendarRange, LayoutDashboard, type LucideIcon } from 'lucide-react';
import { useState, useTransition } from 'react';
import { PageTitle } from '@/components/shared/page-title';
@@ -12,10 +12,10 @@ import { cn } from '@/lib/utils';
import { DashboardAnalytics } from '@/pages/dashboard/dashboard-analytics';
import { DashboardOverview } from '@/pages/dashboard/dashboard-overview';
const periodOptions: { label: string; value: UsageStatsPeriod }[] = [
{ label: 'Week', value: UsageStatsPeriod.Week },
{ label: 'Month', value: UsageStatsPeriod.Month },
{ label: 'Quarter', value: UsageStatsPeriod.Quarter },
const periodOptions: { icon: LucideIcon; label: string; value: UsageStatsPeriod }[] = [
{ icon: CalendarDays, label: 'Week', value: UsageStatsPeriod.Week },
{ icon: Calendar, label: 'Month', value: UsageStatsPeriod.Month },
{ icon: CalendarRange, label: 'Quarter', value: UsageStatsPeriod.Quarter },
];
const VALID_PERIODS = new Set<string>(Object.values(UsageStatsPeriod));
@@ -112,12 +112,17 @@ function Dashboard() {
value={period}
>
<TabsList>
{periodOptions.map(({ label, value }) => (
{periodOptions.map(({ icon: Icon, label, value }) => (
<TabsTrigger
aria-label={label}
key={value}
value={value}
>
{label}
<Icon
aria-hidden="true"
className="size-4 sm:hidden"
/>
<span className="hidden sm:inline">{label}</span>
</TabsTrigger>
))}
</TabsList>