test1 / index.html
huylaughmad's picture
Upload 37 files
17bca00 verified
<!DOCTYPE html>
<html lang="vi">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Nha Khoa TTL - Hệ Thống Quản Lý Công Việc</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<script src="https://www.gstatic.com/firebasejs/9.6.0/firebase-app-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.6.0/firebase-firestore-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.6.0/firebase-auth-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.6.0/firebase-database-compat.js"></script>
<script src="https://www.gstatic.com/firebasejs/9.6.0/firebase-storage-compat.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/locale/vi.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<style>
/* Custom styles for better scrollbar and modal backdrop */
/* Desktop layout */
@media (min-width: 768px) {
body {
display: flex; /* Use flexbox for desktop layout */
}
}
body {
height: 100vh;
position: relative;
background-color: #f3f4f6; /* Light gray background */
}
/* Ẩn tất cả section */
.content-section {
display: none;
}
/* Chỉ show section được gắn .active */
.content-section.active,
.content-section:target { /* :target để hỗ trợ deep linking ban đầu nếu có */
display: block;
}
.modal {
display: none; /* Hidden by default */
position: fixed; /* Stay in place */
z-index: 1000; /* Sit on top */
left: 0;
top: 0;
width: 100%; /* Full width */
height: 100%; /* Full height */
overflow: auto; /* Enable scroll if needed */
background-color: rgba(0,0,0,0.5); /* Black w/ opacity */
justify-content: center; /* Center content horizontally */
align-items: center; /* Center content vertically */
padding: 1rem; /* Add some padding for smaller screens */
}
#confirmModal {
z-index: 1050; /* Ensure confirm modal is always on top of other modals */
}
.modal-content {
background-color: #fefefe;
margin: auto;
padding: 2rem;
border-radius: 0.5rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
width: 90%; /* Responsive width */
max-width: 500px; /* Max width for larger screens */
}
@media (min-width: 768px) {
.modal-content {
width: 50%;
}
}
/* Custom scrollbar for kanban columns */
.kanban-column {
max-height: calc(100vh - 250px); /* Adjust based on header/footer height */
overflow-y: auto;
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
}
.kanban-column::-webkit-scrollbar {
display: none; /* Chrome, Safari, Opera*/
}
.dropdown-menu {
display: none;
}
.dropdown:hover .dropdown-menu {
display: block;
}
.admin-only {
display: none;
}
</style>
</head>
<body class="bg-gray-50">
<div id="react-sidebar-root">
</div>
<div class="flex h-screen overflow-hidden" id="main-content">
<div class="flex flex-col flex-1 overflow-hidden">
<div class="flex items-center justify-between h-16 px-6 bg-white border-b border-gray-200">
<button id="mobile-menu-button" class="md:hidden text-gray-500 focus:outline-none">
<i class="fas fa-bars"></i>
</button>
<div class="flex-1 max-w-md ml-4 md:ml-6">
<div class="relative">
<div class="absolute inset-y-0 left-0 flex items-center pl-3 pointer-events-none">
<i class="fas fa-search text-gray-400"></i>
</div>
<input class="block w-full py-2 pl-10 pr-3 text-sm bg-gray-100 border border-transparent rounded-md focus:bg-white focus:border-gray-300 focus:ring-0" placeholder="Tìm kiếm công việc, nhân viên...">
</div>
</div>
<div class="flex items-center">
<div class="relative mr-4 dropdown">
<button class="flex items-center px-3 py-1 text-sm font-medium text-gray-700 bg-gray-100 rounded-md hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500">
<i class="mr-2 fas fa-plus"></i> Tạo mới
</button>
<div class="absolute right-0 z-50 hidden w-48 py-1 mt-2 bg-white rounded-md shadow-lg dropdown-menu">
<a href="#" id="create-task-btn-top" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Công việc mới</a>
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Cuộc họp</a>
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Báo cáo</a>
</div>
</div>
<button class="relative p-1 text-gray-400 rounded-full hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500">
<span class="sr-only">Thông báo</span>
<i class="fas fa-bell"></i>
<span class="absolute top-0 right-0 w-2 h-2 bg-red-500 rounded-full notification-badge"></span>
</button>
<button class="relative p-1 ml-4 text-gray-400 rounded-full hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-blue-500">
<span class="sr-only">Tin nhắn</span>
<i class="fas fa-envelope"></i>
<span class="absolute top-0 right-0 w-2 h-2 bg-blue-500 rounded-full notification-badge"></span>
</button>
<div class="relative ml-4 dropdown">
<button class="flex items-center max-w-xs text-sm rounded-full focus:outline-none focus:ring-2 focus:ring-blue-500">
<span class="sr-only">Mở menu người dùng</span>
<img id="user-dropdown-avatar" class="w-8 h-8 rounded-full" src="https://ui-avatars.com/api/?name=User&background=3b82f6&color=fff" alt="User">
</button>
<div class="absolute right-0 z-50 hidden w-48 py-1 mt-2 bg-white rounded-md shadow-lg dropdown-menu">
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Hồ sơ</a>
<a href="#" id="changePasswordBtn" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Đổi mật khẩu</a>
<a href="#" id="logoutButton" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Đăng xuất</a>
</div>
</div>
</div>
</div>
<div class="flex-1 overflow-auto p-6 bg-gray-50">
<div id="dashboard-section" class="content-section active">
<div class="flex flex-col mb-6 md:flex-row md:items-center md:justify-between">
<div>
<h1 class="text-2xl font-bold text-gray-900">Dashboard</h1>
<p class="text-gray-600">Tổng quan công việc và hiệu suất toàn hệ thống</p>
</div>
<div class="mt-4 md:mt-0">
<select class="text-sm border-gray-300 rounded-md focus:border-blue-500 focus:ring-blue-500">
<option>Hôm nay</option>
<option>Tuần này</option>
<option>Tháng này</option>
<option>Quý này</option>
</select>
</div>
</div>
<div class="grid grid-cols-1 gap-6 mb-6 sm:grid-cols-2 lg:grid-cols-4" id="stats-cards-container">
<div class="p-6 bg-white rounded-lg shadow">
<div class="flex items-center">
<div class="p-3 bg-blue-100 rounded-full">
<i class="text-blue-600 fas fa-tasks"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Tổng công việc</p>
<p id="totalTasks" class="text-2xl font-semibold text-gray-900">0</p>
<p class="text-xs text-gray-500 mt-1"><span class="text-green-500">+0%</span> so với tuần trước</p>
</div>
</div>
</div>
<div class="p-6 bg-white rounded-lg shadow">
<div class="flex items-center">
<div class="p-3 bg-green-100 rounded-full">
<i class="text-green-600 fas fa-check-circle"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Đã hoàn thành</p>
<p id="completedTasks" class="text-2xl font-semibold text-gray-900">0</p>
<p class="text-xs text-gray-500 mt-1"><span class="text-green-500">+0%</span> hiệu suất</p>
</div>
</div>
</div>
<div class="p-6 bg-white rounded-lg shadow">
<div class="flex items-center">
<div class="p-3 bg-yellow-100 rounded-full">
<i class="text-yellow-600 fas fa-exclamation-circle"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Đang chờ</p>
<p id="pendingTasks" class="text-2xl font-semibold text-gray-900">0</p>
<p class="text-xs text-gray-500 mt-1"><span class="text-red-500">-0%</span> so với tuần trước</p>
</div>
</div>
</div>
<div class="p-6 bg-white rounded-lg shadow">
<div class="flex items-center">
<div class="p-3 bg-red-100 rounded-full">
<i class="text-red-600 fas fa-clock"></i>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Quá hạn</p>
<p id="overdueTasks" class="text-2xl font-semibold text-gray-900">0</p>
<p class="text-xs text-gray-500 mt-1"><span class="text-green-500">-0%</span> so với tuần trước</p>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-1 gap-6 lg:grid-cols-3">
<div class="lg:col-span-2">
<div class="p-6 mb-6 bg-white rounded-lg shadow">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-medium text-gray-900">Trạng thái công việc theo phòng ban</h2>
<select class="text-sm border-gray-300 rounded-md focus:border-blue-500 focus:ring-blue-500">
<option>Tuần này</option>
<option>Tháng này</option>
<option>Quý này</option>
</select>
</div>
<div class="chart-container" style="height: 300px;">
<canvas id="taskStatusByDepartmentChart"></canvas>
</div>
</div>
<div class="p-6 bg-white rounded-lg shadow">
<div class="flex items-center justify-between mb-4">
<h2 class="text-lg font-medium text-gray-900">Hiệu suất phòng ban</h2>
<a href="#" class="text-sm font-medium text-blue-600 hover:text-blue-500">Xem chi tiết</a>
</div>
<div id="departmentPerformanceList" class="space-y-4">
</div>
</div>
</div>
<div>
<div class="p-6 mb-6 bg-white rounded-lg shadow">
<h2 class="text-lg font-medium text-gray-900 mb-4">Giao việc nhanh</h2>
<form id="quick-assign-form">
<div class="mb-4">
<label for="assign-department" class="block text-sm font-medium text-gray-700 mb-1">Phòng ban</label>
<select id="assign-department" class="block w-full text-sm border-gray-300 rounded-md focus:border-blue-500 focus:ring-blue-500">
<option value="">Chọn phòng ban</option>
</select>
</div>
<div class="mb-4">
<label for="assign-employee" class="block text-sm font-medium text-gray-700 mb-1">Nhân viên</label>
<select id="assign-employee" class="block w-full text-sm border-gray-300 rounded-md focus:border-blue-500 focus:ring-blue-500">
<option value="">Chọn nhân viên</option>
</select>
</div>
<div class="mb-4">
<label for="assign-task-title" class="block text-sm font-medium text-gray-700 mb-1">Công việc</label>
<input type="text" id="assign-task-title" class="block w-full text-sm border-gray-300 rounded-md focus:border-blue-500 focus:ring-blue-500" placeholder="Mô tả công việc" required>
</div>
<div class="mb-4">
<label for="assign-due-date" class="block text-sm font-medium text-gray-700 mb-1">Hạn chót</label>
<input type="date" id="assign-due-date" class="block w-full text-sm border-gray-300 rounded-md focus:border-blue-500 focus:ring-blue-500" required>
</div>
<button type="submit" class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
Giao việc
</button>
</form>
</div>
<div class="p-6 bg-white rounded-lg shadow">
<h2 class="text-lg font-medium text-gray-900 mb-4">Hoạt động gần đây</h2>
<div id="recentActivitiesList" class="space-y-4">
</div>
<a href="#" class="block mt-4 text-sm font-medium text-blue-600 hover:text-blue-500 text-center">Xem tất cả</a>
</div>
</div>
</div>
<div class="mt-8">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-bold text-gray-900">Bảng Kanban Công việc (Tổng quan)</h2>
<div class="flex space-x-2">
<button class="px-3 py-1 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
<i class="fas fa-plus mr-1"></i> Tạo công việc
</button>
</div>
</div>
</div>
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-4" id="kanban-board-dashboard">
<div id="todoTasks-dashboard" class="p-4 bg-gray-100 rounded-lg kanban-column">
<div class="flex items-center justify-between mb-4">
<h3 class="font-medium text-gray-700">Cần làm</h3>
<span id="todo-count-dashboard" class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-200 rounded-full">0</span>
</div>
<div id="kanban-todo-dashboard" class="space-y-4">
</div>
</div>
<div id="inProgressTasks-dashboard" class="p-4 bg-gray-100 rounded-lg kanban-column">
<div class="flex items-center justify-between mb-4">
<h3 class="font-medium text-gray-700">Đang thực hiện</h3>
<span id="in-progress-count-dashboard" class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-200 rounded-full">0</span>
</div>
<div id="kanban-in-progress-dashboard" class="space-y-4">
</div>
</div>
<div id="reviewTasks-dashboard" class="p-4 bg-gray-100 rounded-lg kanban-column">
<div class="flex items-center justify-between mb-4">
<h3 class="font-medium text-gray-700">Chờ xét duyệt</h3>
<span id="review-count-dashboard" class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-200 rounded-full">0</span>
</div>
<div id="kanban-review-dashboard" class="space-y-4">
</div>
</div>
<div id="completedTasksBoard-dashboard" class="p-4 bg-gray-100 rounded-lg kanban-column">
<div class="flex items-center justify-between mb-4">
<h3 class="font-medium text-gray-700">Hoàn thành</h3>
<span id="done-count-dashboard" class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-200 rounded-full">0</span>
</div>
<div id="kanban-done-dashboard" class="space-y-4">
</div>
</div>
</div>
<div class="mt-8">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-bold text-gray-900">Đánh giá hiệu suất nhân viên</h2>
<select class="text-sm border-gray-300 rounded-md focus:border-blue-500 focus:ring-blue-500">
<option>Tháng 10/2023</option>
<option>Tháng 9/2023</option>
<option>Tháng 8/2023</option>
</select>
</div>
<div class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
<div class="p-6 bg-white rounded-lg shadow department-card">
<div class="flex flex-col items-center">
<img class="w-16 h-16 rounded-full mb-3" src="https://ui-avatars.com/api/?name=Nguyễn+Văn+A&background=3b82f6&color=fff" alt="User">
<h3 class="text-lg font-medium text-gray-900">Nguyễn Văn A</h3>
<p class="text-sm text-gray-500 mb-4">Quản lý kho</p>
<div class="relative performance-meter" style="width: 100px; height: 100px;">
<svg class="w-full h-full" viewBox="0 0 36 36">
<path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
fill="none" stroke="#eee" stroke-width="3" stroke-dasharray="100, 100" />
<path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
fill="none" stroke="#3b82f6" stroke-width="3" stroke-dasharray="85, 100" />
</svg>
<div class="absolute inset-0 flex items-center justify-center">
<span class="text-2xl font-bold text-gray-900">85%</span>
</div>
</div>
<div class="mt-4 text-center">
<p class="text-sm text-gray-500">Hoàn thành: <span class="font-medium text-gray-900">17/20</span> công việc</p>
<p class="text-sm text-gray-500">Đúng hạn: <span class="font-medium text-gray-900">15</span> công việc</p>
</div>
</div>
</div>
<div class="p-6 bg-white rounded-lg shadow department-card">
<div class="flex flex-col items-center">
<img class="w-16 h-16 rounded-full mb-3" src="https://ui-avatars.com/api/?name=Trần+Thị+B&background=10b981&color=fff" alt="User">
<h3 class="text-lg font-medium text-gray-900">Trần Thị B</h3>
<p class="text-sm text-gray-500 mb-4">Kế toán</p>
<div class="relative performance-meter" style="width: 100px; height: 100px;">
<svg class="w-full h-full" viewBox="0 0 36 36">
<path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
fill="none" stroke="#eee" stroke-width="3" stroke-dasharray="100, 100" />
<path d="M18 2.0845 a 15.9155 15.9155 0 0 1 0 31.831 a 15.9155 15.9155 0 0 1 0 -31.831"
fill="none" stroke="#10b981" stroke-width="3" stroke-dasharray="92, 100" />
</svg>
<div class="absolute inset-0 flex items-center justify-center">
<span class="text-2xl font-bold text-gray-900">92%</span>
</div>
</div>
<div class="mt-4 text-center">
<p class="text-sm text-gray-500">Hoàn thành: <span class="font-medium text-gray-900">23/25</span> công việc</p>
<p class="text-sm text-gray-500">Đúng hạn: <span class="font-medium text-gray-900">22</span> công việc</p>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="tasks-section" class="content-section">
<div class="mt-8">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-bold text-gray-900">Bảng Kanban Công việc</h2>
<div class="flex space-x-2">
<button id="openAddTaskModal" class="px-3 py-1 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500">
<i class="fas fa-plus mr-1"></i> Tạo công việc
</button>
<button id="filterTasksBtn" class="px-3 py-1 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-blue-500">
<i class="fas fa-filter mr-1"></i> Lọc
</button>
</div>
</div>
</div>
<div class="grid grid-cols-1 gap-6 md:grid-cols-2 lg:grid-cols-4" id="kanban-board">
<div id="todoTasks" class="p-4 bg-gray-100 rounded-lg kanban-column">
<div class="flex items-center justify-between mb-4" id="kanban-todo-tasks-header">
<h3 class="font-medium text-gray-700">Cần làm</h3>
<span id="todo-count" class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-200 rounded-full">0</span>
</div>
<div id="kanban-todo" class="space-y-4">
</div>
</div>
<div id="inProgressTasks" class="p-4 bg-gray-100 rounded-lg kanban-column">
<div class="flex items-center justify-between mb-4" id="kanban-in-progress-tasks-header">
<h3 class="font-medium text-gray-700">Đang thực hiện</h3>
<span id="in-progress-count" class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-200 rounded-full">0</span>
</div>
<div id="kanban-in-progress" class="space-y-4">
</div>
</div>
<div id="reviewTasks" class="p-4 bg-gray-100 rounded-lg kanban-column">
<div class="flex items-center justify-between mb-4" id="kanban-review-tasks-header">
<h3 class="font-medium text-gray-700">Chờ xét duyệt</h3>
<span id="review-count" class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-200 rounded-full">0</span>
</div>
<div id="kanban-review" class="space-y-4">
</div>
</div>
<div id="completedTasksBoard" class="p-4 bg-gray-100 rounded-lg kanban-column">
<div class="flex items-center justify-between mb-4" id="kanban-done-tasks-header">
<h3 class="font-medium text-gray-700">Hoàn thành</h3>
<span id="done-count" class="px-2 py-1 text-xs font-medium text-gray-700 bg-gray-200 rounded-full">0</span>
</div>
<div id="kanban-done" class="space-y-4">
</div>
</div>
</div>
</div>
<div id="personnel-section" class="content-section">
<div class="mt-8">
<div class="flex items-center justify-between mb-6">
<h2 class="text-xl font-bold text-gray-900">Quản lý Nhân sự</h2>
<select class="text-sm border-gray-300 rounded-md focus:border-blue-500 focus:ring-blue-500">
<option>Tháng 10/2023</option>
<option>Tháng 9/2023</option>
<option>Tháng 8/2023</option>
</select>
</div>
<div id="employeePerformanceList" class="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-4">
</div>
</div>
<div id="users-list-container" class="mt-8">
<h2 class="text-xl font-bold text-gray-900 mb-4">Danh sách Người dùng (<span id="totalUsers">0</span>)</h2>
<div class="flex justify-end mb-4 admin-only"> <button id="openAddUserModal" class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition duration-200">
<i class="fas fa-user-plus mr-2"></i> Thêm người dùng mới
</button>
</div>
<div class="p-6 bg-white rounded-lg shadow">
<ul id="usersList" class="divide-y divide-gray-200">
</ul>
</div>
</div>
</div>
<div id="departments-section" class="content-section">
<div class="mt-8">
<h2 class="text-2xl font-bold text-gray-900 mb-4">Quản lý Phòng ban</h2>
<div class="flex justify-end mb-4 admin-only"> <button id="openAddDepartmentModal" class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition duration-200">
<i class="fas fa-plus mr-2"></i> Thêm phòng ban mới
</button>
</div>
<div class="p-6 bg-white rounded-lg shadow">
<h3 class="text-lg font-medium text-gray-900 mb-4">Danh sách Phòng ban</h3>
<ul id="departmentsList" class="divide-y divide-gray-200">
</ul>
</div>
</div>
</div>
<div id="reports-section" class="content-section">
<h1 class="text-2xl font-bold text-gray-900 mb-4">Báo cáo & Thống kê</h1>
<p class="text-gray-600 mb-6">Tổng hợp các báo cáo hiệu suất và hoạt động.</p>
<div class="p-6 bg-white rounded-lg shadow">
<h3 class="text-lg font-medium text-gray-900 mb-4">Báo cáo tổng quan</h3>
<p class="text-gray-700">Nội dung báo cáo sẽ được hiển thị tại đây.</p>
</div>
</div>
<div id="calendar-section" class="content-section">
<h1 class="text-2xl font-bold text-gray-900 mb-4">Lịch làm việc</h1>
<p class="text-gray-600 mb-6">Quản lý lịch làm việc và các sự kiện.</p>
<div class="p-6 bg-white rounded-lg shadow">
<h3 class="text-lg font-medium text-gray-900 mb-4">Lịch biểu</h3>
<p class="text-gray-700">Nội dung lịch làm việc sẽ được hiển thị tại đây.</p>
</div>
</div>
<div id="settings-section" class="content-section">
<h1 class="text-2xl font-bold text-gray-900 mb-4">Cài đặt hệ thống</h1>
<p class="text-gray-600 mb-6">Cấu hình các tùy chọn của ứng dụng.</p>
<div class="p-6 bg-white rounded-lg shadow">
<h3 class="text-lg font-medium text-gray-900 mb-4">Tùy chọn chung</h3>
<p class="text-gray-700">Nội dung cài đặt sẽ được hiển thị tại đây.</p>
</div>
</div>
</div>
</div>
</div>
<div id="loginModal" class="modal">
<div class="modal-content">
<h3 class="text-2xl font-bold text-center text-gray-900 mb-6">Đăng nhập</h3>
<form id="loginForm" class="space-y-4">
<div>
<label for="login-email" class="sr-only">Email</label>
<input type="email" id="login-email" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Email" required>
</div>
<div>
<label for="login-password" class="sr-only">Mật khẩu</label>
<input type="password" id="login-password" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Mật khẩu" required>
</div>
<p id="login-error-message" class="text-red-500 text-sm text-center hidden"></p>
<button type="submit" id="vanillaLoginButton" class="w-full bg-blue-600 text-white py-2 rounded-md hover:bg-blue-700 transition duration-200">Đăng nhập</button>
</form>
<div class="mt-4 text-center">
<a href="#" id="showResetPassword" class="text-blue-600 hover:underline text-sm">Quên mật khẩu?</a>
<p class="text-sm text-gray-600 mt-2">Chưa có tài khoản? <a href="#" id="showRegister" class="text-blue-600 hover:underline">Đăng ký ngay</a></p>
</div>
</div>
</div>
<div id="registerModal" class="modal">
<div class="modal-content">
<h3 class="text-2xl font-bold text-center text-gray-900 mb-6">Đăng ký</h3>
<form id="registerForm" class="space-y-4">
<div>
<label for="register-name" class="sr-only">Tên của bạn</label>
<input type="text" id="register-name" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Tên của bạn" required>
</div>
<div>
<label for="register-email" class="sr-only">Email</label>
<input type="email" id="register-email" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Email" required>
</div>
<div>
<label for="register-password" class="sr-only">Mật khẩu</label>
<input type="password" id="register-password" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Mật khẩu (ít nhất 6 ký tự)" required>
</div>
<button type="submit" id="registerButton" class="w-full bg-green-600 text-white py-2 rounded-md hover:bg-green-700 transition duration-200">Đăng ký</button>
</form>
<div class="mt-4 text-center">
<p class="text-sm text-gray-600">Đã có tài khoản? <a href="#" id="showLoginFromRegister" class="text-blue-600 hover:underline close-modal">Đăng nhập</a></p>
</div>
</div>
</div>
<div id="resetPasswordModal" class="modal">
<div class="modal-content">
<h3 class="text-2xl font-bold text-center text-gray-900 mb-6">Đặt lại mật khẩu</h3>
<form id="resetPasswordForm" class="space-y-4">
<div>
<label for="reset-email" class="sr-only">Email</label>
<input type="email" id="reset-email" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Nhập email của bạn" required>
</div>
<button type="submit" id="resetPasswordSubmit" class="w-full bg-blue-600 text-white py-2 rounded-md hover:bg-blue-700 transition duration-200">Gửi liên kết đặt lại</button>
</form>
<div class="mt-4 text-center">
<p class="text-sm text-gray-600">Quay lại <a href="#" id="showLoginFromReset" class="text-blue-600 hover:underline close-modal">Đăng nhập</a></p>
</div>
</div>
</div>
<div id="changePasswordModal" class="modal">
<div class="modal-content">
<h3 class="text-2xl font-bold text-center text-gray-900 mb-6">Đổi mật khẩu</h3>
<form id="changePasswordForm" class="space-y-4">
<div>
<label for="new-password" class="sr-only">Mật khẩu mới</label>
<input type="password" id="new-password" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Mật khẩu mới (ít nhất 6 ký tự)" required>
</div>
<div>
<label for="confirm-new-password" class="sr-only">Xác nhận mật khẩu mới</label>
<input type="password" id="confirm-new-password" class="w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Xác nhận mật khẩu mới" required>
</div>
<button type="submit" id="updatePasswordSubmit" class="w-full bg-blue-600 text-white py-2 rounded-md hover:bg-blue-700 transition duration-200">Cập nhật mật khẩu</button>
</form>
<div class="mt-4 text-center">
<button type="button" class="text-gray-600 hover:underline text-sm close-modal">Hủy</button>
</div>
</div>
</div>
<div id="messageModal" class="modal">
<div class="modal-content">
<h3 id="messageModalTitle" class="text-xl font-semibold text-gray-900 mb-4"></h3>
<p id="messageModalContent" class="text-gray-700 mb-6"></p>
<div class="flex justify-end">
<button type="button" class="px-4 py-2 text-sm font-medium text-white bg-blue-600 rounded-md hover:bg-blue-700 close-modal">Đóng</button>
</div>
</div>
</div>
<div id="confirmModal" class="modal">
<div class="modal-content">
<h3 id="confirmModalTitle" class="text-xl font-semibold text-gray-900 mb-4">Xác nhận</h3>
<p id="confirmModalContent" class="text-gray-700 mb-6"></p>
<div class="flex justify-end space-x-3">
<button type="button" id="confirmCancelBtn" class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 close-modal">Hủy</button>
<button type="button" id="confirmProceedBtn" class="px-4 py-2 text-white bg-red-600 rounded-md hover:bg-red-700">Xác nhận</button>
</div>
</div>
</div>
<div id="addDepartmentModal" class="modal">
<div class="modal-content">
<h3 class="text-2xl font-bold text-center text-gray-900 mb-6">Thêm phòng ban</h3>
<form id="addDepartmentForm" class="space-y-4">
<div>
<label for="departmentName" class="block text-sm font-medium text-gray-700">Tên phòng ban</label>
<input type="text" id="departmentName" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" required>
</div>
<div class="flex justify-end space-x-3">
<button type="button" class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 close-modal">Hủy</button>
<button type="submit" id="saveDepartmentBtn" class="px-4 py-2 text-white bg-blue-600 rounded-md hover:bg-blue-700">Lưu</button>
</div>
</form>
</div>
</div>
<div id="editDepartmentModal" class="modal">
<div class="modal-content">
<h3 class="text-2xl font-bold text-center text-gray-900 mb-6">Sửa phòng ban</h3>
<form id="editDepartmentForm" class="space-y-4">
<input type="hidden" id="editDepartmentId">
<div>
<label for="editDepartmentName" class="block text-sm font-medium text-gray-700">Tên phòng ban</label>
<input type="text" id="editDepartmentName" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" required>
</div>
<div class="flex justify-end space-x-3">
<button type="button" class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 close-modal">Hủy</button>
<button type="submit" id="updateDepartmentBtn" class="px-4 py-2 text-white bg-blue-600 rounded-md hover:bg-blue-700">Cập nhật</button>
</div>
</form>
</div>
</div>
<div id="addUserModal" class="modal">
<div class="modal-content">
<h3 id="userModalTitle" class="text-2xl font-bold text-center text-gray-900 mb-6">Thêm người dùng</h3>
<form id="addUserForm" class="space-y-4">
<div>
<label for="addUserName" class="block text-sm font-medium text-gray-700">Tên người dùng</label>
<input type="text" id="addUserName" name="userName" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" required>
</div>
<div>
<label for="addUserEmail" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="addUserEmail" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" required>
</div>
<div>
<label for="addUserPassword" class="block text-sm font-medium text-gray-700">Mật khẩu</label>
<input type="password" id="addUserPassword" name="addUserPassword" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" placeholder="Ít nhất 6 ký tự" required>
</div>
<div>
<label for="addUserRole" class="block text-sm font-medium text-gray-700">Vai trò</label>
<select id="addUserRole" name="addUserRole" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500">
<option value="employee">Nhân viên</option>
<option value="admin" class="admin-only">Quản trị viên</option>
</select>
</div>
<div>
<label for="addUserDepartment" class="block text-sm font-medium text-gray-700">Phòng ban</label>
<select id="addUserDepartment" name="department" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500">
</select>
</div>
<div class="flex justify-end space-x-3">
<button type="button" class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 close-modal">Hủy</button>
<button type="submit" id="saveUserBtn" class="px-4 py-2 text-white bg-blue-600 rounded-md hover:bg-blue-700">Lưu</button>
</div>
</form>
</div>
</div>
<div id="editUserModal" class="modal">
<div class="modal-content">
<h3 id="editUserModalLabel" class="text-2xl font-bold text-center text-gray-900 mb-6">Sửa người dùng</h3>
<form id="editUserForm" class="space-y-4">
<input type="hidden" id="editUserId">
<div>
<label for="editUserName" class="block text-sm font-medium text-gray-700">Tên người dùng</label>
<input type="text" id="editUserName" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" required>
</div>
<div>
<label for="editUserEmail" class="block text-sm font-medium text-gray-700">Email</label>
<input type="email" id="editUserEmail" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500" required>
</div>
<div>
<label for="editUserRole" class="block text-sm font-medium text-gray-700">Vai trò</label>
<select id="editUserRole" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500">
<option value="employee">Nhân viên</option>
<option value="admin">Quản trị viên</option>
</select>
</div>
<div>
<label for="editUserDepartment" class="block text-sm font-medium text-gray-700">Phòng ban</label>
<select id="editUserDepartment" class="mt-1 w-full px-4 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500">
</select>
</div>
<div class="flex justify-end space-x-3">
<button type="button" class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 close-modal">Hủy</button>
<button type="submit" id="updateUserBtn" class="px-4 py-2 text-white bg-blue-600 rounded-md hover:bg-blue-700">Cập nhật</button>
</div>
</form>
</div>
</div>
<div id="addTaskModal" class="modal">
<div class="modal-content">
<h3 class="text-2xl font-bold text-center text-gray-900 mb-6" id="taskModalTitle">Thêm công việc</h3>
<form id="taskForm" class="space-y-4">
<input type="hidden" id="taskId">
<div>
<label for="taskTitle" class="block text-sm font-medium text-gray-700">Tiêu đề công việc</label>
<input id="taskTitle" name="taskTitle" type="text" class="w-full p-2 border rounded-md mt-1 focus:ring-blue-500 focus:border-blue-500" required>
</div>
<div>
<label for="taskDescription" class="block text-sm font-medium text-gray-700">Mô tả</label>
<textarea id="taskDescription" name="taskDescription" rows="3" class="w-full p-2 border rounded-md mt-1 focus:ring-blue-500 focus:border-blue-500"></textarea>
</div>
<div>
<label for="taskDepartment" class="block text-sm font-medium text-gray-700">Phòng ban</label>
<select id="taskDepartment" class="w-full p-2 border rounded-md mt-1 focus:ring-blue-500 focus:border-blue-500" required>
</select>
</div>
<div>
<label for="taskAssignedTo" class="block text-sm font-medium text-gray-700">Người thực hiện</label>
<select id="taskAssignedTo" class="w-full p-2 border rounded-md mt-1 focus:ring-blue-500 focus:border-blue-500" required>
</select>
</div>
<div>
<label for="taskPriority" class="block text-sm font-medium text-gray-700">Mức độ ưu tiên</label>
<select id="taskPriority" class="w-full p-2 border rounded-md mt-1 focus:ring-blue-500 focus:border-blue-500">
<option value="Cao">Cao</option>
<option value="Trung bình" selected>Trung bình</option>
<option value="Thấp">Thấp</option>
</select>
</div>
<div>
<label for="taskProgress" class="block text-sm font-medium text-gray-700">Tiến độ (%)</label>
<input id="taskProgress" type="number" min="0" max="100" value="0" class="w-full p-2 border rounded-md mt-1 focus:ring-blue-500 focus:border-blue-500">
</div>
<div>
<label for="taskDueDate" class="block text-sm font-medium text-gray-700">Ngày hết hạn</label>
<input id="taskDueDate" type="date" class="w-full p-2 border rounded-md mt-1 focus:ring-blue-500 focus:border-blue-500">
</div>
<div>
<label for="taskStatus" class="block text-sm font-medium text-gray-700">Trạng thái</label>
<select id="taskStatus" name="taskStatus" class="w-full p-2 border rounded-md mt-1 focus:ring-blue-500 focus:border-blue-500">
<option value="Cần làm">Cần làm</option>
<option value="Đang tiến hành">Đang tiến hành</option>
<option value="Đã duyệt">Đã duyệt</option>
<option value="Từ chối">Từ chối</option>
<option value="Hoàn thành">Hoàn thành</option>
</select>
</div>
<div class="flex justify-end space-x-3 mt-6">
<button type="button" id="deleteTaskBtn" class="hidden px-4 py-2 text-white bg-red-600 rounded-md hover:bg-red-700">Xóa</button>
<button type="button" class="px-4 py-2 text-gray-700 bg-gray-200 rounded-md hover:bg-gray-300 close-modal">Hủy</button>
<button type="submit" id="saveTaskBtn" class="px-4 py-2 text-white bg-blue-600 rounded-md hover:bg-blue-700">Lưu</button>
</div>
</form>
</div>
</div>
<div id="taskDetailModal" class="modal">
<div class="modal-content w-full max-w-7xl max-h-[90vh] overflow-y-auto p-6 relative bg-white rounded-xl shadow-lg border border-gray-200">
<button class="absolute top-4 right-4 text-gray-400 hover:text-gray-800 transition close-modal">
<i class="fas fa-times text-xl"></i>
</button>
<span id="detailTaskId" class="hidden"></span>
<h3 id="detailTaskTitle" class="text-2xl font-bold text-gray-800 mb-4">Chi tiết công việc</h3>
<div id="detailTaskBody" class="mb-6 text-sm text-gray-700 leading-relaxed space-y-2 bg-gray-50 p-4 rounded border border-gray-200 shadow-sm">
</div>
<div>
<h4 class="text-lg font-semibold text-gray-800 mb-2">Bình luận</h4>
<div id="commentList" class="space-y-3 max-h-72 overflow-y-auto border rounded-md bg-white p-3 shadow-inner">
</div>
<form id="commentForm" class="mt-4 space-y-2">
<textarea id="commentText" class="w-full border border-gray-300 rounded-md p-3 text-sm shadow-sm focus:outline-none focus:ring focus:border-blue-500" rows="3" placeholder="Nhập bình luận..."></textarea>
<button type="submit" class="bg-blue-600 text-white px-5 py-2 rounded-md hover:bg-blue-700 transition">Gửi bình luận</button>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', () => {
const contentSections = document.querySelectorAll('.content-section');
window.showVanillaSection = function(targetId) {
console.log("VanillaJS: showVanillaSection called for", targetId);
contentSections.forEach(section => {
section.classList.remove('active');
});
const targetSection = document.getElementById(targetId);
if (targetSection) {
targetSection.classList.add('active');
}
}
function handleVanillaHashChangeInitial() {
const hash = window.location.hash.substring(1) || 'dashboard-section';
window.showVanillaSection(hash);
if (window.reactBridge && window.reactBridge.updateActiveSection) {
console.log("VanillaJS: Initial hash check, updating React bridge with active section:", hash);
window.reactBridge.updateActiveSection(hash);
}
}
// window.addEventListener('hashchange', handleVanillaHashChangeInitial); // Removed, only listeners.js should handle
setTimeout(() => {
console.log("VanillaJS: Initial section display. Relying on listeners.js now.");
// handleVanillaHashChangeInitial(); // Removed, handled by listeners.js
}, 200);
const mobileMenuButton = document.getElementById('mobile-menu-button');
if (mobileMenuButton) {
mobileMenuButton.addEventListener('click', () => {
if (window.reactBridge && window.reactBridge.setMobileMenuOpen) {
console.log("VanillaJS: mobile-menu-button clicked, calling reactBridge.setMobileMenuOpen(true)");
window.reactBridge.setMobileMenuOpen(true);
} else {
console.warn("VanillaJS: mobile-menu-button clicked, but reactBridge or setMobileMenuOpen is not available.");
}
});
}
// Đóng modal khi click nút .close-modal (cho các modal thuần)
document.querySelectorAll('.modal .close-modal').forEach(button => {
button.addEventListener('click', () => {
const modal = button.closest('.modal');
if (modal) {
modal.style.display = 'none';
}
});
});
});
</script>
<script type="module" src="public/js/utils/eventBus.js"></script>
<script type="module" src="public/js/firebase-init.js"></script>
<script type="module" src="public/js/utils/utils.js"></script>
<script type="module" src="public/js/utils/errorHandler.js"></script>
<script type="module" src="public/js/utils/dropdownHelpers.js"></script>
<script type="module" src="public/js/services/userService.js"></script>
<script type="module" src="public/js/services/departmentService.js"></script>
<script type="module" src="public/js/services/taskService.js"></script>
<script type="module" src="public/js/services/commentService.js"></script> <script type="module" src="public/js/managers/userManager.js"></script>
<script type="module" src="public/js/managers/departmentManager.js"></script>
<script type="module" src="public/js/managers/taskManager.js"></script>
<script type="module" src="public/js/auth.js"></script>
<script type="module" src="public/js/modal.js"></script>
<script type="module" src="public/js/departments.js"></script>
<script type="module" src="public/js/users.js"></script>
<script type="module" src="public/js/tasks.js"></script>
<script type="module" src="public/js/comments.js"></script>
<script type="module" src="public/js/kanban.js"></script>
<script type="module" src="public/js/dashboard.js"></script>
<script type="module" src="public/js/listeners.js"></script>
<script type="module" src="public/js/index.js"></script> <script type="module" src="/src/main.jsx"></script>
</body>
</html>