├── .all-contributorsrc ├── .github └── FUNDING.yml ├── .gitignore ├── .snyk ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── components ├── head.js └── topBar.js ├── config ├── passport.js └── secret.js ├── ecosystem.config.js ├── models ├── admin.js ├── facebook.js ├── product.js └── user.js ├── package-lock.json ├── package.json ├── pages ├── addProductAdmin.js ├── addToCart.js ├── editDeleteProduct.js ├── editProductForm.js ├── editShowProduct.js ├── index.js ├── loggedIn.js ├── loginAdmin.js ├── loginUser.js ├── productDetails.js ├── showProduct.js └── signup.js ├── server.js └── static ├── No_Image_Available.jpg ├── ReactToastify.css ├── addToCart.png ├── available-now.png ├── favicon.png ├── img_avatar1.png ├── out-of-stock.png └── style.css /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "viveksharmaui", 10 | "name": "Vivek Anand Sharma", 11 | "avatar_url": "https://avatars1.githubusercontent.com/u/28563357?v=4", 12 | "profile": "https://viveksharmaui.js.org", 13 | "contributions": [ 14 | "test", 15 | "code", 16 | "doc", 17 | "infra", 18 | "bug" 19 | ] 20 | }, 21 | { 22 | "login": "sa-js", 23 | "name": "sa-js", 24 | "avatar_url": "https://avatars3.githubusercontent.com/u/17095740?v=4", 25 | "profile": "http://linkedin.com/in/saeeddev", 26 | "contributions": [ 27 | "code" 28 | ] 29 | }, 30 | { 31 | "login": "Mudassar045", 32 | "name": "Mudassar Ali", 33 | "avatar_url": "https://avatars0.githubusercontent.com/u/24487349?v=4", 34 | "profile": "https://github.com/Mudassar045", 35 | "contributions": [ 36 | "doc" 37 | ] 38 | }, 39 | { 40 | "login": "Alwaz", 41 | "name": "Alwaz", 42 | "avatar_url": "https://avatars.githubusercontent.com/u/49204941?v=4", 43 | "profile": "https://github.com/Alwaz", 44 | "contributions": [ 45 | "code" 46 | ] 47 | } 48 | ], 49 | "contributorsPerLine": 7, 50 | "projectName": "E-Commerce", 51 | "projectOwner": "devcreatives", 52 | "repoType": "github", 53 | "repoHost": "https://github.com", 54 | "skipCi": true 55 | } 56 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | custom: https://liberapay.com/DevCreatives/donate 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode 3 | .next 4 | -------------------------------------------------------------------------------- /.snyk: -------------------------------------------------------------------------------- 1 | # Snyk (https://snyk.io) policy file, patches or ignores known vulnerabilities. 2 | version: v1.13.5 3 | ignore: {} 4 | # patches apply the minimum changes required to fix a vulnerability 5 | patch: 6 | SNYK-JS-LODASH-450202: 7 | - next > styled-jsx > babel-types > lodash: 8 | patched: '2019-07-04T00:32:32.315Z' 9 | - lodash: 10 | patched: '2019-07-04T00:32:32.315Z' 11 | - mongoose > async > lodash: 12 | patched: '2019-07-04T00:32:32.315Z' 13 | - pm2 > async > lodash: 14 | patched: '2019-07-04T00:32:32.315Z' 15 | - next > write-file-webpack-plugin > lodash: 16 | patched: '2019-07-04T00:32:32.315Z' 17 | - next > webpackbar > lodash: 18 | patched: '2019-07-04T00:32:32.315Z' 19 | - next > autodll-webpack-plugin > lodash: 20 | patched: '2019-07-04T00:32:32.315Z' 21 | - next > @babel/core > lodash: 22 | patched: '2019-07-04T00:32:32.315Z' 23 | - pm2 > @pm2/js-api > async > lodash: 24 | patched: '2019-07-04T00:32:32.315Z' 25 | - next > webpackbar > table > lodash: 26 | patched: '2019-07-04T00:32:32.315Z' 27 | - next > webpackbar > consola > lodash: 28 | patched: '2019-07-04T00:32:32.315Z' 29 | - cloudinary > lodash: 30 | patched: '2019-07-04T00:32:32.315Z' 31 | - next > autodll-webpack-plugin > webpack-merge > lodash: 32 | patched: '2019-07-04T00:32:32.315Z' 33 | - next > @babel/core > @babel/types > lodash: 34 | patched: '2019-07-04T00:32:32.315Z' 35 | - pm2 > pm2-deploy > async > lodash: 36 | patched: '2019-07-04T00:32:32.315Z' 37 | - pm2 > vizion > async > lodash: 38 | patched: '2019-07-04T00:32:32.315Z' 39 | - next > @babel/plugin-transform-runtime > @babel/helper-module-imports > @babel/types > lodash: 40 | patched: '2019-07-04T00:32:32.315Z' 41 | - next > @babel/preset-env > @babel/plugin-transform-async-to-generator > @babel/helper-module-imports > @babel/types > lodash: 42 | patched: '2019-07-04T00:32:32.315Z' 43 | - next > @babel/preset-env > @babel/plugin-proposal-async-generator-functions > @babel/helper-remap-async-to-generator > @babel/helper-annotate-as-pure > @babel/types > lodash: 44 | patched: '2019-07-04T00:32:32.315Z' 45 | - next > @babel/plugin-proposal-class-properties > @babel/helper-replace-supers > @babel/traverse > @babel/helper-function-name > @babel/template > @babel/types > lodash: 46 | patched: '2019-07-04T00:32:32.315Z' 47 | - next > @babel/preset-env > @babel/plugin-transform-async-to-generator > @babel/helper-remap-async-to-generator > @babel/helper-wrap-function > @babel/helper-function-name > @babel/template > @babel/types > lodash: 48 | patched: '2019-07-04T00:32:32.315Z' 49 | - next > @babel/preset-env > @babel/plugin-proposal-async-generator-functions > @babel/helper-remap-async-to-generator > @babel/helper-wrap-function > @babel/traverse > @babel/helper-function-name > @babel/helper-get-function-arity > @babel/types > lodash: 50 | patched: '2019-07-04T00:32:32.315Z' 51 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "E-Commerce" will be documented in this file. 4 | 5 | ## E-Commerce [1.0.0] - 2019-09-01 (Released) 6 | ### Added 7 | - Added whole E-commerce website prototype added by [@viveksharmaui](https://github.com/viveksharmaui). 8 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, sex characteristics, gender identity and expression, 9 | level of experience, education, socio-economic status, nationality, personal 10 | appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at sharma_vivek62@yahoo.com. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html 72 | 73 | [homepage]: https://www.contributor-covenant.org 74 | 75 | For answers to common questions about this code of conduct, see 76 | https://www.contributor-covenant.org/faq 77 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contribution instructions 2 | 3 | ## Shipping a new functionality 4 | 5 | 1. You can only contribute on master branch. 6 | 2. Fork this repo. 7 | 3. Pull master branch. 8 | 4. Contribute something great. 9 | 5. Don't forget to write unit/integration/e2e/stress test. 10 | 6. Create pull request of your branch to latest master branch. 11 | 7. Wait for Netlify CI/CD test to be passed. 12 | 8. Wait for reviewer to review pull request file changes (This process can take upto few day's so relax). 13 | 9. Wait for admistrator to merge pull request with master branch. 14 | 10. After doing all above steps now wait to see your changes in master and in production (This process can takes upto few weeks or months when we RELEASED new version). 15 | 16 | 17 | **Happy Contributing** 18 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 E-Commerce 4 | 5 | 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: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | 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. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

E-Commerce Website

3 | 4 |

5 | 6 | 7 | 8 |

9 | 10 | 11 | 12 | 13 | 14 | ## Introduction 15 | 16 | E-Commerce website is written for those who want to experiment with MERN Stack and Next JS. 17 | 18 | ## What we are achieving to do 19 | 20 | The purpose behind this is to create a best E-Commerce system. 21 | 22 | ## What is our goal 23 | 24 | Our goal is to make this website as simple as possible and as user friendly as possible. 25 | 26 | ## Report a bug 27 | 28 | If you find any bug, please create an issue in [issues](https://github.com/Techistan/E-Commerce/issues) section. So that our team will fix them as soon as possible. 29 | 30 | ## How you can contribute 31 | 32 | This extension is Open Source and anyone can contribute. We are always ready for new ideas and functionalities so pull requests are always welcome or see [CONTRIBUTING.md](./CONTRIBUTING.md) file for more information. 33 | 34 | 35 | **Happy Contributing** 36 | ## Contributors ✨ 37 | 38 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 |

Vivek Anand Sharma

⚠️ 💻 📖 🚇 🐛

sa-js

💻

Mudassar Ali

📖

Alwaz

💻
51 | 52 | 53 | 54 | 55 | 56 | 57 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome! 58 | -------------------------------------------------------------------------------- /components/head.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//Importing react 2 | import Head from 'next/head';//Importing head from next.js 3 | 4 | export default class extends React.Component {//This class extends react components 5 | render() {//render() is use to show the data on frontend 6 | return (// return() returns the element 7 | 8 | E Commerce Website 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | ) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /components/topBar.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Head from '../components/head';//import head.js component file 3 | import Link from 'next/link'; 4 | import Appbar from 'muicss/lib/react/appbar';//import appbar from muicss library 5 | import Dropdown from 'muicss/lib/react/dropdown';//import dropdown from muicss library 6 | import DropdownItem from 'muicss/lib/react/dropdown-item';//import dropdown from muicss library 7 | import { bubble as Menu } from 'react-burger-menu'; 8 | export default class extends React.Component {//this default class will extends react component 9 | render() {//render() will render the elements in browser 10 | return (//return() will return those elements 11 |
{/*main content*/} 12 | 13 | 14 |
15 |

E-Commerce Website

