38460-vm/frontend/src/components/RecentTrialsTable.tsx
2026-02-16 01:14:10 +00:00

99 lines
4.1 KiB
TypeScript

import React, { useEffect } from 'react'
import { useAppDispatch, useAppSelector } from '../stores/hooks'
import { fetch } from '../stores/trials/trialsSlice'
import BaseButton from './BaseButton'
import BaseButtons from './BaseButtons'
import { mdiEye, mdiPlus } from '@mdi/js'
import Link from 'next/link'
const RecentTrialsTable = () => {
const dispatch = useAppDispatch()
const { trials, loading } = useAppSelector((state) => state.trials)
useEffect(() => {
dispatch(fetch({ query: '?limit=5' }))
}, [dispatch])
const getStatusColor = (status: string) => {
switch (status) {
case 'active':
return 'bg-emerald-100 text-emerald-800 border-emerald-200'
case 'planned':
return 'bg-blue-100 text-blue-800 border-blue-200'
case 'completed':
return 'bg-purple-100 text-purple-800 border-purple-200'
case 'draft':
return 'bg-gray-100 text-gray-800 border-gray-200'
default:
return 'bg-gray-50 text-gray-600 border-gray-200'
}
}
return (
<div className="bg-white border border-gray-200 rounded-xl overflow-hidden shadow-sm">
<div className="px-6 py-4 border-b border-gray-100 flex justify-between items-center bg-gray-50/50">
<h3 className="font-bold text-gray-800">Recent Trials</h3>
<Link href="/trials/trials-list">
<BaseButton label="View All" color="white" small />
</Link>
</div>
<div className="overflow-x-auto">
<table className="w-full text-sm text-left">
<thead className="text-xs text-gray-500 uppercase bg-gray-50/30 border-b border-gray-100">
<tr>
<th className="px-6 py-3 font-semibold">Trial Name</th>
<th className="px-6 py-3 font-semibold text-center">Code</th>
<th className="px-6 py-3 font-semibold text-center">Status</th>
<th className="px-6 py-3 font-semibold text-center">Created</th>
<th className="px-6 py-3"></th>
</tr>
</thead>
<tbody className="divide-y divide-gray-50">
{loading && trials.length === 0 ? (
<tr>
<td colSpan={5} className="px-6 py-10 text-center text-gray-400">
<div className="flex items-center justify-center gap-2">
<div className="w-4 h-4 border-2 border-blue-500 border-t-transparent rounded-full animate-spin" />
Loading trials...
</div>
</td>
</tr>
) : trials.length > 0 ? (
trials.slice(0, 5).map((trial: any) => (
<tr key={trial.id} className="hover:bg-gray-50/80 transition-colors">
<td className="px-6 py-4 font-bold text-gray-900">{trial.name}</td>
<td className="px-6 py-4 text-center font-mono text-gray-500">{trial.code || '-'}</td>
<td className="px-6 py-4 text-center">
<span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-bold border ${getStatusColor(trial.status)}`}>
{trial.status}
</span>
</td>
<td className="px-6 py-4 text-center text-gray-500">
{new Date(trial.createdAt).toLocaleDateString()}
</td>
<td className="px-6 py-4 text-right">
<Link href={`/trials/trials-list`}>
<BaseButton color="info" icon={mdiEye} small rounded-full />
</Link>
</td>
</tr>
))
) : (
<tr>
<td colSpan={5} className="px-6 py-12 text-center">
<p className="text-gray-400 mb-4 italic">No trials found in the system.</p>
<Link href="/trials/trials-list">
<BaseButton label="Create First Trial" icon={mdiPlus} color="info" small />
</Link>
</td>
</tr>
)}
</tbody>
</table>
</div>
</div>
)
}
export default RecentTrialsTable