From 6fdbf48f09eef20e99bf78554e8f9e822a79a8f5 Mon Sep 17 00:00:00 2001 From: kangbeomjoon Date: Mon, 30 Sep 2024 16:06:58 +0900 Subject: [PATCH 1/3] Started mission10-FE --- pages/api/axios.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/api/axios.js b/pages/api/axios.js index d976c7996..35ab3a0bd 100644 --- a/pages/api/axios.js +++ b/pages/api/axios.js @@ -1,7 +1,7 @@ import axios from "axios"; const instance = axios.create({ - baseURL: "http://localhost:3000/", // 모든 요청의 기본 URL 설정 + baseURL: "http://localhost:3000/", }); export default instance; From 5db6ea2dba1290a54e88870b58e09c1bb6328430 Mon Sep 17 00:00:00 2001 From: kangbeomjoon Date: Tue, 1 Oct 2024 10:14:32 +0900 Subject: [PATCH 2/3] Started mission10 --- api/api.js | 97 ++++++ components/ArticleList.js | 2 +- components/BestArticleList.js | 2 +- components/CommentList.js | 2 +- components/CommentOptions.js | 101 ++++++ components/CommentOptions.module.css | 93 +++++ components/DeleteConfirmModal.js | 25 ++ components/DeleteConfirmModal.module.css | 57 +++ components/Footer.js | 102 +++--- components/Footer.module.css | 25 +- components/Modal.js | 19 + components/Modal.module.css | 36 ++ components/Nav.js | 69 +++- components/Nav.module.css | 45 ++- components/ProductOptions.js | 106 ++++++ components/ProductOptions.module.css | 50 +++ components/SignupCompleteModal.js | 19 + components/SignupCompleteModal.module.css | 44 +++ lib/axios.js | 23 ++ next.config.mjs | 8 + package-lock.json | 403 +++++++++++++--------- package.json | 5 +- pages/_app.js | 19 +- pages/api/axios.js | 7 - pages/folder/folder.js | 5 + pages/items/[itemId].js | 307 ++++++++++++++++ pages/items/create.js | 170 +++++++++ pages/items/index.js | 161 +++++++++ pages/login.js | 186 ++++++++++ pages/market.js | 0 pages/registArticle.js | 2 +- pages/signup.js | 262 ++++++++++++++ public/Img_inquiry_empty.png | Bin 0 -> 6265 bytes public/btn-heart.png | Bin 2270 -> 0 bytes public/eye.png | Bin 0 -> 690 bytes public/eye2.png | Bin 0 -> 827 bytes public/heart_filled.svg | 0 public/ic_check.png | Bin 0 -> 635 bytes public/logo.png | Bin 0 -> 6373 bytes public/placeholder-image.jpg | Bin 0 -> 441016 bytes public/product_reply.svg | 3 + styles/CreateItem.module.css | 63 ++++ styles/ItemDetail.module.css | 220 ++++++++++++ styles/Products.module.css | 130 +++++++ styles/global.css | 60 ++++ styles/login.module.css | 188 ++++++++++ styles/signup.module.css | 202 +++++++++++ 47 files changed, 3074 insertions(+), 244 deletions(-) create mode 100644 api/api.js create mode 100644 components/CommentOptions.js create mode 100644 components/CommentOptions.module.css create mode 100644 components/DeleteConfirmModal.js create mode 100644 components/DeleteConfirmModal.module.css create mode 100644 components/Modal.js create mode 100644 components/Modal.module.css create mode 100644 components/ProductOptions.js create mode 100644 components/ProductOptions.module.css create mode 100644 components/SignupCompleteModal.js create mode 100644 components/SignupCompleteModal.module.css create mode 100644 lib/axios.js delete mode 100644 pages/api/axios.js create mode 100644 pages/folder/folder.js create mode 100644 pages/items/[itemId].js create mode 100644 pages/items/create.js create mode 100644 pages/items/index.js create mode 100644 pages/login.js create mode 100644 pages/market.js create mode 100644 pages/signup.js create mode 100644 public/Img_inquiry_empty.png delete mode 100644 public/btn-heart.png create mode 100644 public/eye.png create mode 100644 public/eye2.png create mode 100644 public/heart_filled.svg create mode 100644 public/ic_check.png create mode 100644 public/logo.png create mode 100644 public/placeholder-image.jpg create mode 100644 public/product_reply.svg create mode 100644 styles/CreateItem.module.css create mode 100644 styles/ItemDetail.module.css create mode 100644 styles/Products.module.css create mode 100644 styles/login.module.css create mode 100644 styles/signup.module.css diff --git a/api/api.js b/api/api.js new file mode 100644 index 000000000..254440ab4 --- /dev/null +++ b/api/api.js @@ -0,0 +1,97 @@ +// api.js +import axiosInstance from "../lib/axios"; + +// 사용자 정보 가져오기 +export const fetchCurrentUser = async () => { + const response = await axiosInstance.get("/users/me"); + return response.data; +}; + +// 상품 목록 가져오기 +export const fetchProducts = async (params) => { + const response = await axiosInstance.get("/products", { params }); + return response.data; +}; + +// 상품 등록 +export const createProduct = async (productData) => { + const response = await axiosInstance.post("/products", productData); + return response.data; +}; + +// 상품 상세 정보 가져오기 +export const fetchProductById = async (productId) => { + const response = await axiosInstance.get(`/products/${productId}`); + return response.data; +}; + +// 상품 수정 +export const editProduct = async (productId, productData) => { + const response = await axiosInstance.patch( + `/products/${productId}`, + productData + ); + return response.data; +}; + +// 상품 삭제 +export const deleteProduct = async (productId) => { + const response = await axiosInstance.delete(`/products/${productId}`); + return response.data; +}; + +// 상품 댓글 목록 가져오기 +export const fetchProductComments = async (productId, params) => { + const response = await axiosInstance.get(`/products/${productId}/comments`, { + params, + }); + return response.data; +}; + +// 상품 댓글 작성 +export const postProductComment = async ({ productId, content }) => { + const response = await axiosInstance.post(`/products/${productId}/comments`, { + content, + }); + return response.data; +}; + +// 댓글 수정 +export const editComment = async (commentId, content) => { + const response = await axiosInstance.patch(`/comments/${commentId}`, { + content, + }); + return response.data; +}; + +// 댓글 삭제 +export const deleteComment = async (commentId) => { + const response = await axiosInstance.delete(`/comments/${commentId}`); + return response.data; +}; + +// 상품 좋아요 추가 +export const postProductFavorite = async (productId) => { + const response = await axiosInstance.post(`/products/${productId}/favorite`); + return response.data; +}; + +// 상품 좋아요 취소 +export const deleteProductFavorite = async (productId) => { + const response = await axiosInstance.delete( + `/products/${productId}/favorite` + ); + return response.data; +}; + +// 회원가입 요청 +export const signUp = async (userData) => { + const response = await axiosInstance.post("/auth/signUp", userData); + return response.data; +}; + +// 로그인 요청 +export const logIn = async (userData) => { + const response = await axiosInstance.post("/auth/signIn", userData); + return response.data; +}; diff --git a/components/ArticleList.js b/components/ArticleList.js index 719bdc939..5f8d18081 100644 --- a/components/ArticleList.js +++ b/components/ArticleList.js @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import axios from "@/pages/api/axios"; +import axios from "@/lib/axios.js"; import Article from "./Article"; import Image from "next/image"; import Link from "next/link"; diff --git a/components/BestArticleList.js b/components/BestArticleList.js index d81590d2f..bfb13c777 100644 --- a/components/BestArticleList.js +++ b/components/BestArticleList.js @@ -1,5 +1,5 @@ import { useState, useEffect } from "react"; -import axios from "@/pages/api/axios"; +import axios from "@/lib/axios.js"; import BestArticleCard from "./BestArticleCard"; import styles from "./BestArticleList.module.css"; diff --git a/components/CommentList.js b/components/CommentList.js index 9429942a7..79d5ffead 100644 --- a/components/CommentList.js +++ b/components/CommentList.js @@ -2,7 +2,7 @@ import styles from "@/styles/CommentList.module.css"; import { useState } from "react"; import Image from "next/image"; -import axios from "@/pages/api/axios"; +import axios from "@/lib/axios.js"; export default function Comment({ comment }) { const [isOpen, setIsOpen] = useState(false); diff --git a/components/CommentOptions.js b/components/CommentOptions.js new file mode 100644 index 000000000..c2726d421 --- /dev/null +++ b/components/CommentOptions.js @@ -0,0 +1,101 @@ +// components/CommentOptions.js + +import React, { useState } from "react"; +import Image from "next/image"; +import styles from "./CommentOptions.module.css"; + +const CommentOptions = ({ comments, onEdit, onDelete }) => { + const [editingCommentId, setEditingCommentId] = useState(null); + const [editedContent, setEditedContent] = useState(""); + + const handleEditClick = (comment) => { + setEditingCommentId(comment.id); + setEditedContent(comment.content); + }; + + const handleSaveClick = (commentId) => { + onEdit(commentId, editedContent); + setEditingCommentId(null); + }; + + const handleCancelClick = () => { + setEditingCommentId(null); + setEditedContent(""); + }; + + const [showOptions, setShowOptions] = useState(null); + + const handleCommentOptions = (commentId) => { + setShowOptions((prev) => (prev === commentId ? null : commentId)); + }; + + return ( +
+ {comments.map((comment) => ( +
+
+ 프로필 +
+
+ {editingCommentId === comment.id ? ( + // 인라인 편집 폼 +
+