diff --git a/app/layout.tsx b/app/layout.tsx
index 7b2ae02..f9cb780 100644
--- a/app/layout.tsx
+++ b/app/layout.tsx
@@ -2,7 +2,7 @@ import type { Metadata } from "next";
import { GeistSans } from "geist/font/sans";
import { Toaster } from "@/components/ui/toaster";
import "./globals.css";
-import { ThemeProvider } from "./theme-provider";
+import Providers from "./theme-provider";
export const metadata: Metadata = {
title: "Daphnis",
description: "Artemis score viewer",
@@ -16,14 +16,9 @@ export default function RootLayout({
return (
-
+
{children}
-
+
diff --git a/app/theme-provider.tsx b/app/theme-provider.tsx
index b0ff266..3dbd08e 100644
--- a/app/theme-provider.tsx
+++ b/app/theme-provider.tsx
@@ -1,9 +1,23 @@
"use client";
-import * as React from "react";
-import { ThemeProvider as NextThemesProvider } from "next-themes";
-import { type ThemeProviderProps } from "next-themes/dist/types";
+import { ThemeProvider } from "next-themes";
+import { useEffect, useState } from "react";
-export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
- return {children};
+function Providers({ children }: { children: React.ReactNode }) {
+ const [mounted, setMounted] = useState(false);
+
+ useEffect(() => {
+ setMounted(true);
+ }, []);
+
+ if (!mounted) {
+ return null;
+ }
+ return (
+
+ {children}
+
+ );
}
+
+export default Providers;
diff --git a/components/avatarcustomization/actions.ts b/components/avatarcustomization/actions.ts
index ff0c6b1..a5a571d 100644
--- a/components/avatarcustomization/actions.ts
+++ b/components/avatarcustomization/actions.ts
@@ -7,27 +7,50 @@ import type * as Prisma from "@prisma/client";
// type ChuniScorePlaylog = Prisma.PrismaClient;
// type ChuniStaticMusic = Prisma.PrismaClient;
+export async function getCurrentAvatarParts() {
+ const { user } = await getAuth();
+
+ if (!user || !user.accessCode) {
+ throw new Error("User is not authenticated or accessCode is missing");
+ }
+
+ const avatarParts = await artemis.chuni_profile_data.findMany({
+ where: {
+ user: user.UserId,
+ },
+ select: {
+ avatarSkin: true,
+ avatarBack: true,
+ avatarFace: true,
+ avatarFront: true,
+ avatarHead: true,
+ avatarItem: true,
+ avatarWear: true,
+ },
+ });
+ return avatarParts;
+}
export async function getAllAvatarParts(category: number) {
- const { user } = await getAuth();
-
- if (!user || !user.accessCode) {
- throw new Error("User is not authenticated or accessCode is missing");
- }
-
- const avatarParts = await artemis.chuni_static_avatar.findMany({
- where: {
- category: category
- },
- select: {
- id: true,
- name: true,
- avatarAccessoryId: true,
- category: true,
- version: true,
- iconPath: true,
- texturePath: true,
- }
- });
- return avatarParts;
- }
\ No newline at end of file
+ const { user } = await getAuth();
+
+ if (!user || !user.accessCode) {
+ throw new Error("User is not authenticated or accessCode is missing");
+ }
+
+ const avatarParts = await artemis.chuni_static_avatar.findMany({
+ where: {
+ category: category,
+ },
+ select: {
+ id: true,
+ name: true,
+ avatarAccessoryId: true,
+ category: true,
+ version: true,
+ iconPath: true,
+ texturePath: true,
+ },
+ });
+ return avatarParts;
+}
diff --git a/components/avatarcustomization/page.tsx b/components/avatarcustomization/page.tsx
index 84a4070..d0a0cda 100644
--- a/components/avatarcustomization/page.tsx
+++ b/components/avatarcustomization/page.tsx
@@ -1,9 +1,9 @@
"use client";
-import React, { FC } from "react";
+import React, { FC, useEffect, useState } from "react";
import { chuni_static_avatar } from "@/prisma/schemas/artemis/generated/artemis";
import { Check, ChevronsUpDown } from "lucide-react";
-
+import { getCurrentAvatarParts } from "./actions";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import {
@@ -28,7 +28,6 @@ import {
PopoverTrigger,
} from "@/components/ui/popover";
import { z } from "zod";
-type chunithm_avatar = chuni_static_avatar;
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast } from "../ui/use-toast";
@@ -38,11 +37,12 @@ const getAvatarTextureSrc = (id: number | undefined) => {
return `avatarAccessory/CHU_UI_Avatar_Tex_0${id}.png`;
};
+type chunithm_avatar = chuni_static_avatar;
+
type AvatarSelectionProps = {
avatarHeadSelectionData: {
avatarParts: chunithm_avatar[];
};
-
avatarFaceSelectionData: {
avatarParts: chunithm_avatar[];
};
@@ -86,6 +86,46 @@ export const AvatarCustomization: FC = ({
resolver: zodResolver(FormSchema),
});
+ const [avatarFaceId, setAvatarFaceId] = useState(
+ undefined
+ );
+
+ const [avatarSkinId, setAvatarSkinId] = useState(
+ undefined
+ );
+ const [avatarHeadId, setAvatarHeadId] = useState(
+ undefined
+ );
+ const [avatarWearId, setAvatarWearId] = useState(
+ undefined
+ );
+ const [avatarBackId, setAvatarBackId] = useState(
+ undefined
+ );
+ const [avatarItemId, setAvatarItemId] = useState(
+ undefined
+ );
+
+ useEffect(() => {
+ const fetchAvatarParts = async () => {
+ try {
+ const data = await getCurrentAvatarParts();
+ if (data.length > 0) {
+ setAvatarFaceId(data[0].avatarFace!);
+ setAvatarSkinId(data[0].avatarSkin!);
+ setAvatarHeadId(data[0].avatarHead!);
+ setAvatarWearId(data[0].avatarWear!);
+ setAvatarBackId(data[0].avatarBack!);
+ setAvatarItemId(data[0].avatarItem!);
+ }
+ } catch (error) {
+ console.error("Error fetching avatar parts:", error);
+ }
+ };
+
+ fetchAvatarParts();
+ }, []);
+
function onSubmit(data: z.infer) {
toast({
title: "You submitted the following values:",
@@ -105,67 +145,70 @@ export const AvatarCustomization: FC = ({
AvatarHeadAccessory: {
src: getTexture(
form.watch("AvatarHeadAccessory"),
- "avatarAccessory/CHU_UI_Avatar_Tex_DefaultHead.png"
+ `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarHeadId}.png`
),
className: "avatar_head",
},
AvatarFaceAccessory: {
src: getTexture(
form.watch("AvatarFaceAccessory"),
- "avatarAccessory/CHU_UI_Avatar_Tex_DefaultFace.png"
+ `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarFaceId}.png`
),
className: "avatar_face",
},
AvatarItemAccessoryR: {
src: getTexture(
form.watch("AvatarItemAccessory"),
- "avatarAccessory/CHU_UI_Avatar_Tex_DefaultItem.png"
+ `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarItemId}.png`
),
className: "avatar_item_r ",
},
-
AvatarItemAccessoryL: {
src: getTexture(
form.watch("AvatarItemAccessory"),
- "avatarAccessory/CHU_UI_Avatar_Tex_DefaultItem.png"
+ `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarItemId}.png`
),
className: "avatar_item_l ",
},
-
AvatarBackAccessory: {
src: getTexture(
form.watch("AvatarBackAccessory"),
- "avatarAccessory/CHU_UI_Avatar_Tex_DefaultBack.png"
+ `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarBackId}.png`
),
className: "avatar_back",
},
AvatarWearAccessory: {
src: getTexture(
form.watch("AvatarWearAccessory"),
- "avatarAccessory/CHU_UI_Avatar_Tex_DefaultWear.png"
+ `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarWearId}.png`
),
className: "avatar_wear",
},
avatarSkinAccessory: {
- src: "avatarAccessory/CHU_UI_Avatar_Tex_01400001.png",
+ src: getTexture(
+ avatarSkinId,
+ `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarSkinId}.png`
+ ),
className: "avatar_skin",
},
AvatarRightHand: {
src: "avatarStatic/CHU_UI_Avatar_Tex_RightHand.png",
className: "avatar_hand_r",
},
+
+ AvatarSkinFootR: {
+ src: `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarSkinId}.png`,
+ className: "avatar_skinfoot_r",
+ },
AvatarLeftHand: {
src: "avatarStatic/CHU_UI_Avatar_Tex_LeftHand.png",
className: "avatar_hand_l",
},
AvatarSkinFootL: {
- src: "avatarAccessory/CHU_UI_Avatar_Tex_01400001.png",
+ src: `avatarAccessory/CHU_UI_Avatar_Tex_0${avatarSkinId}.png`,
+
className: "avatar_skinfoot_l",
},
- AvatarSkinFootR: {
- src: "avatarAccessory/CHU_UI_Avatar_Tex_01400001.png",
- className: "avatar_skinfoot_r",
- },
AvatarFaceStatic: {
src: "avatarStatic/CHU_UI_Avatar_Tex_Face.png",
className: "avatar_face_static",
diff --git a/components/darkmode.tsx b/components/darkmode.tsx
index 9264016..f07c74a 100644
--- a/components/darkmode.tsx
+++ b/components/darkmode.tsx
@@ -1,40 +1,46 @@
"use client";
-import * as React from "react";
-import { Moon, Sun } from "lucide-react";
+import React, { useState, useEffect } from "react";
import { useTheme } from "next-themes";
+import { Moon, Sun } from "lucide-react";
-import { Button } from "@/components/ui/button";
-import {
- DropdownMenu,
- DropdownMenuContent,
- DropdownMenuItem,
- DropdownMenuTrigger,
-} from "@/components/ui/dropdown-menu";
+function DarkToggle() {
+ const [mounted, setMounted] = useState(false);
+ const [isDark, setIsDark] = useState(false);
+ const { theme, setTheme } = useTheme();
-export function ModeToggle() {
- const { setTheme } = useTheme();
+ useEffect(() => {
+ setMounted(true);
+ setIsDark(theme === "dark");
+ }, [theme]);
+
+ if (!mounted) {
+ return null;
+ }
+
+ const toggleDarkMode = () => {
+ setIsDark(!isDark);
+ setTheme(theme === "light" ? "dark" : "light");
+ };
return (
-
-
-
-
-
- setTheme("light")}>
- Light
-
- setTheme("dark")}>
- Dark
-
- setTheme("system")}>
- System
-
-
-
+
);
}
+
+export default DarkToggle;
diff --git a/components/navigationbar/navigationbar.tsx b/components/navigationbar/navigationbar.tsx
index 86e1706..be0489b 100644
--- a/components/navigationbar/navigationbar.tsx
+++ b/components/navigationbar/navigationbar.tsx
@@ -16,7 +16,7 @@ import { getAuth } from "@/auth/queries/getauth";
import NavigationMenuDesktop from "./desktopNavBar";
import NavigationMenuMobile from "./mobileNavBar";
import { signOut } from "@/auth/components/signout";
-import { ModeToggle } from "../darkmode";
+import DarkToggle from "../darkmode";
const HeaderNavigation = async () => {
const { user } = await getAuth();
@@ -51,7 +51,7 @@ const HeaderNavigation = async () => {
/>
-
+
diff --git a/next.config.mjs b/next.config.mjs
index f615264..837bd7b 100644
--- a/next.config.mjs
+++ b/next.config.mjs
@@ -1,6 +1,10 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
+ compiler: {
+ styledComponents: true,
+ },
webpack: (config) => {
+
config.externals.push('@node-rs/argon2', '@node-rs/bcrypt');
return config;
},