'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' ? (
{e.items.map((text) => (
- {parseText(text)}
))}
) : (
<>>
)}
>
)
)}
>
)}
>
);
}