diff --git a/src/components/bottomBar/BottomBar.stories.tsx b/src/components/bottomBar/BottomBar.stories.tsx new file mode 100644 index 00000000..86d06340 --- /dev/null +++ b/src/components/bottomBar/BottomBar.stories.tsx @@ -0,0 +1,18 @@ +import { type Meta } from '@storybook/react'; + +import BottomBar from './BottomBar'; + +const meta: Meta = { + title: 'BottomBar', + component: BottomBar, +}; + +export default meta; + +export function Default() { + return ( +
+ +
+ ); +} diff --git a/src/components/bottomBar/BottomBar.tsx b/src/components/bottomBar/BottomBar.tsx new file mode 100644 index 00000000..a126cc68 --- /dev/null +++ b/src/components/bottomBar/BottomBar.tsx @@ -0,0 +1,118 @@ +import { type ComponentType } from 'react'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import { useSession } from 'next-auth/react'; +import { css, type Theme, useTheme } from '@emotion/react'; + +import HomeIcon from '~/components/bottomBar/HomeIcon'; +import MypageIcon from '~/components/bottomBar/MypageIcon'; +import QuestionIcon from '~/components/bottomBar/QuestionIcon'; +import useGetSurveyIdByUserStatus from '~/hooks/api/surveys/useGetSurveyIdByUserStatus'; + +interface TabItem { + text: string; + path: string; + icon: ComponentType<{ color?: string }>; +} + +const BottomBar = () => { + const theme = useTheme(); + const router = useRouter(); + + const currentPath = router.pathname; + const { data, 생성한_질문폼이_있는가 } = useCheckSurveyId(); + + const TAB_ITEMS: TabItem[] = [ + { + text: '홈', + path: '/gallery', + icon: HomeIcon, + }, + { + text: '질문폼', + path: 생성한_질문폼이_있는가 ? '/result' : '/survey/base', + icon: QuestionIcon, + }, + { + text: '내 명함', + path: `/dna/${data?.survey_id}`, + icon: MypageIcon, + }, + ]; + + const getIsSelected = (path: string | string[]) => { + if (Array.isArray(path)) return path.includes(currentPath); + + return path === currentPath; + }; + + const getIconColor = (path: string | string[]) => { + const isSelected = getIsSelected(path); + if (isSelected) return theme.colors.primary_300; + + return theme.colors.gray_300; + }; + + return ( + + ); +}; + +export default BottomBar; + +const BottomBarCss = (theme: Theme) => css` + position: fixed; + bottom: 0; + left: 0; + + display: flex; + gap: 86px; + align-items: center; + justify-content: center; + + width: 100vw; + height: 73px; + padding-top: 10px; + + background-color: ${theme.colors.white}; +`; + +const IconBoxCss = (theme: Theme) => css` + display: flex; + flex-direction: column; + gap: 8px; + align-items: center; + justify-content: center; + + text-decoration: none; + + span { + font-size: 12px; + font-weight: 400; + font-style: normal; + color: ${theme.colors.gray_300}; + text-align: center; + } +`; + +const selectedCss = (theme: Theme) => css` + span { + color: ${theme.colors.primary_300}; + } +`; + +const useCheckSurveyId = () => { + const { status } = useSession(); + + const { isLoading, data } = useGetSurveyIdByUserStatus({ enabled: status === 'authenticated' }); + const 생성한_질문폼이_있는가 = Boolean(data?.survey_id); + + return { isLoading, data, 생성한_질문폼이_있는가 }; +}; diff --git a/src/components/bottomBar/HomeIcon.tsx b/src/components/bottomBar/HomeIcon.tsx new file mode 100644 index 00000000..cb07d563 --- /dev/null +++ b/src/components/bottomBar/HomeIcon.tsx @@ -0,0 +1,21 @@ +import Svg from '~/components/svg/Svg'; + +interface Props { + color?: string; +} + +const HomeIcon = ({ color }: Props) => { + return ( + + + + + ); +}; + +export default HomeIcon; diff --git a/src/components/bottomBar/MypageIcon.tsx b/src/components/bottomBar/MypageIcon.tsx new file mode 100644 index 00000000..f2d711ce --- /dev/null +++ b/src/components/bottomBar/MypageIcon.tsx @@ -0,0 +1,20 @@ +import Svg from '~/components/svg/Svg'; + +interface Props { + color?: string; +} + +const MypageIcon = ({ color }: Props) => { + return ( + + + + ); +}; + +export default MypageIcon; diff --git a/src/components/bottomBar/QuestionIcon.tsx b/src/components/bottomBar/QuestionIcon.tsx new file mode 100644 index 00000000..ab6670f0 --- /dev/null +++ b/src/components/bottomBar/QuestionIcon.tsx @@ -0,0 +1,22 @@ +import Svg from '~/components/svg/Svg'; + +interface Props { + color?: string; +} + +const QuestionIcon = ({ color }: Props) => { + return ( + + + + + + ); +}; + +export default QuestionIcon; diff --git a/src/pages/gallery/index.page.tsx b/src/pages/gallery/index.page.tsx index f63eb7fc..22737b87 100644 --- a/src/pages/gallery/index.page.tsx +++ b/src/pages/gallery/index.page.tsx @@ -2,6 +2,7 @@ import { useState } from 'react'; import Link from 'next/link'; import { css } from '@emotion/react'; +import BottomBar from '~/components/bottomBar/BottomBar'; import Header from '~/components/header/MobileHeader'; import StaggerWrapper from '~/components/stagger/StaggerWrapper'; import Card from '~/features/gallery/Card'; @@ -52,6 +53,7 @@ function Gallery() { /> )} + ); } diff --git a/src/pages/index.page.tsx b/src/pages/index.page.tsx index 26f25dc0..e6e001f1 100644 --- a/src/pages/index.page.tsx +++ b/src/pages/index.page.tsx @@ -55,7 +55,6 @@ const headingWrapperCss = css` const titleCss = css` ${HEAD_2_BOLD} - margin-top: 80px; color: #fff; `; diff --git a/src/pages/survey/base.page.tsx b/src/pages/survey/base.page.tsx new file mode 100644 index 00000000..a8bfd766 --- /dev/null +++ b/src/pages/survey/base.page.tsx @@ -0,0 +1,51 @@ +import { type NextPage } from 'next'; +import Link from 'next/link'; +import { css, type Theme } from '@emotion/react'; + +import BottomBar from '~/components/bottomBar/BottomBar'; +import Button from '~/components/button/Button'; +import { HEAD_1 } from '~/styles/typo'; + +const SurveyBasePage: NextPage = () => { + return ( + <> +
+

