create database connection

This commit is contained in:
2024-09-18 18:38:35 -04:00
parent dab127aed7
commit 0e019e3c30
15 changed files with 557 additions and 607 deletions

122
src/components/Studies.tsx Normal file
View File

@@ -0,0 +1,122 @@
"use client";
import React, { useState, useEffect } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from "~/components/ui/card";
import { Button } from "~/components/ui/button";
import { Input } from "~/components/ui/input";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "~/components/ui/dialog";
interface Study {
id: number;
title: string;
description: string;
}
export function Studies() {
const [studies, setStudies] = useState<Study[]>([]);
const [newStudy, setNewStudy] = useState({ title: '', description: '' });
const [editingStudy, setEditingStudy] = useState<Study | null>(null);
useEffect(() => {
fetchStudies();
}, []);
const fetchStudies = async () => {
const response = await fetch('/api/studies');
const data = await response.json();
setStudies(data);
};
const createStudy = async () => {
const response = await fetch('/api/studies', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newStudy),
});
const createdStudy = await response.json();
setStudies([...studies, createdStudy]);
setNewStudy({ title: '', description: '' });
};
const updateStudy = async () => {
if (!editingStudy) return;
const response = await fetch('/api/studies', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(editingStudy),
});
const updatedStudy = await response.json();
setStudies(studies.map(s => s.id === updatedStudy.id ? updatedStudy : s));
setEditingStudy(null);
};
const deleteStudy = async (id: number) => {
await fetch('/api/studies', {
method: 'DELETE',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ id }),
});
setStudies(studies.filter(s => s.id !== id));
};
return (
<div className="space-y-4">
<h2 className="text-2xl font-bold">Studies</h2>
<Dialog>
<DialogTrigger asChild>
<Button>Create New Study</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Create New Study</DialogTitle>
</DialogHeader>
<Input
placeholder="Title"
value={newStudy.title}
onChange={(e) => setNewStudy({ ...newStudy, title: e.target.value })}
/>
<Input
placeholder="Description"
value={newStudy.description}
onChange={(e) => setNewStudy({ ...newStudy, description: e.target.value })}
/>
<Button onClick={createStudy}>Create</Button>
</DialogContent>
</Dialog>
{studies.map((study) => (
<Card key={study.id}>
<CardHeader>
<CardTitle>{study.title}</CardTitle>
</CardHeader>
<CardContent>
<p>{study.description}</p>
<div className="flex space-x-2 mt-2">
<Dialog>
<DialogTrigger asChild>
<Button variant="outline" onClick={() => setEditingStudy(study)}>Edit</Button>
</DialogTrigger>
<DialogContent>
<DialogHeader>
<DialogTitle>Edit Study</DialogTitle>
</DialogHeader>
<Input
placeholder="Title"
value={editingStudy?.title || ''}
onChange={(e) => setEditingStudy({ ...editingStudy!, title: e.target.value })}
/>
<Input
placeholder="Description"
value={editingStudy?.description || ''}
onChange={(e) => setEditingStudy({ ...editingStudy!, description: e.target.value })}
/>
<Button onClick={updateStudy}>Update</Button>
</DialogContent>
</Dialog>
<Button variant="destructive" onClick={() => deleteStudy(study.id)}>Delete</Button>
</div>
</CardContent>
</Card>
))}
</div>
);
}

View File

@@ -61,8 +61,8 @@ export function Sidebar() {
<div className="flex items-center space-x-4">
<UserButton />
<div>
<p className="text-sm font-medium text-blue-800">{user?.fullName || 'User'}</p>
<p className="text-xs text-blue-600">{user?.primaryEmailAddress?.emailAddress || 'user@example.com'}</p>
<p className="text-sm font-medium text-blue-800">{user?.fullName ?? 'User'}</p>
<p className="text-xs text-blue-600">{user?.primaryEmailAddress?.emailAddress ?? 'user@example.com'}</p>
</div>
</div>
</div>

View File

@@ -2,10 +2,8 @@ import * as React from "react"
import { cn } from "~/lib/utils"
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(
// Use React.InputHTMLAttributes<HTMLInputElement> directly in the component
const Input = React.forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(
({ className, type, ...props }, ref) => {
return (
<input