diff --git a/frontend-admin/app.json b/frontend-admin/app.json index a601099a..89c61f85 100644 --- a/frontend-admin/app.json +++ b/frontend-admin/app.json @@ -1,45 +1,43 @@ { - "expo": { - "name": "Admin Panel", - "slug": "frontend-admin", - "version": "1.0.0", - "orientation": "portrait", - "icon": "./assets/icon.png", - "userInterfaceStyle": "dark", - "newArchEnabled": true, - "splash": { - "image": "./assets/splash-icon.png", - "resizeMode": "contain", - "backgroundColor": "#0a0a0a" - }, - "ios": { - "supportsTablet": true, - "bundleIdentifier": "com.uberstup.adminpanel" - }, - "android": { - "package": "com.uberstup.adminpanel", - "adaptiveIcon": { - "foregroundImage": "./assets/adaptive-icon.png", - "backgroundColor": "#0a0a0a" - }, - "edgeToEdgeEnabled": true, - "permissions": [ - "android.permission.ACCESS_COARSE_LOCATION", - "android.permission.ACCESS_FINE_LOCATION" - ] - }, - "web": { - "favicon": "./assets/favicon.png" - }, - "plugins": [ - "expo-font", - "expo-location" - ], - "extra": { - "eas": { - "projectId": "fcb7a0bc-5b2f-453d-ba16-9f97d9f0e440" - } - }, - "owner": "xor290" - } + "expo": { + "name": "Admin Panel", + "slug": "frontend-admin", + "version": "1.0.0", + "orientation": "portrait", + "icon": "./assets/icon.png", + "userInterfaceStyle": "dark", + "newArchEnabled": false, + "splash": { + "image": "./assets/splash-icon.png", + "resizeMode": "contain", + "backgroundColor": "#0a0a0a" + }, + "ios": { + "supportsTablet": true, + "bundleIdentifier": "com.uberstup.adminpanel" + }, + "android": { + "package": "com.uberstup.adminpanel", + "adaptiveIcon": { + "foregroundImage": "./assets/adaptive-icon.png", + "backgroundColor": "#0a0a0a" + }, + "edgeToEdgeEnabled": true, + "permissions": [ + "android.permission.ACCESS_BACKGROUND_LOCATION", + "android.permission.ACCESS_COARSE_LOCATION", + "android.permission.ACCESS_FINE_LOCATION" + ] + }, + "web": { + "favicon": "./assets/favicon.png" + }, + "plugins": ["expo-font", "expo-location"], + "extra": { + "eas": { + "projectId": "fcb7a0bc-5b2f-453d-ba16-9f97d9f0e440" + } + }, + "owner": "xor290" + } } diff --git a/frontend-admin/src/screens/delivery/DashboardScreen.tsx b/frontend-admin/src/screens/delivery/DashboardScreen.tsx index 6b75fa16..c3be60fb 100644 --- a/frontend-admin/src/screens/delivery/DashboardScreen.tsx +++ b/frontend-admin/src/screens/delivery/DashboardScreen.tsx @@ -21,7 +21,6 @@ import { } from "react-native"; import { Ionicons } from "@expo/vector-icons"; import * as Location from "expo-location"; -import MapView, { Marker, Polyline, PROVIDER_DEFAULT } from "react-native-maps"; import { spacing, fontSize, borderRadius } from "../../theme"; import { useTheme } from "../../context/ThemeContext"; import { @@ -52,6 +51,12 @@ import Badge from "../../components/ui/Badge"; import Button from "../../components/ui/Button"; import AlertModal from "../../components/ui/AlertModal"; import { useAlert } from "../../hooks/useAlert"; +import TomTomMap, { + TomTomMapRef, + TomTomMarker, + TomTomRoute, + TomTomDestination, +} from "../../components/TomTomMap"; const { width: SCREEN_WIDTH } = Dimensions.get("window"); const MAP_HEIGHT = 260; @@ -91,8 +96,10 @@ export default function DashboardScreen() { null, ); const appState = useRef(AppState.currentState); - const mapRef = useRef(null); - const fullscreenMapRef = useRef(null); + + // TomTom map refs + const mapRef = useRef(null); + const fullscreenMapRef = useRef(null); const [mapFullscreen, setMapFullscreen] = useState(false); // TomTom routing @@ -117,6 +124,46 @@ export default function DashboardScreen() { [colors], ); + // -------------------------------------------------- + // Construire les props pour TomTomMap + // -------------------------------------------------- + + // Marker du livreur (position courante) + const driverMarkers: TomTomMarker[] = useMemo(() => { + if (!lastCoords) return []; + return [ + { + id: "driver", + latitude: lastCoords.lat, + longitude: lastCoords.lng, + color: colors.success, + label: "Ma position", + description: lastUpdate + ? lastUpdate.toLocaleTimeString("fr-FR", { + hour: "2-digit", + minute: "2-digit", + }) + : undefined, + }, + ]; + }, [lastCoords, lastUpdate, colors.success]); + + // Route TomTom + const tomtomRoute: TomTomRoute | null = useMemo(() => { + if (!routeInfo || routeInfo.coordinates.length === 0) return null; + return { coordinates: routeInfo.coordinates, color: "#4285F4" }; + }, [routeInfo]); + + // Destination TomTom + const tomtomDestination: TomTomDestination | null = useMemo(() => { + if (!destinationCoords) return null; + return { + latitude: destinationCoords.latitude, + longitude: destinationCoords.longitude, + color: colors.danger, + }; + }, [destinationCoords, colors.danger]); + // -------------------------------------------------- // Data // -------------------------------------------------- @@ -137,7 +184,6 @@ export default function DashboardScreen() { ? deliveriesRes.deliveries : []; - // Include queue commands const queueCommands: DeliveryItem[] = []; if (queueRes.success && queueRes.queue_info?.commands) { for (const cmd of queueRes.queue_info.commands) { @@ -194,7 +240,6 @@ export default function DashboardScreen() { setDeliveries(enriched); - // Auto-calculate route for first in_progress / assigned delivery const activeDelivery = enriched.find( (d) => @@ -227,7 +272,6 @@ export default function DashboardScreen() { if (!lastCoords) return; setRouteLoading(true); try { - // Geocode destination const dest = await geocodeAddress(address); if (!dest) { setRouteLoading(false); @@ -235,7 +279,6 @@ export default function DashboardScreen() { } setDestinationCoords(dest); - // Calculate route const result = await calculateRoute( { latitude: lastCoords.lat, longitude: lastCoords.lng }, dest, @@ -245,30 +288,12 @@ export default function DashboardScreen() { setInstructions(result.instructions); setCurrentInstructionIdx(0); - // Fit map to show both points - if (mapRef.current) { - mapRef.current.fitToCoordinates( - [ - { - latitude: lastCoords.lat, - longitude: lastCoords.lng, - }, - { - latitude: dest.latitude, - longitude: dest.longitude, - }, - ], - { - edgePadding: { - top: 80, - right: 60, - bottom: 80, - left: 60, - }, - animated: true, - }, - ); - } + // Fit la map pour afficher driver + destination + const coords = [ + { latitude: lastCoords.lat, longitude: lastCoords.lng }, + { latitude: dest.latitude, longitude: dest.longitude }, + ]; + mapRef.current?.fitToCoordinates(coords); } } catch { /* silent */ @@ -286,7 +311,6 @@ export default function DashboardScreen() { const sendCurrentLocation = useCallback(async () => { if (sendingRef.current) return; sendingRef.current = true; - try { const loc = await Promise.race([ Location.getCurrentPositionAsync({ @@ -297,7 +321,6 @@ export default function DashboardScreen() { ), ]); - // validation runtime + typage TS if ( !loc || typeof loc !== "object" || @@ -313,7 +336,6 @@ export default function DashboardScreen() { setLastCoords({ lat: latitude, lng: longitude }); setLastUpdate(new Date()); - await updateMyLocation(latitude, longitude); } catch (err) { console.log("GPS error:", err); @@ -440,7 +462,6 @@ export default function DashboardScreen() { return ( - {/* Current instruction */} - {/* Next instruction preview */} {next && ( Puis @@ -482,7 +502,6 @@ export default function DashboardScreen() { )} - {/* Route summary + toggle all instructions */} - {/* Header */} @@ -568,7 +586,6 @@ export default function DashboardScreen() { /> - {/* Address + navigation */} openNavigation(item.adresse)} @@ -589,7 +606,6 @@ export default function DashboardScreen() { /> - {/* Calculate route button for active delivery */} {isActive && lastCoords && ( )} - {/* Items / Products */} {item.items && item.items.length > 0 && ( @@ -652,7 +667,6 @@ export default function DashboardScreen() { )} - {/* Client phone */} {item.clientPhone && ( )} - {/* Action buttons */} {(item.status === "pending" || item.status === "assigned") && (