// App.jsx const { useState: useAppState, useEffect: useAppEffect, useCallback: useAppCallback } = React; // ── Theme toggle helper ─────────────────────────────────────────────────────── function getStoredTheme() { return localStorage.getItem('mona26_theme') || 'dark'; } function applyTheme(t) { document.documentElement.setAttribute('data-theme', t); localStorage.setItem('mona26_theme', t); } // ── App ─────────────────────────────────────────────────────────────────────── function App() { const [view, setView] = useAppState('loading'); const [user, setUser] = useAppState(null); const [stickers, setStickers] = useAppState({}); const [selectedCountry, setSelectedCountry] = useAppState(null); const [mobileOpen, setMobileOpen] = useAppState(false); const [theme, setTheme] = useAppState(getStoredTheme); // Apply theme on mount and change useAppEffect(() => { applyTheme(theme); }, [theme]); function toggleTheme() { setTheme(t => { const n = t==='dark'?'light':'dark'; applyTheme(n); return n; }); } useAppEffect(() => { DB.getCurrentUser().then(u => { if (u) { setUser(u); DB.getStickers().then(s => setStickers(s)); setView('dashboard'); } else setView('auth'); }); }, []); function handleLogin(u) { setUser(u); DB.getStickers().then(s => setStickers(s)); setView('dashboard'); } async function handleLogout() { await DB.logout(); setUser(null); setStickers({}); setView('auth'); } function navigate(v, country) { setView(v); if (country) setSelectedCountry(country); setMobileOpen(false); } const handleUpdateSticker = useAppCallback((id, qty) => { setStickers(prev => ({ ...prev, [id]: qty })); DB.updateSticker(id, qty); }, []); if (view === 'loading') return (
🏆

Cargando…

); if (view === 'auth') return ; const displayName = user?.name || user?.email?.split('@')[0] || 'Coleccionista'; return (
{/* ── Sidebar ─────────────────────────────────────────── */} {/* ── Mobile top bar ────────────────────────────────── */}
{view==='dashboard'?'Resumen':view==='album'?'Álbum':view==='country'?'Láminas':view==='trades'?'Intercambios':''}
{/* Mobile overlay */} {mobileOpen &&
setMobileOpen(false)} />} {/* ── Main content ──────────────────────────────────── */}
{view === 'dashboard' && } {view === 'album' && navigate('country', c)} />} {view === 'country' && selectedCountry && ( setView('album')} /> )} {view === 'trades' && }
); } // ── Sidebar Progress Widget ─────────────────────────────────────────────────── function SidebarProgress({ stickers }) { const { ALL_STICKERS } = ALBUM_DATA; const owned = ALL_STICKERS.filter(s => (stickers[s.id]||0) >= 1).length; const pct = Math.round(owned / ALL_STICKERS.length * 100); return (
Progreso {pct}%
{owned} / {ALL_STICKERS.length}
); } const sCSS = { sidebar: { width:240, background:'var(--surface2)', borderRight:'1px solid var(--border)', display:'flex', flexDirection:'column', position:'fixed', top:0, left:0, height:'100vh', zIndex:100, padding:'20px 0', transition:'transform .3s', overflowY:'auto' }, brand: { display:'flex', alignItems:'center', gap:10, padding:'0 16px 16px', borderBottom:'1px solid var(--border)', marginBottom:12 }, themeBtn: { marginLeft:'auto', background:'none', border:'none', fontSize:18, cursor:'pointer', padding:'4px 6px', borderRadius:8 }, userChip: { display:'flex', alignItems:'center', gap:10, background:'var(--surface)', borderRadius:10, padding:'10px 12px', margin:'0 16px 4px' }, avatar: { width:32, height:32, borderRadius:'50%', background:'var(--green)', color:'#fff', display:'flex', alignItems:'center', justifyContent:'center', fontWeight:800, fontSize:14, flexShrink:0 }, navBtn: { display:'flex', alignItems:'center', gap:12, width:'100%', padding:'10px 12px', background:'none', border:'none', borderRadius:10, color:'var(--text-muted)', fontSize:14, cursor:'pointer', marginBottom:2, fontWeight:500 }, navActive: { background:'var(--green-bg)', color:'var(--green)', fontWeight:700 }, logoutBtn: { padding:'9px 12px', background:'none', border:'none', borderRadius:8, color:'var(--text-dimmer)', fontSize:13, cursor:'pointer', textAlign:'left', marginBottom:8 }, topBar: { display:'none', position:'fixed', top:0, left:0, right:0, height:52, background:'var(--surface2)', borderBottom:'1px solid var(--border)', zIndex:99, alignItems:'center', justifyContent:'space-between', padding:'0 16px' }, menuBtn: { background:'none', border:'none', color:'var(--text)', fontSize:20, cursor:'pointer', width:36 }, overlay: { position:'fixed', inset:0, background:'rgba(0,0,0,.55)', zIndex:99 }, main: { marginLeft:240, flex:1, minHeight:'100vh', background:'var(--bg)' }, }; ReactDOM.createRoot(document.getElementById('root')).render();