// Configuração do token CSRF para requisições AJAX document.addEventListener('DOMContentLoaded', function() { const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); $.ajaxSetup({ beforeSend: function(xhr, settings) { if (!/^(GET|HEAD|OPTIONS|TRACE)$/i.test(settings.type) && !this.crossDomain) { xhr.setRequestHeader("X-CSRFToken", csrfToken); } } }); }); // Máscaras para campos de formulário document.addEventListener('DOMContentLoaded', function() { // Máscara para CPF const cpfInputs = document.querySelectorAll('input[name="cpf"]'); cpfInputs.forEach(input => { input.addEventListener('input', function(e) { let value = e.target.value.replace(/\D/g, ''); if (value.length <= 11) { value = value.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, "$1.$2.$3-$4"); e.target.value = value; } }); }); // Máscara para telefone const phoneInputs = document.querySelectorAll('input[name="telefone"]'); phoneInputs.forEach(input => { input.addEventListener('input', function(e) { let value = e.target.value.replace(/\D/g, ''); if (value.length <= 11) { if (value.length === 11) { value = value.replace(/(\d{2})(\d{5})(\d{4})/, "($1) $2-$3"); } else { value = value.replace(/(\d{2})(\d{4})(\d{4})/, "($1) $2-$3"); } e.target.value = value; } }); }); // Formatação de valores monetários const moneyInputs = document.querySelectorAll('input[type="number"][step="0.01"]'); moneyInputs.forEach(input => { input.addEventListener('blur', function(e) { const value = parseFloat(e.target.value); if (!isNaN(value)) { e.target.value = value.toFixed(2); } }); }); }); // Funções para tabelas document.addEventListener('DOMContentLoaded', function() { const tables = document.querySelectorAll('.table'); tables.forEach(table => { // Ordenação const headers = table.querySelectorAll('th[data-sort]'); headers.forEach(header => { header.addEventListener('click', function() { const column = this.dataset.sort; const asc = this.classList.toggle('sort-asc'); const tbody = table.querySelector('tbody'); const rows = Array.from(tbody.querySelectorAll('tr')); rows.sort((a, b) => { const aVal = a.querySelector(`td[data-${column}]`).dataset[column]; const bVal = b.querySelector(`td[data-${column}]`).dataset[column]; return asc ? aVal.localeCompare(bVal) : bVal.localeCompare(aVal); }); rows.forEach(row => tbody.appendChild(row)); }); }); // Filtro const filterInput = document.querySelector(`#filter-${table.id}`); if (filterInput) { filterInput.addEventListener('input', function() { const searchTerm = this.value.toLowerCase(); const rows = table.querySelectorAll('tbody tr'); rows.forEach(row => { const text = row.textContent.toLowerCase(); row.style.display = text.includes(searchTerm) ? '' : 'none'; }); }); } }); }); // Validação de formulários document.addEventListener('DOMContentLoaded', function() { const forms = document.querySelectorAll('form'); forms.forEach(form => { form.addEventListener('submit', function(e) { if (!form.checkValidity()) { e.preventDefault(); e.stopPropagation(); // Destacar campos inválidos const invalidInputs = form.querySelectorAll(':invalid'); invalidInputs.forEach(input => { input.classList.add('is-invalid'); // Adicionar mensagem de erro const feedback = document.createElement('div'); feedback.className = 'invalid-feedback'; feedback.textContent = input.validationMessage; input.parentNode.appendChild(feedback); }); } form.classList.add('was-validated'); }); }); }); // Animações e feedback visual document.addEventListener('DOMContentLoaded', function() { // Animar cards ao carregar const cards = document.querySelectorAll('.card'); cards.forEach((card, index) => { card.style.opacity = '0'; card.style.transform = 'translateY(20px)'; setTimeout(() => { card.style.transition = 'all 0.3s ease'; card.style.opacity = '1'; card.style.transform = 'translateY(0)'; }, index * 100); }); // Feedback visual para ações const actionButtons = document.querySelectorAll('[data-action]'); actionButtons.forEach(button => { button.addEventListener('click', function() { button.classList.add('animate__animated', 'animate__pulse'); setTimeout(() => { button.classList.remove('animate__animated', 'animate__pulse'); }, 1000); }); }); }); // Confirmações de ações document.addEventListener('DOMContentLoaded', function() { const deleteButtons = document.querySelectorAll('[data-confirm]'); deleteButtons.forEach(button => { button.addEventListener('click', function(e) { if (!confirm(this.dataset.confirm)) { e.preventDefault(); } }); }); });