// Themed frame for pages outside a study project (Home, Import, Settings, Admin): // a calm app bar (brand, three destinations, account menu) and a page heading row. import { useEffect, useRef, useState } from 'react'; import { useApp } from '../../context/AppContext.js'; import { themeVars, READER_THEMES } from '../reader/readerThemes.js'; import { ChevronLeft, SearchIcon } from '../reader/icons.jsx'; import { useIsPhone } from '../../hooks/useIsPhone.js'; // `short` is what a phone shows; the full label is still the button's accessible name. const NAV = [ { id: 'studies', label: 'Studies', short: 'Studies' }, { id: 'reader', label: 'Read Bible', short: 'Bible' }, { id: 'plans', label: 'Reading Plans', short: 'Plans' }, { id: 'prayer', label: 'Prayer', short: 'Prayer' }, ]; const ICONS = { studies: 'M4 5.5A1.5 1.5 0 0 1 5.5 4H18a1 1 0 0 1 1 1v13a1 1 0 0 1-1 1H6a2 2 0 0 1-2-2V5.5ZM8 4v15M11 8h5M11 11.5h5', reader: 'M12 6.5C10.5 5 8 4.5 4.5 4.5V18c3.5 0 6 .5 7.5 2 1.5-1.5 4-2 7.5-2V4.5c-3.5 0-6 .5-7.5 2ZM12 6.5V20', plans: 'M5 6.5h14M5 6.5v12A1.5 1.5 0 0 0 6.5 20h11a1.5 1.5 0 0 0 1.5-1.5v-12M5 6.5A1.5 1.5 0 0 1 6.5 5H8m11 1.5A1.5 1.5 0 0 0 17.5 5H16M8 3.5v3m8-3v3M9 12.5l2 2 4-4', prayer: 'M12 20s-7-4.4-7-10a4 4 0 0 1 7-2.6A4 4 0 0 1 19 10c0 5.6-7 10-7 10Z', }; const TabIcon = ({ id }) => ( ); // Avatar button with a dropdown: who you are, the theme, Settings, Admin, Log out. function AccountMenu({ tab = false, active = false }) { const { authUser, readerTheme, setReaderTheme, setCurrentPage, logout } = useApp(); const [open, setOpen] = useState(false); const ref = useRef(null); useEffect(() => { if (!open) return undefined; const onDown = (e) => { if (!ref.current?.contains(e.target)) setOpen(false); }; const onKey = (e) => { if (e.key === 'Escape') setOpen(false); }; document.addEventListener('mousedown', onDown); document.addEventListener('keydown', onKey); return () => { document.removeEventListener('mousedown', onDown); document.removeEventListener('keydown', onKey); }; }, [open]); const go = (page) => { setOpen(false); setCurrentPage(page); }; const item = 'block w-full rounded-lg px-3 py-2 text-left text-sm hover:bg-black/5'; return (
{tab ? ( ) : ( )} {open && (
{authUser &&

{authUser.email}

}

Theme

{Object.entries(READER_THEMES).map(([id, t]) => ( ))}
{authUser && (
{authUser.isAdmin && }
)}
)}
); } export default function PageShell({ title, onBack, actions, active = null, maxWidth = 'max-w-6xl', children }) { const { readerTheme, goHome, goStudies, openBibleReader, openReadingPlans, openPrayer, openPalette } = useApp(); const go = { studies: goStudies, reader: openBibleReader, plans: openReadingPlans, prayer: openPrayer }; const phone = useIsPhone(); // On a phone the destinations sit in a bar at the bottom, where a thumb reaches; toasts lift above it. useEffect(() => { if (!phone) return undefined; document.documentElement.style.setProperty('--bottom-nav', '56px'); return () => document.documentElement.style.removeProperty('--bottom-nav'); }, [phone]); return (
Skip to content
{!phone && }
{openPalette && ( )} {!phone && }
{onBack && ( )}

{title}

{actions &&
{actions}
}
{children}
{phone && ( <> ); }