"use client" import useFreeSRStore from "@/stores/freesrStore"; import useModelStore from "@/stores/modelStore"; import useUserDataStore from "@/stores/userDataStore"; import { CharacterInfoCardType } from "@/types"; import { useState } from "react"; import CharacterInfoCard from "../card/characterInfoCard"; import { freeSrJsonSchema } from "@/zod"; import { toast } from "react-toastify"; import { converterOneFreeSRDataToAvatarStore } from "@/helper"; import { useTranslations } from "next-intl"; import useDetailDataStore from "@/stores/detailDataStore"; import { useShallow } from "zustand/react/shallow"; import { z } from "zod"; type FreeSRJsonInput = z.infer; const toCharacterInfoCard = (data: FreeSRJsonInput, character: FreeSRJsonInput["avatars"][string]): CharacterInfoCardType => { const lightcone = data.lightcones.find((lightcone) => lightcone.equip_avatar === character.avatar_id) const relics = data.relics.filter((relic) => relic.equip_avatar === character.avatar_id) return { key: character.avatar_id, avatar_id: character.avatar_id, rank: character.data.rank ?? 0, level: character.level, lightcone: { level: lightcone?.level ?? 0, rank: lightcone?.rank ?? 0, item_id: lightcone?.item_id ?? 0, }, relics: relics.map((relic) => ({ level: relic.level, relic_id: relic.relic_id, relic_set_id: relic.relic_set_id, })), } } export default function FreeSRImport() { const { avatars, setAvatar } = useUserDataStore( useShallow((state) => ({ avatars: state.avatars, setAvatar: state.setAvatar, })) ); const { mapAvatar } = useDetailDataStore( useShallow((state) => ({ mapAvatar: state.mapAvatar, })) ); const { setIsOpenImport } = useModelStore( useShallow((state) => ({ setIsOpenImport: state.setIsOpenImport, })) ) const [isLoading, setIsLoading] = useState(false) const [Error, setError] = useState("") const { freeSRData, setFreeSRData, selectedCharacters, setSelectedCharacters } = useFreeSRStore( useShallow((state) => ({ freeSRData: state.freeSRData, setFreeSRData: state.setFreeSRData, selectedCharacters: state.selectedCharacters, setSelectedCharacters: state.setSelectedCharacters, })) ) const transI18n = useTranslations("DataPage") const parsedFreeSRData = freeSrJsonSchema.safeParse(freeSRData) const validFreeSRData = parsedFreeSRData.success ? parsedFreeSRData.data : null const handleCharacterToggle = (character: CharacterInfoCardType) => { if (selectedCharacters.some((selectedCharacter) => selectedCharacter.key === character.key)) { setSelectedCharacters(selectedCharacters.filter((selectedCharacter) => selectedCharacter.key !== character.key)); return; } setSelectedCharacters([...selectedCharacters, character]); }; const clearSelection = () => { setSelectedCharacters([]); }; const selectAll = () => { const parsed = freeSrJsonSchema.safeParse(freeSRData) if (parsed.success) { setSelectedCharacters(Object.values(parsed.data.avatars).filter(it => mapAvatar?.[it.avatar_id]).map((character) => toCharacterInfoCard(parsed.data, character))); } }; const handlerReadFile = (event: React.ChangeEvent) => { setIsLoading(true) const file = event.target.files?.[0]; if (!file) { setSelectedCharacters([]) setFreeSRData(null) setError(transI18n("pleaseSelectAFile")) setIsLoading(false) return } if (!file.name.endsWith(".json") || file.type !== "application/json") { setSelectedCharacters([]) setFreeSRData(null) setError(transI18n("fileMustBeAValidJsonFile")) setIsLoading(false) return } if (file) { const reader = new FileReader(); reader.onload = (e) => { try { const data = JSON.parse(e.target?.result as string); const parsed = freeSrJsonSchema.safeParse(data) if (!parsed.success) { setSelectedCharacters([]) setFreeSRData(null) setError(transI18n("fileMustBeAValidJsonFile")) return } setFreeSRData(parsed.data) setError("") setSelectedCharacters(Object.values(parsed.data.avatars).filter(it => mapAvatar?.[it.avatar_id]).map((character) => toCharacterInfoCard(parsed.data, character))); } catch { setSelectedCharacters([]) setFreeSRData(null) setError(transI18n("fileMustBeAValidJsonFile")) } finally { setIsLoading(false) } }; reader.onerror = () => { setSelectedCharacters([]) setFreeSRData(null) setError(transI18n("fileMustBeAValidJsonFile")) setIsLoading(false) } reader.readAsText(file); } }; const handleImport = () => { if (selectedCharacters.length === 0) { setError(transI18n("pleaseSelectAtLeastOneCharacter")); return; } if (!freeSRData) { setError(transI18n("noDataToImport")); return; } setError(""); const parsed = freeSrJsonSchema.safeParse(freeSRData) if (!parsed.success) { setError(transI18n("fileMustBeAValidJsonFile")); return; } const listAvatars = { ...avatars } const filterData = Object.values(parsed.data.avatars).filter((character) => selectedCharacters.some((selectedCharacter) => selectedCharacter.avatar_id === character.avatar_id)) filterData.forEach((character) => { const currentAvatar = listAvatars[character.avatar_id] if (currentAvatar && Object.keys(currentAvatar).length !== 0) { const newProfileList = [...(currentAvatar.profileList || [])] const newProfile = converterOneFreeSRDataToAvatarStore(parsed.data, newProfileList.length, character.avatar_id) if (newProfile) { newProfileList.push(newProfile) } const newAvatar = { ...currentAvatar, level: character.level, promotion: character.promotion, data: { rank: character.data.rank ?? 0, skills: character.data.skills }, profileList: newProfileList, profileSelect: newProfile ? newProfileList.length - 1 : currentAvatar.profileSelect, } setAvatar(newAvatar) } }) setIsOpenImport(false) toast.success(transI18n("importFreeSRDataSuccess")) } return (
{/* Header */}

{transI18n("freeSRImport")}

{transI18n("pickAFile")}
{selectedCharacters.length > 0 && ( )}
{Error && (
😭 {Error}
)} {/* Selection Info */}
{transI18n("selectedCharacters")}: {selectedCharacters.length}
{isLoading && (
)} {/* Character Grid */}
{validFreeSRData && Object.values(validFreeSRData.avatars).filter(it => mapAvatar?.[it.avatar_id]).map((character) => { return ( ) })}
) }