dd694477b2
Crash fix: - restoreBackup (file + cloud pull) now validates each row through its Zod schema, backfilling new fields — an older backup no longer lands characters missing feats/concentration/etc and crashing the sheet. + test. pf2e parity (closing feature gaps vs 5e): - +9 missing classes (Animist, Exemplar, Gunslinger, Inventor, Kineticist, Magus, Psychic, Summoner, Thaumaturge) with data + class tips. - the wizard now enriches pf2e classes with their caster ability, so pf2e spellcasters get the Spells step + "Caster" tag like 5e. - editable Perception rank and spellcasting proficiency on the pf2e sheet (fixes wrong initiative / spell DC at higher levels); rank-10 spell slots. - pf2e monster resistances/weaknesses/immunities now apply in combat (flat amounts: resistance subtracts, weakness adds, 'all' matches any type). + tests. Glyph purge (finishing the emoji→Lucide migration): replaced ~40 leftover text-glyphs (✕ − + ✦ 🤫 ⬆ ⬇ ☑ ☐ ▶ ◀ ‹ › ★ ↻ ▸ ↑ ●) with Lucide icons across Modal (every dialog), the sheet sections, dice, settings, player panels, world pages, map editor, roll tray, and session UI. Gate: 293 unit + e2e green; tsc + build clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
40 lines
1.8 KiB
TypeScript
40 lines
1.8 KiB
TypeScript
import { Check, ChevronRight, ArrowUp } from 'lucide-react';
|
|
import type { Character } from '@/lib/schemas';
|
|
import { getTurnGuide, getGenericGuide } from '@/lib/assistant/actions';
|
|
|
|
/** Collapsible "What can I do?" guide for the player in-session view. */
|
|
export function ActionGuide({ character }: { character: Character }) {
|
|
const guide = getTurnGuide(character.system, character.className?.toLowerCase() ?? '') ?? getGenericGuide(character.system);
|
|
|
|
return (
|
|
<details className="mt-3 rounded-lg border border-line bg-surface-2">
|
|
<summary className="flex cursor-pointer select-none items-center gap-1 px-3 py-2 text-xs text-muted hover:text-ink">
|
|
<ChevronRight size={13} aria-hidden /> What can I do on my turn?
|
|
</summary>
|
|
<div className="border-t border-line px-3 pb-3 pt-2">
|
|
<ul className="space-y-2">
|
|
{guide.actions.map((a) => (
|
|
<li key={a.label}>
|
|
<span className="text-xs font-semibold text-ink">{a.label}: </span>
|
|
<span className="text-xs text-muted">{a.desc}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
{guide.upgradeAt && character.level < guide.upgradeAt.level && (
|
|
<p className="mt-2 flex items-center gap-1 rounded-md border border-accent/30 bg-accent/5 px-2 py-1 text-xs text-accent">
|
|
<ArrowUp size={12} aria-hidden /> {guide.upgradeAt.note}
|
|
</p>
|
|
)}
|
|
{guide.upgradeAt && character.level >= guide.upgradeAt.level && (
|
|
<p className="mt-2 rounded-md border border-success/30 bg-success/5 px-2 py-1 text-xs text-success">
|
|
<Check size={12} className="mr-1 inline" aria-hidden /> {guide.upgradeAt.note}
|
|
</p>
|
|
)}
|
|
{guide.tip && (
|
|
<p className="mt-2 border-t border-line pt-2 text-xs italic text-muted">{guide.tip}</p>
|
|
)}
|
|
</div>
|
|
</details>
|
|
);
|
|
}
|