("unsure");
const [lensNote, setLensNote] = useState("");
const [action, setAction] = useState("");
const [summaryLine, setSummaryLine] = useState("");
const [summaryAction, setSummaryAction] = useState("");
const effectiveDomain =
selectedDomain === "Other" ? customDomain || "Another domain" : selectedDomain || "";
const causeItems = items.filter((i) => i.type === "cause" || i.type === "both");
const effectItems = items.filter((i) => i.type === "effect" || i.type === "both");
const canGoNext = useMemo(() => {
switch (step) {
case 1:
return !!selectedDomain && (selectedDomain !== "Other" || customDomain.trim().length > 0);
case 2:
return problem.trim().length > 8;
case 3:
return items.length >= 8;
case 4:
return (
items.some((i) => i.type === "cause" || i.type === "both") &&
items.some((i) => i.type === "effect" || i.type === "both")
);
case 5:
return lens !== "unsure";
case 6:
return action.trim().length > 8;
case 7:
return false;
default:
return false;
}
}, [step, selectedDomain, customDomain, problem, items, lens, action]);
const generateSummary = () => {
const topCause = causeItems[0]?.text || "a key underlying cause";
const topEffect = effectItems[0]?.text || "a major harmful effect";
let stakeholder: string;
if (lensNote.trim()) stakeholder = lensNote.trim();
else if (lens === "stakeholder") stakeholder = "key people who are directly affected";
else if (lens === "systemic") stakeholder = "the system-level actors involved";
else stakeholder = "the people and systems involved";
const domainText = effectiveDomain ? `In the domain of ${effectiveDomain}, ` : "";
const s = `${domainText}${topCause} is driving ${topEffect} for ${stakeholder}.`;
const a =
action.trim() ||
"We now need to design testable, collaborative actions that connect this cause to a better outcome.";
setSummaryLine(s);
setSummaryAction(a);
};
const handleNext = () => {
if (step === 6) {
generateSummary();
setStep(7);
} else if (step < 7 && canGoNext) {
setStep((s) => s + 1);
}
};
const handleBack = () => {
if (step > 1) setStep((s) => s - 1);
};
const handleRestart = () => {
setStep(1);
setSelectedDomain(null);
setCustomDomain("");
setProblem("");
setItems([]);
setNewItem("");
setLens("unsure");
setLensNote("");
setAction("");
setSummaryLine("");
setSummaryAction("");
};
const addItem = () => {
const t = newItem.trim();
if (!t || items.length >= 30) return;
setItems((prev) => [...prev, { id: idCounter++, text: t, type: "unspecified" }]);
setNewItem("");
};
const updateItemType = (id: number, type: ItemType) => {
setItems((prev) => prev.map((it) => (it.id === id ? { ...it, type } : it)));
};
const mainCardStyle: React.CSSProperties = {
border: "1px solid #e2e8f0",
borderRadius: 16,
padding: 16,
background: "rgba(255,255,255,0.96)",
boxShadow: "0 1px 2px rgba(15,23,42,0.08)",
};
const pillStyle: React.CSSProperties = {
fontSize: 10,
textTransform: "uppercase",
letterSpacing: "0.08em",
color: "#2563eb",
border: "1px solid #bfdbfe",
borderRadius: 999,
padding: "2px 8px",
background: "#eff6ff",
};
const smallText: React.CSSProperties = { fontSize: 11, color: "#6b7280" };
const renderStep = () => {
switch (step) {
case 1:
return (
Start by choosing the broad domain you want to explore.
{domains.map((d) => (
))}
{selectedDomain === "Other" && (
)}
);
case 2:
return (
Write one big problem statement or phrase. Don't worry about perfection – you can refine it later.
);
case 3:
return (
List 8–30 bad things that are connected to this problem. Think of symptoms, frustrations, risks and
missed opportunities.
Items added: {items.length} / 30
{items.length === 0 ? (
Your list will appear here as you add items.
) : (
items.map((it, idx) => (
{idx + 1}.
{it.text}
))
)}
);
case 4:
return (
For each item, decide if it is mainly a Cause, an Effect, or
Both.
{items.length === 0 ? (
Go back to Step 3 to add items first.
) : (
{items.map((it) => (
{it.text}
Label as:
))}
)}
);
case 5:
return (
Decide if you want to focus on the problem from a Systemic (macro) or
Stakeholder (micro) lens.
{lens !== "unsure" && (
)}
);
case 6:
return (
Write a hopeful, action-oriented statement. Think of IDEO's "How might we" style vision.
);
case 7:
return (
This is your AI-assisted CASE summary combining Causes (C), Stakeholders/System (S), Effects (E)
and your Action (A).
C.S.E summary
{summaryLine || (
Click "Regenerate summary" if you changed your inputs.
)}
Action (A)
{summaryAction || action || (
Your action statement will appear here.
)}
);
default:
return null;
}
};
return (
CASE Problem Definition Tool
C • A • S • E
CASE = Causes • Action statement • Stakeholder/Systemic • Effects
A guided, playful way to define complex problems using Causes, Actions, Stakeholders/System and Effects.
This tool is hard tested by farmers in Africa to leaders in Fortune 500 board rooms and built by Ycenter.
{/* step tabs */}
{stepLabels.map((label, idx) => {
const current = idx + 1;
const isActive = current === step;
const isDone = current < step;
return (
);
})}
Step {step} of {stepLabels.length} – {stepDescription[step]}
You can move backwards any time without losing your work.
{/* main step */}
{renderStep()}
Progress is only stored in this session. Download or email your summary to keep it.
{step < 7 && (
)}
{/* CASE map */}
CASE Map
Live view
A quick visual of your Causes, Actions, Stakeholders/System and Effects as you type.
Domain
{effectiveDomain || Not selected yet}
Problem
{problem || (
Add your problem statement on Step 2
)}
Causes (C)
{!causeItems.length ? (
Label some items as causes to see them here.
) : (
{causeItems.map((c) => (
-
{c.text}
))}
)}
Effects (E)
{!effectItems.length ? (
Label some items as effects to see them here.
) : (
{effectItems.map((e) => (
-
{e.text}
))}
)}
Lens (S - Systemic / Stakeholder)
{lens === "unsure" ? (
Choose your lens on Step 5.
) : (
{lens}
{lensNote ? ` – ${lensNote}` : ""}
)}
Action (A)
{action || (
Write a hopeful action statement on Step 6.
)}
CASE Summary Preview
{summaryLine || (
Your C.S.E summary will appear here on Step 7.
)}
{summaryAction && (
Action: {summaryAction}
)}
Powered by Ycenter
);
};
export default CASEWidget;