TS-Arena / src /components /ModelActiveRounds.tsx
mmcux's picture
responsive container padding; stop hiding horizontal overflow
f26d4d4
Raw
History Blame Contribute Delete
4.41 kB
'use client';
import Link from 'next/link';
import type { ModelActiveRound } from '@/src/services/modelService';
interface ModelActiveRoundsProps {
rounds: ModelActiveRound[];
}
function statusBadgeClasses(status: string): string {
switch (status) {
case 'registration':
return 'bg-yellow-100 text-yellow-800';
case 'active':
return 'bg-green-100 text-green-800';
default:
return 'bg-gray-100 text-gray-800';
}
}
function formatDateTime(value: string | null): string {
if (!value) return '–';
try {
return new Date(value).toLocaleDateString('en-US', {
year: 'numeric',
month: 'short',
day: 'numeric',
hour: '2-digit',
minute: '2-digit',
timeZoneName: 'short',
});
} catch {
return value;
}
}
export default function ModelActiveRounds({ rounds }: ModelActiveRoundsProps) {
if (!rounds || rounds.length === 0) {
return null;
}
return (
<div className="bg-white border border-gray-200 rounded-lg shadow-sm overflow-hidden mb-6">
<div className="px-4 sm:px-6 py-5 border-b border-gray-200 bg-gray-50">
<div className="flex items-center justify-between">
<div>
<h2 className="text-xl font-bold text-gray-900">Active Challenge Rounds</h2>
<p className="mt-1 text-sm text-gray-500">
Rounds this model is registered for that are currently in registration or active state.
</p>
</div>
<span className="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
{rounds.length} {rounds.length === 1 ? 'round' : 'rounds'}
</span>
</div>
</div>
<div className="overflow-x-auto">
<table className="min-w-full divide-y divide-gray-200">
<thead className="bg-gray-50">
<tr>
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Round
</th>
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Challenge
</th>
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Status
</th>
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Submission Deadline
</th>
<th scope="col" className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
Round End
</th>
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
{rounds.map((r) => (
<tr key={`active-round-${r.round_id}`} className="hover:bg-gray-50">
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium">
{r.definition_id ? (
<Link
href={`/challenges/${r.definition_id}/${r.round_id}`}
className="text-blue-600 hover:text-blue-800 hover:underline"
>
{r.round_name}
</Link>
) : (
<span className="text-gray-900">{r.round_name}</span>
)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{r.definition_name || '–'}
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span
className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium ${statusBadgeClasses(
r.status
)}`}
>
{r.status}
</span>
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{formatDateTime(r.registration_end)}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900">
{formatDateTime(r.end_time)}
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
);
}