removed console.log statements

This commit is contained in:
PxlLoewe
2025-02-27 00:34:53 +01:00
parent 9366f8f6b4
commit bbcde2eb4a
7 changed files with 639 additions and 647 deletions

View File

@@ -1,2 +1,2 @@
import "modules/chron"; import "modules/chron";
console.log("VAR hub Server started"); console.log("VAR hub Server started");

View File

@@ -1,246 +1,245 @@
'use client'; "use client";
import { zodResolver } from '@hookform/resolvers/zod'; import { zodResolver } from "@hookform/resolvers/zod";
import { StationOptionalDefaultsSchema } from '@repo/db/zod'; import { StationOptionalDefaultsSchema } from "@repo/db/zod";
import { set, useForm } from 'react-hook-form'; import { set, useForm } from "react-hook-form";
import { z } from 'zod'; import { z } from "zod";
import { BosUse, Country, Station } from '@repo/db'; import { BosUse, Country, Station } from "@repo/db";
import { FileText, LocateIcon, PlaneIcon } from 'lucide-react'; import { FileText, LocateIcon, PlaneIcon } from "lucide-react";
import { Input } from '../../../../_components/ui/Input'; import { Input } from "../../../../_components/ui/Input";
import { useState } from 'react'; import { useState } from "react";
import { deleteStation, upsertStation } from '../action'; import { deleteStation, upsertStation } from "../action";
import { Button } from '../../../../_components/ui/Button'; import { Button } from "../../../../_components/ui/Button";
import { redirect } from 'next/navigation'; import { redirect } from "next/navigation";
export const StationForm = ({ station }: { station?: Station }) => { export const StationForm = ({ station }: { station?: Station }) => {
const form = useForm<z.infer<typeof StationOptionalDefaultsSchema>>({ const form = useForm<z.infer<typeof StationOptionalDefaultsSchema>>({
resolver: zodResolver(StationOptionalDefaultsSchema), resolver: zodResolver(StationOptionalDefaultsSchema),
defaultValues: station, defaultValues: station,
}); });
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [deleteLoading, setDeleteLoading] = useState(false); const [deleteLoading, setDeleteLoading] = useState(false);
console.log(form.formState.errors); return (
return ( <>
<> <form
<form onSubmit={form.handleSubmit(async (values) => {
onSubmit={form.handleSubmit(async (values) => { setLoading(true);
setLoading(true); const createdStation = await upsertStation(values, station?.id);
const createdStation = await upsertStation(values, station?.id); setLoading(false);
setLoading(false); if (!station) redirect(`/admin/station`);
if (!station) redirect(`/admin/station`); })}
})} className="grid grid-cols-6 gap-3"
className="grid grid-cols-6 gap-3" >
> <div className="card bg-base-200 shadow-xl col-span-2 max-xl:col-span-6">
<div className="card bg-base-200 shadow-xl col-span-2 max-xl:col-span-6"> <div className="card-body">
<div className="card-body"> <h2 className="card-title">
<h2 className="card-title"> <FileText className="w-5 h-5" /> Allgemeines
<FileText className="w-5 h-5" /> Allgemeines </h2>
</h2> <Input
<Input form={form}
form={form} label="BOS Rufname"
label="BOS Rufname" name="bosCallsign"
name="bosCallsign" className="input-sm"
className="input-sm" />
/> <Input
<Input form={form}
form={form} label="BOS Rufname (kurz)"
label="BOS Rufname (kurz)" name="bosCallsignShort"
name="bosCallsignShort" className="input-sm"
className="input-sm" />
/> <Input
<Input form={form}
form={form} label="Betreiber"
label="Betreiber" name="operator"
name="operator" className="input-sm"
className="input-sm" />
/> <Input
<Input form={form}
form={form} label="ATC Rufname"
label="ATC Rufname" name="atcCallsign"
name="atcCallsign" className="input-sm"
className="input-sm" />
/> <Input
<Input form={form}
form={form} label="FIR (Flight Information Region)"
label="FIR (Flight Information Region)" name="fir"
name="fir" className="input-sm"
className="input-sm" />
/> <Input
<Input form={form}
form={form} label="Leitstelle Rufname"
label="Leitstelle Rufname" name="bosRadioArea"
name="bosRadioArea" className="input-sm"
className="input-sm" />
/>
<label className="form-control w-full"> <label className="form-control w-full">
<span className="label-text text-lg flex items-center gap-2"> <span className="label-text text-lg flex items-center gap-2">
BOS Nutzung BOS Nutzung
</span> </span>
<select <select
className="input-sm select select-bordered select-sm" className="input-sm select select-bordered select-sm"
{...form.register('bosUse')} {...form.register("bosUse")}
> >
{Object.keys(BosUse).map((use) => ( {Object.keys(BosUse).map((use) => (
<option key={use} value={use}> <option key={use} value={use}>
{use} {use}
</option> </option>
))} ))}
</select> </select>
</label> </label>
</div> </div>
</div> </div>
<div className="card bg-base-200 shadow-xl col-span-2 max-xl:col-span-6"> <div className="card bg-base-200 shadow-xl col-span-2 max-xl:col-span-6">
<div className="card-body"> <div className="card-body">
<h2 className="card-title"> <h2 className="card-title">
<LocateIcon className="w-5 h-5" /> Standort + Ausrüstung <LocateIcon className="w-5 h-5" /> Standort + Ausrüstung
</h2> </h2>
<label className="form-control w-full"> <label className="form-control w-full">
<span className="label-text text-lg flex items-center gap-2"> <span className="label-text text-lg flex items-center gap-2">
Land Land
</span> </span>
<select <select
className="input-sm select select-bordered select-sm" className="input-sm select select-bordered select-sm"
{...form.register('country', {})} {...form.register("country", {})}
> >
{Object.keys(Country).map((use) => ( {Object.keys(Country).map((use) => (
<option key={use} value={use}> <option key={use} value={use}>
{use} {use}
</option> </option>
))} ))}
</select> </select>
</label> </label>
<Input <Input
form={form} form={form}
label="Bundesland" label="Bundesland"
name="locationState" name="locationState"
className="input-sm" className="input-sm"
/> />
<Input <Input
form={form} form={form}
label="Bundesland (kurz)" label="Bundesland (kurz)"
name="locationStateShort" name="locationStateShort"
className="input-sm" className="input-sm"
/> />
<span className="label-text text-lg flex items-center gap-2"> <span className="label-text text-lg flex items-center gap-2">
Ausgerüstet mit: Ausgerüstet mit:
</span> </span>
<div className="form-control"> <div className="form-control">
<label className="label cursor-pointer"> <label className="label cursor-pointer">
<span>Winde</span> <span>Winde</span>
<input <input
type="checkbox" type="checkbox"
className="toggle" className="toggle"
{...form.register('hasWinch')} {...form.register("hasWinch")}
/> />
</label> </label>
<label className="label cursor-pointer"> <label className="label cursor-pointer">
<span>Nachtsicht Gerät</span> <span>Nachtsicht Gerät</span>
<input <input
type="checkbox" type="checkbox"
className="toggle" className="toggle"
{...form.register('hasNvg')} {...form.register("hasNvg")}
/> />
</label> </label>
<label className="label cursor-pointer"> <label className="label cursor-pointer">
<span>24-Stunden Einsatzfähig</span> <span>24-Stunden Einsatzfähig</span>
<input <input
type="checkbox" type="checkbox"
className="toggle" className="toggle"
{...form.register('is24h')} {...form.register("is24h")}
/> />
</label> </label>
<label className="label cursor-pointer"> <label className="label cursor-pointer">
<span>Bergetau</span> <span>Bergetau</span>
<input <input
type="checkbox" type="checkbox"
className="toggle" className="toggle"
{...form.register('hasRope')} {...form.register("hasRope")}
/> />
</label> </label>
</div> </div>
<Input <Input
form={form} form={form}
label="Breitengrad" label="Breitengrad"
name="latitude" name="latitude"
className="input-sm" className="input-sm"
formOptions={{ valueAsNumber: true }} formOptions={{ valueAsNumber: true }}
type="number" type="number"
step="any" step="any"
/> />
<Input <Input
form={form} form={form}
label="Längengrad" label="Längengrad"
name="longitude" name="longitude"
className="input-sm" className="input-sm"
formOptions={{ valueAsNumber: true }} formOptions={{ valueAsNumber: true }}
type="number" type="number"
step="any" step="any"
/> />
<label className="label cursor-pointer"> <label className="label cursor-pointer">
<span className="text-lg">Reichweiten ausblenden</span> <span className="text-lg">Reichweiten ausblenden</span>
<input <input
type="checkbox" type="checkbox"
className="toggle" className="toggle"
{...form.register('hideRangeRings')} {...form.register("hideRangeRings")}
/> />
</label> </label>
</div> </div>
</div> </div>
<div className="card bg-base-200 shadow-xl col-span-2 max-xl:col-span-6"> <div className="card bg-base-200 shadow-xl col-span-2 max-xl:col-span-6">
<div className="card-body"> <div className="card-body">
<h2 className="card-title"> <h2 className="card-title">
<PlaneIcon className="w-5 h-5" /> Hubschrauber <PlaneIcon className="w-5 h-5" /> Hubschrauber
</h2> </h2>
<Input <Input
form={form} form={form}
label="Hubschrauber Typ" label="Hubschrauber Typ"
name="aircraft" name="aircraft"
className="input-sm" className="input-sm"
/> />
<Input <Input
form={form} form={form}
formOptions={{ valueAsNumber: true }} formOptions={{ valueAsNumber: true }}
type="number" type="number"
label="Hubschrauber Geschwindigkeit" label="Hubschrauber Geschwindigkeit"
className="input-sm" className="input-sm"
name="aircraftSpeed" name="aircraftSpeed"
/> />
<Input <Input
form={form} form={form}
label="Hubschrauber Registrierung" label="Hubschrauber Registrierung"
name="aircraftRegistration" name="aircraftRegistration"
className="input-sm" className="input-sm"
/> />
</div> </div>
</div> </div>
<div className="card bg-base-200 shadow-xl col-span-6"> <div className="card bg-base-200 shadow-xl col-span-6">
<div className="card-body "> <div className="card-body ">
<div className="flex w-full gap-4"> <div className="flex w-full gap-4">
<Button <Button
isLoading={loading} isLoading={loading}
type="submit" type="submit"
className="btn btn-primary flex-1" className="btn btn-primary flex-1"
> >
Speichern Speichern
</Button> </Button>
{station && ( {station && (
<Button <Button
isLoading={deleteLoading} isLoading={deleteLoading}
onClick={async () => { onClick={async () => {
setDeleteLoading(true); setDeleteLoading(true);
await deleteStation(station.id); await deleteStation(station.id);
redirect('/admin/station'); redirect("/admin/station");
}} }}
className="btn btn-error" className="btn btn-error"
> >
Löschen Löschen
</Button> </Button>
)} )}
</div> </div>
</div> </div>
</div> </div>
</form> </form>
</> </>
); );
}; };

