Personal Genealogy Research Dashboard

Personal Genealogy Research Dashboard

Organize, visualize, and track your family history.

Research Overview

Family Tree

Individual Records

Name Birth Year Death Year Parents

Manage Individuals

No data to display tree.

`; } }; const renderConfigRows = () => { configRowsContainer.innerHTML = ''; const sortedPeople = [...state.people].sort((a,b) => a.id - b.id); const peopleOptions = state.people.map(p => ``).join(''); sortedPeople.forEach(p => { configRowsContainer.innerHTML += `
`.replaceAll('class="config-input"', 'class="config-input w-full border-gray-300 rounded-md shadow-sm"'); }); // Set selected options for parents after rendering all rows sortedPeople.forEach(p => { if(p.parent1Id) document.querySelector(`select[data-id="${p.id}"][data-field="parent1Id"]`).value = p.parent1Id; if(p.parent2Id) document.querySelector(`select[data-id="${p.id}"][data-field="parent2Id"]`).value = p.parent2Id; }); addConfigEventListeners(); }; // --- EVENT HANDLERS --- const handleConfigChange = (e) => { const id = parseInt(e.target.dataset.id); const field = e.target.dataset.field; const value = e.target.value; const person = state.people.find(p => p.id === id); if (person) { person[field] = value ? parseInt(value, 10) : null; if (field === 'name') person[field] = value; } renderAll(); }; const handleAddPerson = () => { const newId = state.people.length > 0 ? Math.max(...state.people.map(p => p.id)) + 1 : 1; state.people.push({ id: newId, name: "New Person", birthYear: null, deathYear: null, parent1Id: null, parent2Id: null }); renderAll(); }; const handleRemovePerson = (e) => { const id = parseInt(e.target.dataset.id); state.people = state.people.filter(p => p.id !== id); // Also remove from parent fields of other people state.people.forEach(p => { if (p.parent1Id === id) p.parent1Id = null; if (p.parent2Id === id) p.parent2Id = null; }); renderAll(); }; const addConfigEventListeners = () => { document.querySelectorAll('.config-input').forEach(input => input.addEventListener('change', handleConfigChange)); document.querySelectorAll('.remove-btn').forEach(button => button.addEventListener('click', handleRemovePerson)); }; const handleDownloadPdf = () => { const { jsPDF } = window.jspdf; const pdfContent = document.getElementById('pdf-content'); document.querySelectorAll('.no-print').forEach(el => el.style.visibility = 'hidden'); html2canvas(pdfContent, { scale: 2, useCORS: true, backgroundColor: '#ffffff' }).then(canvas => { document.querySelectorAll('.no-print').forEach(el => el.style.visibility = 'visible'); const imgData = canvas.toDataURL('image/png'); const pdf = new jsPDF({ orientation: 'p', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const imgWidth = pdfWidth - 20; const imgHeight = canvas.height * imgWidth / canvas.width; pdf.addImage(imgData, 'PNG', 10, 10, imgWidth, imgHeight); pdf.save('Genealogy-Dashboard.pdf'); }); }; // --- TABBING LOGIC --- let currentTabIndex = 0; const updateTabButtons = () => { prevTabBtn.disabled = currentTabIndex === 0; nextTabBtn.disabled = currentTabIndex === tabContents.length - 1; }; const switchTab = (index) => { tabButtons.forEach(btn => btn.classList.remove('active')); tabContents.forEach(content => content.classList.remove('active')); tabButtons[index].classList.add('active'); tabContents[index].classList.add('active'); currentTabIndex = index; updateTabButtons(); }; tabButtons.forEach((button, index) => button.addEventListener('click', () => switchTab(index))); prevTabBtn.addEventListener('click', () => { if (currentTabIndex > 0) switchTab(currentTabIndex - 1); }); nextTabBtn.addEventListener('click', () => { if (currentTabIndex < tabContents.length - 1) switchTab(currentTabIndex + 1); }); // --- INITIALIZATION --- if (kpiContainer && addPersonBtn && downloadPdfBtn) { addPersonBtn.addEventListener('click', handleAddPerson); downloadPdfBtn.addEventListener('click', handleDownloadPdf); renderAll(); updateTabButtons(); } else { console.error("Essential dashboard elements could not be found."); } });
Scroll to Top