186 lines
7.0 KiB
TypeScript
186 lines
7.0 KiB
TypeScript
'use client';
|
|
|
|
import IconLockDots from '@/components/icon/icon-lock-dots';
|
|
import IconMail from '@/components/icon/icon-mail';
|
|
import { useRouter } from 'next/navigation';
|
|
import React, { useState } from 'react';
|
|
import axios from 'axios';
|
|
import Link from 'next/link';
|
|
import { Eye, EyeOff } from 'lucide-react';
|
|
import { FcGoogle } from 'react-icons/fc';
|
|
import { ApiServerBaseUrl } from '@/utils/baseurl.utils';
|
|
|
|
const ComponentsAuthLoginForm = () => {
|
|
const router = useRouter();
|
|
|
|
const [formData, setFormData] = useState({
|
|
email: '',
|
|
password: '',
|
|
});
|
|
|
|
const [loading, setLoading] = useState(false);
|
|
const [err, setErr] = useState<string | null>(null);
|
|
const [showPassword, setShowPassword] = useState(false);
|
|
|
|
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
|
const { name, value } = e.target;
|
|
setFormData((prev) => ({ ...prev, [name]: value }));
|
|
};
|
|
|
|
const submitForm = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
setErr(null);
|
|
|
|
if (!formData.email || !formData.password) {
|
|
setErr('Please enter email and password.');
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
try {
|
|
const res = await axios.post(`${ApiServerBaseUrl}/auth/login`, formData);
|
|
const data = res.data;
|
|
|
|
localStorage.setItem('token', data.token);
|
|
|
|
if (data?.user) {
|
|
localStorage.setItem("userDetails", JSON.stringify(data?.user))
|
|
localStorage.setItem('user_email', data?.user?.email);
|
|
localStorage.setItem('userId', data?.user?.id);
|
|
}
|
|
if (data?.payment) {
|
|
localStorage.setItem('paymentDetails', JSON.stringify(data.payment));
|
|
data?.payment?.sessionId &&
|
|
localStorage.setItem('payment_session', data.payment.sessionId);
|
|
}
|
|
|
|
router.push('/');
|
|
} catch (err: any) {
|
|
setErr(err.response?.data?.error || 'Login failed');
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<form className="dark:text-white" onSubmit={submitForm}>
|
|
{err && (
|
|
<div className="mb-4 rounded-md border border-red-200 bg-red-50 px-3 py-2 text-sm text-red-700">
|
|
{err}
|
|
</div>
|
|
)}
|
|
|
|
<div className="relative z-10 w-full min-w-[500px] p-8 glass-card rounded-3xl">
|
|
|
|
{/* Logo */}
|
|
<div className="flex flex-col items-center mb-6">
|
|
<img
|
|
src="/assets/images/logo_sb.png"
|
|
alt="Logo"
|
|
className="h-[120px] w-[120px] neon-logo"
|
|
/>
|
|
|
|
<h1 className="text-xl text-white font-medium mt-3">
|
|
Sign in to SocialBuddy
|
|
</h1>
|
|
</div>
|
|
|
|
{/* Email */}
|
|
<div className="mb-4 relative">
|
|
<input
|
|
name="email"
|
|
type="email"
|
|
placeholder="Email Address"
|
|
className="w-full ps-10 py-3 bg-[rgba(7,13,30,0.7)]
|
|
border border-white/15 rounded-lg text-white
|
|
focus:outline-none focus:border-white/30"
|
|
value={formData.email}
|
|
onChange={handleChange}
|
|
/>
|
|
<span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
|
|
<IconMail fill />
|
|
</span>
|
|
</div>
|
|
|
|
{/* Password */}
|
|
<div className="mb-2 relative">
|
|
<input
|
|
name="password"
|
|
type={showPassword ? 'text' : 'password'}
|
|
placeholder="Password"
|
|
className="w-full ps-10 py-3 bg-[rgba(7,13,30,0.7)]
|
|
border border-white/15 rounded-lg text-white
|
|
focus:outline-none focus:border-white/30"
|
|
value={formData.password}
|
|
onChange={handleChange}
|
|
/>
|
|
<span className="absolute start-4 top-1/2 -translate-y-1/2 text-white">
|
|
<IconLockDots fill />
|
|
</span>
|
|
<button
|
|
type="button"
|
|
onClick={() => setShowPassword(!showPassword)}
|
|
className="absolute right-4 top-1/2 -translate-y-1/2 text-gray-400"
|
|
>
|
|
{showPassword ? <EyeOff size={20} /> : <Eye size={20} />}
|
|
</button>
|
|
</div>
|
|
|
|
{/* Forgot password */}
|
|
<div className="flex justify-end mb-6">
|
|
<Link href="/forgot-password" className="text-sm text-blue-400 hover:underline">
|
|
Forgot Password?
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Login button */}
|
|
<button
|
|
disabled={loading}
|
|
className="
|
|
w-full py-3 rounded-xl text-lg font-semibold text-white
|
|
bg-gradient-to-r from-blue-600 to-pink-500
|
|
shadow-lg transition-all
|
|
hover:opacity-90 hover:scale-[1.02]
|
|
disabled:opacity-60
|
|
mb-3
|
|
"
|
|
>
|
|
{loading ? 'Logging in...' : 'LOG IN'}
|
|
</button>
|
|
|
|
{/* Divider */}
|
|
<div className="relative text-center my-3">
|
|
<span className="absolute inset-x-0 top-1/2 h-px bg-white/20" />
|
|
<span className="relative bg-[#0b0d1c] px-3 text-xs uppercase text-gray-300">
|
|
or
|
|
</span>
|
|
</div>
|
|
|
|
{/* Google Sign-in */}
|
|
<div className="flex justify-center px-8 mb-4">
|
|
<Link
|
|
href="https://ebay.backend.data4autos.com/api/auth/google/"
|
|
className="flex items-center gap-3 px-8 py-3 rounded-lg
|
|
border border-white/20 text-white
|
|
hover:bg-white/10 transition active:scale-[0.98]"
|
|
>
|
|
<FcGoogle size={20} />
|
|
<span className="text-sm">Continue with Google</span>
|
|
</Link>
|
|
</div>
|
|
|
|
{/* Footer */}
|
|
<div className="text-center text-sm text-gray-400">
|
|
Don’t have an account?{' '}
|
|
<Link href="/signup" className="text-blue-400 hover:underline">
|
|
SIGN UP
|
|
</Link>
|
|
</div>
|
|
|
|
</div>
|
|
</form>
|
|
);
|
|
};
|
|
|
|
export default ComponentsAuthLoginForm;
|