Skip to content

Charan8x/Cookbook-Virtual-Cooking-Assistant

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🍽️ CookBook — Virtual Kitchen Assistant

A full-stack MERN web application for discovering, creating, and managing recipes

React Node.js Express MongoDB JWT TailwindCSS


CookBook Banner


CookBook is a modern recipe discovery and management platform where users can explore 166+ recipes across 8 cuisines, save their favourites, create their own recipes, and watch video tutorials — all in one place.

FeaturesTech StackGetting StartedAPI ReferenceProject StructureScreenshots


✨ Features

  • 🔐 JWT Authentication — Secure register, login, and protected routes
  • 🔍 Smart Search — Search recipes by name, ingredient, cuisine, or tag
  • 🎛️ Filters — Filter by cuisine type and difficulty level with pagination
  • 📖 166+ Recipes — Pre-loaded dataset covering 8 world cuisines
  • ❤️ Favourites — Save and manage your favourite recipes
  • ✏️ Full CRUD — Create, edit, and delete your own recipes
  • 🎬 YouTube Integration — Every recipe links directly to a YouTube tutorial
  • 🌙 Dark Mode — Full dark/light mode toggle
  • 📊 Nutrition Info — Calories, protein, carbs, and fat per serving
  • Ingredient Checklist — Tick off ingredients while you cook
  • 📱 Fully Responsive — Works on mobile, tablet, and desktop

🛠️ Tech Stack

Frontend

Technology Purpose
React 18 + Vite UI framework and build tool
Tailwind CSS Utility-first styling
React Router DOM Client-side routing
Axios HTTP requests to the backend
React Context API Global state management (auth, theme)
React Toastify Toast notifications
React Icons Icon library

Backend

Technology Purpose
Node.js JavaScript runtime
Express.js Web framework and REST API
MongoDB NoSQL database
Mongoose ODM for schema design and queries
JSON Web Token Stateless authentication
bcryptjs Password hashing
express-validator Input validation
dotenv Environment variable management
cors Cross-origin request handling
nodemon Auto-restart during development

🏗️ Architecture

┌─────────────────────────────────────────┐
│              React Frontend             │
│     (Vite + Tailwind + Context API)     │
└──────────────────┬──────────────────────┘
                   │  HTTP / REST API
                   │  (Axios + JWT Token)
┌──────────────────▼──────────────────────┐
│             Express Backend             │
│                                         │
│  Route → Middleware → Controller        │
│              ↓                          │
│         Mongoose ODM                    │
└──────────────────┬──────────────────────┘
                   │
┌──────────────────▼──────────────────────┐
│               MongoDB                   │
│   users │ recipes │ favorites           │
└─────────────────────────────────────────┘

Request Flow

Client Request
    → Express Router (matches URL)
    → Middleware (CORS, JSON parse, Auth check)
    → Controller (business logic)
    → Mongoose (database query)
    → Response (JSON with status code)

📁 Project Structure

cookbook/
│
├── start.js                    # Single command to run everything
├── package.json                # Root scripts
│
├── backend/
│   ├── server.js               # Express app, middleware, DB connection
│   ├── seed.js                 # Seeds 166 recipes into the database
│   ├── .env                    # Environment variables (not committed)
│   ├── package.json
│   │
│   ├── config/
│   │   └── db.js               # MongoDB connection
│   │
│   ├── models/
│   │   ├── User.js             # User schema (bcrypt pre-save hook)
│   │   ├── Recipe.js           # Recipe schema (text index for search)
│   │   └── Favorite.js         # Favorite schema (unique compound index)
│   │
│   ├── controllers/
│   │   ├── auth.controller.js      # register, login, getMe
│   │   ├── recipe.controller.js    # CRUD + search + pagination
│   │   ├── favorite.controller.js  # add, remove, list favorites
│   │   └── user.controller.js      # profile, change password
│   │
│   ├── routes/
│   │   ├── auth.routes.js
│   │   ├── recipe.routes.js
│   │   ├── favorite.routes.js
│   │   └── user.routes.js
│   │
│   └── middleware/
│       └── auth.middleware.js   # JWT protect + adminOnly
│
└── frontend/
    ├── index.html
    ├── vite.config.js           # Proxy /api → localhost:5000
    ├── tailwind.config.js
    ├── postcss.config.js
    ├── package.json
    │
    └── src/
        ├── main.jsx
        ├── App.jsx              # Router setup + ThemeProvider
        ├── index.css            # Tailwind imports + dark mode overrides
        │
        ├── context/
        │   ├── AuthContext.jsx  # Global auth state (user, token, login, logout)
        │   └── ThemeContext.jsx # Dark/light mode toggle
        │
        ├── services/
        │   ├── api.js           # Axios instance with auto JWT header
        │   └── recipeService.js # All API call functions
        │
        ├── routes/
        │   └── PrivateRoute.jsx # Redirects unauthenticated users
        │
        ├── components/
        │   ├── Navbar.jsx       # Responsive navbar with dropdown + dark toggle
        │   ├── RecipeCard.jsx   # Recipe card with YouTube link + save button
        │   ├── RecipeForm.jsx   # Shared form for create and edit
        │   ├── SearchBar.jsx    # Search input with quick-filter tags
        │   └── Spinner.jsx      # Loading indicator
        │
        └── pages/
            ├── Home.jsx         # Browse, search, filter, paginate recipes
            ├── Login.jsx
            ├── Register.jsx
            ├── RecipeDetail.jsx # Full recipe view with YouTube + checklist
            ├── CreateRecipe.jsx
            ├── EditRecipe.jsx
            ├── Favorites.jsx
            ├── MyRecipes.jsx
            ├── Profile.jsx      # Edit profile + change password
            └── NotFound.jsx

