Skip to content

Commit

Permalink
Merge pull request agiledev-students-fall2023#141 from agiledev-stude…
Browse files Browse the repository at this point in the history
…nts-fall2023/user_story_#80

Switch to Google Api
  • Loading branch information
Nina1o1 authored Nov 16, 2023
2 parents ce4a641 + db29896 commit 060654f
Show file tree
Hide file tree
Showing 5 changed files with 230 additions and 69 deletions.
6 changes: 5 additions & 1 deletion back-end/src/app.mjs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import express from 'express';
import url from 'url';
import path from 'path';
import { fileURLToPath } from 'url';
// middlewares
import multer from "multer";
import cors from 'cors';
Expand All @@ -20,7 +21,8 @@ import register from './routes/register.mjs';
import {addFavListRouter,favListRouter, getArts} from './routes/modifyFavListRouter.mjs'
import { configDotenv } from 'dotenv';
const app = express();
dotenv.config()
//const __filename = fileURLToPath(import.meta.url);


// use the morgan middleware to log all incoming http requests
app.use(morgan("dev"));
Expand All @@ -32,6 +34,7 @@ app.use(express.urlencoded({ extended: true })); // decode url-encoded incoming
// serve static files
const __dirname = path.dirname(url.fileURLToPath(import.meta.url));
app.use("/static", express.static(path.join(__dirname, 'public')));
dotenv.config({ path: path.resolve(__dirname, '../.env') });

// cors
const corsOptions = {
Expand All @@ -48,6 +51,7 @@ app.use(session({
saveUninitialized:true,
cookie: {httpOnly: true, secure: process.env.NODE_ENV==="production"}
}))
console.log('Session secret:', process.env.SESSION_SECRET);

// other middlewares

Expand Down
2 changes: 2 additions & 0 deletions front-end/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
"@mui/material": "^5.14.15",
"axios": "^1.6.0",
"embla-carousel-react": "^8.0.0-rc14",
"google-map-react": "^2.2.1",
"google-maps-react": "^2.0.6",
"leaflet": "^1.9.4",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
64 changes: 64 additions & 0 deletions front-end/src/pages/MainMap/LocationMarker.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useOutletContext } from "react-router-dom"
import React, { useEffect, useRef } from 'react';
import ReactDOMServer from 'react-dom/server';
import FormBtn from '../../components/form/formBtn';

const LocationMarker = ({ map }) => {
const markerRef = useRef(null);
const infoWindowRef = useRef(null);
const [, , setFoundData, setRefreshPopup] = useOutletContext();

const handleLookupClick = () => {
console.log('Look up clicked!');
const position = markerRef.current.getPosition();

// Updating the shared state with the new position
setFoundData(prev => ({
...prev,
location: { lat: position.lat(), lng: position.lng() }
}));
setRefreshPopup(prev => prev + 1);
};

useEffect(() => {
if (!map) return;

const marker = new window.google.maps.Marker({
map: map,
position: map.getCenter(),
icon: {
url: "/mapicon.png",
scaledSize: new window.google.maps.Size(20, 20),
},
});

markerRef.current = marker;

const infoWindow = new window.google.maps.InfoWindow();
infoWindowRef.current = infoWindow;

map.addListener('click', (event) => {
const pos = event.latLng;
marker.setPosition(pos);
infoWindow.setPosition(pos);

// Render FormBtn to an HTML string
const formBtnHtml = ReactDOMServer.renderToString(
<FormBtn value="Look up" handleClick={handleLookupClick} />
);

// Create a container div for the HTML content
const containerDiv = document.createElement('div');
containerDiv.innerHTML = formBtnHtml;
containerDiv.querySelector('button').onclick = handleLookupClick;

// Set the container as the content of the InfoWindow
infoWindow.setContent(containerDiv);
infoWindow.open(map, marker);
});
}, [map]);

return null;
};

export default LocationMarker;
225 changes: 158 additions & 67 deletions front-end/src/pages/MainMap/MainMap.jsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,166 @@
import { useState, useRef } from 'react'
import { MapContainer, TileLayer, Marker, Popup, useMapEvents, GeoJSON } from 'react-leaflet'
import { Icon } from 'leaflet';
// import { useState, useRef } from 'react'
// import { MapContainer, TileLayer, Marker, Popup, useMapEvents, GeoJSON } from 'react-leaflet'
// import { Icon } from 'leaflet';
// import { Map, GoogleApiWrapper } from 'google-maps-react'
import { useOutletContext } from "react-router-dom"
import FormBtn from '../../components/form/formBtn';
// import InfoCard from '../../components/map/InfoCard';
// import countries from '../../util/data/countries.json'
import InfoCard from '../../components/map/InfoCard';
import countries from '../../util/data/countries.json'

// Previous Leaflet map
// import { useState, useRef } from 'react'
// import { MapContainer, TileLayer, Marker, Popup, useMapEvents, GeoJSON } from 'react-leaflet'
// import { Icon } from 'leaflet';
// import { useOutletContext } from "react-router-dom"
// import FormBtn from '../../components/form/formBtn';
// // import InfoCard from '../../components/map/InfoCard';
// // import countries from '../../util/data/countries.json'

// const MainMap = () => {
// const mapRef = useRef(null)

// return(
// <>
// <MapContainer className='mapContainer'
// center={[51.505, -0.09]}
// zoom={4}
// scrollWheelZoom={false}
// whenCreated={map => mapRef.current = map}>
// <TileLayer
// attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
// url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
// />
// <LocationMarker/>
// </MapContainer>
// {/* <div className="fixed left-8 z-[2000] flex-col justify-center items-center">
// <InfoCard title="Welcome!" text="Click anywhere on the map to start your European art & music journey! Let's get started!"/>
// <InfoCard title="What to do :)" text="Click the map for random art or drag the timeline to view map evolution over the history!"/>
// </div> */}
// </>
// )
// }

