Maerge Commits from release to staging #139

Merged
PxlLoewe merged 25 commits from release into staging 2025-11-08 09:40:40 +00:00
5 changed files with 112 additions and 74 deletions
Showing only changes of commit d2a865c955 - Show all commits

View File

@@ -10,12 +10,12 @@ export const fmsStatusDescription: { [key: string]: string } = {
"7": "Einsatzgebunden",
"8": "Bedingt verfügbar",
"9": "Fremdanmeldung",
E: "Indent/Abbruch/Einsatzbefehl abgebrochen",
C: "Anmelden zur Übernahme des Einsatzes",
F: "Kommen über Draht",
E: "Einsatzabbruch",
C: "Einsatzübernahme melden",
F: "Kommen Sie über Draht",
H: "Fahren auf Wache",
J: "Sprechaufforderung",
L: "Lagebericht abgeben",
L: "Geben Sie Lagemeldung",
P: "Einsatz mit Polizei/Pause machen",
U: "Ungültige Statusfolge",
c: "Status korrigieren",

View File

@@ -25,6 +25,7 @@ import { AppointmentModal } from "./AppointmentModal";
import { ParticipantModal } from "./ParticipantModal";
import { ColumnDef } from "@tanstack/react-table";
import toast from "react-hot-toast";
import Link from "next/link";
export const Form = ({ event }: { event?: Event }) => {
const { data: session } = useSession();
@@ -72,10 +73,10 @@ export const Form = ({ event }: { event?: Event }) => {
})}
className="grid grid-cols-6 gap-3"
>
<div className="card bg-base-200 shadow-xl col-span-3 max-xl:col-span-6">
<div className="card bg-base-200 col-span-3 shadow-xl max-xl:col-span-6">
<div className="card-body">
<h2 className="card-title">
<FileText className="w-5 h-5" /> Allgemeines
<FileText className="h-5 w-5" /> Allgemeines
</h2>
<Select
form={form}
@@ -91,10 +92,10 @@ export const Form = ({ event }: { event?: Event }) => {
<MarkdownEditor form={form} name="descriptionShort" />
</div>
</div>
<div className="card bg-base-200 shadow-xl col-span-3 max-xl:col-span-6">
<div className="card bg-base-200 col-span-3 shadow-xl max-xl:col-span-6">
<div className="card-body">
<h2 className="card-title">
<Bot className="w-5 h-5" /> Automation
<Bot className="h-5 w-5" /> Automation
</h2>
<Input
name="finisherMoodleCourseId"
@@ -153,7 +154,7 @@ export const Form = ({ event }: { event?: Event }) => {
</div>
</div>
{form.watch("hasPresenceEvents") ? (
<div className="card bg-base-200 shadow-xl col-span-6">
<div className="card bg-base-200 col-span-6 shadow-xl">
<div className="card-body">
<PaginatedTable
ref={appointmentsTableRef}
@@ -167,7 +168,7 @@ export const Form = ({ event }: { event?: Event }) => {
}}
leftOfSearch={
<h2 className="card-title">
<Calendar className="w-5 h-5" /> Termine
<Calendar className="h-5 w-5" /> Termine
</h2>
}
rightOfSearch={
@@ -210,7 +211,7 @@ export const Form = ({ event }: { event?: Event }) => {
accessorKey: "Participants",
cell: ({ row }) => (
<div className="flex items-center">
<UserIcon className="w-5 h-5" />
<UserIcon className="h-5 w-5" />
<span className="ml-2">{row.original.Participants.length}</span>
</div>
),
@@ -247,12 +248,12 @@ export const Form = ({ event }: { event?: Event }) => {
</div>
) : null}
{!form.watch("hasPresenceEvents") ? (
<div className="card bg-base-200 shadow-xl col-span-6">
<div className="card bg-base-200 col-span-6 shadow-xl">
<div className="card-body">
<PaginatedTable
leftOfSearch={
<h2 className="card-title">
<Calendar className="w-5 h-5" /> Teilnehmer
<Calendar className="h-5 w-5" /> Teilnehmer
</h2>
}
searchFields={["User.firstname", "User.lastname"]}
@@ -264,14 +265,49 @@ export const Form = ({ event }: { event?: Event }) => {
include={{
User: true,
}}
columns={[
columns={
[
{
header: "Vorname",
accessorKey: "User.firstname",
cell: ({ row }) => {
return (
<Link
className="hover:underline"
href={`/admin/user/${row.original.User.id}`}
>
{row.original.User.firstname}
</Link>
);
},
},
{
header: "Nachname",
accessorKey: "User.lastname",
cell: ({ row }) => {
return (
<Link
className="hover:underline"
href={`/admin/user/${row.original.User.id}`}
>
{row.original.User.lastname}
</Link>
);
},
},
{
header: "VAR-Nummer",
accessorKey: "User.publicId",
cell: ({ row }) => {
return (
<Link
className="hover:underline"
href={`/admin/user/${row.original.User.id}`}
>
{row.original.User.publicId}
</Link>
);
},
},
{
header: "Moodle Kurs abgeschlossen",
@@ -297,12 +333,13 @@ export const Form = ({ event }: { event?: Event }) => {
);
},
},
]}
] as ColumnDef<Participant & { User: User }>[]
}
/>
</div>
</div>
) : null}
<div className="card bg-base-200 shadow-xl col-span-6">
<div className="card bg-base-200 col-span-6 shadow-xl">
<div className="card-body">
<div className="flex w-full gap-4">
<Button

View File

@@ -148,13 +148,13 @@ const ModalBtn = ({
<form method="dialog">
<button className="btn btn-sm btn-circle btn-ghost absolute right-3 top-3"></button>
</form>
<h3 className="font-bold text-lg text-left">{title}</h3>
<div className="flex flex-wrap gap-4 mt-4">
<div className="flex flex-col gap-2 flex-1 p-3 bg-base-300 min-w-[300px] shadow rounded-lg">
<h3 className="text-left text-lg font-bold">{title}</h3>
<div className="mt-4 flex flex-wrap gap-4">
<div className="bg-base-300 flex min-w-[300px] flex-1 flex-col gap-2 rounded-lg p-3 shadow">
<h2 className="flex gap-2 text-lg font-bold">
<Info /> Details
</h2>
<div className="text-left text-balance">
<div className="text-balance text-left">
<MDEditor.Markdown
source={event.description}
style={{
@@ -164,14 +164,14 @@ const ModalBtn = ({
</div>
</div>
{event.hasPresenceEvents && (
<div className="flex flex-col gap-2 flex-1 p-3 bg-base-300 min-w-[300px] shadow rounded-lg">
<div className="bg-base-300 flex min-w-[300px] flex-1 flex-col gap-2 rounded-lg p-3 shadow">
<h2 className="flex gap-2 text-lg font-bold">
<Calendar /> Termine
</h2>
<div className="flex flex-1 flex-col justify-center items-center">
<div className="flex flex-1 flex-col items-center justify-center">
{!!dates.length && !selectedDate && (
<>
<p className="text-center text-info">Melde dich zu einem Termin an</p>
<p className="text-info text-center">Melde dich zu einem Termin an</p>
<Select
form={selectAppointmentForm}
options={dates.map((date) => ({
@@ -190,7 +190,7 @@ const ModalBtn = ({
<span>Dein ausgewählter Termin (Deutsche Zeit)</span>
<div>
<button
className="input input-border min-w-[250px] pointer-events-none"
className="input input-border pointer-events-none min-w-[250px]"
style={{ anchorName: "--rdp" } as React.CSSProperties}
>
{new Date(selectedAppointment.appointmentDate).toLocaleString("de-DE", {
@@ -203,12 +203,12 @@ const ModalBtn = ({
</button>
</div>
{participant?.attended ? (
<p className="py-4 flex items-center gap-2 justify-center">
<p className="flex items-center justify-center gap-2 py-4">
<CheckCircledIcon className="text-success" />
Du hast an dem Presenztermin teilgenommen
</p>
) : (
<p className="py-4 flex items-center gap-2 justify-center">
<p className="flex items-center justify-center gap-2 py-4">
Bitte erscheine ~5 minuten vor dem Termin im Discord
</p>
)}
@@ -216,7 +216,7 @@ const ModalBtn = ({
)}
{!dates.length && (
<p className="text-center text-error">Aktuell sind keine Termine verfügbar</p>
<p className="text-error text-center">Aktuell sind keine Termine verfügbar</p>
)}
{!!selectedDate &&
@@ -225,7 +225,7 @@ const ModalBtn = ({
!!(ownPlaceInParticipantList > event.maxParticipants) && (
<p
role="alert"
className="py-4 my-5 flex items-center gap-2 justify-center border alert alert-error alert-outline"
className="alert alert-error alert-outline my-5 flex items-center justify-center gap-2 border py-4"
>
<TriangleAlert className="h-6 w-6 shrink-0 stroke-current" fill="none" />
Dieser Termin ist ausgebucht, wahrscheinlich wirst du nicht teilnehmen
@@ -237,11 +237,11 @@ const ModalBtn = ({
</div>
)}
{event.finisherMoodleCourseId && (
<div className="flex flex-col gap-2 flex-1 p-3 bg-base-300 min-w-[300px] shadow rounded-lg">
<div className="bg-base-300 flex min-w-[300px] flex-1 flex-col gap-2 rounded-lg p-3 shadow">
<h2 className="flex gap-2 text-lg font-bold">
<BookCheck /> Moodle-Kurs
</h2>
<div className="flex flex-col items-center justify-center h-full">
<div className="flex h-full flex-col items-center justify-center">
<MoodleCourseIndicator
participant={participant}
user={user}
@@ -254,9 +254,9 @@ const ModalBtn = ({
)}
</div>
<div className="flex justify-between items-end mt-5">
<div className="mt-5 flex items-end justify-between">
<div>
<p className="text-gray-600 text-left flex items-center gap-2">
<p className="flex items-center gap-2 text-left text-gray-600">
<DrawingPinFilledIcon /> <b>Teilnahmevoraussetzungen: </b>
{!event.requiredBadges.length && "Keine"}
</p>
@@ -347,23 +347,27 @@ const MoodleCourseIndicator = ({
const courseUrl = `${process.env.NEXT_PUBLIC_MOODLE_URL}/course/view.php?id=${moodleCourseId}`;
if (event.hasPresenceEvents && !participant?.attended)
return (
<p className="py-4 flex items-center gap-2 justify-center">
<p className="flex items-center justify-center gap-2 py-4">
<Clock10Icon className="text-error" />
Abschlusstest erst nach Teilnahme verfügbar
</p>
);
if (completed)
return (
<p className="py-4 flex items-center gap-2 justify-center">
<p className="flex items-center justify-center gap-2 py-4">
<CheckCircledIcon className="text-success" />
Moodle Kurs abgeschlossen
</p>
);
return (
<div className="flex flex-col items-center justify-center gap-2">
<p className="text-sm flex items-center gap-2">
<p className="flex items-center gap-2 text-sm">
<CirclePlay className="text-warning" /> Moodle-Kurs bereit
</p>
<p className="font-bold text-gray-400">
Wenn du nach dem Anmelden den moodle Kurs nicht siehst, warte ein paar Sekunden und lade die
Seite neu.
</p>
<button
className="btn btn-sm btn-outline btn-info ml-2"
onClick={async () => {
@@ -386,10 +390,6 @@ const MoodleCourseIndicator = ({
<ExternalLink size={16} />
Zum Moodle Kurs
</button>
<p className="text-xs text-gray-400">
Wenn du nach dem Anmelden den moodle Kurs nicht siehst, warte ein paar Sekunden und lade die
Seite neu.
</p>
</div>
);
};

View File

@@ -13,15 +13,16 @@ export default function () {
BtnIcon={<DiscordLogoIcon />}
btnHref="https://discord.com/invite/x6FAMY7DW6"
btnLabel="Beitreten"
description="Tritt unserem Discord-Server bei, um mit der Community in Kontakt zu bleiben, Unterstützung zu erhalten und über die neuesten Updates informiert zu werden. Wenn du beigetreten bist, kannst du in deinen Einstellungen dein VAR-Konto mit deinem Discord-Konto verknüpfen und eine Rolle erhalten."
description="Tritt unserem Discordserver bei, um mit der Community in Kontakt zu bleiben, Unterstützung zu erhalten und über die neuesten Updates informiert zu werden. Wenn du beigetreten bist kannst du in deinen Einstellungen dein VAR-Konto mit deinem Discordkonto verknüpfen und eine Rolle zu erhalten.
"
/>
<ResourceCard
image={Desktop}
title="Desktop client"
title="Desktop Client"
BtnIcon={<Download />}
btnHref="https://cdn.virtualairrescue.com/desktop/setup.exe"
btnLabel="Herunterladen"
description="Verwende diesen Client, um dich mit dem VAR-Netzwerk zu verbinden. Wenn du dich verbindest, kannst du einen Push-To-Talk Key setzen, um den Funk zu bedienen. Wenn du als Pilot fliegen möchtest, wird deine Position aus dem Simulator an unser Tracker-System übertragen."
description="Verwende diesen Client, um dich mit dem VAR-Netzwerk zu verbinden. Wenn du dich verbindest, kannst du einen Push-To-Talk Key setzen, um den Funk zu bedienen. Möchtest du als Pilot fliegen, wird deine Position aus dem Simulator an unser Tracker-System übertragen."
/>
</div>
);

View File

@@ -397,7 +397,7 @@ export const PasswordForm = (): React.JSX.Element => {
})}
>
<h2 className="card-title">
<LockClosedIcon className="h-5 w-5" /> Password Ändern
<LockClosedIcon className="h-5 w-5" /> Password ändern
</h2>
<div className="">
<label className="floating-label mb-5 mt-5 w-full">