Skip to content

Commit f8fab87

Browse files
committed
fix(glook-23): PR review — useMemo, reduce, composite key, totalVol guard, a11y, SEGMENT_COLORS
1 parent 8e0255f commit f8fab87

1 file changed

Lines changed: 38 additions & 18 deletions

File tree

src/components/ProjectsCard.tsx

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
'use client';
2+
import { useMemo } from 'react';
23
import type { TeamProject } from '@/lib/team-pulse/types';
34

5+
// Segment colors used in both the legend swatches and the bar segments.
6+
const SEGMENT_COLORS = {
7+
prs: '#06B6D4',
8+
jiras: '#A855F7',
9+
commits: 'rgba(255,255,255,0.10)',
10+
} as const;
11+
412
/** Older shape used by the home-page LLM project insights — superset of TeamProject.
513
* Allows the same component to serve both surfaces without a refactor of the home payload. */
614
export interface ProjectsCardItem {
@@ -70,35 +78,40 @@ function ProjectsBody({
7078
return <p className={`text-sm text-gray-500 ${variant === 'collapsible' ? 'py-4' : 'mt-2'}`}>{emptyMessage}</p>;
7179
}
7280

73-
// Sort by meaningful output (PRs + Jiras). Commits are squashed into PRs so
74-
// using raw commit count would inflate commit-heavy, low-PR projects.
75-
const sorted = [...projects].sort(
76-
(a, b) => (b.estimated_prs + b.jira_count) - (a.estimated_prs + a.jira_count),
81+
// Sort by meaningful output (PRs + Jiras). Commits excluded from sort key
82+
// because they are squashed into PRs — including them would inflate rank for
83+
// commit-heavy, low-PR projects. Commits are still shown in the bar for context.
84+
const sorted = useMemo(
85+
() => [...projects].sort((a, b) => (b.estimated_prs + b.jira_count) - (a.estimated_prs + a.jira_count)),
86+
[projects],
7787
);
7888

79-
// Max total volume across all projects — used to normalise bar widths.
80-
const maxVolume = Math.max(
81-
...sorted.map(p => p.estimated_prs + p.jira_count + p.estimated_commits),
82-
1,
89+
// Bar width = total volume (PRs + Jiras + Commits) / max across all projects.
90+
// Commits are intentionally included here even though they are excluded from the
91+
// sort key — the bar shows the full activity footprint of each project (sort rank
92+
// reflects quality output, bar width reflects overall size).
93+
const maxVolume = useMemo(
94+
() => sorted.reduce((max, p) => Math.max(max, p.estimated_prs + p.jira_count + p.estimated_commits), 1),
95+
[sorted],
8396
);
8497

8598
// Hide Jira legend entry when Jira is disabled (all counts are 0).
86-
const hasJira = sorted.some(p => p.jira_count > 0);
99+
const hasJira = useMemo(() => sorted.some(p => p.jira_count > 0), [sorted]);
87100

88101
return (
89102
<div className={`space-y-3 ${variant === 'collapsible' ? 'mt-3' : 'mt-4'}`}>
90103
{/* Legend */}
91104
<div className="flex gap-3 text-[10px] text-gray-600 pl-6">
92105
<span className="flex items-center gap-1">
93-
<span className="inline-block w-2 h-2 rounded-[2px]" style={{ background: '#06B6D4' }} />PRs
106+
<span aria-hidden="true" className="inline-block w-2 h-2 rounded-[2px]" style={{ background: SEGMENT_COLORS.prs }} />PRs
94107
</span>
95108
{hasJira && (
96109
<span className="flex items-center gap-1">
97-
<span className="inline-block w-2 h-2 rounded-[2px]" style={{ background: '#A855F7' }} />Jiras
110+
<span aria-hidden="true" className="inline-block w-2 h-2 rounded-[2px]" style={{ background: SEGMENT_COLORS.jiras }} />Jiras
98111
</span>
99112
)}
100113
<span className="flex items-center gap-1">
101-
<span className="inline-block w-2 h-2 rounded-[2px]" style={{ background: 'rgba(255,255,255,0.18)' }} />Commits
114+
<span aria-hidden="true" className="inline-block w-2 h-2 rounded-[2px]" style={{ background: 'rgba(255,255,255,0.18)' }} />Commits
102115
</span>
103116
</div>
104117

@@ -107,7 +120,7 @@ function ProjectsBody({
107120
const totalVol = p.estimated_prs + p.jira_count + p.estimated_commits;
108121
const barPct = (totalVol / maxVolume) * 100;
109122
return (
110-
<div key={p.name} className="bg-white/[0.02] rounded-lg p-3">
123+
<div key={`${p.name}-${i}`} className="bg-white/[0.02] rounded-lg p-3">
111124
<div className="flex items-start justify-between gap-3 mb-1">
112125
<div className="flex items-center gap-2 min-w-0">
113126
<span className="text-xs text-gray-600 w-4 shrink-0 text-right">{i + 1}</span>
@@ -121,16 +134,23 @@ function ProjectsBody({
121134
</div>
122135
</div>
123136

124-
{/* Volume bar: width = total / max, segments = PRs (cyan) + Jiras (purple) + Commits (ghost) */}
137+
{/* Volume bar: width = total / max, segments = PRs + Jiras + Commits (ghost) */}
138+
{totalVol > 0 && (
125139
<div className="pl-6 mb-1.5">
126-
<div className="h-[5px] rounded-sm overflow-hidden" style={{ background: 'rgba(255,255,255,0.05)' }}>
140+
<div
141+
className="h-[5px] rounded-sm overflow-hidden"
142+
style={{ background: 'rgba(255,255,255,0.05)' }}
143+
role="img"
144+
aria-label={`Volume: ${p.estimated_prs} PRs, ${p.jira_count} Jiras, ${p.estimated_commits} commits`}
145+
>
127146
<div className="h-full flex" style={{ width: `${barPct}%` }}>
128-
<div style={{ flex: p.estimated_prs, background: '#06B6D4' }} />
129-
<div style={{ flex: p.jira_count, background: '#A855F7' }} />
130-
<div style={{ flex: p.estimated_commits, background: 'rgba(255,255,255,0.10)' }} />
147+
<div style={{ flex: p.estimated_prs, background: SEGMENT_COLORS.prs }} />
148+
<div style={{ flex: p.jira_count, background: SEGMENT_COLORS.jiras }} />
149+
<div style={{ flex: p.estimated_commits, background: SEGMENT_COLORS.commits }} />
131150
</div>
132151
</div>
133152
</div>
153+
)}
134154

135155
<p className="text-xs text-gray-500 pl-6 mb-1.5">{p.summary}</p>
136156
<div className="flex gap-1 pl-6 flex-wrap">

0 commit comments

Comments
 (0)