16 |
17 | 18 | Home 19 |
20 | Login As User 21 |
22 | Login As Admin 23 |
24 | Signup As User 25 |
26 |
27 |
28 | ); 29 | } 30 | } -------------------------------------------------------------------------------- /config/passport.js: -------------------------------------------------------------------------------- 1 | //Import Libraries 2 | const passport = require('passport');//Using Module passport for authentication of user 3 | const Strategy = require('passport-local').Strategy; //Using passport-local strateg of passport 4 | 5 | //Import Files 6 | const User = require('../models/user');//Invoking user.js model 7 | const Admin = require('../models/admin');//Invoking user.js model 8 | 9 | 10 | 11 | //Using passport strategy user 12 | passport.use('user', new Strategy(function (username, password, done) { 13 | //compare username if same return user else return false 14 | User.findOne({ username: username }, function (err, user) { 15 | if (err) return done(err); 16 | if (!user) { 17 | return done(null, false); 18 | } 19 | if (!user.comparePassword(password)) { 20 | return done(null, false); 21 | } 22 | return done(null, user); 23 | }); 24 | })); 25 | 26 | //Using passport strategy admin 27 | passport.use('admin', new Strategy(function (username, password, done) { 28 | //compare username if same return user else return false 29 | Admin.findOne({ username: username }, function (err, user) { 30 | if (err) return done(err); 31 | if (!user) { 32 | return done(null, false); 33 | } 34 | if (!user.comparePassword(password)) { 35 | return done(null, false); 36 | } 37 | return done(null, user); 38 | }); 39 | })); 40 | 41 | //passport Serialization 42 | passport.serializeUser(function (user, done) { 43 | done(null, user._id); //serializing the id's of user or admin 44 | }); 45 | 46 | 47 | //passport Deserialize 48 | passport.deserializeUser(function (id, done) { 49 | 50 | User.findById(id, function (err, user) {//find the user by id 51 | 52 | if (err) return done(err); 53 | 54 | if (user) { 55 | done(null, user); //return user 56 | } 57 | else { //else will call when no user return 58 | Admin.findById(id, function (err, admin) {//find the google users by id 59 | 60 | if (err) return done(err); 61 | 62 | if (admin) { 63 | done(null, admin); //return google user 64 | } 65 | }) 66 | 67 | } 68 | }) 69 | 70 | }); 71 | 72 | module.exports = passport;//return the passport.js to other node.js files 73 | -------------------------------------------------------------------------------- /config/secret.js: -------------------------------------------------------------------------------- 1 | //module.exports will use to use this data to other nodejs files 2 | module.exports = { 3 | database: 'mongodb://sharmavivek:sharmavivek123@ds119171.mlab.com:19171/ecommerce', 4 | port: process.env.PORT, 5 | key: 'vivek', 6 | cloudName: 'dwl34s9au', 7 | APIKey: '849874246146269', 8 | APISecret: 'VU345KhOqF8cRZzE_qEdfqFyL7g', 9 | AKVersion: 'v1.0', 10 | AK_appId: '115882382405015', 11 | AK_appSecret: '983e94cc99c5871e045f785ddcdaf8df', 12 | AK_userInfo: 'https://graph.accountkit.com/v1.0/me', 13 | AK_AccessToken: 'https://graph.accountkit.com/v1.0/access_token', 14 | multerURL: './static/uploads/img/' 15 | } 16 | -------------------------------------------------------------------------------- /ecosystem.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | apps : [{ 3 | name : 'API', 4 | script : 'server.js', 5 | instances : 'max', 6 | exec_mode : "cluster", 7 | kill_timeout : 1000, 8 | max_memory_restart : "30M", 9 | env: { 10 | NODE_ENV: 'development' 11 | }, 12 | env_production : { 13 | PORT:process.env.PORT, 14 | NODE_ENV: 'production' 15 | } 16 | }], 17 | }; 18 | -------------------------------------------------------------------------------- /models/admin.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose');//Using Module mongoose for Database 2 | const Schema = mongoose.Schema;//schema will map to mongoose collection and define the shape of documents within that collection 3 | const bcrypt = require('bcrypt-nodejs');//Using Module bcrypt-nodejs for encrypt the password 4 | 5 | //create the new schema of userModel for user 6 | const userModel = new Schema({ 7 | username: { type: String, unique: true, lowercase: true }, 8 | password: String, 9 | role: String 10 | 11 | }) 12 | 13 | //before saving the userModel in schema encrypt user password 14 | userModel.pre('save', function (next) { 15 | const user = this;//invoke userModel in const user 16 | 17 | bcrypt.genSalt(10, function (err, salt) { 18 | if (err) return next(err); 19 | bcrypt.hash(user.password, salt, null, function (err, hash) { 20 | if (err) return next(err) 21 | user.password = hash;//store hash in user password 22 | next();//invoke next function 23 | }) 24 | }) 25 | }) 26 | 27 | //compare password 28 | userModel.methods.comparePassword = function (password) { 29 | return bcrypt.compareSync(password, this.password); 30 | //Return either True or False 31 | } 32 | 33 | module.exports = mongoose.model('Admin', userModel);//exporting the userModel as a key User 34 | -------------------------------------------------------------------------------- /models/facebook.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose');//Using Module mongoose for Database 2 | const Schema = mongoose.Schema;//schema will map to mongoose collection and define the shape of documents within that collection 3 | const bcrypt = require('bcrypt-nodejs');//Using Module bcrypt-nodejs for encrypt the password 4 | 5 | //create the new schema of userModel for user 6 | const userModel = new Schema({ 7 | userId: String, 8 | role: String 9 | }) 10 | 11 | //before saving the userModel in schema encrypt user password 12 | userModel.pre('save', function (next) { 13 | const user = this;//invoke userModel in const user 14 | 15 | bcrypt.genSalt(10, function (err, salt) { 16 | if (err) return next(err); 17 | bcrypt.hash(user.password, salt, null, function (err, hash) { 18 | if (err) return next(err) 19 | user.password = hash;//store hash in user password 20 | next();//invoke next function 21 | }) 22 | }) 23 | }) 24 | 25 | //compare password 26 | userModel.methods.comparePassword = function (password) { 27 | return bcrypt.compareSync(password, this.password); 28 | //Return either True or False 29 | } 30 | 31 | module.exports = mongoose.model('Facebook', userModel);//exporting the userModel as a key User 32 | -------------------------------------------------------------------------------- /models/product.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose');//Using Module mongoose for Database 2 | const Schema = mongoose.Schema;//schema will map to mongoose collection and define the shape of documents within that collection 3 | 4 | 5 | //create the new schema of userModel for user 6 | const products = new Schema({ 7 | name: String, 8 | price: String, 9 | category: String, 10 | image: String, 11 | inStock: String, 12 | stockItem: String 13 | }) 14 | 15 | module.exports = mongoose.model('Products', products);//exporting the userModel as a key User 16 | -------------------------------------------------------------------------------- /models/user.js: -------------------------------------------------------------------------------- 1 | const mongoose = require('mongoose');//Using Module mongoose for Database 2 | const Schema = mongoose.Schema;//schema will map to mongoose collection and define the shape of documents within that collection 3 | const bcrypt = require('bcrypt-nodejs');//Using Module bcrypt-nodejs for encrypt the password 4 | 5 | //create the new schema of userModel for user 6 | const userModel = new Schema({ 7 | username: { type: String, unique: true, lowercase: true }, 8 | password: String, 9 | role: String 10 | 11 | }) 12 | 13 | //before saving the userModel in schema encrypt user password 14 | userModel.pre('save', function (next) { 15 | const user = this;//invoke userModel in const user 16 | bcrypt.genSalt(10, function (err, salt) { 17 | if (err) return next(err); 18 | bcrypt.hash(user.password, salt, null, function (err, hash) { 19 | if (err) return next(err) 20 | user.password = hash;//store hash in user password 21 | next();//invoke next function 22 | }) 23 | }) 24 | }) 25 | 26 | //compare password 27 | userModel.methods.comparePassword = function (password) { 28 | return bcrypt.compareSync(password, this.password); 29 | //Return either True or False 30 | } 31 | 32 | module.exports = mongoose.model('User', userModel);//exporting the userModel as a key User 33 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ecommerce", 3 | "version": "1.0.0", 4 | "description": "ecommerce website", 5 | "main": "server.js", 6 | "scripts": { 7 | "dev": "node server.js -p $PORT", 8 | "build": "next build", 9 | "heroku-postbuild": "next build", 10 | "start": "pm2-runtime start ecosystem.config.js --env production", 11 | "snyk-protect": "snyk protect", 12 | "prepublish": "npm run snyk-protect" 13 | }, 14 | "repository": { 15 | "type": "git", 16 | "url": "git+https://github.com/viveksharmaui/E-Commerce.git" 17 | }, 18 | "author": "Vivek Sharma", 19 | "license": "ISC", 20 | "bugs": { 21 | "url": "https://github.com/viveksharmaui/E-Commerce/issues" 22 | }, 23 | "homepage": "https://github.com/viveksharmaui/E-Commerce#readme", 24 | "dependencies": { 25 | "axios": "^0.21.1", 26 | "bcrypt-nodejs": "0.0.3", 27 | "body-parser": "^1.18.3", 28 | "cloudinary": "^1.11.0", 29 | "cookie-parser": "^1.4.3", 30 | "express": "^4.16.3", 31 | "express-session": "^1.15.6", 32 | "guid": "0.0.12", 33 | "lodash": "^4.17.10", 34 | "mongoose": "^5.1.7", 35 | "muicss": "^0.10.3", 36 | "multer": "^1.3.0", 37 | "next": "^11.1.3", 38 | "passport": "^0.4.0", 39 | "passport-local": "^1.0.0", 40 | "pm2": "^5.1.0", 41 | "querystring": "^0.2.0", 42 | "react": "^17.0.2", 43 | "react-burger-menu": "^3.0.6", 44 | "react-dom": "^17.0.2", 45 | "react-stripe-checkout": "^2.6.3", 46 | "react-toastify": "^7.0.4", 47 | "request": "^2.87.0", 48 | "snyk": "^1.189.0", 49 | "stripe": "^8.165.0" 50 | }, 51 | "engines": { 52 | "node": "6.11.x" 53 | }, 54 | "snyk": true 55 | } 56 | -------------------------------------------------------------------------------- /pages/addProductAdmin.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Head from '../components/head';//import head.js component file 3 | import Link from 'next/link'; 4 | import Appbar from 'muicss/lib/react/appbar';//import appbar from muicss library 5 | import Input from 'muicss/lib/react/input';//import input from muicss library 6 | import Form from 'muicss/lib/react/form';//import from from muicss library 7 | import Button from 'muicss/lib/react/button';//import button from muicss library 8 | export default class extends React.Component {//this default class will extends react component 9 | constructor(props) { 10 | super(props); 11 | this.showInput = this.showInput.bind(this); 12 | } 13 | 14 | componentDidMount() { 15 | $("#stockItem").hide(); 16 | } 17 | showInput() { 18 | $("#stockItem").toggle(); 19 | } 20 | render() {//render() will render the elements in browser 21 | return (//return() will return those elements 22 |
{/*main content*/} 23 | 24 | 25 |
26 |

E-Commerce Website

