diff --git a/backend/app.js b/backend/app.js index 078ed6b..cc33da3 100644 --- a/backend/app.js +++ b/backend/app.js @@ -1,15 +1,15 @@ +const bcrypt = require('bcryptjs'); +const User = require('./models/User'); +const passport = require('passport'); var mongoose = require('mongoose'); -var prodSchema = require('./models/product'); +var nodemailer = require('nodemailer') +var ejs = require("ejs"); +const { ensureAuthenticated } = require('./config/auth'); +const Product = require('./models/Product'); +var Cart = require('./models/carts') +var Order = require('./models/Order') module.exports = function(app){ - app.get('/products', async (req,res) => { - var prods = await prodSchema.find({}); - //console.log(prods); - res.render('products', {'prods': prods}); - }); - app.get('/', (req,res) => { - res.render('index'); - }); app.get('/contactus', (req,res) => { res.render('contactus'); }); @@ -19,55 +19,300 @@ module.exports = function(app){ app.get('/signup', (req,res) => { res.render('signup'); }); - app.get('/cart', (req,res) => { - res.render('cart'); - }); - app.get('/wishlist', (req,res) => { - res.render('wishlist'); - }); - app.get('/beaded', async (req,res) => { - var prods = await prodSchema.find({category: 'Beaded'}); - //console.log(prods); - res.render('categories/beaded', {'prods': prods}); + app.get('/myprofile', (req,res) => { + res.render('my_profile', {user: req.user}); }); - app.get('/bracelets', async (req,res) => { - var prods = await prodSchema.find({category: 'Bracelets'}); - //console.log(prods); - res.render('categories/bracelets', {'prods': prods}); + app.get('/logout', async (req,res) => { + req.logout(); + req.flash('success_msg', 'Logout successful!'); + res.redirect('login'); }); - app.get('/earcuffs', async (req,res) => { - var prods = await prodSchema.find({category: 'Earcuffs'}); - //console.log(prods); - res.render('categories/ear_cuffs', {'prods': prods}); + app.get('/wishlist', ensureAuthenticated, async (req,res) => { + wishlist = req.user.wishlist; + var prods = []; + for(let name of wishlist){ + var prod = await Product.findOne({name: name}); + prods.push(prod); + } + // console.log(prods); + res.render('wishlist', {'prods': prods}); }); - app.get('/necklaces', async (req,res) => { - var prods = await prodSchema.find({category: 'Necklaces'}); - //console.log(prods); - res.render('categories/necklaces', {'prods': prods}); + app.post('/auth', (req,res,next) => { + passport.authenticate('local', { + successRedirect: '/', + failureRedirect: '/login', + failureFlash: true, + })(req,res,next); }); - app.get('/pearls', async (req,res) => { - var prods = await prodSchema.find({category: 'Pearls'}); - //console.log(prods); - res.render('categories/pearls', {'prods': prods}); - }); - app.get('/polymerclay', async (req,res) => { - var prods = await prodSchema.find({category: 'Polymer Clay'}); - //console.log(prods); - res.render('categories/polymer_clay', {'prods': prods}); + app.get('/details/:id', (req,res,next) => { + var productID = req.params.id; + Product.findById(productID, (err, product) => { + if(err){ + return res.redirect('back'); + } + try{ + res.render('product_details', {'product':product, 'wishlist': req.user.wishlist}); + } + catch(err){ + res.render('product_details', {'product':product}); + } + }); + }) + app.get('/add-to-cart/:id', (req,res,next) => { + var productID = req.params.id; + var cart = new Cart(req.session.cart ? req.session.cart : {}); + + Product.updateOne({_id: productID}, {$inc: {stock: -1}}, (err,product) => { + if(err){ + req.flash('error_msg','Error. Please try again.') + return res.redirect('back'); + } + }); + Product.findById(productID, (err,product) => { + if(err){ + req.flash('error_msg','Error. Please try again.') + return res.redirect('back'); + } + cart.add(product, product._id); + req.session.cart = cart; + // if(typeof req.user.wishlist != 'undefined'){ + // if(req.user.wishlist.includes(product.name)){ + // User.updateOne({email: req.user.email}, {$pullAll: {wishlist: [product.name]}}, (err,product) => { + // if(err){ + // req.flash('error_msg','Error. Please try again.') + // return res.redirect('back'); + // } + // }); + // } + // } + req.flash('success_msg','Item added to cart!') + res.redirect('back'); + }); + }) + app.get('/add-to-wishlist/:name', ensureAuthenticated, (req,res,next) => { + User.updateOne({email: req.user.email}, {$push: {wishlist: [req.params.name]}}, (err,product) => { + if(err){ + req.flash('error_msg','Error. Please try again.') + return res.redirect('/'); + } + req.flash('success_msg','Item removed from wishlist!') + res.redirect('back'); + }); + }) + app.get('/remove-from-wishlist/:name', ensureAuthenticated, (req,res,next) => { + User.updateOne({email: req.user.email}, {$pullAll: {wishlist: [req.params.name]}}, (err,product) => { + if(err){ + req.flash('error_msg','Error. Please try again.') + return res.redirect('/'); + } + req.flash('success_msg','Item removed from wishlist!') + res.redirect('back'); + }); + }) + app.get('/reduce/:id', (req,res,next) => { + var productID = req.params.id; + Product.updateOne({_id: productID}, {$inc: {stock: 1}}, (err,product) => { + if(err){ + req.flash('error_msg','Error. Please try again.') + return res.redirect('back'); + } + }); + var cart = new Cart(req.session.cart ? req.session.cart : {}); + cart.reduceByOne(productID); + req.session.cart = cart; + res.redirect('/cart'); + }) + app.get('/remove-from-cart/:id', (req,res,next) => { + var cart = new Cart(req.session.cart); + var productID = req.params.id; + var incQty = cart.items[productID].qty; + Product.updateOne({_id: productID}, {$inc: {stock: incQty}}, (err,product) => { + if(err){ + req.flash('error_msg','Error. Please try again.') + return res.redirect('back'); + } + }); + var cart = new Cart(req.session.cart); + cart.removeItem(productID); + req.session.cart = cart; + res.redirect('/cart'); + }); - app.get('/tassels', async (req,res) => { - var prods = await prodSchema.find({category: 'Tassels'}); - //console.log(prods); - res.render('categories/tassels', {'prods': prods}); + app.get('/clear-cart', (req,res,next) => { + var cart = new Cart(req.session.cart); + for(const property in cart.items){ + var productID = cart.items[property].item._id + var incQty = cart.items[property].qty + Product.updateOne({_id: productID}, {$inc: {stock: incQty}}, (err,product) => { + if(err){ + req.flash('error_msg','Error. Please try again.') + return res.redirect('back'); + } + }); + } + req.session.cart = null; + res.redirect('/cart'); + }); - app.get('/threads', async (req,res) => { - var prods = await prodSchema.find({category: 'Threads'}); - //console.log(prods); - res.render('categories/threads', {'prods': prods}); + app.get('/cart', async (req,res) => { + if(!req.session.cart){ + return res.render('cart', {products: null}); + } + var cart = new Cart(req.session.cart); + var prods = []; + var prod = {}; + for(const property in cart.items){ + var prod = {}; + var product = await Product.findById(property); + prod = { + '_id': cart.items[property].item._id, + 'name': cart.items[property].item.name, + 'price': cart.items[property].item.price, + 'qty': cart.items[property].qty, + 'total': cart.items[property].price, + 'path': cart.items[property].item.imgPath, + 'stock': product.stock + } + prods.push(prod); + } + + res.render('cart', {products: prods, totalPrice: cart.totalPrice}); }); - app.get('/wiredearrings', async (req,res) => { - var prods = await prodSchema.find({category: 'Wired Earrings'}); - //console.log(prods); - res.render('categories/wired_earrings', {'prods': prods}); + app.get('/checkout', ensureAuthenticated, (req,res,next) => { + if(!req.session.cart){ + return res.redirect('/cart'); + } + console.log(req.body.note); + var cart = new Cart(req.session.cart); + var prods = []; + for(const property in cart.items){ + var prod = {}; + prod = { + '_id': cart.items[property].item._id, + 'name': cart.items[property].item.name, + 'price': cart.items[property].item.price, + 'qty': cart.items[property].qty, + 'total': cart.items[property].price, + } + prods.push(prod); + } + var order = new Order({ + email: req.user.email, + cart: prods, + // note: note, + totalAmount: cart.totalPrice, + totalQty: cart.totalQty, + }); + order.save((err,result) => { + if(err){ + req.flash('error_msg', 'Order placement unsuccessful. Please try again.') + return res.redirect('/cart'); + } + var transporter = nodemailer.createTransport({ + service: 'gmail', + auth: { + user: 'elysianhandmade.official@gmail.com', + pass: 'Elysian@1234' + } + }); + ejs.renderFile('./views/confirmation_mail.ejs', {order: order}, (err,data)=>{ + if(err){ + console.log(err); + } + else{ + var mailOptions = { + from: 'elysianhandmade.official@gmail.com', + to: req.user.email, + subject: 'Order Confirmed', + html: data + }; + + transporter.sendMail(mailOptions, (err, info) => { + if(err){ + console.log(err); + } + else{ + console.log('Email sent: '+ info.response); + } + }); + } + }) + + // req.flash('success_msg', 'Order placed successfully!'); + req.session.cart = null; + res.render('thank_you'); + }) + }) + app.post('/register', (req,res) => { + //console.log(req.body); + const { firstname, lastname, email, contact, password, password2 } = req.body; + let errors = []; + // console.log({ firstname, lastname, email, contact, password, password2 }); + + //Check if any fields are empty + if(!firstname || !lastname || !email || !contact || !password || !password2){ + errors.push({ msg: 'Please fill in all fields.' }); + } + + //Check if passwords match + if(password !== password2){ + errors.push({ msg: 'Passwords do no match.' }) + } + + //Check password length + if(password.length < 6){ + errors.push({ msg: 'Password should be atleast 6 characters.'}) + } + + if(errors.length > 0){ + // console.log(errors); + res.render('signup', { + errors, + firstname, + lastname, + email, + contact, + password, + password2, + }); + } + else{ + User.findOne({email: email}).then(user => { + if(user){ + errors.push({msg: 'E-mail already exists.'}) + res.render('signup', { + errors, + firstname, + lastname, + email, + contact, + password, + password2, + }); + } + else{ + const newUser = new User({ + firstName: firstname, + lastName: lastname, + email, + password, + contact, + }); + + bcrypt.genSalt(10, (err,salt) => + bcrypt.hash(newUser.password, salt, (err, hash) => { + if(err) throw err; + + newUser.password = hash; + newUser.save() + .then((user) => { + req.flash('success_msg', 'Sign up successful! You can now login.') + res.redirect('/login'); + }) + .catch(err => console.log(err)); + })) + } + }) + } }); }; \ No newline at end of file diff --git a/backend/config/auth.js b/backend/config/auth.js new file mode 100644 index 0000000..889c1e5 --- /dev/null +++ b/backend/config/auth.js @@ -0,0 +1,17 @@ +module.exports = { + ensureAuthenticated: function(req,res,next) { + if(req.isAuthenticated()){ + return next(); + } + + str=req.url.substring(1); + if(str=='checkout'){ + req.flash('error_msg', `Please log in to ${str}.`); + } + else{ + req.flash('error_msg', `Please log in to access your ${str}.`); + } + + res.redirect('/login'); + } +} \ No newline at end of file diff --git a/backend/config/passport.js b/backend/config/passport.js new file mode 100644 index 0000000..b6ad3a5 --- /dev/null +++ b/backend/config/passport.js @@ -0,0 +1,38 @@ +const LocalStrategy = require('passport-local').Strategy; +const bcrypt = require('bcryptjs'); +const User = require('../models/User'); + +module.exports = function(passport){ + passport.use( + new LocalStrategy({usernameField: 'email'}, (email,password,done) => { + User.findOne({email: email}) + .then(user => { + if(!user) { + return done(null, false, {message: 'This email is not registered.'}); + } + + bcrypt.compare(password, user.password, (err, isMatch) => { + if(err) throw err; + + if(isMatch){ + return done(null, user); + } + else{ + return done(null, false, {message: 'Incorrect password.'}) + } + }); + }) + .catch(err => console.log(err)); + }) + ); + + passport.serializeUser((user, done) => { + done(null, user.id); + }); + + passport.deserializeUser((id, done) => { + User.findById(id, (err, user) => { + done(err, user); + }); + }); +}; \ No newline at end of file diff --git a/backend/index.js b/backend/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/backend/models/Address.js b/backend/models/Address.js new file mode 100644 index 0000000..c2499e9 --- /dev/null +++ b/backend/models/Address.js @@ -0,0 +1,39 @@ +var mongoose = require('mongoose') +var Schema = mongoose.Schema; + +const addressSchema = new Schema( + { + city: + { + type: String, + required: true, + }, + state: + { + type: String, + required: true, + }, + country: + { + type: String, + required: true, + }, + addLine1: + { + type: String, + required: true, + }, + addLine2: + { + type: String, + required: true, + }, + pinCode: + { + type: Number, + required: true, + }, + } +) + +module.exports = addressSchema; \ No newline at end of file diff --git a/backend/models/Cart.js b/backend/models/Cart.js new file mode 100644 index 0000000..ead1996 --- /dev/null +++ b/backend/models/Cart.js @@ -0,0 +1,34 @@ +var mongoose = require('mongoose') +var Schema = mongoose.Schema; + +const cartSchema = Schema( + { + item: + { + type: String, + required: true, + }, + sku: + { + type: String, + required: true, + }, + quantity: + { + type: String, + required: true, + }, + discount: + { + type: Number, + required: true, + }, + amount: + { + type: Number, + required: true, + }, + }, +) + +module.exports = cartSchema; \ No newline at end of file diff --git a/backend/models/Page.js b/backend/models/Page.js new file mode 100644 index 0000000..e23f234 --- /dev/null +++ b/backend/models/Page.js @@ -0,0 +1,19 @@ +var mongoose = require('mongoose'); +var pageSchema = mongoose.Schema({ + title: { + type: String, + required: true + }, + slug: { + type: String, + }, + content: { + type: String, + required: true + }, + sorting: { + type: Number, + } +}) + +module.exports = mongoose.model('Page', pageSchema); \ No newline at end of file diff --git a/backend/models/add_items.js b/backend/models/add_items.js index 460947f..5e34fc3 100644 --- a/backend/models/add_items.js +++ b/backend/models/add_items.js @@ -15,14 +15,40 @@ db.on('error', console.error.bind(console, 'connection error:')); db.once('open', function() { console.log("Connection Successful!"); - - // a document instance - var product = new Product({name: 'Aster', price: 150, stock: 0, description: 'Pearl hoops.', category: ['Pearls'], size: '4cm diameter' , imgPath: 'images/15.jpg'}); - - // save model to database - product.save(function (err, prod) { - if (err) return console.error(err); - console.log(prod.name + " saved to collection."); + + var list = [ + { + name: 'Viola', + price: 130, + stock: 0, + color: [ + 'Violet', + 'Green', + 'Light Blue', + 'White', + 'Red' + ], + description: 'Crystal drop Kidney hoops.', + category: ['Pearls', 'Wired Earrings'], + imgPath: 'images/12.jpg' + }, + ]; + + list.forEach(function(item) { + var product = new Product({ + name: item.name, + price: item.price, + stock: item.stock, + description: item.description, + category: item.category, + imgPath: item.imgPath, + }); + + // save model to database + product.save(function (err, prod) { + if (err) return console.error(err); + console.log(prod.name + " saved to collection."); + }); }); }); \ No newline at end of file diff --git a/backend/models/carts.js b/backend/models/carts.js new file mode 100644 index 0000000..c71ad91 --- /dev/null +++ b/backend/models/carts.js @@ -0,0 +1,41 @@ +module.exports = function Cart(oldCart) { + this.items = oldCart.items || {}; + this.totalQty = oldCart.totalQty || 0; + this.totalPrice = oldCart.totalPrice || 0; + + this.add = (item,id) => { + var storedItem = this.items[id]; + if(!storedItem){ + storedItem = this.items[id] = {item: item, qty:0, price: 0}; + } + storedItem.qty++; + storedItem.price = storedItem.item.price * storedItem.qty; + this.totalQty++; + this.totalPrice += storedItem.item.price; + }; + + this.reduceByOne = (id) => { + this.items[id].qty--; + this.items[id].price -= this.items[id].item.price; + this.totalQty--; + this.totalPrice -= this.items[id].item.price; + + if(this.items[id].qty <= 0){ + delete this.items[id]; + } + } + + this.removeItem = (id) => { + this.totalQty -= this.items[id].qty; + this.totalPrice -= this.items[id].price; + delete this.items[id]; + }; + + this.generateArray = () => { + var arr = []; + for(var id in this.items){ + arr.push(this.items[id]); + } + return arr; + }; +}; \ No newline at end of file diff --git a/backend/models/order.js b/backend/models/order.js index 9eba69c..782f0b4 100644 --- a/backend/models/order.js +++ b/backend/models/order.js @@ -1,113 +1,69 @@ -var mongoose = require('mongoose') +var mongoose = require('mongoose'); +var addressSchema = require('./Address'); +const User = require('./User'); var Schema = mongoose.Schema; const orderSchema = Schema( { - userID: + email: { type: String, required: true, }, - paymentStatus: + cart: { - type: String, - required:true, + type: Array, + required: true, }, - shippingStatus: + totalAmount: { - type: String, + type: Number, required: true, }, - amount: + totalQty: { type: Number, - // required: true, + required: true, }, - items: + shippingStatus: { - type: Array, - required: true, + type: String, + // required: true, }, shippingAddress: { type: [addressSchema], - required: true, + // required: true, }, billingAddress: { type: [addressSchema], - required: true, - }, - trackingID: - { - type: String, - required: true, - }, - }, -) - -const itemSchema = new Schema( - { - sku: { - type: String, // required: true, }, - quantity: { - type: Number, - required: true, - }, - price: { - type: Number, - required: true, - }, - discount: { - type: Number, - required: true, - }, - preTax: { - type: Number, - required: true, - }, - postTax: { - type: Number, - required: true, - }, - } -) - -const addressSchema = new Schema( - { - city: + paymentID: { type: String, - required: true, - }, - state: - { - type: String, - required: true, + // required: true, }, - country: + fulfilled: { - type: String, - required: true, + type: Boolean, + default: false, }, - addLine1: + shipped: { - type: String, - required: true, + type: Boolean, + default: false, }, - addLine2: + delivered: { - type: String, - required: true, - }, - pinCode: - { - type: Number, - required: true, + type: Boolean, + default: false, }, + }, + { + timestamps: true } ) -module.exports = mongoose.model('orders',ordersSchema) \ No newline at end of file +module.exports = mongoose.model('order', orderSchema); \ No newline at end of file diff --git a/backend/models/product.js b/backend/models/product.js index 343edf2..62fe752 100644 --- a/backend/models/product.js +++ b/backend/models/product.js @@ -25,7 +25,7 @@ const prodSchema = Schema( }, color: { - type: String, + type: [String], // required:true, }, size: diff --git a/backend/models/user.js b/backend/models/user.js index d624d16..d954d08 100644 --- a/backend/models/user.js +++ b/backend/models/user.js @@ -1,13 +1,10 @@ -var mongoose = require('mongoose') +var mongoose = require('mongoose'); +var addressSchema = require('./Address'); +var cartSchema = require('./Cart'); var Schema = mongoose.Schema; const userSchema = new Schema( { - _id: - { - type: String, - required: true, - }, firstName: { type: String, @@ -18,57 +15,38 @@ const userSchema = new Schema( type: String, required: true, }, - hashPass: - { - type: String, - // required: true, - }, - billingAddress: - { - type: [addressSchema], - required: true, - }, - shippingAddress: - { - type: [addressSchema], - // required: true, - }, - }, -) - -const addressSchema = new Schema( - { - city: + email: { type: String, required: true, }, - state: + password: { type: String, required: true, }, - country: + contact: { - type: String, + type: Number, required: true, }, - addLine1: + date: { - type: String, - required: true, + type: Date, + default: Date.now }, - addLine2: + address: { - type: String, - required: true, + type: [addressSchema], + // required: true, }, - pinCode: + wishlist: { - type: Number, - required: true, + type: [String], + // required: true, + default: [] }, - } + }, ) module.exports = mongoose.model('users',userSchema) \ No newline at end of file diff --git a/backend/package-lock.json b/backend/package-lock.json index 333e823..2d591bd 100644 --- a/backend/package-lock.json +++ b/backend/package-lock.json @@ -26,18 +26,18 @@ } }, "@types/mongodb": { - "version": "3.6.12", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.12.tgz", - "integrity": "sha512-49aEzQD5VdHPxyd5dRyQdqEveAg9LanwrH8RQipnMuulwzKmODXIZRp0umtxi1eBUfEusRkoy8AVOMr+kVuFog==", + "version": "3.6.16", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.16.tgz", + "integrity": "sha512-D3tM0iRUet3TiIMAdvovxAIRG9gYqFd4j7visGwmPNdQj8Fq/uFFfRxyGCgEwVXAs0NnJPMI/QGVTADxDwhmSQ==", "requires": { "@types/bson": "*", "@types/node": "*" } }, "@types/node": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-15.3.0.tgz", - "integrity": "sha512-8/bnjSZD86ZfpBsDlCIkNXIvm+h6wi9g7IqL+kmFkQ+Wvu3JrasgLElfiPgoo8V8vVfnEi0QVS12gbl94h9YsQ==" + "version": "15.6.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.6.0.tgz", + "integrity": "sha512-gCYSfQpy+LYhOFTKAeE8BkyGqaxmlFxe+n4DKM6DR0wzw/HISUE/hAmkC/KT8Sw5PCJblqg062b3z9gucv3k0A==" }, "abbrev": { "version": "1.1.1", @@ -100,6 +100,17 @@ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, "async": { "version": "0.9.2", "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", @@ -118,6 +129,11 @@ "safe-buffer": "5.1.2" } }, + "bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=" + }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -137,6 +153,11 @@ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" }, + "bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -349,6 +370,49 @@ "xdg-basedir": "^4.0.0" } }, + "connect-flash": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/connect-flash/-/connect-flash-0.1.1.tgz", + "integrity": "sha1-2GMPJtlaf4UfmVax6MxnMvO2qjA=" + }, + "connect-mongo": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/connect-mongo/-/connect-mongo-4.4.1.tgz", + "integrity": "sha512-I1QUE2tSGPtIBDAL2sFqUEPspDeJOR0u4g+N41ARJZk958pncu2PBG48Ev++fnldljobpIfdafak7hSlPYarvA==", + "requires": { + "debug": "^4.3.1", + "kruptein": "^3.0.0", + "mongodb": "3.6.5" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "requires": { + "ms": "2.1.2" + } + }, + "mongodb": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.5.tgz", + "integrity": "sha512-mQlYKw1iGbvJJejcPuyTaytq0xxlYbIoVDm2FODR+OHxyEiMR021vc32bTvamgBjCswsD54XIRwhg3yBaWqJjg==", + "requires": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "require_optional": "^1.0.1", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -556,6 +620,52 @@ "vary": "~1.1.2" } }, + "express-ejs-layouts": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/express-ejs-layouts/-/express-ejs-layouts-2.5.0.tgz", + "integrity": "sha512-27Kza3FR8UqvQsq1ewaxC2IwpgrQttYDEFN5s8D74Fv1VPdzsXFWsiKhPMlNauG+DrgMAmh7FhQl5hKHffd+wQ==" + }, + "express-session": { + "version": "1.17.2", + "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.17.2.tgz", + "integrity": "sha512-mPcYcLA0lvh7D4Oqr5aNJFMtBMKPLl++OKKxkHzZ0U0oDq1rpKBnkR5f5vCHR26VeArlTOEF9td4x5IjICksRQ==", + "requires": { + "cookie": "0.4.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-headers": "~1.0.2", + "parseurl": "~1.3.3", + "safe-buffer": "5.2.1", + "uid-safe": "~2.1.5" + }, + "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + } + } + }, + "express-validator": { + "version": "6.11.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.11.1.tgz", + "integrity": "sha512-XAMdu1P6RESd8bvKtNdgNPsW+abkY6UQ2EVUqPpK6QVqieZKaLrN7W/zeFzDWZmgAy/RPEW8M4KYXMqQk6GmTA==", + "requires": { + "lodash": "^4.17.21", + "validator": "^13.5.2" + } + }, "filelist": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.2.tgz", @@ -826,6 +936,14 @@ "json-buffer": "3.0.0" } }, + "kruptein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/kruptein/-/kruptein-3.0.0.tgz", + "integrity": "sha512-Fh5sIb+3XI9L12GsgeBQqXVRPLB1HVViKSUkqPPOcqTEX4NwoF8Z3pEfMSl3Psd1j+QlloV8Uxxwp4gk3aFBGA==", + "requires": { + "asn1.js": "^5.4.1" + } + }, "latest-version": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", @@ -834,6 +952,11 @@ "package-json": "^6.3.0" } }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", @@ -898,6 +1021,11 @@ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -925,9 +1053,9 @@ } }, "mongoose": { - "version": "5.12.9", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.9.tgz", - "integrity": "sha512-ZSDjW15DmUbHQcZ2PqoXsJeYnpYipISi6QJH/XHR9dcSg3IRNCa86apcTptBux03/YBPiSZlKNYUNDx7iuMWoA==", + "version": "5.12.10", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.12.10.tgz", + "integrity": "sha512-/VmFFEACH2yiuPcJoBjOzVTXozBhCeminVbWI8mxiZwvgCbNu9PQrIABIgeCJncnZH8VT4G7s2IXO5FySxF1XA==", "requires": { "@types/mongodb": "^3.5.27", "bson": "^1.1.4", @@ -1125,6 +1253,28 @@ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "passport": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz", + "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==", + "requires": { + "passport-strategy": "1.x.x", + "pause": "0.0.1" + } + }, + "passport-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-local/-/passport-local-1.0.0.tgz", + "integrity": "sha1-H+YyaMkudWBmJkN+O5BmYsFbpu4=", + "requires": { + "passport-strategy": "1.x.x" + } + }, + "passport-strategy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz", + "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ=" + }, "path-key": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", @@ -1135,6 +1285,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=" }, + "pause": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz", + "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10=" + }, "picomatch": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.3.tgz", @@ -1186,6 +1341,11 @@ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==" }, + "random-bytes": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/random-bytes/-/random-bytes-1.0.0.tgz", + "integrity": "sha1-T2ih3Arli9P7lYSMMDJNt11kNgs=" + }, "range-parser": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", @@ -1256,6 +1416,20 @@ "rc": "^1.2.8" } }, + "require_optional": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", + "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "requires": { + "resolve-from": "^2.0.0", + "semver": "^5.1.0" + } + }, + "resolve-from": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", + "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=" + }, "responselike": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", @@ -1505,6 +1679,14 @@ "is-typedarray": "^1.0.0" } }, + "uid-safe": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", + "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "requires": { + "random-bytes": "~1.0.0" + } + }, "undefsafe": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz", @@ -1609,6 +1791,11 @@ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=" }, + "validator": { + "version": "13.6.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.6.0.tgz", + "integrity": "sha512-gVgKbdbHgtxpRyR8K0O6oFZPhhB5tT1jeEHZR0Znr9Svg03U0+r9DXWMrnRAB+HtCStDQKlaIZm42tVsVjqtjg==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/backend/package.json b/backend/package.json index bb6ff75..4f23469 100644 --- a/backend/package.json +++ b/backend/package.json @@ -4,19 +4,26 @@ "description": "Backend for Elysian Website", "main": "server.js", "scripts": { - "start": "nodemon server.js", - "dev": "cross-env NODE_ENV=development nodemon server" + "start": "nodemon server.js" }, "author": "Akshar", "license": "ISC", "dependencies": { + "bcryptjs": "^2.4.3", + "connect-flash": "^0.1.1", + "connect-mongo": "^4.4.1", "cors": "^2.8.5", "cross-env": "^7.0.3", "dotenv": "^9.0.2", "ejs": "^3.1.6", "express": "^4.17.1", - "mongoose": "^5.12.9", + "express-ejs-layouts": "^2.5.0", + "express-session": "^1.17.2", + "express-validator": "^6.11.1", + "mongoose": "^5.12.10", "morgan": "^1.10.0", - "nodemon": "^2.0.7" + "nodemon": "^2.0.7", + "passport": "^0.4.1", + "passport-local": "^1.0.0" } } diff --git a/backend/public/stylesheet1.css b/backend/public/stylesheet1.css index 309d6e7..e094670 100644 --- a/backend/public/stylesheet1.css +++ b/backend/public/stylesheet1.css @@ -166,3 +166,11 @@ font-family: 'Roboto', sans-serif; text-align: center; color: #ecbbaa; } +.fa { + font-size: 12px; +} +a:hover { + color: #ecbbaa; + background-color: transparent; + text-decoration: underline; + } \ No newline at end of file diff --git a/backend/routes/admin_pages.js b/backend/routes/admin_pages.js new file mode 100644 index 0000000..3aef8fe --- /dev/null +++ b/backend/routes/admin_pages.js @@ -0,0 +1,22 @@ +var express = require('express'); +var router = express.Router(); + +//get index page +router.get('/', (req,res) => { + res.send('Admin Page'); +}) + +//get add page +router.get('/add-page', (req,res) => { + var title = ""; + var slug = ""; + var content = ""; + + res.render('admin/add_page', { + title: title, + slug: slug, + content: content, + }); +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/cart.js b/backend/routes/cart.js new file mode 100644 index 0000000..0427207 --- /dev/null +++ b/backend/routes/cart.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); +var Product = require('../models/Product'); + +router.get('/add/:product', (req,res) => { + +}) + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/pages.js b/backend/routes/pages.js new file mode 100644 index 0000000..80358c2 --- /dev/null +++ b/backend/routes/pages.js @@ -0,0 +1,10 @@ +var express = require('express'); +var router = express.Router(); + +router.get('/', (req,res) => { + res.render('index', { + title: 'Home' + }); +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/routes/products.js b/backend/routes/products.js new file mode 100644 index 0000000..a2e2efc --- /dev/null +++ b/backend/routes/products.js @@ -0,0 +1,46 @@ +var prodSchema = require('../models/Product'); +var express = require('express'); +var router = express.Router(); + +router.get('/', async (req,res) => { + var prods = await prodSchema.find({}); + res.render('products', {'prods': prods}); +}); +router.get('/beaded', async (req,res) => { + var prods = await prodSchema.find({category: 'Beaded'}); + res.render('categories/beaded', {'prods': prods}); +}); +router.get('/bracelets', async (req,res) => { + var prods = await prodSchema.find({category: 'Bracelets'}); + res.render('categories/bracelets', {'prods': prods}); +}); +router.get('/earcuffs', async (req,res) => { + var prods = await prodSchema.find({category: 'Earcuffs'}); + res.render('categories/ear_cuffs', {'prods': prods}); +}); +router.get('/necklaces', async (req,res) => { + var prods = await prodSchema.find({category: 'Necklaces'}); + res.render('categories/necklaces', {'prods': prods}); +}); +router.get('/pearls', async (req,res) => { + var prods = await prodSchema.find({category: 'Pearls'}); + res.render('categories/pearls', {'prods': prods}); +}); +router.get('/polymerclay', async (req,res) => { + var prods = await prodSchema.find({category: 'Polymer Clay'}); + res.render('categories/polymer_clay', {'prods': prods}); +}); +router.get('/tassels', async (req,res) => { + var prods = await prodSchema.find({category: 'Tassels'}); + res.render('categories/tassels', {'prods': prods}); +}); +router.get('/threads', async (req,res) => { + var prods = await prodSchema.find({category: 'Threads'}); + res.render('categories/threads', {'prods': prods}); +}); +router.get('/wiredearrings', async (req,res) => { + var prods = await prodSchema.find({category: 'Wired Earrings'}); + res.render('categories/wired_earrings', {'prods': prods}); +}); + +module.exports = router; \ No newline at end of file diff --git a/backend/server.js b/backend/server.js index 7ce1dcb..5f2207b 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1,26 +1,67 @@ const express = require('express') const connectDB = require('./config/db') -const cors = require('cors') -const morgan = require('morgan') +const passport = require('passport') +const flash = require('connect-flash') +const session = require('express-session') +const MongoStore = require('connect-mongo') require('dotenv').config() -var productsController = require('./app') + const app = express() -connectDB() +require('./config/passport')(passport) -if(process.env.NODE_ENV === 'development'){ - app.use(morgan('dev')) -} +var controller = require('./app') -app.use(cors()) +connectDB() + +//view engine setup app.set('view engine', 'ejs') app.use(express.static('public')) + +//body parser middleware app.use(express.urlencoded({extended: true})) app.use(express.json()) -productsController(app) +//express session middleware +app.use(session({ + secret: 'secret', + resave: false, + saveUninitialized: false, + store: MongoStore.create({ + mongoUrl: `mongodb+srv://akshar:akshar2103@cluster0.70u0k.mongodb.net/elysian?retryWrites=true&w=majority` + }), + cookie: { maxAge: 180*60*1000 } + })) +app.use(passport.initialize()); +app.use(passport.session()); + +//express flash middleware +app.use(flash()) +app.use((req, res, next) => { + res.locals.success_msg = req.flash('success_msg') + res.locals.error_msg = req.flash('error_msg') + res.locals.error = req.flash('error') + next() +}); + +//pass login and session states to all views +app.use((req,res,next) => { + res.locals.login = req.isAuthenticated(); + res.locals.session = req.session; + next(); +}) + +//set routes +var pages = require('./routes/pages') +var adminPages = require('./routes/admin_pages') +var products = require('./routes/products') +app.use('/admin/pages', adminPages) +app.use('/', pages) +app.use('/products', products) + +controller(app) -const PORT = process.env.PORT || 3000 +const PORT = process.env.PORT || 5000 console.log(`Server running on port ${PORT}`) app.listen(PORT) \ No newline at end of file diff --git a/backend/views/admin/add_page.ejs b/backend/views/admin/add_page.ejs new file mode 100644 index 0000000..7162856 --- /dev/null +++ b/backend/views/admin/add_page.ejs @@ -0,0 +1,108 @@ + + + + Elysian + + + + + + + + + + + + + + + + + + + +
+
+

+ Copyrights under Elysian, All Rights Reserved. +

+
+ + + diff --git a/backend/views/cart.ejs b/backend/views/cart.ejs index 5f784a0..078297d 100644 --- a/backend/views/cart.ejs +++ b/backend/views/cart.ejs @@ -1,149 +1,94 @@ - - - Elysian - - - - - - - - - - - - - - + <%- include('layouts/head') %> - - - - -

Cart

- -
- - - - - - - - - - - - - - - -

Item

Price

Quantity

Total

Product

Rs.0.00

1

Rs.0.00

-
-
-
-
-
- -
+ <% if(products && session.cart.totalQty){ %> +
+ + + + + + + + + + + <% products.forEach(function(prod){ %> + + + + + + + + + <% }) %> + +

PREVIEW

ITEM

PRICE

QUANTITY

TOTAL

+ + +

image + +

<%= prod.name %>

+
+

₹<%= prod.price %>

+ + + <%= prod.qty %> + <% if(prod.stock > 0){ %> + + + <% }else { %> + + <% } %> +

₹<%= prod.total %>

+ + +

+
+ <% }else{ %> +

+ Your cart is empty. Add items to the cart to view it here. +

+ <% } %> + <% if(products && session.cart.totalQty){ %> +
+
+
+
+ +
+
-
-
-
-
-

SUBTOTAL Rs.0.00

-

Shipping, taxes, and discount codes calculated at checkout.

-

- Continue Shopping +
+
+
+

Grand Total: ₹<%= totalPrice %>

+

Shipping, taxes, and discount codes calculated at checkout.

+ Check Out + +
-
+ <% } %> -
-
-

- Copyrights under Elysian, All Rights Reserved -

-
- + <%- include('layouts/footer') %> + <%- include('layouts/responsive') %> diff --git a/backend/views/categories/beaded.ejs b/backend/views/categories/beaded.ejs index ff0d442..6047f33 100644 --- a/backend/views/categories/beaded.ejs +++ b/backend/views/categories/beaded.ejs @@ -1,126 +1,10 @@ - - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + - diff --git a/backend/views/categories/bracelets.ejs b/backend/views/categories/bracelets.ejs index 0d9883e..6047f33 100644 --- a/backend/views/categories/bracelets.ejs +++ b/backend/views/categories/bracelets.ejs @@ -1,125 +1,10 @@ - - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + diff --git a/backend/views/categories/ear_cuffs.ejs b/backend/views/categories/ear_cuffs.ejs index 28e7ebf..6047f33 100644 --- a/backend/views/categories/ear_cuffs.ejs +++ b/backend/views/categories/ear_cuffs.ejs @@ -1,124 +1,10 @@ - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + diff --git a/backend/views/categories/necklaces.ejs b/backend/views/categories/necklaces.ejs index b559655..6047f33 100644 --- a/backend/views/categories/necklaces.ejs +++ b/backend/views/categories/necklaces.ejs @@ -1,124 +1,10 @@ - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + diff --git a/backend/views/categories/pearls.ejs b/backend/views/categories/pearls.ejs index a9633c6..6047f33 100644 --- a/backend/views/categories/pearls.ejs +++ b/backend/views/categories/pearls.ejs @@ -1,126 +1,10 @@ - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- - -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + - diff --git a/backend/views/categories/polymer_clay.ejs b/backend/views/categories/polymer_clay.ejs index 7f7fe06..f5d9d4b 100644 --- a/backend/views/categories/polymer_clay.ejs +++ b/backend/views/categories/polymer_clay.ejs @@ -1,127 +1,10 @@ - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- - -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - - - - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + + \ No newline at end of file diff --git a/backend/views/categories/tassels.ejs b/backend/views/categories/tassels.ejs index 96bde62..f5d9d4b 100644 --- a/backend/views/categories/tassels.ejs +++ b/backend/views/categories/tassels.ejs @@ -1,125 +1,10 @@ - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - - - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + + \ No newline at end of file diff --git a/backend/views/categories/threads.ejs b/backend/views/categories/threads.ejs index 65901dc..f5d9d4b 100644 --- a/backend/views/categories/threads.ejs +++ b/backend/views/categories/threads.ejs @@ -1,124 +1,10 @@ - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + + \ No newline at end of file diff --git a/backend/views/categories/wired_earrings.ejs b/backend/views/categories/wired_earrings.ejs index 73bb409..f5d9d4b 100644 --- a/backend/views/categories/wired_earrings.ejs +++ b/backend/views/categories/wired_earrings.ejs @@ -1,125 +1,10 @@ - - - Elysian - - - - - - - - - - - - - - - - - - - - -
-
- <% prods.forEach(function(prod){%> -
-
- image -
-

<%=prod.name%>

-

Rs. <%=prod.price%>

- -
-
-
- <% }); %> -
-
- -
-
-

- Copyrights under Elysian, All Rights Reserved. -

-
- - - + <%- include('../layouts/head') %> + + <%- include('../layouts/header') %> + <%- include('../layouts/items') %> + <%- include('../layouts/footer') %> + <%- include('../layouts/responsive') %> + + \ No newline at end of file diff --git a/backend/views/confirmation_mail.ejs b/backend/views/confirmation_mail.ejs new file mode 100644 index 0000000..1b0846e --- /dev/null +++ b/backend/views/confirmation_mail.ejs @@ -0,0 +1,24 @@ + +

+ Thank you for shopping with us! You will receive your order tracking details shortly. +

+ +

ITEM

+

PRICE

+

QUANTITY

+

TOTAL

+ + <% order.cart.forEach(function(prod){ %> + +

<%= prod.name %>

+

₹<%= prod.price %>

+

<%= prod.qty %>

+

₹<%= prod.total %>

+ + <% }) %> + +

+ Total Quantity: <%= order.totalQty %>
+ Total Amount: ₹<%= order.totalAmount %> +

+ \ No newline at end of file diff --git a/backend/views/contactus.ejs b/backend/views/contactus.ejs index 74de89b..6b5c695 100644 --- a/backend/views/contactus.ejs +++ b/backend/views/contactus.ejs @@ -1,92 +1,8 @@ - - Elysian - - - - - - - - - - - - - - + <%- include('layouts/head') %> - - - - - + <%- include('layouts/header') %>

Contact Us


@@ -114,21 +30,7 @@
-
-
-

- Copyrights under Elysian, All Rights Reserved -

-
- + <%- include('layouts/footer') %> + <%- include('layouts/responsive') %> diff --git a/backend/views/index.ejs b/backend/views/index.ejs index 10c2050..841fcf3 100644 --- a/backend/views/index.ejs +++ b/backend/views/index.ejs @@ -1,94 +1,9 @@ - - Elysian - - - - - - - - - - - - - - + <%- include('layouts/head') %> - - - + <%- include('layouts/header') %> -