Fix playbook steps not rendering text

Playbook steps are stored as simple string arrays in the database,
but the rendering code expected PlaybookStep objects with step/title/
description/duration fields. Handle both formats with a typeof check.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-09-03 11:58:11 -04:00
parent d946a1b9d4
commit eb13f292e4

View File

@@ -87,7 +87,7 @@ export default function PlaybooksPage() {
}; };
const advanceStep = async (p: PlaybookProgress) => { const advanceStep = async (p: PlaybookProgress) => {
const steps: PlaybookStep[] = selectedPlaybook ? JSON.parse(selectedPlaybook.steps_json) : []; const steps: (string | PlaybookStep)[] = selectedPlaybook ? JSON.parse(selectedPlaybook.steps_json) : [];
const nextStep = p.current_step + 1; const nextStep = p.current_step + 1;
const isComplete = nextStep > steps.length; const isComplete = nextStep > steps.length;
await fetch('/api/phase2', { await fetch('/api/phase2', {
@@ -124,7 +124,7 @@ export default function PlaybooksPage() {
}; };
if (selectedPlaybook) { if (selectedPlaybook) {
const steps: PlaybookStep[] = (() => { try { return JSON.parse(selectedPlaybook.steps_json); } catch { return []; } })(); const steps: (string | PlaybookStep)[] = (() => { try { return JSON.parse(selectedPlaybook.steps_json); } catch { return []; } })();
return ( return (
<div className="space-y-6"> <div className="space-y-6">
@@ -162,16 +162,23 @@ export default function PlaybooksPage() {
{/* Steps Overview */} {/* Steps Overview */}
<ChartCard title="Playbook Steps" action={<button onClick={() => startEdit(selectedPlaybook)} className="text-xs text-[#0098C7] hover:text-[#007ba3] font-medium">Edit</button>}> <ChartCard title="Playbook Steps" action={<button onClick={() => startEdit(selectedPlaybook)} className="text-xs text-[#0098C7] hover:text-[#007ba3] font-medium">Edit</button>}>
<div className="space-y-3 py-1"> <div className="space-y-3 py-1">
{steps.map((step, i) => ( {steps.map((step, i) => {
const isString = typeof step === 'string';
const title = isString ? step : step.title;
const desc = isString ? null : step.description;
const dur = isString ? null : step.duration;
const num = isString ? i + 1 : step.step;
return (
<div key={i} className="flex items-start gap-3"> <div key={i} className="flex items-start gap-3">
<div className="w-7 h-7 rounded-full bg-[#1B1D36] text-white flex items-center justify-center text-xs font-bold flex-shrink-0">{step.step}</div> <div className="w-7 h-7 rounded-full bg-[#1B1D36] text-white flex items-center justify-center text-xs font-bold flex-shrink-0">{num}</div>
<div className="flex-1 min-w-0"> <div className="flex-1 min-w-0">
<div className="text-sm font-semibold text-foreground">{step.title}</div> <div className="text-sm font-semibold text-foreground">{title}</div>
<div className="text-xs text-muted mt-0.5">{step.description}</div> {desc && <div className="text-xs text-muted mt-0.5">{desc}</div>}
<div className="text-[10px] text-muted mt-1">{step.duration}</div> {dur && <div className="text-[10px] text-muted mt-1">{dur}</div>}
</div> </div>
</div> </div>
))} );
})}
</div> </div>
</ChartCard> </ChartCard>
@@ -226,7 +233,7 @@ export default function PlaybooksPage() {
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4"> <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4">
{playbooks.map(pb => { {playbooks.map(pb => {
const steps: PlaybookStep[] = (() => { try { return JSON.parse(pb.steps_json); } catch { return []; } })(); const steps: (string | PlaybookStep)[] = (() => { try { return JSON.parse(pb.steps_json); } catch { return []; } })();
return ( return (
<div <div
key={pb.id} key={pb.id}