web: split components into hooks & files
This commit is contained in:
parent
099fe2646e
commit
60519a171a
@ -7,59 +7,3 @@
|
||||
margin: 7px 0;
|
||||
}
|
||||
}
|
||||
|
||||
.button-submit {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button-telegram {
|
||||
@extend .button-submit;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-transform: none;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
animation: colorTransition 1s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
.button-telegram {
|
||||
img {
|
||||
margin: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes colorTransition {
|
||||
0% {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
100% {
|
||||
background-color: #54a9eb;
|
||||
}
|
||||
}
|
||||
|
||||
.button-telegram-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
margin: 0 !important;
|
||||
margin-right: 13px !important;
|
||||
margin-left: none !important;
|
||||
}
|
||||
|
||||
.spinner-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
fill: var(--color-primary);
|
||||
margin: 0 !important;
|
||||
margin-right: 6px !important;
|
||||
}
|
||||
|
||||
.loading-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import styles from './Form.module.scss';
|
||||
import type { FormData, FormProps } from './types';
|
||||
import type { FormData, FormProps } from './lib/types';
|
||||
import { publicRuntimeConfig } from '@/config/runtime';
|
||||
import { FormStateContext } from '@/context/form-state';
|
||||
import type { PropsWithChildren } from 'react';
|
||||
|
||||
@ -1,48 +1,22 @@
|
||||
import { BaseForm } from './base-form';
|
||||
import { ButtonLoading, ButtonLogin } from './buttons';
|
||||
import { ERROR_INVALID_CREDENTIALS, ERROR_SERVER } from './errors';
|
||||
import type { FormData } from './types';
|
||||
import { redirect } from '@/components/Form/utils';
|
||||
import { useLogin } from './hooks/default';
|
||||
import { useRefreshToken } from './hooks/token';
|
||||
import { ButtonLoading, ButtonLogin } from './lib/buttons';
|
||||
import { FormStateContext } from '@/context/form-state';
|
||||
import axios from 'axios';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export function DefaultForm() {
|
||||
useRefreshToken();
|
||||
const { handleLogin } = useLogin();
|
||||
|
||||
const {
|
||||
dispatch,
|
||||
state: { step, user },
|
||||
} = useContext(FormStateContext);
|
||||
|
||||
function handleRefreshToken() {
|
||||
axios
|
||||
.get('/refresh-token')
|
||||
.then(() => redirect())
|
||||
.catch(() =>
|
||||
dispatch({
|
||||
payload: { error: ERROR_SERVER, user: undefined },
|
||||
type: 'set-error',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
if (step === 'login' && user) {
|
||||
handleRefreshToken();
|
||||
|
||||
return <ButtonLoading />;
|
||||
}
|
||||
|
||||
function handleLogin(data: FormData) {
|
||||
return axios
|
||||
.post('/login', data)
|
||||
.then(() => redirect())
|
||||
.catch(() =>
|
||||
dispatch({
|
||||
payload: { error: ERROR_INVALID_CREDENTIALS },
|
||||
type: 'set-error',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseForm onSubmit={(data) => handleLogin(data)}>
|
||||
<ButtonLogin />
|
||||
|
||||
24
apps/web/components/Form/hooks/default.ts
Normal file
24
apps/web/components/Form/hooks/default.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import type { FormData } from '../lib/types';
|
||||
import { redirect } from '@/components/Form/lib/utils';
|
||||
import { ERROR_INVALID_CREDENTIALS } from '@/constants/errors';
|
||||
import { FormStateContext } from '@/context/form-state';
|
||||
import axios from 'axios';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export function useLogin() {
|
||||
const { dispatch } = useContext(FormStateContext);
|
||||
|
||||
function handleLogin(data: FormData) {
|
||||
return axios
|
||||
.post('/login', data)
|
||||
.then(() => redirect())
|
||||
.catch(() =>
|
||||
dispatch({
|
||||
payload: { error: ERROR_INVALID_CREDENTIALS },
|
||||
type: 'set-error',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return { handleLogin };
|
||||
}
|
||||
2
apps/web/components/Form/hooks/index.ts
Normal file
2
apps/web/components/Form/hooks/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './socket';
|
||||
export * from './token';
|
||||
99
apps/web/components/Form/hooks/telegram.ts
Normal file
99
apps/web/components/Form/hooks/telegram.ts
Normal file
@ -0,0 +1,99 @@
|
||||
import type { FormData } from '../lib/types';
|
||||
import { useSocket } from './socket';
|
||||
import { redirect } from '@/components/Form/lib/utils';
|
||||
import { ERROR_INVALID_CREDENTIALS, ERROR_SERVER } from '@/constants/errors';
|
||||
import { FormStateContext } from '@/context/form-state';
|
||||
import type { TelegramUrlResponse } from '@/types/error';
|
||||
import type { LdapUser } from '@/types/user';
|
||||
import axios, { isAxiosError } from 'axios';
|
||||
import { useContext, useEffect } from 'react';
|
||||
|
||||
export function useLogin() {
|
||||
const { dispatch } = useContext(FormStateContext);
|
||||
|
||||
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',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return { handleLogin };
|
||||
}
|
||||
|
||||
export function useTelegramLogin() {
|
||||
const { dispatch } = useContext(FormStateContext);
|
||||
|
||||
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',
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return { handleTelegramLogin };
|
||||
}
|
||||
|
||||
export function useTelegramConfirm() {
|
||||
const {
|
||||
dispatch,
|
||||
state: { step },
|
||||
} = 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]);
|
||||
}
|
||||
28
apps/web/components/Form/hooks/token.ts
Normal file
28
apps/web/components/Form/hooks/token.ts
Normal file
@ -0,0 +1,28 @@
|
||||
import { redirect } from '@/components/Form/lib/utils';
|
||||
import { ERROR_SERVER } from '@/constants/errors';
|
||||
import { FormStateContext } from '@/context/form-state';
|
||||
import axios from 'axios';
|
||||
import { useContext, useEffect } from 'react';
|
||||
|
||||
export function useRefreshToken() {
|
||||
const {
|
||||
dispatch,
|
||||
state: { step, user },
|
||||
} = useContext(FormStateContext);
|
||||
|
||||
function handleRefreshToken() {
|
||||
axios
|
||||
.get('/refresh-token')
|
||||
.then(() => redirect())
|
||||
.catch(() =>
|
||||
dispatch({
|
||||
payload: { error: ERROR_SERVER, user: undefined },
|
||||
type: 'set-error',
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (step === 'login' && user) handleRefreshToken();
|
||||
}, []);
|
||||
}
|
||||
55
apps/web/components/Form/lib/buttons.module.scss
Normal file
55
apps/web/components/Form/lib/buttons.module.scss
Normal file
@ -0,0 +1,55 @@
|
||||
.button-submit {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.button-telegram {
|
||||
@extend .button-submit;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
text-transform: none;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
|
||||
animation: colorTransition 1s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
.button-telegram {
|
||||
img {
|
||||
margin: 0;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes colorTransition {
|
||||
0% {
|
||||
background-color: var(--color-primary);
|
||||
}
|
||||
100% {
|
||||
background-color: #54a9eb;
|
||||
}
|
||||
}
|
||||
|
||||
.button-telegram-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
margin: 0 !important;
|
||||
margin-right: 13px !important;
|
||||
margin-left: none !important;
|
||||
}
|
||||
|
||||
.spinner-icon {
|
||||
filter: brightness(0) invert(1);
|
||||
fill: var(--color-primary);
|
||||
margin: 0 !important;
|
||||
margin-right: 6px !important;
|
||||
}
|
||||
|
||||
.loading-wrapper {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
import Spinner from '../../public/assets/animated/90-ring.svg';
|
||||
import TelegramIcon from '../../public/assets/images/telegram.svg?url';
|
||||
import styles from './Form.module.scss';
|
||||
import styles from './buttons.module.scss';
|
||||
import Spinner from '@/public/assets/animated/90-ring.svg';
|
||||
import TelegramIcon from '@/public/assets/images/telegram.svg?url';
|
||||
import Image from 'next/image';
|
||||
import type { ButtonHTMLAttributes } from 'react';
|
||||
|
||||
@ -1,107 +1,21 @@
|
||||
import { BaseForm } from './base-form';
|
||||
import { ButtonLoading, ButtonLogin, ButtonTelegram, ButtonTelegramLogin } from './buttons';
|
||||
import { ERROR_INVALID_CREDENTIALS, ERROR_SERVER } from './errors';
|
||||
import type { FormData } from './types';
|
||||
import { redirect } from '@/components/Form/utils';
|
||||
import { useLogin, useTelegramConfirm, useTelegramLogin } from './hooks/telegram';
|
||||
import { useRefreshToken } from './hooks/token';
|
||||
import { ButtonLoading, ButtonLogin, ButtonTelegram, ButtonTelegramLogin } from './lib/buttons';
|
||||
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 { useContext, useEffect } from 'react';
|
||||
import { useContext } from 'react';
|
||||
|
||||
export function TelegramForm() {
|
||||
useRefreshToken();
|
||||
const { handleLogin } = useLogin();
|
||||
const { handleTelegramLogin } = useTelegramLogin();
|
||||
useTelegramConfirm();
|
||||
|
||||
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) {
|
||||
handleRefreshToken();
|
||||
|
||||
return <ButtonLoading />;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user