PageSpeed monitoring, Polar billing, sidebar polish, frontend consistency audit #68

Merged
uz1mani merged 45 commits from staging into main 2026-03-23 19:07:54 +00:00
5 changed files with 884 additions and 0 deletions
Showing only changes of commit 8649f37bb9 - Show all commits

View File

@@ -228,12 +228,23 @@ export default function PageSpeedPage() {
score: c.performance_score, score: c.performance_score,
})) }))
// * Parse audits into groups // * Parse audits into groups by Lighthouse category
const audits = currentCheck?.audits ?? [] const audits = currentCheck?.audits ?? []
const failingAudits = audits const passed = audits.filter(a => a.category === 'passed')
.filter(a => a.category !== 'passed')
const categoryGroups = [
{ key: 'performance', label: 'Performance' },
{ key: 'accessibility', label: 'Accessibility' },
{ key: 'best-practices', label: 'Best Practices' },
{ key: 'seo', label: 'SEO' },
]
// * Build per-category failing audits, sorted by impact
const auditsByGroup: Record<string, typeof audits> = {}
for (const group of categoryGroups) {
auditsByGroup[group.key] = audits
.filter(a => a.category !== 'passed' && a.group === group.key)
.sort((a, b) => { .sort((a, b) => {
// Opportunities first (sorted by savings_ms desc), then diagnostics
if (a.category === 'opportunity' && b.category !== 'opportunity') return -1 if (a.category === 'opportunity' && b.category !== 'opportunity') return -1
if (a.category !== 'opportunity' && b.category === 'opportunity') return 1 if (a.category !== 'opportunity' && b.category === 'opportunity') return 1
if (a.category === 'opportunity' && b.category === 'opportunity') { if (a.category === 'opportunity' && b.category === 'opportunity') {
@@ -241,7 +252,7 @@ export default function PageSpeedPage() {
} }
return 0 return 0
}) })
const passed = audits.filter(a => a.category === 'passed') }
// * Core Web Vitals metrics // * Core Web Vitals metrics
const metrics = [ const metrics = [
@@ -503,32 +514,39 @@ export default function PageSpeedPage() {
</div> </div>
)} )}
{/* Section 4 — Diagnostics */} {/* Section 4 — Diagnostics by Category */}
{audits.length > 0 && ( {audits.length > 0 && (
<div className="bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl p-6 sm:p-8"> <div className="space-y-6">
{categoryGroups.map(group => {
const groupAudits = auditsByGroup[group.key] ?? []
const groupPassed = passed.filter(a => a.group === group.key)
if (groupAudits.length === 0 && groupPassed.length === 0) return null
return (
<div key={group.key} className="bg-white dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800 rounded-2xl p-6 sm:p-8">
<h3 className="text-xs font-semibold text-neutral-500 dark:text-neutral-400 uppercase tracking-wider mb-4"> <h3 className="text-xs font-semibold text-neutral-500 dark:text-neutral-400 uppercase tracking-wider mb-4">
Diagnostics {group.label}
</h3> </h3>
{/* Failing audits — flat list sorted by impact */} {groupAudits.length > 0 && (
{failingAudits.length > 0 && (
<div className="divide-y divide-neutral-100 dark:divide-neutral-800"> <div className="divide-y divide-neutral-100 dark:divide-neutral-800">
{failingAudits.map(audit => <AuditRow key={audit.id} audit={audit} />)} {groupAudits.map(audit => <AuditRow key={audit.id} audit={audit} />)}
</div> </div>
)} )}
{/* Passed audits — collapsed */} {groupPassed.length > 0 && (
{passed.length > 0 && (
<details className="mt-4"> <details className="mt-4">
<summary className="cursor-pointer text-sm font-medium text-neutral-500 dark:text-neutral-400 select-none hover:text-neutral-700 dark:hover:text-neutral-300 transition-colors"> <summary className="cursor-pointer text-sm font-medium text-neutral-500 dark:text-neutral-400 select-none hover:text-neutral-700 dark:hover:text-neutral-300 transition-colors">
<span className="ml-1">{passed.length} passed audit{passed.length !== 1 ? 's' : ''}</span> <span className="ml-1">{groupPassed.length} passed audit{groupPassed.length !== 1 ? 's' : ''}</span>
</summary> </summary>
<div className="mt-2 divide-y divide-neutral-100 dark:divide-neutral-800"> <div className="mt-2 divide-y divide-neutral-100 dark:divide-neutral-800">
{passed.map(audit => <AuditRow key={audit.id} audit={audit} />)} {groupPassed.map(audit => <AuditRow key={audit.id} audit={audit} />)}
</div> </div>
</details> </details>
)} )}
</div> </div>
)
})}
</div>
)} )}
</div> </div>
) )

View File

@@ -20,6 +20,7 @@ export interface AuditSummary {
display_value?: string display_value?: string
savings_ms?: number savings_ms?: number
category: 'opportunity' | 'diagnostic' | 'passed' category: 'opportunity' | 'diagnostic' | 'passed'
group?: string // "performance", "accessibility", "best-practices", "seo"
details?: AuditDetailItem[] details?: AuditDetailItem[]
} }