Files
var-monorepo/apps/hub/app/(app)/_components/FirstPath.tsx
2025-06-27 20:11:09 +02:00

168 lines
5.7 KiB
TypeScript

"use client";
import { editUser } from "(app)/admin/user/action";
import { Button } from "_components/ui/Button";
import { Plane, Workflow } from "lucide-react";
import { useSession } from "next-auth/react";
import { useRef, useEffect, useState } from "react";
import { useQuery } from "@tanstack/react-query";
import { getEvents } from "../../../helper/events";
import { EventCard } from "(app)/events/_components/item";
const PathsOptions = ({
selected,
setSelected,
}: {
selected: "disponent" | "pilot" | null;
setSelected: (value: "disponent" | "pilot") => void;
}) => {
return (
<>
<div className="flex gap-6">
{/* Disponent Card */}
<div
className={`cursor-pointer border rounded-lg p-6 w-80 transition-colors ${
selected === "disponent" ? "border-info ring-2 ring-info" : "border-base-300"
}`}
onClick={() => setSelected("disponent")}
role="button"
tabIndex={0}
aria-pressed={selected === "disponent"}
>
<h1 className="font-semibold text-lg mb-2 flex gap-2 justify-center items-center">
Disponent <Workflow />
</h1>
<div className="text-sm text-base-content/70">
Denkt sich realistische Einsatzszenarien aus, koordiniert deren Ablauf und ist die
zentrale Schnittstelle zwischen Piloten und bodengebundenen Rettungsmitteln. Er trägt
die Verantwortung für einen reibungslosen Ablauf und der erfolgreichen Durchführung der
Einsätze.
<div className="badge badge-sm badge-secondary mt-3">
Teilnahme an Einführungsevent nötig
</div>
</div>
</div>
{/* Pilot Card */}
<div
className={`cursor-pointer border rounded-lg p-6 w-80 transition-colors ${
selected === "pilot" ? "border-info ring-2 ring-info" : "border-base-300"
}`}
onClick={() => setSelected("pilot")}
role="button"
tabIndex={0}
aria-pressed={selected === "pilot"}
>
<h1 className="font-semibold text-lg mb-2 flex gap-2 justify-center items-center">
Pilot <Plane />
</h1>
<div className="text-sm text-base-content/70">
Fliegt die vom Disponenten erstellten Einsätze und transportiert die Med-Crew sicher zum
Einsatzort. Er übernimmt die navigatorische Vorbereitung, achtet auf Wetterentwicklungen
und sorgt für die Sicherheit seiner Crew im Flug.
</div>
</div>
</div>
</>
);
};
const EventSelect = ({ pathSelected }: { pathSelected: "disponent" | "pilot" }) => {
const { data: events } = useQuery({
queryKey: ["events", "initial", pathSelected],
queryFn: () =>
getEvents({
type: pathSelected === "pilot" ? "PILOT_STARTER" : "DISPATCH_STARTER",
}),
});
const user = useSession().data?.user;
if (!user) return null;
return events?.map((event) => {
return (
<EventCard
appointments={event.Appointments}
selectedAppointments={event.Appointments.filter((a) =>
a.Participants.find((p) => p.userId == user.id),
)}
user={user}
event={event}
key={event.id}
/>
);
});
};
export const FirstPath = () => {
const modalRef = useRef<HTMLDialogElement>(null);
const { data: session } = useSession();
const [selected, setSelected] = useState<"disponent" | "pilot" | null>(
session?.user.badges.includes("D1") ? "disponent" : null,
);
const [page, setPage] = useState<"path" | "event-select">("path");
useEffect(() => {
if (modalRef.current && !modalRef.current.open) {
modalRef.current.showModal();
}
}, []);
return (
<dialog ref={modalRef} className="modal">
<div className="modal-box w-11/12 max-w-5xl">
<h3 className="flex items-center gap-2 text-lg font-bold mb-10">
{session?.user.migratedFromV1
? "Hallo, hier hat sich einiges geändert!"
: "Wähle deinen Einstieg!"}
</h3>
<h2 className="text-2xl font-bold mb-4 text-center">Willkommen bei Virtual Air Rescue!</h2>
{session?.user.migratedFromV1 ? (
<p className="mb-8 text-base text-base-content/80 text-center">
Dein Account wurde erfolgreich auf das neue System migriert. Herzlich Willkommen im
neuen HUB! Um die Erfahrung für alle Nutzer zu steigern haben wir uns dazu entschlossen,
dass alle Nutzer einen Test absolvieren müssen:{" "}
{session.user.badges.includes("D1") &&
`Da du vorher schon den D1-Test absolviert hast, kannst du unter Disponent das "Quick-Lane-Event" auswählen. Um Pilot zu werden, kannst du dann später den Piloten-Kurs absolvieren.`}
{(!session.user.badges.includes("D1") || session.user.badges.includes("P1")) &&
`Als Pilot musst du den Piloten-Test abschließen.`}
</p>
) : (
<p>
Wie möchtest du bei uns starten? Du kannst später jederzeit auch den anderen Pfad
ausprobieren, wenn du möchtest.
</p>
)}
<div className="flex flex-col items-center justify-center m-20">
{page === "path" && <PathsOptions selected={selected} setSelected={setSelected} />}
{page === "event-select" && (
<div className="flex flex-col gap-3 min-w-[800px]">
<div>
<p className="text-left text-gray-400 text-sm">Wähle dein Einführungs-Event aus:</p>
</div>
<EventSelect pathSelected={selected!} />
</div>
)}
</div>
<div className="modal-action">
<button className="btn" disabled={page === "path"} onClick={() => setPage("path")}>
Zurück
</button>
<Button
className="btn btn-info"
disabled={!selected}
onClick={async () => {
if (page === "path") {
setPage("event-select");
} else if (session?.user.id) {
await editUser(session?.user.id, {
pathSelected: true,
});
modalRef.current?.close();
}
}}
>
{page === "path" ? "Weiter" : "Pfad auswählen"}
</Button>
</div>
</div>
</dialog>
);
};