🚀 Getting Started

Prerequisites

Make sure you have the following installed:

Installation & Running

Step 1 — Clone the repository

git clone https://github.com/yourusername/cookbook.git
cd cookbook

Step 2 — Configure environment variables

Open backend/.env and update the values:

PORT=5000
MONGO_URI=mongodb://localhost:27017/cookbook
JWT_SECRET=your_super_secret_key_here
JWT_EXPIRES_IN=7d
NODE_ENV=development

If using MongoDB Atlas, replace MONGO_URI with your Atlas connection string: mongodb+srv://username:password@cluster0.xxxxx.mongodb.net/cookbook

Step 3 — Install all dependencies (one command)

npm run install:all

Step 4 — Start the entire application (one command)

node start.js

This single command will:

  1. ✅ Start the backend server on port 5000
  2. ✅ Seed 166 recipes from the dataset into MongoDB
  3. ✅ Start the frontend on port 5173

Step 5 — Open in browser

http://localhost:5173

Press Ctrl + C to stop everything.


📡 API Reference

Base URL

http://localhost:5000/api

Authentication Endpoints

Method Endpoint Access Description
POST /auth/register Public Register a new user
POST /auth/login Public Login and receive JWT token
GET /auth/me Private Get current logged-in user

Recipe Endpoints

Method Endpoint Access Description
GET /recipes Public Get all recipes (search, filter, paginate)
GET /recipes/:id Public Get single recipe by ID
GET /recipes/my-recipes Private Get recipes created by logged-in user
POST /recipes Private Create a new recipe
PUT /recipes/:id Private (Owner) Update a recipe
DELETE /recipes/:id Private (Owner) Delete a recipe

Query Parameters for GET /recipes:

?search=pasta          → search by name, ingredient, tag, cuisine
?cuisine=Italian       → filter by cuisine
?difficulty=Easy       → filter by difficulty
?page=1&limit=9        → pagination

Favorites Endpoints

Method Endpoint Access Description
GET /favorites Private Get all saved recipes
POST /favorites/:recipeId Private Save a recipe
DELETE /favorites/:recipeId Private Remove from favorites

User Endpoints

Method Endpoint Access Description
GET /users/profile Private Get user profile
PUT /users/profile Private Update name and bio
PUT /users/change-password Private Change password

Example Request (Authenticated)

# Add Authorization header with Bearer token
curl -X GET http://localhost:5000/api/recipes/my-recipes \
  -H "Authorization: Bearer YOUR_JWT_TOKEN_HERE"

Example Response

{
  "success": true,
  "total": 3,
  "pages": 1,
  "recipes": [
    {
      "_id": "64abc123...",
      "title": "Butter Chicken",
      "cuisine": "Indian",
      "difficulty": "Medium",
      "cookingTime": 45,
      "nutrition": {
        "calories": 420,
        "protein": "32g",
        "carbs": "14g",
        "fat": "24g"
      },
      "createdBy": {
        "_id": "64xyz789...",
        "name": "Sai"
      }
    }
  ]
}

🗄️ Database Schema

User

{
  name:      String (required),
  email:     String (required, unique),
  password:  String (hashed with bcrypt, hidden from responses),
  bio:       String,
  role:      String (enum: 'user', 'admin'),
  createdAt: Date
}

Recipe

{
  title:       String (required),
  description: String,
  image:       String (URL),
  cuisine:     String (enum: Indian, Italian, Mexican...),
  difficulty:  String (enum: Easy, Medium, Hard),
  cookingTime: Number (minutes),
  servings:    Number,
  ingredients: [{ name: String, quantity: String }],
  steps:       [{ stepNumber: Number, instruction: String }],
  tags:        [String],
  nutrition:   { calories, protein, carbs, fat },
  createdBy:   ObjectId  ref: User,
  isPublic:    Boolean,
  createdAt:   Date
}

Favorite

{
  userId:    ObjectId  ref: User,
  recipeId:  ObjectId  ref: Recipe,
  createdAt: Date
}
// Unique compound index on { userId, recipeId }
// Prevents duplicate saves

🔒 Authentication Flow

1. User registers → password hashed with bcrypt (12 salt rounds)
                 → user saved to MongoDB
                 → JWT token generated and returned

2. User logs in  → password compared with bcrypt.compare()
                 → JWT token generated (expires in 7 days)
                 → token stored in localStorage on frontend

3. Protected request → Axios sends token in Authorization header
                     → protect middleware extracts and verifies token
                     → user fetched from DB and attached to req.user
                     → controller executes with req.user available

4. Token invalid/expired → 401 Unauthorized response
                         → frontend redirects to /login

🍱 Recipe Dataset

The application comes pre-loaded with 166 recipes across 8 cuisines:

Cuisine Count
Mediterranean 39
Italian 18
American 17
Indian 13
Japanese 9
Mexican 10
Chinese 8
Thai 6
Other (World) 46

Each recipe includes detailed descriptions, step-by-step instructions, ingredient lists, nutrition values, and a direct YouTube search link.


👥 Team

Member Role
Member 1 Backend & API Design Engineer
Member 2 Authentication & Security Engineer
Member 3 Database & Data Modeling Engineer
Member 4 Frontend Architecture & State Management
Member 5 UI/UX & Feature Implementation

📄 License

This project is built for academic purposes as part of a Full Stack Web Development course.


Made with ❤️ using the MERN Stack

⭐ Star this repo if you found it helpful!

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages