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

[고한샘] sprint10 #663

Open
wants to merge 28 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
87e3f15
chore: 머지 후 브랜치 삭제 github action 추가
withyj-codeit Sep 3, 2023
1472169
Initial commit from Create Next App
withyj-codeit Nov 23, 2023
671d4d5
reset
hanseulhee Oct 10, 2023
14baca2
fix: 머지 후 브랜치 삭제 github action 수정
hanseulhee Oct 10, 2023
8d163dd
env: workflows 폴더로 이동
hanseulhee Oct 10, 2023
cf2e3df
Merge branch 'Next.js-고한샘' of https://github.com/codeit-bootcamp-fron…
gohansaem1 May 30, 2024
398ac6c
fix: 불필요파일 제거, 필요아이콘 세팅
gohansaem1 May 30, 2024
a04698a
test css, 라우팅, 검색쿼리
gohansaem1 May 30, 2024
8f535bd
배포 브랜치 변경용 커밋
gohansaem1 May 30, 2024
921aec0
배포 중 오류 해결
gohansaem1 May 30, 2024
f56d696
배포 중 오류 해결 2
gohansaem1 May 30, 2024
2ee994e
배포 중 오류 해결 3
gohansaem1 May 30, 2024
d80a89a
모르겠다
gohansaem1 May 30, 2024
5d76a22
.
gohansaem1 May 30, 2024
6f12196
.
gohansaem1 May 31, 2024
6cdee27
..
gohansaem1 May 31, 2024
af57418
버셀, 빌드코드제거
gohansaem1 May 31, 2024
c0b2b55
dfd
gohansaem1 May 31, 2024
c5cd127
게시판 글 가져오기 api 확인
gohansaem1 May 31, 2024
069ebed
feat: 검색 기능 구현
gohansaem1 May 31, 2024
c59c0eb
feat: 드롭다운 버튼 기능구현
gohansaem1 May 31, 2024
365a414
feat: 공통 헤더 컴포넌트 추가
gohansaem1 May 31, 2024
b690f65
feat:설정페이지 테마기능 구현
gohansaem1 May 31, 2024
d3bb2bb
fix: header css 수정, 구글폰트 적용하기
gohansaem1 May 31, 2024
eb445b0
fix: 네트리파이 빌드오류
gohansaem1 May 31, 2024
b3d39fd
fix: 타입스크립트 변환
gohansaem1 Jun 3, 2024
fbb8fcf
feat/ 글쓰기 버튼 컴포넌트, addboard 링크 연결
gohansaem1 Jun 6, 2024
270af41
feat: 개별 게시글 페이지, 댓글 달기 기본레이아웃 구성 구현
gohansaem1 Jun 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "next/core-web-vitals"
}
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
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).

## Getting Started

