Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 15

Case Study Problem Statement: E-Commerce Platform

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.

Students reference help


Possible Component Names for E-Commerce Platform
Layout Components
 Header: Main header component for navigation and branding.
 Footer: Footer component for site-wide information and links.
 Navbar: Navigation bar component for main site navigation.
 Sidebar: Sidebar component for additional navigation or filters.
Page Components
 HomePage: The main landing page of the application.
 ProductListPage: Page displaying a list of all products.
 ProductDetailsPage: Page showing details of a specific product.
 CartPage: Page for displaying items in the shopping cart.
 CheckoutPage: Page for reviewing cart items and entering shipping/payment
information.
 LoginPage: User login page.
 SignupPage: User signup/registration page.
 ProfilePage: User profile page with account details.
 OrderHistoryPage: Page displaying the user's order history.
UI Components
 ProductCard: Component for displaying individual product information in a list or
grid.
 ProductImage: Component for displaying product images.
 ProductInfo: Component for displaying product details (name, price, description).
 CartItem: Component for displaying individual items in the cart.
 Button: Reusable button component.
 Input: Reusable input component for forms.
 Form: Generic form component.
 Modal: Component for displaying modal dialogs.
 Spinner: Loading spinner component for indicating loading states.
 Alert: Component for displaying alerts or notifications.
Functional Components
 AddToCartButton: Button component for adding items to the cart.
 RemoveFromCartButton: Button component for removing items from the cart.
 QuantitySelector: Component for selecting the quantity of a product in the cart.
 SearchBar: Component for product search functionality.
 FilterPanel: Component for filtering products based on various criteria.
 Pagination: Component for navigating through pages of products.
 OrderSummary: Component displaying a summary of the order during checkout.
 ShippingForm: Form component for entering shipping details.
 PaymentForm: Form component for entering payment details.
Redux-Related Components
 ProductActions: Actions for fetching and managing product data.
 CartActions: Actions for managing cart state.
 AuthActions: Actions for handling authentication state.
 ProductReducer: Reducer for managing product state.
 CartReducer: Reducer for managing cart state.
 AuthReducer: Reducer for managing authentication state.
Utility Components
 PrivateRoute: Higher-order component for protecting routes that require
authentication.
 ErrorBoundary: Component for catching and displaying errors in the UI.
 ApiService: Utility component for making API calls using Axios.
Possible Naming, Coding, and Project
Structure
Naming Conventions
Component Naming
 Use PascalCase for React component names (e.g., ProductCard, HomePage).
 Use camelCase for props and state variables (e.g., productName, isLoading).
 Use UPPER_CASE for constants (e.g., API_BASE_URL).
File Naming
 Use the same name for component files as the component itself (e.g., ProductCard.js
for ProductCard component).
 Use index.js for entry point files in directories.
Action Types
 Use UPPER_SNAKE_CASE for action types (e.g., FETCH_PRODUCTS_SUCCESS).
CSS Class Naming
 Use BEM (Block Element Modifier) convention for CSS class names (e.g., product-
card, product-card__title).
Coding Conventions
JavaScript/React
 Use ES6+ features like arrow functions, destructuring, and template literals.
 Use functional components and hooks where possible.
 Use PropTypes for type checking props.
 Follow a consistent indentation style (2 or 4 spaces).
 Use meaningful variable and function names.
Redux
 Organize actions, reducers, and constants in separate files.
 Use Redux Thunk for asynchronous actions.
 Keep the Redux store structure flat and normalized.
CSS
 Use CSS Modules or styled-components for scoped styling.
 Follow a consistent naming convention and structure for CSS classes.
Project Structure
Directory Layout
Example Components and Code

ProductCard Component

// src/components/product/ProductCard.js
import React from 'react';
import PropTypes from 'prop-types';
import './ProductCard.css';

const ProductCard = ({ product, onAddToCart }) => (


<div className="product-card">
<img src={product.image} alt={product.name} className="product-
card__image" />
<div className="product-card__info">
<h2 className="product-card__name">{product.name}</h2>
<p className="product-card__price">${product.price}</p>
<button onClick={() => onAddToCart(product)} className="product-
card__add-button">Add to Cart</button>
</div>
</div>
);

ProductCard.propTypes = {
product: PropTypes.shape({
name: PropTypes.string.isRequired,
price: PropTypes.number.isRequired,
image: PropTypes.string.isRequired,
}).isRequired,
onAddToCart: PropTypes.func.isRequired,
};

export default ProductCard;

Product Actions

// src/redux/actions/productActions.js
import axios from 'axios';
import { FETCH_PRODUCTS_SUCCESS, FETCH_PRODUCTS_FAILURE } from '../types';

export const fetchProducts = () => async dispatch => {


try {
const response = await axios.get('/api/products');
dispatch({
type: FETCH_PRODUCTS_SUCCESS,
payload: response.data,
});
} catch (error) {
dispatch({
type: FETCH_PRODUCTS_FAILURE,
payload: error.message,
});
}
};

Product Reducer

