diff --git a/public/images/logo.png b/public/images/logo.png new file mode 100644 index 00000000..8556cb3c Binary files /dev/null and b/public/images/logo.png differ diff --git a/src/components/Button/Button.tsx b/src/components/Button/Button.tsx new file mode 100644 index 00000000..ac5996e2 --- /dev/null +++ b/src/components/Button/Button.tsx @@ -0,0 +1,18 @@ +import { ButtonHTMLAttributes, PropsWithChildren } from 'react'; +import { css } from '@emotion/react'; + +export type ButtonProps = ButtonHTMLAttributes & PropsWithChildren; + +export function Button({ children, ...props }: ButtonProps) { + return ( + + ); +} + +const buttonCss = css` + padding: 12px 32px; + font-size: 20px; + height: 54px; +`; diff --git a/src/components/Button/index.ts b/src/components/Button/index.ts new file mode 100644 index 00000000..fe9c53c5 --- /dev/null +++ b/src/components/Button/index.ts @@ -0,0 +1 @@ +export { Button } from './Button'; diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx new file mode 100644 index 00000000..28418533 --- /dev/null +++ b/src/components/Footer/Footer.tsx @@ -0,0 +1,77 @@ +import Link from 'next/link'; +import { css } from '@emotion/react'; + +import { FIRST_ROW_FOOTER_INFOS, SECOND_ROW_FOOTER_INFOS } from '~/constant/footer'; +import { colors } from '~/styles/colors'; + +export function Footer() { + return ( + + ); +} + +const footerCss = css` + background-color: ${colors.black800}; + padding: 0 20px; + width: 100vw; +`; + +const footerInfoWrapper = css` + max-width: 1240px; + margin: 0 auto; + display: flex; + flex-direction: column; + height: 218px; + justify-content: center; + align-items: center; +`; + +const rowCss = css` + display: flex; + gap: 40px; +`; + +const rowGapCss = css` + margin-top: 16px; +`; + +const linkCss = css` + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25.2px; /* 140% */ + letter-spacing: -0.18px; + color: ${colors.gray100}; +`; + +const copyrightCss = css` + font-size: 18px; + font-style: normal; + font-weight: 500; + line-height: 25.2px; /* 140% */ + letter-spacing: -0.18px; + color: ${colors.gray200}; + margin-top: 40px; +`; diff --git a/src/components/Footer/index.ts b/src/components/Footer/index.ts new file mode 100644 index 00000000..65e2506f --- /dev/null +++ b/src/components/Footer/index.ts @@ -0,0 +1 @@ +export { Footer } from './Footer'; diff --git a/src/components/GNB/GNB.tsx b/src/components/GNB/GNB.tsx new file mode 100644 index 00000000..c6ff91a5 --- /dev/null +++ b/src/components/GNB/GNB.tsx @@ -0,0 +1,100 @@ +import Image from 'next/image'; +import Link from 'next/link'; +import { useRouter } from 'next/router'; +import { css } from '@emotion/react'; + +import { Button } from '~/components/Button'; +import { GNB_MENU_NAME, GNBMenu } from '~/constant/gnb'; +import { colors } from '~/styles/colors'; + +const LOGO_IMAGE = `/images/logo.png`; + +function ApplyButton({ menu }: { menu: GNBMenu }) { + return ( + + ); +} + +export function GNB() { + const { pathname } = useRouter(); + const getActiveLinkcss = (menu: GNBMenu) => { + if (pathname.startsWith(menu.href)) { + return activeLinkCss; + } + return inActiveLinkCss; + }; + return ( + + ); +} + +const navCss = css` + background-color: ${colors.black800}; + position: fixed; + padding: 0 20px; + top: 0; + left: 0; + z-index: 9998; + width: 100vw; +`; + +const navWrapperCss = css` + max-width: 1240px; + display: flex; + justify-content: space-between; + align-items: center; + height: 72px; + margin: 0 auto; +`; + +const menuContainerCss = css` + display: flex; + gap: 60px; +`; + +const menuCss = css` + margin: auto 0; +`; + +const activeLinkCss = css` + color: ${colors.yellow500}; +`; + +const inActiveLinkCss = css` + color: ${colors.white}; +`; + +const linkCss = css` + font-size: 1.25rem; + font-weight: 500; + line-height: 150%; /* 30px */ + letter-spacing: -0.2px; +`; + +const applyButtonCss = css` + background-color: ${colors.yellow500}; + color: ${colors.black800}; +`; diff --git a/src/components/GNB/index.ts b/src/components/GNB/index.ts new file mode 100644 index 00000000..f0886146 --- /dev/null +++ b/src/components/GNB/index.ts @@ -0,0 +1 @@ +export { GNB } from './GNB'; diff --git a/src/constant/depromeet.ts b/src/constant/depromeet.ts index a93631ab..0dc6c269 100644 --- a/src/constant/depromeet.ts +++ b/src/constant/depromeet.ts @@ -1,8 +1,9 @@ -export const DEPROMEET_EMAIL = 'depromeet@gmail.com'; +export const DEPROMEET_EMAIL = 'mailto:depromeet@gmail.com'; export const DEPROMEET_MEDIUM = 'https://depromeet.medium.com/'; export const DEPROMEET_FACEBOOK = 'https://www.facebook.com/depromeet/'; export const DEPROMEET_INSTAGRAM = 'https://www.instagram.com/depromeet/'; export const DEPROMEET_GITHUB = 'https://github.com/depromeet/'; export const DEPROMEET_BEHANCE = 'https://www.behance.net/Depromeet'; -export const KAKAO_PLUS_FRIEND = 'http://pf.kakao.com/_xoxmcxed'; +export const DEPROMEET_KAKAO_PLUS_FRIEND = 'http://pf.kakao.com/_xoxmcxed'; +export const DEPROMEET_LINKEDIN = 'https://www.linkedin.com/company/depromeet/'; diff --git a/src/constant/footer.ts b/src/constant/footer.ts new file mode 100644 index 00000000..f4d9d981 --- /dev/null +++ b/src/constant/footer.ts @@ -0,0 +1,22 @@ +import { + DEPROMEET_BEHANCE, + DEPROMEET_EMAIL, + DEPROMEET_GITHUB, + DEPROMEET_INSTAGRAM, + DEPROMEET_KAKAO_PLUS_FRIEND, + DEPROMEET_LINKEDIN, + DEPROMEET_MEDIUM, +} from '~/constant/depromeet'; + +export const FIRST_ROW_FOOTER_INFOS = [ + { name: 'Instagram', href: DEPROMEET_INSTAGRAM }, + { name: 'Behance', href: DEPROMEET_BEHANCE }, + { name: 'Github', href: DEPROMEET_GITHUB }, + { name: 'Medium', href: DEPROMEET_MEDIUM }, + { name: 'LinkedIn', href: DEPROMEET_LINKEDIN }, +]; + +export const SECOND_ROW_FOOTER_INFOS = [ + { name: 'Kakao channel @depromeet', href: DEPROMEET_KAKAO_PLUS_FRIEND }, + { name: 'E-mail depromeet@gmail', href: DEPROMEET_EMAIL }, +]; diff --git a/src/constant/gnb.ts b/src/constant/gnb.ts new file mode 100644 index 00000000..55ba3f21 --- /dev/null +++ b/src/constant/gnb.ts @@ -0,0 +1,28 @@ +export type GNBMenu = { + name: 'About' | '모집안내' | '프로젝트' | '지원하기'; + href: '/about' | '/recruit' | '/project' | '/'; + type: 'text' | 'button'; +}; +// TODO: 지원하기 url 넣기 +export const GNB_MENU_NAME: GNBMenu[] = [ + { + name: 'About', + href: '/about', + type: 'text', + }, + { + name: '모집안내', + href: '/recruit', + type: 'text', + }, + { + name: '프로젝트', + href: '/project', + type: 'text', + }, + { + name: '지원하기', + href: '/', + type: 'button', + }, +]; diff --git a/src/hooks/useRecordPageView.ts b/src/hooks/useRecordPageView.ts index d1bee6e4..40eea48e 100644 --- a/src/hooks/useRecordPageView.ts +++ b/src/hooks/useRecordPageView.ts @@ -3,7 +3,7 @@ import { useRouter } from 'next/router'; import { GA_ID, IS_PRODUCTION } from '~/constant/common'; -export const useRecordPageView = () => { +export function useRecordPageView() { const router = useRouter(); useEffect(() => { @@ -16,7 +16,7 @@ export const useRecordPageView = () => { if (IS_PRODUCTION) router.events.off('routeChangeComplete', recordPageView); }; }, [router.events]); -}; +} declare global { interface Window { diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index 71be5ecc..0f5d8585 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -4,6 +4,8 @@ import { useRouter } from 'next/router'; import { ThemeProvider } from '@emotion/react'; import { domMax, LazyMotion } from 'framer-motion'; +import { Footer } from '~/components/Footer'; +import { GNB } from '~/components/GNB'; import { BASE_URL } from '~/constant/common'; import { useRecordPageView } from '~/hooks/useRecordPageView'; import GlobalStyle from '~/styles/globalStyle'; @@ -26,12 +28,15 @@ export default function App({ Component, pageProps }: AppProps & InitialProps) { + +