27 |
28 |
29 | 30 |
31 |
32 |
33 | 34 | 35 | 71 |
72 |
73 |
74 | 75 |
76 |
77 | 78 | 100 |
101 | ) 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /pages/addToCart.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Head from '../components/head';//import head.js component file 3 | import Appbar from 'muicss/lib/react/appbar';//import appbar from muicss library 4 | import Form from 'muicss/lib/react/form';//import from from muicss library 5 | import Button from 'muicss/lib/react/button';//import button from muicss library 6 | import Product from './showProduct';//import products from showProduct file 7 | import Input from 'muicss/lib/react/input';//import input from muicss library 8 | import Link from 'next/link'; 9 | import { ToastContainer, toast } from 'react-toastify'; 10 | import axios from 'axios'; 11 | import { bubble as Menu } from 'react-burger-menu'; 12 | import _ from 'lodash'; 13 | export default class extends React.Component {//this default class will extends react component 14 | 15 | constructor(props) { 16 | super(props); 17 | this.state = { addToCart: [], notLoggedIn: this.props.url.query.status } 18 | this.showImage = this.showImage.bind(this); 19 | this.checkArray = this.checkArray.bind(this); 20 | this.removeItemCart = this.removeItemCart.bind(this); 21 | this.saveRemoveItemCart = this.saveRemoveItemCart.bind(this); 22 | } 23 | 24 | componentDidMount() { 25 | let data = JSON.parse(localStorage.getItem("addToCartItems")); 26 | console.log(data); 27 | this.setState({ addToCart: data }); 28 | } 29 | 30 | showImage(a) { 31 | if (a == "on") { 32 | return () 33 | } 34 | } 35 | 36 | clearItem() { 37 | localStorage.removeItem("addToCartItems"); 38 | window.location = "./loggedIn"; 39 | } 40 | 41 | removeItemCart(Id) { 42 | var Array = this.state.addToCart; 43 | if (Id == Array.length) { 44 | Array.pop(); 45 | } 46 | else if (Id > Array.length) { 47 | Array.shift(); 48 | } 49 | else { 50 | Array.splice(Id, 1); 51 | } 52 | console.log(Array); 53 | this.saveRemoveItemCart(); 54 | } 55 | saveRemoveItemCart() { 56 | var Array = JSON.stringify(this.state.addToCart); 57 | localStorage.setItem("addToCartItems", Array); 58 | } 59 | removeItem(Id, name, e) { 60 | console.log("Array " + this.state.addToCart.length); 61 | console.log("Id " + Id); 62 | toast.success("Removing " + name + " From Cart !!", { 63 | position: toast.POSITION.TOP_RIGHT 64 | }); 65 | this.removeItemCart(Id); 66 | this.checkArray(Id); 67 | } 68 | checkArray(Id) { 69 | var Array = this.state.addToCart; 70 | if (Array.length == 0 && this.state.notLoggedIn === "none") { 71 | window.location = "./"; 72 | } 73 | else if (Array.length == 0 && this.state.notLoggedIn !== "none") { 74 | window.location = "./loggedIn"; 75 | } 76 | else { 77 | $("#" + Id).hide(); 78 | } 79 | } 80 | 81 | checkButton() { 82 | if (this.state.notLoggedIn === "none") { 83 | return ( 84 |
85 |
86 | 87 |
88 |
) 89 | } 90 | else { 91 | return ( 92 |
93 | 94 | 95 |
96 |
97 |
98 |
99 |
100 | 101 |
102 |
103 |
104 |
105 |
106 |
107 | 108 |
109 |
110 |
) 111 | } 112 | } 113 | 114 | lastButton(response, i) { 115 | if (this.state.notLoggedIn === "none") { 116 | return ( 117 |
118 | 119 |
120 | ) 121 | } 122 | else { 123 | return (
124 | 125 | 126 |
127 | E-Commerce Website 139 | {this.checkButton()} 140 | 141 |

142 | 143 |

144 |
145 |
146 | { 147 | this.state.addToCart.reverse().map((response, i) => { 148 | return ( 149 |
150 |
151 | {this.showImage(response.inStock)} 152 | 153 |
154 |

{response.name}

155 |

{response.price}

156 |
157 |
158 | 159 | 160 | 161 | 162 | 163 | 164 |
165 | {this.lastButton(response, i)} 166 |
167 |
168 |
) 169 | }) 170 | } 171 |
172 |
173 |
174 | ) 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /pages/editDeleteProduct.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Head from '../components/head';//import head.js component file 3 | import Link from 'next/link'; 4 | import axios from 'axios'; 5 | import Appbar from 'muicss/lib/react/appbar';//import appbar from muicss library 6 | import Input from 'muicss/lib/react/input';//import input from muicss library 7 | import Form from 'muicss/lib/react/form';//import from from muicss library 8 | import Button from 'muicss/lib/react/button';//import button from muicss library 9 | export default class extends React.Component {//this default class will extends react component 10 | constructor(props) { 11 | super(props); 12 | this.state = { data: [] } 13 | 14 | } 15 | componentWillMount() { 16 | axios.get('/product').then((response) => { 17 | this.setState({ data: response.data }, function () { 18 | }) 19 | }) 20 | } 21 | 22 | warningDelete(Id) { 23 | var deleteProduct = confirm('Are You Sure ?'); 24 | if (deleteProduct == true) { 25 | window.location = "./deleteProduct/?id=" + Id; 26 | } 27 | else { 28 | window.location = "./editDeleteProduct"; 29 | } 30 | } 31 | 32 | render() {//render() will render the elements in browser 33 | return (//return() will return those elements 34 |
{/*main content*/} 35 | 36 | 37 |
38 |

E-Commerce Website

39 |
40 |
41 | 42 |
43 |
44 | 45 |
46 |
47 | { 48 | this.state.data.reverse().map((response, i) => { 49 | return ( 50 |
51 | 52 |
53 |

{response.name}

54 |

{response.price}

55 |
56 |
57 | 58 | 59 | 60 | 61 | 62 | 63 |
64 |
Delete Product 67 |
68 |
) 69 | }) 70 | } 71 |
72 |
73 | ) 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /pages/editProductForm.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Head from '../components/head';//import head.js component file 3 | import Link from 'next/link'; 4 | import Appbar from 'muicss/lib/react/appbar';//import appbar from muicss library 5 | import Input from 'muicss/lib/react/input';//import input from muicss library 6 | import Form from 'muicss/lib/react/form';//import from from muicss library 7 | import Button from 'muicss/lib/react/button';//import button from muicss library 8 | export default class extends React.Component { 9 | constructor(props) { 10 | super(props); 11 | this.state = { data: this.props.url.query }; 12 | this.showInput = this.showInput.bind(this); 13 | } 14 | showCheckbox() { 15 | if (this.state.data.inStock == "on") { 16 | return () 17 | } 18 | else { 19 | return () 20 | } 21 | } 22 | showInput() { 23 | if (this.state.data.inStock == "on") { 24 | return () 25 | } 26 | else { 27 | 28 | return () 29 | } 30 | } 31 | removeImage(e) { 32 | alert("Image Deleted Please Click Update"); 33 | e.preventDefault(); 34 | document.getElementById("imageURL").value = ""; 35 | } 36 | render() { 37 | return ( 38 |
39 | 40 |

Edit Product

41 |
42 | 43 | 44 | 45 | 51 |
52 |
53 | 54 | 55 |
56 |
57 | 58 |
59 |
60 | {this.showCheckbox()} 61 | 62 | {this.showInput()} 63 | 64 |
65 |
66 |
Back 67 |
68 | ) 69 | } 70 | } -------------------------------------------------------------------------------- /pages/editShowProduct.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import axios from 'axios';//import library axios 3 | import Head from '../components/head';//Import head components 4 | import Link from 'next/link'; 5 | export default class extends React.Component {//this default class will extends react component 6 | constructor(props) { 7 | super(props); 8 | this.state = { data: [] } 9 | } 10 | 11 | componentWillMount() { 12 | axios.get('/product').then((response) => { 13 | this.setState({ data: response.data }, function () { 14 | }) 15 | }) 16 | } 17 | 18 | render() {//render() will render the elements in browser 19 | return (//return() will return those elements 20 |
{/*main content*/} 21 |
22 | { 23 | this.state.data.reverse().map((response, i) => { 24 | return ( 25 |
26 | 27 |
28 |

{response.name}

29 |

{response.price}

30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 |
38 | Edit 39 |
40 |
) 41 | }) 42 | } 43 |
44 |
45 | ); 46 | 47 | } 48 | } -------------------------------------------------------------------------------- /pages/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Topbar from '../components/topBar';//import topBar 3 | import Product from './showProduct';//import products from showProduct file 4 | import Link from 'next/link'; 5 | export default class extends React.Component {//this default class will extends react component 6 | render() {//render() will render the elements in browser 7 | return (//return() will return those elements 8 |
{/*main content*/} 9 | 10 | 11 |
12 | ); 13 | } 14 | } -------------------------------------------------------------------------------- /pages/loggedIn.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Head from '../components/head';//import head.js component file 3 | import Appbar from 'muicss/lib/react/appbar';//import appbar from muicss library 4 | import Form from 'muicss/lib/react/form';//import from from muicss library 5 | import Button from 'muicss/lib/react/button';//import button from muicss library 6 | import Product from './showProduct';//import products from showProduct file 7 | import Link from 'next/link'; 8 | import { ToastContainer, toast } from 'react-toastify'; 9 | import axios from 'axios'; 10 | import { bubble as Menu } from 'react-burger-menu'; 11 | import _ from 'lodash'; 12 | export default class extends React.Component {//this default class will extends react component 13 | 14 | constructor(props) { 15 | super(props); 16 | this.state = { data: [], totalProduct: [], product: [], addToCart: [], username: this.props.url.query.username } 17 | this.showImage = this.showImage.bind(this); 18 | this.newProductToast = this.newProductToast.bind(this); 19 | this.greetings = this.greetings.bind(this); 20 | } 21 | 22 | componentDidMount() { 23 | this.greetings(); 24 | axios.get('/category').then((response) => { 25 | for (var i = 0; i < response.data.length; i++) { 26 | this.setState({ data: this.state.data.concat(response.data[i].category) }) 27 | } 28 | this.setState({ data: _.uniq(this.state.data) }) 29 | }); 30 | axios.get('/product').then((response) => { 31 | this.setState({ product: response.data, totalProduct: response.data }, function () { 32 | }) 33 | }) 34 | var cartJSON = JSON.parse(localStorage.getItem("addToCartItems")); 35 | if (cartJSON === null) { 36 | this.setState({ addToCart: [] }); 37 | document.getElementById('addToCartLength').innerHTML = '0' 38 | } 39 | else { 40 | this.setState({ addToCart: cartJSON }); 41 | document.getElementById('addToCartLength').innerHTML = cartJSON.length; 42 | } 43 | setInterval(this.newProductToast, 10000); 44 | } 45 | 46 | greetings() { 47 | if (this.state.username == undefined) { 48 | 49 | } 50 | else { 51 | toast.error("Welcome User : " + this.state.username, { 52 | position: toast.POSITION.TOP_LEFT, 53 | autoClose: false, 54 | hideProgressBar: true 55 | }); 56 | } 57 | } 58 | 59 | newProductToast() { 60 | axios.get('/product').then((response) => { 61 | if (response.data.length > this.state.totalProduct.length) { 62 | this.setState({ totalProduct: response.data }, function () { 63 | toast.info("New Product Added !!", { 64 | position: toast.POSITION.TOP_RIGHT, 65 | autoClose: false, 66 | hideProgressBar: true 67 | }); 68 | }) 69 | } 70 | else if (response.data.length < this.state.totalProduct.length) { 71 | this.setState({ totalProduct: response.data }, function () { 72 | }) 73 | } 74 | }) 75 | } 76 | 77 | addToCart(product, e) { 78 | e.preventDefault(); 79 | if (this.state.addToCart != null) { 80 | let counter = 0; 81 | if (product.inStock === "off" || product.stockItem === "0") { 82 | toast.error("This item is out of stock", { 83 | position: toast.POSITION.TOP_RIGHT 84 | }); 85 | } 86 | else { 87 | let addToCart = this.state.addToCart; 88 | if (addToCart.length === 0) { 89 | this.state.addToCart.push(product); 90 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 91 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 92 | toast.success("Adding " + product.name + " To Cart !!", { 93 | position: toast.POSITION.TOP_RIGHT 94 | }); 95 | } 96 | else { 97 | addToCart.map((response, index) => { 98 | if (response._id === product._id) { 99 | toast.error("Your Product is already in the cart", { 100 | position: toast.POSITION.TOP_RIGHT 101 | }); 102 | counter++; 103 | } 104 | }) 105 | if (counter === 0) { 106 | this.state.addToCart.push(product); 107 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 108 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 109 | toast.success("Adding " + product.name + " To Cart !!", { 110 | position: toast.POSITION.TOP_RIGHT 111 | }); 112 | counter = 0; 113 | } 114 | } 115 | } 116 | } 117 | else { 118 | this.state.addToCart.push(product); 119 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 120 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 121 | toast.success("Adding " + product.name + " To Cart !!", { 122 | position: toast.POSITION.TOP_RIGHT 123 | }); 124 | } 125 | } 126 | 127 | renderAddToCart() { 128 | if (this.state.addToCart.length > 0) { 129 | window.location = "./addToCart"; 130 | } 131 | else { 132 | toast.info("No Product In The Cart !!", { 133 | position: toast.POSITION.TOP_RIGHT 134 | }); 135 | } 136 | } 137 | 138 | showProduct(a) { 139 | var array = []; 140 | if (a === 'Recent') { 141 | axios.get('/product').then((response) => { 142 | this.setState({ product: response.data }, function () { 143 | }) 144 | }) 145 | } 146 | else { 147 | axios.get('/product').then((response) => { 148 | for (var i = 0; i < response.data.length; i++) { 149 | if (response.data[i].category === a) { 150 | console.log(response.data[i]); 151 | array.push(response.data[i]); 152 | } 153 | } 154 | if (array.length != 0) { 155 | this.setState({ product: array }); 156 | } 157 | }) 158 | } 159 | } 160 | 161 | showImage(a, Id) { 162 | if (a > 0) { 163 | return () 164 | } 165 | else { 166 | let cartDelete = this.state.addToCart; 167 | let newArray; 168 | let counter = 0; 169 | cartDelete.map((response, index) => { 170 | if (response._id === Id) { 171 | cartDelete.splice(index); 172 | counter++; 173 | } 174 | }) 175 | if (counter > 0) { 176 | localStorage.setItem("addToCartItems", JSON.stringify(cartDelete)); 177 | } 178 | return () 179 | } 180 | } 181 | render() {//render() will render the elements in browser 182 | let product = this.state.product; 183 | if (product.length === 1) { 184 | return (//return() will return those elements 185 |
{/*main content*/} 186 | 187 | 188 |
189 |

