Update participants page UI

This commit is contained in:
2024-11-20 22:50:17 -05:00
parent e5d32830e7
commit 0d2b18217d
2 changed files with 96 additions and 36 deletions

View File

@@ -4,15 +4,15 @@ import { auth } from "@clerk/nextjs/server";
import { db } from "~/db"; import { db } from "~/db";
import { participants } from "~/db/schema"; import { participants } from "~/db/schema";
export async function DELETE(request: Request, { params }: { params: { id: string } }) {
export async function DELETE(request: Request, { params }: any) {
const { userId } = await auth(); const { userId } = await auth();
if (!userId) { if (!userId) {
return new NextResponse("Unauthorized", { status: 401 }); return new NextResponse("Unauthorized", { status: 401 });
} }
const { id } = await params; const participantId = parseInt(params.id);
const participantId = parseInt(id);
try { try {
const result = await db const result = await db

View File

@@ -1,18 +1,24 @@
'use client'; 'use client';
import { PlusIcon, Trash2Icon } from "lucide-react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Button } from "~/components/ui/button"; import { Button } from "~/components/ui/button";
import { Card, CardHeader, CardTitle, CardContent } from "~/components/ui/card"; import {
Card,
CardContent,
CardHeader,
CardTitle,
CardDescription,
CardFooter
} from "~/components/ui/card";
import { Input } from "~/components/ui/input"; import { Input } from "~/components/ui/input";
import { Label } from "~/components/ui/label"; import { Label } from "~/components/ui/label";
import { PlusIcon, Trash2Icon } from "lucide-react";
import { import {
Select, Select,
SelectTrigger,
SelectValue,
SelectContent, SelectContent,
SelectItem, SelectItem,
SelectLabel, SelectTrigger,
SelectValue
} from "~/components/ui/select"; } from "~/components/ui/select";
interface Study { interface Study {
@@ -51,7 +57,13 @@ export default function Participants() {
const fetchParticipants = async (studyId: number) => { const fetchParticipants = async (studyId: number) => {
try { try {
console.log(`Fetching participants for studyId: ${studyId}`);
const response = await fetch(`/api/participants?studyId=${studyId}`); const response = await fetch(`/api/participants?studyId=${studyId}`);
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json(); const data = await response.json();
setParticipants(data); setParticipants(data);
} catch (error) { } catch (error) {
@@ -115,8 +127,19 @@ export default function Participants() {
return ( return (
<div className="max-w-4xl mx-auto"> <div className="max-w-4xl mx-auto">
<h1 className="text-3xl font-bold mb-4">Manage Participants</h1> <div className="flex justify-between items-center mb-8">
<div className="mb-4"> <h1 className="text-3xl font-bold">Participants</h1>
</div>
<Card className="mb-8">
<CardHeader>
<CardTitle>Study Selection</CardTitle>
<CardDescription>
Select a study to manage its participants
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-2">
<Label htmlFor="study">Select Study</Label> <Label htmlFor="study">Select Study</Label>
<Select onValueChange={handleStudyChange}> <Select onValueChange={handleStudyChange}>
<SelectTrigger> <SelectTrigger>
@@ -131,10 +154,15 @@ export default function Participants() {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
</CardContent>
</Card>
<Card> <Card className="mb-8">
<CardHeader> <CardHeader>
<CardTitle>Add New Participant</CardTitle> <CardTitle>Add New Participant</CardTitle>
<CardDescription>
Add a new participant to the selected study
</CardDescription>
</CardHeader> </CardHeader>
<CardContent> <CardContent>
<form onSubmit={addParticipant} className="space-y-4"> <form onSubmit={addParticipant} className="space-y-4">
@@ -156,18 +184,50 @@ export default function Participants() {
</CardContent> </CardContent>
</Card> </Card>
<div className="mt-4"> <div className="grid gap-4">
<h2 className="text-xl font-semibold">Participant List</h2>
<ul>
{participants.map((participant) => ( {participants.map((participant) => (
<li key={participant.id} className="flex justify-between items-center"> <Card key={participant.id}>
<span>{participant.name}</span> <CardHeader>
<Button onClick={() => deleteParticipant(participant.id)} variant="destructive"> <div className="flex justify-between items-start">
<div>
<CardTitle>{participant.name}</CardTitle>
<CardDescription className="mt-1.5">
Participant ID: {participant.id}
</CardDescription>
</div>
<Button
variant="ghost"
size="icon"
className="text-destructive"
onClick={() => deleteParticipant(participant.id)}
>
<Trash2Icon className="w-4 h-4" /> <Trash2Icon className="w-4 h-4" />
</Button> </Button>
</li> </div>
</CardHeader>
<CardFooter className="text-sm text-muted-foreground">
Study ID: {participant.studyId}
</CardFooter>
</Card>
))} ))}
</ul> {participants.length === 0 && selectedStudyId && (
<Card>
<CardContent className="py-8">
<p className="text-center text-muted-foreground">
No participants found for this study. Add one above to get started.
</p>
</CardContent>
</Card>
)}
{!selectedStudyId && (
<Card>
<CardContent className="py-8">
<p className="text-center text-muted-foreground">
Please select a study to view its participants.
</p>
</CardContent>
</Card>
)}
</div> </div>
</div> </div>
); );