import type { WebVitalsDashboardViewProps } from "./WebVitalsDashboard.types";
const getRatingColor = (rating: string): string => {
switch (rating) {
case "good":
return "text-green-600 bg-green-50";
case "needs-improvement":
return "text-yellow-600 bg-yellow-50";
case "poor":
return "text-red-600 bg-red-50";
default:
return "text-gray-600 bg-gray-50";
}
};
const getRatingIcon = (rating: string): string => {
switch (rating) {
case "good":
return "✅";
case "needs-improvement":
return "⚠️";
case "poor":
return "❌";
default:
return "❓";
}
};
const formatValue = (metric: string, value: number): string => {
if (metric === "cls") {
return value.toFixed(3);
}
return `${value}ms`;
};
function WebVitalsDashboardView({
vitals,
metrics,
loading,
}: WebVitalsDashboardViewProps) {
if (loading) {
return (
{[1, 2, 3, 4, 5].map((i) => (
))}
);
}
return (
Web Vitals Dashboard
{Object.entries(vitals).map(([metric, data]) => (
{metric.toUpperCase()}
{getRatingIcon(data.rating)}
Value: {formatValue(metric, data.value)}
Rating: {data.rating.replace("-", " ")}
))}
{/* Historical Metrics */}
{Object.keys(metrics).length > 0 && (
Historical Metrics
{Object.entries(metrics).map(([metric, data]) => (
{metric.toUpperCase()}
Count: {data.count}
Average: {formatValue(metric, data.average)}
Range: {formatValue(metric, data.min)} -{" "}
{formatValue(metric, data.max)}
Good: {data.goodCount}
Needs Improvement: {data.needsImprovementCount}
Poor: {data.poorCount}
))}
)}
{/* Performance Guidelines */}
Performance Guidelines
-
• LCP: Good < 2.5s, Needs Improvement 2.5-4s,
Poor > 4s
-
• FID: Good < 100ms, Needs Improvement
100-300ms, Poor > 300ms
-
• CLS: Good < 0.1, Needs Improvement 0.1-0.25,
Poor > 0.25
-
• FCP: Good < 1.8s, Needs Improvement 1.8-3s,
Poor > 3s
-
• TTFB: Good < 800ms, Needs Improvement
800-1800ms, Poor > 1800ms
);
}
export default WebVitalsDashboardView;