wagtail-enap-designsystem 1.2.1.127__py3-none-any.whl → 1.2.1.128__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1419,7 +1419,7 @@
1419
1419
  </div>
1420
1420
 
1421
1421
  <script>
1422
- // 🎯 CONFIGURAÇÕES GLOBAIS CORRIGIDAS
1422
+ // VARIÁVEIS GLOBAIS
1423
1423
  let currentStep = 0;
1424
1424
  let currentActiveWizardIndex = 0;
1425
1425
  let isScrolling = false;
@@ -1427,242 +1427,85 @@
1427
1427
  const totalSteps = formSteps + 2;
1428
1428
  const successStepIndex = formSteps + 1;
1429
1429
  let wizardSteps = [];
1430
-
1431
- console.log(`📊 Config: formSteps=${formSteps}, totalSteps=${totalSteps}`);
1432
-
1433
- // 📍 INICIALIZAÇÃO DOS STEPS DO WIZARD BASEADO EM DIVISORES (COMO ORIGINAL)
1434
- function initializeWizard() {
1435
- // Encontrar todos os elementos .divider-title em TODOS os steps do formulário
1436
- const allDividers = [];
1437
-
1438
- for (let i = 1; i <= formSteps; i++) {
1439
- const stepElement = document.getElementById(`step${i}`);
1440
- if (stepElement) {
1441
- const dividers = stepElement.querySelectorAll('.divider-title');
1442
- dividers.forEach(divider => {
1443
- allDividers.push({
1444
- title: divider.textContent.trim(),
1445
- element: divider,
1446
- stepNumber: i
1447
- });
1448
- });
1449
- }
1450
- }
1451
-
1452
- // Se não encontrou divisores, criar steps padrão baseado nos form steps
1453
- if (allDividers.length === 0) {
1454
- console.log('⚠️ Nenhum divisor encontrado, usando steps do formulário');
1455
- for (let i = 1; i <= formSteps; i++) {
1456
- allDividers.push({
1457
- title: `Etapa ${i}`,
1458
- element: null,
1459
- stepNumber: i
1460
- });
1461
- }
1462
- }
1463
-
1464
- wizardSteps = allDividers;
1465
-
1466
- console.log(`📍 Wizard inicializado com ${wizardSteps.length} divisores:`, wizardSteps.map(s => s.title));
1467
-
1468
- // Criar visual do wizard
1469
- createWizardSteps();
1430
+
1431
+ // DADOS DO DJANGO COM VALIDAÇÃO
1432
+ let sectionMapData = {};
1433
+ let navigationDataRaw = {};
1434
+
1435
+ try {
1436
+ {% if section_map_json %}
1437
+ sectionMapData = {{ section_map_json|safe }};
1438
+ {% endif %}
1439
+ } catch(e) {
1440
+ console.log('Section map não disponível');
1441
+ sectionMapData = {};
1470
1442
  }
1471
-
1472
- // 🎨 CRIAR ELEMENTOS VISUAIS DO WIZARD - VERSÃO MELHORADA
1473
- function createWizardSteps() {
1474
- const wizardContainer = document.getElementById('wizardSteps');
1475
- if (!wizardContainer) return;
1476
-
1477
- wizardContainer.innerHTML = '';
1478
-
1479
- wizardSteps.forEach((step, index) => {
1480
- const stepDiv = document.createElement('div');
1481
- stepDiv.className = 'wizard-step';
1482
- stepDiv.style.cursor = 'pointer';
1483
- stepDiv.setAttribute('data-index', index);
1484
- stepDiv.setAttribute('data-step-number', step.stepNumber);
1485
-
1486
- stepDiv.innerHTML = `
1487
- <div class="step-circle">
1488
- <span>${index + 1}</span>
1489
- </div>
1490
- <div class="step-label">${step.title}</div>
1491
- `;
1492
-
1493
- // 🎯 CLIQUE PARA NAVEGAR
1494
- stepDiv.addEventListener('click', () => {
1495
- scrollToWizardStep(index);
1496
- });
1497
-
1498
- wizardContainer.appendChild(stepDiv);
1499
- });
1500
-
1501
- console.log(`✅ ${wizardSteps.length} steps visuais criados com eventos de clique`);
1443
+
1444
+ try {
1445
+ {% if navigation_data_json %}
1446
+ navigationDataRaw = {{ navigation_data_json|safe }};
1447
+ {% endif %}
1448
+ } catch(e) {
1449
+ console.log('Navigation data não disponível');
1450
+ navigationDataRaw = {};
1502
1451
  }
1503
-
1504
- // 📡 CONFIGURAR DETECÇÃO DE SCROLL - COM PRIMEIRO STEP ATIVO POR PADRÃO
1505
- function setupScrollDetection() {
1506
- const formContent = document.getElementById('formContent');
1507
- if (!formContent) {
1508
- console.error('❌ #formContent não encontrado');
1452
+
1453
+ // SISTEMA DE NAVEGAÇÃO INTELIGENTE
1454
+ let sectionMap = sectionMapData || {};
1455
+ let navigationData = navigationDataRaw || {};
1456
+ let hiddenSections = new Set();
1457
+
1458
+ console.log('Config: formSteps=' + formSteps + ', totalSteps=' + totalSteps);
1459
+
1460
+ // FUNÇÕES PRINCIPAIS - ESCOPO GLOBAL
1461
+ function nextStep() {
1462
+ console.log('nextStep: currentStep=' + currentStep);
1463
+
1464
+ if (currentStep === 0) {
1465
+ currentStep = 1;
1466
+ showStep(currentStep);
1509
1467
  return;
1510
1468
  }
1511
1469
 
1512
- let scrollTimeout;
1513
-
1514
- function handleScroll() {
1515
- if (isScrolling) return; // Evitar conflito durante scroll programático
1516
-
1517
- const scrollTop = formContent.scrollTop;
1518
- const containerHeight = formContent.clientHeight;
1519
- const viewportCenter = scrollTop + (containerHeight / 3); // 1/3 da tela como referência
1520
-
1521
- console.log(`📜 Scroll: ${scrollTop}px, ViewportCenter: ${viewportCenter}px`);
1522
-
1523
- // COMEÇAR COM O PRIMEIRO STEP ATIVO
1524
- let newActiveIndex = 0;
1525
- let closestDistance = Infinity;
1526
-
1527
- wizardSteps.forEach((step, index) => {
1528
- if (!step.element) return;
1529
-
1530
- // Calcular posição absoluta do divisor
1531
- const elementRect = step.element.getBoundingClientRect();
1532
- const containerRect = formContent.getBoundingClientRect();
1533
- const elementTop = elementRect.top - containerRect.top + scrollTop;
1534
-
1535
- // Log para debug
1536
- console.log(` ${index + 1}: "${step.title}" - Top: ${elementTop}px`);
1537
-
1538
- // Se passou deste divisor, ele vira ativo (mantém o último que passou)
1539
- if (elementTop <= viewportCenter + 50) { // Margem menor para mais precisão
1540
- newActiveIndex = index;
1541
- console.log(` ✅ Step ${index + 1} passou pelo viewportCenter`);
1542
- }
1543
- });
1544
-
1545
- // Atualizar visual se mudou
1546
- if (newActiveIndex !== currentActiveWizardIndex) {
1547
- const previousIndex = currentActiveWizardIndex;
1548
- currentActiveWizardIndex = newActiveIndex;
1549
-
1550
- updateWizardVisual();
1551
- updateDividerVisual();
1552
-
1553
- console.log(`🎯 MUDANÇA! De ${previousIndex + 1} para ${newActiveIndex + 1} - "${wizardSteps[newActiveIndex]?.title}"`);
1470
+ if (currentStep >= 1 && currentStep <= formSteps) {
1471
+ if (!validateCurrentStep()) {
1472
+ console.log('Validação falhou');
1473
+ return;
1554
1474
  }
1555
1475
  }
1556
1476
 
1557
- // DEFINIR PRIMEIRO STEP COMO ATIVO INICIALMENTE
1558
- currentActiveWizardIndex = 0;
1559
- updateWizardVisual();
1560
- updateDividerVisual();
1561
- console.log('🎯 Primeiro step definido como ativo inicialmente');
1562
-
1563
- // Adicionar listener com debounce menor para mais responsividade
1564
- formContent.addEventListener('scroll', () => {
1565
- clearTimeout(scrollTimeout);
1566
- scrollTimeout = setTimeout(handleScroll, 30); // Mais rápido
1567
- });
1568
-
1569
- // Detecção inicial após um delay
1570
- setTimeout(handleScroll, 300);
1571
-
1572
- console.log('📡 Scroll detection configurado - Primeiro step ativo por padrão');
1573
- }
1574
-
1575
- // 🎨 ATUALIZAR VISUAL DO WIZARD - VERSÃO MELHORADA COM LOG
1576
- function updateWizardVisual() {
1577
- const allSteps = document.querySelectorAll('.wizard-step');
1578
-
1579
- allSteps.forEach((stepElement, index) => {
1580
- // Remover todas as classes de status
1581
- stepElement.classList.remove('active', 'completed');
1582
-
1583
- // Aplicar classes baseado no índice atual
1584
- if (index < currentActiveWizardIndex) {
1585
- stepElement.classList.add('completed');
1586
- } else if (index === currentActiveWizardIndex) {
1587
- stepElement.classList.add('active');
1588
- }
1589
- });
1590
-
1591
- console.log(`🎨 Wizard atualizado - Step ${currentActiveWizardIndex + 1}/${wizardSteps.length} ativo: "${wizardSteps[currentActiveWizardIndex]?.title}"`);
1592
-
1593
- // Log das classes aplicadas
1594
- allSteps.forEach((el, i) => {
1595
- const classes = Array.from(el.classList).filter(c => ['active', 'completed'].includes(c)).join(', ');
1596
- if (classes) {
1597
- console.log(` Step ${i + 1}: ${classes}`);
1477
+ if (currentStep === formSteps) {
1478
+ const form = document.getElementById('wagtailForm');
1479
+ if (form) {
1480
+ form.submit();
1598
1481
  }
1599
- });
1600
- }
1601
-
1602
- // 🎯 ATUALIZAR VISUAL DOS DIVISORES
1603
- function updateDividerVisual() {
1604
- // Remover classe active de todos os divisores
1605
- document.querySelectorAll('.divider-title').forEach(divider => {
1606
- divider.classList.remove('active');
1607
- });
1482
+ return;
1483
+ }
1608
1484
 
1609
- // Adicionar classe active ao divisor atual
1610
- const activeStep = wizardSteps[currentActiveWizardIndex];
1611
- if (activeStep && activeStep.element) {
1612
- activeStep.element.classList.add('active');
1485
+ if (currentStep < totalSteps - 1) {
1486
+ currentStep++;
1487
+ showStep(currentStep);
1613
1488
  }
1614
1489
  }
1615
-
1616
- // 🎯 SCROLL PARA DIVISOR ESPECÍFICO
1617
- function scrollToWizardStep(stepIndex) {
1618
- if (stepIndex < 0 || stepIndex >= wizardSteps.length) return;
1619
-
1620
- const step = wizardSteps[stepIndex];
1621
- const formContent = document.getElementById('formContent');
1622
-
1623
- if (!step.element || !formContent) {
1624
- console.log(`❌ Divisor ${stepIndex} não tem elemento ou formContent não encontrado`);
1625
- return;
1490
+
1491
+ function prevStep() {
1492
+ if (currentStep > 1) {
1493
+ currentStep--;
1494
+ showStep(currentStep);
1626
1495
  }
1627
-
1628
- isScrolling = true; // Flag para evitar conflito
1629
-
1630
- // Calcular posição alvo do divisor
1631
- const elementRect = step.element.getBoundingClientRect();
1632
- const containerRect = formContent.getBoundingClientRect();
1633
- const relativeTop = elementRect.top - containerRect.top + formContent.scrollTop;
1634
- const targetScrollTop = relativeTop - 100; // 100px de offset
1635
-
1636
- console.log(`🎯 Scrolling para divisor ${stepIndex}: "${step.title}" - targetScrollTop: ${targetScrollTop}px`);
1637
-
1638
- // Scroll suave
1639
- formContent.scrollTo({
1640
- top: targetScrollTop,
1641
- behavior: 'smooth'
1642
- });
1643
-
1644
- // Atualizar estado imediatamente
1645
- currentActiveWizardIndex = stepIndex;
1646
- updateWizardVisual();
1647
- updateDividerVisual();
1648
-
1649
- // Liberar flag após scroll
1650
- setTimeout(() => {
1651
- isScrolling = false;
1652
- }, 1000);
1653
1496
  }
1654
-
1655
- // 🎨 MOSTRAR STEP PRINCIPAL
1497
+
1656
1498
  function showStep(step) {
1657
- console.log(`🎯 Mostrando step: ${step}`);
1499
+ console.log('Mostrando step: ' + step);
1658
1500
 
1659
1501
  // Ocultar todos os steps
1660
- document.querySelectorAll('.step-content').forEach(content => {
1661
- content.classList.remove('active');
1662
- });
1502
+ const allSteps = document.querySelectorAll('.step-content');
1503
+ for (let i = 0; i < allSteps.length; i++) {
1504
+ allSteps[i].classList.remove('active');
1505
+ }
1663
1506
 
1664
1507
  // Mostrar step atual
1665
- const stepElement = document.getElementById(`step${step}`);
1508
+ const stepElement = document.getElementById('step' + step);
1666
1509
  if (stepElement) {
1667
1510
  stepElement.classList.add('active');
1668
1511
  }
@@ -1697,9 +1540,8 @@
1697
1540
  }
1698
1541
 
1699
1542
  // Configurar scroll listener
1700
- setTimeout(() => {
1543
+ setTimeout(function() {
1701
1544
  setupScrollDetection();
1702
- // Garantir que o primeiro step está ativo após setup
1703
1545
  if (currentActiveWizardIndex === 0) {
1704
1546
  updateWizardVisual();
1705
1547
  updateDividerVisual();
@@ -1713,69 +1555,30 @@
1713
1555
  formContent.scrollTop = 0;
1714
1556
  }
1715
1557
  }
1716
-
1717
- // 🚀 NAVEGAÇÃO ENTRE STEPS PRINCIPAIS
1718
- function nextStep() {
1719
- console.log(`🚀 nextStep: currentStep=${currentStep}`);
1720
-
1721
- if (currentStep === 0) {
1722
- currentStep = 1;
1723
- showStep(currentStep);
1724
- return;
1725
- }
1726
-
1727
- if (currentStep >= 1 && currentStep <= formSteps) {
1728
- if (!validateCurrentStep()) {
1729
- console.log('❌ Validação falhou');
1730
- return;
1731
- }
1732
- }
1733
-
1734
- if (currentStep === formSteps) {
1735
- const form = document.getElementById('wagtailForm');
1736
- if (form) {
1737
- form.submit();
1738
- }
1739
- return;
1740
- }
1741
-
1742
- if (currentStep < totalSteps - 1) {
1743
- currentStep++;
1744
- showStep(currentStep);
1745
- }
1746
- }
1747
-
1748
- function prevStep() {
1749
- if (currentStep > 1) {
1750
- currentStep--;
1751
- showStep(currentStep);
1752
- }
1753
- }
1754
-
1755
- // ⬅️➡️ NAVEGAÇÃO SEQUENCIAL DO WIZARD
1756
- function scrollToNext() {
1757
- const nextIndex = Math.min(currentActiveWizardIndex + 1, wizardSteps.length - 1);
1758
- scrollToWizardStep(nextIndex);
1759
- }
1760
-
1761
- function scrollToPrevious() {
1762
- const prevIndex = Math.max(currentActiveWizardIndex - 1, 0);
1763
- scrollToWizardStep(prevIndex);
1764
- }
1765
-
1766
- // 🔍 VALIDAÇÃO DO STEP ATUAL
1558
+
1767
1559
  function validateCurrentStep() {
1768
- const currentStepElement = document.getElementById(`step${currentStep}`);
1560
+ const currentStepElement = document.getElementById('step' + currentStep);
1769
1561
  if (!currentStepElement) return true;
1770
1562
 
1771
1563
  let isValid = true;
1772
1564
  const requiredInputs = currentStepElement.querySelectorAll('input[required], select[required], textarea[required]');
1773
1565
 
1774
- requiredInputs.forEach(input => {
1566
+ for (let i = 0; i < requiredInputs.length; i++) {
1567
+ const input = requiredInputs[i];
1568
+
1775
1569
  // Pular campos que estão dentro de conditional-fields ocultos
1776
1570
  const conditionalParent = input.closest('.conditional-fields');
1777
1571
  if (conditionalParent && conditionalParent.style.display === 'none') {
1778
- return;
1572
+ continue;
1573
+ }
1574
+
1575
+ // Pular campos em seções ocultas
1576
+ const sectionElement = input.closest('[data-section-name]');
1577
+ if (sectionElement) {
1578
+ const sectionName = sectionElement.dataset.sectionName;
1579
+ if (hiddenSections.has(sectionName)) {
1580
+ continue;
1581
+ }
1779
1582
  }
1780
1583
 
1781
1584
  // Limpar erros anteriores
@@ -1789,8 +1592,13 @@
1789
1592
  if (input.type === 'checkbox') {
1790
1593
  hasValue = input.checked;
1791
1594
  } else if (input.type === 'radio') {
1792
- const radioGroup = currentStepElement.querySelectorAll(`input[name="${input.name}"]`);
1793
- hasValue = Array.from(radioGroup).some(radio => radio.checked);
1595
+ const radioGroup = currentStepElement.querySelectorAll('input[name="' + input.name + '"]');
1596
+ for (let j = 0; j < radioGroup.length; j++) {
1597
+ if (radioGroup[j].checked) {
1598
+ hasValue = true;
1599
+ break;
1600
+ }
1601
+ }
1794
1602
  } else {
1795
1603
  hasValue = input.value.trim() !== '';
1796
1604
  }
@@ -1798,34 +1606,12 @@
1798
1606
  if (!hasValue) {
1799
1607
  showFieldError(input, 'Este campo é obrigatório');
1800
1608
  isValid = false;
1801
- } else {
1802
- // Validações específicas
1803
- if (input.type === 'email' && input.value) {
1804
- if (!validateEmail(input.value)) {
1805
- showFieldError(input, 'Email inválido');
1806
- isValid = false;
1807
- }
1808
- }
1809
-
1810
- if (input.classList.contains('cpf-field') && input.value) {
1811
- if (!validateCPF(input.value)) {
1812
- showFieldError(input, 'CPF deve ter 9 dígitos');
1813
- isValid = false;
1814
- }
1815
- }
1816
-
1817
- if (input.classList.contains('phone-field') && input.value) {
1818
- if (!validatePhone(input.value)) {
1819
- showFieldError(input, 'Telefone inválido');
1820
- isValid = false;
1821
- }
1822
- }
1823
1609
  }
1824
- });
1610
+ }
1825
1611
 
1826
1612
  return isValid;
1827
1613
  }
1828
-
1614
+
1829
1615
  function showFieldError(input, message) {
1830
1616
  let errorDiv = input.parentNode.querySelector('.error-message');
1831
1617
  if (!errorDiv) {
@@ -1836,49 +1622,352 @@
1836
1622
  errorDiv.textContent = message;
1837
1623
  errorDiv.style.display = 'block';
1838
1624
 
1839
- // Scroll para o campo com erro
1840
1625
  input.scrollIntoView({ behavior: 'smooth', block: 'center' });
1841
1626
  input.focus();
1842
1627
  }
1843
-
1844
- function validateEmail(email) {
1845
- const re = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1846
- return re.test(email);
1847
- }
1848
-
1849
- function validateCPF(cpf) {
1850
- const digits = cpf.replace(/[^0-9]/g, '');
1851
- return digits.length === 11;
1852
- }
1853
-
1854
- function validatePhone(phone) {
1855
- const digits = phone.replace(/[^0-9]/g, '');
1856
- return digits.length >= 10 && digits.length <= 11;
1857
- }
1858
-
1859
- // 🔍 VERIFICAR SUCCESS NA URL
1860
- function checkForSuccess() {
1861
- const urlParams = new URLSearchParams(window.location.search);
1862
- const hasSuccess = urlParams.get('success') === '1';
1628
+
1629
+ // SISTEMA DE NAVEGAÇÃO INTELIGENTE
1630
+ function initializeSmartNavigation() {
1631
+ console.log('Inicializando Smart Navigation');
1863
1632
 
1864
- if (hasSuccess) {
1865
- console.log(`✅ Success detectado! Indo para step ${successStepIndex}`);
1866
- currentStep = successStepIndex;
1867
- showStep(currentStep);
1868
- return true;
1633
+ // Verificar se temos dados
1634
+ if (Object.keys(sectionMap).length === 0 && Object.keys(navigationData).length === 0) {
1635
+ console.log('Dados de navegação não disponíveis');
1636
+ return;
1869
1637
  }
1870
- return false;
1638
+
1639
+ // Adicionar listeners
1640
+ document.addEventListener('change', function(e) {
1641
+ const smartField = e.target.closest('[data-field-type="smart_navigation_field"]');
1642
+ if (smartField) {
1643
+ handleSmartNavigation(e.target);
1644
+ }
1645
+ });
1646
+
1647
+ hideDefaultHiddenSections();
1648
+ console.log('Sistema de Navegação Inteligente carregado');
1871
1649
  }
1872
-
1873
- // 🎉 CONFETTI PARA SUCESSO
1874
- function createConfetti() {
1875
- console.log('🎊 Iniciando confetti...');
1876
- const colors = ['#2d5530', '#4CAF50', '#ffd700', '#ff6b6b', '#e74c3c', '#3498db'];
1650
+
1651
+ function handleSmartNavigation(element) {
1652
+ const fieldContainer = element.closest('[data-field-type="smart_navigation_field"]');
1653
+ if (!fieldContainer) return;
1877
1654
 
1878
- for (let i = 0; i < 50; i++) {
1879
- setTimeout(() => {
1880
- const confetti = document.createElement('div');
1881
- confetti.className = 'confetti';
1655
+ const fieldId = fieldContainer.dataset.fieldId;
1656
+ const selectedValue = getSelectedValue(element);
1657
+
1658
+ if (!navigationData[fieldId] || !selectedValue) {
1659
+ return;
1660
+ }
1661
+
1662
+ const actionData = navigationData[fieldId][selectedValue];
1663
+ if (!actionData) {
1664
+ return;
1665
+ }
1666
+
1667
+ console.log('Navegação ativada: ' + fieldId + ' -> ' + selectedValue);
1668
+
1669
+ // Executar ação baseada no tipo
1670
+ switch (actionData.action_type) {
1671
+ case 'continue':
1672
+ console.log('Continuando navegação normal');
1673
+ break;
1674
+
1675
+ case 'jump_to_section':
1676
+ handleJumpToSection(actionData.target_section);
1677
+ break;
1678
+
1679
+ case 'finish_form':
1680
+ handleFinishForm();
1681
+ break;
1682
+
1683
+ case 'show_message_and_finish':
1684
+ handleShowMessageAndFinish(actionData);
1685
+ break;
1686
+ }
1687
+ }
1688
+
1689
+ function getSelectedValue(element) {
1690
+ if (element.type === 'radio') {
1691
+ const radioGroup = document.querySelectorAll('input[name="' + element.name + '"]');
1692
+ for (let i = 0; i < radioGroup.length; i++) {
1693
+ if (radioGroup[i].checked) {
1694
+ return radioGroup[i].value;
1695
+ }
1696
+ }
1697
+ return null;
1698
+ } else if (element.type === 'checkbox') {
1699
+ return element.checked ? element.value : null;
1700
+ } else if (element.tagName === 'SELECT') {
1701
+ return element.value;
1702
+ }
1703
+ return element.value;
1704
+ }
1705
+
1706
+ function handleJumpToSection(targetSectionName) {
1707
+ if (!targetSectionName || !sectionMap[targetSectionName]) {
1708
+ console.log('Seção não encontrada: ' + targetSectionName);
1709
+ return;
1710
+ }
1711
+
1712
+ const targetSection = sectionMap[targetSectionName];
1713
+ showSection(targetSectionName);
1714
+
1715
+ currentStep = targetSection.step;
1716
+ showStep(currentStep);
1717
+
1718
+ setTimeout(function() {
1719
+ scrollToSection(targetSection.block_id);
1720
+ }, 100);
1721
+
1722
+ console.log('Pulando para seção: ' + targetSectionName);
1723
+ }
1724
+
1725
+ function handleFinishForm() {
1726
+ currentStep = totalSteps - 1;
1727
+ showStep(currentStep);
1728
+ console.log('Formulário finalizado antecipadamente');
1729
+ }
1730
+
1731
+ function hideDefaultHiddenSections() {
1732
+ const sections = Object.keys(sectionMap);
1733
+ for (let i = 0; i < sections.length; i++) {
1734
+ const sectionName = sections[i];
1735
+ const sectionData = sectionMap[sectionName];
1736
+ if (sectionData.hidden_by_default) {
1737
+ hideSection(sectionName);
1738
+ }
1739
+ }
1740
+ }
1741
+
1742
+ function hideSection(sectionName) {
1743
+ const sectionData = sectionMap[sectionName];
1744
+ if (!sectionData) return;
1745
+
1746
+ hiddenSections.add(sectionName);
1747
+
1748
+ const sectionElement = document.querySelector('[data-section-name="' + sectionName + '"]');
1749
+ if (sectionElement) {
1750
+ sectionElement.style.display = 'none';
1751
+ disableFieldsInSection(sectionElement);
1752
+ }
1753
+
1754
+ console.log('Seção oculta: ' + sectionName);
1755
+ }
1756
+
1757
+ function showSection(sectionName) {
1758
+ const sectionData = sectionMap[sectionName];
1759
+ if (!sectionData) return;
1760
+
1761
+ hiddenSections.delete(sectionName);
1762
+
1763
+ const sectionElement = document.querySelector('[data-section-name="' + sectionName + '"]');
1764
+ if (sectionElement) {
1765
+ sectionElement.style.display = 'block';
1766
+ enableFieldsInSection(sectionElement);
1767
+ }
1768
+
1769
+ console.log('Seção mostrada: ' + sectionName);
1770
+ }
1771
+
1772
+ function disableFieldsInSection(sectionElement) {
1773
+ const fields = sectionElement.querySelectorAll('input, select, textarea');
1774
+ for (let i = 0; i < fields.length; i++) {
1775
+ const field = fields[i];
1776
+ field.dataset.wasRequired = field.required ? 'true' : 'false';
1777
+ field.required = false;
1778
+ field.disabled = true;
1779
+ }
1780
+ }
1781
+
1782
+ function enableFieldsInSection(sectionElement) {
1783
+ const fields = sectionElement.querySelectorAll('input, select, textarea');
1784
+ for (let i = 0; i < fields.length; i++) {
1785
+ const field = fields[i];
1786
+ field.disabled = false;
1787
+ if (field.dataset.wasRequired === 'true') {
1788
+ field.required = true;
1789
+ }
1790
+ }
1791
+ }
1792
+
1793
+ // WIZARD FUNCTIONS
1794
+ function initializeWizard() {
1795
+ const allDividers = [];
1796
+
1797
+ for (let i = 1; i <= formSteps; i++) {
1798
+ const stepElement = document.getElementById('step' + i);
1799
+ if (stepElement) {
1800
+ const dividers = stepElement.querySelectorAll('.divider-title');
1801
+ for (let j = 0; j < dividers.length; j++) {
1802
+ allDividers.push({
1803
+ title: dividers[j].textContent.trim(),
1804
+ element: dividers[j],
1805
+ stepNumber: i
1806
+ });
1807
+ }
1808
+ }
1809
+ }
1810
+
1811
+ if (allDividers.length === 0) {
1812
+ for (let i = 1; i <= formSteps; i++) {
1813
+ allDividers.push({
1814
+ title: 'Etapa ' + i,
1815
+ element: null,
1816
+ stepNumber: i
1817
+ });
1818
+ }
1819
+ }
1820
+
1821
+ wizardSteps = allDividers;
1822
+ createWizardSteps();
1823
+ }
1824
+
1825
+ function createWizardSteps() {
1826
+ const wizardContainer = document.getElementById('wizardSteps');
1827
+ if (!wizardContainer) return;
1828
+
1829
+ wizardContainer.innerHTML = '';
1830
+
1831
+ for (let i = 0; i < wizardSteps.length; i++) {
1832
+ const step = wizardSteps[i];
1833
+ const stepDiv = document.createElement('div');
1834
+ stepDiv.className = 'wizard-step';
1835
+ stepDiv.style.cursor = 'pointer';
1836
+ stepDiv.setAttribute('data-index', i);
1837
+ stepDiv.setAttribute('data-step-number', step.stepNumber);
1838
+
1839
+ stepDiv.innerHTML = '<div class="step-circle"><span>' + (i + 1) + '</span></div><div class="step-label">' + step.title + '</div>';
1840
+
1841
+ stepDiv.addEventListener('click', function() {
1842
+ scrollToWizardStep(i);
1843
+ });
1844
+
1845
+ wizardContainer.appendChild(stepDiv);
1846
+ }
1847
+ }
1848
+
1849
+ function scrollToWizardStep(stepIndex) {
1850
+ if (stepIndex < 0 || stepIndex >= wizardSteps.length) return;
1851
+
1852
+ const step = wizardSteps[stepIndex];
1853
+ const formContent = document.getElementById('formContent');
1854
+
1855
+ if (!step.element || !formContent) return;
1856
+
1857
+ isScrolling = true;
1858
+
1859
+ const elementRect = step.element.getBoundingClientRect();
1860
+ const containerRect = formContent.getBoundingClientRect();
1861
+ const relativeTop = elementRect.top - containerRect.top + formContent.scrollTop;
1862
+ const targetScrollTop = relativeTop - 100;
1863
+
1864
+ formContent.scrollTo({
1865
+ top: targetScrollTop,
1866
+ behavior: 'smooth'
1867
+ });
1868
+
1869
+ currentActiveWizardIndex = stepIndex;
1870
+ updateWizardVisual();
1871
+ updateDividerVisual();
1872
+
1873
+ setTimeout(function() {
1874
+ isScrolling = false;
1875
+ }, 1000);
1876
+ }
1877
+
1878
+ function setupScrollDetection() {
1879
+ const formContent = document.getElementById('formContent');
1880
+ if (!formContent) return;
1881
+
1882
+ let scrollTimeout;
1883
+
1884
+ function handleScroll() {
1885
+ if (isScrolling) return;
1886
+
1887
+ const scrollTop = formContent.scrollTop;
1888
+ const containerHeight = formContent.clientHeight;
1889
+ const viewportCenter = scrollTop + (containerHeight / 3);
1890
+
1891
+ let newActiveIndex = 0;
1892
+
1893
+ for (let i = 0; i < wizardSteps.length; i++) {
1894
+ const step = wizardSteps[i];
1895
+ if (!step.element) continue;
1896
+
1897
+ const elementRect = step.element.getBoundingClientRect();
1898
+ const containerRect = formContent.getBoundingClientRect();
1899
+ const elementTop = elementRect.top - containerRect.top + scrollTop;
1900
+
1901
+ if (elementTop <= viewportCenter + 50) {
1902
+ newActiveIndex = i;
1903
+ }
1904
+ }
1905
+
1906
+ if (newActiveIndex !== currentActiveWizardIndex) {
1907
+ currentActiveWizardIndex = newActiveIndex;
1908
+ updateWizardVisual();
1909
+ updateDividerVisual();
1910
+ }
1911
+ }
1912
+
1913
+ currentActiveWizardIndex = 0;
1914
+ updateWizardVisual();
1915
+ updateDividerVisual();
1916
+
1917
+ formContent.addEventListener('scroll', function() {
1918
+ clearTimeout(scrollTimeout);
1919
+ scrollTimeout = setTimeout(handleScroll, 30);
1920
+ });
1921
+
1922
+ setTimeout(handleScroll, 300);
1923
+ }
1924
+
1925
+ function updateWizardVisual() {
1926
+ const allSteps = document.querySelectorAll('.wizard-step');
1927
+
1928
+ for (let i = 0; i < allSteps.length; i++) {
1929
+ const stepElement = allSteps[i];
1930
+ stepElement.classList.remove('active', 'completed');
1931
+
1932
+ if (i < currentActiveWizardIndex) {
1933
+ stepElement.classList.add('completed');
1934
+ } else if (i === currentActiveWizardIndex) {
1935
+ stepElement.classList.add('active');
1936
+ }
1937
+ }
1938
+ }
1939
+
1940
+ function updateDividerVisual() {
1941
+ const dividers = document.querySelectorAll('.divider-title');
1942
+ for (let i = 0; i < dividers.length; i++) {
1943
+ dividers[i].classList.remove('active');
1944
+ }
1945
+
1946
+ const activeStep = wizardSteps[currentActiveWizardIndex];
1947
+ if (activeStep && activeStep.element) {
1948
+ activeStep.element.classList.add('active');
1949
+ }
1950
+ }
1951
+
1952
+ function checkForSuccess() {
1953
+ const urlParams = new URLSearchParams(window.location.search);
1954
+ const hasSuccess = urlParams.get('success') === '1';
1955
+
1956
+ if (hasSuccess) {
1957
+ currentStep = successStepIndex;
1958
+ showStep(currentStep);
1959
+ return true;
1960
+ }
1961
+ return false;
1962
+ }
1963
+
1964
+ function createConfetti() {
1965
+ const colors = ['#2d5530', '#4CAF50', '#ffd700', '#ff6b6b', '#e74c3c', '#3498db'];
1966
+
1967
+ for (let i = 0; i < 50; i++) {
1968
+ setTimeout(function() {
1969
+ const confetti = document.createElement('div');
1970
+ confetti.className = 'confetti';
1882
1971
  confetti.style.position = 'fixed';
1883
1972
  confetti.style.left = Math.random() * 100 + 'vw';
1884
1973
  confetti.style.top = '-10px';
@@ -1888,12 +1977,12 @@
1888
1977
  confetti.style.borderRadius = Math.random() > 0.5 ? '50%' : '0';
1889
1978
  confetti.style.zIndex = '1001';
1890
1979
  confetti.style.pointerEvents = 'none';
1891
- confetti.style.animation = `confetti-fall ${Math.random() * 3 + 2}s linear infinite`;
1980
+ confetti.style.animation = 'confetti-fall ' + (Math.random() * 3 + 2) + 's linear infinite';
1892
1981
  confetti.style.animationDelay = Math.random() * 2 + 's';
1893
1982
 
1894
1983
  document.body.appendChild(confetti);
1895
1984
 
1896
- setTimeout(() => {
1985
+ setTimeout(function() {
1897
1986
  if (confetti.parentNode) {
1898
1987
  confetti.remove();
1899
1988
  }
@@ -1901,58 +1990,39 @@
1901
1990
  }, i * 50);
1902
1991
  }
1903
1992
  }
1904
-
1905
- // Adicionar após a função validateCPF
1906
- function validateCNPJ(cnpj) {
1907
- const digits = cnpj.replace(/[^0-9]/g, '');
1908
- return digits.length === 14;
1909
- }
1910
-
1911
- // Adicionar na validação do validateCurrentStep
1912
- if (input.classList.contains('cnpj-field') && input.value) {
1913
- if (!validateCNPJ(input.value)) {
1914
- showFieldError(input, 'CNPJ deve ter 14 dígitos');
1915
- isValid = false;
1916
- }
1917
- }
1918
-
1919
- // Adicionar formatação automática no listener 'input'
1920
- // CNPJ - 14 dígitos
1921
- if (e.target.classList.contains('cnpj-field')) {
1922
- let value = e.target.value.replace(/[^\d]/g, '');
1923
- if (value.length > 14) value = value.slice(0, 14);
1993
+
1994
+ // EVENT LISTENERS E INICIALIZAÇÃO
1995
+ document.addEventListener('DOMContentLoaded', function() {
1996
+ console.log('DOM carregado');
1924
1997
 
1925
- if (value.length > 12) {
1926
- value = value.replace(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, '$1.$2.$3/$4-$5');
1927
- } else if (value.length > 8) {
1928
- value = value.replace(/(\d{2})(\d{3})(\d{3})(\d{4})/, '$1.$2.$3/$4');
1929
- } else if (value.length > 5) {
1930
- value = value.replace(/(\d{2})(\d{3})(\d{3})/, '$1.$2.$3');
1931
- } else if (value.length > 2) {
1932
- value = value.replace(/(\d{2})(\d{3})/, '$1.$2');
1998
+ // Inicializar sistemas
1999
+ initializeSmartNavigation();
2000
+
2001
+ // Verificar success na URL primeiro
2002
+ if (!checkForSuccess()) {
2003
+ showStep(0);
1933
2004
  }
1934
- e.target.value = value;
1935
- }
1936
-
1937
- // 🎨 FORMATAÇÃO DE CAMPOS
1938
- document.addEventListener('input', function(e) {
1939
- // CPF - 9 dígitos
1940
- // CPF - 11 dígitos
1941
- if (e.target.classList.contains('cpf-field')) {
1942
- let value = e.target.value.replace(/[^\d]/g, '');
1943
- if (value.length > 11) value = value.slice(0, 11);
1944
2005
 
1945
- if (value.length > 9) {
1946
- value = value.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
1947
- } else if (value.length > 6) {
1948
- value = value.replace(/(\d{3})(\d{3})(\d{3})/, '$1.$2.$3');
1949
- } else if (value.length > 3) {
1950
- value = value.replace(/(\d{3})(\d{3})/, '$1.$2');
2006
+ // Scroll inicial para o topo
2007
+ window.scrollTo({ top: 0, behavior: 'smooth' });
2008
+ });
2009
+
2010
+ // FORMATAÇÃO DE CAMPOS
2011
+ document.addEventListener('input', function(e) {
2012
+ if (e.target.classList.contains('cpf-field')) {
2013
+ let value = e.target.value.replace(/[^\d]/g, '');
2014
+ if (value.length > 11) value = value.slice(0, 11);
2015
+
2016
+ if (value.length > 9) {
2017
+ value = value.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
2018
+ } else if (value.length > 6) {
2019
+ value = value.replace(/(\d{3})(\d{3})(\d{3})/, '$1.$2.$3');
2020
+ } else if (value.length > 3) {
2021
+ value = value.replace(/(\d{3})(\d{3})/, '$1.$2');
2022
+ }
2023
+ e.target.value = value;
1951
2024
  }
1952
- e.target.value = value;
1953
- }
1954
2025
 
1955
- // Telefone
1956
2026
  if (e.target.classList.contains('phone-field')) {
1957
2027
  let value = e.target.value.replace(/[^\d]/g, '');
1958
2028
  if (value.length <= 10) {
@@ -1965,8 +2035,8 @@ if (input.classList.contains('cnpj-field') && input.value) {
1965
2035
  e.target.value = value;
1966
2036
  }
1967
2037
  });
1968
-
1969
- // 🌟 RATING COM ESTRELAS
2038
+
2039
+ // RATING COM ESTRELAS
1970
2040
  document.addEventListener('click', function(e) {
1971
2041
  if (e.target.classList.contains('star')) {
1972
2042
  const ratingGroup = e.target.parentNode;
@@ -1977,600 +2047,227 @@ if (input.classList.contains('cnpj-field') && input.value) {
1977
2047
  hiddenInput.value = value;
1978
2048
 
1979
2049
  const stars = ratingGroup.querySelectorAll('.star');
1980
- stars.forEach((star, index) => {
1981
- if (index < value) {
1982
- star.classList.add('active');
2050
+ for (let i = 0; i < stars.length; i++) {
2051
+ if (i < value) {
2052
+ stars[i].classList.add('active');
1983
2053
  } else {
1984
- star.classList.remove('active');
2054
+ stars[i].classList.remove('active');
1985
2055
  }
1986
- });
2056
+ }
1987
2057
 
1988
2058
  const ratingText = ratingGroup.querySelector('.rating-text');
1989
2059
  if (ratingText) {
1990
2060
  const maxRating = stars.length;
1991
- ratingText.textContent = `${value} de ${maxRating} estrelas`;
2061
+ ratingText.textContent = value + ' de ' + maxRating + ' estrelas';
1992
2062
  }
1993
2063
  }
1994
2064
  }
1995
2065
  });
2066
+
2067
+ console.log('Formulário carregado com sucesso!');
1996
2068
 
1997
- // ⌨️ NAVEGAÇÃO POR TECLADO
1998
- document.addEventListener('keydown', function(e) {
1999
- if (e.key === 'Enter' && e.target.tagName !== 'TEXTAREA') {
2000
- e.preventDefault();
2001
- nextStep();
2002
- }
2003
-
2004
- if (e.key === 'Escape' && currentStep > 1 && currentStep < successStepIndex) {
2005
- prevStep();
2006
- }
2007
-
2008
- // Navegação do wizard por teclado
2009
- if (currentStep >= 1 && currentStep <= formSteps) {
2010
- if (e.key === 'ArrowDown' || e.key === 'PageDown') {
2011
- e.preventDefault();
2012
- scrollToNext();
2013
- } else if (e.key === 'ArrowUp' || e.key === 'PageUp') {
2014
- e.preventDefault();
2015
- scrollToPrevious();
2016
- }
2017
- }
2018
- });
2019
-
2020
- // 🚀 INICIALIZAÇÃO PRINCIPAL
2021
- document.addEventListener('DOMContentLoaded', function() {
2022
- console.log('📄 DOM carregado - Wizard com scroll detection corrigido');
2069
+ // Adicione esta função no seu script principal
2070
+ function handleChildrenNavigation(selectedValue, targetSection) {
2071
+ console.log(`Resposta sobre filhos: ${selectedValue}`);
2072
+
2073
+ if (selectedValue === 'SIM') {
2074
+ // Mostrar perguntas 2-5 sobre filhos
2075
+ showChildrenQuestions();
2076
+ console.log('Mostrando perguntas sobre filhos');
2023
2077
 
2024
- // Verificar success na URL primeiro
2025
- if (!checkForSuccess()) {
2026
- showStep(0);
2027
- }
2078
+ } else if (selectedValue === 'NÃO') {
2079
+ // Ocultar perguntas 2-5 e pular para próxima seção
2080
+ hideChildrenQuestions();
2028
2081
 
2029
- // Scroll inicial para o topo
2030
- window.scrollTo({ top: 0, behavior: 'smooth' });
2031
- });
2032
-
2033
- // 🔧 FUNÇÕES DE DEBUG GLOBAIS
2034
- window.debugFormulario = {
2035
- currentStep: () => currentStep,
2036
- currentWizardIndex: () => currentActiveWizardIndex,
2037
- wizardSteps: () => wizardSteps,
2038
- goToStep: (step) => {
2039
- currentStep = step;
2040
- showStep(step);
2041
- },
2042
- goToWizardStep: (index) => scrollToWizardStep(index),
2043
- updateWizardVisual: () => updateWizardVisual(),
2044
- logPositions: () => {
2045
- const formContent = document.getElementById('formContent');
2046
- const scrollTop = formContent.scrollTop;
2047
-
2048
- console.log(`📍 Debug das posições dos divisores:`);
2049
- console.log(`ScrollTop atual: ${scrollTop}px`);
2050
- console.log(`Wizard ativo: ${currentActiveWizardIndex + 1}/${wizardSteps.length} - "${wizardSteps[currentActiveWizardIndex]?.title}"`);
2051
- console.log(`ViewportCenter: ${scrollTop + (formContent.clientHeight / 3)}px`);
2052
-
2053
- wizardSteps.forEach((step, index) => {
2054
- if (step.element) {
2055
- const rect = step.element.getBoundingClientRect();
2056
- const containerRect = formContent.getBoundingClientRect();
2057
- const elementTop = rect.top - containerRect.top + scrollTop;
2058
- const viewportCenter = scrollTop + (formContent.clientHeight / 3);
2059
- const distance = Math.abs(elementTop - viewportCenter);
2060
- const isInView = elementTop <= viewportCenter + 100;
2061
-
2062
- console.log(`${index + 1}: "${step.title}"`);
2063
- console.log(` - ElementTop: ${elementTop}px`);
2064
- console.log(` - Distance: ${distance}px`);
2065
- console.log(` - InView: ${isInView}`);
2066
- console.log(` - IsActive: ${index === currentActiveWizardIndex}`);
2067
- console.log(` ---`);
2068
- }
2069
- });
2070
- },
2071
- forceUpdate: (index) => {
2072
- currentActiveWizardIndex = index;
2073
- updateWizardVisual();
2074
- updateDividerVisual();
2075
- console.log(`🔧 Forçado update para index ${index}`);
2082
+ // Pular para "DADOS PESSOAIS E PROFISSIONAIS"
2083
+ if (targetSection) {
2084
+ setTimeout(() => {
2085
+ redirectToSpecificSection(targetSection);
2086
+ }, 500);
2076
2087
  }
2077
- };
2078
-
2079
- console.log('🚀 Wizard com detecção de scroll CORRIGIDO carregado!');
2080
- console.log('🔧 Para debug: window.debugFormulario');
2081
- </script>
2082
-
2083
- {% if form_success %}
2084
- <script>
2085
- console.log('🎉 Form success detectado via template');
2086
- document.addEventListener('DOMContentLoaded', function() {
2087
- setTimeout(() => {
2088
- currentStep = successStepIndex;
2089
- showStep(currentStep);
2090
- }, 100);
2091
- });
2092
-
2093
-
2094
- // ========================================
2095
- // SISTEMA AVANÇADO DE MULTI-REDIRECIONAMENTO
2096
- // ========================================
2097
-
2098
- // Variáveis para controle avançado
2099
- let multiRedirectFields = new Map();
2100
- let pendingActions = new Map();
2101
- let conditionalFieldsVisible = new Set();
2102
-
2103
- // INICIALIZAÇÃO DOS CAMPOS MULTI-REDIRECT
2104
- function initializeMultiRedirectFields() {
2105
- console.log('🔀 Inicializando sistema multi-redirecionamento...');
2106
2088
 
2107
- const multiRedirectGroups = document.querySelectorAll('.checkbox-multi-redirect-group');
2108
-
2109
- multiRedirectGroups.forEach(group => {
2110
- try {
2111
- const configData = group.getAttribute('data-field-config');
2112
- const config = JSON.parse(configData);
2113
-
2114
- multiRedirectFields.set(config.fieldId, config);
2115
-
2116
- // Configurar listeners baseado no tipo de campo
2117
- if (config.fieldType === 'checkbox') {
2118
- setupCheckboxListeners(group, config);
2119
- } else if (config.fieldType === 'radio') {
2120
- setupRadioListeners(group, config);
2121
- } else if (config.fieldType === 'dropdown') {
2122
- setupDropdownListeners(group, config);
2123
- }
2124
-
2125
- console.log(`✅ Multi-redirect configurado: ${config.fieldId} (${config.fieldType})`);
2126
-
2127
- } catch (error) {
2128
- console.error('❌ Erro configuração multi-redirect:', error);
2129
- }
2130
- });
2131
-
2132
- console.log(`🔀 ${multiRedirectFields.size} campos multi-redirect ativos`);
2089
+ console.log('Ocultando perguntas sobre filhos e pulando para próxima seção');
2133
2090
  }
2091
+ }
2134
2092
 
2135
- // CONFIGURAR LISTENERS PARA CHECKBOX
2136
- function setupCheckboxListeners(group, config) {
2137
- const checkbox = group.querySelector('.multi-redirect-input');
2138
- const item = group.querySelector('.multi-redirect-item');
2139
-
2140
- if (checkbox && item) {
2141
- checkbox.addEventListener('change', function(e) {
2142
- const isChecked = e.target.checked;
2143
-
2144
- if (isChecked) {
2145
- item.classList.add('selected');
2146
- handleOptionSelected(config, 0, config.options[0]); // Primeira opção
2147
- } else {
2148
- item.classList.remove('selected');
2149
- handleOptionDeselected(config);
2093
+ function showChildrenQuestions() {
2094
+ // IDs ou seletores das perguntas 2-5 sobre filhos
2095
+ const childrenQuestionIds = [
2096
+ '#question-2-children', // Substitua pelos IDs reais
2097
+ '#question-3-children',
2098
+ '#question-4-children',
2099
+ '#question-5-children'
2100
+ ];
2101
+
2102
+ childrenQuestionIds.forEach(questionId => {
2103
+ const questionElement = document.querySelector(questionId);
2104
+ if (questionElement) {
2105
+ questionElement.style.display = 'block';
2106
+ questionElement.style.animation = 'fadeIn 0.3s ease-in-out';
2107
+
2108
+ // Reativar campos obrigatórios
2109
+ const inputs = questionElement.querySelectorAll('input, select, textarea');
2110
+ inputs.forEach(input => {
2111
+ if (input.dataset.originalRequired === 'true') {
2112
+ input.required = true;
2150
2113
  }
2151
2114
  });
2152
2115
  }
2153
- }
2116
+ });
2117
+ }
2154
2118
 
2155
- // CONFIGURAR LISTENERS PARA RADIO
2156
- function setupRadioListeners(group, config) {
2157
- const radios = group.querySelectorAll('.multi-redirect-input');
2158
- const items = group.querySelectorAll('.multi-redirect-item');
2159
-
2160
- radios.forEach((radio, index) => {
2161
- radio.addEventListener('change', function(e) {
2162
- if (e.target.checked) {
2163
- // Remover seleção anterior
2164
- items.forEach(item => item.classList.remove('selected'));
2165
-
2166
- // Adicionar seleção atual
2167
- const selectedItem = e.target.closest('.multi-redirect-item');
2168
- if (selectedItem) {
2169
- selectedItem.classList.add('selected');
2170
- }
2171
-
2172
- const optionIndex = parseInt(e.target.getAttribute('data-option-index'));
2173
- handleOptionSelected(config, optionIndex, config.options[optionIndex]);
2119
+ function hideChildrenQuestions() {
2120
+ // IDs ou seletores das perguntas 2-5 sobre filhos
2121
+ const childrenQuestionIds = [
2122
+ '#question-2-children', // Substitua pelos IDs reais
2123
+ '#question-3-children',
2124
+ '#question-4-children',
2125
+ '#question-5-children'
2126
+ ];
2127
+
2128
+ childrenQuestionIds.forEach(questionId => {
2129
+ const questionElement = document.querySelector(questionId);
2130
+ if (questionElement) {
2131
+ questionElement.style.display = 'none';
2132
+
2133
+ // Salvar estado required e desativar
2134
+ const inputs = questionElement.querySelectorAll('input, select, textarea');
2135
+ inputs.forEach(input => {
2136
+ // Salvar estado original
2137
+ if (!input.dataset.originalRequired) {
2138
+ input.dataset.originalRequired = input.required.toString();
2174
2139
  }
2175
- });
2176
- });
2177
- }
2178
-
2179
- // CONFIGURAR LISTENERS PARA DROPDOWN
2180
- function setupDropdownListeners(group, config) {
2181
- const select = group.querySelector('.multi-redirect-input');
2182
-
2183
- if (select) {
2184
- select.addEventListener('change', function(e) {
2185
- const selectedOption = e.target.selectedOptions[0];
2140
+ input.required = false;
2186
2141
 
2187
- if (selectedOption && selectedOption.value) {
2188
- const optionIndex = parseInt(selectedOption.getAttribute('data-option-index'));
2189
- handleOptionSelected(config, optionIndex, config.options[optionIndex]);
2142
+ // Limpar valores
2143
+ if (input.type === 'checkbox' || input.type === 'radio') {
2144
+ input.checked = false;
2190
2145
  } else {
2191
- handleOptionDeselected(config);
2146
+ input.value = '';
2192
2147
  }
2193
2148
  });
2194
2149
  }
2195
- }
2150
+ });
2151
+ }
2196
2152
 
2197
- // GERENCIAR OPÇÃO SELECIONADA
2198
- function handleOptionSelected(config, optionIndex, option) {
2199
- console.log(`🎯 Opção selecionada: "${option.value}" - Ação: ${option.action}`);
2200
-
2201
- const fieldId = config.fieldId;
2202
- const group = document.querySelector(`[data-field-id="${fieldId}"]`);
2203
-
2204
- // Limpar ações anteriores
2205
- clearPreviousActions(fieldId);
2206
-
2207
- // Mostrar mensagem se configurada
2208
- if (option.message) {
2209
- showRedirectMessage(fieldId, optionIndex, option.message);
2153
+ // Modificar a função handleSmartNavigation para incluir a lógica de filhos
2154
+ function handleSmartNavigation(element) {
2155
+ const fieldContainer = element.closest('[data-field-type="smart_navigation_field"]');
2156
+ if (!fieldContainer) return;
2157
+
2158
+ const fieldId = fieldContainer.dataset.fieldId;
2159
+ const selectedValue = getSelectedValue(element);
2160
+
2161
+ // Verificar se é a pergunta sobre filhos (substitua pelo ID real)
2162
+ if (fieldId.includes('filhos') || fieldContainer.querySelector('label').textContent.toLowerCase().includes('filhos')) {
2163
+ // Encontrar dados de navegação
2164
+ if (!navigationData[fieldId] || !selectedValue) {
2165
+ return;
2210
2166
  }
2211
2167
 
2212
- // Processar ação baseada no tipo
2213
- switch (option.action) {
2214
- case 'continue':
2215
- // Não fazer nada, apenas continuar
2216
- console.log('➡️ Continuando normalmente');
2217
- break;
2218
-
2219
- case 'next_step':
2220
- schedulePendingAction(fieldId, {
2221
- type: 'next_step',
2222
- delay: option.delay || 1,
2223
- message: option.message
2224
- });
2225
- break;
2226
-
2227
- case 'specific_section':
2228
- if (option.targetSection) {
2229
- schedulePendingAction(fieldId, {
2230
- type: 'specific_section',
2231
- target: option.targetSection,
2232
- delay: option.delay || 1,
2233
- message: option.message
2234
- });
2235
- }
2236
- break;
2237
-
2238
- case 'skip_to_end':
2239
- schedulePendingAction(fieldId, {
2240
- type: 'skip_to_end',
2241
- delay: option.delay || 2,
2242
- message: option.message
2243
- });
2244
- break;
2245
-
2246
- case 'show_fields':
2247
- showConditionalFields(fieldId, option.value);
2248
- break;
2168
+ const actionData = navigationData[fieldId][selectedValue];
2169
+ if (!actionData) {
2170
+ return;
2249
2171
  }
2250
- }
2251
-
2252
- // GERENCIAR OPÇÃO DESELECIONADA
2253
- function handleOptionDeselected(config) {
2254
- const fieldId = config.fieldId;
2255
- console.log(`❌ Opção deselecionada: ${fieldId}`);
2256
2172
 
2257
- clearPreviousActions(fieldId);
2258
- hideAllConditionalFields(fieldId);
2173
+ // Executar lógica específica para filhos
2174
+ handleChildrenNavigation(selectedValue, actionData.target_section);
2175
+ return;
2259
2176
  }
2260
-
2261
- // AGENDAR AÇÃO PENDENTE
2262
- function schedulePendingAction(fieldId, action) {
2263
- // Adicionar indicador visual
2264
- const group = document.querySelector(`[data-field-id="${fieldId}"]`);
2265
- if (group) {
2266
- group.classList.add('action-pending');
2267
-
2268
- let pendingText = '🔄 Processando...';
2269
- if (action.type === 'next_step') pendingText = '⏩ Próxima etapa...';
2270
- else if (action.type === 'specific_section') pendingText = '🎯 Redirecionando...';
2271
- else if (action.type === 'skip_to_end') pendingText = '⏭️ Finalizando...';
2272
-
2273
- group.setAttribute('data-pending-action', pendingText);
2274
- }
2275
-
2276
- // Agendar execução
2277
- pendingActions.set(fieldId, action);
2278
-
2279
- console.log(`📅 Ação agendada para ${action.delay}s: ${action.type}`);
2177
+
2178
+ // Continuar com lógica normal para outros campos
2179
+ if (!navigationData[fieldId] || !selectedValue) {
2180
+ return;
2280
2181
  }
2281
-
2282
- // LIMPAR AÇÕES ANTERIORES
2283
- function clearPreviousActions(fieldId) {
2284
- // Remover ação pendente
2285
- pendingActions.delete(fieldId);
2286
-
2287
- // Remover indicador visual
2288
- const group = document.querySelector(`[data-field-id="${fieldId}"]`);
2289
- if (group) {
2290
- group.classList.remove('action-pending');
2291
- group.removeAttribute('data-pending-action');
2292
- }
2293
-
2294
- // Ocultar mensagens
2295
- hideAllRedirectMessages(fieldId);
2182
+
2183
+ const actionData = navigationData[fieldId][selectedValue];
2184
+ if (!actionData) {
2185
+ return;
2296
2186
  }
2297
-
2298
- // MOSTRAR MENSAGEM DE REDIRECIONAMENTO
2299
- function showRedirectMessage(fieldId, optionIndex, message) {
2300
- const blockId = fieldId.split('_').pop();
2301
- const messageElement = document.getElementById(`redirect_message_${blockId}_${optionIndex}`);
2302
-
2303
- if (messageElement) {
2304
- messageElement.style.display = 'block';
2187
+
2188
+ console.log(`Navegação ativada: ${fieldId} -> ${selectedValue}`);
2189
+
2190
+ // Executar ação baseada no tipo
2191
+ switch (actionData.action_type) {
2192
+ case 'continue':
2193
+ console.log('Continuando navegação normal');
2194
+ break;
2305
2195
 
2306
- setTimeout(() => {
2307
- messageElement.scrollIntoView({
2308
- behavior: 'smooth',
2309
- block: 'center'
2310
- });
2311
- }, 100);
2312
- }
2313
- }
2314
-
2315
- // OCULTAR TODAS AS MENSAGENS
2316
- function hideAllRedirectMessages(fieldId) {
2317
- const blockId = fieldId.split('_').pop();
2318
- const messages = document.querySelectorAll(`[id^="redirect_message_${blockId}_"]`);
2319
-
2320
- messages.forEach(message => {
2321
- message.style.display = 'none';
2322
- });
2323
- }
2324
-
2325
- // MOSTRAR CAMPOS CONDICIONAIS
2326
- function showConditionalFields(fieldId, optionValue) {
2327
- const conditionalField = document.querySelector(`[data-parent-field="${fieldId}"][data-option-value="${optionValue}"]`);
2328
-
2329
- if (conditionalField) {
2330
- conditionalField.style.display = 'block';
2331
- conditionalFieldsVisible.add(`${fieldId}_${optionValue}`);
2196
+ case 'jump_to_section':
2197
+ handleJumpToSection(actionData.target_section);
2198
+ break;
2332
2199
 
2333
- console.log(`👁️ Campos condicionais mostrados para: ${optionValue}`);
2200
+ case 'finish_form':
2201
+ handleFinishForm();
2202
+ break;
2334
2203
 
2335
- setTimeout(() => {
2336
- conditionalField.scrollIntoView({
2337
- behavior: 'smooth',
2338
- block: 'center'
2339
- });
2340
- }, 200);
2341
- }
2342
- }
2343
-
2344
- // OCULTAR TODOS OS CAMPOS CONDICIONAIS
2345
- function hideAllConditionalFields(fieldId) {
2346
- const conditionalFields = document.querySelectorAll(`[data-parent-field="${fieldId}"]`);
2347
-
2348
- conditionalFields.forEach(field => {
2349
- field.style.display = 'none';
2350
- });
2351
-
2352
- // Limpar controle
2353
- Array.from(conditionalFieldsVisible).forEach(key => {
2354
- if (key.startsWith(fieldId)) {
2355
- conditionalFieldsVisible.delete(key);
2356
- }
2357
- });
2358
- }
2359
-
2360
- // EXECUTAR AÇÃO PENDENTE
2361
- function executePendingAction(action) {
2362
- console.log(`🚀 Executando ação: ${action.type}`);
2363
-
2364
- switch (action.type) {
2365
- case 'next_step':
2366
- executeNextStep();
2367
- break;
2368
-
2369
- case 'specific_section':
2370
- executeSpecificSection(action.target);
2371
- break;
2372
-
2373
- case 'skip_to_end':
2374
- executeSkipToEnd();
2375
- break;
2376
- }
2377
- }
2378
-
2379
- // EXECUTAR PRÓXIMA ETAPA
2380
- function executeNextStep() {
2381
- console.log(`➡️ Indo para próxima etapa`);
2382
-
2383
- if (currentStep < formSteps) {
2384
- currentStep++;
2385
- showStep(currentStep);
2386
- } else {
2387
- const form = document.getElementById('wagtailForm');
2388
- if (form) {
2389
- form.submit();
2390
- }
2391
- }
2392
- }
2393
-
2394
- // EXECUTAR SEÇÃO ESPECÍFICA
2395
- function executeSpecificSection(sectionTitle) {
2396
- console.log(`🎯 Redirecionando para: "${sectionTitle}"`);
2397
-
2398
- const success = redirectToSpecificSection(sectionTitle);
2399
- if (!success) {
2400
- console.log(`⚠️ Seção não encontrada, indo para próxima etapa`);
2401
- executeNextStep();
2402
- }
2204
+ case 'show_message_and_finish':
2205
+ handleShowMessageAndFinish(actionData);
2206
+ break;
2403
2207
  }
2208
+ }
2404
2209
 
2405
- // EXECUTAR PULAR PARA O FINAL
2406
- function executeSkipToEnd() {
2407
- console.log(`⏭️ Pulando para o final`);
2408
-
2409
- const form = document.getElementById('wagtailForm');
2410
- if (form) {
2411
- let skipField = form.querySelector('input[name="form_multi_redirected"]');
2412
- if (!skipField) {
2413
- skipField = document.createElement('input');
2414
- skipField.type = 'hidden';
2415
- skipField.name = 'form_multi_redirected';
2416
- form.appendChild(skipField);
2417
- }
2418
- skipField.value = 'true';
2419
- }
2420
-
2421
- currentStep = totalSteps - 1;
2422
- showStep(currentStep);
2423
-
2424
- // Auto-submeter após delay
2425
- setTimeout(() => {
2426
- if (form) {
2427
- console.log('📨 Auto-submetendo formulário');
2428
- form.submit();
2429
- }
2430
- }, 1500);
2431
- }
2432
-
2433
- // MODIFICAR VALIDAÇÃO PARA CONSIDERAR AÇÕES PENDENTES
2434
- const originalValidateCurrentStep = validateCurrentStep;
2435
- validateCurrentStep = function() {
2436
- // Executar ações pendentes antes da validação
2437
- if (pendingActions.size > 0) {
2438
- console.log(`🔀 ${pendingActions.size} ações pendentes`);
2439
-
2440
- const actions = Array.from(pendingActions.values());
2441
- pendingActions.clear();
2442
-
2443
- // Limpar indicadores visuais
2444
- document.querySelectorAll('.action-pending').forEach(group => {
2445
- group.classList.remove('action-pending');
2446
- group.removeAttribute('data-pending-action');
2447
- });
2448
-
2449
- if (actions.length > 0) {
2450
- setTimeout(() => executePendingAction(actions[0]), (actions[0].delay || 1) * 1000);
2451
- return true;
2452
- }
2453
- }
2454
-
2455
- return originalValidateCurrentStep();
2456
- };
2457
-
2458
- // MODIFICAR NEXTSTEP PARA CONSIDERAR AÇÕES
2459
- const originalNextStep = nextStep;
2460
- nextStep = function() {
2461
- if (pendingActions.size > 0) {
2462
- console.log('🔀 Executando ações pendentes...');
2463
-
2464
- const actions = Array.from(pendingActions.values());
2465
- pendingActions.clear();
2466
-
2467
- // Limpar indicadores visuais
2468
- document.querySelectorAll('.action-pending').forEach(group => {
2469
- group.classList.remove('action-pending');
2470
- group.removeAttribute('data-pending-action');
2471
- });
2472
-
2473
- if (actions.length > 0) {
2474
- executePendingAction(actions[0]);
2475
- return;
2476
- }
2477
- }
2478
-
2479
- originalNextStep();
2480
- };
2481
-
2482
- // FUNÇÃO PARA REDIRECIONAR PARA SEÇÃO ESPECÍFICA (reutilizada)
2483
- function redirectToSpecificSection(sectionTitle) {
2484
- console.log(`🎯 Procurando seção: "${sectionTitle}"`);
2485
-
2486
- const dividers = document.querySelectorAll('[data-block-type="divider"], .divider-title');
2487
-
2488
- for (const divider of dividers) {
2489
- let dividerTitle = '';
2490
-
2491
- if (divider.classList.contains('divider-title')) {
2492
- dividerTitle = divider.textContent?.trim() || '';
2493
- } else {
2494
- const titleElement = divider.querySelector('.divider-title');
2495
- if (titleElement) {
2496
- dividerTitle = titleElement.textContent?.trim() || '';
2497
- }
2498
- }
2499
-
2500
- if (dividerTitle.toLowerCase().includes(sectionTitle.toLowerCase()) ||
2501
- sectionTitle.toLowerCase().includes(dividerTitle.toLowerCase())) {
2502
-
2503
- console.log(`✅ Seção encontrada: "${dividerTitle}"`);
2210
+ // Função melhorada para redirecionar para seção específica
2211
+ function redirectToSpecificSection(sectionTitle) {
2212
+ console.log(`Procurando seção: "${sectionTitle}"`);
2213
+
2214
+ // Procurar por diferentes tipos de elementos que podem conter o título da seção
2215
+ const selectors = [
2216
+ '.divider-title',
2217
+ '.section-title',
2218
+ '[data-section-title]',
2219
+ 'h2', 'h3', 'h4'
2220
+ ];
2221
+
2222
+ for (let selector of selectors) {
2223
+ const elements = document.querySelectorAll(selector);
2224
+
2225
+ for (let element of elements) {
2226
+ const elementText = element.textContent?.trim() || '';
2227
+ const dataTitle = element.dataset.sectionTitle || '';
2228
+
2229
+ // Verificar se o texto corresponde (ignorando case e espaços extras)
2230
+ if (elementText.toLowerCase().includes(sectionTitle.toLowerCase()) ||
2231
+ dataTitle.toLowerCase().includes(sectionTitle.toLowerCase()) ||
2232
+ sectionTitle.toLowerCase().includes(elementText.toLowerCase())) {
2504
2233
 
2505
- let stepElement = divider;
2506
- while (stepElement && !stepElement.classList.contains('step-content')) {
2507
- stepElement = stepElement.parentElement;
2508
- }
2234
+ console.log(`Seção encontrada: "${elementText}"`);
2509
2235
 
2510
- if (stepElement && stepElement.id) {
2511
- const stepMatch = stepElement.id.match(/step(\d+)/);
2512
- if (stepMatch) {
2513
- const targetStep = parseInt(stepMatch[1]);
2236
+ // Scroll suave para a seção
2237
+ setTimeout(() => {
2238
+ const formContent = document.getElementById('formContent');
2239
+ if (formContent) {
2240
+ const offset = 120;
2241
+ const elementPosition = element.getBoundingClientRect().top +
2242
+ formContent.scrollTop - offset;
2243
+
2244
+ formContent.scrollTo({
2245
+ top: elementPosition,
2246
+ behavior: 'smooth'
2247
+ });
2248
+
2249
+ // Destacar temporariamente a seção
2250
+ element.style.background = 'rgba(42, 94, 44, 0.1)';
2251
+ element.style.padding = '1rem';
2252
+ element.style.borderRadius = '8px';
2253
+ element.style.transition = 'all 0.3s ease';
2514
2254
 
2515
- if (targetStep >= 1 && targetStep <= formSteps) {
2516
- currentStep = targetStep;
2517
- showStep(currentStep);
2518
-
2519
- setTimeout(() => {
2520
- const formContent = document.getElementById('formContent');
2521
- if (formContent) {
2522
- const offset = 150;
2523
- const elementTop = divider.offsetTop - offset;
2524
-
2525
- formContent.scrollTo({
2526
- top: Math.max(0, elementTop),
2527
- behavior: 'smooth'
2528
- });
2529
- }
2530
- }, 300);
2531
-
2532
- return true;
2533
- }
2255
+ setTimeout(() => {
2256
+ element.style.background = '';
2257
+ element.style.padding = '';
2258
+ }, 2000);
2534
2259
  }
2535
- }
2260
+ }, 100);
2261
+
2262
+ return true;
2536
2263
  }
2537
2264
  }
2538
-
2539
- console.log(`❌ Seção "${sectionTitle}" não encontrada`);
2540
- return false;
2541
2265
  }
2542
-
2543
- // INICIALIZAÇÃO
2544
- document.addEventListener('DOMContentLoaded', function() {
2545
- setTimeout(() => {
2546
- initializeMultiRedirectFields();
2547
- }, 300);
2548
- });
2549
-
2550
- // DEBUGGING
2551
- window.debugMultiRedirect = {
2552
- fields: () => multiRedirectFields,
2553
- pending: () => pendingActions,
2554
- conditionals: () => conditionalFieldsVisible,
2555
- testSection: (name) => redirectToSpecificSection(name),
2556
- clearAll: () => {
2557
- pendingActions.clear();
2558
- conditionalFieldsVisible.clear();
2559
- document.querySelectorAll('.action-pending').forEach(group => {
2560
- group.classList.remove('action-pending');
2561
- group.removeAttribute('data-pending-action');
2562
- });
2563
- console.log('🧹 Multi-redirect limpo');
2564
- },
2565
- executeAction: (type, target) => {
2566
- executePendingAction({ type: type, target: target });
2567
- }
2568
- };
2569
-
2570
- console.log('🔀 Sistema Multi-Redirecionamento Avançado carregado');
2571
- console.log('🔧 Debug: window.debugMultiRedirect');
2572
-
2266
+
2267
+ console.log(`Seção "${sectionTitle}" não encontrada`);
2268
+ return false;
2269
+ }
2573
2270
  </script>
2574
- {% endif %}
2271
+
2575
2272
 
2576
2273
  {% endblock %}