Online Food Delivery System with React

Spread the love

Online Food Delivery System with React

This tutorial covers creating an online food delivery system using React, Node.js, Express, and MongoDB. The system includes:

  1. Frontend: React app for users, admin, and restaurant login systems.
  2. Backend: Node.js with Express for RESTful API services.
  3. Database: MongoDB for managing users, items, categories, orders, and roles.
  4. Payment Gateway: Integration using Stripe (or another payment service).

Step 1: Setup Project Structure

1.1 Install Node.js and Create a Project

# Install Node.js from https://nodejs.org/
npx create-react-app food-delivery-system
cd food-delivery-system

1.2 Install Required Packages

Install dependencies for the frontend and backend.

# Frontend (React)
npm install react-router-dom axios redux react-redux

# Backend (Express + MongoDB)
npm install express mongoose body-parser cors bcrypt jsonwebtoken dotenv

# Payment Gateway (Stripe)
npm install stripe

Step 2: Backend Development

2.1 Setup Express Server

Create a folder backend/ and initialize it.

cd ..
mkdir backend
cd backend
npm init -y

Create server.js.

const express = require('express');
const cors = require('cors');
const mongoose = require('mongoose');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());

mongoose.connect(process.env.MONGO_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

const connection = mongoose.connection;
connection.once('open', () => {
  console.log('MongoDB database connection established successfully');
});

// Example Routes
const userRoutes = require('./routes/users');
const adminRoutes = require('./routes/admin');
app.use('/api/users', userRoutes);
app.use('/api/admin', adminRoutes);

app.listen(PORT, () => {
  console.log(`Server is running on port: ${PORT}`);
});

2.2 Define Models

Create a folder models/ for MongoDB schemas.

User.js

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true },
  role: { type: String, enum: ['user', 'restaurant', 'admin', 'superadmin'], default: 'user' },
  credit: { type: Number, default: 0 },
});

module.exports = mongoose.model('User', userSchema);

FoodItem.js

const mongoose = require('mongoose');

const foodItemSchema = new mongoose.Schema({
  name: { type: String, required: true },
  category: { type: String, enum: ['veg', 'non-veg', 'spicy'], required: true },
  price: { type: Number, required: true },
  addons: [{ name: String, price: Number }],
});

module.exports = mongoose.model('FoodItem', foodItemSchema);

Order.js

const mongoose = require('mongoose');

const orderSchema = new mongoose.Schema({
  userId: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  items: [
    {
      item: { type: mongoose.Schema.Types.ObjectId, ref: 'FoodItem' },
      quantity: { type: Number, required: true },
      addons: [String],
    },
  ],
  totalAmount: { type: Number, required: true },
  status: { type: String, enum: ['pending', 'in-progress', 'delivered'], default: 'pending' },
});

module.exports = mongoose.model('Order', orderSchema);

2.3 Implement Routes

Create a folder routes/ and define routes for users, food items, orders, etc.

Example: routes/users.js

const express = require('express');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const User = require('../models/User');

const router = express.Router();

// Register
router.post('/register', async (req, res) => {
  const { name, email, password, role } = req.body;
  const hashedPassword = await bcrypt.hash(password, 10);
  const newUser = new User({ name, email, password: hashedPassword, role });
  await newUser.save();
  res.status(201).send('User registered');
});

// Login
router.post('/login', async (req, res) => {
  const { email, password } = req.body;
  const user = await User.findOne({ email });
  if (!user || !(await bcrypt.compare(password, user.password))) {
    return res.status(400).send('Invalid credentials');
  }
  const token = jwt.sign({ id: user._id, role: user.role }, process.env.JWT_SECRET);
  res.json({ token });
});

module.exports = router;

Step 3: Frontend Development

3.1 Setup React Router

Add routes for user pages, admin dashboard, and restaurant dashboard.

App.js

import React from 'react';
import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';

import UserHome from './pages/UserHome';
import AdminDashboard from './pages/AdminDashboard';
import RestaurantDashboard from './pages/RestaurantDashboard';
import Login from './pages/Login';
import Register from './pages/Register';

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<UserHome />} />
        <Route path="/admin" element={<AdminDashboard />} />
        <Route path="/restaurant" element={<RestaurantDashboard />} />
        <Route path="/login" element={<Login />} />
        <Route path="/register" element={<Register />} />
      </Routes>
    </Router>
  );
}

export default App;

3.2 User Interfaces

Login.js

import React, { useState } from 'react';
import axios from 'axios';

function Login() {
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const handleSubmit = async (e) => {
    e.preventDefault();
    try {
      const response = await axios.post('/api/users/login', { email, password });
      localStorage.setItem('token', response.data.token);
      alert('Login successful');
    } catch (error) {
      alert('Login failed');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="Email" required />
      <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" required />
      <button type="submit">Login</button>
    </form>
  );
}

export default Login;

Continue developing the UI for AdminDashboard, RestaurantDashboard, and Order Management.


Step 4: Payment Integration

Integrate Stripe or another payment service. Example with Stripe:

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

router.post('/create-payment-intent', async (req, res) => {
  const { amount } = req.body;
  const paymentIntent = await stripe.paymentIntents.create({
    amount,
    currency: 'usd',
  });
  res.send({ clientSecret: paymentIntent.client_secret });
});

Step 5: Deployment

Deploy the React frontend to Netlify or Vercel and the backend to Heroku, AWS, or another hosting platform.

Related Posts

Leave a Reply