diff --git a/app/(authenticated)/chunithm/page.tsx b/app/(authenticated)/chunithm/page.tsx
index 44e18ed..b6cda25 100644
--- a/app/(authenticated)/chunithm/page.tsx
+++ b/app/(authenticated)/chunithm/page.tsx
@@ -1,6 +1,5 @@
"use server";
//https://github.com/vercel/next.js/discussions/63862
-
import React from "react";
import { AvatarCustomization } from "@/components/(customization)/avatarcustomization/page";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
@@ -8,8 +7,8 @@ import ChunithmScorePlaylog from "@/components/scoreplaylog/page";
import { getAllAvatarParts } from "@/components/(customization)/avatarcustomization/actions";
import { TrophyCustomization } from "@/components/(customization)/trophycustomization/page";
import { getTrophies } from "@/components/(customization)/trophycustomization/actions";
-
-// the number is the category id for the specific part
+import { NameplateCustomization } from "@/components/(customization)/nameplatecustomization/page";
+import { getNamePlates } from "@/components/(customization)/nameplatecustomization/actions";
const getAvatarHeadAccessories = async () => {
const avatarParts = await getAllAvatarParts(2); // head
@@ -25,19 +24,27 @@ const getAvatarItemAccessories = async () => {
const avatarParts = await getAllAvatarParts(5); // item_l item_r
return { avatarParts };
};
+
const getAvatarBackAccessories = async () => {
const avatarParts = await getAllAvatarParts(7); // back
return { avatarParts };
};
+
const getAvatarWearAccessories = async () => {
const avatarParts = await getAllAvatarParts(1); // wear
return { avatarParts };
};
+
const getAllTrophies = async () => {
const statictrophies = await getTrophies();
return { statictrophies };
};
+const getAllNameplates = async () => {
+ const namePlates = await getNamePlates();
+ return { namePlates };
+};
+
const Page = async () => {
const AvatarHeadAccessories = await getAvatarHeadAccessories();
const AvatarFaceAccessories = await getAvatarFaceAccessories();
@@ -45,6 +52,8 @@ const Page = async () => {
const AvatarBackAccessories = await getAvatarBackAccessories();
const AvatarWearAccessories = await getAvatarWearAccessories();
const AllPlayerTrophies = await getAllTrophies();
+ const AllStaticNameplates = await getAllNameplates();
+
return (
@@ -65,7 +74,14 @@ const Page = async () => {
avatarWearSelectionData={AvatarWearAccessories}
/>
-
+
+
+
+
diff --git a/components/(customization)/avatarcustomization/page.tsx b/components/(customization)/avatarcustomization/page.tsx
index e23f491..f24170e 100644
--- a/components/(customization)/avatarcustomization/page.tsx
+++ b/components/(customization)/avatarcustomization/page.tsx
@@ -539,7 +539,9 @@ export const AvatarCustomization: FC = ({
)}
/>
-
+
+
+
diff --git a/components/(customization)/nameplatecustomization/actions.ts b/components/(customization)/nameplatecustomization/actions.ts
new file mode 100644
index 0000000..a089b6c
--- /dev/null
+++ b/components/(customization)/nameplatecustomization/actions.ts
@@ -0,0 +1,47 @@
+"use server";
+
+import { getAuth } from "@/auth/queries/getauth";
+import { artemis, daphnis } from "@/lib/prisma";
+import type * as Prisma from "@prisma/client";
+
+// type ChuniScorePlaylog = Prisma.PrismaClient;
+// type ChuniStaticMusic = Prisma.PrismaClient;
+
+export async function getCurrentNameplate() {
+ const { user } = await getAuth();
+
+ if (!user || !user.accessCode) {
+ throw new Error("User is not authenticated or accessCode is missing");
+ }
+
+ const nameplates = await artemis.chuni_profile_data.findMany({
+ where: {
+ user: user.UserId,
+ },
+ select: {
+ nameplateId: true,
+ },
+ });
+ return nameplates;
+}
+
+export async function getNamePlates() {
+ const { user } = await getAuth();
+
+ if (!user || !user.accessCode) {
+ throw new Error("User is not authenticated or accessCode is missing");
+ }
+
+ const nameplates = await artemis.cozynet_chuni_static_nameplate.findMany({
+ select: {
+ id: true,
+ str: true,
+ sortName: true,
+ category: true,
+ imagePath: true,
+ rareType: true,
+ netOpenName: true,
+ },
+ });
+ return nameplates;
+}
diff --git a/components/(customization)/nameplatecustomization/page.tsx b/components/(customization)/nameplatecustomization/page.tsx
new file mode 100644
index 0000000..2088951
--- /dev/null
+++ b/components/(customization)/nameplatecustomization/page.tsx
@@ -0,0 +1,187 @@
+"use client";
+
+import React, { FC, useEffect, useState } from "react";
+import { chuni_static_avatar } from "@/prisma/schemas/artemis/generated/artemis";
+import { Check, ChevronsUpDown } from "lucide-react";
+import { getCurrentNameplate } from "./actions";
+import { cn } from "@/lib/utils";
+import { Button } from "@/components/ui/button";
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandItem,
+ CommandList,
+} from "@/components/ui/command";
+import {
+ Form,
+ FormControl,
+ FormDescription,
+ FormField,
+ FormItem,
+ FormLabel,
+ FormMessage,
+} from "@/components/ui/form";
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover";
+import { z } from "zod";
+import { useForm } from "react-hook-form";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { toast } from "../../ui/use-toast";
+import { cozynet_chuni_static_nameplate } from "@/prisma/schemas/artemis/generated/artemis";
+
+const getNamePlateTextures = (id: number | undefined) => {
+ if (id === undefined) return "";
+ // Pad the id to be 8 digits long, using leading zeros
+ const paddedId = id.toString().padStart(8, "0");
+ return `namePlates/CHU_UI_NamePlate_${paddedId}.png`;
+};
+
+type player_nameplates = cozynet_chuni_static_nameplate;
+
+type AvatarSelectionProps = {
+ playerNamePlateSelectionData: {
+ namePlates: player_nameplates[];
+ };
+};
+
+export const NameplateCustomization: FC = ({
+ playerNamePlateSelectionData,
+}) => {
+ const FormSchema = z.object({
+ PlayerNamePlateId: z.number({
+ required_error: "Please select an Avatar Head Item.",
+ }),
+ });
+
+ const form = useForm>({
+ resolver: zodResolver(FormSchema),
+ });
+
+ const [nameplateId, setNameplateId] = useState(undefined);
+
+ useEffect(() => {
+ const fetchAvatarParts = async () => {
+ try {
+ const data = await getCurrentNameplate();
+ if (data.length > 0) {
+ setNameplateId(data[0].nameplateId!);
+ }
+ } catch (error) {
+ console.error("Error fetching avatar parts:", error);
+ }
+ };
+
+ fetchAvatarParts();
+ }, []);
+
+ function onSubmit(data: z.infer) {
+ toast({
+ title: "You submitted the following values:",
+ description: (
+
+ {JSON.stringify(data, null, 2)}
+
+ ),
+ });
+ }
+
+ const getTexture = (id: number | undefined, defaultSrc: string) => {
+ return id ? getNamePlateTextures(id) : defaultSrc;
+ };
+
+ const AvatarTextures = {
+ AvatarHeadAccessory: {
+ src: getTexture(
+ form.watch("PlayerNamePlateId"),
+ `namePlates/CHU_UI_NamePlate_000${nameplateId}.png`
+ ),
+ className: "avatar_head",
+ },
+ };
+
+ return (
+
+
+
+
+ {Object.entries(AvatarTextures).map(([key, { src }]) => (
+
+
+
+ ))}
+
+
+ );
+};
diff --git a/components/(customization)/trophycustomization/page.tsx b/components/(customization)/trophycustomization/page.tsx
index 4cc7229..9b96a29 100644
--- a/components/(customization)/trophycustomization/page.tsx
+++ b/components/(customization)/trophycustomization/page.tsx
@@ -40,13 +40,13 @@ const getAvatarTextureSrc = (id: number | undefined) => {
type static_trophies = cozynet_chuni_static_trophies;
type AvatarSelectionProps = {
- allTrophies: {
+ playerTrophySelectionData: {
statictrophies: static_trophies[];
};
};
export const TrophyCustomization: FC = ({
- allTrophies,
+ playerTrophySelectionData,
}) => {
const FormSchema = z.object({
trophies: z.number({
@@ -109,7 +109,7 @@ export const TrophyCustomization: FC = ({
)}
>
{field.value
- ? allTrophies.statictrophies.find(
+ ? playerTrophySelectionData.statictrophies.find(
(part) => part.id === field.value
)?.str
: "Select Trophy"}
@@ -122,25 +122,27 @@ export const TrophyCustomization: FC = ({
No avatar part found.
- {allTrophies.statictrophies.map((part) => (
- {
- form.setValue("trophies", part.id);
- }}
- >
-
- {part.str}
-
- ))}
+ {playerTrophySelectionData.statictrophies.map(
+ (part) => (
+ {
+ form.setValue("trophies", part.id);
+ }}
+ >
+
+ {part.str}
+
+ )
+ )}
@@ -150,7 +152,9 @@ export const TrophyCustomization: FC = ({
)}
/>
-
+
+
+