Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feat] 버튼 컴포넌트, GNB, Footer 추가 #253

Merged
merged 10 commits into from
Sep 10, 2023
Binary file added public/images/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions src/components/Button/Button.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ButtonHTMLAttributes, PropsWithChildren } from 'react';
import { css } from '@emotion/react';

export type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & PropsWithChildren;

export function Button({ children, ...props }: ButtonProps) {
return (
<button {...props} css={buttonCss}>
{children}
</button>
);
}

const buttonCss = css`
padding: 12px 32px;
font-size: 20px;
height: 54px;
`;
1 change: 1 addition & 0 deletions src/components/Button/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Button } from './Button';
77 changes: 77 additions & 0 deletions src/components/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<footer css={footerCss}>
<div css={footerInfoWrapper}>
<ul css={rowCss}>
{FIRST_ROW_FOOTER_INFOS.map(footer => (
<li key={footer.name}>
<Link css={linkCss} href={footer.href}>
{footer.name}
</Link>
</li>
))}
</ul>
<ul css={[rowCss, rowGapCss]}>
{SECOND_ROW_FOOTER_INFOS.map(footer => (
<li key={footer.name}>
<Link css={linkCss} href={footer.href}>
{footer.name}
</Link>
</li>
))}
</ul>
<p css={copyrightCss}>© 2023 DEPROMEET. ALL RIGHTS RESERVED.</p>
</div>
</footer>
);
}

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;
`;
1 change: 1 addition & 0 deletions src/components/Footer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { Footer } from './Footer';
100 changes: 100 additions & 0 deletions src/components/GNB/GNB.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Button css={applyButtonCss}>
<Link css={linkCss} href={menu.href}>
{menu.name}
</Link>
</Button>
);
}

export function GNB() {
const { pathname } = useRouter();
const getActiveLinkcss = (menu: GNBMenu) => {
if (pathname.startsWith(menu.href)) {
return activeLinkCss;
}
return inActiveLinkCss;
};
return (
<nav css={navCss}>
<div css={navWrapperCss}>
<Link href={'/'}>
{<Image src={LOGO_IMAGE} alt="로고 이미지" width={240} height={30} />}
</Link>
<ul css={menuContainerCss}>
{GNB_MENU_NAME.map(menu => (
<li css={menuCss} key={menu.name}>
{menu.type === 'button' ? (
<ApplyButton menu={menu} />
) : (
<Link css={[linkCss, getActiveLinkcss(menu)]} href={menu.href}>
{menu.name}
</Link>
)}
</li>
))}
</ul>
</div>
</nav>
);
}

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};
`;
1 change: 1 addition & 0 deletions src/components/GNB/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { GNB } from './GNB';
5 changes: 3 additions & 2 deletions src/constant/depromeet.ts
Original file line number Diff line number Diff line change
@@ -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/';
22 changes: 22 additions & 0 deletions src/constant/footer.ts
Original file line number Diff line number Diff line change
@@ -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 },
];
28 changes: 28 additions & 0 deletions src/constant/gnb.ts
Original file line number Diff line number Diff line change
@@ -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',
},
];
4 changes: 2 additions & 2 deletions src/hooks/useRecordPageView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(() => {
Expand All @@ -16,7 +16,7 @@ export const useRecordPageView = () => {
if (IS_PRODUCTION) router.events.off('routeChangeComplete', recordPageView);
};
}, [router.events]);
};
}

declare global {
interface Window {
Expand Down
5 changes: 5 additions & 0 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand All @@ -26,12 +28,15 @@ export default function App({ Component, pageProps }: AppProps & InitialProps) {
<link rel="canonical" href={currentUrl} />
<meta property="og:url" content={currentUrl} />
</Head>
<GNB />
<GlobalStyle />
<Component {...pageProps} />
<Footer />
</LazyMotion>
</ThemeProvider>
);
}

App.getInitialProps = async ({ ctx }: AppContext) => {
const userAgent = ctx.req?.headers['user-agent'] || 'Desktop';

Expand Down
2 changes: 1 addition & 1 deletion src/styles/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export const colors = {
blue500: '#4FA0FF',
blue400: '#1B84FF',
blue300: '#0973EE',
yellow: '#E3FF3A',
yellow500: '#E3FF3A',
yellow400: '#C6E413',
yellow300: '#A1BB00',
} as const;
2 changes: 0 additions & 2 deletions src/styles/globalStyle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ const globalCss = css`
box-sizing: border-box;
word-break: keep-all;
word-wrap: break-word;

cursor: none !important;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

불편했는데 굳굳👍

}
}
`;
Loading