import React, {
useCallback,
useMemo,
useRef,
useState,
useEffect,
} from "react";
import { View, StyleSheet } from "react-native";
import Maplibre from "@maplibre/maplibre-react-native";
import { MaterialCommunityIcons } from "@expo/vector-icons";
import { useNavigation } from "@react-navigation/native";
import MapView from "~/containers/Map/MapView";
import Camera from "~/containers/Map/Camera";
import LastKnownLocationMarker from "~/containers/Map/LastKnownLocationMarker";
import { BoundType, DEFAULT_ZOOM_LEVEL } from "~/containers/Map/constants";
import StepZoomButtonGroup from "~/containers/Map/StepZoomButtonGroup";
import Text from "~/components/Text";
import Loader from "~/components/Loader";
import { useTheme } from "~/theme";
import { defibsActions } from "~/stores";
import { getDefibAvailability } from "~/utils/dae/getDefibAvailability";
import useNearbyDefibs from "./useNearbyDefibs";
const STATUS_COLORS = {
open: "#4CAF50",
closed: "#F44336",
unknown: "#9E9E9E",
};
function defibsToGeoJSON(defibs) {
return {
type: "FeatureCollection",
features: defibs.map((d) => {
const { status } = getDefibAvailability(d.horaires_std, d.disponible_24h);
return {
type: "Feature",
id: d.id,
geometry: {
type: "Point",
coordinates: [d.longitude, d.latitude],
},
properties: {
id: d.id,
nom: d.nom || "Défibrillateur",
status,
color: STATUS_COLORS[status],
},
};
}),
};
}
function EmptyNoLocation() {
const { colors } = useTheme();
return (
Localisation indisponible
Activez la géolocalisation pour afficher les défibrillateurs sur la
carte.
);
}
export default React.memo(function DAEListCarte() {
const { colors } = useTheme();
const navigation = useNavigation();
const {
defibs,
loading,
noLocation,
hasLocation,
isLastKnown,
lastKnownTimestamp,
coords,
} = useNearbyDefibs();
const mapRef = useRef();
const cameraRef = useRef();
const [cameraKey, setCameraKey] = useState(1);
const refreshCamera = useCallback(() => {
setCameraKey(`${Date.now()}`);
}, []);
const hasCoords =
coords && coords.latitude !== null && coords.longitude !== null;
// Camera state — simple follow user
const [followUserLocation] = useState(true);
const [followUserMode] = useState(Maplibre.UserTrackingMode.Follow);
const [zoomLevel, setZoomLevel] = useState(DEFAULT_ZOOM_LEVEL);
const geoJSON = useMemo(() => defibsToGeoJSON(defibs), [defibs]);
const onMarkerPress = useCallback(
(e) => {
const feature = e?.features?.[0];
if (!feature) return;
const defibId = feature.properties?.id;
const defib = defibs.find((d) => d.id === defibId);
if (defib) {
defibsActions.setSelectedDefib(defib);
navigation.navigate("DAEItem");
}
},
[defibs, navigation],
);
if (noLocation && !hasLocation) {
return ;
}
if (loading && defibs.length === 0 && !hasCoords) {
return ;
}
return (
{geoJSON.features.length > 0 && (
)}
{isLastKnown && hasCoords ? (
) : (
)}
);
});
const styles = StyleSheet.create({
container: {
flex: 1,
},
emptyContainer: {
flex: 1,
alignItems: "center",
justifyContent: "center",
paddingHorizontal: 32,
},
emptyIcon: {
marginBottom: 16,
},
emptyTitle: {
fontSize: 18,
fontWeight: "600",
textAlign: "center",
marginBottom: 8,
},
emptyText: {
fontSize: 14,
textAlign: "center",
lineHeight: 20,
},
});