Merge pull request #338 from OpenSignLabs/api-v1-beta

feat: enable automatic redirect to remembered url after login
This commit is contained in:
prafull-opensignlabs
2024-01-22 14:21:19 +05:30
committed by GitHub
14 changed files with 1507 additions and 186 deletions
+1
View File
@@ -0,0 +1 @@
v1.1.1-beta
+17 -99
View File
@@ -7,7 +7,7 @@ import Signup from "./routes/Signup";
import Form from "./routes/Form";
import Report from "./routes/Report";
import Dashboard from "./routes/Dashboard";
import PlanSubscriptions from "./routes/PlanSubscriptions";
import Subscriptions from "./routes/PlanSubscriptions";
import HomeLayout from "./layout/HomeLayout";
import UserProfile from "./routes/UserProfile";
import PageNotFound from "./routes/PageNotFound";
@@ -60,112 +60,30 @@ function App() {
) : (
<BrowserRouter>
<Routes>
<Route
exact
path="/"
element={
<ValidateRoute>
<Login />
</ValidateRoute>
}
/>
<Route
exact
path="/signup"
element={
<ValidateRoute>
<Signup />
</ValidateRoute>
}
/>
<Route element={<ValidateRoute />}>
<Route exact path="/" element={<Login />} />
<Route exact path="/signup" element={<Signup />} />
</Route>
<Route exact path="/loadmf/:remoteApp/*" element={<LoadMf />} />
<Route exact path="/forgetpassword" element={<ForgetPassword />} />
{process.env.REACT_APP_ENABLE_SUBSCRIPTION && (
<>
<Route exact path="/pgsignup" element={<Pgsignup />} />
<Route
exact
path="/subscription"
element={<PlanSubscriptions />}
/>
<Route exact path="/subscription" element={<Subscriptions />} />
</>
)}
<Route
exact
path="/changepassword"
element={
<HomeLayout>
<ChangePassword />
</HomeLayout>
}
/>
<Route
path="/mf/:remoteApp/*"
element={
<HomeLayout>
<Microapp />
</HomeLayout>
}
/>
<Route
path="/asmf/:remoteApp/*"
element={
<HomeLayout>
<Microapp />
</HomeLayout>
}
/>
<Route
path="/rpmf/:remoteApp/*"
element={
<HomeLayout>
<ReportMicroapp />
</HomeLayout>
}
/>
<Route
path="/form/:id"
element={
<HomeLayout>
<Form />
</HomeLayout>
}
/>
<Route
path="/report/:id"
element={
<HomeLayout>
<Report />
</HomeLayout>
}
/>
<Route
path="/dashboard/:id"
element={
<HomeLayout>
<Dashboard />
</HomeLayout>
}
/>
<Route
path="/profile"
element={
<HomeLayout>
<UserProfile />
</HomeLayout>
}
/>
<Route
path="/generatetoken"
element={
<HomeLayout>
<GenerateToken />
</HomeLayout>
}
/>
<Route element={<HomeLayout />}>
<Route path="/changepassword" element={<ChangePassword />} />
<Route path="/mf/:remoteApp/*" element={<Microapp />} />
<Route path="/asmf/:remoteApp/*" element={<Microapp />} />
<Route path="/rpmf/:remoteApp/*" element={<ReportMicroapp />} />
<Route path="/form/:id" element={<Form />} />
<Route path="/report/:id" element={<Report />} />
<Route path="/dashboard/:id" element={<Dashboard />} />
<Route path="/profile" element={<UserProfile />} />
<Route path="/generatetoken" element={<GenerateToken />} />
</Route>
<Route path="*" element={<PageNotFound />} />
{/* <Route exact path="/ForgotPassword" element={<ForgotPassword />} /> */}
</Routes>
</BrowserRouter>
)}
+47 -24
View File
@@ -8,15 +8,16 @@ import axios from "axios";
import { useSelector } from "react-redux";
import Parse from "parse";
import ModalUi from "../primitives/ModalUi";
import { useNavigate } from "react-router-dom";
import { useNavigate, useLocation, Outlet } from "react-router-dom";
const HomeLayout = ({ children }) => {
const HomeLayout = () => {
const navigate = useNavigate();
const location = useLocation();
const { width } = useWindowSize();
const [isOpen, setIsOpen] = useState(true);
const arr = useSelector((state) => state.TourSteps);
const [isUserValid, setIsUserValid] = useState(true);
const [isLoader, setIsLoader] = useState(true);
useEffect(() => {
(async () => {
try {
@@ -27,6 +28,7 @@ const HomeLayout = ({ children }) => {
});
if (user) {
setIsUserValid(true);
setIsLoader(false);
} else {
setIsUserValid(false);
}
@@ -184,7 +186,7 @@ const HomeLayout = ({ children }) => {
console.log("err ", err);
} finally {
localStorage.removeItem("accesstoken");
navigate("/", { replace: true });
navigate("/", { replace: true, state: { from: location } });
}
};
return (
@@ -194,27 +196,48 @@ const HomeLayout = ({ children }) => {
</div>
{isUserValid ? (
<>
<div className="flex md:flex-row flex-col z-50">
<Sidebar isOpen={isOpen} closeSidebar={closeSidebar} />
<div className="relative h-screen flex flex-col justify-between w-full overflow-y-auto">
<div className="bg-[#eef1f5] p-3">{children}</div>
<div className="z-30">
<Footer />
</div>
{isLoader ? (
<div
style={{
height: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center"
}}
>
<div
style={{
fontSize: "45px",
color: "#3dd3e0"
}}
className="loader-37"
></div>
</div>
</div>
<Tour
onRequestClose={closeTour}
steps={tourConfigs}
isOpen={isTour}
closeWithMask={false}
disableKeyboardNavigation={["esc"]}
// disableInteraction={true}
scrollOffset={-100}
rounded={5}
showCloseButton={isCloseBtn}
/>
) : (
<>
<div className="flex md:flex-row flex-col z-50">
<Sidebar isOpen={isOpen} closeSidebar={closeSidebar} />
<div className="relative h-screen flex flex-col justify-between w-full overflow-y-auto">
<div className="bg-[#eef1f5] p-3">{<Outlet />}</div>
<div className="z-30">
<Footer />
</div>
</div>
</div>
<Tour
onRequestClose={closeTour}
steps={tourConfigs}
isOpen={isTour}
closeWithMask={false}
disableKeyboardNavigation={["esc"]}
// disableInteraction={true}
scrollOffset={-100}
rounded={5}
showCloseButton={isCloseBtn}
/>
</>
)}
</>
) : (
<ModalUi title={"Session Expired"} isOpen={true} showClose={false}>
@@ -1,7 +1,7 @@
import React, { useEffect } from "react";
import Parse from "parse";
const ValidateRoute = ({ children }) => {
import { Outlet } from "react-router-dom";
const ValidateRoute = () => {
useEffect(() => {
(async () => {
try {
@@ -28,7 +28,7 @@ const ValidateRoute = ({ children }) => {
localStorage.removeItem("accesstoken");
}
};
return <div>{children}</div>;
return <div>{<Outlet />}</div>;
};
export default ValidateRoute;
+1 -1
View File
@@ -24,7 +24,7 @@ const Dashboard = (props) => {
getDashboard(localStorage.getItem("PageLanding"));
}
} else {
navigate("/", { replace: true });
navigate("/", { replace: true, state: { from: location } });
}
// eslint-disable-next-line
}, [id]);
+19 -22
View File
@@ -8,12 +8,13 @@ import axios from "axios";
import Title from "../components/Title";
import GoogleSignInBtn from "../components/LoginGoogle";
// import LoginFacebook from "../components/LoginFacebook";
import { NavLink, useNavigate } from "react-router-dom";
import { NavLink, useNavigate, useLocation } from "react-router-dom";
import login_img from "../assets/images/login_img.svg";
import { useWindowSize } from "../hook/useWindowSize";
function Login(props) {
const navigate = useNavigate();
const location = useLocation();
const { width } = useWindowSize();
const [state, setState] = useState({
email: "",
@@ -132,6 +133,9 @@ function Login(props) {
`${localStorage.getItem("_appName")}_appeditor`
) {
userSettings.forEach(async (element) => {
const redirectUrl =
location?.state?.from ||
`/${element.pageType}/${element.pageId}`;
if (element.role === _currentRole) {
let _role = _currentRole.replace(
`${localStorage.getItem("_appName")}_`,
@@ -260,9 +264,8 @@ function Login(props) {
localStorage.removeItem(
"userDetails"
);
navigate(
`/${element.pageType}/${element.pageId}`
);
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
} else {
navigate(`/subscription`, {
replace: true
@@ -274,9 +277,8 @@ function Login(props) {
});
}
} else {
navigate(
`/${element.pageType}/${element.pageId}`
);
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
}
}
} else {
@@ -313,9 +315,8 @@ function Login(props) {
});
}
} else {
navigate(
`/${element.pageType}/${element.pageId}`
);
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
}
}
},
@@ -462,6 +463,9 @@ function Login(props) {
`${localStorage.getItem("_appName")}_appeditor`
) {
userSettings.forEach(async (element) => {
const redirectUrl =
location?.state?.from ||
`/${element.pageType}/${element.pageId}`;
if (element.role === _currentRole) {
let _role = _currentRole.replace(
`${localStorage.getItem("_appName")}_`,
@@ -569,9 +573,7 @@ function Login(props) {
if (billingDate) {
if (billingDate > new Date()) {
localStorage.removeItem("userDetails");
navigate(
`/${element.pageType}/${element.pageId}`
);
navigate(redirectUrl);
} else {
navigate(`/subscription`, {
replace: true
@@ -581,9 +583,7 @@ function Login(props) {
navigate(`/subscription`, { replace: true });
}
} else {
navigate(
`/${element.pageType}/${element.pageId}`
);
navigate(redirectUrl);
}
}
} else {
@@ -599,9 +599,8 @@ function Login(props) {
if (billingDate) {
if (billingDate > new Date()) {
localStorage.removeItem("userDetails");
navigate(
`/${element.pageType}/${element.pageId}`
);
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
} else {
navigate(`/subscription`, { replace: true });
}
@@ -609,9 +608,7 @@ function Login(props) {
navigate(`/subscription`, { replace: true });
}
} else {
navigate(
`/${element.pageType}/${element.pageId}`
);
navigate(redirectUrl);
}
}
},
+16 -7
View File
@@ -5,7 +5,7 @@ import axios from "axios";
import { fetchAppInfo, showTenantName } from "../redux/actions/index";
import { connect } from "react-redux";
import Title from "../components/Title";
import { useNavigate } from "react-router-dom";
import { useNavigate, useLocation } from "react-router-dom";
const appId = localStorage.getItem("AppID12");
const server = localStorage.getItem("BaseUrl12");
@@ -13,6 +13,7 @@ Parse.serverURL = server;
Parse.initialize(appId);
const PgSignUp = (props) => {
const navigate = useNavigate();
const location = useLocation();
const [parseBaseUrl] = useState(localStorage.getItem("BaseUrl12"));
const [parseAppId] = useState(localStorage.getItem("AppID12"));
const [formData, setFormData] = useState({
@@ -187,7 +188,7 @@ const PgSignUp = (props) => {
console.log("err ", error);
if (error.message === "Account already exists for this username.") {
alert("Account already exists!");
navigate("/");
navigate("/", { replace: true });
} else {
setIsLoader(false);
alert("Something went wrong, please try again later!");
@@ -351,7 +352,7 @@ const PgSignUp = (props) => {
element.pageType
);
setIsLoader(false);
navigate("/");
navigate("/", { replace: true });
} else {
extendedInfo.forEach((x) => {
if (x.TenantId) {
@@ -389,9 +390,12 @@ const PgSignUp = (props) => {
);
setIsLoader(false);
alert("Registered user successfully");
navigate(
`/${element.pageType}/${element.pageId}`
);
const redirectUrl =
location?.state?.from ||
`/${element.pageType}/${element.pageId}`;
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
}
} else {
alert("Registered user successfully");
@@ -402,7 +406,12 @@ const PgSignUp = (props) => {
);
localStorage.setItem("pageType", element.pageType);
setIsLoader(false);
navigate(`/${element.pageType}/${element.pageId}`);
const redirectUrl =
location?.state?.from ||
`/${element.pageType}/${element.pageId}`;
// Redirect to the appropriate URL after successful login
navigate(redirectUrl);
}
},
(error) => {
+1 -26
View File
@@ -39,7 +39,7 @@ const PlanSubscriptions = () => {
setIsLoader(false);
setYearlyVisible(false);
} else {
navigate("/");
navigate("/", { replace: true });
}
// eslint-disable-next-line
}, []);
@@ -78,31 +78,6 @@ const PlanSubscriptions = () => {
id="monthlyPlans"
className={`${yearlyVisible ? "none" : "block my-2"}`}
>
{/* <div className=" my-2 w-full flex justify-center">
<ul
className="navs"
style={{
listStyle: "none",
display: "flex",
alignItems: "baseline"
}}
>
<li className="nav-item">
<button className="nav-link frequency active" name="1_months">
Monthly
</button>
</li>
<li className="nav-item">
<button
className="nav-link frequency "
onClick={toggleFrequency}
name="1_years"
>
Yearly
</button>
</li>
</ul>
</div> */}
<div className="flex justify-center w-full my-2">
<ul className=" flex flex-col md:flex-row h-full bg-white justify-center border-collapse border-[1px] border-gray-300">
{plansArr.map((item) => (
@@ -20,7 +20,7 @@ import multer from 'multer';
// import fs from 'node:fs';
import updateDocument from './routes/updateDocument.js';
import deleteDocument from './routes/deleteDocument.js';
// import createDocumentWithTemplate from './routes/CreateDocumentWithTemplate.js';
import createDocumentWithTemplate from './routes/CreateDocumentWithTemplate.js';
dotenv.config();
const storage = multer.memoryStorage();
@@ -49,7 +49,8 @@ app.get('/contactlist', getContactList);
app.post('/createdocument', upload.array('file', 1), createDocument);
// create Document with templateId
// app.post('/createdocument/:template_id', createDocumentWithTemplate);
app.post('/createdocument/:template_id', createDocumentWithTemplate);
// get Document on the basis of id
app.get('/document/:document_id', getDocument);
@@ -0,0 +1,98 @@
const randomId = () => Math.floor(1000 + Math.random() * 9000);
export default async function createDocumentWithTemplate(request, response) {
const signers = request.body.Signers;
const folderId = request.body.FolderId;
const templateId = request.params.template_id;
const url = process.env.SERVER_URL;
try {
const reqToken = request.headers['x-api-token'];
if (!reqToken) {
return response.status(400).json({ error: 'Please Provide API Token' });
}
const tokenQuery = new Parse.Query('appToken');
tokenQuery.equalTo('token', reqToken);
const token = await tokenQuery.first({ useMasterKey: true });
if (token !== undefined) {
// Valid Token then proceed request
const userPtr = token.get('userId');
const templateQyuery = new Parse.Query('contracts_Template');
const templateRes = await templateQyuery.get(templateId, { useMasterKey: true });
if (templateRes) {
const template = JSON.parse(JSON.stringify(templateRes));
if (template?.Placeholders?.length > 0) {
let isValid = template?.Placeholders?.length <= signers?.length;
let updateSigners = template?.Placeholders?.every(y =>
signers?.some(x => x.Role === y.Role)
);
if (isValid && updateSigners) {
const folderPtr = {
__type: 'Pointer',
className: 'contracts_Document',
objectId: folderId,
};
const template = JSON.parse(JSON.stringify(templateRes));
const object = new Parse.Object('contracts_Document');
object.set('Name', template.Name);
if (template?.Note) {
object.set('Note', template.Note);
}
if (template?.Description) {
object.set('Description', template.Description);
}
if (template?.Signers) {
object.set('Signers', template?.Signers);
}
object.set('URL', template.URL);
object.set('CreatedBy', template.CreatedBy);
object.set('ExtUserPtr', template.ExtUserPtr);
if (signers) {
const placeholders = template?.Placeholders?.map(placeholder => {
let matchingSigner = signers.find(y => y.Role === placeholder.Role);
if (matchingSigner) {
return {
...placeholder,
email: matchingSigner.Email,
signerObjId: '',
signerPtr: {},
};
} else {
return {
...placeholder,
};
}
});
console.log('placeholders ', placeholders);
object.set('Placeholders', placeholders);
}
if (folderId) {
object.set('Folder', folderPtr);
}
const newACL = new Parse.ACL();
newACL.setPublicReadAccess(false);
newACL.setPublicWriteAccess(false);
newACL.setReadAccess(userPtr.id, true);
newACL.setWriteAccess(userPtr.id, true);
object.setACL(newACL);
const res = await object.save(null, { useMasterKey: true });
return response.json({ objectId: res.id, url: url });
} else {
return response.status(400).json({ error: 'Please provide signers properly!' });
}
} else {
return response.status(400).json({ error: 'Please setup template properly!' });
}
} else {
return response.status(404).json({ error: 'Invalid template id!' });
}
} else {
return response.status(405).json({ error: 'Invalid API Token!' });
}
} catch (err) {
console.log('err ', err);
if (err.code === 101) {
return response.status(404).json({ error: 'Invalid template id!' });
}
return response.status(400).json({ error: 'Something went wrong!' });
}
}
@@ -151,7 +151,7 @@ exports.up = async Parse => {
},
{
icon: 'fa-solid fa-key',
title: 'Generate token',
title: 'API Token',
target: '_self',
pageType: 'generatetoken',
description: '',
@@ -316,7 +316,7 @@ exports.up = async Parse => {
},
{
icon: 'fa-solid fa-key',
title: 'Generate token',
title: 'API Token',
target: '_self',
pageType: 'generatetoken',
description: '',
@@ -10,6 +10,7 @@ import LegaDrive from "./Component/LegaDrive/LegaDrive";
import PageNotFound from "./Component/PageNotFound";
import TemplatePlaceHolder from "./Component/TemplatePlaceholder";
import Parse from "parse";
import GuestLogin from "./premitives/GuestLogin";
Parse.serverURL = localStorage.getItem("baseUrl");
Parse.initialize(localStorage.getItem("parseAppId"));
// `AppRoutes` is used to define route path of app and
@@ -50,6 +51,8 @@ function AppRoutes() {
<Route path="/legadrive" element={<LegaDrive />} />
{/* Page Not Found */}
<Route path="/template/:templateId" element={<TemplatePlaceHolder />} />
<Route path="/guestlogin" element={<GuestLogin />} />
<Route path="*" element={<PageNotFound />} />
</Routes>
</div>
@@ -0,0 +1,294 @@
import React, { useState } from "react";
import ModalUi from './ModalUi'
import "../css/LoginPage.css";
import loader from "../assests/loader2.gif";
import axios from "axios";
import { useParams } from "react-router-dom";
import { themeColor } from "../utils/ThemeColor/backColor";
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import GuestSign from "./GuestSign";
function GuestLogin({children, userdetails}) {
const { id, userMail, contactBookId, serverUrl } = useParams();
let navigate = useNavigate();
const [email, setEmail] = useState(userMail || "prafull.navkar@nxglabs.com");
const [OTP, setOTP] = useState("");
const [EnterOTP, setEnterOtp] = useState(false);
const [loading, setLoading] = useState(false);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
handleServerUrl();
}, []);
//function generate serverUrl and parseAppId from url and save it in local storage
const handleServerUrl = () => {
//split url in array from '&'
localStorage.clear();
// const checkSplit = serverUrl?.split("&");
// const server = checkSplit?.[0];
// const parseId = checkSplit?.[1];
// const appName = checkSplit?.[2];
// const newServer = server.replaceAll("%2F", "/");
// localStorage.setItem("baseUrl", newServer);
// localStorage.setItem("parseAppId", parseId);
// localStorage.setItem("_appName", appName);
localStorage.setItem("baseUrl", "https://staging-app.opensignlabs.com/api/app/");
localStorage.setItem("parseAppId", "opensignstgn");
localStorage.setItem("_appName", "contracts");
setIsLoading(false);
};
const handleChange = (event) => {
const { value } = event.target;
setOTP(value);
};
//send email OTP function
const SendOtp = async (e) => {
const serverUrl =
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
const parseId =
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
if (serverUrl && localStorage) {
setLoading(true);
e.preventDefault();
setEmail(email);
try {
let url = `${serverUrl}functions/SendOTPMailV1/`;
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": parseId
};
let body = {
email: email.toString()
};
let Otp = await axios.post(url, body, { headers: headers });
if (Otp) {
setLoading(false);
setEnterOtp(true);
}
} catch (error) {
alert("something went wrong!");
}
} else {
alert("something went wrong!");
}
};
//verify OTP send on via email
const VerifyOTP = async (e) => {
e.preventDefault();
const serverUrl =
localStorage.getItem("baseUrl") && localStorage.getItem("baseUrl");
const parseId =
localStorage.getItem("parseAppId") && localStorage.getItem("parseAppId");
if (OTP) {
setLoading(true);
try {
let url = `${serverUrl}functions/AuthLoginAsMail/`;
const headers = {
"Content-Type": "application/json",
"X-Parse-Application-Id": parseId
};
let body = {
email: email,
otp: OTP
};
let user = await axios.post(url, body, { headers: headers });
if (user.data.result === "Invalid Otp") {
alert("Invalid Otp");
setLoading(false);
} else if (user.data.result === "user not found!") {
alert("User not found!");
setLoading(false);
} else {
let _user = user.data.result;
const parseId = localStorage.getItem("parseAppId");
localStorage.setItem("UserInformation", JSON.stringify(_user));
localStorage.setItem(
`Parse/${parseId}/currentUser`,
JSON.stringify(_user)
);
localStorage.setItem("username", _user.name);
localStorage.setItem("accesstoken", _user.sessionToken);
//save isGuestSigner true in local to handle login flow header in mobile view
localStorage.setItem("isGuestSigner", true);
setLoading(false);
// uKymQWaYL6
navigate(
`/loadmf/signmicroapp/recipientSignPdf/${id}/${contactBookId}`
);
}
} catch (error) {}
} else {
alert("Please Enter OTP!");
}
};
return (
<div style={{ padding: "2rem" }}>
<ModalUi isOpen>
<>
{isLoading ? (
<div
style={{
display: "flex",
justifyContent: "center",
alignItems: "center",
height: "100vh",
flexDirection: "column"
}}
>
<img
alt="no img"
src={loader}
style={{ width: "80px", height: "80px" }}
/>
<span style={{ fontSize: "13px", color: "gray" }}>
{isLoading.message}
</span>
</div>
) : (
<div
style={{
margin: "10px",
border: "0.5px solid #c5c7c9",
padding: "30px",
boxShadow: "rgba(99, 99, 99, 0.2) 0px 2px 8px 0px"
}}
>
<div className="main_head">
<div className="main-logo">
<img
alt="sign img"
src="https://qikinnovation.ams3.digitaloceanspaces.com/logo.png"
width="100%"
/>
</div>
</div>
{!EnterOTP ? (
<div >
<div >
<span className="welcomeText">Welcome Back !</span>
<br />
<span className="KNLO">
Verification code is sent to your email
</span>
<div className="card card-box" style={{ borderRadius: "0px" }}>
<div className="card-body">
<input
type="email"
name="mobile"
value={email}
disabled
className="loginInput"
/>
<br />
</div>
</div>
<div className="btnContainer">
{loading ? (
<button
type="button"
style={{
background: themeColor(),
color: "white"
}}
className="verifyBtn"
disabled
>
<span
className="spinner-border spinner-border-sm "
role="status"
aria-hidden="true"
></span>
Loading...
</button>
) : (
<button
className="verifyBtn"
style={{
background: themeColor(),
color: "white",
marginLeft: "0px !important"
}}
onClick={(e) => SendOtp(e)}
>
Send OTP
</button>
)}
</div>
</div>
</div>
) : (
<div >
<div >
<span className="welcomeText">Welcome Back !</span>
<br />
<span className="KNLO">You will get a OTP via Email</span>
<div className="card card-box">
<div className="card-body">
<label>Enter Verification Code</label>
<input
type="number"
className="loginInput"
name="OTP"
value={OTP}
onChange={handleChange}
/>
<br />
</div>
</div>
<div>
{loading ? (
<button
style={{
background: themeColor(),
color: "white"
}}
className="verifyBtn"
type="button"
disabled
>
<span
className="spinner-border spinner-border-sm "
role="status"
aria-hidden="true"
></span>
Loading...
</button>
) : (
<button
type="button"
onClick={(e) => VerifyOTP(e)}
style={{
background: themeColor(),
color: "white"
}}
className="verifyBtn"
>
Verify
</button>
)}
</div>
</div>
</div>
)}
</div>
)}
</>
</ModalUi>
<div><GuestSign /></div>
</div>
);
}
export default GuestLogin;
File diff suppressed because it is too large Load Diff