This commit is contained in:
Nicolas
2025-02-22 17:23:27 +01:00
9 changed files with 199 additions and 47 deletions

View File

@@ -8,6 +8,14 @@ export default async ({ params }: { params: Promise<{ id: string }> }) => {
id: parseInt(id),
},
});
const users = await prisma.user.findMany({
select: {
id: true,
firstname: true,
lastname: true,
publicId: true,
},
});
if (!event) return <div>Event not found</div>;
return <Form event={event} />;
return <Form event={event} users={users} />;
};

View File

@@ -1,12 +1,13 @@
'use client';
import { zodResolver } from '@hookform/resolvers/zod';
import {
EventAppointmentOptionalDefaultsSchema,
EventOptionalDefaults,
EventOptionalDefaultsSchema,
ParticipantOptionalDefaultsSchema,
} from '@repo/db/zod';
import { set, useForm } from 'react-hook-form';
import { BADGES, Event } from '@repo/db';
import { BADGES, Event, User } from '@repo/db';
import { Bot, FileText, UserIcon } from 'lucide-react';
import { Input } from '../../../../_components/ui/Input';
import { useRef, useState } from 'react';
@@ -17,15 +18,26 @@ import { Switch } from '../../../../_components/ui/Switch';
import { PaginatedTable } from '../../../../_components/PaginatedTable';
import { Select } from '../../../../_components/ui/Select';
export const Form = ({ event }: { event?: Event }) => {
export const Form = ({
event,
users,
}: {
event?: Event;
users: {
id: string;
firstname: string;
lastname: string;
publicId: string;
}[];
}) => {
const form = useForm({
resolver: zodResolver(EventOptionalDefaultsSchema),
defaultValues: event,
});
const participantForm = useForm({
resolver: zodResolver(ParticipantOptionalDefaultsSchema),
const appointmentForm = useForm({
resolver: zodResolver(EventAppointmentOptionalDefaultsSchema),
});
console.log(appointmentForm.formState.errors);
const [loading, setLoading] = useState(false);
const [deleteLoading, setDeleteLoading] = useState(false);
const addParticipantModal = useRef<HTMLDialogElement>(null);
@@ -33,13 +45,33 @@ export const Form = ({ event }: { event?: Event }) => {
<>
<dialog ref={addParticipantModal} className="modal">
<div className="modal-box">
<h3 className="font-bold text-lg">Teilnehmer</h3>
<div className="modal-action">
<form method="dialog">
{/* if there is a button in form, it will close the modal */}
<button className="btn">Close</button>
</form>
</div>
<form method="dialog">
{/* if there is a button in form, it will close the modal */}
<button className="btn btn-sm btn-circle btn-ghost absolute right-2 top-2">
</button>
</form>
<h3 className="font-bold text-lg">Teilnehmer hinzufügen</h3>
<form
onSubmit={appointmentForm.handleSubmit(async (values) => {
console.log(values);
})}
>
<Select
form={appointmentForm}
name="userId"
label="Teilnehmer"
options={users.map((user) => ({
label: `${user.firstname} ${user.lastname} (${user.publicId})`,
value: user.id,
}))}
/>
<div className="modal-action">
<Button type="submit" className="btn btn-primary">
Hinzufügen
</Button>
</div>
</form>
</div>
</dialog>
<form
@@ -122,18 +154,18 @@ export const Form = ({ event }: { event?: Event }) => {
<div className="card-body">
<div className="flex justify-between">
<h2 className="card-title">
<UserIcon className="w-5 h-5" /> Teilnehmer
<UserIcon className="w-5 h-5" /> Termine
</h2>
<button
className="btn btn-primary btn-outline"
onClick={() => addParticipantModal.current?.showModal()}
>
Teilnehmer hinzufügen
Hinzufügen
</button>
</div>
<PaginatedTable
prismaModel={'participant'}
prismaModel={'eventAppointment'}
filter={{
eventId: event?.id,
}}
@@ -142,24 +174,7 @@ export const Form = ({ event }: { event?: Event }) => {
user: true,
},
]}
columns={[
{
header: 'Vorname',
accessorKey: 'user.firstName',
},
{
header: 'Nachname',
accessorKey: 'user.lastname',
},
{
header: 'VAR ID',
accessorKey: 'user.publicId',
},
{
header: 'Status',
accessorKey: 'status',
},
]}
columns={[]}
/>
</div>
</div>

View File

@@ -35,7 +35,11 @@ const SelectCom = <T extends FieldValues>({
<SelectTemplate
{...form.register(name, formOptions)}
onChange={(newValue: any) => {
form.setValue(name, newValue);
if ('value' in newValue) {
form.setValue(name, newValue.value);
} else {
form.setValue(name, newValue);
}
form.trigger(name);
}}
className={cn('w-full placeholder:text-neutral-600', className)}

View File

@@ -23,6 +23,7 @@
"next": "15.1.4",
"next-auth": "^4.24.11",
"react": "^19.0.0",
"react-day-picker": "^9.5.1",
"react-dom": "^19.0.0",
"react-hook-form": "^7.54.2",
"react-hot-toast": "^2.5.1",

40
package-lock.json generated
View File

@@ -119,6 +119,7 @@
"next": "15.1.4",
"next-auth": "^4.24.11",
"react": "^19.0.0",
"react-day-picker": "^9.5.1",
"react-dom": "^19.0.0",
"react-hook-form": "^7.54.2",
"react-hot-toast": "^2.5.1",
@@ -335,6 +336,11 @@
"node": ">=12"
}
},
"node_modules/@date-fns/tz": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@date-fns/tz/-/tz-1.2.0.tgz",
"integrity": "sha512-LBrd7MiJZ9McsOgxqWX7AaxrDjcFVjWH/tIKJd7pnR7McaslGYOP1QmmiBXdJH/H/yLCT+rcQ7FaPBUxRGUtrg=="
},
"node_modules/@emnapi/runtime": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz",
@@ -3316,6 +3322,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/date-fns": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-4.1.0.tgz",
"integrity": "sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/date-fns-jalali": {
"version": "4.1.0-0",
"resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz",
"integrity": "sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg=="
},
"node_modules/debug": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
@@ -7896,6 +7916,26 @@
"node": ">=0.10.0"
}
},
"node_modules/react-day-picker": {
"version": "9.5.1",
"resolved": "https://registry.npmjs.org/react-day-picker/-/react-day-picker-9.5.1.tgz",
"integrity": "sha512-PxuK8inYLlYgM2zZUVBPsaBM5jI40suPeG+naKyx7kpyF032RRlEAUEjkpW9/poTASh/vyWAOVqjGuGw+47isw==",
"dependencies": {
"@date-fns/tz": "^1.2.0",
"date-fns": "^4.1.0",
"date-fns-jalali": "^4.1.0-0"
},
"engines": {
"node": ">=18"
},
"funding": {
"type": "individual",
"url": "https://github.com/sponsors/gpbl"
},
"peerDependencies": {
"react": ">=16.8.0"
}
},
"node_modules/react-dom": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.0.0.tgz",

View File

@@ -0,0 +1,57 @@
/*
Warnings:
- You are about to drop the column `selectedForParticipatioon` on the `Participant` table. All the data in the column will be lost.
- You are about to drop the column `status` on the `Participant` table. All the data in the column will be lost.
- Added the required column `eventAppointmentId` to the `Participant` table without a default value. This is not possible if the table is not empty.
*/
-- AlterEnum
-- This migration adds more than one value to an enum.
-- With PostgreSQL versions 11 and earlier, this is not possible
-- in a single migration. This can be worked around by creating
-- multiple migrations, each migration adding only one value to
-- the enum.
ALTER TYPE "PERMISSION" ADD VALUE 'PILOT';
ALTER TYPE "PERMISSION" ADD VALUE 'DISPO';
-- AlterTable
ALTER TABLE "Participant" DROP COLUMN "selectedForParticipatioon",
DROP COLUMN "status",
ADD COLUMN "eventAppointmentId" INTEGER NOT NULL,
ADD COLUMN "finisherMoodleCurseCompleted" BOOLEAN NOT NULL DEFAULT false,
ADD COLUMN "starterMoodleCurseCompleted" BOOLEAN NOT NULL DEFAULT false;
-- CreateTable
CREATE TABLE "EventAppointment" (
"id" SERIAL NOT NULL,
"eventId" INTEGER NOT NULL,
"appointmentDate" TIMESTAMP(3) NOT NULL,
CONSTRAINT "EventAppointment_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "_EventAppointmentToUser" (
"A" INTEGER NOT NULL,
"B" TEXT NOT NULL,
CONSTRAINT "_EventAppointmentToUser_AB_pkey" PRIMARY KEY ("A","B")
);
-- CreateIndex
CREATE INDEX "_EventAppointmentToUser_B_index" ON "_EventAppointmentToUser"("B");
-- AddForeignKey
ALTER TABLE "EventAppointment" ADD CONSTRAINT "EventAppointment_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Participant" ADD CONSTRAINT "Participant_eventAppointmentId_fkey" FOREIGN KEY ("eventAppointmentId") REFERENCES "EventAppointment"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_EventAppointmentToUser" ADD CONSTRAINT "_EventAppointmentToUser_A_fkey" FOREIGN KEY ("A") REFERENCES "EventAppointment"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "_EventAppointmentToUser" ADD CONSTRAINT "_EventAppointmentToUser_B_fkey" FOREIGN KEY ("B") REFERENCES "users"("id") ON DELETE CASCADE ON UPDATE CASCADE;

View File

@@ -0,0 +1,8 @@
-- DropForeignKey
ALTER TABLE "Participant" DROP CONSTRAINT "Participant_eventAppointmentId_fkey";
-- AlterTable
ALTER TABLE "Participant" ALTER COLUMN "eventAppointmentId" DROP NOT NULL;
-- AddForeignKey
ALTER TABLE "Participant" ADD CONSTRAINT "Participant_eventAppointmentId_fkey" FOREIGN KEY ("eventAppointmentId") REFERENCES "EventAppointment"("id") ON DELETE SET NULL ON UPDATE CASCADE;

View File

@@ -10,16 +10,30 @@ enum PARTICIPANT_STATUS {
WAVED
}
model Participant {
id Int @id @default(autoincrement())
userId String @map(name: "user_id")
status PARTICIPANT_STATUS
selectedForParticipatioon Boolean @default(false)
statusLog Json[]
eventId Int
model EventAppointment {
id Int @id @default(autoincrement())
eventId Int
appointmentDate DateTime
presenterId String
// relations:
user User @relation(fields: [userId], references: [id])
Event Event? @relation(fields: [eventId], references: [id])
Users User[] @relation("EventAppointmentUser")
participants Participant[]
Event Event @relation(fields: [eventId], references: [id])
Presenter User @relation(fields: [presenterId], references: [id])
}
model Participant {
id Int @id @default(autoincrement())
userId String @map(name: "user_id")
starterMoodleCurseCompleted Boolean @default(false)
finisherMoodleCurseCompleted Boolean @default(false)
eventAppointmentId Int?
statusLog Json[]
eventId Int
// relations:
User User @relation(fields: [userId], references: [id])
Event Event @relation(fields: [eventId], references: [id])
EventAppointment EventAppointment? @relation(fields: [eventAppointmentId], references: [id])
}
model Event {
@@ -38,6 +52,7 @@ model Event {
// relations:
participants Participant[]
appointments EventAppointment[]
}
model File {

View File

@@ -12,6 +12,8 @@ enum PERMISSION {
ADMIN_EVENT
ADMIN_USER
SUSPENDED
PILOT
DISPO
}
model User {
@@ -30,9 +32,11 @@ model User {
updatedAt DateTime @default(now()) @map(name: "updated_at")
// relations:
oauthTokens OAuthToken[]
discordAccounts DiscordAccount[]
participants Participant[]
oauthTokens OAuthToken[]
discordAccounts DiscordAccount[]
participants Participant[]
EventAppointmentUser EventAppointment[] @relation("EventAppointmentUser")
EventAppointment EventAppointment[]
@@map(name: "users")
}