document.addEventListener('DOMContentLoaded', () => { // Configurações const API_URL = '/api/admin/clinics'; // Pegar Token JWT do Admin const token = localStorage.getItem('auth_token') || ''; // Se não tem token, redirecionar imediatamente para login if (!token) { window.location.href = '/login'; return; } const fetchOptions = { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` } }; // Elementos UI const clinicsTableBody = document.getElementById('clinicsTableBody'); const addClinicBtn = document.getElementById('addClinicBtn'); const clinicModal = document.getElementById('clinicModal'); const tokenModal = document.getElementById('tokenModal'); const closeModals = document.querySelectorAll('.close-modal'); const closeTokenModal = document.querySelector('.close-token-modal'); const clinicForm = document.getElementById('clinicForm'); const generatedTokenElem = document.getElementById('generatedToken'); const copyTokenBtn = document.getElementById('copyTokenBtn'); // Stats const totalDevicesElem = document.getElementById('totalDevices'); const activeDevicesElem = document.getElementById('activeDevices'); const blockedDevicesElem = document.getElementById('blockedDevices'); // Inicializar loadClinics(); // ========================================== // Carregar Clínicas // ========================================== async function loadClinics() { try { const response = await fetch(API_URL, fetchOptions); // Se recebeu 401 ou 403, token expirou — vai para login if (response.status === 401 || response.status === 403) { localStorage.removeItem('auth_token'); window.location.href = '/login'; return; } // Verificar se a resposta é realmente JSON (evita erro com HTML) const contentType = response.headers.get('content-type') || ''; if (!contentType.includes('application/json')) { throw new Error('Sessão expirada ou servidor indisponível. Faça login novamente.'); } if (!response.ok) { throw new Error(`Erro HTTP ${response.status}`); } const data = await response.json(); if (data.success) { renderClinics(data.clinics); updateStats(data.clinics); } else { showToast(data.message, 'error'); } } catch (error) { console.error(error); clinicsTableBody.innerHTML = `${error.message || 'Erro ao carregar dados.'}`; } } // ========================================== // Renderizar Tabela // ========================================== function renderClinics(clinics) { if (clinics.length === 0) { clinicsTableBody.innerHTML = `Nenhum dispositivo cadastrado.`; return; } clinicsTableBody.innerHTML = ''; clinics.forEach(c => { const isAct = c.is_active; const statusClass = isAct ? 'status-active' : 'status-inactive'; const statusIcon = isAct ? 'fa-check' : 'fa-ban'; const statusText = isAct ? 'Ativo' : 'Bloqueado'; const tr = document.createElement('tr'); tr.innerHTML = ` ${statusText} ${c.clinic_name} ${c.pc_name || '-'} ${c.email} ${c.last_ip || 'Nunca conectou'} ${c.machine_token.split('-')[0]}...
`; clinicsTableBody.appendChild(tr); }); } function updateStats(clinics) { const total = clinics.length; const active = clinics.filter(c => c.is_active).length; const blocked = total - active; totalDevicesElem.textContent = total; activeDevicesElem.textContent = active; blockedDevicesElem.textContent = blocked; } // ========================================== // Cadastrar Clínica // ========================================== clinicForm.addEventListener('submit', async (e) => { e.preventDefault(); const submitBtn = document.getElementById('submitBtn'); submitBtn.disabled = true; submitBtn.innerHTML = ' Salvando...'; const formData = new FormData(clinicForm); const bodyData = Object.fromEntries(formData.entries()); try { const response = await fetch(API_URL, { method: 'POST', headers: fetchOptions.headers, body: JSON.stringify(bodyData) }); const data = await response.json(); if (data.success) { clinicModal.classList.remove('active'); clinicForm.reset(); loadClinics(); // Show Token Modal generatedTokenElem.textContent = data.machine_token; tokenModal.classList.add('active'); } else { showToast(data.message, 'error'); } } catch (error) { showToast('Erro de conexão ao salvar', 'error'); } finally { submitBtn.disabled = false; submitBtn.innerHTML = ' Salvar e Gerar Token'; } }); // ========================================== // Toggle Status // ========================================== window.toggleStatus = async (id, isActive) => { try { const response = await fetch(`${API_URL}/${id}/status`, { method: 'PUT', headers: fetchOptions.headers, body: JSON.stringify({ is_active: isActive }) }); const data = await response.json(); if(data.success) { showToast(isActive ? 'Dispositivo Ativado' : 'Dispositivo Bloqueado', 'success'); loadClinics(); } else { showToast(data.message, 'error'); loadClinics(); // revert UI } } catch (error) { showToast('Erro ao alterar status', 'error'); loadClinics(); } }; // ========================================== // Deletar // ========================================== window.deleteClinic = async (id) => { if(!confirm('Tem certeza que deseja excluir este dispositivo permanentemente? O Desktop perderá acesso instantaneamente.')) return; try { const response = await fetch(`${API_URL}/${id}`, { method: 'DELETE', headers: fetchOptions.headers }); const data = await response.json(); if(data.success) { showToast('Dispositivo removido', 'success'); loadClinics(); } else { showToast(data.message, 'error'); } } catch (error) { showToast('Erro ao excluir', 'error'); } }; // ========================================== // UI Actions (Modals, Copy, Logout) // ========================================== addClinicBtn.addEventListener('click', () => clinicModal.classList.add('active')); closeModals.forEach(btn => btn.addEventListener('click', () => { clinicModal.classList.remove('active'); })); closeTokenModal.addEventListener('click', () => { tokenModal.classList.remove('active'); }); copyTokenBtn.addEventListener('click', () => { navigator.clipboard.writeText(generatedTokenElem.textContent).then(() => { showToast('Token copiado com sucesso!', 'success'); copyTokenBtn.innerHTML = ''; setTimeout(() => { copyTokenBtn.innerHTML = ''; }, 2000); }); }); document.getElementById('logoutBtn').addEventListener('click', () => { localStorage.removeItem('auth_token'); window.location.href = '/login'; }); function showToast(message, type = 'success') { const toast = document.getElementById('toast'); toast.textContent = message; toast.className = `toast show ${type}`; setTimeout(() => { toast.className = 'toast'; }, 3000); } });