/** * Supera Glia - Aplicação Principal * @module App * * Este módulo inicializa todos os componentes e gerencia * o estado principal da aplicação. */ (function() { 'use strict'; const { API_BASE } = SuperaGlia.config; /** * Inicializa todos os módulos da aplicação */ SuperaGlia.init = function() { // Inicializar hooks do React SuperaGlia.initHooks(); // Inicializar módulos core SuperaGlia.initAuth(); SuperaGlia.initIcons(); // Inicializar componentes compartilhados SuperaGlia.initSidebar(); SuperaGlia.initLoginScreen(); SuperaGlia.initAlunoDetalhesModal(); // Inicializar tabs SuperaGlia.initPedagogicoTab(); SuperaGlia.initAlunosTab(); SuperaGlia.initCalendarioTab(); SuperaGlia.initComunicacaoTab(); SuperaGlia.initAssistenteTab(); SuperaGlia.initEquipeTab(); SuperaGlia.initEmailTab(); SuperaGlia.initComercialTab(); // Tabs de Turmas SuperaGlia.initAlertasTab(); SuperaGlia.initReposicoesTab(); SuperaGlia.initGradeTab(); SuperaGlia.initTurmasTab(); // Tab Financeiro SuperaGlia.initFinanceiroTab(); // Renderizar aplicação ReactDOM.render( React.createElement(SuperaGlia.AuthProvider, null, React.createElement(App) ), document.getElementById('root') ); }; /** * Componente principal da aplicação */ const App = () => { const { useState, useEffect } = SuperaGlia.hooks; const { useAuth, LoginScreen, Sidebar } = SuperaGlia; const { PedagogicoTab, AlunosTab, TurmasTab, FinanceiroTab, ComercialTab, CalendarioTab, ComunicacaoTab, AssistenteTab, EquipeTab, EmailTab } = SuperaGlia; const { user, loading } = useAuth(); const [activeTab, setActiveTab] = useState('pedagogico'); const [collapsed, setCollapsed] = useState(false); // Dados estáticos para gráficos const dadosEstaticos = { motivosDesistencia: [ { motivo: 'Não Possui Horário', quantidade: 40 }, { motivo: 'Abandono / Desinteresse', quantidade: 23 }, { motivo: 'Saúde', quantidade: 18 }, { motivo: 'Financeiro', quantidade: 9 }, { motivo: 'Saúde Familiar', quantidade: 7 }, { motivo: 'Viagem', quantidade: 7 } ], evolucaoMensal: [ { mes: 'Jan/24', evasao: 4, matriculas: 7, ativos: 111 }, { mes: 'Fev/24', evasao: 2, matriculas: 5, ativos: 114 }, { mes: 'Mar/24', evasao: 3, matriculas: 6, ativos: 117 }, { mes: 'Abr/24', evasao: 2, matriculas: 4, ativos: 119 }, { mes: 'Mai/24', evasao: 4, matriculas: 5, ativos: 120 }, { mes: 'Jun/24', evasao: 5, matriculas: 8, ativos: 123 }, { mes: 'Jul/24', evasao: 14, matriculas: 6, ativos: 115 }, { mes: 'Ago/24', evasao: 6, matriculas: 9, ativos: 118 }, { mes: 'Set/24', evasao: 3, matriculas: 7, ativos: 122 }, { mes: 'Out/24', evasao: 4, matriculas: 8, ativos: 126 }, { mes: 'Nov/24', evasao: 5, matriculas: 10, ativos: 131 }, { mes: 'Dez/24', evasao: 6, matriculas: 5, ativos: 130 }, { mes: 'Jan/25', evasao: 4, matriculas: 12, ativos: 138 } ] }; const [dados, setDados] = useState({ alunos: [], turmas: [], frequencia: [], evolucaoMensal: dadosEstaticos.evolucaoMensal, motivosDesistencia: dadosEstaticos.motivosDesistencia }); const [carregandoDados, setCarregandoDados] = useState(true); // Carregar dados principais quando autenticado useEffect(() => { if (user) { carregarDados(); } }, [user]); const carregarDados = async () => { setCarregandoDados(true); try { const [alunosRes, turmasRes, frequenciaRes] = await Promise.all([ fetch(`${API_BASE}/alunos`).then(r => r.json()).catch(() => ({ alunos: [] })), fetch(`${API_BASE}/turmas`).then(r => r.json()).catch(() => ({ turmas: [] })), fetch(`${API_BASE}/pedagogico/frequencia`).then(r => r.json()).catch(() => ({ frequencia: [] })) ]); setDados({ alunos: alunosRes?.alunos || [], turmas: turmasRes?.turmas || [], frequencia: frequenciaRes?.frequencia || [], evolucaoMensal: dadosEstaticos.evolucaoMensal, motivosDesistencia: dadosEstaticos.motivosDesistencia }); } catch (e) { console.error('Erro ao carregar dados:', e); } finally { setCarregandoDados(false); } }; // Loading inicial if (loading) { return React.createElement('div', { className: 'min-h-screen flex items-center justify-center bg-gray-50' }, React.createElement('div', { className: 'text-center' }, React.createElement('div', { className: 'w-12 h-12 border-4 border-orange-200 border-t-orange-500 rounded-full animate-spin mx-auto mb-4' }), React.createElement('p', { className: 'text-gray-500' }, 'Carregando...') ) ); } // Tela de login if (!user) { return React.createElement(LoginScreen); } // Tabs que usam iframe (precisam de altura total) const TABS_IFRAME = ['comunicacao', 'email', 'assistente', 'equipe']; const isIframeTab = TABS_IFRAME.includes(activeTab); // Renderizar tab ativa const renderTab = () => { if (carregandoDados && ['pedagogico', 'turmas', 'alunos'].includes(activeTab)) { return React.createElement('div', { className: 'flex items-center justify-center h-64' }, React.createElement('div', { className: 'text-center' }, React.createElement('div', { className: 'w-10 h-10 border-4 border-orange-200 border-t-orange-500 rounded-full animate-spin mx-auto mb-4' }), React.createElement('p', { className: 'text-gray-500' }, 'Carregando dados...') ) ); } switch (activeTab) { case 'pedagogico': return React.createElement(PedagogicoTab, { dados }); case 'turmas': return React.createElement(TurmasTab, { dados, carregarDados }); case 'calendario': return React.createElement(CalendarioTab); case 'alunos': return React.createElement(AlunosTab, { dados }); case 'financeiro': return React.createElement(FinanceiroTab, { dados }); case 'comercial': return React.createElement(ComercialTab); case 'comunicacao': return React.createElement(ComunicacaoTab); case 'email': return React.createElement(EmailTab); case 'assistente': return React.createElement(AssistenteTab); case 'equipe': return React.createElement(EquipeTab); default: return React.createElement('div', { className: 'p-8 text-center text-gray-500' }, 'Página não encontrada'); } }; // Aplicação principal - SEM HEADER SUPERIOR return React.createElement('div', { className: 'min-h-screen bg-gray-50' }, // Sidebar (recebe user para mostrar nome) React.createElement(Sidebar, { activeTab, setActiveTab, collapsed, setCollapsed, user }), // Conteúdo principal - SEM HEADER React.createElement('main', { className: `sidebar-transition ${collapsed ? 'ml-16' : 'ml-64'} ${isIframeTab ? 'h-screen' : 'min-h-screen'}` }, // Conteúdo da tab React.createElement('div', { className: isIframeTab ? 'h-full p-4' : 'p-6' }, renderTab() ) ) ); }; })();