22
33import type React from 'react'
44import { createContext , useCallback , useEffect , useMemo , useState } from 'react'
5+ import { createLogger } from '@sim/logger'
56import { useQueryClient } from '@tanstack/react-query'
67import { client } from '@/lib/auth/auth-client'
78import { extractSessionDataFromAuthClientResult } from '@/lib/auth/session-response'
@@ -34,6 +35,8 @@ export type SessionHookResult = {
3435
3536export const SessionContext = createContext < SessionHookResult | null > ( null )
3637
38+ const logger = createLogger ( 'SessionProvider' )
39+
3740export function SessionProvider ( { children } : { children : React . ReactNode } ) {
3841 const [ data , setData ] = useState < AppSession > ( null )
3942 const [ isPending , setIsPending ] = useState ( true )
@@ -49,14 +52,18 @@ export function SessionProvider({ children }: { children: React.ReactNode }) {
4952 : await client . getSession ( )
5053 const session = extractSessionDataFromAuthClientResult ( res ) as AppSession
5154 setData ( session )
55+ return session
5256 } catch ( e ) {
5357 setError ( e instanceof Error ? e : new Error ( 'Failed to fetch session' ) )
58+ return null
5459 } finally {
5560 setIsPending ( false )
5661 }
5762 } , [ ] )
5863
5964 useEffect ( ( ) => {
65+ let isCancelled = false
66+
6067 // Check if user was redirected after plan upgrade
6168 const params = new URLSearchParams ( window . location . search )
6269 const wasUpgraded = params . get ( 'upgraded' ) === 'true'
@@ -69,12 +76,51 @@ export function SessionProvider({ children }: { children: React.ReactNode }) {
6976 window . history . replaceState ( { } , '' , newUrl )
7077 }
7178
72- loadSession ( wasUpgraded ) . then ( ( ) => {
73- if ( wasUpgraded ) {
74- queryClient . invalidateQueries ( { queryKey : [ 'organizations' ] } )
75- queryClient . invalidateQueries ( { queryKey : [ 'subscription' ] } )
79+ const initializeSession = async ( ) => {
80+ const session = await loadSession ( wasUpgraded )
81+
82+ if ( ! wasUpgraded || isCancelled ) {
83+ return
7684 }
77- } )
85+
86+ queryClient . invalidateQueries ( { queryKey : [ 'organizations' ] } )
87+ queryClient . invalidateQueries ( { queryKey : [ 'subscription' ] } )
88+
89+ const activeOrganizationId = session ?. session ?. activeOrganizationId ?? null
90+ if ( activeOrganizationId ) {
91+ return
92+ }
93+
94+ try {
95+ const response = await fetch ( '/api/organizations' )
96+ if ( ! response . ok ) {
97+ return
98+ }
99+
100+ const orgData = ( await response . json ( ) ) as {
101+ organizations ?: Array < { id : string } >
102+ }
103+ const organizationId = orgData . organizations ?. [ 0 ] ?. id
104+
105+ if ( ! organizationId || isCancelled ) {
106+ return
107+ }
108+
109+ await client . organization . setActive ( { organizationId } )
110+
111+ if ( ! isCancelled ) {
112+ await loadSession ( true )
113+ }
114+ } catch ( error ) {
115+ logger . warn ( 'Failed to activate organization after subscription upgrade' , { error } )
116+ }
117+ }
118+
119+ void initializeSession ( )
120+
121+ return ( ) => {
122+ isCancelled = true
123+ }
78124 } , [ loadSession , queryClient ] )
79125
80126 useEffect ( ( ) => {
@@ -100,9 +146,13 @@ export function SessionProvider({ children }: { children: React.ReactNode }) {
100146 . catch ( ( ) => { } )
101147 } , [ data , isPending ] )
102148
149+ const refetch = useCallback ( async ( ) => {
150+ await loadSession ( )
151+ } , [ loadSession ] )
152+
103153 const value = useMemo < SessionHookResult > (
104- ( ) => ( { data, isPending, error, refetch : loadSession } ) ,
105- [ data , isPending , error , loadSession ]
154+ ( ) => ( { data, isPending, error, refetch } ) ,
155+ [ data , isPending , error , refetch ]
106156 )
107157
108158 return < SessionContext . Provider value = { value } > { children } </ SessionContext . Provider >
0 commit comments