vchikalkin e4357070af apps/web: add FormStateContext
apps/api: add methods ldap-tfa/login-telegram
2024-05-27 12:02:05 +03:00

110 lines
2.9 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.

/* eslint-disable react/jsx-curly-newline */
/* eslint-disable sonarjs/no-small-switch */
import TelegramIcon from '../public/assets/images/telegram.svg';
import styles from './Form.module.scss';
import { publicRuntimeConfig } from '@/config/runtime';
import { AuthModeContext } from '@/context/auth-mode';
import { FormStateContext } from '@/context/form-state';
import type { LdapUser } from '@/types/user';
import axios from 'axios';
import Image from 'next/image';
import { useContext, useState } from 'react';
import { useForm } from 'react-hook-form';
const { APP_BASE_PATH } = publicRuntimeConfig;
type FormData = {
readonly login: string;
readonly password: string;
};
function handleDefaultLogin(data: FormData) {
const redirectUrl =
(window.location.pathname.replace(APP_BASE_PATH, '') || '/') + (window.location.search || '');
return axios.post('/login', data).then(() => {
window.location.replace(redirectUrl);
});
}
function handleTelegramLogin(data: FormData) {
return axios.post<LdapUser>('/login', data);
}
export function Form() {
const [hasError, setHasError] = useState(false);
const { handleSubmit, register } = useForm<FormData>();
const { tfa } = useContext(AuthModeContext);
const {
dispatch,
state: { step, user },
} = useContext(FormStateContext);
return (
<form
className={styles.form}
onSubmit={handleSubmit((data) => {
if (!tfa) return handleDefaultLogin(data).catch(() => setHasError(true));
return handleTelegramLogin(data).then((res) =>
dispatch({
payload: {
step: 'telegram',
user: res.data,
},
type: 'set-step',
})
);
})}
>
<input
disabled={step === 'telegram'}
type="text"
placeholder="Логин"
required
autoComplete="on"
{...register('login', { required: true })}
/>
<input
disabled={step === 'telegram'}
type="password"
placeholder="Пароль"
required
autoComplete="on"
{...register('password', { required: true })}
/>
{hasError ? <span className="error">Неверный логин или пароль</span> : null}
<ButtonSubmit tfa={tfa} step={step} user={user} />
</form>
);
}
type ButtonSumitProps = {
readonly step: string;
readonly tfa: boolean;
readonly user: LdapUser | undefined;
};
function ButtonSubmit({ step, tfa, user }: ButtonSumitProps) {
if (!tfa || step === 'login') {
return (
<button className={styles['button-submit']} type="submit">
Войти
</button>
);
}
return (
<button type="button" className={styles['button-telegram']}>
<Image
className={styles['button-telegram-icon']}
src={TelegramIcon}
width={24}
height={22}
alt="Telegram icon"
/>
Войти как &nbsp; <b>{user?.displayName}</b>
</button>
);
}