'use client'; import React, {Dispatch, SetStateAction, useState} from 'react'; import {defaultTagColors, SpellEditState, spellPowerLevels, SpellTagProps} from "@/lib/models/Spell"; import {SelectBoxProps} from "@/shared/interface"; import CollapsableArea from "@/components/CollapsableArea"; 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 DeleteButton from "@/components/form/DeleteButton"; import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import { faArrowLeft, faBolt, faBook, faEye, faHatWizard, faPlus, faPuzzlePiece, faSave, faStickyNote, faTags, faTriangleExclamation } from "@fortawesome/free-solid-svg-icons"; import {useTranslations} from "next-intl"; interface SpellDetailProps { selectedSpell: SpellEditState; setSelectedSpell: Dispatch>; availableTags: SpellTagProps[]; handleSpellChange: (key: keyof SpellEditState, value: string | string[] | null) => void; handleSaveSpell: () => Promise; handleDeleteSpell: (spellId: string) => Promise; handleCreateTagInline: (name: string, color: string) => Promise; } export default function SpellDetail( { selectedSpell, setSelectedSpell, availableTags, handleSpellChange, handleSaveSpell, handleDeleteSpell, handleCreateTagInline, }: SpellDetailProps) { const t = useTranslations(); const [tagSearchQuery, setTagSearchQuery] = useState(''); const [showTagDropdown, setShowTagDropdown] = useState(false); const [isCreatingTag, setIsCreatingTag] = useState(false); const [newTagColor, setNewTagColor] = useState(defaultTagColors[0]); function handleAddTag(tagId: string): void { if (!selectedSpell.tags.includes(tagId)) { handleSpellChange('tags', [...selectedSpell.tags, tagId]); } setTagSearchQuery(''); setShowTagDropdown(false); } function handleRemoveTag(tagId: string): void { handleSpellChange('tags', selectedSpell.tags.filter((id: string) => id !== tagId)); } function getFilteredAvailableTags(): SpellTagProps[] { return availableTags.filter((tag: SpellTagProps) => { const notAlreadyAdded = !selectedSpell.tags.includes(tag.id); const matchesSearch = tag.name.toLowerCase().includes(tagSearchQuery.toLowerCase()); return notAlreadyAdded && matchesSearch; }); } function getSelectedTags(): SpellTagProps[] { return availableTags.filter((tag: SpellTagProps) => selectedSpell.tags.includes(tag.id)); } async function handleCreateTag(): Promise { if (!tagSearchQuery.trim()) { return; } const newTag: SpellTagProps | null = await handleCreateTagInline(tagSearchQuery.trim(), newTagColor); if (newTag) { handleAddTag(newTag.id); setIsCreatingTag(false); setNewTagColor(defaultTagColors[0]); } } function getLocalizedPowerLevels(): SelectBoxProps[] { return spellPowerLevels.map((level: SelectBoxProps): SelectBoxProps => ({ value: level.value, label: t(level.label), })); } const filteredTags = getFilteredAvailableTags(); const selectedTags = getSelectedTags(); const showCreateOption = tagSearchQuery.trim() && !availableTags.some((tag: SpellTagProps) => tag.name.toLowerCase() === tagSearchQuery.toLowerCase()); return (
{selectedSpell.name || t("spellDetail.newSpell")}
{selectedSpell.id && ( => handleDeleteSpell(selectedSpell.id as string)} confirmTitle={t("spellDetail.deleteTitle")} confirmMessage={t("spellDetail.deleteMessage", {name: selectedSpell.name})} confirmButtonText={t("common.delete")} cancelButtonText={t("common.cancel")} /> )}
handleSpellChange('name', e.target.value)} placeholder={t("spellDetail.namePlaceholder")} /> } /> handleSpellChange('description', e.target.value)} placeholder={t("spellDetail.descriptionPlaceholder")} /> } /> handleSpellChange('appearance', e.target.value)} placeholder={t("spellDetail.appearancePlaceholder")} /> } />
{selectedTags.length > 0 && (
{selectedTags.map((tag: SpellTagProps) => ( handleRemoveTag(tag.id)} /> ))}
)}
{ setTagSearchQuery(e.target.value); setShowTagDropdown(true); }} placeholder={t("spellDetail.addTag")} onFocus={() => setShowTagDropdown(true)} /> {showTagDropdown && (tagSearchQuery || filteredTags.length > 0) && (
{filteredTags.map((tag: SpellTagProps) => ( ))} {showCreateOption && !isCreatingTag && ( )} {isCreatingTag && (

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

{defaultTagColors.map((color: string) => (
)}
)}
handleSpellChange('powerLevel', e.target.value === 'none' ? null : e.target.value)} data={getLocalizedPowerLevels()} />
handleSpellChange('components', e.target.value || null)} placeholder={t("spellDetail.componentsPlaceholder")} />
handleSpellChange('limitations', e.target.value || null)} placeholder={t("spellDetail.limitationsPlaceholder")} />
handleSpellChange('notes', e.target.value || null)} placeholder={t("spellDetail.notesPlaceholder")} />
); }