// A person's family: the relatives named in their record (click one to read about them), and a tree of ancestors and // descendants a few generations out. From Theographic Bible Metadata. import { useEffect, useState } from 'react'; import { loadPerson } from '../hooks/useVerseStudy.js'; import { relatives, walk } from '../utils/family.js'; function Branch({ node, onOpen }) { return (
  • {node.more && …} {node.kids.length > 0 && }
  • ); } function Tree({ id, onOpen }) { const [state, setState] = useState({ loading: true }); useEffect(() => { let live = true; Promise.all([walk(loadPerson, id, { direction: 'up', depth: 3, max: 30 }), walk(loadPerson, id, { direction: 'down', depth: 2, max: 40 })]) .then(([up, down]) => { if (live) setState({ up, down }); }) .catch(() => { if (live) setState({ error: true }); }); return () => { live = false; }; }, [id]); if (state.loading) return

    Loading the family…

    ; if (state.error) return

    The family tree couldn’t be loaded right now.

    ; const block = (title, node, empty) => (

    {title}

    {node.kids.length ? :

    {empty}

    }
    ); return
    {block('Ancestors', state.up, 'None recorded.')}{block('Descendants', state.down, 'None recorded.')}
    ; } // `person` is the record; `renderPerson(id)` shows another person's details inside this one when a name is clicked. export default function Family({ person, renderPerson }) { const groups = relatives(person); const [shown, setShown] = useState(null); // a relative opened from a name or the tree const [treeOpen, setTreeOpen] = useState(false); // the tree's records are only fetched once it is opened if (groups.length === 0) return null; return (
    {groups.map((g) => (

    {g.label} {g.people.map((p) => ( ))}

    ))}
    setTreeOpen(e.currentTarget.open)}> Family tree {treeOpen && setShown(id)} />}
    {shown &&
    {renderPerson(shown)}
    }
    ); }