diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffDashboard.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffDashboard.razor
index d3c35311..2aac0b69 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffDashboard.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffDashboard.razor
@@ -69,7 +69,7 @@
@_leaveBalance
- Ngày phép còn lại
+ Ngày phép đã dùng
@@ -141,7 +141,9 @@
private bool _checkedOut = false;
private string _todayHours = "0";
private int _monthDays = 0;
- private int _leaveBalance = 12;
+ // EN: Leave balance — loaded from real leave request data. TODO: load annual allowance from merchant config API.
+ // VI: Số phép còn lại — tính từ dữ liệu nghỉ phép thực. TODO: tải số phép năm từ API cấu hình merchant.
+ private int _leaveBalance = 0;
private int _unreadCount = 0;
private string _displayName => _profile?.FirstName ?? AuthState.UserEmail?.Split('@').FirstOrDefault() ?? "Staff";
@@ -177,16 +179,28 @@
_unreadCount = _notifications.Count(n => !n.IsRead);
_monthDays = _recentAttendance.Count(r => r.Status == "Completed");
- var today = _recentAttendance.FirstOrDefault(r => r.Date.Date == DateTime.Now.Date);
+ // EN: Compare UTC dates consistently — backend stores all times in UTC.
+ // VI: So sánh ngày UTC nhất quán — backend lưu tất cả thời gian theo UTC.
+ var todayUtc = DateTime.UtcNow.Date;
+ var today = _recentAttendance.FirstOrDefault(r => r.Date.Date == todayUtc);
if (today != null)
{
_checkedIn = today.CheckIn.HasValue;
_checkedOut = today.CheckOut.HasValue;
if (today.CheckIn.HasValue && !today.CheckOut.HasValue)
- _todayHours = ((DateTime.Now - today.CheckIn.Value).TotalHours).ToString("0.#");
+ _todayHours = ((DateTime.UtcNow - today.CheckIn.Value).TotalHours).ToString("0.#");
else if (today.HoursWorked.HasValue)
_todayHours = today.HoursWorked.Value.ToString("0.#");
}
+
+ // EN: Calculate leave days used from approved leave requests (real data).
+ // VI: Tính số ngày phép đã dùng từ các yêu cầu nghỉ phép đã duyệt (dữ liệu thực).
+ try
+ {
+ var leaveRequests = await DataService.GetMyLeaveRequestsAsync();
+ _leaveBalance = leaveRequests.Where(r => r.Status == "Approved").Sum(r => (r.EndDate - r.StartDate).Days + 1);
+ }
+ catch { }
}
catch { }
finally { _loading = false; }
diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffLeave.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffLeave.razor
index e4a8bb12..1ddd81ce 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffLeave.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffLeave.razor
@@ -26,23 +26,25 @@
@* ═══ SUMMARY ═══ *@
+ @* EN: Leave stats from real data. Total annual allowance will come from merchant config API (TODO).
+ VI: Thống kê phép từ dữ liệu thực. Tổng phép năm sẽ từ API cấu hình merchant (TODO). *@
-
- 12
- Tổng phép năm
-
@_usedDays
- Đã sử dụng
-
-
- @(12 - _usedDays)
- Còn lại
+ Ngày phép đã dùng
@_pendingCountChờ duyệt
+
+ @_rejectedCount
+ Từ chối
+
+
+ @_requests.Count
+ Tổng yêu cầu
+
@* ═══ CREATE FORM ═══ *@
@@ -129,6 +131,7 @@
private bool _submitting = false;
private int _usedDays = 0;
private int _pendingCount = 0;
+ private int _rejectedCount = 0;
// Form fields
private string _leaveType = "Annual";
@@ -158,6 +161,7 @@
_requests = await DataService.GetMyLeaveRequestsAsync();
_usedDays = _requests.Where(r => r.Status == "Approved").Sum(r => (r.EndDate - r.StartDate).Days + 1);
_pendingCount = _requests.Count(r => r.Status == "Pending");
+ _rejectedCount = _requests.Count(r => r.Status == "Rejected");
}
catch { }
finally { _loading = false; }
diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Server/Controllers/StaffController.cs b/apps/web-client-tpos-net/src/WebClientTpos.Server/Controllers/StaffController.cs
index bd7c5340..ce476b5d 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Server/Controllers/StaffController.cs
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Server/Controllers/StaffController.cs
@@ -367,21 +367,15 @@ public class StaffController : ControllerBase
}
///
- /// EN: Get notifications for current staff.
- /// VI: Lấy thông báo của nhân viên hiện tại.
+ /// EN: Get notifications for current staff. Returns empty list until notification service is implemented.
+ /// VI: Lấy thông báo của nhân viên hiện tại. Trả về danh sách trống cho đến khi notification service được triển khai.
///
[HttpGet("staff/me/notifications")]
public IActionResult GetMyNotifications()
{
- // EN: Stub — returns sample notifications
- // VI: Stub — trả về thông báo mẫu
- var notifications = new List