Skip to content
This repository was archived by the owner on Jan 14, 2025. It is now read-only.

Commit

Permalink
Handle server response and display the generated plan.
Browse files Browse the repository at this point in the history
  • Loading branch information
soniyaprasad77 committed May 18, 2024
1 parent db2006b commit 69e954f
Show file tree
Hide file tree
Showing 9 changed files with 1,573 additions and 145 deletions.
1,285 changes: 1,275 additions & 10 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,11 @@
"@testing-library/user-event": "^14.5.2",
"axios": "^1.6.8",
"google-maps-react": "^2.0.6",
"openai": "^4.47.1",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-icons": "^5.2.1",
"react-markdown": "^9.0.1",
"react-router-dom": "^6.23.1",
"react-scripts": "^5.0.1",
"web-vitals": "^3.5.2"
Expand Down
Binary file removed public/favicon.ico
Binary file not shown.
6 changes: 3 additions & 3 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="icon" href="%PUBLIC_URL%/tryvalleylogo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
Expand All @@ -15,9 +15,9 @@
href="https://fonts.googleapis.com/css2?family=Reem+Kufi:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/tryvalleylogo.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>landing page</title>
<title>Event Planner</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
Expand Down
Binary file removed public/logo192.png
Binary file not shown.
Binary file removed public/logo512.png
Binary file not shown.
Binary file added public/tryvalleylogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
230 changes: 213 additions & 17 deletions src/Components/EventPlannerAi.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,150 @@
import React, { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import axios from "axios"; // Make sure you have axios imported
import axios from "axios";
import EventCoverCard from "./EventCoverCard";
import LocationOnIcon from "@mui/icons-material/LocationOn";
import LinkIcon from "@mui/icons-material/Link";
import GoogleMapsCard from "./GoogleMapsCard";
import ReactMarkdown from "react-markdown";
import React, { useState, useCallback, useEffect } from "react";
import {
useJsApiLoader,
GoogleMap,
Marker,
InfoWindow,
} from "@react-google-maps/api";
import { Skeleton } from "@mui/material";

const EventPlannerAi = ({ props }) => {
const { eventId } = useParams();
const [budget, setBudget] = useState("5000");
const [timeToStay, setTimeToStay] = useState("2");
const [generatedAnswer, setGeneratedAnswer] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const { eventId } = useParams();
console.log(eventId);
// props[eventId - 1].event_type.map((type) => console.log(type));
const eventName = props[eventId - 1].name;
const destination = props[eventId - 1].address;
const [eventLocation, setEventLocation] = useState(null);
const [userLocation, setUserLocation] = useState(null);
const [distance, setDistance] = useState(null);
const [zoom, setZoom] = useState(15);
const [infoWindowOpen, setInfoWindowOpen] = useState(false);
const { isLoaded } = useJsApiLoader({
googleMapsApiKey: process.env.REACT_APP_GOOGLE_MAPS_API_KEY,
});

const geocodeAddress = useCallback(async (address) => {
try {
const response = await fetch(
`https://maps.googleapis.com/maps/api/geocode/json?address=${encodeURIComponent(
address
)}&key=${process.env.REACT_APP_GOOGLE_MAPS_API_KEY}`
);
const data = await response.json();
if (data.status === "OK") {
const location = data.results[0].geometry.location;
setEventLocation(location);
} else {
console.error(
"Geocode was not successful for the following reason:",
data.status
);
}
} catch (error) {
console.error("Error fetching geocode:", error);
}
}, []);

useEffect(() => {
if (props[eventId - 1] && props[eventId - 1].address) {
geocodeAddress(props[eventId - 1].address);
}
}, [props, eventId, geocodeAddress]);

const gotLocation = useCallback((position) => {
setUserLocation({
lat: position.coords.latitude,
lng: position.coords.longitude,
});
}, []);

const errorLocation = useCallback((error) => {
console.log("Error getting location:", error);
}, []);

const handleGetLocation = useCallback(() => {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(gotLocation, errorLocation, {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0,
});
} else {
console.log("Geolocation is not supported by this browser.");
}
}, [gotLocation, errorLocation]);

useEffect(() => {
handleGetLocation();
}, [handleGetLocation]);

useEffect(() => {
if (userLocation && eventLocation) {
// Calculate distance between two points using Haversine formula
const R = 6371; // Radius of the Earth in kilometers
const lat1 = userLocation.lat;
const lon1 = userLocation.lng;
const lat2 = eventLocation.lat;
const lon2 = eventLocation.lng;

const dLat = (lat2 - lat1) * (Math.PI / 180);
const dLon = (lon2 - lon1) * (Math.PI / 180);
const a =
Math.sin(dLat / 2) * Math.sin(dLat / 2) +
Math.cos(lat1 * (Math.PI / 180)) *
Math.cos(lat2 * (Math.PI / 180)) *
Math.sin(dLon / 2) *
Math.sin(dLon / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
const distance = R * c;

// Set distance state
setDistance(distance);

// Calculate bounds to fit both markers
const bounds = new window.google.maps.LatLngBounds();
bounds.extend(
new window.google.maps.LatLng(userLocation.lat, userLocation.lng)
);
bounds.extend(
new window.google.maps.LatLng(eventLocation.lat, eventLocation.lng)
);

// Set zoom level
const mapWidth = 100;
const mapHeight = 200;
const ne = bounds.getNorthEast();
const sw = bounds.getSouthWest();
const zoomLevel = getZoomLevel(
ne.lat(),
sw.lat(),
ne.lng(),
sw.lng(),
mapWidth,
mapHeight
);
setZoom(zoomLevel);
}
}, [userLocation, eventLocation]);

const getZoomLevel = (lat1, lat2, lng1, lng2, mapWidth, mapHeight) => {
const GLOBE_WIDTH = 256; // a constant in Google's map projection
const angle = lng2 - lng1;
const zoomX = Math.floor(Math.log2((GLOBE_WIDTH * 360) / angle / mapWidth));
const zoomY = Math.floor(
Math.log2((GLOBE_WIDTH * 180) / (lat1 - lat2) / mapHeight)
);
return Math.min(zoomX, zoomY);
};

const handleSubmit = async (e) => {
e.preventDefault();
Expand All @@ -23,18 +153,31 @@ const EventPlannerAi = ({ props }) => {
setError("");

try {
const response = await axios.post("http://localhost:8000/predict", {
const response = await axios.post("http://localhost:8000/prediction", {
budget,
timeToStay,
eventName,
destination,
distance,
});
setGeneratedAnswer(response.data.prediction);
setGeneratedAnswer(response.data.response);
} catch (error) {
setError("Something went wrong. Please try again later.");
} finally {
setLoading(false);
}
};

if (!isLoaded || !eventLocation) {
return (
<div className="py-2 px">
<div className="w-full relative p-2 sm:my-6 sm:px-16">
<Skeleton variant="rectangular" width="100%" height={600} />
</div>
</div>
);
}

return (
<>
<EventCoverCard events={props} eventId={eventId} />
Expand Down Expand Up @@ -152,35 +295,88 @@ const EventPlannerAi = ({ props }) => {
</div>
<button
type="submit"
className="secondary-button h-10 mx-auto sm:mx-0 bg-slate-300 text-gray-900 hover:bg-gray-500"
className="secondary-button h-10 mx-auto sm:mx-0 bg-slate-300 text-black hover:bg-gray-500"
>
Generate Plan
</button>
</form>
</div>
<div className="border border-gray-300 w-full shadow-md rounded-lg">
{!loading && !generatedAnswer && !error && (
<div>
<h2 className="text-sm flex justify-center items-center align-middle p-2">
Your Generated Plan will be visible here
</h2>
</div>
)}
{loading && <p className="text-center mt-4 ">Loading...</p>}
{error && (
<p className="text-red-500 text-center mt-4">{error}</p>
)}
{/* Render the generated answer with proper formatting */}
{generatedAnswer && (
<div className="bg-gray-50 rounded-md p-4 shadow-md mt-4 text-sm">
<p className="text-gray-800">{generatedAnswer}</p>
<ReactMarkdown>{generatedAnswer}</ReactMarkdown>
</div>
)}
</div>
</div>
</div>
</div>
</div>
<GoogleMapsCard events={props} eventId={eventId} />
<div className="py-2 px">
<div className="w-full relative p-2 sm:my-6 sm:px-16">
<h1 className="text-xl">LOCATION</h1>
<div className="block sm:flex justify-between">
{/* <button
className="secondary-button h-10 mx-auto sm:mx-0 my-4 bg-slate-300 text-gray-900 hover:bg-gray-500"
>
Get your Location
</button> */}
<div>
{distance && (
<p className="h-10 mx-auto sm:mx-0 my-4 text-gray-900 hover:bg-gray-500">
Distance between you and the event: {distance.toFixed(2)} km
</p>
)}
</div>
</div>

<div id="map" className="h-300 sm:h-600">
<GoogleMap
mapContainerStyle={{
width: "100%",
height: 600,
}}
center={eventLocation}
zoom={zoom}
options={{
zoomControl: false,
fullscreenControl: false,
}}
>
{userLocation && (
<Marker
position={userLocation}
onClick={() => setInfoWindowOpen(true)}
>
{infoWindowOpen && (
<InfoWindow onCloseClick={() => setInfoWindowOpen(false)}>
<div>Your Location</div>
</InfoWindow>
)}
</Marker>
)}
{eventLocation && (
<Marker
position={eventLocation}
onMouseOver={() => setInfoWindowOpen(true)}
>
{infoWindowOpen && (
<InfoWindow onMouseOver={() => setInfoWindowOpen(false)}>
<div>Event Location</div>
</InfoWindow>
)}
</Marker>
)}
</GoogleMap>
</div>
</div>
</div>
</>
);
};
Expand Down
Loading

0 comments on commit 69e954f

Please sign in to comment.