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

[FE] refactor/#450 모아보기 기능 비회원도 가능하도록 수정 #516

Merged
merged 14 commits into from
Oct 6, 2023
Merged
Show file tree
Hide file tree
Changes from 4 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
26 changes: 24 additions & 2 deletions frontend/src/components/AddSeeTogether/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,22 @@ interface AddSeeTogetherProps {
id: number;
children: React.ReactNode;
getTopicsFromServer: () => void;
onClickAtlas: () => void;
}

const AddSeeTogether = ({
isInAtlas,
id,
children,
getTopicsFromServer,
onClickAtlas,
}: AddSeeTogetherProps) => {
const { showToast } = useToast();
const { seeTogetherTopics, setSeeTogetherTopics } =
useContext(SeeTogetherContext);

const accessToken = localStorage.getItem('userToken');

const addSeeTogetherList = async (e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();

Expand All @@ -37,10 +41,11 @@ const AddSeeTogether = ({

const topics = await getApi<TopicCardProps[]>('/members/my/atlas');

setSeeTogetherTopics(topics);
setSeeTogetherTopics(topics.map((topic) => topic.id));

// TODO: 모아보기 페이지에서는 GET /members/my/atlas 두 번 됨
getTopicsFromServer();
onClickAtlas();

showToast('info', '모아보기에 추가했습니다.');
} catch {
Expand All @@ -56,17 +61,34 @@ const AddSeeTogether = ({

const topics = await getApi<TopicCardProps[]>('/members/my/atlas');

setSeeTogetherTopics(topics);
setSeeTogetherTopics(topics.map((topic) => topic.id));

// TODO: 모아보기 페이지에서는 GET /members/my/atlas 두 번 됨
getTopicsFromServer();
onClickAtlas();

showToast('info', '해당 지도를 모아보기에서 제외했습니다.');
} catch {
showToast('error', '로그인 후 사용해주세요.');
}
};

const onChangeIsInAtlas = (e: React.MouseEvent<HTMLDivElement>) => {
e.stopPropagation();

if (seeTogetherTopics?.includes(id))
setSeeTogetherTopics(
seeTogetherTopics.filter((topicId) => topicId !== id),
);
else setSeeTogetherTopics((prev) => [...prev, id]);

onClickAtlas();
};

if (accessToken === null) {
return <Wrapper onClick={onChangeIsInAtlas}>{children}</Wrapper>;
}

return (
<Wrapper onClick={isInAtlas ? deleteSeeTogether : addSeeTogetherList}>
{children}
Expand Down
231 changes: 162 additions & 69 deletions frontend/src/components/Layout/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import useNavigator from '../../hooks/useNavigator';
import Flex from '../common/Flex';
Copy link
Collaborator

Choose a reason for hiding this comment

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

여기 Navbar.tsx전체 반복되는 부분 map으로 묶어서 리팩토링 해둔거 머지된거같은데 지금 패트릭 로컬에 반영 안되서 다시 원상복귀 되는거 같아요. 혹시 일부러 되돌리시는건가요??

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아이고 충돌 해결하면서 되돌아간 것 같아요! 수정하도록 하겠습니다!!

import Button from '../common/Button';
import Space from '../common/Space';
import Text from '../common/Text';
import Home from '../../assets/nav_home.svg';
import SeeTogether from '../../assets/nav_seeTogether.svg';
import Favorite from '../../assets/nav_favorite.svg';
Expand All @@ -15,74 +16,155 @@ import FocusFavorite from '../../assets/nav_favorite_focus.svg';
import FocusAddMapOrPin from '../../assets/nav_addMapOrPin_focus.svg';
import FocusProfile from '../../assets/nav_profile_focus.svg';
import Modal from '../Modal';
import {
NavbarHighlightKeys,
NavbarHighlightsContext,
} from '../../context/NavbarHighlightsContext';
import NavbarItem from './NavbarItem';
import { ModalContext } from '../../context/ModalContext';
import { NavbarHighlightsContext } from '../../context/NavbarHighlightsContext';
import { useParams } from 'react-router-dom';
import SeeTogetherCounter from '../SeeTogetherCounter';
import useKeyDown from '../../hooks/useKeyDown';
import { SeeTogetherContext } from '../../context/SeeTogetherContext';

interface NavBarProps {
$layoutWidth: '100vw' | '372px';
}

interface NavbarItemProps {
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 부분 로직 왜 다시 옛날 로직으로 돌아갔나요??

머지 충돌이 잘못 해결된건가용?

Copy link
Collaborator

Choose a reason for hiding this comment

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

이미 세인이 커멘트 남겼네요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

충돌 해결하다가 되돌아간 것 같아요!! 바로 수정하도록 하겠습니다~!!

key: NavbarHighlightKeys;
label: string;
icon: React.FunctionComponent;
focusIcon: React.FunctionComponent;
}

const NAV_ITEMS: NavbarItemProps[] = [
{ key: 'home', label: '홈', icon: Home, focusIcon: FocusHome },
{
key: 'seeTogether',
label: '모아보기',
icon: SeeTogether,
focusIcon: FocusSeeTogether,
},
{
key: 'addMapOrPin',
label: '추가하기',
icon: AddMapOrPin,
focusIcon: FocusAddMapOrPin,
},
{
key: 'favorite',
label: '즐겨찾기',
icon: Favorite,
focusIcon: FocusFavorite,
},
{
key: 'profile',
label: '내 정보',
icon: Profile,
focusIcon: FocusProfile,
},
];

const Navbar = ({ $layoutWidth }: NavBarProps) => {
const { routingHandlers } = useNavigator();
const { routePage } = useNavigator();
const { topicId } = useParams();
const { openModal, closeModal } = useContext(ModalContext);
const { navbarHighlights } = useContext(NavbarHighlightsContext);
const { elementRef: firstElement, onElementKeyDown: firstKeyDown } =
useKeyDown<HTMLDivElement>();
const { elementRef: secondElement, onElementKeyDown: secondKeyDown } =
useKeyDown<HTMLDivElement>();
const { elementRef: thirdElement, onElementKeyDown: thirdKeyDown } =
useKeyDown<HTMLDivElement>();
const { elementRef: fourElement, onElementKeyDown: fourKeyDown } =
useKeyDown<HTMLDivElement>();
const { elementRef: FifthElement, onElementKeyDown: FifthKeyDown } =
useKeyDown<HTMLDivElement>();
const { seeTogetherTopics } =
useContext(SeeTogetherContext);

const goToHome = () => {
routePage('/');
};

const goToSeeTogether = () => {
routePage(`/topics/${seeTogetherTopics?.length===0 ? -1 : seeTogetherTopics?.join(',')}`);
Copy link
Collaborator

Choose a reason for hiding this comment

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

프리티어 한 번 확인부탁드려용

자동저장 또 요놈인가?! 🤔

Copy link
Collaborator Author

@GC-Park GC-Park Oct 4, 2023

Choose a reason for hiding this comment

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

허헣.. 😉 NavBar 되돌리면서 useNavigator 파일에 옮긴 후 저장 꾹 눌렀습니다~!

};

const onClickAddMapOrPin = () => {
openModal('addMapOrPin');
};

const goToFavorite = () => {
routePage('/favorite');
};

const goToProfile = () => {
routePage('/my-page');
};

const goToNewTopic = () => {
routePage('/new-topic');
closeModal('addMapOrPin');
};

const goToNewPin = () => {
routePage('/new-pin', topicId);
closeModal('addMapOrPin');
};

return (
<>
<Wrapper
$isAddPage={navbarHighlights.addMapOrPin}
<Wrapper
$isAddPage={navbarHighlights.addMapOrPin}
$layoutWidth={$layoutWidth}
>
<IconWrapper
$layoutWidth={$layoutWidth}
onClick={goToHome}
tabIndex={10}
ref={firstElement}
onKeyDown={firstKeyDown}
>
{navbarHighlights.home ? <FocusHome /> : <Home />}
<Text
color={navbarHighlights.home ? 'primary' : 'darkGray'}
$fontSize="extraSmall"
$fontWeight="normal"
>
</Text>
</IconWrapper>

<IconWrapper
$layoutWidth={$layoutWidth}
onClick={goToSeeTogether}
tabIndex={10}
ref={secondElement}
onKeyDown={secondKeyDown}
>
{navbarHighlights.seeTogether ? <FocusSeeTogether /> : <SeeTogether />}
<Text
color={navbarHighlights.seeTogether ? 'primary' : 'darkGray'}
$fontSize="extraSmall"
$fontWeight="normal"
>
모아보기
</Text>
<SeeTogetherCounter />
</IconWrapper>

<IconWrapper
$layoutWidth={$layoutWidth}
onClick={onClickAddMapOrPin}
tabIndex={10}
ref={thirdElement}
onKeyDown={thirdKeyDown}
>
{navbarHighlights.addMapOrPin ? <FocusAddMapOrPin /> : <AddMapOrPin />}
<Text
color={navbarHighlights.addMapOrPin ? 'primary' : 'darkGray'}
$fontSize="extraSmall"
$fontWeight="normal"
>
추가하기
</Text>
</IconWrapper>

<IconWrapper
$layoutWidth={$layoutWidth}
onClick={goToFavorite}
tabIndex={11}
ref={fourElement}
onKeyDown={fourKeyDown}
>
{NAV_ITEMS.map((item) => {
return (
<NavbarItem
key={item.key}
label={item.label}
icon={item.icon}
focusIcon={item.focusIcon}
isHighlighted={navbarHighlights[item.key]}
onClick={() => routingHandlers[item.key]()}
$layoutWidth={$layoutWidth}
/>
);
})}
</Wrapper>
{navbarHighlights.favorite ? <FocusFavorite /> : <Favorite />}
<Text
color={navbarHighlights.favorite ? 'primary' : 'darkGray'}
$fontSize="extraSmall"
$fontWeight="normal"
>
즐겨찾기
</Text>
</IconWrapper>

<IconWrapper
$layoutWidth={$layoutWidth}
onClick={goToProfile}
tabIndex={11}
ref={FifthElement}
onKeyDown={FifthKeyDown}
>
{navbarHighlights.profile ? <FocusProfile /> : <Profile />}
<Text
color={navbarHighlights.profile ? 'primary' : 'darkGray'}
$fontSize="extraSmall"
$fontWeight="normal"
>
내 정보
</Text>
</IconWrapper>

<Modal
modalKey="addMapOrPin"
Expand All @@ -94,24 +176,16 @@ const Navbar = ({ $layoutWidth }: NavBarProps) => {
left={$layoutWidth === '100vw' ? '' : `${372 / 2}px`}
>
<Flex $justifyContent="center" width="100%">
<RouteButton
variant="primary"
onClick={routingHandlers['newTopic']}
tabIndex={10}
>
<RouteButton variant="primary" onClick={goToNewTopic} tabIndex={10}>
지도 추가하기
</RouteButton>
<Space size={4} />
<RouteButton
variant="primary"
onClick={routingHandlers['newPin']}
tabIndex={10}
>
<RouteButton variant="primary" onClick={goToNewPin} tabIndex={10}>
핀 추가하기
</RouteButton>
</Flex>
</Modal>
</>
</Wrapper>
);
};

Expand Down Expand Up @@ -141,6 +215,25 @@ const Wrapper = styled.nav<{
}
`;

const IconWrapper = styled.div<{ $layoutWidth: '100vw' | '372px' }>`
position: relative;
display: flex;
flex-direction: column;
align-items: center;
width: 52px;
cursor: pointer;
margin-right: ${({ $layoutWidth }) =>
$layoutWidth === '100vw' ? '48px' : '0'};

&:last-of-type {
margin-right: 0;
}

@media (max-width: 1076px) {
margin-right: 0;
}
`;

const RouteButton = styled(Button)`
box-shadow: 2px 4px 4px rgba(0, 0, 0, 0.5);
`;
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/SeeTogetherCounter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const SeeTogetherCounter = () => {
if (!userToken) return;

const topics = await getApi<TopicCardProps[]>('/members/my/atlas');
setSeeTogetherTopics(topics);
setSeeTogetherTopics(topics.map((topic) => topic.id));
} catch {
showToast(
'error',
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/components/TopicCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Text from '../common/Text';
import useNavigator from '../../hooks/useNavigator';
import Box from '../common/Box';
import Image from '../common/Image';
import { SyntheticEvent, useContext } from 'react';
import { SyntheticEvent, useContext, useState } from 'react';
import Space from '../common/Space';
import Flex from '../common/Flex';
import FavoriteSVG from '../../assets/favoriteBtn_filled.svg';
Expand Down Expand Up @@ -47,6 +47,7 @@ const TopicCard = ({
const { routePage } = useNavigator();
const { closeModal } = useContext(ModalContext);
const { elementRef, onElementKeyDown } = useKeyDown<HTMLLIElement>();
const [atlas, setAtlas] = useState<boolean>(isInAtlas);
Copy link
Collaborator

Choose a reason for hiding this comment

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

비회원을 위한 atlas임을 알려주는 네이밍이면 좋겠어요. 현재 isInAtlas도 있다보니 혼동이 조금 예상되서요.

isInNonMemberAtlas 이런 느낌은 어떤가요? boolean 값이다보니 is 프리픽스도 필요할것 같군요.

Copy link
Collaborator

Choose a reason for hiding this comment

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

AddSeeTogether에서부터 뭔가 하고 찾아 내려왔는데 세인 커멘트처럼 비회원용인지 바로 알 수 있으면 좋을것 같아요

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

너무 좋은 제안 바로 받아 반영하도록 하겠습니다! 👍


const goToSelectedTopic = () => {
routePage(`/topics/${id}`, [id]);
Expand All @@ -60,6 +61,9 @@ const TopicCard = ({
closeModal('newPin');
};

const onChangeIsInAtlas = () => {
setAtlas(!atlas);
};
return (
<Wrapper
data-cy="topic-card"
Expand Down Expand Up @@ -139,10 +143,11 @@ const TopicCard = ({
<ButtonWrapper>
<AddSeeTogether
isInAtlas={isInAtlas}
onClickAtlas={onChangeIsInAtlas}
Copy link
Collaborator

Choose a reason for hiding this comment

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

onChange 기능을 하는 함수가 onClick 으로 네이밍이 변경이 되면서 처음 읽을 때 기능이 헷갈리는 것 같아요.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

아 그럴 수도 있겠군요!!! onClick으로 통일하도록 하겠습니다 굿굿!

id={id}
getTopicsFromServer={getTopicsFromServer}
>
{isInAtlas ? <SeeTogetherSVG /> : <SeeTogetherNotFilledSVG />}
{atlas ? <SeeTogetherSVG /> : <SeeTogetherNotFilledSVG />}
Copy link
Collaborator

Choose a reason for hiding this comment

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

이 곳도 accessToken 여부에 따라서 UI 렌더링을 달리 해야하지 않을까 했는데 post 요청하는 로직 부분이 try catch 문으로 감싸져 있어서 괜찮을 것 같군요.

post 에러가 발생하면 UI 업데이트가 발생하지 않겠네용. 우선은 이렇게 진행해도 괜찮을 것 같습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

와우 이 부분까지 생각하지 못하고 코드 작성했던 것 같은데 굿!

누군가가 추상화를 잘 해주었기에 예방할 수 있었던거죠 😉

</AddSeeTogether>
<AddFavorite
isBookmarked={isBookmarked}
Expand Down
Loading
Loading