feat: upgrade login page to split-screen layout with branding

This commit is contained in:
2026-09-23 00:35:13 +05:30
parent 29ce3eb9c8
commit 3bbe454e1f
+140 -68
View File
@@ -1,6 +1,7 @@
import React, { useState } from 'react'; import React, { useState } from 'react';
import { useNavigate } from 'react-router'; import { useNavigate } from 'react-router';
import { FiEye, FiEyeOff } from 'react-icons/fi'; import { FiEye, FiEyeOff, FiActivity, FiUserCheck, FiFileText } from 'react-icons/fi';
import { BsStars } from 'react-icons/bs';
const LoginPage = () => { const LoginPage = () => {
const [credentials, setCredentials] = useState({ email: '', password: '' }); const [credentials, setCredentials] = useState({ email: '', password: '' });
@@ -26,81 +27,152 @@ const LoginPage = () => {
}; };
return ( return (
<div className="min-h-screen bg-gradient-to-br from-[#0a0a0a] via-[#1a1a24] to-[#2a0810] flex items-center justify-center p-4 font-sans relative overflow-hidden"> <div className="min-h-screen bg-[#0a0a0a] font-sans flex overflow-hidden">
{/* Background Ambient Glows */}
<div className="absolute top-0 left-0 w-[500px] h-[500px] bg-limelite-red/20 rounded-full blur-[120px] -translate-x-1/2 -translate-y-1/2"></div>
<div className="absolute bottom-0 right-0 w-[500px] h-[500px] bg-limelite-maroon/20 rounded-full blur-[120px] translate-x-1/2 translate-y-1/2"></div>
<div className="w-full max-w-md relative z-10 animate-[fadeIn_0.5s_ease-out]"> {/* LEFT COLUMN: Branding & Features */}
<div className="backdrop-blur-xl bg-white/5 border border-white/10 p-10 shadow-2xl rounded-2xl"> <div className="hidden lg:flex w-3/5 relative flex-col justify-between p-12 overflow-hidden border-r border-white/5">
<div className="flex flex-col items-center mb-10"> {/* Background Ambient Glows */}
<div className="bg-gradient-to-tr from-limelite-maroon to-limelite-red p-1 rounded-2xl mb-6 shadow-lg shadow-limelite-red/30"> <div className="absolute top-0 left-0 w-[600px] h-[600px] bg-limelite-red/20 rounded-full blur-[150px] -translate-x-1/4 -translate-y-1/4"></div>
<div className="bg-black/40 backdrop-blur-md p-4 rounded-xl"> <div className="absolute bottom-0 right-0 w-[600px] h-[600px] bg-limelite-maroon/20 rounded-full blur-[150px] translate-x-1/4 translate-y-1/4"></div>
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite" className="h-8 brightness-0 invert opacity-90" />
</div> {/* Hexagon Grid Pattern Overlay */}
<div className="absolute inset-0 bg-[url('https://www.transparenttextures.com/patterns/cubes.png')] opacity-[0.03]"></div>
{/* Header / Logo */}
<div className="relative z-10 flex items-center gap-4 animate-[fadeIn_0.5s_ease-out]">
<div className="bg-gradient-to-tr from-limelite-maroon to-limelite-red p-1 rounded-2xl shadow-lg shadow-limelite-red/20">
<div className="bg-black/60 backdrop-blur-md p-3 rounded-xl">
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite" className="h-6 brightness-0 invert opacity-90" />
</div> </div>
<h2 className="text-3xl font-serif italic text-white tracking-wide">Admin Portal</h2> </div>
<p className="text-gray-400 text-sm mt-2 font-light">Secure access to Limelite dashboard</p> <span className="text-white text-xl font-serif italic tracking-wider">Limelite</span>
</div>
{/* Main Value Proposition */}
<div className="relative z-10 max-w-2xl my-auto animate-[fadeIn_0.7s_ease-out]">
<div className="inline-flex items-center gap-2 px-4 py-2 rounded-full bg-limelite-red/10 border border-limelite-red/20 text-limelite-red text-sm font-semibold tracking-widest uppercase mb-8">
<BsStars className="animate-pulse" />
Powered by AI
</div> </div>
{error && ( <h1 className="text-5xl xl:text-7xl font-light text-white leading-tight mb-6">
<div className="bg-red-500/10 border border-red-500/20 rounded-lg p-3 mb-6 animate-shake"> Intelligent <br />
<p className="text-red-400 text-sm font-semibold text-center">{error}</p> <span className="font-serif italic text-transparent bg-clip-text bg-gradient-to-r from-limelite-red to-rose-400">
</div> Face Analysis
)} </span>
</h1>
<form onSubmit={handleSubmit} className="space-y-6"> <p className="text-gray-400 text-lg xl:text-xl font-light leading-relaxed mb-12 max-w-xl">
<div className="group"> The next generation of aesthetic intelligence. Deeply analyze facial structures, map skin conditions with precision, and generate automated, tailored client reports in seconds.
<label className="block text-xs font-bold text-gray-400 uppercase tracking-widest mb-2 group-focus-within:text-white transition-colors">Email Address</label> </p>
<input
type="email" {/* Feature Cards Grid */}
required <div className="grid grid-cols-2 gap-6">
className="w-full bg-white/5 border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-500 focus:outline-none focus:border-limelite-red focus:bg-white/10 transition-all" <div className="bg-white/5 border border-white/10 backdrop-blur-sm p-6 rounded-2xl hover:bg-white/10 transition-colors group">
placeholder="admin@limelite.com" <FiActivity className="text-limelite-red text-3xl mb-4 group-hover:scale-110 transition-transform" />
value={credentials.email} <h3 className="text-white font-semibold mb-2">Precision Mapping</h3>
onChange={(e) => setCredentials({ ...credentials, email: e.target.value })} <p className="text-gray-500 text-sm">Advanced AI models to detect and map subtle skin features.</p>
/>
</div> </div>
<div className="relative group"> <div className="bg-white/5 border border-white/10 backdrop-blur-sm p-6 rounded-2xl hover:bg-white/10 transition-colors group">
<label className="block text-xs font-bold text-gray-400 uppercase tracking-widest mb-2 group-focus-within:text-white transition-colors">Password</label> <FiFileText className="text-limelite-red text-3xl mb-4 group-hover:scale-110 transition-transform" />
<div className="relative"> <h3 className="text-white font-semibold mb-2">Automated Reports</h3>
<input <p className="text-gray-500 text-sm">Generate beautiful PDF reports instantly for your clients.</p>
type={showPassword ? "text" : "password"} </div>
required </div>
className="w-full bg-white/5 border border-white/10 rounded-lg py-3 pl-4 pr-12 text-white placeholder-gray-500 focus:outline-none focus:border-limelite-red focus:bg-white/10 transition-all" </div>
placeholder="••••••••"
value={credentials.password} {/* Footer info */}
onChange={(e) => setCredentials({ ...credentials, password: e.target.value })} <div className="relative z-10 text-gray-500 text-sm flex items-center justify-between">
/> <p>© 2026 Limelite Smart Mirror. All rights reserved.</p>
<button <p>System Version 3.1.0</p>
type="button" </div>
className="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white transition-colors" </div>
onClick={() => setShowPassword(!showPassword)}
> {/* RIGHT COLUMN: Login Form */}
{showPassword ? <FiEye size={18} /> : <FiEyeOff size={18} />} <div className="w-full lg:w-2/5 relative flex items-center justify-center p-4 bg-[#111115]">
</button> {/* Mobile ambient glow */}
<div className="lg:hidden absolute top-0 left-0 w-[400px] h-[400px] bg-limelite-red/20 rounded-full blur-[100px] -translate-x-1/2 -translate-y-1/2"></div>
<div className="w-full max-w-md relative z-10 animate-[fadeIn_0.5s_ease-out]">
<div className="backdrop-blur-xl bg-black/40 border border-white/10 p-10 shadow-2xl rounded-2xl relative overflow-hidden">
{/* Subtle top border gradient */}
<div className="absolute top-0 left-0 w-full h-1 bg-gradient-to-r from-transparent via-limelite-red to-transparent opacity-50"></div>
<div className="flex flex-col items-center mb-10">
{/* Mobile Logo */}
<div className="lg:hidden bg-gradient-to-tr from-limelite-maroon to-limelite-red p-1 rounded-2xl mb-6 shadow-lg shadow-limelite-red/30">
<div className="bg-black/40 backdrop-blur-md p-4 rounded-xl">
<img src={process.env.PUBLIC_URL + '/assets/images/logo.jpg'} alt="Limelite" className="h-8 brightness-0 invert opacity-90" />
</div>
</div> </div>
<h2 className="text-3xl font-serif italic text-white tracking-wide">Admin Portal</h2>
<p className="text-gray-400 text-sm mt-2 font-light">Secure access to Limelite dashboard</p>
</div> </div>
<button
type="submit" {error && (
disabled={isLoading} <div className="bg-red-500/10 border border-red-500/20 rounded-lg p-3 mb-6 animate-shake">
className="w-full relative overflow-hidden bg-gradient-to-r from-limelite-maroon to-limelite-red text-white py-4 font-bold uppercase tracking-widest rounded-lg hover:shadow-[0_0_20px_rgba(200,20,50,0.4)] transition-all active:scale-[0.98] disabled:opacity-70 disabled:cursor-wait mt-4 group" <p className="text-red-400 text-sm font-semibold text-center">{error}</p>
> </div>
{/* Hover shine effect */} )}
<div className="absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-white/20 to-transparent group-hover:animate-[shimmer_1.5s_infinite]"></div>
<span className="relative z-10 flex items-center justify-center gap-2"> <form onSubmit={handleSubmit} className="space-y-6">
{isLoading ? ( <div className="group">
<> <label className="block text-xs font-bold text-gray-400 uppercase tracking-widest mb-2 group-focus-within:text-white transition-colors">Email Address</label>
<svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"> <input
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle> type="email"
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path> required
</svg> className="w-full bg-white/5 border border-white/10 rounded-lg py-3 px-4 text-white placeholder-gray-600 focus:outline-none focus:border-limelite-red focus:bg-white/10 transition-all"
Authenticating... placeholder="admin@limelite.com"
</> value={credentials.email}
) : 'Login to Admin'} onChange={(e) => setCredentials({ ...credentials, email: e.target.value })}
</span> />
</button> </div>
</form> <div className="relative group">
<label className="block text-xs font-bold text-gray-400 uppercase tracking-widest mb-2 group-focus-within:text-white transition-colors">Password</label>
<div className="relative">
<input
type={showPassword ? "text" : "password"}
required
className="w-full bg-white/5 border border-white/10 rounded-lg py-3 pl-4 pr-12 text-white placeholder-gray-600 focus:outline-none focus:border-limelite-red focus:bg-white/10 transition-all"
placeholder="••••••••"
value={credentials.password}
onChange={(e) => setCredentials({ ...credentials, password: e.target.value })}
/>
<button
type="button"
className="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400 hover:text-white transition-colors"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? <FiEye size={18} /> : <FiEyeOff size={18} />}
</button>
</div>
</div>
<button
type="submit"
disabled={isLoading}
className="w-full relative overflow-hidden bg-gradient-to-r from-limelite-maroon to-limelite-red text-white py-4 font-bold uppercase tracking-widest rounded-lg hover:shadow-[0_0_20px_rgba(200,20,50,0.4)] transition-all active:scale-[0.98] disabled:opacity-70 disabled:cursor-wait mt-4 group"
>
{/* Hover shine effect */}
<div className="absolute inset-0 -translate-x-full bg-gradient-to-r from-transparent via-white/20 to-transparent group-hover:animate-[shimmer_1.5s_infinite]"></div>
<span className="relative z-10 flex items-center justify-center gap-2">
{isLoading ? (
<>
<svg className="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
Authenticating...
</>
) : (
<>
Login to Admin <FiUserCheck className="ml-1" />
</>
)}
</span>
</button>
</form>
</div>
</div> </div>
</div> </div>
</div> </div>