E-Commerce Website

190 | 191 |

192 |
193 |

194 | 195 |

196 | 197 | All 198 | { 199 | this.state.data.sort().map((response, i) => { 200 | return {response} 201 | }) 202 | } 203 | 204 |
205 | 206 |
207 |
208 |
209 |
210 | {this.showImage(product[0].stockItem, product[0]._id)} 211 | 212 |
213 |

{product[0].name}

214 |

{product[0].price}

215 |
216 |
217 | 218 | 219 | 220 | 221 | 222 | 223 |
224 | 225 |
226 | E-Commerce Website 241 | 242 |

243 | 244 |

245 | 246 |

247 |
248 | All 249 | { 250 | this.state.data.sort().map((response, i) => { 251 | 252 | return {response} 253 | }) 254 | } 255 |
256 |
257 |
258 |
259 |
260 | 261 |
262 |
263 |
264 |
265 | { 266 | this.state.product.reverse().map((response, i) => { 267 | return ( 268 |
269 | {this.showImage(response.stockItem, response._id)} 270 | 271 |
272 |

{response.name}

273 |

{response.price}

274 |
275 |
276 | 277 | 278 | 279 | 280 | 281 | 282 |
283 | 284 |
285 | 23 |
{/*post the form data to /loginAdmin*/} 24 | 25 | 26 | 27 |
28 |
29 |
30 | ) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /pages/loginUser.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Link from 'next/link';//import link from next.js 3 | import axios from 'axios'; 4 | import Form from 'muicss/lib/react/form';//import from from muicss library 5 | import Input from 'muicss/lib/react/input';//import input from muicss library 6 | import Button from 'muicss/lib/react/button';//import button from muicss library 7 | import TopBar from '../components/topBar';//import TopBary 8 | export default class extends React.Component {//this default class will extends react component 9 | 10 | constructor(props) { 11 | super(props); 12 | this.state = { VIEW: [], status: this.props.url.query.status } 13 | this.smsLogin = this.smsLogin.bind(this); 14 | this.emailLogin = this.emailLogin.bind(this); 15 | } 16 | componentDidMount() { 17 | let status = this.state.status; 18 | if (status === 'wrong') { 19 | window.alert('Invalid Username and Password'); 20 | } 21 | axios.get('/view').then((response) => { 22 | this.setState({ VIEW: response.data }); 23 | // initialize Account Kit with CSRF protection 24 | AccountKit.init( 25 | { 26 | appId: response.data.appId, 27 | state: response.data.csrf, 28 | version: response.data.version, 29 | fbAppEventsEnabled: true 30 | } 31 | ); 32 | }) 33 | } 34 | 35 | smsLogin() { 36 | AccountKit.login( 37 | 'PHONE', {}, function loginCallback(response) { 38 | if (response.status === "PARTIALLY_AUTHENTICATED") { 39 | document.getElementById("code").value = response.code;//authorization code 40 | document.getElementById("csrf").value = response.state;//csrf value generated by loginCallback 41 | document.getElementById("login_success").submit(); 42 | } 43 | else if (response.status === "NOT_AUTHENTICATED") { 44 | // handle authentication failure 45 | } 46 | else if (response.status === "BAD_PARAMS") { 47 | // handle bad parameters 48 | } 49 | } 50 | ) 51 | } 52 | 53 | emailLogin() { 54 | AccountKit.login( 55 | 'EMAIL', {}, function loginCallback(response) { 56 | console.log(response); 57 | if (response.status === "PARTIALLY_AUTHENTICATED") { 58 | document.getElementById("code").value = response.code; 59 | document.getElementById("csrf").value = response.state; 60 | document.getElementById("login_success").submit(); 61 | } 62 | else if (response.status === "NOT_AUTHENTICATED") { 63 | // handle authentication failure 64 | } 65 | else if (response.status === "BAD_PARAMS") { 66 | // handle bad parameters 67 | } 68 | } 69 | ); 70 | } 71 | render() {//render() will render the elements in browser 72 | return (//return() will return those elements 73 |
{/*main content*/} 74 | 75 |
76 |
{/*post the form data to /loginUser*/} 77 | 78 | 79 | 80 |
81 |
82 | 83 | 110 |
111 |
112 |

Click here to Signup

113 |
114 |
115 | ) 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /pages/productDetails.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Head from '../components/head';//import head.js component file 3 | import Appbar from 'muicss/lib/react/appbar';//import appbar from muicss library 4 | import Input from 'muicss/lib/react/input';//import input from muicss library 5 | import Form from 'muicss/lib/react/form';//import from from muicss library 6 | import Button from 'muicss/lib/react/button';//import button from muicss library 7 | import { bubble as Menu } from 'react-burger-menu'; 8 | import StripeCheckout from 'react-stripe-checkout'; 9 | import { ToastContainer, toast } from 'react-toastify'; 10 | import axios from 'axios'; 11 | export default class extends React.Component { 12 | constructor(props) { 13 | super(props); 14 | this.state = { data: this.props.url.query, priceInUSD: 0, addToCart: [] } 15 | this.inStock = this.inStock.bind(this); 16 | this.stockItem = this.stockItem.bind(this); 17 | this.addToCart = this.addToCart.bind(this); 18 | } 19 | 20 | componentDidMount() { 21 | if (this.state.data.inStock == "null" || this.state.data.stockItem == "undefined" || this.state.data.stockItem == "" || this.state.data.stockItem == null || this.state.data.stockItem == 0) { 22 | $('#hide').hide(); 23 | } 24 | else { 25 | $('#hide').show(); 26 | } 27 | var PriceInRuppees = parseInt(this.state.data.price.substring(3)) 28 | var PriceInUSD = (PriceInRuppees / 105.41) * 100; 29 | this.setState({ priceInUSD: PriceInUSD }); 30 | var cartJSON = JSON.parse(localStorage.getItem("addToCartItems")); 31 | if (cartJSON === null) { 32 | this.setState({ addToCart: [] }); 33 | document.getElementById('addToCartLength').innerHTML = '0'; 34 | } 35 | else { 36 | this.setState({ addToCart: cartJSON }); 37 | document.getElementById('addToCartLength').innerHTML = cartJSON.length; 38 | } 39 | } 40 | 41 | onToken = (token) => { 42 | axios.post('/buyNow', { 43 | myToken: token, 44 | userId: document.getElementById('userId').value, 45 | totalStockItem: document.getElementById('totalStockItem').value, 46 | name: document.getElementById('name').value, 47 | image: document.getElementById('image').value, 48 | price: document.getElementById('price').value, 49 | inStock: document.getElementById('inStock').value, 50 | inputStockItem: document.getElementById('inputStockItem').value 51 | }).then((response) => { 52 | window.location.pathname = '/loggedIn'; 53 | }) 54 | } 55 | 56 | handleChange(e) { 57 | let item = document.getElementById("inputStockItem").value; 58 | if (item === "") { 59 | window.alert('Please Provide Stock Item'); 60 | window.location.reload(); 61 | } 62 | e.preventDefault(); 63 | } 64 | 65 | addToCart(product, e) { 66 | e.preventDefault(); 67 | console.log(this.state.addToCart); 68 | if (this.state.addToCart != null) { 69 | let counter = 0; 70 | if (product.inStock === "off" || product.stockItem === "0") { 71 | toast.error("This item is out of stock", { 72 | position: toast.POSITION.TOP_RIGHT 73 | }); 74 | } 75 | else { 76 | let addToCart = this.state.addToCart; 77 | if (addToCart.length === 0) { 78 | this.state.addToCart.push(product); 79 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 80 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 81 | toast.success("Adding " + product.name + " To Cart !!", { 82 | position: toast.POSITION.TOP_RIGHT 83 | }); 84 | } 85 | else { 86 | addToCart.map((response, index) => { 87 | if (response._id === product._id) { 88 | toast.error("Your Product is already in the cart", { 89 | position: toast.POSITION.TOP_RIGHT 90 | }); 91 | counter++; 92 | } 93 | }) 94 | if (counter === 0) { 95 | this.state.addToCart.push(product); 96 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 97 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 98 | toast.success("Adding " + product.name + " To Cart !!", { 99 | position: toast.POSITION.TOP_RIGHT 100 | }); 101 | counter = 0; 102 | } 103 | } 104 | } 105 | } 106 | else { 107 | this.state.addToCart.push(product); 108 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 109 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 110 | toast.success("Adding " + product.name + " To Cart !!", { 111 | position: toast.POSITION.TOP_RIGHT 112 | }); 113 | } 114 | } 115 | 116 | stockItemPriceChange(price) { 117 | var stockItemPrice = parseInt(document.getElementById('stockItem').value) * price; 118 | console.log(stockItemPrice); 119 | } 120 | 121 | 122 | inStock(inStock) { 123 | if (inStock == "off" || inStock == "null") { 124 | return ( 125 |

Not Available

126 |

Stock Item's : None

127 |
) 128 | } 129 | else { 130 | if (this.state.data.stockItem == "undefined" || this.state.data.stockItem == "" || this.state.data.stockItem == null) { 131 | return (

Not Available

132 |

Stock Item : None

133 |
) 134 | } 135 | else { 136 | } 137 | } 138 | } 139 | 140 | stockItem(stockItem) { 141 | if (this.state.data.inStock == "null" || stockItem == "undefined" || stockItem == "" || stockItem == null || !stockItem || stockItem == 0) { 142 | 143 | } 144 | else { 145 | return ( 146 |
147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 |
155 | 156 | 166 | 167 | 168 |
169 | ) 170 | } 171 | } 172 | 173 | renderAddToCart() { 174 | if (this.state.addToCart.length > 0) { 175 | window.location = "./addToCart"; 176 | } 177 | else { 178 | toast.info("No Product In The Cart !!", { 179 | position: toast.POSITION.TOP_RIGHT 180 | }); 181 | } 182 | } 183 | 184 | render() { 185 | return ( 186 |
{/*main content*/} 187 | 188 | 189 |
190 |

E-Commerce Website

191 | 192 |

193 |
194 | 195 |
196 | 197 |
198 |
199 |
200 |
201 | 202 |
203 |
204 |

205 | 206 |

207 |
208 |
209 | 210 |
211 |
212 |

Product Detail's

213 |
214 |

Available

215 |

Stock Item : {this.state.data.stockItem}

216 |
217 | {this.inStock(this.state.data.inStock)} 218 |
219 |

Product Name : {this.state.data.name}

220 |

Product Price : {this.state.data.price}

221 | {this.stockItem(this.state.data.stockItem)} 222 |
223 |
224 |
225 |
226 | ) 227 | } 228 | } -------------------------------------------------------------------------------- /pages/showProduct.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Head from '../components/head';//import head.js component file 3 | import Appbar from 'muicss/lib/react/appbar';//import appbar from muicss library 4 | import Form from 'muicss/lib/react/form';//import from from muicss library 5 | import Button from 'muicss/lib/react/button';//import button from muicss library 6 | import Product from './showProduct';//import products from showProduct file 7 | import Link from 'next/link'; 8 | import { ToastContainer, toast } from 'react-toastify'; 9 | import axios from 'axios'; 10 | import { bubble as Menu } from 'react-burger-menu'; 11 | import _ from 'lodash'; 12 | export default class extends React.Component {//this default class will extends react component 13 | constructor(props) { 14 | super(props); 15 | this.state = { category: [], data: [], addToCart: [] } 16 | } 17 | 18 | showImage(a, Id) { 19 | if (a > 0) { 20 | return () 21 | } 22 | else { 23 | let cartDelete = this.state.addToCart; 24 | let newArray; 25 | let counter = 0; 26 | cartDelete.map((response, index) => { 27 | if (response._id === Id) { 28 | cartDelete.splice(index); 29 | counter++; 30 | } 31 | }) 32 | if (counter > 0) { 33 | localStorage.setItem("addToCartItems", JSON.stringify(cartDelete)); 34 | } 35 | return () 36 | } 37 | } 38 | 39 | renderAddToCart() { 40 | if (this.state.addToCart.length > 0) { 41 | window.location = "./addToCart?status=none"; 42 | } 43 | else { 44 | toast.info("No Product In The Cart !!", { 45 | position: toast.POSITION.TOP_RIGHT 46 | }); 47 | } 48 | } 49 | 50 | addToCart(product, e) { 51 | console.log('invoked'); 52 | e.preventDefault(); 53 | if (this.state.addToCart != null) { 54 | let counter = 0; 55 | if (product.inStock === "off" || product.stockItem === "0") { 56 | toast.error("This item is out of stock", { 57 | position: toast.POSITION.TOP_RIGHT 58 | }); 59 | } 60 | else { 61 | let addToCart = this.state.addToCart; 62 | if (addToCart.length === 0) { 63 | this.state.addToCart.push(product); 64 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 65 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 66 | toast.success("Adding " + product.name + " To Cart !!", { 67 | position: toast.POSITION.TOP_RIGHT 68 | }); 69 | } 70 | else { 71 | addToCart.map((response, index) => { 72 | if (response._id === product._id) { 73 | toast.error("Your Product is already in the cart", { 74 | position: toast.POSITION.TOP_RIGHT 75 | }); 76 | counter++; 77 | } 78 | }) 79 | if (counter === 0) { 80 | this.state.addToCart.push(product); 81 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 82 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 83 | toast.success("Adding " + product.name + " To Cart !!", { 84 | position: toast.POSITION.TOP_RIGHT 85 | }); 86 | counter = 0; 87 | } 88 | } 89 | } 90 | } 91 | else { 92 | this.state.addToCart.push(product); 93 | localStorage.setItem("addToCartItems", JSON.stringify(this.state.addToCart)); 94 | document.getElementById('addToCartLength').innerHTML = this.state.addToCart.length; 95 | toast.success("Adding " + product.name + " To Cart !!", { 96 | position: toast.POSITION.TOP_RIGHT 97 | }); 98 | } 99 | } 100 | 101 | 102 | componentWillMount() { 103 | axios.get('/product').then((response) => { 104 | this.setState({ data: response.data }, function () { 105 | }) 106 | }) 107 | } 108 | 109 | componentDidMount() { 110 | var cartJSON = JSON.parse(localStorage.getItem("addToCartItems")); 111 | if (cartJSON === null) { 112 | this.setState({ addToCart: [] }); 113 | document.getElementById('addToCartLength').innerHTML = '0' 114 | } 115 | else { 116 | this.setState({ addToCart: cartJSON }); 117 | document.getElementById('addToCartLength').innerHTML = cartJSON.length; 118 | } 119 | axios.get('/category').then((response) => { 120 | for (var i = 0; i < response.data.length; i++) { 121 | this.state.category.push(response.data[i].category); 122 | } 123 | this.setState({ category: _.uniq(this.state.category) }) 124 | }); 125 | } 126 | 127 | showProduct(a) { 128 | var array = []; 129 | if (a === 'Recent') { 130 | axios.get('/product').then((response) => { 131 | this.setState({ data: response.data }, function () { 132 | }) 133 | }) 134 | } 135 | else { 136 | axios.get('/product').then((response) => { 137 | for (var i = 0; i < response.data.length; i++) { 138 | if (response.data[i].category === a) { 139 | console.log(response.data[i]); 140 | array.push(response.data[i]); 141 | } 142 | } 143 | if (array.length != 0) { 144 | this.setState({ data: array }); 145 | } 146 | }) 147 | } 148 | } 149 | 150 | render() {//render() will render the elements in browser 151 | return (//return() will return those elements 152 |
153 | 154 |

