// The Outline stage: choose a chapter, then cut it into chunks by clicking between // verses (or let the section headings suggest them). Each chunk becomes one unit of // study in the next stage. import { STUDY_TEMPLATES, getTemplate } from '../utils/studyTemplates.js'; import { useApp } from '../context/AppContext.js'; import { useChunkBuilder } from '../hooks/useChunkBuilder.js'; import StudioShell from '../components/study/StudioShell.jsx'; import { bookOptions, formatChunkReference } from '../utils/bibleUtils.jsx'; const inputCls = 'mt-1 block w-full rounded-xl border border-[var(--r-line)] bg-[var(--r-bg)] px-3 py-2 text-sm text-[var(--r-text)] focus:outline-none focus:ring-2 focus:ring-[var(--r-line)]'; const smallBtn = 'rounded-lg border border-[var(--r-line)] px-2.5 py-1.5 text-xs hover:bg-black/5 disabled:opacity-40'; const primaryBtn = 'rounded-xl bg-[var(--r-accent)] px-5 py-2.5 text-sm font-medium text-[var(--r-on)] hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-40'; // Band tints that alternate from chunk to chunk so neighbouring chunks are easy to tell apart. const BANDS = ['color-mix(in srgb, var(--r-accent) 13%, transparent)', 'color-mix(in srgb, var(--r-sub) 17%, transparent)']; function PassageForm({ setup, onField, onTitleChange, onLoad, loading, error, withTitle, userTemplates = [], onDeleteTemplate }) { return (
{withTitle && ( )} {withTitle && ( )}

{error ? {error} : 'Text: Berean Standard Bible (BSB).'}

); } export default function SetupPage() { const { project, setProject, allChunks, updateProject, setCurrentPage, userTemplates, deleteUserTemplate } = useApp(); const b = useChunkBuilder({ project, setProject, updateProject, allChunks, setCurrentPage, userTemplates }); const { activeChapter, activeChapterIndex } = b; const chapters = project?.chapters ?? []; const onTitleChange = (val) => { b.setTitleEdited(true); b.handleSetupField('title', val); }; const select = (id) => updateProject((current) => ({ ...current, selectedChunkId: id })); // Which chunk (if any) each verse of the active chapter belongs to const chunkOf = (n) => activeChapter?.chunks.findIndex((c) => n >= c.startVerse && n <= c.endVerse) ?? -1; const prevChapter = chapters[activeChapterIndex - 1]; const spilledFromPrev = (n) => !!prevChapter && prevChapter.bookAbbrev === activeChapter.bookAbbrev && prevChapter.chunks.some((c) => Number.isInteger(c.spilloverEndVerse) && n <= c.spilloverEndVerse); const lastVerse = activeChapter?.verses.at(-1)?.number ?? 0; const uncovered = activeChapter ? activeChapter.verses.some((v) => chunkOf(v.number) < 0 && !spilledFromPrev(v.number)) : false; return (
{!project && (

New study

Pick a chapter, then cut it into chunks. You’ll study one chunk at a time.

)} {project && (
{chapters.map((ch, idx) => ( ))}
{b.showAddChapterForm && (

Add another chapter

)} {activeChapter && (

Scripture & Chunks

{activeChapter.book} {activeChapter.chapter} ({project.translation})

Click the line between two verses to split or join chunks. Or click a verse, then shift-click another, to make a chunk from that range.

b.setVerseSearch(e.target.value)} placeholder="Search verses in this chapter…" className="mb-3 w-full rounded-xl border border-[var(--r-line)] bg-[var(--r-bg)] px-3 py-2 text-sm text-[var(--r-text)] focus:outline-none focus:ring-2 focus:ring-[var(--r-line)]" />
{activeChapter.verses .filter((v) => v.text.toLowerCase().includes(b.verseSearch.trim().toLowerCase())) .map((verse) => { const n = verse.number; const ci = chunkOf(n); const chunk = ci >= 0 ? activeChapter.chunks[ci] : null; const inRange = b.rangeStart !== null && n >= Math.min(b.rangeStart, b.rangeEnd) && n <= Math.max(b.rangeStart, b.rangeEnd); const isFirst = chunk && chunk.startVerse === n; const next = activeChapter.chunks.find((c) => c.startVerse === n + 1); const insideChunk = chunk && n < chunk.endVerse && !chunk.spilloverEndVerse; const endsChunk = chunk && chunk.endVerse === n && next && chunk.id; const showGutter = n < lastVerse && !b.verseSearch.trim(); return (
{isFirst && ( )} {showGutter && (insideChunk ? ( ) : endsChunk ? ( ) : !chunk && !spilledFromPrev(n) ? ( ) :
)}
); })}
)}
{activeChapter && (