• Stars
    star
    584
  • Rank 76,554 (Top 2 %)
  • Language
    JavaScript
  • Created over 1 year ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

ProShop ecommerce website built with MERN & Redux Toolkit

ProShop eCommerce Platform (v2)

eCommerce platform built with the MERN stack & Redux.

This project is part of my MERN Stack From Scratch | eCommerce Platform course. It is a full-featured shopping cart with PayPal & credit/debit payments. See it in action at https://www.proshopdemo.dev

This is version 2.0 of the app, which uses Redux Toolkit. The first version can be found here

Features

  • Full featured shopping cart
  • Product reviews and ratings
  • Top products carousel
  • Product pagination
  • Product search feature
  • User profile with orders
  • Admin product management
  • Admin user management
  • Admin Order details page
  • Mark orders as delivered option
  • Checkout process (shipping, payment method, etc)
  • PayPal / credit card integration
  • Database seeder (products & users)

Usage

Env Variables

Rename the .env.example file to .env and add the following

NODE_ENV = development
PORT = 5000
MONGO_URI = your mongodb uri
JWT_SECRET = 'abc123'
PAYPAL_CLIENT_ID = your paypal client id
PAGINATION_LIMIT = 8

Change the JWT_SECRET and PAGINATION_LIMIT to what you want

Install Dependencies (frontend & backend)

npm install
cd frontend
npm install

Run


# Run frontend (:3000) & backend (:5000)
npm run dev

# Run backend only
npm run server

Build & Deploy

# Create frontend prod build
cd frontend
npm run build

Seed Database

You can use the following commands to seed the database with some sample users and products as well as destroy all data

# Import data
npm run data:import

# Destroy data
npm run data:destroy
Sample User Logins

[email protected] (Admin)
123456

[email protected] (Customer)
123456

[email protected] (Customer)
123456

Bug Fixes, corrections and code FAQ

The code here in the main branch has been updated since the course was published to fix bugs found by students of the course and answer common questions, if you are looking to compare your code to that from the course lessons then please refer to the originalcoursecode branch of this repository.

There are detailed notes in the comments that will hopefully help you understand and adopt the changes and corrections. An easy way of seeing all the changes and fixes is to use a note highlighter extension such as This one for VSCode or this one for Vim Where by you can easily list all the NOTE: and FIX: tags in the comments.

BUG: Warnings on ProfileScreen

We see the following warning in the browser console..

<tD> cannot appear as a child of <tr>.

and

warning: Received 'true' for a non-boolean attribute table.

Code changes can be seen in ProfileScreen.jsx

BUG: Changing an uncontrolled input to be controlled

In our SearchBox input, it's possible that our urlKeyword is undefined, in which case our initial state will be undefined and we will have an uncontrolled input initially i.e. not bound to state. In the case of urlKeyword being undefined we can set state to an empty string.

Code changes can be seen in SearchBox.jsx

BUG: All file types are allowed when updating product images

When updating and uploading product images as an Admin user, all file types are allowed. We only want to upload image files. This is fixed by using a fileFilter function and sending back an appropriate error when the wrong file type is uploaded.

You may see that our checkFileType function is declared but never actually used, this change fixes that. The function has been renamed to fileFilter and passed to the instance of multer

Code changes can be seen in uploadRoutes.js

BUG: Throwing error from productControllers will not give a custom error response

In section 3 - Custom Error Middleware we throw an error from our getProductById controller function, with a custom message. However if we have a invalid ObjectId as req.params.id and use that to query our products in the database, Mongoose will throw an error before we reach the line of code where we throw our own error.

Original code

const getProductById = asyncHandler(async (req, res) => {
  const product = await Product.findById(req.params.id);
  if (product) {
    return res.json(product);
  }
  // NOTE: the following will never run if we have an invalid ObjectId
  res.status(404);
  throw new Error('Resource not found');
});

Instead what we can do is if we do want to check for an invalid ObjectId is use a built in method from Mongoose - isValidObjectId There are a number of places in the project where we may want to check we are getting a valid ObjectId, so we can extract this logic to it's own middleware and drop it in to any route handler that needs it.
This also removes the need to check for a cast error in our errorMiddleware and is a little more explicit in checking fo such an error.

Changes can be seen in errorMiddleware.js, productRoutes.js, productController.js and checkObjectId.js

BUG: Bad responses not handled in the frontend

