Skip to content
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
11 changes: 11 additions & 0 deletions src/api/member/getAuthRedirect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { axiosInstance } from '@api/axiosInstance';

export const getAuthRedirect = async ({
oauthProvider,
}: {
oauthProvider: 'KAKAO';
}) => {
const { data } = await axiosInstance.get(`/auth/${oauthProvider}`, {});

return data;
};
4 changes: 2 additions & 2 deletions src/components/Header/Header.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ export const Title = styled.div`
text-align: center;
`;

export const RightSideContainer = styled.div`
export const RightSideContainer = styled.div<{ isLogin?: boolean }>`
width: 5.5rem;
${({ theme }) => theme.STYLES.FLEX_JUSTIFY_CENTER}
justify-content: space-between;
justify-content:${({ isLogin }) => (isLogin ? 'flex-end' : 'space-between')};

&.invisible {
visibility: hidden;
Expand Down
83 changes: 65 additions & 18 deletions src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { useNavigate } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';

import { Button } from '@components/shared/Button';

import { theme } from '@styles/theme';

import bellIcon from '@assets/bell.svg';
import leftArrowIcon from '@assets/leftArrow.svg';
Expand Down Expand Up @@ -52,6 +57,28 @@ export const Header = ({
navigate('/all-services');
};

const handleLoginClick = () => {
navigate('/login');
};

const url = useParams();
const [isLogin, setIsLogin] = useState(false);
useEffect(() => {
const loginInfo = localStorage.getItem('LOGIN_INFO');

if (!loginInfo) {
setIsLogin(false);
} else {
const { refreshToken } = JSON.parse(loginInfo);

if (!refreshToken) {
setIsLogin(false);
} else {
setIsLogin(true);
}
Comment on lines +72 to +78
Copy link
Member

Choose a reason for hiding this comment

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

여기서 refreshToken으로 검증하는 이유가 있나요?

}
}, [url]);

return (
<>
<HeaderBackground>
Expand All @@ -70,23 +97,43 @@ export const Header = ({
</BackwardWrapper>
)}
{title === '' ? <></> : <Title>{title}</Title>}
<RightSideContainer className={isRightContainer ? '' : 'invisible'}>
<RightSideIconWrapper>
<RightSideIcon onClick={() => handleSearchIconClick()}>
<img src={searchIcon} alt="" />
</RightSideIcon>
</RightSideIconWrapper>
<RightSideIconWrapper>
<RightSideIcon onClick={() => handleBellIconClick()}>
<img src={bellIcon} alt="" />
</RightSideIcon>
</RightSideIconWrapper>
<RightSideIconWrapper>
<RightSideIcon onClick={() => handleProfileIconClick()}>
<img src={profileIcon} alt="" />
</RightSideIcon>
</RightSideIconWrapper>
</RightSideContainer>
{isLogin ? (
<RightSideContainer className={isRightContainer ? '' : 'invisible'}>
<RightSideIconWrapper>
<RightSideIcon onClick={() => handleSearchIconClick()}>
<img src={searchIcon} alt="" />
</RightSideIcon>
</RightSideIconWrapper>
<RightSideIconWrapper>
<RightSideIcon onClick={() => handleBellIconClick()}>
<img src={bellIcon} alt="" />
</RightSideIcon>
</RightSideIconWrapper>
<RightSideIconWrapper>
<RightSideIcon onClick={() => handleProfileIconClick()}>
<img src={profileIcon} alt="" />
</RightSideIcon>
</RightSideIconWrapper>
</RightSideContainer>
) : (
<RightSideContainer
className={isRightContainer ? '' : 'invisible'}
isLogin={true}
>
<Button
width="60px"
height="24px"
fontWeight={300}
textColor={theme.PALETTE.GRAY_600}
fontSize={theme.FONT_SIZE.XS}
backgroundColor="white"
borderColor={theme.PALETTE.GRAY_600}
onClick={handleLoginClick}
>
로그인
</Button>
</RightSideContainer>
)}
</HeaderContainer>
</HeaderBackground>
</>
Expand Down
25 changes: 16 additions & 9 deletions src/components/shared/ToggleButton/ToggleButtons.hook.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,25 @@
import { useState } from 'react';

type ToggleButtonsProps = {
initialValues?: string[];
onToggle: (value: string[]) => void;
type ToggleButtonsProps<T> = {
initialValues?: T[];
onToggle: (value: T[]) => void;
isMultipleSelect: boolean;
};
export const useToggleButtons = ({
initialValues = [],

export const useToggleButtons = <T>({
initialValues = [] as T[],
isMultipleSelect,
onToggle,
}: ToggleButtonsProps) => {
const [selectedItems, setSelectedItems] = useState<string[]>(initialValues);
}: ToggleButtonsProps<T>) => {
const [selectedItems, setSelectedItems] = useState<T[]>(initialValues);

const handleToggle = (value: T) => {
if (!value) {
setSelectedItems([]);
onToggle([]);
return;
}

const handleToggle = (value: string) => {
const updatedItems = isMultipleSelect
? selectedItems.includes(value)
? selectedItems.filter((item) => item !== value)
Expand All @@ -23,5 +30,5 @@ export const useToggleButtons = ({
onToggle(updatedItems);
};

return { handleToggle, selectedItems };
return { handleToggle, selectedItems, setSelectedItems };
};
9 changes: 9 additions & 0 deletions src/consts/positions.ts
Original file line number Diff line number Diff line change
@@ -1 +1,10 @@
export const POSITIONS = ['C', 'PF', 'SF', 'PG', 'SG', '없음'];

export const POSITIONS_BUTTON = {
C: 'C',
PF: 'PF',
SF: 'SF',
PG: 'PG',
SG: 'SG',
없음: '',
};
6 changes: 4 additions & 2 deletions src/hooks/mutations/useRegistrationMutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ export const useRegistrationMutation = () => {
const mutation = useMutation({
mutationFn: postRegistration,
onSuccess: (data) => {
console.log('useRegistrationMutation Success!');
// TODO : 쿠키와 사용자 정보에 대한 처리 필요
localStorage.setItem('LOGIN_INFO', JSON.stringify(data));
localStorage.setItem(
'ACCESS_TOKEN',
JSON.stringify({ accessToken: data.accessToken })
);
},
onError: () => {
console.log('useRegistrationMutation Error!');
Expand Down
25 changes: 2 additions & 23 deletions src/pages/LoginPage/LoginPage.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
import { useNavigate } from 'react-router-dom';

import { Header } from '@components/Header';

import { useLoginQuery } from '@hooks/queries/useLoginQuery';

import KAKAO_LOGIN_SRC from '@assets/kakao_login_large_wide.png';
import LOGO_SRC from '@assets/logoSvg.svg';

Expand All @@ -19,27 +15,10 @@ const LOGIN_MAIN =
'https://github.com/Java-and-Script/pickple-front/assets/87280835/1134921d-2e91-4b47-b99a-4095c91f0a6d';

export const LoginPage = () => {
const navigate = useNavigate();

const { refetch } = useLoginQuery({
oauthProvider: 'KAKAO',
authCode: '23',
});
const BASE_URL = import.meta.env.VITE_BASE_URL;

const onClickKakaoLogin = async () => {
const { data } = await refetch();

if (!data) {
return;
}

localStorage.setItem('LOGIN_INFO', JSON.stringify(data));
localStorage.setItem(
'ACCESS_TOKEN',
JSON.stringify({ accessToken: data.accessToken })
);

navigate(-1);
window.location.href = `${BASE_URL}/auth/kakao`;
};

return (
Expand Down
50 changes: 50 additions & 0 deletions src/pages/RedirectPage/RedirectPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { useCallback, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';

import { useLoginQuery } from '@hooks/queries/useLoginQuery';

import { Authenticated, Registration } from '@type/models';

export const RedirectPage = () => {
const navigate = useNavigate();

const authCode = new URL(window.location.href).searchParams.get('code');

const { refetch } = useLoginQuery({
oauthProvider: 'KAKAO',
authCode: authCode!,
});
console.log('authCode', authCode);

const isAuthenticated = (target: Authenticated | Registration) => {
const result = target.refreshToken === null;

return !result;
};

const getLoginInfo = useCallback(async () => {
const { data } = await refetch();

if (!data) {
return;
}

localStorage.setItem('LOGIN_INFO', JSON.stringify(data));
localStorage.setItem(
'ACCESS_TOKEN',
JSON.stringify({ accessToken: data.accessToken })
);

if (isAuthenticated(data)) {
navigate('/');
} else {
navigate('/register');
}
}, [navigate, refetch]);

useEffect(() => {
getLoginInfo();
}, [getLoginInfo]);

return <div>로그인 중입니다.</div>;
};
1 change: 1 addition & 0 deletions src/pages/RedirectPage/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './RedirectPage';
44 changes: 40 additions & 4 deletions src/pages/RegisterPage/RegisterPage.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';

import { LogoImage } from '@pages/LoginPage/LoginPage.style';

Expand All @@ -11,10 +12,15 @@ import {
useToggleButtons,
} from '@components/shared/ToggleButton';

import { useRegistrationMutation } from '@hooks/mutations/useRegistrationMutation';

import { theme } from '@styles/theme';

import { Position } from '@type/models/Position';

import { SEOUL } from '@consts/location';
import { POSITIONS } from '@consts/positions';
import { PATH_NAME } from '@consts/pathName';
import { POSITIONS_BUTTON } from '@consts/positions';

import LOGO_SRC from '@assets/logoSvg.svg';

Expand All @@ -27,6 +33,13 @@ import {
} from './RegisterPage.style';

export const RegisterPage = () => {
const navigate = useNavigate();
const json = localStorage.getItem('LOGIN_INFO');
if (!json) {
throw new Error('no login info available');
}
const userInfo = JSON.parse(json);

const [selectedLocation, setSelectedLocation] = useState<string[]>();
const [selectedPosition, setSelectedPosition] = useState<string[]>();

Expand All @@ -46,6 +59,28 @@ export const RegisterPage = () => {
isMultipleSelect: true,
});

const { mutate } = useRegistrationMutation();

const submitRegistration = () => {
const { email, nickname, profileImageUrl, oauthId, oauthProvider } =
userInfo;
if (!selectedLocation) {
window.alert('지역을 선택해주세요');
return;
}
mutate({
email,
nickname,
profileImageUrl,
positions: selectedPosition as Position[],
addressDepth1: '서울시',
addressDepth2: selectedLocation[0],
oauthId,
oauthProvider,
});

navigate(PATH_NAME.MAIN);
};
return (
<RegisterContainer>
<Header isLogo={false} title="정보 입력" isRightContainer={false} />
Expand Down Expand Up @@ -74,10 +109,11 @@ export const RegisterPage = () => {
주 포지션
</Text>
<PositionButtonGroup>
{POSITIONS.map((position) => (
{Object.entries(POSITIONS_BUTTON).map(([position, value]) => (
<ToggleButton
key={position}
value={position}
value={value}
label={position}
isActive={selectedPositions.includes(position)}
onToggle={handleTogglePosition}
/>
Expand All @@ -89,7 +125,7 @@ export const RegisterPage = () => {
width="100%"
height="3.125rem"
{...theme.BUTTON_PROPS.LARGE_RED_OUTLINED_BUTTON_PROPS}
onClick={() => console.log(selectedLocation, selectedPosition)}
onClick={submitRegistration}
>
입력 완료
</Button>
Expand Down
5 changes: 5 additions & 0 deletions src/routes/router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Layout } from '@pages/Layout';
import { LoginPage } from '@pages/LoginPage';
import { MainPage } from '@pages/MainPage';
import { ProfilePage } from '@pages/ProfilePage';
import { RedirectPage } from '@pages/RedirectPage';
import { RegisterPage } from '@pages/RegisterPage';
import { ReviewPage } from '@pages/ReviewPage';

Expand Down Expand Up @@ -125,6 +126,10 @@ export const router = createBrowserRouter([
path: 'message',
element: <h3>message</h3>,
},
{
path: 'auth/kakao/callback',
element: <RedirectPage />,
},
],
},
]);