-
diff --git a/pages/addboard.tsx b/pages/addboard.tsx
new file mode 100644
index 00000000..3fb0333b
--- /dev/null
+++ b/pages/addboard.tsx
@@ -0,0 +1,120 @@
+import Button from "@/components/Button";
+import { ImgInput, Input } from "@/components/Input";
+import instance from "@/lib/api";
+import { createArticle } from "@/lib/Articles";
+import { GetServerSideProps } from "next";
+import { parseCookies, setCookie } from "nookies";
+import { useState } from "react";
+
+const InputAttributes = [
+ {
+ name: "title",
+ value: "",
+ placeholder: "제목을 입력해주세요",
+ label: "제목",
+ validation: "",
+ key: 1,
+ },
+ {
+ name: "content",
+ value: "",
+ placeholder: "내용을 입력해주세요",
+ label: "내용",
+ validation: "",
+ key: 2,
+ },
+];
+
+export const getServerSideProps: GetServerSideProps = async (ctx) => {
+ const cookies = parseCookies(ctx);
+ const accessToken = cookies.accessToken;
+ const refreshToken = cookies.refreshToken;
+ if (!accessToken) {
+ return {
+ redirect: {
+ destination: "/",
+ },
+ props: {},
+ };
+ }
+ try {
+ await instance.get(`/user/me`);
+ } catch (err: any) {
+ if (err.response?.status === 401) {
+ try {
+ const refreshRes = await instance.post(
+ `/auth/refresh-token`,
+ {},
+ { headers: { Cookie: `refreshToken=${refreshToken}` } }
+ );
+ const newAccessToken = refreshRes.data.accessToken;
+ setCookie(ctx, "accessToken", newAccessToken, {
+ path: "/",
+ httpOnly: true,
+ sameSite: "lax",
+ });
+ } catch {
+ return {
+ redirect: { destination: "/" },
+ props: {},
+ };
+ }
+ }
+ }
+ return { props: {} };
+};
+
+export default function AddBoard() {
+ const [formData, setFormData] = useState({
+ title: "",
+ content: "",
+ image: "",
+ });
+
+ const handleChange = (key: string, value: unknown) => {
+ setFormData((prev) => ({ ...prev, [key]: value }));
+ };
+
+ const handleSubmit = async () => {
+ await createArticle(formData);
+ };
+
+ return (
+
+
+
게시글 쓰기
+
+
+
+
+
+
+
+ );
+}
diff --git a/pages/board/[articleId].tsx b/pages/board/[articleId].tsx
new file mode 100644
index 00000000..e93ac420
--- /dev/null
+++ b/pages/board/[articleId].tsx
@@ -0,0 +1,135 @@
+import Image from "next/image";
+import Previous from "@/public/assets/icons/previous.icon.svg";
+import Button from "@/components/Button";
+import Link from "next/link";
+import { EditSelect } from "@/components/Select";
+import { Articles } from "@/components/Card";
+import { GetServerSideProps } from "next";
+import { deleteArticle, editArticle, getArticleDetail } from "@/lib/Articles";
+import { Input } from "@/components/Input";
+import { ChangeEvent, useState } from "react";
+import { getArticleComment, postArticleComment } from "@/lib/comments.api";
+import Comment from "@/components/board/comment";
+import { signIn } from "@/lib/auth";
+import noCommentImg from "@/public/assets/noComment.svg";
+//
+interface Props {
+ articleId: string;
+ detailArticle: Article;
+ comments: Comment[];
+}
+const LIMIT = 5;
+
+export const getServerSideProps: GetServerSideProps = async (context) => {
+ const { articleId } = context.query as {
+ articleId: string;
+ };
+ let cursor = 0;
+ const detailArticle = await getArticleDetail(Number(articleId));
+ const data = await getArticleComment(Number(articleId), LIMIT, cursor);
+ cursor = data.cursor;
+ return {
+ props: { articleId, detailArticle, comments: data.list },
+ };
+};
+
+export default function DetailArticle({
+ articleId,
+ detailArticle,
+ comments,
+}: Props) {
+ const [commentValue, setCommentValue] = useState("");
+ const [currentComments, setCurrentComments] = useState(comments);
+ const [isEditArticle, setIsEditArticle] = useState(false);
+ const [currentArticle, setCurrentArticle] = useState({
+ title: detailArticle.title,
+ content: detailArticle.content,
+ image: detailArticle.image,
+ });
+
+ const handleSelect = async (option: string) => {
+ switch (option) {
+ case "수정하기": {
+ setIsEditArticle(true);
+ break;
+ // await editArticle({ articleId, articleData: currentArticle });
+ }
+ case "삭제하기": {
+ await deleteArticle(Number(articleId));
+ break;
+ }
+ }
+ };
+
+ const handleChange = (value: string) => {
+ setCommentValue(value);
+ };
+
+ const handleSubmit = async () => {
+ const newComment = await postArticleComment(
+ Number(articleId),
+ commentValue
+ );
+
+ setCurrentComments((prev) => [newComment, ...prev]);
+ setCommentValue("");
+ };
+
+ return (
+
+
+
+
+
+ handleSelect(option)} />
+
+
+
{detailArticle.content}
+
+
+
handleChange(value)}
+ />
+
+
+
+
+
+ {currentComments.length < 1 ? (
+
+
+
+ 아직 댓글이 없어요,
+
+ 지금 댓글을 달아보세요!
+
+
+ ) : (
+ currentComments.map((comment) => {
+ return
;
+ })
+ )}
+
+
+
+
+
+
+
+ );
+}
diff --git a/pages/boards.tsx b/pages/board/index.tsx
similarity index 87%
rename from pages/boards.tsx
rename to pages/board/index.tsx
index 89402092..394f05c9 100644
--- a/pages/boards.tsx
+++ b/pages/board/index.tsx
@@ -7,8 +7,8 @@ import useWindowSize from "@/hooks/useWindowSize";
import { getArticles, getBestArticles } from "@/lib/Articles";
import { GetServerSideProps } from "next";
import { useRouter } from "next/router";
+import Link from "next/link";
-//
const BEST_PAGE_SIZE: number = 3;
const PAGE_SIZE: number = 10;
interface Props {
@@ -16,6 +16,7 @@ interface Props {
sortedArticles: Article[];
decodedKeyword: string;
}
+
export const getServerSideProps: GetServerSideProps = async (context) => {
const { orderBy = "recent", keyword } = context.query as {
orderBy: string;
@@ -33,7 +34,7 @@ export const getServerSideProps: GetServerSideProps = async (context) => {
props: { bestArticles, sortedArticles, decodedKeyword },
};
};
-//
+
export default function Board({
bestArticles,
sortedArticles,
@@ -45,8 +46,6 @@ export default function Board({
const device: string = useWindowSize();
const router = useRouter();
- const handleClick = () => {};
-
const handleSortChange = (option: string) => {
const newOrderBy = option === "최신순" ? "recent" : "like";
router.replace(
@@ -84,8 +83,8 @@ export default function Board({
}
}, [device, sortedArticles]);
- const handleSearchChange = (e: ChangeEvent
) => {
- const searchValue = e.target.value.toLowerCase();
+ const handleSearchChange = (value: string) => {
+ const searchValue = value.toLowerCase();
const newQuery = { ...router.query };
if (!searchValue) {
delete newQuery.keyword;
@@ -112,7 +111,9 @@ export default function Board({
{best.length > 0 &&
best.map((article) => (
-
+
+
+
))}
@@ -122,21 +123,25 @@ export default function Board({
게시글