import Apis from "../../APIs"; import React, { useState } from "react"; import axios from "axios"; import emailjs from "@emailjs/browser"; import { ToastContainer, toast } from "react-toastify"; import "react-toastify/dist/ReactToastify.css"; import { useNavigate } from "react-router-dom"; const RegisterForm = () => { const [email, setEmail] = useState(""); const [name, setName] = useState(""); const [phone, setPhone] = useState(""); const [emailError, setEmailError] = useState(""); const [nameError, setNameError] = useState(""); const [phoneError, setPhoneError] = useState(""); const [loading, setLoading] = useState(false); const navigate = useNavigate(); const loadScript = (src) => { return new Promise((resolve) => { const script = document.createElement("script"); script.src = src; script.onload = () => resolve(true); script.onerror = () => resolve(false); document.body.appendChild(script); }); }; const createRazorpayOrder = async (amount) => { setLoading(true); // Start loading before order creation const data = { amount: amount * 100, currency: "INR", }; try { const response = await axios.post(Apis.PAYMENT_API.CREATE_ORDER, data); handleRazorpayScreen(response.data.amount, response.data.order_id); } catch (error) { console.error("Error creating order:", error); toast.error("Payment failed. Please try again."); setLoading(false); // Stop loading on error } }; const handleRazorpayScreen = async (amount, orderId) => { const res = await loadScript( "https://checkout.razorpay.com/v1/checkout.js" ); if (!res) { alert("Failed to load Razorpay SDK. Are you online?"); setLoading(false); // Stop loading if script fails to load return; } const options = { key: "rzp_test_GcZZFDPP0jHtC4", amount: amount, currency: "INR", name: name, description: "Payment for Registration", image: "https://papayacoders.com/demo.png", order_id: orderId, handler: async function (response) { setLoading(false); // Stop loading after payment if (response && response.razorpay_payment_id) { await registerUser(response); // Pass the response object to registerUser } else { console.error("Payment response is missing or invalid."); toast.error("Payment verification failed. Please try again."); } }, prefill: { name: name, email: email, }, theme: { color: "#F4C430", }, modal: { ondismiss: function () { setLoading(false); // Stop loading when Razorpay modal is dismissed }, }, }; const paymentObject = new window.Razorpay(options); setLoading(false); // Stop showing the loader once the payment interface is ready to open paymentObject.open(); }; const generateRandomPassword = () => { return Math.random().toString(36).slice(-8); }; const sendEmail = (password) => { emailjs .send( import.meta.env.VITE_APP_EMAILJS_SERVICE_ID, import.meta.env.VITE_APP_EMAILJS_TEMPLATE_ID, { from_name: "See Change", to_name: name, from_email: "rishirri108@gmail.com", to_email: email, phoneNumber: phone, message: "Thank you for registering on SEE CHANGE", password: password, }, import.meta.env.VITE_APP_EMAILJS_PUBLIC_KEY ) .then((result) => { console.log("Email successfully sent:", result.text); }) .catch((error) => { console.error("Error sending email:", error); }); }; const registerUser = async (paymentResponse) => { if (!paymentResponse || !paymentResponse.razorpay_payment_id) { toast.error("Payment response is missing or invalid."); return; } const password = generateRandomPassword(); const userData = { fullName: name, email: email, phoneNumber: phone, password: password, }; try { const response = await axios.post(Apis.USER_API, userData); if (response.status === 201 || response.status === 200) { const paymentData = { paymentId: paymentResponse.razorpay_payment_id, user: response.data._id, amount: 100, currency: "INR", status: "captured", method: "razorpay", }; await axios.post(Apis.PAYMENT_API.SAVE_PAYMENT, paymentData); setEmail(""); setName(""); setPhone(""); sendEmail(password); navigate("/login", { state: { message: "User registered successfully!" }, }); } else { toast.error("Failed to register user. Please try again."); } } catch (error) { toast.error("This Email or Phone already in use"); console.error("Error while registering user:", error); } }; const handleSubmit = async (e) => { e.preventDefault(); if (!name) setNameError("Please enter your name"); if (!email) setEmailError("Please enter your email"); if (!phone) setPhoneError("Please enter your phone number"); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) setEmailError("Please enter a valid email address"); if (phone.length !== 10) setPhoneError("Phone number must be 10 digits"); if (name && emailRegex.test(email) && phone.length === 10) { createRazorpayOrder(100); } }; return ( <> {loading && ( <div className="min-h-screen w-full flex items-center justify-center bg-primary-gradient fixed inset-0 z-50"> <l-infinity size="200" stroke="4" stroke-length="0.15" bg-opacity="0.1" speed="1.3" color="white" ></l-infinity> </div> )} <form className="mt-[25px]" onSubmit={handleSubmit}> <label className="relative"> <input value={name} onChange={(e) => { setName(e.target.value.toUpperCase()); setNameError(""); }} type="text" placeholder="Enter Full Name" className="w-full h-[55px] bg-secondary2 pl-4 text-[22px] font-Roboto font-light rounded-lg outline-none border-[0.5px] border-[#1e1e1e] placeholder-gray-600" /> <p className="absolute text-white mix-blend-difference top-[-40px] left-2 text-sm animate-pulse"> {nameError} </p> </label> <label className="relative"> <input value={email} onChange={(e) => { setEmail(e.target.value); setEmailError(""); }} type="email" placeholder="Enter Email" className="w-full h-[55px] bg-secondary2 pl-4 text-[22px] font-Roboto font-light rounded-lg mt-[22px] outline-none border-[0.5px] border-[#1e1e1e] placeholder-gray-600" /> <p className="absolute text-white mix-blend-difference top-[-40px] left-2 text-sm animate-pulse"> {emailError} </p> </label> <label className="relative"> <input value={phone} onChange={(e) => { setPhone(e.target.value.replace(/[^0-9]/g, "")); setPhoneError(""); }} type="text" placeholder="Enter Phone Number" maxLength={10} className="w-full h-[55px] bg-secondary2 pl-4 text-[22px] font-Roboto font-light rounded-lg mt-[22px] outline-none border-[0.5px] border-[#1e1e1e] placeholder-gray-600" /> <p className="absolute text-white mix-blend-difference top-[-40px] left-2 text-sm animate-pulse"> {phoneError} </p> </label> <button className="w-full h-[50px] bg-secondary1 hover:bg-sky-300 outline-none rounded-lg mt-5 font-black font-Roboto text-lg border-[2px] border-[#1e1e1e]" type="submit" > Pay and Register </button> </form> <ToastContainer /> </> ); }; export default RegisterForm;
Preview:
downloadDownload PNG
downloadDownload JPEG
downloadDownload SVG
Tip: You can change the style, width & colours of the snippet with the inspect tool before clicking Download!
Click to optimize width for Twitter