BishalBazar Javascript E-commerce project tutorial
-
Create Folder Structure
- Create root folder as bishalBazaar
- Add frontend and backend folders inside bishalBazaar
- Create src folder inside frontend
- Create index.html with heading-1 Bishal Bazaar inside src folder
- Open terminal and go to frontend folder
- Run npm init inside frontend
- Run npm install -D live-server (here, -D means Development dependencies )
- Add "start" command as "live-server src --verbose" in scripts section inside package.json
- Run npm start
-
Design Website
- Create a css folder inside src folder
- Create style.css file inside css folder
- Link style.css to index.html
- Create div.grid-container
- Create header, main, and footer
- Style html, body, grid-container, header, main, and footer
-
Create Static Home Screen
- Inside main section, create ul.products
- Create inside ul.products
- Create div.product inside
- 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 inside an
- Export HomeScreen
- Create app.js
- Link it to index.html as module
- Set id to main-container inside index.html
- Create router() function inside app.js
- 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 in app.js
- Create ProductScreen.js in screens folder
- Export ProductScreen as an object with render() method
- Create utils.js inside js folder
- Export parseRequestURL() method
- Set URL as hash address split by slash
- Return resource, id and verb of url
- Update router() method inside app.js
- Set request as parseRequestURL()
- Build paresedUrl and compare with routes
- If route exists render it, else render Error404
- Create screens/Error404.js and render error message
-
Create Node.JS Server
- Create backend folder inside root folder
- Create server.js file inside backend folder
- Run npm init in root bishalBazaar folder
- npm install express
- Create server.js
- Add start command as node backend/server.js
- require express
- Move data.js from frontend to backend
- Change "export default" to "module.exports =" inside data.js
- Create route from /api/products
- return products in data.js
- Add "start" command with "node backend/server.js" in the packaged.json located at the root folder (not in the frotend folder)
- 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() in app.js
- Use cors on backend
-
Add Webpack
- Go to frontend folder from terminal. (cd frontend)
- npm install -D webpack webpack-cli webpack-dev-server
- Unistall live-server. (npm unistall live-server)
- Update package.json inside frontend folder
- Add "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 src="main.js"></script> before
- Start the server. (npm start)
- Install axios library inside frontend folder. (npm install axios)
- Change fetch to axios in HomeScreen
-
Install Babel For ES6 Syntax
- npm install -D @babel/core @babel/cli @babel/node @babel/preset-env
- Create .babelrc and set presets to @babel/preset-env in the root folder
- npm install -D nodemon
- Set start: nodemon --watch backend --exec babel-node backend/server.js in package.json located in the root folder
- 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 in the root folder
- Set VSCode setting for editor.codeActionsOnSave source.fixAll.eslint to true
- Check result for linting error
- npm install -D eslint-config-airbnb-base 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
- npm install -D eslint-config-prettier in the root folder
- Add 'prettier' in the extends section in .eslintrc.js
- HTML&LESS grammar injections
-
Create Rating Component
- Create components/Rating.js
- Create div.rating
- Link to fontawesome.css in index.html
- Define Rating object with render()
- If !props.value return empty div
- Else use fa fa-star, fa-start-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 in product screen
- Implement /api/product/:id api
- Send AJAX request to product api
-
Product Screen UI
- Create back to result link
- Create div.results with 3 columns
- Column 1 for product image
- Column 2 for product information
- Column 3 for prodcut 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
- Define cartItems = getCartItems() inside CartScreen.js
- Create 2 columns for cart items and cart action
- cartItems.length === 0 ? cart is empty
- Show item image, name, quantity and price
- Cart action
- Subtotal
- Proceed to Checkout button
- Add CSS style
-
Update and Delete Cart Items
- Add qty select next to each item in CartScreen.js
- Implement after_render() function
- Add change event to qty select
- getCartItems() and pass to addToCart()
- Set force to true to addToCart()
- Create rerender() as (component, areaName = 'content') in util.js
- 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 in the root directory
- Connect to mongodb inside server.js
- Create config.js inside backend
- npm install dotenv to the root directory
- Create .env file in the root directory
- Export PORT and MONGODB_URL inside .env file
- Create models/userModel.js file inside backend folder
- Create userSchema and User, and export it
- Create routers/userRouter.js file in backend folder
- Use userRouter inside server.js located in backend folder
- 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 then return 401 error
- npm install body-parser in the root directory
- Import bodyParser inside server.js
- npm install express-async-handler
- Wrap it in expressAsyncHandler
- Add error middleware in server.js
- Install Postman
- Sent post request
- Test with invalid user password
- Otherwise generate token
- Install jsonwebtoken
- Create backend/utils.js file
- Add generateToken to utils.js
- Set config.JWT_SECRET to somethingsecret
- 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 in util.js inside frontend
- 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 step 4
- Create redirectUser() in utils.js in Frontend
- 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