Skip to content

Commit

Permalink
Merge pull request #288 from junghwa1996/Next-양정화-sprint9
Browse files Browse the repository at this point in the history
[양정화] sprint9
  • Loading branch information
jyh0521 authored Nov 26, 2024
2 parents 8d163dd + f54a263 commit f709d34
Show file tree
Hide file tree
Showing 109 changed files with 5,818 additions and 3,820 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

# production
/build
example.http

# misc
.DS_Store
Expand All @@ -33,3 +34,6 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts

# React Component Preview
previewConfig.json
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/pages/api-reference/create-next-app).

## Getting Started

Expand All @@ -18,23 +18,23 @@ Open [http://localhost:3000](http://localhost:3000) with your browser to see the

You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.

[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
[API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.

The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/pages/building-your-application/routing/api-routes) instead of React pages.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
This project uses [`next/font`](https://nextjs.org/docs/pages/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.

## Learn More

To learn more about Next.js, take a look at the following resources:

- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
- [Learn Next.js](https://nextjs.org/learn-pages-router) - an interactive Next.js tutorial.

You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!

## Deploy on Vercel

The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.

Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/pages/building-your-application/deploying) for more details.
114 changes: 114 additions & 0 deletions components/layout/Footer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import styled from 'styled-components';
import { Container } from '../../styles/Common.styles';
import font from '@/styles/fontStyle.styles';
import { media } from '@/styles/media.styles';

const ICON_FACEBOOK = '/ic_facebook.png';
const ICON_INSTAGRAM = '/ic_instagram.png';
const ICON_TWITTER = '/ic_twitter.png';
const ICON_YOUTUBE = '/ic_youtube.png';
import Link from 'next/link';
import IconLink from '../shared/IconLink';

const snsLink = [
{
id: 1,
name: 'facebook',
to: 'https://www.facebook.com/',
src: ICON_FACEBOOK,
},
{ id: 2, name: 'twitter', to: 'https://x.com/', src: ICON_TWITTER },
{
id: 3,
name: 'youtube',
to: 'https://www.youtube.com/',
src: ICON_YOUTUBE,
},
{
id: 4,
name: 'instagram',
to: 'https://www.instagram.com/',
src: ICON_INSTAGRAM,
},
];

function Footer() {
return (
<StyledFooter>
<FooterContainer>
<FooterItem className='text-copyright'>
<p>©codeit - 2024</p>
</FooterItem>
<FooterItem className='link-page'>
<Link href='/privacy'>Privacy Policy</Link>
<Link href='/faq'>FAQ</Link>
</FooterItem>
<FooterItem className='link-sns'>
{snsLink.map((sns) => (
<IconLink key={sns.id} to={sns.to} name={sns.name} src={sns.src} />
))}
</FooterItem>
</FooterContainer>
</StyledFooter>
);
}

export default Footer;

export const StyledFooter = styled.footer`
height: 16rem;
padding-top: 3.2rem;
background-color: var(--gray-900);
`;

export const FooterContainer = styled(Container)`
display: flex;
justify-content: space-between;
${media.mo`
flex-wrap: wrap;
gap: 2.5rem 0;
justify-content: center;
`}
`;

export const FooterItem = styled.div`
${font('16')}
${media.mo`
flex-basis: 100%;
`}
&.text-copyright {
${media.mo`
order: 2;
flex: 1;
`}
p {
color: var(--gray-400);
${media.mo`
color: #676767;
`}
}
}
&.link-page {
display: flex;
gap: 3rem;
${media.mo`
flex: 1;
flex-basis: 50%;
`}
a {
color: var(--gray-200);
${media.mo`
color: #cfcfcf;
`}
}
}
&.link-sns {
display: flex;
gap: 1.2rem;
${media.mo`
flex: 1;
flex-basis: 50%;
justify-content: flex-end;
`}
}
`;
64 changes: 64 additions & 0 deletions components/layout/Headers.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { useRouter } from 'next/router';
import styled from 'styled-components';
import useDeviceType from '@/utils/deviceType';
import { useAuth } from '@/context/AuthContext';

import { Container } from '@/styles/Common.styles';
import { media } from '@/styles/media.styles';

import Navigation from './Navigation';
import ProfileImage from '../shared/ProfileImage';
import Logo from '../shared/Logo';
import Button from '../shared/Button';

function Headers() {
const router = useRouter();
const deviceType = useDeviceType();
const { hasLogin } = useAuth();

return (
<HeaderContainer>
<StlyedContainer>
<Logo size='sm' />
{router.pathname !== '/' && <Navigation />}
{hasLogin ? (
<>
<ProfileImage />
</>
) : (
<Button
href='/login'
color='blue'
size={deviceType === 'mo' ? 'small' : 'medium'}>
로그인
</Button>
)}
</StlyedContainer>
</HeaderContainer>
);
}

export default Headers;

const HeaderContainer = styled.div`
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 7rem;
border-bottom: 1px solid #dfdfdf;
background-color: #fff;
z-index: 999;
`;

const StlyedContainer = styled(Container)`
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
gap: 3.2rem;
${media.mo`
gap: 0.8rem;
`}
`;
52 changes: 52 additions & 0 deletions components/layout/Navigation.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useRouter } from 'next/router';
import Link from 'next/link';
import styled from 'styled-components';

import font from '@/styles/fontStyle.styles';
import { media } from '@/styles/media.styles';

function Navigation() {
const router = useRouter();

const navLinks = [
{ name: '자유게시판', path: '/boards' },
{ name: '중고마켓', path: '/items' },
];

return (
<StyledGnb>
{navLinks.map((link) => {
const isActive = router.pathname === link.path;

return (
<li key={link.name}>
<StyledLink href={link.path} $isActive={isActive} shallow>
{link.name}
</StyledLink>
</li>
);
})}
</StyledGnb>
);
}

export default Navigation;

const StyledGnb = styled.ul`
display: flex;
flex: 1;
`;

const StyledLink = styled(Link)<{ $isActive: boolean }>`
color: ${({ $isActive }) =>
$isActive ? 'var(--blue-100)' : 'var(--gray-600)'};
padding: 2.1rem 1.5rem;
${font('18b')}
text-align: center;
text-decoration: none;
${media.mo`
padding: 2.1rem 0.4rem;
${font('16b')}
`}
`;
93 changes: 93 additions & 0 deletions components/pages/boards/BoardCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import styled from 'styled-components';
import { formatRegistrationDate } from '@/utils/format';

import font from '@/styles/fontStyle.styles';
import { media } from '@/styles/media.styles';

import UserInfo from '@/components/shared/UserInfo';
const IMG_BEST = '/img_badge.svg';

interface Writer {
nickname: string;
}

export interface BoardCardProps {
title: string;
likeCount: number;
updatedAt: string;
image: string;
writer: Writer;
}

function BoardCard({
title = '타이틀',
likeCount = 0,
updatedAt = '',
writer = { nickname: '닉네임' },
image = '',
}: BoardCardProps) {
return (
<BoardCardContainer>
<BoardCardBestBege src={IMG_BEST} alt='Best 뱃지' />
<BoardCardTitleArea>
<h3>{title}</h3>
<BoardCardProdImagesArea>
<img src={image} alt='상품 이미지' />
</BoardCardProdImagesArea>
</BoardCardTitleArea>
<UserInfo wide>
<UserInfo.UserName userName={writer.nickname} />
<UserInfo.Heart count={likeCount} size='sm' wide />
<UserInfo.Date date={formatRegistrationDate(updatedAt)} />
</UserInfo>
</BoardCardContainer>
);
}

const BoardCardContainer = styled.div`
background-color: var(--gray-50);
border-radius: 0.8rem;
padding: 0 2.4rem 1.6rem;
width: 38.4rem;
height: auto;
${media.ta`
width: 34rem;
`}
${media.mo`
width: 34.3rem;
`}
`;

const BoardCardBestBege = styled.img`
width: 10.2rem;
height: 3rem;
margin-bottom: 1.6rem;
`;

const BoardCardTitleArea = styled.div`
display: flex;
gap: 0.8rem;
justify-content: space-between;
margin-bottom: 1.8rem;
${media.tamo`
margin-bottom: 4rem;
gap: 4rem;
`}
h3 {
${font('20sb')}
${media.tamo`
${font('18sb')}
`}
}
`;

export const BoardCardProdImagesArea = styled.div`
width: 7.2rem;
height: 7.2rem;
border-radius: 0.6rem;
overflow: hidden;
border: 1px solid var(--gray-200);
`;

export default BoardCard;
Loading

0 comments on commit f709d34

Please sign in to comment.