Foodie App
Table of contents
- MERN Stack Application Documentation
- Setting Up a MERN App - Creating "Foodie" React App
- Integrating Bootstrap Dark Theme into "Foodie" React App
- Foodie React App Component Documentation
- Foodie React App with React Router Documentation
- Integrating the Card Component in the "Foodie" React App
- Enhanced "Foodie" React App Component Documentation
- Importing JSON Data into MongoDB Cloud
- Setting Up Backend for "Foodie" App
- User Login and Data Management - Backend Documentation
- User Registration Validation - Backend Documentation
MERN Stack Application Documentation
Foodie Website Documentation
This comprehensive documentation provides an in-depth overview of the "Foodie" website project, explaining its purpose, features, technologies used, and providing research-backed examples to showcase its capabilities.
MERN Stack Overview:
The MERN stack is a popular combination of technologies used for building modern web applications. It stands for:
MongoDB: A NoSQL database that stores data in a flexible, JSON-like format.
Express.js: A backend web application framework for building APIs and handling server-side logic.
React: A JavaScript library for building dynamic and responsive user interfaces.
Node.js: A runtime environment that enables server-side JavaScript execution.
Benefits of the MERN-based Food Ordering Website:
Modular Development: The MERN stack promotes modular development, allowing developers to break down complex applications into smaller components. This leads to better code organization and maintainability.
Full Stack Consistency: Since both frontend and backend are built using JavaScript, there's a seamless transition between different parts of the application. This streamlines development and reduces the learning curve for developers.
Real-time Interaction: React's component-based architecture enables real-time updates on the user interface without the need to refresh the page. This results in a smooth and interactive user experience.
Efficient State Management: React's state management, coupled with the use of Context and Reducer in this project, ensures efficient management of application state, making it easier to handle dynamic changes and updates.
Responsive Design: React's component-driven approach and Material-UI's responsive components allow the website to adapt to various screen sizes and devices, ensuring a consistent user experience.
Scalability: MERN-based applications are highly scalable. As user demand increases, the backend can be easily scaled by deploying more instances of the Node.js server and MongoDB database.
Rich UI: React's component library and Material-UI's pre-designed components allow for the creation of visually appealing and user-friendly interfaces. This enhances the overall aesthetic of the website.
NoSQL Database: MongoDB's flexible document-based structure allows for efficient storage and retrieval of data, making it well-suited for applications with varying data types and structures.
Rapid Development: The MERN stack's reusable components, libraries, and frameworks significantly speed up the development process, enabling faster time-to-market for the application.
Cross-Platform Compatibility: The MERN stack supports the development of cross-platform applications, ensuring that the website functions seamlessly on different operating systems and devices.
Community Support: All four components of the MERN stack have active and large communities, resulting in a wealth of online resources, tutorials, and forums for troubleshooting and learning.
Conclusion:
The MERN-based food ordering website exemplifies the power of the MERN stack in creating feature-rich, scalable, and interactive web applications. The combined strengths of MongoDB, Express.js, React, and Node.js enable developers to build dynamic user interfaces, handle server-side logic, manage data efficiently, and deliver an exceptional user experience. The modular nature of the stack and the benefits outlined above make the MERN stack a compelling choice for modern web application development.
Setting Up a MERN App - Creating "Foodie" React App
This documentation will guide you through the process of setting up a MERN (MongoDB, Express.js, React, Node.js) stack project. You'll create a React application named "Foodie" and visualize the setup in Visual Studio Code and your web browser.
Step 1: Create Project Directory
Create a Folder: Open your terminal and navigate to the directory where you want to create your MERN project.
Create Project Folder: Run the following command to create a directory for your MERN app:
mkdir MernApp
Navigate to Project Directory: Use the
cd
command to navigate into the newly created directory:cd MernApp
Step 2: Setting Up React App
Create React App: Run the following command to create a new React application named "Foodie":
npx create-react-app foodie
Step 3: Visualize Setup
Open Visual Studio Code: Open Visual Studio Code (VS Code) and navigate to the "MernApp" folder. You can do this by using the
File > Open Folder
option.Explore Project Structure: Inside the "MernApp" folder, you should have the "foodie" folder (your React app) and any other files or folders you've created.
Open React App in VS Code: Open the "foodie" folder in VS Code to work on your React app.
Terminal Integration: Use the integrated terminal in VS Code to execute commands without leaving the editor.
Step 4: Start Development Server
Navigate to React App Directory: In the integrated terminal of VS Code, navigate to your React app's directory:
cd foodie
Start Development Server: Run the following command to start the development server:
npm start
View in Browser: Open your web browser and go to http://localhost:3000. You should see your "Foodie" React app running.
Step 5: Verify Setup
VS Code: You can now work on your React app's source code in VS Code, making changes and watching them reflect in the browser.
Browser View: Compare your React app in the browser with the one displayed in VS Code. The content should match.
Conclusion
You've successfully set up your MERN stack project by creating a "Foodie" React app. You've visualized the project setup in Visual Studio Code and verified the app's functionality in the web browser. Now you can begin developing your app's user interface, adding components, and integrating backend functionality using the Express.js and MongoDB parts of the MERN stack.
Integrating Bootstrap Dark Theme into "Foodie" React App
In this section, we will guide you through the process of integrating the Bootstrap Dark Theme into your "Foodie" React app. The Bootstrap Dark Theme provides a visually appealing dark mode interface for your application.
Step 1: Adding Bootstrap Dark Theme CSS
Get Bootstrap Dark Theme CSS: Visit the Bootstrap Dark Theme GitHub Page to access the theme's documentation.
Copy the CSS Link: From the documentation, locate the following line of code:
<!-- Add the Bootstrap-Nightfall Variant CSS (the media attribute is for dark auto-switching) --> <link href="https://cdn.jsdelivr.net/npm/bootstrap-dark-5@1.1.3/dist/css/ bootstrap-nightfall.min.css" rel="stylesheet" media="(prefers-color-scheme: dark)">
Add CSS Link to
index.html
: Open thepublic/index.html
file of your React app (foodie/public/index.html
). Within the<head>
section, paste the copied link to include the Bootstrap Dark Theme CSS:<!DOCTYPE html> <html lang="en"> <head> <!-- ...other meta tags and stylesheets... --> <!-- Replace the Bootstrap CSS with the Bootstrap-Dark Variant CSS --> <link href="https://cdn.jsdelivr.net/npm/bootstrap-dark-5@1.1.3 /dist/css/bootstrap-dark.min.css" rel="stylesheet"> <!-- ... --> </head> <body> <div id="root"></div> </body> </html>
Step 2: Update the Title and Test the Dark Theme
Update Title: While you're in the
public/index.html
file, make sure to update the<title>
tag to reflect the title of your app:<title>Foodie App</title>
Save Changes: Save the
index.html
file.
Step 3: Preview the Dark Theme
Start the Development Server: Make sure your development server is still running. If not, run:
npm start
Open the App in Browser: Your React app will open automatically in your browser.
Inspect the Dark Theme: With the Bootstrap Dark Theme CSS added, you should see your "Foodie" app with the dark-themed styling. The Bootstrap Dark Theme CSS should apply automatically if your system's color scheme is set to dark.
Screenshots
Browser Preview with Bootstrap Dark Theme:
Conclusion
You have successfully integrated the Bootstrap Dark Theme into your "Foodie" React app. Your app's UI should now showcase the visually pleasing dark mode interface. Feel free to explore further customizations and adapt the styling according to your project's needs. Happy coding!
Foodie React App Component Documentation
This documentation provides a guide for setting up reusable components and creating the home screen for the "Foodie" React app. It covers the creation of the Navbar.js
component, multiple reusable components within the components
folder, and the assembly of these components in the Home.js
screen.
Step 1: Organizing Components
Creating the components
Folder
- Create the
components
Directory: In your app'ssrc
directory, create a folder namedcomponents
to store reusable React components.
Creating Navbar.js
Navigate to
src/components
: Open your terminal and navigate to thecomponents
directory:cd path/to/foodie/src/components
Create
Navbar.js
: Create a new file namedNavbar.js
and add the following code:// Navbar.js import React from 'react'; export default function Navbar() { return ( <div> {/* Paste the provided Navbar code here */} </div> ); }
Step 2: Creating the Home Screen
Creating Home.js
Navigate to
src/screens
: In your terminal, navigate to thesrc
directory and create a folder namedscreens
:cd path/to/foodie/src mkdir screens
Navigate to
screens
Directory: Change into thescreens
directory:cd screens
Create
Home.js
: Create a new file namedHome.js
and add the following code:// Home.js import React from 'react'; import Navbar from "../components/Navbar"; // Import the Navbar component export default function Home() { return ( <div> <Navbar /> {/* Use the Navbar component */} <div>Body</div> </div> ); }
Step 3: Integrating Components
Updating App.js
Navigate to
src
: Return to thesrc
directory:cd path/to/foodie/src
Edit
App.js
: Open theApp.js
file and add the following code:// App.js import React from 'react'; import Home from "./screens/Home"; // Import the Home screen function App() { return ( <div> <Home /> {/* Use the Home screen */} </div> ); } export default App;
Conclusion
You have successfully organized your components by creating a components
folder, creating the Navbar.js
and Home.js
components, and integrating them into the main App.js
file. This documentation covered the initial setup of reusable components and assembling them into a basic home screen.
In the next steps, you will learn about implementing React Router to enable smooth navigation within your app without page refreshes. This will transform your app into a Single Page Application (SPA).
Next Steps
To enhance your app's navigation and make it a Single Page Application (SPA), follow the next steps in your documentation. These steps will guide you through the implementation of React Router for seamless navigation.
Foodie React App with React Router Documentation
In this updated documentation, we'll go over the steps to integrate React Router into the "Foodie" React app for creating a Single Page Application (SPA). Additionally, we'll make modifications to the Navbar and improve its appearance and functionality.
Step 1: Installing React Router
Install React Router Dom: In your terminal, install the
react-router-dom
package:npm install react-router-dom
Step 2: Integrating React Router
Update App.js
Import React Router Components: Import the required components from
react-router-dom
:import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
Update App Component: Wrap your app content with the
Router
component and define routes using theRoutes
andRoute
components:function App() { return ( <Router> <div> <Routes> <Route path="/" element={<Home />} /> {/* Add more routes as needed */} </Routes> </div> </Router> ); }
Update Navbar.js
Update Navbar Component: Update the Navbar component to use the
Link
component fromreact-router-dom
for navigation:// Navbar.js import React from 'react'; import { Link } from 'react-router-dom'; export default function Navbar() { return ( <div> <nav className="navbar navbar-expand-lg navbar-dark bg-success"> <div className="container-fluid"> <Link className="navbar-brand fs-1 fst-italic" to="/">Foodie</Link> <button className="navbar-toggler" type="button" data-bs-toggle= "collapse" data-bs-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation"> <span className="navbar-toggler-icon"></span> </button> <div className="collapse navbar-collapse" id="navbarNav"> <ul className="navbar-nav"> <li className="nav-item"> <Link className="nav-link active" aria-current="page" to="/">Home</Link> </li> <li className="nav-item"> <Link className="nav-link" to="/login">Login</Link> </li> </ul> </div> </div> </nav> </div> ); }
Step 3: Create the Login Page
Create
Login.js
: Create a new file namedLogin.js
inside thescreens
folder and implement the Login component.Define Route for Login: In
App.js
, add a newRoute
for theLogin
component:<Route path="/login" element={<Login />} />
Additional Changes
Styling Changes in
index.css
: Update the body's font-family and make necessary styling adjustments.Modify
public/index.html
: Add a font stylesheet link to the<head>
section.
Conclusion
You have successfully integrated React Router into your "Foodie" React app, transforming it into a Single Page Application (SPA). The Navbar has been updated to include navigation links that navigate without page reloading, resulting in a seamless user experience. The Login page has also been introduced, and you have made additional styling improvements.
Your app is now ready for further development, adding more pages, and enhancing its functionality. Enjoy building your SPA with React Router!
Integrating the Card Component in the "Foodie" React App
In this documentation, we'll guide you through the process of creating and integrating the Card.js
component into the "Foodie" React app's Home.js
screen. The Card.js
component will display a card with customizable details and options.
Step 1: Creating the Card Component
Create Card.js
Navigate to
src/components
: Open your terminal and navigate to thecomponents
directory:cd path/to/foodie/src/components
Create
Card.js
: Create a new file namedCard.js
and add the following code:// Card.js import React from 'react'; export default function Card() { return ( <div> <div className="card mt-3" style={{ "width": "18rem", maxHeight: "360px" }}> <img src="..." className="card-img-top" alt="..." /> <div className="card-body"> <h5 className="card-title">Card title</h5> <p className="card-text">It is some important text</p> <div className="container w-100"> <select className='m-2 h-100 bg-success rounded'> {Array.from(Array(6), (e, i) => ( <option key={i + 1} value={i + 1}>{i + 1}</option> ))} </select> <select className='m-2 h-100 bg-success rounded'> <option value="half" key="">Half</option> <option value="full" key="">Full</option> </select> <div className="d-inline h-100 fs-5"> Total Price </div> </div> </div> </div> </div> ); }
Step 2: Integrating the Card Component
Update Home.js
Navigate to
src/screens
: In your terminal, navigate to thesrc
directory and then thescreens
directory:cd path/to/foodie/src/screens
Edit
Home.js
: Open theHome.js
file and add the following code to import and use theCard
component:// Home.js import React from 'react'; import Navbar from "../components/Navbar"; import Card from "../components/Card"; // Import the Card component import Footer from "../components/Footer"; export default function Home() { return ( <div> <div><Navbar /></div> <div><Card /></div> {/* Use the Card component */} <div><Footer /></div> </div> ); }
Conclusion
You have successfully created and integrated the Card.js
component into the Home.js
screen of your "Foodie" React app. The Card
component displays a customizable card with various options.
In the upcoming sections, you will explore how to populate these cards with data from your backend, making them dynamic and interactive.
Your app is now equipped with a basic card component, and you can continue building upon this foundation to create a rich user experience.
Preview
Here's how the integrated Card
component might appear in your app's Home
screen:
Enhanced "Foodie" React App Component Documentation
In this updated documentation, we have made several improvements to your "Foodie" React app, including the creation of new components (Footer.js
, Carousel.js
) and enhancements to existing components (Card.js
, Home.js
). Additionally, we've added some styles to the index.css
file and installed necessary packages.
Step 1: Creating New Components
Footer.js
Create the
Footer.js
Component: We have created a newFooter.js
component that provides a footer section with a link to the homepage. It is designed to enhance the overall appearance and user experience of your app.// Footer.js import React from 'react'; import { Link } from "react-router-dom"; export default function Footer() { return ( <footer className="d-flex flex-wrap justify-content-between align-items-center py-3 my-4 border-top"> <div className="col-md-4 d-flex align-items-center"> <Link to="/" className="mb-3 me-2 mb-md-0 text-muted text-decoration-none lh-1"> <svg className="bi" width="30" height="24"></svg> </Link> <span className="text-muted">© August 2023 Foodie, Inc</span> </div> <ul className="nav col-md-4 justify-content-end list-unstyled d-flex"> </ul> </footer> ) }
Carousel.js
Create the
Carousel.js
Component: We have created a newCarousel.js
component that displays an image carousel with a search bar. This enhances the visual appeal and interactivity of your app.// Carousel.js import React from 'react'; export default function Carousel() { return ( <div id="carouselExampleFade" className="carousel slide carousel-fade" data-bs-ride="carousel" style={{ objectFit: "contain !important" }}> <div className="carousel-inner " id="carousel"> <div className="carousel-caption" style={{ zIndex: "10" }}> <form className="d-flex"> <input className="form-control me-2" type="search" placeholder="Search" aria-label="Search" /> <button className="btn btn-outline-success text-white bg-success" type="submit">Search</button> </form> </div> <div className="carousel-item active"> <img src="https://source.unsplash.com/random/900x700/?burger" className="d-block w-100" style={{ filter: "brightness(30%" }} alt="..." /> </div> <div className="carousel-item"> <img src="https://source.unsplash.com/random/900x700/?pizza" className="d-block w-100" style={{ filter: "brightness(30%" }} alt="..." /> </div> <div className="carousel-item"> <img src="https://source.unsplash.com/random/900x700/?chowmein" className="d-block w-100" style={{ filter: "brightness(30%" }} alt="..." /> </div> </div> <button className="carousel-control-prev" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="prev"> <span className="carousel-control-prev-icon" aria-hidden="true"></span> <span className="visually-hidden">Previous</span> </button> <button className="carousel-control-next" type="button" data-bs-target="#carouselExampleFade" data-bs-slide="next"> <span className="carousel-control-next-icon" aria-hidden="true"></span> <span className="visually-hidden">Next</span> </button> </div> ) }
Step 2: Integrating Components
Update Home.js
Integrate New Components: We have integrated the new
Carousel
and enhancedCard
components into yourHome.js
screen. This enriches the home page with a dynamic image carousel and customizable cards.// Home.js import React from 'react'; import Navbar from "../components/Navbar"; import Carousel from "../components/Carousel"; // Import the Carousel component import Card from "../components/Card"; // Enhance the Card component import Footer from "../components/Footer"; export default function Home() { return ( <div> <div><Navbar /></div> <div><Carousel /></div> {/* Use the Carousel component */} <div className="m-4"><Card /></div> {/* Enhanced Card component */} <div><Footer /></div> </div> ); }
Step 3: Styling Enhancements
Update index.css
Enhance Styling: We have added a new style rule to the
index.css
file to ensure the carousel images have a maximum height, enhancing their display./* index.css */ #carousel { max-height: 500px; }
Conclusion
You have successfully added new components (Footer.js
, Carousel.js
) to your "Foodie" React app, enhanced the existing Card.js
component, and integrated them into the Home.js
screen. Additionally, you've made styling improvements using CSS.
With these enhancements, your app now offers a visually appealing and interactive user experience, making it more engaging for users.
Importing JSON Data into MongoDB Cloud
In this documentation, we will go over the steps to successfully import JSON files into your MongoDB Cloud database using the mongoimport
command.
Step 1: Prepare Your JSON Files
- Prepare JSON Files: Make sure you have the JSON files you want to import ready. In your case, you have the
foodCategory.json
andfoodData2.json
files containing data for your "Foodie" app.
Step 2: MongoDB Connection URI
MongoDB Connection URI: You will need the MongoDB connection URI for your database to perform the import. Your connection URI will look similar to the ones you provided:
mongodb+srv://<username>:<password>@<cluster>.mongodb.net/<database>
Replace
<username>
,<password>
,<cluster>
, and<database>
with your actual credentials and database details.
Step 3: Execute mongoimport
Command
- Execute
mongoimport
Command: Open your terminal or command prompt and run the followingmongoimport
commands to import the JSON files into your MongoDB Cloud database:
Import foodCategory.json
Replace <connection-uri>
with your actual MongoDB connection URI and <path-to-json>
with the actual path to your foodCategory.json
file.
mongoimport --uri <connection-uri> --collection foodCategory --jsonArray --file "<path-to-json>"
Example:
mongoimport --uri mongodb+srv://kc90040:NpCO7camfOxUcmYk@foodie.az4dnxx.mongodb.net/foodie --collection foodCategory --jsonArray --file "C:\Users\kapil chaudhary\OneDrive\Desktop\Mern App\foodie\backend\foodCategory.json"
Import foodData2.json
Replace <connection-uri>
with your actual MongoDB connection URI and <path-to-json>
with the actual path to your foodData2.json
file.
mongoimport --uri <connection-uri> --collection food_items --jsonArray --file "<path-to-json>"
Example:
mongoimport --uri mongodb+srv://kc90040:NpCO7camfOxUcmYk@foodie.az4dnxx.mongodb.net/foodie --collection food_items --jsonArray --file "C:\Users\kapil chaudhary\OneDrive\Desktop\Mern App\foodie\backend\foodData2.json"
The provided JSON data contains categories and food items for your "Foodie" app. Here's how you can use this data within your React app:
- Categories Data (foodCategory):
[
{
"CategoryName": "Biryani/Rice"
},
{
"CategoryName": "Starter"
},
{
"CategoryName": "Pizza"
}
]
- Food Items Data (food_items):
[
{
"CategoryName": "Biryani/Rice",
"name": "Chicken Fried Rice",
"img": "...",
"options": [
{
"half": "130",
"full": "220"
}
],
"description": "..."
},
{
// Other food items...
}
]
You can use this data to dynamically render your app's components based on the categories and food items. Here's a high-level guide on how you might use this data:
Rendering Categories: Use the
foodCategory
data to render category links or buttons. You can map through the array and generate buttons or links for each category.Rendering Food Items: Use the
food_items
data to render food items within their respective categories. For example, you can filter the food items based on the selected category and map through the filtered array to render the food cards.Dynamic Rendering: Depending on the selected category, you can update the displayed food items accordingly. This can be achieved using state management or context in React.
Components: You might have components like
CategoryList
,FoodItem
,FoodCard
, etc., to encapsulate the rendering logic and make your code more modular and maintainable.
Remember that this is a high-level overview, and the actual implementation might involve more details and considerations based on your app's structure and design.
Please let me know if you need further assistance or guidance on implementing specific parts of your app using this data!
Conclusion
You have successfully imported JSON data into your MongoDB Cloud database using the mongoimport
command. This process allows you to populate your collections with data that will be used by your "Foodie" app.
Setting Up Backend for "Foodie" App
In this documentation, we will guide you through setting up the backend for your "Foodie" app using Node.js, Express, and MongoDB. We'll cover creating the backend folder, initializing the project, installing dependencies, establishing a MongoDB connection, and creating a simple server.
Step 1: Create Backend Folder
- Create Backend Folder: Inside your "Foodie" project directory, create a new folder named
backend
.
Step 2: Initialize Project and Install Dependencies
- Initialize Project and Install Dependencies: Open your terminal and navigate to the
backend
folder. Run the following commands:
cd backend
npm init
Follow the prompts to initialize the project. Then, install the required dependencies:
npm install express nodemon mongoose
Step 3: Create MongoDB Connection
- Create MongoDB Connection: Inside the
backend
folder, create a file nameddb.js
. Add the following code to establish a connection to your MongoDB Atlas cluster:
const mongoose = require('mongoose');
const mongoURI = "mongodb+srv://kc90040:NpCO7camfOxUcmYk@foodie.az4dnxx.mongodb.net/foodie?retryWrites=true&w=majority";
const mongoDB = async () => {
try {
await mongoose.connect(mongoURI, { useNewUrlParser: true });
console.log("Connected to MongoDB");
const fetched_data = await mongoose.connection.db.collection("food_items");
const data = await fetched_data.find({}).toArray();
console.log("Fetched Data:", data);
} catch (err) {
console.error("Error connecting to MongoDB:", err.message);
}
};
module.exports = mongoDB;
Replace <username>
, <password>
, <cluster>
, and <database>
with your actual MongoDB Atlas credentials and database details.
Step 4: Create Express Server
- Create Express Server: In the
backend
folder, create a file namedindex.js
. Add the following code to set up a basic Express server and connect to MongoDB:
// index.js
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;
const mongoDB = require("./db");
// Connect to MongoDB
mongoDB();
app.get('/', (req, res) => {
res.send('Hello World from Foodie Backend!');
});
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Step 5: Run the Server
- Run the Server: In your terminal, make sure you are in the
backend
folder and run the server using the following command:
npm run start
Your backend server will start running on the specified port (default is 5000). You should see the message "Server is running on port 5000" in the console.
Conclusion
Congratulations! You have successfully set up the backend for your "Foodie" app using Node.js, Express, and MongoDB. The server is now running and connected to your MongoDB Atlas database.
User Login and Data Management - Backend Documentation
In this documentation, we will cover the process of implementing user login functionality and data management using Node.js, Express, and MongoDB for your "Foodie" app's backend. We will guide you through creating user models, setting up routes for user registration, and updating the database.
Step 1: User Model
- User Model: Inside the
models
folder in yourbackend
, create a file namedUser.js
. This file will define the schema for your user data.
// User.js
const mongoose = require('mongoose');
const { Schema } = mongoose;
const UserSchema = new Schema({
name: {
type: String,
required: true,
},
location: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
date: {
type: Date,
default: Date.now,
},
});
module.exports = mongoose.model('user', UserSchema);
Step 2: User Registration Route
- User Registration Route: Create a new route for user registration in the
Routes
folder. Name the fileCreateUser.js
.
// CreateUser.js
const express = require('express');
const router = express.Router();
const User = require('../models/User');
router.post("/createuser", async (req, res) => {
try {
await User.create({
name: req.body.name,
password: req.body.password,
email: req.body.email,
location: req.body.location,
});
res.json({ success: true });
} catch (error) {
console.log(error);
res.json({ success: false });
}
});
module.exports = router;
Step 3: Connect to MongoDB and Implement Routes
- Connect to MongoDB and Implement Routes: In your
db.js
file, update the code to include your user registration route and connect to MongoDB.
// db.js
const mongoose = require('mongoose');
const mongoURI = "mongodb+srv://<username>:<password>@<cluster>.mongodb.net/<database>?retryWrites=true&w=majority";
const mongoDB = async () => {
try {
await mongoose.connect(mongoURI, { useNewUrlParser: true });
console.log("Connected to MongoDB");
} catch (err) {
console.error("Error connecting to MongoDB:", err.message);
}
};
module.exports = mongoDB;
Step 4: Use User Registration Route in Index.js
- Use User Registration Route in Index.js: Modify your
index.js
file to include the user registration route and JSON parsing middleware.
// index.js
const express = require('express');
const app = express();
const port = process.env.PORT || 5000;
const mongoDB = require("./db");
mongoDB();
app.use(express.json()); // JSON parsing middleware
app.get('/', (req, res) => {
res.send('Hello World from Foodie Backend!');
});
app.use('/api', require("./Routes/CreateUser"));
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
Step 5: Testing User Registration
- Testing User Registration: Use Thunder Client or any API testing tool to send a POST request to your user registration route (
/api/createuser
) with the user data JSON in the request body.
Example JSON for testing:
{
"name": "Ravi",
"password": "123457",
"email": "ravi@gmail.com",
"location": "New Delhi"
}
Conclusion
You have successfully implemented user registration functionality for your "Foodie" app's backend. Users can now register with their information, and the data will be stored in your MongoDB Atlas database. This marks a significant step towards building a complete user management system for your app.
User Registration Validation - Backend Documentation
In this section, we will enhance the user registration process by implementing input validation using the express-validator
package. This package helps ensure that the data provided by the user is valid before processing.
Step 1: Install express-validator
Install
express-validator
: Open your terminal and navigate to thebackend
folder. Run the following command to install theexpress-validator
package:npm install express-validator
Step 2: Update CreateUser.js
- Update
CreateUser.js
: Open theCreateUser.js
file in theRoutes
folder and make the following changes:
const express = require('express');
const router = express.Router();
const User = require('../models/User');
const { body, validationResult } = require('express-validator'); // Import express-validator
router.post(
"/createuser",
body('email', 'Invalid email').isEmail(),
body('name', 'Name must be of minimum 5 characters').isLength({ min: 5 }),
body('password', 'Password must be at least 5 characters').isLength({ min: 5 }),
async (req, res) => {
// Validate input data
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
try {
await User.create({
name: req.body.name,
password: req.body.password,
email: req.body.email,
location: req.body.location,
});
res.json({ success: true });
} catch (error) {
console.log(error);
res.json({ success: false });
}
}
);
module.exports = router;
Explanation of Changes
We imported the necessary modules from
express-validator
.Added validation checks for the
email
,name
, andpassword
fields using thebody()
function.The
validationResult()
function is used to check if there are any validation errors.If validation errors are found, the server responds with a
400 Bad Request
status and an array of error messages.
Step 3: Test User Registration with Validation
- Test User Registration with Validation: Use your preferred API testing tool (e.g., Thunder Client) to send a POST request to your user registration route (
/api/createuser
). Make sure the request body includes valid and invalid data for testing.
Example JSON for testing invalid data:
{
"name": "Ravi",
"password": "123", // Invalid password
"email": "invalidEmail", // Invalid email
"location": "ND"
}
Example JSON for testing valid data:
{
"name": "JohnDoe",
"password": "secure123",
"email": "johndoe@example.com",
"location": "New York"
}
Conclusion
You've successfully integrated input validation using express-validator
into your user registration route. This will ensure that the data provided by users is valid and meets the required criteria before being processed and stored in the database.
Documentation: Creating Signup and Login Pages with Database Integration
In this documentation, we will guide you through the process of creating a signup and login page using React for the frontend and Node.js with Express for the backend. We will also cover the steps to properly link these pages to a MongoDB database for user data storage.
Frontend Setup:
Create React App: Start by creating a new React app using the following command:
npx create-react-app your-app-name
Creating Signup Page (
Signup.js
): Create a new component namedSignup.js
in thesrc
folder of your React app.Signup.js
:import React, { useState } from 'react'; import { Link } from 'react-router-dom'; function Signup() { // State for storing user input const [credentials, setCredentials] = useState({ name: "", email: "", password: "", geolocation: "" }); // Handle form submission const handleSubmit = async (e) => { e.preventDefault(); // Fetch API call to send user data to the backend try { const response = await fetch("http://localhost:5000/api/signup", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(credentials) }); const data = await response.json(); console.log(data); // Handle success/failure } catch (error) { console.error(error); } }; // Handle input changes const handleChange = (e) => { setCredentials({ ...credentials, [e.target.name]: e.target.value }); }; return ( <div> {/* Signup form */} <form onSubmit={handleSubmit}> {/* ... (form fields) */} <button type="submit">Sign Up</button> </form> {/* Link to login */} <Link to="/login">Already have an account? Login</Link> </div> ); } export default Signup;
Creating Login Page (
Login.js
): Similar to the signup page, create a component namedLogin.js
for the login page.Login.js
:// Similar to Signup.js, handle login form and API call
Backend Setup:
Create Backend Directory and Install Dependencies: Create a new folder named
backend
in your project root. Open a terminal and navigate to this folder. Initialize a new Node.js project and install required packages.mkdir backend cd backend npm init -y npm install express mongoose bcrypt cors
Setting Up MongoDB: Set up a MongoDB Atlas account and create a new cluster. Get the connection URI.
Database Model (
User.js
): Create a new folder namedmodels
in the backend directory. Inside this folder, create aUser.js
file for defining the user schema.User.js
:const mongoose = require('mongoose'); const userSchema = new mongoose.Schema({ name: String, email: String, password: String, geolocation: String }); module.exports = mongoose.model('User', userSchema);
Routes (
authRoutes.js
): Create a new folder namedroutes
in the backend directory. Inside this folder, create anauthRoutes.js
file for handling signup and login routes.authRoutes.js
:const express = require('express'); const bcrypt = require('bcrypt'); const router = express.Router(); const User = require('../models/User'); // Signup route router.post('/signup', async (req, res) => { try { // Hash the password before saving to the database const hashedPassword = await bcrypt.hash(req.body.password, 10); const newUser = new User({ name: req.body.name, email: req.body.email, password: hashedPassword, geolocation: req.body.geolocation }); await newUser.save(); res.json({ success: true, message: 'User registered successfully' }); } catch (error) { res.status(500).json({ success: false, message: 'Error registering user' }); } }); // Login route // ... (implement login route) module.exports = router;
App Setup (
index.js
): In the backend directory, create anindex.js
file to set up the Express app.index.js
:const express = require('express'); const mongoose = require('mongoose'); const cors = require('cors'); const authRoutes = require('./routes/authRoutes'); const app = express(); const port = 5000; // Middleware app.use(cors()); app.use(express.json()); // Connect to MongoDB mongoose.connect('mongodb+connection-uri', { useNewUrlParser: true, useUnifiedTopology: true }) .then(() => console.log('Connected to MongoDB')) .catch(err => console.error('Error connecting to MongoDB:', err.message)); // Routes app.use('/api', authRoutes); // Start the server app.listen(port, () => { console.log(`Server is running on port ${port}`); });
Linking Frontend and Backend:
API URLs: Make sure to use correct API URLs in your frontend components. Replace
"
http://localhost:5000
"
with the appropriate URL where your backend is hosted.Routing: Use the
react-router-dom
package for routing between signup and login pages.
Testing:
Run the App: Run both the frontend and backend apps using appropriate commands (
npm start
for frontend andnode index.js
for backend).Signup and Login: Access the signup and login pages through the browser. Fill in the details and test the signup and login functionality.
Database Check: Verify that user data is being stored in your MongoDB Atlas database.
Congratulations! You have successfully created signup and login pages linked with a MongoDB database. Users can now sign up and log in to your application securely. Remember to handle errors and implement password hashing and encryption for security.
Using bcrypt to Hash Passwords - Documentation
In this documentation, we'll explore how to securely hash passwords using the bcrypt
library in a Node.js application. Hashing passwords is a crucial step to ensure the security of user data, preventing exposure of plain passwords even if the database is compromised.
Step 1: Install bcrypt
Before you begin, make sure you have Node.js and npm installed. If not, you can download them from the official Node.js website. Once you have Node.js and npm set up, you can install the bcrypt
library by running the following command in your project directory:
npm install bcrypt
Step 2: Hash Passwords
Here's how you can use bcrypt
to hash passwords in just a few lines of code:
Import the bcrypt library: In your JavaScript file (e.g.,
app.js
oruserController.js
), import thebcrypt
library at the top:const bcrypt = require('bcrypt');
Generate Salt and Hash Password:
// Password to be hashed const password = 'user_password'; // Number of salt rounds for better security (recommended: 10) const saltRounds = 10; // Generate a salt and hash the password bcrypt.genSalt(saltRounds, (err, salt) => { if (err) { console.error(err); return; } // Hash the password using the generated salt bcrypt.hash(password, salt, (err, hash) => { if (err) { console.error(err); return; } // Now you can store the 'hash' in your database console.log('Hashed Password:', hash); }); });
Replace
'user_password'
with the actual password you want to hash. The code generates a salt usingbcrypt.genSalt()
with a specified number of salt rounds. It then uses the salt to hash the password usingbcrypt.hash()
and outputs the hashed password.
Step 3: Storing Hashed Passwords
When a user signs up or resets their password, you should store the resulting hash in your database.
Step 4: Verifying Passwords
When a user tries to log in, you can use the bcrypt.compare
()
function to verify the entered password against the stored hash:
// Assuming 'enteredPassword' is the user's entered password
// and 'storedHash' is the hash retrieved from the database
bcrypt.compare(enteredPassword, storedHash, (err, result) => {
if (err) {
console.error(err);
return;
}
if (result) {
// Passwords match, user is authenticated
console.log('Password Matched');
} else {
// Passwords do not match
console.log('Password Mismatch');
}
});
Conclusion
Using the bcrypt
library to hash passwords is a crucial step in securing user data. By hashing passwords with a unique salt for each user and using a sufficient number of salt rounds, you significantly enhance the security of your application's authentication process. Always remember to handle errors appropriately and store the hash securely in your database.
Shopping Cart Component Documentation
In this documentation, we'll explain the functionality of the Cart
component, which displays and manages items in a shopping cart. The component uses React and Material-UI icons for a user-friendly cart experience.
Introduction
The Cart
component displays the items in the user's shopping cart. Users can view the items, their quantities, sizes, prices, and remove items from the cart. Additionally, users can proceed to checkout, which involves sending the cart data to the server for order processing.
Component Functionality
Import Dependencies: Import the required dependencies at the top of your
Cart.js
file:import React from 'react'; import Delete from '@material-ui/icons/Delete'; import { useCart, useDispatchCart } from '../components/ContextReducer';
Component Logic: The
Cart
component uses theuseCart
hook to get the cart data and theuseDispatchCart
hook to dispatch actions to modify the cart state.Display Cart Items: The component checks if the cart is empty. If empty, it displays a message. Otherwise, it maps through the cart items and displays them in a table format. The user can see the item name, quantity, size, price, and a delete button for each item. When the user clicks the delete button, the item is removed from the cart using the
dispatch
function and theREMOVE
action type.Calculate Total Price: The total price of all items in the cart is calculated using the
reduce
function. The calculated total is displayed below the cart items.Handle Checkout: When the user clicks the "Check Out" button, the
handleCheckOut
function is triggered. This function sends a POST request to the server with the cart data, user's email, and order date. If the response status is 200 (success), the cart is cleared using theDROP
action type.
Usage Example
Here's how you can use the Cart
component in your application:
import React from 'react';
import Cart from './Cart'; // Path to your Cart component
function App() {
return (
<div>
{/* Other components */}
<Cart />
{/* Other components */}
</div>
);
}
export default App;
Conclusion
The Cart
component is an integral part of an e-commerce application, allowing users to manage their selected items and proceed to checkout. It displays the cart items, calculates the total price, and handles the checkout process. By documenting its functionality, developers can better understand and maintain the codebase.
Navigation Bar Components Documentation
In this documentation, we'll explain the components displayed in the navigation bar when a user is logged in. The navigation bar typically includes links to the home page, the user's orders, the shopping cart, and a logout button.
Introduction
When a user logs in, a set of navigation bar components is displayed at the top of the application interface. These components provide easy access to important sections of the application, such as the home page, the user's order history, the shopping cart, and the ability to log out.
Navigation Bar Components
Home Link: This component is a link that navigates the user to the home page of the application. It's typically represented as the brand logo or the application name. Clicking on it takes the user back to the main page.
My Orders Link: The "My Orders" link directs the user to a page where they can view their order history. This page displays a list of previous orders with details such as order date, items purchased, and order status.
Cart Link: The shopping cart link displays a count of items in the user's cart. Clicking on this link takes the user to their shopping cart page, where they can view and manage the items they've added to the cart.
Logout Button: The logout button allows the user to securely log out from the application. When clicked, it logs the user out, removes their authentication credentials, and returns them to the login or home page.
Component Usage Example
Here's how you can integrate these navigation bar components into your application:
import React from 'react';
import { Link } from 'react-router-dom';
import { useAuth } from './auth'; // Path to your authentication context
import { useCart } from './cart'; // Path to your cart context
function NavigationBar() {
const { isAuthenticated, logout } = useAuth();
const cartItems = useCart();
return (
<nav>
<Link to="/">Home</Link>
{isAuthenticated && <Link to="/myorders">My Orders</Link>}
<Link to="/cart">
Cart {cartItems.length > 0 && <span>({cartItems.length})</span>}
</Link>
{isAuthenticated && <button onClick={logout}>Logout</button>}
</nav>
);
}
export default NavigationBar;
Conclusion
The navigation bar components are an essential part of user navigation and interaction within your application. By providing clear links to key sections of the app, such as the home page, order history, and shopping cart, along with a logout button for security, you enhance the user experience and usability of your application. This documentation helps developers understand the purpose and usage of each component, making maintenance and updates smoother.
/Using Context and Reducer for Adding Items to Cart
In this documentation, we'll explain how to use React's Context API and a reducer to manage the state of a shopping cart. Whenever an item is added to the cart, the state will be updated using the context and reducer pattern.
Context and Reducer Setup
Creating Context and Reducer: First, we create two contexts -
CartStateContext
andCartDispatchContext
. We also define a reducer function that handles different actions like adding, removing, dropping, and updating items in the cart.import React, { useReducer, useContext, createContext } from 'react'; const CartStateContext = createContext(); const CartDispatchContext = createContext(); const reducer = (state, action) => { switch (action.type) { // Reducer cases for ADD, REMOVE, DROP, and UPDATE } }; export const CartProvider = ({ children }) => { const [state, dispatch] = useReducer(reducer, []); return ( <CartDispatchContext.Provider value={dispatch}> <CartStateContext.Provider value={state}> {children} </CartStateContext.Provider> </CartDispatchContext.Provider> ) }; export const useCart = () => useContext(CartStateContext); export const useDispatchCart = () => useContext(CartDispatchContext);
Adding an Item to Cart: To add an item to the cart, you can dispatch an action of type "ADD" along with the necessary item details. This action will be handled by the reducer, and the state will be updated accordingly.
// In your component import { useDispatchCart } from './yourCartContext'; const CartItem = ({ id, name, qty, size, price, img }) => { const dispatch = useDispatchCart(); const addToCart = () => { dispatch({ type: 'ADD', id, name, qty, size, price, img }); }; return ( <div> {/* Your component content */} <button onClick={addToCart}>Add to Cart</button> </div> ); };
Conclusion
By using React's Context API and reducer pattern, you can manage the state of the shopping cart efficiently and ensure that it's updated consistently across your application. This approach helps in keeping the codebase clean and maintainable, as the state management logic is centralized and can be accessed and modified from different components.
Cart Checkout Documentation
In this documentation, we'll explain how the cart checkout process works using the provided code snippet. This process involves sending the cart data to the server and storing it in the database.
Function Explanation: The
handleCheckOut
function is responsible for sending the cart data to the server when the user proceeds to checkout. Here's how it works:const handleCheckOut = async () => { let userEmail = localStorage.getItem("userEmail"); let response = await fetch("http://localhost:5000/api/auth/orderData", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ order_data: data, // Cart data email: userEmail, order_date: new Date().toDateString() }) }); if (response.status === 200) { dispatch({ type: "DROP" }); // Clear the cart after successful checkout } }
This function performs the following steps:
Retrieves the user's email from the local storage.
Sends a POST request to the server's endpoint (
http://localhost:5000/api/auth/orderData
).The request includes the cart data (
data
), user's email, and the order date.If the response status is 200 (successful), it dispatches a "DROP" action to the reducer to clear the cart.
MyOrder Page Documentation
The MyOrder
component displays the user's order history retrieved from the server. Here's an explanation of how the code works:
Fetching Order History: The
fetchMyOrder
function sends a POST request to the server'smyOrderData
endpoint to retrieve the user's order history based on their email.Rendering Order Data: The component renders the order data as cards, displaying details like item name, quantity, size, price, and order date. It iterates through the nested order data to display each item and its associated details.
Here's a summarized explanation of the process:
The
fetchMyOrder
function fetches the user's order data and sets it in theorderData
state.The
useEffect
hook callsfetchMyOrder
when the component mounts.The
orderData
state is then used to render each item's details on the page.
This enables users to view their past orders, their details, and the associated prices.
My Orders Page Documentation
In this documentation, we'll explain how the MyOrder
page works using the provided code snippet. This page allows users to view their order history, displaying details of their past orders.
Function Explanation: The
MyOrder
component fetches the user's order history from the server and displays it on the page. Here's how it works:import React, { useEffect, useState } from 'react'; import Footer from '../components/Footer'; import Navbar from '../components/Navbar'; export default function MyOrder() { const [orderData, setOrderData] = useState({}); const fetchMyOrder = async () => { const userEmail = localStorage.getItem('userEmail'); const response = await fetch("http://localhost:5000/api/auth/myOrderData", { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: userEmail }) }); const responseData = await response.json(); setOrderData(responseData); } useEffect(() => { fetchMyOrder(); }, []); return ( <div> <div> <Navbar /> </div> <div className='container'> <div className='row'> {Object.keys(orderData).length > 0 ? Object.values(orderData).map(data => ( data.order_data.map((itemArray) => ( <div> {/* Render each order's data */} </div> )) )) : ( <div className='m-5 w-100 text-center fs-3'>No Orders Yet!</div> )} </div> </div> <Footer /> </div> ) }
Fetching Order History: The
fetchMyOrder
function sends a POST request to the server'smyOrderData
endpoint to retrieve the user's order history based on their email.Rendering Order Data: The component renders the user's order data as cards, displaying details like item names, quantities, sizes, prices, and order dates. It iterates through the nested order data to display each order and its associated details.
Here's a summarized explanation of the process:
The
fetchMyOrder
function fetches the user's order data and sets it in theorderData
state.The
useEffect
hook callsfetchMyOrder
when the component mounts.The component iterates through the
orderData
to display each order's details.If there are no orders, a message indicating so is displayed.
This allows users to view their past orders, their details, and the associated prices on the My Orders page.
Summary of the Project
The project is an online food ordering and delivery system that facilitates the entire process of browsing and selecting food items, adding them to the cart, placing orders, and viewing order history. It comprises various components, routes, and backend functionalities to create a seamless user experience. The project is built using React for the frontend, Express for the backend, and MongoDB for the database.
Key Features:
User Authentication and Registration: The application allows users to register and log in securely using their credentials. The user's information is stored in a MongoDB database with encrypted passwords.
Home Page: The home page showcases various food items available for ordering. Users can browse through the menu, view item details, and choose the desired quantity and size.
Cart Management: Users can add food items to their cart, modify quantities, and remove items. The cart updates in real-time, providing users with the total price of their selected items.
Context and Reducer: The application uses context and a reducer to manage the cart state across components. This ensures that the cart data remains consistent and accessible throughout the user's journey.
Checkout: Users can proceed to checkout their cart items. The system calculates the total price and prompts the user to confirm their order.
Order History: The "My Orders" page displays the user's order history, including the details of each order, such as items, quantities, sizes, prices, and order dates. Users can review their past orders.
Responsive Design: The application is responsive, ensuring a smooth and consistent user experience across various devices, including desktops, tablets, and smartphones.
Backend Integration: The Express backend handles authentication, registration, order placement, and order history retrieval. It interacts with the MongoDB database to store and retrieve user information and order data.
CORS Handling: Cross-Origin Resource Sharing (CORS) is managed to allow communication between the frontend and backend, ensuring a secure connection.
Project Flow:
Users register or log in to access the food menu and place orders.
Users browse the menu, add items to their cart, and modify cart items.
Users proceed to checkout, confirming their order and submitting it.
Users can view their order history on the "My Orders" page, which displays details of past orders.
Navigation is facilitated through the navbar, offering links to the home page, order history, cart, and a logout option.
Technologies Used:
Frontend: React, React Router, Material-UI
Backend: Express.js, Node.js
Database: MongoDB
State Management: Context and Reducer
Authentication: bcrypt
API Interaction: Fetch API
Responsive Design: CSS
Project Outcome:
The project successfully creates an interactive and user-friendly online food ordering platform. It showcases how frontend and backend technologies can be integrated to provide users with a seamless experience, from browsing the menu to placing orders and viewing order history. The use of context and a reducer for cart management ensures data consistency and efficient state updates. The application's modular structure allows for easy scalability and further feature enhancements.