mirror of
https://github.com/soconnor0919/hristudio.git
synced 2026-03-24 03:37:51 -04:00
feat: Introduce dedicated participant, experiment, and trial detail/edit pages, enable MinIO, and refactor dashboard navigation.
This commit is contained in:
@@ -0,0 +1,109 @@
|
||||
import { notFound } from "next/navigation";
|
||||
import { api } from "~/trpc/server";
|
||||
import {
|
||||
EntityView,
|
||||
EntityViewHeader,
|
||||
EntityViewSection,
|
||||
} from "~/components/ui/entity-view";
|
||||
import { ParticipantDocuments } from "./participant-documents";
|
||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "~/components/ui/card";
|
||||
import { Badge } from "~/components/ui/badge";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "~/components/ui/tabs";
|
||||
import { Button } from "~/components/ui/button";
|
||||
import { Edit } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
interface ParticipantDetailPageProps {
|
||||
params: Promise<{ id: string; participantId: string }>;
|
||||
}
|
||||
|
||||
export default async function ParticipantDetailPage({
|
||||
params,
|
||||
}: ParticipantDetailPageProps) {
|
||||
const { id: studyId, participantId } = await params;
|
||||
|
||||
const participant = await api.participants.get({ id: participantId });
|
||||
|
||||
if (!participant) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
// Ensure participant belongs to study
|
||||
if (participant.studyId !== studyId) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return (
|
||||
<EntityView>
|
||||
<EntityViewHeader
|
||||
title={participant.participantCode}
|
||||
subtitle={participant.name ?? "Unnamed Participant"}
|
||||
icon="Users"
|
||||
badge={
|
||||
<Badge variant={participant.consentGiven ? "default" : "secondary"}>
|
||||
{participant.consentGiven ? "Consent Given" : "No Consent"}
|
||||
</Badge>
|
||||
}
|
||||
actions={
|
||||
<Button asChild variant="outline" size="sm">
|
||||
<Link href={`/studies/${studyId}/participants/${participantId}/edit`}>
|
||||
<Edit className="mr-2 h-4 w-4" />
|
||||
Edit Participant
|
||||
</Link>
|
||||
</Button>
|
||||
}
|
||||
/>
|
||||
|
||||
<Tabs defaultValue="overview" className="w-full">
|
||||
<TabsList className="mb-4">
|
||||
<TabsTrigger value="overview">Overview</TabsTrigger>
|
||||
<TabsTrigger value="files">Files & Documents</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="overview">
|
||||
<div className="grid gap-6 grid-cols-1">
|
||||
<EntityViewSection title="Participant Information" icon="Info">
|
||||
<div className="grid grid-cols-2 gap-4 text-sm md:grid-cols-4">
|
||||
<div>
|
||||
<span className="text-muted-foreground block mb-1">Code</span>
|
||||
<span className="font-medium text-base">{participant.participantCode}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="text-muted-foreground block mb-1">Name</span>
|
||||
<span className="font-medium text-base">{participant.name || "-"}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="text-muted-foreground block mb-1">Email</span>
|
||||
<span className="font-medium text-base">{participant.email || "-"}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="text-muted-foreground block mb-1">Added</span>
|
||||
<span className="font-medium text-base">{new Date(participant.createdAt).toLocaleDateString()}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="text-muted-foreground block mb-1">Age</span>
|
||||
<span className="font-medium text-base">{(participant.demographics as any)?.age || "-"}</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span className="text-muted-foreground block mb-1">Gender</span>
|
||||
<span className="font-medium capitalize text-base">{(participant.demographics as any)?.gender?.replace("_", " ") || "-"}</span>
|
||||
</div>
|
||||
</div>
|
||||
</EntityViewSection>
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="files">
|
||||
<EntityViewSection title="Documents" icon="FileText">
|
||||
<ParticipantDocuments participantId={participantId} />
|
||||
</EntityViewSection>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</EntityView>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user