There are a few cases in our frontend where if we get a bad response from our API then we try and render the error object. This you cannot do in React - if you are seeing an error along the lines of Objects are not valid as a React child and the app breaks for you, then this is likely the fix you need.

Example from PlaceOrderScreen.jsx

<ListGroup.Item>
  {error && <Message variant='danger'>{error}</Message>}
</ListGroup.Item>

In the above code we check for a error that we get from our useMutation hook. This will be an object though which we cannot render in React, so here we need the message we sent back from our API server...

<ListGroup.Item>
  {error && <Message variant='danger'>{error.data.message}</Message>}
</ListGroup.Item>

The same is true for handling errors from our RTK queries.

Changes can be seen in:-

BUG: After switching users, our new user gets the previous users cart

When our user logs out we clear userInfo and expirationTime from local storage but not the cart.
So when we log in with a different user, they inherit the previous users cart and shipping information.

The solution is to simply clear local storage entirely and so remove the cart, userInfo and expirationTime.

Changes can be seen in:-

FAQ: How do I use Vite instead of CRA?

Ok so you're at Section 1 - Starting The Frontend in the course and you've heard cool things about Vite and why you should use that instead of Create React App in 2023.

There are a few differences you need to be aware of using Vite in place of CRA here in the course after scaffolding out your Vite React app

Setting up the proxy

Using CRA we have a "proxy" setting in our frontend/package.json to avoid breaking the browser Same Origin Policy in development. In Vite we have to set up our proxy in our vite.config.js.

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  server: {
    // proxy requests prefixed '/api' and '/uploads'
    proxy: {
      '/api': 'http://localhost:5000',
      '/uploads': 'http://localhost:5000',
    },
  },
});

Setting up linting

By default CRA outputs linting from eslint to your terminal and browser console. To get Vite to ouput linting to the terminal you need to add a plugin as a development dependency...

npm i -D vite-plugin-eslint

Then add the plugin to your vite.config.js

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// import the plugin
import eslintPlugin from 'vite-plugin-eslint';

export default defineConfig({
  plugins: [
    react(),
    eslintPlugin({
      // setup the plugin
      cache: false,
      include: ['./src/**/*.js', './src/**/*.jsx'],
      exclude: [],
    }),
  ],
  server: {
    proxy: {
      '/api': 'http://localhost:5000',
      '/uploads': 'http://localhost:5000',
    },
  },
});

By default the eslint config that comes with a Vite React project treats some rules from React as errors which will break your app if you are following Brad exactly. You can change those rules to give a warning instead of an error by modifying the eslintrc.cjs that came with your Vite project.

module.exports = {
  env: { browser: true, es2020: true },
  extends: [
    'eslint:recommended',
    'plugin:react/recommended',
    'plugin:react/jsx-runtime',
    'plugin:react-hooks/recommended',
  ],
  parserOptions: { ecmaVersion: 'latest', sourceType: 'module' },
  settings: { react: { version: '18.2' } },
  plugins: ['react-refresh'],
  rules: {
    // turn this one off
    'react/prop-types': 'off',
    // change these errors to warnings
    'react-refresh/only-export-components': 'warn',
    'no-unused-vars': 'warn',
  },
};

Vite outputs the build to /dist

Create React App by default outputs the build to a /build directory and this is what we serve from our backend in production.
Vite by default outputs the build to a /dist directory so we need to make some adjustments to our backend/server.js Change...

app.use(express.static(path.join(__dirname, '/frontend/build')));

to...

app.use(express.static(path.join(__dirname, '/frontend/dist')));

and...

app.get('*', (req, res) =>
  res.sendFile(path.resolve(__dirname, 'frontend', 'build', 'index.html'))
);

to...

app.get('*', (req, res) =>
  res.sendFile(path.resolve(__dirname, 'frontend', 'dist', 'index.html'))
);

Vite has a different script to run the dev server

In a CRA project you run npm start to run the development server, in Vite you start the development server with npm run dev
If you are using the dev script in your root pacakge.json to run the project using concurrently, then you will also need to change your root package.json scripts from...

    "client": "npm start --prefix frontend",

to...

    "client": "npm run dev --prefix frontend",

Or you can if you wish change the frontend/package.json scripts to use npm start...

    "start": "vite",

A final note:

Vite requires you to name React component files using the .jsx file type, so you won't be able to use .js for your components. The entry point to your app will be in main.jsx instead of index.js