+ 질문 폼을 생성하고 +
+ 동료에게 피드백을 요청해보세요 +

+ + + + +
+ + + + ); +}; + +export default SurveyBasePage; + +const mainCss = css` + position: relative; + + display: flex; + flex-direction: column; + align-items: center; + justify-content: space-between; + + height: 100dvh; + padding: 120px 0 130px; +`; + +const h1Css = (theme: Theme) => css` + ${HEAD_1}; + color: ${theme.colors.black}; + text-align: center; +`; + +const linkCss = css` + text-decoration: none; +`; diff --git a/src/pages/survey/create.page.tsx b/src/pages/survey/create.page.tsx index dff4ad7c..a4b54bce 100644 --- a/src/pages/survey/create.page.tsx +++ b/src/pages/survey/create.page.tsx @@ -2,6 +2,7 @@ import { useSession } from 'next-auth/react'; import { css, type Theme } from '@emotion/react'; import { useAtom, useAtomValue } from 'jotai'; +import BottomBar from '~/components/bottomBar/BottomBar'; import CTAButton from '~/components/button/CTAButton'; import Header from '~/components/header/Header'; import SEO from '~/components/SEO/SEO'; @@ -82,6 +83,7 @@ const CreateSurveyPage = () => { + ); @@ -102,10 +104,8 @@ const containerCss = css` const deleteButtonCss = (isDeleteMode: boolean, theme: Theme) => css` ${BODY_1} - color: ${isDeleteMode ? theme.colors.primary_200 : theme.colors.red}; ${isDeleteMode && 'text-decoration: underline;'} - transition: color 0.2s ease-in-out; &:disabled {