-
-
-
- updateStudyProgram(study.id, 'title', e.target.value)} />
-
-
-
- updateStudyProgram(study.id, 'slug', e.target.value.trim().toLowerCase().replace(/[^a-z0-9-]/g, '-'))} />
-
-
-
-
updateStudyProgram(study.id, 'bibleBook', e.target.value.trim().toLowerCase().replace(/\s+/g, ''))} />
-
Lowercase book name used to fetch BSB passage text. E.g. colossians, ephesians, 1corinthians. Leave blank if the slug matches the book name.
-
-
-
-
-
-
-
-
-
-
- updateStudyProgram(study.id, 'homepageEyebrow', e.target.value)} />
-
-
-
- updateStudyProgram(study.id, 'newTagLabel', e.target.value)} />
-
-
- updateStudyProgram(study.id, 'showOnHomepage', e.target.checked)} />
-
-
-
- updateStudyProgram(study.id, 'showNewTag', e.target.checked)} />
-
-
-
-
-
- updateStudyProgram(study.id, "numberOfChapters", Number(e.target.value) || 1)} />
-
-
+ {/* ── LEVEL 0: Study list ── */}
+ {!activeStudy && (
+ <>
+
+
Studies
+
Select a study to manage its lessons and settings.
+
+ {(form.studies ?? []).length === 0 &&
No studies yet.
}
+
+ {(form.studies ?? []).map(study => (
+
+ ))}
+
+
+ {renderSaveStatus()}
+ >
+ )}
+
+ {/* ── LEVEL 1: Study detail + compact lesson list ── */}
+ {activeStudy && !activeLesson && (
+ <>
+
+
+
{activeStudy.title || 'Untitled Study'}
- {(study.sections ?? []).length === 0 && (
-
No sections yet for this study.
- )}
+
+
+ Study SettingsTitle, slug, description, and homepage display
+ Expand to edit
+
+
+
+
+
+ updateStudyProgram(activeStudy.id, 'title', e.target.value)} />
+
+
+
+ updateStudyProgram(activeStudy.id, 'slug', e.target.value.trim().toLowerCase().replace(/[^a-z0-9-]/g, '-'))} />
+
+
+
+
updateStudyProgram(activeStudy.id, 'bibleBook', e.target.value.trim().toLowerCase().replace(/\s+/g, ''))} />
+
Lowercase book name for BSB fetch. E.g. colossians, ephesians, 1corinthians. Leave blank if slug matches.
+
+
+
+
+
+
+
+
+
+
+ updateStudyProgram(activeStudy.id, 'homepageEyebrow', e.target.value)} />
+
+
+
+ updateStudyProgram(activeStudy.id, 'newTagLabel', e.target.value)} />
+
+
+
+ updateStudyProgram(activeStudy.id, 'numberOfChapters', Number(e.target.value) || 1)} />
+
+
+ updateStudyProgram(activeStudy.id, 'showOnHomepage', e.target.checked)} />
+
+
+
+ updateStudyProgram(activeStudy.id, 'showNewTag', e.target.checked)} />
+
+
+
+
+
+
+
+
+
Lessons ({(activeStudy.sections ?? []).length})
+
+
+ {(activeStudy.sections ?? []).length === 0 &&
No lessons yet. Add one below.
}
+
+
+
+ Reference
+ Title
+ Status
+
+
) {
onDragEnd={({ active, over }) => {
const overId = over?.id
if (!overId || active.id === overId) return
- setForm(f => {
- const studies = f.studies.map(s => {
- if (s.id !== study.id) return s
- const oldIndex = s.sections.findIndex(sec => sec.id === active.id)
- const newIndex = s.sections.findIndex(sec => sec.id === overId)
- if (oldIndex === -1 || newIndex === -1) return s
- const newSections = arrayMove(s.sections, oldIndex, newIndex)
- return { ...s, sections: newSections }
- })
- return { ...f, studies }
- })
+ setForm(f => ({
+ ...f,
+ studies: (f.studies ?? []).map(s => {
+ if (s.id !== activeStudy.id) return s
+ const oldIdx = s.sections.findIndex(sec => sec.id === active.id)
+ const newIdx = s.sections.findIndex(sec => sec.id === overId)
+ if (oldIdx === -1 || newIdx === -1) return s
+ return { ...s, sections: arrayMove(s.sections, oldIdx, newIdx) }
+ }),
+ }))
}}
>
- section.id)}
- strategy={verticalListSortingStrategy}
- >
- {(study.sections ?? []).map(section => (
- s.id)} strategy={verticalListSortingStrategy}>
+ {(activeStudy.sections ?? []).map(section => (
+ setSelectedLessonId(section.id)}
removeStudySection={removeStudySection}
- rssEpisodes={rssEpisodes}
/>
))}
+
+ {renderSaveStatus()}
+ >
+ )}
-
-
- ))}
+ {/* ── LEVEL 2: Lesson editor ── */}
+ {activeStudy && activeLesson && (
+ <>
+
+
+
+ {activeLessonIndex > 0 && (
+
+ )}
+ {activeLessonIndex < activeStudy.sections.length - 1 && (
+
+ )}
+
Preview ↗
+
+
-
- {renderSaveStatus()}
-
- )}
+
+
{activeLesson.title || 'Untitled Lesson'}{activeLesson.reference ? ` · ${activeLesson.reference}` : ''}
+
+
+
+
+
+
+
+
+
+ updateStudySection(activeStudy.id, activeLesson.id, 'reference', e.target.value)} />
+
+
+
+ updateStudySection(activeStudy.id, activeLesson.id, 'title', e.target.value)} />
+
+
+
+
+
+
+
+ {
+ const val = e.target.value
+ updateStudySection(activeStudy.id, activeLesson.id, 'releasedAt', val ? new Date(val + ':00Z').toISOString() : '')
+ }} />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ updateStudySection(activeStudy.id, activeLesson.id, 'focusQuestion', e.target.value)} />
+
+
+
+
+
+
+ updateStudySection(activeStudy.id, activeLesson.id, 'checkpointPrompt', e.target.value)} />
+
+
+
+
+
+ {renderSaveStatus()}
+ >
+ )}
+
+
+ )
+ })()}
{/* GLOBAL / FOOTER & PLATFORM */}
{adminView === 'global' && (
diff --git a/src/App.css b/src/App.css
index 1641c4d..52db602 100644
--- a/src/App.css
+++ b/src/App.css
@@ -6122,6 +6122,166 @@
border-color: rgba(224, 92, 92, 0.4);
}
+/* ── Studies master-detail ── */
+
+.study-program-list {
+ display: flex;
+ flex-direction: column;
+ gap: 0.375rem;
+ margin-bottom: 1rem;
+}
+
+.study-program-row {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ padding: 0.875rem 1rem;
+ background: var(--admin-card-bg);
+ border: 1px solid var(--admin-card-border);
+ border-radius: 8px;
+ cursor: pointer;
+ text-align: left;
+ width: 100%;
+ color: var(--admin-text);
+ font-family: var(--brand-font-body);
+ transition: border-color 0.15s, background 0.15s;
+}
+.study-program-row:hover {
+ border-color: rgba(201, 168, 76, 0.5);
+ background: rgba(201, 168, 76, 0.04);
+}
+.study-program-info {
+ display: flex;
+ flex-direction: column;
+ gap: 0.2rem;
+}
+.study-program-info strong { font-size: 0.95rem; color: var(--admin-heading); }
+.study-program-info span { font-size: 0.78rem; color: var(--admin-muted); }
+.study-program-meta {
+ display: flex;
+ align-items: center;
+ gap: 0.75rem;
+ font-size: 0.8rem;
+ color: var(--admin-muted);
+ flex-shrink: 0;
+}
+
+.study-status-pill {
+ display: inline-flex;
+ align-items: center;
+ padding: 0.15rem 0.55rem;
+ border-radius: 100px;
+ font-size: 0.72rem;
+ font-weight: 600;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+}
+.study-status-pill.active { background: rgba(122, 191, 122, 0.15); color: #7abf7a; }
+.study-status-pill.planned { background: rgba(201, 168, 76, 0.15); color: var(--brand-gold); }
+
+.study-drill-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ gap: 1rem;
+ margin-bottom: 1.25rem;
+ flex-wrap: wrap;
+}
+.study-drill-header h2 { margin: 0; font-size: 1.15rem; }
+
+.study-back-btn {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.3rem;
+ background: transparent;
+ border: none;
+ color: var(--brand-gold);
+ font-family: var(--brand-font-body);
+ font-size: 0.85rem;
+ font-weight: 600;
+ cursor: pointer;
+ padding: 0.3rem 0;
+ letter-spacing: 0.03em;
+}
+.study-back-btn:hover { opacity: 0.75; }
+
+.study-lesson-list-header {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0 0.75rem 0.4rem;
+ font-size: 0.72rem;
+ font-weight: 700;
+ letter-spacing: 0.07em;
+ text-transform: uppercase;
+ color: var(--admin-muted);
+ border-bottom: 1px solid var(--admin-card-border);
+ margin-bottom: 0.25rem;
+}
+
+.study-lesson-row {
+ display: flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.6rem 0.75rem;
+ border-bottom: 1px solid var(--admin-card-border);
+ transition: background 0.12s;
+}
+.study-lesson-row:hover { background: rgba(201, 168, 76, 0.04); }
+
+.study-lesson-drag {
+ cursor: grab;
+ color: var(--admin-muted);
+ font-size: 1rem;
+ padding: 0 0.1rem;
+ width: 20px;
+ text-align: center;
+ flex-shrink: 0;
+ user-select: none;
+}
+.study-lesson-drag:active { cursor: grabbing; }
+
+.study-lesson-ref {
+ width: 80px;
+ flex-shrink: 0;
+ font-size: 0.82rem;
+ color: var(--admin-muted);
+ font-variant-numeric: tabular-nums;
+}
+
+.study-lesson-title {
+ flex: 1;
+ font-size: 0.88rem;
+ color: var(--admin-text);
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.study-lesson-pill {
+ display: inline-flex;
+ align-items: center;
+ padding: 0.12rem 0.5rem;
+ border-radius: 100px;
+ font-size: 0.7rem;
+ font-weight: 600;
+ letter-spacing: 0.04em;
+ text-transform: uppercase;
+ flex-shrink: 0;
+ width: 48px;
+ justify-content: center;
+}
+.study-lesson-pill.live { background: rgba(122, 191, 122, 0.15); color: #7abf7a; }
+.study-lesson-pill.draft { background: rgba(201, 168, 76, 0.1); color: var(--brand-gold); }
+
+.study-lesson-actions {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ flex-shrink: 0;
+}
+
.btn-admin-apply {
background: transparent;
color: var(--brand-gold);