Wartungsmodus funktional #9

This commit is contained in:
nocnico
2025-07-03 21:23:37 +02:00
parent 84d326ddf5
commit 44d51cd1a8
4 changed files with 98 additions and 12 deletions

View File

@@ -8,16 +8,35 @@ import { Settings } from "_components/navbar/Settings";
import ModeSwitchDropdown from "_components/navbar/ModeSwitchDropdown"; import ModeSwitchDropdown from "_components/navbar/ModeSwitchDropdown";
import AdminPanel from "_components/navbar/AdminPanel"; import AdminPanel from "_components/navbar/AdminPanel";
import { getServerSession } from "api/auth/[...nextauth]/auth"; import { getServerSession } from "api/auth/[...nextauth]/auth";
import { prisma } from "@repo/db";
export default async function Navbar() { export default async function Navbar() {
const session = await getServerSession(); const session = await getServerSession();
const latestNotam = await prisma.notam.findFirst({
orderBy: { createdAt: "desc" },
});
let wartungsarbeiten = false;
if (
latestNotam &&
latestNotam.wartungsmodus &&
latestNotam.active &&
((latestNotam.showUntilActive && new Date(latestNotam.showUntil) > new Date()) ||
!latestNotam.showUntilActive)
) {
wartungsarbeiten = true;
}
return ( return (
<div className="navbar bg-base-100 shadow-sm flex gap-5 justify-between"> <div className="navbar bg-base-100 shadow-sm flex gap-5 justify-between">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<ModeSwitchDropdown /> <ModeSwitchDropdown />
{session?.user.permissions.includes("ADMIN_KICK") && <AdminPanel />} {session?.user.permissions.includes("ADMIN_KICK") && <AdminPanel />}
</div> </div>
{wartungsarbeiten && (
<p className="alert alert-error shadow-lg font-bold">Wartungsmodus aktiv!</p>
)}
<div className="flex items-center gap-5"> <div className="flex items-center gap-5">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<Audio /> <Audio />

View File

@@ -5,6 +5,7 @@ import { NextAuthSessionProvider } from "./_components/AuthSessionProvider";
import { getServerSession } from "./api/auth/[...nextauth]/auth"; import { getServerSession } from "./api/auth/[...nextauth]/auth";
import { Toaster } from "react-hot-toast"; import { Toaster } from "react-hot-toast";
import { QueryProvider } from "_components/QueryProvider"; import { QueryProvider } from "_components/QueryProvider";
import { prisma } from "@repo/db";
import { Error as ErrorComp } from "_components/Error"; import { Error as ErrorComp } from "_components/Error";
const geistSans = localFont({ const geistSans = localFont({
@@ -27,6 +28,22 @@ export default async function RootLayout({
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
const session = await getServerSession(); const session = await getServerSession();
const latestNotam = await prisma.notam.findFirst({
orderBy: { createdAt: "desc" },
});
let wartungsarbeiten = false;
if (
latestNotam &&
latestNotam.wartungsmodus &&
latestNotam.active &&
((latestNotam.showUntilActive && new Date(latestNotam.showUntil) > new Date()) ||
!latestNotam.showUntilActive)
) {
wartungsarbeiten = true;
}
return ( return (
<html lang="de" data-theme="dark"> <html lang="de" data-theme="dark">
<body <body
@@ -53,7 +70,20 @@ export default async function RootLayout({
{session?.user.isBanned && ( {session?.user.isBanned && (
<ErrorComp title="You are banned from using this service" statusCode={403} /> <ErrorComp title="You are banned from using this service" statusCode={403} />
)} )}
{!session?.user.isBanned && children} {!session?.user.isBanned &&
wartungsarbeiten &&
!session?.user.permissions.includes("ADMIN_MESSAGE") && (
<ErrorComp
title={
latestNotam?.message ||
"Wir führen aktuell Wartungsarbeiten am System durch, versuche es später erneut."
}
statusCode={503}
/>
)}
{!session?.user.isBanned &&
(!wartungsarbeiten || session?.user.permissions.includes("ADMIN_MESSAGE")) &&
children}
</NextAuthSessionProvider> </NextAuthSessionProvider>
</QueryProvider> </QueryProvider>
</body> </body>

View File

@@ -11,6 +11,10 @@ const fetchMainMessage = async () => {
export const WarningAlert = async () => { export const WarningAlert = async () => {
const mainMessage = await fetchMainMessage(); const mainMessage = await fetchMainMessage();
if (mainMessage?.showUntilActive && new Date(mainMessage.showUntil) < new Date()) {
return <></>;
}
let msgColor; let msgColor;
switch (mainMessage?.color) { switch (mainMessage?.color) {
case "WARNING": case "WARNING":
@@ -29,13 +33,15 @@ export const WarningAlert = async () => {
msgColor = "alert alert-soft ml-3 py-2 flex items-center gap-2"; msgColor = "alert alert-soft ml-3 py-2 flex items-center gap-2";
} }
if (mainMessage?.message == "" || !mainMessage) { if ((mainMessage?.message == "" && !mainMessage?.wartungsmodus) || !mainMessage) {
return <></>; return <></>;
} else { } else {
return ( return (
<div role="alert" className={msgColor}> <div role="alert" className={msgColor}>
<MessageCircleWarning /> <MessageCircleWarning />
<span className="font-bold m-0">{mainMessage?.message}</span> <span className="font-bold m-0">
{mainMessage?.wartungsmodus ? "Wartungsmodus aktiv!" : mainMessage?.message}
</span>
</div> </div>
); );
} }

View File

@@ -5,6 +5,9 @@ import { CustomErrorBoundary } from "_components/ErrorBoundary";
import { Toaster } from "react-hot-toast"; import { Toaster } from "react-hot-toast";
import "./globals.css"; import "./globals.css";
import { QueryProvider } from "_components/QueryClient"; import { QueryProvider } from "_components/QueryClient";
import { prisma } from "@repo/db";
import React from "react";
import { Error as ErrorComp } from "_components/Error";
const geistSans = Geist({ const geistSans = Geist({
variable: "--font-geist-sans", variable: "--font-geist-sans",
@@ -23,20 +26,48 @@ const RootLayout = async ({
}>) => { }>) => {
const session = await getServerSession(); const session = await getServerSession();
const latestNotam = await prisma.notam.findFirst({
orderBy: { createdAt: "desc" },
});
let wartungsarbeiten = false;
if (
latestNotam &&
latestNotam.wartungsmodus &&
latestNotam.active &&
((latestNotam.showUntilActive && new Date(latestNotam.showUntil) > new Date()) ||
!latestNotam.showUntilActive)
) {
wartungsarbeiten = true;
}
return ( return (
<html lang="en" data-theme="dark"> <html lang="en" data-theme="dark">
<NextAuthSessionProvider session={session}> <NextAuthSessionProvider session={session}>
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`}> <body className={`${geistSans.variable} ${geistMono.variable} antialiased`}>
<div> {wartungsarbeiten && !session?.user.permissions.includes("ADMIN_MESSAGE") && (
<Toaster <ErrorComp
containerStyle={{ zIndex: "999999999" }} title={
position="top-center" latestNotam?.message ||
reverseOrder={false} "Wir führen aktuell Wartungsarbeiten am System durch, versuche es später erneut."
}
statusCode={503}
/> />
</div> )}
<QueryProvider> {(!wartungsarbeiten || session?.user.permissions.includes("ADMIN_MESSAGE")) && (
<CustomErrorBoundary>{children}</CustomErrorBoundary> <>
</QueryProvider> <div>
<Toaster
containerStyle={{ zIndex: "999999999" }}
position="top-center"
reverseOrder={false}
/>
</div>
<QueryProvider>
<CustomErrorBoundary>{children}</CustomErrorBoundary>
</QueryProvider>
</>
)}
</body> </body>
</NextAuthSessionProvider> </NextAuthSessionProvider>
</html> </html>