From 405fe5c70087c437fa80aaf06e70e0d81ddcdf0f Mon Sep 17 00:00:00 2001 From: Rohith31-WD Date: Mon, 29 Jun 2026 21:40:15 +0530 Subject: [PATCH] fix: send email verification otp --- lecture-pulse/.env.example | 3 ++ lecture-pulse/package-lock.json | 10 +++++ lecture-pulse/package.json | 1 + lecture-pulse/src/context/AuthContext.jsx | 45 ++++++++++++++++++++--- lecture-pulse/src/pages/Profile.jsx | 27 +++++++++----- 5 files changed, 70 insertions(+), 16 deletions(-) create mode 100644 lecture-pulse/.env.example diff --git a/lecture-pulse/.env.example b/lecture-pulse/.env.example new file mode 100644 index 0000000..55e1737 --- /dev/null +++ b/lecture-pulse/.env.example @@ -0,0 +1,3 @@ +VITE_EMAILJS_SERVICE_ID=your_emailjs_service_id +VITE_EMAILJS_TEMPLATE_ID=your_emailjs_template_id +VITE_EMAILJS_PUBLIC_KEY=your_emailjs_public_key diff --git a/lecture-pulse/package-lock.json b/lecture-pulse/package-lock.json index 9891360..4da278c 100644 --- a/lecture-pulse/package-lock.json +++ b/lecture-pulse/package-lock.json @@ -8,6 +8,7 @@ "name": "lecture-pulse", "version": "0.0.0", "dependencies": { + "@emailjs/browser": "^4.4.1", "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/vite": "^4.1.18", "class-variance-authority": "^0.7.1", @@ -331,6 +332,15 @@ "node": ">=6.9.0" } }, + "node_modules/@emailjs/browser": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@emailjs/browser/-/browser-4.4.1.tgz", + "integrity": "sha512-DGSlP9sPvyFba3to2A50kDtZ+pXVp/0rhmqs2LmbMS3I5J8FSOgLwzY2Xb4qfKlOVHh29EAutLYwe5yuEZmEFg==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.27.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", diff --git a/lecture-pulse/package.json b/lecture-pulse/package.json index 94764cf..6efe44d 100644 --- a/lecture-pulse/package.json +++ b/lecture-pulse/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@emailjs/browser": "^4.4.1", "@radix-ui/react-slot": "^1.2.4", "@tailwindcss/vite": "^4.1.18", "class-variance-authority": "^0.7.1", diff --git a/lecture-pulse/src/context/AuthContext.jsx b/lecture-pulse/src/context/AuthContext.jsx index 66853bb..6393bc3 100644 --- a/lecture-pulse/src/context/AuthContext.jsx +++ b/lecture-pulse/src/context/AuthContext.jsx @@ -1,4 +1,5 @@ import { createContext, useContext, useState } from "react"; +import emailjs from "@emailjs/browser"; import { getCurrentTeacher } from "@/utils/storage"; const AuthContext = createContext(); @@ -95,7 +96,18 @@ export function AuthProvider({ children }) { const OTP_EXPIRY_TIME = 5 * 60 * 1000; // 5 minutes - const sendOTP = (email) => { + const sendOTP = async (email) => { + const emailJsServiceId = import.meta.env.VITE_EMAILJS_SERVICE_ID; + const emailJsTemplateId = import.meta.env.VITE_EMAILJS_TEMPLATE_ID; + const emailJsPublicKey = import.meta.env.VITE_EMAILJS_PUBLIC_KEY; + + if (!emailJsServiceId || !emailJsTemplateId || !emailJsPublicKey) { + return { + success: false, + message: "Email service is not configured. Please add the EmailJS environment variables.", + }; + } + const otp = Math.floor(100000 + Math.random() * 900000).toString(); const otpData = { @@ -103,12 +115,33 @@ export function AuthProvider({ children }) { timestamp: Date.now(), }; - localStorage.setItem( - `lecturePulse_otp_${email}`, - JSON.stringify(otpData) - ); + try { + await emailjs.send( + emailJsServiceId, + emailJsTemplateId, + { + to_email: email, + otp_code: otp, + app_name: "LecturePulse", + }, + { + publicKey: emailJsPublicKey, + } + ); + + localStorage.setItem( + `lecturePulse_otp_${email}`, + JSON.stringify(otpData) + ); - return otp; + return { success: true }; + } catch (error) { + console.error("Failed to send OTP email:", error); + return { + success: false, + message: "Could not send the verification code. Please try again.", + }; + } }; const verifyOTP = (email, otp) => { diff --git a/lecture-pulse/src/pages/Profile.jsx b/lecture-pulse/src/pages/Profile.jsx index fa76f23..8eae0e6 100644 --- a/lecture-pulse/src/pages/Profile.jsx +++ b/lecture-pulse/src/pages/Profile.jsx @@ -16,25 +16,32 @@ export default function Profile() { const [otp, setOtp] = useState(""); const [step, setStep] = useState(1); // 1: Enter Email, 2: Enter OTP const [isEditing, setIsEditing] = useState(false); + const [isSendingOtp, setIsSendingOtp] = useState(false); if (!teacher) { navigate("/login"); return null; } - const handleSendOTP = (e) => { + const handleSendOTP = async (e) => { e.preventDefault(); if (!email) { toast.error("Please enter an email address"); return; } - const generatedOtp = sendOTP(email); - setStep(2); - // Simulating sending email - toast.success("Verification code sent!", { - description: `For hackathon demo, your code is: ${generatedOtp}`, - duration: 10000, - }); + + setIsSendingOtp(true); + const result = await sendOTP(email); + setIsSendingOtp(false); + + if (result.success) { + setStep(2); + toast.success("Verification code sent!", { + description: "Please check your inbox for the 6-digit code.", + }); + } else { + toast.error(result.message); + } }; const handleVerifyOTP = (e) => { @@ -165,8 +172,8 @@ export default function Profile() {
- {isEditing && (