// App shell: header with angled tabs, role toggle, menu, settings, persistence.
const { useState, useEffect } = React;
const DEFAULT_CONFIG = {
name: 'Shalom Bible Baptist Mission',
logo: 'Shalom logo',
welcomeBg: 'Plants.png',
admins: 'Admin User 1, Admin User 2, Admin User 3',
users: 'User 1, User 2, User 3, User 4, User 5, User 6',
themeId: 'warm-stone',
slidesName: 'The Salvation',
deckName: 'The Salvation',
ytUser: 'sample@gmail.com',
ytPass: '12345678abc',
emailjsKey: '',
emailjsService: '',
emailjsTemplate: '',
slideImages: [],
hymns: window.DEMO_HYMNS.map(h=>({ ...h })),
prayer: JSON.parse(JSON.stringify(window.DEMO_PRAYER)),
lastUpdate: 'Feb 1, 2026'
};
function loadConfig(){
try{
const raw = localStorage.getItem('cwa-config');
if(raw){ return { ...DEFAULT_CONFIG, ...JSON.parse(raw) }; }
}catch(e){}
return JSON.parse(JSON.stringify(DEFAULT_CONFIG));
}
const TABS = ['Slides','Bible','Hymns','Prayer'];
function App(){
const themes = window.CHURCH_THEMES;
const [config, setConfig] = useState(loadConfig);
const [tab, setTab] = useState(()=> localStorage.getItem('cwa-tab') || 'Slides');
const [accounts, setAccounts] = useState(()=> window.loadAccounts());
const [currentUser, setCurrentUser] = useState(()=>{ const a = window.loadAccounts(); return a ? window.loadSession(a) : null; });
const [menu, setMenu] = useState(false);
const [settings, setSettings] = useState(false);
const [fs, setFs] = useState(false);
const [fsPrompt, setFsPrompt] = useState(()=> !localStorage.getItem('cwa-fsdismiss'));
// ----- Full-screen "focus" mode -----
function toggleFs(){
const d = document;
if(!d.fullscreenElement){
const el = d.documentElement;
const req = el.requestFullscreen || el.webkitRequestFullscreen || el.msRequestFullscreen;
if(req) req.call(el).catch(()=>{});
}else{
(d.exitFullscreen || d.webkitExitFullscreen || d.msExitFullscreen).call(d);
}
}
function dismissPrompt(){ setFsPrompt(false); localStorage.setItem('cwa-fsdismiss','1'); }
useEffect(()=>{
const on = ()=> setFs(!!document.fullscreenElement);
document.addEventListener('fullscreenchange', on);
document.addEventListener('webkitfullscreenchange', on);
// keyboard: F toggles, Esc exits (browser handles esc natively)
const key = (e)=>{ if((e.key==='f'||e.key==='F') && !/input|textarea/i.test(e.target.tagName) && !e.target.isContentEditable){ toggleFs(); } };
window.addEventListener('keydown', key);
return ()=>{ document.removeEventListener('fullscreenchange', on); document.removeEventListener('webkitfullscreenchange', on); window.removeEventListener('keydown', key); };
}, []);
// apply theme whenever it changes
useEffect(()=>{
const t = themes.find(x=>x.id===config.themeId) || themes[0];
window.applyTheme(t);
}, [config.themeId]);
useEffect(()=>{
try{ localStorage.setItem('cwa-config', JSON.stringify(config)); }
catch(e){
// uploaded slide images can exceed the localStorage quota — persist everything else
try{ const { slideImages, ...rest } = config; localStorage.setItem('cwa-config', JSON.stringify(rest)); }catch(e2){}
}
}, [config]);
useEffect(()=>{ localStorage.setItem('cwa-tab', tab); }, [tab]);
const today = ()=> new Date().toLocaleDateString('en-US',{ month:'short', day:'numeric', year:'numeric' });
const setPrayer = (updater)=> setConfig(c=>({ ...c, prayer: typeof updater==='function' ? updater(c.prayer) : updater }));
const touchPrayer = ()=> setConfig(c=>({ ...c, lastUpdate: today() }));
function saveSettings(draft){
setConfig(c=>({ ...c, ...draft }));
setSettings(false);
}
function onAuth(a, user){ setAccounts(a); setCurrentUser(user); }
function logout(){ window.setSession(null); setCurrentUser(null); setMenu(false); setSettings(false); }
const role = currentUser ? currentUser.role : 'user';
const isAdmin = window.isAdminRole(role);
// theme is applied above; show login until authenticated
if(!currentUser){
return