Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
100afa6
inital package install
JeffieJansson Feb 10, 2026
fffbb72
import dotenv
JeffieJansson Feb 10, 2026
3cc71e8
Add API documentation and route setup for user and recipes
JeffieJansson Feb 10, 2026
f1fef0b
Add authentication middleware for user validation
JeffieJansson Feb 10, 2026
fd9dd2e
Add Recipe model schema
JeffieJansson Feb 10, 2026
7fc6dc1
Add User model schema
JeffieJansson Feb 10, 2026
71cfcf6
Add user authentication routes and forms for login and signup
JeffieJansson Feb 10, 2026
02e6b71
Add recipe routes for creating, fetching, and searching recipes
JeffieJansson Feb 10, 2026
ff5be9d
Update package.json
JeffieJansson Feb 10, 2026
540eea7
Fix import paths for user and recipe routes in server.js
JeffieJansson Feb 10, 2026
f6da433
Fix import paths for User model in authMiddleware and userRoutes
JeffieJansson Feb 10, 2026
e17a7bf
Add svg icon
JeffieJansson Feb 10, 2026
ac7c43b
Add API_URL constant
JeffieJansson Feb 10, 2026
a52a224
Add axios dependency to package.json
JeffieJansson Feb 10, 2026
974c59e
Add LoginForm component with styled elements and authentication
JeffieJansson Feb 10, 2026
069eae6
Add SignupForm component with form handling and validation
JeffieJansson Feb 10, 2026
4ebe129
Add axios dependency to package.json
JeffieJansson Feb 10, 2026
d5e8df1
Remove authentication requirement for some recipe routes
JeffieJansson Feb 11, 2026
2de5846
Add user store with Zustand
JeffieJansson Feb 11, 2026
b7d8915
create nav skeleton
JeffieJansson Feb 11, 2026
e4c65b0
Add recipe store using Zustand
JeffieJansson Feb 11, 2026
3108057
Add Home component with login/signup form
JeffieJansson Feb 11, 2026
8300e5c
add routing and user state management
JeffieJansson Feb 11, 2026
6f7e54f
add framer-motion dependency to package.json
JeffieJansson Feb 11, 2026
8239b31
add About page skeleton with basic design and framer motion animation
JeffieJansson Feb 11, 2026
0eb4543
add Member page/router and moved authentication forms and styling fr…
JeffieJansson Feb 11, 2026
df02348
update About link text and ensure Login link connect to /member page
JeffieJansson Feb 11, 2026
76e316d
add mode management to recipe store(allow extra or exact ingredient)
JeffieJansson Feb 11, 2026
b39472a
import search recipe and moved toggle signup/login from home componen…
JeffieJansson Feb 11, 2026
7af0126
add SearchRecipe component with input and filter without functionalit…
JeffieJansson Feb 11, 2026
c1c487a
Add APi functions for recipes: search, details, save, fetch saved, an…
JeffieJansson Feb 12, 2026
81fe448
Refactor recipe routes: add ingredient search with filter, improve er…
JeffieJansson Feb 12, 2026
0ce7897
Fix import path for API_URL in LoginForm and SignupForm components
JeffieJansson Feb 12, 2026
3479bd9
Update favicon to use PantryMatch.svg
JeffieJansson Feb 13, 2026
1bcf3e2
Add GlobalStyles component and update member page message
JeffieJansson Feb 13, 2026
6488114
Add global media.js and responsive media queries to components
JeffieJansson Feb 13, 2026
29ee8bc
Add Hero component to home page with logo
JeffieJansson Feb 13, 2026
8a46b46
structure api url, add recipe fields, changes req ingredient for sear…
JeffieJansson Feb 17, 2026
d4271ae
Add initial RecipeCard component for displaying recipe details
JeffieJansson Feb 17, 2026
4aab4de
Add initial RecipeList component to display a list of recipes
JeffieJansson Feb 17, 2026
793d495
Add useRecipeActions custom hook for managing recipe search functiona…
JeffieJansson Feb 17, 2026
f9139df
Implement recipe search functionality with ingredient management and …
JeffieJansson Feb 17, 2026
64b9866
add todos
JeffieJansson Feb 17, 2026
17bc992
Refactor recipe search route, add recipe details endpoint and add err…
JeffieJansson Feb 18, 2026
e8bbb8a
Refactor Recipe model to include detailed ingredient schema
JeffieJansson Feb 18, 2026
e5fe5ee
refactor APi calls to use consistent API_URL and improve error handli…
JeffieJansson Feb 18, 2026
988fcd0
add mode
JeffieJansson Feb 18, 2026
6ff92b3
add setError for minimun ingredient input and add remove ingredient
JeffieJansson Feb 18, 2026
c434143
Refactor SearchRecipe component to improve ingredient handling,
JeffieJansson Feb 18, 2026
3d1e1e9
add expandable details, fetch add display instructions and ingredient…
JeffieJansson Feb 18, 2026
ee39fc0
add syled components and improve layout and remove unnecessary elements
JeffieJansson Feb 18, 2026
68a46df
debug spoonacular extra API calls for readyInMinutes and servings by …
JeffieJansson Feb 18, 2026
9a36884
improve ingredient display by filtering out unwanted ''other things'…
JeffieJansson Feb 18, 2026
f655392
add logging for fetchRecipeByIngredients response
JeffieJansson Feb 18, 2026
57df2b0
add save button to recipeCard
JeffieJansson Feb 22, 2026
ed22408
add save functionality: redirect to login if user not authenticated, …
JeffieJansson Feb 23, 2026
9c4bcaf
update saved recipes route to render SavedRecipes component
JeffieJansson Feb 23, 2026
37bf753
add basic SavedRecipes component to display and manage saved recipes
JeffieJansson Feb 23, 2026
bc8282b
enhance design with styled components, add loading,error,expand state…
JeffieJansson Feb 24, 2026
3e63a24
add analyzedInstructions to recipe details response
JeffieJansson Feb 24, 2026
deca57c
update recipe instructions display to show analyzed instructions if a…
JeffieJansson Feb 24, 2026
ec73124
update grid and button styling for RecipeCard ,RecipeList and savedRe…
JeffieJansson Feb 24, 2026
427b190
add diet and intolerance filters to recipe search functionality
JeffieJansson Feb 24, 2026
1c91fa7
update navigation to display saved recipes link and logout button whe…
JeffieJansson Feb 24, 2026
a51279f
add title for diet filters and debug netlify deploy
JeffieJansson Feb 24, 2026
717b182
add redirect rule to serve index.html for all routes
JeffieJansson Feb 24, 2026
baf1b78
add dist folder in git ignore for deployment to netlify
JeffieJansson Feb 24, 2026
f39294e
Remove dist from git tracking
JeffieJansson Feb 24, 2026
e289d32
Add netlify.toml for correct build and publish directory
JeffieJansson Feb 24, 2026
4d3f654
Fix Netlify build: install frontend dependencies
JeffieJansson Feb 24, 2026
92bbe04
netlify debug
JeffieJansson Feb 24, 2026
8a4dccc
netlify debug
JeffieJansson Feb 24, 2026
3e1c385
Calculate matched and missed ingredients manually in backend, since S…
JeffieJansson Feb 25, 2026
050670d
Update ingredient display to use original names if available for matc…
JeffieJansson Feb 25, 2026
a252189
Refactor useRecipeActions to remove local filters state and use store…
JeffieJansson Feb 25, 2026
777edd6
Removed lactose-free filter since spoonacular complexSearch endpoint …
JeffieJansson Feb 26, 2026
2830bcf
Clean code
JeffieJansson Feb 26, 2026
11f9854
Refactor recipe search endpoint:
JeffieJansson Mar 1, 2026
cfecd42
move globalstyles to style folder
JeffieJansson Mar 1, 2026
65c606d
move globalstyles to style folder
JeffieJansson Mar 1, 2026
a697df9
update import from globalstyles
JeffieJansson Mar 1, 2026
5f82b4a
fix: improved layout with media query and styling
JeffieJansson Mar 1, 2026
14fede1
fix: add hasSearched state to manage search status, so error appears …
JeffieJansson Mar 1, 2026
ff6b981
fix: added filledIngredients parameter
JeffieJansson Mar 1, 2026
0754647
feat: add sourceUrl to recipeRoutes for the copy url button
JeffieJansson Mar 2, 2026
e5e0f37
install lucide-react
JeffieJansson Mar 2, 2026
e31b442
fix: remove unused code
JeffieJansson Mar 2, 2026
9952eb4
feat: add copy link function to RecipeCard
JeffieJansson Mar 2, 2026
bc008c2
feat: add loading spinner
JeffieJansson Mar 2, 2026
acf197c
fix: add unused code
JeffieJansson Mar 2, 2026
db34604
refactor: move copy and loading spinner to own components and import …
JeffieJansson Mar 2, 2026
ada70fc
fix: add loading lazy to improve score in lighthouse
JeffieJansson Mar 2, 2026
18c2c5e
fix: add meta description to improve score in lighthouse
JeffieJansson Mar 2, 2026
ad270f3
style: change RecipeCard, RecipeList, and SavedRecipes components layout
JeffieJansson Mar 2, 2026
3a0ea1b
refactor: app and member component to send user when logging in to ho…
JeffieJansson Mar 2, 2026
44012cf
fix: change colors to pass accessibility score in lighthouse
JeffieJansson Mar 2, 2026
d7a6c85
style: add styling to logout button in navigation menu
JeffieJansson Mar 2, 2026
7a29539
refactor: change design and content
JeffieJansson Mar 2, 2026
8a0eff0
fix: change colors to pass accessibility score in lighthouse
JeffieJansson Mar 2, 2026
2a583b3
fix: update colors to pass accissibility score in lighthouse and impr…
JeffieJansson Mar 2, 2026
876a334
fix: update colors for accessibility score and improve error handling
JeffieJansson Mar 2, 2026
5be16ac
fix: replaced clipboard copy functionality with navigator.share() as the
JeffieJansson Mar 3, 2026
be37c60
fix: removed summary from details and added addRecipeInstructions/ins…
JeffieJansson Mar 3, 2026
c7b77c6
fix: remove summary field from recipe schema and ensure analyzedInstr…
JeffieJansson Mar 3, 2026
e6a6db3
clean code: adding clearer comments, aria labels and variable names
JeffieJansson Mar 3, 2026
20bdb76
refactor: clean code structure, add variable helpers for more readabl…
JeffieJansson Mar 3, 2026
6113a49
fix: change name from cpy to share and size changes
JeffieJansson Mar 3, 2026
c96868d
remove /add space and comments
JeffieJansson Mar 5, 2026
33f6810
style: update color scheme for accessibility and improve comments for…
JeffieJansson Mar 5, 2026
eda83ba
refactor: consolidate API imports, update styles for improved readabi…
JeffieJansson Mar 5, 2026
87b2a27
feat: move and import empty state component and enhance recipe displa…
JeffieJansson Mar 5, 2026
00febd6
remove error in UI since button is disabled and user can never receiv…
JeffieJansson Mar 6, 2026
9f1d2ad
refactor: simplify input handling and update comments for clarity
JeffieJansson Mar 6, 2026
718396c
fix: remove unused logout function from user store since move to navi…
JeffieJansson Mar 6, 2026
68c6ecb
refactor: remove default value for mode in fetchRecipeByIngredients s…
JeffieJansson Mar 6, 2026
1d2b292
refactor: improve code readability and validation in recipe search an…
JeffieJansson Mar 6, 2026
f2c5f03
refactor: improve spacing and media query handling in
JeffieJansson Mar 6, 2026
35adf35
refactor: move EmptyState, ShareButton and LoadingSpinner components …
JeffieJansson Mar 8, 2026
1bd2e34
Add readme
JeffieJansson Mar 8, 2026
9e6a35e
remove old files
JeffieJansson Mar 8, 2026
f9c4fa1
Add react icons and update readme
JeffieJansson Mar 8, 2026
7889530
refactor: update styles to use CSS variables for consistency across c…
JeffieJansson Mar 8, 2026
4546e0d
refactor: improved styling and structure for more UI friendly look.
JeffieJansson Mar 8, 2026
72ee6b8
update readme
JeffieJansson Mar 8, 2026
a60c624
update readme
JeffieJansson Mar 8, 2026
ccdce08
refactor: adjust spacing and font sizes for improved responsiveness f…
JeffieJansson Mar 19, 2026
1fe4e8e
refactor: add focus to email input on load with useRef hook for Login…
JeffieJansson Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
# Ignore Vite/React build output
frontend/dist/
node_modules
.DS_Store
.env
Expand Down
22 changes: 16 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
# Final Project
# PantryMatch – Final Project

