From 9fd0343b305c4ef3f2ba1dae5606bfe6e403665e Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 2 Aug 2023 13:44:46 +0900 Subject: [PATCH 1/3] =?UTF-8?q?refactor:=20tagId=20Context=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0=20=ED=9B=84=20Router=20state=EB=A1=9C=20=EB=8C=80?= =?UTF-8?q?=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/App.tsx | 7 +- frontend/src/components/PinPreview/index.tsx | 13 ++-- frontend/src/components/TopicCard/index.tsx | 18 ++--- frontend/src/pages/Home.tsx | 21 +++--- frontend/src/pages/NewPin.tsx | 3 +- frontend/src/pages/NewTopic.tsx | 79 ++++++-------------- frontend/src/pages/SelectedTopic.tsx | 14 +--- frontend/src/store/TagId.tsx | 28 ------- 8 files changed, 54 insertions(+), 129 deletions(-) delete mode 100644 frontend/src/store/TagId.tsx diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index d24282f2..719a571a 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,13 +1,8 @@ import { RouterProvider } from 'react-router-dom'; import router from './router'; -import TagContextProvider from './store/TagId'; const App = () => { - return ( - - ; - - ); + return ; }; export default App; diff --git a/frontend/src/components/PinPreview/index.tsx b/frontend/src/components/PinPreview/index.tsx index deda4c6a..f39c4cee 100644 --- a/frontend/src/components/PinPreview/index.tsx +++ b/frontend/src/components/PinPreview/index.tsx @@ -4,7 +4,6 @@ import Space from '../common/Space'; import Text from '../common/Text'; import useNavigator from '../../hooks/useNavigator'; import { useContext } from 'react'; -import { TagIdContext } from '../../store/TagId'; export interface PinPreviewProps { pinTitle: string; @@ -15,6 +14,8 @@ export interface PinPreviewProps { topicId: number | undefined; tagPins: string[]; setTagPins: (value: string[]) => void; + taggedPinIds: number[]; + setTaggedPinIds: React.Dispatch>; } const PinPreview = ({ @@ -26,18 +27,18 @@ const PinPreview = ({ topicId, tagPins, setTagPins, + taggedPinIds, + setTaggedPinIds, }: PinPreviewProps) => { const { routePage } = useNavigator(); - const { tagId, setTagId } = useContext(TagIdContext); - const onAddTagOfTopic = (e: React.ChangeEvent) => { if (e.target.checked) { setTagPins([...tagPins, pinTitle]); - setTagId([...tagId, pinId]); + setTaggedPinIds((prev) => [...prev, pinId]); } else { setTagPins(tagPins.filter((value) => value !== pinTitle)); - setTagId(tagId.filter((value) => value !== pinId)); + setTaggedPinIds(taggedPinIds.filter((value) => value !== pinId)); } }; @@ -62,7 +63,7 @@ const PinPreview = ({ onChange={(e: React.ChangeEvent) => onAddTagOfTopic(e) } - checked={Boolean(tagId.includes(pinId))} + checked={Boolean(taggedPinIds.includes(pinId))} /> void; + setTagTopics: React.Dispatch>; + taggedTopicIds: number[]; + setTaggedTopicIds: React.Dispatch>; } const TopicCard = ({ @@ -23,11 +24,10 @@ const TopicCard = ({ topicPinCount, tagTopics, setTagTopics, + taggedTopicIds, + setTaggedTopicIds, }: TopicCardProps) => { const { routePage } = useNavigator(); - - const { tagId, setTagId } = useContext(TagIdContext); - const goToSelectedTopic = () => { routePage(`topics/${topicId}`, [topicId]); }; @@ -35,10 +35,10 @@ const TopicCard = ({ const onAddTagOfTopic = (e: React.ChangeEvent) => { if (e.target.checked) { setTagTopics([...tagTopics, topicTitle]); - setTagId([...tagId, topicId]); + setTaggedTopicIds((prev) => [...prev, topicId]); } else { setTagTopics(tagTopics.filter((value) => value !== topicTitle)); - setTagId(tagId.filter((value) => value !== topicId)); + setTaggedTopicIds(taggedTopicIds.filter((value) => value !== topicId)); } }; @@ -60,7 +60,7 @@ const TopicCard = ({ onChange={(e: React.ChangeEvent) => onAddTagOfTopic(e) } - checked={Boolean(tagId.includes(topicId))} + checked={taggedTopicIds.includes(topicId)} /> { const [topics, setTopics] = useState([]); + const [taggedTopicIds, setTaggedTopicIds] = useState([]); const [tagTopics, setTagTopics] = useState([]); const { routePage } = useNavigator(); const { setCoordinates } = useContext(CoordinatesContext); - const { tagId, setTagId } = useContext(TagIdContext); - const goToNewTopic = () => { - routePage('new-topic', 'topics'); + routePage('new-topic', taggedTopicIds); }; const goToSeveralTopic = () => { - routePage(`topics/${tagId}`, tagId); + routePage(`topics/${taggedTopicIds.join(',')}`, taggedTopicIds.join(',')); }; const onTagCancel = () => { setTagTopics([]); - setTagId([]); }; const getAndSetDataFromServer = async () => { @@ -43,13 +40,11 @@ const Home = () => { useEffect(() => { getAndSetDataFromServer(); - setCoordinates([{ latitude: String(37.5055), longitude: String(127.0509) }]); + setCoordinates([ + { latitude: String(37.5055), longitude: String(127.0509) }, + ]); }, []); - useEffect(() => { - if (topics.length === 0) setTagId([]); - }, [topics]); - return ( @@ -79,6 +74,8 @@ const Home = () => { topicPinCount={topic.pinCount} tagTopics={tagTopics} setTagTopics={setTagTopics} + taggedTopicIds={taggedTopicIds} + setTaggedTopicIds={setTaggedTopicIds} /> @@ -87,7 +84,7 @@ const Home = () => { diff --git a/frontend/src/pages/NewPin.tsx b/frontend/src/pages/NewPin.tsx index b43c9c3f..238dc505 100644 --- a/frontend/src/pages/NewPin.tsx +++ b/frontend/src/pages/NewPin.tsx @@ -14,6 +14,7 @@ import { NewPinValuesType } from '../types/FormValues'; import useFormValues from '../hooks/useFormValues'; import { MarkerContext } from '../context/MarkerContext'; import { CoordinatesContext } from '../context/CoordinatesContext'; +import { useLocation } from 'react-router-dom'; const NewPin = () => { const [topic, setTopic] = useState(null); @@ -53,7 +54,7 @@ const NewPin = () => { e.preventDefault(); await postToServer(); - routePage(`/topics/${topic?.id}`, [topic!.id]); + routePage(`/topics/${topic?.id}`, [topic!.id]); // 선택된 마커가 있으면 마커를 지도에서 제거 if (clickedMarker) { clickedMarker.setMap(null); diff --git a/frontend/src/pages/NewTopic.tsx b/frontend/src/pages/NewTopic.tsx index f6a121c6..a52bec69 100644 --- a/frontend/src/pages/NewTopic.tsx +++ b/frontend/src/pages/NewTopic.tsx @@ -4,13 +4,10 @@ import Flex from '../components/common/Flex'; import Space from '../components/common/Space'; import Button from '../components/common/Button'; import Textarea from '../components/common/Textarea'; -import { styled } from 'styled-components'; import { postApi } from '../utils/postApi'; import useNavigator from '../hooks/useNavigator'; import { NewTopicFormValuesType } from '../types/FormValues'; import useFormValues from '../hooks/useFormValues'; -import { useContext, useEffect } from 'react'; -import { TagIdContext } from '../store/TagId'; import { useLocation } from 'react-router-dom'; const NewTopic = () => { @@ -21,10 +18,7 @@ const NewTopic = () => { topics: [], }); const { routePage } = useNavigator(); - - const { state } = useLocation(); - - const { tagId, setTagId } = useContext(TagIdContext); + const { state: taggedIds } = useLocation(); const goToBack = () => { routePage(-1); @@ -34,38 +28,30 @@ const NewTopic = () => { e.preventDefault(); const topicId = await postToServer(); - if (topicId) routePage(`/topics/${topicId}`, [Number(topicId)]); + if (topicId) routePage(`/topics/${topicId}`); }; const postToServer = async () => { - if (state === 'topics') { - const response = await postApi('/topics/merge', { - image: formValues.image, - name: formValues.name, - description: formValues.description, - topics: tagId, - }); - - const location = response.headers.get('Location'); - - if (location) { - const topicIdFromLocation = location.split('/')[2]; - return topicIdFromLocation; - } - } else { - const response = await postApi('/topics/new', { - image: formValues.image, - name: formValues.name, - description: formValues.description, - pins: tagId, - }); - - const location = response.headers.get('Location'); - - if (location) { - const topicIdFromLocation = location.split('/')[2]; - return topicIdFromLocation; - } + const response = + taggedIds?.length > 1 && typeof taggedIds !== 'string' + ? await postApi('/topics/merge', { + image: formValues.image, + name: formValues.name, + description: formValues.description, + topics: taggedIds, + }) + : await postApi('/topics/new', { + image: formValues.image, + name: formValues.name, + description: formValues.description, + pins: typeof taggedIds === 'string' ? taggedIds.split(',') : [], + }); + + const location = response.headers.get('Location'); + + if (location) { + const topicIdFromLocation = location.split('/')[2]; + return topicIdFromLocation; } }; @@ -153,25 +139,4 @@ const NewTopic = () => { ); }; -const TopicIcon = styled(Input)` - display: none; - position: relative; - - & + label { - display: flex; - justify-content: center; - align-items: center; - width: 52px; - height: 52px; - font-size: 36px; - border: 1px solid ${({ theme }) => theme.color.black}; - border-radius: 4px; - cursor: pointer; - } - - &:checked + label { - background-color: ${({ theme }) => theme.color.primary}; - } -`; - export default NewTopic; diff --git a/frontend/src/pages/SelectedTopic.tsx b/frontend/src/pages/SelectedTopic.tsx index 4755e338..6a2c787b 100644 --- a/frontend/src/pages/SelectedTopic.tsx +++ b/frontend/src/pages/SelectedTopic.tsx @@ -10,7 +10,6 @@ import theme from '../themes'; import PinDetail from './PinDetail'; import { getApi } from '../utils/getApi'; import { MergeOrSeeTogether } from '../components/MergeOrSeeTogether'; -import { TagIdContext } from '../store/TagId'; import { CoordinatesContext } from '../context/CoordinatesContext'; import useNavigator from '../hooks/useNavigator'; @@ -49,20 +48,18 @@ const ToggleButton = styled.button<{ isCollapsed: boolean }>` const SelectedTopic = () => { const { topicId } = useParams(); - const { state } = useLocation(); const [tagPins, setTagPins] = useState([]); const [searchParams, setSearchParams] = useSearchParams(); const [topicDetail, setTopicDetail] = useState([]); const [selectedPinId, setSelectedPinId] = useState(null); + const [taggedPinIds, setTaggedPinIds] = useState([]); const { routePage } = useNavigator(); const { setCoordinates } = useContext(CoordinatesContext); const [isOpen, setIsOpen] = useState(true); - const { tagId, setTagId } = useContext(TagIdContext); - const onClickSetSelectedPinId = (pinId: number) => { setSelectedPinId(pinId); @@ -82,12 +79,11 @@ const SelectedTopic = () => { }; const onClickConfirm = () => { - routePage('/new-topic', 'pins'); + routePage('/new-topic', taggedPinIds.join(',')); }; const onTagCancel = () => { setTagPins([]); - setTagId([]); }; useEffect(() => { @@ -100,10 +96,6 @@ const SelectedTopic = () => { setIsOpen(true); }, [searchParams]); - useEffect(() => { - if (tagPins.length === 0) setTagId([]); - }, [tagPins, state]); - const togglePinDetail = () => { setIsOpen(!isOpen); }; @@ -151,6 +143,8 @@ const SelectedTopic = () => { topicId={topic.id} tagPins={tagPins} setTagPins={setTagPins} + taggedPinIds={taggedPinIds} + setTaggedPinIds={setTaggedPinIds} /> ))} diff --git a/frontend/src/store/TagId.tsx b/frontend/src/store/TagId.tsx deleted file mode 100644 index 15f0a9b7..00000000 --- a/frontend/src/store/TagId.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { createContext, useState } from 'react'; - -export interface TagIdContextProps { - tagId: number[]; - setTagId: (value: number[]) => void; -} - -export const TagIdContext = createContext({ - tagId: [], - setTagId: () => {}, -}); - -const TagContextProvider = (props: { children: React.ReactNode }) => { - const [tagId, setTagId] = useState([]); - - const contextValue: TagIdContextProps = { - tagId, - setTagId - }; - - return ( - - {props.children} - - ); -}; - -export default TagContextProvider; From bf5655142bc4bddfd567a00b582106e0d6d2e8fe Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 2 Aug 2023 13:47:09 +0900 Subject: [PATCH 2/3] =?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/components/PinPreview/index.tsx | 1 - frontend/src/components/TopicCard/index.tsx | 1 - frontend/src/pages/NewPin.tsx | 1 - frontend/src/pages/SelectedTopic.tsx | 2 +- 4 files changed, 1 insertion(+), 4 deletions(-) diff --git a/frontend/src/components/PinPreview/index.tsx b/frontend/src/components/PinPreview/index.tsx index f39c4cee..d96db9d8 100644 --- a/frontend/src/components/PinPreview/index.tsx +++ b/frontend/src/components/PinPreview/index.tsx @@ -3,7 +3,6 @@ import Flex from '../common/Flex'; import Space from '../common/Space'; import Text from '../common/Text'; import useNavigator from '../../hooks/useNavigator'; -import { useContext } from 'react'; export interface PinPreviewProps { pinTitle: string; diff --git a/frontend/src/components/TopicCard/index.tsx b/frontend/src/components/TopicCard/index.tsx index 5b08eccf..43352b0a 100644 --- a/frontend/src/components/TopicCard/index.tsx +++ b/frontend/src/components/TopicCard/index.tsx @@ -2,7 +2,6 @@ import { styled } from 'styled-components'; import Flex from '../common/Flex'; import Text from '../common/Text'; import useNavigator from '../../hooks/useNavigator'; -import { useContext, useState } from 'react'; export interface TopicCardProps { topicId: number; diff --git a/frontend/src/pages/NewPin.tsx b/frontend/src/pages/NewPin.tsx index 238dc505..ef3ec61c 100644 --- a/frontend/src/pages/NewPin.tsx +++ b/frontend/src/pages/NewPin.tsx @@ -14,7 +14,6 @@ import { NewPinValuesType } from '../types/FormValues'; import useFormValues from '../hooks/useFormValues'; import { MarkerContext } from '../context/MarkerContext'; import { CoordinatesContext } from '../context/CoordinatesContext'; -import { useLocation } from 'react-router-dom'; const NewPin = () => { const [topic, setTopic] = useState(null); diff --git a/frontend/src/pages/SelectedTopic.tsx b/frontend/src/pages/SelectedTopic.tsx index 6a2c787b..c2876d4e 100644 --- a/frontend/src/pages/SelectedTopic.tsx +++ b/frontend/src/pages/SelectedTopic.tsx @@ -5,7 +5,7 @@ import Flex from '../components/common/Flex'; import PinPreview from '../components/PinPreview'; import TopicInfo from '../components/TopicInfo'; import { TopicInfoType } from '../types/Topic'; -import { useLocation, useParams, useSearchParams } from 'react-router-dom'; +import { useParams, useSearchParams } from 'react-router-dom'; import theme from '../themes'; import PinDetail from './PinDetail'; import { getApi } from '../utils/getApi'; From c0e4c5eee6ba17f01c464ffe0e9aee27c381694f Mon Sep 17 00:00:00 2001 From: semnil5202 Date: Wed, 2 Aug 2023 14:04:57 +0900 Subject: [PATCH 3/3] =?UTF-8?q?fix:=20li=20=ED=83=9C=EA=B7=B8=20=EB=82=B4?= =?UTF-8?q?=EB=B6=80=20li=20=ED=83=9C=EA=B7=B8=20=EC=98=A4=EB=A5=98=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/src/pages/SelectedTopic.tsx | 82 ++++++++++++++-------------- 1 file changed, 40 insertions(+), 42 deletions(-) diff --git a/frontend/src/pages/SelectedTopic.tsx b/frontend/src/pages/SelectedTopic.tsx index c2876d4e..dcb987ec 100644 --- a/frontend/src/pages/SelectedTopic.tsx +++ b/frontend/src/pages/SelectedTopic.tsx @@ -113,48 +113,46 @@ const SelectedTopic = () => { onClickConfirm={onClickConfirm} onClickClose={onTagCancel} /> -
    - {topicDetail.length !== 0 ? ( - topicDetail.map((topic) => { - return ( -
  • - - {topic.pins.map((pin) => ( -
  • { - onClickSetSelectedPinId(Number(pin.id)); - setIsOpen(true); - }} - > - - -
  • - ))} - - ); - }) - ) : ( - <> - )} -
+ {topicDetail.length !== 0 ? ( + topicDetail.map((topic) => { + return ( +
    + + {topic.pins.map((pin) => ( +
  • { + onClickSetSelectedPinId(Number(pin.id)); + setIsOpen(true); + }} + > + + +
  • + ))} +
+ ); + }) + ) : ( + <> + )} {selectedPinId && ( <>