feat(pagespeed): render audit sub-group headers in diagnostics

Group audits within each category by sub-group (e.g., "Names and
Labels", "Contrast") with small uppercase headers, matching the
pagespeed.web.dev layout.
This commit is contained in:
Usman Baig
2026-03-22 22:03:13 +01:00
parent a0173636d4
commit 98429f82f5
2 changed files with 49 additions and 3 deletions

View File

@@ -526,9 +526,7 @@ export default function PageSpeedPage() {
</div>
{groupAudits.length > 0 && (
<div className="divide-y divide-neutral-100 dark:divide-neutral-800">
{groupAudits.map(audit => <AuditRow key={audit.id} audit={audit} />)}
</div>
<AuditsBySubGroup audits={groupAudits} />
)}
{groupPassed.length > 0 && (
@@ -550,6 +548,52 @@ export default function PageSpeedPage() {
)
}
// * Group audits by sub-group within a category (e.g., "Names and Labels", "Contrast")
function AuditsBySubGroup({ audits }: { audits: AuditSummary[] }) {
// * Collect unique sub-groups in order of appearance
const subGroupOrder: string[] = []
const bySubGroup: Record<string, AuditSummary[]> = {}
for (const audit of audits) {
const key = audit.sub_group || '__none__'
if (!bySubGroup[key]) {
bySubGroup[key] = []
subGroupOrder.push(key)
}
bySubGroup[key].push(audit)
}
// * If no sub-groups exist, render flat list
if (subGroupOrder.length === 1 && subGroupOrder[0] === '__none__') {
return (
<div className="divide-y divide-neutral-100 dark:divide-neutral-800">
{audits.map(audit => <AuditRow key={audit.id} audit={audit} />)}
</div>
)
}
return (
<div className="space-y-5">
{subGroupOrder.map(key => {
const items = bySubGroup[key]
const title = items[0]?.sub_group_title
return (
<div key={key}>
{title && (
<h4 className="text-[11px] font-semibold text-neutral-400 dark:text-neutral-500 uppercase tracking-wider mb-2">
{title}
</h4>
)}
<div className="divide-y divide-neutral-100 dark:divide-neutral-800">
{items.map(audit => <AuditRow key={audit.id} audit={audit} />)}
</div>
</div>
)
})}
</div>
)
}
// * Severity indicator based on audit score (pagespeed.web.dev style)
function AuditSeverityIcon({ score }: { score: number | null }) {
if (score === null) {