22// Copyright © 2026 Giancarlo Erra — AGPL-3.0-or-later
33
44import { useState , useEffect , useMemo } from "react" ;
5- import { Star , Cloud , CloudSnow , Telescope , Globe , Settings , Home , HelpCircle } from "lucide-react" ;
5+ import { Star , Cloud , CloudSnow , Telescope , Globe , Settings , Home , HelpCircle , AlertTriangle } from "lucide-react" ;
66import { weatherService } from "../services/weatherService" ;
77import { processWeatherData , processSolarData , getScoreColor , getScoreLabel } from "../utils/weatherUtils" ;
88import {
@@ -29,6 +29,7 @@ export function Dashboard() {
2929 } ) ;
3030 const [ isLoading , setIsLoading ] = useState ( true ) ;
3131 const [ showHelp , setShowHelp ] = useState ( false ) ;
32+ const [ configuredLocation , setConfiguredLocation ] = useState < { lat : number ; lon : number } | null > ( null ) ;
3233
3334 useEffect ( ( ) => {
3435 // Subscribe to download status updates
@@ -37,6 +38,11 @@ export function Dashboard() {
3738 // Load initial data (with automatic download check)
3839 loadWeatherData ( ) ;
3940
41+ // Fetch configured location to detect mismatches
42+ fetch ( '/api/location' ) . then ( r => r . json ( ) ) . then ( loc => {
43+ if ( loc && typeof loc . lat === 'number' ) setConfiguredLocation ( loc ) ;
44+ } ) . catch ( ( ) => { } ) ;
45+
4046 return unsubscribe ;
4147 } , [ ] ) ;
4248
@@ -207,6 +213,11 @@ export function Dashboard() {
207213 . sort ( ( a , b ) => a . date . localeCompare ( b . date ) ) ;
208214 } , [ solarData , metOfficeSolarData ] ) ;
209215
216+ const locationMismatch = weatherData && configuredLocation
217+ ? Math . abs ( weatherData . metadata . latitude - configuredLocation . lat ) > 0.01 ||
218+ Math . abs ( weatherData . metadata . longitude - configuredLocation . lon ) > 0.01
219+ : false ;
220+
210221 if ( isLoading && ! weatherData && metOfficeDayData . length === 0 ) {
211222 return (
212223 < div className = "min-h-screen bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 flex items-center justify-center" >
@@ -336,9 +347,9 @@ export function Dashboard() {
336347 </ p >
337348 </ div >
338349
339- < div className = " bg-slate-800 border border-slate-700 rounded-lg p-6" >
350+ < div className = { ` bg-slate-800 border rounded-lg p-6 ${ locationMismatch ? 'border-amber-500/60' : 'border-slate-700' } ` } >
340351 < div className = "flex items-center space-x-3 mb-2" >
341- < Globe className = " h-6 w-6 text-blue-400" />
352+ < Globe className = { ` h-6 w-6 ${ locationMismatch ? ' text-amber-400' : 'text- blue-400' } ` } />
342353 < h3 className = "text-lg font-semibold text-white" > Location</ h3 >
343354 </ div >
344355 < div className = "text-lg font-medium text-white" >
@@ -348,6 +359,12 @@ export function Dashboard() {
348359 < p className = "text-sm text-slate-400 mt-1" >
349360 Elevation: { weatherData . metadata . height } m
350361 </ p >
362+ { locationMismatch && (
363+ < div className = "flex items-center gap-1.5 mt-2 text-xs text-amber-400" >
364+ < AlertTriangle className = "h-3.5 w-3.5 flex-shrink-0" />
365+ < span > Location changed — < button onClick = { handleRefresh } className = "underline hover:text-amber-300" > refresh</ button > to update</ span >
366+ </ div >
367+ ) }
351368 </ div >
352369
353370 < div className = "bg-slate-800 border border-slate-700 rounded-lg p-6" >
@@ -400,7 +417,7 @@ export function Dashboard() {
400417 />
401418 < div >
402419 < span className = "text-sm font-semibold text-white" >
403- Best night this week :{ " " }
420+ Best night:{ " " }
404421 </ span >
405422 < span
406423 className = { `text-sm font-bold ${ getScoreColor ( best . score ) } ` }
@@ -562,7 +579,7 @@ export function Dashboard() {
562579 />
563580 < div >
564581 < span className = "text-sm font-semibold text-white" >
565- Best solar day this week :{ " " }
582+ Best solar day:{ " " }
566583 </ span >
567584 < span
568585 className = { `text-sm font-bold ${ getScoreColor ( best . score ) } ` }
0 commit comments