Replace this readme with your own information about your project.

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
PantryMatch is a web app that helps users find recipes based on the ingredients they already have at home. The assignment was to build a fullstack project with user authentication, recipe search, and a modern UI.

## The problem

Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
The challenge was choosing endpoint from Spoonacular adn deciding what parameters I want to use. In the beginning I struggled with making missing and matched ingredients visible. I tried to manually calculate at first, but after experimenting in postman I found the fillIngredients=true parameters that add information about the ingredients and whether they are used or missing in relation to the query. By using postman I solved the struggle and no unnecessary extra code for calculation was needed and also made my code more clean. So in the end I landed on the complex search endpoint

Technologies used:
- Backend: Node.js, Express, MongoDB, Mongoose, JWT
- Frontend: React, Vite, styled-components, react-icons

If I had more time, I would add:
- Autocomplete a partial input to suggest possible ingredient names.
- User profiles and recipe ratings
- Create an add to shopping list for ingredients
- Pagination or 'more recipes' button
- Have the save button stay as saved when re-render so when user searcher for recipes again, they can see if they have already saved the recipe. At the moment there's only an error.

## View it live

Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
The project is deployed here:
[https://pantrymatch.netlify.app/](https://pantrymatch.onrender.com/)
38 changes: 33 additions & 5 deletions backend/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,36 @@
# Backend part of Final Project
# PantryMatch Backend

This project includes the packages and babel setup for an express server, and is just meant to make things a little simpler to get up and running with.
This is the backend part of the PantryMatch project.
The server is built with Express and handles users, recipes, and authentication.
External API - Spoonacular

## Getting Started
## Structure

1. Install the required dependencies using `npm install`.
2. Start the development server using `npm run dev`.
- `server.js` – Main file for the Express server
- `routes/` – API routes for users and recipes
- `model/` – Mongoose models for User and Recipe
- `middleware/` – Middleware for authentication

## API Endpoints

### Users
- `POST /api/users/signup` – Create a new user
- `POST /api/users/login` – Log in a user

### Recipes
- `GET /api/recipes` – Get all recipes
- `POST /api/recipes` – Create a new recipe
- `GET /api/recipes/:id` – Get recipe by id

## Environment Variables

Using a `.env` file with :
```
MONGO_URL
Spoonacular API key
```

## Development

- Nodemon is used for automatic restarts
- All code is in ES6 modules
23 changes: 23 additions & 0 deletions backend/middleware/authMiddleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import User from "../model/User.js";

const authenticateUser = async (req, res, next) => {
try {
const user = await User.findOne({
accessToken: req.header("Authorization").replace("Bearer ", ""),
});
if (user) {
req.user = user;
next();
} else {
res.status(401).json({
message: "Authentication missing or invalid.",
loggedOut: true,
});
}
} catch (err) {
res
.status(500)
.json({ message: "Internal server error", error: err.message });
}
};
export default authenticateUser;
47 changes: 47 additions & 0 deletions backend/model/Recipe.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import mongoose from "mongoose";

const ingredientSchema = new mongoose.Schema({
name: String,
amount: Number,
unit: String,
original: String
}, { _id: false });

const recipeSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},

