nguyenhai266 commited on
Commit
4654788
·
1 Parent(s): 7d99195

Add CMS templates; update pom and properties

Browse files

Add a large set of CMS UI templates (dashboard, attendance, absent, account, auth pages, charts, layouts, etc.) and minor view updates (WEB-INF/login.jsp). Update PageController to add /homet mapping (note: home() now returns "home." which looks like a typo). Modify pom.xml to add/replace many Spring Boot and related dependencies (Thymeleaf, JSTL, MariaDB/MySQL driver, OAuth2, mail, devtools, tomcat embed, lombok, JPA, etc.) and reorganize entries — pom.xml currently contains unresolved merge conflict markers that must be manually resolved. Update application.properties with server, multipart, thymeleaf and datasource settings (including hardcoded DB credentials) and also contains conflict markers; remove or secure secrets and resolve conflicts before building. Also update a test file. Manual cleanup (resolve merge conflicts, fix home() return value, and remove plaintext credentials) is required before this branch can be built and run.

Files changed (36) hide show
  1. pom.xml +46 -37
  2. src/main/java/com/attendenceSystem/frontroller/PageController.java +6 -2
  3. src/main/resources/application.properties +43 -10
  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,41 +30,51 @@
31
  <java.version>21</java.version>
32
  </properties>
33
  <dependencies>
34
- <!-- <dependency>
35
- <groupId>org.springframework.boot</groupId>
36
- <artifactId>spring-boot-starter-data-jpa</artifactId>
37
- </dependency> -->
 
 
 
 
 
 
 
 
 
 
 
 
38
  <dependency>
39
  <groupId>org.springframework.boot</groupId>
40
  <artifactId>spring-boot-starter-validation</artifactId>
41
  </dependency>
 
 
 
 
42
  <dependency>
43
  <groupId>org.projectlombok</groupId>
44
  <artifactId>lombok</artifactId>
45
- <version>1.18.32</version>
46
  <optional>true</optional>
47
  </dependency>
 
48
  <dependency>
49
  <groupId>org.springframework.boot</groupId>
50
- <artifactId>spring-boot-starter-restclient</artifactId>
51
- </dependency>
52
- <dependency>
53
- <groupId>org.apache.tomcat.embed</groupId>
54
- <artifactId>tomcat-embed-jasper</artifactId>
55
  </dependency>
56
-
57
  <dependency>
58
- <groupId>jakarta.servlet.jsp.jstl</groupId>
59
- <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
60
  </dependency>
61
 
62
- <dependency>
63
- <groupId>org.glassfish.web</groupId>
64
- <artifactId>jakarta.servlet.jsp.jstl</artifactId>
65
- </dependency>
66
  <dependency>
67
  <groupId>org.springframework.boot</groupId>
68
- <artifactId>spring-boot-starter-webmvc</artifactId>
69
  </dependency>
70
  <dependency>
71
  <groupId>org.springframework.boot</groupId>
@@ -73,27 +82,27 @@
73
  <scope>runtime</scope>
74
  <optional>true</optional>
75
  </dependency>
76
- <!-- <dependency>
77
- <groupId>com.mysql</groupId>
78
- <artifactId>mysql-connector-j</artifactId>
79
- <scope>runtime</scope>
80
- </dependency> -->
81
- <!-- <dependency>
82
- <groupId>org.springframework.boot</groupId>
83
- <artifactId>spring-boot-starter-data-jpa-test</artifactId>
84
- <scope>test</scope>
85
- </dependency> -->
86
  <dependency>
87
- <groupId>org.springframework.boot</groupId>
88
- <artifactId>spring-boot-starter-restclient-test</artifactId>
89
- <scope>test</scope>
90
  </dependency>
91
 
 
92
  <dependency>
93
- <groupId>org.springframework.boot</groupId>
94
- <artifactId>spring-boot-starter-webmvc-test</artifactId>
95
- <scope>test</scope>
 
 
 
96
  </dependency>
 
 
 
 
 
 
97
  </dependencies>
98
 
99
  <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-mail</artifactId>
36
+ </dependency>
37
+ <dependency>
38
+ <groupId>org.thymeleaf.extras</groupId>
39
+ <artifactId>thymeleaf-extras-springsecurity6</artifactId>
40
+ </dependency>
41
+ <dependency>
42
+ <groupId>org.springframework.boot</groupId>
43
+ <artifactId>spring-boot-starter-thymeleaf</artifactId>
44
+ </dependency>
45
+ <dependency>
46
+ <groupId>org.mariadb.jdbc</groupId>
47
+ <artifactId>mariadb-java-client</artifactId>
48
+ </dependency>
49
  <dependency>
50
  <groupId>org.springframework.boot</groupId>
51
  <artifactId>spring-boot-starter-validation</artifactId>
52
  </dependency>
53
+ <dependency>
54
+ <groupId>org.springframework.boot</groupId>
55
+ <artifactId>spring-boot-starter-data-jpa</artifactId>
56
+ </dependency>
57
  <dependency>
