This commit is contained in:
nocnico
2025-07-24 03:24:28 +02:00
9 changed files with 112 additions and 74 deletions

View File

@@ -34,7 +34,7 @@ export const handleParticipantFinished = async (
},
});
if (event.discordRoleId && discordAccount) {
if (discordAccount) {
await setStandardName({
memberId: discordAccount.discordId,
userId: user.id,

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,15 +248,15 @@ 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"]}
searchFields={["User.firstname", "User.lastname", "User.publicId"]}
ref={appointmentsTableRef}
prismaModel={"participant"}
filter={{
@@ -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,13 +333,14 @@ 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-body ">
<div className="card bg-base-200 col-span-6 shadow-xl">
<div className="card-body">
<div className="flex w-full gap-4">
<Button
isLoading={form.formState.isSubmitting}

View File

@@ -36,7 +36,7 @@ export const EventCard = ({
</div>
<div className="grid grid-cols-6 gap-4">
<div className="col-span-4">
<div className="text-left text-balance">
<div className="text-left text-balance" data-color-mode="dark">
<MDEditor.Markdown
source={event.descriptionShort}
style={{

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" data-color-mode="dark">
<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,7 +13,8 @@ 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}

View File

@@ -169,7 +169,7 @@ export const ProfileForm = ({
{...form.register("settingsHideLastname")}
className="checkbox"
/>
Anfangsbuchstaben des Nachnamens verstecken
Immer nur den Vornamen anzeigen ("Max" statt "Max M.")
</label>
<label className="floating-label mt-4 w-full">
<span className="flex items-center gap-2 text-lg">

View File

@@ -13,7 +13,7 @@ export const resetPassword = async (email: string) => {
email,
},
});
const oldUser = (OLD_USER as OldUser[]).find((u) => u.email === email);
const oldUser = (OLD_USER as OldUser[]).find((u) => u.email.toLowerCase() === email.toLowerCase());
if (!user) {
if (oldUser) {
user = await createNewUserFromOld(oldUser);

View File

@@ -29,7 +29,7 @@ export const register = async ({ password, ...user }: Omit<Prisma.UserCreateInpu
},
});
const existingOldUser = (OLD_USER as OldUser[]).find((u) => u.email === user.email);
const existingOldUser = (OLD_USER as OldUser[]).find((u) => u.email.toLocaleLowerCase() === user.email.toLocaleLowerCase());
if (existingUser) {
return {

View File

@@ -20,7 +20,7 @@ export const options: AuthOptions = {
const user = await prisma.user.findFirst({
where: { email: credentials.email },
});
const v1User = (oldUser as OldUser[]).find((u) => u.email === credentials.email);
const v1User = (oldUser as OldUser[]).find((u) => u.email.toLowerCase() === credentials.email.toLowerCase());
if (!user && v1User) {
if (bcrypt.compareSync(credentials.password, v1User.password)) {
const newUser = await createNewUserFromOld(v1User);