From 867dc717ccfcdd7c1d31e8cdfe98bf1f03d9086c Mon Sep 17 00:00:00 2001 From: WorkClub Automation Date: Mon, 9 Mar 2026 14:46:35 +0100 Subject: [PATCH] fix(shifts): expose ExternalUserId in ShiftSignupDto to fix frontend signup state --- .../Services/MemberSyncService.cs | 14 ++++++++++++ backend/WorkClub.Api/Services/ShiftService.cs | 22 ++++++++++++------- .../Shifts/DTOs/ShiftDetailDto.cs | 2 +- .../src/app/(protected)/shifts/[id]/page.tsx | 2 +- frontend/src/hooks/useShifts.ts | 1 + 5 files changed, 31 insertions(+), 10 deletions(-) diff --git a/backend/WorkClub.Api/Services/MemberSyncService.cs b/backend/WorkClub.Api/Services/MemberSyncService.cs index 7700f2b..369bf1e 100644 --- a/backend/WorkClub.Api/Services/MemberSyncService.cs +++ b/backend/WorkClub.Api/Services/MemberSyncService.cs @@ -41,6 +41,20 @@ public class MemberSyncService } var email = httpContext.User.FindFirst("email")?.Value ?? httpContext.User.FindFirst("preferred_username")?.Value ?? "unknown@example.com"; + + // If not found by ExternalUserId, try to find by Email (for seeded users) + var memberByEmail = await _context.Members + .FirstOrDefaultAsync(m => m.Email == email && m.TenantId == tenantId); + + if (memberByEmail != null) + { + // Update the seeded user with the real ExternalUserId + memberByEmail.ExternalUserId = externalUserId; + memberByEmail.UpdatedAt = DateTimeOffset.UtcNow; + await _context.SaveChangesAsync(); + return; + } + var name = httpContext.User.FindFirst("name")?.Value ?? email.Split('@')[0]; var roleClaim = httpContext.User.FindFirst(System.Security.Claims.ClaimTypes.Role)?.Value ?? "Member"; diff --git a/backend/WorkClub.Api/Services/ShiftService.cs b/backend/WorkClub.Api/Services/ShiftService.cs index 5e77c91..e40475e 100644 --- a/backend/WorkClub.Api/Services/ShiftService.cs +++ b/backend/WorkClub.Api/Services/ShiftService.cs @@ -61,14 +61,17 @@ public class ShiftService if (shift == null) return null; - var signups = await _context.ShiftSignups - .Where(ss => ss.ShiftId == id) - .OrderBy(ss => ss.SignedUpAt) - .ToListAsync(); + var signups = await (from ss in _context.ShiftSignups + where ss.ShiftId == id + join m in _context.Members on ss.MemberId equals m.Id + orderby ss.SignedUpAt + select new { ss.Id, ss.MemberId, m.ExternalUserId, ss.SignedUpAt }) + .ToListAsync(); var signupDtos = signups.Select(ss => new ShiftSignupDto( ss.Id, ss.MemberId, + ss.ExternalUserId, ss.SignedUpAt )).ToList(); @@ -165,14 +168,17 @@ public class ShiftService return (null, "Shift was modified by another user. Please refresh and try again.", true); } - var signups = await _context.ShiftSignups - .Where(ss => ss.ShiftId == id) - .OrderBy(ss => ss.SignedUpAt) - .ToListAsync(); + var signups = await (from ss in _context.ShiftSignups + where ss.ShiftId == id + join m in _context.Members on ss.MemberId equals m.Id + orderby ss.SignedUpAt + select new { ss.Id, ss.MemberId, m.ExternalUserId, ss.SignedUpAt }) + .ToListAsync(); var signupDtos = signups.Select(ss => new ShiftSignupDto( ss.Id, ss.MemberId, + ss.ExternalUserId, ss.SignedUpAt )).ToList(); diff --git a/backend/WorkClub.Application/Shifts/DTOs/ShiftDetailDto.cs b/backend/WorkClub.Application/Shifts/DTOs/ShiftDetailDto.cs index 4b541ee..1e4250a 100644 --- a/backend/WorkClub.Application/Shifts/DTOs/ShiftDetailDto.cs +++ b/backend/WorkClub.Application/Shifts/DTOs/ShiftDetailDto.cs @@ -17,6 +17,6 @@ public record ShiftDetailDto( public record ShiftSignupDto( Guid Id, - Guid MemberId, + Guid MemberId, string? ExternalUserId, DateTimeOffset SignedUpAt ); diff --git a/frontend/src/app/(protected)/shifts/[id]/page.tsx b/frontend/src/app/(protected)/shifts/[id]/page.tsx index aeff791..be3409f 100644 --- a/frontend/src/app/(protected)/shifts/[id]/page.tsx +++ b/frontend/src/app/(protected)/shifts/[id]/page.tsx @@ -23,7 +23,7 @@ export default function ShiftDetailPage({ params }: { params: Promise<{ id: stri const capacityPercentage = (shift.signups.length / shift.capacity) * 100; const isFull = shift.signups.length >= shift.capacity; const isPast = new Date(shift.startTime) < new Date(); - const isSignedUp = shift.signups.some((s) => s.memberId === session?.user?.id); + const isSignedUp = shift.signups.some((s) => s.memberId === session?.user?.id || s.externalUserId === session?.user?.id); const handleSignUp = async () => { await signUpMutation.mutateAsync(shift.id); diff --git a/frontend/src/hooks/useShifts.ts b/frontend/src/hooks/useShifts.ts index abf3199..26fdafe 100644 --- a/frontend/src/hooks/useShifts.ts +++ b/frontend/src/hooks/useShifts.ts @@ -36,6 +36,7 @@ export interface ShiftDetailDto { export interface ShiftSignupDto { id: string; memberId: string; + externalUserId?: string; signedUpAt: string; }