Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into db_rework
Browse files Browse the repository at this point in the history
  • Loading branch information
IanHollow committed May 13, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 06f1125 + dc3f363 commit c1a6dd4
Showing 29 changed files with 1,035 additions and 144 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/js-ts-formatting-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Prettier Check

on:
push: {}

jobs:
prettier:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4
- uses: oven-sh/setup-bun@v1

- name: Install dependencies
run: bun install

- name: Run Prettier check
run: bunx prettier --check '**/*.{js,ts,jsx,tsx}'
15 changes: 15 additions & 0 deletions .github/workflows/python-formatting-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
name: Black Formatting Check

on:
push: {}

jobs:
black:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: psf/black@stable # Official Black action
with:
options: "--check --verbose" # Check for formatting issues only
src: "." # Path to your Python source code (optional)
16 changes: 7 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -2,13 +2,13 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next

## Running Code

* Make sure to have a private folder in the root directory that contains all secrets. (for now you can get this folder from our shared google drive folder) [link](https://drive.google.com/drive/folders/1oz7vGXPAI2S8vzYIpQ2ATTfjgqFHDD_p?usp=sharing)
* Make sure that you have all the python dependencies installed in the requirements.txt
* Make sure to install JS dependencies with `bun i` or `npm i`
* you then will have to have two terminals to run backend and frontend
* the backend is run with: `python backend/manage.py runserver`
* the frontend is run one of the commands below in the Getting Started
* Also, if you have nix installed with flakes you can skip most of the environment setup steps and use `nix develop` to setup your dev environment
- Make sure to have a private folder in the root directory that contains all secrets. (for now you can get this folder from our shared google drive folder) [link](https://drive.google.com/drive/folders/1oz7vGXPAI2S8vzYIpQ2ATTfjgqFHDD_p?usp=sharing)
- Make sure that you have all the python dependencies installed in the requirements.txt
- Make sure to install JS dependencies with `bun i` or `npm i`
- you then will have to have two terminals to run backend and frontend
- the backend is run with: `python backend/manage.py runserver`
- the frontend is run one of the commands below in the Getting Started
- Also, if you have nix installed with flakes you can skip most of the environment setup steps and use `nix develop` to setup your dev environment

## Getting Started

@@ -24,8 +24,6 @@ pnpm dev
bun dev
```



Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
32 changes: 32 additions & 0 deletions app/[dh_choice]/accordian.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.accordion {
background-color: #ffffff;
border: transparent;
}
.accordion-item {
border: 1px solid #1321e1;
margin-bottom: 10px;
}
.accordion-button {
background-color: transparent; /* Transparent background */
color: #003c6c; /* Category font color */
padding: 10px;
font-size: 16px;
border-bottom: 1px solid #ffffff;
}
.accordion-collapse {
padding: 10px;
}

.sub-category {
background-color: transparent;
padding: 10px;
border-radius: 8px;
border-bottom: 1px solid #fdc700;
}

.food-item {
background-color: #9c9c9c;
padding: 8px;
margin-bottom: 4px;
border-radius: 4px;
}
198 changes: 144 additions & 54 deletions app/[dh_choice]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
"use client";

import { 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 {
name: string;
allergies: Array<string>;
}

interface subCategory {
@@ -19,10 +21,10 @@ interface Category {

interface DiningHall {
name: string;
categories: Category;
categories: Category[];
}

function name_to_dh_index(dhName: string, dhArray: Array<DiningHall>) {
function name_to_dh_index(dhName: string, dhArray: DiningHall[]) {
for (let i = 0; i < dhArray.length; i++) {
if (dhArray[i].name === dhName) {
return i;
@@ -31,76 +33,164 @@ function name_to_dh_index(dhName: string, dhArray: Array<DiningHall>) {
return -1;
}

export default function Page({
searchParams,
}: {
searchParams: {
name: string;
};
}) {
const [categories, set_categories]: [Array<Category>, any] = useState([]);
function Accordion({ category, isOpen }) {
const [isOpenState, setIsOpenState] = useState(isOpen);

useEffect(() => {
setIsOpenState(isOpen);
}, [isOpen]);

return (
<div className="accordion border border-gray-200 rounded mb-2">
<button
className="accordion-button w-full text-left p-3 focus:outline-none"
onClick={() => setIsOpenState(!isOpenState)}
>
{category.name}
<span className="float-right">{isOpenState ? "▲" : "▼"}</span>
</button>
{isOpenState && (
<div className="accordion-collapse p-3">
{category.sub_categories.map((sub_category, j) => (
<div key={j} className="mb-2">
<h4 className="sub-category">{sub_category.name}</h4>
<ul className="pl-4">
{sub_category.foods.map((food, k) => (
<li key={k} className="food-item">
{food.name}
</li>
))}
</ul>
</div>
))}
</div>
)}
</div>
);
}

export default function Page({ searchParams }) {
const [categories, set_categories] = useState<Category[]>([]);
const [searchInput, setSearchInput] = useState("");
const [filteredFoods, setFilteredFoods] = useState<Food[]>([]);
const [expandedCategory, setExpandedCategory] = useState<number | null>(null);
const [noFoodsFound, setNoFoodsFound] = useState(false);
const [searchActive, setSearchActive] = useState(false);
const searchRef = useRef<HTMLDivElement>(null);

useEffect(() => {
axios
.get("http://localhost:8000/myapi/dining-halls/")
.get("http://localhost:8000/myapi/locations/")
.then((response) => {
// fetch the data from the response
const dhs = response.data["locations"];

// find the dining hall with the name
const dhs = response.data.locations;
const dh_index = name_to_dh_index(searchParams.name, dhs);
// if the dining hall is not found, alert the user
if (dh_index == -1) {
alert("Dh not found");
if (dh_index === -1) {
alert("Dining hall not found");
return;
}

// get the dining hall with the name
const a_dh = dhs[dh_index];

// get the categories from the dining hall
set_categories(a_dh["categories"]);

// if the dining hall does not have any values in the categories object, alert the user
if (Object.keys(a_dh["categories"]).length == 0) {
set_categories(a_dh.categories);
if (Object.keys(a_dh.categories).length === 0) {
alert("No food categories found");
return;
}

console.log(a_dh);
const timeOfDay = getTimeOfDay();
const timeIndex = a_dh.categories.findIndex(
(category) => category.name.toLowerCase() === timeOfDay,
);
if (timeIndex !== -1) {
setExpandedCategory(timeIndex);
}
})
.catch((error) => {
console.log(error);
});
}, []);
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<HTMLInputElement>,
) => {
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 (
<main>

<div className="container mx-auto">
{/* Dining Hall Name */}
<h2 className="text-xl">{searchParams.name}</h2>

{/* List all the meal times and their foods */}
{categories &&
categories.map((category: Category, i: number) => (
<div key={i}>
<h3 className="text-lg">{category.name}</h3>
<ul>
{category.sub_categories.map(
(sub_category: subCategory, j: number) => (
<li key={j}>
<h4 className="text-md">{sub_category.name}</h4>
<ul>
{sub_category.foods.map((food: Food, k: number) => (
<li key={k}>{food.name}</li>
))}
</ul>
</li>
)
)}
</ul>
</div>
))}
<h1 className="font-semibold py-5 text-4xl text-[#003C6C]">
{searchParams.name}
</h1>






{/* Search button */}
<div>
<button onClick={handleSearch}>Search</button>
</div>

{/* Categories */}
{categories.map((category, i) => (
<div key={i}>
<Accordion
category={category}
isOpen={expandedCategory === i}
/>
</div>
))}
</div>
</main>
);
Loading
Oops, something went wrong.

0 comments on commit c1a6dd4

Please sign in to comment.