'use client'; import { Spell } from '@/api/spells.types'; import { levelText, rollDice } from '@/js/spells'; import { capitalize } from '@/js/utils'; import { Grid, Modal } from '@mantine/core'; import { notifications } from '@mantine/notifications'; interface SpellModalProps { spell: Spell; isOpen: boolean; onClose(): void; } export default function SpellModal({ spell, isOpen, onClose }: SpellModalProps) { return (

{spell.name}

{capitalize(spell.school)} {levelText(spell)}
{spell.components.verbal && spell.components.somatic ? 'V, ' : 'V '} {spell.components.somatic && spell.components.material ? 'S, ' : 'S '} {spell.components.material && spell.components.materials_needed ? 'M*' : 'M'} {spell.components.materials_needed && (
*{capitalize(spell.components.materials_needed)}
)}
Sources: {spell.sources.map((s) => ( {s.source} {s.page ? `.${s.page}` : ''} ))} Classes: {spell.classes.map((c) => ( {capitalize(c)} ))} Casting Time: {spell.casting_time.value} {capitalize(spell.casting_time.unit)} Range: {spell.range.type != 'point' && capitalize(spell.range.type)} {spell.range.value}{' '} {capitalize(spell.range.unit)} Duration: {spell.durations.map((d) => ( {capitalize(d.type)} {d.value} {capitalize(d.unit)} ))}
); } function SpellDescription({ spell }: { spell: Spell }) { function parseText(text: string) { const regex = /{@(.*?) (.*?)}/g; const matches = text.matchAll(regex); const result = []; let lastIndex = 0; for (const match of matches) { const [full, type, name] = match; result.push(text.slice(lastIndex, match.index)); if (match.index !== undefined) { result.push( handleLink(type, name)} className='link'> {name} ); lastIndex = match.index + full.length; } } result.push(text.slice(lastIndex)); return result; } function handleLink(type: string, name: string) { if (type == 'spell') { console.log(`Link to spell: ${name}`); } else if (type == 'dice' || type == 'damage') { const rolls = rollDice(name); notifications.show({ title: `Rolling ${name}`, message: `${rolls.join(' + ')} = ${rolls.reduce((a, b) => a + b, 0)}`, color: 'blue', autoClose: 5000, withCloseButton: false }); } else { console.error(`Unknown link type: ${type}`); } } return ( <> {spell.description && ( <> {spell.description.entries.map((e) => typeof e === 'string' ? (

{parseText(e)}

) : ( <> {e.type == 'list' ? ( ) : ( <> )} ) )} )} ); }