diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopSchedule.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopSchedule.razor
index ed4e19df..f2cf577c 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopSchedule.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Admin/Shop/ShopSchedule.razor
@@ -82,10 +82,10 @@
var schedStaffName = schedStaff != null && (!string.IsNullOrWhiteSpace(schedStaff.LastName) || !string.IsNullOrWhiteSpace(schedStaff.FirstName)) ? $"{schedStaff.LastName} {schedStaff.FirstName}".Trim() : (s.EmployeeCode ?? s.StaffId.ToString()[..8]);
| @schedStaffName |
- @(s.Role ?? "—") |
+ @(schedStaff?.Role ?? s.Role ?? "—") |
@ShopHelpers.DayLabel(s.DayOfWeek) |
- @s.StartTime |
- @s.EndTime |
+ @FormatTime(s.StartTime) |
+ @FormatTime(s.EndTime) |
|
}
@@ -278,4 +278,15 @@ else if (SubSection == "shifts")
}
catch (Exception ex) { Console.Error.WriteLine($"Không thể xóa lịch làm việc: {ex.Message}"); }
}
+
+ ///
+ /// EN: Format time string — remove seconds if present (08:00:00 → 08:00).
+ /// VI: Định dạng giờ — bỏ giây nếu có (08:00:00 → 08:00).
+ ///
+ private static string FormatTime(string? time)
+ {
+ if (string.IsNullOrEmpty(time)) return "—";
+ var parts = time.Split(':');
+ return parts.Length >= 2 ? $"{parts[0]}:{parts[1]}" : time;
+ }
}
diff --git a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffSchedule.razor b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffSchedule.razor
index c6358fc2..9875d174 100644
--- a/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffSchedule.razor
+++ b/apps/web-client-tpos-net/src/WebClientTpos.Client/Pages/Staff/StaffSchedule.razor
@@ -1,11 +1,14 @@
@page "/staff/schedule"
@layout StaffLayout
-@inject WebClientTpos.Client.Services.PosDataService DataService
+@using WebClientTpos.Client.Services
+@inject PosDataService DataService
+@inject AuthService AuthSvc
+@inject AuthStateService AuthState
@inject IJSRuntime JS
@*
- EN: Staff schedule page — view weekly work schedule.
- VI: Trang lịch làm việc — xem lịch làm việc hàng tuần.
+ EN: Staff schedule page — view weekly work schedule from real API data.
+ VI: Trang lịch làm việc — xem lịch làm việc hàng tuần từ dữ liệu API thật.
*@
Lịch làm việc
@@ -16,60 +19,124 @@
Lịch trình làm việc của bạn
- @* ═══ WEEK VIEW ═══ *@
-
- @for (int i = 0; i < 7; i++)
- {
- var day = _weekStart.AddDays(i);
- var isToday = day.Date == DateTime.Now.Date;
- var isWeekend = day.DayOfWeek == DayOfWeek.Sunday;
-
-
@GetDayName(day)
-
@day.Day
- @if (isWeekend)
- {
-
Nghỉ
- }
- else
- {
-
08:00 - 17:00
- }
+ @if (_loading)
+ {
+
+ }
+ else if (!_mySchedules.Any())
+ {
+
+
Chưa có lịch làm việc
+
Quản lý chưa phân lịch cho bạn
+
+ }
+ else
+ {
+ @* ═══ WEEK VIEW ═══ *@
+
+ @for (int i = 0; i < 7; i++)
+ {
+ var day = _weekStart.AddDays(i);
+ var isToday = day.Date == DateTime.Now.Date;
+ var dow = (int)day.DayOfWeek;
+ var daySchedules = _mySchedules.Where(s => s.DayOfWeek == dow).OrderBy(s => s.StartTime).ToList();
+ var hasSchedule = daySchedules.Any();
+
+
@GetDayName(day)
+
@day.Day
+ @if (hasSchedule)
+ {
+ @foreach (var sched in daySchedules)
+ {
+
@FormatTime(sched.StartTime) - @FormatTime(sched.EndTime)
+ }
+ }
+ else
+ {
+
Nghỉ
+ }
+
+ }
+
- @* ═══ UPCOMING SHIFTS ═══ *@
-
-
-
-
-
-
-
-
Ca sáng: 08:00 - 12:00
-
Thu 2 - Thu 6
-
-
-
-
-
-
Ca chiều: 13:00 - 17:00
-
Thu 2 - Thu 6
-
+ @* ═══ SHIFT DETAILS ═══ *@
+
+
+
+
+ @foreach (var group in _mySchedules.GroupBy(s => new { s.StartTime, s.EndTime }).OrderBy(g => g.Key.StartTime))
+ {
+ var isMorning = group.Key.StartTime?.CompareTo("12:00") < 0;
+ var isEvening = group.Key.StartTime?.CompareTo("18:00") >= 0;
+ var color = isEvening ? "#F59E0B" : isMorning ? "#22C55E" : "#3B82F6";
+ var label = isEvening ? "Ca tối" : isMorning ? "Ca sáng" : "Ca chiều";
+ var days = string.Join(", ", group.OrderBy(s => s.DayOfWeek == 0 ? 7 : s.DayOfWeek).Select(s => DayLabel(s.DayOfWeek)));
+
+
+
+
@label: @FormatTime(group.Key.StartTime) - @FormatTime(group.Key.EndTime)
+
@days
+
+
+ }
-
+ }
@code {
+ private bool _loading = true;
+ private List
_mySchedules = new();
private DateTime _weekStart = DateTime.Now.Date.AddDays(-(int)DateTime.Now.DayOfWeek + (int)DayOfWeek.Monday);
protected override async Task OnAfterRenderAsync(bool firstRender)
{
try { await JS.InvokeVoidAsync("lucide.createIcons"); } catch { }
+
+ if (firstRender)
+ {
+ // EN: Restore staff session and load schedule data
+ // VI: Khôi phục session nhân viên và tải dữ liệu lịch
+ if (!AuthState.IsAuthenticated)
+ {
+ try { await AuthSvc.TryRestoreSessionAsync("staff"); } catch { }
+ }
+
+ try
+ {
+ var profile = await DataService.GetMyStaffProfileAsync();
+ if (profile?.ShopId != null)
+ {
+ var allSchedules = await DataService.GetStaffSchedulesAsync(profile.ShopId.Value);
+ _mySchedules = allSchedules.Where(s => s.StaffId == profile.StaffId).ToList();
+ }
+ }
+ catch { /* API unavailable */ }
+
+ _loading = false;
+ StateHasChanged();
+ }
+ }
+
+ ///
+ /// EN: Format time string — remove seconds if present (08:00:00 → 08:00).
+ /// VI: Định dạng giờ — bỏ giây nếu có (08:00:00 → 08:00).
+ ///
+ private static string FormatTime(string? time)
+ {
+ if (string.IsNullOrEmpty(time)) return "—";
+ // Handle "08:00:00" -> "08:00"
+ var parts = time.Split(':');
+ return parts.Length >= 2 ? $"{parts[0]}:{parts[1]}" : time;
}
private static string GetDayName(DateTime d) => d.DayOfWeek switch
@@ -83,4 +150,16 @@
DayOfWeek.Sunday => "CN",
_ => ""
};
+
+ private static string DayLabel(int dow) => dow switch
+ {
+ 1 => "Thứ 2",
+ 2 => "Thứ 3",
+ 3 => "Thứ 4",
+ 4 => "Thứ 5",
+ 5 => "Thứ 6",
+ 6 => "Thứ 7",
+ 0 => "CN",
+ _ => ""
+ };
}