QPAT commited on
Commit
75ee1b5
·
2 Parent(s): 7403a3f4654788

Merge branch 'main' of https://github.com/minhhai266/Attendance

Browse files
Files changed (36) hide show
  1. pom.xml +32 -39
  2. src/main/java/com/attendenceSystem/frontroller/PageController.java +5 -1
  3. src/main/resources/application.properties +31 -9
  4. src/main/resources/templates/cms/absent/absent-create.html +91 -0
  5. src/main/resources/templates/cms/absent/absent-history.html +0 -0
  6. src/main/resources/templates/cms/absent/absent-list.html +193 -0
  7. src/main/resources/templates/cms/account/account-list.html +134 -0
  8. src/main/resources/templates/cms/attendance/attendance-list.html +143 -0
  9. src/main/resources/templates/cms/attendance/attendance.html +50 -0
  10. src/main/resources/templates/cms/auths/login.html +65 -0
  11. src/main/resources/templates/cms/auths/register.html +81 -0
  12. src/main/resources/templates/cms/auths/verify-otp.html +0 -0
  13. src/main/resources/templates/cms/chart/column-chart.html +0 -0
  14. src/main/resources/templates/cms/chart/pie-chart..html +29 -0
  15. src/main/resources/templates/cms/dashboard/dashboard-admin.html +311 -0
  16. src/main/resources/templates/cms/dashboard/dashboard-employee.html +274 -0
  17. src/main/resources/templates/cms/dashboard/dashboard-manage.html +216 -0
  18. src/main/resources/templates/cms/documents/document-create.html +71 -0
  19. src/main/resources/templates/cms/documents/document-detail.html +26 -0
  20. src/main/resources/templates/cms/documents/document-list.html +155 -0
  21. src/main/resources/templates/cms/face-id/faceID-create.html +197 -0
  22. src/main/resources/templates/cms/face-id/faceID-list.html +81 -0
  23. src/main/resources/templates/cms/homaPage.jsp +127 -0
  24. src/main/resources/templates/cms/layouts/footer.html +15 -0
  25. src/main/resources/templates/cms/layouts/header.html +44 -0
  26. src/main/resources/templates/cms/password/change-password.html +0 -0
  27. src/main/resources/templates/cms/password/forgot-password.html +0 -0
  28. src/main/resources/templates/cms/reports/report-day.html +0 -0
  29. src/main/resources/templates/cms/reports/report-month.html +0 -0
  30. src/main/resources/templates/cms/sidebar/sidebar-admin.html +52 -0
  31. src/main/resources/templates/cms/sidebar/sidebar-employee.html +63 -0
  32. src/main/resources/templates/cms/sidebar/sidebar-manage.html +81 -0
  33. src/main/resources/templates/cms/users/user-information.html +90 -0
  34. src/main/webapp/WEB-INF/views/homet.html +475 -0
  35. src/main/webapp/WEB-INF/views/webapp1/login.jsp +88 -79
  36. src/test/java/com/attendenceSystem/AttendenceSystemApplicationTests.java +9 -9
pom.xml CHANGED
@@ -1,7 +1,6 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <project xmlns="http://maven.apache.org/POM/4.0.0"
3
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
5
  <modelVersion>4.0.0</modelVersion>
6
  <parent>
7
  <groupId>org.springframework.boot</groupId>
@@ -31,45 +30,39 @@
31
  <java.version>21</java.version>
32
  </properties>
33
  <dependencies>
34
- <dependency>
35
- <groupId>org.mariadb.jdbc</groupId>
36
- <artifactId>mariadb-java-client</artifactId>
37
- </dependency>
38
  <dependency>
39
  <groupId>org.springframework.boot</groupId>
40
- <artifactId>spring-boot-starter-data-jpa</artifactId>
41
  </dependency>
42
  <dependency>
43
  <groupId>org.springframework.boot</groupId>
44
- <artifactId>spring-boot-starter-validation</artifactId>
45
  </dependency>
46
  <dependency>
47
  <groupId>org.projectlombok</groupId>
48
  <artifactId>lombok</artifactId>
49
- <version>1.18.32</version>
50
  <optional>true</optional>
51
  </dependency>
 
52
  <dependency>
53
  <groupId>org.springframework.boot</groupId>
54
- <artifactId>spring-boot-starter-restclient</artifactId>
55
- </dependency>
56
- <dependency>
57
- <groupId>org.apache.tomcat.embed</groupId>
58
- <artifactId>tomcat-embed-jasper</artifactId>
59
  </dependency>
60
-
61
  <dependency>
62
- <groupId>jakarta.servlet.jsp.jstl</groupId>
63
- <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
64
  </dependency>
65
 
66
- <dependency>
67
- <groupId>org.glassfish.web</groupId>
68
- <artifactId>jakarta.servlet.jsp.jstl</artifactId>
69
- </dependency>
70
  <dependency>
71
  <groupId>org.springframework.boot</groupId>
72
- <artifactId>spring-boot-starter-webmvc</artifactId>
73
  </dependency>
74
  <dependency>
75
  <groupId>org.springframework.boot</groupId>
@@ -77,27 +70,27 @@
77
  <scope>runtime</scope>
78
  <optional>true</optional>
79
  </dependency>
80
- <!-- <dependency>
81
- <groupId>com.mysql</groupId>
82
- <artifactId>mysql-connector-j</artifactId>
83
- <scope>runtime</scope>
84
- </dependency> -->
85
- <!-- <dependency>
86
- <groupId>org.springframework.boot</groupId>
87
- <artifactId>spring-boot-starter-data-jpa-test</artifactId>
88
- <scope>test</scope>
89
- </dependency> -->
90
  <dependency>
91
- <groupId>org.springframework.boot</groupId>
92
- <artifactId>spring-boot-starter-restclient-test</artifactId>
93
- <scope>test</scope>
94
  </dependency>
95
 
 
96
  <dependency>
97
- <groupId>org.springframework.boot</groupId>
98
- <artifactId>spring-boot-starter-webmvc-test</artifactId>
99
- <scope>test</scope>
 
 
 
100
  </dependency>
 
 
 
 
 
 
101
  </dependencies>
102
 
103
  <build>
 
1
  <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
 
4
  <modelVersion>4.0.0</modelVersion>
5
  <parent>
6
  <groupId>org.springframework.boot</groupId>
 
30
  <java.version>21</java.version>
31
  </properties>
32
  <dependencies>
33
+ <!-- <dependency>
34
+ <groupId>org.springframework.boot</groupId>
35
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
36
+ </dependency> -->
37
  <dependency>
38
  <groupId>org.springframework.boot</groupId>
39
+ <artifactId>spring-boot-starter-validation</artifactId>
40
  </dependency>
41
  <dependency>
42
  <groupId>org.springframework.boot</groupId>
43
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
44
  </dependency>
45
  <dependency>
46
  <groupId>org.projectlombok</groupId>
47
  <artifactId>lombok</artifactId>
48
+ <!-- <version>1.18.32</version> -->
49
  <optional>true</optional>
50
  </dependency>
51
+ <!-- OAuth2 Google Login -->
52
  <dependency>
53
  <groupId>org.springframework.boot</groupId>
54
+ <artifactId>spring-boot-starter-oauth2-client</artifactId>
 
 
 
 
55
  </dependency>
56
+ <!-- Spring Boot Web -->
57
  <dependency>
58
+ <groupId>org.springframework.boot</groupId>
59
+ <artifactId>spring-boot-starter-web</artifactId>
60
  </dependency>
61
 
62
+ <!-- Embedded Tomcat (not provided so java -jar works) -->
 
 
 
63
  <dependency>
64
  <groupId>org.springframework.boot</groupId>
65
+ <artifactId>spring-boot-starter-tomcat</artifactId>
66
  </dependency>
67
  <dependency>
68
  <groupId>org.springframework.boot</groupId>
 
70
  <scope>runtime</scope>
71
  <optional>true</optional>
72
  </dependency>
73
+ <!-- JSP support -->
 
 
 
 
 
 
 
 
 
74
  <dependency>
75
+ <groupId>org.apache.tomcat.embed</groupId>
76
+ <artifactId>tomcat-embed-jasper</artifactId>
 
77
  </dependency>
78
 
79
+ <!-- JSTL -->
80
  <dependency>
81
+ <groupId>jakarta.servlet.jsp.jstl</groupId>
82
+ <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
83
+ </dependency>
84
+ <dependency>
85
+ <groupId>org.glassfish.web</groupId>
86
+ <artifactId>jakarta.servlet.jsp.jstl</artifactId>
87
  </dependency>
88
+ <dependency>
89
+ <groupId>com.mysql</groupId>
90
+ <artifactId>mysql-connector-j</artifactId>
91
+ <scope>runtime</scope>
92
+ </dependency>
93
+
94
  </dependencies>
95
 
96
  <build>
