From 2ba9c9f7f417e16166c8af9e34c4a707009a859a Mon Sep 17 00:00:00 2001 From: nmemmert Date: Mon, 10 Aug 2026 10:23:48 -0400 Subject: [PATCH] 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 --- data/study-reminders.json | 2 +- package.json | 2 +- server/routes/bible-passage.js | 3 ++- src/AdminPage.tsx | 32 ++++++++++++++++++++++++++++++-- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/data/study-reminders.json b/data/study-reminders.json index 02e42e8..a03faf5 100644 --- a/data/study-reminders.json +++ b/data/study-reminders.json @@ -1,4 +1,4 @@ { "users": {}, - "updatedAt": "2026-08-10T14:07:00.476Z" + "updatedAt": "2026-08-10T14:22:31.192Z" } \ No newline at end of file diff --git a/package.json b/package.json index dd6b1b0..debb8e8 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "siteforge", "private": true, - "version": "1.1.35", + "version": "1.1.36", "type": "module", "scripts": { "dev": "vite", diff --git a/server/routes/bible-passage.js b/server/routes/bible-passage.js index b200673..745d873 100644 --- a/server/routes/bible-passage.js +++ b/server/routes/bible-passage.js @@ -18,7 +18,8 @@ const BOLLS_BOOK_MAP = { } function parseReference(reference) { - const match = reference.match(/^(\d+):(\d+)(?:-(\d+))?$/) + const stripped = reference.replace(/^[a-z]+/i, '') + const match = stripped.match(/^(\d+):(\d+)(?:-(\d+))?$/) if (!match) return null return { chapter: parseInt(match[1], 10), diff --git a/src/AdminPage.tsx b/src/AdminPage.tsx index ea57ce9..ee99859 100644 --- a/src/AdminPage.tsx +++ b/src/AdminPage.tsx @@ -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