Skip to content

Commit

Permalink
[FE] Refactor/#593 모아보기와 단일조회페이지 분리 및 리팩토링 (#607)
Browse files Browse the repository at this point in the history
* refactor: isNotTabBoxShow에 따라 스와이퍼 버튼 위치 조정

* design: banner TabBox 라인 삭제

* refactor: 모아보기 기능 SelectedTopic 페이지에서 분리

* refactor: resizeMap 로직 훅으로 분리 및 재사용

* refactor: 네비게이션 하이라이트 기능 훅으로 분리 및 재사용

* refactor: tag 관련 로직 훅으로 분리 및 재사용

* refactor: 토스트 ui 변경

* refactor: seetogether 페이지 분리

* fix: 모아보기 페이지에서 모아보기 삭제 시 발생하던 오류 수정

* refactor: 불필요한 import 제거

* refactor: 네비게이션 하이라이트 topics에서 무효화 및 로그인 페이지 오류 수정

* fix: 회원일때는 url 상태로 토픽 조회 하도록 변경하여 새로고침 오류 수정

* fix: 모아보기를 모두 비운 후 핀이 남아있는 오류 수정

* fix: 모아보기 상태에서 토픽 이미지 수정이 선택한 토픽으로 되지 않는 오류 수정

* chore: swiper 제거 후 npm 배포 버전으로 import

* refactor: search 페이지 서스펜스 제거
  • Loading branch information
