|
|
import { useEffect, FormEventHandler, useState } from 'react'; import Checkbox from '@/Components/Checkbox'; import GuestLayout from '@/Layouts/GuestLayout'; import InputError from '@/Components/InputError'; import InputLabel from '@/Components/InputLabel'; import PrimaryButton from '@/Components/PrimaryButton'; import TextInput from '@/Components/TextInput'; import { Head, Link, useForm } from '@inertiajs/react'; import { AtSign, Lock, Eye, EyeOff, LogIn, CheckCircle, XOctagon } from 'react-feather'; import FormGroup from '@/Components/FormGroup'; import ProjectBanner from '@/Components/ProjectBanner'; import Modal from '@/Components/Modal'; import axios from 'axios'; import ModalButton from '@/Components/ModalButton';
export default function Login({ status, canResetPassword }: { status?: string, canResetPassword: boolean }) { const { data, setData, post, processing, errors, reset } = useForm({ username: '', password: '', remember: false, });
useEffect(() => { return () => { reset('password'); }; }, []);
const [showPassword, setShowPassword] = useState(false); const toggleShowPassword = () => { setShowPassword((prevShowPassword) => !prevShowPassword); };
const [statusTitle, setStatusTitle] = useState(''); const [feedback, setFeedback] = useState(''); const [isSuccessModalOpen, setIsSuccessModalOpen] = useState(false); const [isErrorModalOpen, setIsErrorModalOpen] = useState(false);
const handleCloseSuccessModal = () => { setIsSuccessModalOpen(false); window.location.href = '/login'; };
const submit: FormEventHandler = async (e) => { e.preventDefault();
try { const response = await axios.post(route('login'), data); setStatusTitle('Success') setFeedback(response.data.message); setIsSuccessModalOpen(true); } catch (error) { setStatusTitle('Error') if (axios.isAxiosError(error)) { setFeedback(error.response?.data.message || 'An error occurred'); } else { setFeedback('An unexpected error occurred'); } setIsErrorModalOpen(true); } };
return ( <GuestLayout> <Head title="Log in" />
{status && <div className="mb-4 font-medium text-sm text-green-600">{status}</div>}
<div id="Login" className="hero min-h-screen bg-secondary-main"> <div className="hero-content flex-row"> <ProjectBanner />
<div className="card w-104 shrink-0 bg-primary-background"> <div className="card-body justify-center items-center"> <img src="assets/images/img-login.png" alt="An image that represents a login form from StorySet" width="250" height="250" /> <form id="SignInForm" onSubmit={ submit }> <FormGroup> <InputLabel htmlFor='username'> <AtSign className='stroke-neutral-10' /> </InputLabel> <TextInput id='username' name='username' value={data.username} autoComplete='off' placeholder='Username' required onChange={(e) => setData('username', e.target.value)} /> <InputError message={errors.username} className="mt-2" /> </FormGroup>
<FormGroup> <InputLabel htmlFor='password'> <Lock className='stroke-neutral-10' /> </InputLabel> <TextInput type={showPassword ? "text" : "password"} id='password' name='password' value={data.password} autoComplete='off' placeholder='Password' required onChange={(e) => setData('password', e.target.value)} className='border-r-0' /> <label htmlFor="showPassword" className="swap items-center border border-primary-hover border-l-0"> <input type="checkbox" name="showPassword" id="showPassword" onChange={toggleShowPassword} checked={showPassword} className='hidden' /> <Eye className='swap-off px-1 stroke-secondary-main' /> <EyeOff className='swap-on px-1 stroke-secondary-main' /> </label> <InputError message={errors.password} className="mt-2" /> </FormGroup> <div className="flex items-center justify-between"> <label className="flex items-center"> <Checkbox name="remember" checked={data.remember} onChange={(e) => setData('remember', e.target.checked)} /> <span className="ml-1 text-secondary-main">Remember me</span> </label>
{canResetPassword && ( <Link href={route('password.request')} className="btn btn-link text-secondary-main m-0 p-0" > Forgot password... </Link> )} </div>
<div className="flex items-center justify-end mt-4"> <p className="invisible">No account yet? Register instead.</p> <PrimaryButton type='submit' disabled={processing}> Log In <LogIn className='stroke-neutral-10' /> </PrimaryButton> </div> </form> </div> </div> </div>
<Modal show={isSuccessModalOpen} onClose={() => setIsSuccessModalOpen(false)} maxWidth="lg" styling='success'> <div className="p-4 flex flex-col items-center"> <CheckCircle className='stroke-success-main' size={80} /> <h2 className="text-xl font-bold mt-2">{ statusTitle }</h2> <p className="mt-4">{ feedback }</p> <ModalButton onClick={handleCloseSuccessModal} className="bg-success-main text-white hover:bg-success-hover active:bg-success-pressed"> Go to Dashboard </ModalButton> </div> </Modal>
<Modal show={isErrorModalOpen} onClose={() => setIsErrorModalOpen(false)} maxWidth="lg" styling='error'> <div className="p-4 flex flex-col items-center"> <XOctagon className='stroke-error-main' size={80} /> <h2 className="text-xl font-bold mt-2">{ statusTitle }</h2> <p className="mt-4">{ feedback }</p> <ModalButton onClick={() => setIsErrorModalOpen(false)} className="bg-error-main text-white hover:bg-error-hover active:bg-error-pressed"> Close </ModalButton> </div> </Modal> </div> </GuestLayout> ); }
|