@@ -2,9 +2,6 @@ import React, { useState, useEffect } from 'react';
22import { Routes , Route , useSearchParams , useNavigate } from 'react-router-dom' ;
33import KeplerMap from './KeplerMap' ;
44
5- // Get Mapbox token from environment variable
6- const MAPBOX_TOKEN = import . meta. env . VITE_MAPBOX_TOKEN || '' ;
7-
85function NetworkMap ( ) {
96 const [ searchParams ] = useSearchParams ( ) ;
107 const navigate = useNavigate ( ) ;
@@ -13,17 +10,64 @@ function NetworkMap() {
1310 const [ config , setConfig ] = useState ( { } ) ;
1411 const [ loading , setLoading ] = useState ( true ) ;
1512 const [ error , setError ] = useState ( null ) ;
13+ const [ mapboxToken , setMapboxToken ] = useState ( '' ) ;
1614
1715 // Back URL
1816 const backUrl = id
1917 ? ( import . meta. env . DEV ? `http://localhost:5173/network?id=${ id } ` : `/network?id=${ id } ` )
2018 : '/network' ;
2119
20+ // Login URL - in dev mode, the SvelteKit app runs on port 5173
21+ const loginUrl = import . meta. env . DEV ? 'http://localhost:5173/login' : '/login' ;
22+
23+ // Check authentication on mount
24+ useEffect ( ( ) => {
25+ async function checkAuth ( ) {
26+ try {
27+ const response = await fetch ( '/api/v1/auth/me' ) ;
28+ // If we get 401, redirect to login (auth is enabled and user not authenticated)
29+ if ( response . status === 401 ) {
30+ window . location . href = loginUrl ;
31+ }
32+ } catch ( err ) {
33+ // Network errors - continue anyway (auth might be disabled)
34+ console . warn ( 'Auth check failed:' , err ) ;
35+ }
36+ }
37+
38+ checkAuth ( ) ;
39+ } , [ ] ) ;
40+
41+ useEffect ( ( ) => {
42+ // Fetch mapbox token from backend config
43+ async function fetchMapConfig ( ) {
44+ try {
45+ const response = await fetch ( '/api/v1/map/config' ) ;
46+ if ( response . ok ) {
47+ const data = await response . json ( ) ;
48+ setMapboxToken ( data . mapbox_token || '' ) ;
49+ }
50+ } catch ( err ) {
51+ console . warn ( 'Failed to fetch map config:' , err ) ;
52+ // Token will remain empty, map will show warning
53+ }
54+ }
55+
56+ fetchMapConfig ( ) ;
57+ } , [ ] ) ;
58+
2259 useEffect ( ( ) => {
2360 // Poll task status until complete
2461 async function pollTaskStatus ( statusUrl , maxAttempts = 60 ) {
2562 for ( let i = 0 ; i < maxAttempts ; i ++ ) {
2663 const response = await fetch ( statusUrl ) ;
64+
65+ // Check for auth errors
66+ if ( response . status === 401 ) {
67+ window . location . href = loginUrl ;
68+ return ;
69+ }
70+
2771 const result = await response . json ( ) ;
2872
2973 if ( result . state === 'SUCCESS' ) {
@@ -43,6 +87,11 @@ function NetworkMap() {
4387 async function fetchData ( endpoint , dataType ) {
4488 const response = await fetch ( endpoint ) ;
4589 if ( ! response . ok ) {
90+ if ( response . status === 401 ) {
91+ // User not authenticated - redirect to login
92+ window . location . href = loginUrl ;
93+ return ;
94+ }
4695 if ( response . status === 404 ) {
4796 throw new Error ( `Network "${ id } " not found` ) ;
4897 }
@@ -209,14 +258,14 @@ function NetworkMap() {
209258 ) ;
210259 }
211260
212- if ( ! MAPBOX_TOKEN ) {
261+ if ( ! mapboxToken ) {
213262 return (
214263 < div style = { styles . center } >
215264 < div style = { styles . warning } >
216265 < h2 > Mapbox Token Required</ h2 >
217266 < p > To display the network map, configure a Mapbox access token in your environment.</ p >
218267 < p style = { styles . small } >
219- Set < code > VITE_MAPBOX_TOKEN </ code > in your < code > .env </ code > file .
268+ Set < code > MAPBOX_TOKEN </ code > environment variable when running the application .
220269 </ p >
221270 < p style = { styles . small } >
222271 Create a free account and obtain a token at < a href = "https://www.mapbox.com/" target = "_blank" rel = "noopener" > mapbox.com</ a >
@@ -238,7 +287,7 @@ function NetworkMap() {
238287 < KeplerMap
239288 datasets = { datasets }
240289 config = { config }
241- mapboxToken = { MAPBOX_TOKEN }
290+ mapboxToken = { mapboxToken }
242291 />
243292 </ div >
244293 </ div >
0 commit comments