const API_BASE = 'https://api.dongfeng-systems.org' export interface WeatherLocation { city: string latitude: number longitude: number } export interface CurrentWeather { city: string temperatureF: number humidityPercent: number windSpeedMph: number weatherCode: number description: string } const LOCATION_SET_KEY = 'weatherLocationSet' const TEMP_UNIT_KEY = 'weatherTempUnit' const TIME_FORMAT_KEY = 'timeFormat' export type TempUnit = 'C' | 'F' export type TimeFormat = '12h' | '24h' /** * Check if location has been set (localStorage hint) */ export function hasLocationHint(): boolean { if (typeof window === 'undefined') return false return localStorage.getItem(LOCATION_SET_KEY) === 'true' } /** * Get temperature unit preference from localStorage */ export function getTempUnit(): TempUnit { if (typeof window === 'undefined') return 'F' const stored = localStorage.getItem(TEMP_UNIT_KEY) return stored === 'C' ? 'C' : 'F' } /** * Set temperature unit preference in localStorage */ export function setTempUnit(unit: TempUnit): void { if (typeof window === 'undefined') return localStorage.setItem(TEMP_UNIT_KEY, unit) } /** * Convert Fahrenheit to Celsius */ export function fahrenheitToCelsius(f: number): number { return (f - 32) * (5 / 9) } /** * Format temperature with unit */ export function formatTemperature(tempF: number, unit: TempUnit): string { if (unit === 'C') { return `${Math.round(fahrenheitToCelsius(tempF))}°C` } return `${Math.round(tempF)}°F` } /** * Get time format preference from localStorage */ export function getTimeFormat(): TimeFormat { if (typeof window === 'undefined') return '12h' const stored = localStorage.getItem(TIME_FORMAT_KEY) return stored === '24h' ? '24h' : '12h' } /** * Set time format preference in localStorage */ export function setTimeFormat(format: TimeFormat): void { if (typeof window === 'undefined') return localStorage.setItem(TIME_FORMAT_KEY, format) } /** * Mark location as set in localStorage */ export function setLocationHint(value: boolean): void { if (typeof window === 'undefined') return if (value) { localStorage.setItem(LOCATION_SET_KEY, 'true') } else { localStorage.removeItem(LOCATION_SET_KEY) } } /** * Set user's weather location by city name */ export async function setWeatherLocation(city: string, user: string = 'frontend'): Promise { const res = await fetch( `${API_BASE}/api/weather/set-location?user=${encodeURIComponent(user)}&city=${encodeURIComponent(city)}`, { cache: 'no-store' } ) if (!res.ok) { const text = await res.text() throw new Error(text || 'Failed to set location') } return res.json() } /** * Get current weather for user * Returns null if no location is set (instead of throwing) */ export async function getCurrentWeather(user: string = 'frontend'): Promise { try { const res = await fetch( `${API_BASE}/api/weather/current?user=${encodeURIComponent(user)}`, { cache: 'no-store' } ) if (!res.ok) { const text = await res.text() // Check if it's a "no location set" error - treat 404 and location-related errors as needing location if ( text.toLowerCase().includes('no location') || text.toLowerCase().includes('location not set') || text.toLowerCase().includes('not found') || res.status === 404 || res.status === 400 ) { return null } throw new Error(text || 'Failed to fetch weather') } return res.json() } catch (err) { // Network errors or other fetch failures - treat as needing location setup if (err instanceof TypeError && err.message.includes('fetch')) { return null } // Re-throw actual errors throw err } }