'use client'; import React, {ChangeEvent, useState} from 'react'; import {defaultTagColors, SpellEditState, spellPowerLevels, SpellTagProps} from '@/lib/models/Spell'; import {SeriesSpellDetailResponse} from '@/lib/models/Series'; import {SelectBoxProps} from '@/shared/interface'; import InputField from '@/components/form/InputField'; import TextInput from '@/components/form/TextInput'; import TexteAreaInput from '@/components/form/TexteAreaInput'; import SelectBox from '@/components/form/SelectBox'; import SpellTagChip from '@/components/book/settings/spells/SpellTagChip'; import SyncFieldWrapper from '@/components/form/SyncFieldWrapper'; import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; import {faPlus} from '@fortawesome/free-solid-svg-icons'; import {useTranslations} from 'next-intl'; interface SpellEditorEditProps { spell: SpellEditState; availableTags: SpellTagProps[]; onSpellChange: (key: keyof SpellEditState, value: string | string[] | null) => void; onCreateTag: (name: string, color: string) => Promise; seriesSpell?: SeriesSpellDetailResponse | null; onSyncComplete?: () => void; } /** * SpellEditorEdit - Version sidebar édition * Mêmes fonctionnalités que SpellSettingsEdit, layout linéaire * Gestion des tags, SyncFieldWrapper, tous les champs */ export default function SpellEditorEdit({ spell, availableTags, onSpellChange, onCreateTag, seriesSpell, onSyncComplete, }: SpellEditorEditProps): React.JSX.Element { const t = useTranslations(); const [tagSearchQuery, setTagSearchQuery] = useState(''); const [isCreatingTag, setIsCreatingTag] = useState(false); const [newTagColor, setNewTagColor] = useState(defaultTagColors[0]); function handleAddTag(tagId: string): void { if (!spell.tags.includes(tagId)) { onSpellChange('tags', [...spell.tags, tagId]); } setTagSearchQuery(''); } function handleRemoveTag(tagId: string): void { onSpellChange('tags', spell.tags.filter(function (id: string): boolean { return id !== tagId; })); } function getFilteredAvailableTags(): SpellTagProps[] { return availableTags.filter(function (tag: SpellTagProps): boolean { const notAlreadyAdded: boolean = !spell.tags.includes(tag.id); const matchesSearch: boolean = tag.name.toLowerCase().includes(tagSearchQuery.toLowerCase()); return notAlreadyAdded && matchesSearch; }); } function getSelectedTags(): SpellTagProps[] { return availableTags.filter(function (tag: SpellTagProps): boolean { return spell.tags.includes(tag.id); }); } async function handleCreateTag(): Promise { if (!tagSearchQuery.trim()) return; const newTag: SpellTagProps | null = await onCreateTag(tagSearchQuery.trim(), newTagColor); if (newTag) { handleAddTag(newTag.id); setIsCreatingTag(false); setNewTagColor(defaultTagColors[0]); } } function getLocalizedPowerLevels(): SelectBoxProps[] { return spellPowerLevels.map(function (level: SelectBoxProps): SelectBoxProps { return { value: level.value, label: t(level.label), }; }); } const filteredTags: SpellTagProps[] = getFilteredAvailableTags(); const selectedTags: SpellTagProps[] = getSelectedTags(); const showCreateOption: boolean = Boolean( tagSearchQuery.trim() && !availableTags.some(function (tag: SpellTagProps): boolean { return tag.name.toLowerCase() === tagSearchQuery.toLowerCase(); }) ); return (
{/* Informations de base */}

{t('spellDetail.basicInfo')}

): void { onSpellChange('name', e.target.value); }} placeholder={t('spellDetail.namePlaceholder')} /> } /> ): void { onSpellChange('description', e.target.value); }} placeholder={t('spellDetail.descriptionPlaceholder')} /> } /> ): void { onSpellChange('appearance', e.target.value); }} placeholder={t('spellDetail.appearancePlaceholder')} /> } />
{/* Tags */}

{t('spellDetail.tags')}

{selectedTags.length > 0 && (
{selectedTags.map(function (tag: SpellTagProps): React.JSX.Element { return ( ); })}
)} ): void { setTagSearchQuery(e.target.value); }} placeholder={t('spellDetail.addTag')} /> {filteredTags.length > 0 && (
{filteredTags.map(function (tag: SpellTagProps): React.JSX.Element { return ( ); })}
)} {showCreateOption && !isCreatingTag && ( )} {isCreatingTag && (

{t('spellDetail.createTag', {name: tagSearchQuery})}

{defaultTagColors.map(function (color: string): React.JSX.Element { return (
)}
{/* Niveau de puissance */}

{t('spellDetail.powerLevel')}

): void { onSpellChange('powerLevel', e.target.value === 'none' ? null : e.target.value); }} data={getLocalizedPowerLevels()} />
{/* Composants */}

{t('spellDetail.components')}

): void { onSpellChange('components', e.target.value || null); }} placeholder={t('spellDetail.componentsPlaceholder')} />
{/* Limitations */}

{t('spellDetail.limitations')}

): void { onSpellChange('limitations', e.target.value || null); }} placeholder={t('spellDetail.limitationsPlaceholder')} />
{/* Notes */}

{t('spellDetail.notes')}

): void { onSpellChange('notes', e.target.value || null); }} placeholder={t('spellDetail.notesPlaceholder')} />
); }