// admin-app.jsx — Wrapper principal: auth → tabs → CRUD const { useState, useEffect } = React; const AdminApp = () => { const [booting, setBooting] = useState(true); const [authed, setAuthed] = useState(false); const [profile, setProfile] = useState(null); const [tab, setTab] = useState('vehiculos'); // 'vehiculos' | 'leads' | 'usuarios' const [route, setRoute] = useState('list'); // 'list' | 'new' | 'edit' const [editingId, setEditingId] = useState(null); const [vehicles, setVehicles] = useState([]); const [loading, setLoading] = useState(true); const [toast, setToast] = useState(null); const [configError, setConfigError] = useState(false); // Global helpers window.__adm_toast = (t) => setToast(t); const puede = (s) => profile?.role === 'admin' || (profile?.secciones || []).includes(s); useEffect(() => { if (!profile) return; const ord = [['vehiculos','web_vehiculos'],['leads','web_consultas'],['usuarios','web_usuarios']]; const ok = ord.filter(([t,sx]) => profile.role==='admin' || (profile.secciones||[]).includes(sx)); if (ok.length && !ok.some(([t]) => t===tab)) setTab(ok[0][0]); }, [profile]); // === BOOT: ¿hay sesión activa? === useEffect(() => { (async () => { try { // Si no hay backend (ni Supabase configurado ni store local), mostramos config if (!window.OMEGA_STORE) { setConfigError(true); setBooting(false); return; } await window.OMEGA_STORE.init(); const p = window.OMEGA_STORE.currentProfile(); if (p) { setProfile(p); setAuthed(true); await loadVehicles(); } } catch (e) { console.warn('Boot error:', e); } finally { setBooting(false); } })(); }, []); const loadVehicles = async () => { setLoading(true); try { const list = await window.OMEGA_STORE.getRawVehicles(window.OMEGA_DATA.vehicles); setVehicles(list); } catch (e) { window.__adm_toast({ msg: 'Error al cargar vehículos: ' + e.message, type: 'error' }); } finally { setLoading(false); } }; const handleAuth = async () => { const p = await window.OMEGA_STORE.refreshProfile(); setProfile(p); setAuthed(true); await loadVehicles(); }; const handleLogout = async () => { await window.OMEGA_STORE.signOut(); setAuthed(false); setProfile(null); setVehicles([]); setRoute('list'); setTab('vehiculos'); }; const handleNew = () => { setEditingId(null); setRoute('new'); }; const handleEdit = (id) => { setEditingId(id); setRoute('edit'); }; const handleCancel = async () => { setRoute('list'); await loadVehicles(); }; const handleSave = async (vehicleData) => { try { await window.OMEGA_STORE.saveVehicle(vehicleData); await loadVehicles(); setRoute('list'); setToast({ msg: vehicleData.draft ? 'Auto oculto de la web' : 'Cambios guardados · visible en la web', type:'success' }); } catch (e) { setToast({ msg: 'Error al guardar: ' + e.message, type:'error' }); } }; const handleDelete = async (id) => { try { await window.OMEGA_STORE.deleteVehicle(id); await loadVehicles(); setToast({ msg: 'Fotos eliminadas de la web', type:'success' }); } catch (e) { setToast({ msg: 'Error al eliminar: ' + e.message, type:'error' }); } }; const handleTogglePublished = async (id) => { const v = vehicles.find(x => x.id === id); if (!v) return; try { await window.OMEGA_STORE.saveVehicle({ ...v, draft: !v.draft }); await loadVehicles(); setToast({ msg: v.draft ? 'Visible en la web' : 'Oculto de la web', type:'success' }); } catch (e) { setToast({ msg: 'Error: ' + e.message, type:'error' }); } }; // === RENDER === if (configError) { return (
OMEGA
Configuración pendiente

Conectar a Supabase

El back-office requiere conectarse a la base de datos. Seguí los pasos del archivo SETUP-SUPABASE.md:

  1. Crear proyecto en supabase.com
  2. Ejecutar el schema SQL
  3. Crear bucket vehicle-photos
  4. Editar supabase-config.js con tu URL y anon key
Editá supabase-config.js para empezar
); } if (booting) { return (
Iniciando back-office...
); } if (!authed) return ; if (loading) { return (
CARGANDO INVENTARIO...
); } const currentVehicle = route === 'edit' && editingId ? vehicles.find(v => v.id === editingId) : null; return ( {/* === Vehículos === */} {tab === 'vehiculos' && puede('web_vehiculos') && route === 'list' && ( )} {tab === 'vehiculos' && puede('web_vehiculos') && (route === 'new' || route === 'edit') && ( )} {/* === Leads === */} {tab === 'leads' && puede('web_consultas') && ( )} {/* === Usuarios (solo admin) === */} {tab === 'usuarios' && puede('web_usuarios') && ( )} {/* === Toast === */} {toast && setToast(null)}/>} ); }; const root = ReactDOM.createRoot(document.getElementById('root')); root.render();