Files
revenue-fe/src/auth/pages/jwt/Login.tsx
2025-02-01 16:44:51 +07:00

190 lines
6.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { type MouseEvent, useState } from 'react';
import { Link, useLocation, useNavigate } from 'react-router-dom';
import clsx from 'clsx';
import * as Yup from 'yup';
import { useFormik } from 'formik';
import { KeenIcon } from '@/components';
import { toAbsoluteUrl } from '@/utils';
import { useAuthContext } from '@/auth';
import { useLayout } from '@/providers';
import { Alert } from '@/components';
import moment from 'moment';
const loginSchema = Yup.object().shape({
username: Yup.string().required('Username is required'),
password: Yup.string()
.min(3, 'Minimum 3 symbols')
.max(50, 'Maximum 50 symbols')
.required('Password is required'),
remember: Yup.boolean()
});
const initialValues = {
username: '',
password: '',
application: 'credit',
remember: false
};
const Login = () => {
const [loading, setLoading] = useState(false);
const { login } = useAuthContext();
const navigate = useNavigate();
const location = useLocation();
const from = location.state?.from?.pathname || '/';
const [showPassword, setShowPassword] = useState(false);
const { currentLayout } = useLayout();
const formik = useFormik({
initialValues,
validationSchema: loginSchema,
onSubmit: async (values, { setStatus, setSubmitting }) => {
setLoading(true);
try {
if (!login) {
throw new Error('JWTProvider is required for this form.');
}
await login(values.username, values.password, values.application);
console.log(login);
if (values.remember) {
localStorage.setItem('username', values.username);
} else {
localStorage.removeItem('username');
}
navigate(from, { replace: true });
} catch (error: any) {
if (error.response && error.response.data) {
setStatus(error.response.data.message);
} else {
setStatus('The login details are incorrect');
}
setSubmitting(false);
}
setLoading(false);
}
});
const togglePassword = (event: MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
setShowPassword(!showPassword);
};
return (
<div className="card max-w-[390px] border-0 shadow-none w-full">
<form className="card-body flex flex-col gap-5 p-5" onSubmit={formik.handleSubmit} noValidate>
<div className="flex align-center justify-center text-center mb-2.5">
<img
src={toAbsoluteUrl('/media/app/bri_tl_logo.png')}
className="h-[50px] max-w-none mb-2 text-center"
alt=""
/>
</div>
<div className="flex flex-col gap-3">
<div className="flex gap-3 items-center">
<div>
<img
src={toAbsoluteUrl('/media/app/brilian_apps_logo.png')}
className="h-[40px] max-w-none"
alt=""
/>
</div>
<h3 className="font-semibold text-gray-700" style={{ fontSize: '18px' }}>
/ Pengajuan Kredit
</h3>
</div>
</div>
{formik.status && <Alert variant="danger">{formik.status}</Alert>}
<div className="flex flex-col gap-1">
<label className="form-label text-gray-900 ps-2.5">Login</label>
<label className="input">
<input
placeholder="Enter username"
autoComplete="off"
{...formik.getFieldProps('username')}
className={clsx('form-control', {
'is-invalid': formik.touched.username && formik.errors.username
})}
/>
</label>
{formik.touched.username && formik.errors.username && (
<span role="alert" className="text-danger text-xs mt-1">
{formik.errors.username}
</span>
)}
</div>
<div className="flex flex-col gap-1">
<div className="flex items-center justify-between gap-1">
<label className="form-label text-gray-900 ps-2.5">Password</label>
</div>
<label className="input">
<input
type={showPassword ? 'text' : 'password'}
placeholder="Enter Password"
autoComplete="off"
{...formik.getFieldProps('password')}
className={clsx('form-control', {
'is-invalid': formik.touched.password && formik.errors.password
})}
/>
<button className="btn btn-icon" onClick={togglePassword}>
<KeenIcon icon="eye" className={clsx('text-gray-500', { hidden: showPassword })} />
<KeenIcon
icon="eye-slash"
className={clsx('text-gray-500', { hidden: !showPassword })}
/>
</button>
</label>
{formik.touched.password && formik.errors.password && (
<span role="alert" className="text-danger text-xs mt-1">
{formik.errors.password}
</span>
)}
</div>
<div className="flex items-center justify-between gap-1">
<label className="checkbox-group">
<input
className="checkbox checkbox-sm"
type="checkbox"
{...formik.getFieldProps('remember')}
/>
<span className="checkbox-label">Remember me</span>
</label>
<Link
to={
currentLayout?.name === 'auth-branded'
? '/auth/reset-password'
: '/auth/classic/reset-password'
}
className="text-2sm link shrink-0"
>
Forgot Password?
</Link>
</div>
<button
type="submit"
className="btn btn-primary flex justify-center grow"
disabled={loading || formik.isSubmitting}
>
{loading ? 'Please wait...' : 'Sign In'}
</button>
<div>
<p className="text-2sm" style={{ fontSize: '12px', letterSpacing: 0.25 }}>
Copyright {moment().year()} &copy; Bank Rakyat Indonesia Timor Leste.All rights
reserved.
</p>
</div>
</form>
</div>
);
};
export { Login };