Case Study Problem Statement - React JS
Case Study Problem Statement - React JS
with React JS
Problem Statement
Objective
Develop a full-featured e-commerce web application using React JS. The platform should
allow users to browse products, view product details, manage a shopping cart, authenticate
their accounts, and proceed through a checkout process. The application should leverage
React Hooks for state management, React Router for navigation, Axios for API interactions,
and Redux for global state management.
Key Features and Requirements
1. Project Setup
o Use create-react-app to initialize the project.
o Install and configure essential dependencies including react-router-dom,
axios, redux, react-redux, and redux-thunk.
2. Application Structure
o Organize the application into a clear folder structure with separate directories
for components, pages, and Redux-related files.
3. Product Listing Page
o Fetch and display a list of products from a mock API using Axios.
o Implement a grid layout to showcase products with details such as name,
price, and image.
o Provide an "Add to Cart" button for each product.
4. Product Details Page
o Use dynamic routing to handle product detail pages based on product ID.
o Fetch detailed information about a product when its detail page is accessed.
o Include an "Add to Cart" button on the product details page.
5. Cart Management
o Create a cart page to display products added to the cart.
o Allow users to update the quantity of items in the cart.
o Implement functionality to remove products from the cart.
6. User Authentication
o Develop signup and login forms using React Hooks.
o Use Redux to manage authentication state across the application.
o Protect routes such as the cart and checkout pages to ensure only
authenticated users can access them.
7. Checkout Process
o Implement a checkout page where users can review their cart and proceed to
payment.
o Display an order summary including products, quantities, and total price.
o Use forms to capture shipping and payment details from the user.
8. State Management with Redux
o Configure Redux store and create reducers and actions for handling products,
cart, and authentication states.
o Utilize Redux Thunk middleware for asynchronous operations like API calls.
o Connect React components to the Redux store to manage state efficiently.
9. Error Handling and Loading States
o Implement error boundaries to catch and display errors gracefully.
o Show loading indicators during API calls to enhance the user experience.
Implementation Plan
1. Project Initialization
o Initialize the React project and set up necessary dependencies.
o Establish a clear folder structure for the application.
2. Building the Product Listing Page
o Fetch product data from the API and display it in a grid layout.
o Implement the "Add to Cart" functionality.
3. Creating the Product Details Page
o Set up dynamic routing for product details.
o Fetch and display detailed product information.
o Include the option to add the product to the cart.
4. Implementing Cart Management
o Develop the cart page to display and manage cart items.
o Provide options to update item quantities and remove items.
5. User Authentication
o Create signup and login forms using React Hooks.
o Manage authentication state with Redux and protect certain routes.
6. Developing the Checkout Process
o Implement the checkout page with order summary and forms for user details.
o Ensure the checkout process is only accessible to authenticated users.
7. Setting Up Redux for State Management
o Configure Redux store, reducers, and actions.
o Use Redux Thunk for handling asynchronous operations.
o Connect components to Redux store for state management.
8. Handling Errors and Loading States
o Implement error boundaries to handle errors gracefully.
o Display loading indicators during API calls.
ProductCard Component
// src/components/product/ProductCard.js
import React from 'react';
import PropTypes from 'prop-types';
import './ProductCard.css';
ProductCard.propTypes = {
product: PropTypes.shape({
name: PropTypes.string.isRequired,
price: PropTypes.number.isRequired,
image: PropTypes.string.isRequired,
}).isRequired,
onAddToCart: PropTypes.func.isRequired,
};
Product Actions
// src/redux/actions/productActions.js
import axios from 'axios';
import { FETCH_PRODUCTS_SUCCESS, FETCH_PRODUCTS_FAILURE } from '../types';
Product Reducer
// src/redux/reducers/productReducer.js
import { FETCH_PRODUCTS_SUCCESS, FETCH_PRODUCTS_FAILURE } from '../types';
const initialState = {
products: [],
loading: true,
error: null,
};
Store Configuration
// src/redux/store.js
import { createStore, applyMiddleware, combineReducers } from 'redux';
import thunk from 'redux-thunk';
import productReducer from './reducers/productReducer';
import cartReducer from './reducers/cartReducer';
import authReducer from './reducers/authReducer';
// src/App.js
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from './redux/store';
import HomePage from './pages/HomePage';
import ProductDetailsPage from './pages/ProductDetailsPage';
import CartPage from './pages/CartPage';
import CheckoutPage from './pages/CheckoutPage';
import LoginPage from './pages/LoginPage';
import SignupPage from './pages/SignupPage';
import Header from './components/layout/Header';
import Footer from './components/layout/Footer';
import PrivateRoute from './utils/PrivateRoute';
API Design
Endpoints
1. User Authentication
o POST /api/auth/signup: Create a new user
Request Body: { "username": "string", "email": "string",
"password": "string" }
Response: { "id": "UUID", "username": "string", "email":
"string" }
o POST /api/auth/login: Authenticate a user
Request Body: { "email": "string", "password": "string" }
Response: { "token": "JWT", "user": { "id": "UUID",
"username": "string", "email": "string" } }
o POST /api/auth/logout: Log out the user
Request Body: {}
Response: { "message": "Logged out successfully" }
2. Product Management
o GET /api/products: Fetch all products
Response: [ { "id": "UUID", "name": "string",
"description": "string", "price": "decimal", "image_url":
"string", "stock": "integer" } ]
o GET /api/products/
: Fetch product details by ID
Response: { "id": "UUID", "name": "string",
"description": "string", "price": "decimal", "image_url":
"string", "stock": "integer" }
o POST /api/products: Create a new product (Admin only)
Request Body: { "name": "string", "description":
"string", "price": "decimal", "image_url": "string",
"stock": "integer" }
Response: { "id": "UUID", "name": "string",
"description": "string", "price": "decimal", "image_url":
"string", "stock": "integer" }
o PUT /api/products/
: Update a product by ID (Admin only)
Request Body: { "name": "string", "description":
"string", "price": "decimal", "image_url": "string",
"stock": "integer" }
Response: { "id": "UUID", "name": "string",
"description": "string", "price": "decimal", "image_url":
"string", "stock": "integer" }
o DELETE /api/products/
: Delete a product by ID (Admin only)
Response: { "message": "Product deleted successfully" }
3. Cart Management
o GET /api/cart: Fetch the current user's cart items
Response: [ { "id": "UUID", "product": { "id": "UUID",
"name": "string", "price": "decimal" }, "quantity":
"integer" } ]
o POST /api/cart: Add an item to the cart
Request Body: { "product_id": "UUID", "quantity":
"integer" }
Response: { "id": "UUID", "product": { "id": "UUID",
"name": "string", "price": "decimal" }, "quantity":
"integer" }
o PUT /api/cart/
: Update the quantity of an item in the cart
Request Body: { "quantity": "integer" }
Response: { "id": "UUID", "product": { "id": "UUID",
"name": "string", "price": "decimal" }, "quantity":
"integer" }
o DELETE /api/cart/
: Remove an item from the cart
Response: { "message": "Cart item removed successfully" }
4. Order Management
o GET /api/orders: Fetch the current user's orders
Response: [ { "id": "UUID", "total_price": "decimal",
"status": "string", "created_at": "timestamp" } ]
o POST /api/orders: Create a new order
Request Body: { "shipping_address": "string",
"payment_method": "string" }
Response: { "id": "UUID", "total_price": "decimal",
"status": "string", "created_at": "timestamp" }
o GET /api/orders/
: Fetch order details by ID
Response: { "id": "UUID", "user_id": "UUID",
"total_price": "decimal", "status": "string",
"created_at": "timestamp", "items": [ { "id": "UUID",
"product": { "id": "UUID", "name": "string", "price":
"decimal" }, "quantity": "integer", "price":
"decimal" } ] }
router.post('/signup', signup);
router.post('/login', login);
router.post('/logout', logout);
module.exports = router;
Product Management Routes
// routes/products.js
const express = require('express');
const router = express.Router();
const { getProducts, getProductById, createProduct, updateProduct, deleteProduct } =
require('../controllers/productController');
const { isAdmin } = require('../middlewares/authMiddleware');
router.get('/', getProducts);
router.get('/:id', getProductById);
router.post('/', isAdmin, createProduct);
router.put('/:id', isAdmin, updateProduct);
router.delete('/:id', isAdmin, deleteProduct);
module.exports = router;
Cart Management Routes
// routes/cart.js
const express = require('express');
const router = express.Router();
const { getCart, addToCart, updateCartItem, removeCartItem } =
require('../controllers/cartController');
const { isAuthenticated } = require('../middlewares/authMiddleware');
module.exports = router;
Order Management Routes
// routes/orders.js
const express = require('express');
const router = express.Router();
const { getOrders, createOrder, getOrderById } = require('../controllers/orderController');
const { isAuthenticated } = require('../middlewares/authMiddleware');
// Middleware
app.use(bodyParser.json());
app.use(cors());
// Routes
app.use('/api/auth', authRoutes);
app.use('/api/products', productRoutes);
app.use('/api/cart', cartRoutes);
app.use('/api/orders', orderRoutes);
// Start server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
{
"user_id": "1",
"product_id": "1",
"quantity": 1,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
Create an Order
POST http://localhost:5000/orders
Content-Type: application/json
{
"user_id": "1",
"total_price": 49.98,
"status": "Pending",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"items": [
{
"product_id": "1",
"quantity": 2,
"price": 19.99,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
]
}
Integrating with React
In your React application, you can use Axios to interact with this mock API.
Example Axios Integration
// src/services/apiService.js
import axios from 'axios';