155 |

156 | 157 |

158 | 168 |
169 | { 170 | this.state.data.reverse().map((response, i) => { 171 | return ( 172 |
173 | {this.showImage(response.stockItem, response._id)} 174 | 175 |
176 |

{response.name}

177 |

{response.price}

178 | 179 |
180 |
) 181 | }) 182 | } 183 |
184 |
185 | ); 186 | 187 | } 188 | } -------------------------------------------------------------------------------- /pages/signup.js: -------------------------------------------------------------------------------- 1 | import React from 'react';//import library react 2 | import Link from 'next/link'; 3 | import Form from 'muicss/lib/react/form';//import from from muicss library 4 | import Input from 'muicss/lib/react/input';//import input from muicss library 5 | import Button from 'muicss/lib/react/button';//import button from muicss library 6 | import TopBar from '../components/topBar';//import TopBary 7 | export default class extends React.Component {//this default class will extends react component 8 | constructor(props) { 9 | super(props); 10 | this.state = { status: this.props.url.query.status } 11 | } 12 | componentDidMount() { 13 | let status = this.state.status; 14 | if (status === 'wrong') { 15 | window.alert('This User Already Exist'); 16 | } 17 | } 18 | render() {//render() will render the elements in browser 19 | return (//return() will return those elements 20 |
{/*main content*/} 21 | 22 |
23 |
24 | 25 | 26 | 27 |
28 |
29 |
30 |

Already have an account ? please Login

