Skip to content

Commit

Permalink
search events by address
Browse files Browse the repository at this point in the history
  • Loading branch information
heybereket committed May 10, 2023
1 parent 5008abf commit 43d60f5
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 27 deletions.
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ NEXT_PUBLIC_SECRET=
NEXTAUTH_URL=http://localhost:3000/api/auth
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=
8 changes: 6 additions & 2 deletions components/Search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,15 @@ export const Search = (props: any) => {
<input
type="text"
spellCheck="false"
className="border border-[#2A2A2A] bg-card placeholder-lightGray outline-none rounded-lg text-lightGray px-3 py-2 text-sm pl-8 mt-5 md:w-[500px]"
className="border border-[#2A2A2A] bg-card placeholder-lightGray outline-none rounded-lg text-lightGray px-3 py-2 text-sm pl-8 mt-5 md:w-[350px]"
{...props}
/>
<span className="absolute inset-y-0 left-0 flex items-center pl-3 mt-5">
<FaSearch className="text-sm text-lightGray" />
{props.icon ? (
<div>{props.icon}</div>
) : (
<FaSearch className="text-sm text-lightGray" />
)}
</span>
</div>
);
Expand Down
94 changes: 69 additions & 25 deletions components/screens/EventsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import Link from "next/link";
import { Search } from "../Search";
import { ReactNode, useEffect, useState } from "react";
import haversine from "haversine-distance";
import { FaCrosshairs } from "react-icons/fa";
import { FaCrosshairs, FaFire, FaGlobe, FaMapMarkerAlt } from "react-icons/fa";
import { getGeoData } from "@/utils/geo";

const Event = (props: any) => {
return (
Expand Down Expand Up @@ -51,6 +52,8 @@ export const EventsScreen = (props: any) => {
const [nearbyRange, setNearbyRange] = useState<string | number>(350);
const [invalidNavigation, setInvalidNavigation] = useState(false);
const [eventDistances, setEventDistances] = useState({});
const [address, setAddress] = useState("");
const [filterByAddress, setFilterByAddress] = useState(false);
const today = new Date();
const newToday = today.toISOString().split("T")[0];

Expand All @@ -61,18 +64,25 @@ export const EventsScreen = (props: any) => {
setNearbyRange(350);
}

navigator.permissions.query({ name: "geolocation" }).then((result) => {
if (result.state === "granted") {
navigator.geolocation.getCurrentPosition((position) => {
const fetchGeoData = async () => {
const data = await getGeoData(address);
return data;
};

if (filterByAddress) {
fetchGeoData()
.then((data) => {
const lat = Number(data?.lat);
const lng = Number(data?.lng);
const eventDistances: any = {};

const nearbyEvents = props.events.filter((event: any) => {
const distance =
haversine(
{ lat: event.lat, lng: event.lng },
{
lat: position.coords.latitude,
lng: position.coords.longitude,
lat,
lng,
}
) / 1000; // convert to km

Expand All @@ -82,12 +92,37 @@ export const EventsScreen = (props: any) => {

setNearbyEvents(nearbyEvents);
setEventDistances(eventDistances);
});
} else {
setInvalidNavigation(true);
}
});
}, [props.events, nearbyRange]);
})
.then(() => setFilterByAddress(false));
} else if (address === "") {
navigator.permissions.query({ name: "geolocation" }).then((result) => {
if (result.state === "granted") {
navigator.geolocation.getCurrentPosition((position) => {
const eventDistances: any = {};

const nearbyEvents = props.events.filter((event: any) => {
const distance =
haversine(
{ lat: event.lat, lng: event.lng },
{
lat: position.coords.latitude,
lng: position.coords.longitude,
}
) / 1000; // convert to km

eventDistances[event.event_code] = distance;
return distance <= Number(nearbyRange); // events within x km range
});

setNearbyEvents(nearbyEvents);
setEventDistances(eventDistances);
});
} else {
setInvalidNavigation(true);
}
});
}
}, [props.events, nearbyRange, filterByAddress, address]);

const renderEventsSection = (
filterCondition: any,
Expand Down Expand Up @@ -120,14 +155,7 @@ export const EventsScreen = (props: any) => {
})
) : (
<p className="text-lightGray whitespace-nowrap">
{invalidNavigation ? (
<span>
Uh oh, looks like you haven&apos;t given us{" "}
<b className="text-white">Location Permissions</b>.
</span>
) : (
"Uh oh, looks like there were no events found."
)}
Uh oh, looks like there were no events found.
</p>
)}
</div>
Expand All @@ -136,7 +164,7 @@ export const EventsScreen = (props: any) => {

return (
<div className="pr-4 pl-4 md:pl-8 md:pr-8 max-w-screen-3xl w-full">
<div className="flex flex-wrap gap-3">
<div className="flex flex-wrap gap-x-3">
<button
onClick={() => setShowNearbyEvents(!showNearbyEvents)}
className="flex text-sm mt-5 bg-card border border-[#2A2A2A] hover:border-gray-600 text-lightGray hover:text-white transition-all duration-150 rounded-lg px-3 py-2"
Expand All @@ -146,10 +174,26 @@ export const EventsScreen = (props: any) => {
</button>

{showNearbyEvents ? (
<Search
placeholder="Event Range..."
onChange={(e: any) => setNearbyRange(e.target.value)}
/>
<>
<Search
placeholder="City / Zip Code / Address"
onChange={(e: any) => setAddress(e.target.value)}
icon={<FaMapMarkerAlt className="text-sm text-lightGray" />}
/>
<Search
placeholder="Radius (in km)"
onChange={(e: any) => setNearbyRange(e.target.value)}
icon={<FaGlobe className="text-sm text-lightGray" />}
/>
{address && (
<button
onClick={() => setFilterByAddress(true)}
className="flex text-sm mt-5 bg-card border border-[#2A2A2A] hover:border-gray-600 text-lightGray hover:text-white transition-all duration-150 rounded-lg px-3 py-2"
>
Search
</button>
)}
</>
) : (
<Search
placeholder="Search all events..."
Expand Down
32 changes: 32 additions & 0 deletions utils/geo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import axios from "axios";

interface GeoData {
lat: number;
lng: number;
}

interface GeocodeResult {
results: {
geometry: {
location: {
lat: number;
lng: number;
};
};
}[];
}

export const getGeoData = async (address: string): Promise<GeoData | null> => {
const response = await axios.get<GeocodeResult>(
`https://maps.googleapis.com/maps/api/geocode/json?address=${address.replace(
/ /g,
""
)}&key=${process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY}`
);
const json = response.data;
if (json.results.length === 0) {
return null;
}
const { lat, lng } = json.results[0].geometry.location;
return { lat, lng };
};

1 comment on commit 43d60f5

@vercel
Copy link

@vercel vercel bot commented on 43d60f5 May 10, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

machine – ./

machine-6070.vercel.app
scoutmachine.vercel.app
machine.frc6070.ca
machine-git-main-6070.vercel.app

Please sign in to comment.