// 1. CẤU TRÚC DỮ LIỆU MỚI (Bổ sung ngày mượn, ngày trả) const defaultDevices = [ { id: "EQ-2026-001", name: "MacBook Pro M3", category: "Máy tính xách tay", dept: "Phòng Công Nghệ", status: "Sử dụng", borrowDate: "", returnDate: "" }, { id: "EQ-2026-002", name: "Dell UltraSharp 27\"", category: "Màn hình", dept: "Phòng Thiết Kế", status: "Sử dụng", borrowDate: "", returnDate: "" }, { id: "EQ-2026-003", name: "Sony Alpha A7 IV", category: "Thiết bị media", dept: "Phòng Truyền Thông", status: "Bảo trì", borrowDate: "", returnDate: "" }, { id: "EQ-2026-004", name: "iPad Air 6", category: "Máy tính bảng", dept: "Ban Giám Đốc", status: "Đang mượn", borrowDate: "2026-05-15", returnDate: "2026-05-22" } ]; let devices = JSON.parse(localStorage.getItem('devices')) || defaultDevices; let filteredDevices = [...devices]; let currentPage = 1; const rowsPerPage = 5; function removeVietnameseTones(str) { return str.normalize('NFD') .replace(/[\u0300-\u036f]/g, '') .replace(/đ/g, 'd').replace(/Đ/g, 'D'); } // 2. Quản lý Đăng nhập / Đăng xuất function handleLogin(event) { event.preventDefault(); const userInput = document.getElementById('username').value; const passwordInput = document.getElementById('password').value; const errorMsg = document.getElementById('error-msg'); if (userInput === 'Admin' && passwordInput === '26092k4T') { errorMsg.style.display = 'none'; const loginScreen = document.getElementById('login-screen'); loginScreen.classList.add('hidden'); setTimeout(() => loginScreen.style.display = 'none', 400); const mainApp = document.getElementById('main-app'); mainApp.style.display = 'flex'; setTimeout(() => mainApp.classList.add('visible'), 50); sessionStorage.setItem('isLoggedIn', 'true'); handleSearchFilter(); } else { errorMsg.style.display = 'block'; } } function handleLogout() { sessionStorage.removeItem('isLoggedIn'); window.location.reload(); } function toggleMenu() { document.getElementById('sidebar').classList.toggle('open'); document.getElementById('overlay').classList.toggle('active'); } // 3. XỬ LÝ TÌM KIẾM VÀ BỘ LỌC (Cập nhật trạng thái mới) function handleSearchFilter() { const keyword = removeVietnameseTones(document.getElementById('search-box').value.toLowerCase().trim()); const statusFilter = document.getElementById('filter-status').value; filteredDevices = devices.filter(device => { const rawString = removeVietnameseTones(`${device.id} ${device.name} ${device.dept} ${device.category}`.toLowerCase()); const matchKeyword = rawString.includes(keyword); const matchStatus = (statusFilter === 'Tất cả') || (device.status === statusFilter); return matchKeyword && matchStatus; }); currentPage = 1; renderTable(); } // 4. HIỂN THỊ BẢNG (Thêm cột ngày mượn/trả và màu sắc nhãn trạng thái mới) function renderTable() { const tbody = document.getElementById('device-table-body'); tbody.innerHTML = ''; // Cập nhật thẻ thống kê mở rộng rộng hơn document.getElementById('total-count').textContent = devices.length; document.getElementById('active-count').textContent = devices.filter(d => d.status === 'Sử dụng').length; document.getElementById('maintenance-count').textContent = devices.filter(d => d.status === 'Bảo trì').length; // Nếu giao diện của bạn có thẻ hiển thị số lượng thiết bị mượn, hãy thêm dòng dưới: // document.getElementById('borrow-count').textContent = devices.filter(d => d.status === 'Đang mượn').length; const start = (currentPage - 1) * rowsPerPage; const end = start + rowsPerPage; const paginatedItems = filteredDevices.slice(start, end); if(paginatedItems.length === 0) { tbody.innerHTML = `Không tìm thấy thiết bị phù hợp`; } else { paginatedItems.forEach((device) => { // Định nghĩa class màu sắc động cho từng loại trạng thái let statusClass = 'status-active'; // Mặc định Sử dụng if (device.status === 'Bảo trì') statusClass = 'status-maintenance'; if (device.status === 'Đang mượn') statusClass = 'status-borrowed'; // Xử lý hiển thị ngày trống (nếu không mượn trả thì hiện dấu gạch ngang) const bDate = device.borrowDate ? formatDateDisplay(device.borrowDate) : '-'; const rDate = device.returnDate ? formatDateDisplay(device.returnDate) : '-'; const tr = document.createElement('tr'); tr.innerHTML = ` ${device.id} ${device.name} ${device.category} ${device.dept} ${device.status} ${bDate} ${rDate}
`; tbody.appendChild(tr); }); } setupPagination(); localStorage.setItem('devices', JSON.stringify(devices)); } // Định dạng hiển thị DD/MM/YYYY cho người dùng dễ nhìn function formatDateDisplay(dateString) { if(!dateString) return ''; const [year, month, day] = dateString.split('-'); return `${day}/${month}/${year}`; } function setupPagination() { const container = document.getElementById('pagination-zone'); container.innerHTML = ''; const pageCount = Math.ceil(filteredDevices.length / rowsPerPage); if(pageCount <= 1) return; const prevBtn = document.createElement('button'); prevBtn.className = 'page-btn'; prevBtn.textContent = '◀'; prevBtn.disabled = currentPage === 1; prevBtn.onclick = () => { currentPage--; renderTable(); }; container.appendChild(prevBtn); for(let i = 1; i <= pageCount; i++) { const btn = document.createElement('button'); btn.className = `page-btn ${i === currentPage ? 'active' : ''}`; btn.textContent = i; btn.onclick = () => { currentPage = i; renderTable(); }; container.appendChild(btn); } const nextBtn = document.createElement('button'); nextBtn.className = 'page-btn'; nextBtn.textContent = '▶'; nextBtn.disabled = currentPage === pageCount; nextBtn.onclick = () => { currentPage++; renderTable(); }; container.appendChild(nextBtn); } // 5. Quản lý Modal function openDeviceModal() { document.getElementById('modal-title').textContent = "Thêm thiết bị mới"; document.getElementById('device-form').reset(); document.getElementById('edit-id-flag').value = ""; document.getElementById('dev-id').disabled = false; document.getElementById('id-error').style.display = 'none'; toggleDateFields(); // Reset ẩn hiện trường ngày tháng document.getElementById('device-modal').classList.add('open'); } // Tự động ẩn/hiện trường nhập Ngày mượn & Ngày trả dựa theo trạng thái đang chọn function toggleDateFields() { const status = document.getElementById('dev-status').value; const dateFields = document.getElementById('date-fields-group'); if (dateFields) { if (status === 'Đang mượn') { dateFields.style.display = 'block'; // Hoặc 'grid' tùy cấu trúc CSS của bạn } else { dateFields.style.display = 'none'; // Xóa dữ liệu cũ khi không ở trạng thái mượn document.getElementById('dev-borrow-date').value = ''; document.getElementById('dev-return-date').value = ''; } } } window.onclick = function(event) { const modal = document.getElementById('device-modal'); if (event.target === modal) { closeDeviceModal(); } } function closeDeviceModal() { document.getElementById('device-modal').classList.remove('open'); } // 6. THAO TÁC LƯU (Bổ sung thu thập dữ liệu ngày mượn/trả) function saveDevice(event) { event.preventDefault(); const editIdFlag = document.getElementById('edit-id-flag').value; const inputId = document.getElementById('dev-id').value.trim(); const idError = document.getElementById('id-error'); const newDevice = { id: inputId, name: document.getElementById('dev-name').value.trim(), category: document.getElementById('dev-category').value.trim(), dept: document.getElementById('dev-dept').value.trim(), status: document.getElementById('dev-status').value, borrowDate: document.getElementById('dev-borrow-date').value, returnDate: document.getElementById('dev-return-date').value }; if (editIdFlag === "") { const isDuplicate = devices.some(d => d.id.toLowerCase() === inputId.toLowerCase()); if(isDuplicate) { idError.style.display = 'block'; return; } devices.push(newDevice); } else { const globalIndex = devices.findIndex(d => d.id === editIdFlag); if(globalIndex !== -1) { devices[globalIndex] = newDevice; } } idError.style.display = 'none'; closeDeviceModal(); handleSearchFilter(); } // 7. Chỉnh sửa thiết bị (Đổ dữ liệu ngày mượn/trả ngược lại form) function editDevice(deviceId) { const device = devices.find(d => d.id === deviceId); if(!device) return; document.getElementById('modal-title').textContent = "Chỉnh sửa thông tin thiết bị"; document.getElementById('edit-id-flag').value = device.id; document.getElementById('dev-id').value = device.id; document.getElementById('dev-id').disabled = true; document.getElementById('dev-name').value = device.name; document.getElementById('dev-category').value = device.category; document.getElementById('dev-dept').value = device.dept; document.getElementById('dev-status').value = device.status; // Đổ dữ liệu ngày tháng document.getElementById('dev-borrow-date').value = device.borrowDate || ''; document.getElementById('dev-return-date').value = device.returnDate || ''; toggleDateFields(); // Đồng bộ ẩn hiện dựa trên dữ liệu trạng thái vừa đổ vào document.getElementById('id-error').style.display = 'none'; document.getElementById('device-modal').classList.add('open'); } function deleteDevice(deviceId) { const globalIndex = devices.findIndex(d => d.id === deviceId); if (globalIndex !== -1) { if (confirm(`Bạn có chắc chắn muốn xóa thiết bị mã ${deviceId} không?`)) { devices.splice(globalIndex, 1); handleSearchFilter(); } } } window.onload = function() { if (sessionStorage.getItem('isLoggedIn') === 'true') { document.getElementById('login-screen').style.display = 'none'; const mainApp = document.getElementById('main-app'); mainApp.style.display = 'flex'; mainApp.classList.add('visible'); handleSearchFilter(); } }