From 6d4850f4cee125fe3ec8d9d65958f981548daf64 Mon Sep 17 00:00:00 2001 From: Iqbal Date: Mon, 26 Oct 2026 09:59:22 +0700 Subject: [PATCH] Switch organizations from the Learning space card Co-Authored-By: Claude Opus 5.5 --- src/components/AppLayout.tsx | 55 ++++++++++++++++++++++++++++++++---- src/components/Icon.tsx | 3 +- src/i18n.ts | 2 ++ src/styles/theme.css | 9 ++++++ 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/src/components/AppLayout.tsx b/src/components/AppLayout.tsx index 24cae55..0d4af3f 100644 --- a/src/components/AppLayout.tsx +++ b/src/components/AppLayout.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState } from 'react' -import { useClerk, useOrganization, useUser } from '@clerk/react' +import { useClerk, useOrganization, useOrganizationList, useUser } from '@clerk/react' import { useQuery } from '@tanstack/react-query' import { NavLink, Outlet, useLocation } from 'react-router-dom' import { LANGS, locale, setLang, t, useLang, type Key } from '../i18n' @@ -70,11 +70,57 @@ function CreditBalance() { ) } +// The Learning space card switches the active organization. AuthGate keys the pages by orgId and +// clears the query cache, so Brain, schedules, results and credits all reload for the new one. +function OrgSwitcher() { + const [open, setOpen] = useState(false) + const ref = useRef(null) + const { organization } = useOrganization() + const { setActive, userMemberships } = useOrganizationList({ userMemberships: { infinite: true } }) + + useEffect(() => { + if (!open) return + const onClick = (e: MouseEvent) => { if (!ref.current?.contains(e.target as Node)) setOpen(false) } + const onKey = (e: KeyboardEvent) => { if (e.key === 'Escape') setOpen(false) } + document.addEventListener('mousedown', onClick) + document.addEventListener('keydown', onKey) + return () => { document.removeEventListener('mousedown', onClick); document.removeEventListener('keydown', onKey) } + }, [open]) + + const choose = (id: string) => { + setOpen(false) + if (id !== organization?.id) void setActive?.({ organization: id }) + } + + return ( +
+ + {open && ( +
    + {userMemberships.data?.map(({ organization: org }) => ( +
  • + +
  • + ))} +
+ )} +
+ ) +} + export function AppLayout() { useLang() const [help, setHelp] = useState(false) const { user } = useUser() - const { organization } = useOrganization() const { signOut } = useClerk() const { pathname } = useLocation() const current = NAV.find(n => pathname.startsWith(n.to)) @@ -84,10 +130,7 @@ export function AppLayout() {