ERP-node/frontend/hooks/useReportList.ts

113 lines
3.6 KiB
TypeScript

import { useState, useEffect, useCallback } from "react";
import { ReportMaster, GetReportsParams } from "@/types/report";
import { reportApi } from "@/lib/api/reportApi";
import { useToast } from "@/hooks/use-toast";
type SearchField = "report_name" | "created_by" | "report_type" | "updated_at" | "created_at";
export function useReportList() {
const [reports, setReports] = useState<ReportMaster[]>([]);
const [total, setTotal] = useState(0);
const [typeSummary, setTypeSummary] = useState<Array<{ type: string; count: number }>>([]);
const [allTypes, setAllTypes] = useState<string[]>([]);
const [recentActivity, setRecentActivity] = useState<Array<{ date: string; count: number }>>([]);
const [recentTotal, setRecentTotal] = useState(0);
const [page, setPage] = useState(1);
const [limit, setLimit] = useState(8);
const [isLoading, setIsLoading] = useState(false);
const [searchText, setSearchText] = useState("");
const [searchField, setSearchField] = useState<SearchField>("report_name");
const [startDate, setStartDate] = useState("");
const [endDate, setEndDate] = useState("");
const [reportType, setReportType] = useState("");
const { toast } = useToast();
const fetchReports = async () => {
setIsLoading(true);
try {
const isDateSearch = searchField === "created_at" || searchField === "updated_at";
const params: GetReportsParams = {
page,
limit,
searchText: isDateSearch ? undefined : searchText || undefined,
searchField: (isDateSearch && startDate && endDate) || searchText ? searchField : undefined,
startDate: isDateSearch && startDate ? startDate : undefined,
endDate: isDateSearch && endDate ? endDate : undefined,
reportType: reportType || undefined,
useYn: "Y",
sortBy: "created_at",
sortOrder: "DESC",
};
const response = await reportApi.getReports(params);
if (response.success && response.data) {
setReports(response.data.items);
setTotal(response.data.total);
setTypeSummary(response.data.typeSummary ?? []);
setAllTypes(response.data.allTypes ?? []);
setRecentActivity(response.data.recentActivity ?? []);
setRecentTotal(response.data.recentTotal ?? 0);
}
} catch (error: unknown) {
const msg = error instanceof Error ? error.message : "리포트 목록을 불러오는데 실패했습니다.";
console.error("리포트 목록 조회 에러:", error);
toast({ title: "오류", description: msg, variant: "destructive" });
} finally {
setIsLoading(false);
}
};
useEffect(() => {
fetchReports();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [page, limit, searchText, searchField, startDate, endDate, reportType]);
const handleSearch = (text: string) => {
setSearchText(text);
setPage(1);
};
const handleSearchFieldChange = (field: SearchField) => {
setSearchField(field);
if (field !== "created_at" && field !== "updated_at") {
setStartDate("");
setEndDate("");
}
setPage(1);
};
const handleDateRangeChange = useCallback((start: string, end: string) => {
setStartDate(start);
setEndDate(end);
setPage(1);
}, []);
const handleTypeFilter = (type: string) => {
setReportType(type);
setPage(1);
};
return {
reports,
total,
typeSummary,
allTypes,
recentActivity,
recentTotal,
page,
limit,
isLoading,
searchField,
startDate,
endDate,
refetch: fetchReports,
setPage,
setLimit,
handleSearch,
handleSearchFieldChange,
handleDateRangeChange,
handleTypeFilter,
};
}