// function LocationMarker(props) {
// // props: position, setPosition
// const markerRef = useRef(null)
// const [, , setFoundData, setRefreshPopup] = useOutletContext()
// const [position, setPosition] = useState([51.505, -0.09])
// const customIcon = new Icon({
// iconUrl: "/mapicon.png",
// iconSize: [38, 38],
// });

// const map = useMapEvents({
// click(evt) {
// const pos = [evt.latlng.lat, evt.latlng.lng]
// setPosition(pos)
// map.flyTo(evt.latlng)
// markerRef.current.openPopup()
// }
// })

// const handleClick = (evt) => {
// // TODO: center at upper side
// setFoundData(prev => ({
// ...prev,
// location: position,
// }))
// setRefreshPopup(prev => prev+1)
// }


// return(
// <Marker icon={customIcon} position={position} ref={markerRef}>
// <Popup>
// <div className='pt-1'>
// {position}
// </div>
// <FormBtn value="Look up" handleClick={handleClick}/>
// </Popup>
// </Marker>

// )
// }
// export default MainMap

import React, { useState, useEffect, useRef } from 'react';
import LocationMarker from './LocationMarker';

const loadGoogleMapsScript = (callback) => {
if (window.google) {
callback();
return;
}

const script = document.createElement('script');
script.src = `https://maps.googleapis.com/maps/api/js?key=AIzaSyBcllYee9ft1HTD20Z395jqWIzTS_WmTIA&language=en`;
script.async = true;
script.defer = true;
script.onload = () => callback();
document.head.appendChild(script);
};

const MainMap = () => {
const mapRef = useRef(null)

return(
<>
<MapContainer className='mapContainer'
center={[51.505, -0.09]}
zoom={4}
scrollWheelZoom={false}
whenCreated={map => mapRef.current = map}>
<TileLayer
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
/>
<LocationMarker/>
</MapContainer>
{/* <div className="fixed left-8 z-[2000] flex-col justify-center items-center">
<InfoCard title="Welcome!" text="Click anywhere on the map to start your European art & music journey! Let's get started!"/>
<InfoCard title="What to do :)" text="Click the map for random art or drag the timeline to view map evolution over the history!"/>
</div> */}
</>
)
}

function LocationMarker(props) {
// props: position, setPosition
const markerRef = useRef(null)
const [, , setFoundData, setRefreshPopup] = useOutletContext()
const [position, setPosition] = useState([51.505, -0.09])
const customIcon = new Icon({
iconUrl: "/mapicon.png",
iconSize: [38, 38],
});

const map = useMapEvents({
click(evt) {
const pos = [evt.latlng.lat, evt.latlng.lng]
setPosition(pos)
map.flyTo(evt.latlng)
markerRef.current.openPopup()
const mapRef = useRef(null);
const [isApiLoaded, setIsApiLoaded] = useState(false);
const [map, setMap] = useState(null); // State to store the map instance
const [position, setPosition] = useState({ lat: 51.505, lng: -0.09 });

useEffect(() => {
loadGoogleMapsScript(() => setIsApiLoaded(true));
}, []);

useEffect(() => {
if (isApiLoaded && !window.google) {
console.error("Google Maps API not loaded");
return;
}
})

const handleClick = (evt) => {
// TODO: center at upper side
setFoundData(prev => ({
...prev,
location: position,
}))
setRefreshPopup(prev => prev+1)
}

return(
<Marker icon={customIcon} position={position} ref={markerRef}>
<Popup>
<div className='pt-1'>
{position}
</div>
<FormBtn value="Look up" handleClick={handleClick}/>
</Popup>
</Marker>

)
}
if (isApiLoaded && mapRef.current && !map) {
const googleMap = new window.google.maps.Map(mapRef.current, {
center: position,
zoom: 3,
});

setMap(googleMap); // Store the map instance in the state

const marker = new window.google.maps.Marker({
position: position,
map: googleMap,
icon: {
url: "/mapicon.png",
scaledSize: new window.google.maps.Size(30, 30)
}
});

googleMap.addListener('click', (event) => {
const newPos = {
lat: event.latLng.lat(),
lng: event.latLng.lng(),
};
setPosition(newPos);
marker.setPosition(newPos);
googleMap.panTo(newPos);
});
}
}, [isApiLoaded, map]);

return (
<div style={{ position: 'relative', width: '100%', height: '74vh' }}>
<div ref={mapRef} style={{ width: '100%', height: '100%' }}></div>
{map && <LocationMarker map={map} />}
<div style={{ position: 'absolute', top: '-3px', left: '10px', zIndex: 2000 }}>
<div style={{ marginBottom: '5px', width: '200px', fontSize: '0.8rem' }}>
<InfoCard title="Welcome!" text="Click anywhere on the map to start your European art & music journey! Let's get started!" />
</div>
<div style={{ width: '200px', fontSize: '0.8rem' }}>
<InfoCard title="What to do :)" text="Click the map for random art or drag the timeline to view map evolution over the history!" />
</div>
</div>
</div>
);


};

export default MainMap
export default MainMap;
2 changes: 1 addition & 1 deletion front-end/src/util/api/axios.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const serverURL = "http://localhost:3000";

const axiosProvider = axios.create({
baseURL: serverURL,
withCredentials: true
// withCredentials: true
});

export default axiosProvider;

0 comments on commit 060654f

Please sign in to comment.