| import { useState, useEffect, useCallback } from 'react'; |
| import { eq, desc, sql, and } from 'drizzle-orm'; |
| import { useDatabase } from './useDatabase'; |
| import { savedLocations } from '../db/schema'; |
|
|
| |
|
|
| type LocationType = 'home' | 'work' | 'favorite' | 'recent'; |
|
|
| interface SavedLocationData { |
| id: string; |
| userId: string; |
| name: string; |
| address: string; |
| latitude: number; |
| longitude: number; |
| type: LocationType; |
| createdAt: string | null; |
| } |
|
|
| interface NewLocation { |
| id: string; |
| userId: string; |
| name: string; |
| address: string; |
| latitude: number; |
| longitude: number; |
| type?: LocationType; |
| } |
|
|
| interface UpdateLocationData { |
| name?: string; |
| address?: string; |
| latitude?: number; |
| longitude?: number; |
| type?: LocationType; |
| } |
|
|
| interface UseSavedLocationsReturn { |
| locations: SavedLocationData[]; |
| loading: boolean; |
| loadLocations: () => Promise<void>; |
| addLocation: (data: NewLocation) => Promise<SavedLocationData | null>; |
| updateLocation: (locationId: string, data: UpdateLocationData) => Promise<void>; |
| deleteLocation: (locationId: string) => Promise<void>; |
| incrementUsage: (locationId: string) => Promise<void>; |
| refresh: () => Promise<void>; |
| } |
|
|
| |
|
|
| export function useSavedLocations(userId?: string): UseSavedLocationsReturn { |
| const { db } = useDatabase(); |
| const [locationsList, setLocationsList] = useState<SavedLocationData[]>([]); |
| const [loading, setLoading] = useState(true); |
|
|
| |
|
|
| const loadLocations = useCallback(async () => { |
| try { |
| setLoading(true); |
|
|
| let results; |
|
|
| if (userId) { |
| results = await db |
| .select() |
| .from(savedLocations) |
| .where(eq(savedLocations.userId, userId)) |
| .orderBy(desc(savedLocations.createdAt)) |
| .all(); |
| } else { |
| results = await db |
| .select() |
| .from(savedLocations) |
| .orderBy(desc(savedLocations.createdAt)) |
| .all(); |
| } |
|
|
| setLocationsList(results as SavedLocationData[]); |
| } catch (error) { |
| console.error('[useSavedLocations] Failed to load locations:', error); |
| setLocationsList([]); |
| } finally { |
| setLoading(false); |
| } |
| }, [db, userId]); |
|
|
| useEffect(() => { |
| loadLocations(); |
| }, [loadLocations]); |
|
|
| |
|
|
| const addLocation = useCallback( |
| async (data: NewLocation): Promise<SavedLocationData | null> => { |
| try { |
| await db.insert(savedLocations).values({ |
| id: data.id, |
| userId: data.userId, |
| name: data.name, |
| address: data.address, |
| latitude: data.latitude, |
| longitude: data.longitude, |
| type: data.type ?? 'favorite', |
| }).run(); |
|
|
| await loadLocations(); |
|
|
| return ( |
| (locationsList.find((l) => l.id === data.id) as SavedLocationData) ?? null |
| ); |
| } catch (error) { |
| console.error('[useSavedLocations] Failed to add location:', error); |
| return null; |
| } |
| }, |
| [db, loadLocations, locationsList], |
| ); |
|
|
| |
|
|
| const updateLocation = useCallback( |
| async (locationId: string, data: UpdateLocationData) => { |
| try { |
| await db |
| .update(savedLocations) |
| .set(data) |
| .where(eq(savedLocations.id, locationId)) |
| .run(); |
|
|
| await loadLocations(); |
| } catch (error) { |
| console.error('[useSavedLocations] Failed to update location:', error); |
| } |
| }, |
| [db, loadLocations], |
| ); |
|
|
| |
|
|
| const deleteLocation = useCallback( |
| async (locationId: string) => { |
| try { |
| await db |
| .delete(savedLocations) |
| .where(eq(savedLocations.id, locationId)) |
| .run(); |
|
|
| await loadLocations(); |
| } catch (error) { |
| console.error('[useSavedLocations] Failed to delete location:', error); |
| } |
| }, |
| [db, loadLocations], |
| ); |
|
|
| |
|
|
| const incrementUsage = useCallback( |
| async (locationId: string) => { |
| try { |
| |
| await db |
| .update(savedLocations) |
| .set({ type: 'recent', createdAt: new Date().toISOString() }) |
| .where(eq(savedLocations.id, locationId)) |
| .run(); |
|
|
| await loadLocations(); |
| } catch (error) { |
| console.error( |
| '[useSavedLocations] Failed to increment usage:', |
| error, |
| ); |
| } |
| }, |
| [db, loadLocations], |
| ); |
|
|
| return { |
| locations: locationsList, |
| loading, |
| loadLocations, |
| addLocation, |
| updateLocation, |
| deleteLocation, |
| incrementUsage, |
| refresh: loadLocations, |
| }; |
| } |
|
|