Build and Push Docker Image / build-and-push (push) Successful in 4m15s
Studies now move through a stage bar in the reader's themes. Outline splits chunks by clicking between verses (join merges notes) and suggests chunks from section headings. Study is three panes: outline, passage with an Observe / Interpret / Apply accordion, and commentary / word study / cross-refs / people & places for the chunk; original words are added by clicking them in the interlinear. Script drafts an outline from notes; Export holds files and the share link. Home, Import and the Pronunciation guide are restyled. Study projects are BSB only. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
31 lines
2.4 KiB
React
31 lines
2.4 KiB
React
// People, places and events (Theographic data) tied to the chunk's verses.
|
|
import { loadTheographic, useAsync } from '../../hooks/useVerseStudy.js';
|
|
import { PersonCard } from '../StudyPanel.jsx';
|
|
|
|
export default function PeopleChunkTab({ book, chapter, chunk }) {
|
|
const { status, data } = useAsync(() => loadTheographic(book, chapter), [book, chapter]);
|
|
if (status === 'loading') return <p className="text-sm text-[var(--r-sub)]">Loading…</p>;
|
|
if (status === 'empty') return <p className="text-sm text-[var(--r-sub)]">No people or places data for this chapter.</p>;
|
|
const inChunk = (x) => x.verses?.some((n) => n >= chunk.startVerse && n <= chunk.endVerse);
|
|
const people = data.people.filter(inChunk);
|
|
const places = [...new Map(data.places.filter(inChunk).map((p) => [p.name, p])).values()];
|
|
const events = data.events.filter(inChunk);
|
|
if (!people.length && !places.length && !events.length) return <p className="text-sm text-[var(--r-sub)]">Nothing tagged in these verses.</p>;
|
|
const head = 'mb-1 text-[11px] uppercase tracking-wide text-[var(--r-sub)]';
|
|
return (
|
|
<div className="space-y-4">
|
|
{people.length > 0 && <div><p className={head}>People</p><ul className="space-y-1">{people.map((p) => <PersonCard key={p.id} person={p} />)}</ul></div>}
|
|
{places.length > 0 && (
|
|
<div><p className={head}>Places</p>
|
|
<ul className="space-y-1">{places.map((p) => (
|
|
<li key={p.id} className="flex items-center justify-between rounded-xl bg-[var(--r-bg)] px-3 py-2 text-sm">
|
|
<span>{p.name}{p.featureType && <span className="ml-1 text-xs text-[var(--r-sub)]">{p.featureType}</span>}</span>
|
|
{p.latitude != null && <a href={`https://www.openstreetmap.org/?mlat=${p.latitude}&mlon=${p.longitude}#map=8/${p.latitude}/${p.longitude}`} target="_blank" rel="noopener noreferrer" className="text-xs text-[var(--r-accent)] hover:underline">Map ↗</a>}
|
|
</li>))}</ul></div>
|
|
)}
|
|
{events.length > 0 && <div><p className={head}>Events</p><ul className="space-y-1">{events.map((e) => <li key={e.id} className="rounded-xl bg-[var(--r-bg)] px-3 py-2 text-sm">{e.name}{e.startDate && <span className="ml-1 text-xs text-[var(--r-sub)]">approx. AD {e.startDate}</span>}</li>)}</ul></div>}
|
|
<p className="text-[10px] text-[var(--r-sub)]">People, places and events: Theographic Bible Metadata, CC BY-SA 4.0.</p>
|
|
</div>
|
|
);
|
|
}
|