import type {ContentListItem, ContentSearchParams} from "../../type/content.types.ts"; import type { CheckableTableModel, HeaderModel, ListActionsModel, PaginationModel, RowActionsModel, SearchModel, StatusModel } from "../../../../../type/viewModel.ts"; import {useMemo, useState} from "react"; import {useContentList} from "../query/useContentList.ts"; import {useCheckedList} from "../../../../hook/useCheckedList.ts"; import {toast} from "react-toastify"; import {useNavigate} from "react-router-dom"; import {useDeleteBatchContent} from "../mutation/useDeleteBatchContent.ts"; import {ADMIN_CONTENT_FORM_ROUTE} from "../../../../route/adminRouteMap.ts"; type ContentListRowActions = { onDetail: (cntId: string, cntDtId: string) => void, onPreview: (cntId: string, cntDtId: string) => void, } type ContentListPageModel = { header: HeaderModel; status: StatusModel; search: SearchModel table: CheckableTableModel & RowActionsModel actions: ListActionsModel; pagination: PaginationModel; } const initSearchParams: ContentSearchParams = { pageIndex: 1, pageUnit: 10, searchCnd: "0", searchKeyword: "", searchSortCnd: "", searchSortOrd: "" } const pageSizeOptions = [ {value: '10', label: '10줄'}, {value: '20', label: '20줄'}, {value: '30', label: '30줄'}, ] const title = "콘텐츠관리" const breadcrumb = [ {label: "콘텐츠관리"} ] export const useContentListPage = (): ContentListPageModel => { const navigate = useNavigate(); const [searchParams, setSearchParams] = useState(initSearchParams); const { list, totalItems, totalPages, currentPage, size, isLoading, error } = useContentList(searchParams); const {mutateAsync: deleteBatchContent} = useDeleteBatchContent(); const contentIds = useMemo(() => list.map((item) => item.cntId), [list]); const { checkedIds, isAllChecked, isPartiallyChecked, isChecked, handleCheck, handleCheckAll } = useCheckedList(contentIds); const handleDetail = (cntId:string, cntDtId: string) => { navigate(`${ADMIN_CONTENT_FORM_ROUTE}?cntId=${cntId}&cntDtId=${cntDtId}`); } const handlePreview = (cntId: string, cntDtId: string) => { const params = new URLSearchParams({ skin: 'user', cntId, cntDtId, }); const previewUrl = `/preview/content?${params.toString()}`; window.open( previewUrl, 'contentPreview', 'width=1200,height=900,top=80,left=120,scrollbars=yes,resizable=yes', ); } const handleDeleteBatch = async () => { if(checkedIds.length === 0) { toast.warning('삭제할 컨텐츠를 선택해주세요'); return; } const contentList = checkedIds.map((cntId) => ({ cntId, })); await toast.promise( deleteBatchContent(contentList), { pending: '삭제 처리중...', success: '삭제 완료', error: '삭제 실패' } ) } const handleCreate = () => { navigate(`${ADMIN_CONTENT_FORM_ROUTE}`); } const handlePageChange = (pageIndex: number) => { setSearchParams((prev) =>({ ...prev, pageIndex })); } return { header: { title, breadcrumb, homeUrl: '#', }, status : { isLoading, error, successMessage: '콘텐츠의 조회가 완료되었습니다.' }, search: { totalItems, searchParams, onChange: setSearchParams, pageSizeOptions, }, table: { items: list, params: searchParams, onChange: setSearchParams, pagination: { totalItems, currentPage, totalPages, }, check: { isAllChecked, isPartiallyChecked, isChecked, onCheck: handleCheck, onCheckAll: handleCheckAll, }, rowActions: { onDetail: handleDetail, onPreview: handlePreview, } }, actions: { onDelete: handleDeleteBatch, onCreate: handleCreate }, pagination: { totalItems, totalPages, currentPage, size, onPageChange: handlePageChange } } }