diff --git a/app/[dh_choice]/page.tsx b/app/[dh_choice]/page.tsx index c1631b7..e41a0cd 100644 --- a/app/[dh_choice]/page.tsx +++ b/app/[dh_choice]/page.tsx @@ -1,8 +1,8 @@ "use client"; - -import React, { useState, useEffect } from "react"; +import React, { useState, useEffect, useRef } from "react"; import axios from "axios"; import './accordian.css'; +import Link from "next/link"; interface Food { @@ -22,10 +22,10 @@ interface Category { interface DiningHall { name: string; - categories: Category; + categories: Category[]; } -function name_to_dh_index(dhName: string, dhArray: Array) { +function name_to_dh_index(dhName: string, dhArray: DiningHall[]) { for (let i = 0; i < dhArray.length; i++) { if (dhArray[i].name === dhName) { return i; @@ -34,21 +34,25 @@ function name_to_dh_index(dhName: string, dhArray: Array) { return -1; } -function Accordion({ category, index }) { - const [isOpen, setIsOpen] = useState(false); +function Accordion({ category, index, isOpen }) { + const [isOpenState, setIsOpenState] = useState(isOpen); + + useEffect(() => { + setIsOpenState(isOpen); + }, [isOpen]); return (
- {isOpen && ( + {isOpenState && (
{category.sub_categories.map((sub_category, j) => (
@@ -67,7 +71,13 @@ function Accordion({ category, index }) { } export default function Page({ searchParams }) { - const [categories, set_categories] = useState([]); + const [categories, set_categories] = useState([]); + const [searchInput, setSearchInput] = useState(''); + const [filteredFoods, setFilteredFoods] = useState([]); + const [expandedCategory, setExpandedCategory] = useState(null); + const [noFoodsFound, setNoFoodsFound] = useState(false); + const [searchActive, setSearchActive] = useState(false); + const searchRef = useRef(null); useEffect(() => { axios @@ -85,6 +95,11 @@ export default function Page({ searchParams }) { alert("No food categories found"); return; } + const timeOfDay = getTimeOfDay(); + const timeIndex = a_dh.categories.findIndex(category => category.name.toLowerCase() === timeOfDay); + if (timeIndex !== -1) { + setExpandedCategory(timeIndex); + } }) .catch((error) => { console.log(error); @@ -93,19 +108,72 @@ export default function Page({ searchParams }) { console.log(categories) + useEffect(() => { + const timeOfDay = getTimeOfDay(); + const timeIndex = categories.findIndex(category => category.name.toLowerCase() === timeOfDay); + if (timeIndex !== -1) { + setExpandedCategory(timeIndex); + } + }, [categories]); + + const handleSearchInputChange = (event: React.ChangeEvent) => { + setSearchInput(event.target.value); + }; + + function handleSearch() { + const dhChoice = searchParams.name; + const searchResultPageUrl = `/search?diningHall=${encodeURIComponent(searchParams.name)}`; + // Navigate to the search result page + window.location.href = searchResultPageUrl; + localStorage.setItem('diningHall', dhChoice); + } + + function getTimeOfDay(): string { + const currentTime = new Date(); + const currentHour = currentTime.getHours(); + + if (currentHour >= 7 && currentHour < 11) { + return "breakfast"; + } else if (currentHour >= 11 && currentHour < 16) { + return "lunch"; + } else if (currentHour >= 16 && currentHour < 19) { + return "dinner"; + } else { + return "late night"; + } + } + + useEffect(() => { + const handleOutsideClick = (event: MouseEvent) => { + if (searchRef.current && !searchRef.current.contains(event.target as Node)) { + setSearchActive(false); + } + }; + + document.addEventListener("mousedown", handleOutsideClick); + + return () => { + document.removeEventListener("mousedown", handleOutsideClick); + }; + }, []); + return (

{searchParams.name}

+ + {/* Search button */} +
+ +
+ + {/* Categories */} {categories.map((category, i) => (
- {/*

{category.name}

*/} -
- -
+
))}
); -} \ No newline at end of file +} diff --git a/app/global_search/page.tsx b/app/global_search/page.tsx new file mode 100644 index 0000000..d200c17 --- /dev/null +++ b/app/global_search/page.tsx @@ -0,0 +1,103 @@ +"use client"; +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; + +interface Food { + name: string; +} + +interface subCategory { + name: string; + foods: Array; +} + +interface Category { + name: string; + sub_categories: Array; +} + +interface DiningHall { + name: string; + categories: Category[]; +} + +const BarebonesComponent = () => { + const [dhs, setDhs] = useState([]); + const [searchInput, setSearchInput] = useState(''); + const [filteredFoods, setFilteredFoods] = useState<{ food: Food; dhName: string; categoryName: string }[]>([]); + const [showSearchResults, setShowSearchResults] = useState(false); + const [noFoodsFound, setNoFoodsFound] = useState(false); + + useEffect(() => { + axios + .get('http://localhost:8000/myapi/dining-halls/') + .then((response) => { + const dhsData: DiningHall[] = response.data.locations; + setDhs(dhsData); + }) + .catch((error) => { + console.log(error); + }); + }, []); + + const handleSearchInputChange = (event: React.ChangeEvent) => { + setSearchInput(event.target.value); + }; + + const handleSearch = () => { + const allFoods: { food: Food; dhName: string; categoryName: string }[] = []; + dhs.forEach((dh) => { + dh.categories.forEach((category) => { + category.sub_categories.forEach((subCategory) => { + subCategory.foods.forEach((food) => { + allFoods.push({ food, dhName: dh.name, categoryName: category.name }); + }); + }); + }); + }); + + const filtered = allFoods.filter(({ food }) => food.name.toLowerCase().includes(searchInput.toLowerCase())); + + setNoFoodsFound(filtered.length === 0); + setFilteredFoods(filtered); + setShowSearchResults(true); + }; + + return ( +
+ {/* Title */} +

Welcome to Hungry Slugs!

+ {/* Search bar */} +
{/* Adjust margin as needed */} + + +
+ {/* Display search results if button clicked */} + {showSearchResults && ( +
+

Search Results:

+
    + {filteredFoods.map(({ food, dhName, categoryName }, index) => ( +
  • + {food.name} - {categoryName} ({dhName}) +
  • + ))} +
+
+ )} + + {noFoodsFound && ( +
+

No foods found at this dining hall.

+
+ )} +
+ ); +}; + +export default BarebonesComponent; diff --git a/app/page.tsx b/app/page.tsx index 02ba1c0..8cc2072 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -48,49 +48,101 @@ function ButtonLink(props: any) { } function Home() { - const [dhs_names, set_dhs_names] = useState([""]); + const [dhs, setDhs] = useState([]); + const [searchInput, setSearchInput] = useState(''); + const [filteredFoods, setFilteredFoods] = useState<{ food: Food; dhName: string; categoryName: string }[]>([]); + const [showSearchResults, setShowSearchResults] = useState(false); + const [noFoodsFound, setNoFoodsFound] = useState(false); + useEffect(() => { axios .get("http://localhost:8000/myapi/dining-halls/") .then((response) => { - // get the data from the response - const dhs: Array = response.data["locations"]; - - // print the data to the console - console.log(dhs); - - // extract the names of the dining halls - const dhs_names: string[] = []; - dhs.forEach((dh: DiningHall) => { - dhs_names.push(dh["name"]); - }); - - // set the state of the dining hall names - set_dhs_names(dhs_names); + const dhs: DiningHall[] = response.data["locations"]; + setDhs(dhs); }) .catch((error) => { console.log(error); }); }, []); + const handleSearchInputChange = (event: React.ChangeEvent) => { + setSearchInput(event.target.value); + }; + + const handleSearch = () => { + const allFoods: { food: Food; dhName: string; categoryName: string }[] = []; + dhs.forEach((dh) => { + dh.categories.forEach((category) => { + category.sub_categories.forEach((subCategory) => { + subCategory.foods.forEach((food) => { + allFoods.push({ food, dhName: dh.name, categoryName: category.name }); + }); + }); + }); + }); + + const filtered = allFoods + .filter(({ food }) => food.name.toLowerCase().includes(searchInput.toLowerCase())) + // .filter(({ food }, index, self) => self.findIndex(({ food }) => food.name === food.name) === index); + + setNoFoodsFound(filtered.length === 0); + setFilteredFoods(filtered); + setShowSearchResults(true); + }; + return (
{/* Title */}

Welcome to Hungry Slugs!

- {/* Display All of the dinning hall names as links */} -
    - {dhs_names.map((dh, i) => ( -
  • - -
  • - ))} -
+ {/* Search bar */} + {/*
+ + +
*/} + {/* Display search results if button clicked */} + {showSearchResults && ( +
+

Search Results:

+
    + {filteredFoods.map(({ food, dhName, categoryName }, index) => ( +
  • + {food.name} - {categoryName} ({dhName}) +
  • + ))} +
+
+ )} + + {noFoodsFound && ( +
+

No foods found at this dining hall.

+
+ )} + {/* Display all dining halls */} +
+

Dining Halls:

+
    + {dhs.map((dh, i) => ( +
  • + +
  • + ))} +
+
); } + + export default function Page() { const [user, setUser] = useState(null); diff --git a/app/search/page.tsx b/app/search/page.tsx new file mode 100644 index 0000000..f2d1596 --- /dev/null +++ b/app/search/page.tsx @@ -0,0 +1,108 @@ +"use client"; +import React, { useState, useEffect } from 'react'; +import axios from 'axios'; + +interface Food { + name: string; +} + +interface subCategory { + name: string; + foods: Array; +} + +interface Category { + name: string; + sub_categories: Array; +} + +interface DiningHall { + name: string; + categories: Category[]; +} + +const BarebonesComponent = () => { + const [dhs, setDhs] = useState([]); + const [searchInput, setSearchInput] = useState(''); + const [filteredFoods, setFilteredFoods] = useState<{ food: Food; dhName: string; categoryName: string }[]>([]); + const [showSearchResults, setShowSearchResults] = useState(false); + const [noFoodsFound, setNoFoodsFound] = useState(false); + + const diningHall = localStorage.getItem('diningHall'); + + useEffect(() => { + axios + .get('http://localhost:8000/myapi/dining-halls/') + .then((response) => { + const dhsData: DiningHall[] = response.data.locations; + setDhs(dhsData); + }) + .catch((error) => { + console.log(error); + }); + }, []); + + const handleSearchInputChange = (event: React.ChangeEvent) => { + setSearchInput(event.target.value); + }; + + const handleSearch = () => { + const currentDiningHall = dhs.find((dh) => dh.name === diningHall); + if (!currentDiningHall) return; + + const allFoods: { food: Food; dhName: string; categoryName: string }[] = []; + currentDiningHall.categories.forEach((category) => { + category.sub_categories.forEach((subCategory) => { + subCategory.foods.forEach((food) => { + allFoods.push({ food, dhName: currentDiningHall.name, categoryName: category.name }); + }); + }); + }); + + const filtered = allFoods.filter(({ food }) => food.name.toLowerCase().includes(searchInput.toLowerCase())); + + setNoFoodsFound(filtered.length === 0); + setFilteredFoods(filtered); + setShowSearchResults(true); + }; + + return ( +
+ {/* Dining Hall Name */} +

{diningHall} Search

+ + {/* Search bar */} +
{/* Adjust margin as needed */} + + +
+ + {/* Display search results if button clicked */} + {showSearchResults && ( +
+

Search Results:

+
    + {filteredFoods.map(({ food, dhName, categoryName }, index) => ( +
  • + {food.name} - {categoryName} ({dhName}) +
  • + ))} +
+
+ )} + + {noFoodsFound && ( +
+

No foods found at this dining hall.

+
+ )} +
+ ); +}; + +export default BarebonesComponent; diff --git a/components/navbar.tsx b/components/navbar.tsx index 1250b27..9372a7e 100644 --- a/components/navbar.tsx +++ b/components/navbar.tsx @@ -2,8 +2,37 @@ export default function Navbar({ height }: { height: string }) { return ( -
-

Hungry Slugs

-
+ + + + + ); -} +} \ No newline at end of file