From 07052b9c018c0ff254c880cb2836391ca57aefbe Mon Sep 17 00:00:00 2001 From: SD Date: Sat, 6 Apr 2024 17:26:35 +0400 Subject: [PATCH] feat: add window for oauth --- .../Modals/authModalContent/EnterContent.tsx | 49 +++++++++++++++++++ src/constants/social.ts | 16 ++++++ src/hooks/useOauthWindow.ts | 38 ++++++++++++++ src/types/social.ts | 5 ++ 4 files changed, 108 insertions(+) create mode 100644 src/constants/social.ts create mode 100644 src/hooks/useOauthWindow.ts create mode 100644 src/types/social.ts diff --git a/src/components/Modals/authModalContent/EnterContent.tsx b/src/components/Modals/authModalContent/EnterContent.tsx index b286b61..b884c8d 100644 --- a/src/components/Modals/authModalContent/EnterContent.tsx +++ b/src/components/Modals/authModalContent/EnterContent.tsx @@ -1,7 +1,10 @@ import React, { FC, useState } from 'react'; import { Form, FormInstance, notification } from 'antd'; import Image from 'next/image'; +import { Social } from '../../../types/social'; import { AUTH_USER } from '../../../constants/common'; +import { SocialConfig } from '../../../constants/social'; +import { useOauthWindow } from '../../../hooks/useOauthWindow'; import { getAuth } from '../../../actions/auth'; import { getPersonalData } from '../../../actions/profile'; import { CustomInput } from '../../view/CustomInput'; @@ -26,6 +29,7 @@ export const EnterContent: FC = ({ handleCancel }) => { const [isLoading, setIsLoading] = useState(false); + const { openOauthWindow } = useOauthWindow(); const onLogin = () => { form.validateFields().then(() => { @@ -54,6 +58,48 @@ export const EnterContent: FC = ({ }); }; + 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 ( <>
@@ -110,16 +156,19 @@ export const EnterContent: FC = ({ or } + onClick={() => onSocialClick(Social.FACEBOOK)} > Facebook account } + onClick={() => onSocialClick(Social.APPLE)} > Apple account } + onClick={() => onSocialClick(Social.GOOGLE)} > Google account diff --git a/src/constants/social.ts b/src/constants/social.ts new file mode 100644 index 0000000..0240456 --- /dev/null +++ b/src/constants/social.ts @@ -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: '' + } +}; diff --git a/src/hooks/useOauthWindow.ts b/src/hooks/useOauthWindow.ts new file mode 100644 index 0000000..dd3e2e7 --- /dev/null +++ b/src/hooks/useOauthWindow.ts @@ -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, + } +} diff --git a/src/types/social.ts b/src/types/social.ts new file mode 100644 index 0000000..a430eeb --- /dev/null +++ b/src/types/social.ts @@ -0,0 +1,5 @@ +export enum Social { + FACEBOOK = 'meta', + APPLE = 'apple', + GOOGLE = 'google' +}