Events & Kurse User Page
This commit is contained in:
93
apps/hub/app/(app)/events/_components/item.tsx
Normal file
93
apps/hub/app/(app)/events/_components/item.tsx
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
"use client";
|
||||||
|
import { DrawingPinFilledIcon, EnterIcon } from "@radix-ui/react-icons";
|
||||||
|
import { User } from "@repo/db";
|
||||||
|
import ModalBtn from "./modalBtn";
|
||||||
|
|
||||||
|
export const KursItem = ({
|
||||||
|
user,
|
||||||
|
title,
|
||||||
|
type,
|
||||||
|
beschreibung,
|
||||||
|
badge,
|
||||||
|
moodleReq,
|
||||||
|
}: {
|
||||||
|
user: User;
|
||||||
|
title: string;
|
||||||
|
type: string;
|
||||||
|
beschreibung: string;
|
||||||
|
badge: string;
|
||||||
|
moodleReq: boolean;
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<div className="col-span-full">
|
||||||
|
<div className="card bg-base-200 shadow-xl mb-4">
|
||||||
|
<div className="card-body">
|
||||||
|
<h2 className="card-title">{title}</h2>
|
||||||
|
<div className="absolute top-0 right-0 m-4">
|
||||||
|
<span className="badge badge-info badge-outline">
|
||||||
|
Zusatzqualifikation
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-6 gap-4">
|
||||||
|
<div className="col-span-4">
|
||||||
|
<p className="text-left text-balance">{beschreibung}</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-2">{badge}</div>
|
||||||
|
</div>
|
||||||
|
<div className="card-actions flex justify-between items-center mt-5">
|
||||||
|
<p className="text-gray-600 text-left flex items-center gap-2">
|
||||||
|
<DrawingPinFilledIcon /> <b>Teilnahmevoraussetzungen:</b>
|
||||||
|
<a className="link link-info" href="">
|
||||||
|
Moodle Kurs /MOODLEKURSTITLE\
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<ModalBtn
|
||||||
|
title={title}
|
||||||
|
dates={["Dienstag, 25 Februar 2025", "Mittwoch, 26 Februar 2025"]}
|
||||||
|
modalId={title + "_modal" + Math.random()}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const PilotKurs = ({ user }: { user: User }) => {
|
||||||
|
{
|
||||||
|
/* STATISCH, DA FÜR ALLE NEUEN MITGLIEDER MANDATORY, WIRD AUSGEBLENDET WENN ABSOLVIERT */
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div className="col-span-full">
|
||||||
|
<div className="card card-bordered border-secondary bg-base-200 shadow-xl mb-4">
|
||||||
|
<div className="card-body">
|
||||||
|
<h2 className="card-title">Einsteigerkurs für Piloten</h2>
|
||||||
|
<div className="absolute top-0 right-0 m-4">
|
||||||
|
<span className="badge badge-secondary badge-outline">
|
||||||
|
Verpflichtend
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-6 gap-4">
|
||||||
|
<div className="col-span-4">
|
||||||
|
<p className="text-left text-balance">
|
||||||
|
In diesem Kurs lernen Piloten die Grundlagen der Luftrettung,
|
||||||
|
Einsatzverfahren, den Umgang mit dem BOS-Funk und einige
|
||||||
|
medizinische Basics. Der Kurs bietet eine ideale Vorbereitung
|
||||||
|
für alle Standard Operations bei Virtual Air Rescue.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-2">Badge</div>
|
||||||
|
</div>
|
||||||
|
<div className="card-actions flex justify-between items-center mt-5">
|
||||||
|
<p className="text-gray-600 text-left flex items-center gap-2">
|
||||||
|
<DrawingPinFilledIcon /> <b>Teilnahmevoraussetzungen:</b> Keine
|
||||||
|
</p>
|
||||||
|
<button className="btn btn-outline btn-secondary btn-wide">
|
||||||
|
<EnterIcon /> Zum Moodle Kurs
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
87
apps/hub/app/(app)/events/_components/modalBtn.tsx
Normal file
87
apps/hub/app/(app)/events/_components/modalBtn.tsx
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
"use client";
|
||||||
|
import { useEffect } from "react";
|
||||||
|
import {
|
||||||
|
CheckCircledIcon,
|
||||||
|
CalendarIcon,
|
||||||
|
EnterIcon,
|
||||||
|
} from "@radix-ui/react-icons";
|
||||||
|
|
||||||
|
interface ModalBtnProps {
|
||||||
|
title: string;
|
||||||
|
dates: string[];
|
||||||
|
modalId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ModalBtn = ({ title, dates, modalId }: ModalBtnProps) => {
|
||||||
|
useEffect(() => {
|
||||||
|
const modal = document.getElementById(modalId) as HTMLDialogElement;
|
||||||
|
const handleOpen = () => {
|
||||||
|
document.body.classList.add("modal-open");
|
||||||
|
};
|
||||||
|
const handleClose = () => {
|
||||||
|
document.body.classList.remove("modal-open");
|
||||||
|
};
|
||||||
|
modal?.addEventListener("show", handleOpen);
|
||||||
|
modal?.addEventListener("close", handleClose);
|
||||||
|
return () => {
|
||||||
|
modal?.removeEventListener("show", handleOpen);
|
||||||
|
modal?.removeEventListener("close", handleClose);
|
||||||
|
};
|
||||||
|
}, [modalId]);
|
||||||
|
|
||||||
|
const openModal = () => {
|
||||||
|
const modal = document.getElementById(modalId) as HTMLDialogElement;
|
||||||
|
document.body.classList.add("modal-open");
|
||||||
|
modal?.showModal();
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeModal = () => {
|
||||||
|
const modal = document.getElementById(modalId) as HTMLDialogElement;
|
||||||
|
document.body.classList.remove("modal-open");
|
||||||
|
modal?.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button className="btn btn-outline btn-info btn-wide" onClick={openModal}>
|
||||||
|
<EnterIcon /> Anmelden
|
||||||
|
</button>
|
||||||
|
<dialog id={modalId} className="modal">
|
||||||
|
<div className="modal-box">
|
||||||
|
<h3 className="font-bold text-lg">{title}</h3>
|
||||||
|
<p className="py-4 flex items-center gap-2 justify-center">
|
||||||
|
<CheckCircledIcon className="text-success" />
|
||||||
|
Moodle Kurs abgeschlossen
|
||||||
|
</p>
|
||||||
|
<div>
|
||||||
|
<div className="flex items-center gap-2 justify-center">
|
||||||
|
<CalendarIcon />
|
||||||
|
<select className="select w-full max-w-xs" defaultValue={0}>
|
||||||
|
<option disabled>Bitte wähle einen Termin aus</option>
|
||||||
|
{dates.map((date, index) => (
|
||||||
|
<option key={index}>{date}</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<p className="mt-3 text-center">
|
||||||
|
Bitte finde dich an diesem Termin in unserem Discord ein.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="modal-action flex justify-between">
|
||||||
|
<button className="btn" onClick={closeModal}>
|
||||||
|
Abbrechen
|
||||||
|
</button>
|
||||||
|
<button className="btn btn-info btn-outline btn-wide">
|
||||||
|
<EnterIcon /> Anmelden
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button className="modal-backdrop" onClick={closeModal}>
|
||||||
|
Abbrechen
|
||||||
|
</button>
|
||||||
|
</dialog>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ModalBtn;
|
||||||
45
apps/hub/app/(app)/events/page.tsx
Normal file
45
apps/hub/app/(app)/events/page.tsx
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
import { getServerSession } from "../../api/auth/[...nextauth]/auth";
|
||||||
|
import { PrismaClient } from "@repo/db";
|
||||||
|
import { PilotKurs, KursItem } from "./_components/item";
|
||||||
|
import {
|
||||||
|
RocketIcon,
|
||||||
|
DrawingPinFilledIcon,
|
||||||
|
EnterIcon,
|
||||||
|
} from "@radix-ui/react-icons";
|
||||||
|
|
||||||
|
export default async () => {
|
||||||
|
const prisma = new PrismaClient();
|
||||||
|
const session = await getServerSession();
|
||||||
|
if (!session) return null;
|
||||||
|
const user = await prisma.user.findFirst({
|
||||||
|
where: {
|
||||||
|
id: session.user.id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!user) return null;
|
||||||
|
return (
|
||||||
|
<div className="grid grid-cols-6 gap-4">
|
||||||
|
<div className="col-span-full">
|
||||||
|
<p className="text-2xl font-semibold text-left flex items-center gap-2">
|
||||||
|
<RocketIcon className="w-5 h-5" /> Events & Kurse
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<PilotKurs user={user} />
|
||||||
|
<KursItem
|
||||||
|
user={user}
|
||||||
|
title="Einsteigerkurs für Disponenten"
|
||||||
|
type="1"
|
||||||
|
beschreibung="In diesem Kurs lernen Teilnehmer die Aufgaben eines
|
||||||
|
Disponenten in der Rettungsfliegerei kennen. Dazu gehören die
|
||||||
|
Koordination von Notfalleinsätzen, die effiziente Planung von
|
||||||
|
Ressourcen und die Kommunikation mit Piloten sowie
|
||||||
|
Rettungsdiensten. Der Kurs vermittelt praxisnahe Kenntnisse
|
||||||
|
für die schnelle und präzise Entscheidungsfindung unter
|
||||||
|
Zeitdruck, um eine reibungslose Abwicklung von
|
||||||
|
Rettungseinsätzen zu gewährleisten."
|
||||||
|
badge="Badge"
|
||||||
|
moodleReq={true}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -40,7 +40,7 @@ export default async function RootLayout({
|
|||||||
<VerticalNav />
|
<VerticalNav />
|
||||||
|
|
||||||
{/* Scrollbarer Content-Bereich */}
|
{/* Scrollbarer Content-Bereich */}
|
||||||
<div className="flex-grow bg-base-100 p-6 rounded-lg shadow-md ml-4 overflow-auto h-full">
|
<div className="flex-grow bg-base-100 p-6 rounded-lg shadow-md ml-4 overflow-auto h-full max-w-full w-full">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -4,8 +4,9 @@ import {
|
|||||||
GearIcon,
|
GearIcon,
|
||||||
ExitIcon,
|
ExitIcon,
|
||||||
LockClosedIcon,
|
LockClosedIcon,
|
||||||
} from '@radix-ui/react-icons';
|
RocketIcon,
|
||||||
import Link from 'next/link';
|
} from "@radix-ui/react-icons";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
export const VerticalNav = () => {
|
export const VerticalNav = () => {
|
||||||
return (
|
return (
|
||||||
@@ -18,7 +19,13 @@ export const VerticalNav = () => {
|
|||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<Link href="/profile">
|
<Link href="/profile">
|
||||||
<PersonIcon /> Profile
|
<PersonIcon /> Profil
|
||||||
|
</Link>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<Link href="/events">
|
||||||
|
<RocketIcon />
|
||||||
|
Events & Kurse
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
@@ -62,7 +69,7 @@ export const HorizontalNav = () => (
|
|||||||
<ul className="flex space-x-2 px-1">
|
<ul className="flex space-x-2 px-1">
|
||||||
<li>
|
<li>
|
||||||
<Link href="/">
|
<Link href="/">
|
||||||
<button className="btn btn-sm btn-outline btn-primary">
|
<button className="btn btn-sm btn-outline btn-info">
|
||||||
Zur Leitstelle
|
Zur Leitstelle
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -7,3 +7,7 @@
|
|||||||
--foreground: #171717;
|
--foreground: #171717;
|
||||||
/* --p: 47.67% 0.2484 267.02; */
|
/* --p: 47.67% 0.2484 267.02; */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body.modal-open {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user