feat: add window for oauth

This commit is contained in:
SD 2024-04-06 17:26:35 +04:00
parent b74c86789f
commit 07052b9c01
4 changed files with 108 additions and 0 deletions

View File

@ -1,7 +1,10 @@
import React, { FC, useState } from 'react'; import React, { FC, useState } from 'react';
import { Form, FormInstance, notification } from 'antd'; import { Form, FormInstance, notification } from 'antd';
import Image from 'next/image'; import Image from 'next/image';
import { Social } from '../../../types/social';
import { AUTH_USER } from '../../../constants/common'; import { AUTH_USER } from '../../../constants/common';
import { SocialConfig } from '../../../constants/social';
import { useOauthWindow } from '../../../hooks/useOauthWindow';
import { getAuth } from '../../../actions/auth'; import { getAuth } from '../../../actions/auth';
import { getPersonalData } from '../../../actions/profile'; import { getPersonalData } from '../../../actions/profile';
import { CustomInput } from '../../view/CustomInput'; import { CustomInput } from '../../view/CustomInput';
@ -26,6 +29,7 @@ export const EnterContent: FC<EnterProps> = ({
handleCancel handleCancel
}) => { }) => {
const [isLoading, setIsLoading] = useState<boolean>(false); const [isLoading, setIsLoading] = useState<boolean>(false);
const { openOauthWindow } = useOauthWindow();
const onLogin = () => { const onLogin = () => {
form.validateFields().then(() => { form.validateFields().then(() => {
@ -54,6 +58,48 @@ export const EnterContent: FC<EnterProps> = ({
}); });
}; };
const onSocialClick = (type: Social) => {
const url = SocialConfig[type].oauthUrl;
if (!url) return;
openOauthWindow(url, type, async (event: MessageEvent) => {
const { data: socialData } = event
// примерная схема последующей обработки
// const socialErrors: string[] = [];
// try {
// // отправляем запрос на бэк с данными из соц сети
// const { data: { jwtToken } } = await query(socialData);
// // обновляем токен
// updateToken(jwtToken);
// // получаем данные о пользователе
// await getAuthUser()
// } catch (error: any) {
// if (error.httpStatus === 449) {
// // ошибка, когда отсутствует e-mail
//
// // какие-то дальнейшие действия после получения ошибки, например, закрываем окно и открываем модалку регистрации
// handleCancel();
// openSocialEmailRequestModal(socialData);
// } else if (error.httpStatus === 409) {
// // ошибка, когда по переданному email уже существует аккаунт
//
// // какие-то дальнейшие действия после получения ошибки, например, закрываем окно и открываем модалку с вводом пароля
// handleCancel();
// openSocialPasswordModal(socialData);
// } else {
// // в остальных случаях записываем ошибку в массив ошибок
// socialErrors.push(error.toString());
// }
// }
//
// // если все успешно, закрываем окно oauth
// handleCancel();
})
}
return ( return (
<> <>
<Form form={form} style={{ display: 'flex', gap: 16, flexDirection: 'column' }}> <Form form={form} style={{ display: 'flex', gap: 16, flexDirection: 'column' }}>
@ -110,16 +156,19 @@ export const EnterContent: FC<EnterProps> = ({
<span>or</span> <span>or</span>
<OutlinedButton <OutlinedButton
icon={<Image src="/images/facebook-logo.png" height={20} width={20} alt="" />} icon={<Image src="/images/facebook-logo.png" height={20} width={20} alt="" />}
onClick={() => onSocialClick(Social.FACEBOOK)}
> >
Facebook account Facebook account
</OutlinedButton> </OutlinedButton>
<OutlinedButton <OutlinedButton
icon={<Image src="/images/apple-logo.png" height={22} width={22} alt="" />} icon={<Image src="/images/apple-logo.png" height={22} width={22} alt="" />}
onClick={() => onSocialClick(Social.APPLE)}
> >
Apple account Apple account
</OutlinedButton> </OutlinedButton>
<OutlinedButton <OutlinedButton
icon={<Image src="/images/google-logo.png" height={20} width={20} alt="" />} icon={<Image src="/images/google-logo.png" height={20} width={20} alt="" />}
onClick={() => onSocialClick(Social.GOOGLE)}
> >
Google account Google account
</OutlinedButton> </OutlinedButton>

16
src/constants/social.ts Normal file
View File

@ -0,0 +1,16 @@
import { Social } from '../types/social';
export const SocialConfig = {
[Social.FACEBOOK]: {
oauthUrl: 'http://vk.com',
redirectUrl: ''
},
[Social.APPLE]: {
oauthUrl: 'http://apple.com',
redirectUrl: ''
},
[Social.GOOGLE]: {
oauthUrl: 'http://google.com',
redirectUrl: ''
}
};

View File

@ -0,0 +1,38 @@
const DEFAULT_WINDOW_PARAMS = 'toolbar=no, menubar=no, width=600, height=700, top=100, left=100';
export const useOauthWindow = () => {
let oauthWindow: Window | null = null;
const openOauthWindow = (
url: string,
name: string,
messageHandler: (e: MessageEvent) => void,
params: string = DEFAULT_WINDOW_PARAMS,
) => {
const handler = (event: MessageEvent) => {
const { data } = event;
if (data.messageType === 'oAuth') {
messageHandler(event);
window.removeEventListener('message', handler);
}
}
window.removeEventListener('message', handler);
if (!oauthWindow || oauthWindow.closed) {
// окно ещё не существует, либо было закрыто
oauthWindow = window.open(url, name, params)!;
} else {
// окно уже существует
oauthWindow!.focus();
}
window.addEventListener('message', handler);
}
return {
oauthWindow,
openOauthWindow,
}
}

5
src/types/social.ts Normal file
View File

@ -0,0 +1,5 @@
export enum Social {
FACEBOOK = 'meta',
APPLE = 'apple',
GOOGLE = 'google'
}