From a9cf2634cdf054162f85994712de9bedb71ae76c Mon Sep 17 00:00:00 2001 From: Anshuman Tiwari Date: Sun, 21 Jul 2024 20:47:25 +0000 Subject: [PATCH 1/2] full otp feat added frontend and backend both --- account/login-signup.html | 34 ++++++++-------- js/login-signup.js | 75 +++++++++++++++++++++++++++++++++++ server_backend/.env | 4 +- server_backend/models/User.js | 13 +++++- server_backend/package.json | 2 + server_backend/routes/auth.js | 51 ++++++++++++++++++++++++ 6 files changed, 159 insertions(+), 20 deletions(-) diff --git a/account/login-signup.html b/account/login-signup.html index ab2f6857..e416c27f 100644 --- a/account/login-signup.html +++ b/account/login-signup.html @@ -1,9 +1,7 @@ - - @@ -15,7 +13,7 @@ <link href="https://cdn.jsdelivr.net/npm/bootstrap-icons/font/bootstrap-icons.css" rel="stylesheet" /> <link rel="stylesheet" href="../css/login-signup.css" /> </head> - +<body> <header id="header-login" class="text-center text-secondary fs-4"> This is Header </header> @@ -25,23 +23,22 @@ <div class="signupin"> <div class="leftpanal"> <h4 class="login-display">Login</h4> - <p> Get access to your Orders, - Wishlist and Recommendations</p> + <p> Get access to your Orders, Wishlist and Recommendations</p> </div> <div class="rightSignuppanal"> <form autocomplete="on"> <div class="I-qZ4MvLRlQb"> - <input autocomplete="off" id="inputsin" type="text" class="r4vIwl BV+Dqf input-field" placeholder=" Enter Email/Mobile number" value="" required /> + <input autocomplete="off" id="inputsin" type="text" class="r4vIwl BV+Dqf input-field" placeholder="Enter Email/Mobile number" required /> <label class="Gq-80aa label" id="inputsin"></label> <div class="underline"></div> </div> <div class="EpHS0A">By continuing, you agree to Flipkart's <a class="c9RDXR" target="_blank" href="../pages/terms/">Terms of Use</a> - and + and <a class="c9RDXR" target="_blank" href="../pages/privacypolicy/">Privacy Policy</a>. </div> <div class="LSOAQH mt-2"> - <button class="QqFHMw twnTnD _7Pd1Fp">Request OTP</button> + <button id="requestOtpButton" class="QqFHMw twnTnD _7Pd1Fp">Request OTP</button> </div> <div class="ZJ3AS1 d-flex justify-content-center mt-4"> <a class="azBkHf" href="#" id="buttonA">New to Flipkart? Create an account</a> @@ -50,19 +47,24 @@ <h4 class="login-display">Login</h4> </div> </div> </div> + <!-- signup page --> <div id="divB"> - <div class="signupin container-fluid"> + <div class="signupin container-fluid"> <div class="leftpanal"> <h4>Looks like you're new here!</h4> <p>Sign up with your mobile number to get started</p> </div> - <div class="rightSignuppanal"> <form autocomplete="on"> <div class="I-qZ4MvLRlQb"> - <input autocomplete="off" id="inputi" type="text" class="r4vIwl BV+Dqf" value="" required="" /> - <label class="Gq-80aa label" id="inputi">Enter Email/Mobile number</label> + <input autocomplete="off" id="inputi" type="text" class="r4vIwl BV+Dqf" placeholder="Enter Email/Mobile number" required /> + <label class="Gq-80aa label" id="inputi"></label> + <div class="underlineii"></div> + </div> + <div class="I-qZ4MvLRlQb"> + <input autocomplete="off" id="otpInput" type="text" class="r4vIwl BV+Dqf" placeholder="Enter OTP" required /> + <label class="Gq-80aa label" id="otpInput"></label> <div class="underlineii"></div> </div> <div class="EpHS0A">By continuing, you agree to Flipkart's @@ -71,7 +73,7 @@ <h4>Looks like you're new here!</h4> <a class="c9RDXR" target="_blank" href="../pages/privacypolicy/">Privacy Policy</a>. </div> <div class="LSOAQH mt-2"> - <button class="QqFHMw twnTnD _7Pd1Fp">Continue</button> + <button id="verifyOtpButton" class="QqFHMw twnTnD _7Pd1Fp">Verify OTP</button> </div> <div class="ZJ3AS1 d-flex justify-content-center mt-4"> <a class="azBkHf" href="#" id="buttonB">Existing User? Log in</a> @@ -84,7 +86,5 @@ <h4>Looks like you're new here!</h4> <footer id="footer-login" style="background-color: #293649 !important"></footer> <script src="../js/bootstrap.bundle.min.js"></script> <script src="../js/login-signup.js"></script> - -<body></body> - -</html> \ No newline at end of file +</body> +</html> diff --git a/js/login-signup.js b/js/login-signup.js index 70ad8db2..b1bdcd3a 100644 --- a/js/login-signup.js +++ b/js/login-signup.js @@ -1,3 +1,78 @@ +// code added for otp: +document.addEventListener('DOMContentLoaded', () => { + const requestOtpButton = document.getElementById('requestOtpButton'); + const verifyOtpButton = document.getElementById('verifyOtpButton'); + + // Request OTP + requestOtpButton.addEventListener('click', async (event) => { + event.preventDefault(); // Prevent form submission + + const email = document.getElementById('inputsin').value; + + if (!email) { + alert('Please enter your email'); + return; + } + + try { + const response = await fetch('http://localhost:5000/send-otp', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ email }), + }); + + const result = await response.json(); + if (response.ok) { + alert('OTP sent to your email'); + // Show OTP verification fields here + } else { + alert(result.msg || 'Failed to send OTP'); + } + } catch (error) { + console.error('Error:', error); + alert('Server will be publically available soon to send otp. ThankYou for visiting.'); + } + }); + + // Verify OTP + verifyOtpButton.addEventListener('click', async (event) => { + event.preventDefault(); // Prevent form submission + + const email = document.getElementById('inputi').value; + const otp = document.getElementById('otpInput').value; // Add an OTP input field with id `otpInput` + + if (!email || !otp) { + alert('Please enter your email and OTP'); + return; + } + + try { + const response = await fetch('http://localhost:5000/verify-otp', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ email, otp }), + }); + + const result = await response.json(); + if (response.ok) { + alert('OTP verified successfully'); + // Proceed with the next steps (e.g., redirect to a different page) + } else { + alert(result.msg || 'Failed to verify OTP'); + } + } catch (error) { + console.error('Error:', error); + alert('An error occurred while verifying OTP'); + } + }); + }); + + + document.addEventListener('DOMContentLoaded', () => { const components = [ { id: 'footer-login', url: '../footer/footer.html' }, diff --git a/server_backend/.env b/server_backend/.env index 66e6e27c..b058a841 100644 --- a/server_backend/.env +++ b/server_backend/.env @@ -1,2 +1,4 @@ MONGOURI = mongodb+srv://tanshuman145:Ansh%4012a1@cluster0.a87t2mr.mongodb.net/ecommerce -JWTSECRET = uyteuweuuihu$677773hjkj \ No newline at end of file +JWTSECRET = uyteuweuuihu$677773hjkj +EMAIL_USER=tanshuman145@gmail.com +EMAIL_PASS=uruq rcii ebcv roms \ No newline at end of file diff --git a/server_backend/models/User.js b/server_backend/models/User.js index caefbf93..70e3f6b8 100644 --- a/server_backend/models/User.js +++ b/server_backend/models/User.js @@ -1,8 +1,17 @@ const mongoose = require('mongoose'); const UserSchema = new mongoose.Schema({ - email: { type: String, required: true, unique: true }, - password: { type: String, required: true }, + email: { + type: String, + required: true, + unique: true, + }, + password: { + type: String, + required: true, + }, + otp: String, + otpExpires: Date, }); module.exports = mongoose.model('User', UserSchema); diff --git a/server_backend/package.json b/server_backend/package.json index 8bdd157d..625f0a73 100644 --- a/server_backend/package.json +++ b/server_backend/package.json @@ -13,11 +13,13 @@ "bcryptjs": "^2.4.3", "body-parser": "^1.20.2", "cors": "^2.8.5", + "crypto": "^1.0.1", "dotenv": "^16.4.5", "express": "^4.19.2", "jsonwebtoken": "^9.0.2", "mongodb": "^6.8.0", "mongoose": "^8.5.1", + "nodemailer": "^6.9.14", "nodemon": "^3.1.4" } } diff --git a/server_backend/routes/auth.js b/server_backend/routes/auth.js index 42e7c6b6..f178923b 100644 --- a/server_backend/routes/auth.js +++ b/server_backend/routes/auth.js @@ -4,9 +4,20 @@ const bcrypt = require('bcryptjs'); const jwt = require('jsonwebtoken'); const User = require('../models/User'); const dotenv = require('dotenv'); +const crypto = require('crypto'); +const nodemailer = require('nodemailer'); dotenv.config(); +const transporter = nodemailer.createTransport({ + service: 'Gmail', + auth: { + user: process.env.EMAIL_USER, + pass: process.env.EMAIL_PASS, + }, +}); + + // Register route router.post('/register', async (req, res) => { const { email, password } = req.body; @@ -87,4 +98,44 @@ router.post('/login', async (req, res) => { } }); + +// Generate OTP and send email +router.post('/send-otp', async (req, res) => { + const { email } = req.body; + + try { + // Check if user exists + const user = await User.findOne({ email }); + if (!user) { + return res.status(400).json({ msg: 'Email not registered' }); + } + + const otp = crypto.randomInt(100000, 999999).toString(); + + user.otp = otp; + user.otpExpires = Date.now() + 15 * 60 * 1000; + await user.save(); + + const mailOptions = { + from: process.env.EMAIL_USER, + to: email, + subject: 'Your OTP Code', + text: `Your OTP code is ${otp}. It is valid for 15 minutes.`, + }; + + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + console.error('Error sending email:', error); + return res.status(500).json({ msg: 'Error sending OTP email' }); + } + res.json({ msg: 'OTP sent' }); + }); + } catch (err) { + console.error(err.message); + res.status(500).send('Server Error'); + } +}); + + + module.exports = router; From 79c58a328a04fb9a42319800c5b85ea78b986f23 Mon Sep 17 00:00:00 2001 From: Anshuman Tiwari <tanshuman145@gmail.com> Date: Sun, 21 Jul 2024 21:34:15 +0000 Subject: [PATCH 2/2] carousel added --- plus/index.html | 73 ++++++++++++++++++++++++++++++------------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/plus/index.html b/plus/index.html index e64bff65..33d0124e 100644 --- a/plus/index.html +++ b/plus/index.html @@ -15,7 +15,6 @@ <link rel="stylesheet" href="plus.css" /> </head> - <body> <header id="header-plus" class="text-center text-secondary fs-4"> This is Header @@ -23,25 +22,17 @@ <section> <style> - .banner { - background-image: url('../img/fpz.jpg'); - background-size: cover; - background-position: center; + .carousel-inner { height: 400px; - display: flex; - align-items: center; - justify-content: center; - color: white; - font-size: 36px; - font-weight: bold; - box-shadow: inset 0 0 500px 0px black; - text-shadow: 0 0 14px black; - transition: background-size 0.5s ease-in-out; - } - - .banner:hover { - background-size: 120%; + + .carousel-item { + height: 400px; + } + + .carousel-item img { + height: 100%; + object-fit: cover; } section .container { @@ -57,7 +48,7 @@ } .product-list:hover { - transform: translateX(-10px); + transform: translateX(-10px); } .product { @@ -70,7 +61,7 @@ } .product:hover { - box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); } .product img { @@ -81,7 +72,7 @@ } .product img:hover { - transform: scale(1.1); + transform: scale(1.1); } .product .name { @@ -92,23 +83,50 @@ } .product .name:hover { - color: #97b3e0; + color: #97b3e0; } .product .price { color: #2874f0; font-size: 16px; font-weight: bold; - transition: color 0.3s ease-in-out; + transition: color 0.3s ease-in-out; } .product .price:hover { - color: #007bff; + color: #007bff; } </style> <h3 class="text-center">Welcome to Flipkart Plus Zone</h3> - <div class="banner"> + + <!-- Bootstrap Carousel for Banner Images --> + <div id="bannerCarousel" class="carousel slide" data-bs-ride="carousel"> + <div class="carousel-indicators"> + <button type="button" data-bs-target="#bannerCarousel" data-bs-slide-to="0" class="active" aria-current="true" aria-label="Slide 1"></button> + <button type="button" data-bs-target="#bannerCarousel" data-bs-slide-to="1" aria-label="Slide 2"></button> + <button type="button" data-bs-target="#bannerCarousel" data-bs-slide-to="2" aria-label="Slide 3"></button> + </div> + <div class="carousel-inner"> + <div class="carousel-item active"> + <img src="https://images.thequint.com/thequint/2018-08/05043882-7588-48ca-aaf8-13786bdcfb23/3e8a80bd_a21b_4f6e_aec3_b49fb417e1f5.jpg" class="d-block w-100" alt="First slide"> + </div> + <div class="carousel-item"> + <img src="https://i.gadgets360cdn.com/large/Flipkart-plus-screenshot_1539013276085.jpg" class="d-block w-100" alt="Second slide"> + </div> + <div class="carousel-item"> + <img src="https://storiesflistgv2.blob.core.windows.net/stories/2023/08/banner.jpg" class="d-block w-100" alt="Third slide"> + </div> + </div> + <button class="carousel-control-prev" type="button" data-bs-target="#bannerCarousel" data-bs-slide="prev"> + <span class="carousel-control-prev-icon" aria-hidden="true"></span> + <span class="visually-hidden">Previous</span> + </button> + <button class="carousel-control-next" type="button" data-bs-target="#bannerCarousel" data-bs-slide="next"> + <span class="carousel-control-next-icon" aria-hidden="true"></span> + <span class="visually-hidden">Next</span> + </button> </div> + <div class="container"> <div class="product-list"> <div class="product"> @@ -118,7 +136,7 @@ <h3 class="text-center">Welcome to Flipkart Plus Zone</h3> </div> <div class="product"> <img src="../img/phone-2.webp" alt="Product Image" /> - <div class="name">Poco M6 </div> + <div class="name">Poco M6</div> <div class="price">₹11,999</div> </div> <div class="product"> @@ -149,7 +167,6 @@ <h3 class="text-center">Welcome to Flipkart Plus Zone</h3> <footer id="footer-plus" style="background-color: #293649 !important"></footer> <script src="../js/bootstrap.bundle.min.js"></script> <script src="plus.js"></script> - </body> -</html> \ No newline at end of file +</html>