158 lines
3.9 KiB
TypeScript
158 lines
3.9 KiB
TypeScript
import TelegramIcon from '../../public/assets/images/telegram.svg';
|
||
import { BaseForm } from './base-form';
|
||
import { ERROR_INVALID_CREDENTIALS, ERROR_SERVER } from './errors';
|
||
import styles from './Form.module.scss';
|
||
import type { FormData } from './types';
|
||
import { redirect } from '@/components/Form/utils';
|
||
import { FormStateContext } from '@/context/form-state';
|
||
import { useSocket } from '@/hooks/socket';
|
||
import type { TelegramUrlResponse } from '@/types/error';
|
||
import type { LdapUser } from '@/types/user';
|
||
import axios, { isAxiosError } from 'axios';
|
||
import Image from 'next/image';
|
||
import { useContext, useEffect } from 'react';
|
||
|
||
export function TelegramForm() {
|
||
const {
|
||
dispatch,
|
||
state: { step, user },
|
||
} = useContext(FormStateContext);
|
||
|
||
const { socket } = useSocket();
|
||
|
||
useEffect(() => {
|
||
if (step === 'telegram-login') {
|
||
socket.open();
|
||
socket.on('connect', () => {});
|
||
|
||
socket.on('auth-allow', () => {
|
||
socket.off('connect');
|
||
axios
|
||
.get('/login-confirm')
|
||
.then(() => redirect())
|
||
.catch(() =>
|
||
dispatch({
|
||
payload: { error: ERROR_SERVER },
|
||
type: 'set-error',
|
||
})
|
||
);
|
||
});
|
||
}
|
||
|
||
return () => {
|
||
socket.off('connect');
|
||
};
|
||
}, [dispatch, socket, step]);
|
||
|
||
function handleLogin(data: FormData) {
|
||
axios
|
||
.post<LdapUser>('/login', data)
|
||
.then((res) => {
|
||
dispatch({
|
||
payload: {
|
||
step: 'telegram',
|
||
user: res.data,
|
||
},
|
||
type: 'set-step',
|
||
});
|
||
})
|
||
.catch(() =>
|
||
dispatch({
|
||
payload: { error: ERROR_INVALID_CREDENTIALS },
|
||
type: 'set-error',
|
||
})
|
||
);
|
||
}
|
||
|
||
function handleTelegramLogin() {
|
||
axios
|
||
.post<LdapUser>('/login-telegram')
|
||
.then(() => {
|
||
dispatch({
|
||
payload: {
|
||
step: 'telegram-login',
|
||
},
|
||
type: 'set-step',
|
||
});
|
||
})
|
||
.catch((error_) => {
|
||
let error = ERROR_SERVER;
|
||
|
||
if (isAxiosError<TelegramUrlResponse>(error_) && error_.response?.data?.message) {
|
||
error = error_.response?.data?.message;
|
||
}
|
||
|
||
return dispatch({
|
||
payload: { error },
|
||
type: 'set-error',
|
||
});
|
||
});
|
||
}
|
||
|
||
function handleRefreshToken() {
|
||
axios
|
||
.get('/refresh-token')
|
||
.then(() => redirect())
|
||
.catch(() =>
|
||
dispatch({
|
||
payload: { error: ERROR_SERVER },
|
||
type: 'set-error',
|
||
})
|
||
);
|
||
}
|
||
|
||
if (step === 'login' && user) {
|
||
return (
|
||
<button
|
||
className={styles['button-submit']}
|
||
type="submit"
|
||
onClick={() => handleRefreshToken()}
|
||
>
|
||
Продолжить как <b>{user?.displayName || user.username}</b>
|
||
</button>
|
||
);
|
||
}
|
||
|
||
if (step === 'telegram') {
|
||
return (
|
||
<BaseForm onSubmit={() => handleTelegramLogin()}>
|
||
<button type="submit" className={styles['button-telegram']}>
|
||
<Image
|
||
className={styles['button-telegram-icon']}
|
||
src={TelegramIcon}
|
||
width={24}
|
||
height={22}
|
||
alt="Telegram icon"
|
||
/>
|
||
Войти как <b>{user?.displayName}</b>
|
||
</button>
|
||
</BaseForm>
|
||
);
|
||
}
|
||
|
||
if (step === 'telegram-login') {
|
||
return (
|
||
<BaseForm onSubmit={() => {}}>
|
||
<button disabled type="submit" className={styles['button-telegram']}>
|
||
<Image
|
||
className={styles['button-telegram-icon']}
|
||
src={TelegramIcon}
|
||
width={24}
|
||
height={22}
|
||
alt="Telegram icon"
|
||
/>
|
||
Ожидаем подтверждения...
|
||
</button>
|
||
</BaseForm>
|
||
);
|
||
}
|
||
|
||
return (
|
||
<BaseForm onSubmit={(data) => handleLogin(data)}>
|
||
<button className={styles['button-submit']} type="submit">
|
||
Войти
|
||
</button>
|
||
</BaseForm>
|
||
);
|
||
}
|