View File

@@ -1,22 +1,22 @@
import { PrismaClient } from '@repo/db'; import { PrismaClient } from "@repo/db";
export default async ({ params }: { params: Promise<{ id: string }> }) => { export default async ({ params }: { params: Promise<{ id: string }> }) => {
const prisma = new PrismaClient(); const prisma = new PrismaClient();
const { id } = await params; const { id } = await params;
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { where: {
id: id, id: id,
}, },
}); });
console.log(user); console.log(user);
return ( return (
<div> <div>
<h1> <h1>
{user?.firstname} {user?.lastname} {user?.firstname} {user?.lastname}
</h1> </h1>
<p>{user?.email}</p> <p>{user?.email}</p>
{/* TODO: Hier Nutzerdaten bearbeiten */} {/* TODO: Hier Nutzerdaten bearbeiten */}
</div> </div>
); );
}; };

View File

@@ -10,345 +10,344 @@ import { useSession } from "next-auth/react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { Button } from "../../../_components/ui/Button"; import { Button } from "../../../_components/ui/Button";
import { import {
PersonIcon, PersonIcon,
EnvelopeClosedIcon, EnvelopeClosedIcon,
BookmarkIcon, BookmarkIcon,
DiscordLogoIcon, DiscordLogoIcon,
PaperPlaneIcon, PaperPlaneIcon,
Link2Icon, Link2Icon,
MixerHorizontalIcon, MixerHorizontalIcon,
LockClosedIcon, LockClosedIcon,
LockOpen2Icon, LockOpen2Icon,
LockOpen1Icon, LockOpen1Icon,
} from "@radix-ui/react-icons"; } from "@radix-ui/react-icons";
export const ProfileForm = ({ user }: { user: User }) => { export const ProfileForm = ({ user }: { user: User }) => {
const schema = z.object({ const schema = z.object({
firstname: z.string().min(2).max(30), firstname: z.string().min(2).max(30),
lastname: z.string().min(2).max(30), lastname: z.string().min(2).max(30),
email: z.string().email({ email: z.string().email({
message: "Bitte gebe eine gültige E-Mail Adresse ein", message: "Bitte gebe eine gültige E-Mail Adresse ein",
}), }),
}); });
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
type IFormInput = z.infer<typeof schema>; type IFormInput = z.infer<typeof schema>;
const form = useForm<IFormInput>({ const form = useForm<IFormInput>({
defaultValues: { defaultValues: {
firstname: user.firstname, firstname: user.firstname,
lastname: user.lastname, lastname: user.lastname,
email: user.email, email: user.email,
}, },
resolver: zodResolver(schema), resolver: zodResolver(schema),
}); });
return ( return (
<form <form
className="card-body" className="card-body"
onSubmit={form.handleSubmit(async (values) => { onSubmit={form.handleSubmit(async (values) => {
setIsLoading(true); setIsLoading(true);
await updateUser(values); await updateUser(values);
form.reset(values); form.reset(values);
setIsLoading(false); setIsLoading(false);
toast.success("Deine Änderungen wurden gespeichert!", { toast.success("Deine Änderungen wurden gespeichert!", {
style: { style: {
background: "var(--color-base-100)", background: "var(--color-base-100)",
color: "var(--color-base-content)", color: "var(--color-base-content)",
}, },
}); });
})} })}
> >
<h2 className="card-title"> <h2 className="card-title">
<MixerHorizontalIcon className="w-5 h-5" /> Persönliche Informationen <MixerHorizontalIcon className="w-5 h-5" /> Persönliche Informationen
</h2> </h2>
<div className="text-left"> <div className="text-left">
<label className="floating-label w-full mb-5 mt-5"> <label className="floating-label w-full mb-5 mt-5">
<span className="text-lg flex items-center gap-2"> <span className="text-lg flex items-center gap-2">
<PersonIcon /> Vorname <PersonIcon /> Vorname
</span> </span>
<input <input
{...form.register("firstname")} {...form.register("firstname")}
type="text" type="text"
className="input input-bordered w-full" className="input input-bordered w-full"
defaultValue={user.firstname} defaultValue={user.firstname}
placeholder="Vorname" placeholder="Vorname"
/> />
</label> </label>
{form.formState.errors.firstname && ( {form.formState.errors.firstname && (
<p className="text-error"> <p className="text-error">
{form.formState.errors.firstname.message} {form.formState.errors.firstname.message}
</p> </p>
)} )}
<label className="floating-label w-full mb-5"> <label className="floating-label w-full mb-5">
<span className="text-lg flex items-center gap-2"> <span className="text-lg flex items-center gap-2">
<PersonIcon /> Nachname <PersonIcon /> Nachname
</span> </span>
<input <input
{...form.register("lastname")} {...form.register("lastname")}
type="text" type="text"
className="input input-bordered w-full" className="input input-bordered w-full"
defaultValue={user.lastname} defaultValue={user.lastname}
placeholder="Nachname" placeholder="Nachname"
/> />
</label> </label>
{form.formState.errors.lastname && ( {form.formState.errors.lastname && (
<p className="text-error"> <p className="text-error">
{form.formState.errors.lastname?.message} {form.formState.errors.lastname?.message}
</p> </p>
)} )}
<label className="floating-label w-full"> <label className="floating-label w-full">
<span className="text-lg flex items-center gap-2"> <span className="text-lg flex items-center gap-2">
<EnvelopeClosedIcon /> E-Mail <EnvelopeClosedIcon /> E-Mail
</span> </span>
<input <input
{...form.register("email")} {...form.register("email")}
type="text" type="text"
className="input input-bordered w-full" className="input input-bordered w-full"
defaultValue={user.email} defaultValue={user.email}
placeholder="E-Mail" placeholder="E-Mail"
/> />
</label> </label>
{form.formState.errors.email && ( {form.formState.errors.email && (
<p className="text-error">{form.formState.errors.email?.message}</p> <p className="text-error">{form.formState.errors.email?.message}</p>
)} )}
<div className="card-actions justify-center pt-6"> <div className="card-actions justify-center pt-6">
<Button <Button
role="submit" role="submit"
className="btn-sm btn-wide btn-outline btn-primary" className="btn-sm btn-wide btn-outline btn-primary"
disabled={!form.formState.isDirty} disabled={!form.formState.isDirty}
isLoading={isLoading} isLoading={isLoading}
> >
<BookmarkIcon /> Speichern <BookmarkIcon /> Speichern
</Button> </Button>
</div> </div>
</div> </div>
</form> </form>
); );
}; };
export const SocialForm = ({ export const SocialForm = ({
discordAccount, discordAccount,
user, user,
}: { }: {
discordAccount?: DiscordAccount; discordAccount?: DiscordAccount;
user: User; user: User;
}) => { }) => {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const [vatsimLoading, setVatsimLoading] = useState(false); const [vatsimLoading, setVatsimLoading] = useState(false);
const router = useRouter(); const router = useRouter();
const schema = z.object({ const schema = z.object({
vatsimCid: z.number().min(1000).max(9999999), vatsimCid: z.number().min(1000).max(9999999),
}); });
type IFormInput = z.infer<typeof schema>; type IFormInput = z.infer<typeof schema>;
const form = useForm<IFormInput>({ const form = useForm<IFormInput>({
defaultValues: { defaultValues: {
vatsimCid: user?.vatsimCid || undefined, vatsimCid: user?.vatsimCid || undefined,
}, },
resolver: zodResolver(schema), resolver: zodResolver(schema),
}); });
if (!user) return null; if (!user) return null;
console.log("Dirty", form.formState.isDirty); return (
return ( <form
<form className="card-body"
className="card-body" onSubmit={form.handleSubmit(async (values) => {
onSubmit={form.handleSubmit(async (values) => { form.handleSubmit(async () => {
form.handleSubmit(async () => { setVatsimLoading(true);
setVatsimLoading(true); });
}); await updateUser({
await updateUser({ vatsimCid: values.vatsimCid,
vatsimCid: values.vatsimCid, });
}); setVatsimLoading(false);
setVatsimLoading(false); form.reset(values);
form.reset(values); toast.success("Deine Änderungen wurden gespeichert!", {
toast.success("Deine Änderungen wurden gespeichert!", { style: {
style: { background: "var(--color-base-100)",
background: "var(--color-base-100)", color: "var(--color-base-content)",
color: "var(--color-base-content)", },
}, });
}); })}
})} >
> <h2 className="card-title">
<h2 className="card-title"> <Link2Icon className="w-5 h-5" /> Verbindungen & Benachrichtigungen
<Link2Icon className="w-5 h-5" /> Verbindungen & Benachrichtigungen </h2>
</h2> <div>
<div> <div>
<div> <div className="label">
<div className="label"> <span className="label-text text-lg flex items-center gap-2">
<span className="label-text text-lg flex items-center gap-2"> <DiscordLogoIcon /> Discord
<DiscordLogoIcon /> Discord </span>
</span> </div>
</div>
{discordAccount ? ( {discordAccount ? (
<Button <Button
className="btn-success btn-block btn-outline group transition-all duration-0 hover:btn-error" className="btn-success btn-block btn-outline group transition-all duration-0 hover:btn-error"
isLoading={isLoading} isLoading={isLoading}
onClick={async () => { onClick={async () => {
setIsLoading(true); setIsLoading(true);
await unlinkDiscord(user.id); await unlinkDiscord(user.id);
router.refresh(); router.refresh();
setIsLoading(false); setIsLoading(false);
}} }}
> >
<DiscordLogoIcon className="w-5 h-5" /> <DiscordLogoIcon className="w-5 h-5" />
<span className="group-hover:hidden"> <span className="group-hover:hidden">
Verbunden mit {discordAccount.username} Verbunden mit {discordAccount.username}
</span> </span>
<span className="hidden group-hover:inline"> <span className="hidden group-hover:inline">
Verbindung trennen{isLoading && "..."} Verbindung trennen{isLoading && "..."}
</span> </span>
</Button> </Button>
) : ( ) : (
<a href={process.env.NEXT_PUBLIC_DISCORD_URL}> <a href={process.env.NEXT_PUBLIC_DISCORD_URL}>
<button <button
type="button" type="button"
className="btn btn-primary btn-block" className="btn btn-primary btn-block"
onSubmit={() => false} onSubmit={() => false}
> >
<DiscordLogoIcon className="w-5 h-5" /> Mit Discord verbinden <DiscordLogoIcon className="w-5 h-5" /> Mit Discord verbinden
</button> </button>
</a> </a>
)} )}
</div> </div>
</div> </div>
<div className="content-center"> <div className="content-center">
<label className="floating-label w-full mt-5"> <label className="floating-label w-full mt-5">
<span className="text-lg flex items-center gap-2"> <span className="text-lg flex items-center gap-2">
<PaperPlaneIcon /> VATSIM-CID <PaperPlaneIcon /> VATSIM-CID
</span> </span>
<input <input
type="number" type="number"
className="input input-bordered w-full" className="input input-bordered w-full"
placeholder="1445241" placeholder="1445241"
defaultValue={user.vatsimCid as number | undefined} defaultValue={user.vatsimCid as number | undefined}
{...form.register("vatsimCid", { {...form.register("vatsimCid", {
valueAsNumber: true, valueAsNumber: true,
})} })}
/> />
</label> </label>
{form.formState.errors.vatsimCid && ( {form.formState.errors.vatsimCid && (
<p className="text-error"> <p className="text-error">
{form.formState.errors.vatsimCid.message} {form.formState.errors.vatsimCid.message}
</p> </p>
)} )}
</div> </div>
<div className="card-actions justify-center pt-6 mt-auto"> <div className="card-actions justify-center pt-6 mt-auto">
<Button <Button
className="btn-sm btn-wide btn-outline btn-primary" className="btn-sm btn-wide btn-outline btn-primary"
isLoading={vatsimLoading} isLoading={vatsimLoading}
disabled={!form.formState.isDirty} disabled={!form.formState.isDirty}
role="submit" role="submit"
> >
<BookmarkIcon /> Speichern <BookmarkIcon /> Speichern
</Button> </Button>
</div> </div>
</form> </form>
); );
}; };
export const PasswordForm = ({ user }: { user: User }) => { export const PasswordForm = ({ user }: { user: User }) => {
const schema = z.object({ const schema = z.object({
password: z.string().min(2).max(30), password: z.string().min(2).max(30),
newPassword: z.string().min(2).max(30), newPassword: z.string().min(2).max(30),
newPasswordConfirm: z.string().min(2).max(30), newPasswordConfirm: z.string().min(2).max(30),
}); });
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
type IFormInput = z.infer<typeof schema>; type IFormInput = z.infer<typeof schema>;
const form = useForm<IFormInput>({ const form = useForm<IFormInput>({
defaultValues: {}, defaultValues: {},
resolver: zodResolver(schema), resolver: zodResolver(schema),
}); });
return ( return (
<form <form
className="card-body" className="card-body"
onSubmit={form.handleSubmit(async (values) => { onSubmit={form.handleSubmit(async (values) => {
setIsLoading(true); setIsLoading(true);
const result = await changePassword( const result = await changePassword(
values.password, values.password,
values.newPassword values.newPassword,
); );
form.reset(values); form.reset(values);
setIsLoading(false); setIsLoading(false);
if (result.error) { if (result.error) {
form.setError("password", { form.setError("password", {
type: "manual", type: "manual",
message: result.error, message: result.error,
}); });
} else if (result.success) { } else if (result.success) {
toast.success("Dein Passwort wurde geändert!", { toast.success("Dein Passwort wurde geändert!", {
style: { style: {
background: "var(--color-base-100)", background: "var(--color-base-100)",
color: "var(--color-base-content)", color: "var(--color-base-content)",
}, },
}); });
} }
})} })}
> >
<h2 className="card-title"> <h2 className="card-title">
<LockClosedIcon className="w-5 h-5" /> Password Ändern <LockClosedIcon className="w-5 h-5" /> Password Ändern
</h2> </h2>
<div className=""> <div className="">
<label className="floating-label w-full mt-5 mb-5"> <label className="floating-label w-full mt-5 mb-5">
<span className="text-lg flex items-center gap-2"> <span className="text-lg flex items-center gap-2">
<LockOpen2Icon /> Aktuelles Passwort <LockOpen2Icon /> Aktuelles Passwort
</span> </span>
<input <input
{...form.register("password")} {...form.register("password")}
type="text" type="text"
className="input input-bordered w-full" className="input input-bordered w-full"
defaultValue={""} defaultValue={""}
/> />
</label> </label>
{form.formState.errors.password && ( {form.formState.errors.password && (
<p className="text-error">{form.formState.errors.password.message}</p> <p className="text-error">{form.formState.errors.password.message}</p>
)} )}
<label className="floating-label w-full mb-5"> <label className="floating-label w-full mb-5">
<span className="text-lg flex items-center gap-2"> <span className="text-lg flex items-center gap-2">
<LockOpen1Icon /> Neues Passwort <LockOpen1Icon /> Neues Passwort
</span> </span>
<input <input
{...form.register("newPassword")} {...form.register("newPassword")}
type="text" type="text"
className="input input-bordered w-full" className="input input-bordered w-full"
defaultValue={""} defaultValue={""}
/> />
</label> </label>
{form.formState.errors.newPassword && ( {form.formState.errors.newPassword && (
<p className="text-error"> <p className="text-error">
{form.formState.errors.newPassword?.message} {form.formState.errors.newPassword?.message}
</p> </p>
)} )}
<label className="floating-label w-full"> <label className="floating-label w-full">
<span className="text-lg flex items-center gap-2"> <span className="text-lg flex items-center gap-2">
<LockOpen1Icon /> Passwort wiederholen <LockOpen1Icon /> Passwort wiederholen
</span> </span>
<input <input
{...form.register("newPasswordConfirm")} {...form.register("newPasswordConfirm")}
type="text" type="text"
className="input input-bordered w-full" className="input input-bordered w-full"
defaultValue={""} defaultValue={""}
/> />
</label> </label>
{form.formState.errors.newPasswordConfirm && ( {form.formState.errors.newPasswordConfirm && (
<p className="text-error"> <p className="text-error">
{form.formState.errors.newPasswordConfirm?.message} {form.formState.errors.newPasswordConfirm?.message}
</p> </p>
)} )}
<div className="card-actions justify-center pt-6"> <div className="card-actions justify-center pt-6">
<Button <Button
role="submit" role="submit"
className="btn-sm btn-wide btn-outline btn-primary" className="btn-sm btn-wide btn-outline btn-primary"
disabled={!form.formState.isDirty} disabled={!form.formState.isDirty}
isLoading={isLoading} isLoading={isLoading}
> >
<BookmarkIcon /> Speichern <BookmarkIcon /> Speichern
</Button> </Button>
</div> </div>
</div> </div>
</form> </form>
); );
}; };