31 |
32 | ) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | //Import Libraries 2 | const express = require('express'),//Using Module express for building web application 3 | next = require('next'),//Using Module next for server-side rendering 4 | mongoose = require('mongoose'),//Using Module mongoose for Database 5 | bodyParser = require('body-parser'),//Using Module body-parser for specify the type of the data server use 6 | cookieParser = require('cookie-parser'),//Using Module cookie-parser for parse the cookie 7 | session = require('express-session'),//Using Module express-session for create session 8 | passport = require('passport'),//Using this module for user authentication 9 | Request = require('request'),//Using This Module for sending request to server 10 | Querystring = require('querystring'),//USing this Module for convert JSON into String 11 | Guid = require('guid'),//Using this Module for generating GUID (a Web site may generate a GUID and assign it to a user's browser to record and track the session.) 12 | multer = require('multer'),//Using this Module for upload image's from local path 13 | stripe = require("stripe")("sk_test_qOTpTPUhYPGyLL9bdR97nqIs");//Using this module for payment gateway 14 | const path = require('path'); 15 | const url = require('url'); 16 | const cloudinary = require('cloudinary');//Using this module for storing image to cloud 17 | 18 | //Import File's 19 | const User = require('./models/user');//Invoking user.js model 20 | const Admin = require('./models/admin');//Invoking user.js model 21 | const Facebook = require('./models/facebook');//Invoking facebook.js model 22 | const Product = require('./models/product');//Invoking product.js model 23 | const passportConf = require('./config/passport');//Invoking passport.js file 24 | const secret = require('./config/secret');//Invoking secret file 25 | 26 | 27 | //Cloudinary Configuration 28 | cloudinary.config({ 29 | cloud_name:secret.cloudName, 30 | api_key:secret.APIKey, 31 | api_secret:secret.APISecret 32 | }) 33 | 34 | var csrf_guid = Guid.raw();//Gernerating GUID (global unique identifier) of user browser 35 | const account_kit_api_version = secret.AKVersion;//Facebook Account Kit APP API version 36 | const app_id = secret.AK_appId;//Facebook Account Kit APP Id 37 | const app_secret = secret.AK_appSecret;//Facebook Account Kit APP secret 38 | const me_endpoint_base_url = secret.AK_userInfo;//URL use to get user information 39 | const token_exchange_base_url = secret.AK_AccessToken;//URL use to get access token 40 | 41 | var information = [];//All User information will be stored in this array 42 | 43 | const upload = multer({dest: secret.multerURL}) 44 | 45 | var productInformation = []; 46 | 47 | 48 | 49 | const dev = process.env.NODE_ENV !== 'production' ;//This means that node environment is in development mode 50 | 51 | const port = secret.port; 52 | 53 | const app = next({ dir: '.', dev }); //this will call the node pages in developement mode 54 | 55 | const handle = app.getRequestHandler();//this will handle request all the pages of next 56 | 57 | 58 | //Connect to Db 59 | mongoose.connect(secret.database,(err)=>{ 60 | if(err){console.error(err);} 61 | else{console.log("Database connected");} 62 | }) 63 | 64 | 65 | //When App prepares 66 | app.prepare()//when app prepare do something 67 | .then(() => { 68 | const server = express(); // Invoke methods of express in server constant 69 | 70 | if (!dev) { 71 | // Enforce SSL & HSTS in production 72 | server.use(function(req, res, next) { 73 | var proto = req.headers["x-forwarded-proto"]; 74 | if (proto === "https") { 75 | res.set({ 76 | 'Strict-Transport-Security': 'max-age=31557600' // one-year 77 | }); 78 | return next(); 79 | } 80 | res.redirect("https://" + req.headers.host + req.url); 81 | }); 82 | } 83 | 84 | // Static files 85 | // https://github.com/zeit/next.js/tree/4.2.3#user-content-static-file-serving-eg-images 86 | server.use('/static', express.static(path.join(__dirname, 'static'), { 87 | maxAge: dev ? '0' : '365d' 88 | })); 89 | 90 | 91 | //MIDDLEWARE 92 | server.use(bodyParser.json())//Calling the data in json format 93 | server.use(bodyParser.urlencoded({extended: false}))//no url encoded representation 94 | server.use(cookieParser())//Using Cookie Parser 95 | server.use(session({//Creating session 96 | secret: process.env.SESSION_SECRET || secret.key,//this key will use to check user was already logged in 97 | resave: false,//Forces the session to be saved back to the session store, even if the session was never modified during the request 98 | saveUninitialized:false//Forces a session that is "uninitialized" to be saved to the store. A session is uninitialized when it is new but not modified. 99 | })) 100 | server.use(passport.initialize())//Initializing Passport.js 101 | server.use(passport.session())//Using Session in passport.js 102 | 103 | 104 | server.get('/',(req,res)=>{ 105 | //Check if user is already loggedIn 106 | if(req.user){ 107 | if(req.user.role=="User") 108 | { 109 | return app.render(req,res,'/loggedIn',req.query);//Return loggedIn.js 110 | } 111 | else 112 | { 113 | return app.render(req,res,'/addProductAdmin',req.query); 114 | } 115 | } 116 | else if(req.session.facebook) 117 | { 118 | return app.render(req,res,'/loggedIn',req.query);//Return loggedIn.js 119 | } 120 | else{ 121 | return app.render(req,res,'/index',req.query); 122 | } 123 | }) 124 | 125 | //This API will get facebook account kit information 126 | server.get('/view',(req,res)=>{ 127 | var view = { 128 | appId: app_id, 129 | csrf: csrf_guid, 130 | version: account_kit_api_version, 131 | }; 132 | res.send(view); 133 | 134 | }) 135 | 136 | //This API will get all the product and after getting it shows to user 137 | server.get('/product',(req,res) => { 138 | Product.find({},(err,product) => { 139 | if(err){console.error("Error: ",err)} 140 | else{ 141 | res.json(product); 142 | } 143 | }) 144 | }) 145 | 146 | //This API will get all the product category and after getting it shows to user 147 | server.get('/category',(req,res) => { 148 | Product.find({},'category',(err,product) => { 149 | if(err){console.error("Error: ",err)} 150 | else{ 151 | productInformation = product; 152 | res.json(product); 153 | } 154 | }) 155 | }) 156 | 157 | 158 | server.post('/login_success',(req,res) => { 159 | // CSRF check 160 | //Cross-Site Request Forgery (CSRF) is an attack that forces an end user to execute unwanted actions on a web application in which they're currently authenticated. 161 | if (req.body.csrf === csrf_guid) { 162 | 163 | // Creating session 164 | req.session.facebook="connect.sid"; 165 | 166 | var app_access_token = ['AA', app_id, app_secret].join('|');//This kind of access token is needed to modify and read the app settings.. form :- AA|| 167 | 168 | var params = { 169 | grant_type: 'authorization_code',//An authorization code returned from the SDK is intended to be passed to your server, which exchanges it for an access token. 170 | code: req.body.code,//authorization_code 171 | access_token: app_access_token 172 | }; 173 | var token_exchange_url = token_exchange_base_url + '?' + Querystring.stringify(params);//Retrieving User Access Tokens with an Authorization Code.. form:- https://graph.accountkit.com/v1.2/access_token?grant_type=authorization_code&code=&access_token=AA|| 174 | Request.get(token_exchange_url, function(err,resp,body) { 175 | var view = JSON.parse(body); 176 | var me_endpoint_url = me_endpoint_base_url + '?access_token=' + view.access_token;//Access Token Validation 177 | Request.get(me_endpoint_url, function(err,resp,body) { 178 | information = JSON.parse(body); 179 | Facebook.findOne({userId:information.id},function(err,user){ 180 | if(err){ 181 | console.log('Error'); 182 | } 183 | if(user){ 184 | res.redirect('/loggedIn'); 185 | } 186 | else{ 187 | var user=new Facebook(); 188 | user.userId=information.id; 189 | user.role='User'; 190 | user.save(function(err){ 191 | if(err){ 192 | throw err; 193 | } 194 | else{res.redirect('/signup');} 195 | }); 196 | } 197 | }) 198 | }); 199 | }); 200 | 201 | } 202 | else { 203 | res.send('Sorry Something Went Wrong '); 204 | } 205 | }) 206 | 207 | //This API will send the information of Facebook User 208 | server.get('/login_success', (req, res) => 209 | { 210 | res.send(information); 211 | }) 212 | 213 | //This API will post product data 214 | server.post('/addProduct',upload.single('product'),(req,res) => { 215 | let url ; 216 | let str ; 217 | cloudinary.uploader.upload(req.file.path,function(result) 218 | { 219 | var product = new Product();//Call UserModel in var user 220 | product.name = req.body.name; 221 | product.price = "Rs."+req.body.price; 222 | product.category = req.body.select; 223 | if(req.file==undefined) 224 | { 225 | product.image = "./static/No_Image_Available.jpg"; 226 | } 227 | else 228 | { 229 | url = result.url; 230 | str = url.slice(4); 231 | product.image = "https"+str; 232 | } 233 | if(req.body.inStock=="on") 234 | { 235 | product.inStock = req.body.inStock; 236 | } 237 | else 238 | { 239 | product.inStock = "off"; 240 | } 241 | if(req.body.stockItem == "") 242 | { 243 | product.stockItem ="undefined"; 244 | } 245 | else 246 | { 247 | product.stockItem = req.body.stockItem; 248 | } 249 | product.save((err,user) => { 250 | if(!err){res.redirect('/editDeleteProduct')} 251 | else{console.log(err)} 252 | }) 253 | }) 254 | }) 255 | 256 | //This will add admin in database 257 | server.post('/addAdmin',(req,res) => { 258 | var admin = new Admin();//Call UserModel in var user 259 | admin.username = req.body.username; 260 | admin.password = req.body.password; 261 | admin.role = "Admin"; 262 | admin.save((err,user) => { 263 | if(err){console.error("Error: ", err)} 264 | else{res.redirect('/loginAdmin')} 265 | }) 266 | }) 267 | 268 | //This API will delete the product 269 | server.get('/deleteProduct', function(req, res) { 270 | Product.findByIdAndRemove(req.query.id, (err, product) => { if(err){console.error("Error: ", err)} 271 | else{res.redirect('/editDeleteProduct')} }); 272 | }); 273 | 274 | //This API will update the product 275 | server.post('/productUpdate',upload.single('productImage'), function(req, res) { 276 | let url ; 277 | let str ; 278 | if(req.file==undefined && req.body.productImageURL != "") 279 | { 280 | Product.findOneAndUpdate({_id:req.body.UserId} ,{$set:{name:req.body.name, 281 | price:"Rs."+req.body.price,category:req.body.select,inStock:req.body.inStock, 282 | image:req.body.productImageURL,stockItem:req.body.stockItem} }, (err,user) => { 283 | if(err){console.error("Error: ", err)} 284 | else{res.redirect('/editDeleteProduct')} 285 | }) 286 | } 287 | else if (req.file==undefined && req.body.productImageURL == "") 288 | { 289 | Product.findOneAndUpdate({_id:req.body.UserId} ,{$set:{name:req.body.name, 290 | price:"Rs."+req.body.price,category:req.body.select,inStock:req.body.inStock, 291 | image:"./static/No_Image_Available.jpg",stockItem:req.body.stockItem} }, (err,user) => { 292 | if(err){console.error("Error: ", err)} 293 | else{res.redirect('/editDeleteProduct')} 294 | }) 295 | 296 | } 297 | else 298 | { 299 | cloudinary.uploader.upload(req.file.path,function(result) 300 | { 301 | url = result.url; 302 | str = url.slice(4); 303 | Product.findOneAndUpdate({_id:req.body.UserId} ,{$set:{name:req.body.name, 304 | price:"Rs."+req.body.price,category:req.body.select,inStock:req.body.inStock, 305 | image:"https"+str,stockItem:req.body.stockItem} }, (err,user) => { 306 | if(err){console.error("Error: ", err)} 307 | else{res.redirect('/editDeleteProduct')} 308 | }) 309 | }) 310 | } 311 | }); 312 | 313 | //This API will remove the total stock from user input stock item 314 | server.post('/buyNow', function(req, res) { 315 | var PriceInRuppees = parseInt(req.body.price.substring(3)); 316 | var PriceInUSD = Math.round((PriceInRuppees/105.41)*100); 317 | stripe.charges.create({ 318 | amount: PriceInUSD, 319 | currency: "USD", 320 | description: req.body.name, 321 | source:req.body.myToken.id, 322 | }); 323 | var stockItemAfterTransaction = req.body.totalStockItem - req.body.inputStockItem; 324 | Product.findOneAndUpdate({_id:req.body.userId} ,{$set:{stockItem:stockItemAfterTransaction} }, (err,user) => { 325 | if(err){console.error("Error: "+ err)} 326 | else{ 327 | res.redirect('/loggedIn')} 328 | }) 329 | }); 330 | 331 | //This API Authenticate user by using passport locale 332 | server.post('/loginUser',passport.authenticate('user',{failureRedirect:'/loginUser?status=wrong',failureMessage: "Invalid username or password"}),(req,res) => { 333 | res.redirect('/loggedIn?username='+req.body.username); 334 | }) 335 | 336 | //This API Authenticate admin by using passport locale 337 | server.post('/loginAdmin',passport.authenticate('admin',{failureRedirect:'/loginAdmin?status=wrong',failureMessage: "Invalid username or password"}),(req,res) => { 338 | res.redirect('/addProductAdmin'); 339 | }) 340 | 341 | //This API will create account of users 342 | server.post('/signup',(req,res) => { 343 | var user = new User();//Call UserModel in var user 344 | user.username = req.body.username; 345 | user.password = req.body.password; 346 | user.role = "User"; 347 | user.save((err,user) => { 348 | if(err){res.redirect('/signup?status=wrong')} 349 | else{res.redirect('/loggedIn?username='+req.body.username)} 350 | }) 351 | }) 352 | 353 | 354 | //This API will delete user session and cookie 355 | server.post('/logout', (req, res) => 356 | { 357 | res.clearCookie('connect.sid');//Clear The cookie 358 | req.logout();//delete session of user 359 | res.redirect('/'); 360 | }) 361 | 362 | // Default catch-all renders Next app 363 | server.get('*', (req, res) => { 364 | // res.set({ 365 | // 'Cache-Control': 'public, max-age=3600' 366 | // }); 367 | const parsedUrl = url.parse(req.url, true); 368 | handle(req, res, parsedUrl); 369 | }); 370 | 371 | server.listen(port, (err) => { 372 | if (err) throw err; 373 | console.log(`Listening on http://localhost:${port}`); 374 | }); 375 | }) -------------------------------------------------------------------------------- /static/No_Image_Available.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devcreatives/E-Commerce/edcffc5d43e6132a3938127da4e61826f9cf36e0/static/No_Image_Available.jpg -------------------------------------------------------------------------------- /static/ReactToastify.css: -------------------------------------------------------------------------------- 1 | .Toastify__toast-container { 2 | z-index: 9999; 3 | position: fixed; 4 | padding: 4px; 5 | width: 320px; 6 | box-sizing: border-box; 7 | color: #fff; } 8 | .Toastify__toast-container--top-left { 9 | top: 1em; 10 | left: 1em; } 11 | .Toastify__toast-container--top-center { 12 | top: 1em; 13 | left: 50%; 14 | margin-left: -160px; } 15 | .Toastify__toast-container--top-right { 16 | top: 1em; 17 | right: 1em; } 18 | .Toastify__toast-container--bottom-left { 19 | bottom: 1em; 20 | left: 1em; } 21 | .Toastify__toast-container--bottom-center { 22 | bottom: 1em; 23 | left: 50%; 24 | margin-left: -160px; } 25 | .Toastify__toast-container--bottom-right { 26 | bottom: 1em; 27 | right: 1em; } 28 | 29 | @media only screen and (max-width: 480px) { 30 | .Toastify__toast-container { 31 | width: 100vw; 32 | padding: 0; 33 | left: 0; 34 | margin: 0; } 35 | .Toastify__toast-container--top-left, .Toastify__toast-container--top-center, .Toastify__toast-container--top-right { 36 | top: 0; } 37 | .Toastify__toast-container--bottom-left, .Toastify__toast-container--bottom-center, .Toastify__toast-container--bottom-right { 38 | bottom: 0; } 39 | .Toastify__toast-container--rtl { 40 | right: 0; 41 | left: initial; } } 42 | 43 | .Toastify__toast { 44 | position: relative; 45 | min-height: 64px; 46 | box-sizing: border-box; 47 | margin-bottom: 1rem; 48 | padding: 8px; 49 | border-radius: 1px; 50 | box-shadow: 0 1px 10px 0 rgba(0, 0, 0, 0.1), 0 2px 15px 0 rgba(0, 0, 0, 0.05); 51 | display: -ms-flexbox; 52 | display: flex; 53 | -ms-flex-pack: justify; 54 | justify-content: space-between; 55 | max-height: 800px; 56 | overflow: hidden; 57 | font-family: sans-serif; 58 | cursor: pointer; 59 | direction: ltr; } 60 | .Toastify__toast--rtl { 61 | direction: rtl; } 62 | .Toastify__toast--default { 63 | background: #fff; 64 | color: #aaa; } 65 | .Toastify__toast--info { 66 | background: #3498db; } 67 | .Toastify__toast--success { 68 | background: #07bc0c; } 69 | .Toastify__toast--warning { 70 | background: #f1c40f; } 71 | .Toastify__toast--error { 72 | background: #e74c3c; } 73 | .Toastify__toast-body { 74 | margin: auto 0; 75 | -ms-flex: 1; 76 | flex: 1; } 77 | 78 | @media only screen and (max-width: 480px) { 79 | .Toastify__toast { 80 | margin-bottom: 0; } } 81 | 82 | .Toastify__close-button { 83 | color: #fff; 84 | font-weight: bold; 85 | font-size: 14px; 86 | background: transparent; 87 | outline: none; 88 | border: none; 89 | padding: 0; 90 | cursor: pointer; 91 | opacity: 0.7; 92 | transition: 0.3s ease; 93 | -ms-flex-item-align: start; 94 | align-self: flex-start; } 95 | .Toastify__close-button--default { 96 | color: #000; 97 | opacity: 0.3; } 98 | .Toastify__close-button:hover, .Toastify__close-button:focus { 99 | opacity: 1; } 100 | 101 | @keyframes Toastify__trackProgress { 102 | 0% { 103 | width: 100%; } 104 | 100% { 105 | width: 0; } } 106 | 107 | .Toastify__progress-bar { 108 | position: absolute; 109 | bottom: 0; 110 | left: 0; 111 | width: 0; 112 | height: 5px; 113 | z-index: 9999; 114 | opacity: 0.7; 115 | animation: Toastify__trackProgress linear 1; 116 | background-color: rgba(255, 255, 255, 0.7); } 117 | .Toastify__progress-bar--rtl { 118 | right: 0; 119 | left: initial; } 120 | .Toastify__progress-bar--default { 121 | background: linear-gradient(to right, #4cd964, #5ac8fa, #007aff, #34aadc, #5856d6, #ff2d55); } 122 | 123 | @keyframes Toastify__bounceInRight { 124 | from, 125 | 60%, 126 | 75%, 127 | 90%, 128 | to { 129 | animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); } 130 | from { 131 | opacity: 0; 132 | transform: translate3d(3000px, 0, 0); } 133 | 60% { 134 | opacity: 1; 135 | transform: translate3d(-25px, 0, 0); } 136 | 75% { 137 | transform: translate3d(10px, 0, 0); } 138 | 90% { 139 | transform: translate3d(-5px, 0, 0); } 140 | to { 141 | transform: none; } } 142 | 143 | @keyframes Toastify__bounceOutRight { 144 | 20% { 145 | opacity: 1; 146 | transform: translate3d(-20px, 0, 0); } 147 | to { 148 | opacity: 0; 149 | transform: translate3d(2000px, 0, 0); } } 150 | 151 | @keyframes Toastify__bounceInLeft { 152 | from, 153 | 60%, 154 | 75%, 155 | 90%, 156 | to { 157 | animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); } 158 | 0% { 159 | opacity: 0; 160 | transform: translate3d(-3000px, 0, 0); } 161 | 60% { 162 | opacity: 1; 163 | transform: translate3d(25px, 0, 0); } 164 | 75% { 165 | transform: translate3d(-10px, 0, 0); } 166 | 90% { 167 | transform: translate3d(5px, 0, 0); } 168 | to { 169 | transform: none; } } 170 | 171 | @keyframes Toastify__bounceOutLeft { 172 | 20% { 173 | opacity: 1; 174 | transform: translate3d(20px, 0, 0); } 175 | to { 176 | opacity: 0; 177 | transform: translate3d(-2000px, 0, 0); } } 178 | 179 | @keyframes Toastify__bounceInUp { 180 | from, 181 | 60%, 182 | 75%, 183 | 90%, 184 | to { 185 | animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); } 186 | from { 187 | opacity: 0; 188 | transform: translate3d(0, 3000px, 0); } 189 | 60% { 190 | opacity: 1; 191 | transform: translate3d(0, -20px, 0); } 192 | 75% { 193 | transform: translate3d(0, 10px, 0); } 194 | 90% { 195 | transform: translate3d(0, -5px, 0); } 196 | to { 197 | transform: translate3d(0, 0, 0); } } 198 | 199 | @keyframes Toastify__bounceOutUp { 200 | 20% { 201 | transform: translate3d(0, -10px, 0); } 202 | 40%, 203 | 45% { 204 | opacity: 1; 205 | transform: translate3d(0, 20px, 0); } 206 | to { 207 | opacity: 0; 208 | transform: translate3d(0, -2000px, 0); } } 209 | 210 | @keyframes Toastify__bounceInDown { 211 | from, 212 | 60%, 213 | 75%, 214 | 90%, 215 | to { 216 | animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1); } 217 | 0% { 218 | opacity: 0; 219 | transform: translate3d(0, -3000px, 0); } 220 | 60% { 221 | opacity: 1; 222 | transform: translate3d(0, 25px, 0); } 223 | 75% { 224 | transform: translate3d(0, -10px, 0); } 225 | 90% { 226 | transform: translate3d(0, 5px, 0); } 227 | to { 228 | transform: none; } } 229 | 230 | @keyframes Toastify__bounceOutDown { 231 | 20% { 232 | transform: translate3d(0, 10px, 0); } 233 | 40%, 234 | 45% { 235 | opacity: 1; 236 | transform: translate3d(0, -20px, 0); } 237 | to { 238 | opacity: 0; 239 | transform: translate3d(0, 2000px, 0); } } 240 | 241 | .Toastify__bounce-enter--top-left, .Toastify__bounce-enter--bottom-left { 242 | animation-name: Toastify__bounceInLeft; } 243 | 244 | .Toastify__bounce-enter--top-right, .Toastify__bounce-enter--bottom-right { 245 | animation-name: Toastify__bounceInRight; } 246 | 247 | .Toastify__bounce-enter--top-center { 248 | animation-name: Toastify__bounceInDown; } 249 | 250 | .Toastify__bounce-enter--bottom-center { 251 | animation-name: Toastify__bounceInUp; } 252 | 253 | .Toastify__bounce-exit--top-left, .Toastify__bounce-exit--bottom-left { 254 | animation-name: Toastify__bounceOutLeft; } 255 | 256 | .Toastify__bounce-exit--top-right, .Toastify__bounce-exit--bottom-right { 257 | animation-name: Toastify__bounceOutRight; } 258 | 259 | .Toastify__bounce-exit--top-center { 260 | animation-name: Toastify__bounceOutUp; } 261 | 262 | .Toastify__bounce-exit--bottom-center { 263 | animation-name: Toastify__bounceOutDown; } 264 | 265 | @keyframes Toastify__zoomIn { 266 | from { 267 | opacity: 0; 268 | transform: scale3d(0.3, 0.3, 0.3); } 269 | 50% { 270 | opacity: 1; } } 271 | 272 | @keyframes Toastify__zoomOut { 273 | from { 274 | opacity: 1; } 275 | 50% { 276 | opacity: 0; 277 | transform: scale3d(0.3, 0.3, 0.3); } 278 | to { 279 | opacity: 0; } } 280 | 281 | .Toastify__zoom-enter { 282 | animation-name: Toastify__zoomIn; } 283 | 284 | .Toastify__zoom-exit { 285 | animation-name: Toastify__zoomOut; } 286 | 287 | @keyframes Toastify__flipIn { 288 | from { 289 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 290 | animation-timing-function: ease-in; 291 | opacity: 0; } 292 | 40% { 293 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 294 | animation-timing-function: ease-in; } 295 | 60% { 296 | transform: perspective(400px) rotate3d(1, 0, 0, 10deg); 297 | opacity: 1; } 298 | 80% { 299 | transform: perspective(400px) rotate3d(1, 0, 0, -5deg); } 300 | to { 301 | transform: perspective(400px); } } 302 | 303 | @keyframes Toastify__flipOut { 304 | from { 305 | transform: perspective(400px); } 306 | 30% { 307 | transform: perspective(400px) rotate3d(1, 0, 0, -20deg); 308 | opacity: 1; } 309 | to { 310 | transform: perspective(400px) rotate3d(1, 0, 0, 90deg); 311 | opacity: 0; } } 312 | 313 | .Toastify__flip-enter { 314 | animation-name: Toastify__flipIn; } 315 | 316 | .Toastify__flip-exit { 317 | animation-name: Toastify__flipOut; } 318 | 319 | @keyframes Toastify__slideInRight { 320 | from { 321 | transform: translate3d(110%, 0, 0); 322 | visibility: visible; } 323 | to { 324 | transform: translate3d(0, 0, 0); } } 325 | 326 | @keyframes Toastify__slideInLeft { 327 | from { 328 | transform: translate3d(-110%, 0, 0); 329 | visibility: visible; } 330 | to { 331 | transform: translate3d(0, 0, 0); } } 332 | 333 | @keyframes Toastify__slideInUp { 334 | from { 335 | transform: translate3d(0, 110%, 0); 336 | visibility: visible; } 337 | to { 338 | transform: translate3d(0, 0, 0); } } 339 | 340 | @keyframes Toastify__slideInDown { 341 | from { 342 | transform: translate3d(0, -110%, 0); 343 | visibility: visible; } 344 | to { 345 | transform: translate3d(0, 0, 0); } } 346 | 347 | @keyframes Toastify__slideOutRight { 348 | from { 349 | transform: translate3d(0, 0, 0); } 350 | to { 351 | visibility: hidden; 352 | transform: translate3d(110%, 0, 0); } } 353 | 354 | @keyframes Toastify__slideOutLeft { 355 | from { 356 | transform: translate3d(0, 0, 0); } 357 | to { 358 | visibility: hidden; 359 | transform: translate3d(-110%, 0, 0); } } 360 | 361 | @keyframes Toastify__slideOutUp { 362 | from { 363 | transform: translate3d(0, 0, 0); } 364 | to { 365 | visibility: hidden; 366 | transform: translate3d(0, 110%, 0); } } 367 | 368 | @keyframes Toastify__slideOutDown { 369 | from { 370 | transform: translate3d(0, 0, 0); } 371 | to { 372 | visibility: hidden; 373 | transform: translate3d(0, -110%, 0); } } 374 | 375 | .Toastify__slide-enter--top-left, .Toastify__slide-enter--bottom-left { 376 | animation-name: Toastify__slideInLeft; } 377 | 378 | .Toastify__slide-enter--top-right, .Toastify__slide-enter--bottom-right { 379 | animation-name: Toastify__slideInRight; } 380 | 381 | .Toastify__slide-enter--top-center { 382 | animation-name: Toastify__slideInDown; } 383 | 384 | .Toastify__slide-enter--bottom-center { 385 | animation-name: Toastify__slideInUp; } 386 | 387 | .Toastify__slide-exit--top-left, .Toastify__slide-exit--bottom-left { 388 | animation-name: Toastify__slideOutLeft; } 389 | 390 | .Toastify__slide-exit--top-right, .Toastify__slide-exit--bottom-right { 391 | animation-name: Toastify__slideOutRight; } 392 | 393 | .Toastify__slide-exit--top-center { 394 | animation-name: Toastify__slideOutUp; } 395 | 396 | .Toastify__slide-exit--bottom-center { 397 | animation-name: Toastify__slideOutDown; } 398 | 399 | /*# sourceMappingURL=ReactToastify.css.map */ -------------------------------------------------------------------------------- /static/addToCart.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devcreatives/E-Commerce/edcffc5d43e6132a3938127da4e61826f9cf36e0/static/addToCart.png -------------------------------------------------------------------------------- /static/available-now.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devcreatives/E-Commerce/edcffc5d43e6132a3938127da4e61826f9cf36e0/static/available-now.png -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devcreatives/E-Commerce/edcffc5d43e6132a3938127da4e61826f9cf36e0/static/favicon.png -------------------------------------------------------------------------------- /static/img_avatar1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devcreatives/E-Commerce/edcffc5d43e6132a3938127da4e61826f9cf36e0/static/img_avatar1.png -------------------------------------------------------------------------------- /static/out-of-stock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/devcreatives/E-Commerce/edcffc5d43e6132a3938127da4e61826f9cf36e0/static/out-of-stock.png -------------------------------------------------------------------------------- /static/style.css: -------------------------------------------------------------------------------- 1 | /* Position and sizing of burger button */ 2 | .bm-burger-button { 3 | position: fixed; 4 | width: 36px; 5 | height: 30px; 6 | left: 15px; 7 | top: 15px; 8 | } 9 | 10 | /* Color/shape of burger icon bars */ 11 | .bm-burger-bars { 12 | background: rgba(11,11,11,0.5); 13 | } 14 | 15 | /* Position and sizing of clickable cross button */ 16 | .bm-cross-button { 17 | height: 24px; 18 | width: 24px; 19 | } 20 | 21 | /* Color/shape of close button cross */ 22 | .bm-cross { 23 | background:black; 24 | } 25 | 26 | /* General sidebar styles */ 27 | .bm-menu { 28 | background:whitesmoke; 29 | padding-top:20px; 30 | } 31 | 32 | /* Morph shape necessary with bubble or elastic */ 33 | .bm-morph-shape { 34 | fill:whitesmoke; 35 | } 36 | 37 | /* Wrapper for item list */ 38 | .bm-item-list { 39 | color: #b8b7ad; 40 | } 41 | 42 | /* Styling of overlay */ 43 | .bm-overlay { 44 | background: rgba(0, 0, 0, 0.7); 45 | } 46 | /*Style menu items*/ 47 | .a:link 48 | { 49 | font-family:'Times New Roman', Times, serif; 50 | color:white; 51 | font-size:25px; 52 | padding:50px; 53 | } 54 | .b:nth-child(odd) 55 | { 56 | padding-right:180px; 57 | padding-left:30px; 58 | margin-top:20px; 59 | text-align: center; 60 | background-color:white; 61 | color:black; 62 | font-size:20px; 63 | } 64 | .b:nth-child(even) 65 | { 66 | padding-right:180px; 67 | padding-left:30px; 68 | margin-top:20px; 69 | background-color:white; 70 | color:black; 71 | font-size:20px; 72 | } 73 | .b:hover 74 | { 75 | font-size:21px; 76 | background-color:blue; 77 | } 78 | .a:hover 79 | { 80 | font-size:27px; 81 | text-decoration: none; 82 | color:white; 83 | } 84 | /* Add padding to login user,admin and signup */ 85 | #loginUser,#loginAdmin 86 | { 87 | padding-top:5%; 88 | } 89 | #loginAsUser 90 | { 91 | width:300px; 92 | box-shadow:20px 20px 20px 20px rgba(0, 0, 0, 0.2); 93 | text-align:center; 94 | position: absolute; 95 | left:40%; 96 | } 97 | #loginAsUser img 98 | { 99 | width:300px; 100 | height:300px; 101 | } 102 | #signup 103 | { 104 | font-size:30px; 105 | } 106 | #title 107 | { 108 | text-align: center; 109 | } 110 | #logoutbtn 111 | { 112 | position: absolute; 113 | left: 0; 114 | top: 5px; 115 | } 116 | /* Adding styling to card */ 117 | #product div 118 | { 119 | margin-bottom:20px; 120 | box-shadow:20px 20px 20px hsla(0, 0%, 0%, 0.2); 121 | display: inline-block; 122 | } 123 | #product div h3 124 | { 125 | border:1px solid rgba(0, 0, 0, 0.2); 126 | border-collapse: collapse; 127 | white-space: nowrap; 128 | overflow: hidden; 129 | text-overflow: ellipsis; 130 | padding-bottom:10px; 131 | font-family: cursive; 132 | } 133 | .MenuItem 134 | { 135 | cursor:pointer; 136 | } 137 | #productImage 138 | { 139 | height:400px; 140 | width:300px; 141 | z-index:-1; 142 | box-shadow:10px 10px 10px 10px rgba(22,22,22,0.1); 143 | } 144 | #productDetails 145 | { 146 | margin-top:2%; 147 | margin-left:2%; 148 | position: relative; 149 | top:-40px; 150 | } 151 | #border 152 | { 153 | padding-top:80px; 154 | border-left: 15px solid #2980B9 ; 155 | border-right:15px solid #2980B9; 156 | margin-left:2.5%; 157 | margin-right:76%; 158 | } 159 | #productDetailsBorder 160 | { 161 | border-top:2px solid #2980B9; 162 | border-left: 3px dotted #3498DB; 163 | border-right:3px dotted #3498DB; 164 | } 165 | #productDetailsBorder div 166 | { 167 | padding-top:20px; 168 | } 169 | #productDetailsBorder div h3 170 | { 171 | padding-top:20px; 172 | padding-bottom:20px; 173 | } 174 | #productDetailsBorder div h3:hover 175 | { 176 | background-color: rgba(22,22,22,0.1); 177 | } 178 | #productDetailsBorder div h2 179 | { 180 | text-align: center; 181 | color:#2980B9; 182 | } 183 | #productDetailsBorder div #status 184 | { 185 | text-align: center; 186 | color:rgba(33,33,33,0.4); 187 | } 188 | #inStock 189 | { 190 | font-size:20px; 191 | padding-left:10px; 192 | } 193 | .inStock 194 | { 195 | position: absolute; 196 | left:15px; 197 | } 198 | .outStock 199 | { 200 | position: absolute; 201 | top:-5%; 202 | width:200px; 203 | } 204 | .card-title,.card-text 205 | { 206 | white-space: nowrap; 207 | width: 420px; 208 | overflow: hidden; 209 | text-overflow: ellipsis; 210 | } 211 | #productData 212 | { 213 | visibility: hidden; 214 | } 215 | #addToCartImage 216 | { 217 | position: absolute; 218 | right:30px; 219 | top:0px; 220 | } 221 | #addToCartLength 222 | { 223 | position: absolute; 224 | right:80px; 225 | top:0px; 226 | } 227 | #addToCartProduct 228 | { 229 | box-shadow:20px 20px 20px hsla(0, 0%, 0%, 0.2); 230 | border-right:1px solid black; 231 | width:50%; 232 | } 233 | #addToCartSingle 234 | { 235 | margin-top:20px; 236 | } 237 | #MenuOverflow 238 | { 239 | float: left; 240 | width:10%; 241 | height:100%; 242 | text-align:center; 243 | border-right:1px solid black; 244 | font-size:20px; 245 | word-wrap: break-word; 246 | padding-top:20px; 247 | padding-bottom:20px; 248 | background-color:white; 249 | position:fixed; 250 | z-index:2; 251 | } 252 | #MenuOverflow a:hover 253 | { 254 | color:blue; 255 | } 256 | .showProduct 257 | { 258 | margin-left:200px; 259 | } --------------------------------------------------------------------------------