'use client'; import React, {useContext, useEffect, useMemo, useState} from 'react'; import { advancedCharacterElements, Attribute, basicCharacterElements, CharacterAttribute, characterCategories, CharacterElement, CharacterProps, characterStatus } from '@/lib/models/Character'; import {SeriesCharacterProps} from '@/lib/models/Series'; import InputField from '@/components/form/InputField'; import TextInput from '@/components/form/TextInput'; import TexteAreaInput from '@/components/form/TexteAreaInput'; import NumberInput from '@/components/form/NumberInput'; import SelectBox from '@/components/form/SelectBox'; import CharacterSectionElement from '@/components/book/settings/characters/CharacterSectionElement'; import SyncFieldWrapper from '@/components/form/SyncFieldWrapper'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faSliders} from '@fortawesome/free-solid-svg-icons'; import {useTranslations} from 'next-intl'; import {SessionContext} from '@/context/SessionContext'; import {AlertContext} from '@/context/AlertContext'; import {LangContext} from '@/context/LangContext'; import OfflineContext, {OfflineContextType} from '@/context/OfflineContext'; import {BookContext} from '@/context/BookContext'; import System from '@/lib/models/System'; import {Dispatch, SetStateAction} from 'react'; import * as tauri from '@/lib/tauri'; type AttributeResponse = { type: string; values: Attribute[] }[]; interface CharacterEditorEditProps { character: CharacterProps; setCharacter: Dispatch>; onCharacterChange: (key: keyof CharacterProps, value: string | number | null) => void; onAddAttribute: (section: keyof CharacterProps, attr: Attribute) => Promise; onRemoveAttribute: (section: keyof CharacterProps, idx: number, id: string) => Promise; seriesCharacter?: SeriesCharacterProps | null; onSyncComplete?: () => void; } /** * CharacterEditorEdit - Version sidebar édition * Mêmes fonctionnalités que CharacterSettingsEdit, layout linéaire */ export default function CharacterEditorEdit({ character, setCharacter, onCharacterChange, onAddAttribute, onRemoveAttribute, seriesCharacter, onSyncComplete, }: CharacterEditorEditProps): React.JSX.Element { const t = useTranslations(); const {lang} = useContext(LangContext); const {session} = useContext(SessionContext); const {errorMessage} = useContext(AlertContext); const {isCurrentlyOffline} = useContext(OfflineContext); const {book} = useContext(BookContext); const [showAdvanced, setShowAdvanced] = useState(false); // Traduire les données des SelectBox const translatedCharacterCategories = useMemo(() => characterCategories.map((item) => ({ ...item, label: t(item.label) })), [t]); const translatedCharacterStatus = useMemo(() => characterStatus.map((item) => ({ ...item, label: t(item.label) })), [t]); useEffect(function (): void { if (character?.id !== null) { getAttributes().then(); } }, [character?.id]); async function getAttributes(): Promise { try { let response: AttributeResponse; if (isCurrentlyOffline() || book?.localBook) { response = await tauri.getCharacterAttributes(character?.id!) as AttributeResponse; } else { response = await System.authGetQueryToServer( 'character/attribute', session.accessToken, lang, {characterId: character?.id} ); } if (response) { const attributes: CharacterAttribute = {}; response.forEach(function (item: { type: string; values: Attribute[] }): void { attributes[item.type] = item.values; }); setCharacter(function (prev: CharacterProps | null): CharacterProps | null { if (!prev) return null; return { ...prev, 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); } } } return (
{/* Informations de base */}

{t('characterDetail.basicInfo')}

): void { onCharacterChange('name', e.target.value); }} placeholder={t('characterDetail.namePlaceholder')} /> } /> ): void { onCharacterChange('lastName', e.target.value); }} placeholder={t('characterDetail.lastNamePlaceholder')} /> } /> ): void { setCharacter(function (prev: CharacterProps | null): CharacterProps | null { return prev ? {...prev, category: e.target.value as CharacterProps['category']} : prev; }); }} data={translatedCharacterCategories} /> } /> ): void { onCharacterChange('gender', e.target.value); }} placeholder={t('characterDetail.genderPlaceholder')} /> } /> } />
{/* Histoire */}

{t('characterDetail.historySection')}

): void { onCharacterChange('biography', e.target.value); }} placeholder={t('characterDetail.biographyPlaceholder')} /> } /> ): void { onCharacterChange('role', e.target.value); }} placeholder={t('characterDetail.roleFullPlaceholder')} /> } />
{/* Attributs de base */} {basicCharacterElements.map(function (item: CharacterElement, index: number): React.JSX.Element { return ( ); })} {/* Toggle Mode Avancé */}
{t('characterDetail.advancedMode')}
{/* Sections avancées */} {showAdvanced && ( <>

{t('characterDetail.identitySection')}

): void { onCharacterChange('species', e.target.value); }} placeholder={t('characterDetail.speciesPlaceholder')} /> } /> ): void { setCharacter(function (prev: CharacterProps | null): CharacterProps | null { return prev ? {...prev, status: e.target.value as CharacterProps['status']} : prev; }); }} data={translatedCharacterStatus} /> } />

{t('characterDetail.authorSection')}

): void { onCharacterChange('notes', e.target.value); }} placeholder={t('characterDetail.notesPlaceholder')} /> } />
{advancedCharacterElements.map(function (item: CharacterElement, index: number): React.JSX.Element { return ( ); })} )}
); }