import CollapsableArea from "@/components/CollapsableArea"; import InputField from "@/components/form/InputField"; import TexteAreaInput from "@/components/form/TexteAreaInput"; import TextInput from "@/components/form/TextInput"; import SelectBox from "@/components/form/SelectBox"; import {AlertContext} from "@/context/AlertContext"; import {SessionContext} from "@/context/SessionContext"; import { Attribute, CharacterAttribute, characterCategories, CharacterElement, basicCharacterElements, advancedCharacterElements, CharacterProps, characterStatus } from "@/lib/models/Character"; import System from "@/lib/models/System"; import { faArrowLeft, faBook, faPlus, faSave, faScroll, faUser, faSliders, faGlobe, faCommentDots, faStickyNote } from "@fortawesome/free-solid-svg-icons"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import {Dispatch, SetStateAction, useContext, useEffect, useState} from "react"; import CharacterSectionElement from "@/components/book/settings/characters/CharacterSectionElement"; import DeleteButton from "@/components/form/DeleteButton"; import {useTranslations} from "next-intl"; import {LangContext} from "@/context/LangContext"; import OfflineContext, {OfflineContextType} from "@/context/OfflineContext"; import {BookContext} from "@/context/BookContext"; type AttributeResponse = { type: string; values: Attribute[] }[]; 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; handleDeleteCharacter: (characterId: string) => Promise; } export default function CharacterDetail( { setSelectedCharacter, selectedCharacter, handleCharacterChange, handleRemoveElement, handleAddElement, handleSaveCharacter, handleDeleteCharacter, }: CharacterDetailProps ) { const t = useTranslations(); const {lang} = useContext(LangContext); const {isCurrentlyOffline} = useContext(OfflineContext); const {book} = useContext(BookContext); const {session} = useContext(SessionContext); const {errorMessage} = useContext(AlertContext); const [showAdvanced, setShowAdvanced] = useState(false); useEffect((): void => { if (selectedCharacter?.id !== null) { getAttributes().then(); } }, []); async function getAttributes(): Promise { try { let response: AttributeResponse; if (isCurrentlyOffline()) { response = await window.electron.invoke('db:character:attributes', { characterId: selectedCharacter?.id, }); } else { if (book?.localBook) { response = await window.electron.invoke('db:character:attributes', { characterId: selectedCharacter?.id, }); } else { response = await System.authGetQueryToServer(`character/attribute`, session.accessToken, lang, { characterId: selectedCharacter?.id, }); } } if (response) { const attributes: CharacterAttribute = {}; response.forEach((item: { type: string values: Attribute[] }):void => { attributes[item.type] = item.values; }); setSelectedCharacter({ id: selectedCharacter?.id ?? '', name: selectedCharacter?.name ?? '', lastName: selectedCharacter?.lastName ?? '', nickname: selectedCharacter?.nickname ?? '', age: selectedCharacter?.age ?? '', gender: selectedCharacter?.gender ?? '', species: selectedCharacter?.species ?? '', nationality: selectedCharacter?.nationality ?? '', status: selectedCharacter?.status ?? 'alive', category: selectedCharacter?.category ?? 'none', title: selectedCharacter?.title ?? '', image: selectedCharacter?.image ?? '', role: selectedCharacter?.role ?? '', biography: selectedCharacter?.biography, history: selectedCharacter?.history, speechPattern: selectedCharacter?.speechPattern, catchphrase: selectedCharacter?.catchphrase, residence: selectedCharacter?.residence, notes: selectedCharacter?.notes, color: selectedCharacter?.color, physical: attributes.physical ?? [], psychological: attributes.psychological ?? [], relations: attributes.relations ?? [], skills: attributes.skills ?? [], weaknesses: attributes.weaknesses ?? [], strengths: attributes.strengths ?? [], goals: attributes.goals ?? [], motivations: attributes.motivations ?? [], arc: attributes.arc ?? [], secrets: attributes.secrets ?? [], fears: attributes.fears ?? [], flaws: attributes.flaws ?? [], beliefs: attributes.beliefs ?? [], conflicts: attributes.conflicts ?? [], quotes: attributes.quotes ?? [], distinguishingMarks: attributes.distinguishingMarks ?? [], items: attributes.items ?? [], affiliations: attributes.affiliations ?? [], }); } } catch (e: unknown) { if (e instanceof Error) { errorMessage(e.message); } else { errorMessage(t("characterDetail.fetchAttributesError")); } } } return (
{selectedCharacter?.name || t("characterDetail.newCharacter")}
{selectedCharacter?.id && ( => handleDeleteCharacter(selectedCharacter.id as string)} confirmTitle={t("characterDetail.deleteTitle")} confirmMessage={t("characterDetail.deleteMessage", {name: selectedCharacter.name})} confirmButtonText={t("common.delete")} cancelButtonText={t("common.cancel")} /> )}
handleCharacterChange('name', e.target.value)} placeholder={t("characterDetail.namePlaceholder")} /> } /> handleCharacterChange('lastName', e.target.value)} placeholder={t("characterDetail.lastNamePlaceholder")} /> } /> handleCharacterChange('nickname', e.target.value)} placeholder={t("characterDetail.nicknamePlaceholder")} /> } /> setSelectedCharacter(prev => prev ? {...prev, category: e.target.value as CharacterProps['category']} : prev )} data={characterCategories} /> } /> handleCharacterChange('title', e.target.value)} placeholder={t("characterDetail.titlePlaceholder")} /> } /> handleCharacterChange('gender', e.target.value)} placeholder={t("characterDetail.genderPlaceholder")} /> } /> handleCharacterChange('age', e.target.value)} placeholder={t("characterDetail.agePlaceholder")} /> } />
handleCharacterChange('biography', e.target.value)} placeholder={t("characterDetail.biographyPlaceholder")} /> } icon={faBook} /> handleCharacterChange('history', e.target.value)} placeholder={t("characterDetail.historyPlaceholder")} /> } icon={faScroll} /> handleCharacterChange('role', e.target.value)} placeholder={t("characterDetail.roleFullPlaceholder")} /> } icon={faScroll} />
{/* Attributs de base - toujours visibles */} {basicCharacterElements.map((item: CharacterElement, index: number) => ( ))} {/* Toggle Mode Avancé */}
{t("characterDetail.advancedMode")}
{/* Sections avancées - visibles uniquement si showAdvanced est true */} {showAdvanced && ( <> {/* Identité étendue */}
handleCharacterChange('species', e.target.value)} placeholder={t("characterDetail.speciesPlaceholder")} /> } /> handleCharacterChange('nationality', e.target.value)} placeholder={t("characterDetail.nationalityPlaceholder")} /> } /> setSelectedCharacter(prev => prev ? {...prev, status: e.target.value as CharacterProps['status']} : prev )} data={characterStatus} /> } /> handleCharacterChange('residence', e.target.value)} placeholder={t("characterDetail.residencePlaceholder")} /> } />
{/* Voix du personnage */}
handleCharacterChange('speechPattern', e.target.value)} placeholder={t("characterDetail.speechPatternPlaceholder")} /> } /> handleCharacterChange('catchphrase', e.target.value)} placeholder={t("characterDetail.catchphrasePlaceholder")} /> } />
{/* Notes de l'auteur */}
handleCharacterChange('notes', e.target.value)} placeholder={t("characterDetail.notesPlaceholder")} /> } /> handleCharacterChange('color', e.target.value)} placeholder={t("characterDetail.colorPlaceholder")} /> } />
{/* Attributs avancés */} {advancedCharacterElements.map((item: CharacterElement, index: number) => ( ))} )}
); }