From 6c544ab41d4c31ee87873583b1076296b5c431d0 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 16 Mar 2026 20:59:28 +0000 Subject: [PATCH 1/2] [#190] Make chapter title required on chain page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Title field no longer marked optional — label updated - Submit button disabled when title is empty - Validation message shown when content is entered but title is blank Fixes #190 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/chain/page.tsx | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/app/chain/page.tsx b/src/app/chain/page.tsx index 1a13f2f0..001d1274 100644 --- a/src/app/chain/page.tsx +++ b/src/app/chain/page.tsx @@ -52,9 +52,11 @@ export default function ChainPlotPage() { const { state, error, chainPlot, reset } = useChainPlot(); const { valid, charCount } = validateContentLength(content); + const titleValid = title.trim().length > 0; const canSubmit = (state === "idle" || state === "error") && storylineId !== null && + titleValid && valid; if (!isConnected) { @@ -139,7 +141,7 @@ export default function ChainPlotPage() { {/* Chapter title */}
- {title.length}/100 +
+ {!titleValid && content.length > 0 ? ( + Title is required + ) : ( + + )} + {title.length}/100 +
{/* Content */} From 3f124fc7b4b47509e2333eada58f45851584e91d Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 16 Mar 2026 21:00:36 +0000 Subject: [PATCH 2/2] [#190] Fix placeholder and counter copy per issue spec - Placeholder: "e.g. The Silent Storm" - Counter: "42 / 100 chars" format Addresses T2a review feedback on PR #226. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/chain/page.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/chain/page.tsx b/src/app/chain/page.tsx index 001d1274..3737958c 100644 --- a/src/app/chain/page.tsx +++ b/src/app/chain/page.tsx @@ -148,7 +148,7 @@ export default function ChainPlotPage() { value={title} onChange={(e) => setTitle(e.target.value.slice(0, 100))} disabled={busy || noStoryline} - placeholder={noStoryline ? "Select a storyline first" : "e.g. The Awakening"} + placeholder={noStoryline ? "Select a storyline first" : "e.g. The Silent Storm"} maxLength={100} className="border-border bg-surface text-foreground placeholder:text-muted w-full rounded border px-3 py-2 text-sm focus:border-accent focus:outline-none disabled:opacity-50" /> @@ -158,7 +158,7 @@ export default function ChainPlotPage() { ) : ( )} - {title.length}/100 + {title.length} / 100 chars