mirror of
https://github.com/soconnor0919/hristudio.git
synced 2025-12-11 22:54:45 -05:00
create database connection
This commit is contained in:
122
src/components/Studies.tsx
Normal file
122
src/components/Studies.tsx
Normal 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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user