diff --git a/apps/web/app/auth/connect/page.tsx b/apps/web/app/auth/connect/page.tsx index 8ca89f37..bbd6bb95 100644 --- a/apps/web/app/auth/connect/page.tsx +++ b/apps/web/app/auth/connect/page.tsx @@ -5,7 +5,7 @@ import { useSession } from "@lib/auth" import { cn } from "@lib/utils" import { Logo } from "@ui/assets/Logo" import { dmSans125ClassName } from "@/lib/fonts" -import { ArrowLeft, ArrowRight, LoaderIcon, XCircle } from "lucide-react" +import { ArrowRight, LoaderIcon, XCircle } from "lucide-react" import Image from "next/image" import { useRouter, useSearchParams } from "next/navigation" import { @@ -193,7 +193,7 @@ function AuthConnectContent() { const params = useSearchParams() const router = useRouter() const { data: session, isPending } = useSession() - const { organizations, isRestoring } = useAuth() + const { org, organizations, isRestoring } = useAuth() const [status, setStatus] = useState("loading") const [error, setError] = useState(null) const [selectedOrgId, setSelectedOrgId] = useState(null) @@ -205,6 +205,7 @@ function AuthConnectContent() { const client = params.get("client") const clientsParam = params.get("clients") const hasClientList = params.has("clients") + const isSwitchMode = params.get("mode") === "switch_organization" const rawRequestedClients = useMemo( () => (clientsParam !== null ? clientsParam.split(",") : client ? [client] : []) @@ -270,33 +271,31 @@ function AuthConnectContent() { router.replace("/onboarding") }, [isPending, isRestoring, session, organizations, router, requestError]) - const selectOrganization = useCallback( - (organization: NonNullable[number]) => { - setError(null) - setSelectedOrgId(organization.id) - setStatus("approval") - }, - [], - ) - useEffect(() => { if (requestError || isPending || isRestoring || organizations === null) return if (!session || organizations.length === 0 || status !== "loading") return - if (organizations.length > 1) { + if (isSwitchMode) { setStatus("selection") return } - const onlyOrganization = organizations[0] - if (onlyOrganization) selectOrganization(onlyOrganization) + + const defaultOrganization = + organizations.find((organization) => organization.id === org?.id) ?? + organizations[0] + if (defaultOrganization) { + setSelectedOrgId(defaultOrganization.id) + setStatus("approval") + } }, [ + isSwitchMode, requestError, isPending, isRestoring, + org?.id, organizations, session, status, - selectOrganization, ]) useEffect(() => { @@ -325,9 +324,9 @@ function AuthConnectContent() { measureFades(listRef.current) }, [measureFades, status]) - async function handleConnect() { + async function handleConnect(organization = selectedOrg): Promise { if (requestError || !callback) return - if (!session || !selectedOrg) { + if (!session || !organization) { setError( selectedOrgId ? "That organization is no longer available. Choose another one." @@ -345,7 +344,7 @@ function AuthConnectContent() { const fetchParams = new URLSearchParams({ callback, client: requestedClient, - orgId: selectedOrg.id, + orgId: organization.id, }) const res = await fetch(`${API_URL}/v3/auth/key?${fetchParams}`, { credentials: "include", @@ -362,9 +361,9 @@ function AuthConnectContent() { key: string organization?: { id: string } } - const expectedKeyPrefix = `sm_${selectedOrg.id}_` + const expectedKeyPrefix = `sm_${organization.id}_` if ( - (data.organization && data.organization.id !== selectedOrg.id) || + (data.organization && data.organization.id !== organization.id) || !data.key.startsWith(expectedKeyPrefix) ) { throw new Error( @@ -417,10 +416,22 @@ function AuthConnectContent() { } catch (err) { console.error("Failed to get API key:", err) setError(err instanceof Error ? err.message : "Failed to get API key") - setStatus("approval") + setStatus(isSwitchMode ? "selection" : "approval") } } + function selectOrganization( + organization: NonNullable[number], + ): void { + setError(null) + setSelectedOrgId(organization.id) + if (isSwitchMode) { + void handleConnect(organization) + return + } + setStatus("approval") + } + const isAuthLoading = isPending || isRestoring || organizations === null if (requestError) { @@ -545,6 +556,19 @@ function AuthConnectContent() { ) } + if (isSwitchMode && status === "creating") { + return ( +
+
+
+

+ Switching organization… +

+
+
+ ) + } + if (status === "approval" || status === "creating") { const creating = status === "creating" return ( @@ -584,7 +608,7 @@ function AuthConnectContent() { ))}
-
+
Connecting to @@ -593,20 +617,6 @@ function AuthConnectContent() { {selectedOrg?.name ?? "Organization unavailable"}

- {multiOrg && ( - - )}
{error && ( @@ -645,6 +655,19 @@ function AuthConnectContent() { )}
+ {multiOrg && ( + + )}