import { ChevronDown, Download, ExternalLink } from "lucide-react";
import {
extractPathname,
HttpStatusBadge,
LighthouseScoreBadge,
} from "@/client/features/audit/shared";
import type { AuditResultsData } from "@/client/features/audit/results/types";
type LighthouseFailureFields = {
errorMessage: string | null;
performanceScore: number | null;
accessibilityScore: number | null;
bestPracticesScore: number | null;
seoScore: number | null;
};
function hasMissingLighthouseScores(row: LighthouseFailureFields) {
return (
row.performanceScore == null &&
row.accessibilityScore == null &&
row.bestPracticesScore == null &&
row.seoScore == null
);
}
export function isLighthouseFailure(row: LighthouseFailureFields) {
return !!row.errorMessage || hasMissingLighthouseScores(row);
}
function getLighthouseFailureMessage(row: LighthouseFailureFields) {
return row.errorMessage ?? "Lighthouse returned no category scores";
}
export function PagesTable({ pages }: { pages: AuditResultsData["pages"] }) {
return (
| URL |
Status |
Title |
H1 |
Words |
Images |
Speed |
{pages.map((page: AuditResultsData["pages"][number]) => (
|
{extractPathname(page.url)}
|
|
{page.title || (
missing
)}
|
{page.h1Count} |
{page.wordCount} |
{page.imagesMissingAlt > 0 ? (
{page.imagesMissingAlt}/{page.imagesTotal}
) : (
page.imagesTotal
)}
|
{page.responseTimeMs ? `${page.responseTimeMs}ms` : "-"}
|
))}
);
}
export function PerformanceTable({
auditId,
projectId,
lighthouse,
pages,
}: {
auditId: string;
projectId: string;
lighthouse: AuditResultsData["lighthouse"];
pages: AuditResultsData["pages"];
}) {
return (
| URL |
Device |
Status |
Perf |
A11y |
SEO |
LCP |
CLS |
INP |
TTFB |
Issues |
{lighthouse.map((result: AuditResultsData["lighthouse"][number]) => (
candidate.id === result.pageId,
)}
/>
))}
);
}
function PerformanceRow({
auditId,
projectId,
result,
page,
}: {
auditId: string;
projectId: string;
result: AuditResultsData["lighthouse"][number];
page: AuditResultsData["pages"][number] | undefined;
}) {
const isFailed = isLighthouseFailure(result);
const failureMessage = getLighthouseFailureMessage(result);
return (
|
{page ? extractPathname(page.url) : "-"}
|
{result.strategy} |
{isFailed ? (
failed
) : (
ok
)}
|
|
|
|
{result.lcpMs ? `${(result.lcpMs / 1000).toFixed(1)}s` : "-"}
|
{result.cls != null ? result.cls.toFixed(3) : "-"}
|
{result.inpMs ? `${Math.round(result.inpMs)}ms` : "-"}
|
{result.ttfbMs ? `${Math.round(result.ttfbMs)}ms` : "-"}
|
{result.r2Key && !isFailed ? (
View issues
) : (
-
)}
|
);
}
export function ExportDropdown({
onExport,
}: {
onExport: (format: "csv" | "json") => void;
}) {
return (
Export
-
-
);
}