import { MaterialCommunityIcons } from "@expo/vector-icons"; import { router } from "expo-router"; import { useEffect, useState } from "react"; import { ScrollView, Text, TouchableOpacity, View } from "react-native"; import { POI_CATEGORIES, searchNearby } from "@/lib/places"; import { useT } from "@/lib/i18n"; import { useLocationStore } from "@/store"; import type { NearbyPlace } from "@/types/type"; // Four quick destination chips: nearest mall / hospital / pharmacy / restaurant // around the rider. Tapping one sets it as the destination and opens find-ride. // Each chip resolves independently, so a category with no result nearby just // shows "none nearby" instead of breaking the whole row. type ChipState = | { status: "loading" } | { status: "empty" } | { status: "ready"; place: NearbyPlace }; export const NearbySuggestions = () => { const { userLatitude, userLongitude, setDestinationLocation } = useLocationStore(); const t = useT(); const [chips, setChips] = useState>({}); useEffect(() => { if (userLatitude == null || userLongitude == null) return; let cancelled = false; setChips({}); // Resolve all four categories in parallel. POI_CATEGORIES.forEach(async (category) => { setChips((prev) => ({ ...prev, [category.id]: { status: "loading" } })); const place = await searchNearby(category.googleType, { latitude: userLatitude, longitude: userLongitude, }); if (cancelled) return; setChips((prev) => ({ ...prev, [category.id]: place ? { status: "ready", place } : { status: "empty" }, })); }); return () => { cancelled = true; }; }, [userLatitude, userLongitude]); const select = (place: NearbyPlace) => { setDestinationLocation({ latitude: place.latitude, longitude: place.longitude, address: place.name, }); router.push("/(root)/find-ride"); }; return ( {t("pois.nearbyTitle")} {POI_CATEGORIES.map((category) => { const state = chips[category.id]; const ready = state?.status === "ready" ? state.place : null; return ( ready && select(ready)} activeOpacity={0.8} className={`flex-row items-center rounded-2xl border px-3 py-2.5 ${ ready ? "border-primary-500 bg-primary-500/10" : "border-neutral-200 bg-neutral-100 dark:border-neutral-800 dark:bg-neutral-800" }`} style={{ minWidth: 150 }} > {t(category.labelKey)} {!state || state.status === "loading" ? t("pois.searching") : state.status === "empty" ? t("pois.noneNearby") : state.place.routeDistanceMeters != null ? t("pois.routeAway", { km: Math.round( state.place.routeDistanceMeters / 100, ) / 10, min: Math.max( 1, Math.round( (state.place.routeDurationSeconds ?? 0) / 60, ), ), }) : state.place.distanceMeters != null ? t("pois.kmAway", { km: Math.round(state.place.distanceMeters / 100) / 10, }) : state.place.name} ); })} ); };