diff --git a/apps/common/features/app/(with-base-layout)/pst/bbsnotice/[bbsId]/[pstNo]/page.tsx b/apps/common/features/app/(with-base-layout)/pst/bbsnotice/[bbsId]/[pstNo]/page.tsx new file mode 100644 index 000000000..0f59903d4 --- /dev/null +++ b/apps/common/features/app/(with-base-layout)/pst/bbsnotice/[bbsId]/[pstNo]/page.tsx @@ -0,0 +1,10 @@ +import { NoticePost } from "@/pages/notice"; + +export default async function PstBbsNoticePostPage({ + params, +}: { + params: Promise<{ bbsId: string; pstNo: string }>; +}) { + const { bbsId, pstNo } = await params; + return ; +} diff --git a/apps/common/features/src/entities/post/api/post-service.ts b/apps/common/features/src/entities/post/api/post-service.ts index b623af4fe..04034bc78 100644 --- a/apps/common/features/src/entities/post/api/post-service.ts +++ b/apps/common/features/src/entities/post/api/post-service.ts @@ -1,6 +1,7 @@ import { client } from "@/shared/api"; import { ENDPOINT } from "@/shared/config"; import type { + PostInfo, PostList, PostParams, PostService, @@ -13,6 +14,17 @@ export class PostApiService implements PostService { }); return response.data; } + + public async getPostInfo(bbsId: string, pstNo: string): Promise { + const response = await client.get( + `${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`, + ); + return response.data; + } + + public async deletePost(bbsId: string, pstNo: string): Promise { + await client.delete(`${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`); + } } export const PostApi = new PostApiService(); diff --git a/apps/common/features/src/entities/post/model/post-interface.ts b/apps/common/features/src/entities/post/model/post-interface.ts index 5e0f394be..ec9021fad 100644 --- a/apps/common/features/src/entities/post/model/post-interface.ts +++ b/apps/common/features/src/entities/post/model/post-interface.ts @@ -31,8 +31,17 @@ export interface Post { rgtrNm: string; } +export interface PostInfo extends Post { + pstCn: string; + rgtr: string; + mdfcnDt: string; + mdfr: string; +} + export type PostList = PageableList; export interface PostService { getPostList(params: PostParams): Promise; + getPostInfo(bbsId: string, pstNo: string): Promise; + deletePost(bbsId: string, pstNo: string): Promise; } diff --git a/apps/common/features/src/pages/notice/index.ts b/apps/common/features/src/pages/notice/index.ts index 1b5281e57..c75abbdc8 100644 --- a/apps/common/features/src/pages/notice/index.ts +++ b/apps/common/features/src/pages/notice/index.ts @@ -1 +1,2 @@ export { NoticePage } from "./ui/notice-page"; +export { NoticePost } from "./ui/notice-post"; diff --git a/apps/common/features/src/pages/notice/ui/notice-layout.tsx b/apps/common/features/src/pages/notice/ui/notice-layout.tsx new file mode 100644 index 000000000..b4b5e37fb --- /dev/null +++ b/apps/common/features/src/pages/notice/ui/notice-layout.tsx @@ -0,0 +1,26 @@ +"use client"; + +import { useEffect, useState } from "react"; +import type { Board } from "@/entities/board"; +import { PageLayout } from "@/shared/ui/page-layout"; +import { useLocalStorage } from "@frontend-opensource/use-react-hooks"; + +function NoticeLayout({ children }: { children: React.ReactNode }) { + const [bbsInfo, setBbsInfo] = useState(null); + const [storedBbsInfo] = useLocalStorage("bbs-info", ""); + + useEffect(() => { + if (storedBbsInfo) setBbsInfo(JSON.parse(storedBbsInfo)); + }, [storedBbsInfo]); + + return ( + + {children} + + ); +} + +export { NoticeLayout }; diff --git a/apps/common/features/src/pages/notice/ui/notice-page.tsx b/apps/common/features/src/pages/notice/ui/notice-page.tsx index c86483a43..fdf28c2ee 100644 --- a/apps/common/features/src/pages/notice/ui/notice-page.tsx +++ b/apps/common/features/src/pages/notice/ui/notice-page.tsx @@ -1,7 +1,7 @@ "use client"; import { useEffect, useState } from "react"; -import { useRouter } from "next/navigation"; +import { usePathname, useRouter } from "next/navigation"; import { useQuery } from "@tanstack/react-query"; import { getCoreRowModel, @@ -9,7 +9,6 @@ import { type PaginationState, type RowSelectionState, } from "@tanstack/react-table"; -import { useLocalStorage } from "@frontend-opensource/use-react-hooks"; import { Button, DataTable, @@ -21,16 +20,14 @@ import { SelectTrigger, SelectValue, } from "@common/components/ui"; -import type { Board } from "@/entities/board"; import { PostApi, type Post, type PostParams } from "@/entities/post"; import { ENDPOINT } from "@/shared/config"; -import { PageLayout } from "@/shared/ui/page-layout"; import { columns } from "../model/notice-table-columns"; +import { NoticeLayout } from "./notice-layout"; function NoticePage({ bbsId }: { bbsId: string }) { const router = useRouter(); - const [storedBbsInfo] = useLocalStorage("bbs-info", ""); - const [bbsInfo, setBbsInfo] = useState(null); + const pathname = usePathname(); const [rowSelection, setRowSelection] = useState({}); const [postParams, setPostParams] = useState({ keywordType: "title", @@ -75,22 +72,15 @@ function NoticePage({ bbsId }: { bbsId: string }) { }; const handleRowClick = (row: Post) => { - router.push(`/bbs/register/${row.bbsId}`); + router.push(`${pathname}/${row.pstNo}`); }; useEffect(() => { refetch(); }, [pagination]); - useEffect(() => { - if (storedBbsInfo) setBbsInfo(JSON.parse(storedBbsInfo)); - }, [storedBbsInfo]); - return ( - + @@ -175,7 +165,7 @@ function NoticePage({ bbsId }: { bbsId: string }) { - + ); } diff --git a/apps/common/features/src/pages/notice/ui/notice-post.tsx b/apps/common/features/src/pages/notice/ui/notice-post.tsx new file mode 100644 index 000000000..964e16a91 --- /dev/null +++ b/apps/common/features/src/pages/notice/ui/notice-post.tsx @@ -0,0 +1,14 @@ +"use client"; + +import { Post } from "@/widgets/post"; +import { NoticeLayout } from "./notice-layout"; + +function NoticePost({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { + return ( + + + + ); +} + +export { NoticePost }; diff --git a/apps/common/features/src/widgets/post/index.ts b/apps/common/features/src/widgets/post/index.ts new file mode 100644 index 000000000..9c833e568 --- /dev/null +++ b/apps/common/features/src/widgets/post/index.ts @@ -0,0 +1 @@ +export { Post } from "./ui/post"; diff --git a/apps/common/features/src/widgets/post/ui/post-action.tsx b/apps/common/features/src/widgets/post/ui/post-action.tsx new file mode 100644 index 000000000..9a4d93de3 --- /dev/null +++ b/apps/common/features/src/widgets/post/ui/post-action.tsx @@ -0,0 +1,51 @@ +import { useRouter } from "next/navigation"; +import { useMutation } from "@tanstack/react-query"; +import { useConfirm } from "@frontend-opensource/use-react-hooks"; +import { Button } from "@common/components/ui"; +import { PostApi } from "@/entities/post"; + +type PostActionProps = { + bbsId: string; + pstNo: string; + children: React.ReactNode; +}; + +function PostAction({ children, bbsId, pstNo }: PostActionProps) { + const router = useRouter(); + const { confirm } = useConfirm(); + + const { mutate: deletePost } = useMutation({ + mutationFn: () => PostApi.deletePost(bbsId, pstNo), + onSuccess: () => { + router.back(); + }, + }); + + const onDelete = async () => { + if (await confirm("삭제하시겠습니까?")) deletePost(); + }; + + return ( + + {children} + + router.back()} + > + 목록 + + + 수정 + + + 삭제 + + + + ); +} + +export { PostAction }; diff --git a/apps/common/features/src/widgets/post/ui/post.tsx b/apps/common/features/src/widgets/post/ui/post.tsx new file mode 100644 index 000000000..5ed0235f3 --- /dev/null +++ b/apps/common/features/src/widgets/post/ui/post.tsx @@ -0,0 +1,46 @@ +"use client"; + +import dayjs from "dayjs"; +import { useQuery } from "@tanstack/react-query"; +import { PostApi } from "@/entities/post"; +import { ENDPOINT } from "@/shared/config"; +import { PostAction } from "./post-action"; + +function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { + const { data: postData } = useQuery({ + queryKey: [ENDPOINT.BOARD_SERVICE.POSTS], + queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + }); + + return ( + + + {postData?.pstTtl} + + + + 작성자: {postData?.wrtrNm} + + + 등록일: {dayjs(postData?.regDt).format("YYYY-MM-DD")} + + + 조회수: {postData?.inqNocs} + + + + + + + + 첨부파일 + + + + ); +} + +export { Post };