diff --git a/components/map.tsx b/components/map.tsx index 70fa02a..7924476 100644 --- a/components/map.tsx +++ b/components/map.tsx @@ -1,16 +1,71 @@ -import { useLocationStore } from '@/store' -import React from 'react' +import { icons } from '@/constants' +import { calculateRegion, generateMarkersFromData } from '@/lib/map' +import { useDriverStore, useLocationStore } from '@/store' +import { MarkerData } from '@/types/type' +import React, { useEffect, useState } from 'react' import { Text, View } from 'react-native' -import MapView, { PROVIDER_DEFAULT } from "react-native-maps" -const Map = () => { - const { - userLongitude, userLatitude, destinationLatitude, destinationLongitude - } = useLocationStore +import MapView, { Marker, PROVIDER_DEFAULT } from "react-native-maps" +const drivers = [ + { + "id": "1", + "first_name": "James", + "last_name": "Wilson", + "profile_image_url": "https://ucarecdn.com/dae59f69-2c1f-48c3-a883-017bcf0f9950/-/preview/1000x666/", + "car_image_url": "https://ucarecdn.com/a2dc52b2-8bf7-4e49-9a36-3ffb5229ed02/-/preview/465x466/", + "car_seats": 4, + "rating": "4.80" + }, + { + "id": "2", + "first_name": "David", + "last_name": "Brown", + "profile_image_url": "https://ucarecdn.com/6ea6d83d-ef1a-483f-9106-837a3a5b3f67/-/preview/1000x666/", + "car_image_url": "https://ucarecdn.com/a3872f80-c094-409c-82f8-c9ff38429327/-/preview/930x932/", + "car_seats": 5, + "rating": "4.60" + }, + { + "id": "3", + "first_name": "Michael", + "last_name": "Johnson", + "profile_image_url": "https://ucarecdn.com/0330d85c-232e-4c30-bd04-e5e4d0e3d688/-/preview/826x822/", + "car_image_url": "https://ucarecdn.com/289764fb-55b6-4427-b1d1-f655987b4a14/-/preview/930x932/", + "car_seats": 4, + "rating": "4.70" + }, + { + "id": "4", + "first_name": "Robert", + "last_name": "Green", + "profile_image_url": "https://ucarecdn.com/fdfc54df-9d24-40f7-b7d3-6f391561c0db/-/preview/626x417/", + "car_image_url": "https://ucarecdn.com/b6fb3b55-7676-4ff3-8484-fb115e268d32/-/preview/930x932/", + "car_seats": 4, + "rating": "4.90" + } +] +const Map = () => { - const region = { + const [markers, setMarkers] = useState([]) + useEffect(() => { + if (Array.isArray(drivers)) { + if (!userLatitude || !userLongitude) return - } + const newMarkers = generateMarkersFromData({ + data: drivers, + userLatitude, + userLongitude, + }) + setMarkers(newMarkers) + } + }, [drivers]) + const { + userLongitude, userLatitude, destinationLatitude, destinationLongitude + } = useLocationStore() + const { selectedDriver, setDrivers } = useDriverStore(); + const region = calculateRegion({ + userLongitude, userLatitude, destinationLatitude, destinationLongitude + }) return ( { tintColor='black' mapType='mutedStandard' showsPointsOfInterest={false} - //initialRegion={region} + initialRegion={region} showsUserLocation={true} userInterfaceStyle='light' > - - Map - + {markers.map((marker) => ( + + ))} ) } diff --git a/lib/map.ts b/lib/map.ts new file mode 100644 index 0000000..f2cbf14 --- /dev/null +++ b/lib/map.ts @@ -0,0 +1,121 @@ +import {Driver, MarkerData} from "@/types/type"; + +const directionsAPI = process.env.EXPO_PUBLIC_GOOGLE_API_KEY; + +export const generateMarkersFromData = ({ + data, + userLatitude, + userLongitude, + }: { + data: Driver[]; + userLatitude: number; + userLongitude: number; +}): MarkerData[] => { + return data.map((driver) => { + const latOffset = (Math.random() - 0.5) * 0.01; // Random offset between -0.005 and 0.005 + const lngOffset = (Math.random() - 0.5) * 0.01; // Random offset between -0.005 and 0.005 + + return { + latitude: userLatitude + latOffset, + longitude: userLongitude + lngOffset, + title: `${driver.first_name} ${driver.last_name}`, + ...driver, + }; + }); +}; + +export const calculateRegion = ({ + userLatitude, + userLongitude, + destinationLatitude, + destinationLongitude, + }: { + userLatitude: number | null; + userLongitude: number | null; + destinationLatitude?: number | null; + destinationLongitude?: number | null; +}) => { + if (!userLatitude || !userLongitude) { + return { + latitude: 37.78825, + longitude: -122.4324, + latitudeDelta: 0.01, + longitudeDelta: 0.01, + }; + } + + if (!destinationLatitude || !destinationLongitude) { + return { + latitude: userLatitude, + longitude: userLongitude, + latitudeDelta: 0.01, + longitudeDelta: 0.01, + }; + } + + const minLat = Math.min(userLatitude, destinationLatitude); + const maxLat = Math.max(userLatitude, destinationLatitude); + const minLng = Math.min(userLongitude, destinationLongitude); + const maxLng = Math.max(userLongitude, destinationLongitude); + + const latitudeDelta = (maxLat - minLat) * 1.3; // Adding some padding + const longitudeDelta = (maxLng - minLng) * 1.3; // Adding some padding + + const latitude = (userLatitude + destinationLatitude) / 2; + const longitude = (userLongitude + destinationLongitude) / 2; + + return { + latitude, + longitude, + latitudeDelta, + longitudeDelta, + }; +}; + +export const calculateDriverTimes = async ({ + markers, + userLatitude, + userLongitude, + destinationLatitude, + destinationLongitude, + }: { + markers: MarkerData[]; + userLatitude: number | null; + userLongitude: number | null; + destinationLatitude: number | null; + destinationLongitude: number | null; +}) => { + if ( + !userLatitude || + !userLongitude || + !destinationLatitude || + !destinationLongitude + ) + return; + + try { + const timesPromises = markers.map(async (marker) => { + const responseToUser = await fetch( + `https://maps.googleapis.com/maps/api/directions/json?origin=${marker.latitude},${marker.longitude}&destination=${userLatitude},${userLongitude}&key=${directionsAPI}`, + ); + const dataToUser = await responseToUser.json(); + const timeToUser = dataToUser.routes[0].legs[0].duration.value; // Time in seconds + + const responseToDestination = await fetch( + `https://maps.googleapis.com/maps/api/directions/json?origin=${userLatitude},${userLongitude}&destination=${destinationLatitude},${destinationLongitude}&key=${directionsAPI}`, + ); + const dataToDestination = await responseToDestination.json(); + const timeToDestination = + dataToDestination.routes[0].legs[0].duration.value; // Time in seconds + + const totalTime = (timeToUser + timeToDestination) / 60; // Total time in minutes + const price = (totalTime * 0.5).toFixed(2); // Calculate price based on time + + return {...marker, time: totalTime, price}; + }); + + return await Promise.all(timesPromises); + } catch (error) { + console.error("Error calculating driver times:", error); + } +}; \ No newline at end of file diff --git a/store/index.ts b/store/index.ts index faa01a1..da5402b 100644 --- a/store/index.ts +++ b/store/index.ts @@ -1,4 +1,4 @@ -import { LocationStore } from "@/types/type" +import { DriverStore, LocationStore, MarkerData } from "@/types/type" import { create } from "zustand" export const useLocationStore = create((set) => ({ @@ -22,4 +22,13 @@ export const useLocationStore = create((set) => ({ destinationAddress: address, })) }, +})) + +export const useDriverStore = create((set) => ({ + drivers: [] as MarkerData[], + selectedDriver: null, + setSelectedDriver: (driverId: number) => + set(() => ({ selectedDriver: driverId })), + setDrivers: (drivers: MarkerData[]) => set(() => ({ drivers: drivers })), + clearSelectedDriver: () => set(() => ({ selectedDriver: null })) })) \ No newline at end of file