Volunteer Activity Log Sheet
Formal Time Tracking and Service Record
Total Logged Hours:
0.0
Volunteer Service Log
Volunteer: Volunteer Name | Organization: Organization Name
Project: Project Name | Period: MM/DD - MM/DD
Detailed Activity Record
| Date | Activity Description | Hours | Supervisor Initials |
|---|---|---|---|
| TOTAL HOURS COMPLETED | 0.0 | ||
I certify that the information recorded above is accurate and complete.
Volunteer Signature
Supervisor Name/Signature (Verification)
Generated by Volunteer Activity Log Sheet
Volunteer & Project Information
Activity Log Entry
Add detailed entries for each day or shift.
Current Activity Entries
Log is empty.
"; return; } sortedActivities.forEach(activity => { const row = document.createElement('div'); row.className = 'vtl-activity-row'; const dateFmt = formatDate(activity.date); row.innerHTML = `
[${dateFmt}] ${activity.description}
(${activity.hours.toFixed(1)} hrs)
`;
outputs.listEditor.appendChild(row);
});
}
// --- 5. EVENT LISTENERS & ACTIONS ---
function attachListeners() {
// Meta Inputs
const metaInputs = Object.values(inputs).filter(i => !i.id.includes('activity'));
metaInputs.forEach(inp => inp.addEventListener('input', renderAll));
// Add Activity Button
document.getElementById('btn-add-activity').addEventListener('click', addActivity);
}
function addActivity() {
const date = inputs.activityDate.value;
const hours = parseFloat(inputs.activityHours.value) || 0;
const description = inputs.activityDesc.value.trim();
if (!date || hours <= 0 || !description) {
alert("Please enter a Date, Description, and Hours greater than 0.");
return;
}
const newActivity = {
id: Date.now(),
date: date,
hours: hours,
description: description
};
vtlData.activities.push(newActivity);
// Clear inputs
inputs.activityHours.value = "";
inputs.activityDesc.value = "";
renderAll();
}
window.removeActivity = function(id) {
if(confirm("Remove this activity entry?")) {
vtlData.activities = vtlData.activities.filter(a => a.id !== id);
renderAll();
}
};
// --- 6. TAB NAVIGATION ---
window.vtlSwitchTab = function(tabId) {
document.querySelectorAll('.vtl-tab-pane').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.vtl-tab-btn').forEach(b => b.classList.remove('active'));
document.getElementById(tabId).classList.add('active');
document.querySelector(`.vtl-tab-btn[data-tab="${tabId}"]`).classList.add('active');
document.getElementById('volunteer-log-tool').scrollIntoView({behavior: 'smooth'});
};
document.querySelectorAll('.vtl-tab-btn').forEach(btn => {
btn.addEventListener('click', function() { vtlSwitchTab(this.dataset.tab); });
});
// --- 7. PDF EXPORT ---
const btnDown = document.getElementById('vtl-download-btn');
if(btnDown) {
btnDown.addEventListener('click', function() {
renderAll();
const element = document.getElementById('vtl-render-area');
const filename = (inputs.volunteerName.value || 'Volunteer_Log').replace(/\s+/g,'_');
const opt = {
margin: 0.4,
filename: `${filename}_Activity_Log.pdf`,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, useCORS: true },
jsPDF: { unit: 'in', format: 'letter', orientation: 'portrait' }
};
const origText = btnDown.innerText;
btnDown.innerText = "Generating Log...";
html2pdf().set(opt).from(element).save().then(() => {
btnDown.innerText = origText;
});
});
}
// Start
init();
});
