changes to green theme
This commit is contained in:
parent
394d28f80d
commit
0d0b7f2cbc
@ -31,6 +31,8 @@
|
||||
<link rel="stylesheet" href="/assets/css/default.css" />
|
||||
<link rel="stylesheet" href="/assets/css/skeleton.css" />
|
||||
<link rel="stylesheet" href="/assets/css/hover-utility.css" />
|
||||
<link rel="stylesheet" href="/assets/css/theme-green.css" />
|
||||
|
||||
|
||||
<link rel="stylesheet" href="/assets/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
||||
|
||||
|
||||
55
public/assets/css/theme-green.css
Normal file
55
public/assets/css/theme-green.css
Normal file
@ -0,0 +1,55 @@
|
||||
.btn-green {
|
||||
background-color: #49bf3c;
|
||||
color: #fff;
|
||||
border-radius: 50px;
|
||||
padding: 10px 30px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-green-outline {
|
||||
border-color: #49bf3c;
|
||||
background-color: transparent;
|
||||
color: unset;
|
||||
}
|
||||
|
||||
.btn-green-outline:hover {
|
||||
background-color: #49bf3c;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-square-small {
|
||||
border-radius: 3px;
|
||||
padding-bottom: 5.072px;
|
||||
padding-inline-end: 12px;
|
||||
padding-inline-start: 12px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
padding-top: 5.072px;
|
||||
}
|
||||
|
||||
.btn-green:hover {
|
||||
background-color: #00a85a;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.text-blue {
|
||||
color: #696cff !important;
|
||||
}
|
||||
.text-green {
|
||||
color: #49bf3c !important;
|
||||
}
|
||||
|
||||
.btn-outline-green {
|
||||
border-radius: 50px;
|
||||
padding: 10px 30px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-outline-green:hover {
|
||||
background-color: #49bf3c;
|
||||
color: #fff;
|
||||
}
|
||||
@ -28,16 +28,13 @@
|
||||
color: #4fc143;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
/* .text-primary {
|
||||
color: #49bf3c !important;
|
||||
}
|
||||
.text-blue {
|
||||
color: #696cff !important;
|
||||
}
|
||||
} */
|
||||
|
||||
.btn-primary {
|
||||
/* .btn-primary {
|
||||
background-color: #49bf3c !important;
|
||||
}
|
||||
} */
|
||||
|
||||
body {
|
||||
font-family: "Segoe UI", Roboto, sans-serif;
|
||||
@ -238,28 +235,3 @@ body {
|
||||
margin-top: 15px;
|
||||
margin-bottom: 25px;
|
||||
}
|
||||
|
||||
.btn-green {
|
||||
background-color: #49bf3c;
|
||||
color: #fff;
|
||||
border-radius: 50px;
|
||||
padding: 10px 30px;
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.btn-square-small {
|
||||
border-radius: 3px;
|
||||
padding-bottom: 5.072px;
|
||||
padding-inline-end: 12px;
|
||||
padding-inline-start: 12px;
|
||||
padding-left: 12px;
|
||||
padding-right: 12px;
|
||||
padding-top: 5.072px;
|
||||
}
|
||||
|
||||
.btn-green:hover {
|
||||
background-color: #00a85a;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ const LandingPage = () => {
|
||||
<div className="container-fluid px-5 w-100">
|
||||
<div className="row w-100">
|
||||
<div className="col-md-auto d-flex justify-content-between align-items-center">
|
||||
<a className="navbar-brand fw-bold text-primary" href="#">
|
||||
<a className="navbar-brand fw-bold text-green" href="#">
|
||||
<span className="text-blue">OnField</span>
|
||||
<span>Work</span>
|
||||
<span className="text-dark">.com</span>
|
||||
@ -187,7 +187,7 @@ const LandingPage = () => {
|
||||
<div className="card-slider p-4 bg-light rounded-4 h-100 text-start border">
|
||||
<div className="feature-icon mb-3">
|
||||
<img
|
||||
src="../../../public/img/icons/dashboard.png"
|
||||
src="/img/icons/dashboard.png"
|
||||
alt="Dashboard"
|
||||
className="w-14 mb-4 feature-icon-image"
|
||||
/>
|
||||
@ -203,7 +203,7 @@ const LandingPage = () => {
|
||||
<div className="card-slider p-4 bg-light rounded-4 h-100 text-start border">
|
||||
<div className="feature-icon mb-3">
|
||||
<img
|
||||
src="../../../public/img/icons/attendance.png"
|
||||
src="/img/icons/attendance.png"
|
||||
alt="Smart Attendance"
|
||||
className="w-14 mb-4 feature-icon-image"
|
||||
/>
|
||||
@ -220,7 +220,7 @@ const LandingPage = () => {
|
||||
<div className="card-slider p-4 bg-light rounded-4 h-100 text-start border">
|
||||
<div className="feature-icon mb-3">
|
||||
<img
|
||||
src="../../../public/img/icons/spending.png"
|
||||
src="/img/icons/spending.png"
|
||||
alt="Expense & Budget Tracking"
|
||||
className="w-14 mb-4 feature-icon-image"
|
||||
/>
|
||||
@ -236,7 +236,7 @@ const LandingPage = () => {
|
||||
<div className="card-slider p-4 bg-light rounded-4 h-100 text-start border">
|
||||
<div className="feature-icon mb-3">
|
||||
<img
|
||||
src="../../../public/img/icons/directory.png"
|
||||
src="/img/icons/directory.png"
|
||||
alt="Cloud Scalability"
|
||||
className="w-14 mb-4 feature-icon-image"
|
||||
/>
|
||||
@ -252,7 +252,7 @@ const LandingPage = () => {
|
||||
<div className="card-slider p-4 bg-light rounded-4 h-100 text-start border">
|
||||
<div className="feature-icon mb-3">
|
||||
<img
|
||||
src="../../../public/img/icons/report.png"
|
||||
src="/img/icons/report.png"
|
||||
alt="Advanced Reporting"
|
||||
className="w-14 mb-4 feature-icon-image"
|
||||
/>
|
||||
@ -269,7 +269,7 @@ const LandingPage = () => {
|
||||
<div className="card-slider p-4 bg-light rounded-4 h-100 text-start border">
|
||||
<div className="feature-icon mb-3">
|
||||
<img
|
||||
src="../../../public/img/icons/cloud-service.png"
|
||||
src="/img/icons/cloud-service.png"
|
||||
alt="Cloud Scalability"
|
||||
className="w-14 mb-4 feature-icon-image"
|
||||
/>
|
||||
@ -298,7 +298,7 @@ const LandingPage = () => {
|
||||
<div className="col-md-4">
|
||||
<div className="card pricing-card border-0 shadow-sm">
|
||||
<div className="card-body">
|
||||
<h5 className="text-primary fw-bold">Starter</h5>
|
||||
<h5 className="text-green fw-bold">Starter</h5>
|
||||
<h2>
|
||||
₹499<span className="fs-6 text-muted">/month</span>
|
||||
</h2>
|
||||
@ -317,7 +317,7 @@ const LandingPage = () => {
|
||||
<div className="col-md-4">
|
||||
<div className="card pricing-card border-primary shadow-lg">
|
||||
<div className="card-body">
|
||||
<h5 className="text-primary fw-bold">Professional</h5>
|
||||
<h5 className="text-green fw-bold">Professional</h5>
|
||||
<h2>
|
||||
₹999<span className="fs-6 text-muted">/month</span>
|
||||
</h2>
|
||||
@ -339,7 +339,7 @@ const LandingPage = () => {
|
||||
<div className="col-md-4">
|
||||
<div className="card pricing-card border-0 shadow-sm">
|
||||
<div className="card-body">
|
||||
<h5 className="text-primary fw-bold">Enterprise</h5>
|
||||
<h5 className="text-green fw-bold">Enterprise</h5>
|
||||
<h2>Custom</h2>
|
||||
<ul className="list-unstyled mt-3 mb-4 text-muted">
|
||||
<li>Dedicated support</li>
|
||||
@ -360,14 +360,14 @@ const LandingPage = () => {
|
||||
<div className="container text-start" style={{ maxWidth: "75%" }}>
|
||||
<h2 className="fw-bold mb-4 text-center">
|
||||
About{" "}
|
||||
<a className="text-primary" href="#">
|
||||
<a className="text-green" href="#">
|
||||
<span className="text-blue">OnField</span>
|
||||
<span>Work</span>
|
||||
<span className="text-dark">.com</span>
|
||||
</a>
|
||||
</h2>
|
||||
<p>
|
||||
<a className="text-primary" href="#">
|
||||
<a className="text-green" href="#">
|
||||
<span className="text-blue">OnField</span>
|
||||
<span>Work</span>
|
||||
<span className="text-dark">.com</span>
|
||||
@ -378,7 +378,7 @@ const LandingPage = () => {
|
||||
<p>
|
||||
Whether you manage on-site teams, oversee multiple projects, or
|
||||
coordinate vendors and suppliers,{" "}
|
||||
<a className="text-primary" href="#">
|
||||
<a className="text-green" href="#">
|
||||
<span className="text-blue">OnField</span>
|
||||
<span>Work</span>
|
||||
<span className="text-dark">.com</span>
|
||||
@ -388,7 +388,7 @@ const LandingPage = () => {
|
||||
operations.
|
||||
</p>
|
||||
<h5> Our Mission</h5> At{" "}
|
||||
<a className="text-primary" href="#">
|
||||
<a className="text-green" href="#">
|
||||
<span className="text-blue">OnField</span>
|
||||
<span>Work</span>
|
||||
<span className="text-dark">.com</span>
|
||||
@ -401,7 +401,7 @@ const LandingPage = () => {
|
||||
a comprehensive suite of tools designed to handle every critical
|
||||
aspect of field management — from workforce tracking to expense
|
||||
control and reporting. With
|
||||
<a className="text-primary" href="#">
|
||||
<a className="text-green" href="#">
|
||||
<span className="text-blue">OnField</span>
|
||||
<span>Work</span>
|
||||
<span className="text-dark">.com</span>
|
||||
@ -443,7 +443,7 @@ const LandingPage = () => {
|
||||
</ul>
|
||||
<h5>
|
||||
Why Choose{" "}
|
||||
<a className="text-primary" href="#">
|
||||
<a className="text-green" href="#">
|
||||
<span className="text-blue">OnField</span>
|
||||
<span>Work</span>
|
||||
<span className="text-dark">.com</span>
|
||||
@ -498,7 +498,7 @@ const LandingPage = () => {
|
||||
aria-expanded="true"
|
||||
aria-controls="accordionOne"
|
||||
>
|
||||
What is MarcoPMS?
|
||||
What is OnFieldWork.com?
|
||||
</button>
|
||||
</h2>
|
||||
<div
|
||||
@ -552,7 +552,7 @@ const LandingPage = () => {
|
||||
aria-expanded="false"
|
||||
aria-controls="accordionThree"
|
||||
>
|
||||
How secure is Marco PMS?
|
||||
How secure is OnFieldWork.com?
|
||||
</button>
|
||||
</h2>
|
||||
<div
|
||||
@ -562,14 +562,14 @@ const LandingPage = () => {
|
||||
data-bs-parent="#accordionExample"
|
||||
>
|
||||
<div className="accordion-body text-start">
|
||||
Security is at the core of Marco PMS. We use industry-standard
|
||||
encryption (SSL/TLS) to protect data in transit and advanced
|
||||
encryption to safeguard data at rest. Role-based access
|
||||
controls ensure that only authorized users can access
|
||||
sensitive information. Our system is hosted on secure,
|
||||
cloud-ready infrastructure with regular backups, monitoring,
|
||||
and compliance with best practices to keep your data safe and
|
||||
available at all times.
|
||||
Security is at the core of OnFieldWork.com. We use
|
||||
industry-standard encryption (SSL/TLS) to protect data in
|
||||
transit and advanced encryption to safeguard data at rest.
|
||||
Role-based access controls ensure that only authorized users
|
||||
can access sensitive information. Our system is hosted on
|
||||
secure, cloud-ready infrastructure with regular backups,
|
||||
monitoring, and compliance with best practices to keep your
|
||||
data safe and available at all times.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -621,8 +621,8 @@ const LandingPage = () => {
|
||||
data-bs-parent="#accordionExample"
|
||||
>
|
||||
<div className="accordion-body text-start">
|
||||
Marco PMS operate under a proprietary license combined with a
|
||||
subscription model. This means customers don’t own the
|
||||
OnFieldWork.com operate under a proprietary license combined
|
||||
with a subscription model. This means customers don’t own the
|
||||
software but are granted the right to access and use it
|
||||
through the cloud under our Terms of Service. Depending on the
|
||||
plan, licensing may be based on users, features, or usage, and
|
||||
@ -640,7 +640,7 @@ const LandingPage = () => {
|
||||
aria-expanded="false"
|
||||
aria-controls="accordionSix"
|
||||
>
|
||||
Can I customize Marco PMS for my business needs?
|
||||
Can I customize OnFieldWork.com for my business needs?
|
||||
</button>
|
||||
</h2>
|
||||
<div
|
||||
@ -650,8 +650,8 @@ const LandingPage = () => {
|
||||
data-bs-parent="#accordionExample"
|
||||
>
|
||||
<div className="accordion-body text-start">
|
||||
Yes, Marco PMS is designed to be flexible and adaptable. You
|
||||
can customize workflows, user roles, permissions, and
|
||||
Yes, OnFieldWork.com is designed to be flexible and adaptable.
|
||||
You can customize workflows, user roles, permissions, and
|
||||
reporting to match your organization’s unique processes.
|
||||
Depending on your plan, we also support advanced customization
|
||||
such as integrating with third-party tools, adding custom
|
||||
@ -680,7 +680,7 @@ const LandingPage = () => {
|
||||
</div>
|
||||
<div className="col-lg-6 contact-text">
|
||||
<h2>
|
||||
Contact <span className="text-success">Us</span>
|
||||
Contact <span className="text-green">Us</span>
|
||||
</h2>
|
||||
<p>
|
||||
We’d love to hear from you! Whether you have a question about
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import { AuthWrapper } from "./AuthWrapper"
|
||||
import { AuthWrapper } from "./AuthWrapper";
|
||||
import "./page-auth.css";
|
||||
import AuthRepository from "../../repositories/AuthRepository";
|
||||
import showToast from "../../services/toastService";
|
||||
@ -8,54 +8,65 @@ import { useForm } from "react-hook-form";
|
||||
import { zodResolver } from "@hookform/resolvers/zod";
|
||||
import { z } from "zod";
|
||||
|
||||
|
||||
const forgotPassSceham = z.object({
|
||||
email: z.string().trim().email(),
|
||||
})
|
||||
});
|
||||
|
||||
const ForgotPasswordPage = () => {
|
||||
const [loding, setLoading] = useState(false);
|
||||
|
||||
const [loding, setLoading] = useState(false)
|
||||
|
||||
const { register,
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors },
|
||||
reset,
|
||||
getValues } = useForm({
|
||||
resolver: zodResolver(forgotPassSceham),
|
||||
defaultValues: {
|
||||
email: ""
|
||||
}
|
||||
})
|
||||
getValues,
|
||||
} = useForm({
|
||||
resolver: zodResolver(forgotPassSceham),
|
||||
defaultValues: {
|
||||
email: "",
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = async (data) => {
|
||||
try {
|
||||
setLoading(true)
|
||||
const response = await AuthRepository.forgotPassword(data)
|
||||
setLoading(true);
|
||||
const response = await AuthRepository.forgotPassword(data);
|
||||
if (response.data && response.success)
|
||||
showToast("verification email has been sent to your registered email address", "success")
|
||||
reset()
|
||||
setLoading(false)
|
||||
showToast(
|
||||
"verification email has been sent to your registered email address",
|
||||
"success"
|
||||
);
|
||||
reset();
|
||||
setLoading(false);
|
||||
} catch (err) {
|
||||
reset()
|
||||
reset();
|
||||
if (err.response.status === 404) {
|
||||
showToast("verification email has been sent to your registered email address", "success")
|
||||
showToast(
|
||||
"verification email has been sent to your registered email address",
|
||||
"success"
|
||||
);
|
||||
} else {
|
||||
showToast("Something wrong", "error")
|
||||
showToast("Something wrong", "error");
|
||||
}
|
||||
|
||||
setLoading(false)
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
return (
|
||||
<div className="col-12 col-lg-5 col-xl-4 d-flex align-items-center p-4 p-sm-5 bg-gray-60">
|
||||
<div className="col-12 col-lg-5 col-xl-4 d-flex align-items-center p-4 p-sm-5 bg-gray-60">
|
||||
<div className="w-100" style={{ maxWidth: 420, margin: "0 auto" }}>
|
||||
<h4 className="mb-2">Forgot Password? 🔒</h4>
|
||||
<p className="mb-4">
|
||||
Enter your email and we'll send you instructions to reset your password
|
||||
Enter your email and we'll send you instructions to reset your
|
||||
password
|
||||
</p>
|
||||
|
||||
<form id="formAuthentication" className="mb-3" onSubmit={handleSubmit(onSubmit)}>
|
||||
<form
|
||||
id="formAuthentication"
|
||||
className="mb-3"
|
||||
onSubmit={handleSubmit(onSubmit)}
|
||||
>
|
||||
<div className="mb-3 text-start">
|
||||
<label htmlFor="email" className="form-label">
|
||||
Email
|
||||
@ -78,26 +89,25 @@ const ForgotPasswordPage = () => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<button aria-label="Click me" className="btn btn-primary d-grid w-100">
|
||||
<button aria-label="Click me" className=" btn-green d-grid w-100">
|
||||
{loding ? "Please Wait..." : "Send Reset Link"}
|
||||
</button>
|
||||
</form>
|
||||
<div className="text-center">
|
||||
<Link
|
||||
aria-label="Go to Login Page"
|
||||
to="/auth/login"
|
||||
className="d-flex align-items-center justify-content-center"
|
||||
>
|
||||
<i className="bx bx-chevron-left scaleX-n1-rtl bx-sm"></i>
|
||||
Back to login
|
||||
</Link>
|
||||
</div>
|
||||
<div className="text-center">
|
||||
<Link
|
||||
aria-label="Go to Login Page"
|
||||
to="/auth/login"
|
||||
className="d-flex align-items-center justify-content-center text-green"
|
||||
>
|
||||
<i className="bx bx-chevron-left scaleX-n1-rtl bx-sm text-green"></i>
|
||||
Back to login
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Footer Text */}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ForgotPasswordPage;
|
||||
export default ForgotPasswordPage;
|
||||
|
||||
@ -49,16 +49,16 @@ const LoginPage = () => {
|
||||
// sessionStorage.setItem("refreshToken", response.data.refreshToken);
|
||||
// }
|
||||
setLoading(false);
|
||||
localStorage.setItem("jwtToken", response.data.token);
|
||||
localStorage.setItem("refreshToken", response.data.refreshToken);
|
||||
navigate("/dashboard",{ replace: true });
|
||||
localStorage.setItem("jwtToken", response.data.token);
|
||||
localStorage.setItem("refreshToken", response.data.refreshToken);
|
||||
navigate("/dashboard", { replace: true });
|
||||
} else {
|
||||
await AuthRepository.sendOTP({ email: data.username });
|
||||
showToast("OTP has been sent to your email.", "success");
|
||||
localStorage.setItem("otpUsername", data.username);
|
||||
localStorage.setItem("otpSentTime", now.toString());
|
||||
// navigate("/auth/login-otp");
|
||||
navigate("/dashboard",{ replace: true });
|
||||
navigate("/dashboard", { replace: true });
|
||||
}
|
||||
} catch (err) {
|
||||
showToast("Invalid username or password.", "error");
|
||||
@ -78,14 +78,13 @@ const LoginPage = () => {
|
||||
}, [IsLoginWithOTP]);
|
||||
|
||||
useEffect(() => {
|
||||
const token =
|
||||
localStorage.getItem("jwtToken") ||
|
||||
sessionStorage.getItem("jwtToken");
|
||||
const token =
|
||||
localStorage.getItem("jwtToken") || sessionStorage.getItem("jwtToken");
|
||||
|
||||
if (token) {
|
||||
navigate("/dashboard", { replace: true });
|
||||
}
|
||||
}, []);
|
||||
if (token) {
|
||||
navigate("/dashboard", { replace: true });
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="col-12 col-lg-5 col-xl-4 d-flex align-items-center p-4 p-sm-5 bg-gray-60">
|
||||
@ -182,7 +181,7 @@ const LoginPage = () => {
|
||||
</div>
|
||||
<Link
|
||||
to="/auth/forgot-password"
|
||||
className="text-decoration-none"
|
||||
className="text-decoration-none text-green"
|
||||
>
|
||||
Forgot Password?
|
||||
</Link>
|
||||
@ -191,11 +190,7 @@ const LoginPage = () => {
|
||||
)}
|
||||
|
||||
{/* Submit */}
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-primary w-100"
|
||||
disabled={loading}
|
||||
>
|
||||
<button type="submit" className=" btn-green w-100" disabled={loading}>
|
||||
{loading
|
||||
? "Please Wait..."
|
||||
: IsLoginWithOTP
|
||||
@ -211,7 +206,7 @@ const LoginPage = () => {
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-outline-secondary w-100"
|
||||
className="btn-green btn-green-outline w-100"
|
||||
onClick={() => setLoginWithOtp(true)}
|
||||
>
|
||||
Login With OTP
|
||||
@ -224,17 +219,20 @@ const LoginPage = () => {
|
||||
{!IsLoginWithOTP ? (
|
||||
<p className="text-center mt-3">
|
||||
<span>New on our platform? </span>
|
||||
<Link to="/auth/reqest/demo" className="btn btn-link p-0">
|
||||
<Link
|
||||
to="/auth/reqest/demo"
|
||||
className="btn btn-link p-0 text-green"
|
||||
>
|
||||
Request a Demo
|
||||
</Link>
|
||||
</p>
|
||||
) : (
|
||||
<div className="text-center mt-3">
|
||||
<button
|
||||
className="btn btn-link p-0"
|
||||
className="btn btn-link p-0 text-green"
|
||||
onClick={() => setLoginWithOtp(false)}
|
||||
>
|
||||
<i className="bx bx-chevron-left scaleX-n1-rtl bx-sm"></i>
|
||||
<i className="bx bx-chevron-left scaleX-n1-rtl bx-sm "></i>
|
||||
Back to login
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@ -21,7 +21,6 @@ const LoginWithOtp = () => {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [timeLeft, setTimeLeft] = useState(0);
|
||||
|
||||
|
||||
const inputRefs = useRef([]);
|
||||
|
||||
const {
|
||||
@ -43,17 +42,16 @@ const LoginWithOtp = () => {
|
||||
try {
|
||||
let requestedData = {
|
||||
email: username,
|
||||
otp: finalOtp
|
||||
}
|
||||
const response = await AuthRepository.verifyOTP(requestedData)
|
||||
otp: finalOtp,
|
||||
};
|
||||
const response = await AuthRepository.verifyOTP(requestedData);
|
||||
|
||||
localStorage.setItem("jwtToken", response.data.token);
|
||||
localStorage.setItem("refreshToken", response.data.refreshToken);
|
||||
setLoading(false);
|
||||
localStorage.removeItem("otpUsername");
|
||||
localStorage.removeItem("otpSentTime");
|
||||
navigate("/auth/switch/org");
|
||||
|
||||
navigate("/auth/switch/org");
|
||||
} catch (err) {
|
||||
showToast("Invalid or expired OTP.", "error");
|
||||
|
||||
@ -61,7 +59,9 @@ const LoginWithOtp = () => {
|
||||
}
|
||||
};
|
||||
const formatTime = (seconds) => {
|
||||
const min = Math.floor(seconds / 60).toString().padStart(2, "0");
|
||||
const min = Math.floor(seconds / 60)
|
||||
.toString()
|
||||
.padStart(2, "0");
|
||||
const sec = (seconds % 60).toString().padStart(2, "0");
|
||||
return `${min}:${sec}`;
|
||||
};
|
||||
@ -78,7 +78,6 @@ const LoginWithOtp = () => {
|
||||
}
|
||||
}, []);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (timeLeft <= 0) return;
|
||||
|
||||
@ -112,22 +111,22 @@ const LoginWithOtp = () => {
|
||||
}
|
||||
trigger(["otp1", "otp2", "otp3", "otp4"]);
|
||||
} else {
|
||||
showToast("Invalid OTP format pasted. Please enter 4 digits")
|
||||
showToast("Invalid OTP format pasted. Please enter 4 digits");
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
setValue(`otp${i + 1}`, "")
|
||||
|
||||
setValue(`otp${i + 1}`, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
return (
|
||||
// <AuthWrapper>
|
||||
<div className="col-12 col-lg-5 col-xl-4 d-flex align-items-center justify-content-center p-4 p-sm-5 bg-gray-60 h-100">
|
||||
<div className="block p-4 p-sm-5 bg-gray-60">
|
||||
<div className="col-12 col-lg-5 col-xl-4 d-flex align-items-center justify-content-center p-4 p-sm-5 bg-gray-60 h-100">
|
||||
<div className="block p-4 p-sm-5 bg-gray-60">
|
||||
<h4>Verify Your OTP</h4>
|
||||
<p className="mb-4">Please enter the 4-digit code sent to your email.</p>
|
||||
<p className="mb-4">
|
||||
Please enter the 4-digit code sent to your email.
|
||||
</p>
|
||||
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="d-flex justify-content-center gap-6 mb-3">
|
||||
@ -139,8 +138,9 @@ const LoginWithOtp = () => {
|
||||
key={num}
|
||||
type="text"
|
||||
maxLength={1}
|
||||
className={`form-control text-center ${errors[`otp${num}`] ? "is-invalid" : ""
|
||||
}`}
|
||||
className={`form-control text-center ${
|
||||
errors[`otp${num}`] ? "is-invalid" : ""
|
||||
}`}
|
||||
ref={(el) => {
|
||||
inputRefs.current[idx] = el;
|
||||
ref(el);
|
||||
@ -150,7 +150,6 @@ const LoginWithOtp = () => {
|
||||
onChange(e);
|
||||
if (/^\d$/.test(val) && idx < 3) {
|
||||
inputRefs.current[idx + 1]?.focus();
|
||||
|
||||
} else if (val === "" && idx > 0) {
|
||||
inputRefs.current[idx - 1]?.focus();
|
||||
}
|
||||
@ -164,7 +163,6 @@ const LoginWithOtp = () => {
|
||||
inputRefs.current[idx - 1]?.focus();
|
||||
}
|
||||
}}
|
||||
|
||||
onPaste={idx === 0 ? handlePaste : undefined}
|
||||
style={{ width: "40px", height: "40px", fontSize: "15px" }}
|
||||
{...rest}
|
||||
@ -184,7 +182,7 @@ const LoginWithOtp = () => {
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
className="btn btn-primary d-grid w-100"
|
||||
className="btn-green d-grid w-100"
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? "Verifying..." : "Verify OTP"}
|
||||
@ -199,19 +197,20 @@ const LoginWithOtp = () => {
|
||||
</p>
|
||||
) : (
|
||||
<div>
|
||||
<p
|
||||
className="text-center text-danger mt-2 text small-text m-0"
|
||||
|
||||
>
|
||||
<p className="text-center text-danger mt-2 text small-text m-0">
|
||||
OTP has expired. Please request a new one.
|
||||
</p>
|
||||
<a className="text-primary cursor-pointer" onClick={() => navigate('/auth/login')}>Try Again</a>
|
||||
<a
|
||||
className="text-green cursor-pointer"
|
||||
onClick={() => navigate("/auth/login")}
|
||||
>
|
||||
Try Again
|
||||
</a>
|
||||
</div>
|
||||
|
||||
)}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
// </AuthWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user