spoonacularId: {
type: Number,
required: true,
},
title: String,
image: String,
readyInMinutes: Number,
servings: Number,
extendedIngredients: [ingredientSchema], // detailed ingredient info from Spoonacular
instructions: String, // HTML or plain text from Spoonacular
createdAt: {
type: Date,
default: Date.now,
},

analyzedInstructions: [
{
name: String,
steps: [
{
number: Number,
step: String
}
]
}
],
});

const Recipe = mongoose.model("Recipe", recipeSchema);

export default Recipe;
24 changes: 24 additions & 0 deletions backend/model/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import mongoose, { Schema } from "mongoose";
import crypto from "crypto";

const userSchema = new Schema({
email: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
required: true,
minlength: 6,
},
accessToken: {
type: String,
required: true,
default: () => crypto.randomBytes(128).toString("hex"),
},
})

const User = mongoose.model("User", userSchema);

export default User;
17 changes: 12 additions & 5 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,22 @@
"start": "babel-node server.js",
"dev": "nodemon server.js --exec babel-node"
},
"author": "",
"license": "ISC",
"author": "",
"type": "commonjs",
"main": "server.js",
"dependencies": {
"@babel/core": "^7.17.9",
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
"axios": "^1.13.5",
"bcrypt": "^6.0.0",
"cors": "^2.8.5",
"express": "^4.17.3",
"mongoose": "^8.4.0",
"nodemon": "^3.0.1"
"dotenv": "^17.2.3",
"express": "^4.22.1",
"express-list-endpoints": "^7.1.1",
"mongodb": "^7.0.0",
"mongoose": "^9.1.5",
"nodemon": "^3.1.11"
}
}
}
Loading