Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 예약 화면에서 로그인 후, 예약 화면으로 바로 돌아가는 기능 구현 #988

Merged
merged 1 commit into from
Apr 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const buttonCSS = css`
border-radius: 0.125rem;
`;

export const SocialLoginButton = styled.a<LoginButtonProps>`
export const SocialLoginButton = styled.button<LoginButtonProps>`
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

버튼으로 변경되었군요

${({ provider }) => providerCSS[provider]}
${buttonCSS};
width: ${({ variant }) => (variant === 'icon' ? '52px' : '100%')};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { AnchorHTMLAttributes } from 'react';
import { ButtonHTMLAttributes } from 'react';
import { ReactComponent as GithubIcon } from 'assets/svg/github-logo.svg';
import { ReactComponent as GoogleIcon } from 'assets/svg/google-logo.svg';
import * as Styled from './SocialAuthButton.styles';

export interface Props extends AnchorHTMLAttributes<HTMLAnchorElement> {
export interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
provider: 'GITHUB' | 'GOOGLE';
variant?: 'default' | 'icon';
}
Expand All @@ -21,7 +21,7 @@ const social = {

const SocialLoginButton = ({ provider, variant = 'default', ...props }: Props): JSX.Element => {
return (
<Styled.SocialLoginButton provider={provider} variant={variant} {...props}>
<Styled.SocialLoginButton {...props} type="button" provider={provider} variant={variant}>
<Styled.Icon>{social[provider].icon}</Styled.Icon>
{variant === 'default' && <Styled.Text>{social[provider].text}</Styled.Text>}
</Styled.SocialLoginButton>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/constants/storage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const LOCAL_STORAGE_KEY = {
ACCESS_TOKEN: 'accessToken',
AFTER_LOGIN_PATH: 'afterLoginPath',
};
31 changes: 27 additions & 4 deletions frontend/src/pages/GuestMap/units/LoginPopup.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AxiosError, AxiosResponse } from 'axios';
import { useContext, useState } from 'react';
import { useMutation } from 'react-query';
import { useHistory } from 'react-router-dom';
import { useHistory, useLocation } from 'react-router-dom';
import { postLogin } from 'api/login';
import Button from 'components/Button/Button';
import Input from 'components/Input/Input';
Expand All @@ -10,9 +10,11 @@ import SocialLoginButton from 'components/SocialAuthButton/SocialLoginButton';
import MANAGER from 'constants/manager';
import MESSAGE from 'constants/message';
import PATH from 'constants/path';
import { LOCAL_STORAGE_KEY } from 'constants/storage';
import useInputs from 'hooks/useInputs';
import { AccessTokenContext } from 'providers/AccessTokenProvider';
import { ErrorResponse, LoginSuccess } from 'types/response';
import { setLocalStorageItem } from 'utils/localStorage';
import * as Styled from './LoginPopup.styles';

interface LoginPopupProps {
Expand All @@ -25,6 +27,7 @@ const LoginPopup = ({ open, onClose, onLogin }: LoginPopupProps): JSX.Element =>
const { setAccessToken } = useContext(AccessTokenContext);

const history = useHistory();
const location = useLocation();

const [{ email, password }, onChangeForm, setValues] = useInputs<{
email: string;
Expand Down Expand Up @@ -109,16 +112,36 @@ const LoginPopup = ({ open, onClose, onLogin }: LoginPopupProps): JSX.Element =>
variant="inverse"
size="medium"
fullWidth
onClick={() => history.push('/join')}
onClick={() => history.push(PATH.MANAGER_JOIN)}
>
회원가입
</Button>
</Styled.LoginFormButtonWrapper>
</Styled.LoginPopupForm>
<Styled.Line />
<Styled.SocialLoginButtonWrapper>
<SocialLoginButton provider="GITHUB" variant="icon" href={PATH.GITHUB_LOGIN} />
<SocialLoginButton provider="GOOGLE" variant="icon" href={PATH.GOOGLE_LOGIN} />
<SocialLoginButton
provider="GITHUB"
variant="icon"
onClick={() => {
setLocalStorageItem({
key: LOCAL_STORAGE_KEY.AFTER_LOGIN_PATH,
item: location.pathname,
});
window.location.href = PATH.GITHUB_LOGIN;
}}
/>
<SocialLoginButton
provider="GOOGLE"
variant="icon"
onClick={() => {
setLocalStorageItem({
key: LOCAL_STORAGE_KEY.AFTER_LOGIN_PATH,
item: location.pathname,
});
window.location.href = PATH.GOOGLE_LOGIN;
}}
/>
</Styled.SocialLoginButtonWrapper>
<Styled.ContinueWithNonMemberWrapper>
<Styled.ContinueWithNonMember onClick={onClose}>
Expand Down
14 changes: 12 additions & 2 deletions frontend/src/pages/Login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,18 @@ const Login = (): JSX.Element => {
<LoginForm errorMessage={errorMessage} onSubmit={handleSubmit} />
<Styled.HorizontalLine />
<Styled.SocialLogin>
<SocialLoginButton provider="GITHUB" href={PATH.GITHUB_LOGIN} />
<SocialLoginButton provider="GOOGLE" href={PATH.GOOGLE_LOGIN} />
<SocialLoginButton
provider="GITHUB"
onClick={() => {
window.location.href = PATH.GITHUB_LOGIN;
}}
/>
<SocialLoginButton
provider="GOOGLE"
onClick={() => {
window.location.href = PATH.GOOGLE_LOGIN;
}}
/>
</Styled.SocialLogin>
<Styled.JoinLinkMessage>
아직 회원이 아니신가요?
Expand Down
20 changes: 18 additions & 2 deletions frontend/src/pages/OAuthRedirect/GithubOAuthRedirect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { useContext } from 'react';
import { useHistory } from 'react-router';
import MESSAGE from 'constants/message';
import PATH from 'constants/path';
import { LOCAL_STORAGE_KEY } from 'constants/storage';
import useGithubLogin from 'hooks/query/useGithubLogin';
import useQueryString from 'hooks/useQueryString';
import { AccessTokenContext } from 'providers/AccessTokenProvider';
import { LoginSuccess, SocialLoginFailure } from 'types/response';
import { getLocalStorageItem, removeLocalStorageItem } from 'utils/localStorage';

const GithubOAuthRedirect = (): JSX.Element => {
const history = useHistory();
Expand All @@ -23,7 +25,12 @@ const GithubOAuthRedirect = (): JSX.Element => {

setAccessToken(accessToken);

history.replace(PATH.GUEST_MAIN);
const afterLoginPath = getLocalStorageItem({
key: LOCAL_STORAGE_KEY.AFTER_LOGIN_PATH,
defaultValue: PATH.GUEST_MAIN,
});

history.replace(afterLoginPath);
},

onError: (error: AxiosError<SocialLoginFailure>) => {
Expand All @@ -41,7 +48,16 @@ const GithubOAuthRedirect = (): JSX.Element => {

alert(error.response?.data.message ?? MESSAGE.LOGIN.UNEXPECTED_ERROR);

history.replace(PATH.LOGIN);
const afterLoginPath = getLocalStorageItem({
key: LOCAL_STORAGE_KEY.AFTER_LOGIN_PATH,
defaultValue: PATH.LOGIN,
});

history.replace(afterLoginPath);
},

onSettled: () => {
removeLocalStorageItem({ key: LOCAL_STORAGE_KEY.AFTER_LOGIN_PATH });
},
}
);
Expand Down
20 changes: 18 additions & 2 deletions frontend/src/pages/OAuthRedirect/GoogleOAuthRedirect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { useContext } from 'react';
import { useHistory } from 'react-router';
import MESSAGE from 'constants/message';
import PATH from 'constants/path';
import { LOCAL_STORAGE_KEY } from 'constants/storage';
import useGoogleLogin from 'hooks/query/useGoogleLogin';
import useQueryString from 'hooks/useQueryString';
import { AccessTokenContext } from 'providers/AccessTokenProvider';
import { LoginSuccess, SocialLoginFailure } from 'types/response';
import { getLocalStorageItem, removeLocalStorageItem } from 'utils/localStorage';

const GoogleOAuthRedirect = (): JSX.Element => {
const history = useHistory();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

history 뭔가 오랜만에 보는 느낌 ㅋㅋㅋ

Expand All @@ -23,7 +25,12 @@ const GoogleOAuthRedirect = (): JSX.Element => {

setAccessToken(accessToken);

history.replace(PATH.GUEST_MAIN);
const afterLoginPath = getLocalStorageItem({
key: LOCAL_STORAGE_KEY.AFTER_LOGIN_PATH,
defaultValue: PATH.GUEST_MAIN,
});

history.replace(afterLoginPath);
},

onError: (error: AxiosError<SocialLoginFailure>) => {
Expand All @@ -41,7 +48,16 @@ const GoogleOAuthRedirect = (): JSX.Element => {

alert(error.response?.data.message ?? MESSAGE.LOGIN.UNEXPECTED_ERROR);

history.replace(PATH.LOGIN);
const afterLoginPath = getLocalStorageItem({
key: LOCAL_STORAGE_KEY.AFTER_LOGIN_PATH,
defaultValue: PATH.LOGIN,
});

history.replace(afterLoginPath);
},

onSettled: () => {
removeLocalStorageItem({ key: LOCAL_STORAGE_KEY.AFTER_LOGIN_PATH });
},
}
);
Expand Down
8 changes: 4 additions & 4 deletions frontend/src/utils/localStorage.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import THROW_ERROR from 'constants/throwError';

export const getLocalStorageItem = ({
export const getLocalStorageItem = <T = unknown>({
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

체프 T야? 농담이고 확장성 있게 만든 부분 아주 좋네요 👍 👍 👍

key,
defaultValue,
}: {
key: string;
defaultValue: unknown;
}): unknown => {
defaultValue: T;
}): T => {
const storedData = localStorage.getItem(key);

if (!storedData) {
return defaultValue;
}

try {
return JSON.parse(storedData);
return JSON.parse(storedData) as T;
} catch {
throw new Error(THROW_ERROR.NOT_JSON_FORMAT);
}
Expand Down
Loading