diff --git a/public/icons/ic_back.svg b/public/icons/ic_back.svg new file mode 100644 index 000000000..253a47d7b --- /dev/null +++ b/public/icons/ic_back.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/app/board/[id]/BoardDetail.jsx b/src/app/board/[id]/BoardDetail.jsx index cceb65384..051001afd 100644 --- a/src/app/board/[id]/BoardDetail.jsx +++ b/src/app/board/[id]/BoardDetail.jsx @@ -1,12 +1,14 @@ "use client"; import ActionDropdown from "@/components/ActionDropdown"; +import { API_BASE_URL } from "@/lib/api"; import Image from "next/image"; import { useRouter } from "next/navigation"; import React from "react"; const BoardDetail = ({ data }) => { const router = useRouter(); + const handleModify = () => { router.push( `/board/new?id=${data.id}&title=${encodeURIComponent( @@ -16,17 +18,15 @@ const BoardDetail = ({ data }) => { )}&author=${encodeURIComponent(data.author)}` ); }; + const handleDelete = async () => { try { - const res = await fetch(`http://localhost:4000/posts/${data.id}`, { + const res = await fetch(`${API_BASE_URL}/posts/${data.id}`, { method: "DELETE", // header 필요해? // 오답노트: 나중에 인가시에 필요 }); - if (!res.ok) { - alert("게시글 삭제에 실패했습니다."); - console.error(res.statusText); - } + if (!res.ok) throw new Error(`delete failed: ${res.statusText}`); alert("삭제가 완료되었습니다."); router.push("/board"); @@ -34,13 +34,14 @@ const BoardDetail = ({ data }) => { console.error(err); } }; + return ( -
+
-
{data.title}
+
{data.title}
-
+
{ />
-
{data.author}
-
{data.createdAt.split("T")[0].replace(/-/g, ".")}
+
{data.author}
+
+ {data.createdAt.split("T")[0].replace(/-/g, ". ")} +
-
+
Mark this post {data.likes}

-
{data.content}
+
{data.content}
); }; diff --git a/src/app/board/[id]/page.jsx b/src/app/board/[id]/page.jsx index 379dfc628..a37dea5e1 100644 --- a/src/app/board/[id]/page.jsx +++ b/src/app/board/[id]/page.jsx @@ -1,11 +1,22 @@ import React from "react"; import BoardDetail from "./BoardDetail"; import Comments from "@/app/components/comments"; +import { API_BASE_URL } from "@/lib/api"; +import { notFound } from "next/navigation"; const BoardDetailPage = async ({ params }) => { - const { id } = await params; - const res = await fetch(`http://localhost:4000/posts/${id}`); - const post = await res.json(); + const { id } = await params; + let post; + try { + const res = await fetch(`${API_BASE_URL}/posts/${id}`); + + if (!res.ok) notFound(); + + post = await res.json(); + } catch (err) { + console.err("fetch failed: ", err); + return <>게시물 로드 중 문제가 발생했습니다.; + } return (
diff --git a/src/app/board/_components/BestItem.jsx b/src/app/board/_components/BestItem.jsx index fcca7e02f..269cd1b7c 100644 --- a/src/app/board/_components/BestItem.jsx +++ b/src/app/board/_components/BestItem.jsx @@ -4,15 +4,15 @@ import React from "react"; const BestItem = ({ post }) => { const isoDate = post.createdAt; - const formatted = isoDate.split("T")[0].replace(/-/g, "."); + const formatted = isoDate.split("T")[0].replace(/-/g, ". "); return ( -
-
{post.title}
+
+
{post.title}
post thumbnail { className="border border-gray-200 rounded-md" />
-
+
-
{post.author}
-
+
{post.author}
+
Mark this post { {post.likes}
-
{formatted}
+
{formatted}
); diff --git a/src/app/board/_components/BoardBest.jsx b/src/app/board/_components/BoardBest.jsx index a08c8043c..4daf0b2e0 100644 --- a/src/app/board/_components/BoardBest.jsx +++ b/src/app/board/_components/BoardBest.jsx @@ -1,16 +1,20 @@ import React from "react"; import BestItem from "./BestItem"; +import { API_BASE_URL } from "@/lib/api"; const BoardBest = async () => { const res = await fetch( - "http://localhost:4000/posts?_sort=likes&_order=asc&_limit=3" + `${API_BASE_URL}/posts?_sort=likes&_order=asc&_limit=3` ); const posts = await res.json(); return ( -
- {posts.map((post) => ( - - ))} +
+
베스트 게시글
+
+ {posts.map((post) => ( + + ))} +
); }; diff --git a/src/app/board/_components/BoardItem.jsx b/src/app/board/_components/BoardItem.jsx index ee622d20b..ff515c337 100644 --- a/src/app/board/_components/BoardItem.jsx +++ b/src/app/board/_components/BoardItem.jsx @@ -6,7 +6,7 @@ const BoardItem = ({ post }) => { return (
-
{post.title}
+
{post.title}
{ className="border border-gray-200 rounded-md" />
-
+
{ height={24} alt="click likes" /> -
{post.author}
-
{post.createdAt.split("T")[0].replace(/-/g, ".")}
+
{post.author}
+
+ {post.createdAt.split("T")[0].replace(/-/g, ". ")} +
-
+
click likes -
{post.likes}
+
{post.likes}

diff --git a/src/app/board/_components/BoardList.jsx b/src/app/board/_components/BoardList.jsx index 88a51b358..19a8a1df2 100644 --- a/src/app/board/_components/BoardList.jsx +++ b/src/app/board/_components/BoardList.jsx @@ -4,6 +4,7 @@ import React, { useEffect, useRef, useState } from "react"; import BoardItem from "./BoardItem"; import Button from "@/app/components/Button"; import Link from "next/link"; +import { API_BASE_URL } from "@/lib/api"; const BoardList = () => { const [posts, setPosts] = useState([]); @@ -16,11 +17,9 @@ const BoardList = () => { sort === "latest" ? "_sort=-createdAt" : "_sort=-likes"; try { - const res = await fetch(`http://localhost:4000/posts?${sortParams}`); + const res = await fetch(`${API_BASE_URL}/posts?${sortParams}`); - if (!res.ok) { - throw new Error("response error: ", res.statusText); - } + if (!res.ok) throw new Error(`get failed: ${res.statusText}`); const data = await res.json(); setPosts(data); @@ -39,7 +38,7 @@ const BoardList = () => { return (
-

게시글

+

게시글

diff --git a/src/app/board/new/BoardForm.jsx b/src/app/board/new/BoardForm.jsx index c2f20d4b3..1827f1701 100644 --- a/src/app/board/new/BoardForm.jsx +++ b/src/app/board/new/BoardForm.jsx @@ -1,6 +1,7 @@ "use client"; import Button from "@/app/components/Button"; +import { API_BASE_URL } from "@/lib/api"; import { useRouter, useSearchParams } from "next/navigation"; import React, { useState } from "react"; @@ -23,9 +24,9 @@ const BoardForm = () => { try { const apiUrl = isModifyMode - ? `http://localhost:4000/posts/${modifyId}` - : "http://localhost:4000/posts"; - const method = isModifyMode ? "PUT" : "POST"; + ? `${API_BASE_URL}/posts/${modifyId}` + : `${API_BASE_URL}/posts`; + const method = isModifyMode ? "PATCH" : "POST"; const res = await fetch(apiUrl, { method: method, diff --git a/src/app/components/comments/_components/Item.jsx b/src/app/components/comments/_components/Item.jsx index 5fc2de614..8638b2778 100644 --- a/src/app/components/comments/_components/Item.jsx +++ b/src/app/components/comments/_components/Item.jsx @@ -10,18 +10,18 @@ const Item = ({ data, onModify, onDelete }) => { const [modifyMode, setModifyMode] = useState(false); return ( -
+
{modifyMode ? ( -
- +