semnil5202 authored Oct 19, 2023
1 parent 4574c3a commit 4dce3c3
Show file tree
Hide file tree
Showing 29 changed files with 510 additions and 800 deletions.
1 change: 1 addition & 0 deletions frontend/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ module.exports = {
'no-unused-expressions': 'off',
'react/jsx-props-no-spreading': 'off',
'react/no-unused-prop-types': 'off',
'import/no-extraneous-dependencies': 'off',
},
settings: {
'import/resolver': {
Expand Down
11 changes: 11 additions & 0 deletions frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"license": "ISC",
"dependencies": {
"history": "^5.3.0",
"map-befine-swiper": "^0.8.2",
"msw-storybook-addon": "^1.8.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
17 changes: 16 additions & 1 deletion frontend/src/components/AddSeeTogether/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { deleteApi } from '../../apis/deleteApi';
import { getApi } from '../../apis/getApi';
import { postApi } from '../../apis/postApi';
import { SeeTogetherContext } from '../../context/SeeTogetherContext';
import useNavigator from '../../hooks/useNavigator';
import useToast from '../../hooks/useToast';
import { TopicCardProps } from '../../types/Topic';

interface AddSeeTogetherProps {
parentType: 'topicCard' | 'topicInfo';
isInAtlas: boolean;
id: number;
children: React.ReactNode;
Expand All @@ -17,6 +19,7 @@ interface AddSeeTogetherProps {
}

function AddSeeTogether({
parentType,
isInAtlas,
id,
children,
Expand All @@ -26,6 +29,7 @@ function AddSeeTogether({
const { showToast } = useToast();
const { seeTogetherTopics, setSeeTogetherTopics } =
useContext(SeeTogetherContext);
const { routePage } = useNavigator();

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

Expand All @@ -34,7 +38,7 @@ function AddSeeTogether({

try {
if (seeTogetherTopics && seeTogetherTopics.length === 7) {
showToast('warning', '모아보기는 7개까지만 가능합니다.');
showToast('error', '모아보기는 7개까지만 가능합니다.');
return;
}

Expand Down Expand Up @@ -69,11 +73,22 @@ function AddSeeTogether({
onClickAtlas();

showToast('info', '해당 지도를 모아보기에서 제외했습니다.');

if (parentType === 'topicInfo') routePageAfterSuccessToDelete(topics);
} catch {
showToast('error', '로그인 후 사용해주세요.');
}
};

const routePageAfterSuccessToDelete = (topics: TopicCardProps[]) => {
if (topics.length === 0) {
routePage(`/`);
return;
}

routePage(`/see-together/${topics.map((topic) => topic.id).join(',')}`);
};

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

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/Banner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { Swiper, Tab } from 'map-befine-swiper';
import styled from 'styled-components';

import BannerItemBoongWEBP from '../../assets/banner_boong.webp';
import BannerItemUsageWEBP from '../../assets/banner_usage.webp';
import useNavigator from '../../hooks/useNavigator';
import Box from '../common/Box';
import Swiper from '../common/Swiper';
import Tab from '../common/Swiper/Tab';

const USAGE_URL =
'https://yoondgu.notion.site/3e5b3c98c4814aa1bd5887104fee314e?pvs=4';
Expand All @@ -28,6 +27,7 @@ export default function Banner() {
height={400}
$simpleTab
$tabBoxPosition="bottom"
$isNotTabBoxShow
swipeable
swiper
autoplay
Expand Down
101 changes: 49 additions & 52 deletions frontend/src/components/PinImageContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import { Swiper, Tab } from 'map-befine-swiper';
import { useState } from 'react';
import styled from 'styled-components';

import { ImageProps } from '../../types/Pin';
import Image from '../common/Image';
import RemoveImageButton from '../../assets/remove_image_icon.svg';
import useDelete from '../../apiHooks/useDelete';
import RemoveImageButton from '../../assets/remove_image_icon.svg';
import { ImageModal, useModalContext } from '../../context/ImageModalContext';
import useToast from '../../hooks/useToast';
import { useModalContext, ImageModal } from '../../context/ImageModalContext';
import { useState } from 'react';
import { ImageProps } from '../../types/Pin';
import Button from '../common/Button';
import Image from '../common/Image';
import Space from '../common/Space';
import Swiper from '../common/Swiper';
import Tab from '../common/Swiper/Tab';

interface PinImageContainerProps {
images: ImageProps[];
Expand All @@ -19,7 +18,7 @@ interface PinImageContainerProps {
const NOT_FOUND_IMAGE =
'https://dr702blqc4x5d.cloudfront.net/2023-map-be-fine/icon/notFound_image.svg';

const PinImageContainer = ({ images, getPinData }: PinImageContainerProps) => {
function PinImageContainer({ images, getPinData }: PinImageContainerProps) {
const { fetchDelete } = useDelete();
const { showToast } = useToast();
const { isModalOpen, openModal, closeModal } = useModalContext();
Expand Down Expand Up @@ -85,52 +84,50 @@ const PinImageContainer = ({ images, getPinData }: PinImageContainerProps) => {

return (
<Wrapper>
{
<Swiper
as="ul"
width={330}
height={100}
$elementsOneTab={3}
swiper
swipeable
$isNotTabBoxShow
>
{images.map((image, index) => (
<Tab label={`${index}`} key={image.id}>
<ImageWrapper key={`image-${index}`}>
<div onClick={() => onImageOpen(image.imageUrl)}>
<Image
key={image.id}
height="100px"
width="100px"
src={image.imageUrl}
$errorDefaultSrc={NOT_FOUND_IMAGE}
/>
</div>
<RemoveImageIconWrapper
onClick={() => onRemovePinImage(image.id)}
>
<RemoveImageButton />
</RemoveImageIconWrapper>
</ImageWrapper>
</Tab>
))}
{isModalOpen && (
<ImageModal closeModalHandler={closeModal}>
<ModalImageWrapper>
<ModalImage src={modalImage} />
<Space size={3} />
<Button variant="custom" onClick={closeModal}>
닫기
</Button>
</ModalImageWrapper>
</ImageModal>
)}
</Swiper>
}
<Swiper
as="ul"
width={330}
height={100}
$elementsOneTab={3}
swiper
swipeable
$isNotTabBoxShow
>
{images.map((image, index) => (
<Tab label={`${index}`} key={image.id}>
<ImageWrapper key={`image-${index}`}>
<div onClick={() => onImageOpen(image.imageUrl)}>
<Image
key={image.id}
height="100px"
width="100px"
src={image.imageUrl}
$errorDefaultSrc={NOT_FOUND_IMAGE}
/>
</div>
<RemoveImageIconWrapper
onClick={() => onRemovePinImage(image.id)}
>
<RemoveImageButton />
</RemoveImageIconWrapper>
</ImageWrapper>
</Tab>
))}
{isModalOpen && (
<ImageModal closeModalHandler={closeModal}>
<ModalImageWrapper>
<ModalImage src={modalImage} />
<Space size={3} />
<Button variant="custom" onClick={closeModal}>
닫기
</Button>
</ModalImageWrapper>
</ImageModal>
)}
</Swiper>
</Wrapper>
);
};
}

const Wrapper = styled.div`
width: 330px;
Expand Down
15 changes: 12 additions & 3 deletions frontend/src/components/PinPreview/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { KeyboardEvent, useContext, useEffect, useRef, useState } from 'react';
import { useLocation } from 'react-router-dom';
import { styled } from 'styled-components';

import { TagContext } from '../../context/TagContext';
Expand All @@ -11,12 +12,13 @@ import Text from '../common/Text';

export interface PinPreviewProps {
idx: number;
pinId: number;
topicId: string;
urlTopicId: string;
pinTitle: string;
pinLocation: string;
pinInformation: string;
setSelectedPinId: React.Dispatch<React.SetStateAction<number | null>>;
pinId: number;
topicId: string;
setIsEditPinDetail: React.Dispatch<React.SetStateAction<boolean>>;
}

Expand All @@ -28,8 +30,10 @@ function PinPreview({
setSelectedPinId,
pinId,
topicId,
urlTopicId,
setIsEditPinDetail,
}: PinPreviewProps) {
const { pathname } = useLocation();
const { routePage } = useNavigator();
const { tags, setTags } = useContext(TagContext);
const [announceText, setAnnounceText] = useState<string>('토픽 핀 선택');
Expand Down Expand Up @@ -63,7 +67,12 @@ function PinPreview({
setSelectedPinId(pinId);
setIsEditPinDetail(false);

routePage(`/topics/${topicId}?pinDetail=${pinId}`);
if (pathname.split('/')[1] === 'topics') {
routePage(`/topics/${urlTopicId}?pinDetail=${pinId}`);
return;
}

routePage(`/see-together/${urlTopicId}?pinDetail=${pinId}`);
};

const onInputKeyDown = (e: KeyboardEvent<HTMLInputElement>) => {
Expand Down
7 changes: 5 additions & 2 deletions frontend/src/components/PinsOfTopic/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import PinPreview from '../PinPreview';
import TopicInfo from '../TopicInfo';

interface PinsOfTopicProps {
urlTopicId?: string;
topicId: string;
topicDetail: TopicDetailProps;
setSelectedPinId: React.Dispatch<React.SetStateAction<number | null>>;
Expand All @@ -13,6 +14,7 @@ interface PinsOfTopicProps {
}

function PinsOfTopic({
urlTopicId,
topicId,
topicDetail,
setSelectedPinId,
Expand All @@ -38,13 +40,14 @@ function PinsOfTopic({
{topicDetail.pins.map((pin, idx) => (
<li key={pin.id}>
<PinPreview
urlTopicId={urlTopicId || topicId}
idx={idx}
pinId={Number(pin.id)}
topicId={topicId}
pinTitle={pin.name}
pinLocation={pin.address}
pinInformation={pin.description}
setSelectedPinId={setSelectedPinId}
pinId={Number(pin.id)}
topicId={topicId}
setIsEditPinDetail={setIsEditPinDetail}
/>
</li>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/TopicCard/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ function TopicCard({
{cardType === 'default' && getTopicsFromServer && (
<ButtonWrapper>
<AddSeeTogether
parentType="topicCard"
isInAtlas={isInAtlas}
onClickAtlas={onClickIsInAtlas}
id={id}
Expand Down
3 changes: 1 addition & 2 deletions frontend/src/components/TopicCardContainer/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Swiper, Tab } from 'map-befine-swiper';
import { useEffect, useState } from 'react';
import { styled } from 'styled-components';

Expand All @@ -7,8 +8,6 @@ import { TopicCardProps } from '../../types/Topic';
import Box from '../common/Box';
import Flex from '../common/Flex';
import Space from '../common/Space';
import Swiper from '../common/Swiper';
import Tab from '../common/Swiper/Tab';
import Text from '../common/Text';
import MediaText from '../common/Text/MediaText';
import TopicCard from '../TopicCard';
Expand Down
Loading

0 comments on commit 4dce3c3

Please sign in to comment.