58
  <groupId>org.projectlombok</groupId>
59
  <artifactId>lombok</artifactId>
60
+ <!-- <version>1.18.32</version> -->
61
  <optional>true</optional>
62
  </dependency>
63
+ <!-- OAuth2 Google Login -->
64
  <dependency>
65
  <groupId>org.springframework.boot</groupId>
66
+ <artifactId>spring-boot-starter-oauth2-client</artifactId>
 
 
 
 
67
  </dependency>
68
+ <!-- Spring Boot Web -->
69
  <dependency>
70
+ <groupId>org.springframework.boot</groupId>
71
+ <artifactId>spring-boot-starter-web</artifactId>
72
  </dependency>
73
 
74
+ <!-- Embedded Tomcat (not provided so java -jar works) -->
 
 
 
75
  <dependency>
76
  <groupId>org.springframework.boot</groupId>
77
+ <artifactId>spring-boot-starter-tomcat</artifactId>
78
  </dependency>
79
  <dependency>
80
  <groupId>org.springframework.boot</groupId>
 
82
  <scope>runtime</scope>
83
  <optional>true</optional>
84
  </dependency>
85
+ <!-- JSP support -->
 
 
 
 
 
 
 
 
 
86
  <dependency>
87
+ <groupId>org.apache.tomcat.embed</groupId>
88
+ <artifactId>tomcat-embed-jasper</artifactId>
 
89
  </dependency>
90
 
91
+ <!-- JSTL -->
92
  <dependency>
93
+ <groupId>jakarta.servlet.jsp.jstl</groupId>
94
+ <artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
95
+ </dependency>
96
+ <dependency>
97
+ <groupId>org.glassfish.web</groupId>
98
+ <artifactId>jakarta.servlet.jsp.jstl</artifactId>
99
  </dependency>
100
+ <dependency>
101
+ <groupId>com.mysql</groupId>
102
+ <artifactId>mysql-connector-j</artifactId>
103
+ <scope>runtime</scope>
104
+ </dependency>
105
+
106
  </dependencies>
107
 
108
  <build>
src/main/java/com/attendenceSystem/frontroller/PageController.java CHANGED
@@ -1,4 +1,4 @@
1
- package com.attendenceSystem.controller;
2
 
3
  import org.springframework.stereotype.Controller;
4
  import org.springframework.web.bind.annotation.GetMapping;
@@ -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() {
 
1
+ package com.attendenceSystem.frontroller;
2
 
3
  import org.springframework.stereotype.Controller;
4
  import org.springframework.web.bind.annotation.GetMapping;
 
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,15 +1,48 @@
1
- spring.application.name=attendenceSystem
2
-
3
 
 
 
4
  # JSP Configuration
5
  spring.mvc.view.prefix=/WEB-INF/views/
6
  spring.mvc.view.suffix=.jsp
7
  # Thymeleaf Configuration
8
- # spring.thymeleaf.prefix=classpath:/templates/
9
- # spring.thymeleaf.suffix=.html
10
- # spring.thymeleaf.cache=false
11
- # spring.thymeleaf.encoding=UTF-8
12
- # spring.thymeleaf.mode=HTML
13
-
14
- #TimeZone Setting
15
- 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
8
  # Thymeleaf Configuration
9
+
10
+
11
+ spring.thymeleaf.prefix=classpath:/templates/
12
+ spring.thymeleaf.suffix=.html
13
+ spring.thymeleaf.cache=false
14
+ spring.thymeleaf.encoding=UTF-8
15
+ spring.thymeleaf.mode=HTML
16
+
17
+ # Google OAuth2
18
+ # spring.security.oauth2.client.registration.google.client-id=
19
+ # spring.security.oauth2.client.registration.google.client-secret=
20
+ # spring.security.oauth2.client.registration.google.scope=email,profile
21
+
22
+ spring.devtools.restart.enabled=true
23
+ spring.devtools.livereload.enabled=true
24
+
25
+ server.servlet.jsp.init-parameters.development=true
26
+
27
+ # DataSource Configuration for SQL Server
28
+ # spring.datasource.url=jdbc:mariadb://localhost:3306/MOONBLIGHT
29
+ # spring.datasource.username=root
30
+ # spring.datasource.password=QQQewqwqa401!
31
+ # spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
32
+
33
+ spring.datasource.url=jdbc:mysql://localhost:3306/game_promo_web
34
+ spring.datasource.username=root
35
+ spring.datasource.password=annguyenthanh2k5
36
+
37
+
38
+ # SMPT EMAIL
39
+ # spring.mail.host=smtp.gmail.com
40
+ # spring.mail.port=587
41
+ # spring.mail.username=donhatquang401@gmail.com
42
+ # spring.mail.password=lzzxdgzmirxdwqdv
43
+
44
+ # JPA configuration
45
+
46
+
47
+
48
+ >>>>>>> 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
+ // }