├── .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 |
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 |
31 |
32 |
33 |
34 | Add Product
35 |
36 |
37 |
38 |
39 |
Add Product
40 |
41 | ×
42 |
43 |
44 |
45 |
64 |
65 |
66 | Close
67 |
68 |
69 |
70 |
71 |
72 |
73 |
76 |
77 | Add Admin
78 |
79 |
80 |
81 |
82 |
Add Admin
83 |
84 | ×
85 |
86 |
87 |
88 |
93 |
94 |
95 | Close
96 |
97 |
98 |
99 |
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 |
88 | )
89 | }
90 | else {
91 | return (
92 |
93 |
94 | Remove All Item
95 |
96 |
97 |
98 |
99 |
102 |
103 |
104 |
105 |
106 |
109 |
110 | )
111 | }
112 | }
113 |
114 | lastButton(response, i) {
115 | if (this.state.notLoggedIn === "none") {
116 | return (
117 |
118 | Remove Item
119 |
120 | )
121 | }
122 | else {
123 | return (
124 |
125 | Remove Item
126 |
127 | Details
128 | )
129 | }
130 | }
131 |
132 | render() {//render() will render the elements in browser
133 | return (//return() will return those elements
134 | {/*main content*/}
135 |
136 |
137 |
138 | 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 |
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 |
43 |
46 |
47 | {
48 | this.state.data.reverse().map((response, i) => {
49 | return (
50 |
51 |
52 |
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 |
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 |
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 |
207 |
208 |
209 |
210 | {this.showImage(product[0].stockItem, product[0]._id)}
211 |
212 |
228 |
229 |
230 |
231 |
232 | )
233 | }
234 | else {
235 | return (//return() will return those elements
236 | {/*main content*/}
237 |
238 |
239 |
240 | 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 |
262 |
263 |
264 |
265 | {
266 | this.state.product.reverse().map((response, i) => {
267 | return (
268 |
269 | {this.showImage(response.stockItem, response._id)}
270 |
271 |
287 |
)
288 | })
289 | }
290 |
291 |
292 |
293 | )
294 | }
295 | }
296 | }
297 |
--------------------------------------------------------------------------------
/pages/loginAdmin.js:
--------------------------------------------------------------------------------
1 | import React from 'react';//import library react
2 | import Link from 'next/link';//import link from next.js
3 | import TopBar from '../components/topBar';//import TopBar
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 | 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('Invalid Username and Password');
16 | }
17 | }
18 | render() {//render() will render the elements in browser
19 | return (//return() will return those elements
20 | {/*main content*/}
21 |
22 |
23 |
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 |
81 |
82 |
Login With Facebook
83 |
84 |
85 |
86 |
87 |
Login With Facebook
88 |
89 | ×
90 |
91 |
92 |
93 | Login via SMS
94 |
95 |
96 |
OR
97 |
98 | Login via Email
99 |
103 |
104 |
105 | Close
106 |
107 |
108 |
109 |
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 |
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 |
198 |
199 |
200 |
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 | Add To Cart
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 |
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 | }
--------------------------------------------------------------------------------