Download — Attendance Management System
// simple escape for XSS safety function escapeHtml(str) if (!str) return ''; return str.replace(/[&<>]/g, function(m) if (m === '&') return '&'; if (m === '<') return '<'; if (m === '>') return '>'; return m; ).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, function(c) return c; );
// Data model: employees: [ id, name, createdAt ], attendanceRecords: [ employeeId, date, status, timestamp ] // We'll also keep a convenience "today" YYYY-MM-DD logic. function getTodayDateStr() const today = new Date(); return today.toISOString().split('T')[0];
function deleteEmployee(employeeId) let data = loadData(); // remove employee data.employees = data.employees.filter(emp => emp.id !== employeeId); // remove all attendance records for this employee data.attendanceRecords = data.attendanceRecords.filter(rec => rec.employeeId !== employeeId); saveData(data); renderAll();
// attach event listeners after rendering document.querySelectorAll('.mark-present').forEach(btn => btn.addEventListener('click', (e) => const empId = btn.getAttribute('data-id'); setAttendanceStatus(empId, 'present'); ); ); document.querySelectorAll('.mark-late').forEach(btn => btn.addEventListener('click', () => const empId = btn.getAttribute('data-id'); setAttendanceStatus(empId, 'late'); ); ); document.querySelectorAll('.mark-absent').forEach(btn => btn.addEventListener('click', () => const empId = btn.getAttribute('data-id'); setAttendanceStatus(empId, 'absent'); ); ); document.querySelectorAll('.delete-emp').forEach(btn => btn.addEventListener('click', () => const empId = btn.getAttribute('data-id'); if (confirm(`Delete employee $empId and all their attendance history?`)) deleteEmployee(empId); ); ); download attendance management system
.btn-warning background: #d97706; .btn-warning:hover background: #b45309;
.input-group input padding: 10px 14px; border-radius: 60px; border: 1px solid #cbdde9; background: white; font-size: 0.9rem; transition: 0.2s;
// ---------- EXPORT FUNCTIONS: CSV / JSON (full attendance + employees) ---------- function generateFullReportData() const data = loadData(); const employees, attendanceRecords = data; // enrich each attendance record with employee name const enriched = attendanceRecords.map(rec => const emp = employees.find(e => e.id === rec.employeeId); return employeeId: rec.employeeId, employeeName: emp ? emp.name : 'Unknown', date: rec.date, status: rec.status, timestamp: rec.timestamp ; ); return employees, attendanceDetails: enriched ; // simple escape for XSS safety function escapeHtml(str)
.status-present background: #dff9e6; color: #11734c;
function loadData() const raw = localStorage.getItem(STORAGE_KEY); if (!raw) // initial demo dataset return getDefaultData(); try !data.attendanceRecords) throw new Error("corrupted"); return data; catch(e) console.warn("invalid data, resetting"); return getDefaultData();
/* table container */ .table-wrapper overflow-x: auto; border-radius: 1.5rem; background: white; box-shadow: 0 6px 14px rgba(0,0,0,0.05); margin-top: 15px; if (m === '<
table width: 100%; border-collapse: collapse; font-size: 0.85rem;
.btn-outline background: transparent; border: 1.5px solid #1f5e7e; color: #1f5e7e;
// reset to demo dataset (keep same structure) function resetToDemo() const defaultData = getDefaultData(); saveData(defaultData); renderAll();
const row = document.createElement('tr'); row.innerHTML = ` <td style="font-family: monospace;">$escapeHtml(emp.id)</td> <td class="employee-name">$escapeHtml(emp.name)</td> <td><span class="status-badge $badgeClass">$statusDisplay</span></td> <td style="font-size:0.75rem; color:#4b6f8c;">$timeStr</td> <td class="action-btns"> <button class="small-btn mark-present" data-id="$emp.id" data-status="present">✅ Present</button> <button class="small-btn mark-late" data-id="$emp.id" data-status="late">⏰ Late</button> <button class="small-btn mark-absent" data-id="$emp.id" data-status="absent">❌ Absent</button> <button class="small-btn delete-emp" data-id="$emp.id" style="background:#fbe9e7; color:#b91c1c;">🗑️ Del</button> </td> `; tbody.appendChild(row); );
<!-- Add employee section --> <div class="action-section"> <div class="input-group"> <label>👤 Employee Name</label> <input type="text" id="empNameInput" placeholder="e.g., Olivia Chen" autocomplete="off"> </div> <div class="input-group"> <label>🆔 Employee ID (unique)</label> <input type="text" id="empIdInput" placeholder="EMP-001" autocomplete="off"> </div> <button id="addEmployeeBtn">➕ Add Employee</button> <div class="toolbar"> <button id="downloadCsvBtn" class="btn-outline">📎 Download CSV</button> <button id="downloadJsonBtn" class="btn-outline">📄 Download JSON</button> <button id="resetDemoBtn" class="btn-warning">🔄 Reset Demo Data</button> </div> </div>