// src/redux/reducers/productReducer.js
import { FETCH_PRODUCTS_SUCCESS, FETCH_PRODUCTS_FAILURE } from '../types';
const initialState = {
products: [],
loading: true,
error: null,
};

const productReducer = (state = initialState, action) => {


switch (action.type) {
case FETCH_PRODUCTS_SUCCESS:
return {
...state,
products: action.payload,
loading: false,
};
case FETCH_PRODUCTS_FAILURE:
return {
...state,
error: action.payload,
loading: false,
};
default:
return state;
}
};

export default productReducer;

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';

const rootReducer = combineReducers({


products: productReducer,
cart: cartReducer,
auth: authReducer,
});

const store = createStore(rootReducer, applyMiddleware(thunk));

export default store;

App Component with Routing

// 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';

const App = () => (


<Provider store={store}>
<Router>
<Header />
<main>
<Switch>
<Route path="/" component={HomePage} exact />
<Route path="/product/:id" component={ProductDetailsPage} />
<Route path="/cart" component={CartPage} />
<PrivateRoute path="/checkout" component={CheckoutPage} />
<Route path="/login" component={LoginPage} />
<Route path="/signup" component={SignupPage} />
</Switch>
</main>
<Footer />
</Router>
</Provider>
);

export default App;

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" } ] }

Example API Implementation with


Express.js
User Authentication Routes
// routes/auth.js
const express = require('express');
const router = express.Router();
const { signup, login, logout } = require('../controllers/authController');

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');

router.get('/', isAuthenticated, getCart);


router.post('/', isAuthenticated, addToCart);
router.put('/:id', isAuthenticated, updateCartItem);
router.delete('/:id', isAuthenticated, removeCartItem);

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');

router.get('/', isAuthenticated, getOrders);


router.post('/', isAuthenticated, createOrder);
router.get('/:id', isAuthenticated, getOrderById);
module.exports = router;
Express.js Server Setup
// server.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const authRoutes = require('./routes/auth');
const productRoutes = require('./routes/products');
const cartRoutes = require('./routes/cart');
const orderRoutes = require('./routes/orders');

const app = express();

// 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);

// Error handling middleware


app.use((err, req, res, next) => {
res.status(err.status || 500).json({ message: err.message || 'Internal Server Error' });
});

// Start server
const PORT = process.env.PORT || 5000;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});

Possible JSON Server for E-Commerce


Platform
To create a mock backend for the e-commerce platform, you can use JSON Server. JSON
Server allows you to quickly set up a RESTful API with a JSON file as a database. Here’s a
possible JSON file structure and the steps to set up JSON Server.
JSON Database Structure
db.json
{
"users": [
{
"id": "1",
"username": "john_doe",
"email": "john.doe@example.com",
"password_hash": "hashedpassword123",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
],
"products": [
{
"id": "1",
"name": "Product 1",
"description": "Description for product 1",
"price": 19.99,
"image_url": "/images/product1.jpg",
"stock": 100,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
},
{
"id": "2",
"name": "Product 2",
"description": "Description for product 2",
"price": 29.99,
"image_url": "/images/product2.jpg",
"stock": 50,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
],
"orders": [
{
"id": "1",
"user_id": "1",
"total_price": 49.98,
"status": "Completed",
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z",
"items": [
{
"id": "1",
"product_id": "1",
"quantity": 2,
"price": 19.99,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
]
}
],
"cartItems": [
{
"id": "1",
"user_id": "1",
"product_id": "1",
"quantity": 2,
"created_at": "2023-01-01T00:00:00Z",
"updated_at": "2023-01-01T00:00:00Z"
}
]
}
Setting Up JSON Server
Step-by-Step Guide
1. Install JSON Server: First, install JSON Server globally using npm.
npm install -g json-server
2. Create a db.json File: Create a db.json file in your project root directory and copy the
above JSON structure into it.
3. Run JSON Server: Use the following command to start JSON Server.
json-server --watch db.json --port 5000
This will start a JSON Server on http://localhost:5000.
Accessing the API
 Users: http://localhost:5000/users
 Products: http://localhost:5000/products
 Orders: http://localhost:5000/orders
 Cart Items: http://localhost:5000/cartItems
Example API Requests
Fetch All Products
GET http://localhost:5000/products
Fetch a Single Product by ID
GET http://localhost:5000/products/1
Add a Product to Cart
POST http://localhost:5000/cartItems
Content-Type: application/json

{
"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';

const API_BASE_URL = 'http://localhost:5000';

export const fetchProducts = async () => {


try {
const response = await axios.get(`${API_BASE_URL}/products`);
return response.data;
} catch (error) {
throw error;
}
};

export const fetchProductById = async (id) => {


try {
const response = await axios.get(`${API_BASE_URL}/products/${id}`);
return response.data;
} catch (error) {
throw error;
}
};

export const addToCart = async (cartItem) => {


try {
const response = await axios.post(`${API_BASE_URL}/cartItems`, cartItem);
return response.data;
} catch (error) {
throw error;
}
};

// Other API functions...


With JSON Server, you can quickly set up a mock backend to develop and test your React e-
commerce platform without needing a full-fledged backend initially.

You might also like