Skip to content

Commit

Permalink
Merge pull request #183 from agiledev-students-fall2023/map_search
Browse files Browse the repository at this point in the history
Map search
  • Loading branch information
Nina1o1 authored Dec 7, 2023
2 parents 34f557a + 7b2f8c9 commit 6c1847a
Show file tree
Hide file tree
Showing 12 changed files with 134 additions and 88 deletions.
6 changes: 3 additions & 3 deletions back-end/src/app.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import delaccountRouter from './routes/delaccountRouter.mjs';
import getpieceRouter from './routes/getpieceRouter.mjs';
import resetpasswordRouter from './routes/resetpasswordRouter.mjs';
import resetemailRouter from './routes/resetemailRouter.mjs';
import searchRouter from './routes/searchRouter.mjs';
import searchArtsRouter from './routes/searchArtsRouter.mjs';

import {addFavListRouter,favListRouter, getArts} from './routes/modifyFavListRouter.mjs'
import { configDotenv } from 'dotenv';
Expand Down Expand Up @@ -114,8 +114,8 @@ app.delete("/delaccount", delaccountRouter); //Finished
// Favorites list routes
app.post('/addFavorite', addFavListRouter);//finished
app.get('/getfavlist', favListRouter);
app.post('/getArts', getArts);//finished
app.get('/search', searchRouter);
app.get('/getArts', getArts);//finished
app.get('/searchArts', searchArtsRouter);
// app.post('/favlist/remove',removeFavListRouter);

// export the express app we created to make it available to other modules
Expand Down
4 changes: 2 additions & 2 deletions back-end/src/routes/modifyFavListRouter.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import mongoose from 'mongoose';


