Skip to content

Commit

Permalink
feat: 메뉴바 공통 컴포넌트 구현 (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
seobbang authored Aug 14, 2024
1 parent 612fcfc commit 2ad7440
Show file tree
Hide file tree
Showing 13 changed files with 227 additions and 4 deletions.
3 changes: 3 additions & 0 deletions src/assets/icon/icon-home-mono.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions src/assets/icon/icon-kakaotalk.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/icon/icon-map-mono.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/assets/icon/icon-search-mono.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icon/icon-user-mono.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/assets/icon/icon-x-mono.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 6 additions & 1 deletion src/assets/icon/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
/// <reference types="vite-plugin-svgr/client" />
export { default as UnitripIcon } from './UNITRIP.svg?react';
export { default as HomeMonoIcon } from './icon-home-mono.svg?react';
export { default as MapMonoIcon } from './icon-map-mono.svg?react';
export { default as SearchMonoIcon } from './icon-search-mono.svg?react';
export { default as UserMonoIcon } from './icon-user-mono.svg?react';
export { default as XMonoIcon } from './icon-x-mono.svg?react';
export { default as KakaoTalkIcon } from './icon-kakaotalk.svg?react';
export { default as UnitripIcon } from './UNITRIP.svg?react';
export { default as HeartMonoIcon } from './icon-heart-mono.svg?react';
export { default as PinLocationMonoIcon } from './icon-pin-location-mono.svg?react';
export { default as ShieldCheckMonoIcon } from './icon-shield-check-mono.svg?react';
Expand Down
1 change: 0 additions & 1 deletion src/components/ExampleCommon.tsx

This file was deleted.

100 changes: 100 additions & 0 deletions src/components/LoginModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { css } from '@emotion/react';
import { createPortal } from 'react-dom';
import { Link } from 'react-router-dom';

import { KakaoTalkIcon, XMonoIcon } from '@/assets/icon';
import { COLORS, FONTS } from '@/styles/constants';

interface LoginModalProps {
onClick: () => void;
}

/**
* a와 b를 더한 결과를 반환
* @param {()=>void} props.onClick X(닫기) 버튼 클릭시 실행 함수
*/
const LoginModal = (props: LoginModalProps) => {
const { onClick } = props;

const portalContent = (
<div css={backgroundCss}>
<div css={container}>
<p css={titleCss}>카카오톡 로그인</p>
<p css={descriptionCss}>서비스 이용을 위해 로그인이 필요해요.</p>
<Link to="/login" css={linkCss}>
<KakaoTalkIcon />
카카오톡 로그인
</Link>
<button type="button" css={closeButtonCss} onClick={onClick}>
<XMonoIcon />
</button>
</div>
</div>
);

return createPortal(portalContent, document.body);
};

export default LoginModal;

const backgroundCss = css`
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
z-index: 999;
width: 100vw;
height: 100vh;
background-color: rgb(82 82 82 / 72%);
`;

const container = css`
display: flex;
flex-direction: column;
position: relative;
width: 35rem;
padding: 2rem;
border-radius: 1.2rem;
background-color: ${COLORS.white};
`;

const titleCss = css`
color: ${COLORS.gray9};
${FONTS.H4};
`;

const descriptionCss = css`
margin: 1.2rem 0 2rem;
color: ${COLORS.gray5};
${FONTS.Body3};
`;

const linkCss = css`
display: flex;
gap: 0.8rem;
justify-content: center;
align-items: center;
height: 5.6rem;
border-radius: 1.2rem;
background-color: ${COLORS.brand2};
color: ${COLORS.gray6};
${FONTS.Body2};
`;

const closeButtonCss = css`
position: absolute;
top: 2rem;
right: 2rem;
`;
86 changes: 86 additions & 0 deletions src/components/MenuBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { css } from '@emotion/react';
import { Link, useLocation } from 'react-router-dom';

import {
HomeMonoIcon,
MapMonoIcon,
SearchMonoIcon,
UserMonoIcon,
} from '@/assets/icon';
import { COLORS } from '@/styles/constants';

// 각 페이지 url 변경시 이 부분을 수정해주세요.
const PATH_MATCH = [
{ url: '/', name: '홈', icon: <HomeMonoIcon /> },
{ url: '/search', name: '검색', icon: <SearchMonoIcon /> },
{ url: '/map', name: '지도', icon: <MapMonoIcon /> },
{ url: '/mypage', name: '마이', icon: <UserMonoIcon /> },
];

const MenuBar = () => {
const { pathname } = useLocation();

const menuList = PATH_MATCH.map(({ url, name, icon }) => {
return (
<Link
key={url}
to={url}
className={pathname === url ? 'selected' : ''}
css={linkCss}>
{icon}
<span css={spanCss}>{name}</span>
</Link>
);
});

return (
<nav css={navCss}>
<div css={container}>{menuList}</div>
</nav>
);
};

export default MenuBar;

const navCss = css`
display: flex;
position: fixed;
bottom: 1.6rem;
width: 100vw;
`;

const container = css`
display: flex;
justify-content: space-between;
width: 100%;
padding: 1rem 3.2rem;
margin: 0 2rem;
border-radius: 99.9rem;
background-color: ${COLORS.brand1};
`;

const linkCss = css`
display: flex;
justify-content: space-between;
align-items: center;
flex-direction: column;
width: 5.6rem;
color: gray;
&.selected {
color: ${COLORS.white};
}
`;

const spanCss = css`
font-family: 'Apple SD Gothic Neo', sans-serif;
font-style: normal;
font-size: 1.1rem;
font-weight: 400;
line-height: 140%;
`;
6 changes: 6 additions & 0 deletions src/styles/reset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export const reset = css`
font-size: 62.5%;
}
html,
body {
min-width: 100vw;
min-height: 100%;
}
img,
picture,
video,
Expand Down
7 changes: 6 additions & 1 deletion src/views/Main/components/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { css } from '@emotion/react';

import { SearchMonoIcon, UnitripIcon } from '@/assets/icon';
import { COLORS } from '@/styles/constants';

const Header = () => {
return (
<header css={header}>
<UnitripIcon />
<button onClick={() => {}}>
<button onClick={() => {}} css={searchCss}>
<SearchMonoIcon />
</button>
</header>
Expand All @@ -24,3 +25,7 @@ const header = css`
height: 4.8rem;
padding: 0 2rem;
`;

const searchCss = css`
color: ${COLORS.gray5};
`;
2 changes: 2 additions & 0 deletions src/views/Main/pages/MainPage.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { css } from '@emotion/react';

import MenuBar from '@/components/MenuBar';
import { COLORS, FONTS } from '@/styles/constants';

import Header from '../components/Header';
Expand All @@ -26,6 +27,7 @@ const MainPage = () => {
<div css={graySpacing} />
<RecommendedTravel />
</main>
<MenuBar />
</>
);
};
Expand Down

0 comments on commit 2ad7440

Please sign in to comment.