First, run the development server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

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`.

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.

This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

## 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.

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.
15 changes: 15 additions & 0 deletions components/BlueButton.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
.write {
width: 84px;
height: 42px;
border-radius: 8px;
background-color: #3692ff;
font-family: Pretendard;
Copy link
Collaborator

Choose a reason for hiding this comment

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

해당 버튼에만 Pretendard가 적용되어야 하나요?
그런게 아니라면 font는 최상위 node에서 사용하는게 좋을것 같습니다 ㅎ

font-size: 16px;
font-weight: 600;
color: #ffffff;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
border: none;
}
9 changes: 9 additions & 0 deletions components/BlueButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import styles from "@/components/BlueButton.module.css";

export default function BlueButton({ type = "", children }) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

타입스크립트를 사용한다면 타입을 꼭 지정해주세요!

return (
<button type={type} className={styles.write}>
{children}
</button>
);
}
22 changes: 22 additions & 0 deletions components/BoardItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";

interface Article {
id?: number;
title?: string;
content?: string;
}

interface BoardItemProps {
article: Article;
}

const BoardItem: React.FC<BoardItemProps> = ({ article }) => {
return (
<div>
<h2>{article.title}</h2>
<p>{article.content}</p>
</div>
);
};

export default BoardItem;
11 changes: 11 additions & 0 deletions components/Container.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
.container {
width: 100%;
max-width: 1020px;
margin-right: auto;
margin-left: auto;
}

.page.container {
margin-top: 80px;
margin-bottom: 80px;
}
21 changes: 21 additions & 0 deletions components/Container.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import styles from "@/components/Container.module.css";
import React from "react";

interface ContainerProps {
className?: string;
page?: boolean;
children: React.ReactNode;
}

const Container: React.FC<ContainerProps> = ({
className = "",
page = false,
children,
}) => {
const classNames = `${styles.container} ${
page ? styles.page : ""
} ${className}`;

return <div className={classNames}>{children}</div>;
};
export default Container;
39 changes: 39 additions & 0 deletions components/DropDown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React, { useState } from "react";

interface DropDownProps {
order?: string;
onChangeOrder: (order: string) => void;
}

const DropDown: React.FC<DropDownProps> = ({
order = "recent",
onChangeOrder,
}) => {
const [isDropDown, setIsDropDown] = useState(false);
const [localOrder, setLocalOrder] = useState(order);

const handleDropDown = () => {
setIsDropDown(!isDropDown);
};
const handleOptionClick = (order: string) => {
setLocalOrder(order);
onChangeOrder(order);
setIsDropDown(false);
};

return (
<>
<div onClick={handleDropDown}>
{localOrder == "recent" ? "최신순" : "좋아요순"}
</div>
{isDropDown && (
<div>
<div onClick={() => handleOptionClick("recent")}>최신순</div>
<div onClick={() => handleOptionClick("like")}>좋아요순</div>
</div>
)}
</>
);
};

export default DropDown;
41 changes: 41 additions & 0 deletions components/Header.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.header {
padding: 0 200px;
height: 70px;
border-bottom: 1px solid #dfdfdf;
position: fixed;
top: 0;
left: 0;
max-width: 1920px;
z-index: 1000;
width: 100%;
background-color: white;
}

.container {
display: flex;

align-items: center;
justify-content: space-between;
}

.leftNav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 33px;
}

.leftNav div {
font-family: Pretendard;
font-size: 18px;
font-weight: 700;
line-height: 21.48px;
text-align: center;
}

.rightNav {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
}
43 changes: 43 additions & 0 deletions components/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import Link from "next/link";
import styles from "./Header.module.css";
import Container from "./Container";
import Image from "next/image";

export default function Header() {
return (
<header className={styles.header}>
<Container className={styles.container}>
<div className={styles.leftNav}>
<Link href="/">
<Image
src="/icon/header-logoIcon.png"
alt="Home Logo"
width={153}
height={51}
priority
/>
</Link>
<Link href="/boards">
<div>자유게시판</div>
</Link>
<Link href="/market">
<div>중고마켓</div>
</Link>
</div>
<div className={styles.rightNav}>
<Link href="/join">
<Image
src="/icon/profile-login-icon.png"
alt="user profile"
width={40}
height={40}
/>
</Link>
<Link href="/setting">
<div>설정</div>
</Link>
</div>
</Container>
</header>
);
}
41 changes: 41 additions & 0 deletions components/SearchForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { useRouter } from "next/router";
import { ChangeEvent, FormEvent, useState } from "react";

interface SearchFormProps {
keyword?: string;
onChangeKeyword?: (keyword: string) => void;
}

const SearchForm: React.FC<SearchFormProps> = ({
keyword = "",
onChangeKeyword,
}) => {
const [value, setValue] = useState(keyword);
const router = useRouter();

const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
setValue(e.target.value);
};

const handleSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();

if (!value) {
router.push("/boards");
onChangeKeyword(" ");
Copy link
Collaborator

Choose a reason for hiding this comment

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

empty string이 아니라 공백으로 처리하는게 맞나요?

return;
}
if (onChangeKeyword) {
onChangeKeyword(value);
}
router.push(`boards?keyword=${value}`);
};
return (
<form onSubmit={handleSubmit}>
<input name="keyword" value={value} onChange={handleChange} />
<button type="submit">검색</button>
</form>
);
};

export default SearchForm;
27 changes: 27 additions & 0 deletions lib/ThemeContext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { createContext, useContext, useEffect, useState } from "react";

export const ThemeContext = createContext();

export default function ThemeProvider({ children }) {
const [theme, setTheme] = useState("white");
useEffect(() => {
document.body.classList.add(theme);
return () => {
document.body.classList.remove(theme);
};
}, [theme]);

return (
<ThemeContext.Provider value={{ theme, setTheme }}>
{children}
</ThemeContext.Provider>
);
}

export function useTheme() {
const themeContext = useContext(ThemeContext);
if (!themeContext) {
throw new Error("ThemeContext 안에서 써야 합니다.");
}
return themeContext;
}
7 changes: 7 additions & 0 deletions lib/axios.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import axios from "axios";

const instance = axios.create({
baseURL: "https://panda-market-api.vercel.app",
});

export default instance;
6 changes: 6 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}

module.exports = nextConfig
Loading