And that's it! You should be good to go with the course using Vite.


License

The MIT License

Copyright (c) 2023 Traversy Media https://traversymedia.com

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

More Repositories

1

design-resources-for-developers

Curated list of design and UI resources from stock photos, web templates, CSS frameworks, UI libraries, tools and much more
58,625
star
2

50projects50days

50+ mini web projects using HTML, CSS & JS
CSS
36,264
star
3

vanillawebprojects

Mini projects built with HTML5, CSS & JavaScript. No frameworks or libraries
JavaScript
15,520
star
4

proshop_mern

Shopping cart built with MERN & Redux
JavaScript
1,995
star
5

devconnector_2.0

Social network for developers, built on the MERN stack
JavaScript
1,907
star
6

node_passport_login

Node.js login, registration and access control using Express and Passport
JavaScript
1,695
star
7

react-crash-2021

Task tracking application from the React crash course
JavaScript
1,359
star
8

chatcord

Realtime chat app with rooms
HTML
1,161
star
9

modern_js_udemy_projects

Project files for Modern JS From The Beginning course
JavaScript
1,121
star
10

traversy-js-challenges

Challenges & docs from JS Algorithms & Data Structures course
JavaScript
903
star
11

react_express_starter

Starter pack for React and Express full stack development
JavaScript
774
star
12

mern-tutorial

Goalsetter application from Youtube series
JavaScript
710
star
13

modern_portfolio

Responsive portfolio website
SCSS
681
star
14

laragigs

Laravel job listing app
PHP
606
star
15

loruki-website

Cloud hosting website
HTML
595
star
16

mern_shopping_list

Shopping List built with MERN and Redux
TypeScript
594
star
17

lead_manager_react_django

Full stack app with React, Redux & Django
JavaScript
590
star
18

php-crash

Code for my PHP crash course on YouTube
PHP
572
star
19

storybooks

Node.js app with Google OAuth
JavaScript
561
star
20

feedback-app

React feedback app from React course
JavaScript
542
star
21

vue-crash-2021

Task Tracker project from youtube crash course
Vue
536
star
22

devcamper-api

Backend for devcamper app
HTML
516
star
23

btre_project

Django real estate website
CSS
507
star
24

tailwind-landing-page

CSS
500
star
25

javascript_cardio

JavaScript challenges and problems
JavaScript
490
star
26

expense-tracker-react

Simple expense tracker using React hooks & context
JavaScript
485
star
27

ui_components

Collection of HTML & CSS UI components
HTML
484
star
28

python_sandbox

Files to learn Python basics
Python
483
star
29

angular-crash-2021

Task tracker app from the 2021 youtube crash course
TypeScript
480
star
30

simple_react_pagination

Frontend pagination with React
JavaScript
479
star
31

vanilla-parcel-boilerplate

Simple starter workflow for building vanilla js apps with Parcel
JavaScript
436
star
32

next-crash-course

Project from my Next.js crash course on YouTube
JavaScript
425
star
33

tailwind-course-projects

Projects from my TailwindCSS course
CSS
425
star
34

redux_crash_course

Simple implementation of Redux with React 16
JavaScript
416
star
35

node_crash_course

Files for YouTube crash course
JavaScript
401
star
36

bootstrap-bootcamp-website

HTML
390
star
37

react_crash_todo

React crash course files
JavaScript
373
star
38

javascript-sandbox

Sandbox from the Modern JS From The Beginning 2.0 course
JavaScript
372
star
39

github-finder

Search Github users - React hooks & context
JavaScript
372
star
40

expense-tracker-mern

Full stack expense tracker
JavaScript
368
star
41

vanilla-node-rest-api

REST API using Node.js without a framework
JavaScript
368
star
42

rust_sandbox

Fundamentals of the Rust language
Rust
358
star
43

express_crash_course

Express crash course on YouTube
JavaScript
358
star
44

docker-node-mongo

Sample node and mongo app that uses docker
JavaScript
357
star
45

vue_crash_todolist

Vue crash course application
Vue
351
star
46

project-mgmt-graphql

Full stack GraphQL, Express & React app
JavaScript
339
star
47

webpack-starter

Boilerplate for Webpack apps
JavaScript
337
star
48

github-finder-app

Find github users and display their info
JavaScript
336
star
49

react_redux_express_starter

Boiler plate for React/Redux applications with Express
JavaScript
336
star
50

