@@ -11,8 +11,18 @@ import {
1111 DialogTrigger ,
1212 DialogClose ,
1313} from "@ui/components/dialog"
14+ import { authClient } from "@lib/auth"
15+ import { Popover , PopoverContent , PopoverTrigger } from "@ui/components/popover"
1416import { useCustomer } from "autumn-js/react"
15- import { Check , X , Trash2 , LoaderIcon , Settings } from "lucide-react"
17+ import {
18+ Check ,
19+ X ,
20+ Trash2 ,
21+ LoaderIcon ,
22+ Settings ,
23+ ChevronDown ,
24+ Building2 ,
25+ } from "lucide-react"
1626import { useState } from "react"
1727
1828function SectionTitle ( { children } : { children : React . ReactNode } ) {
@@ -76,11 +86,25 @@ function PlanFeatureRow({
7686}
7787
7888export default function Account ( ) {
79- const { user, org } = useAuth ( )
89+ const { user, org, setActiveOrg } = useAuth ( )
8090 const autumn = useCustomer ( )
8191 const [ isUpgrading , setIsUpgrading ] = useState ( false )
8292 const [ deleteConfirmText , setDeleteConfirmText ] = useState ( "" )
8393 const [ isDeleteDialogOpen , setIsDeleteDialogOpen ] = useState ( false )
94+ const [ switchingOrgId , setSwitchingOrgId ] = useState < string | null > ( null )
95+ const { data : allOrgs } = authClient . useListOrganizations ( )
96+
97+ const handleOrgSwitch = async ( orgSlug : string , orgId : string ) => {
98+ if ( orgId === org ?. id ) return
99+ setSwitchingOrgId ( orgId )
100+ try {
101+ await setActiveOrg ( orgSlug )
102+ window . location . reload ( )
103+ } catch ( error ) {
104+ console . error ( "Failed to switch organization:" , error )
105+ setSwitchingOrgId ( null )
106+ }
107+ }
84108
85109 const {
86110 memoriesUsed,
@@ -163,7 +187,6 @@ export default function Account() {
163187 </ div >
164188 </ div >
165189
166- { /* Organization + Member since */ }
167190 < div className = "flex gap-4" >
168191 < div className = "flex-1 flex flex-col gap-2" >
169192 < p
@@ -174,14 +197,76 @@ export default function Account() {
174197 >
175198 Organization
176199 </ p >
177- < p
178- className = { cn (
179- dmSans125ClassName ( ) ,
180- "font-medium text-[16px] tracking-[-0.16px] text-[#FAFAFA]" ,
200+ < Popover >
201+ < PopoverTrigger
202+ className = { cn (
203+ "flex items-center gap-2 cursor-pointer transition-opacity hover:opacity-90" ,
204+ dmSans125ClassName ( ) ,
205+ ) }
206+ >
207+ < span
208+ className = { cn (
209+ dmSans125ClassName ( ) ,
210+ "font-medium text-[16px] tracking-[-0.16px] text-[#FAFAFA]" ,
211+ ) }
212+ >
213+ { org ?. name ?? "Personal" }
214+ </ span >
215+ < ChevronDown className = "size-4 text-[#737373]" />
216+ </ PopoverTrigger >
217+ { allOrgs && allOrgs . length > 1 && (
218+ < PopoverContent
219+ align = "start"
220+ className = "w-72 bg-[#1B1F24] rounded-[12px] border-white/10 p-1.5 shadow-[0px_4px_16px_rgba(0,0,0,0.4)]"
221+ >
222+ { allOrgs . map ( ( organization ) => {
223+ const isCurrent = organization . id === org ?. id
224+ const isSwitching = switchingOrgId === organization . id
225+ const isConsumer =
226+ organization . metadata ?. isConsumer === true
227+ return (
228+ < button
229+ key = { organization . id }
230+ type = "button"
231+ disabled = { isCurrent || isSwitching }
232+ onClick = { ( ) =>
233+ handleOrgSwitch (
234+ organization . slug ,
235+ organization . id ,
236+ )
237+ }
238+ className = { cn (
239+ "w-full flex items-center gap-3 px-3 py-2.5 rounded-[8px] text-left transition-colors" ,
240+ isCurrent
241+ ? "bg-white/5"
242+ : "hover:bg-white/5 cursor-pointer" ,
243+ "disabled:opacity-60 disabled:cursor-default" ,
244+ dmSans125ClassName ( ) ,
245+ ) }
246+ >
247+ < Building2 className = "size-4 text-[#737373] shrink-0" />
248+ < div className = "flex-1 min-w-0 flex items-center gap-2" >
249+ < p className = "text-[14px] tracking-[-0.14px] text-[#FAFAFA] truncate" >
250+ { organization . name }
251+ </ p >
252+ { isCurrent && (
253+ < Check className = "size-4 text-[#4BA0FA] shrink-0" />
254+ ) }
255+ { isSwitching && (
256+ < LoaderIcon className = "size-4 text-[#4BA0FA] shrink-0 animate-spin" />
257+ ) }
258+ </ div >
259+ { ! isConsumer && (
260+ < span className = "text-[11px] font-medium tracking-[0.3px] px-1.5 py-0.5 rounded-[4px] shrink-0 bg-[#737373]/15 text-[#737373]" >
261+ API
262+ </ span >
263+ ) }
264+ </ button >
265+ )
266+ } ) }
267+ </ PopoverContent >
181268 ) }
182- >
183- { org ?. name ?? "Personal" }
184- </ p >
269+ </ Popover >
185270 </ div >
186271 < div className = "flex-1 flex flex-col gap-2" >
187272 < p
0 commit comments