Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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: 1 addition & 2 deletions backend/prisma_back/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,6 @@ app.get(
where: { productId },
skip: lastId ? 1 : 0, //cursor 항목 제외
take: parseInt(limit),
cursor: lastId,
...(lastId && { cursor: { id: lastId } }), //lastId를 쿼리로 받으면 커서 사용.

//댓글에는 아직 favoriteCount가 없지만 일단 구현했습니다.(쿼리로 전달하지 말아주세요)
Expand Down Expand Up @@ -231,7 +230,7 @@ app.post(
const comment = await prisma.comment.create({
data: {
content,
article: {
product: {
connect: { id: productId },
},
},
Expand Down
9 changes: 8 additions & 1 deletion backend/prisma_back/http/comment.http
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# 게시글 댓글
GET http://localhost:3000/articles/733653fb-6a4d-4a0d-90ca-31de1072de91/comments
GET http://localhost:4000/articles/b717e4f5-159c-4ca8-81bb-a3397caaf387/comments

###

Expand Down Expand Up @@ -62,3 +62,10 @@ Content-Type: application/json
###

DELETE http://localhost:3000/products/comments/733653fb-6a4d-4a0d-90ca-31de1072de91



###

# 상품 댓글
GET http://localhost:4000/products/b8f11e76-0a9e-4b3f-bccf-8d9b4fbf331e/comments
2 changes: 1 addition & 1 deletion backend/prisma_back/http/products.http
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
GET http://localhost:3000/products
GET http://localhost:4000/products

###

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "public"."Product" ADD COLUMN "userName" TEXT NOT NULL DEFAULT '판매자판다';
1 change: 1 addition & 0 deletions backend/prisma_back/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ model Product {
name String
price Int
description String
userName String @default("판매자판다")
tags String[]
images String[]
favoriteCount Int @default(0)
Expand Down
32 changes: 31 additions & 1 deletion frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@
"lint": "eslint"
},
"dependencies": {
"next": "15.5.3",
"react": "19.1.0",
"react-dom": "19.1.0",
"next": "15.5.3"
"zustand": "^5.0.8"
},
"devDependencies": {
"@eslint/eslintrc": "^3",
"@tailwindcss/postcss": "^4",
"tailwindcss": "^4",
"eslint": "^9",
"eslint-config-next": "15.5.3",
"@eslint/eslintrc": "^3"
"tailwindcss": "^4"
}
}
15 changes: 15 additions & 0 deletions frontend/public/images/logo/logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
68 changes: 68 additions & 0 deletions frontend/src/api/Auth.js
Copy link
Collaborator

Choose a reason for hiding this comment

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

  1. .then((res) => res.data) 부분이 잘못됐어요!
    API 응답 구조는 { accessToken, refreshToken, user } 인데
    res.data를 하면 undefined가 반환됩니다.

  2. catch에서 에러 메시지(문자열)를 반환하는데,
    호출하는 쪽에서 res.accessToken을 기대하면 undefined 에러 발생!

Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
const url = "https://panda-market-api.vercel.app/";


export async function login(body){
const res = await fetch(`${url}/auth/signIn`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
})
.then((res) => {
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
return res.json();
})
.then((res) => res.data)
.catch((err)=> {
console.log(`에러: ${err.message}`);
return err.message;
});

return res;
}

export async function signup(body){
const res = await fetch(`${url}/auth/signUp`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
})
.then((res) => {
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
return res.json();
})
.then((res) => res.data)
.catch((err)=> {
console.log(`에러: ${err.message}`);
return err.message;
});

return res;
}

export async function getToken(refreshToken){
const body = {
refreshToken
}
const res = await fetch(`${url}/auth/refresh-token`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
})
.then((res) => {
if (!res.ok) {
throw new Error(`HTTP error! status: ${res.status}`);
}
return res.json();
})
.then((res) => res.data)
.catch((err)=> {
console.log(`에러: ${err.message}`);
return err.message;
});

return res;
}
83 changes: 64 additions & 19 deletions frontend/src/api/ProductService.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
//const url = 'https://panda-market-api-crud.vercel.app/products' //판다마켓 코드잇 api (사용시 result.list 경로 사용)
const url = 'http://localhost:4000/products'; //직접 만든 개발용 백엔드 로컬 주소입니다.
const url = 'http://localhost:4000'; //직접 만든 개발용 백엔드 로컬 주소입니다.
// const url = 'https://pandamarket-1.onrender.com/api/products' //Render 배포 백엔드 주소입니다.


//리스폰스 에러만 잡는 코드 (fetch를 써서 필요)
export async function resErrorCatch(res) {
if (!res.ok) {
//404, 500 에러는 리퀘스트 에러가 아니라 리스폰스 에러. fetch는 따로 처리해줘야 합니다.(axois는 같이 담아준다)
const errorMessage = await res.text();
throw new Error(`리스폰스 에러: ${res.status} - ${errorMessage}`); //수동으로 에러 던지기
}
}


//상품 목록 조회 - 요구사항
async function getProductList(page = 1, pagesize = 10, orderBy = 'recent', keyword = '') {
export async function getProductList(page = 1, pagesize = 10, orderBy = 'recent', keyword = '') {
const result = await fetch(
url + `?page=${page}&pageSize=${pagesize}&orderBy=${orderBy}&keyword=${keyword}`
`${url}/products?page=${page}&pageSize=${pagesize}&orderBy=${orderBy}&keyword=${keyword}`
)
.then(async (res) => {
await resErrorCatch(res); //fetch에서 404, 500 리스폰스 에러는 따로 처리
Expand All @@ -16,8 +27,8 @@ async function getProductList(page = 1, pagesize = 10, orderBy = 'recent', keywo
}

//상품 상세 조회 - 요구사항 (api만)
async function getProduct(id) {
const result = await fetch(url + `/${id}`)
export async function getProduct(id) {
const result = await fetch(`${url}/products/${id}`)
.then(async (res) => {
await resErrorCatch(res);
return res.json();
Expand All @@ -27,8 +38,8 @@ async function getProduct(id) {
}

//상품 등록 - 요구사항
async function createProduct(RqBody) {
const result = await fetch(url, {
export async function createProduct(RqBody) {
const result = await fetch(`${url}/products`, {
method: 'POST',
body: JSON.stringify(RqBody),
headers: { 'Content-Type': 'application/json' },
Expand All @@ -42,8 +53,8 @@ async function createProduct(RqBody) {
}

//상품 수정 - 요구사항 (api만)
async function patchProduct(id, RqBody) {
const result = await fetch(url + `/${id}`, {
export async function patchProduct(id, RqBody) {
const result = await fetch(`${url}/products/${id}`, {
method: 'PATCH',
body: JSON.stringify(RqBody),
headers: { 'Content-Type': 'application/json' },
Expand All @@ -57,8 +68,8 @@ async function patchProduct(id, RqBody) {
}

//상품 삭제 (api만)
async function deleteProduct(id) {
const result = await fetch(url + `/${id}`, {
export async function deleteProduct(id) {
const result = await fetch(`${url}/products/${id}`, {
method: 'DELETE',
})
.then(async (res) => {
Expand All @@ -69,13 +80,47 @@ async function deleteProduct(id) {
return result;
}

//리스폰스 에러만 잡는 코드 (fetch를 써서 필요)
async function resErrorCatch(res) {
if (!res.ok) {
//404, 500 에러는 리퀘스트 에러가 아니라 리스폰스 에러. fetch는 따로 처리해줘야 합니다.(axois는 같이 담아준다)
const errorMessage = await res.text();
throw new Error(`리스폰스 에러: ${res.status} - ${errorMessage}`); //수동으로 에러 던지기
}
export async function getComments(id) {
const result = await fetch(`${url}/products/${id}/comments`)
.then(async (res) => {
await resErrorCatch(res);
return res.json();
})
.catch((err) => console.log(err));
return result;
}

export async function createComment(id, body) {
const result = await fetch(`${url}/products/${id}/comments`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
})
.then(async (res) => {
await resErrorCatch(res);
return res.json();
})
.catch((err) => console.log(err));
return result;
}

export default { getProduct, getProductList, createProduct, patchProduct, deleteProduct };
export async function updateComment(id, body) {
const result = await fetch(`${url}/comments/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
})
.then(async (res) => {
await resErrorCatch(res);
return res.json();
})
.catch((err) => console.log(err));
return result;
}

export async function deleteComment(id) {
const result = await fetch(`${url}/comments/${id}`, {
method: 'DELETE'
})
return result;
}
2 changes: 1 addition & 1 deletion frontend/src/app/articles/[id]/page.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import backIcon from './ic_back.svg';

//스타일
import styles from './articlePage.module.css';
import InputForm from '@/components/molecules/Articles/InputForm/InputForm';
import InputForm from '@/components/molecules/InputForm/InputForm';
import Button from '@/components/Atoms/Button';
import useAsync from '@/hooks/useAsync';

Expand Down
3 changes: 3 additions & 0 deletions frontend/src/app/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
--Cool-Gray-500: #6B7280;
--Cool-Gray-400: #9CA3AF;
--Cool-Gray-200: #e5e7eb;
--Cool-Gray-100: #F3F4F6;
--Cool-Gray-50: #f9fafb;

/* Secondary */
Expand All @@ -46,6 +47,8 @@

/* Primary color */
--brand-blue: #3692ff;
--hover-blue: #1967d6;
--focus-blue: #1251aa;

/* Layout dimensions */
--header-height: 70px;
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/items/[id]/ic_back.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions frontend/src/app/items/[id]/ic_heart.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions frontend/src/app/items/[id]/ic_more.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions frontend/src/app/items/[id]/ic_noComment.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading