// Google Places (New) Nearby Search — powers the "nearby mall / hospital / // pharmacy / restaurant" destination chips on the home screen. Reuses the same // API key and header pattern as the autocomplete in components/google-text-input. import { haversine } from "@/lib/utils"; import type { NearbyPlace } from "@/types/type"; const googleApiKey = process.env.EXPO_PUBLIC_GOOGLE_API_KEY!; // The four POI categories surfaced as quick destination chips. Each maps to a // Google Places (New) `includedTypes` value. export type PoiCategory = { id: "mall" | "hospital" | "pharmacy" | "restaurant"; label: string; /** MaterialCommunityIcons glyph name. */ icon: string; googleType: string; }; export const POI_CATEGORIES: PoiCategory[] = [ { id: "mall", label: "Mall", icon: "shopping-mall", googleType: "shopping_mall" }, { id: "hospital", label: "Hospital", icon: "hospital", googleType: "hospital" }, { id: "pharmacy", label: "Pharmacy", icon: "pill", googleType: "pharmacy" }, { id: "restaurant", label: "Restaurant", icon: "silverware-fork-knife", googleType: "restaurant" }, ]; const DEFAULT_RADIUS_M = 4000; // Searches for the nearest place of `googleType` around (latitude, longitude) // and returns it as a NearbyPlace with its distance from the rider. Returns // null when no place of that type is found nearby — the chip then shows an // empty state rather than a broken one. export const searchNearby = async ( googleType: string, { latitude, longitude, radiusM = DEFAULT_RADIUS_M, }: { latitude: number; longitude: number; radiusM?: number }, ): Promise => { try { const res = await fetch( "https://places.googleapis.com/v1/places:searchNearby", { method: "POST", headers: { "Content-Type": "application/json", "X-Goog-Api-Key": googleApiKey, "X-Goog-FieldMask": "places.displayName,places.formattedAddress,places.location,places.id", }, body: JSON.stringify({ includedTypes: [googleType], languageCode: "en", regionCode: "lb", locationRestriction: { circle: { center: { latitude, longitude }, radius: radiusM, }, }, }), }, ); const data = await res.json(); const place = data.places?.[0]; if (!place) return null; const lat = place.location?.latitude as number; const lng = place.location?.longitude as number; return { name: (place.displayName?.text as string) ?? "Nearby place", address: (place.formattedAddress as string) ?? "", latitude: lat, longitude: lng, distanceMeters: Number.isFinite(lat) && Number.isFinite(lng) ? haversine(latitude, longitude, lat, lng) : undefined, }; } catch (error) { console.log("[PLACES_NEARBY]: ", error); return null; } };