Files
QMS/fe/web/teller-app/src/pages/LoginPage/LoginPage.jsx
T
2026-07-21 10:24:14 +08:00

131 lines
4.1 KiB
React

import { useContext, useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { ROLES, SERVER_URL } from '../../constants.js';
import { fetchData } from '../../fetching/Fetch.js';
import { UserContext } from '../../context/UserContext.jsx';
import { clearSession, getToken, setSession } from '../../utils/session.js';
import './LoginPage.css';
const TELLER_ROLES = [
ROLES.ROLE_USER,
ROLES.ROLE_SUPER_ADMIN,
ROLES.ROLE_BRANCH_ADMIN,
];
function canAccessTellerApp(userData) {
const roles = Array.isArray(userData?.roles) ? userData.roles : [];
return roles.some((role) => TELLER_ROLES.includes(role));
}
export default function LoginPage() {
const navigate = useNavigate();
const { user, setUser } = useContext(UserContext);
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
useEffect(() => {
if (user && getToken()) {
navigate('/', { replace: true });
}
}, [user, navigate]);
async function handleSubmit(event) {
event.preventDefault();
if (!email.trim()) {
setError('Email is required.');
return;
}
if (!password.trim()) {
setError('Password is required.');
return;
}
setLoading(true);
setError('');
try {
const { data, success } = await fetchData(`${SERVER_URL}/api/v1/auth/login`, 'POST', {
email: email.trim(),
password: password.trim(),
});
if (!success || !data) {
setError('Your credentials are incorrect.');
return;
}
const userData = data.userData ?? data;
const token = data.token;
if (!canAccessTellerApp(userData)) {
clearSession();
setUser(null);
setError('This account cannot access the teller app.');
return;
}
if (!token) {
setError('Two-factor login is not supported in the teller app yet. Disable 2FA for this account or use an account without 2FA.');
return;
}
if (!userData?.tenantCode) {
setError('Login succeeded but tenant information is missing.');
return;
}
setSession({ userData, token });
setUser(userData);
navigate('/', { replace: true });
} catch (err) {
console.error(err);
setError('An error occurred. Please try again.');
} finally {
setLoading(false);
}
}
return (
<div id="teller-login-form">
<h1>Teller Login</h1>
<form onSubmit={handleSubmit}>
<div className="form-group">
<label htmlFor="email">Email</label>
<input
id="email"
type="email"
value={email}
autoComplete="username"
onChange={(event) => {
setEmail(event.target.value);
setError('');
}}
/>
</div>
<div className="form-group">
<label htmlFor="password">Password</label>
<input
id="password"
type="password"
value={password}
autoComplete="current-password"
onChange={(event) => {
setPassword(event.target.value);
setError('');
}}
/>
</div>
{error ? <p className="error">{error}</p> : null}
<button type="submit" disabled={loading}>
{loading ? 'Signing in…' : 'Sign in'}
</button>
</form>
</div>
);
}