From f6cad23bf4db7785ddc63364044978987f7baff8 Mon Sep 17 00:00:00 2001 From: nocnico Date: Mon, 3 Mar 2025 03:59:44 +0100 Subject: [PATCH] Global Messages --- .../admin/message/_components/messageForm.tsx | 107 ++++++++++++++++++ apps/hub/app/(app)/admin/message/action.tsx | 36 ++++++ apps/hub/app/(app)/admin/message/page.tsx | 19 ++++ apps/hub/app/_components/Nav.tsx | 7 +- apps/hub/app/_components/ui/PageAlert.tsx | 57 ++++++++++ .../database/prisma/schema/message.prisma | 19 ++++ 6 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 apps/hub/app/(app)/admin/message/_components/messageForm.tsx create mode 100644 apps/hub/app/(app)/admin/message/action.tsx create mode 100644 apps/hub/app/(app)/admin/message/page.tsx create mode 100644 apps/hub/app/_components/ui/PageAlert.tsx create mode 100644 packages/database/prisma/schema/message.prisma diff --git a/apps/hub/app/(app)/admin/message/_components/messageForm.tsx b/apps/hub/app/(app)/admin/message/_components/messageForm.tsx new file mode 100644 index 00000000..3feb36e0 --- /dev/null +++ b/apps/hub/app/(app)/admin/message/_components/messageForm.tsx @@ -0,0 +1,107 @@ +"use client"; + +import { zodResolver } from "@hookform/resolvers/zod"; +import { Message } from "@repo/db"; +import { MessageOptionalDefaultsSchema } from "@repo/db/zod"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; +import { addMessage, disableMessage } from "../action"; +import { useState } from "react"; + +export const MessageForm = ({ message }: { message?: Message }) => { + const [isSubmitting, setIsSubmitting] = useState(false); + + const getDefaultShowUntilDate = () => { + const date = new Date(); + date.setDate(date.getDate() + 5); + return date; + }; + + const disableMessageClient = async () => { + disableMessage(); + }; + + const form = useForm>({ + resolver: zodResolver(MessageOptionalDefaultsSchema), + defaultValues: { + message: message?.message, + color: message?.color, + isMainMsg: true, + active: true, + showUntil: getDefaultShowUntilDate(), + }, + }); + + return ( +
{ + setIsSubmitting(true); + try { + const msg = await addMessage(values); + } catch (error) { + setIsSubmitting(false); + console.error("Failed to add message", error); + } + })} + className="grid grid-cols-6 gap-3" + > + +
+
+ + Info + + Success + + Warning + + Error +
+
+ + +
+
+
+ ); +}; diff --git a/apps/hub/app/(app)/admin/message/action.tsx b/apps/hub/app/(app)/admin/message/action.tsx new file mode 100644 index 00000000..eff17da8 --- /dev/null +++ b/apps/hub/app/(app)/admin/message/action.tsx @@ -0,0 +1,36 @@ +"use server"; +import { prisma, Prisma } from "@repo/db"; + +export const addMessage = async (message: Prisma.MessageCreateInput) => { + try { + // Set all current messages with isMainMsg=true to active=false + await prisma.message.updateMany({ + where: { isMainMsg: true }, + data: { active: false }, + }); + + await prisma.message.create({ + data: { + message: message.message, + color: message.color, + isMainMsg: true, + active: true, + showUntil: new Date().toISOString(), + }, + }); + } catch (error) { + throw new Error("Failed to add message"); + } +}; + +export const disableMessage = async () => { + try { + // Set all current messages with isMainMsg=true to active=false + await prisma.message.updateMany({ + where: { isMainMsg: true }, + data: { active: false }, + }); + } catch (error) { + throw new Error("Failed to disable message"); + } +}; diff --git a/apps/hub/app/(app)/admin/message/page.tsx b/apps/hub/app/(app)/admin/message/page.tsx new file mode 100644 index 00000000..c60c48d4 --- /dev/null +++ b/apps/hub/app/(app)/admin/message/page.tsx @@ -0,0 +1,19 @@ +import { MessageSquareWarning } from "lucide-react"; +import { MessageForm } from "./_components/messageForm"; + +export default function MessagePage() { + return ( +
+
+

+ Service Nachrichten +

+
+
+
+ +
+
+
+ ); +} diff --git a/apps/hub/app/_components/Nav.tsx b/apps/hub/app/_components/Nav.tsx index 7851dc13..5b3e9017 100644 --- a/apps/hub/app/_components/Nav.tsx +++ b/apps/hub/app/_components/Nav.tsx @@ -7,10 +7,11 @@ import { ReaderIcon, } from "@radix-ui/react-icons"; import Link from "next/link"; +import { WarningAlert } from "./ui/PageAlert"; export const VerticalNav = () => { return ( -