lsapp

Laravel from scratch website/blog application
PHP
333
star
51

contact-keeper

Contact manager using React hooks & context
JavaScript
327
star
52

dj-events-frontend

Next.js website to list DJ and other musical events
JavaScript
324
star
53

vuex_todo_manager

Vuex crah course app
Vue
314
star
54

myflaskapp

Python Flask app with authentication
Python
312
star
55

house-marketplace

House marketplace built with React and FIrebase
JavaScript
311
star
56

hulu-webpage-clone

Hulu webpage clone
CSS
307
star
57

nodejs-openai-image

Web app that uses Node.js and OpenAI to generate images
CSS
305
star
58

nodekb

Simple knowledgebase app with Node.js, Express and MongoDB
JavaScript
303
star
59

react_step_form

Multi step form built with React and Material UI
JavaScript
302
star
60

axios-crash

Axios crash course files
JavaScript
298
star
61

mern-auth

MERN authentication using JWT and HTTP-Only cookie
JavaScript
291
star
62

node-api-proxy-server

Proxy server to hide public API keys with rate limiting, caching
JavaScript
286
star
63

laravel-sanctum-api

REST API with auth using Laravel 8 and Sanctum
PHP
285
star
64

php_rest_myblog

PHP
281
star
65

tailwind-sandbox

Sandbox used with the Tailwind From Scratch course
HTML
280
star
66

react_webpack_starter

React 16 and Webpack 4 starter pack
TypeScript
277
star
67

next-markdown-blog

Simple blog using Next and Markdown
JavaScript
276
star
68

creative-agency-website

Agency website - basic HTML/CSS
HTML
275
star
69

react-crash-2024

React jobs project from YouTube crash course
HTML
271
star
70

react_file_uploader

React and Express file uploader
JavaScript
268
star
71

alexis_speech_assistant

Python speech assist app
Python
267
star
72

deno-rest-api

Simple REST API using Deno and Oak
TypeScript
266
star
73

go_crash_course

Basics of the go language
Go
264
star
74

url_shortener_service

API to shorten urls using Node, Express & MongoDB
JavaScript
250
star
75

breaking-bad-cast

App to show cast info for breaking bad
JavaScript
250
star
76

electron-course-files

Files and apps for Electron course
JavaScript
248
star
77

react_native_shopping_list

React Native app from crash course
JavaScript
244
star
78

simple-electron-react

Simple boilerplate for building Electron apps with React
JavaScript
243
star
79

bookstore

Simple RESTful JSON api using Nodejs, Express and MongoDB
HTML
240
star
80

meanauthapp

Complete MEAN stack app with authentication
JavaScript
240
star
81

angular-crash-todolist

Simple app for Angular crash course
TypeScript
231
star
82

qr-code-generator

Simple Tool to Generate QR Codes
HTML
223
star
83

node_jwt_example

Example of Node JSON Web Tokens
JavaScript
221
star
84

electronshoppinglist

Shopping list desktop app built on electron
JavaScript
219
star
85

go_restapi

Simple RESTful API using Golang
Go
214
star
86

lyricfinder

App that finds song lyrics using React and the Musixmatch API
JavaScript
211
star
87

svg-css-generator-examples

Tiny projects using generated code from different CSS & SVG generators
HTML
204
star
88

ciblog

Simple blog built on Codeigniter
PHP
202
star
89

larticles_api

Laravel 5.5 API using resources
PHP
193
star
90

codegig

Simple job find app for coders
CSS
191
star
91

node_push_notifications

Example using Node.js and service workers to send and show push notifications
JavaScript
186
star
92

bs4starter

Starter pack for Bootstrap 4 Beta
JavaScript
183
star
93

support-desk

Support ticket app built with the MERN stack
JavaScript
178
star
94

mongochat

Simple chat app using Mongo and websockets
HTML
178
star
95

nestjs_rest_api

Rest api built with Nest and MongoDB
TypeScript
173
star
96

next-13-crash-course

JavaScript
173
star
97

microposts_fullstack_vue

Full stack vue and express
JavaScript
172
star
98

flask_sqlalchemy_rest

Products REST API using Flask, SQL Alchemy & Marshmallow
Python
171
star
99

pollster_django_crash

Polling app built with Django (Django Crash Course)
Python
170
star
100

huddle_styled_components

Landing page from styled components crash course
JavaScript
168
star