Update src/app/verify-otp/page.tsx
This commit is contained in:
@@ -1,14 +1,65 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
|
||||
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
|
||||
import HeroBillboardGallery from "@/components/sections/hero/HeroBillboardGallery";
|
||||
import FeatureCardNine from "@/components/sections/feature/FeatureCardNine";
|
||||
import MetricCardThree from "@/components/sections/metrics/MetricCardThree";
|
||||
import { Lock, Shield, Zap, Users } from "lucide-react";
|
||||
import { Lock, Shield, Zap, Users, CheckCircle } from "lucide-react";
|
||||
import Link from "next/link";
|
||||
|
||||
export default function VerifyOtpPage() {
|
||||
const [otp, setOtp] = useState(["", "", "", "", "", ""]);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [isVerified, setIsVerified] = useState(false);
|
||||
|
||||
const navItems = [
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Features", id: "#features" },
|
||||
{ name: "Security", id: "#security" },
|
||||
{ name: "Sign In", id: "https://example.com/login" },
|
||||
{ name: "Sign Up", id: "https://example.com/signup" },
|
||||
];
|
||||
|
||||
const handleOtpChange = (index: number, value: string) => {
|
||||
if (value.length > 1) return;
|
||||
if (!/^[0-9]*$/.test(value)) return;
|
||||
|
||||
const newOtp = [...otp];
|
||||
newOtp[index] = value;
|
||||
setOtp(newOtp);
|
||||
|
||||
if (value && index < 5) {
|
||||
const nextInput = document.getElementById(`otp-${index + 1}`);
|
||||
if (nextInput) nextInput.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const handleKeyDown = (
|
||||
e: React.KeyboardEvent<HTMLInputElement>,
|
||||
index: number
|
||||
) => {
|
||||
if (e.key === "Backspace" && !otp[index] && index > 0) {
|
||||
const prevInput = document.getElementById(`otp-${index - 1}`);
|
||||
if (prevInput) prevInput.focus();
|
||||
}
|
||||
};
|
||||
|
||||
const handleVerify = async () => {
|
||||
const otpString = otp.join("");
|
||||
if (otpString.length !== 6) return;
|
||||
|
||||
setIsLoading(true);
|
||||
try {
|
||||
// Simulate API call
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
setIsVerified(true);
|
||||
setTimeout(() => {
|
||||
window.location.href = "/profile";
|
||||
}, 2000);
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeProvider
|
||||
defaultButtonVariant="directional-hover"
|
||||
@@ -23,149 +74,136 @@ export default function VerifyOtpPage() {
|
||||
headingFontWeight="medium"
|
||||
>
|
||||
<div id="nav" data-section="nav">
|
||||
<NavbarStyleApple
|
||||
brandName="AuthVault"
|
||||
navItems={[
|
||||
{ name: "Home", id: "/" },
|
||||
{ name: "Features", id: "#features" },
|
||||
{ name: "Security", id: "#security" },
|
||||
{ name: "Sign In", id: "https://example.com/login" },
|
||||
{ name: "Sign Up", id: "https://example.com/signup" },
|
||||
]}
|
||||
/>
|
||||
<NavbarStyleApple brandName="AuthVault" navItems={navItems} />
|
||||
</div>
|
||||
|
||||
<div id="hero" data-section="hero">
|
||||
<HeroBillboardGallery
|
||||
title="Two-Factor Authentication Verification"
|
||||
description="Secure your account with enterprise-grade OTP verification. Complete two-step authentication to verify your identity and access your AuthVault account safely."
|
||||
background={{ variant: "animated-grid" }}
|
||||
tag="Identity Verification"
|
||||
tagIcon={Shield}
|
||||
tagAnimation="slide-up"
|
||||
buttons={[
|
||||
{ text: "Verify Now", href: "https://example.com/otp" },
|
||||
{ text: "Back to Login", href: "https://example.com/login" },
|
||||
]}
|
||||
buttonAnimation="blur-reveal"
|
||||
mediaItems={[
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/register-sign-up-membership-concept_53876-121221.jpg?_wi=5", imageAlt: "Two-factor authentication verification"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/top-view-keyboard-with-lock-metal-chain_23-2148578114.jpg?_wi=6", imageAlt: "Secure password protection"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/software-developers-using-laptop-data-center-managing-server-virtualization_482257-122525.jpg?_wi=6", imageAlt: "Authentication dashboard"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-vector/antibacterial-logo-template_23-2148502706.jpg?_wi=6", imageAlt: "Security encryption technology"},
|
||||
{
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/businesswoman-discussing-with-disabled-woman_482257-2402.jpg?_wi=6", imageAlt: "Secure session verification"},
|
||||
]}
|
||||
mediaAnimation="slide-up"
|
||||
ariaLabel="OTP verification interface"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="features" data-section="features">
|
||||
<FeatureCardNine
|
||||
title="OTP Verification Process"
|
||||
description="Multi-layered identity verification with secure one-time password delivery and real-time authentication confirmation across all devices."
|
||||
tag="Security Features"
|
||||
tagIcon={Zap}
|
||||
tagAnimation="opacity"
|
||||
features={[
|
||||
{
|
||||
id: 1,
|
||||
title: "OTP Code Delivery", description: "Receive one-time passwords via SMS, email, or authenticator applications. Time-limited codes (valid for 5-10 minutes) ensure only authorized users can access accounts. No codes are reusable.", phoneOne: {
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/register-sign-up-membership-concept_53876-121221.jpg?_wi=6", imageAlt: "OTP delivery methods"},
|
||||
phoneTwo: {
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/businesswoman-discussing-with-disabled-woman_482257-2402.jpg?_wi=7", imageAlt: "Authentication confirmation"},
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Authenticator App Integration", description: "Support for industry-standard authenticator apps like Google Authenticator and Microsoft Authenticator. TOTP (Time-based One-Time Password) algorithm generates unique codes every 30 seconds without internet connection.", phoneOne: {
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/software-developers-using-laptop-data-center-managing-server-virtualization_482257-122525.jpg?_wi=7", imageAlt: "Authenticator app setup"},
|
||||
phoneTwo: {
|
||||
imageSrc: "http://img.b2bpic.net/free-vector/antibacterial-logo-template_23-2148502706.jpg?_wi=7", imageAlt: "App-based verification"},
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Backup Codes & Recovery", description: "Generate and securely store backup codes for emergency access if you lose your authenticator device. Recovery codes bypass 2FA and restore account access. Single-use codes prevent unauthorized access.", phoneOne: {
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/top-view-keyboard-with-lock-metal-chain_23-2148578114.jpg?_wi=7", imageAlt: "Backup code generation"},
|
||||
phoneTwo: {
|
||||
imageSrc: "http://img.b2bpic.net/free-photo/register-sign-up-membership-concept_53876-121221.jpg?_wi=7", imageAlt: "Recovery code storage"},
|
||||
},
|
||||
]}
|
||||
showStepNumbers={true}
|
||||
textboxLayout="default"
|
||||
animationType="slide-up"
|
||||
useInvertedBackground={false}
|
||||
ariaLabel="OTP verification features"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div id="security" data-section="security">
|
||||
<MetricCardThree
|
||||
title="OTP Security Standards"
|
||||
description="Industry-leading verification standards and security metrics for two-factor authentication across all platforms."
|
||||
metrics={[
|
||||
{ id: "1", icon: Lock, title: "Code Encryption", value: "AES-256" },
|
||||
{ id: "2", icon: Shield, title: "Uptime Guarantee", value: "99.99%" },
|
||||
{ id: "3", icon: Zap, title: "Verification Time", value: "<100ms" },
|
||||
{ id: "4", icon: Users, title: "Code Validity", value: "5-10min" },
|
||||
]}
|
||||
animationType="blur-reveal"
|
||||
textboxLayout="default"
|
||||
useInvertedBackground={true}
|
||||
ariaLabel="OTP security metrics"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<footer className="border-t border-gray-200 bg-white py-12">
|
||||
<div className="mx-auto max-w-6xl px-4 md:px-6">
|
||||
<div className="grid grid-cols-2 gap-8 md:grid-cols-4 mb-8">
|
||||
<div>
|
||||
<h3 className="font-semibold text-sm text-foreground mb-4">Product</h3>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li><Link href="#features" className="text-gray-600 hover:text-primary-cta transition">Features</Link></li>
|
||||
<li><Link href="#security" className="text-gray-600 hover:text-primary-cta transition">Security</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Pricing</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Documentation</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-sm text-foreground mb-4">Company</h3>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">About Us</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Blog</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Careers</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Contact</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-sm text-foreground mb-4">Resources</h3>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">API Docs</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Security Guide</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">FAQ</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Status</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="font-semibold text-sm text-foreground mb-4">Legal</h3>
|
||||
<ul className="space-y-2 text-sm">
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Privacy Policy</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Terms of Service</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Cookie Policy</Link></li>
|
||||
<li><Link href="#" className="text-gray-600 hover:text-primary-cta transition">Compliance</Link></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t border-gray-200 pt-8 flex flex-col md:flex-row justify-between items-center">
|
||||
<p className="text-sm text-gray-600">© 2025 AuthVault. All rights reserved. Enterprise-grade security solutions.</p>
|
||||
<p className="text-sm text-gray-600">Made with security in mind</p>
|
||||
<div id="otp-verify" data-section="otp-verify" className="min-h-screen flex items-center justify-center px-4 py-20 relative overflow-hidden">
|
||||
{/* Animated background */}
|
||||
<div className="absolute inset-0 -z-10">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-background via-card to-background" />
|
||||
<div className="absolute inset-0 opacity-20">
|
||||
<div className="absolute top-0 -right-1/3 w-96 h-96 bg-primary-cta/20 rounded-full blur-3xl animate-pulse" />
|
||||
<div className="absolute bottom-0 -left-1/3 w-96 h-96 bg-accent/20 rounded-full blur-3xl animate-pulse delay-1000" />
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<div className="w-full max-w-md animate-in fade-in zoom-in duration-500">
|
||||
{/* Header */}
|
||||
<div className="text-center mb-8">
|
||||
<div className="flex justify-center mb-4">
|
||||
{isVerified ? (
|
||||
<div className="animate-in bounce duration-500">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-green-400 to-green-600 rounded-lg blur-lg opacity-60" />
|
||||
<div className="relative bg-background p-3 rounded-lg border border-green-500/40">
|
||||
<CheckCircle className="w-8 h-8 text-green-500" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-gradient-to-br from-primary-cta to-accent rounded-lg blur-lg opacity-60 animate-pulse" />
|
||||
<div className="relative bg-background p-3 rounded-lg border border-primary-cta/20 animate-bounce">
|
||||
<Lock className="w-8 h-8 text-primary-cta" />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<h1 className="text-4xl font-bold text-foreground mb-2 animate-in slide-in-from-bottom duration-700">
|
||||
{isVerified ? "Verified!" : "Enter OTP"}
|
||||
</h1>
|
||||
<p className="text-foreground/70 animate-in slide-in-from-bottom duration-700 delay-100">
|
||||
{isVerified
|
||||
? "Your identity has been confirmed. Redirecting to dashboard..."
|
||||
: "We've sent a 6-digit code to your registered email address"}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* OTP Card */}
|
||||
<div className="bg-card border border-accent/30 rounded-lg p-8 shadow-lg backdrop-blur-sm animate-in scale-in duration-700 delay-200">
|
||||
{!isVerified ? (
|
||||
<>
|
||||
{/* OTP Input Fields */}
|
||||
<div className="mb-8">
|
||||
<label className="block text-sm font-medium text-foreground mb-4">
|
||||
Enter 6-digit code
|
||||
</label>
|
||||
<div className="flex gap-3 justify-center">
|
||||
{otp.map((digit, index) => (
|
||||
<input
|
||||
key={index}
|
||||
id={`otp-${index}`}
|
||||
type="text"
|
||||
inputMode="numeric"
|
||||
maxLength={1}
|
||||
value={digit}
|
||||
onChange={(e) => handleOtpChange(index, e.target.value)}
|
||||
onKeyDown={(e) => handleKeyDown(e, index)}
|
||||
className={`w-14 h-14 text-center text-2xl font-bold border-2 rounded-lg transition-all duration-300 focus:outline-none ${
|
||||
digit
|
||||
? "bg-accent/10 border-primary-cta text-foreground"
|
||||
: "bg-transparent border-accent/30 text-foreground/50"
|
||||
} focus:border-primary-cta focus:ring-2 focus:ring-primary-cta/20`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Verify Button */}
|
||||
<button
|
||||
onClick={handleVerify}
|
||||
disabled={otp.join("").length !== 6 || isLoading}
|
||||
className="w-full relative group bg-gradient-to-r from-primary-cta to-accent text-white font-semibold py-3 px-4 rounded-lg overflow-hidden transition-all duration-300 hover:shadow-lg hover:shadow-primary-cta/50 disabled:opacity-50 disabled:cursor-not-allowed mb-4"
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-accent to-primary-cta opacity-0 group-hover:opacity-100 transition-opacity duration-300" />
|
||||
<div className="relative flex items-center justify-center gap-2">
|
||||
{isLoading ? (
|
||||
<>
|
||||
<div className="w-4 h-4 border-2 border-white/30 border-t-white rounded-full animate-spin" />
|
||||
<span>Verifying...</span>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Zap className="w-4 h-4" />
|
||||
<span>Verify Code</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
|
||||
{/* Resend Link */}
|
||||
<p className="text-center text-sm text-foreground/70">
|
||||
Didn't receive the code?{" "}
|
||||
<button className="text-primary-cta hover:text-primary-cta/80 font-semibold transition-colors">
|
||||
Resend OTP
|
||||
</button>
|
||||
</p>
|
||||
</>
|
||||
) : (
|
||||
<div className="text-center space-y-4 animate-in fade-in duration-500">
|
||||
<div className="flex justify-center">
|
||||
<div className="relative">
|
||||
<div className="absolute inset-0 bg-green-400/20 rounded-full blur-lg" />
|
||||
<div className="relative w-16 h-16 rounded-full bg-green-400/10 border-2 border-green-500 flex items-center justify-center">
|
||||
<CheckCircle className="w-10 h-10 text-green-500" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold text-foreground">Authentication Successful</h2>
|
||||
<p className="text-foreground/70">Your account is now secured with two-factor authentication.</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Info Box */}
|
||||
<div className="mt-6 p-4 bg-accent/5 border border-accent/20 rounded-lg animate-in fade-in duration-700 delay-500">
|
||||
<p className="text-xs text-foreground/70 flex items-start gap-2">
|
||||
<Shield className="w-4 h-4 mt-0.5 flex-shrink-0 text-primary-cta" />
|
||||
<span>Your OTP code is valid for 5 minutes and can only be used once.</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ThemeProvider>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user