Medication Dashboard

Medication Dashboard

Medication Overview

Current Medications

Medication Name Dosage Frequency Start Date End Date Status Notes

Manage Your Medications

Add, edit, or remove your medication details below. All changes will automatically update the dashboard.

Medication Name Dosage Frequency Start Date End Date Notes Actions

${totalMedications}

Active Medications

${activeMedications}

Upcoming Medications

${upcomingMedications}

Completed Medications

${completedMedications}

`; } /** * Renders the current medications table in the Dashboard tab. */ function renderCurrentMedications() { // Null check for the current medications table body if (!currentMedicationsTableBody) { console.error("Current medications table body not found."); return; } currentMedicationsTableBody.innerHTML = ''; // Clear existing rows medicationData.forEach(med => { const status = getMedicationStatus(med.startDate, med.endDate); const row = document.createElement('tr'); row.innerHTML = ` ${med.medicationName} ${med.dosage} ${med.frequency} ${med.startDate || 'N/A'} ${med.endDate || 'N/A'} ${status} ${med.notes || 'N/A'} `; currentMedicationsTableBody.appendChild(row); }); } /** * Renders the data input table in the Medication Management tab. */ function renderMedicationInputTable() { // Null check for the medication input table body if (!medicationInputTableBody) { console.error("Medication input table body not found."); return; } medicationInputTableBody.innerHTML = ''; // Clear existing rows medicationData.forEach(med => { const row = document.createElement('tr'); row.innerHTML = ` `; medicationInputTableBody.appendChild(row); }); // Attach event listeners to newly created input fields and delete buttons document.querySelectorAll('.medication-input').forEach(input => { input.addEventListener('change', handleInputChange); }); document.querySelectorAll('.delete-row-btn').forEach(button => { button.addEventListener('click', handleDeleteRow); }); } /** * Updates all dashboard and management views. */ function updateViews() { renderMedicationSummary(); renderCurrentMedications(); renderMedicationInputTable(); } // --- Event Handlers --- /** * Handles tab button clicks to switch between tabs. * @param {Event} event - The click event. */ function handleTabClick(event) { // Null check for event target if (!event.target) { console.error("Event target is null."); return; } const targetTab = event.target.dataset.tab; // Remove 'active' class from all tab buttons and content tabButtons.forEach(button => button.classList.remove('active')); tabContents.forEach(content => content.classList.remove('active')); // Add 'active' class to the clicked tab button and corresponding content event.target.classList.add('active'); const activeTabContent = document.getElementById(`${targetTab}-tab`); if (activeTabContent) { // Null check for activeTabContent activeTabContent.classList.add('active'); } else { console.error(`Tab content for ${targetTab} not found.`); } updateViews(); // Update views whenever tab changes } /** * Handles changes in data input fields. * @param {Event} event - The change event. */ function handleInputChange(event) { // Null check for event target if (!event.target) { console.error("Event target is null."); return; } const input = event.target; const id = parseInt(input.dataset.id); const field = input.dataset.field; let value = input.value; const medicationIndex = medicationData.findIndex(d => d.id === id); if (medicationIndex !== -1) { medicationData[medicationIndex][field] = value; updateViews(); // Re-render tables } else { console.error(`Medication with ID ${id} not found.`); } } /** * Adds a new empty row to the medication input table. */ function handleAddMedication() { const newMedication = { id: nextId++, medicationName: 'New Medication', dosage: '', frequency: 'Once Daily', startDate: '', endDate: '', notes: '' }; medicationData.push(newMedication); updateViews(); // Re-render data input table } /** * Deletes a row from the medication input table. * @param {Event} event - The click event. */ function handleDeleteRow(event) { // Null check for event target if (!event.target) { console.error("Event target is null."); return; } const idToDelete = parseInt(event.target.dataset.id); medicationData = medicationData.filter(d => d.id !== idToDelete); updateViews(); // Re-render data input table } /** * Handles navigation to the previous tab. */ function handlePrevTab() { const currentActiveTab = document.querySelector('.tab-button.active'); if (!currentActiveTab) { console.error("No active tab found."); return; } const currentIndex = Array.from(tabButtons).indexOf(currentActiveTab); if (currentIndex > 0) { tabButtons[currentIndex - 1].click(); // Simulate click on previous tab } } /** * Handles navigation to the next tab. */ function handleNextTab() { const currentActiveTab = document.querySelector('.tab-button.active'); if (!currentActiveTab) { console.error("No active tab found."); return; } const currentIndex = Array.from(tabButtons).indexOf(currentActiveTab); if (currentIndex < tabButtons.length - 1) { tabButtons[currentIndex + 1].click(); // Simulate click on next tab } } /** * Handles the PDF download functionality. * It uses html2canvas to capture the dashboard content and jsPDF to generate the PDF. */ async function handleDownloadPdf() { const dashboardContent = document.querySelector('.dashboard-content-for-pdf'); if (!dashboardContent) { console.error("Dashboard content for PDF not found."); return; } // Add a temporary title for the PDF const tempTitle = document.createElement('h1'); tempTitle.textContent = "Medication Dashboard"; tempTitle.style.textAlign = 'center'; tempTitle.style.marginBottom = '20px'; tempTitle.style.fontSize = '2em'; tempTitle.style.fontWeight = 'bold'; tempTitle.style.color = '#333'; dashboardContent.prepend(tempTitle); // Prepend to capture // Temporarily hide tab navigation and buttons for PDF capture const elementsToHide = document.querySelectorAll('.tab-nav, .tab-navigation-buttons, .add-row-btn, .delete-row-btn, .pdf-download-section .btn-primary'); elementsToHide.forEach(el => el.style.display = 'none'); // Ensure the dashboard tab is active before capturing for PDF const dashboardTabButton = document.querySelector('.tab-button[data-tab="dashboard"]'); if (dashboardTabButton && !dashboardTabButton.classList.contains('active')) { dashboardTabButton.click(); // Activate dashboard tab if not already active // A small delay might be needed here if content takes time to render after tab switch await new Promise(resolve => setTimeout(resolve, 100)); } try { const canvas = await html2canvas(dashboardContent, { scale: 2, // Increase scale for better resolution useCORS: true, // Required if images are from different origin (though we don't use external images) windowWidth: dashboardContent.scrollWidth, windowHeight: dashboardContent.scrollHeight }); const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'portrait', unit: 'px', format: 'a4' }); const imgWidth = pdf.internal.pageSize.getWidth(); const pageHeight = pdf.internal.pageSize.getHeight(); const imgHeight = canvas.height * imgWidth / canvas.width; let heightLeft = imgHeight; let position = 0; pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; while (heightLeft >= 0) { position = heightLeft - imgHeight; pdf.addPage(); pdf.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight); heightLeft -= pageHeight; } pdf.save('medication_dashboard.pdf'); } catch (error) { console.error("Error generating PDF:", error); // Using alert as a fallback for critical error feedback, as per standard specification alert("Failed to generate PDF. Please try again."); } finally { // Restore hidden elements and remove temporary title elementsToHide.forEach(el => el.style.display = ''); if (tempTitle.parentNode) { tempTitle.parentNode.removeChild(tempTitle); } } } // --- Event Listener Attachments --- tabButtons.forEach(button => { // Null check for button if (button) { button.addEventListener('click', handleTabClick); } }); // Null checks before attaching listeners if (addMedicationBtn) { addMedicationBtn.addEventListener('click', handleAddMedication); } else { console.error("Add Medication button not found."); } if (downloadPdfBtn) { downloadPdfBtn.addEventListener('click', handleDownloadPdf); } else { console.error("Download PDF button not found."); } if (prevTabBtn) { prevTabBtn.addEventListener('click', handlePrevTab); } else { console.error("Previous Tab button not found."); } if (nextTabBtn) { nextTabBtn.addEventListener('click', handleNextTab); } else { console.error("Next Tab button not found."); } // Initial render of the dashboard and data input table updateViews(); });
Scroll to Top