Spaces:
Running
Running
| // State management for the hexagon grid | |
| let hexagonState = { | |
| traits: { | |
| // These will be populated from the component | |
| }, | |
| positions: {}, | |
| colors: {}, | |
| centerRing: ['Authenticity', 'Compassion', 'Courage', 'Discipline', 'Empathy', 'Fairness'], | |
| selectedTraits: { | |
| green: [], | |
| amber: [], | |
| red: [] | |
| } | |
| }; | |
| // Initialize drag and drop | |
| function setupDragAndDrop() { | |
| const hexGrid = document.querySelector('custom-hexagon-grid'); | |
| document.addEventListener('dragover', (e) => { | |
| e.preventDefault(); // Allow drop | |
| }); | |
| // Set up drop zones for each ring | |
| document.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| const targetRing = e.target.closest('.ring'); | |
| if (!targetRing) return; | |
| const ringNumber = parseInt(targetRing.classList[1].split('-')[1]); | |
| const draggedRing = parseInt(e.dataTransfer.getData('hexagon-ring')); | |
| const draggedIndex = parseInt(e.dataTransfer.getData('hexagon-index')); | |
| if (draggedRing === ringNumber) return; // Can't drop on same ring | |
| // In a full implementation, this would: | |
| // 1. Calculate the molecular reaction path | |
| // 2. Shift traits along the path | |
| // 3. Update the visual representation | |
| console.log(`Moving trait from ring ${draggedRing} to ring ${ringNumber}`); | |
| }); | |
| } | |
| // Update trait colors in state | |
| function updateTraitColor(traitName, color) { | |
| // Remove from any existing color groups | |
| for (const group in hexagonState.selectedTraits) { | |
| const index = hexagonState.selectedTraits[group].indexOf(traitName); | |
| if (index > -1) { | |
| hexagonState.selectedTraits[group].splice(index, 1); | |
| } | |
| } | |
| // Add to new color group if not resetting | |
| if (color !== 'reset') { | |
| hexagonState.selectedTraits[color].push(traitName); | |
| // Enforce max 6 per category | |
| if (hexagonState.selectedTraits[color].length > 6) { | |
| hexagonState.selectedTraits[color].shift(); | |
| } | |
| } | |
| console.log('Updated trait colors:', hexagonState.selectedTraits); | |
| } | |
| // DOM elements | |
| const selectedTraitsContainer = document.getElementById('selected-traits'); | |
| const generateReportBtn = document.getElementById('generate-report'); | |
| // Initialize the app | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // Step navigation | |
| const nextButtons = document.querySelectorAll('.next-step'); | |
| nextButtons.forEach(button => { | |
| button.addEventListener('click', goToNextStep); | |
| }); | |
| // Setup drag and drop | |
| setupDragAndDrop(); | |
| // Initialize first step | |
| updateStepProgress(1); | |
| // Generate report handler | |
| if (generateReportBtn) { | |
| generateReportBtn.addEventListener('click', generateReport); | |
| } | |
| }); | |
| let currentStep = 1; | |
| function goToNextStep() { | |
| if (currentStep < 4) { | |
| currentStep++; | |
| updateStepProgress(currentStep); | |
| } | |
| } | |
| function updateStepProgress(step) { | |
| // Update step indicators | |
| document.querySelectorAll('.step').forEach((stepEl, index) => { | |
| const stepNum = index + 1; | |
| stepEl.classList.remove('active', 'completed'); | |
| if (stepNum < step) { | |
| stepEl.classList.add('completed'); | |
| } else if (stepNum === step) { | |
| stepEl.classList.add('active'); | |
| } | |
| }); | |
| // Update step dividers | |
| document.querySelectorAll('.step-divider').forEach((divider, index) => { | |
| const stepNum = index + 1; | |
| divider.classList.remove('completed'); | |
| if (stepNum < step) { | |
| divider.classList.add('completed'); | |
| } | |
| }); | |
| // Show current step content | |
| document.querySelectorAll('.step-content').forEach(content => { | |
| content.classList.remove('active'); | |
| if (parseInt(content.dataset.step) === step) { | |
| content.classList.add('active'); | |
| } | |
| }); | |
| // Initialize specific step functionality | |
| switch(step) { | |
| case 2: | |
| initializeTraitExploration(); | |
| break; | |
| case 3: | |
| setupTraitCategorization(); | |
| break; | |
| case 4: | |
| generateSummary(); | |
| break; | |
| } | |
| } | |
| function initializeTraitExploration() { | |
| // Setup trait selection in sidebar | |
| const hexGrid = document.querySelector('custom-hexagon-grid'); | |
| hexGrid.addEventListener('traitSelected', (e) => { | |
| const { traitName, color } = e.detail; | |
| updateTraitColor(traitName, color); | |
| // Update the sidebar display | |
| const selectedTraits = document.getElementById('selected-traits'); | |
| const existingTrait = Array.from(selectedTraits.children).find(el => | |
| el.textContent.includes(traitName) | |
| ); | |
| if (color === 'reset' && existingTrait) { | |
| existingTrait.remove(); | |
| } else { | |
| if (existingTrait) { | |
| existingTrait.className = `trait-${color} bg-${color}-100 p-2 rounded border-l-4 border-${color}-500 mb-2`; | |
| } else { | |
| const traitDiv = document.createElement('div'); | |
| traitDiv.className = `trait-${color} bg-${color}-100 p-2 rounded border-l-4 border-${color}-500 mb-2`; | |
| traitDiv.textContent = traitName; | |
| selectedTraits.appendChild(traitDiv); | |
| } | |
| } | |
| }); | |
| } | |
| function setupTraitCategorization() { | |
| // Setup drag and drop for trait categorization | |
| const containers = { | |
| strengths: document.getElementById('strengths-traits'), | |
| opportunities: document.getElementById('opportunities-traits'), | |
| gaps: document.getElementById('gaps-traits') | |
| }; | |
| Object.values(containers).forEach(container => { | |
| container.addEventListener('dragover', (e) => { | |
| e.preventDefault(); | |
| container.style.borderStyle = 'solid'; | |
| }); | |
| container.addEventListener('dragleave', () => { | |
| container.style.borderStyle = 'dashed'; | |
| }); | |
| container.addEventListener('drop', (e) => { | |
| e.preventDefault(); | |
| container.style.borderStyle = 'dashed'; | |
| const traitName = e.dataTransfer.getData('text/plain'); | |
| const color = container.id.split('-')[0]; // 'strengths', 'opportunities', or 'gaps' | |
| // Update the trait color | |
| updateTraitColor(traitName, color === 'strengths' ? 'green' : | |
| color === 'opportunities' ? 'amber' : 'red'); | |
| // Add to the container | |
| const traitDiv = document.createElement('div'); | |
| traitDiv.className = `bg-${color}-100 p-2 rounded mb-2`; | |
| traitDiv.textContent = traitName; | |
| container.appendChild(traitDiv); | |
| }); | |
| }); | |
| } | |
| function generateSummary() { | |
| // Generate the final summary from selected traits | |
| const strengthsSummary = document.getElementById('strengths-summary'); | |
| const opportunitiesSummary = document.getElementById('opportunities-summary'); | |
| const gapsSummary = document.getElementById('gaps-summary'); | |
| strengthsSummary.innerHTML = hexagonState.selectedTraits.green | |
| .map(trait => `<div>${trait}</div>`) | |
| .join(''); | |
| opportunitiesSummary.innerHTML = hexagonState.selectedTraits.amber | |
| .map(trait => `<div>${trait}</div>`) | |
| .join(''); | |
| gapsSummary.innerHTML = hexagonState.selectedTraits.red | |
| .map(trait => `<div>${trait}</div>`) | |
| .join(''); | |
| } | |
| function generateReport() { | |
| // Collect all selected traits | |
| const reportData = { | |
| strengths: hexagonState.selectedTraits.green, | |
| opportunities: hexagonState.selectedTraits.amber, | |
| gaps: hexagonState.selectedTraits.red, | |
| centerTraits: hexagonState.centerRing, | |
| timestamp: new Date().toISOString() | |
| }; | |
| // In a real implementation, this would send to server or generate PDF | |
| console.log('Generating report with data:', reportData); | |
| alert('Your Character Quotient report is being generated. You will receive it by email shortly.'); | |
| // Simulate sending to server | |
| setTimeout(() => { | |
| // Here you would redirect to the report page or show a download link | |
| console.log('Report generated successfully'); | |
| }, 2000); | |
| } | |
| // Function to handle trait selection | |
| function selectTrait(traitId, color) { | |
| // Implementation would handle adding/removing traits from the state | |
| // and updating the UI accordingly | |
| console.log(`Selected trait ${traitId} as ${color}`); | |
| } | |
| // Function to generate report | |
| function generateReport() { | |
| // In a real app, this would collect all selected traits | |
| // and generate a report or send data to the server | |
| alert('Report generation would happen here with the selected traits'); | |
| } | |
| // Drag and drop functions would be implemented here | |
| function setupDragAndDrop() { | |
| // Implementation would handle the molecular reaction effect | |
| // when dragging traits to the center | |
| } |