diff --git a/devfront/src/features/clients/ClientsPage.tsx b/devfront/src/features/clients/ClientsPage.tsx index edcd5edd..74e49484 100644 --- a/devfront/src/features/clients/ClientsPage.tsx +++ b/devfront/src/features/clients/ClientsPage.tsx @@ -97,6 +97,14 @@ function ClientsPage() { enabled: hasAccessToken, }); + const { data: me, isLoading: isLoadingMe } = useQuery({ + queryKey: ["userMe"], + queryFn: fetchMe, + enabled: hasAccessToken, + }); + + const profileRole = me?.role?.trim() || role; + const { data: requestStatus, isLoading: isLoadingRequest, @@ -104,21 +112,16 @@ function ClientsPage() { } = useQuery({ queryKey: ["developer-request", tenantId], queryFn: () => fetchDeveloperRequestStatus(tenantId), - enabled: hasAccessToken && (role === "user" || role === "tenant_member"), + enabled: hasAccessToken && (profileRole === "user" || profileRole === "tenant_member"), }); const { data: tenants } = useQuery({ queryKey: ["myTenants"], queryFn: fetchMyTenants, enabled: hasAccessToken, }); - const { data: me } = useQuery({ - queryKey: ["userMe"], - queryFn: fetchMe, - enabled: hasAccessToken, - }); const createAccessState = resolveClientCreateAccess({ - role, + role: profileRole, requestStatus: requestStatus?.status, }); const canCreateClient = createAccessState === "can_create"; @@ -193,7 +196,6 @@ function ClientsPage() { (userProfile?.phone as string | undefined) || (userProfile?.phone_number as string | undefined) || ""; - const profileRole = me?.role || role; const profileRoleLabel = t(`ui.admin.role.${profileRole}`, profileRole); type StatTone = "up" | "down" | "stable"; @@ -236,7 +238,11 @@ function ClientsPage() { }, ]; - const isLoading = isLoadingClients || isLoadingStats || isLoadingRequest; + const isLoading = + isLoadingClients || + isLoadingStats || + isLoadingRequest || + (hasAccessToken && !profileRole && isLoadingMe); const requestSort = (key: ClientSortKey) => { setSortConfig((current) => toggleSort(current, key)); diff --git a/devfront/src/features/clients/clientCreateAccess.test.ts b/devfront/src/features/clients/clientCreateAccess.test.ts index 11ebcff8..79200c10 100644 --- a/devfront/src/features/clients/clientCreateAccess.test.ts +++ b/devfront/src/features/clients/clientCreateAccess.test.ts @@ -19,6 +19,15 @@ describe("client create access", () => { ).toBe("request_required"); }); + it("treats unresolved roles as request required instead of allowing creation", () => { + expect( + resolveClientCreateAccess({ + role: "", + requestStatus: undefined, + }), + ).toBe("request_required"); + }); + it("shows pending state while a developer request is under review", () => { expect( resolveClientCreateAccess({ diff --git a/devfront/src/features/clients/clientCreateAccess.ts b/devfront/src/features/clients/clientCreateAccess.ts index 150dce0e..64e3e556 100644 --- a/devfront/src/features/clients/clientCreateAccess.ts +++ b/devfront/src/features/clients/clientCreateAccess.ts @@ -19,6 +19,10 @@ export function resolveClientCreateAccess({ role, requestStatus, }: ResolveClientCreateAccessParams): ClientCreateAccessState { + if (!role.trim()) { + return "request_required"; + } + if (!canSelfRequestDeveloperAccess(role)) { return "can_create"; }