Add Fetch from BSB button to admin lesson editor; v1.1.36
Adds a one-click "Fetch from BSB" button in the lesson passage text field that calls the BSB API and overwrites the field with verse-numbered text. Also fixes reference parsing to tolerate leading book abbreviations like t:1-2 or col:1-2 by stripping letters before the chapter:verse pattern. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+30
-2
@@ -21,6 +21,28 @@ interface SortableLessonSectionProps {
|
||||
|
||||
function SortableLessonSection({ section, study, updateStudySection, removeStudySection, rssEpisodes }: SortableLessonSectionProps) {
|
||||
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: section.id })
|
||||
const [bsbFetching, setBsbFetching] = useState(false)
|
||||
const [bsbMsg, setBsbMsg] = useState('')
|
||||
|
||||
async function fetchBsbPassage() {
|
||||
const bookKey = (study.bibleBook?.trim() || study.slug).toLowerCase()
|
||||
const reference = section.reference?.trim()
|
||||
if (!bookKey || !reference) { setBsbMsg('Set the passage reference first.'); return }
|
||||
setBsbFetching(true)
|
||||
setBsbMsg('')
|
||||
try {
|
||||
const params = new URLSearchParams({ book: bookKey, reference })
|
||||
const res = await fetch(`/api/bible-passage?${params}`)
|
||||
const data = await res.json() as { text?: string; message?: string }
|
||||
if (!res.ok || !data.text) { setBsbMsg(data.message ?? 'Passage not found.'); return }
|
||||
updateStudySection(study.id, section.id, 'passageText', data.text)
|
||||
setBsbMsg('Passage filled from BSB.')
|
||||
} catch {
|
||||
setBsbMsg('Could not reach the BSB API.')
|
||||
} finally {
|
||||
setBsbFetching(false)
|
||||
}
|
||||
}
|
||||
const style = {
|
||||
transform: CSS.Transform.toString(transform),
|
||||
transition,
|
||||
@@ -94,8 +116,14 @@ function SortableLessonSection({ section, study, updateStudySection, removeStudy
|
||||
<textarea id={`study-section-announcement-${study.id}-${section.id}`} rows={3} value={section.announcement ?? ''} placeholder="A short instructor announcement for this lesson." onChange={e => updateStudySection(study.id, section.id, 'announcement', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`study-section-passage-${study.id}-${section.id}`}>Passage Text</label>
|
||||
<textarea id={`study-section-passage-${study.id}-${section.id}`} rows={4} value={section.passageText} placeholder="Paste the passage text here." onChange={e => updateStudySection(study.id, section.id, 'passageText', e.target.value)} />
|
||||
<div style={{ display: 'flex', alignItems: 'center', gap: '0.75rem', flexWrap: 'wrap', marginBottom: '0.35rem' }}>
|
||||
<label htmlFor={`study-section-passage-${study.id}-${section.id}`} style={{ margin: 0 }}>Passage Text</label>
|
||||
<button type="button" className="btn-admin-secondary" disabled={bsbFetching} onClick={fetchBsbPassage} style={{ fontSize: '0.8rem', padding: '0.2rem 0.75rem' }}>
|
||||
{bsbFetching ? 'Fetching…' : 'Fetch from BSB'}
|
||||
</button>
|
||||
{bsbMsg && <span style={{ fontSize: '0.8rem', color: bsbMsg.includes('filled') ? '#7abf7a' : '#c97070' }}>{bsbMsg}</span>}
|
||||
</div>
|
||||
<textarea id={`study-section-passage-${study.id}-${section.id}`} rows={4} value={section.passageText} placeholder="Paste the passage text here, or use Fetch from BSB." onChange={e => updateStudySection(study.id, section.id, 'passageText', e.target.value)} />
|
||||
</div>
|
||||
<div className="admin-field">
|
||||
<label htmlFor={`study-section-commentary-${study.id}-${section.id}`}>Commentary</label>
|
||||
|
||||
Reference in New Issue
Block a user