feat: 설문 사이트 게시 이력 관리 작업
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import dayjs from "dayjs";
|
||||
import type { ColumnDef } from "@tanstack/react-table";
|
||||
import { Checkbox } from "@common/components";
|
||||
import type { Post } from "@/entities/posting";
|
||||
|
||||
export const columns: ColumnDef<Post>[] = [
|
||||
{
|
||||
id: "select",
|
||||
header: ({ table }) => (
|
||||
<Checkbox
|
||||
checked={table.getIsAllPageRowsSelected()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onCheckedChange={(checked) =>
|
||||
table.toggleAllPageRowsSelected(!!checked)
|
||||
}
|
||||
className="h-4 w-4 rounded border-gray-300"
|
||||
/>
|
||||
),
|
||||
cell: ({ row }) => (
|
||||
<Checkbox
|
||||
checked={row.getIsSelected()}
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
onCheckedChange={(checked) => row.toggleSelected(!!checked)}
|
||||
className="h-4 w-4 rounded border-gray-300"
|
||||
/>
|
||||
),
|
||||
meta: {
|
||||
width: 50,
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "siteNm",
|
||||
header: "사이트",
|
||||
},
|
||||
{
|
||||
accessorKey: "pstgPrdSeNm",
|
||||
header: "게시기간",
|
||||
cell: ({ row }) => {
|
||||
const pstgPrdSeNm = row.original.pstgPrdSeNm;
|
||||
const pstgBgngDt = row.original.pstgBgngDt;
|
||||
const pstgEndDt = row.original.pstgEndDt;
|
||||
return `${pstgPrdSeNm} (${dayjs(pstgBgngDt).format("YYYY-MM-DD")} ~ ${dayjs(pstgEndDt).format("YYYY-MM-DD")})`;
|
||||
},
|
||||
},
|
||||
];
|
||||
@@ -1,54 +1,128 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { usePathname, useRouter } from "next/navigation";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { Button } from "@common/components";
|
||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import {
|
||||
getCoreRowModel,
|
||||
useReactTable,
|
||||
type RowSelectionState,
|
||||
} from "@tanstack/react-table";
|
||||
import { useConfirm } from "@frontend-opensource/use-react-hooks";
|
||||
import { Button, DataTable } from "@common/components";
|
||||
import { PostingApi, type PostPayload } from "@/entities/posting";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { useAlertStore } from "@/shared/lib";
|
||||
import { SurveyApi } from "../api/survey-service";
|
||||
import { columns } from "../model/posting-table-columns";
|
||||
|
||||
function DetailPage({ srvySn }: { srvySn: string }) {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const { confirm } = useConfirm();
|
||||
const queryClient = useQueryClient();
|
||||
const alert = useAlertStore((state) => state.setMessage);
|
||||
|
||||
const [rowSelection, setRowSelection] = useState<RowSelectionState>({});
|
||||
|
||||
const { data: surveyInfo } = useQuery({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.SURVEY, srvySn],
|
||||
queryFn: () => SurveyApi.getSurveyInfo(parseInt(srvySn)),
|
||||
});
|
||||
|
||||
const { data: postHistory } = useQuery({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.POSTINGS, srvySn],
|
||||
queryFn: () =>
|
||||
PostingApi.getPostingHistory({ pstgTrgtNo: parseInt(srvySn) }),
|
||||
});
|
||||
|
||||
const { mutateAsync: savePostingHistory } = useMutation({
|
||||
mutationFn: (data: PostPayload[]) => PostingApi.savePosting(data),
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({
|
||||
queryKey: [ENDPOINT.CMS_SERVICE.POSTINGS, srvySn],
|
||||
});
|
||||
alert("삭제되었습니다.");
|
||||
},
|
||||
});
|
||||
|
||||
const table = useReactTable({
|
||||
data: postHistory?.content ?? [],
|
||||
columns,
|
||||
state: {
|
||||
rowSelection,
|
||||
},
|
||||
enableMultiRowSelection: true,
|
||||
getCoreRowModel: getCoreRowModel(),
|
||||
onRowSelectionChange: setRowSelection,
|
||||
});
|
||||
|
||||
const handleDeletePostingHistory = async () => {
|
||||
const data = table.getFilteredSelectedRowModel().rows.map((row) => ({
|
||||
...row.original,
|
||||
mode: "D",
|
||||
}));
|
||||
|
||||
if (await confirm("삭제하시겠습니까?")) {
|
||||
savePostingHistory(data);
|
||||
setRowSelection({});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="card card-border !mb-0 !mt-6">
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">설문 상세</h3>
|
||||
<div className="flex gap-2">
|
||||
<Button color="white" onClick={() => router.back()}>
|
||||
목록
|
||||
</Button>
|
||||
<Button onClick={() => router.push(`${pathname}/modify`)}>
|
||||
수정
|
||||
</Button>
|
||||
<Button color="red">삭제</Button>
|
||||
<div className="mt-6 flex flex-col">
|
||||
<div className="card card-border !mb-0 !mt-6">
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">설문 상세</h3>
|
||||
<div className="flex gap-2">
|
||||
<Button color="white" onClick={() => router.back()}>
|
||||
목록
|
||||
</Button>
|
||||
<Button onClick={() => router.push(`${pathname}/modify`)}>
|
||||
수정
|
||||
</Button>
|
||||
<Button color="red">삭제</Button>
|
||||
</div>
|
||||
</div>
|
||||
<ul className="flex flex-col">
|
||||
<li className="flex items-center gap-8 border-b border-border py-6">
|
||||
<span className="w-[16rem] text-right text-label">설문 제목</span>
|
||||
<p className="text-2xl font-bold">{surveyInfo?.srvyTtl}</p>
|
||||
</li>
|
||||
<li className="flex items-center gap-8 border-b border-border py-6">
|
||||
<span className="w-[16rem] text-right text-label">설문 목적</span>
|
||||
<p className="text-2xl font-bold">{surveyInfo?.srvyPrps}</p>
|
||||
</li>
|
||||
<li className="flex items-center gap-8 border-b border-border py-6">
|
||||
<span className="w-[16rem] text-right text-label">
|
||||
설문 작성 안내 내용
|
||||
</span>
|
||||
<p className="text-2xl font-bold">{surveyInfo?.srvyWrtGdCn}</p>
|
||||
</li>
|
||||
<li className="flex items-center gap-8 py-6">
|
||||
<span className="w-[16rem] text-right text-label">설문 대상</span>
|
||||
<p className="text-2xl font-bold">{surveyInfo?.srvyTrgt}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="card card-border">
|
||||
<div className="card-header">
|
||||
<h3 className="text-2xl font-medium text-label">사이트 게시 이력</h3>
|
||||
</div>
|
||||
<div className="card">
|
||||
<div className="mb-4 flex justify-end">
|
||||
<Button
|
||||
size="sm"
|
||||
color="red"
|
||||
disabled={!table.getFilteredSelectedRowModel().rows.length}
|
||||
onClick={handleDeletePostingHistory}
|
||||
>
|
||||
이력삭제
|
||||
</Button>
|
||||
</div>
|
||||
<DataTable table={table} />
|
||||
</div>
|
||||
</div>
|
||||
<ul className="flex flex-col">
|
||||
<li className="flex items-center gap-8 border-b border-border py-6">
|
||||
<span className="w-[16rem] text-right text-label">설문 제목</span>
|
||||
<p className="text-2xl font-bold">{surveyInfo?.srvyTtl}</p>
|
||||
</li>
|
||||
<li className="flex items-center gap-8 border-b border-border py-6">
|
||||
<span className="w-[16rem] text-right text-label">설문 목적</span>
|
||||
<p className="text-2xl font-bold">{surveyInfo?.srvyPrps}</p>
|
||||
</li>
|
||||
<li className="flex items-center gap-8 border-b border-border py-6">
|
||||
<span className="w-[16rem] text-right text-label">
|
||||
설문 작성 안내 내용
|
||||
</span>
|
||||
<p className="text-2xl font-bold">{surveyInfo?.srvyWrtGdCn}</p>
|
||||
</li>
|
||||
<li className="flex items-center gap-8 py-6">
|
||||
<span className="w-[16rem] text-right text-label">설문 대상</span>
|
||||
<p className="text-2xl font-bold">{surveyInfo?.srvyTrgt}</p>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import { AuthorityButton } from "@/entities/menu-authority";
|
||||
import { ENDPOINT } from "@/shared/config";
|
||||
import { SurveyApi } from "../api/survey-service";
|
||||
import type { Survey, SurveyParams } from "../model/survey-interface";
|
||||
import { columns } from "../model/table-columns";
|
||||
import { columns } from "../model/survey-table-columns";
|
||||
|
||||
type PostingTarget = {
|
||||
pstgTrgtNm: string;
|
||||
|
||||
Reference in New Issue
Block a user