export const getArts = async (req, res) => {
const { timeRange, location } = req.body;
console.log(location)
const { timeRange, location } = req.query;
console.log(location, timeRange)

const startYear = parseInt(timeRange[0]);
const endYear = parseInt(timeRange[1]);
Expand Down
33 changes: 33 additions & 0 deletions back-end/src/routes/searchArtsRouter.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import Artwork from '../models/Artwork.mjs';

const searchArtsRouter = async (req, res) => {
// artinfo, timeRange
const { artInfo, timeRange } = req.query;
console.log(artInfo, timeRange)

const startYear = parseInt(timeRange[0]);
const endYear = parseInt(timeRange[1]);

console.log(req.query);
console.log(startYear);
console.log(endYear);

try {
console.log('Searching for artworks...');
const artworks = await Artwork.find({
Year: { $gte: startYear, $lte: endYear },
$or: [
{ title: { $regex: `${artInfo}`, $options: 'i' } },
{ artist: { $regex: `${artInfo}`, $options: 'i' } }
]
}).limit(15);
console.log('Artworks found');
console.log(artworks);
return res.json(artworks);
} catch (err) {
console.error(err); // Log the error for debugging
return res.status(500).send('Internal Server Error');
}
};

export default searchArtsRouter;
30 changes: 0 additions & 30 deletions back-end/src/routes/searchRouter.mjs

This file was deleted.

6 changes: 3 additions & 3 deletions front-end/src/components/map/lookupBtn.jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
const LookupBtn = (props) => {
//attribute: value, handleClick
return (
<div className="w-full py-2">
<button className="rounded-lg py-2 w-full
<div className="w-full py-1">
<button className="rounded-lg p-2 w-full
border-solid border-0 border-navyBlue bg-transparent text-navyBlue
hover:cursor-pointer hover:bg-navyBlue hover:text-beige1
active:cursor-pointer active:bg-transparent active:text-navyBlue"
onClick={props?.handleClick}>
{props?.value ?? "Submit"}
</button>
</button>
</div>
)
}
Expand Down
3 changes: 2 additions & 1 deletion front-end/src/pages/Account/Account.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ const AccountEdit = (props) => {
setCurrentActionData(null)
}

console.log("Component render, current username:", username);
// console.log("Component render, current username:", username);

//Return the AccountEdit component
return (
<>
Expand Down
3 changes: 1 addition & 2 deletions front-end/src/pages/FavoriteList/FavoriteList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,7 @@ const FavoriteList = () => {
return (
<>
<NavBar>
<div className="flex justify-start items-center gap-3">
<LeftBtn/>
<div className="w-full text-center">
<h2>My Favorite Arts</h2>
</div>
</NavBar>
Expand Down
6 changes: 3 additions & 3 deletions front-end/src/pages/MainMap/MainMap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,21 +45,21 @@ function LocationMarker(props) {
}
})

// update search data upon user click "look up" btn
const handleClick = (evt) => {
// TODO: center at upper side
setFoundData(prev => ({
...prev,
location: position,
}))
setRefreshPopup(prev => prev+1)
setRefreshPopup(prev => prev >= 0 ? prev+1 : 1)
}


return(
<Marker icon={customIcon} position={position} ref={markerRef}>
<Popup>

<LookupBtn value="Look up 🔍" handleClick={handleClick}/>
<LookupBtn value="Look up 🔍" handleClick={handleClick}/>
</Popup>
</Marker>

Expand Down
35 changes: 17 additions & 18 deletions front-end/src/pages/MainMap/MapLayout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,47 @@ import { useEffect, useState } from "react";
import PopupSearch from "./popupSearch";
import TimeRange from '../../components/timeline/TimeRange.jsx';
import { format, setYear, endOfYear } from 'date-fns';
import InfoCard from "../../components/map/InfoCard.jsx";

//timeline-related
const getSpecificYear = (year) => setYear(new Date(), year);
const timelineInterval = [getSpecificYear(1000), endOfYear(getSpecificYear(2020))];


const MapLayout = () => {
const location = useLocation()
const navigate = useNavigate()
const [searchPage, setSearchPage] = useState(false) // display search page or not
const [searchData, setSearchData] = useState("") // content that user typed in bar
// subject to changes
// data necessary to search for art object (time & location)
// {location:[lng, lat] (or city), time: num}
const [foundData, setFoundData] = useState({location:[],timeRange:[1920, 1940]})
const [refreshPopup, setRefreshPopup] = useState(0) // change counter to refresh popup, 0 to close popup

//timeline
// States related to send request to backend
// Data required to search for art object (time & location)
// {location:[lng, lat], timeRange: [startYear, endYaer], artInfo: "str"}
const [foundData, setFoundData] = useState({location:[], timeRange:[1920, 1940], artInfo:""})
// Counter to refresh popup page: 0 - close, positive - search by click, positive - search by type
const [refreshPopup, setRefreshPopup] = useState(0)
// timeline
const [selectedInterval, setSelectedInterval] = useState([getSpecificYear(1920), getSpecificYear(1940)]);
const [error, setError] = useState(false);
const errorHandler = ({ error }) => setError(error);


// timeline error handler
const errorHandler = ({ error }) => setError(error);

// change timeline upon user interaction
const onChangeCallback = (newInterval) => {
setSelectedInterval(newInterval);
setFoundData(prevData => ({
...prevData,
timeRange: [format(newInterval[0], "yyyy"),format(newInterval[1], "yyyy")]
}));
setRefreshPopup(prev => prev > 0 ? prev+1 : (prev < 0 ? prev-1 : prev));
};


// display search page if user is in search page
useEffect(() => {
if (location.pathname === "/search") !searchPage && setSearchPage(true)
}, [])


// submit search result
// update user input data to searchData state. Display search page if necessary
const handleSubmit = (evt) => {
evt.stopPropagation()
// send data via react Context to SearchMap
if (evt.target.value) {
setSearchData(evt.target.value)
if (location.pathname === "/") {
Expand All @@ -60,15 +59,15 @@ const MapLayout = () => {
}
}

// navigate back to home page
// navigate back to home page upon click back btn
const handleClickBack = (evt) => {
evt.stopPropagation()
evt.preventDefault()
navigate("/", { state: { from: location.pathname } });
searchPage && setSearchPage(false)
setRefreshPopup(0)
}
// navigate to search page
// navigate to search page upon click search btn
const handleClickSearch = (evt) => {
evt.stopPropagation()
evt.preventDefault()
Expand Down
52 changes: 41 additions & 11 deletions front-end/src/pages/MainMap/SearchMap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,68 @@ import axiosProvider from "../../util/api/axios"

const SearchMap = () => {
const [searchData, ,setFoundData, setRefreshPopup] = useOutletContext();
const [searchdata, setSearchData] = useState('');
const [suggestions, setSuggestions] = useState([]);

/*
useEffect(() => {
const loadSuggestions = async () => {
try {
const response = await axiosProvider.get(`/search`);
const response = await axiosProvider.get(`/searchArts`);
setSuggestions(response.data);
} catch (error) {
console.error('Error fetching search suggestions', error);
}
};
if (searchdata) {
loadSuggestions();
} else {
setSuggestions([]);
}
if (searchData) loadSuggestions();
else setSuggestions([]);
// setRefreshPopup(0)
}, [searchData]);
*/

console.log(suggestions);
// update suggestions on every user input
useEffect(() => {
// may add another route to get a list of suggestions
if (searchData) setSuggestions(["albert irvin"]) // random author
else setSuggestions([])
}, [searchData])

const handleCityClick = (evt, city) => {
// click on suggestion to fetch art data
const handleSuggestionClick = (evt, suggestion) => {
evt.stopPropagation()
// TODO: find the location of city
setFoundData(prev => ({
...prev,
location: city
artInfo: suggestion
}))
setRefreshPopup(prev => prev+1)
setRefreshPopup(prev => prev<=0 ? prev-1 : -1)
};

return(
<>
<div className="px-[10%]">
<div className='overflow-scroll content-center'>
<ul>

{suggestions.length ?

suggestions?.map((suggestion, index) => (
<li className="border-b border-navyBlue" key={index} onClick={(evt) => handleSuggestionClick(evt, suggestion)}>
<div className="p-2 rounded-lg active:bg-white cursor-pointer">
{suggestion}
</div>
</li>
)) :

<li className="border-b border-navyBlue p-2 text-gray-400">
No suggestion found, try another one
</li>
}

</ul>
</div>
</div>
</>
)
}
export default SearchMap
42 changes: 28 additions & 14 deletions front-end/src/pages/MainMap/popupSearch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,30 +13,44 @@ const PopupSearch = (props) => {
const location = useLocation()

useEffect(() => {
async function getData() {
const postData = {
// request to "searchArts" route
async function searchArtsData() {
const getData = {
artInfo: props.foundData.artInfo,
timeRange: props.foundData.timeRange
}
console.log(getData)
try {
const res = await axiosProvider.get(
"/searchArts",
{ params: getData }
)
setArts(res.data);
} catch (error) {
console.error(err);
}
}

// request to "/getArts" route
async function getArtsData() {
const getData = {
location: props.foundData.location,
timeRange: props.foundData.timeRange
};
const postOptions = {
headers: {
'Content-Type': 'application/json'
}
};
try {
const res = await axiosProvider.post(
const res = await axiosProvider.get(
"/getArts",
JSON.stringify(postData),
postOptions
{ params: getData }
);
const retData = res.data;
setArts(retData);
setArts(res.data);
} catch (err) {
console.error(err);
}
}
if (props.refreshPopup) getData();
}, [props.refreshPopup, props.foundData]);
if (props.refreshPopup > 0) getArtsData()
else if (props.refreshPopup < 0) searchArtsData()
}, [props.refreshPopup]);


const handleArtItemClick = (art) => {
// Navigate to the art information page
Expand Down
2 changes: 1 addition & 1 deletion front-end/src/pages/MainMapGoogle/LocationMarker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ const LocationMarker = ({ map }) => {
...prev,
location: { lat: position.lat(), lng: position.lng() }
}));
setRefreshPopup(prev => prev + 1);
setRefreshPopup(prev => prev<=0 ? prev-1 : -1)
};

useEffect(() => {
Expand Down

0 comments on commit 6c1847a

Please sign in to comment.