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 ( +
+
+ + ( + + Name plate Item + + + + + + + + + + No name plate found. + + {playerNamePlateSelectionData.namePlates.map( + (part) => ( + { + form.setValue("PlayerNamePlateId", part.id!); + }} + > + + {part.str} + + ) + )} + + + + + + + + + )} + /> + +
+ +
+ + +
+ {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 = ({ )} /> - +
+ +