src/main/java/com/attendenceSystem/frontroller/PageController.java CHANGED
@@ -11,7 +11,11 @@ public class PageController {
11
 
12
  @GetMapping({"home",""})
13
  public String home() {
14
- return "home";
 
 
 
 
15
  }
16
  @GetMapping("login")
17
  public String login() {
 
11
 
12
  @GetMapping({"home",""})
13
  public String home() {
14
+ return "home.";
15
+ }
16
+ @GetMapping("homet")
17
+ public String homet() {
18
+ return "homet";
19
  }
20
  @GetMapping("login")
21
  public String login() {
src/main/resources/application.properties CHANGED
@@ -1,6 +1,7 @@
1
- spring.application.name=attendenceSystem
2
-
3
 
 
 
4
  # JSP Configuration
5
  spring.mvc.view.prefix=/WEB-INF/views/
6
  spring.mvc.view.suffix=.jsp
@@ -11,14 +12,35 @@ spring.mvc.view.suffix=.jsp
11
  # spring.thymeleaf.encoding=UTF-8
12
  # spring.thymeleaf.mode=HTML
13
 
 
 
 
 
 
 
 
 
 
 
14
  # DataSource Configuration for SQL Server
15
- spring.datasource.url=jdbc:mariadb://localhost:3306/MOONBLIGHT
 
 
 
 
 
16
  spring.datasource.username=root
17
- spring.datasource.password=QQQewqwqa401!
18
- spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
 
 
 
 
 
 
 
19
  # JPA configuration
20
- spring.jpa.hibernate.ddl-auto=update
21
- spring.jpa.show-sql=true
22
 
23
- #TimeZone Setting
24
- app.timezone=Asia/Ho_Chi_Minh
 
 
1
+ server.port=8080
 
2
 
3
+ spring.servlet.multipart.max-file-size=10MB
4
+ spring.servlet.multipart.max-request-size=10MB
5
  # JSP Configuration
6
  spring.mvc.view.prefix=/WEB-INF/views/
7
  spring.mvc.view.suffix=.jsp
 
12
  # spring.thymeleaf.encoding=UTF-8
13
  # spring.thymeleaf.mode=HTML
14
 
15
+ # Google OAuth2
16
+ # spring.security.oauth2.client.registration.google.client-id=
17
+ # spring.security.oauth2.client.registration.google.client-secret=
18
+ # spring.security.oauth2.client.registration.google.scope=email,profile
19
+
20
+ spring.devtools.restart.enabled=true
21
+ spring.devtools.livereload.enabled=true
22
+
23
+ server.servlet.jsp.init-parameters.development=true
24
+
25
  # DataSource Configuration for SQL Server
26
+ # spring.datasource.url=jdbc:mariadb://localhost:3306/MOONBLIGHT
27
+ # spring.datasource.username=root
28
+ # spring.datasource.password=QQQewqwqa401!
29
+ # spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
30
+
31
+ spring.datasource.url=jdbc:mysql://localhost:3306/game_promo_web
32
  spring.datasource.username=root
33
+ spring.datasource.password=annguyenthanh2k5
34
+
35
+
36
+ # SMPT EMAIL
37
+ # spring.mail.host=smtp.gmail.com
38
+ # spring.mail.port=587
39
+ # spring.mail.username=donhatquang401@gmail.com
40
+ # spring.mail.password=lzzxdgzmirxdwqdv
41
+
42
  # JPA configuration
 
 
43
 
44
+
45
+
46
+ >>>>>>> Stashed changes
src/main/resources/templates/cms/absent/absent-create.html ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="vi">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Xin nghỉ phép</title>
8
+
9
+ <!-- Font Awesome -->
10
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/css/all.min.css">
11
+ </head>
12
+
13
+ <body>
14
+ <div class="bg-image"></div>
15
+ <div th:replace="~{cms/fragments/sidebar :: sidebar}"></div>
16
+ <div class="absent-page">
17
+ <header class="page-header">
18
+ <h1>Xin nghỉ phép</h1>
19
+
20
+ <div class="notification">
21
+ <i class="fa-regular fa-bell"></i>
22
+ <span class="dot"></span>
23
+ </div>
24
+ </header>
25
+ <main class="main-section">
26
+
27
+ <!-- Form -->
28
+ <div class="absent-card">
29
+
30
+ <h2>Đơn xin nghỉ phép</h2>
31
+
32
+ <!-- Loại nghỉ phép -->
33
+ <div class="form-group">
34
+ <label>Loại nghỉ phép</label>
35
+
36
+ <div class="select-wrapper">
37
+ <select>
38
+ <option selected disabled>Chọn loại nghỉ phép</option>
39
+ <option>Nghỉ có lương</option>
40
+ <option>Nghỉ không lương</option>
41
+ <option>Nghỉ bệnh</option>
42
+ <option>Nghỉ phép năm</option>
43
+ </select>
44
+
45
+ <i class="fa-solid fa-chevron-down"></i>
46
+ </div>
47
+ </div>
48
+
49
+ <!-- Từ ngày - Đến ngày -->
50
+ <div class="date-row">
51
+
52
+ <div class="form-group">
53
+ <label>Từ ngày</label>
54
+
55
+ <div class="input-icon">
56
+ <input type="date">
57
+ <i class="fa-regular fa-calendar"></i>
58
+ </div>
59
+ </div>
60
+
61
+ <div class="form-group">
62
+ <label>Đến ngày</label>
63
+
64
+ <div class="input-icon">
65
+ <input type="date">
66
+ <i class="fa-regular fa-calendar"></i>
67
+ </div>
68
+ </div>
69
+
70
+ </div>
71
+
72
+ <!-- Lý do -->
73
+ <div class="form-group">
74
+ <label>Lý do</label>
75
+
76
+ <textarea rows="6" placeholder="Nhập lý do xin nghỉ phép..."></textarea>
77
+ </div>
78
+
79
+ <!-- Button -->
80
+ <button class="submit-btn">
81
+ <i class="fa-regular fa-paper-plane"></i>
82
+ Gửi đơn
83
+ </button>
84
+
85
+ </div>
86
+ </main>
87
+ </div>
88
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
89
+ </body>
90
+
91
+ </html>
src/main/resources/templates/cms/absent/absent-history.html ADDED
File without changes
src/main/resources/templates/cms/absent/absent-list.html ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+
3
+ <html xmlns:th="http://www.thymeleaf.org">
4
+
5
+ <head>
6
+ <meta charset="UTF-8" />
7
+ <title>Danh sách thế giới</title>
8
+ <link rel="stylesheet" th:href="@{/css/world/world.css}">
9
+
10
+ </head>
11
+
12
+ <body>
13
+ <div class="bg-image"></div>
14
+ <div th:replace="~{cms/fragments/sidebar :: sidebar}"></div>
15
+
16
+ <div class="container-layout">
17
+ <div class="absent-header">
18
+ <h1 class="header-title">Duyệt nghỉ phép</h1>
19
+ <div class="header-divider"></div>
20
+ </div>
21
+
22
+ <main class="main-section">
23
+
24
+ <div class="absent-card">
25
+
26
+ <div class="main-absent">
27
+ <div class="absent-search">
28
+
29
+ <div class="filter-group">
30
+
31
+ <!-- Tìm theo tên -->
32
+ <div class="filter-item">
33
+ <label>Tên nhân viên</label>
34
+ <input type="text" name="keyword" placeholder="Nhập tên..." />
35
+ </div>
36
+
37
+ <!-- Lọc theo trạng thái -->
38
+ <div class="filter-item">
39
+ <label>Trạng thái</label>
40
+ <select name="status">
41
+ <option value="">Tất cả</option>
42
+ <option value="PENDING">Chờ duyệt</option>
43
+ <option value="APPROVED">Đã duyệt</option>
44
+ <option value="REJECTED">Từ chối</option>
45
+ </select>
46
+ </div>
47
+
48
+ <div class="filter-item">
49
+ <label>Tuần</label>
50
+ <input type="week" name="week">
51
+ </div>
52
+
53
+ <div class="filter-item">
54
+ <button type="submit" class="btn btn-primary">
55
+ Tìm kiếm
56
+ </button>
57
+ </div>
58
+
59
+ </div>
60
+
61
+ </div>
62
+ <table class="absent-table">
63
+ <thead>
64
+ <tr>
65
+ <th>Tên</th>
66
+ <th>Phòng</th>
67
+ <th>Lý do</th>
68
+ <th>Từ ngày</th>
69
+ <th>Đến ngày</th>
70
+ <th>Chi tiết</th>
71
+ <th>Trạng thái</th>
72
+ <th></th>
73
+ </tr>
74
+ </thead>
75
+
76
+ <tbody>
77
+ <tr>
78
+ <td></td>
79
+ <td></td>
80
+ <td></td>
81
+ <td></td>
82
+ <td></td>
83
+ <td></td>
84
+ <td></td>
85
+ <td>
86
+ <span class="status-active">
87
+ Đang hiển thị
88
+ </span>
89
+
90
+ <span class="status-deleted">
91
+ Đang ẩn
92
+ </span>
93
+ </td>
94
+ <td>
95
+ <div class="action-group">
96
+
97
+ <form method="get">
98
+ <button class="btn btn-primary btn-small">
99
+ Phê duyệt
100
+ </button>
101
+ </form>
102
+
103
+ <form method="post">
104
+ <button class="btn btn-secondary btn-small">
105
+ Từ chối
106
+ </button>
107
+ </form>
108
+
109
+ </div>
110
+ </td>
111
+ </tr>
112
+ </tbody>
113
+ </table>
114
+ </div>
115
+
116
+
117
+ <div class="pagination">
118
+ <a class="btn btn-pagination">
119
+ ← Trước
120
+ </a>
121
+
122
+ <span>
123
+ <a></a>
124
+ <span></span>
125
+ </span>
126
+
127
+ <a class="btn btn-pagination">
128
+ Sau →
129
+ </a>
130
+ </div>
131
+ </div>
132
+
133
+ </main>
134
+
135
+ </div>
136
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
137
+ ```html
138
+ <div id="accountModal" class="detail-modal">
139
+
140
+ <div class="detail-content">
141
+
142
+ <div class="detail-header">
143
+
144
+ <h2>Thông tin cá nhân</h2>
145
+
146
+ <button class="close-btn" onclick="closeAccountDetail()">
147
+
148
+
149
+
150
+ </button>
151
+
152
+ </div>
153
+
154
+ <div class="detail-body">
155
+
156
+ <div class="detail-item">
157
+ <label>Họ và tên</label>
158
+ <p id="detailFullName"></p>
159
+ </div>
160
+
161
+ <div class="detail-item">
162
+ <label>Email</label>
163
+ <p id="detailEmail"></p>
164
+ </div>
165
+
166
+ <div class="detail-item">
167
+ <label>Số điện thoại</label>
168
+ <p id="detailPhone"></p>
169
+ </div>
170
+
171
+ <div class="detail-item">
172
+ <label>Phòng ban</label>
173
+ <p id="detailDepartment"></p>
174
+ </div>
175
+
176
+ <div class="detail-item">
177
+ <label>Vai trò</label>
178
+ <p id="detailRole"></p>
179
+ </div>
180
+
181
+ <div class="detail-item">
182
+ <label>Trạng thái</label>
183
+ <span id="detailStatus"></span>
184
+ </div>
185
+
186
+ </div>
187
+
188
+ </div>
189
+
190
+ </div>
191
+ </body>
192
+
193
+ </html>
src/main/resources/templates/cms/account/account-list.html ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+
3
+ <html xmlns:th="http://www.thymeleaf.org">
4
+
5
+ <head>
6
+ <meta charset="UTF-8" />
7
+ <title>Danh sách thế giới</title>
8
+ <link rel="stylesheet" th:href="@{/css/world/world.css}">
9
+
10
+ </head>
11
+
12
+ <body>
13
+ <div class="bg-image"></div>
14
+ <div th:replace="~{cms/fragments/sidebar-employee :: sidebar}"></div>
15
+
16
+ <div class="container-layout">
17
+ <header class="page-header">
18
+ <h1>Quản lý người dùng</h1>
19
+
20
+ <div class="notification">
21
+ <i class="fa-regular fa-bell"></i>
22
+ <span class="dot"></span>
23
+ </div>
24
+ </header>
25
+
26
+ <div class="card">
27
+
28
+ <div class="card-header">
29
+ <h2>Quản lý người dùng</h2>
30
+ <button class="add-btn">+ Thêm người dùng</button>
31
+ </div>
32
+
33
+ <div class="search-box">
34
+ <input type="text" placeholder="Tìm kiếm người dùng...">
35
+ </div>
36
+
37
+ <table>
38
+ <thead>
39
+ <tr>
40
+ <th>Người dùng</th>
41
+ <th>Email</th>
42
+ <th>Vai trò</th>
43
+ <th>Trạng thái</th>
44
+ <th>Hành động</th>
45
+ </tr>
46
+ </thead>
47
+
48
+ <tbody>
49
+ <tr>
50
+ <td>
51
+ <div class="user">
52
+ <div class="avatar">A</div>
53
+ <strong>Nguyễn Văn A</strong>
54
+ </div>
55
+ </td>
56
+ <td>nguyenvana@company.com</td>
57
+ <td><span class="role">Nhân viên</span></td>
58
+ <td><span class="status active">Hoạt động</span></td>
59
+ <td>
60
+ <div class="actions">
61
+ <button class="icon-btn btn-role">Đổi quyền</button>
62
+ <button class="icon-btn lock">🔒</button>
63
+ </div>
64
+ </td>
65
+ </tr>
66
+
67
+
68
+ </tbody>
69
+ </table>
70
+
71
+ </div>
72
+
73
+ </div>
74
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
75
+
76
+ ```html
77
+ <div id="accountModal" class="detail-modal">
78
+
79
+ <div class="detail-content">
80
+
81
+ <div class="detail-header">
82
+
83
+ <h2>Thông tin cá nhân</h2>
84
+
85
+ <button class="close-btn" onclick="closeAccountDetail()">
86
+
87
+
88
+
89
+ </button>
90
+
91
+ </div>
92
+
93
+ <div class="detail-body">
94
+
95
+ <div class="detail-item">
96
+ <label>Họ và tên</label>
97
+ <p id="detailFullName"></p>
98
+ </div>
99
+
100
+ <div class="detail-item">
101
+ <label>Email</label>
102
+ <p id="detailEmail"></p>
103
+ </div>
104
+
105
+ <div class="detail-item">
106
+ <label>Số điện thoại</label>
107
+ <p id="detailPhone"></p>
108
+ </div>
109
+
110
+ <div class="detail-item">
111
+ <label>Phòng ban</label>
112
+ <p id="detailDepartment"></p>
113
+ </div>
114
+
115
+ <div class="detail-item">
116
+ <label>Vai trò</label>
117
+ <p id="detailRole"></p>
118
+ </div>
119
+
120
+ <div class="detail-item">
121
+ <label>Trạng thái</label>
122
+ <span id="detailStatus"></span>
123
+ </div>
124
+
125
+ </div>
126
+
127
+ </div>
128
+
129
+ </div>
130
+
131
+
132
+ </body>
133
+
134
+ </html>
src/main/resources/templates/cms/attendance/attendance-list.html ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <%@ page contentType="text/html;charset=UTF-8" %>
2
+
3
+
4
+ <html lang="en">
5
+
6
+ <head>
7
+ <meta charset="UTF-8">
8
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
9
+ <title>Home Attendance</title>
10
+ <link href="/css/attendance.css" rel="stylesheet">
11
+ </head>
12
+
13
+ <body>
14
+
15
+ <!-- =======================================================================
16
+ HEADER
17
+ ==========================================================================-->
18
+ <header class="header">
19
+ <div class="header-left">
20
+ <div class="header-logo">
21
+ <a href="/home">MyApp</a>
22
+ </div>
23
+
24
+ <div class="header-info">
25
+ <h1 class="header-title">Home Attendance 1</h1>
26
+ <div class="header-time">22/22/22</div>
27
+ </div>
28
+ </div>
29
+
30
+ <div class="header-right">
31
+
32
+ <div class="header-clock" id="clock">
33
+ 00:00:00
34
+ </div>
35
+
36
+ <button class="header-btn theme-toggle" id="themeToggle">
37
+ 🌙
38
+ </button>
39
+
40
+
41
+
42
+ </div>
43
+ </header>
44
+ <!-- =======================================================================
45
+ BODY
46
+ ==========================================================================-->
47
+ <div class="container">
48
+ <div class="container-attend-left history">
49
+ <h3 class="history-title">Lịch sử chấm công</h3>
50
+
51
+ <ul class="history-list">
52
+
53
+ <li class="history-item">
54
+ <div class="history-card">
55
+ <span class="history-date">
56
+ Ngày 01/01/2024
57
+ </span>
58
+
59
+ <span class="history-status status-in">
60
+ Vào lúc 08:00
61
+ </span>
62
+
63
+ <span class="history-status status-out">
64
+ Ra lúc 17:00
65
+ </span>
66
+ </div>
67
+ </li>
68
+
69
+ </ul>
70
+ </div>
71
+ <div class="container-attend-main">
72
+
73
+ <div class="face-scanner scanner-card">
74
+
75
+ <!-- <video id="camera" autoplay playsinline></video> -->
76
+
77
+ <div class="scan-overlay">
78
+ <div class="scan-frame"></div>
79
+ <div class="scan-line"></div>
80
+ </div>
81
+
82
+ <div class="result-card success-result">
83
+ ✓ Nhận diện thành công
84
+ </div>
85
+
86
+ </div>
87
+
88
+ <div class="face-guide guide-card">
89
+ <p class="guide-title">
90
+ Hướng dẫn chấm công bằng nhận diện khuôn mặt:
91
+ </p>
92
+
93
+ <ol class="guide-list">
94
+ <li>Đứng cách camera khoảng 50cm - 1m</li>
95
+ <li>Nhìn thẳng vào camera</li>
96
+ <li>Giữ khuôn mặt trong khung hình</li>
97
+ <li>Hệ thống sẽ tự động nhận diện và ghi nhận</li>
98
+ </ol>
99
+ </div>
100
+
101
+ </div>
102
+ <div class="container-attend-right">
103
+
104
+ <h3 class="attendance-title">
105
+ Thống kê hôm nay
106
+ </h3>
107
+
108
+ <div class="stat-card success-card">
109
+ <p class="attendance-present">
110
+ Đã chấm công
111
+ </p>
112
+ <span class="stat-number">42</span>
113
+ </div>
114
+
115
+ <div class="stat-card warning-card">
116
+ <p class="attendance-late">
117
+ Đi muộn
118
+ </p>
119
+ <span class="stat-number">8</span>
120
+ </div>
121
+
122
+ <div class="stat-card danger-card">
123
+ <p class="attendance-absent">
124
+ Chưa chấm công
125
+ </p>
126
+ <span class="stat-number">12</span>
127
+ </div>
128
+
129
+ <div class="attendance-info">
130
+ <p class="attendance-sum">
131
+ Tổng nhân viên: 50
132
+ </p>
133
+
134
+ <p class="attendance-date">
135
+ Giờ làm việc: 08:00 - 17:00
136
+ </p>
137
+ </div>
138
+
139
+ </div>
140
+
141
+ </body>
142
+
143
+ </html>
src/main/resources/templates/cms/attendance/attendance.html ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <section id="attendance" class="page">
2
+ <div class="card attendance-card">
3
+ <div class="card-header">
4
+ <h3>Điểm danh</h3>
5
+ <div>
6
+ <button onclick="loadAttendanceRecords()">Tải lại</button>
7
+ </div>
8
+ </div>
9
+ <div class="filter-panel">
10
+ <input id="attendanceSearch" class="search-input" placeholder="Tìm mã SV hoặc họ tên" />
11
+ <select id="attendanceStatusFilter">
12
+ <option value="">Tất cả trạng thái</option>
13
+ <option value="present_on_time">Đúng giờ</option>
14
+ <option value="late">Đi muộn</option>
15
+ <option value="early_leave">Về sớm</option>
16
+ <option value="late_and_early_leave">Muộn + về sớm</option>
17
+ <option value="missing_checkout">Thiếu check-out</option>
18
+ <option value="absent">Vắng</option>
19
+ <option value="pending">Chưa ghi nhận</option>
20
+ <option value="unfinalized">Chưa chốt</option>
21
+ </select>
22
+ <label>Từ ngày<input id="attendanceDateFrom" type="date" /></label>
23
+ <label>Đến ngày<input id="attendanceDateTo" type="date" /></label>
24
+ <button onclick="loadAttendanceRecords()">Lọc</button>
25
+ <button class="secondary" onclick="resetAttendanceFilters()">Hôm nay</button>
26
+ <span id="attendanceCount" class="filter-count"></span>
27
+ </div>
28
+ <div class="table-scroll">
29
+ <table class="attendance-table">
30
+ <thead>
31
+ <tr>
32
+ <th>Ngày</th>
33
+ <th>Sinh viên</th>
34
+ <th>Vào</th>
35
+ <th>Ra</th>
36
+ <th>Trạng thái</th>
37
+ <th>Hiện diện</th>
38
+ <th>Muộn</th>
39
+ <th>Về sớm</th>
40
+ <th>Tổng giờ</th>
41
+ <th>Ghi chú</th>
42
+ <th>Chi tiết</th>
43
+ </tr>
44
+ </thead>
45
+ <tbody id="attendanceTable"></tbody>
46
+ </table>
47
+ </div>
48
+ <div id="attendanceMessage" class="message"></div>
49
+ </div>
50
+ </section>
src/main/resources/templates/cms/auths/login.html ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="vi">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Đăng Nhập - Face ID Attendance</title>
8
+ <link rel="stylesheet" href="css/components.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="bg-img"></div>
13
+ <div th:replace="~{cms/layouts/header :: header}"></div>
14
+
15
+ <div class="card-auth layout">
16
+ <div class="card-header">
17
+
18
+ <h1 class="card-title">Đăng nhập</h1>
19
+ <p class="card-description">Nhập thông tin để truy cập!</p>
20
+ </div>
21
+ <div class="card-body">
22
+ <p class="error-message"></p>
23
+
24
+ <!-- form -->
25
+ <form method="post">
26
+
27
+ <!-- username/email -->
28
+ <div class="auth-group">
29
+ <label>Username hoặc Email</label>
30
+ <input type="text" />
31
+
32
+ <div class="error-message">
33
+ </div>
34
+ </div>
35
+
36
+ <!-- password -->
37
+ <div class="auth-group">
38
+ <label>Password</label>
39
+ <input type="password" />
40
+
41
+ <div class="error-message">
42
+ </div>
43
+ </div>
44
+
45
+ <button class="auth-btn" type="submit">
46
+ Đăng nhập
47
+ </button>
48
+ </form>
49
+
50
+ <hr style="margin: 1rem 0; opacity: 0.2;" />
51
+
52
+ <a class="register-link">
53
+ Tạo tài khoản mới
54
+ </a>
55
+
56
+ <a class="forgotPass-link">
57
+ Quên mật khẩu
58
+ </a>
59
+ </div>
60
+ </div>
61
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
62
+
63
+ </body>
64
+
65
+ </html>
src/main/resources/templates/cms/auths/register.html ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="vi">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Đăng Ký - Face ID Attendance</title>
8
+ <link rel="stylesheet" href="css/components.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="bg-img"></div>
13
+ <div th:replace="~{cms/layouts/header :: header}"></div>
14
+
15
+ <div class="card-auth layout">
16
+ <div class="card-header">
17
+
18
+ <h1 class="card-title">Đăng nhập</h1>
19
+ <p class="card-description">Nhập thông tin để truy cập!</p>
20
+ </div>
21
+ <div class="card-body">
22
+ <p class="error-message"></p>
23
+
24
+ <!-- form -->
25
+ <form method="post">
26
+
27
+ <div class="auth-group">
28
+ <label>Username hoặc Email</label>
29
+ <input type="text" />
30
+ <div class="error-message"></div>
31
+ </div>
32
+ <div class="auth-group">
33
+ <label class="auth-label">Họ và tên *</label>
34
+ <input type="text" class="auth-control" placeholder="Nguyễn Văn A" required>
35
+ <div class="error-message"></div>
36
+ </div>
37
+
38
+ <div class="auth-group">
39
+ <label class="auth-label">Email *</label>
40
+ <input type="email" class="auth-control" placeholder="your.email@company.com" required>
41
+ <div class="error-message"></div>
42
+
43
+ </div>
44
+
45
+ <div class="auth-group">
46
+ <label class="auth-label">Số điện thoại *</label>
47
+ <input type="tel"class="auth-control" placeholder="0901234567" required>
48
+ </div>
49
+
50
+ <div class="auth-group">
51
+ <label class="auth-label">Mật khẩu *</label>
52
+ <input type="password" class="auth-control" placeholder="••••••••"
53
+ required>
54
+ </div>
55
+
56
+ <div class="auth-group">
57
+ <label class="auth-label">Xác nhận mật khẩu *</label>
58
+ <input type="password"class="auth-control" placeholder="••••••••" required>
59
+ </div>
60
+
61
+ <button class="auth-btn" type="submit">
62
+ Đăng ký
63
+ </button>
64
+ </form>
65
+
66
+ <hr style="margin: 1rem 0; opacity: 0.2;" />
67
+
68
+ <a class="register-link">
69
+ Đã có tài khoản
70
+ </a>
71
+
72
+ <a class="forgotPass-link">
73
+ Quên mật khẩu
74
+ </a>
75
+ </div>
76
+ </div>
77
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
78
+
79
+ </body>
80
+
81
+ </html>
src/main/resources/templates/cms/auths/verify-otp.html ADDED
File without changes
src/main/resources/templates/cms/chart/column-chart.html ADDED
File without changes
src/main/resources/templates/cms/chart/pie-chart..html ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="distribution-layout">
2
+
3
+ <div class="distribution-chart">
4
+ <canvas id="attendancePieChart"></canvas>
5
+ </div>
6
+
7
+ <div class="distribution-legend">
8
+
9
+ <div class="legend-item">
10
+ <span class="legend-color green"></span>
11
+ <span class="legend-label">Đúng giờ</span>
12
+ <span class="legend-value">75%</span>
13
+ </div>
14
+
15
+ <div class="legend-item">
16
+ <span class="legend-color yellow"></span>
17
+ <span class="legend-label">Đi muộn</span>
18
+ <span class="legend-value">18%</span>
19
+ </div>
20
+
21
+ <div class="legend-item">
22
+ <span class="legend-color red"></span>
23
+ <span class="legend-label">Vắng mặt</span>
24
+ <span class="legend-value">7%</span>
25
+ </div>
26
+
27
+ </div>
28
+
29
+ </div>
src/main/resources/templates/cms/dashboard/dashboard-admin.html ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+
3
+ <html xmlns:th="http://www.thymeleaf.org">
4
+
5
+ <head>
6
+ <meta charset="UTF-8" />
7
+ <title>Danh sách thế giới</title>
8
+ <link rel="stylesheet" th:href="@{/css/world/world.css}">
9
+
10
+ </head>
11
+
12
+ <body>
13
+ <div class="bg-image"></div>
14
+ <div th:replace="~{cms/fragments/sidebar-admin :: sidebar}"></div>
15
+
16
+ <div class="container-layout">
17
+ <header class="page-header">
18
+ <h1>Dashboard</h1>
19
+
20
+ <div class="notification">
21
+ <i class="fa-regular fa-bell"></i>
22
+ <span class="dot"></span>
23
+ </div>
24
+ </header>
25
+
26
+ <main class="dashboard-admin">
27
+
28
+ <!-- =====================
29
+ OVERVIEW
30
+ ====================== -->
31
+ <section class="admin-overview">
32
+
33
+ <div class="admin-stat-card total-account">
34
+ <div class="admin-stat-card__header">
35
+ <span class="admin-stat-card__title">Tổng tài khoản</span>
36
+ <div class="admin-stat-card__icon"></div>
37
+ </div>
38
+
39
+ <div class="admin-stat-card__body">
40
+ <h2 class="admin-stat-card__number">53</h2>
41
+ <p class="admin-stat-card__description">
42
+ +12% so với tháng trước
43
+ </p>
44
+ </div>
45
+ </div>
46
+
47
+ <div class="admin-stat-card active-account">
48
+ <div class="admin-stat-card__header">
49
+ <span class="admin-stat-card__title">
50
+ Tài khoản hoạt động
51
+ </span>
52
+ <div class="admin-stat-card__icon"></div>
53
+ </div>
54
+
55
+ <div class="admin-stat-card__body">
56
+ <h2 class="admin-stat-card__number">48</h2>
57
+ <p class="admin-stat-card__description">
58
+ 90.6% tổng số
59
+ </p>
60
+ </div>
61
+ </div>
62
+
63
+ <div class="admin-stat-card locked-account">
64
+ <div class="admin-stat-card__header">
65
+ <span class="admin-stat-card__title">
66
+ Tài khoản bị khóa
67
+ </span>
68
+ <div class="admin-stat-card__icon"></div>
69
+ </div>
70
+
71
+ <div class="admin-stat-card__body">
72
+ <h2 class="admin-stat-card__number">5</h2>
73
+ <p class="admin-stat-card__description">
74
+ Cần xem xét
75
+ </p>
76
+ </div>
77
+ </div>
78
+
79
+ <div class="admin-stat-card pending-account">
80
+ <div class="admin-stat-card__header">
81
+ <span class="admin-stat-card__title">
82
+ Chờ duyệt
83
+ </span>
84
+ <div class="admin-stat-card__icon"></div>
85
+ </div>
86
+
87
+ <div class="admin-stat-card__body">
88
+ <h2 class="admin-stat-card__number">7</h2>
89
+ <p class="admin-stat-card__description">
90
+ Tài khoản mới đăng ký
91
+ </p>
92
+ </div>
93
+ </div>
94
+
95
+ <div class="admin-stat-card uptime-system">
96
+ <div class="admin-stat-card__header">
97
+ <span class="admin-stat-card__title">
98
+ Uptime hệ thống
99
+ </span>
100
+ <div class="admin-stat-card__icon"></div>
101
+ </div>
102
+
103
+ <div class="admin-stat-card__body">
104
+ <h2 class="admin-stat-card__number">99.8%</h2>
105
+ <p class="admin-stat-card__description">
106
+ Hoạt động ổn định
107
+ </p>
108
+ </div>
109
+ </div>
110
+
111
+ <div class="admin-stat-card today-login">
112
+ <div class="admin-stat-card__header">
113
+ <span class="admin-stat-card__title">
114
+ Đăng nhập hôm nay
115
+ </span>
116
+ <div class="admin-stat-card__icon"></div>
117
+ </div>
118
+
119
+ <div class="admin-stat-card__body">
120
+ <h2 class="admin-stat-card__number">142</h2>
121
+ <p class="admin-stat-card__description">
122
+ Lượt đăng nhập
123
+ </p>
124
+ </div>
125
+ </div>
126
+
127
+ </section>
128
+
129
+
130
+
131
+ <!-- =====================
132
+ QUICK ACTION
133
+ ====================== -->
134
+ <section class="admin-quick-actions">
135
+
136
+ <a href="#" class="admin-action-card">
137
+ <span class="admin-action-card__badge">7</span>
138
+
139
+ <div class="admin-action-card__icon"></div>
140
+
141
+ <h3 class="admin-action-card__title">
142
+ Quản Lý Tài Khoản
143
+ </h3>
144
+
145
+ <p class="admin-action-card__description">
146
+ Thêm, sửa, xóa, khóa tài khoản
147
+ </p>
148
+ </a>
149
+
150
+ <a href="#" class="admin-action-card">
151
+
152
+ <div class="admin-action-card__icon"></div>
153
+
154
+ <h3 class="admin-action-card__title">
155
+ Quản Lý Phân Quyền
156
+ </h3>
157
+
158
+ <p class="admin-action-card__description">
159
+ Cấu hình vai trò và quyền hạn
160
+ </p>
161
+ </a>
162
+
163
+ <a href="#" class="admin-action-card">
164
+
165
+ <div class="admin-action-card__icon"></div>
166
+
167
+ <h3 class="admin-action-card__title">
168
+ Cài Đặt Hệ Thống
169
+ </h3>
170
+
171
+ <p class="admin-action-card__description">
172
+ Cấu hình chung
173
+ </p>
174
+ </a>
175
+
176
+ </section>
177
+
178
+
179
+
180
+ <!-- =====================
181
+ CHARTS
182
+ ====================== -->
183
+ <section class="admin-charts">
184
+
185
+ <!-- Pie Chart -->
186
+ <div class="admin-chart-card">
187
+
188
+ <div class="admin-chart-card__header">
189
+ <h2>Phân Bố Loại Tài Khoản</h2>
190
+ </div>
191
+
192
+ <div class="admin-chart-card__body">
193
+ <canvas id="accountTypeChart"></canvas>
194
+ </div>
195
+
196
+ </div>
197
+
198
+
199
+ <!-- Bar Chart -->
200
+ <div class="admin-chart-card">
201
+
202
+ <div class="admin-chart-card__header">
203
+ <h2>Hoạt Động Hệ Thống (6 Tháng)</h2>
204
+ </div>
205
+
206
+ <div class="admin-chart-card__body">
207
+ <canvas id="systemActivityChart"></canvas>
208
+ </div>
209
+
210
+ </div>
211
+
212
+ </section>
213
+
214
+
215
+
216
+ <!-- =====================
217
+ RECENT ACTIVITY
218
+ ====================== -->
219
+ <section class="recent-activity">
220
+
221
+ <div class="section-header">
222
+ <h2>Hoạt Động Gần Đây</h2>
223
+ </div>
224
+
225
+ <div class="activity-list">
226
+
227
+ <div class="activity-item">
228
+
229
+ <div class="activity-item__left">
230
+ <span class="activity-dot activity-dot--blue"></span>
231
+
232
+ <span class="activity-content">
233
+ <strong>NV007</strong>
234
+ Đăng ký tài khoản mới
235
+ </span>
236
+ </div>
237
+
238
+ <span class="activity-time">
239
+ 5 phút trước
240
+ </span>
241
+
242
+ </div>
243
+
244
+
245
+
246
+ <div class="activity-item">
247
+
248
+ <div class="activity-item__left">
249
+ <span class="activity-dot activity-dot--green"></span>
250
+
251
+ <span class="activity-content">
252
+ <strong>Admin</strong>
253
+ Phê duyệt tài khoản NV006
254
+ </span>
255
+ </div>
256
+
257
+ <span class="activity-time">
258
+ 1 giờ trước
259
+ </span>
260
+
261
+ </div>
262
+
263
+
264
+
265
+ <div class="activity-item">
266
+
267
+ <div class="activity-item__left">
268
+ <span class="activity-dot activity-dot--yellow"></span>
269
+
270
+ <span class="activity-content">
271
+ <strong>NV004</strong>
272
+ Đăng nhập thất bại (3 lần)
273
+ </span>
274
+ </div>
275
+
276
+ <span class="activity-time">
277
+ 2 giờ trước
278
+ </span>
279
+
280
+ </div>
281
+
282
+
283
+
284
+ <div class="activity-item">
285
+
286
+ <div class="activity-item__left">
287
+ <span class="activity-dot activity-dot--red"></span>
288
+
289
+ <span class="activity-content">
290
+ <strong>Admin</strong>
291
+ Khóa tài khoản NV003
292
+ </span>
293
+ </div>
294
+
295
+ <span class="activity-time">
296
+ 3 giờ trước
297
+ </span>
298
+
299
+ </div>
300
+
301
+ </div>
302
+
303
+ </section>
304
+
305
+ </main>
306
+
307
+ </div>
308
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
309
+ </body>
310
+
311
+ </html>
src/main/resources/templates/cms/dashboard/dashboard-employee.html ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+
3
+ <html xmlns:th="http://www.thymeleaf.org">
4
+
5
+ <head>
6
+ <meta charset="UTF-8" />
7
+ <title>Danh sách thế giới</title>
8
+ <link rel="stylesheet" th:href="@{/css/world/world.css}">
9
+
10
+ </head>
11
+
12
+ <body>
13
+ <div class="bg-image"></div>
14
+ <div th:replace="~{cms/fragments/sidebar-employee :: sidebar}"></div>
15
+
16
+ <div class="container-layout">
17
+ <header class="page-header">
18
+ <h1>Dashboard</h1>
19
+
20
+ <div class="notification">
21
+ <i class="fa-regular fa-bell"></i>
22
+ <span class="dot"></span>
23
+ </div>
24
+ </header>
25
+
26
+ <main class="dashboard-employee">
27
+
28
+
29
+ <!-- ======================
30
+ THỐNG KÊ
31
+ ======================= -->
32
+ <section class="employee-overview">
33
+
34
+ <div class="employee-stat-card report-submitted">
35
+ <div class="employee-stat-card__icon"></div>
36
+
37
+ <div class="employee-stat-card__content">
38
+ <h3 class="employee-stat-card__number">12</h3>
39
+ <p class="employee-stat-card__label">Báo cáo đã nộp</p>
40
+ </div>
41
+
42
+ <span class="employee-stat-card__trend">↗</span>
43
+ </div>
44
+
45
+ <div class="employee-stat-card report-approved">
46
+ <div class="employee-stat-card__icon"></div>
47
+
48
+ <div class="employee-stat-card__content">
49
+ <h3 class="employee-stat-card__number">10</h3>
50
+ <p class="employee-stat-card__label">Báo cáo được duyệt</p>
51
+ </div>
52
+ </div>
53
+
54
+ <div class="employee-stat-card report-rejected">
55
+ <div class="employee-stat-card__icon"></div>
56
+
57
+ <div class="employee-stat-card__content">
58
+ <h3 class="employee-stat-card__number">1</h3>
59
+ <p class="employee-stat-card__label">Báo cáo bị từ chối</p>
60
+ </div>
61
+ </div>
62
+
63
+ <div class="employee-stat-card attendance-rate">
64
+ <div class="employee-stat-card__icon"></div>
65
+
66
+ <div class="employee-stat-card__content">
67
+ <h3 class="employee-stat-card__number">95%</h3>
68
+ <p class="employee-stat-card__label">Tỷ lệ chuyên cần</p>
69
+ </div>
70
+
71
+ <span class="employee-stat-card__status">
72
+ Xuất sắc
73
+ </span>
74
+ </div>
75
+
76
+ </section>
77
+
78
+
79
+
80
+ <!-- ======================
81
+ NỘI DUNG CHÍNH
82
+ ======================= -->
83
+ <section class="employee-content">
84
+
85
+ <!-- LEFT -->
86
+ <div class="employee-main">
87
+
88
+ <!-- Quick Action -->
89
+ <div class="quick-actions">
90
+
91
+ <h2 class="section-title">
92
+ Thao Tác Nhanh
93
+ </h2>
94
+
95
+ <div class="quick-actions-grid">
96
+
97
+ <a href="#" class="quick-action-card">
98
+ <div class="quick-action-card__icon"></div>
99
+
100
+ <h3>Thông Tin Cá Nhân</h3>
101
+ <p>Xem và cập nhật profile</p>
102
+ </a>
103
+
104
+ <a href="#" class="quick-action-card">
105
+ <div class="quick-action-card__icon"></div>
106
+
107
+ <h3>Nộp Báo Cáo</h3>
108
+ <p>Tạo báo cáo công việc</p>
109
+ </a>
110
+
111
+ <a href="#" class="quick-action-card">
112
+ <div class="quick-action-card__icon"></div>
113
+
114
+ <h3>Lịch Sử Điểm Danh</h3>
115
+ <p>Xem lịch sử check-in/out</p>
116
+ </a>
117
+
118
+ <a href="#" class="quick-action-card">
119
+ <div class="quick-action-card__icon"></div>
120
+
121
+ <h3>Xin Nghỉ Phép</h3>
122
+ <p>Tạo đơn xin nghỉ</p>
123
+ </a>
124
+
125
+ </div>
126
+
127
+ </div>
128
+
129
+
130
+
131
+ <!-- Attendance History -->
132
+ <div class="attendance-history">
133
+
134
+ <h2 class="section-title">
135
+ Lịch Sử Điểm Danh Gần Đây
136
+ </h2>
137
+
138
+ <div class="table-wrapper">
139
+
140
+ <table class="attendance-table">
141
+
142
+ <thead>
143
+ <tr>
144
+ <th>Ngày</th>
145
+ <th>Check In</th>
146
+ <th>Check Out</th>
147
+ <th>Trạng Thái</th>
148
+ </tr>
149
+ </thead>
150
+
151
+ <tbody>
152
+
153
+ <tr>
154
+ <td>2/6/2026</td>
155
+ <td>07:58</td>
156
+ <td>17:05</td>
157
+ <td>
158
+ <span class="status-badge status-success">
159
+ Đúng giờ
160
+ </span>
161
+ </td>
162
+ </tr>
163
+
164
+ <tr>
165
+ <td>1/6/2026</td>
166
+ <td>08:12</td>
167
+ <td>17:02</td>
168
+ <td>
169
+ <span class="status-badge status-warning">
170
+ Đi muộn
171
+ </span>
172
+ </td>
173
+ </tr>
174
+
175
+ <tr>
176
+ <td>31/5/2026</td>
177
+ <td>08:00</td>
178
+ <td>17:00</td>
179
+ <td>
180
+ <span class="status-badge status-success">
181
+ Đúng giờ
182
+ </span>
183
+ </td>
184
+ </tr>
185
+
186
+ <tr>
187
+ <td>30/5/2026</td>
188
+ <td>07:55</td>
189
+ <td>16:45</td>
190
+ <td>
191
+ <span class="status-badge status-danger">
192
+ Về sớm
193
+ </span>
194
+ </td>
195
+ </tr>
196
+
197
+ </tbody>
198
+
199
+ </table>
200
+
201
+ </div>
202
+
203
+ </div>
204
+
205
+ </div>
206
+
207
+
208
+
209
+ <!-- RIGHT -->
210
+ <aside class="employee-sidebar">
211
+
212
+ <!-- Profile -->
213
+ <div class="profile-card">
214
+
215
+ <h2 class="profile-card__title">
216
+ Thông Tin Cá Nhân
217
+ </h2>
218
+
219
+ <div class="profile-item">
220
+ <label>Email</label>
221
+ <span>nguyenvana@company.com</span>
222
+ </div>
223
+
224
+ <div class="profile-item">
225
+ <label>Số điện thoại</label>
226
+ <span>0123456789</span>
227
+ </div>
228
+
229
+ <div class="profile-item">
230
+ <label>Phòng ban</label>
231
+ <span>IT Department</span>
232
+ </div>
233
+
234
+ <div class="profile-item">
235
+ <label>Face ID</label>
236
+
237
+ <span class="faceid-badge">
238
+ ✓ Đã đăng ký
239
+ </span>
240
+ </div>
241
+
242
+ <button class="btn-update-profile">
243
+ Cập nhật thông tin
244
+ </button>
245
+
246
+ </div>
247
+
248
+
249
+
250
+ <!-- Reminder -->
251
+ <div class="reminder-card">
252
+
253
+ <div class="reminder-card__header">
254
+ 💡 Lời nhắc
255
+ </div>
256
+
257
+ <p class="reminder-card__content">
258
+ Nhớ nộp báo cáo công việc hàng tuần
259
+ trước 17:00 thứ 6.
260
+ </p>
261
+
262
+ </div>
263
+
264
+ </aside>
265
+
266
+ </section>
267
+
268
+ </main>
269
+
270
+ </div>
271
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
272
+ </body>
273
+
274
+ </html>
src/main/resources/templates/cms/dashboard/dashboard-manage.html ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+
3
+ <html xmlns:th="http://www.thymeleaf.org">
4
+
5
+ <head>
6
+ <meta charset="UTF-8" />
7
+ <title>Danh sách thế giới</title>
8
+ <link rel="stylesheet" th:href="@{/css/world/world.css}">
9
+
10
+ </head>
11
+
12
+ <body>
13
+ <div class="bg-image"></div>
14
+ <div th:replace="~{cms/fragments/sidebar-manage :: sidebar}"></div>
15
+
16
+ <div class="container-layout">
17
+ <header class="page-header">
18
+ <h1>Dashboard</h1>
19
+
20
+ <div class="notification">
21
+ <i class="fa-regular fa-bell"></i>
22
+ <span class="dot"></span>
23
+ </div>
24
+ </header>
25
+
26
+ <main class="dashboard-manager">
27
+
28
+ <!-- ======================
29
+ THỐNG KÊ TỔNG QUAN
30
+ ======================= -->
31
+ <section class="dashboard-overview">
32
+
33
+ <div class="stat-card total-employee">
34
+ <div class="stat-card__icon"></div>
35
+
36
+ <div class="stat-card__content">
37
+ <h3 class="stat-card__number">50</h3>
38
+ <p class="stat-card__label">Tổng nhân viên</p>
39
+ </div>
40
+ </div>
41
+
42
+ <div class="stat-card present">
43
+ <div class="stat-card__icon"></div>
44
+
45
+ <div class="stat-card__content">
46
+ <h3 class="stat-card__number">42</h3>
47
+ <p class="stat-card__label">Có mặt hôm nay</p>
48
+ </div>
49
+
50
+ <span class="stat-card__percent">84%</span>
51
+ </div>
52
+
53
+ <div class="stat-card late">
54
+ <div class="stat-card__icon"></div>
55
+
56
+ <div class="stat-card__content">
57
+ <h3 class="stat-card__number">8</h3>
58
+ <p class="stat-card__label">Đi muộn hôm nay</p>
59
+ </div>
60
+ </div>
61
+
62
+ <div class="stat-card absent">
63
+ <div class="stat-card__icon"></div>
64
+
65
+ <div class="stat-card__content">
66
+ <h3 class="stat-card__number">10</h3>
67
+ <p class="stat-card__label">Vắng mặt hôm nay</p>
68
+ </div>
69
+ </div>
70
+
71
+ </section>
72
+
73
+
74
+
75
+ <!-- ======================
76
+ NỘI DUNG CHÍNH
77
+ ======================= -->
78
+ <section class="dashboard-content">
79
+
80
+ <!-- LEFT -->
81
+ <div class="dashboard-main">
82
+
83
+ <!-- Biểu đồ cột -->
84
+ <div class="dashboard-card attendance-chart">
85
+
86
+ <div class="card-header">
87
+ <h2>Chuyên Cần Tuần Này</h2>
88
+ </div>
89
+
90
+ <div class="card-body">
91
+
92
+ <!-- ChartJS -->
93
+ <canvas id="weeklyAttendanceChart"></canvas>
94
+
95
+ </div>
96
+
97
+ </div>
98
+
99
+
100
+
101
+ <!-- Biểu đồ tròn -->
102
+ <div class="dashboard-card attendance-distribution">
103
+
104
+ <div class="card-header">
105
+ <h2>Phân Bổ Chuyên Cần</h2>
106
+ </div>
107
+
108
+ <div class="card-body">
109
+
110
+ <div class="distribution-layout">
111
+
112
+ <div class="distribution-chart">
113
+ <canvas id="attendancePieChart"></canvas>
114
+ </div>
115
+
116
+ <div class="distribution-legend">
117
+
118
+ <div class="legend-item">
119
+ <span class="legend-color green"></span>
120
+ <span class="legend-label">Đúng giờ</span>
121
+ <span class="legend-value">75%</span>
122
+ </div>
123
+
124
+ <div class="legend-item">
125
+ <span class="legend-color yellow"></span>
126
+ <span class="legend-label">Đi muộn</span>
127
+ <span class="legend-value">18%</span>
128
+ </div>
129
+
130
+ <div class="legend-item">
131
+ <span class="legend-color red"></span>
132
+ <span class="legend-label">Vắng mặt</span>
133
+ <span class="legend-value">7%</span>
134
+ </div>
135
+
136
+ </div>
137
+
138
+ </div>
139
+
140
+ </div>
141
+
142
+ </div>
143
+
144
+ </div>
145
+
146
+
147
+
148
+ <!-- RIGHT -->
149
+ <aside class="dashboard-sidebar">
150
+
151
+ <a href="#" class="action-card">
152
+ <div class="action-card__badge">3</div>
153
+
154
+ <div class="action-card__icon"></div>
155
+
156
+ <div class="action-card__content">
157
+ <h3>Duyệt Face ID</h3>
158
+ <p>Phê duyệt đăng ký Face ID</p>
159
+ </div>
160
+ </a>
161
+
162
+
163
+ <a href="#" class="action-card">
164
+ <div class="action-card__badge">5</div>
165
+
166
+ <div class="action-card__icon"></div>
167
+
168
+ <div class="action-card__content">
169
+ <h3>Duyệt Nghỉ Phép</h3>
170
+ <p>Phê duyệt đơn xin nghỉ</p>
171
+ </div>
172
+ </a>
173
+
174
+
175
+ <a href="#" class="action-card">
176
+ <div class="action-card__badge">7</div>
177
+
178
+ <div class="action-card__icon"></div>
179
+
180
+ <div class="action-card__content">
181
+ <h3>Quản Lý Báo Cáo</h3>
182
+ <p>Duyệt báo cáo nhân viên</p>
183
+ </div>
184
+ </a>
185
+
186
+
187
+ <a href="#" class="action-card">
188
+ <div class="action-card__icon"></div>
189
+
190
+ <div class="action-card__content">
191
+ <h3>Quản Lý Nhân Viên</h3>
192
+ <p>Xem danh sách nhân viên</p>
193
+ </div>
194
+ </a>
195
+
196
+
197
+ <a href="#" class="action-card">
198
+ <div class="action-card__icon"></div>
199
+
200
+ <div class="action-card__content">
201
+ <h3>Báo Cáo Điểm Danh</h3>
202
+ <p>Xem báo cáo chi tiết</p>
203
+ </div>
204
+ </a>
205
+
206
+ </aside>
207
+
208
+ </section>
209
+
210
+ </main>
211
+
212
+ </div>
213
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
214
+ </body>
215
+
216
+ </html>
src/main/resources/templates/cms/documents/document-create.html ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="vi">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+ <title>Báo cáo công việc</title>
8
+ <link rel="stylesheet" href="style.css">
9
+ </head>
10
+
11
+ <body>
12
+ <div class="bg-image"></div>
13
+ <div th:replace="~{cms/fragments/sidebar-employee :: sidebar}"></div>
14
+
15
+ <div class="container-layout">
16
+ <header class="page-header">
17
+ <h1>Nộp báo cáo công việc</h1>
18
+
19
+ <div class="notification">
20
+ <i class="fa-regular fa-bell"></i>
21
+ <span class="dot"></span>
22
+ </div>
23
+ </header>
24
+
25
+
26
+ <div class="report-card">
27
+
28
+ <h2>Gửi báo cáo công việc</h2>
29
+
30
+ <form>
31
+
32
+ <!-- Nội dung -->
33
+ <div class="form-group">
34
+ <label>Nội dung báo cáo</label>
35
+ <textarea placeholder="Nhập nội dung báo cáo công việc của bạn..."></textarea>
36
+ </div>
37
+
38
+ <!-- Upload file -->
39
+ <div class="form-group">
40
+ <label>Tệp đính kèm</label>
41
+
42
+ <label class="upload-box">
43
+ <input type="file" multiple>
44
+ <span>📎 Chọn file hoặc kéo thả vào đây</span>
45
+ <small>
46
+ Hỗ trợ PDF, DOCX, XLSX, JPG, PNG, ZIP
47
+ </small>
48
+ </label>
49
+ </div>
50
+
51
+ <!-- Link tài liệu -->
52
+ <div class="form-group">
53
+ <label>Hoặc đính kèm liên kết</label>
54
+
55
+ <input type="url" placeholder="https://drive.google.com/..." class="link-input">
56
+ </div>
57
+
58
+ <button type="submit" class="submit-btn">
59
+ ✈ Gửi báo cáo
60
+ </button>
61
+
62
+ </form>
63
+
64
+ </div>
65
+
66
+ </div>
67
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
68
+
69
+ </body>
70
+
71
+ </html>
src/main/resources/templates/cms/documents/document-detail.html ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div id="reportModal" class="modal">
2
+
3
+ <div class="modal-content">
4
+
5
+ <span class="close-btn">&times;</span>
6
+
7
+ <h2 id="modalTitle"></h2>
8
+
9
+ <p>
10
+ <strong>Nhân viên:</strong>
11
+ <span id="modalEmployee"></span>
12
+ </p>
13
+
14
+ <p>
15
+ <strong>Ngày nộp:</strong>
16
+ <span id="modalDate"></span>
17
+ </p>
18
+
19
+ <div class="report-detail">
20
+ <strong>Nội dung:</strong>
21
+ <p id="modalContent"></p>
22
+ </div>
23
+
24
+ </div>
25
+
26
+ </div>
src/main/resources/templates/cms/documents/document-list.html ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+
3
+ <html xmlns:th="http://www.thymeleaf.org">
4
+
5
+ <head>
6
+ <meta charset="UTF-8" />
7
+ <title>Danh sách báo cáo</title>
8
+ <link rel="stylesheet" th:href="@{/css/world/world.css}">
9
+
10
+ </head>
11
+
12
+ <body>
13
+ <div class="bg-image"></div>
14
+ <div th:replace="~{cms/fragments/sidebar :: sidebar}"></div>
15
+
16
+ <div class="container-layout">
17
+ <div class="absent-header">
18
+ <h1 class="header-title">Danh sách báo cáo</h1>
19
+ <div class="header-divider"></div>
20
+ </div>
21
+
22
+ <main class="main-section">
23
+
24
+ <div class="document-card">
25
+
26
+ <div class="main-document">
27
+
28
+ <table class="document-table">
29
+ <thead>
30
+ <tr>
31
+ <th>Nhân viên</th>
32
+ <th>Tiêu đề</th>
33
+ <th>Ngày nộp</th>
34
+ <th>File đính kèm</th>
35
+ <th>Link tài liệu</th>
36
+ <th>Trạng thái</th>
37
+ <th>Chi tiết</th>
38
+ <th>Thao tác</th>
39
+ </tr>
40
+ </thead>
41
+
42
+ <tbody>
43
+
44
+ <tr >
45
+
46
+ <td ">
47
+ Nguyễn Văn A
48
+ </td>
49
+
50
+ <td >
51
+ Báo cáo tuần 01
52
+ </td>
53
+
54
+ <td >
55
+ 15/02/2025
56
+ </td>
57
+
58
+ <td>
59
+ <a
60
+ class="file-link">
61
+ 📎 Tải file
62
+ </a>
63
+
64
+ <span >
65
+ Không có
66
+ </span>
67
+ </td>
68
+
69
+ <td>
70
+ <a
71
+ target="_blank" class="file-link">
72
+ 🔗 Mở link
73
+ </a>
74
+
75
+ <span >
76
+ Không có
77
+ </span>
78
+ </td>
79
+
80
+ <td>
81
+
82
+ <span th:if="${report.status == 'PENDING'}" class="status-pending">
83
+ Chờ duyệt
84
+ </span>
85
+
86
+ <span th:if="${report.status == 'APPROVED'}" class="status-approved">
87
+ Đã duyệt
88
+ </span>
89
+
90
+ <span th:if="${report.status == 'REJECTED'}" class="status-rejected">
91
+ Từ chối
92
+ </span>
93
+
94
+ </td>
95
+
96
+ <td>
97
+ <a class="btn btn-detail">
98
+ Xem
99
+ </a>
100
+ </td>
101
+
102
+ <td>
103
+
104
+ <div class="action-group" th:if="${report.status == 'PENDING'}">
105
+
106
+ <form method="post">
107
+
108
+ <button class="btn btn-success">
109
+ Duyệt
110
+ </button>
111
+
112
+ </form>
113
+
114
+ <form method="post">
115
+
116
+ <button class="btn btn-danger">
117
+ Từ chối
118
+ </button>
119
+
120
+ </form>
121
+
122
+ </div>
123
+
124
+ </td>
125
+
126
+ </tr>
127
+
128
+ </tbody>
129
+ </table>
130
+ </div>
131
+
132
+
133
+ <div class="pagination">
134
+ <a class="btn btn-pagination">
135
+ ← Trước
136
+ </a>
137
+
138
+ <span>
139
+ <a></a>
140
+ <span></span>
141
+ </span>
142
+
143
+ <a class="btn btn-pagination">
144
+ Sau →
145
+ </a>
146
+ </div>
147
+ </div>
148
+
149
+ </main>
150
+
151
+ </div>
152
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
153
+ </body>
154
+
155
+ </html>
src/main/resources/templates/cms/face-id/faceID-create.html ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ```html
2
+ <!DOCTYPE html>
3
+ <html lang="vi">
4
+
5
+ <head>
6
+ <meta charset="UTF-8">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <title>Face Recognition Dashboard</title>
9
+
10
+ <link rel="stylesheet" href="style.css">
11
+
12
+ </head>
13
+
14
+ <body>
15
+ <div class="bg-image"></div>
16
+ <div th:replace="~{cms/fragments/sidebar-employee :: sidebar}"></div>
17
+
18
+ <div class="container-layout">
19
+ <header class="page-header">
20
+ <h1>Nộp báo cáo công việc</h1>
21
+
22
+ <div class="notification">
23
+ <i class="fa-regular fa-bell"></i>
24
+ <span class="dot"></span>
25
+ </div>
26
+ </header>
27
+ <!-- FACE REGISTER -->
28
+ <section class="card">
29
+
30
+ <div class="section-header">
31
+ <h2>Đăng ký khuôn mặt</h2>
32
+ </div>
33
+
34
+ <div class="student-select">
35
+
36
+ <label>Sinh viên</label>
37
+
38
+ <select id="faceStudentSelect">
39
+ <option>Chọn sinh viên</option>
40
+ </select>
41
+
42
+ <button id="faceSampleCount" class="sample-btn">
43
+ 0 / 10 mẫu
44
+ </button>
45
+
46
+ </div>
47
+
48
+ <div class="face-register-grid">
49
+
50
+ <!-- CAMERA -->
51
+ <div class="panel">
52
+
53
+ <div class="panel-header">
54
+ <h3>Camera đăng ký</h3>
55
+
56
+ <button id="faceRegisterToggleBtn">
57
+ Bật camera
58
+ </button>
59
+ </div>
60
+
61
+ <div class="mode-tabs">
62
+
63
+ <button class="active">
64
+ Thêm mẫu
65
+ </button>
66
+
67
+ <button>
68
+ Quét lại
69
+ </button>
70
+
71
+ </div>
72
+
73
+ <div class="guide-box">
74
+
75
+ <div id="scanGuideCurrent">
76
+ Nhìn thẳng vào camera
77
+ </div>
78
+
79
+ <div id="scanGuideSteps">
80
+ Bước 1 / 5
81
+ </div>
82
+
83
+ </div>
84
+
85
+ <div class="video-wrap">
86
+ <video autoplay muted></video>
87
+ <canvas></canvas>
88
+ </div>
89
+
90
+ <div class="action-row">
91
+
92
+ <button>
93
+ 📷 Chụp mẫu
94
+ </button>
95
+
96
+ <button class="secondary">
97
+ Làm lại
98
+ </button>
99
+
100
+ </div>
101
+
102
+ </div>
103
+
104
+ <!-- UPLOAD -->
105
+ <div class="panel">
106
+
107
+ <div class="panel-header">
108
+ <h3>Thêm ảnh từ máy</h3>
109
+ </div>
110
+
111
+ <input type="file" multiple accept="image/*">
112
+
113
+ <button class="upload-btn">
114
+ Upload ảnh
115
+ </button>
116
+
117
+ <div class="info-box">
118
+ Ảnh cần chứa đúng 1 khuôn mặt, rõ nét và đủ sáng.
119
+ </div>
120
+
121
+ </div>
122
+
123
+ </div>
124
+
125
+ </section>
126
+
127
+ <!-- REALTIME CAMERA -->
128
+
129
+ <section class="card">
130
+
131
+ <div class="section-header">
132
+ <h2>Điểm danh Realtime</h2>
133
+ </div>
134
+
135
+ <div class="camera-actions">
136
+
137
+ <button>
138
+ Check In ON
139
+ </button>
140
+
141
+ <button>
142
+ Check Out ON
143
+ </button>
144
+
145
+ <button class="secondary">
146
+ Tắt tất cả
147
+ </button>
148
+
149
+ </div>
150
+
151
+ <div class="dual-camera-grid">
152
+
153
+ <div class="camera-panel">
154
+
155
+ <div class="camera-panel-header">
156
+ <h3>Check In</h3>
157
+ <span>Đang tắt</span>
158
+ </div>
159
+
160
+ <div class="video-wrap">
161
+ <video autoplay muted></video>
162
+ <canvas></canvas>
163
+ </div>
164
+
165
+ <div class="camera-result">
166
+ Chưa bật camera
167
+ </div>
168
+
169
+ </div>
170
+
171
+ <div class="camera-panel">
172
+
173
+ <div class="camera-panel-header">
174
+ <h3>Check Out</h3>
175
+ <span>Đang tắt</span>
176
+ </div>
177
+
178
+ <div class="video-wrap">
179
+ <video autoplay muted></video>
180
+ <canvas></canvas>
181
+ </div>
182
+
183
+ <div class="camera-result">
184
+ Chưa bật camera
185
+ </div>
186
+
187
+ </div>
188
+
189
+ </div>
190
+
191
+ </section>
192
+
193
+ </div>
194
+
195
+ </body>
196
+
197
+ </html>
src/main/resources/templates/cms/face-id/faceID-list.html ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <section class="page">
2
+
3
+ <div class="card">
4
+
5
+ <div class="card-header">
6
+ <h2>Danh sách Face ID</h2>
7
+
8
+ <input
9
+ type="text"
10
+ placeholder="Tìm kiếm sinh viên..."
11
+ class="search-input">
12
+ </div>
13
+
14
+ <table class="face-table">
15
+
16
+ <thead>
17
+ <tr>
18
+ <th>Mã SV</th>
19
+ <th>Họ tên</th>
20
+ <th>Face ID</th>
21
+ <th>Số mẫu</th>
22
+ <th>Phòng</th>
23
+ <th>Cập nhật</th>
24
+ <th>Chi tiết</th>
25
+ </tr>
26
+ </thead>
27
+
28
+ <tbody>
29
+
30
+ <tr>
31
+ <td>SV001</td>
32
+ <td>Nguyễn Văn A</td>
33
+ <td>#face_001</td>
34
+ <td>
35
+ <span class="sample-badge">
36
+ 10 / 10
37
+ </span>
38
+ </td>
39
+ <td>21/02/2025</td>
40
+
41
+ <td>
42
+ <button
43
+ class="detail-btn"
44
+ onclick="openFaceGallery()">
45
+
46
+ Xem ảnh
47
+
48
+ </button>
49
+ </td>
50
+ </tr>
51
+
52
+ <tr>
53
+ <td>SV002</td>
54
+ <td>Trần Văn B</td>
55
+ <td>#face_002</td>
56
+ <td>
57
+ <span class="sample-badge">
58
+ 7 / 10
59
+ </span>
60
+ </td>
61
+ <td>DE214</td>
62
+ <td>20/02/2025</td>
63
+
64
+ <td>
65
+ <button
66
+ class="detail-btn"
67
+ onclick="openFaceGallery()">
68
+
69
+ Xem ảnh
70
+
71
+ </button>
72
+ </td>
73
+ </tr>
74
+
75
+ </tbody>
76
+
77
+ </table>
78
+
79
+ </div>
80
+
81
+ </section>
src/main/resources/templates/cms/homaPage.jsp ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html xmlns:th="http://www.thymeleaf.org">
3
+
4
+ <head>
5
+ <meta charset="UTF-8">
6
+ <title>Dashboard</title>
7
+
8
+ <link rel="stylesheet" th:href="@{/css/dashboard-user.css}">
9
+ </head>
10
+
11
+ <body>
12
+
13
+ <!-- Background -->
14
+ <div class="bg-image"></div>
15
+
16
+ <div th:replace="~{cms/layouts/header :: header}"></div>
17
+
18
+ <div class="layout">
19
+
20
+
21
+ <main class="section">
22
+
23
+ <div class="container-xl">
24
+
25
+ <div class="section-header">
26
+ <div class="header-left">
27
+ <div class="section-eyebrow">
28
+ SMART ATTENDANCE
29
+ </div>
30
+
31
+ <div class="section-title">
32
+ SYSTEM
33
+ </div>
34
+
35
+ <div class="section-divider"></div>
36
+
37
+ <p class="section-subtitle">
38
+ Giải pháp điểm danh Face ID thông minh cho doanh nghiệp và cơ sở giáo dục.
39
+ Quản lý hiệu quả, chính xác và an toàn
40
+ </p>
41
+
42
+ <a href="" class="btn btn-primary">Bắt đầu ngay</a>
43
+ <a href="" class="btn btn-secondery">
44
+ Xem Demo
45
+ </a>
46
+ </div>
47
+
48
+ <div class="header-right">
49
+ <div class="right-box">
50
+ <div class="grid grid-cols-2 gap-4">
51
+ <div class="header-form">
52
+ <i data-lucide="users" class="form-icon"></i>
53
+ <div class="form-line">5000+</div>
54
+ <div class="form-text">Người dùng</div>
55
+ </div>
56
+ <div class="header-form">
57
+ <i data-lucide="target" class="form-icon"></i>
58
+ <div class="form-line">99.8%</div>
59
+ <div class="form-text">Độ chính xác</div>
60
+ </div>
61
+ <div class="header-form">
62
+ <i data-lucide="building-2" class="form-icon"></i>
63
+ <div class="form-line">50+</div>
64
+ <div class="form-text">Đơn vị</div>
65
+ </div>
66
+ <div class="header-form">
67
+ <i data-lucide="clock" class="form-icon"></i>
68
+ <div class="form-line">24/7</div>
69
+ <div class="form-text">Hoạt động</div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ </div>
74
+ </div>
75
+
76
+ <!-- Home body -->
77
+ <div class="section-body">
78
+ <div class="body-bg">
79
+ <div class="body-header">
80
+ <h2 class="header-title">Tính năng nổi bật</h2>
81
+ <p class="section-subtitle">Giải pháp toàn diện cho quản lý điểm danh</p>
82
+ </div>
83
+ <div class="body-container">
84
+ <div class="container-box">
85
+ <div class="container-icon">
86
+ <i data-lucide="camera" class="icon"></i>
87
+ </div>
88
+ <h3 class="container-title">Face Recognition</h3>
89
+ <p class="container-text">Nhận diện khuôn mặt chính xác với AI, chống
90
+ điểm danh hộ</p>
91
+ </div>
92
+ <div class="container-box">
93
+ <div class="container-icon">
94
+ <i data-lucide="bar-chart-3" class="icon"></i>
95
+ </div>
96
+ <h3 class="container-title">Analytics Dashboard</h3>
97
+ <p class="container-text">Thống kê realtime, biểu đồ trực quan, báo cáo
98
+ chi tiết</p>
99
+ </div>
100
+ <div class="container-box">
101
+ <div class="container-icon">
102
+ <i data-lucide="file-text" class="icon"></i>
103
+ </div>
104
+ <h3 class="container-title">Report Management</h3>
105
+ <p class="container-text">Quản lý báo cáo công việc hằng ngày và cuối
106
+ tuần</p>
107
+ </div>
108
+ <div class="container-box">
109
+ <div class="container-icon">
110
+ <i data-lucide="calendar" class="icon"></i>
111
+ </div>
112
+ <h3 class="container-title">Leave Management</h3>
113
+ <p class="container-text">Xin nghỉ phép, duyệt đơn, theo dõi lịch sử
114
+ nghỉ</p>
115
+ </div>
116
+ </div>
117
+ </div>
118
+ </div>
119
+
120
+ </div>
121
+ </main>
122
+ </div>
123
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
124
+
125
+ </body>
126
+
127
+ </html>
src/main/resources/templates/cms/layouts/footer.html ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <footer>
2
+ <div class="footer-layout">
3
+ <div class="footer-left">
4
+ <h2 class="left-title">Smart Attendance</h2>
5
+ <div class="left-description">Hệ thống điểm danh thông minh</div>
6
+ </div>
7
+ <div class="footer-right">
8
+ <div class="right-title">Thông tin liên hệ</div>
9
+ <a href="" class="right-description">Liên hệ với chúng tôi</a>
10
+ <a href="" class="right-description">Báo cáo lỗi</a>
11
+
12
+ </div>
13
+ </div>
14
+
15
+ </footer>
src/main/resources/templates/cms/layouts/header.html ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <header class="header-layout">
2
+ <div class="header-container">
3
+ <div class="header-left">
4
+ <h3 class="header-title">Smart Attendance</h3>
5
+ </div>
6
+ <div class="header-right">
7
+ <div class="change-light">
8
+ <button>Icon</button>
9
+ </div>
10
+ <div class="header-auth">
11
+ <div class="btn btn-register">Đăng ký</div>
12
+ <div class="btn btn-login">Đăng nhập</div>
13
+ </div>
14
+ <div class="user-dropdown">
15
+ <summary class="user-summary">
16
+ <span th:text="${#authentication.name}"></span>
17
+ <span class="arrow">▾</span>
18
+ </summary>
19
+
20
+ <div class="dropdown-menu">
21
+ <a th:href="@{/user/moonblight/change-password}">
22
+ 🔒 Đổi mật khẩu
23
+ </a>
24
+
25
+ <form th:action="@{/user/moonblight/logout}" method="post">
26
+ <button type="submit">
27
+ 🚪 Logout
28
+ </button>
29
+ </form>
30
+ </div>
31
+ </div>
32
+
33
+ </div>
34
+ </div>
35
+ <script>
36
+ document.addEventListener('click', function (e) {
37
+ const dropdown = document.querySelector('.user-dropdown');
38
+
39
+ if (!dropdown.contains(e.target)) {
40
+ dropdown.removeAttribute('open');
41
+ }
42
+ });
43
+ </script>
44
+ </header>
src/main/resources/templates/cms/password/change-password.html ADDED
File without changes
src/main/resources/templates/cms/password/forgot-password.html ADDED
File without changes
src/main/resources/templates/cms/reports/report-day.html ADDED
File without changes
src/main/resources/templates/cms/reports/report-month.html ADDED
File without changes
src/main/resources/templates/cms/sidebar/sidebar-admin.html ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="sidebar">
2
+
3
+ <div class="sidebar-header">
4
+ <i class="sidebar-icon"></i>
5
+ <h2> Smart Attendance</h2>
6
+ <div class="header-description">Quản lý</div>
7
+ </div>
8
+ <div class="sidebar-line"></div>
9
+
10
+ <ul class="sidebar-menu">
11
+
12
+ <li class="sidebar-option">
13
+ <i class="icon"></i>
14
+ <a class="sidebar-link">
15
+ Dashboard
16
+ </a>
17
+ </li>
18
+
19
+ <li class="sidebar-option">
20
+ <i class="icon"></i>
21
+ <a class="sidebar-link">
22
+ Quản lý tài khoản
23
+ </a>
24
+ </li>
25
+
26
+ <li class="sidebar-option">
27
+ <i class="icon"></i>
28
+ <a class="sidebar-link">
29
+ Đơn xét duyệt báo cáo
30
+ </a>
31
+ </li>
32
+ <li class="sidebar-option">
33
+ <i class="icon"></i>
34
+ <a class="sidebar-link">
35
+ Đổi mật khẩu
36
+ </a>
37
+ </li>
38
+
39
+ </ul>
40
+ <div class="sidebar-line"></div>
41
+ <div class="sidebar-footer">
42
+ <div class="footer-user">
43
+ <i class="sidebar-icon"></i>
44
+ <h3> Smart Attendance</h3>
45
+ <div class="header-description">Admin</div>
46
+ </div>
47
+ <div class="logout">
48
+ <i class="logout-icon"></i>
49
+ <div class="logout-text">Đăng xuất</div>
50
+ </div>
51
+ </div>
52
+ </div>
src/main/resources/templates/cms/sidebar/sidebar-employee.html ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="sidebar">
2
+
3
+ <div class="sidebar-header">
4
+ <i class="sidebar-icon"></i>
5
+ <h2> Smart Attendance</h2>
6
+ <div class="header-description">Nhân viên</div>
7
+ </div>
8
+ <div class="sidebar-line"></div>
9
+
10
+ <ul class="sidebar-menu">
11
+
12
+ <li class="sidebar-option">
13
+ <i class="icon"></i>
14
+ <a class="sidebar-link">
15
+ Dashboard
16
+ </a>
17
+ </li>
18
+
19
+ <li class="sidebar-option">
20
+ <i class="icon"></i>
21
+ <a class="sidebar-link">
22
+ Quản lý điểm danh
23
+ </a>
24
+ </li>
25
+
26
+ <li class="sidebar-option">
27
+ <i class="icon"></i>
28
+ <a class="sidebar-link">
29
+ Đăng kí nghỉ phép
30
+ </a>
31
+ </li>
32
+ <li class="sidebar-option">
33
+ <i class="icon"></i>
34
+ <a class="sidebar-link">
35
+ Đăng kí Face ID
36
+ </a>
37
+ </li>
38
+ <li class="sidebar-option">
39
+ <i class="icon"></i>
40
+ <a class="sidebar-link">
41
+ Nộp báo cáo
42
+ </a>
43
+ </li>
44
+ <li class="sidebar-option">
45
+ <i class="icon"></i>
46
+ <a class="sidebar-link">
47
+ Thông tin cá nhân
48
+ </a>
49
+ </li>
50
+ </ul>
51
+ <div class="sidebar-line"></div>
52
+ <div class="sidebar-footer">
53
+ <div class="footer-user">
54
+ <i class="sidebar-icon"></i>
55
+ <h3> Smart Attendance</h3>
56
+ <div class="header-description">Nhân viên</div>
57
+ </div>
58
+ <div class="logout">
59
+ <i class="logout-icon"></i>
60
+ <div class="logout-text">Đăng xuất</div>
61
+ </div>
62
+ </div>
63
+ </div>
src/main/resources/templates/cms/sidebar/sidebar-manage.html ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="sidebar">
2
+
3
+ <div class="sidebar-header">
4
+ <i class="sidebar-icon"></i>
5
+ <h2> Smart Attendance</h2>
6
+ <div class="header-description">Quản lý</div>
7
+ </div>
8
+ <div class="sidebar-line"></div>
9
+
10
+ <ul class="sidebar-menu">
11
+
12
+ <li class="sidebar-option">
13
+ <i class="icon"></i>
14
+ <a class="sidebar-link">
15
+ Dashboard
16
+ </a>
17
+ </li>
18
+
19
+ <li class="sidebar-option">
20
+ <i class="icon"></i>
21
+ <a class="sidebar-link">
22
+ Quản lý điểm danh
23
+ </a>
24
+ </li>
25
+
26
+ <li class="sidebar-option">
27
+ <i class="icon"></i>
28
+ <a class="sidebar-link">
29
+ Duyệt nghỉ phép
30
+ </a>
31
+ </li>
32
+ <li class="sidebar-option">
33
+ <i class="icon"></i>
34
+ <a class="sidebar-link">
35
+ Duyệt Face ID
36
+ </a>
37
+ </li>
38
+ <li class="sidebar-option">
39
+ <i class="icon"></i>
40
+ <a class="sidebar-link">
41
+ Báo cáo tháng
42
+ </a>
43
+ </li>
44
+ <li class="sidebar-option">
45
+ <i class="icon"></i>
46
+ <a class="sidebar-link">
47
+ Danh sách báo cáo
48
+ </a>
49
+ </li>
50
+ <li class="sidebar-option">
51
+ <i class="icon"></i>
52
+ <a class="sidebar-link">
53
+ Quản lý tài khoản
54
+ </a>
55
+ </li>
56
+ <li class="sidebar-option">
57
+ <i class="icon"></i>
58
+ <a class="sidebar-link">
59
+ Quản lý tài khoản
60
+ </a>
61
+ </li>
62
+ <li class="sidebar-option">
63
+ <i class="icon"></i>
64
+ <a class="sidebar-link">
65
+ Thông tin cá nhân
66
+ </a>
67
+ </li>
68
+ </ul>
69
+ <div class="sidebar-line"></div>
70
+ <div class="sidebar-footer">
71
+ <div class="footer-user">
72
+ <i class="sidebar-icon"></i>
73
+ <h3> Smart Attendance</h3>
74
+ <div class="header-description">Nhân viên</div>
75
+ </div>
76
+ <div class="logout">
77
+ <i class="logout-icon"></i>
78
+ <div class="logout-text">Đăng xuất</div>
79
+ </div>
80
+ </div>
81
+ </div>
src/main/resources/templates/cms/users/user-information.html ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+
3
+ <html xmlns:th="http://www.thymeleaf.org">
4
+
5
+ <head>
6
+ <meta charset="UTF-8" />
7
+ <title>Danh sách thế giới</title>
8
+ <link rel="stylesheet" th:href="@{/css/world/world.css}">
9
+
10
+ </head>
11
+
12
+ <body>
13
+ <div class="bg-image"></div>
14
+ <div th:replace="~{cms/layouts/sidebar :: sidebar}"></div>
15
+
16
+ <div class="container-layout">
17
+ <header class="page-header">
18
+ <h1>Thông tin cá nhân</h1>
19
+
20
+ <div class="notification">
21
+ <i class="fa-regular fa-bell"></i>
22
+ <span class="dot"></span>
23
+ </div>
24
+ </header>
25
+ <main class="main-section">
26
+ <!-- Form -->
27
+ <div class="absent-card">
28
+
29
+ <h2>Thông tin cá nhân</h2>
30
+
31
+ <div class="form-group">
32
+ <div class="information-icon"></div>
33
+ <label>Họ và tên</label>
34
+ <a>Nguyễn văn x</a>
35
+ </div>
36
+
37
+ <div class="form-group">
38
+ <div class="information-icon"></div>
39
+ <label>Email</label>
40
+ <p>abc@gmail.com</p>
41
+ </div>
42
+
43
+ <div class="form-group">
44
+ <div class="information-icon"></div>
45
+ <label>Phone</label>
46
+ <p>0987654321</p>
47
+ </div>
48
+
49
+ <div class="form-group">
50
+ <div class="information-icon"></div>
51
+ <label>Phòng ban</label>
52
+ <p>Phòng Lab 213</p>
53
+ </div>
54
+
55
+ <div class="form-group">
56
+ <div class="information-icon"></div>
57
+ <label>Mật khẩu</label>
58
+ <p>.................</p>
59
+ </div>
60
+
61
+ </div>
62
+ <div class="change-password">
63
+ <div class="change-header">
64
+ <i class="change-icon"></i>
65
+ <h2>Đổi mật khẩu</h2>
66
+ </div>
67
+ <div class="change-body">
68
+ <div class="form-group">
69
+ <label>Mật khẩu hiện tại</label>
70
+ <p type="text" class="change-text">......</p>
71
+ </div>
72
+ <div class="form-group">
73
+ <label>Mật khẩu mới</label>
74
+ <p type="text" class="change-text">......</p>
75
+ </div>
76
+ <div class="form-group">
77
+ <label>Xác nhận mật khẩu</label>
78
+ <p type="text" class="change-text">......</p>
79
+ </div>
80
+ </div>
81
+
82
+ </div>
83
+
84
+ </main>
85
+
86
+ </div>
87
+ <div th:replace="~{cms/layouts/footer :: footer}"></div>
88
+ </body>
89
+
90
+ </html>
src/main/webapp/WEB-INF/views/homet.html ADDED
@@ -0,0 +1,475 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+
3
+ <!doctype html>
4
+
5
+ <!-- <html xmlns:th="http://www.thymeleaf.org"> -->
6
+ <html>
7
+ <head>
8
+ <meta charset="UTF-8" />
9
+ <title>Danh sách thế giới</title>
10
+ <style>
11
+ /* =====================================================
12
+ WORLD LIST PAGE - DARK FANTASY ADMIN
13
+ ===================================================== */
14
+
15
+ :root {
16
+ --blood-red: #8B0000;
17
+ --crimson: #C41E3A;
18
+ --dark-bg: #080604;
19
+ --dark-card: #1C1410;
20
+ --border-dark: #2E201A;
21
+ --border-mid: #4A3028;
22
+ --cream: #DDD0B8;
23
+ --parchment: #C4A882;
24
+ --light-grey: #C8C1BC;
25
+ --mid-grey: #8F7E76;
26
+ --gold: #C9A44C;
27
+ }
28
+
29
+ /* =====================================================
30
+ PAGE
31
+ ===================================================== */
32
+
33
+ main {
34
+ padding: 30px;
35
+ }
36
+
37
+ h1 {
38
+ color: var(--cream);
39
+ margin-bottom: 25px;
40
+
41
+ font-size: 2.2rem;
42
+ font-family: "Cormorant Garamond", serif;
43
+
44
+ letter-spacing: .05em;
45
+
46
+ }
47
+
48
+ /* =====================================================
49
+ ALERT
50
+ ===================================================== */
51
+
52
+ p[style*="green"] {
53
+ background: rgba(60, 150, 60, .15);
54
+ color: #8ff19d;
55
+ padding: 12px 16px;
56
+ border-left: 4px solid #4caf50;
57
+ margin-bottom: 15px;
58
+ }
59
+
60
+ p[style*="red"] {
61
+ background: rgba(196, 30, 58, .12);
62
+ color: #ff9e9e;
63
+ padding: 12px 16px;
64
+ border-left: 4px solid var(--crimson);
65
+ margin-bottom: 15px;
66
+ }
67
+
68
+ /* =====================================================
69
+ CREATE BUTTON
70
+ ===================================================== */
71
+
72
+ a[href*="create"] {
73
+ display: inline-block;
74
+ padding: 12px 22px;
75
+ background: var(--blood-red);
76
+ border: 1px solid var(--crimson);
77
+ color: white;
78
+ text-decoration: none;
79
+ border-radius: 6px;
80
+ transition: .3s;
81
+ }
82
+
83
+ a[href*="create"]:hover {
84
+ background: var(--crimson);
85
+ transform: translateY(-2px);
86
+ }
87
+
88
+ /* =====================================================
89
+ TABLE
90
+ ===================================================== */
91
+
92
+ table {
93
+ width: 100%;
94
+ border-collapse: collapse;
95
+ margin-top: 25px;
96
+ background: var(--dark-card);
97
+ border: 1px solid var(--border-dark);
98
+ overflow: hidden;
99
+
100
+ }
101
+
102
+ thead {
103
+ background:
104
+ linear-gradient(180deg,
105
+ rgba(139, 0, 0, .25),
106
+ rgba(139, 0, 0, .08));
107
+ }
108
+
109
+ th {
110
+ padding: 15px;
111
+ color: var(--parchment);
112
+ text-transform: uppercase;
113
+ letter-spacing: .08em;
114
+ font-size: .85rem;
115
+ border-bottom: 1px solid var(--border-dark);
116
+ }
117
+
118
+ td {
119
+ padding: 15px;
120
+ color: var(--light-grey);
121
+ border-bottom: 1px solid rgba(255, 255, 255, .05);
122
+ vertical-align: middle;
123
+
124
+ }
125
+
126
+ tbody tr {
127
+ transition: .25s;
128
+ }
129
+
130
+ tbody tr:hover {
131
+ background: rgba(139, 0, 0, .08);
132
+ }
133
+
134
+ tbody tr:last-child td {
135
+ border-bottom: none;
136
+ }
137
+
138
+ /* =====================================================
139
+ IMAGE
140
+ ===================================================== */
141
+
142
+ td img {
143
+ width: 120px;
144
+ height: 70px;
145
+
146
+ object-fit: cover;
147
+
148
+ border: 1px solid var(--border-mid);
149
+
150
+ border-radius: 4px;
151
+
152
+ }
153
+
154
+ /* =====================================================
155
+ STATUS
156
+ ===================================================== */
157
+
158
+ .status-active {
159
+ color: #86f3a2;
160
+ font-weight: 600;
161
+ }
162
+
163
+ .status-deleted {
164
+ color: #ff8f8f;
165
+ font-weight: 600;
166
+ }
167
+
168
+ /* =====================================================
169
+ ACTION BUTTONS
170
+ ===================================================== */
171
+
172
+ td form {
173
+ display: inline-block;
174
+
175
+ margin-right: 5px;
176
+ margin-bottom: 5px;
177
+
178
+ }
179
+
180
+ button {
181
+ cursor: pointer;
182
+
183
+ padding: 8px 16px;
184
+
185
+ border: none;
186
+
187
+ border-radius: 4px;
188
+
189
+ transition: .3s;
190
+
191
+ }
192
+
193
+ /* Edit */
194
+
195
+ button[type="submit"] {
196
+ background: #2b211c;
197
+ color: var(--cream);
198
+ border: 1px solid var(--border-mid);
199
+ }
200
+
201
+ button[type="submit"]:hover {
202
+ border-color: var(--crimson);
203
+ }
204
+
205
+ /* Delete */
206
+
207
+ form[action*="delete"] button {
208
+ background: transparent;
209
+
210
+ border: 1px solid var(--crimson);
211
+
212
+ color: var(--crimson);
213
+
214
+ }
215
+
216
+ form[action*="delete"] button:hover {
217
+ background: var(--crimson);
218
+ color: white;
219
+ }
220
+
221
+ /* Restore */
222
+
223
+ form[action*="restore"] button {
224
+ background: var(--gold);
225
+
226
+ color: #111;
227
+
228
+ }
229
+
230
+ form[action*="restore"] button:hover {
231
+ filter: brightness(1.1);
232
+ }
233
+
234
+ /* =====================================================
235
+ PAGINATION
236
+ ===================================================== */
237
+
238
+ div[th\:if] {
239
+ margin-top: 30px;
240
+ }
241
+
242
+ div[th\:if] a,
243
+ div[th\:if] span {
244
+ display: inline-block;
245
+
246
+ margin: 0 3px;
247
+
248
+ }
249
+
250
+ div[th\:if] a {
251
+ padding: 10px 15px;
252
+
253
+ background: var(--dark-card);
254
+
255
+ border: 1px solid var(--border-mid);
256
+
257
+ color: var(--cream);
258
+
259
+ text-decoration: none;
260
+
261
+ transition: .3s;
262
+
263
+ }
264
+
265
+ div[th\:if] a:hover {
266
+ border-color: var(--crimson);
267
+
268
+ color: var(--crimson);
269
+
270
+ }
271
+
272
+ div[th\:if] span[style] {
273
+ padding: 10px 15px;
274
+
275
+ background: var(--blood-red);
276
+
277
+ border: 1px solid var(--crimson);
278
+
279
+ color: white;
280
+
281
+ }
282
+ .bg-image{
283
+ position:fixed;
284
+ inset:0;
285
+
286
+ background-image:
287
+ linear-gradient(
288
+ rgba(0,0,0,.65),
289
+ rgba(0,0,0,.85)
290
+ ),
291
+ url('img/back.png');
292
+
293
+ background-size:cover;
294
+ background-position:center;
295
+
296
+ z-index:-2;
297
+ }
298
+
299
+ .bg-image::after{
300
+ content:"";
301
+
302
+ position:absolute;
303
+ inset:0;
304
+
305
+ background:
306
+ radial-gradient(
307
+ circle at top,
308
+ rgba(196,30,58,.15),
309
+ transparent 35%
310
+ );
311
+
312
+ z-index:-1;
313
+ }
314
+ /* =====================================================
315
+ RESPONSIVE
316
+ ===================================================== */
317
+
318
+ @media(max-width:992px) {
319
+
320
+
321
+ table {
322
+ min-width: 900px;
323
+ }
324
+
325
+ main {
326
+ overflow-x: auto;
327
+ }
328
+
329
+
330
+ }
331
+
332
+ @media(max-width:768px) {
333
+
334
+
335
+ h1 {
336
+ font-size: 1.8rem;
337
+ }
338
+
339
+ td,
340
+ th {
341
+ padding: 10px;
342
+ }
343
+
344
+
345
+ }
346
+ </style>
347
+ </head>
348
+
349
+ <body>
350
+ <div class="layout">
351
+ <th:block th:replace="~{cms/fragments/sidebar :: sidebar}"></th:block>
352
+
353
+ <div class="content-wrapper">
354
+ <th:block th:replace="~{cms/fragments/header :: header}"></th:block>
355
+ <div class="bg-image"></div>
356
+ <main class="cms-page">
357
+
358
+ <div class="cms-header">
359
+ <h1 class="cms-title">Danh sách thế giới</h1>
360
+
361
+ <a th:href="@{/world/moonblight/create}" class="btn btn-primary">
362
+ + Tạo thế giới mới
363
+ </a>
364
+ </div>
365
+
366
+ <p class="alert-success" th:if="${successMessage}" th:text="${successMessage}">
367
+ </p>
368
+
369
+ <p class="alert-error" th:if="${errorMessage}" th:text="${errorMessage}">
370
+ </p>
371
+
372
+ <div class="table-wrapper">
373
+
374
+ <table class="cms-table">
375
+
376
+ <thead>
377
+ <tr>
378
+ <th>ID</th>
379
+ <th>Ảnh</th>
380
+ <th>Ưu tiên</th>
381
+ <th>Tag</th>
382
+ <th>Tiêu đề</th>
383
+ <th>Trạng thái</th>
384
+ <th>Hành động</th>
385
+ </tr>
386
+ </thead>
387
+
388
+ <tbody>
389
+ <tr th:each="world : ${worlds.content}">
390
+
391
+ <td th:text="${world.id}"></td>
392
+
393
+ <td>
394
+ <img th:if="${world.image != null}" th:src="${world.image}" alt="World Image"
395
+ class="table-image">
396
+ </td>
397
+
398
+ <td th:text="${world.priority}"></td>
399
+
400
+ <td th:text="${world.tag}"></td>
401
+
402
+ <td th:text="${world.title}"></td>
403
+
404
+ <td>
405
+ <span class="status"
406
+ th:classappend="${world.deleted} ? 'status-deleted' : 'status-active'"
407
+ th:text="${world.deleted ? 'Đã xóa' : 'Đang hiển thị'}">
408
+ </span>
409
+ </td>
410
+
411
+ <td class="action-group">
412
+
413
+ <form th:action="@{/world/moonblight/{id}/edit(id=${world.id})}" method="get">
414
+ <button type="submit" class="btn btn-secondary">
415
+ Sửa
416
+ </button>
417
+ </form>
418
+
419
+ <form th:if="${!world.deleted}"
420
+ th:action="@{/world/moonblight/{id}/delete(id=${world.id})}" method="post">
421
+
422
+ <button type="submit" class="btn btn-outline-red">
423
+ Xóa
424
+ </button>
425
+ </form>
426
+
427
+ <form th:if="${world.deleted}"
428
+ th:action="@{/world/moonblight/{id}/restore(id=${world.id})}" method="post">
429
+
430
+ <button type="submit" class="btn btn-gold">
431
+ Khôi phục
432
+ </button>
433
+ </form>
434
+
435
+ </td>
436
+
437
+ </tr>
438
+ </tbody>
439
+
440
+ </table>
441
+
442
+ </div>
443
+
444
+ <div class="pagination" th:if="${worlds.totalPages > 1}">
445
+
446
+ <a class="page-btn" th:if="${!worlds.first}"
447
+ th:href="@{/world/moonblight/list(page=${worlds.number - 1})}">
448
+ ← Trước
449
+ </a>
450
+
451
+ <!-- <span th:each="i : ${#numbers.sequence(0, worlds.totalPages - 1)}"> -->
452
+ <span >
453
+
454
+ <a class="page-number" th:if="${i != worlds.number}"
455
+ th:href="@{/world/moonblight/list(page=${i})}" th:text="${i + 1}">
456
+ </a>
457
+
458
+ <span class="page-number active" th:if="${i == worlds.number}" th:text="${i + 1}">
459
+ </span>
460
+
461
+ </span>
462
+
463
+ <a class="page-btn" th:if="${!worlds.last}"
464
+ th:href="@{/world/moonblight/list(page=${worlds.number + 1})}">
465
+ Sau →
466
+ </a>
467
+
468
+ </div>
469
+
470
+ </main>
471
+ </div>
472
+ </div>
473
+ </body>
474
+
475
+ </html>
src/main/webapp/WEB-INF/views/webapp1/login.jsp CHANGED
@@ -1,89 +1,98 @@
1
- <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
2
- <!DOCTYPE html>
3
- <html lang="vi">
4
- <head>
5
- <meta charset="UTF-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Đăng Nhập - Face ID Attendance</title>
8
- <link rel="stylesheet" href="css/theme.css">
9
- <link rel="stylesheet" href="css/components.css">
10
- </head>
11
- <body>
12
- <div class="min-h-screen flex items-center justify-center" style="background-color: var(--background); padding: 1.5rem;">
13
- <div class="card" style="max-width: 450px; width: 100%;">
14
- <div class="card-header text-center">
15
- <h1 class="card-title" style="font-size: 2rem;">Đăng Nhập</h1>
16
- <p class="card-description">Nhập thông tin để truy cập hệ thống</p>
17
- </div>
18
-
19
- <div class="card-body">
20
- <% String error = request.getParameter("error");
21
- if (error != null) { %>
22
- <div class="alert alert-destructive mb-4">
23
- Sai email hoặc mật khẩu!
24
- </div>
25
- <% } %>
26
 
27
- <form action="login" method="post" id="loginForm">
28
- <div class="form-group">
29
- <label class="form-label">Vai trò</label>
30
- <select name="role" class="form-control" required>
31
- <option value="EMPLOYEE">Nhân viên (Employee)</option>
32
- <option value="TEACHER">Giáo viên / Quản lý (Teacher)</option>
33
- <option value="ADMIN">Quản trị viên (Admin)</option>
34
- </select>
35
- </div>
36
 
37
- <div class="form-group">
38
- <label class="form-label">Email</label>
39
- <input type="email" name="email" class="form-control" placeholder="your.email@company.com" required>
40
- </div>
 
 
 
 
41
 
42
- <div class="form-group">
43
- <label class="form-label">Mật khẩu</label>
44
- <div style="position: relative;">
45
- <input type="password" name="password" id="password" class="form-control" placeholder="••••••••" required>
46
- <button type="button" onclick="AttendanceSystem.togglePassword('password')"
47
- style="position: absolute; right: 10px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer;">
48
- <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2">
49
- <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
50
- <circle cx="12" cy="12" r="3"></circle>
51
- </svg>
52
- </button>
53
  </div>
54
- </div>
55
 
56
- <button type="submit" class="btn btn-primary w-full" style="width: 100%; margin-top: 1.5rem;">
57
- <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
58
- <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
59
- <polyline points="10 17 15 12 10 7"></polyline>
60
- <line x1="15" y1="12" x2="3" y2="12"></line>
61
- </svg>
62
- Đăng nhập
63
- </button>
64
- </form>
65
- </div>
66
 
67
- <div class="card-footer text-center">
68
- <p class="text-sm text-muted">
69
- Chưa tài khoản?
70
- <a href="register.jsp" class="text-primary font-semibold">Đăng ký ngay</a>
71
- </p>
72
- <p class="text-sm text-muted" style="margin-top: 0.5rem;">
73
- <a href="index.jsp" class="text-muted">← Về trang chủ</a>
74
- </p>
75
- </div>
76
 
77
- <div style="text-align: center; margin-top: 1rem;">
78
- <button id="theme-toggle" onclick="AttendanceSystem.toggleTheme()" class="btn btn-icon btn-outline">
79
- <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
80
- <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
81
- </svg>
82
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
83
  </div>
84
  </div>
85
- </div>
86
 
87
- <script src="js/main.js"></script>
88
- </body>
89
- </html>
 
 
1
+ <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
2
+ <!DOCTYPE html>
3
+ <html lang="vi">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
+ <head>
6
+ <meta charset="UTF-8">
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
8
+ <title>Đăng Nhập - Face ID Attendance</title>
9
+ <link rel="stylesheet" href="css/theme.css">
10
+ <link rel="stylesheet" href="css/components.css">
11
+ </head>
 
 
12
 
13
+ <body>
14
+ <div class="min-h-screen flex items-center justify-center"
15
+ style="background-color: var(--background); padding: 1.5rem;">
16
+ <div class="card" style="max-width: 450px; width: 100%;">
17
+ <div class="card-header text-center">
18
+ <h1 class="card-title" style="font-size: 2rem;">Đăng Nhập</h1>
19
+ <p class="card-description">Nhập thông tin để truy cập hệ thống</p>
20
+ </div>
21
 
22
+ <div class="card-body">
23
+ <% String error=request.getParameter("error"); if (error !=null) { %>
24
+ <div class="alert alert-destructive mb-4">
25
+ Sai email hoặc mật khẩu!
 
 
 
 
 
 
 
26
  </div>
27
+ <% } %>
28
 
29
+ <form action="login" method="post" id="loginForm">
30
+ <div class="form-group">
31
+ <label class="form-label">Vai trò</label>
32
+ <select name="role" class="form-control" required>
33
+ <option value="EMPLOYEE">Nhân viên (Employee)</option>
34
+ <option value="TEACHER">Giáo viên / Quản lý (Teacher)</option>
35
+ <option value="ADMIN">Quản trị viên (Admin)</option>
36
+ </select>
37
+ </div>
 
38
 
39
+ <div class="form-group">
40
+ <label class="form-label">Email</label>
41
+ <input type="email" name="email" class="form-control"
42
+ placeholder="your.email@company.com" required>
43
+ </div>
 
 
 
 
44
 
45
+ <div class="form-group">
46
+ <label class="form-label">Mật khẩu</label>
47
+ <div style="position: relative;">
48
+ <input type="password" name="password" id="password" class="form-control"
49
+ placeholder="••••••••" required>
50
+ <button type="button" onclick="AttendanceSystem.togglePassword('password')"
51
+ style="position: absolute; right: 10px; top: 50%; transform: translateY(-50%); background: none; border: none; cursor: pointer;">
52
+ <svg width="20" height="20" fill="none" stroke="currentColor"
53
+ stroke-width="2">
54
+ <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"></path>
55
+ <circle cx="12" cy="12" r="3"></circle>
56
+ </svg>
57
+ </button>
58
+ </div>
59
+ </div>
60
+
61
+ <button type="submit" class="btn btn-primary w-full"
62
+ style="width: 100%; margin-top: 1.5rem;">
63
+ <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2"
64
+ stroke-linecap="round" stroke-linejoin="round">
65
+ <path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path>
66
+ <polyline points="10 17 15 12 10 7"></polyline>
67
+ <line x1="15" y1="12" x2="3" y2="12"></line>
68
+ </svg>
69
+ Đăng nhập
70
+ </button>
71
+ </form>
72
+ </div>
73
+
74
+ <div class="card-footer text-center">
75
+ <p class="text-sm text-muted">
76
+ Chưa có tài khoản?
77
+ <a href="register.jsp" class="text-primary font-semibold">Đăng ký ngay</a>
78
+ </p>
79
+ <p class="text-sm text-muted" style="margin-top: 0.5rem;">
80
+ <a href="index.jsp" class="text-muted">← Về trang chủ</a>
81
+ </p>
82
+ </div>
83
+
84
+ <div style="text-align: center; margin-top: 1rem;">
85
+ <button id="theme-toggle" onclick="AttendanceSystem.toggleTheme()" class="btn btn-icon btn-outline">
86
+ <svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2"
87
+ stroke-linecap="round" stroke-linejoin="round">
88
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
89
+ </svg>
90
+ </button>
91
+ </div>
92
  </div>
93
  </div>
 
94
 
95
+ <script src="js/main.js"></script>
96
+ </body>
97
+
98
+ </html>
src/test/java/com/attendenceSystem/AttendenceSystemApplicationTests.java CHANGED
@@ -1,13 +1,13 @@
1
- package com.attendenceSystem;
2
 
3
- import org.junit.jupiter.api.Test;
4
- import org.springframework.boot.test.context.SpringBootTest;
5
 
6
- @SpringBootTest
7
- class AttendenceSystemApplicationTests {
8
 
9
- @Test
10
- void contextLoads() {
11
- }
12
 
13
- }
 
1
+ // package com.attendenceSystem;
2
 
3
+ // import org.junit.jupiter.api.Test;
4
+ // import org.springframework.boot.test.context.SpringBootTest;
5
 
6
+ // @SpringBootTest
7
+ // class AttendenceSystemApplicationTests {
8
 
9
+ // @Test
10
+ // void contextLoads() {
11
+ // }
12
 
13
+ // }