add google maps service for lat/long of chosen location

This commit is contained in:
Michael Fatemi 2021-06-27 21:59:41 -04:00
parent 28932b2627
commit 12c0f9d32f
4 changed files with 82 additions and 48 deletions

View File

@ -1,16 +1,19 @@
export const GOOGLE_MAPS_API_KEY = 'AIzaSyDUnWIrt-H4RuP2YFLpVPz4oAjBhpOOoyI'; export type PlaceDetails = {
formattedAddress: string;
latitude: number;
longitude: number;
};
export async function searchForPlaces(query: string) { export async function getPlaceDetails(
const url = new URL( placeId: string
'https://maps.googleapis.com/maps/api/place/findplacefromtext/json' ): Promise<PlaceDetails | null> {
); if (placeId == null) {
url.searchParams.set('key', GOOGLE_MAPS_API_KEY); console.warn('placeId was null');
url.searchParams.set('input', query); return null;
url.searchParams.set('inputtype', 'textquery'); }
url.searchParams.set('fields', 'place_id,name,formatted_address');
console.log(url.toString()); const result = await fetch('http://localhost:5000/api/place/' + placeId);
let res = await fetch(url.toString(), { mode: 'no-cors' }); const json = await result.json();
let json = await res.text();
return json; return json;
} }

View File

@ -4,6 +4,7 @@ import UIButton from './UIButton';
import UIPlacesAutocomplete from './UIPlacesAutocomplete'; import UIPlacesAutocomplete from './UIPlacesAutocomplete';
import UISecondaryBox from './UISecondaryBox'; import UISecondaryBox from './UISecondaryBox';
import UISecondaryHeader from './UISecondaryHeader'; import UISecondaryHeader from './UISecondaryHeader';
import usePlace from './usePlace';
import useThrottle from './useThrottle'; import useThrottle from './useThrottle';
import useToggle from './useToggle'; import useToggle from './useToggle';
@ -205,18 +206,22 @@ const dummyPeopleData: IPerson[] = [
longitude: 10.12, longitude: 10.12,
}, },
]; ];
function People({ event }: { event: IEvent }) { function People({ event, placeId }: { event: IEvent; placeId: string }) {
const PADDING = '1rem'; const PADDING = '1rem';
// eslint-disable-next-line // eslint-disable-next-line
const [people, setPeople] = useState(dummyPeopleData); const [people, setPeople] = useState(dummyPeopleData);
const placeDetails = usePlace(placeId);
const myLatitude = 10; const myLatitude = 10;
const myLongitude = 10; const myLongitude = 10;
const locationLatitude = 12;
const locationLongitude = 12;
return ( return (
<div style={{ display: 'flex', flexDirection: 'column' }}> <div style={{ display: 'flex', flexDirection: 'column' }}>
<h3 style={{ marginBlockEnd: '0' }}>People</h3> <h3 style={{ marginBlockEnd: '0' }}>People</h3>
{people.map(({ name, latitude, longitude, id }) => { {people.map(({ name, latitude, longitude, id }) => {
let extraDistance = null;
if (placeDetails != null) {
const locationLatitude = placeDetails.latitude;
const locationLongitude = placeDetails.longitude;
const meToThem = latlongdist( const meToThem = latlongdist(
latitude, latitude,
longitude, longitude,
@ -239,7 +244,8 @@ function People({ event }: { event: IEvent }) {
locationLongitude, locationLongitude,
R_miles R_miles
); );
const extraDistance = totalWithThem - totalWithoutThem; extraDistance = totalWithThem - totalWithoutThem;
}
return ( return (
<div <div
@ -254,7 +260,8 @@ function People({ event }: { event: IEvent }) {
marginBottom: '0.5rem', marginBottom: '0.5rem',
}} }}
> >
<b>{name}</b>: +{extraDistance.toFixed(1)} miles <b>{name}</b>
{extraDistance ? `: +${extraDistance.toFixed(1)} miles` : ''}
<div <div
style={{ style={{
borderRadius: '0.5em', borderRadius: '0.5em',
@ -278,7 +285,7 @@ function People({ event }: { event: IEvent }) {
export default function Event({ event }: { event: IEvent }) { export default function Event({ event }: { event: IEvent }) {
const { name, group, formattedAddress, startTime, endTime } = event; const { name, group, formattedAddress, startTime, endTime } = event;
const [haveRide, toggleHaveRide] = useToggle(false); const [haveRide, toggleHaveRide] = useToggle(false);
const [locationPlaceId, setLocationPlaceId] = useState<string>(null!); const [placeId, setPlaceId] = useState<string>(null!);
const [interested, toggleInterested] = useToggle(false); const [interested, toggleInterested] = useToggle(false);
const toggleInterestedThrottled = useThrottle(toggleInterested, 500); const toggleInterestedThrottled = useThrottle(toggleInterested, 500);
@ -302,11 +309,9 @@ export default function Event({ event }: { event: IEvent }) {
<UIPlacesAutocomplete <UIPlacesAutocomplete
placeholder="Pickup and dropoff location" placeholder="Pickup and dropoff location"
onSelected={(_address, placeID) => { onSelected={(_address, placeID) => {
setLocationPlaceId(placeID); setPlaceId(placeID);
}} }}
style={ style={placeId != null ? { border: '2px solid ' + green } : {}}
locationPlaceId != null ? { border: '2px solid ' + green } : {}
}
/> />
{false && ( {false && (
<div <div
@ -332,7 +337,7 @@ export default function Event({ event }: { event: IEvent }) {
</div> </div>
)} )}
<Carpools event={event} /> <Carpools event={event} />
<People event={event} /> <People event={event} placeId={placeId} />
</> </>
)} )}
</UISecondaryBox> </UISecondaryBox>

View File

@ -0,0 +1,24 @@
import { useState, useEffect, useCallback } from 'react';
import { getPlaceDetails, PlaceDetails } from '../../api/google';
import useThrottle from './useThrottle';
export default function usePlace(placeId: string) {
const [placeDetails, setPlaceDetails] = useState<PlaceDetails | null>(null);
const updatePlaceDetails = useCallback(() => {
if (placeId == null) {
setPlaceDetails(null);
} else {
getPlaceDetails(placeId).then(setPlaceDetails);
}
}, [placeId]);
const updatePlaceDetailsThrottled = useThrottle(updatePlaceDetails, 500);
useEffect(updatePlaceDetailsThrottled, [
placeId,
updatePlaceDetailsThrottled,
]);
return placeDetails;
}

View File

@ -1,11 +1,13 @@
import { useMemo } from 'react'; import { useMemo } from 'react';
function throttle<F extends (...args: any) => any, T>( type Void = (...args: any) => void;
export function throttle<T>(
this: T, this: T,
callback: F, callback: Void,
limit: number, limit: number,
thisArg?: T thisArg?: T
): F { ): (...args: Parameters<typeof callback>) => void {
let waiting = false; let waiting = false;
let pendingArgs: null | any[] = null; let pendingArgs: null | any[] = null;
const scope = thisArg ?? this; const scope = thisArg ?? this;