UNPKG

quikfrontend

Version:

A CLI tool for generating React-Vite frontend projects with pre-configured setups

327 lines (301 loc) 11.8 kB
import React, { useState } from 'react'; import { Eye, EyeOff } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { useDispatch } from 'react-redux'; import { GoogleLogin } from '@react-oauth/google'; import { login, loginWithGoogle, register, } from '../../services/repository/userRepo'; const Login = () => { const [isLoginView, setIsLoginView] = useState(true); const [showPassword, setShowPassword] = useState(false); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [name, setName] = useState(''); const [mobile, setMobile] = useState(''); const navigate = useNavigate(); const dispatch = useDispatch(); const handleSubmit = (e) => { e.preventDefault(); if (isLoginView) { dispatch(login(email, password, navigate)); } else { dispatch(register(name, email, password, mobile, navigate)); } }; const handleSuccess = async (credentialResponse) => { dispatch(loginWithGoogle(credentialResponse, navigate)); }; const handleError = () => { alert('Google Sign-In failed'); }; const toggleView = () => { setIsLoginView(!isLoginView); }; return ( <div className="flex items-center justify-center min-h-screen bg-gray-50"> <div className="w-full max-w-md bg-white rounded-lg shadow-md p-8"> {/* Logo */} <div className="flex justify-center mb-6"> <div className="w-12 h-12 bg-green-500 rounded-full flex items-center justify-center"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" > <path d="M17 8C8 10 5.9 16.17 3.82 21.34L5.71 22L6.66 19.7C7.14 19.87 7.64 20 8 20C19 20 22 3 22 3C21 5 14 5.25 9 6.25C4 7.25 2 11.5 2 13.5C2 15.5 3.75 17.25 3.75 17.25C7 8 17 8 17 8Z" fill="white" /> </svg> </div> </div> {isLoginView ? ( <div> <h2 className="text-2xl font-bold text-center mb-6 text-gray-800"> Sign In </h2> <form className="space-y-4" onSubmit={handleSubmit}> <div> <label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1" > Email </label> <input type="email" id="email" value={email} onChange={(e) => setEmail(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500" placeholder="Enter your email" required /> </div> <div> <label htmlFor="password" className="block text-sm font-medium text-gray-700 mb-1" > Password </label> <div className="relative"> <input type={showPassword ? 'text' : 'password'} id="password" value={password} onChange={(e) => setPassword(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500" placeholder="Enter your password" required /> <button type="button" onClick={() => setShowPassword(!showPassword)} className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500" > {showPassword ? <EyeOff size={18} /> : <Eye size={18} />} </button> </div> </div> <div className="flex items-center justify-between"> <div className="flex items-center"> <input id="remember-me" name="remember-me" type="checkbox" className="h-4 w-4 text-green-600 focus:ring-green-500 border-gray-300 rounded" /> <label htmlFor="remember-me" className="ml-2 block text-sm text-gray-700" > Remember me </label> </div> <a href="#" className="text-sm font-medium text-green-600 hover:text-green-500" > Forgot password? </a> </div> <button type="submit" className="w-full bg-green-600 text-white py-2 px-4 rounded-md hover:bg-green-700 transition" > Sign In </button> </form> <div className="mt-6"> <div className="relative"> <div className="absolute inset-0 flex items-center"> <div className="w-full border-t border-gray-300"></div> </div> <div className="relative flex justify-center text-sm"> <span className="px-2 bg-white text-gray-500"> Or continue with </span> </div> </div> <div className="mt-6"> <div className="w-full"> <GoogleLogin onSuccess={handleSuccess} onError={handleError} scope="email profile" /> </div> </div> </div> <p className="mt-6 text-center text-sm text-gray-600"> Don't have an account?{' '} <button onClick={toggleView} className="font-medium text-green-600 hover:text-green-500" > Sign up </button> </p> </div> ) : ( <div> <h2 className="text-2xl font-bold text-center mb-6 text-gray-800"> Create Account </h2> <form className="space-y-4" onSubmit={handleSubmit}> <div> <label htmlFor="name" className="block text-sm font-medium text-gray-700 mb-1" > Full Name </label> <input type="text" id="name" value={name} onChange={(e) => setName(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500" placeholder="Enter your full name" required /> </div> <div> <label htmlFor="mobile" className="block text-sm font-medium text-gray-700 mb-1" > Mobile Number </label> <input type="tel" id="mobile" value={mobile} onChange={(e) => setMobile(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500" placeholder="Enter your mobile number" /> </div> <div> <label htmlFor="register-email" className="block text-sm font-medium text-gray-700 mb-1" > Email </label> <input type="email" id="register-email" value={email} onChange={(e) => setEmail(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500" placeholder="Enter your email" required /> </div> <div> <label htmlFor="register-password" className="block text-sm font-medium text-gray-700 mb-1" > Password </label> <div className="relative"> <input type={showPassword ? 'text' : 'password'} id="register-password" value={password} onChange={(e) => setPassword(e.target.value)} className="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-green-500" placeholder="Create a password" required /> <button type="button" onClick={() => setShowPassword(!showPassword)} className="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500" > {showPassword ? <EyeOff size={18} /> : <Eye size={18} />} </button> </div> </div> <button type="submit" className="w-full bg-green-600 text-white py-2 px-4 rounded-md hover:bg-green-700 transition" > Create Account </button> </form> <div className="mt-6"> <div className="relative"> <div className="absolute inset-0 flex items-center"> <div className="w-full border-t border-gray-300"></div> </div> <div className="relative flex justify-center text-sm"> <span className="px-2 bg-white text-gray-500"> Or sign up with </span> </div> </div> <div className="mt-6"> <div className="w-full"> <GoogleLogin onSuccess={handleSuccess} onError={handleError} scope="email profile" /> </div> </div> </div> <p className="mt-6 text-center text-sm text-gray-600"> Already have an account?{' '} <button onClick={toggleView} className="font-medium text-green-600 hover:text-green-500" > Sign in </button> </p> </div> )} <p className="mt-6 text-xs text-center text-gray-500"> By continuing, you agree to our{' '} <a href="#" className="text-green-600 hover:text-green-500"> Terms of Service </a>{' '} and{' '} <a href="#" className="text-green-600 hover:text-green-500"> Privacy Policy </a> </p> </div> </div> ); }; export default Login;