diff --git a/src/api/articles/get-article-detail.ts b/src/api/articles/get-article-detail.ts new file mode 100644 index 00000000..349cf7ce --- /dev/null +++ b/src/api/articles/get-article-detail.ts @@ -0,0 +1,31 @@ +import axios from "axios"; +import { Article } from "@/types/article"; + +const getArticleDetail = async ( + articleId: number, + accessToken?: string +): Promise
=> { + try { + const headers: Record = { + "Content-Type": "application/json", + }; + + if (accessToken) { + headers.Authorization = `Bearer ${accessToken}`; + } + + const response = await axios.get( + `${process.env.NEXT_PUBLIC_API_URL}/articles/${articleId}`, + { headers } + ); + + if (!response) throw new Error("데이터를 불러오지 못했습니다."); + + return response.data; + } catch (error) { + console.error(error); + return null; + } +}; + +export default getArticleDetail; diff --git a/src/app/addteam/page.tsx b/src/app/addteam/page.tsx index 56636f18..25d88892 100644 --- a/src/app/addteam/page.tsx +++ b/src/app/addteam/page.tsx @@ -1,5 +1,27 @@ +import type { Metadata } from "next"; import AddTeamContents from "./_components/add-team-contents"; +export const metadata: Metadata = { + title: "팀 생성", + description: "새로운 Coworkers 팀을 생성하세요", + openGraph: { + title: "팀 생성 | Coworkers", + description: "새로운 Coworkers 팀을 생성하세요", + type: "website", + url: "https://coworkes.com/addteam", + locale: "ko_KR", + siteName: "Coworkers", + images: [ + { + url: "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Coworkers/user/2449/open_graph.jpg", + width: 1200, + height: 630, + alt: "Coworkers 팀 생성", + }, + ], + }, +}; + const addTeamPage = () => { return (
diff --git a/src/app/boards/[articleId]/_components/article-detail-client.tsx b/src/app/boards/[articleId]/_components/article-detail-client.tsx index 0dad50a9..57977e1d 100644 --- a/src/app/boards/[articleId]/_components/article-detail-client.tsx +++ b/src/app/boards/[articleId]/_components/article-detail-client.tsx @@ -1,5 +1,6 @@ "use client"; +import { useEffect } from "react"; import { useGetArticleDetail } from "@/hooks/api/articles/use-get-article-detail"; import ArticleHeader from "./article-header/article-header"; import ArticleContents from "./article-contents/article-contents"; @@ -16,10 +17,16 @@ export default function ArticleDetailClient({ }: ArticleDetailClientProps) { const { data, isPending, isError } = useGetArticleDetail(articleId); + useEffect(() => { + if (data?.article?.title) { + document.title = data.article.title; + } + }, [data]); + if (isPending) return ; if (isError || !data?.article) { - notFound(); + return notFound(); } const articleData = data.article; diff --git a/src/app/boards/[articleId]/edit/_components/article-edit-client.tsx b/src/app/boards/[articleId]/edit/_components/article-edit-client.tsx new file mode 100644 index 00000000..b951584b --- /dev/null +++ b/src/app/boards/[articleId]/edit/_components/article-edit-client.tsx @@ -0,0 +1,42 @@ +"use client"; + +import { useEffect } from "react"; +import cn from "@/utils/clsx"; +import { useGetArticleDetail } from "@/hooks/api/articles/use-get-article-detail"; +import { ArticleEditSkeleton } from "@/components"; +import ArticleEditContents from "./article-edit-contents/article-edit-contents"; +import { notFound } from "next/navigation"; + +interface ArticleEditClientProps { + articleId: number; +} + +export default function ArticleEditClient({ + articleId, +}: ArticleEditClientProps) { + const { data, isPending } = useGetArticleDetail(articleId); + + useEffect(() => { + if (data?.article?.title) { + document.title = `${data.article.title} 수정`; + } + }, [data]); + + if (isPending) return ; + + if (!data?.article) { + notFound(); + } + + return ( +
+ +
+ ); +} diff --git a/src/app/boards/[articleId]/edit/page.tsx b/src/app/boards/[articleId]/edit/page.tsx index cb0be3c5..7fdbe6d1 100644 --- a/src/app/boards/[articleId]/edit/page.tsx +++ b/src/app/boards/[articleId]/edit/page.tsx @@ -1,26 +1,61 @@ -"use client"; +import type { Metadata } from "next"; +import { cookies } from "next/headers"; +import { redirect } from "next/navigation"; +import ArticleEditClient from "./_components/article-edit-client"; +import getArticleDetail from "@/api/articles/get-article-detail"; -import { useParams } from "next/navigation"; -import { useGetArticleDetail } from "@/hooks/api/articles/use-get-article-detail"; -import { ArticleEditSkeleton } from "@/components"; -import ArticleEditContents from "./_components/article-edit-contents/article-edit-contents"; -import { notFound } from "next/navigation"; +interface PageProps { + params: Promise<{ articleId: string }>; +} + +async function getAccessToken() { + const cookieStore = await cookies(); + return cookieStore.get("accessToken")?.value; +} -export default function EditPage() { - const params = useParams(); - const articleId = params.articleId; +export async function generateMetadata({ + params, +}: PageProps): Promise { + const { articleId } = await params; + const accessToken = await getAccessToken(); + const article = await getArticleDetail(Number(articleId), accessToken); - const { data, isPending } = useGetArticleDetail(Number(articleId)); + if (!article) { + return { + title: "게시글 수정", + description: "Coworkers 자유게시판 게시글 수정", + }; + } + + return { + title: `${article.title} 수정`, + description: "Coworkers 자유게시판 게시글 수정", + openGraph: { + title: `${article.title} 수정 | Coworkers`, + description: "Coworkers 자유게시판 게시글 수정", + type: "website", + url: `https://coworkes.com/boards/${articleId}/edit`, + locale: "ko_KR", + siteName: "Coworkers", + images: [ + { + url: "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Coworkers/user/2449/open_graph.jpg", + width: 1200, + height: 630, + alt: "Coworkers 게시글 수정", + }, + ], + }, + }; +} - if (isPending) return ; +export default async function EditPage({ params }: PageProps) { + const { articleId } = await params; + const accessToken = await getAccessToken(); - if (!data?.article) { - notFound(); + if (!accessToken) { + redirect("/signin"); } - return ( -
- -
- ); + return ; } diff --git a/src/app/boards/[articleId]/page.tsx b/src/app/boards/[articleId]/page.tsx index 0d9fc2a9..1b1ca6c5 100644 --- a/src/app/boards/[articleId]/page.tsx +++ b/src/app/boards/[articleId]/page.tsx @@ -1,11 +1,61 @@ +import type { Metadata } from "next"; +import { cookies } from "next/headers"; +import { redirect } from "next/navigation"; import ArticleDetailClient from "./_components/article-detail-client"; +import getArticleDetail from "@/api/articles/get-article-detail"; interface PageProps { params: Promise<{ articleId: string }>; } +async function getAccessToken() { + const cookieStore = await cookies(); + return cookieStore.get("accessToken")?.value; +} + +export async function generateMetadata({ + params, +}: PageProps): Promise { + const { articleId } = await params; + const accessToken = await getAccessToken(); + const article = await getArticleDetail(Number(articleId), accessToken); + + if (!article) { + return { + title: "게시글", + description: "Coworkers 자유게시판", + }; + } + + return { + title: article.title, + description: article.content.slice(0, 160), + openGraph: { + title: `${article.title} | Coworkers`, + description: article.content.slice(0, 160), + type: "article", + url: `https://coworkes.com/boards/${articleId}`, + locale: "ko_KR", + siteName: "Coworkers", + images: [ + { + url: "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Coworkers/user/2449/open_graph.jpg", + width: 1200, + height: 630, + alt: "Coworkers 자유게시판", + }, + ], + }, + }; +} + export default async function Page({ params }: PageProps) { const { articleId } = await params; + const accessToken = await getAccessToken(); + + if (!accessToken) { + redirect("/signin"); + } return ; } diff --git a/src/app/boards/_components/boards-best/boards-best-header/boards-best-header.tsx b/src/app/boards/_components/boards-best/boards-best-header/boards-best-header.tsx index 1239a051..103f1c5e 100644 --- a/src/app/boards/_components/boards-best/boards-best-header/boards-best-header.tsx +++ b/src/app/boards/_components/boards-best/boards-best-header/boards-best-header.tsx @@ -1,13 +1,7 @@ -import { Icon } from "@/components/index"; - const BoardsBestHeader = () => { return ( -
+

베스트 게시글

-
- 더보기 - -
); }; diff --git a/src/app/boards/layout.tsx b/src/app/boards/layout.tsx new file mode 100644 index 00000000..ec6e3261 --- /dev/null +++ b/src/app/boards/layout.tsx @@ -0,0 +1,29 @@ +import { Metadata } from "next"; +import { ReactNode } from "react"; + +export const metadata: Metadata = { + title: "자유게시판", + description: "Coworkers 자유게시판에서 다양한 이야기를 나누세요", + openGraph: { + title: "자유게시판 | Coworkers", + description: "Coworkers 자유게시판에서 다양한 이야기를 나누세요", + type: "website", + url: "https://coworkes.com/boards", + locale: "ko_KR", + siteName: "Coworkers", + images: [ + { + url: "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Coworkers/user/2449/open_graph.jpg", + width: 1200, + height: 630, + alt: "Coworkers 자유게시판", + }, + ], + }, +}; + +const Layout = ({ children }: { children: ReactNode }) => { + return <>{children}; +}; + +export default Layout; diff --git a/src/app/boards/write/page.tsx b/src/app/boards/write/page.tsx index 3e20a6eb..9d44d920 100644 --- a/src/app/boards/write/page.tsx +++ b/src/app/boards/write/page.tsx @@ -1,6 +1,28 @@ +import type { Metadata } from "next"; import cn from "@/utils/clsx"; import ArticleWriteContents from "./_components/article-write-contents/article-write-contents"; +export const metadata: Metadata = { + title: "게시글 작성", + description: "Coworkers 자유게시판에 새로운 글을 작성하세요", + openGraph: { + title: "게시글 작성 | Coworkers", + description: "Coworkers 자유게시판에 새로운 글을 작성하세요", + type: "website", + url: "https://coworkes.com/boards/write", + locale: "ko_KR", + siteName: "Coworkers", + images: [ + { + url: "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Coworkers/user/2449/open_graph.jpg", + width: 1200, + height: 630, + alt: "Coworkers 게시글 작성", + }, + ], + }, +}; + const Page = () => { return (
{ return ( -
+
diff --git a/src/app/taketeam/page.tsx b/src/app/taketeam/page.tsx index fcfc7b82..8baa3173 100644 --- a/src/app/taketeam/page.tsx +++ b/src/app/taketeam/page.tsx @@ -1,5 +1,27 @@ +import type { Metadata } from "next"; import TakeTeamContents from "./_components/take-team-contents"; +export const metadata: Metadata = { + title: "팀 참여", + description: "Coworkers 팀에 참여하세요", + openGraph: { + title: "팀 참여 | Coworkers", + description: "Coworkers 팀에 참여하세요", + type: "website", + url: "https://coworkes.com/taketeam", + locale: "ko_KR", + siteName: "Coworkers", + images: [ + { + url: "https://sprint-fe-project.s3.ap-northeast-2.amazonaws.com/Coworkers/user/2449/open_graph.jpg", + width: 1200, + height: 630, + alt: "Coworkers 팀 참여", + }, + ], + }, +}; + const TakeTeamPage = () => { return (
diff --git a/src/components/image-upload/image-upload.tsx b/src/components/image-upload/image-upload.tsx index 27c00171..ec1d0d4d 100644 --- a/src/components/image-upload/image-upload.tsx +++ b/src/components/image-upload/image-upload.tsx @@ -88,7 +88,7 @@ const ImageUpload = ({ {`preview-${preview.id}`}