Files
frontend/apps/st/src/components/statistics/verification/GeneralVerificationManagement.tsx
T

202 lines
8.6 KiB
TypeScript

"use client";
import { useState, useEffect, useMemo } from 'react';
import { CodeSelectWithAll } from '@/entities/code';
import {
Button,
Label,
Select,
SelectTrigger,
SelectContent,
SelectValue,
SelectItem,
DataTable,
} from "@common/components";
import { LoadingWithAnimation } from '@common/components';
import { NoData } from '@/shared/ui/no-data';
import DetailComponent from './generalVerification/DetailComponent';
import RegistDialog from './generalVerification/RegistDialog';
import { getCoreRowModel, useReactTable } from "@tanstack/react-table";
import { getGeneralVerificationColumns } from '@/components/util/column/management/GeneralVerificationColumn';
import type { GeneralverificationList } from '@/entities/statistics/model/general-verification-interface';
import { generalverificationApiService } from '@/entities/statistics/api/general-verification-service';
import { useAlertStore } from '@/shared/lib';
const GeneralVerificationManagement = () => {
const [searchValues, setSearchValues] = useState<{
statsCd: string;
useYn: string;
vrfcClsfCd: string;
}>({
statsCd: '',
useYn: '',
vrfcClsfCd: '',
});
const [vrfcMasterData, setVrfcMasterData] = useState<GeneralverificationList[]>([]);
const [rowSelection, setRowSelection] = useState<Record<string, boolean>>({});
const [isLoading, setIsLoading] = useState<boolean>(false);
const [selectedVrfcRow, setSelectedVrfcRow] = useState<number | null>(null);
const [showRegistForm, setShowRegistForm] = useState<boolean>(false);
const { setMessage: alert } = useAlertStore((state) => state);
const handleSearch = async () => {
try {
setIsLoading(true);
const params = Object.fromEntries(
Object.entries({
trgtStatsCd: searchValues.statsCd,
vrfcClsfCd: searchValues.vrfcClsfCd,
useYn: searchValues.useYn,
}).filter(([, value]) => value !== '' && value !== 'ALL')
);
const response = await generalverificationApiService.getGeneralverificationList(params);
if (response.status === 'success') {
setVrfcMasterData(response.data);
setRowSelection({});
setSelectedVrfcRow(null);
setShowRegistForm(false);
} else {
alert(response.message || '데이터 조회 중 오류가 발생했습니다.');
}
} catch {
alert('데이터 조회 중 오류가 발생했습니다.');
} finally {
setIsLoading(false);
}
};
const columns = useMemo(
() => getGeneralVerificationColumns(handleSearch),
[searchValues.statsCd, searchValues.vrfcClsfCd, searchValues.useYn],
);
const table = useReactTable({
data: vrfcMasterData,
columns,
getCoreRowModel: getCoreRowModel(),
getRowId: (row) => String(row.vrfcSn),
state: { rowSelection },
onRowSelectionChange: setRowSelection,
});
const handleVrfcMasterRowClick = async (row: GeneralverificationList) => {
setRowSelection({ [row.vrfcSn]: true });
setSelectedVrfcRow(row.vrfcSn);
setShowRegistForm(false);
};
const handleReset = () => {
setRowSelection({});
setSelectedVrfcRow(null);
handleSearch();
setShowRegistForm(false);
}
useEffect(() => {
handleSearch();
}, []);
return (
<div className="h-full">
<div className="card card-border">
<div className="flex items-center gap-8 p-2">
<div className="flex items-center gap-2">
<Label className="text-label">
통계항목
</Label>
<CodeSelectWithAll
upCd="STITEM"
value={searchValues.statsCd}
onValueChange={(value) => setSearchValues({ ...searchValues, statsCd: value })}
placeholder="전체"
className="w-[16rem]"
/>
</div>
<div className="flex items-center gap-2">
<Label className="text-label">
검증분류
</Label>
<Select value={searchValues.vrfcClsfCd} onValueChange={(value) => setSearchValues({ ...searchValues, vrfcClsfCd: value })}>
<SelectTrigger className="w-[10rem]">
<SelectValue placeholder="전체"></SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem value="ALL">전체</SelectItem>
<SelectItem value="DO_SI">도단위 검증</SelectItem>
<SelectItem value="SI_GU">시단위 검증</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex items-center gap-2">
<Label className="text-label">
사용여부
</Label>
<Select value={searchValues.useYn} onValueChange={(value) => setSearchValues({ ...searchValues, useYn: value })}>
<SelectTrigger className="w-[10rem]">
<SelectValue placeholder="전체"></SelectValue>
</SelectTrigger>
<SelectContent>
<SelectItem value="ALL">전체</SelectItem>
<SelectItem value="Y">Y</SelectItem>
<SelectItem value="N">N</SelectItem>
</SelectContent>
</Select>
</div>
<div className="flex items-center gap-2 ml-auto">
<Button color="green" className="h-[3.2rem] w-[96px]" type="button" onClick={handleReset}>
초기화
</Button>
<Button className="h-[3.2rem] w-[96px]" type="button" onClick={handleSearch}>
조회
</Button>
</div>
</div>
</div>
<div className="card !my-0 flex flex-col !p-0">
<div className='flex items-center justify-end gap-[0.6rem] px-[1.2rem]'>
<RegistDialog open={showRegistForm} onOpenChange={setShowRegistForm} onSuccess={handleSearch}>
<Button className="h-[3.2rem] w-[96px]" type="button">
등록
</Button>
</RegistDialog>
</div>
<div className="flex justify-center gap-5 !p-0 h-[65vh]">
<div className="card card-border w-1/2 !mx-0 flex flex-col">
<div className="card-header">
<h3 className="text-2xl font-medium text-label">일반 검증 목록</h3>
</div>
<div className="card !m-4 h-full overflow-auto !p-0">
{isLoading && (
<div className="absolute inset-0 z-50 [data-theme='black']:bg-transparent rounded-lg p-10 flex justify-center items-center">
<div className="relative size-[5rem]">
<LoadingWithAnimation color="primary" />
</div>
</div>
)}
{isLoading ? null
:
vrfcMasterData.length > 0 ?
<DataTable table={table} onRowClick={(value) => handleVrfcMasterRowClick(value)} />
:
<div className="flex h-full items-center justify-center">
<NoData />
</div>
}
</div>
</div>
<DetailComponent selectedVrfcRow={selectedVrfcRow} />
</div>
</div>
</div>
);
};
export default GeneralVerificationManagement;