2024-05-07 13:42:55 +03:00

138 lines
3.3 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 axios from 'axios';
import Image from 'next/image';
import { useContext, useReducer, useState } from 'react';
import { useForm } from 'react-hook-form';
const { APP_BASE_PATH } = publicRuntimeConfig;
type FormData = {
readonly login: string;
readonly password: string;
};
type User = {
department: string;
displayName: string;
domain: string;
domainName: string;
mail: string;
position: string;
username: 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<User>('/login', data);
}
type State = {
step: 'login' | 'telegram';
user: User | undefined;
};
type Action = {
payload: State;
type: 'set-step';
};
const reducer = (state: State, action: Action): State => {
switch (action.type) {
case 'set-step':
return {
...state,
...action.payload,
};
default:
return state;
}
};
export function Form() {
const [hasError, setHasError] = useState(false);
const { handleSubmit, register } = useForm<FormData>();
const { tfa } = useContext(AuthModeContext);
const [{ step, user }, dispatch] = useReducer(reducer, { step: 'login', user: undefined });
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: User | 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>
);
}