.toolbar display: flex; gap: 12px; flex-wrap: wrap; align-items: center;
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();
.status-absent background: #ffe6e5; color: #b91c1c;
/* 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; download attendance management system
button:hover background: #134b66; transform: translateY(-1px);
.status-present background: #dff9e6; color: #11734c;
// ----- event binding and initialization ----- document.addEventListener('DOMContentLoaded', () => renderAll(); // For better UX: total employees = all
// helper: update or create today's record for a specific employee function setAttendanceStatus(employeeId, newStatus) const data = loadData(); const today = getTodayDateStr(); const existingIndex = data.attendanceRecords.findIndex(rec => rec.employeeId === employeeId && rec.date === today); const newRecord = employeeId, date: today, status: newStatus, timestamp: new Date().toISOString() ; if (existingIndex !== -1) data.attendanceRecords[existingIndex] = newRecord; else data.attendanceRecords.push(newRecord); saveData(data); renderAll(); // refresh UI
/* add employee section */ .action-section background: #ffffffcc; backdrop-filter: blur(4px); border-radius: 1.6rem; padding: 1.2rem 1.6rem; margin-bottom: 28px; display: flex; flex-wrap: wrap; gap: 15px; align-items: flex-end; justify-content: space-between; border: 1px solid #ffffff;
// ---------- 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 ; const recordedEmpIds = todayRecords.map(r =>
@media (max-width: 700px) .dashboard padding: 1.2rem; .action-section flex-direction: column; align-items: stretch; .toolbar justify-content: flex-start; th, td padding: 8px 6px; </style> </head> <body>
.small-btn background: none; padding: 5px 10px; font-size: 0.7rem; box-shadow: none; background: #f0f4f9; color: #2c5a74;
.input-group input padding: 10px 14px; border-radius: 60px; border: 1px solid #cbdde9; background: white; font-size: 0.9rem; transition: 0.2s;
// compute stats based on today's records function computeStats(employees, attendanceRecords) const today = getTodayDateStr(); const todayRecords = attendanceRecords.filter(rec => rec.date === today); const presentCount = todayRecords.filter(rec => rec.status === 'present').length; const lateCount = todayRecords.filter(rec => rec.status === 'late').length; const absentCount = todayRecords.filter(rec => rec.status === 'absent').length; // employees without any record today considered absent? but we count from existing records only. // For better UX: total employees = all employees, but absent shown as those not present/late. const totalEmp = employees.length; const recordedEmpIds = todayRecords.map(r => r.employeeId); const missingEmp = employees.filter(emp => !recordedEmpIds.includes(emp.id)).length; const totalAbsentEffective = absentCount + missingEmp; return totalEmployees: totalEmp, presentToday: presentCount, lateToday: lateCount, absentToday: totalAbsentEffective ;