diff --git a/.changeset/tasty-animals-grab.md b/.changeset/tasty-animals-grab.md
new file mode 100644
index 00000000000..a5ba5caec27
--- /dev/null
+++ b/.changeset/tasty-animals-grab.md
@@ -0,0 +1,5 @@
+---
+'@clerk/ui': patch
+---
+
+Fix "You must belong to an organization" screen showing when user has existing memberships, invitations or suggestions
diff --git a/packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/__tests__/TaskChooseOrganization.test.tsx b/packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/__tests__/TaskChooseOrganization.test.tsx
index 28952bd96c9..5cf4ed8e53f 100644
--- a/packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/__tests__/TaskChooseOrganization.test.tsx
+++ b/packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/__tests__/TaskChooseOrganization.test.tsx
@@ -3,7 +3,10 @@ import { describe, expect, it } from 'vitest';
import { bindCreateFixtures } from '@/test/create-fixtures';
import { render } from '@/test/utils';
-import { createFakeUserOrganizationMembership } from '@/ui/components/OrganizationSwitcher/__tests__/test-utils';
+import {
+ createFakeUserOrganizationMembership,
+ createFakeUserOrganizationSuggestion,
+} from '@/ui/components/OrganizationSwitcher/__tests__/test-utils';
import { TaskChooseOrganization } from '..';
@@ -296,5 +299,56 @@ describe('TaskChooseOrganization', () => {
expect(queryByText(/you must belong to an organization/i)).toBeInTheDocument();
expect(queryByText(/contact your organization admin for an invitation/i)).toBeInTheDocument();
});
+
+ it('with existing memberships or suggestions, displays create organization screen', async () => {
+ const { wrapper, fixtures } = await createFixtures(f => {
+ f.withOrganizations();
+ f.withForceOrganizationSelection();
+ f.withUser({
+ create_organization_enabled: false,
+ });
+ });
+
+ fixtures.clerk.user?.getOrganizationMemberships.mockReturnValueOnce(
+ Promise.resolve({
+ data: [
+ createFakeUserOrganizationMembership({
+ id: '1',
+ organization: {
+ id: '1',
+ name: 'Existing Org',
+ slug: 'org1',
+ membersCount: 1,
+ adminDeleteEnabled: false,
+ maxAllowedMemberships: 1,
+ pendingInvitationsCount: 1,
+ },
+ }),
+ ],
+ total_count: 1,
+ }),
+ );
+
+ fixtures.clerk.user?.getOrganizationSuggestions.mockReturnValueOnce(
+ Promise.resolve({
+ data: [
+ createFakeUserOrganizationSuggestion({
+ id: '2',
+ emailAddress: 'two@clerk.com',
+ publicOrganizationData: {
+ name: 'OrgTwoSuggestion',
+ },
+ }),
+ ],
+ total_count: 1,
+ }),
+ );
+
+ const { findByText, queryByRole } = render(, { wrapper });
+
+ expect(await findByText('Existing Org')).toBeInTheDocument();
+ expect(await findByText('Create new organization')).toBeInTheDocument();
+ expect(queryByRole('textbox', { name: /name/i })).not.toBeInTheDocument();
+ });
});
});
diff --git a/packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/index.tsx b/packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/index.tsx
index 3275a184707..dc3375e0d0b 100644
--- a/packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/index.tsx
+++ b/packages/ui/src/components/SessionTasks/tasks/TaskChooseOrganization/index.tsx
@@ -1,5 +1,5 @@
import { useClerk, useSession, useUser } from '@clerk/shared/react';
-import { useState, type ComponentType } from 'react';
+import { useState } from 'react';
import { useSignOutContext, withCoreSessionSwitchGuard } from '@/ui/contexts';
import { descriptors, Flex, Flow, localizationKeys, Spinner } from '@/ui/customizables';
@@ -14,24 +14,16 @@ import { ChooseOrganizationScreen } from './ChooseOrganizationScreen';
import { CreateOrganizationScreen } from './CreateOrganizationScreen';
const TaskChooseOrganizationInternal = () => {
- const { signOut } = useClerk();
const { user } = useUser();
- const { session } = useSession();
const { userMemberships, userSuggestions, userInvitations } = useOrganizationListInView();
- const { otherSessions } = useMultipleSessions({ user });
- const { navigateAfterSignOut, navigateAfterMultiSessionSingleSignOutUrl } = useSignOutContext();
-
- const handleSignOut = () => {
- if (otherSessions.length === 0) {
- return signOut(navigateAfterSignOut);
- }
-
- return signOut(navigateAfterMultiSessionSingleSignOutUrl, { sessionId: session?.id });
- };
const isLoading = userMemberships?.isLoading || userInvitations?.isLoading || userSuggestions?.isLoading;
const hasExistingResources = !!(userMemberships?.count || userInvitations?.count || userSuggestions?.count);
- const identifier = user?.primaryEmailAddress?.emailAddress ?? user?.username;
+ const isOrganizationCreationDisabled = !isLoading && !user?.createOrganizationEnabled && !hasExistingResources;
+
+ if (isOrganizationCreationDisabled) {
+ return ;
+ }
return (
@@ -127,18 +119,6 @@ const TaskChooseOrganizationFlows = withCardStateProvider((props: TaskChooseOrga
return setCurrentFlow('create')} />;
});
-export const withOrganizationCreationEnabledGuard = (Component: ComponentType) => {
- return (props: T) => {
- const { user } = useUser();
-
- if (!user?.createOrganizationEnabled) {
- return ;
- }
-
- return ;
- };
-};
-
function OrganizationCreationDisabledScreen() {
return (
@@ -163,8 +143,5 @@ function OrganizationCreationDisabledScreen() {
}
export const TaskChooseOrganization = withCoreSessionSwitchGuard(
- withTaskGuard(
- withCardStateProvider(withOrganizationCreationEnabledGuard(TaskChooseOrganizationInternal)),
- 'choose-organization',
- ),
+ withTaskGuard(withCardStateProvider(TaskChooseOrganizationInternal), 'choose-organization'),
);