chore: improve dashboard stat btn ui (#30)

Added a highlight state to the UI of the stat buttons:
<img width="1588" height="876" alt="CleanShot 2026-02-23 at 18 40 38@2x"
src="https://github.com/user-attachments/assets/9ad17c3e-df3b-4cf0-8ba2-cddee6d97dcc"
/>
This commit is contained in:
Maxwell
2026-02-23 18:42:08 -08:00
committed by GitHub
parent a1bcef627b
commit d56a28a7ec
@@ -112,9 +112,10 @@ export function DashboardContent({
<div className="shrink-0 grid grid-cols-2 sm:grid-cols-4 gap-2 sm:gap-3"> <div className="shrink-0 grid grid-cols-2 sm:grid-cols-4 gap-2 sm:gap-3">
<Stat <Stat
icon={<Eye className="w-3.5 h-3.5" />} icon={<Eye className="w-3.5 h-3.5" />}
label="Reviews" label="Needs review"
value={reviewRequests.total_count} value={reviewRequests.total_count}
accent={reviewRequests.total_count > 0} accent={reviewRequests.total_count > 0}
active={activeTab === "reviews"}
onClick={() => handleStatClick("reviews")} onClick={() => handleStatClick("reviews")}
/> />
<Stat <Stat
@@ -124,6 +125,7 @@ export function DashboardContent({
label="Open PRs" label="Open PRs"
value={myOpenPRs.total_count} value={myOpenPRs.total_count}
accent={myOpenPRs.total_count > 0} accent={myOpenPRs.total_count > 0}
active={activeTab === "prs"}
onClick={() => handleStatClick("prs")} onClick={() => handleStatClick("prs")}
/> />
<Stat <Stat
@@ -131,6 +133,7 @@ export function DashboardContent({
label="Assigned Issues" label="Assigned Issues"
value={myIssues.total_count} value={myIssues.total_count}
accent={myIssues.total_count > 0} accent={myIssues.total_count > 0}
active={activeTab === "issues"}
onClick={() => handleStatClick("issues")} onClick={() => handleStatClick("issues")}
/> />
<Stat <Stat
@@ -141,6 +144,7 @@ export function DashboardContent({
(n) => n.unread, (n) => n.unread,
).length ).length
} }
active={activeTab === "notifs"}
onClick={() => handleStatClick("notifs")} onClick={() => handleStatClick("notifs")}
/> />
</div> </div>
@@ -449,6 +453,7 @@ function Stat({
label, label,
value, value,
accent, accent,
active,
onClick, onClick,
href, href,
}: { }: {
@@ -456,6 +461,7 @@ function Stat({
label: string; label: string;
value: number; value: number;
accent?: boolean; accent?: boolean;
active?: boolean;
onClick?: () => void; onClick?: () => void;
href?: string; href?: string;
}) { }) {
@@ -476,7 +482,14 @@ function Stat({
> >
{icon} {icon}
</span> </span>
<span className="text-[10px] font-mono uppercase tracking-wider text-muted-foreground/60"> <span
className={cn(
"text-[10px] font-mono uppercase tracking-wider",
active
? "text-foreground"
: "text-muted-foreground/60",
)}
>
{label} {label}
</span> </span>
</div> </div>
@@ -501,12 +514,12 @@ function Stat({
const className = cn( const className = cn(
"stat-card relative overflow-hidden rounded-lg px-3 py-3 text-left w-full", "stat-card relative overflow-hidden rounded-lg px-3 py-3 text-left w-full",
"border border-black/[0.04] dark:border-white/[0.06]",
"bg-gradient-to-br from-black/[0.02] via-black/[0.01] to-transparent dark:from-white/[0.04] dark:via-white/[0.02] dark:to-transparent", "bg-gradient-to-br from-black/[0.02] via-black/[0.01] to-transparent dark:from-white/[0.04] dark:via-white/[0.02] dark:to-transparent",
"transition-all duration-150 cursor-pointer", "transition-all duration-150 cursor-pointer",
"hover:border-black/[0.08] dark:hover:border-white/[0.12]", "hover:border-black/[0.08] dark:hover:border-white/[0.12]",
"hover:bg-gradient-to-br hover:from-black/[0.04] hover:via-black/[0.02] dark:hover:from-white/[0.06] dark:hover:via-white/[0.03]", "hover:bg-gradient-to-br hover:from-black/[0.04] hover:via-black/[0.02] dark:hover:from-white/[0.06] dark:hover:via-white/[0.03]",
"dark:active:from-white/[0.03] dark:active:via-white/[0.02] transition-all duration-150", "dark:active:from-white/[0.03] dark:active:via-white/[0.02]",
active ? "border border-primary/20!" : "border border-border/50!",
); );
if (href) { if (href) {
@@ -524,34 +537,6 @@ function Stat({
); );
} }
/* ── Panel ─────────────────────────────────────────────────────────── */
function Panel({
title,
count,
children,
}: {
title: string;
count?: number;
children: React.ReactNode;
}) {
return (
<section className="border border-border">
<div className="flex items-center gap-2 px-4 py-2 border-b border-border">
<h2 className="text-[11px] font-mono uppercase tracking-wider text-muted-foreground">
{title}
</h2>
{count !== undefined && (
<span className="text-[10px] font-mono text-muted-foreground/50 tabular-nums ml-auto">
{count}
</span>
)}
</div>
<div>{children}</div>
</section>
);
}
function ItemRow({ item, type }: { item: IssueItem; type: "pr" | "issue" }) { function ItemRow({ item, type }: { item: IssueItem; type: "pr" | "issue" }) {
const repo = extractRepoName(item.repository_url); const repo = extractRepoName(item.repository_url);
const isMerged = type === "pr" && item.pull_request?.merged_at; const isMerged = type === "pr" && item.pull_request?.merged_at;