removed ui, docs package
This commit is contained in:
@@ -1,11 +1,10 @@
|
||||
import { getServerSession } from "../../api/auth/[...nextauth]/auth";
|
||||
import { PrismaClient } from "@repo/db";
|
||||
import { prisma } from "@repo/db";
|
||||
import { KursItem } from "../events/_components/item";
|
||||
import { RocketIcon } from "lucide-react";
|
||||
import { eventCompleted } from "@repo/ui";
|
||||
import { eventCompleted } from "../../../helper/events";
|
||||
|
||||
export default async () => {
|
||||
const prisma = new PrismaClient();
|
||||
const page = async () => {
|
||||
const session = await getServerSession();
|
||||
if (!session) return null;
|
||||
const user = await prisma.user.findUnique({
|
||||
@@ -63,10 +62,7 @@ export default async () => {
|
||||
|
||||
const filteredEvents = events.filter((event) => {
|
||||
if (eventCompleted(event, event.participants[0])) return false;
|
||||
if (
|
||||
event.type === "OBLIGATED_COURSE" &&
|
||||
!eventCompleted(event, event.participants[0])
|
||||
)
|
||||
if (event.type === "OBLIGATED_COURSE" && !eventCompleted(event, event.participants[0]))
|
||||
return true;
|
||||
return false;
|
||||
});
|
||||
@@ -95,3 +91,5 @@ export default async () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default page;
|
||||
|
||||
@@ -1,32 +1,17 @@
|
||||
"use client";
|
||||
import { useEffect } from "react";
|
||||
import {
|
||||
CheckCircledIcon,
|
||||
CalendarIcon,
|
||||
EnterIcon,
|
||||
} from "@radix-ui/react-icons";
|
||||
import { Event, EventAppointment, Participant, prisma, User } from "@repo/db";
|
||||
import { CheckCircledIcon, CalendarIcon, EnterIcon } from "@radix-ui/react-icons";
|
||||
import { Event, EventAppointment, Participant, User } from "@repo/db";
|
||||
import { cn } from "../../../../helper/cn";
|
||||
import { inscribeToMoodleCourse, upsertParticipant } from "../actions";
|
||||
import {
|
||||
Check,
|
||||
Clock10Icon,
|
||||
Cross,
|
||||
EyeIcon,
|
||||
MessageCircleWarning,
|
||||
TriangleAlert,
|
||||
} from "lucide-react";
|
||||
import { Check, Clock10Icon, EyeIcon, TriangleAlert } from "lucide-react";
|
||||
import { useForm } from "react-hook-form";
|
||||
import {
|
||||
ParticipantOptionalDefaults,
|
||||
ParticipantOptionalDefaultsSchema,
|
||||
} from "@repo/db/zod";
|
||||
import { ParticipantOptionalDefaults, ParticipantOptionalDefaultsSchema } from "@repo/db/zod";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { Select } from "../../../_components/ui/Select";
|
||||
import toast from "react-hot-toast";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { eventCompleted } from "@repo/ui";
|
||||
import { se } from "date-fns/locale";
|
||||
import { eventCompleted } from "../../../../helper/events";
|
||||
|
||||
interface ModalBtnProps {
|
||||
title: string;
|
||||
@@ -91,12 +76,11 @@ const ModalBtn = ({
|
||||
const selectedAppointment = selectedAppointments[0];
|
||||
const selectedDate = dates.find(
|
||||
(date) =>
|
||||
date.id === selectAppointmentForm.watch("eventAppointmentId") ||
|
||||
selectedAppointment?.id,
|
||||
date.id === selectAppointmentForm.watch("eventAppointmentId") || selectedAppointment?.id,
|
||||
);
|
||||
const ownIndexInParticipantList = (selectedDate as any)?.Participants?.findIndex(
|
||||
(p: Participant) => p.userId === user.id,
|
||||
);
|
||||
const ownIndexInParticipantList = (
|
||||
selectedDate as any
|
||||
)?.Participants?.findIndex((p: Participant) => p.userId === user.id);
|
||||
|
||||
const ownPlaceInParticipantList =
|
||||
ownIndexInParticipantList === -1
|
||||
@@ -154,9 +138,7 @@ const ModalBtn = ({
|
||||
)}
|
||||
{}
|
||||
{!dates.length && (
|
||||
<p className="text-center text-info">
|
||||
Keine Termine verfügbar
|
||||
</p>
|
||||
<p className="text-center text-info">Keine Termine verfügbar</p>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
@@ -174,13 +156,9 @@ const ModalBtn = ({
|
||||
role="alert"
|
||||
className="py-4 my-5 flex items-center gap-2 justify-center border alert alert-error alert-outline"
|
||||
>
|
||||
<TriangleAlert
|
||||
className="h-6 w-6 shrink-0 stroke-current"
|
||||
fill="none"
|
||||
/>
|
||||
Dieser Termin ist ausgebucht, wahrscheinlich wirst du nicht
|
||||
teilnehmen können. (Listenplatz: {ownPlaceInParticipantList}{" "}
|
||||
, max. {event.maxParticipants})
|
||||
<TriangleAlert className="h-6 w-6 shrink-0 stroke-current" fill="none" />
|
||||
Dieser Termin ist ausgebucht, wahrscheinlich wirst du nicht teilnehmen können.
|
||||
(Listenplatz: {ownPlaceInParticipantList} , max. {event.maxParticipants})
|
||||
</p>
|
||||
)}
|
||||
{selectedAppointment && !participant?.appointmentCancelled && (
|
||||
@@ -188,11 +166,7 @@ const ModalBtn = ({
|
||||
<div className="flex items-center gap-2 justify-center">
|
||||
<p>Dein Ausgewähler Termin</p>
|
||||
|
||||
<p>
|
||||
{new Date(
|
||||
selectedAppointment.appointmentDate,
|
||||
).toLocaleString()}
|
||||
</p>
|
||||
<p>{new Date(selectedAppointment.appointmentDate).toLocaleString()}</p>
|
||||
<button
|
||||
onClick={async () => {
|
||||
await upsertParticipant({
|
||||
@@ -204,8 +178,7 @@ const ModalBtn = ({
|
||||
{
|
||||
data: {
|
||||
appointmentId: selectedAppointment.id,
|
||||
appointmentDate:
|
||||
selectedAppointment.appointmentDate,
|
||||
appointmentDate: selectedAppointment.appointmentDate,
|
||||
},
|
||||
user: `${user?.firstname} ${user?.lastname} - ${user?.publicId}`,
|
||||
event: "Termin abgesagt",
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { prisma } from "@repo/db";
|
||||
import { getServerSession } from "../../api/auth/[...nextauth]/auth";
|
||||
import { PrismaClient } from "@repo/db";
|
||||
import { KursItem } from "./_components/item";
|
||||
import { RocketIcon } from "@radix-ui/react-icons";
|
||||
|
||||
export default async () => {
|
||||
const prisma = new PrismaClient();
|
||||
const page = async () => {
|
||||
const session = await getServerSession();
|
||||
if (!session) return null;
|
||||
const user = await prisma.user.findUnique({
|
||||
@@ -86,3 +85,5 @@ export default async () => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default page;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
"use server";
|
||||
import { prisma, Prisma, PrismaClient } from "@repo/db";
|
||||
import { prisma, Prisma } from "@repo/db";
|
||||
import { getServerSession } from "../../api/auth/[...nextauth]/auth";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
export const unlinkDiscord = async (userId: string) => {
|
||||
const client = new PrismaClient();
|
||||
await client.discordAccount.deleteMany({
|
||||
await prisma.discordAccount.deleteMany({
|
||||
where: {
|
||||
userId,
|
||||
},
|
||||
@@ -16,9 +15,7 @@ export const updateUser = async (changes: Prisma.UserUpdateInput) => {
|
||||
const session = await getServerSession();
|
||||
if (!session) return null;
|
||||
|
||||
const client = new PrismaClient();
|
||||
|
||||
await client.user.update({
|
||||
await prisma.user.update({
|
||||
where: {
|
||||
id: session.user.id,
|
||||
},
|
||||
@@ -26,10 +23,7 @@ export const updateUser = async (changes: Prisma.UserUpdateInput) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const changePassword = async (
|
||||
oldPassword: string,
|
||||
newPassword: string,
|
||||
) => {
|
||||
export const changePassword = async (oldPassword: string, newPassword: string) => {
|
||||
const session = await getServerSession();
|
||||
if (!session)
|
||||
return {
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
import { prisma } from "@repo/db";
|
||||
import { getServerSession } from "../../api/auth/[...nextauth]/auth";
|
||||
import { PrismaClient } from "@repo/db";
|
||||
import {
|
||||
ProfileForm,
|
||||
SocialForm,
|
||||
PasswordForm,
|
||||
PilotForm,
|
||||
} from "./_components/forms";
|
||||
import { ProfileForm, SocialForm, PasswordForm, PilotForm } from "./_components/forms";
|
||||
import { GearIcon } from "@radix-ui/react-icons";
|
||||
|
||||
export const page = async () => {
|
||||
const prisma = new PrismaClient();
|
||||
const session = await getServerSession();
|
||||
if (!session) return null;
|
||||
const user = await prisma.user.findFirst({
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
import { generateUUID } from "../../../../helper/uuid";
|
||||
import { getServerSession } from "../../../api/auth/[...nextauth]/auth";
|
||||
import { Service } from "../page";
|
||||
import { PrismaClient } from "@repo/db";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
import { prisma } from "@repo/db";
|
||||
|
||||
export const generateToken = async (service: Service) => {
|
||||
const session = await getServerSession();
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"use server";
|
||||
import { PrismaClient } from "@repo/db";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
import { prisma, PrismaClient } from "@repo/db";
|
||||
|
||||
export async function getData(
|
||||
model: keyof PrismaClient,
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import {
|
||||
AuthOptions,
|
||||
getServerSession as getNextAuthServerSession,
|
||||
} from "next-auth";
|
||||
import { AuthOptions, getServerSession as getNextAuthServerSession } from "next-auth";
|
||||
import { PrismaAdapter } from "@next-auth/prisma-adapter";
|
||||
import Credentials from "next-auth/providers/credentials";
|
||||
import { PrismaClient } from "@repo/db";
|
||||
import { prisma } from "@repo/db";
|
||||
import bcrypt from "bcryptjs";
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
export const options: AuthOptions = {
|
||||
providers: [
|
||||
@@ -15,7 +11,7 @@ export const options: AuthOptions = {
|
||||
email: { label: "Email", type: "email", placeholder: "E-Mail" },
|
||||
password: { label: "Password", type: "password" },
|
||||
},
|
||||
async authorize(credentials, req) {
|
||||
async authorize(credentials) {
|
||||
try {
|
||||
if (!credentials) throw new Error("No credentials provided");
|
||||
const user = await prisma.user.findFirstOrThrow({
|
||||
|
||||
@@ -1,92 +1,82 @@
|
||||
import axios, { AxiosError } from 'axios';
|
||||
import { NextRequest, NextResponse } from 'next/server';
|
||||
import { DiscordAccount, PrismaClient } from '@repo/db';
|
||||
import { getServerSession } from '../auth/[...nextauth]/auth';
|
||||
import axios, { AxiosError } from "axios";
|
||||
import { NextRequest, NextResponse } from "next/server";
|
||||
import { DiscordAccount, prisma, PrismaClient } from "@repo/db";
|
||||
import { getServerSession } from "../auth/[...nextauth]/auth";
|
||||
|
||||
export const GET = async (req: NextRequest) => {
|
||||
const session = await getServerSession();
|
||||
const prisma = new PrismaClient();
|
||||
const code = req.nextUrl.searchParams.get('code');
|
||||
const session = await getServerSession();
|
||||
const code = req.nextUrl.searchParams.get("code");
|
||||
|
||||
if (!session) {
|
||||
return NextResponse.redirect(`${process.env.NEXTAUTH_URL}/login`);
|
||||
}
|
||||
if (!session) {
|
||||
return NextResponse.redirect(`${process.env.NEXTAUTH_URL}/login`);
|
||||
}
|
||||
|
||||
if (
|
||||
!process.env.DISCORD_OAUTH_CLIENT_ID ||
|
||||
!process.env.DISCORD_OAUTH_SECRET ||
|
||||
!process.env.DISCORD_REDIRECT ||
|
||||
!code
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: 'Discord OAuth not configured',
|
||||
},
|
||||
{
|
||||
status: 500,
|
||||
}
|
||||
);
|
||||
}
|
||||
if (
|
||||
!process.env.DISCORD_OAUTH_CLIENT_ID ||
|
||||
!process.env.DISCORD_OAUTH_SECRET ||
|
||||
!process.env.DISCORD_REDIRECT ||
|
||||
!code
|
||||
) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "Discord OAuth not configured",
|
||||
},
|
||||
{
|
||||
status: 500,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
const params = new URLSearchParams({
|
||||
client_id: process.env.DISCORD_OAUTH_CLIENT_ID,
|
||||
client_secret: process.env.DISCORD_OAUTH_SECRET,
|
||||
redirect_uri: process.env.DISCORD_REDIRECT,
|
||||
grant_type: 'authorization_code',
|
||||
code,
|
||||
});
|
||||
const params = new URLSearchParams({
|
||||
client_id: process.env.DISCORD_OAUTH_CLIENT_ID,
|
||||
client_secret: process.env.DISCORD_OAUTH_SECRET,
|
||||
redirect_uri: process.env.DISCORD_REDIRECT,
|
||||
grant_type: "authorization_code",
|
||||
code,
|
||||
});
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
};
|
||||
try {
|
||||
const { data: authData } = await axios.post(
|
||||
'https://discord.com/api/oauth2/token',
|
||||
params,
|
||||
{
|
||||
headers,
|
||||
}
|
||||
);
|
||||
const headers = {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
};
|
||||
try {
|
||||
const { data: authData } = await axios.post("https://discord.com/api/oauth2/token", params, {
|
||||
headers,
|
||||
});
|
||||
|
||||
const { data: discordUser } = await axios.get(
|
||||
'https://discord.com/api/users/@me',
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${authData.access_token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
const { data: discordUser } = await axios.get("https://discord.com/api/users/@me", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${authData.access_token}`,
|
||||
},
|
||||
});
|
||||
|
||||
const discordObject = {
|
||||
userId: session.user.id,
|
||||
accessToken: authData.access_token,
|
||||
refreshToken: authData.refresh_token,
|
||||
discordId: discordUser.id,
|
||||
email: discordUser.email,
|
||||
avatar: discordUser.avatar,
|
||||
username: discordUser.username,
|
||||
globalName: discordUser.global_name,
|
||||
verified: discordUser.verified,
|
||||
tokenType: authData.token_type,
|
||||
} as DiscordAccount;
|
||||
const discordObject = {
|
||||
userId: session.user.id,
|
||||
accessToken: authData.access_token,
|
||||
refreshToken: authData.refresh_token,
|
||||
discordId: discordUser.id,
|
||||
email: discordUser.email,
|
||||
avatar: discordUser.avatar,
|
||||
username: discordUser.username,
|
||||
globalName: discordUser.global_name,
|
||||
verified: discordUser.verified,
|
||||
tokenType: authData.token_type,
|
||||
} as DiscordAccount;
|
||||
|
||||
const discord = await prisma.discordAccount.upsert({
|
||||
where: { discordId: discordUser.id },
|
||||
update: discordObject, // Updates if found
|
||||
create: discordObject, // Creates if not found
|
||||
});
|
||||
return NextResponse.redirect(
|
||||
`${process.env.NEXTAUTH_URL}/settings/account`
|
||||
);
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "Couldn't connect to Discord",
|
||||
},
|
||||
{
|
||||
status: 500,
|
||||
}
|
||||
);
|
||||
}
|
||||
const discord = await prisma.discordAccount.upsert({
|
||||
where: { discordId: discordUser.id },
|
||||
update: discordObject, // Updates if found
|
||||
create: discordObject, // Creates if not found
|
||||
});
|
||||
return NextResponse.redirect(`${process.env.NEXTAUTH_URL}/settings/account`);
|
||||
} catch (error: any) {
|
||||
console.error(error);
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "Couldn't connect to Discord",
|
||||
},
|
||||
{
|
||||
status: 500,
|
||||
},
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
8
apps/hub/helper/events.ts
Normal file
8
apps/hub/helper/events.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Event, Participant } from "@repo/db";
|
||||
|
||||
export const eventCompleted = (event: Event, participant?: Participant) => {
|
||||
if (!participant) return false;
|
||||
if (event.finisherMoodleCourseId && !participant.finisherMoodleCurseCompleted) return false;
|
||||
if (event.hasPresenceEvents && !participant.attended) return false;
|
||||
return true;
|
||||
};
|
||||
Reference in New Issue
Block a user