Online Smart Work Anniversary Reminder System

Smart Work Anniversary Reminder System

Never miss an opportunity to celebrate your team's milestones.

🎉 Celebrating Today!

Upcoming Anniversaries

Celebrating ${emp.tenure} Years!

`).join(''); } else { todayContainer.innerHTML = `

No anniversaries today.

`; } // Render Upcoming Anniversaries Table if (upcomingAnniversaries.length > 0) { upcomingTableContainer.innerHTML = ` ${upcomingAnniversaries.map(emp => ` `).join('')}
Employee Anniversary Date Milestone
${emp.name} ${emp.nextAnniversary.toLocaleDateString('en-US', { month: 'long', day: 'numeric', year: 'numeric' })} ${emp.tenure} Years
`; } else { upcomingTableContainer.innerHTML = `

No upcoming anniversaries found.

`; } }; const renderConfigTab = () => { const empTable = document.getElementById('config-employees-table'); empTable.innerHTML = data.employees.map(emp => ` ${emp.id} `).join(''); }; // --- DATA MANIPULATION (global for inline onclick) --- window.addEmployee = () => { const nameInput = document.getElementById('new-employee-name'); const dateInput = document.getElementById('new-employee-start-date'); const messageEl = document.getElementById('add-employee-message'); if (nameInput.value && dateInput.value) { messageEl.textContent = ''; // Clear any previous error message const newId = data.employees.length > 0 ? Math.max(...data.employees.map(e => e.id)) + 1 : 1; data.employees.push({ id: newId, name: nameInput.value, startDate: dateInput.value }); nameInput.value = ''; dateInput.value = ''; fullRender(); } else { messageEl.textContent = "Employee name and start date are required."; // Clear the message after 3 seconds setTimeout(() => { messageEl.textContent = ''; }, 3000); } }; window.updateEmployee = (id, field, value) => { const employee = data.employees.find(e => e.id === id); if (employee) { employee[field] = value; fullRender(); } }; window.deleteEmployee = (id) => { data.employees = data.employees.filter(e => e.id !== id); fullRender(); }; // --- PDF DOWNLOAD --- const downloadAnniversaryReport = () => { const { jsPDF } = window.jspdf; const doc = new jsPDF(); const anniversaryData = getAnniversaryData(); doc.setFontSize(20); doc.text("Work Anniversary Report", 14, 22); doc.setFontSize(11); doc.setTextColor(100); doc.text(`Generated on: ${new Date().toLocaleDateString('en-US')}`, 14, 30); const tableData = anniversaryData.map(emp => [ emp.name, emp.nextAnniversary.toLocaleDateString('en-US'), `${emp.tenure} Years`, emp.isToday ? 'Today!' : 'Upcoming' ]); doc.autoTable({ startY: 40, head: [['Employee', 'Anniversary Date', 'Milestone', 'Status']], body: tableData, theme: 'striped', headStyles: { fillColor: [5, 150, 105] }, // Emerald-600 }); doc.save('Work-Anniversary-Report.pdf'); }; document.getElementById('download-pdf-btn').addEventListener('click', downloadAnniversaryReport); // --- TAB NAVIGATION --- const tabs = document.querySelectorAll('[role="tab"]'); const prevBtn = document.getElementById('prev-tab-btn'); const nextBtn = document.getElementById('next-tab-btn'); let currentTabIndex = 0; const switchTab = (newIndex) => { tabs.forEach((tab, index) => { const panel = document.getElementById(tab.getAttribute('aria-controls')); if (index === newIndex) { tab.classList.remove('tab-inactive'); tab.classList.add('tab-active'); if (panel) panel.classList.remove('hidden'); } else { tab.classList.remove('tab-active'); tab.classList.add('tab-inactive'); if (panel) panel.classList.add('hidden'); } }); currentTabIndex = newIndex; updateNavButtons(); }; const updateNavButtons = () => { prevBtn.disabled = currentTabIndex === 0; nextBtn.disabled = currentTabIndex === tabs.length - 1; prevBtn.classList.toggle('opacity-50', prevBtn.disabled); nextBtn.classList.toggle('opacity-50', nextBtn.disabled); }; tabs.forEach((tab, index) => tab.addEventListener('click', () => switchTab(index))); prevBtn.addEventListener('click', () => { if (currentTabIndex > 0) switchTab(currentTabIndex - 1); }); nextBtn.addEventListener('click', () => { if (currentTabIndex < tabs.length - 1) switchTab(currentTabIndex + 1); }); // --- INITIALIZATION --- const fullRender = () => { renderDashboard(); renderConfigTab(); }; fullRender(); updateNavButtons(); });
Scroll to Top