A quick vibe-coded site to test response times of PLC.directory mirrors (over 3 attempts)
1import { BenchmarkResult } from "@/types/benchmark";
2import {
3 Table,
4 TableBody,
5 TableCell,
6 TableHead,
7 TableHeader,
8 TableRow,
9} from "@/components/ui/table";
10import { Badge } from "@/components/ui/badge";
11import { CheckCircle2, XCircle } from "lucide-react";
12
13interface BenchmarkTableProps {
14 results: BenchmarkResult[];
15}
16
17export const BenchmarkTable = ({ results }: BenchmarkTableProps) => {
18 // Sort by average response time (fastest first)
19 const sortedResults = [...results].sort((a, b) => {
20 if (a.status === "error" && b.status === "success") return 1;
21 if (a.status === "success" && b.status === "error") return -1;
22 return a.avgResponseTime - b.avgResponseTime;
23 });
24
25 // Calculate overall average across all successful attempts
26 const allSuccessfulAttempts = sortedResults.flatMap((r) =>
27 r.attempts.filter((a) => a.status === "success")
28 );
29 const overallAvg = allSuccessfulAttempts.length > 0
30 ? allSuccessfulAttempts.reduce((sum, a) => sum + a.responseTime, 0) /
31 allSuccessfulAttempts.length
32 : 0;
33
34 return (
35 <div className="space-y-4">
36 {/* Overall Average */}
37 {overallAvg > 0 && (
38 <div className="bg-primary/5 border border-primary/20 rounded-lg p-4 flex items-center justify-between">
39 <span className="font-semibold text-foreground">
40 Overall Average Response Time
41 </span>
42 <span className="text-2xl font-bold font-mono text-primary">
43 {overallAvg.toFixed(0)}ms
44 </span>
45 </div>
46 )}
47
48 {/* Results Table */}
49 <div className="rounded-lg border border-border bg-card overflow-hidden">
50 <Table>
51 <TableHeader>
52 <TableRow className="bg-muted/50">
53 <TableHead className="font-semibold">URL</TableHead>
54 <TableHead className="font-semibold">Implementation</TableHead>
55 <TableHead className="font-semibold text-center">
56 #1
57 </TableHead>
58 <TableHead className="font-semibold text-center">
59 #2
60 </TableHead>
61 <TableHead className="font-semibold text-center">
62 #3
63 </TableHead>
64 <TableHead className="font-semibold text-center">
65 #4
66 </TableHead>
67 <TableHead className="font-semibold text-center">
68 #5
69 </TableHead>
70 <TableHead className="font-semibold text-center">
71 Average
72 </TableHead>
73 <TableHead className="font-semibold">Status</TableHead>
74 </TableRow>
75 </TableHeader>
76 <TableBody>
77 {sortedResults.map((result, index) => (
78 <TableRow
79 key={index}
80 className="hover:bg-muted/30 transition-colors"
81 >
82 <TableCell className="font-mono text-sm text-muted-foreground">
83 {result.mirrorUrl}
84 </TableCell>
85 <TableCell className="font-medium">
86 {result.implementation}
87 </TableCell>
88 {result.attempts.map((attempt, attemptIndex) => (
89 <TableCell
90 key={attemptIndex}
91 className="text-center font-mono text-sm"
92 >
93 {attempt.status === "success"
94 ? (
95 <span className="text-foreground">
96 {attempt.responseTime.toFixed(0)}ms
97 </span>
98 )
99 : (
100 <span className="text-destructive">
101 <XCircle className="w-4 h-4 inline" />
102 </span>
103 )}
104 </TableCell>
105 ))}
106 <TableCell className="text-center font-mono text-sm">
107 {result.status === "success"
108 ? (
109 <span className="font-bold text-primary text-base">
110 {result.avgResponseTime.toFixed(0)}ms
111 </span>
112 )
113 : <span className="text-muted-foreground">—</span>}
114 </TableCell>
115 <TableCell>
116 {result.status === "success"
117 ? (
118 <Badge
119 variant="outline"
120 className="bg-success/10 text-success border-success/20 gap-1"
121 >
122 <CheckCircle2 className="w-3 h-3" />
123 Success
124 </Badge>
125 )
126 : (
127 <Badge
128 variant="outline"
129 className="bg-destructive/10 text-destructive border-destructive/20 gap-1"
130 >
131 <XCircle className="w-3 h-3" />
132 Error
133 </Badge>
134 )}
135 </TableCell>
136 </TableRow>
137 ))}
138 </TableBody>
139 </Table>
140 {sortedResults.length === 0 && (
141 <div className="text-center py-12 text-muted-foreground">
142 No results yet. Enter a DID and run the benchmark.
143 </div>
144 )}
145 </div>
146 </div>
147 );
148};