Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
7ea4495
docs: update readme
sprint-edu Apr 2, 2025
a7a56a2
navbar. useUrl이 작동은 되는데 에러 발생.
yewonlee1211 Jul 7, 2025
f58a119
노트북 작업. 스타일 위주
yewonlee1211 Jul 8, 2025
f12fd5f
footer 적용 완료
yewonlee1211 Jul 7, 2025
e7c7336
자유게시물 best 하는중
yewonlee1211 Jul 9, 2025
4213150
데탑에서 합침
yewonlee1211 Jul 9, 2025
3754137
best 게시글 불러오기 완료
yewonlee1211 Jul 13, 2025
73afc23
hearts 컴포넌트 제작
yewonlee1211 Jul 14, 2025
1f0fa33
article 페이지 완료(아마도..)
yewonlee1211 Jul 16, 2025
e8afdd5
제품 상세 페이지 진행. (아직 수정, 삭제 기능 없음)
yewonlee1211 Jul 16, 2025
af39eb6
게시글 post 정상 작동
yewonlee1211 Jul 16, 2025
fd657f3
백엔드 수정에 맞춰서 article 일부 수정
yewonlee1211 Jul 17, 2025
66a6b17
하트 카운팅 함수 생성, 적용. 날짜 형식 함수 생성, 적용
yewonlee1211 Jul 17, 2025
bb54173
베스트 섹션 css 조정
yewonlee1211 Jul 17, 2025
d5e1926
customButtonSquare에 valid 프롭 추가
yewonlee1211 Jul 17, 2025
5922d16
드롭다운 스타일 완성, 게시글 등록 페이지 완성
yewonlee1211 Jul 17, 2025
2c39bae
댓글 입력 유효성 검사 로직 추가
yewonlee1211 Jul 17, 2025
75c233d
댓글 등록 성공
yewonlee1211 Jul 17, 2025
1448d92
댓글 수정 기능 추가
yewonlee1211 Jul 17, 2025
e3cb791
댓글 삭제 기능 추가, 댓글에 변동 있을시 refetch 코드 추가
yewonlee1211 Jul 18, 2025
224ac64
게시글 삭제 기능 추가
yewonlee1211 Jul 18, 2025
a12f9f0
게시글 수정 기능 추가(세션스토리지 이용)
yewonlee1211 Jul 18, 2025
a8b1f10
7차 미션 완료
yewonlee1211 Jul 18, 2025
01fc4d6
회원가입, 로그인 post 기능, 액세스토큰 로컬스토리지 저장 기능 구현
yewonlee1211 Jul 25, 2025
d81cbfe
로그인, 회원가입 페이지 css
yewonlee1211 Jul 28, 2025
560fb20
비밀번호 입력란 visible 아이콘 추가
yewonlee1211 Jul 28, 2025
1e75982
네비게이션바에 로그인 여부 표시하게 수정, items[id] 페이지 시작
yewonlee1211 Jul 29, 2025
7da707d
개별 페이지 ui 작성, comment 관련 컴포넌트를 article과 product 모두에서 쓸 수 있게 수정
yewonlee1211 Jul 29, 2025
7050358
push용 커밋
yewonlee1211 Aug 1, 2025
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
27 changes: 0 additions & 27 deletions .github/pull-request-template.md

This file was deleted.

31 changes: 0 additions & 31 deletions .github/workflows/auto-label-assign.yml

This file was deleted.

41 changes: 41 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

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

# env files (can opt-in for committing if needed)
.env*

# 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://nextjs.org/docs/pages/api-reference/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.js`. The page auto-updates as you edit the file.

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

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/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-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!

## 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/pages/building-your-application/deploying) for more details.
44 changes: 44 additions & 0 deletions components/ArticleItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import Image from "next/image";
import styles from "./ArticleItem.module.css";
import Hearts from "./Hearts";
import { useRouter } from "next/router";
import dateFormat from "@/utils/dateFormat";

