diff --git a/apps/common/features/src/entities/attachment/api/attachment-service.ts b/apps/common/features/src/entities/attachment/api/attachment-service.ts index a5352c712..fc2dcab05 100644 --- a/apps/common/features/src/entities/attachment/api/attachment-service.ts +++ b/apps/common/features/src/entities/attachment/api/attachment-service.ts @@ -52,7 +52,15 @@ export class AttachmentApiService implements AttachmentService { return URL.createObjectURL(blob); } - public async getMovieThumbnailUrl(atflId: string): Promise { + public async getStreamVideoUrlByAtflId(atflId: string): Promise { + const response = await fetch( + `${ENDPOINT.ATTACH_SERVICE.STREAM_VIDEO}/${atflId}`, + ); + const blob = await response.blob(); + return URL.createObjectURL(blob); + } + + public async getMovieThumbnailUrlByAtflId(atflId: string): Promise { const response = await fetch( `${ENDPOINT.ATTACH_SERVICE.MOVIE_THUMBNAIL}/${atflId}`, ); @@ -60,6 +68,14 @@ export class AttachmentApiService implements AttachmentService { return URL.createObjectURL(blob); } + public async getMovieThumbnailUrlByAtflCd(atflCd: string): Promise { + const response = await fetch( + `${ENDPOINT.ATTACH_SERVICE.MOVIE_THUMBNAIL}/atflCd/${atflCd}`, + ); + const blob = await response.blob(); + return URL.createObjectURL(blob); + } + public async downloadAttachmentByAtflCd( atflCd: string, ): Promise { diff --git a/apps/common/features/src/entities/attachment/model/attachment-interface.ts b/apps/common/features/src/entities/attachment/model/attachment-interface.ts index 5ad0fc3ea..0f1b5d1ee 100644 --- a/apps/common/features/src/entities/attachment/model/attachment-interface.ts +++ b/apps/common/features/src/entities/attachment/model/attachment-interface.ts @@ -40,6 +40,8 @@ export interface AttachmentService { deleteAttachmentByAtflCd: (atflCd: string) => Promise; getImageUrlByAtflId: (atflId: string) => Promise; getImageUrlByAtflCd: (atflCd: string) => Promise; - getMovieThumbnailUrl: (atflId: string) => Promise; + getStreamVideoUrlByAtflId: (atflId: string) => Promise; + getMovieThumbnailUrlByAtflId: (atflId: string) => Promise; + getMovieThumbnailUrlByAtflCd: (atflCd: string) => Promise; downloadAttachmentByAtflCd: (atflCd: string) => Promise; } 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 a07fc4d2a..1e5ac5146 100644 --- a/apps/common/features/src/entities/post/api/post-service.ts +++ b/apps/common/features/src/entities/post/api/post-service.ts @@ -14,7 +14,7 @@ import { export class PostApiService implements PostService { public async getPostList( - bbsId: string, + bbsId: number, params: PostParams, ): Promise { const response = await client.get( @@ -24,7 +24,7 @@ export class PostApiService implements PostService { return response.data; } - public async getPostInfo(bbsId: string, pstNo: string): Promise { + public async getPostInfo(bbsId: number, pstNo: number): Promise { const response = await client.get( `${ENDPOINT.BOARD_SERVICE.POSTS_USER}/${bbsId}/${pstNo}`, ); @@ -41,8 +41,8 @@ export class PostApiService implements PostService { } public async updatePost( - bbsId: string, - pstNo: string, + bbsId: number, + pstNo: number, data: PostUpdateFormData, ): Promise { const validatedData = postUpdateFormSchema.parse(data); @@ -54,8 +54,8 @@ export class PostApiService implements PostService { } public async deletePost( - bbsId: string, - pstNo: string, + bbsId: number, + pstNo: number, pstPswd?: string, ): Promise { await client.delete( 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 9cb97ef92..11778002f 100644 --- a/apps/common/features/src/entities/post/model/post-interface.ts +++ b/apps/common/features/src/entities/post/model/post-interface.ts @@ -8,13 +8,15 @@ export interface PostParams extends PageableParams { upndFixYn?: string; prdPstgYn?: string; siteId?: string; + bbsTypeCd?: string; } export interface Post { - bbsId: number; rowNo: number; + bbsId: number; pstNo: number; pstTtl: string; + pstCn: string; inqNocs: number; rfrncUrl: string; popupYn: string; @@ -73,13 +75,13 @@ export type PostFormData = z.infer; export type PostUpdateFormData = z.infer; export interface PostService { - getPostList(bbsId: string, params: PostParams): Promise; - getPostInfo(bbsId: string, pstNo: string): Promise; + getPostList(bbsId: number, params: PostParams): Promise; + getPostInfo(bbsId: number, pstNo: number): Promise; createPost(data: PostFormData): Promise; updatePost( - bbsId: string, - pstNo: string, + bbsId: number, + pstNo: number, data: PostUpdateFormData, ): Promise; - deletePost(bbsId: string, pstNo: string, pstPswd?: string): Promise; + deletePost(bbsId: number, pstNo: number, pstPswd?: string): Promise; } diff --git a/apps/common/features/src/pages/(pst)/image/ui/modify-page.tsx b/apps/common/features/src/pages/(pst)/image/ui/modify-page.tsx index c721286e4..8b09be8c3 100644 --- a/apps/common/features/src/pages/(pst)/image/ui/modify-page.tsx +++ b/apps/common/features/src/pages/(pst)/image/ui/modify-page.tsx @@ -20,12 +20,12 @@ function ModifyPage({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const { data: postInfo } = useQuery({ queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { mutateAsync: updatePost } = useMutation({ mutationFn: (data: PostUpdateFormData) => - PostApi.updatePost(bbsId, pstNo, data), + PostApi.updatePost(parseInt(bbsId), parseInt(pstNo), data), onSuccess: () => { alert("수정되었습니다.", router.back); }, diff --git a/apps/common/features/src/pages/(pst)/normal/ui/modify-page.tsx b/apps/common/features/src/pages/(pst)/normal/ui/modify-page.tsx index d6114ab44..e0d1834d4 100644 --- a/apps/common/features/src/pages/(pst)/normal/ui/modify-page.tsx +++ b/apps/common/features/src/pages/(pst)/normal/ui/modify-page.tsx @@ -20,12 +20,12 @@ function ModifyPage({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const { data: postInfo } = useQuery({ queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { mutateAsync: updatePost } = useMutation({ mutationFn: (data: PostUpdateFormData) => - PostApi.updatePost(bbsId, pstNo, data), + PostApi.updatePost(parseInt(bbsId), parseInt(pstNo), data), onSuccess: () => { alert("수정되었습니다.", router.back); }, diff --git a/apps/common/features/src/pages/(pst)/notice/ui/modify-page.tsx b/apps/common/features/src/pages/(pst)/notice/ui/modify-page.tsx index bd014917f..9fe65782d 100644 --- a/apps/common/features/src/pages/(pst)/notice/ui/modify-page.tsx +++ b/apps/common/features/src/pages/(pst)/notice/ui/modify-page.tsx @@ -20,12 +20,12 @@ function ModifyPage({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const { data: postInfo } = useQuery({ queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { mutateAsync: updatePost } = useMutation({ mutationFn: (data: PostUpdateFormData) => - PostApi.updatePost(bbsId, pstNo, data), + PostApi.updatePost(parseInt(bbsId), parseInt(pstNo), data), onSuccess: () => { alert("수정되었습니다.", router.back); }, diff --git a/apps/common/features/src/shared/config/api.ts b/apps/common/features/src/shared/config/api.ts index 243afca6d..b6191979e 100644 --- a/apps/common/features/src/shared/config/api.ts +++ b/apps/common/features/src/shared/config/api.ts @@ -10,6 +10,7 @@ export const ENDPOINT = { MOVIE_THUMBNAIL: "/attach-service/api/v1/movie/thumbnail", ATTACHMENTS: "/attach-service/api/v1/atfl/attachments", DOWNLOAD: "/attach-service/api/v1/atflcd/download", + STREAM_VIDEO: "/attach-service/api/v1/stream/video", }, USER_SERVICE: { LOGIN: "/user-service/login", diff --git a/apps/common/features/src/shared/lib/use-prompt.tsx b/apps/common/features/src/shared/lib/use-prompt.tsx index da9c4b386..f36858eb0 100644 --- a/apps/common/features/src/shared/lib/use-prompt.tsx +++ b/apps/common/features/src/shared/lib/use-prompt.tsx @@ -7,18 +7,18 @@ export const usePrompt = () => { const prompt = (message: string) => { setMessage(message); - return new Promise((resolve) => { + return new Promise<{ resolved: boolean; value?: string }>((resolve) => { setResolve(() => resolve); }); }; const onSubmit = (value: string) => { - resolve?.(value); + resolve?.({ resolved: true, value }); setMessage(""); }; const onCancel = () => { - resolve?.(""); + resolve?.({ resolved: false }); setMessage(""); }; diff --git a/apps/common/features/src/shared/providers/prompt-provider.tsx b/apps/common/features/src/shared/providers/prompt-provider.tsx index 267b7aafc..10338c338 100644 --- a/apps/common/features/src/shared/providers/prompt-provider.tsx +++ b/apps/common/features/src/shared/providers/prompt-provider.tsx @@ -2,9 +2,15 @@ import { createContext, useState } from "react"; interface PromptContext { message?: string; - resolve?: (value: string) => void; + resolve?: ({ + resolved, + value, + }: { + resolved: boolean; + value?: string; + }) => void; setMessage: (message: string) => void; - setResolve: (resolve: (value: string) => void) => void; + setResolve: (resolve: () => void) => void; } export const PromptContext = createContext({ @@ -16,7 +22,10 @@ export const PromptContext = createContext({ export const PromptProvider = ({ children }: { children: React.ReactNode }) => { const [message, setMessage] = useState(); - const [resolve, setResolve] = useState<(value: string) => void>(); + const [resolve, setResolve] = + useState< + ({ resolved, value }: { resolved: boolean; value?: string }) => void + >(); return ( ({ key={row.id} onClick={() => onRowClick?.(row.original)} className={cn( - "rounded-md border border-border bg-background p-4 shadow-md", + "overflow-hidden rounded-md border border-border bg-background p-4 shadow-md", onRowClick && "cursor-pointer hover:bg-accent", )} > diff --git a/apps/common/features/src/widgets/post/model/grid-view-table-columns.tsx b/apps/common/features/src/widgets/post/model/grid-view-table-columns.tsx index 242c7ee2f..34f2fc237 100644 --- a/apps/common/features/src/widgets/post/model/grid-view-table-columns.tsx +++ b/apps/common/features/src/widgets/post/model/grid-view-table-columns.tsx @@ -1,11 +1,19 @@ import dayjs from "dayjs"; import Image from "next/image"; import type { ColumnDef } from "@tanstack/react-table"; -import { Badge, Checkbox, Skeleton } from "@common/components"; +import { Badge, Checkbox, Skeleton, cn } from "@common/components"; +import { AttachmentApi } from "@/entities/attachment"; import type { Post } from "@/entities/post"; import { useQuery } from "@tanstack/react-query"; import { ENDPOINT } from "@/shared/config"; -import { AttachmentApi } from "@/entities/attachment"; +import type { BbsType } from "@/shared/store/menu-store"; + +declare module "@tanstack/react-table" { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface TableMeta { + bbsTypeCd?: BbsType; + } +} export const createColumns = ( thumbRefs: React.MutableRefObject>, @@ -22,68 +30,120 @@ export const createColumns = ( className="h-4 w-4 rounded border-gray-300" /> ), - cell: ({ row }) => { - const { pstTtl, inqNocs } = row.original; - return ( -
-
- e.stopPropagation()} - onCheckedChange={(checked) => row.toggleSelected(!!checked)} - className="h-4 w-4 rounded border-gray-300" + cell: ({ row, table }) => { + const { atflCd, pstNo, pstTtl, inqNocs, rgtrNm, regDt } = row.original; + const bbsTypeCd = table.options.meta?.bbsTypeCd; + + if (bbsTypeCd === "BBSIMAGE") { + return ( +
+
+ e.stopPropagation()} + onCheckedChange={(checked) => row.toggleSelected(!!checked)} + className="h-4 w-4 rounded border-gray-300" + /> + {inqNocs >= 100 && HOT} + {dayjs().diff(dayjs(row.original.regDt), "hour") < 24 && ( + NEW + )} + + {pstTtl} + +
+ - {inqNocs >= 100 && HOT} - {dayjs().diff(dayjs(row.original.regDt), "hour") < 24 && ( - NEW - )} +
+ + {rgtrNm} + + + {dayjs(regDt).format("YYYY-MM-DD")} + +
- - {pstTtl} - -
- ); + ); + } + + if (bbsTypeCd === "BBSMOVIE") { + return ( +
+ +
+
+
+ e.stopPropagation()} + onCheckedChange={(checked) => row.toggleSelected(!!checked)} + className="h-4 w-4 rounded border-gray-300" + /> + {inqNocs >= 100 && HOT} + {dayjs().diff(dayjs(regDt), "hour") < 24 && ( + NEW + )} + + {pstTtl} + +
+
+ + {rgtrNm} + + + {dayjs(regDt).format("YYYY-MM-DD")} + +
+
+
+
+ ); + } }, }, - { - id: "atflCd", - cell: ({ row }) => { - const { atflCd, pstNo } = row.original; - return ; - }, - }, - { - id: "rgtrNm", - cell: ({ row }) => { - return ( - - {row.original.rgtrNm} - - ); - }, - }, - { - id: "regDt", - cell: ({ row }) => ( - - {dayjs(row.original.regDt).format("YYYY-MM-DD")} - - ), - }, ]; type ThumbImageProps = { atflCd: string; pstNo: number; thumbRefs: React.MutableRefObject>; + bbsTypeCd?: string; + classes?: { + image?: string; + }; }; -const ThumbImage = ({ atflCd, pstNo, thumbRefs }: ThumbImageProps) => { +const ThumbImage = ({ + atflCd, + pstNo, + thumbRefs, + bbsTypeCd, + classes, +}: ThumbImageProps) => { const prevImage = thumbRefs.current.get(pstNo); const { data: imageUrl, isLoading } = useQuery({ queryKey: [ENDPOINT.ATTACH_SERVICE.IMAGES, atflCd], - queryFn: () => AttachmentApi.getImageUrlByAtflCd(atflCd), + queryFn: () => { + if (bbsTypeCd === "BBSIMAGE") { + return AttachmentApi.getImageUrlByAtflCd(atflCd); + } else if (bbsTypeCd === "BBSMOVIE") { + return AttachmentApi.getMovieThumbnailUrlByAtflCd(atflCd); + } + }, select: (url) => { if (url) thumbRefs.current.set(pstNo, url); return url; @@ -93,17 +153,17 @@ const ThumbImage = ({ atflCd, pstNo, thumbRefs }: ThumbImageProps) => { if (isLoading) return ( -
- +
+
); if (imageUrl) return ( -
+
썸네일 이미지 @@ -111,7 +171,7 @@ const ThumbImage = ({ atflCd, pstNo, thumbRefs }: ThumbImageProps) => { ); return ( -
+
); diff --git a/apps/common/features/src/widgets/post/ui/post-action.tsx b/apps/common/features/src/widgets/post/ui/post-action.tsx index c74c76482..0169e313c 100644 --- a/apps/common/features/src/widgets/post/ui/post-action.tsx +++ b/apps/common/features/src/widgets/post/ui/post-action.tsx @@ -35,7 +35,7 @@ function PostAction({ children, handleDelete }: PostActionProps) { }; return ( -
+ <> {children}
-
+ ); } diff --git a/apps/common/features/src/widgets/post/ui/post-comment.tsx b/apps/common/features/src/widgets/post/ui/post-comment.tsx index f87a90fca..1800b2581 100644 --- a/apps/common/features/src/widgets/post/ui/post-comment.tsx +++ b/apps/common/features/src/widgets/post/ui/post-comment.tsx @@ -89,7 +89,8 @@ function PostComment({ bbsId, pstNo }: { bbsId: number; pstNo: number }) { if (userInfo?.userUnqId) { cmntPswd = userInfo?.userUnqId; } else { - cmntPswd = await prompt("비밀번호를 입력해주세요."); + const { resolved, value } = await prompt("비밀번호를 입력해주세요."); + if (resolved) cmntPswd = value ?? ""; } return cmntPswd; }; diff --git a/apps/common/features/src/widgets/post/ui/post-page.tsx b/apps/common/features/src/widgets/post/ui/post-page.tsx index 262226a48..c4bf33576 100644 --- a/apps/common/features/src/widgets/post/ui/post-page.tsx +++ b/apps/common/features/src/widgets/post/ui/post-page.tsx @@ -24,11 +24,10 @@ import { } from "@common/components"; import { PostApi, type Post, type PostParams } from "@/entities/post"; import { ENDPOINT } from "@/shared/config"; -import type { BbsType } from "@/shared/store/menu-store"; import { useMenuStore, useUserStore } from "@/shared/lib"; import { GridViewDataTable } from "@/shared/ui/grid-view-data-table"; -import { columns } from "../model/post-table-columns"; -import { createColumns } from "../model/grid-view-table-columns"; +import { columns as tableColumns } from "../model/post-table-columns"; +import { createColumns as createGridViewColumns } from "../model/grid-view-table-columns"; function PostPage({ bbsId }: { bbsId: string }) { const router = useRouter(); @@ -36,7 +35,6 @@ function PostPage({ bbsId }: { bbsId: string }) { const { confirm } = useConfirm(); const { userInfo } = useUserStore((state) => state); const { bbsInfo, pageMenuAuthority } = useMenuStore((state) => state); - const bbsType = bbsInfo?.bbsTypeCd as BbsType; const [postParams, setPostParams] = useState({ keywordType: "title", @@ -53,7 +51,7 @@ function PostPage({ bbsId }: { bbsId: string }) { const { data: upndFixPostList } = useQuery({ queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, bbsInfo], queryFn: () => - PostApi.getPostList(bbsId, { + PostApi.getPostList(parseInt(bbsId), { ...postParams, upndFixYn: bbsInfo?.upndFixUseYn, }), @@ -77,7 +75,7 @@ function PostPage({ bbsId }: { bbsId: string }) { } = useQuery({ queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId], queryFn: () => - PostApi.getPostList(bbsId, { + PostApi.getPostList(parseInt(bbsId), { ...postParams, page: pagination.pageIndex, size: pagination.pageSize, @@ -85,9 +83,14 @@ function PostPage({ bbsId }: { bbsId: string }) { enabled: false, }); + const isGridViewPage = + bbsInfo?.bbsTypeCd === "BBSIMAGE" || bbsInfo?.bbsTypeCd === "BBSMOVIE"; + const table = useReactTable({ - data: [...(upndFixPostList?.content ?? []), ...(postList?.content ?? [])], - columns, + data: isGridViewPage + ? (postList?.content ?? []) + : [...(upndFixPostList?.content ?? []), ...(postList?.content ?? [])], + columns: isGridViewPage ? createGridViewColumns(thumbRefs) : tableColumns, state: { pagination, rowSelection }, rowCount: postList?.totalElements ?? 0, manualPagination: true, @@ -95,19 +98,10 @@ function PostPage({ bbsId }: { bbsId: string }) { getCoreRowModel: getCoreRowModel(), onPaginationChange: setPagination, onRowSelectionChange: setRowSelection, + meta: { bbsTypeCd: bbsInfo?.bbsTypeCd }, }); - const gridViewTable = useReactTable({ - data: postList?.content ?? [], - columns: createColumns(thumbRefs), - state: { pagination, rowSelection }, - rowCount: postList?.totalElements ?? 0, - manualPagination: true, - enableMultiRowSelection: true, - getCoreRowModel: getCoreRowModel(), - onPaginationChange: setPagination, - onRowSelectionChange: setRowSelection, - }); + const DataTableComponent = isGridViewPage ? GridViewDataTable : DataTable; const onPostDelete = async () => { const selectedPosts = table @@ -118,7 +112,7 @@ function PostPage({ bbsId }: { bbsId: string }) { setRowSelection({}); await Promise.all( selectedPosts.map((pstNo) => - PostApi.deletePost(bbsId, pstNo.toString(), userInfo?.userUnqId), + PostApi.deletePost(parseInt(bbsId), pstNo, userInfo?.userUnqId), ), ); refetch(); @@ -211,19 +205,11 @@ function PostPage({ bbsId }: { bbsId: string }) {
{isFetched ? ( - bbsType === "BBSIMAGE" ? ( - - ) : ( - - ) + ) : ( )} diff --git a/apps/common/features/src/widgets/post/ui/post.tsx b/apps/common/features/src/widgets/post/ui/post.tsx index 379bcdd38..19e271315 100644 --- a/apps/common/features/src/widgets/post/ui/post.tsx +++ b/apps/common/features/src/widgets/post/ui/post.tsx @@ -29,7 +29,7 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const { data: postData } = useQuery({ queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { data: downloadResponse, isFetching } = useQuery({ @@ -47,7 +47,8 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { }); const { mutate: deletePost } = useMutation({ - mutationFn: (pstPswd: string) => PostApi.deletePost(bbsId, pstNo, pstPswd), + mutationFn: (pstPswd: string) => + PostApi.deletePost(parseInt(bbsId), parseInt(pstNo), pstPswd), onSuccess: () => { alert("삭제되었습니다.", router.back); }, @@ -58,7 +59,8 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { if (userInfo?.userUnqId) { pstPswd = userInfo?.userUnqId; } else { - pstPswd = await prompt("비밀번호를 입력해주세요."); + const { resolved, value } = await prompt("비밀번호를 입력해주세요."); + if (resolved) pstPswd = value ?? ""; } deletePost(pstPswd); }; diff --git a/apps/common/features/src/widgets/post/ui/with-preview-file-uploader.tsx b/apps/common/features/src/widgets/post/ui/with-preview-file-uploader.tsx index 618108017..9496280e6 100644 --- a/apps/common/features/src/widgets/post/ui/with-preview-file-uploader.tsx +++ b/apps/common/features/src/widgets/post/ui/with-preview-file-uploader.tsx @@ -50,7 +50,7 @@ function WithPreviewFileUploader({ imageUrl = await AttachmentApi.getImageUrlByAtflId(atflId); } if (bbsInfo?.bbsTypeCd === "BBSMOVIE") { - imageUrl = await AttachmentApi.getMovieThumbnailUrl(atflId); + imageUrl = await AttachmentApi.getMovieThumbnailUrlByAtflId(atflId); } setThumbnailUrl(imageUrl); } diff --git a/apps/cs/src/app/providers/app-provider.tsx b/apps/cs/src/app/providers/app-provider.tsx index 713bc172c..7732d34ba 100644 --- a/apps/cs/src/app/providers/app-provider.tsx +++ b/apps/cs/src/app/providers/app-provider.tsx @@ -6,8 +6,9 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { ConfirmProvider } from "@frontend-opensource/use-react-hooks"; import { AuthWrapper } from "@/entities/auth"; import { MenuWrapper } from "@/entities/menu"; -import { StoreProvider } from "@/shared/providers"; +import { PromptProvider, StoreProvider } from "@/shared/providers"; import { AlertDialog } from "@/shared/ui/alert-dialog"; +import { PromptDialog } from "@/shared/ui/prompt-dialog"; import { ConfirmDialog } from "@/shared/ui/confirm-dialog"; import { initializeNextClientConfig } from "@common/config"; @@ -19,17 +20,23 @@ const AppProvider = ({ children }: Readonly<{ children: React.ReactNode }>) => { return ( - - - - - {children} - - - - - - + + + + + + {children} + + + + + + + + ); diff --git a/apps/cs/src/entities/post/api/post-service.ts b/apps/cs/src/entities/post/api/post-service.ts index a07fc4d2a..7820af709 100644 --- a/apps/cs/src/entities/post/api/post-service.ts +++ b/apps/cs/src/entities/post/api/post-service.ts @@ -14,19 +14,19 @@ import { export class PostApiService implements PostService { public async getPostList( - bbsId: string, + bbsId: number, params: PostParams, ): Promise { const response = await client.get( - `${ENDPOINT.BOARD_SERVICE.POSTS_USER}/${bbsId}`, + `${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}`, { params }, ); return response.data; } - public async getPostInfo(bbsId: string, pstNo: string): Promise { + public async getPostInfo(bbsId: number, pstNo: number): Promise { const response = await client.get( - `${ENDPOINT.BOARD_SERVICE.POSTS_USER}/${bbsId}/${pstNo}`, + `${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`, ); return response.data; } @@ -34,34 +34,33 @@ export class PostApiService implements PostService { public async createPost(data: PostFormData): Promise { const validatedData = postFormSchema.parse(data); const response = await client.post( - `${ENDPOINT.BOARD_SERVICE.POSTS_USER}`, + `${ENDPOINT.BOARD_SERVICE.POSTS}`, validatedData, ); return response.data; } public async updatePost( - bbsId: string, - pstNo: string, + bbsId: number, + pstNo: number, data: PostUpdateFormData, ): Promise { const validatedData = postUpdateFormSchema.parse(data); const response = await client.put( - `${ENDPOINT.BOARD_SERVICE.POSTS_USER}/${bbsId}/${pstNo}`, + `${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`, validatedData, ); return response.data; } public async deletePost( - bbsId: string, - pstNo: string, - pstPswd?: string, + bbsId: number, + pstNo: number, + delRsn?: string, ): Promise { - await client.delete( - `${ENDPOINT.BOARD_SERVICE.POSTS_USER}/${bbsId}/${pstNo}`, - { params: { pstPswd } }, - ); + await client.delete(`${ENDPOINT.BOARD_SERVICE.POSTS}/${bbsId}/${pstNo}`, { + params: { delRsn }, + }); } } diff --git a/apps/cs/src/entities/post/model/post-interface.ts b/apps/cs/src/entities/post/model/post-interface.ts index 9cb97ef92..b848ccc6b 100644 --- a/apps/cs/src/entities/post/model/post-interface.ts +++ b/apps/cs/src/entities/post/model/post-interface.ts @@ -8,13 +8,15 @@ export interface PostParams extends PageableParams { upndFixYn?: string; prdPstgYn?: string; siteId?: string; + bbsTypeCd?: string; } export interface Post { - bbsId: number; rowNo: number; + bbsId: number; pstNo: number; pstTtl: string; + pstCn: string; inqNocs: number; rfrncUrl: string; popupYn: string; @@ -73,13 +75,13 @@ export type PostFormData = z.infer; export type PostUpdateFormData = z.infer; export interface PostService { - getPostList(bbsId: string, params: PostParams): Promise; - getPostInfo(bbsId: string, pstNo: string): Promise; + getPostList(bbsId: number, params: PostParams): Promise; + getPostInfo(bbsId: number, pstNo: number): Promise; createPost(data: PostFormData): Promise; updatePost( - bbsId: string, - pstNo: string, + bbsId: number, + pstNo: number, data: PostUpdateFormData, ): Promise; - deletePost(bbsId: string, pstNo: string, pstPswd?: string): Promise; + deletePost(bbsId: number, pstNo: number, delRsn?: string): Promise; } diff --git a/apps/cs/src/pages/(post)/image/ui/modify-page.tsx b/apps/cs/src/pages/(post)/image/ui/modify-page.tsx index c721286e4..c2426c134 100644 --- a/apps/cs/src/pages/(post)/image/ui/modify-page.tsx +++ b/apps/cs/src/pages/(post)/image/ui/modify-page.tsx @@ -19,13 +19,13 @@ function ModifyPage({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const { userInfo } = useUserStore((state) => state); const { data: postInfo } = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryKey: [ENDPOINT.BOARD_SERVICE.POSTS, bbsId, pstNo], + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { mutateAsync: updatePost } = useMutation({ mutationFn: (data: PostUpdateFormData) => - PostApi.updatePost(bbsId, pstNo, data), + PostApi.updatePost(parseInt(bbsId), parseInt(pstNo), data), onSuccess: () => { alert("수정되었습니다.", router.back); }, diff --git a/apps/cs/src/pages/(post)/movie/ui/modify-page.tsx b/apps/cs/src/pages/(post)/movie/ui/modify-page.tsx index 2f67e313c..bee473938 100644 --- a/apps/cs/src/pages/(post)/movie/ui/modify-page.tsx +++ b/apps/cs/src/pages/(post)/movie/ui/modify-page.tsx @@ -19,13 +19,13 @@ function ModifyPage({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const { userInfo } = useUserStore((state) => state); const { data: postInfo } = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryKey: [ENDPOINT.BOARD_SERVICE.POSTS, bbsId, pstNo], + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { mutateAsync: updatePost } = useMutation({ mutationFn: (data: PostUpdateFormData) => - PostApi.updatePost(bbsId, pstNo, data), + PostApi.updatePost(parseInt(bbsId), parseInt(pstNo), data), onSuccess: () => { alert("수정되었습니다.", router.back); }, diff --git a/apps/cs/src/pages/(post)/normal/ui/modify-page.tsx b/apps/cs/src/pages/(post)/normal/ui/modify-page.tsx index d6114ab44..2e23f62a0 100644 --- a/apps/cs/src/pages/(post)/normal/ui/modify-page.tsx +++ b/apps/cs/src/pages/(post)/normal/ui/modify-page.tsx @@ -19,13 +19,13 @@ function ModifyPage({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const { userInfo } = useUserStore((state) => state); const { data: postInfo } = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryKey: [ENDPOINT.BOARD_SERVICE.POSTS, bbsId, pstNo], + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { mutateAsync: updatePost } = useMutation({ mutationFn: (data: PostUpdateFormData) => - PostApi.updatePost(bbsId, pstNo, data), + PostApi.updatePost(parseInt(bbsId), parseInt(pstNo), data), onSuccess: () => { alert("수정되었습니다.", router.back); }, diff --git a/apps/cs/src/pages/(post)/notice/ui/modify-page.tsx b/apps/cs/src/pages/(post)/notice/ui/modify-page.tsx index bd014917f..fa12dbcce 100644 --- a/apps/cs/src/pages/(post)/notice/ui/modify-page.tsx +++ b/apps/cs/src/pages/(post)/notice/ui/modify-page.tsx @@ -19,13 +19,13 @@ function ModifyPage({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const { userInfo } = useUserStore((state) => state); const { data: postInfo } = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryKey: [ENDPOINT.BOARD_SERVICE.POSTS, bbsId, pstNo], + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { mutateAsync: updatePost } = useMutation({ mutationFn: (data: PostUpdateFormData) => - PostApi.updatePost(bbsId, pstNo, data), + PostApi.updatePost(parseInt(bbsId), parseInt(pstNo), data), onSuccess: () => { alert("수정되었습니다.", router.back); }, diff --git a/apps/cs/src/shared/config/api.ts b/apps/cs/src/shared/config/api.ts index 0ff7efe42..4238dec5f 100644 --- a/apps/cs/src/shared/config/api.ts +++ b/apps/cs/src/shared/config/api.ts @@ -40,7 +40,7 @@ export const ENDPOINT = { BOARD_SERVICE: { BBS: "/board-service/api/v1/bbs", BBS_TEMPLATES: "/board-service/api/v1/bbsTmplt", - POSTS_USER: "/board-service/api/v1/posts/user", + POSTS: "/board-service/api/v1/posts", POSTS_COMMENTS: "/board-service/api/v1/posts-cmnts", }, }; diff --git a/apps/cs/src/shared/lib/use-prompt.tsx b/apps/cs/src/shared/lib/use-prompt.tsx index da9c4b386..f36858eb0 100644 --- a/apps/cs/src/shared/lib/use-prompt.tsx +++ b/apps/cs/src/shared/lib/use-prompt.tsx @@ -7,18 +7,18 @@ export const usePrompt = () => { const prompt = (message: string) => { setMessage(message); - return new Promise((resolve) => { + return new Promise<{ resolved: boolean; value?: string }>((resolve) => { setResolve(() => resolve); }); }; const onSubmit = (value: string) => { - resolve?.(value); + resolve?.({ resolved: true, value }); setMessage(""); }; const onCancel = () => { - resolve?.(""); + resolve?.({ resolved: false }); setMessage(""); }; diff --git a/apps/cs/src/shared/providers/index.ts b/apps/cs/src/shared/providers/index.ts index f2e092170..fa8320fe7 100644 --- a/apps/cs/src/shared/providers/index.ts +++ b/apps/cs/src/shared/providers/index.ts @@ -1 +1,2 @@ export { StoreProvider } from "./store-provider"; +export { PromptProvider } from "./prompt-provider"; diff --git a/apps/cs/src/shared/providers/prompt-provider.tsx b/apps/cs/src/shared/providers/prompt-provider.tsx index 267b7aafc..10338c338 100644 --- a/apps/cs/src/shared/providers/prompt-provider.tsx +++ b/apps/cs/src/shared/providers/prompt-provider.tsx @@ -2,9 +2,15 @@ import { createContext, useState } from "react"; interface PromptContext { message?: string; - resolve?: (value: string) => void; + resolve?: ({ + resolved, + value, + }: { + resolved: boolean; + value?: string; + }) => void; setMessage: (message: string) => void; - setResolve: (resolve: (value: string) => void) => void; + setResolve: (resolve: () => void) => void; } export const PromptContext = createContext({ @@ -16,7 +22,10 @@ export const PromptContext = createContext({ export const PromptProvider = ({ children }: { children: React.ReactNode }) => { const [message, setMessage] = useState(); - const [resolve, setResolve] = useState<(value: string) => void>(); + const [resolve, setResolve] = + useState< + ({ resolved, value }: { resolved: boolean; value?: string }) => void + >(); return ( ({ key={row.id} onClick={() => onRowClick?.(row.original)} className={cn( - "rounded-md border border-border bg-background p-4 shadow-md", + "overflow-hidden rounded-md border border-border bg-background p-4 shadow-md", onRowClick && "cursor-pointer hover:bg-accent", )} > diff --git a/apps/cs/src/shared/ui/prompt-dialog.tsx b/apps/cs/src/shared/ui/prompt-dialog.tsx new file mode 100644 index 000000000..54c2f3fcc --- /dev/null +++ b/apps/cs/src/shared/ui/prompt-dialog.tsx @@ -0,0 +1,45 @@ +import { useState } from "react"; +import { + Button, + Dialog, + DialogContent, + DialogFooter, + DialogClose, + Input, +} from "@common/components"; +import { usePrompt } from "@/shared/lib/use-prompt"; + +function PromptDialog() { + const { message, isOpen, onSubmit, onCancel } = usePrompt(); + const [value, setValue] = useState(""); + + return ( + + +
+

+ {message} +

+ setValue(e.target.value)} + /> +
+ + + + + + + + +
+
+ ); +} + +export { PromptDialog }; diff --git a/apps/cs/src/widgets/post/model/grid-view-table-columns.tsx b/apps/cs/src/widgets/post/model/grid-view-table-columns.tsx index 96f7866db..34f2fc237 100644 --- a/apps/cs/src/widgets/post/model/grid-view-table-columns.tsx +++ b/apps/cs/src/widgets/post/model/grid-view-table-columns.tsx @@ -1,12 +1,19 @@ import dayjs from "dayjs"; import Image from "next/image"; import type { ColumnDef } from "@tanstack/react-table"; -import { Badge, Checkbox, Skeleton } from "@common/components"; +import { Badge, Checkbox, Skeleton, cn } from "@common/components"; import { AttachmentApi } from "@/entities/attachment"; import type { Post } from "@/entities/post"; import { useQuery } from "@tanstack/react-query"; import { ENDPOINT } from "@/shared/config"; -import { useMenuStore } from "@/shared/lib"; +import type { BbsType } from "@/shared/store/menu-store"; + +declare module "@tanstack/react-table" { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + interface TableMeta { + bbsTypeCd?: BbsType; + } +} export const createColumns = ( thumbRefs: React.MutableRefObject>, @@ -23,73 +30,117 @@ export const createColumns = ( className="h-4 w-4 rounded border-gray-300" /> ), - cell: ({ row }) => { - const { pstTtl, inqNocs } = row.original; - return ( -
-
- e.stopPropagation()} - onCheckedChange={(checked) => row.toggleSelected(!!checked)} - className="h-4 w-4 rounded border-gray-300" + cell: ({ row, table }) => { + const { atflCd, pstNo, pstTtl, inqNocs, rgtrNm, regDt } = row.original; + const bbsTypeCd = table.options.meta?.bbsTypeCd; + + if (bbsTypeCd === "BBSIMAGE") { + return ( +
+
+ e.stopPropagation()} + onCheckedChange={(checked) => row.toggleSelected(!!checked)} + className="h-4 w-4 rounded border-gray-300" + /> + {inqNocs >= 100 && HOT} + {dayjs().diff(dayjs(row.original.regDt), "hour") < 24 && ( + NEW + )} + + {pstTtl} + +
+ - {inqNocs >= 100 && HOT} - {dayjs().diff(dayjs(row.original.regDt), "hour") < 24 && ( - NEW - )} +
+ + {rgtrNm} + + + {dayjs(regDt).format("YYYY-MM-DD")} + +
- - {pstTtl} - -
- ); + ); + } + + if (bbsTypeCd === "BBSMOVIE") { + return ( +
+ +
+
+
+ e.stopPropagation()} + onCheckedChange={(checked) => row.toggleSelected(!!checked)} + className="h-4 w-4 rounded border-gray-300" + /> + {inqNocs >= 100 && HOT} + {dayjs().diff(dayjs(regDt), "hour") < 24 && ( + NEW + )} + + {pstTtl} + +
+
+ + {rgtrNm} + + + {dayjs(regDt).format("YYYY-MM-DD")} + +
+
+
+
+ ); + } }, }, - { - id: "atflCd", - cell: ({ row }) => { - const { atflCd, pstNo } = row.original; - return ; - }, - }, - { - id: "rgtrNm", - cell: ({ row }) => { - return ( - - {row.original.rgtrNm} - - ); - }, - }, - { - id: "regDt", - cell: ({ row }) => ( - - {dayjs(row.original.regDt).format("YYYY-MM-DD")} - - ), - }, ]; type ThumbImageProps = { atflCd: string; pstNo: number; thumbRefs: React.MutableRefObject>; + bbsTypeCd?: string; + classes?: { + image?: string; + }; }; -const ThumbImage = ({ atflCd, pstNo, thumbRefs }: ThumbImageProps) => { +const ThumbImage = ({ + atflCd, + pstNo, + thumbRefs, + bbsTypeCd, + classes, +}: ThumbImageProps) => { const prevImage = thumbRefs.current.get(pstNo); - const { bbsInfo } = useMenuStore((state) => state); - const { data: imageUrl, isLoading } = useQuery({ queryKey: [ENDPOINT.ATTACH_SERVICE.IMAGES, atflCd], queryFn: () => { - if (bbsInfo?.bbsTypeCd === "BBSIMAGE") { + if (bbsTypeCd === "BBSIMAGE") { return AttachmentApi.getImageUrlByAtflCd(atflCd); - } else if (bbsInfo?.bbsTypeCd === "BBSMOVIE") { + } else if (bbsTypeCd === "BBSMOVIE") { return AttachmentApi.getMovieThumbnailUrlByAtflCd(atflCd); } }, @@ -102,17 +153,17 @@ const ThumbImage = ({ atflCd, pstNo, thumbRefs }: ThumbImageProps) => { if (isLoading) return ( -
- +
+
); if (imageUrl) return ( -
+
썸네일 이미지 @@ -120,7 +171,7 @@ const ThumbImage = ({ atflCd, pstNo, thumbRefs }: ThumbImageProps) => { ); return ( -
+
); diff --git a/apps/cs/src/widgets/post/model/post-table-columns.tsx b/apps/cs/src/widgets/post/model/post-table-columns.tsx index 862538896..973ce9315 100644 --- a/apps/cs/src/widgets/post/model/post-table-columns.tsx +++ b/apps/cs/src/widgets/post/model/post-table-columns.tsx @@ -34,7 +34,7 @@ export const columns: ColumnDef[] = [ return ( diff --git a/apps/cs/src/widgets/post/ui/post-action.tsx b/apps/cs/src/widgets/post/ui/post-action.tsx index c74c76482..acaa60bf5 100644 --- a/apps/cs/src/widgets/post/ui/post-action.tsx +++ b/apps/cs/src/widgets/post/ui/post-action.tsx @@ -1,24 +1,24 @@ import { useRouter, usePathname } from "next/navigation"; -import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { Button } from "@common/components"; -import { useMenuStore, useUserStore } from "@/shared/lib"; +import { useMenuStore, usePrompt, useUserStore } from "@/shared/lib"; type PostActionProps = { bbsId: string; pstNo: string; children: React.ReactNode; - handleDelete: () => Promise; + handleDelete: (delRsn?: string) => Promise; }; function PostAction({ children, handleDelete }: PostActionProps) { const router = useRouter(); const pathname = usePathname(); - const { confirm } = useConfirm(); + const { prompt } = usePrompt(); const { bbsInfo } = useMenuStore((state) => state); const { userInfo } = useUserStore((state) => state); const onDelete = async () => { - if (await confirm("삭제하시겠습니까?")) handleDelete(); + const { resolved, value } = await prompt("삭제 사유를 입력해주세요."); + if (resolved) handleDelete(value); }; const checkAnsUseAuthrt = () => { @@ -35,7 +35,7 @@ function PostAction({ children, handleDelete }: PostActionProps) { }; return ( -
+ <> {children}
-
+ ); } diff --git a/apps/cs/src/widgets/post/ui/post-comment.tsx b/apps/cs/src/widgets/post/ui/post-comment.tsx index f87a90fca..1800b2581 100644 --- a/apps/cs/src/widgets/post/ui/post-comment.tsx +++ b/apps/cs/src/widgets/post/ui/post-comment.tsx @@ -89,7 +89,8 @@ function PostComment({ bbsId, pstNo }: { bbsId: number; pstNo: number }) { if (userInfo?.userUnqId) { cmntPswd = userInfo?.userUnqId; } else { - cmntPswd = await prompt("비밀번호를 입력해주세요."); + const { resolved, value } = await prompt("비밀번호를 입력해주세요."); + if (resolved) cmntPswd = value ?? ""; } return cmntPswd; }; diff --git a/apps/cs/src/widgets/post/ui/post-page.tsx b/apps/cs/src/widgets/post/ui/post-page.tsx index 6389bc799..d419f19f6 100644 --- a/apps/cs/src/widgets/post/ui/post-page.tsx +++ b/apps/cs/src/widgets/post/ui/post-page.tsx @@ -2,7 +2,6 @@ import { useEffect, useRef, useState } from "react"; import { usePathname, useRouter } from "next/navigation"; -import { useConfirm } from "@frontend-opensource/use-react-hooks"; import { useQuery } from "@tanstack/react-query"; import { getCoreRowModel, @@ -24,7 +23,7 @@ import { } from "@common/components"; import { PostApi, type Post, type PostParams } from "@/entities/post"; import { ENDPOINT } from "@/shared/config"; -import { useMenuStore, useUserStore } from "@/shared/lib"; +import { useMenuStore, usePrompt } from "@/shared/lib"; import { GridViewDataTable } from "@/shared/ui/grid-view-data-table"; import { columns as tableColumns } from "../model/post-table-columns"; import { createColumns as createGridViewColumns } from "../model/grid-view-table-columns"; @@ -32,8 +31,7 @@ import { createColumns as createGridViewColumns } from "../model/grid-view-table function PostPage({ bbsId }: { bbsId: string }) { const router = useRouter(); const pathname = usePathname(); - const { confirm } = useConfirm(); - const { userInfo } = useUserStore((state) => state); + const { prompt } = usePrompt(); const { bbsInfo, pageMenuAuthority } = useMenuStore((state) => state); const thumbRefs = useRef>(new Map()); @@ -48,9 +46,9 @@ function PostPage({ bbsId }: { bbsId: string }) { const [rowSelection, setRowSelection] = useState({}); const { data: upndFixPostList } = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, bbsInfo], + queryKey: [ENDPOINT.BOARD_SERVICE.POSTS, bbsId, bbsInfo], queryFn: () => - PostApi.getPostList(bbsId, { + PostApi.getPostList(parseInt(bbsId), { ...postParams, upndFixYn: bbsInfo?.upndFixUseYn, }), @@ -69,9 +67,9 @@ function PostPage({ bbsId }: { bbsId: string }) { isFetched, refetch, } = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId], + queryKey: [ENDPOINT.BOARD_SERVICE.POSTS, bbsId], queryFn: () => - PostApi.getPostList(bbsId, { + PostApi.getPostList(parseInt(bbsId), { ...postParams, page: pagination.pageIndex, size: pagination.pageSize, @@ -94,6 +92,7 @@ function PostPage({ bbsId }: { bbsId: string }) { getCoreRowModel: getCoreRowModel(), onPaginationChange: setPagination, onRowSelectionChange: setRowSelection, + meta: { bbsTypeCd: bbsInfo?.bbsTypeCd }, }); const DataTableComponent = isGridViewPage ? GridViewDataTable : DataTable; @@ -103,15 +102,16 @@ function PostPage({ bbsId }: { bbsId: string }) { .getFilteredSelectedRowModel() .rows.map((row) => row.original.pstNo); - if (await confirm("삭제하시겠습니까?")) { - setRowSelection({}); - await Promise.all( - selectedPosts.map((pstNo) => - PostApi.deletePost(bbsId, pstNo.toString(), userInfo?.userUnqId), - ), - ); - refetch(); - } + const { resolved, value: delRsn } = + await prompt("삭제 사유를 입력해주세요."); + if (!resolved) return; + setRowSelection({}); + await Promise.all( + selectedPosts.map((pstNo) => + PostApi.deletePost(parseInt(bbsId), pstNo, delRsn), + ), + ); + refetch(); }; const handleSubmit = (e: React.FormEvent) => { diff --git a/apps/cs/src/widgets/post/ui/post.tsx b/apps/cs/src/widgets/post/ui/post.tsx index 3cac19401..370c9cc1d 100644 --- a/apps/cs/src/widgets/post/ui/post.tsx +++ b/apps/cs/src/widgets/post/ui/post.tsx @@ -8,28 +8,21 @@ import { useMutation, useQuery } from "@tanstack/react-query"; import { Button, Skeleton } from "@common/components"; import { AttachmentApi } from "@/entities/attachment"; import { PostApi } from "@/entities/post"; -import { - useAlertStore, - useUserStore, - useMenuStore, - usePrompt, -} from "@/shared/lib"; +import { useAlertStore, useMenuStore } from "@/shared/lib"; import { ENDPOINT } from "@/shared/config"; import { PostAction } from "./post-action"; import { PostComment } from "./post-comment"; function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { const router = useRouter(); - const { prompt } = usePrompt(); const { setMessage: alert } = useAlertStore((state) => state); - const { userInfo } = useUserStore((state) => state); const { bbsInfo } = useMenuStore((state) => state); const [filename, setFilename] = useState(""); const { data: postData } = useQuery({ - queryKey: [ENDPOINT.BOARD_SERVICE.POSTS_USER, bbsId, pstNo], - queryFn: () => PostApi.getPostInfo(bbsId, pstNo), + queryKey: [ENDPOINT.BOARD_SERVICE.POSTS, bbsId, pstNo], + queryFn: () => PostApi.getPostInfo(parseInt(bbsId), parseInt(pstNo)), }); const { data: downloadResponse, isFetching } = useQuery({ @@ -65,23 +58,14 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { enabled: !!videoAttachment?.atflId, }); - const { mutate: deletePost } = useMutation({ - mutationFn: (pstPswd: string) => PostApi.deletePost(bbsId, pstNo, pstPswd), + const { mutateAsync: deletePost } = useMutation({ + mutationFn: (delRsn?: string) => + PostApi.deletePost(parseInt(bbsId), parseInt(pstNo), delRsn), onSuccess: () => { alert("삭제되었습니다.", router.back); }, }); - const handleDelete = async () => { - let pstPswd = ""; - if (userInfo?.userUnqId) { - pstPswd = userInfo?.userUnqId; - } else { - pstPswd = await prompt("비밀번호를 입력해주세요."); - } - deletePost(pstPswd); - }; - const handleDownload = async () => { if (!downloadResponse) return; try { @@ -123,7 +107,7 @@ function Post({ bbsId, pstNo }: { bbsId: string; pstNo: string }) { return ( <> - +

{postData?.pstTtl}