Welcome to my React and Node tutorial to build a fully-functional e-commerce website exactly like amazon. Open your code editor and follow me for the next hours to build an e-commerce website using Vanilla JavaScript and Node.JS, ExpressJS and MongoDB.
https://www.youtube.com/watch?v=N3FDyheHVMM
- 👉 Heroku : https://jsamazona.herokuapp.com
- 👉 AWS : https://jsamazona.webacademy.pro
- HTML5 and CSS3: Semantic Elements, CSS Grid, Flexbox
- JavaScript: ES6+, Array Functions, Rendering System
- Node & Express: Web API, Body Parser, File Upload, JWT
- MongoDB: Mongoose, Aggregation
- Development: ESLint, Babel, Git, Github,
- Deployment: Heroku
- Watch React & Node Tutorial
$ git clone git@github.com:basir/node-javascript-ecommerce.git
$ cd node-javascript-ecommerce
- Download and Install it from mongodb.com
- Create .env file in project folder
- Enter these lines to that:
MONGODB_URL=mongodb://localhost/jsamazona
JWT_SECRET=somethingsecret
PAYPAL_CLIENT_ID="your paypal client id" or sb
$ npm install
$ npm run build
$ npm start
# open new terminal
$ cd frontend
$ npm install
$ npm start
- Run this on chrome: http://localhost:5000/api/users/createadmin
- Note admin email and password
- Run http://localhost:8080/#/signin
- Enter admin email and password and click signin
- Click Dashboard Link on Header Menu
- Click Products on left sidebar
- Click Create Product Button
- Enter Product Information
- Go to home page (http://localhost:8080) and test Ecommerce Website
- Q/A: https://codingwithbasir.com
- Contact Instructor: Basir
- Home Screen
- Static Web Page Design
- CSS Grid to create website layout
- Flexbox to shape product thumbnails and responsive design
- Product Screen
- create single page application
- Create buttons and add events to buttons
- Cart Screen
- Save and retrieve data in local storage
- Master in javascript array functions
- Use combo box and add event to it
- re-render screen based on changes in item count
- Sign-in and Register Screen
- Create dynamic form
- Input validation in frontend and backend
- Create web server using node.js
- Connect to Mongodb database
- Add registered user to the database
- Authenticate user based on email and password
- Using Jsonwebtoken to authorize users
- Shipping and Payment Screen
- Create wizard form to get user data in multiple steps
- Save user info in the local storage
- Place Order Screen
- Validate and create order in the database
- Order Screen
- Payment with paypal
- Show order state based on user and admin activities
- Profile Screen
- Create authenticated routes
- enable user to update their informations
- enable user to logout and clear local storage
- show list of orders to user and link it to details
- Dashboard Screen
- Create professional dashboard using pure CSS
- Using chart library to show sales information
- Order Screen
- Enable admin to mange orders
- show loading message and alert message
- Product Screen
- enable admin to manage products
- upload product images to server
- Create Folder Structure
- create root folder as jsamazona
- add frontend and backend folder
- create src folder in frontend
- create index.html with heading jsamazona in src
- run npm init in frontend folder
- npm install live-server
- add start command as live-server src --verbose
- run npm start
- check result
- Design Website
- create style.css
- link style.css to index.html
- create div.grid-container
- create header, main and footer
- style html, body
- style grid-container, header, main and footer
- Create Static Home Screen
- create ul.products
- create li
- create div.product
- add .product-image, .product-name, .product-brand, .product-price
- style ul.products and internal divs
- duplicate 2 times to show 3 products
- Render Dynamic Home Screen
- create data.js
- export an array of 6 products
- create screens/HomeScreen.js
- export HomeScreen as an object with render() method
- implement render()
- import data.js
- return products mapped to lis inside an ul
- create app.js
- link it to index.html as module
- set main id to main-container
- create router() function
- set main_container innerHTML to HomeScreen.render()
- set load event of window to router() function
- Build Url Router
- create routes as route:screen object for home screen
- create utils.js
- export parseRequestURL()
- set url as hash address split by slash
- return resource, id and verb of url
- update router()
- set request as parseRequestURL()
- build parsedUrl and compare with routes
- if route exists render it, else render Error404
- create screens/Error404.js and render error message
- Create Node.JS Server
- run npm init in root jsamazona folder
- npm install express
- create server.js
- add start command as node backend/server.js
- require express
- move data.js from frontend to backend
- create route for /api/products
- return products in data.js
- run npm start
- Load Products From Backend
- edit HomeScreen.js
- make render async
- fetch products from '/api/products' in render()
- make router() async and call await HomeScreen.render()
- use cors on backend
- check the result
- Add Webpack
- cd frontend
- npm install -D webpack webpack-cli webpack-dev-server
- npm uninstall live-server
- "start": "webpack-dev-server --mode development --watch-content-base --open"
- move index.html, style.css and images to frontend folder
- rename app.js to index.js
- update index.html
- add script main.js before body tag
- npm start
- npm install axios
- change fetch to axios in HomeScreen
- Install Babel For ES6 Syntax
- npm install -D babel core, cli, node, preset-env
- Create .babelrc and set presets to @babel/preset-env
- npm install -D nodemon
- set start: nodemon --watch backend --exec babel-node backend/server.js
- convert require to import in server.js
- npm start
- Enable Code Linting
- npm install -D eslint
- install VSCode eslint extension
- create .eslintrc and set module.exports for env to node
- Set VSCode setting for editor.codeActionsOnSave source.fixAll.eslint to true
- check result for linting error
- npm install eslint-config-airbnb-base and eslint-plugin-import
- set extends to airbnb-base
- set parserOptions to ecmaVersion 11 and sourceType to module
- set rules for no-console to 0 to ignore linting error
- Install VSCode Extension
- JavaScript (ES6) code snippets
- ES7 React/Redux/GraphQL/React-Native snippets
- Prettier - Code formatter
- HTML&LESS grammar injections
- Create Rating Component
- create components/Rating.js
- link to fontawesome.css in index.html
- create div.rating
- define Rating object with render()
- if !props.value return empty div
- else use fa fa-star, fa-star-half-o and fa-star-o
- last span for props.text || ''
- style div.rating, span and last span
- Edit HomeScreen
- Add div.product-rating and use Rating component
- Product Screen
- get product id from request
- implement /api/product/:id api
- send Ajax request to product api
- Product Screen UI
- create back to result link
- create div.details with 3 columns
- column 1 for product image
- column 2 for product information
- column 3 form product action
- style .details and all columns
- create add to cart button with add-button id
- Product Screen Action
- after_render() to add event to the button
- add event handler for the button
- redirect user to cart/:product_id
- implement after_render in index.js
- Add To Cart Action
- create CartScreen.js
- parseRequestUrl
- getProduct(request.id)
- addToCart
- getCartItems
- cartItems.find
- if existItem update qty
- else add item
- setCartItems
- Cart Screen UI
- cartItems = getCartItems()
- create 2 columns for cart items and cart action
- cartItems.length === 0 ? cart is empty
- show item image, name, qty and price
- cart action
- Subtotal
- Proceed to Checkout button
- Add CSS Style
- Update and Delete Cart Items
- add qty select next to each item
- after_render()
- add change event to qty select
- getCartItems() and pass to addToCart()
- set force to true to addToCart()
- create rerender() as (component, areaName = 'content')
- component.render and component.after_render
- if force is true then rerender()
- add delete button next to each item
- add click event to qty button
- call removeFromCart(deleteButton.id)
- implement removeFromCart(id)
- setCartItems( getCartItems().filter)
- if id === parseRequestUrl().id? redirect to '/cart'
- else rerender(CartScreen);
- Connect To MongoDB and Create Admin User
- npm install mongoose
- connect to mongodb
- create config.js
- npm install dotenv
- export MONGODB_URL
- create models/userModel.js
- create userSchema and userModel
- create userRoute
- create createadmin route
- Sign-in Screen UI
- create SigninScreen
- render email and password fields
- style signin form
- Sign-in Screen Backend
- create signin api in backend
- create route for /api/users/signin
- create check user name and password
- if it is not ok the return 401 error
- install express-async-handler
- wrap it in expressAsyncHandler
- add error middleware in server.js
- install Postman
- send post request
- test with invalid user password
- otherwise generate token
- install jsonwebtoken
- set config.JWT_SECRET to somethingsecret
- add generateToken to utils.js
- return token
- test with correct user and password
- Sign-in Screen Action
- after_render handle form submit
- create signin request in frontend
- show alert if email or password is incorrect
- Add getUserInfo and setUserInfo to localStorage
- create Header component
- if userInfo.email exist show user name otherwise show signin
- Create Progress Indicator and Alert Component
- create overlay loading div in index.html
- Style overlay loading
- create showLoading() function
- set loading-overlay classList add active
- create hideLoading() function
- create overlay message div in index.html
- add style overlay message
- create showMessage(message, callback)
- document message-overlay set inner HTML
- div > div id message-overlay-content
- show message
- button id message-overlay-close-button OK
- add class active to it
- add event listener for button to call callback
- Register Screen
- create RegisterScreen.js
- add form elements
- after_render handle form submit
- create register request in frontend
- create register api in backend
- User Profile Screen
- create ProfileScreen.js
- add form elements
- after_render handle form submit
- create profile update request in frontend
- create profile update api in backend
- create isAuth in utils.js and use in update profile
- implement sign out
- Checkout Wizard
- create CheckoutSteps.js
- create div elements for step 1 to 4
- create redirectUser() in utils.js
- copy profile screen and as shipping screen
- use CheckoutStep
- define getShipping and setShipping
- copy shipping screen and as payment screen
- define getPayment and setPayment
- redirect user to PlaceOrder.js
- PlaceOrder Screen UI
- create PlaceOrder.js
- style elements
- PlaceOrder Screen Action
- handle place order button click
- createOrder api
- create orderModel
- create orderRouter
- create post order route
- Order Screen
- create OrderScreen.js
- style elements
- PayPal Payment
- get client id from paypal
- set it in .env file
- create route form /api/paypal/clientId
- create getPaypalClientID in api.js
- add paypal checkout script in OrderScreen.js
- show paypal button
- update order after payment
- create payOrder in api.js
- create route for /:id/pay in orderRouter.js
- rerender after pay order
- Display Orders History
- create customer orders api
- create api for getMyOrders
- show orders in profile screen
- style orders
- Admin Dashboard UI
- Header.js
- if user is admin show Dashboard
- create DashboardScreen
- create DashboardMenu
- Style dashboard
- Admin Products UI
- create ProductListScreen.js
- show products with edit and delete button
- show create product button
- Create Product
- create product model
- implement create product route
- create product function in api.js
- call create product function in ProductListScreen
- redirect to edit product
- Edit Product UI
- create ProductEditScreen.js
- load product data from backend
- handle form submit
- save product in backend
- Edit Product Backend
- handle form submit
- create updateProduct
- save product in backend
- Upload Product Image
- npm install multer
- create routes/uploadRoute.js
- import express and multer
- create disk storage with Date.now().jpg as filename
- set upload as multer({ storage })
- router.post('/', upload.single('image'))
- return req.file.path
- app.use('/api/uploads',uploadRoute) in server.js
- create uploads folder and put empty file.txt there.
- ProductEditScreen.js
- create file input and set id to image-file
- after_render() handle image-file change
- create form data
- call uploadProductImage()
- create uploadProductImage in api.js
- update server.js
- Build Project
- create build script for frontend
- create build script for backend
- update sever.js to serve frontend build folder and uploads folder
- stop running frontend
- npm run build
- check localhost:5000 for running website and showing images
- Delete Product
- update ProductListScreen.js
- handle delete button
- rerender after deletion
- Admin Orders
- create Admin Order menu in header
- create AdminOrder.js
- load orders from backend
- list them in the screen
- show delete and edit button
- redirect to order details on edit action
- Deliver Order
- if order is payed show deliver button for admin
- handle click on deliver button
- set state to delivered
- Show Summary Report in Dashboard
- create summary section
- style summary
- create summary backend
- create getSummary in api.js
- load data in dashboard screen
- show 3 boxes for Users, Orders and Sales
- Show Chart in Dashboard
- import chartist
- add chartist css to index.html
- create linear chart for daily sales
- create pie chart for product categories
- Publish heroku
- Create git repository
- Create heroku account
- install Heroku CLI
- heroku login
- heroku apps:create jsamazona
- Edit package.json for heroku-prebuild
- Edit package.json for heroku-postbuild
- Edit package.json for node engines
- Create Procfile
- Edit server.js for PORT
- Create mongodb atlas database
- create MongoDB Account
- open cloud.mongodb.com
- add new user and save username and password
- set Network Access to accept all requests
- Create new database
- create connection string based on db name and user and password
- Set Cloud MongoDB connection in heroku env variables
- Commit and push
- Product Search Bar
- create search bar in Header.js
- add style
- handle submit form
- edit parse url to get query string
- update product list api for search keyword
- Show Categories In Sidebar Menu
- create aside-open-button in Header.js
- add event to open aside
- create Aside.js component
- Add style aside
- after render close it on click on close button
- Use it in index.html
- Update index.js to render aside 9.
- call getCategories
- create getCategories in api.js
- Review Products
- create review model
- create review form
- create review api
- style review form