export default function ArticleItem({ article }) {
const router = useRouter();
const updatedAt = dateFormat(article.updatedAt);

return (
<div
className={styles.article}
onClick={() => {
router.push(`/article/${article.id}`);
}}
>
<div className={styles.content}>
<div className={styles.title}>{article.title}</div>
<Image src={"/default.png"} alt="이미지" width={48} height={48} />
</div>
<div className={styles.info}>
<div className={styles.user}>
<Image
src={"/user-default-img.svg"}
className={styles.userImg}
alt="이미지"
width={24}
height={24}
/>
<div className={styles.nickname}>{article.nickname}</div>
<div className={styles.updatedAt}>{updatedAt}</div>
</div>
<Hearts
heartId={article.heartId}
articleId={article.id}
heartCount={article.heart_count}
isHearted={article.isHearted}
size="middle"
/>
</div>
</div>
);
}
104 changes: 104 additions & 0 deletions components/ArticleItem.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
.article {
width: 100%;

padding-bottom: 24px;

display: flex;
flex-direction: column;
gap: 16px;

border-bottom: var(--Cool-Gray-200, #e5e7eb) solid 1px;

cursor: pointer;
}

.content {
width: 100%;

display: flex;
flex-direction: row;
gap: 8px;
align-self: stretch;
}

.title {
flex-grow: 1;

color: var(--Cool-Gray-800, #1f2937);

/* pretendard/xl-20px-semibold */
font-family: Pretendard;
font-size: 20px;
font-style: normal;
font-weight: 600;
line-height: 32px; /* 160% */
}

.info {
width: 100%;
display: flex;
flex-direction: row;

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

.user {
display: flex;
flex-direction: row;
gap: 8px;

align-items: center;
}

.userImg {
background-color: #d1d5db;
border-radius: 50px;
}

.nickname {
color: var(--Secondary-600, #4b5563);

/* pretendard/md-14px-regular */
font-family: Pretendard;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 24px; /* 171.429% */
}

.updatedAt {
color: var(--Secondary-400, #9ca3af);

/* pretendard/md-14px-regular */
font-family: Pretendard;
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 24px; /* 171.429% */
}

.heart {
display: flex;
flex-direction: row;

gap: 8px;

align-items: center;
}

.heartBtn {
width: 24px;
height: 24px;
}

.heartCount {
color: var(--Secondary-500, #6b7280);

/* pretendard/lg-16px-regular */
font-family: Pretendard;
font-size: 16px;
font-style: normal;
font-weight: 400;
line-height: 26px; /* 162.5% */
}
70 changes: 70 additions & 0 deletions components/ArticleSection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import CustomButtonSquare from "./CustomButtonSquare";
import InputBox from "./InputBox";
import SortOption from "./SortOption";
import Image from "next/image";
import ArticleItem from "./ArticleItem";
import styles from "./ArticleSection.module.css";
import { useEffect, useState } from "react";
import axios from "axios";
import { useRouter } from "next/router";

export default function ArticleSection() {
const [keyword, setKeyword] = useState("");

const [articles, setArticles] = useState([]);
const [isLoading, setIsLoading] = useState(false);

const router = useRouter();

useEffect(() => {
async function getArticles(keyword) {
setIsLoading(true);
try {
const res = await axios.get("http://localhost:5000/article", {
params: { keyword, limit: 4 },
});
setArticles(res.data);
} catch (e) {
console.error(e);
} finally {
setIsLoading(false);
}
}

getArticles(keyword);
}, [keyword]);

let count = 1;

return (
<div className={styles.section}>
<div className={styles.header}>
<div className={styles.title}>게시글</div>
<CustomButtonSquare
text="글쓰기"
onClick={() => {
router.push(`/postArticle?mode=post`);
}}
valid={true}
/>
</div>
<div className={styles.option}>
<InputBox
keyword={keyword}
onChange={setKeyword}
placeholder={"검색할 상품을 입력해주세요"}
/>
<SortOption />
</div>
{!isLoading && (
<div className={styles.articleList}>
{articles.map((article) => {
const key = "a" + count;
count += 1;
return <ArticleItem key={key} article={article} />;
})}
</div>
)}
</div>
);
}
Loading