fix: before admin stations removal

This commit is contained in:
Eric Gullickson
2025-12-24 17:20:11 -06:00
parent 96ee43ea94
commit 8ef6b3d853
32 changed files with 1258 additions and 176 deletions

View File

@@ -0,0 +1,13 @@
/**
* @ai-summary API client for user preferences endpoints
* @ai-context Handles unit system, currency, and timezone preferences sync
*/
import { apiClient } from '../../../core/api/client';
import { UserPreferences, UpdatePreferencesRequest } from '../types/preferences.types';
export const preferencesApi = {
getPreferences: () => apiClient.get<UserPreferences>('/user/preferences'),
updatePreferences: (data: UpdatePreferencesRequest) =>
apiClient.put<UserPreferences>('/user/preferences', data),
};

View File

@@ -0,0 +1,61 @@
/**
* @ai-summary React hooks for user preferences management
* @ai-context Handles unit system, currency, and timezone preference sync with backend
*/
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useAuth0 } from '@auth0/auth0-react';
import { preferencesApi } from '../api/preferences.api';
import { UpdatePreferencesRequest } from '../types/preferences.types';
import toast from 'react-hot-toast';
interface ApiError {
response?: {
data?: {
error?: string;
message?: string;
};
};
message?: string;
}
export const usePreferences = () => {
const { isAuthenticated, isLoading } = useAuth0();
return useQuery({
queryKey: ['user-preferences'],
queryFn: async () => {
const response = await preferencesApi.getPreferences();
return response.data;
},
enabled: isAuthenticated && !isLoading,
staleTime: 5 * 60 * 1000, // 5 minutes
gcTime: 10 * 60 * 1000, // 10 minutes cache time
retry: (failureCount, error: any) => {
// Retry 401s a few times (auth token might be refreshing)
if (error?.response?.status === 401 && failureCount < 3) {
return true;
}
return false;
},
retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 30000),
refetchOnWindowFocus: false,
refetchOnMount: false,
});
};
export const useUpdatePreferences = () => {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (data: UpdatePreferencesRequest) => preferencesApi.updatePreferences(data),
onSuccess: (response) => {
queryClient.setQueryData(['user-preferences'], response.data);
// Don't show toast for unit system changes - context handles UI feedback
},
onError: (error: ApiError) => {
const message = error.response?.data?.message || error.response?.data?.error || 'Failed to update preferences';
toast.error(message);
},
});
};

View File

@@ -1,5 +1,6 @@
import { useState, useEffect } from 'react';
import { useSettingsPersistence, SettingsState } from './useSettingsPersistence';
import { useUnits } from '../../../core/units/UnitsContext';
const defaultSettings: SettingsState = {
darkMode: false,
@@ -13,10 +14,12 @@ const defaultSettings: SettingsState = {
export const useSettings = () => {
const { loadSettings, saveSettings } = useSettingsPersistence();
const { unitSystem: contextUnitSystem, setUnitSystem: setContextUnitSystem } = useUnits();
const [settings, setSettings] = useState<SettingsState>(defaultSettings);
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
// Load settings from localStorage on mount
useEffect(() => {
try {
setIsLoading(true);
@@ -33,6 +36,13 @@ export const useSettings = () => {
}
}, [loadSettings]);
// Sync unitSystem from context (which may load from backend)
useEffect(() => {
if (contextUnitSystem && contextUnitSystem !== settings.unitSystem) {
setSettings(prev => ({ ...prev, unitSystem: contextUnitSystem }));
}
}, [contextUnitSystem, settings.unitSystem]);
const updateSetting = <K extends keyof SettingsState>(
key: K,
value: SettingsState[K]
@@ -42,6 +52,11 @@ export const useSettings = () => {
const newSettings = { ...settings, [key]: value };
setSettings(newSettings);
saveSettings(newSettings);
// Sync unitSystem changes to context (which syncs to backend)
if (key === 'unitSystem' && typeof value === 'string') {
setContextUnitSystem(value as 'imperial' | 'metric');
}
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to save settings');
}

View File

@@ -367,7 +367,7 @@ export const MobileSettingsScreen: React.FC = () => {
<div>
<p className="font-medium text-slate-800">Unit System</p>
<p className="text-sm text-slate-500">
Currently using {settings.unitSystem === 'imperial' ? 'Miles & Gallons' : 'Kilometers & Liters'}
Currently using {settings.unitSystem === 'imperial' ? 'Miles, Gallons, MPG, USD' : 'Km, Liters, L/100km, EUR'}
</p>
</div>
<button

View File

@@ -0,0 +1,22 @@
/**
* @ai-summary Type definitions for user preferences
* @ai-context Types for unit system, currency, and timezone preferences
*/
import { UnitSystem } from '../../../core/units/units.types';
export interface UserPreferences {
id: string;
userId: string;
unitSystem: UnitSystem;
currencyCode: string;
timeZone: string;
createdAt: string;
updatedAt: string;
}
export interface UpdatePreferencesRequest {
unitSystem?: UnitSystem;
currencyCode?: string;
timeZone?: string;
}