idrh hjj
drop in the dynamic hexagonal grid as mentioned earlier
d41a4fc verified
Raw
History Blame Contribute Delete
9.04 kB
// 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
}