Files
frontend/apps/cs/src/pages/groups/ui/groups-section.tsx
T

162 lines
4.6 KiB
TypeScript

"use client";
import { useState } from "react";
import {
keepPreviousData,
useQuery,
useQueryClient,
} from "@tanstack/react-query";
import { getCoreRowModel, type PaginationState } from "@tanstack/react-table";
import { Button, Input, Label } from "@common/components";
import { GroupApi, type GroupSearchParams } from "@/entities/group";
import { ENDPOINT } from "@/shared/config";
import { useDataTable } from "@/shared/lib";
import { createColumns } from "../model/groups-table-columns";
import { GroupsDialog } from "./groups-dialog";
import { useConfirm } from "@frontend-opensource/use-react-hooks";
import { useAlertStore, useMutationWrapper } from "@/shared/lib";
type GroupsSectionProps = {
handleSelectedGroup: (groupId: string) => void;
};
function GroupsSection({ handleSelectedGroup }: GroupsSectionProps) {
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const [groupNm, setGroupNm] = useState("");
const [searchParams, setSearchParams] = useState<GroupSearchParams>({
groupNm: "",
delYn: "N",
sort: "groupId,desc",
});
const query = useQuery({
queryKey: [ENDPOINT.CMS_SERVICE.GROUPS, searchParams, pagination],
queryFn: () =>
GroupApi.findPageGroup({
...searchParams,
page: pagination.pageIndex,
size: pagination.pageSize,
}),
placeholderData: keepPreviousData,
});
const { confirm } = useConfirm();
const alert = useAlertStore((state) => state.setMessage);
const queryClient = useQueryClient();
const { mutateAsync: deleteGroup } = useMutationWrapper({
mutationFn: (groupId: string) => GroupApi.deleteGroup(groupId),
onSuccess: () => {
alert("삭제되었습니다.");
queryClient.invalidateQueries({
predicate: (query) => query.queryKey[0] === ENDPOINT.CMS_SERVICE.GROUPS,
});
},
});
const handleDelete = async (groupId: string) => {
if (await confirm("삭제하시겠습니까?")) {
await deleteGroup(groupId);
}
};
const handleSubmit = (e: React.SubmitEvent<HTMLFormElement>) => {
e.preventDefault();
setPagination({
...pagination,
pageIndex: 0,
});
setSearchParams({
...searchParams,
groupNm,
});
};
const handleReset = () => {
setGroupNm("");
setSearchParams({
...searchParams,
groupNm: "",
delYn: "N",
});
};
const handleRowClick = (row: { groupId: string }) => {
table.setRowSelection({ [row.groupId]: true });
handleSelectedGroup(row.groupId); // 1. 리스트에서 선택된 groupId 저장
};
const { tableComponent, tableInstance: table } = useDataTable({
query,
tableOptions: {
columns: createColumns({ onDelete: handleDelete }),
state: { pagination },
manualPagination: true,
enableMultiRowSelection: false,
getCoreRowModel: getCoreRowModel(),
onPaginationChange: setPagination,
getRowId: (row) => row.groupId,
},
dataTableOptions: {
onRowClick: handleRowClick,
viewPagination: true,
},
});
return (
<div className="flex-1">
<div className="card card-border">
<form onSubmit={handleSubmit} className="flex items-center gap-2 p-2">
<Label htmlFor="" className="mr-2 text-label">
그룹명
</Label>
<Input
className="h-[3.2rem] w-[20rem] rounded-sm !text-[1.3rem]"
value={groupNm}
onChange={(e) => setGroupNm(e.target.value)}
/>
<Button className="h-[3.2rem]" type="submit">
조회
</Button>
<Button
type="button"
color="white"
className="h-[3.2rem]"
onClick={handleReset}
>
초기화
</Button>
<Label htmlFor="delYn" className="ml-4 mr-2 text-label">
삭제여부
</Label>
<input
id="delYn"
type="checkbox"
checked={searchParams.delYn === "Y"}
onChange={(e) =>
setSearchParams({
...searchParams,
delYn: e.target.checked ? "Y" : "N",
})
}
/>
</form>
</div>
<div className="card card-border">
<div className="card-header">
<h3 className="text-2xl font-medium text-label">그룹 목록</h3>
<GroupsDialog onSuccess={query.refetch}>
<Button>등록</Button>
</GroupsDialog>
</div>
<div className="card !m-4 h-[calc(100vh-25.5rem)] overflow-auto !p-0">
{tableComponent}
</div>
</div>
</div>
);
}
export { GroupsSection };