import { createAtom } from "~/lib/atomic-zustand"; import getNearbyDefibs from "~/data/getNearbyDefibs"; import { computeCorridorQueryRadiusMeters, filterDefibsInCorridor, } from "~/utils/geo/corridor"; const DEFAULT_NEAR_USER_RADIUS_M = 10_000; const DEFAULT_CORRIDOR_M = 10_000; const DEFAULT_LIMIT = 200; export default createAtom(({ merge, reset }) => { const actions = { reset, setShowDefibsOnAlertMap: (showDefibsOnAlertMap) => { merge({ showDefibsOnAlertMap }); }, setSelectedDefib: (selectedDefib) => { merge({ selectedDefib }); }, setShowDaeSuggestModal: (showDaeSuggestModal) => { merge({ showDaeSuggestModal }); }, setShowUnavailable: (showUnavailable) => { merge({ showUnavailable }); }, loadNearUser: async ({ userLonLat, radiusMeters = DEFAULT_NEAR_USER_RADIUS_M, }) => { merge({ loadingNearUser: true, errorNearUser: null }); try { const [lon, lat] = userLonLat; const nearUserDefibs = await getNearbyDefibs({ lat, lon, radiusMeters, limit: DEFAULT_LIMIT, progressive: true, }); merge({ nearUserDefibs, loadingNearUser: false }); return { defibs: nearUserDefibs, error: null }; } catch (error) { merge({ nearUserDefibs: [], loadingNearUser: false, errorNearUser: error, }); return { defibs: [], error }; } }, loadCorridor: async ({ userLonLat, alertLonLat, corridorMeters = DEFAULT_CORRIDOR_M, }) => { merge({ loadingCorridor: true, errorCorridor: null }); try { const radiusMeters = computeCorridorQueryRadiusMeters({ userLonLat, alertLonLat, corridorMeters, }); const midLon = (userLonLat[0] + alertLonLat[0]) / 2; const midLat = (userLonLat[1] + alertLonLat[1]) / 2; const candidates = await getNearbyDefibs({ lat: midLat, lon: midLon, radiusMeters, limit: DEFAULT_LIMIT, progressive: true, }); const corridorDefibs = filterDefibsInCorridor({ defibs: candidates, userLonLat, alertLonLat, corridorMeters, }).slice(0, DEFAULT_LIMIT); merge({ corridorDefibs, loadingCorridor: false }); return { defibs: corridorDefibs, error: null }; } catch (error) { merge({ corridorDefibs: [], loadingCorridor: false, errorCorridor: error, }); return { defibs: [], error }; } }, }; return { default: { nearUserDefibs: [], corridorDefibs: [], showDefibsOnAlertMap: false, selectedDefib: null, showDaeSuggestModal: false, showUnavailable: false, loadingNearUser: false, loadingCorridor: false, errorNearUser: null, errorCorridor: null, }, actions, }; });