DC Menu App

2023–2024 Yearlong Spark Project Update

CodeLab UC Davis
8 min readDec 28, 2023

Introduction

Currently, the UC Davis dining commons’ website is divided into four separate sites corresponding to each dining commons. This fragmentation poses challenges for both staff and students when transitioning between options and exploring menus, dietary choices, and macros. Our goal is to develop a React Native app that simplifies the process for students, allowing them to effortlessly access information on all four dining commons’ menus, dietary options, and macros with just a few taps. Additionally, the app will offer a feature enabling users to save their personal favorites and track their dietary choices efficiently.

The Team

Avnoor Sidhu: Project Mentor
Roshini Pothapragada: Project Manager
Aadam Mirza: Developer
Aiden DeVaney: Developer
Connie Zhu: Developer
Hideaki Park: Developer
Varun Thakkar: Developer
Rytham Dawar: Developer
Rashi Bihani: Designer
Reiley Johnson: Designer
Maxim Saschin: Designer

Timeframe

Oct 2022 — Jun 2023 | 22 weeks

Tools

Figma, MongoDB, Express JS, Python, ReactNative

The Project

We are still working on our project and building our pages. Here is a little glimpse

Design

Market + User Research

First, our team had to figure out our go-to market. Since our app was aimed directly towards UC Davis students, we began narrowing our search from there. UC Davis has around 40,850 students as of Fall 2023. Of these students, primarily freshmen and transfer students would have a dining meal plan, and would visit the dining commons the most. This narrowed our market to around 9,000 undergraduate students. Our app would be for these 9,000 students.

Next, we had to research which features our market deemed the most important when choosing which dining commons to eat at.

Comparative Analysis

First, we looked at potential competitors across the market, as well as what features they had to offer. We found that three traits were offered on all three apps: a list of dining locations, their opening/closing times, and information on when each menu item was available (whether time, or sorted by breakfast/lunch/dinner). Additionally, we noticed that some competitors had features that we were implementing as well, such as dietary restriction filters, some sort of nutrition info, etc. We also noticed that both campus apps also had breakfast/lunch/dinner categories. However, we realized there were no specific timestamps for each meal time, and we figured that defining the specific times each meal is served would be helpful since college students are known for having hectic and unusual schedules.

We did not just stop at comparative analysis, however. We took a further look at our market by interviewing and surveying fellow students as well.

Analysis and Key Insights

This process also helped us come up with our user flows. We started off with a simple user flow and iterated upon it utilizing the data we analyzed during our ideation phase.

User Flow

Wireframing + Prototyping

The design process went through multiple iterations, starting from lo-fi sketches and progressing towards final wireframes. Each iteration aimed to refine and improve the user experience.

Low-Fidelity Sketches

Mid-Fidelity Sketches

As we continued along the design process, more focus was given to the aesthetics of our app. We created a comprehensive design system to start bringing the app to life as well as begin brand development efforts. This design system included colorography, typography, as well as iconography.

Comprehensive Design System

Moving onto mid-fidelity designs, we gave our attention to the functionality of the app. Flexible search filters were introduced to allow users to customize their searches and narrow down results based on their specific preferences. This flexibility improved the overall search experience and made it easier for users to find the information they were looking for. Additionally, the team implemented saving options, enabling users to store their preferred food items from specific dining commons for future use. With this feature, users will be able to receive notifications for favorite foods after saving favorite foods in the app. This eliminated the need for users to repeatedly search for their preferences and enhanced their overall efficiency within the interface.

Another important consideration was the progress page. We wanted users to be able to keep track of the macros consumed from dining commons items and check their daily, weekly, or monthly progress.

Dining Commons Menu App High-Fidelity Wireframes

Login/Logout Page

Home Page

Menu Page

Profile Page

In conclusion, the design process progressed through several iterations and incorporated different features within the interface to enhance the user experience. From creating hierarchy and clarifying user flows to introducing flexible search filters, saving options, and a progress tracker, the iterative enhancements led to a polished and user-friendly interface. The final wireframes exemplified the culmination of these improvements, providing users with an intuitive, efficient, and gratifying experience in the application.

Development

React Native App → Express Server → MongoDB Database → Data Retrieval/Updates → App Display

This quarter our developers got started with web scraping and user authentication. Staring with web scraping, menu items are systematically scraped directly from the current DC website using BeautifulSoup, ensuring an up-to-date and accurate representation of the available offerings. This scraping process includes the extraction of comprehensive data, encompassing nutritional information such as calories and macros, as well as dietary details like allergens and ingredients.