View File

@@ -64,7 +64,6 @@ export function PaginatedTable<TData>({
useImperativeHandle(ref, () => ({ useImperativeHandle(ref, () => ({
refresh: () => { refresh: () => {
console.log("refresh");
RefreshTableData(); RefreshTableData();
}, },
})); }));

View File

@@ -1,67 +1,66 @@
import { import {
AuthOptions, AuthOptions,
getServerSession as getNextAuthServerSession, getServerSession as getNextAuthServerSession,
} from 'next-auth'; } from "next-auth";
import { PrismaAdapter } from '@next-auth/prisma-adapter'; import { PrismaAdapter } from "@next-auth/prisma-adapter";
import Credentials from 'next-auth/providers/credentials'; import Credentials from "next-auth/providers/credentials";
import { PrismaClient } from '@repo/db'; import { PrismaClient } from "@repo/db";
import bcrypt from 'bcryptjs'; import bcrypt from "bcryptjs";
const prisma = new PrismaClient(); const prisma = new PrismaClient();
export const options: AuthOptions = { export const options: AuthOptions = {
providers: [ providers: [
Credentials({ Credentials({
credentials: { credentials: {
email: { label: 'Email', type: 'email', placeholder: 'E-Mail' }, email: { label: "Email", type: "email", placeholder: "E-Mail" },
password: { label: 'Password', type: 'password' }, password: { label: "Password", type: "password" },
}, },
async authorize(credentials, req) { async authorize(credentials, req) {
try { try {
if (!credentials) throw new Error('No credentials provided'); if (!credentials) throw new Error("No credentials provided");
const user = await prisma.user.findFirstOrThrow({ const user = await prisma.user.findFirstOrThrow({
where: { email: credentials.email }, where: { email: credentials.email },
}); });
if (bcrypt.compareSync(credentials.password, user.password)) { if (bcrypt.compareSync(credentials.password, user.password)) {
console.log('User found and password correct', user); return user;
return user; }
} return null;
return null; } catch (error) {
} catch (error) { return null;
return null; }
} },
}, }),
}), ],
], secret: process.env.NEXTAUTH_SECRET,
secret: process.env.NEXTAUTH_SECRET, session: {
session: { strategy: "jwt",
strategy: 'jwt', maxAge: 30 * 24 * 60 * 60,
maxAge: 30 * 24 * 60 * 60, },
},
adapter: PrismaAdapter(prisma as any), adapter: PrismaAdapter(prisma as any),
callbacks: { callbacks: {
jwt: async ({ token, user }) => { jwt: async ({ token, user }) => {
if (user && 'firstname' in user) { if (user && "firstname" in user) {
return { return {
...token, ...token,
...user, ...user,
}; };
} }
return token; return token;
}, },
session: async ({ session, user, token }) => { session: async ({ session, user, token }) => {
return { return {
...session, ...session,
user: token, user: token,
}; };
}, },
}, },
pages: { pages: {
signIn: '/login', signIn: "/login",
signOut: '/logout', signOut: "/logout",
error: '/authError', error: "/authError",
newUser: '/register', newUser: "/register",
}, },
} satisfies AuthOptions; } satisfies AuthOptions;
export const getServerSession = async () => getNextAuthServerSession(options); export const getServerSession = async () => getNextAuthServerSession(options);

View File

@@ -5,15 +5,11 @@ import { services } from "../../../(auth)/oauth/page";
export const POST = async (req: NextRequest) => { export const POST = async (req: NextRequest) => {
const form = new URLSearchParams(await req.text()); const form = new URLSearchParams(await req.text());
console.log("POST body:");
const client = new PrismaClient(); const client = new PrismaClient();
const accessToken = form.get("token") || form.get("code"); const accessToken = form.get("token") || form.get("code");
const clientId = form.get("client_id"); const clientId = form.get("client_id");
const clientSecret = form.get("client_secret"); const clientSecret = form.get("client_secret");
console.log("Access token:", accessToken);
console.log("Client ID:", clientId);
console.log("Secret:", clientSecret);
const service = services.find((s) => s.id === clientId); const service = services.find((s) => s.id === clientId);
if (!accessToken) if (!accessToken)