From fa1947894c20561ca67a6e9bd5bbcdb851717daa Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 18 Oct 2023 20:44:55 +0900 Subject: [PATCH 01/16] =?UTF-8?q?refactor:=20isNotTabBoxShow=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=9D=BC=20=EC=8A=A4=EC=99=80=EC=9D=B4=ED=8D=BC=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=9C=84=EC=B9=98=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/common/Swiper/index.tsx | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/common/Swiper/index.tsx b/frontend/src/components/common/Swiper/index.tsx index afa8a0055..ff61c4fe4 100644 --- a/frontend/src/components/common/Swiper/index.tsx +++ b/frontend/src/components/common/Swiper/index.tsx @@ -158,10 +158,16 @@ function Swiper({ {swiper && ( <> - + - + @@ -332,24 +338,36 @@ const TabBox = styled.button<{ `} `; -const SwiperButtonLeftWrapper = styled.div<{ $tabBoxHeight: number }>` +const SwiperButtonLeftWrapper = styled.div<{ + $tabBoxHeight: number; + $isNotTabBoxShow: boolean; +}>` position: absolute; - top: ${({ $tabBoxHeight }) => `calc(50% + ${$tabBoxHeight}px / 2)`}; + top: ${({ $tabBoxHeight, $isNotTabBoxShow }) => + $isNotTabBoxShow ? `50%` : `calc(50% + ${$tabBoxHeight}px / 2)`}; left: 1%; - transform: ${({ $tabBoxHeight }) => - `translateY(calc(-50% - ${$tabBoxHeight}px))`}; + transform: ${({ $tabBoxHeight, $isNotTabBoxShow }) => + $isNotTabBoxShow + ? `translateY(-50%)` + : `translateY(calc(-50% - ${$tabBoxHeight}px))`}; @media (max-width: 744px) { display: none; } `; -const SwiperButtonRightWrapper = styled.div<{ $tabBoxHeight: number }>` +const SwiperButtonRightWrapper = styled.div<{ + $tabBoxHeight: number; + $isNotTabBoxShow: boolean; +}>` position: absolute; - top: ${({ $tabBoxHeight }) => `calc(50% + ${$tabBoxHeight}px / 2)`}; + top: ${({ $tabBoxHeight, $isNotTabBoxShow }) => + $isNotTabBoxShow ? `50%` : `calc(50% + ${$tabBoxHeight}px / 2)`}; right: 1%; - transform: ${({ $tabBoxHeight }) => - `translateY(calc(-50% - ${$tabBoxHeight}px))`}; + transform: ${({ $tabBoxHeight, $isNotTabBoxShow }) => + $isNotTabBoxShow + ? `translateY(-50%)` + : `translateY(calc(-50% - ${$tabBoxHeight}px))`}; @media (max-width: 744px) { display: none; From 4dd35e44187d4fb52b91954a87221bf77ee32605 Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 18 Oct 2023 20:45:38 +0900 Subject: [PATCH 02/16] =?UTF-8?q?design:=20banner=20TabBox=20=EB=9D=BC?= =?UTF-8?q?=EC=9D=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/Banner/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/src/components/Banner/index.tsx b/frontend/src/components/Banner/index.tsx index 833862195..dce5428a6 100644 --- a/frontend/src/components/Banner/index.tsx +++ b/frontend/src/components/Banner/index.tsx @@ -28,6 +28,7 @@ export default function Banner() { height={400} $simpleTab $tabBoxPosition="bottom" + $isNotTabBoxShow swipeable swiper autoplay From 16b09a5fae0dc8e35e86b87c71f46f38327c4ddd Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 18 Oct 2023 21:54:51 +0900 Subject: [PATCH 03/16] =?UTF-8?q?refactor:=20=EB=AA=A8=EC=95=84=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20=EA=B8=B0=EB=8A=A5=20SelectedTopic=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SelectedTopic.tsx | 131 ++++++--------------------- 1 file changed, 27 insertions(+), 104 deletions(-) diff --git a/frontend/src/pages/SelectedTopic.tsx b/frontend/src/pages/SelectedTopic.tsx index a640b11cc..4522439ab 100644 --- a/frontend/src/pages/SelectedTopic.tsx +++ b/frontend/src/pages/SelectedTopic.tsx @@ -1,29 +1,16 @@ -import { - Fragment, - lazy, - Suspense, - useContext, - useEffect, - useState, -} from 'react'; +import { lazy, Suspense, useContext, useEffect, useState } from 'react'; import { useParams, useSearchParams } from 'react-router-dom'; import { styled } from 'styled-components'; import { getApi } from '../apis/getApi'; -import SeeTogetherNotFilledSVG from '../assets/seeTogetherBtn_notFilled.svg'; -import Button from '../components/common/Button'; -import Flex from '../components/common/Flex'; import Space from '../components/common/Space'; -import Text from '../components/common/Text'; import PullPin from '../components/PullPin'; import PinsOfTopicSkeleton from '../components/Skeletons/PinsOfTopicSkeleton'; import { LAYOUT_PADDING, SIDEBAR } from '../constants'; import { CoordinatesContext } from '../context/CoordinatesContext'; -import { SeeTogetherContext } from '../context/SeeTogetherContext'; import { TagContext } from '../context/TagContext'; import useNavigator from '../hooks/useNavigator'; import useSetLayoutWidth from '../hooks/useSetLayoutWidth'; -import useSetNavbarHighlight from '../hooks/useSetNavbarHighlight'; import useMapStore from '../store/mapInstance'; import { PinProps } from '../types/Pin'; import { TopicDetailProps } from '../types/Topic'; @@ -39,9 +26,7 @@ const getAvailableHeight = () => window.innerHeight; function SelectedTopic() { const { topicId } = useParams(); const [searchParams, _] = useSearchParams(); - const [topicDetails, setTopicDetails] = useState( - null, - ); + const [topicDetail, setTopicDetail] = useState(null); const [selectedPinId, setSelectedPinId] = useState(null); const [isOpen, setIsOpen] = useState(true); const [isEditPinDetail, setIsEditPinDetail] = useState(false); @@ -49,11 +34,6 @@ function SelectedTopic() { const { setCoordinates } = useContext(CoordinatesContext); const { tags, setTags } = useContext(TagContext); const { width } = useSetLayoutWidth(SIDEBAR); - const { navbarHighlights: __ } = useSetNavbarHighlight( - topicId && topicId.split(',').length > 1 ? 'seeTogether' : 'home', - ); - const { seeTogetherTopics, setSeeTogetherTopics } = - useContext(SeeTogetherContext); const { mapInstance } = useMapStore((state) => state); const resizeMap = () => { @@ -62,54 +42,35 @@ function SelectedTopic() { mapInstance.resize(getAvailableWidth(372), getAvailableHeight()); }; - const goToHome = () => { - routePage('/'); - }; - const getAndSetDataFromServer = async () => { - if (topicId === '-1') return; - - const data = await getApi(`/topics/ids?ids=${topicId}`); - - const topicHashmap = new Map([]); + const topicInArray = await getApi( + `/topics/ids?ids=${topicId}`, + ); + const topic = topicInArray[0]; - setTopicDetails(data); + setTopicDetail(topic); // 각 topic의 pin들의 좌표를 가져옴 const newCoordinates: any = []; - data.forEach((topic: TopicDetailProps) => { - topic.pins.forEach((pin: PinProps) => { - newCoordinates.push({ - id: pin.id, - topicId: topic.id, - pinName: pin.name, - latitude: pin.latitude, - longitude: pin.longitude, - }); + topic.pins.forEach((pin: PinProps) => { + newCoordinates.push({ + id: pin.id, + topicId, + pinName: pin.name, + latitude: pin.latitude, + longitude: pin.longitude, }); }); setCoordinates(newCoordinates); - - data.forEach((topicDetailFromData: TopicDetailProps) => - topicHashmap.set(`${topicDetailFromData.id}`, topicDetailFromData), - ); - - const topicDetailFromData = topicId - ?.split(',') - .map((number) => topicHashmap.get(number)) as TopicDetailProps[]; - - if (!topicDetailFromData) return; - - setTopicDetails([...topicDetailFromData]); }; - const onClickConfirm = () => { + const onClickCreateTopicWithTags = () => { routePage('/new-topic', tags.map((tag) => tag.id).join(',')); }; - const onTagCancel = () => { + const onClickInitTags = () => { setTags([]); }; @@ -134,29 +95,7 @@ function SelectedTopic() { setIsOpen(!isOpen); }; - if (!seeTogetherTopics) return <>; - - if (seeTogetherTopics.length === 0 && topicId === '-1') { - return ( - - - - - - 버튼을 눌러 지도를 추가해보세요. - - - - - - - ); - } - - if (!topicDetails) return <>; - if (!topicId) return <>; + if (!topicId || !topicDetail) return <>; return ( )} }> - {topicDetails.map((topicDetail, idx) => ( - - - {idx !== topicDetails.length - 1 ? : <>} - - ))} + @@ -252,7 +186,7 @@ const ToggleButton = styled.button<{ props.$isCollapsed && ` transform: rotate(180deg); - top:45%; + top: 45%; left: 372px; z-index: 1; `} @@ -266,15 +200,4 @@ const ToggleButton = styled.button<{ } `; -const WrapperWhenEmpty = styled.section<{ width: '372px' | '100vw' }>` - width: ${({ width }) => `calc(${width} - 40px)`}; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - - margin: 0 auto; -`; - export default SelectedTopic; From 036b1b55c314eeabb6b741061b369908888d5baa Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 18 Oct 2023 22:01:33 +0900 Subject: [PATCH 04/16] =?UTF-8?q?refactor:=20resizeMap=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84=EB=A6=AC=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9E=AC=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useResizeMap.ts | 26 ++++++++++++++++++++++++++ frontend/src/pages/SelectedTopic.tsx | 16 ++-------------- 2 files changed, 28 insertions(+), 14 deletions(-) create mode 100644 frontend/src/hooks/useResizeMap.ts diff --git a/frontend/src/hooks/useResizeMap.ts b/frontend/src/hooks/useResizeMap.ts new file mode 100644 index 000000000..57e074dfb --- /dev/null +++ b/frontend/src/hooks/useResizeMap.ts @@ -0,0 +1,26 @@ +import { useEffect } from 'react'; + +import useMapStore from '../store/mapInstance'; + +const getAvailableWidth = (sidebarWidth: number = 372) => + window.innerWidth - sidebarWidth; + +const getAvailableHeight = () => window.innerHeight; + +const useResizeMap = () => { + const { mapInstance } = useMapStore((state) => state); + + const resizeMap = () => { + if (!mapInstance) return; + + mapInstance.resize(getAvailableWidth(372), getAvailableHeight()); + }; + + useEffect(() => { + if (window.innerWidth > 1180) resizeMap(); + }, [getAvailableWidth(372)]); + + return { resizeMap }; +}; + +export default useResizeMap; diff --git a/frontend/src/pages/SelectedTopic.tsx b/frontend/src/pages/SelectedTopic.tsx index 4522439ab..1b688fdfd 100644 --- a/frontend/src/pages/SelectedTopic.tsx +++ b/frontend/src/pages/SelectedTopic.tsx @@ -10,19 +10,14 @@ import { LAYOUT_PADDING, SIDEBAR } from '../constants'; import { CoordinatesContext } from '../context/CoordinatesContext'; import { TagContext } from '../context/TagContext'; import useNavigator from '../hooks/useNavigator'; +import useResizeMap from '../hooks/useResizeMap'; import useSetLayoutWidth from '../hooks/useSetLayoutWidth'; -import useMapStore from '../store/mapInstance'; import { PinProps } from '../types/Pin'; import { TopicDetailProps } from '../types/Topic'; import PinDetail from './PinDetail'; const PinsOfTopic = lazy(() => import('../components/PinsOfTopic')); -const getAvailableWidth = (sidebarWidth: number = 372) => - window.innerWidth - sidebarWidth; - -const getAvailableHeight = () => window.innerHeight; - function SelectedTopic() { const { topicId } = useParams(); const [searchParams, _] = useSearchParams(); @@ -34,13 +29,7 @@ function SelectedTopic() { const { setCoordinates } = useContext(CoordinatesContext); const { tags, setTags } = useContext(TagContext); const { width } = useSetLayoutWidth(SIDEBAR); - const { mapInstance } = useMapStore((state) => state); - - const resizeMap = () => { - if (!mapInstance) return; - - mapInstance.resize(getAvailableWidth(372), getAvailableHeight()); - }; + useResizeMap(); const getAndSetDataFromServer = async () => { const topicInArray = await getApi( @@ -88,7 +77,6 @@ function SelectedTopic() { useEffect(() => { getAndSetDataFromServer(); setTags([]); - if (window.innerWidth > 1180) resizeMap(); }, []); const togglePinDetail = () => { From 66ef51116ecc06fd2058a648f9457353b358abdd Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 18 Oct 2023 22:14:29 +0900 Subject: [PATCH 05/16] =?UTF-8?q?refactor:=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=ED=95=98=EC=9D=B4=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20=EA=B8=B0=EB=8A=A5=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC=20=EB=B0=8F=20=EC=9E=AC=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useSetNavbarHighlight.ts | 9 +++++++-- frontend/src/pages/SelectedTopic.tsx | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/frontend/src/hooks/useSetNavbarHighlight.ts b/frontend/src/hooks/useSetNavbarHighlight.ts index 54e198c9a..c359fe4f7 100644 --- a/frontend/src/hooks/useSetNavbarHighlight.ts +++ b/frontend/src/hooks/useSetNavbarHighlight.ts @@ -6,20 +6,25 @@ import { NavbarHighlightsContext, } from '../context/NavbarHighlightsContext'; -const navbarPageNames: NavbarHighlightKeys[] = [ +type NavbarPageNamesType = 'none' | NavbarHighlightKeys; + +const navbarPageNames: NavbarPageNamesType[] = [ 'home', 'seeTogether', 'addMapOrPin', 'favorite', 'profile', + 'none', ]; -const useSetNavbarHighlight = (pageName: NavbarHighlightKeys) => { +const useSetNavbarHighlight = (pageName: NavbarPageNamesType) => { const { navbarHighlights, setNavbarHighlights } = useContext( NavbarHighlightsContext, ); useEffect(() => { + if (pageName === 'none') return; + const newNavbarHighlights: NavbarHighlights = navbarPageNames.reduce( (acc, curr) => ({ ...acc, [curr]: curr === pageName }), {} as NavbarHighlights, diff --git a/frontend/src/pages/SelectedTopic.tsx b/frontend/src/pages/SelectedTopic.tsx index 1b688fdfd..5617f31ac 100644 --- a/frontend/src/pages/SelectedTopic.tsx +++ b/frontend/src/pages/SelectedTopic.tsx @@ -12,6 +12,7 @@ import { TagContext } from '../context/TagContext'; import useNavigator from '../hooks/useNavigator'; import useResizeMap from '../hooks/useResizeMap'; import useSetLayoutWidth from '../hooks/useSetLayoutWidth'; +import useSetNavbarHighlight from '../hooks/useSetNavbarHighlight'; import { PinProps } from '../types/Pin'; import { TopicDetailProps } from '../types/Topic'; import PinDetail from './PinDetail'; @@ -29,6 +30,7 @@ function SelectedTopic() { const { setCoordinates } = useContext(CoordinatesContext); const { tags, setTags } = useContext(TagContext); const { width } = useSetLayoutWidth(SIDEBAR); + useSetNavbarHighlight('none'); useResizeMap(); const getAndSetDataFromServer = async () => { @@ -38,8 +40,10 @@ function SelectedTopic() { const topic = topicInArray[0]; setTopicDetail(topic); + setCoordinatesTopicDetail(topic); + }; - // 각 topic의 pin들의 좌표를 가져옴 + const setCoordinatesTopicDetail = (topic: TopicDetailProps) => { const newCoordinates: any = []; topic.pins.forEach((pin: PinProps) => { From 8b9f3de18b4f2c7f52ed314be1af17886982500a Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 18 Oct 2023 22:46:58 +0900 Subject: [PATCH 06/16] =?UTF-8?q?refactor:=20tag=20=EA=B4=80=EB=A0=A8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=ED=9B=85=EC=9C=BC=EB=A1=9C=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC=20=EB=B0=8F=20=EC=9E=AC=EC=82=AC=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useTags.ts | 21 +++++++++++++++++++++ frontend/src/pages/SelectedTopic.tsx | 26 +++++++++----------------- 2 files changed, 30 insertions(+), 17 deletions(-) create mode 100644 frontend/src/hooks/useTags.ts diff --git a/frontend/src/hooks/useTags.ts b/frontend/src/hooks/useTags.ts new file mode 100644 index 000000000..fa3e2ad6d --- /dev/null +++ b/frontend/src/hooks/useTags.ts @@ -0,0 +1,21 @@ +import { useContext } from 'react'; + +import { TagContext } from '../context/TagContext'; +import useNavigator from './useNavigator'; + +const useTags = () => { + const { tags, setTags } = useContext(TagContext); + const { routePage } = useNavigator(); + + const onClickCreateTopicWithTags = () => { + routePage('/new-topic', tags.map((tag) => tag.id).join(',')); + }; + + const onClickInitTags = () => { + setTags([]); + }; + + return { tags, setTags, onClickInitTags, onClickCreateTopicWithTags }; +}; + +export default useTags; diff --git a/frontend/src/pages/SelectedTopic.tsx b/frontend/src/pages/SelectedTopic.tsx index 5617f31ac..45e63dd8c 100644 --- a/frontend/src/pages/SelectedTopic.tsx +++ b/frontend/src/pages/SelectedTopic.tsx @@ -8,11 +8,10 @@ import PullPin from '../components/PullPin'; import PinsOfTopicSkeleton from '../components/Skeletons/PinsOfTopicSkeleton'; import { LAYOUT_PADDING, SIDEBAR } from '../constants'; import { CoordinatesContext } from '../context/CoordinatesContext'; -import { TagContext } from '../context/TagContext'; -import useNavigator from '../hooks/useNavigator'; import useResizeMap from '../hooks/useResizeMap'; import useSetLayoutWidth from '../hooks/useSetLayoutWidth'; import useSetNavbarHighlight from '../hooks/useSetNavbarHighlight'; +import useTags from '../hooks/useTags'; import { PinProps } from '../types/Pin'; import { TopicDetailProps } from '../types/Topic'; import PinDetail from './PinDetail'; @@ -26,10 +25,10 @@ function SelectedTopic() { const [selectedPinId, setSelectedPinId] = useState(null); const [isOpen, setIsOpen] = useState(true); const [isEditPinDetail, setIsEditPinDetail] = useState(false); - const { routePage } = useNavigator(); const { setCoordinates } = useContext(CoordinatesContext); - const { tags, setTags } = useContext(TagContext); const { width } = useSetLayoutWidth(SIDEBAR); + const { tags, setTags, onClickInitTags, onClickCreateTopicWithTags } = + useTags(); useSetNavbarHighlight('none'); useResizeMap(); @@ -59,23 +58,20 @@ function SelectedTopic() { setCoordinates(newCoordinates); }; - const onClickCreateTopicWithTags = () => { - routePage('/new-topic', tags.map((tag) => tag.id).join(',')); - }; - - const onClickInitTags = () => { - setTags([]); + const togglePinDetail = () => { + setIsOpen(!isOpen); }; useEffect(() => { const queryParams = new URLSearchParams(location.search); + if (queryParams.has('pinDetail')) { setSelectedPinId(Number(queryParams.get('pinDetail'))); - } else { - setSelectedPinId(null); + setIsOpen(true); + return; } - setIsOpen(true); + setSelectedPinId(null); }, [searchParams]); useEffect(() => { @@ -83,10 +79,6 @@ function SelectedTopic() { setTags([]); }, []); - const togglePinDetail = () => { - setIsOpen(!isOpen); - }; - if (!topicId || !topicDetail) return <>; return ( From 85bd580319ed7ad42c48c0ef1010eb8d1898b1a9 Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 11:41:12 +0900 Subject: [PATCH 07/16] =?UTF-8?q?refactor:=20=ED=86=A0=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=20ui=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/AddSeeTogether/index.tsx | 2 +- frontend/src/components/TopicInfo/index.tsx | 2 +- frontend/src/pages/Home.tsx | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/frontend/src/components/AddSeeTogether/index.tsx b/frontend/src/components/AddSeeTogether/index.tsx index 6d4154eb8..55c7b73a1 100644 --- a/frontend/src/components/AddSeeTogether/index.tsx +++ b/frontend/src/components/AddSeeTogether/index.tsx @@ -34,7 +34,7 @@ function AddSeeTogether({ try { if (seeTogetherTopics && seeTogetherTopics.length === 7) { - showToast('warning', '모아보기는 7개까지만 가능합니다.'); + showToast('error', '모아보기는 7개까지만 가능합니다.'); return; } diff --git a/frontend/src/components/TopicInfo/index.tsx b/frontend/src/components/TopicInfo/index.tsx index fc251ee93..0ae2f0c1a 100644 --- a/frontend/src/components/TopicInfo/index.tsx +++ b/frontend/src/components/TopicInfo/index.tsx @@ -67,7 +67,7 @@ function TopicInfo({ }; const onChangeIsInAtlas = () => { - showToast('warning', '비회원은 홈에서만 모아보기에 담을 수 있습니다.'); + showToast('error', '비회원은 홈에서만 모아보기에 담을 수 있습니다.'); return false; }; diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index 5350ca3e1..4aa859eab 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -12,12 +12,14 @@ import { SeeTogetherContext } from '../context/SeeTogetherContext'; import useNavigator from '../hooks/useNavigator'; import useSetLayoutWidth from '../hooks/useSetLayoutWidth'; import useSetNavbarHighlight from '../hooks/useSetNavbarHighlight'; +import useToast from '../hooks/useToast'; const TopicListContainer = lazy( () => import('../components/TopicCardContainer'), ); function Home() { + const accessToken = localStorage.getItem('userToken'); const { routingHandlers } = useNavigator(); const { goToPopularTopics, goToLatestTopics, goToNearByMeTopics } = routingHandlers; @@ -25,7 +27,7 @@ function Home() { useContext(SeeTogetherContext); const { markers, removeMarkers, removeInfowindows } = useContext(MarkerContext); - const accessToken = localStorage.getItem('userToken'); + const { showToast } = useToast(); useSetLayoutWidth(FULLSCREEN); useSetNavbarHighlight('home'); @@ -33,6 +35,7 @@ function Home() { useEffect(() => { if (accessToken === null && seeTogetherTopics?.length !== 0) { setSeeTogetherTopics([]); + showToast('info', '로그인을 하면 모아보기가 유지돼요.'); } }, []); From bc5fa28484e0c6f256a0bb428395becd90b4d74d Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 11:41:21 +0900 Subject: [PATCH 08/16] =?UTF-8?q?refactor:=20seetogether=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/components/PinPreview/index.tsx | 15 +- frontend/src/components/PinsOfTopic/index.tsx | 7 +- frontend/src/context/MarkerContext.tsx | 10 +- frontend/src/hooks/useNavigator.ts | 2 +- frontend/src/pages/SeeTogether.tsx | 281 ++++++++++++++++++ frontend/src/router.tsx | 16 +- 6 files changed, 322 insertions(+), 9 deletions(-) create mode 100644 frontend/src/pages/SeeTogether.tsx diff --git a/frontend/src/components/PinPreview/index.tsx b/frontend/src/components/PinPreview/index.tsx index 8b901686f..0ec637f31 100644 --- a/frontend/src/components/PinPreview/index.tsx +++ b/frontend/src/components/PinPreview/index.tsx @@ -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'; @@ -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>; - pinId: number; - topicId: string; setIsEditPinDetail: React.Dispatch>; } @@ -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('토픽 핀 선택'); @@ -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) => { diff --git a/frontend/src/components/PinsOfTopic/index.tsx b/frontend/src/components/PinsOfTopic/index.tsx index 0c3e93a9a..0e9622ed5 100644 --- a/frontend/src/components/PinsOfTopic/index.tsx +++ b/frontend/src/components/PinsOfTopic/index.tsx @@ -5,6 +5,7 @@ import PinPreview from '../PinPreview'; import TopicInfo from '../TopicInfo'; interface PinsOfTopicProps { + urlTopicId?: string; topicId: string; topicDetail: TopicDetailProps; setSelectedPinId: React.Dispatch>; @@ -13,6 +14,7 @@ interface PinsOfTopicProps { } function PinsOfTopic({ + urlTopicId, topicId, topicDetail, setSelectedPinId, @@ -38,13 +40,14 @@ function PinsOfTopic({ {topicDetail.pins.map((pin, idx) => (
  • diff --git a/frontend/src/context/MarkerContext.tsx b/frontend/src/context/MarkerContext.tsx index 500f0f574..2410c0e31 100644 --- a/frontend/src/context/MarkerContext.tsx +++ b/frontend/src/context/MarkerContext.tsx @@ -1,5 +1,5 @@ import { createContext, useContext, useState } from 'react'; -import { useParams } from 'react-router-dom'; +import { useLocation, useParams } from 'react-router-dom'; import { pinColors, pinImageMap } from '../constants/pinImage'; import useNavigator from '../hooks/useNavigator'; @@ -41,6 +41,7 @@ function MarkerProvider({ children }: Props): JSX.Element { const { coordinates, clickedCoordinate } = useContext(CoordinatesContext); const { topicId } = useParams<{ topicId: string }>(); const { routePage } = useNavigator(); + const { pathname } = useLocation(); const createMarker = ( coordinate: Coordinate, @@ -87,7 +88,12 @@ function MarkerProvider({ children }: Props): JSX.Element { newMarkers.forEach((marker: Marker) => { marker.on('click', () => { - routePage(`/topics/${topicId}?pinDetail=${marker.id}`); + if (pathname.split('/')[1] === 'topics') { + routePage(`/topics/${topicId}?pinDetail=${marker.id}`); + return; + } + + routePage(`/see-together/${topicId}?pinDetail=${marker.id}`); }); }); setMarkers(newMarkers); diff --git a/frontend/src/hooks/useNavigator.ts b/frontend/src/hooks/useNavigator.ts index b6d0adbc1..52a541516 100644 --- a/frontend/src/hooks/useNavigator.ts +++ b/frontend/src/hooks/useNavigator.ts @@ -21,7 +21,7 @@ const useNavigator = () => { home: () => routePage('/'), seeTogether: () => routePage( - `/topics/${ + `/see-together/${ seeTogetherTopics?.length === 0 ? -1 : seeTogetherTopics?.join(',') }`, ), diff --git a/frontend/src/pages/SeeTogether.tsx b/frontend/src/pages/SeeTogether.tsx new file mode 100644 index 000000000..377ae6663 --- /dev/null +++ b/frontend/src/pages/SeeTogether.tsx @@ -0,0 +1,281 @@ +import { Fragment, Suspense, useContext, useEffect, useState } from 'react'; +import { useLocation, useParams, useSearchParams } from 'react-router-dom'; +import { styled } from 'styled-components'; + +import { getApi } from '../apis/getApi'; +import SeeTogetherNotFilledSVG from '../assets/seeTogetherBtn_notFilled.svg'; +import Button from '../components/common/Button'; +import Flex from '../components/common/Flex'; +import Space from '../components/common/Space'; +import Text from '../components/common/Text'; +import PinsOfTopic from '../components/PinsOfTopic'; +import PullPin from '../components/PullPin'; +import PinsOfTopicSkeleton from '../components/Skeletons/PinsOfTopicSkeleton'; +import { LAYOUT_PADDING, SIDEBAR } from '../constants'; +import { CoordinatesContext } from '../context/CoordinatesContext'; +import { SeeTogetherContext } from '../context/SeeTogetherContext'; +import useNavigator from '../hooks/useNavigator'; +import useResizeMap from '../hooks/useResizeMap'; +import useSetLayoutWidth from '../hooks/useSetLayoutWidth'; +import useSetNavbarHighlight from '../hooks/useSetNavbarHighlight'; +import useTags from '../hooks/useTags'; +import { PinProps } from '../types/Pin'; +import { TopicDetailProps } from '../types/Topic'; +import PinDetail from './PinDetail'; + +function SeeTogether() { + const accessToken = localStorage.getItem('userToken'); + + const { topicId } = useParams(); + const { routePage } = useNavigator(); + const [searchParams, _] = useSearchParams(); + const location = useLocation(); + + const [isOpen, setIsOpen] = useState(true); + const [isEditPinDetail, setIsEditPinDetail] = useState(false); + const [selectedPinId, setSelectedPinId] = useState(null); + const [topicDetails, setTopicDetails] = useState( + null, + ); + + const { tags, setTags, onClickInitTags, onClickCreateTopicWithTags } = + useTags(); + const { setCoordinates } = useContext(CoordinatesContext); + const { width } = useSetLayoutWidth(SIDEBAR); + const { seeTogetherTopics } = useContext(SeeTogetherContext); + useSetNavbarHighlight('seeTogether'); + useResizeMap(); + + const goToHome = () => { + routePage('/'); + }; + + // console.log(topicDetails); + console.log(seeTogetherTopics, 'render'); + + const getAndSetDataFromServer = async (temp) => { + if (topicId === '-1' || !topicId) return; + + const requestTopicIds = seeTogetherTopics?.join(','); + console.log(seeTogetherTopics, 'getAndSet'); + + // if (temp) { + // console.log(temp, 'temp'); + // const topics = await getApi( + // `/topics/ids?ids=${temp.map((topic) => topic.id).join(',')}`, + // ); + // console.log(topics, 'topics'); + // window.location.pathname = `see-together/${window.location.pathname + // .split('/') + // [window.location.pathname.split('/').length - 1].split(',') + // .filter((id) => topics.map((topic) => topic.id).includes(Number(id))) + // .join(',')}`; + + // setCoordinatesTopicDetailWithHashMap(topics); + + // return; + // } + + const topics = await getApi( + `/topics/ids?ids=${requestTopicIds}`, + ); + + setCoordinatesTopicDetailWithHashMap(topics); + }; + + const setCoordinatesTopicDetailWithHashMap = (topics: TopicDetailProps[]) => { + if (topicId === '-1' || !topicId) return; + + const newCoordinates: any = []; + const topicHashmap = new Map([]); + + topics.forEach((topic: TopicDetailProps) => { + topic.pins.forEach((pin: PinProps) => { + newCoordinates.push({ + id: pin.id, + topicId: topic.id, + pinName: pin.name, + latitude: pin.latitude, + longitude: pin.longitude, + }); + }); + }); + + setCoordinates(newCoordinates); + + topics.forEach((topicDetailFromData: TopicDetailProps) => + topicHashmap.set(`${topicDetailFromData.id}`, topicDetailFromData), + ); + + const topicDetailFromData = topicId + .split(',') + .map((number) => topicHashmap.get(number)) as TopicDetailProps[]; + + setTopicDetails([...topicDetailFromData]); + }; + + const togglePinDetail = () => { + setIsOpen(!isOpen); + }; + + useEffect(() => { + const queryParams = new URLSearchParams(location.search); + + if (queryParams.has('pinDetail')) { + setSelectedPinId(Number(queryParams.get('pinDetail'))); + setIsOpen(true); + return; + } + + setSelectedPinId(null); + }, [searchParams]); + + useEffect(() => { + getAndSetDataFromServer(); + setTags([]); + }, []); + + if (!seeTogetherTopics || !topicId) return <>; + + if (seeTogetherTopics.length === 0 || topicId === '-1') { + return ( + + + + + + 버튼을 눌러 지도를 추가해보세요. + + + + + + + ); + } + + return ( + + + {tags.length > 0 && ( + + )} + }> + {topicDetails?.map((topicDetail, idx) => ( + + topicDetail.id) + .join(',')} + topicId={String(topicDetail.id)} + topicDetail={topicDetail} + setSelectedPinId={setSelectedPinId} + setIsEditPinDetail={setIsEditPinDetail} + setTopicsFromServer={getAndSetDataFromServer} + /> + {idx !== topicDetails.length - 1 ? : null} + + ))} + + + + + {selectedPinId && ( + <> + + ◀ + + + + + + )} + + ); +} + +const WrapperWhenEmpty = styled.section<{ width: '372px' | '100vw' }>` + width: ${({ width }) => `calc(${width} - 40px)`}; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + + margin: 0 auto; +`; + +const Wrapper = styled.section<{ + width: 'calc(100vw - 40px)' | 'calc(372px - 40px)'; + $selectedPinId: number | null; +}>` + display: flex; + flex-direction: column; + width: ${({ width }) => width}; + margin: 0 auto; + + @media (max-width: 1076px) { + width: ${({ $selectedPinId }) => ($selectedPinId ? '49vw' : '50vw')}; + margin: ${({ $selectedPinId }) => $selectedPinId && '0'}; + } + + @media (max-width: 744px) { + width: 100%; + } +`; + +const PinDetailWrapper = styled.div` + &.collapsedPinDetail { + z-index: -1; + } +`; + +const ToggleButton = styled.button<{ + $isCollapsed: boolean; +}>` + position: absolute; + top: 50%; + left: 744px; + transform: translateY(-50%); + z-index: 1; + height: 80px; + background-color: #fff; + padding: 12px; + border-radius: 4px; + box-shadow: 0px 1px 5px rgba(0, 0, 0, 0.2); + cursor: pointer; + + ${(props) => + props.$isCollapsed && + ` + transform: rotate(180deg); + top: 45%; + left: 372px; + z-index: 1; + `} + + &:hover { + background-color: #f5f5f5; + } + + @media (max-width: 1076px) { + display: none; + } +`; + +export default SeeTogether; diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index a68049886..ee9bf813b 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -17,6 +17,7 @@ const KakaoRedirect = lazy(() => import('./pages/KakaoRedirect')); const Profile = lazy(() => import('./pages/Profile')); const AskLogin = lazy(() => import('./pages/AskLogin')); const Bookmark = lazy(() => import('./pages/Bookmark')); +const SeeTogether = lazy(() => import('./pages/SeeTogether')); interface routeElement { path: string; @@ -140,7 +141,20 @@ const routes: routeElement[] = [ }, { path: '/search', - element: , + element: ( + + + + ), + withAuth: false, + }, + { + path: '/see-together/:topicId', + element: ( + + + + ), withAuth: false, }, ], From 295569b2cb5eb519a9654324855027b4017692ce Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 13:28:40 +0900 Subject: [PATCH 09/16] =?UTF-8?q?fix:=20=EB=AA=A8=EC=95=84=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=EB=AA=A8=EC=95=84=EB=B3=B4=EA=B8=B0=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EC=8B=9C=20=EB=B0=9C=EC=83=9D=ED=95=98=EB=8D=98=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/components/AddSeeTogether/index.tsx | 15 ++++++++++ frontend/src/components/TopicCard/index.tsx | 1 + frontend/src/components/TopicInfo/index.tsx | 1 + frontend/src/pages/SeeTogether.tsx | 29 +++---------------- 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/frontend/src/components/AddSeeTogether/index.tsx b/frontend/src/components/AddSeeTogether/index.tsx index 55c7b73a1..9d2604b98 100644 --- a/frontend/src/components/AddSeeTogether/index.tsx +++ b/frontend/src/components/AddSeeTogether/index.tsx @@ -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; @@ -17,6 +19,7 @@ interface AddSeeTogetherProps { } function AddSeeTogether({ + parentType, isInAtlas, id, children, @@ -26,6 +29,7 @@ function AddSeeTogether({ const { showToast } = useToast(); const { seeTogetherTopics, setSeeTogetherTopics } = useContext(SeeTogetherContext); + const { routePage } = useNavigator(); const accessToken = localStorage.getItem('userToken'); @@ -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) => { e.stopPropagation(); diff --git a/frontend/src/components/TopicCard/index.tsx b/frontend/src/components/TopicCard/index.tsx index 03637dbc0..3e8f6d3b9 100644 --- a/frontend/src/components/TopicCard/index.tsx +++ b/frontend/src/components/TopicCard/index.tsx @@ -154,6 +154,7 @@ function TopicCard({ {cardType === 'default' && getTopicsFromServer && ( { + const getAndSetDataFromServer = async () => { if (topicId === '-1' || !topicId) return; const requestTopicIds = seeTogetherTopics?.join(','); - console.log(seeTogetherTopics, 'getAndSet'); - - // if (temp) { - // console.log(temp, 'temp'); - // const topics = await getApi( - // `/topics/ids?ids=${temp.map((topic) => topic.id).join(',')}`, - // ); - // console.log(topics, 'topics'); - // window.location.pathname = `see-together/${window.location.pathname - // .split('/') - // [window.location.pathname.split('/').length - 1].split(',') - // .filter((id) => topics.map((topic) => topic.id).includes(Number(id))) - // .join(',')}`; - - // setCoordinatesTopicDetailWithHashMap(topics); - - // return; - // } - const topics = await getApi( `/topics/ids?ids=${requestTopicIds}`, ); @@ -132,6 +108,9 @@ function SeeTogether() { useEffect(() => { getAndSetDataFromServer(); + }, [topicId]); + + useEffect(() => { setTags([]); }, []); From f9c4bb8ea3f75c19c9c89969ae630033fd023413 Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 13:35:23 +0900 Subject: [PATCH 10/16] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20import=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/context/SeeTogetherContext.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/frontend/src/context/SeeTogetherContext.tsx b/frontend/src/context/SeeTogetherContext.tsx index 292551ea5..67a5d9175 100644 --- a/frontend/src/context/SeeTogetherContext.tsx +++ b/frontend/src/context/SeeTogetherContext.tsx @@ -6,8 +6,6 @@ import { useState, } from 'react'; -import { TopicCardProps } from '../types/Topic'; - interface SeeTogetherContextProps { seeTogetherTopics: number[] | null; setSeeTogetherTopics: Dispatch>; From 5c1553e07486df137e31149a46c8085e9dc0c79c Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 13:35:56 +0900 Subject: [PATCH 11/16] =?UTF-8?q?refactor:=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=ED=95=98=EC=9D=B4=EB=9D=BC=EC=9D=B4?= =?UTF-8?q?=ED=8A=B8=20topics=EC=97=90=EC=84=9C=20=EB=AC=B4=ED=9A=A8?= =?UTF-8?q?=ED=99=94=20=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/hooks/useSetNavbarHighlight.ts | 15 +++++++++++++-- frontend/src/pages/AskLogin.tsx | 2 ++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/frontend/src/hooks/useSetNavbarHighlight.ts b/frontend/src/hooks/useSetNavbarHighlight.ts index c359fe4f7..7b95567f4 100644 --- a/frontend/src/hooks/useSetNavbarHighlight.ts +++ b/frontend/src/hooks/useSetNavbarHighlight.ts @@ -17,16 +17,27 @@ const navbarPageNames: NavbarPageNamesType[] = [ 'none', ]; +const deleteNavbarHighlights = { + home: false, + seeTogether: false, + addMapOrPin: false, + favorite: false, + profile: false, +}; + const useSetNavbarHighlight = (pageName: NavbarPageNamesType) => { const { navbarHighlights, setNavbarHighlights } = useContext( NavbarHighlightsContext, ); useEffect(() => { - if (pageName === 'none') return; + if (pageName === 'none') { + setNavbarHighlights(deleteNavbarHighlights); + return; + } const newNavbarHighlights: NavbarHighlights = navbarPageNames.reduce( - (acc, curr) => ({ ...acc, [curr]: curr === pageName }), + (acc, cur) => ({ ...acc, [cur]: cur === pageName }), {} as NavbarHighlights, ); diff --git a/frontend/src/pages/AskLogin.tsx b/frontend/src/pages/AskLogin.tsx index 69a2101c6..559a18b5e 100644 --- a/frontend/src/pages/AskLogin.tsx +++ b/frontend/src/pages/AskLogin.tsx @@ -7,9 +7,11 @@ import Space from '../components/common/Space'; import Text from '../components/common/Text'; import { DEFAULT_PROD_URL, FULLSCREEN } from '../constants'; import useSetLayoutWidth from '../hooks/useSetLayoutWidth'; +import useSetNavbarHighlight from '../hooks/useSetNavbarHighlight'; function AskLogin() { const { width } = useSetLayoutWidth(FULLSCREEN); + useSetNavbarHighlight('none'); const loginButtonClick = async () => { window.location.href = `${DEFAULT_PROD_URL}/oauth/kakao`; From 183bb11297f2d09b08afb6a9c3898fb359983ead Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 13:42:28 +0900 Subject: [PATCH 12/16] =?UTF-8?q?fix:=20=ED=9A=8C=EC=9B=90=EC=9D=BC?= =?UTF-8?q?=EB=95=8C=EB=8A=94=20url=20=EC=83=81=ED=83=9C=EB=A1=9C=20?= =?UTF-8?q?=ED=86=A0=ED=94=BD=20=EC=A1=B0=ED=9A=8C=20=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EB=B3=80=EA=B2=BD=ED=95=98=EC=97=AC=20=EC=83=88?= =?UTF-8?q?=EB=A1=9C=EA=B3=A0=EC=B9=A8=20=EC=98=A4=EB=A5=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SeeTogether.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frontend/src/pages/SeeTogether.tsx b/frontend/src/pages/SeeTogether.tsx index 8ce645570..4256738bc 100644 --- a/frontend/src/pages/SeeTogether.tsx +++ b/frontend/src/pages/SeeTogether.tsx @@ -24,6 +24,8 @@ import { TopicDetailProps } from '../types/Topic'; import PinDetail from './PinDetail'; function SeeTogether() { + const accessToken = localStorage.getItem('userToken'); + const { topicId } = useParams(); const { routePage } = useNavigator(); const [searchParams, _] = useSearchParams(); @@ -51,7 +53,10 @@ function SeeTogether() { const getAndSetDataFromServer = async () => { if (topicId === '-1' || !topicId) return; - const requestTopicIds = seeTogetherTopics?.join(','); + const requestTopicIds = accessToken + ? topicId + : seeTogetherTopics?.join(','); + const topics = await getApi( `/topics/ids?ids=${requestTopicIds}`, ); From 9322c58888058b3f2d28d82d98fb81df866fd176 Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 13:47:04 +0900 Subject: [PATCH 13/16] =?UTF-8?q?fix:=20=EB=AA=A8=EC=95=84=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=EB=A5=BC=20=EB=AA=A8=EB=91=90=20=EB=B9=84=EC=9A=B4=20?= =?UTF-8?q?=ED=9B=84=20=ED=95=80=EC=9D=B4=20=EB=82=A8=EC=95=84=EC=9E=88?= =?UTF-8?q?=EB=8A=94=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SeeTogether.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/frontend/src/pages/SeeTogether.tsx b/frontend/src/pages/SeeTogether.tsx index 4256738bc..b2849cb3a 100644 --- a/frontend/src/pages/SeeTogether.tsx +++ b/frontend/src/pages/SeeTogether.tsx @@ -13,6 +13,7 @@ import PullPin from '../components/PullPin'; import PinsOfTopicSkeleton from '../components/Skeletons/PinsOfTopicSkeleton'; import { LAYOUT_PADDING, SIDEBAR } from '../constants'; import { CoordinatesContext } from '../context/CoordinatesContext'; +import { MarkerContext } from '../context/MarkerContext'; import { SeeTogetherContext } from '../context/SeeTogetherContext'; import useNavigator from '../hooks/useNavigator'; import useResizeMap from '../hooks/useResizeMap'; @@ -43,6 +44,8 @@ function SeeTogether() { const { setCoordinates } = useContext(CoordinatesContext); const { width } = useSetLayoutWidth(SIDEBAR); const { seeTogetherTopics } = useContext(SeeTogetherContext); + const { markers, removeMarkers, removeInfowindows } = + useContext(MarkerContext); useSetNavbarHighlight('seeTogether'); useResizeMap(); @@ -117,6 +120,11 @@ function SeeTogether() { useEffect(() => { setTags([]); + + if (markers && markers.length > 0) { + removeMarkers(); + removeInfowindows(); + } }, []); if (!seeTogetherTopics || !topicId) return <>; From 9062508694ca17b8130f48b7e13d83aa33056eb2 Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 14:07:44 +0900 Subject: [PATCH 14/16] =?UTF-8?q?fix:=20=EB=AA=A8=EC=95=84=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0=20=EC=83=81=ED=83=9C=EC=97=90=EC=84=9C=20=ED=86=A0?= =?UTF-8?q?=ED=94=BD=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=EC=9D=B4=20=EC=84=A0=ED=83=9D=ED=95=9C=20=ED=86=A0=ED=94=BD?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/TopicInfo/UpdatedTopicInfo.tsx | 21 ++++++++++++------- frontend/src/pages/SeeTogether.tsx | 12 +---------- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/frontend/src/components/TopicInfo/UpdatedTopicInfo.tsx b/frontend/src/components/TopicInfo/UpdatedTopicInfo.tsx index 930a089a1..0bdc3d317 100644 --- a/frontend/src/components/TopicInfo/UpdatedTopicInfo.tsx +++ b/frontend/src/components/TopicInfo/UpdatedTopicInfo.tsx @@ -5,18 +5,18 @@ import useDelete from '../../apiHooks/useDelete'; import useGet from '../../apiHooks/useGet'; import usePost from '../../apiHooks/usePost'; import usePut from '../../apiHooks/usePut'; +import { putApi } from '../../apis/putApi'; +import { DEFAULT_TOPIC_IMAGE } from '../../constants'; +import useCompressImage from '../../hooks/useCompressImage'; import useFormValues from '../../hooks/useFormValues'; import useToast from '../../hooks/useToast'; import { TopicAuthorInfo } from '../../types/Topic'; import Button from '../common/Button'; import Flex from '../common/Flex'; +import Image from '../common/Image'; import Space from '../common/Space'; -import InputContainer from '../InputContainer'; import Text from '../common/Text'; -import useCompressImage from '../../hooks/useCompressImage'; -import Image from '../common/Image'; -import { DEFAULT_TOPIC_IMAGE } from '../../constants'; -import { putApi } from '../../apis/putApi'; +import InputContainer from '../InputContainer'; interface UpdatedTopicInfoProp { id: number; @@ -85,7 +85,7 @@ function UpdatedTopicInfo({ // await updateTopicPermissionMembers(); // } - showToast('info', '지도를 수정하였습니다.'); + showToast('info', `${name} 지도를 수정하였습니다.`); setIsUpdate(false); setTopicsFromServer(); } catch {} @@ -147,10 +147,15 @@ function UpdatedTopicInfo({ const compressedFile = await compressImage(file); formData.append('image', compressedFile); - await putApi(`/topics/images/${id}`, formData); + try { + await putApi(`/topics/images/${id}`, formData); + } catch { + showToast('error', '사용할 수 없는 이미지입니다.'); + } const updatedImageUrl = URL.createObjectURL(compressedFile); setChangedImages(updatedImageUrl); + showToast('info', '지도 이미지를 수정하였습니다.'); }; return ( @@ -166,7 +171,7 @@ function UpdatedTopicInfo({ ) => { diff --git a/frontend/src/pages/SeeTogether.tsx b/frontend/src/pages/SeeTogether.tsx index b2849cb3a..c13cef557 100644 --- a/frontend/src/pages/SeeTogether.tsx +++ b/frontend/src/pages/SeeTogether.tsx @@ -64,6 +64,7 @@ function SeeTogether() { `/topics/ids?ids=${requestTopicIds}`, ); + setTopicDetails([...topics]); setCoordinatesTopicDetailWithHashMap(topics); }; @@ -71,7 +72,6 @@ function SeeTogether() { if (topicId === '-1' || !topicId) return; const newCoordinates: any = []; - const topicHashmap = new Map([]); topics.forEach((topic: TopicDetailProps) => { topic.pins.forEach((pin: PinProps) => { @@ -86,16 +86,6 @@ function SeeTogether() { }); setCoordinates(newCoordinates); - - topics.forEach((topicDetailFromData: TopicDetailProps) => - topicHashmap.set(`${topicDetailFromData.id}`, topicDetailFromData), - ); - - const topicDetailFromData = topicId - .split(',') - .map((number) => topicHashmap.get(number)) as TopicDetailProps[]; - - setTopicDetails([...topicDetailFromData]); }; const togglePinDetail = () => { From 8df9e1473aa75c825b2d2d500a96c0b2bba9c07d Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 17:57:50 +0900 Subject: [PATCH 15/16] =?UTF-8?q?chore:=20swiper=20=EC=A0=9C=EA=B1=B0=20?= =?UTF-8?q?=ED=9B=84=20npm=20=EB=B0=B0=ED=8F=AC=20=EB=B2=84=EC=A0=84?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20import?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/.eslintrc.js | 1 + frontend/package-lock.json | 11 + frontend/package.json | 1 + frontend/src/components/Banner/index.tsx | 3 +- .../components/TopicCardContainer/index.tsx | 3 +- frontend/src/components/common/Swiper/Tab.tsx | 12 - .../common/Swiper/hooks/useAutoplay.ts | 52 --- .../common/Swiper/hooks/useMatchMedia.ts | 60 --- .../common/Swiper/hooks/useSwipeable.ts | 82 ---- .../src/components/common/Swiper/index.tsx | 397 ------------------ 10 files changed, 15 insertions(+), 607 deletions(-) delete mode 100644 frontend/src/components/common/Swiper/Tab.tsx delete mode 100644 frontend/src/components/common/Swiper/hooks/useAutoplay.ts delete mode 100644 frontend/src/components/common/Swiper/hooks/useMatchMedia.ts delete mode 100644 frontend/src/components/common/Swiper/hooks/useSwipeable.ts delete mode 100644 frontend/src/components/common/Swiper/index.tsx diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 3b13b0d09..9605c722f 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -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': { diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 8931b020a..88662ca3a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -10,6 +10,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", @@ -18306,6 +18307,16 @@ "tmpl": "1.0.5" } }, + "node_modules/map-befine-swiper": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/map-befine-swiper/-/map-befine-swiper-0.8.2.tgz", + "integrity": "sha512-8Adxs0eHS5bqcAgXsX7+bDWALHH7WMx/agxVEUasGh/ABgJbCF1WzNmBQMwkFJ89JoYIn3E5weDA1LAGF832IA==", + "dependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0", + "styled-components": "^6.0.8" + } + }, "node_modules/map-obj": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 2ab0e1b41..9e6614568 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -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", diff --git a/frontend/src/components/Banner/index.tsx b/frontend/src/components/Banner/index.tsx index dce5428a6..1793b0f06 100644 --- a/frontend/src/components/Banner/index.tsx +++ b/frontend/src/components/Banner/index.tsx @@ -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'; diff --git a/frontend/src/components/TopicCardContainer/index.tsx b/frontend/src/components/TopicCardContainer/index.tsx index 92d5e19ab..b7d7272d4 100644 --- a/frontend/src/components/TopicCardContainer/index.tsx +++ b/frontend/src/components/TopicCardContainer/index.tsx @@ -1,3 +1,4 @@ +import { Swiper, Tab } from 'map-befine-swiper'; import { useEffect, useState } from 'react'; import { styled } from 'styled-components'; @@ -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'; diff --git a/frontend/src/components/common/Swiper/Tab.tsx b/frontend/src/components/common/Swiper/Tab.tsx deleted file mode 100644 index 6c54f369d..000000000 --- a/frontend/src/components/common/Swiper/Tab.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from 'react'; - -interface Props { - label: string; - children?: React.ReactNode; -} - -function Tab({ children }: Props) { - return
    {children}
    ; -} - -export default Tab; diff --git a/frontend/src/components/common/Swiper/hooks/useAutoplay.ts b/frontend/src/components/common/Swiper/hooks/useAutoplay.ts deleted file mode 100644 index 97306f7d0..000000000 --- a/frontend/src/components/common/Swiper/hooks/useAutoplay.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { useEffect, useRef, useState } from 'react'; - -interface Props { - autoplay: boolean; - $autoplayTime: number; - childrenListLength: number; - pos: number; - setPos: React.Dispatch>; -} - -const useAutoplay = ({ - autoplay, - $autoplayTime, - childrenListLength, - pos, - setPos, -}: Props) => { - const [isPlaying, setIsPlaying] = useState(autoplay); - const intervalId = useRef(null); - - useEffect(() => { - if (childrenListLength < 2) setIsPlaying(false); - - if (isPlaying) { - intervalId.current = setInterval( - () => { - pos <= childrenListLength - 2 - ? setPos((prev) => prev + 1) - : setPos(0); - }, - $autoplayTime < 1000 ? 1000 : $autoplayTime, - ); - } - - if (!isPlaying && intervalId.current) clearInterval(intervalId.current); - - return () => { - if (intervalId.current) clearInterval(intervalId.current); - }; - }, [childrenListLength, pos, setPos, $autoplayTime, isPlaying]); - - const toggleAutoplay = () => { - setIsPlaying((prev) => !prev); - }; - - return { - isPlaying, - toggleAutoplay, - }; -}; - -export default useAutoplay; diff --git a/frontend/src/components/common/Swiper/hooks/useMatchMedia.ts b/frontend/src/components/common/Swiper/hooks/useMatchMedia.ts deleted file mode 100644 index 72c0c1700..000000000 --- a/frontend/src/components/common/Swiper/hooks/useMatchMedia.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { useEffect, useRef, useState } from 'react'; - -const useMediaQuery = ( - mediaQueries: number[] = [], - defaultValueIgnoreMedia: number = 1, -) => { - const currentPageWidth = window.innerWidth; - - const mediaQueriesIncludeInit = mediaQueries - .concat(currentPageWidth) - .sort((a, b) => b - a); - - const [matches, setMatches] = useState( - mediaQueriesIncludeInit.length > 1 - ? mediaQueriesIncludeInit.length - - mediaQueriesIncludeInit.indexOf(currentPageWidth) - : defaultValueIgnoreMedia, - ); - const mediaQueryListRef = useRef(null); - - useEffect(() => { - mediaQueryListRef.current = mediaQueriesIncludeInit.map( - (mediaQuery) => `(max-width: ${mediaQuery}px)`, - ); - - const handleMediaChange = (elementsCount: number) => { - setMatches(elementsCount); - }; - - mediaQueryListRef.current.forEach((mediaQuery, index) => { - const matchMedia = window.matchMedia(mediaQuery); - - if (mediaQueryListRef.current) { - const mediaQueryConditions = mediaQueryListRef.current; - - matchMedia.addEventListener('change', () => - handleMediaChange(mediaQueryConditions.length - index), - ); - } - }); - - return () => { - if (mediaQueryListRef.current) { - const mediaQueryConditions = mediaQueryListRef.current; - - mediaQueryConditions.forEach((mediaQuery, index) => { - const matchMedia = window.matchMedia(mediaQuery); - - matchMedia.removeEventListener('change', () => - handleMediaChange(mediaQueryConditions.length - index), - ); - }); - } - }; - }, []); - - return { elementsCount: matches }; -}; - -export default useMediaQuery; diff --git a/frontend/src/components/common/Swiper/hooks/useSwipeable.ts b/frontend/src/components/common/Swiper/hooks/useSwipeable.ts deleted file mode 100644 index 4599d2396..000000000 --- a/frontend/src/components/common/Swiper/hooks/useSwipeable.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { TouchEventHandler, useRef, useState } from 'react'; - -interface Props { - childrenListLength: number; - pos: number; - setPos: React.Dispatch>; -} - -let isAcceleratingPos = false; -const CAN_SWIPE = 10; -const OPPOSITE_DIRECTION_CAN_SWIPE = 4; - -const useSwipeable = ({ childrenListLength, pos, setPos }: Props) => { - const [prevTouch, setPrevTouch] = useState(null); - const timerId = useRef(null); - - const acceleratePos = (diff: number) => { - if (isAcceleratingPos) return; - - if (pos < childrenListLength - 1 && diff < -CAN_SWIPE) { - isAcceleratingPos = true; - setPos(pos + 1); - } - - if (pos > 0 && diff > CAN_SWIPE) { - isAcceleratingPos = true; - setPos(pos - 1); - } - - if (timerId.current) return; - - timerId.current = setTimeout(() => { - isAcceleratingPos = false; - - if (timerId.current) { - clearTimeout(timerId.current); - timerId.current = null; - } - }, 150); - }; - - const increasePos = () => { - if (pos < childrenListLength - 1) setPos(pos + 1); - }; - - const decreasePos = () => { - if (pos > 0) setPos(pos - 1); - }; - - const moveToSettedPos = (settedPos: number) => { - setPos(settedPos); - }; - - const handleTouchMove: TouchEventHandler = (event) => { - const touch = event.touches[0]!; - - setPrevTouch(touch); - if (!prevTouch) return; - - const diff = touch.pageX - prevTouch.pageX; - const otherPos = touch.pageY - prevTouch.pageY; - - if (Math.abs(otherPos) > OPPOSITE_DIRECTION_CAN_SWIPE) return; - - acceleratePos(diff); - }; - - const handleTouchEnd: TouchEventHandler = () => { - setPrevTouch(null); - }; - - return { - pos, - increasePos, - decreasePos, - moveToSettedPos, - handleTouchMove, - handleTouchEnd, - }; -}; - -export default useSwipeable; diff --git a/frontend/src/components/common/Swiper/index.tsx b/frontend/src/components/common/Swiper/index.tsx deleted file mode 100644 index ff61c4fe4..000000000 --- a/frontend/src/components/common/Swiper/index.tsx +++ /dev/null @@ -1,397 +0,0 @@ -import React, { useState } from 'react'; -import styled, { css } from 'styled-components'; - -import SwiperLeftBtnSVG from '../../../assets/swiper_left_button.svg'; -import SwiperRightBtnSVG from '../../../assets/swiper_right_button.svg'; -import useAutoplay from './hooks/useAutoplay'; -import useMediaQuery from './hooks/useMatchMedia'; -import useSwipeable from './hooks/useSwipeable'; - -type TabBoxPositionType = 'top' | 'bottom'; - -interface TabProps { - label: string; -} - -interface Props { - children: React.ReactNode; - width?: number; - height?: number; - $tabBoxHeight?: number; - $tabColor?: string | string[]; - $tabBoxPosition?: TabBoxPositionType; - $elementsOneTab?: number; - $focusColor?: string; - $simpleTab?: boolean; - $isNotTabBoxShow?: boolean; - responsive?: boolean; - swiper?: boolean; - swipeable?: boolean; - autoplay?: boolean; - $autoplayTime?: number; - $autoplayButton?: boolean; - $elementsMediaQueries?: number[]; - as?: string; -} - -const getTabsColor = (indexOfTab: number, $tabColor: string | string[]) => { - if (typeof $tabColor === 'string') return $tabColor; - - return $tabColor[indexOfTab] || '#e4e4e4'; -}; - -const calculateTabCountUsingElements = ( - childrenList: React.ReactElement[], - $elementsOneTab: number, -) => { - if ($elementsOneTab > 1) { - const tabBoxesCount = Math.ceil(childrenList.length / $elementsOneTab); - return childrenList.filter((_, idx) => idx < tabBoxesCount); - } - - return childrenList; -}; - -function Swiper({ - width = 400, - height = 400, - $simpleTab = false, - $isNotTabBoxShow = false, - $tabBoxHeight = height / 10, - $tabBoxPosition = 'top', - $elementsOneTab = 1, - $tabColor = '#e4e4e4', - $focusColor = '#316fc4', - responsive = true, - swiper = false, - swipeable = false, - autoplay = false, - $autoplayTime = 5000, - $autoplayButton = false, - $elementsMediaQueries = [], - as = 'div', - children, -}: Props) { - const childrenList = React.Children.toArray( - children, - ) as React.ReactElement[]; - const isShowTabBox = - !$isNotTabBoxShow && childrenList.length > $elementsOneTab; - - const [pos, setPos] = useState(0); - const { elementsCount } = useMediaQuery( - $elementsMediaQueries, - $elementsOneTab, - ); - const { - increasePos, - decreasePos, - moveToSettedPos, - handleTouchMove, - handleTouchEnd, - } = useSwipeable({ - childrenListLength: calculateTabCountUsingElements( - childrenList, - elementsCount, - ).length, - pos, - setPos, - }); - const { isPlaying, toggleAutoplay } = useAutoplay({ - autoplay, - $autoplayTime, - childrenListLength: calculateTabCountUsingElements( - childrenList, - elementsCount, - ).length, - pos, - setPos, - }); - - return ( - - {isShowTabBox && ( - - {calculateTabCountUsingElements(childrenList, elementsCount).map( - (children, idx) => - children && ( - moveToSettedPos(idx)} - > - {!$simpleTab && (children.props.label || idx + 1)} - - ), - )} - - )} - - - {children} - - - {swiper && ( - <> - - - - - - - - )} - - {$autoplayButton && childrenList.length > 1 && ( - - {isPlaying ? ( - || - ) : ( - ▶️ - )} - - )} - - ); -} - -const Wrapper = styled.div<{ - width: number; - responsive: boolean; - $tabBoxPosition: TabBoxPositionType; -}>` - width: ${({ width }) => `${width}px`}; - overflow: hidden; - margin: 0 auto; - position: relative; - display: flex; - flex-direction: ${({ $tabBoxPosition }) => - $tabBoxPosition === 'top' ? 'column' : 'column-reverse'}; - - // responsive가 true 이면 입력 받은 width 값 보다 뷰포트가 작아질 때 뷰포트에 맞게 width를 설정합니다. - ${({ responsive, width }) => - responsive && - css` - @media (max-width: ${width}px) { - width: 100%; - } - `} -`; - -const calculateWidthUsingElementsCount = ( - width: number | '100vw', - elementCount: number, -) => { - if (typeof width === 'number' && elementCount > 1) - return width / elementCount; - if (typeof width === 'string' && elementCount > 1) - return `calc(${width} / ${elementCount})`; - - return width; -}; - -const TabSectionWrapper = styled.div<{ - width: number; - height: number; - $childrenLength: number; - pos: number; - responsive: boolean; - $elementsOneTab: number; -}>` - display: flex; - - // 사용자가 입력한 의 width 값을 컴포넌트 개수만큼 곱하여 Tab Section의 width를 설정합니다. 따라서 overflow 됩니다. - width: ${({ width, $childrenLength }) => `${width * $childrenLength}px`}; - height: ${({ height }) => `${height}px`}; - - // 사용자가 입력한 width 값 보다 컴포넌트 개수만큼 overflow 되었으므로 width * index 만큼 transform 하여 요소의 위치로 이동합니다. (전환 효과) - transform: ${({ width, pos }) => `translateX(${-width * pos}px)`}; - transition: 0.3s ease transform; - - ${({ responsive, width, $childrenLength, pos }) => - responsive && - css` - @media (max-width: ${width}px) { - width: calc(100vw * ${$childrenLength}); - height: auto; - transform: translateX(calc(-100vw * ${pos})); - } - `} - - // 컴포넌트에 입력한 width와 컴포넌트 width를 동일하게 합니다. - & > * { - width: ${({ width, $elementsOneTab }) => - calculateWidthUsingElementsCount(width, $elementsOneTab)}px; - - ${({ responsive, width, $elementsOneTab }) => - responsive && - css` - @media (max-width: ${width}px) { - width: ${calculateWidthUsingElementsCount('100vw', $elementsOneTab)}; - } - `} - } -`; - -const TabBoxWrapper = styled.div<{ - $simpleTab: boolean; - $tabBoxHeight: number; -}>` - display: flex; - align-items: center; - - // 기본값은 height / 10 입니다. 하지만 사용자가 직접 지정할 수도 있게 해두었습니다. - height: ${({ $tabBoxHeight }) => `${$tabBoxHeight}px`}; - overflow: auto; - - // simpleTab 모드에서는 TabButton이 작아지므로 가운데 정렬하도록 합니다. - ${({ $simpleTab }) => - $simpleTab && - css` - justify-content: center; - `} -`; - -const TabBox = styled.button<{ - width: number; - idx: number; - pos: number; - $tabBoxHeight: number; - $childrenLength: number; - $simpleTab: boolean; - $tabColor: string; - $focusColor: string; -}>` - width: ${({ width, $childrenLength }) => `${width / $childrenLength}px`}; - height: inherit; - padding: 0.2rem 1rem; - border: 0; - cursor: pointer; - background-color: ${({ $tabColor }) => $tabColor}; - - // simpleTab 모드일 때 탭 박스 대신 원이 생성됩니다. 해당 원의 크기를 지정합니다. - ${({ $simpleTab, $tabBoxHeight }) => - $simpleTab && - css` - padding: 0; - width: ${$tabBoxHeight / 2}px; - height: ${$tabBoxHeight / 2}px; - border-radius: 50%; - `} - - // simpleTab 모드에서 원들이 가운데 정렬되므로 각 요소의 margin을 설정합니다. - ${({ $simpleTab }) => - $simpleTab && - css` - margin-right: 12px; - - &:last-of-type { - margin-right: 0; - } - `} - - // simpleTab 모드가 아닐때, 포커스 된 탭 박스 하단 밑줄 구현부입니다. - ${({ idx, pos, $focusColor }) => - idx === pos && - css` - border-bottom: 2px solid ${$focusColor}; - `} - - // simpleTab 모드 일 때, 포커스 된 원 배경색 구현부입니다. - ${({ $simpleTab, idx, pos, $focusColor }) => - idx === pos && - $simpleTab && - css` - border-bottom: 0; - border: 2px solid ${$focusColor}; - `} -`; - -const SwiperButtonLeftWrapper = styled.div<{ - $tabBoxHeight: number; - $isNotTabBoxShow: boolean; -}>` - position: absolute; - top: ${({ $tabBoxHeight, $isNotTabBoxShow }) => - $isNotTabBoxShow ? `50%` : `calc(50% + ${$tabBoxHeight}px / 2)`}; - left: 1%; - transform: ${({ $tabBoxHeight, $isNotTabBoxShow }) => - $isNotTabBoxShow - ? `translateY(-50%)` - : `translateY(calc(-50% - ${$tabBoxHeight}px))`}; - - @media (max-width: 744px) { - display: none; - } -`; - -const SwiperButtonRightWrapper = styled.div<{ - $tabBoxHeight: number; - $isNotTabBoxShow: boolean; -}>` - position: absolute; - top: ${({ $tabBoxHeight, $isNotTabBoxShow }) => - $isNotTabBoxShow ? `50%` : `calc(50% + ${$tabBoxHeight}px / 2)`}; - right: 1%; - transform: ${({ $tabBoxHeight, $isNotTabBoxShow }) => - $isNotTabBoxShow - ? `translateY(-50%)` - : `translateY(calc(-50% - ${$tabBoxHeight}px))`}; - - @media (max-width: 744px) { - display: none; - } -`; - -const AutoplayButtonWrapper = styled.div` - width: 100%; - display: flex; - justify-content: center; - position: absolute; - bottom: 12%; -`; - -const AutoplayButton = styled.div` - display: flex; - justify-content: center; - align-items: center; - background-color: transparent; - color: rgba(149, 149, 149, 0.8); - border: 1px solid rgba(149, 149, 149, 0.8); - width: 64px; - height: 32px; - cursor: pointer; -`; - -export default Swiper; From 01c6e8896ecf1f80712411ae80d1f5103a5dd2e9 Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Thu, 19 Oct 2023 18:10:40 +0900 Subject: [PATCH 16/16] =?UTF-8?q?refactor:=20search=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EC=84=9C=EC=8A=A4=ED=8E=9C=EC=8A=A4=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/router.tsx | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/frontend/src/router.tsx b/frontend/src/router.tsx index ee9bf813b..dd9b8268a 100644 --- a/frontend/src/router.tsx +++ b/frontend/src/router.tsx @@ -141,11 +141,7 @@ const routes: routeElement[] = [ }, { path: '/search', - element: ( - - - - ), + element: , withAuth: false, }, {