# Function to extract and structure nutrition and allergy info
nutrition_section = food_item.find('ul', class_='nutrition')
if nutrition_section:
# Extracting nutrition and allergy info
nutrition_allergy_info = extract_info(nutrition_section)
# Structuring the data
food_data = {
'date': date,
'meal_period': meal_period,
'station': station,
'food_name': food_name,
'nutrition_allergy_info': nutrition_allergy_info
}
data.append(food_data)

To efficiently manage and retrieve this wealth of information, a MongoDB database is employed for storage. The stored data is then made accessible through an API implemented with Express, facilitating seamless retrieval and utilization of the extracted menu data. This integrated system ensures that users can access and leverage the most current and relevant information about the menu items offered by the DC.

// MongoDB Schema
{
"_id": {
"$oid": "656964af56f9ae97c45f7ca9"
},
"date": "Monday, November 27, 2023",
"meal_period": "Lunch",
"station": "1",
"food_name": "Andino Bowl",
"nutrition_allergy_info": {
"Serving Size": ": 100 g",
"Calories": ": 122.66",
"Fat (g)": ": 5.11",
"Carbohydrates (g)": ": 2.63",
"Protein (g)": ": 15.24",
"Allergens": "SOY, SOYBEAN OIL, VINEGAR, DAIRY, WHEAT/GLUTEN, ALCOHOL",
"Ingredients": "Frozen 1/2in diced beef carne asada rib, Fat Free Italian Dressing (water, distilled vinegar, sugar, salt. Contains less than 2% of modified food starch, garlic juice, dried garlic, dried onion, xanthan gum, sodium benzoate, potassium sorbate, dried red bell pepper, spices, phosphoric acid, soybean oil, extractive of carrot), Julienned Yellow Onions, Coarse Flake Kosher Salt (salt, yellow prussiate of soda), Granulated Garlic, Coarse Ground Black Pepper"
}
}

Moving forward to ensure user authentication, The registration process begins when a user inputs their name, email, and password. Upon submission, a POST request is sent to the Express API, initiating the registration function. This function, in turn, verifies whether the user already exists within the database. If the user is not found, the system proceeds to create a new user account. Crucially, security measures are implemented during this process, with the user’s password undergoing hashing before being stored in the database. This ensures that sensitive information remains protected, enhancing the overall security of the registration system.

// Segment of the User Verification
if (!isPasswordMatched) {
return res.status(400).json({
status: 400,
success: false,
message: "Wrong password",
});
}
if (!process.env.JWT_SECRET) {
throw new Error('JWT_SECRET is not defined in the environment variables.');
}
const token = jwt.sign(
{ _id: isUserExist?._id, email: isUserExist?.email },
process.env.JWT_SECRET,
{
expiresIn: process.env.JWT_EXPIRES_IN,
}
);
return res.status(200).json({
status: 200,
success: true,
message: "Login success",
token: token,
});

Upon a user attempting to log in, the login function is triggered within the system. During this process, Bcrypt comes into play, comparing the hashed password entered by the user with the stored hashed password associated with the corresponding email. If the comparison yields a match, indicating that the user has entered the correct credentials, the system proceeds to generate an access token using JSON Web Tokens (JWT). This enhances the overall security of the login system, ensuring a robust and protected user authentication process.

Takeaways & Challenges

Navigating timing conflicts and task assignments within our sizable college student group, amidst the complexities of demanding schedules, presented a formidable hurdle in the course of our project. The intricate balance required for academic commitments, extracurricular engagements, and various responsibilities made the identification of mutually convenient collaboration windows a daunting task. To address this challenge, we underscored the importance of transparent communication, consistently sharing our availability updates with the team. A hybrid workflow, melding in-person gatherings with asynchronous work, emerged as a strategic choice, adeptly accommodating diverse schedules and work preferences. This approach not only facilitated continuous progress but also optimized productivity. Despite the initial challenges, our success lay in the adept allocation of tasks, capitalizing on individual strengths and preferences, thereby nurturing collaboration and triumphing over scheduling hurdles.

Another significant challenge we faced involved establishing a connection to MongoDB through the Visual Studio Code extension. Unfortunately, our initial attempts to connect were consistently met with rejection, preventing us from accessing the database. Essentially, we found ourselves at an impasse, unable to navigate within the database at all. However, through diligent troubleshooting and exploration, and help from our wonderful mentor, we identified the root cause and successfully overcame this challenge. By implementing a tailored solution, we managed to establish a seamless connection, enabling effective interaction with the MongoDB environment through the Visual Studio Code extension. This experience highlighted the importance of resilience and problem-solving in overcoming technical obstacles.

--

--

CodeLab UC Davis

CodeLab is a student-run software development and UX design agency at UC Davis.