'use client'; import React, {Dispatch, forwardRef, SetStateAction, useContext, useEffect, useImperativeHandle, useState} from 'react'; import {Attribute, CharacterProps} from "@/lib/models/Character"; import {SessionContext} from "@/context/SessionContext"; import CharacterList from './CharacterList'; import System from '@/lib/models/System'; import {AlertContext} from "@/context/AlertContext"; import {BookContext} from "@/context/BookContext"; import CharacterDetail from "@/components/book/settings/characters/CharacterDetail"; import {useTranslations} from "next-intl"; import {LangContext, LangContextProps} from "@/context/LangContext"; interface CharacterDetailProps { selectedCharacter: CharacterProps | null; setSelectedCharacter: Dispatch>; handleCharacterChange: (key: keyof CharacterProps, value: string) => void; handleAddElement: (section: keyof CharacterProps, element: any) => void; handleRemoveElement: ( section: keyof CharacterProps, index: number, attrId: string, ) => void; handleSaveCharacter: () => void; } const initialCharacterState: CharacterProps = { id: null, name: '', lastName: '', category: 'none', title: '', role: '', image: 'https://via.placeholder.com/150', biography: '', history: '', physical: [], psychological: [], relations: [], skills: [], weaknesses: [], strengths: [], goals: [], motivations: [], }; export function CharacterComponent(props: any, ref: any) { const t = useTranslations(); const {lang} = useContext(LangContext) const {session} = useContext(SessionContext); const {book} = useContext(BookContext); const {errorMessage, successMessage} = useContext(AlertContext); const [characters, setCharacters] = useState([]); const [selectedCharacter, setSelectedCharacter] = useState(null); useImperativeHandle(ref, function () { return { handleSave: handleSaveCharacter, }; }); useEffect((): void => { getCharacters().then(); }, []); async function getCharacters(): Promise { try { const response: CharacterProps[] = await System.authGetQueryToServer(`character/list`, session.accessToken, lang, { bookid: book?.bookId, }); if (response) { setCharacters(response); } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("common.unknownError")); } } } function handleCharacterClick(character: CharacterProps): void { setSelectedCharacter({...character}); } function handleAddCharacter(): void { setSelectedCharacter({...initialCharacterState}); } async function handleSaveCharacter(): Promise { if (selectedCharacter) { const updatedCharacter: CharacterProps = {...selectedCharacter}; if (selectedCharacter.id === null) { await addNewCharacter(updatedCharacter); } else { await updateCharacter(updatedCharacter); } } } async function addNewCharacter(updatedCharacter: CharacterProps): Promise { if (!updatedCharacter.name) { errorMessage(t("characterComponent.errorNameRequired")); return; } if (updatedCharacter.category === 'none') { errorMessage(t("characterComponent.errorCategoryRequired")); return; } try { const characterId: string = await System.authPostToServer(`character/add`, { bookId: book?.bookId, character: updatedCharacter, }, session.accessToken, lang); if (!characterId) { errorMessage(t("characterComponent.errorAddCharacter")); return; } updatedCharacter.id = characterId; setCharacters([...characters, updatedCharacter]); setSelectedCharacter(null); } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("common.unknownError")); } } } async function updateCharacter(updatedCharacter: CharacterProps,): Promise { try { const response: boolean = await System.authPostToServer(`character/update`, { character: updatedCharacter, }, session.accessToken, lang); if (!response) { errorMessage(t("characterComponent.errorUpdateCharacter")); return; } setCharacters( characters.map((char: CharacterProps): CharacterProps => char.id === updatedCharacter.id ? updatedCharacter : char, ), ); setSelectedCharacter(null); successMessage(t("characterComponent.successUpdate")); } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("common.unknownError")); } } } function handleCharacterChange( key: keyof CharacterProps, value: string, ): void { if (selectedCharacter) { setSelectedCharacter({...selectedCharacter, [key]: value}); } } async function handleAddElement( section: keyof CharacterProps, value: Attribute, ): Promise { if (selectedCharacter) { if (selectedCharacter.id === null) { const updatedSection: any[] = [ ...(selectedCharacter[section] as any[]), value, ]; setSelectedCharacter({...selectedCharacter, [section]: updatedSection}); } else { try { const attributeId: string = await System.authPostToServer(`character/attribute/add`, { characterId: selectedCharacter.id, type: section, name: value.name, }, session.accessToken, lang); if (!attributeId) { errorMessage(t("characterComponent.errorAddAttribute")); return; } const newValue: Attribute = { name: value.name, id: attributeId, }; const updatedSection: Attribute[] = [...(selectedCharacter[section] as Attribute[]), newValue,]; setSelectedCharacter({...selectedCharacter, [section]: updatedSection}); } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("common.unknownError")); } } } } } async function handleRemoveElement( section: keyof CharacterProps, index: number, attrId: string, ): Promise { if (selectedCharacter) { if (selectedCharacter.id === null) { const updatedSection: Attribute[] = ( selectedCharacter[section] as Attribute[] ).filter((_, i: number): boolean => i !== index); setSelectedCharacter({...selectedCharacter, [section]: updatedSection}); } else { try { const response: boolean = await System.authDeleteToServer(`character/attribute/delete`, { attributeId: attrId, }, session.accessToken, lang); if (!response) { errorMessage(t("characterComponent.errorRemoveAttribute")); return; } const updatedSection: Attribute[] = ( selectedCharacter[section] as Attribute[] ).filter((_, i: number): boolean => i !== index); setSelectedCharacter({ ...selectedCharacter, [section]: updatedSection, }); } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("common.unknownError")); } } } } } return (
{selectedCharacter ? ( ) : ( )}
); } export default forwardRef(CharacterComponent);