@@ -7,7 +7,8 @@ const API_BASE = process.env.NEXT_PUBLIC_API_URL || "https://edeziav2.onrender.c
77
88const safeFetch = async ( url : string , options : RequestInit = { } ) : Promise < Response > => {
99 const isHeavyRequest = url . includes ( "/upload" ) || url . includes ( "/submissions" ) || url . includes ( "/runs" ) || url . includes ( "/grade" ) ;
10- const defaultTimeout = isHeavyRequest ? 120000 : 8000 ; // 120 seconds for AI/upload tasks, 8 seconds for fast auth
10+ const isListRequest = url . includes ( "/exam-cycles" ) || url . includes ( "/question-papers" ) || url . includes ( "/classrooms" ) || url . includes ( "/schools" ) ;
11+ const defaultTimeout = isHeavyRequest ? 120000 : isListRequest ? 30000 : 8000 ; // 120s for AI/upload, 30s for list endpoints (cold starts), 8s for auth
1112 const timeoutMs = ( options as any ) . timeout !== undefined ? ( options as any ) . timeout : defaultTimeout ;
1213
1314 const controller = new AbortController ( ) ;
@@ -23,7 +24,7 @@ const safeFetch = async (url: string, options: RequestInit = {}): Promise<Respon
2324 const parts = url . split ( "," ) ;
2425 const firstBase = parts [ 0 ] ;
2526 const rest = parts . slice ( 1 ) . join ( "," ) ;
26-
27+
2728 // Resolve path from secondary base dynamically
2829 const secondBase = "https://edeziav2.onrender.com/api/v1" ;
2930 let path = "" ;
@@ -35,17 +36,17 @@ const safeFetch = async (url: string, options: RequestInit = {}): Promise<Respon
3536 path = rest . substring ( idx + "/api/v1" . length ) ;
3637 }
3738 }
38-
39+
3940 const url1 = `${ firstBase } ${ path } ` ;
4041 const url2 = rest ;
41-
42+
4243 try {
4344 const res = await fetch ( url1 , fetchOptions ) ;
4445 if ( id ) clearTimeout ( id ) ;
4546 return res ;
4647 } catch ( err ) {
4748 console . warn ( `Local API offline at ${ url1 } , falling back to remote production at ${ url2 } ` , err ) ;
48-
49+
4950 // Reset timeout for fallback fetch
5051 const fallbackController = new AbortController ( ) ;
5152 const fallbackId = timeoutMs > 0 ? setTimeout ( ( ) => fallbackController . abort ( ) , timeoutMs ) : null ;
@@ -113,7 +114,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
113114 if ( storedToken ) {
114115 setToken ( storedToken ) ;
115116 setRefreshToken ( typeof window !== "undefined" ? localStorage . getItem ( "ozymorlab_refresh_token" ) : null ) ;
116-
117+
117118 safeFetch ( `${ API_BASE } /auth/me` , {
118119 headers : { Authorization : `Bearer ${ storedToken } ` } ,
119120 } )
@@ -145,7 +146,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
145146 if ( session ) {
146147 setToken ( session . access_token ) ;
147148 setRefreshToken ( session . refresh_token || null ) ;
148-
149+
149150 // Validate token and sync profile with Edexia backend
150151 safeFetch ( `${ API_BASE } /auth/me` , {
151152 headers : { Authorization : `Bearer ${ session . access_token } ` } ,
@@ -180,7 +181,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
180181 if ( session ) {
181182 setToken ( session . access_token ) ;
182183 setRefreshToken ( session . refresh_token || null ) ;
183-
184+
184185 try {
185186 const res = await safeFetch ( `${ API_BASE } /auth/me` , {
186187 headers : { Authorization : `Bearer ${ session . access_token } ` } ,
@@ -224,15 +225,15 @@ export function AuthProvider({ children }: { children: ReactNode }) {
224225 if ( ! res . ok ) {
225226 return { success : false , error : json . detail || "Invalid email or password" } ;
226227 }
227-
228+
228229 const { access_token, refresh_token } = json . data ;
229230 setToken ( access_token ) ;
230231 setRefreshToken ( refresh_token ) ;
231232 if ( typeof window !== "undefined" ) {
232233 localStorage . setItem ( "ozymorlab_token" , access_token ) ;
233234 localStorage . setItem ( "ozymorlab_refresh_token" , refresh_token ) ;
234235 }
235-
236+
236237 // Fetch profile
237238 const profileRes = await safeFetch ( `${ API_BASE } /auth/me` , {
238239 headers : { Authorization : `Bearer ${ access_token } ` } ,
@@ -306,7 +307,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
306307 if ( ! res . ok ) {
307308 return { success : false , error : json . detail || "Account creation failed" } ;
308309 }
309-
310+
310311 const { tokens, user : userProfile } = json . data ;
311312 setToken ( tokens . access_token ) ;
312313 setRefreshToken ( tokens . refresh_token ) ;
@@ -446,9 +447,9 @@ export function AuthProvider({ children }: { children: ReactNode }) {
446447 headers : { "Content-Type" : "application/json" } ,
447448 body : JSON . stringify ( { gemini_api_key : key } ) ,
448449 } ) ;
449-
450+
450451 console . log ( "➡️ Response status code:" , res . status , res . statusText ) ;
451-
452+
452453 let responseBody = "" ;
453454 try {
454455 responseBody = await res . text ( ) ;
@@ -474,9 +475,9 @@ export function AuthProvider({ children }: { children: ReactNode }) {
474475 return { success : true } ;
475476 } catch ( err : any ) {
476477 console . error ( "❌ hard network failure inside setGeminiKey fetch block:" , err ) ;
477- return {
478- success : false ,
479- error : `Network error: ${ err . message || "Failed to reach backend" } . Please check your browser DevTools Console for CORS preflight blocks or connection drops.`
478+ return {
479+ success : false ,
480+ error : `Network error: ${ err . message || "Failed to reach backend" } . Please check your browser DevTools Console for CORS preflight blocks or connection drops.`
480481 } ;
481482 }
482483 } ;
@@ -487,7 +488,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
487488 const res = await fetchWithAuth ( `${ API_BASE } /auth/gemini-key` , {
488489 method : "DELETE" ,
489490 } ) ;
490-
491+
491492 console . log ( "➡️ Response status code:" , res . status ) ;
492493 let responseBody = "" ;
493494 try {
@@ -521,7 +522,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
521522 console . log ( "➡️ refreshUser response status:" , res . status ) ;
522523 const text = await res . text ( ) ;
523524 console . log ( "➡️ refreshUser raw response:" , text ) ;
524-
525+
525526 if ( res . ok ) {
526527 const json = JSON . parse ( text ) ;
527528 setUser ( json . data ) ;
0 commit comments