diff --git a/frontend/src/components/Layout/Navbar.tsx b/frontend/src/components/Layout/Navbar.tsx index 434d057f..cd732b90 100644 --- a/frontend/src/components/Layout/Navbar.tsx +++ b/frontend/src/components/Layout/Navbar.tsx @@ -4,7 +4,6 @@ import useNavigator from '../../hooks/useNavigator'; import Flex from '../common/Flex'; import Button from '../common/Button'; import Space from '../common/Space'; -import Text from '../common/Text'; import Home from '../../assets/nav_home.svg'; import SeeTogether from '../../assets/nav_seeTogether.svg'; import Favorite from '../../assets/nav_favorite.svg'; @@ -16,152 +15,72 @@ import FocusFavorite from '../../assets/nav_favorite_focus.svg'; import FocusAddMapOrPin from '../../assets/nav_addMapOrPin_focus.svg'; import FocusProfile from '../../assets/nav_profile_focus.svg'; import Modal from '../Modal'; -import { ModalContext } from '../../context/ModalContext'; -import { NavbarHighlightsContext } from '../../context/NavbarHighlightsContext'; -import { useParams } from 'react-router-dom'; -import SeeTogetherCounter from '../SeeTogetherCounter'; -import useKeyDown from '../../hooks/useKeyDown'; +import { + NavbarHighlightKeys, + NavbarHighlightsContext, +} from '../../context/NavbarHighlightsContext'; +import NavbarItem from './NavbarItem'; interface NavBarProps { $layoutWidth: '100vw' | '372px'; } -const Navbar = ({ $layoutWidth }: NavBarProps) => { - const { routePage } = useNavigator(); - const { topicId } = useParams(); - const { openModal, closeModal } = useContext(ModalContext); - const { navbarHighlights } = useContext(NavbarHighlightsContext); - const { elementRef: firstElement, onElementKeyDown: firstKeyDown } = - useKeyDown(); - const { elementRef: secondElement, onElementKeyDown: secondKeyDown } = - useKeyDown(); - const { elementRef: thirdElement, onElementKeyDown: thirdKeyDown } = - useKeyDown(); - const { elementRef: fourElement, onElementKeyDown: fourKeyDown } = - useKeyDown(); - const { elementRef: FifthElement, onElementKeyDown: FifthKeyDown } = - useKeyDown(); - - const goToHome = () => { - routePage('/'); - }; - - const goToSeeTogether = () => { - routePage('/see-together'); - }; - - const onClickAddMapOrPin = () => { - openModal('addMapOrPin'); - }; - - const goToFavorite = () => { - routePage('/favorite'); - }; - - const goToProfile = () => { - routePage('/my-page'); - }; - - const goToNewTopic = () => { - routePage('/new-topic'); - closeModal('addMapOrPin'); - }; +interface NavbarItemProps { + key: NavbarHighlightKeys; + label: string; + icon: React.FunctionComponent; + focusIcon: React.FunctionComponent; +} - const goToNewPin = () => { - routePage('/new-pin', topicId); - closeModal('addMapOrPin'); - }; +const NAV_ITEMS: NavbarItemProps[] = [ + { key: 'home', label: '홈', icon: Home, focusIcon: FocusHome }, + { + key: 'seeTogether', + label: '모아보기', + icon: SeeTogether, + focusIcon: FocusSeeTogether, + }, + { + key: 'addMapOrPin', + label: '추가하기', + icon: AddMapOrPin, + focusIcon: FocusAddMapOrPin, + }, + { + key: 'favorite', + label: '즐겨찾기', + icon: Favorite, + focusIcon: FocusFavorite, + }, + { + key: 'profile', + label: '내 정보', + icon: Profile, + focusIcon: FocusProfile, + }, +]; +const Navbar = ({ $layoutWidth }: NavBarProps) => { + const { routingHandlers } = useNavigator(); + const { navbarHighlights } = useContext(NavbarHighlightsContext); return ( - - {navbarHighlights.home ? : } - - 홈 - - - - - {navbarHighlights.seeTogether ? : } - - 모아보기 - - - - - - {navbarHighlights.addMapOrPin ? : } - - 추가하기 - - - - - {navbarHighlights.favorite ? : } - - 즐겨찾기 - - - - - {navbarHighlights.profile ? : } - - 내 정보 - - + {NAV_ITEMS.map((item) => { + return ( + routingHandlers[item.key]()} + $layoutWidth={$layoutWidth} + /> + ); + })} { left={$layoutWidth === '100vw' ? '' : `${372 / 2}px`} > - + 지도 추가하기 - + 핀 추가하기 @@ -212,25 +139,6 @@ const Wrapper = styled.nav<{ } `; -const IconWrapper = styled.div<{ $layoutWidth: '100vw' | '372px' }>` - position: relative; - display: flex; - flex-direction: column; - align-items: center; - width: 52px; - cursor: pointer; - margin-right: ${({ $layoutWidth }) => - $layoutWidth === '100vw' ? '48px' : '0'}; - - &:last-of-type { - margin-right: 0; - } - - @media (max-width: 1076px) { - margin-right: 0; - } -`; - const RouteButton = styled(Button)` box-shadow: 2px 4px 4px rgba(0, 0, 0, 0.5); `; diff --git a/frontend/src/components/Layout/NavbarItem.tsx b/frontend/src/components/Layout/NavbarItem.tsx new file mode 100644 index 00000000..6773d2cf --- /dev/null +++ b/frontend/src/components/Layout/NavbarItem.tsx @@ -0,0 +1,64 @@ +import { FunctionComponent } from 'react'; +import styled from 'styled-components'; +import useKeyDown from '../../hooks/useKeyDown'; +import Text from '../common/Text'; + +interface NavbarItemProps { + label: string; + icon: FunctionComponent; + focusIcon: FunctionComponent; + isHighlighted?: boolean; + onClick: () => void; + $layoutWidth: '100vw' | '372px'; +} + +const NavbarItem = ({ + label, + icon: Icon, + focusIcon: FocusIcon, + isHighlighted = false, + onClick, + $layoutWidth, +}: NavbarItemProps) => { + const { elementRef, onElementKeyDown } = useKeyDown(); + + return ( + + {isHighlighted ? : } + + {label} + + + ); +}; + +const IconWrapper = styled.div<{ $layoutWidth: '100vw' | '372px' }>` + position: relative; + display: flex; + flex-direction: column; + align-items: center; + width: 52px; + cursor: pointer; + margin-right: ${({ $layoutWidth }) => + $layoutWidth === '100vw' ? '48px' : '0'}; + + &:last-of-type { + margin-right: 0; + } + + @media (max-width: 1076px) { + margin-right: 0; + } +`; + +export default NavbarItem; diff --git a/frontend/src/hooks/useNavigator.ts b/frontend/src/hooks/useNavigator.ts index 957b1937..77f76cde 100644 --- a/frontend/src/hooks/useNavigator.ts +++ b/frontend/src/hooks/useNavigator.ts @@ -1,14 +1,38 @@ -import { useNavigate } from 'react-router-dom'; +import { useContext } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import { ModalContext } from '../context/ModalContext'; const useNavigator = () => { const navigator = useNavigate(); + const { openModal, closeModal } = useContext(ModalContext); + const { topicId } = useParams(); const routePage = (url: string | -1, value?: string | number | number[]) => { if (typeof url === 'string') navigator(url, { state: value }); if (url === -1) navigator(url); }; - return { routePage }; + return { + routingHandlers: { + home: () => routePage('/'), + seeTogether: () => routePage('/see-together'), + addMapOrPin: () => openModal('addMapOrPin'), + favorite: () => routePage('/favorite'), + profile: () => routePage('/my-page'), + newTopic: () => { + routePage('/new-topic'); + closeModal('addMapOrPin'); + }, + newPin: () => { + routePage('/new-pin', topicId); + closeModal('addMapOrPin'); + }, + goToPopularTopics: () => routePage('see-all/popularity'), + goToNearByMeTopics: () => routePage('see-all/near'), + goToLatestTopics: () => routePage('see-all/latest'), + }, + routePage, + }; }; export default useNavigator; diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index ee07737b..5ca139b9 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -1,5 +1,4 @@ import Space from '../components/common/Space'; -import Box from '../components/common/Box'; import useNavigator from '../hooks/useNavigator'; import { css, styled } from 'styled-components'; import useSetLayoutWidth from '../hooks/useSetLayoutWidth'; @@ -15,24 +14,16 @@ const TopicListContainer = lazy( ); const Home = () => { - const { routePage } = useNavigator(); + const { routingHandlers } = useNavigator(); + const { goToPopularTopics, goToLatestTopics, goToNearByMeTopics } = + routingHandlers; + const { markers, removeMarkers, removeInfowindows } = useContext(MarkerContext); + useSetLayoutWidth(FULLSCREEN); useSetNavbarHighlight('home'); - const goToPopularTopics = () => { - routePage('see-all/popularity'); - }; - - const goToNearByMeTopics = () => { - routePage('see-all/near'); - }; - - const goToLatestTopics = () => { - routePage('see-all/latest'); - }; - useEffect(() => { if (markers && markers.length > 0) { removeMarkers();