Spaces:
Running
Running
| // Sample employee data | |
| let employees = [ | |
| { id: 1, name: 'John Doe', position: 'Software Engineer', department: 'IT', avatar: 'http://static.photos/technology/200x200/1' }, | |
| { id: 2, name: 'Jane Smith', position: 'HR Manager', department: 'Human Resources', avatar: 'http://static.photos/office/200x200/2' }, | |
| { id: 3, name: 'Robert Johnson', position: 'Accountant', department: 'Finance', avatar: 'http://static.photos/finance/200x200/3' }, | |
| { id: 4, name: 'Emily Davis', position: 'Marketing Specialist', department: 'Marketing', avatar: 'http://static.photos/retail/200x200/4' }, | |
| { id: 5, name: 'Michael Brown', position: 'Operations Manager', department: 'Operations', avatar: 'http://static.photos/industry/200x200/5' }, | |
| ]; | |
| let selectedEmployees = []; | |
| let currentPayPeriod = 'January 1-15, 2023'; | |
| let currentDepartment = 'All Departments'; | |
| // Sample DTR data with Philippine format | |
| const dtrData = [ | |
| { | |
| date: '2023-01-01', | |
| day: 'Sunday', | |
| amIn: '--', | |
| amOut: '--', | |
| pmIn: '--', | |
| pmOut: '--', | |
| tardiness: '0.00', | |
| undertime: '0.00', | |
| overtime: '0.00', | |
| totalHours: '0.0', | |
| status: 'Rest Day' | |
| }, | |
| { | |
| date: '2023-01-02', | |
| day: 'Monday', | |
| amIn: '08:15 AM', | |
| amOut: '12:00 PM', | |
| pmIn: '01:00 PM', | |
| pmOut: '05:15 PM', | |
| tardiness: '0.25', | |
| undertime: '0.00', | |
| overtime: '0.00', | |
| totalHours: '8.0', | |
| status: 'Present' | |
| }, | |
| { | |
| date: '2023-01-03', | |
| day: 'Tuesday', | |
| amIn: '08:00 AM', | |
| amOut: '12:00 PM', | |
| pmIn: '01:00 PM', | |
| pmOut: '06:30 PM', | |
| tardiness: '0.00', | |
| undertime: '0.00', | |
| overtime: '1.50', | |
| totalHours: '9.5', | |
| status: 'Present' | |
| }, | |
| { | |
| date: '2023-01-04', | |
| day: 'Wednesday', | |
| amIn: '08:45 AM', | |
| amOut: '12:00 PM', | |
| pmIn: '01:00 PM', | |
| pmOut: '04:30 PM', | |
| tardiness: '0.75', | |
| undertime: '0.50', | |
| overtime: '0.00', | |
| totalHours: '7.0', | |
| status: 'Present' | |
| }, | |
| { | |
| date: '2023-01-05', | |
| day: 'Thursday', | |
| amIn: '--', | |
| amOut: '--', | |
| pmIn: '--', | |
| pmOut: '--', | |
| tardiness: '0.00', | |
| undertime: '0.00', | |
| overtime: '0.00', | |
| totalHours: '0.0', | |
| status: 'Absent' | |
| }, | |
| ]; | |
| // Load employees into the list with search and filter | |
| function loadEmployees() { | |
| const employeeList = document.querySelector('.w-full.md\\:w-1\\/3 .space-y-3'); | |
| employeeList.innerHTML = ''; | |
| const searchInput = document.querySelector('input[type="text"]'); | |
| const searchTerm = searchInput.value.toLowerCase(); | |
| const filteredEmployees = employees.filter(employee => { | |
| const matchesSearch = employee.name.toLowerCase().includes(searchTerm) || | |
| employee.position.toLowerCase().includes(searchTerm) || | |
| employee.department.toLowerCase().includes(searchTerm); | |
| const matchesDepartment = currentDepartment === 'All Departments' || | |
| employee.department === currentDepartment; | |
| return matchesSearch && matchesDepartment; | |
| }); | |
| filteredEmployees.forEach(employee => { | |
| const isSelected = selectedEmployees.some(e => e.id === employee.id); | |
| const employeeCard = document.createElement('div'); | |
| employeeCard.className = `employee-card bg-white p-4 rounded-lg border ${isSelected ? 'border-blue-500 bg-blue-50' : 'border-gray-200'} hover:border-blue-300 hover:shadow-sm transition-all cursor-pointer`; | |
| employeeCard.dataset.id = employee.id; | |
| employeeCard.innerHTML = ` | |
| <div class="flex items-center gap-4"> | |
| <img src="${employee.avatar}" alt="${employee.name}" class="w-12 h-12 rounded-full object-cover"> | |
| <div> | |
| <h3 class="font-medium text-gray-800">${employee.name}</h3> | |
| <p class="text-sm text-gray-500">${employee.position} • ${employee.department}</p> | |
| </div> | |
| <button class="ml-auto text-blue-500 hover:text-blue-700"> | |
| <i data-feather="${isSelected ? 'check-circle' : 'plus-circle'}" class="w-5 h-5"></i> | |
| </button> | |
| </div> | |
| `; | |
| employeeList.appendChild(employeeCard); | |
| }); | |
| updateSelectedEmployeesList(); | |
| feather.replace(); | |
| } | |
| // Update selected employees list | |
| function updateSelectedEmployeesList() { | |
| const selectedContainer = document.querySelector('.bg-gray-100.rounded-lg.p-4 .flex'); | |
| selectedContainer.innerHTML = ''; | |
| selectedEmployees.forEach(employee => { | |
| const chip = document.createElement('div'); | |
| chip.className = 'bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm flex items-center gap-1'; | |
| chip.innerHTML = ` | |
| ${employee.name} | |
| <button class="text-blue-500 hover:text-blue-700" data-id="${employee.id}"> | |
| <i data-feather="x" class="w-3 h-3"></i> | |
| </button> | |
| `; | |
| selectedContainer.appendChild(chip); | |
| }); | |
| feather.replace(); | |
| } | |
| // Load DTR data into the table | |
| function loadDTRData() { | |
| const dtrTableBody = document.querySelector('table tbody'); | |
| dtrTableBody.innerHTML = ''; | |
| // Only show data if employees are selected | |
| if (selectedEmployees.length === 0) { | |
| const row = document.createElement('tr'); | |
| row.innerHTML = `<td colspan="11" class="py-4 text-center text-gray-500">Select employees to view their DTR</td>`; | |
| dtrTableBody.appendChild(row); | |
| return; | |
| } | |
| dtrData.forEach(record => { | |
| const row = document.createElement('tr'); | |
| row.className = 'hover:bg-gray-50'; | |
| row.innerHTML = ` | |
| <td class="py-3 px-4">${record.date}</td> | |
| <td class="py-3 px-4">${record.day}</td> | |
| <td class="py-3 px-4">${record.amIn}</td> | |
| <td class="py-3 px-4">${record.amOut}</td> | |
| <td class="py-3 px-4">${record.pmIn}</td> | |
| <td class="py-3 px-4">${record.pmOut}</td> | |
| <td class="py-3 px-4">${record.tardiness}</td> | |
| <td class="py-3 px-4">${record.undertime}</td> | |
| <td class="py-3 px-4">${record.overtime}</td> | |
| <td class="py-3 px-4">${record.totalHours}</td> | |
| <td class="py-3 px-4"> | |
| <span class="px-2 py-1 rounded-full text-xs ${ | |
| record.status === 'Present' ? 'bg-green-100 text-green-800' : | |
| record.status === 'Absent' ? 'bg-red-100 text-red-800' : | |
| 'bg-yellow-100 text-yellow-800' | |
| }"> | |
| ${record.status} | |
| </span> | |
| </td> | |
| `; | |
| dtrTableBody.appendChild(row); | |
| }); | |
| } | |
| // Event listeners for interactive elements | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // Search functionality | |
| document.querySelector('input[type="text"]').addEventListener('input', loadEmployees); | |
| // Pay period dropdown | |
| document.querySelector('select:nth-of-type(1)').addEventListener('change', function() { | |
| currentPayPeriod = this.value; | |
| loadDTRData(); | |
| }); | |
| // Department dropdown | |
| document.querySelector('select:nth-of-type(2)').addEventListener('change', function() { | |
| currentDepartment = this.value; | |
| loadEmployees(); | |
| }); | |
| // Add employee button | |
| document.querySelector('.bg-blue-500').addEventListener('click', function() { | |
| // In a real app, this would open a modal for adding a new employee | |
| alert('Add employee functionality would go here'); | |
| }); | |
| // Generate DTR button | |
| document.querySelector('.mt-6 .bg-blue-500').addEventListener('click', function() { | |
| if (selectedEmployees.length === 0) { | |
| alert('Please select at least one employee'); | |
| return; | |
| } | |
| // In a real app, this would generate and download the DTR | |
| alert(`Generating DTR for ${selectedEmployees.length} employees for ${currentPayPeriod}`); | |
| }); | |
| // Cancel button | |
| document.querySelector('.mt-6 .border-gray-300').addEventListener('click', function() { | |
| selectedEmployees = []; | |
| loadEmployees(); | |
| loadDTRData(); | |
| }); | |
| // Employee selection | |
| document.addEventListener('click', function(e) { | |
| // Employee card click | |
| if (e.target.closest('.employee-card')) { | |
| const card = e.target.closest('.employee-card'); | |
| const employeeId = parseInt(card.dataset.id); | |
| const employee = employees.find(e => e.id === employeeId); | |
| const index = selectedEmployees.findIndex(e => e.id === employeeId); | |
| if (index === -1) { | |
| selectedEmployees.push(employee); | |
| } else { | |
| selectedEmployees.splice(index, 1); | |
| } | |
| loadEmployees(); | |
| loadDTRData(); | |
| } | |
| // Remove selected employee chip | |
| if (e.target.closest('.bg-blue-100 button')) { | |
| const button = e.target.closest('button'); | |
| const employeeId = parseInt(button.dataset.id); | |
| selectedEmployees = selectedEmployees.filter(e => e.id !== employeeId); | |
| loadEmployees(); | |
| loadDTRData(); | |
| } | |
| }); | |
| }); | |