Files
frontend/apps/wr/app/(with-layout)/matMng/coMng/drgtSttn/page.tsx
T

291 lines
14 KiB
TypeScript

"use client";
import { useWrStore } from "@/app/store";
import { btnClass } from "@/app/store/common/code";
import type { customDrgt } from "@/app/store/matDmd/drgtSttn";
import { drgtHeadListExport } from "@/app/store/matDmd/drgtSttn/headList";
import { getCity } from "@/components/lib/func/commom";
import DrgtDetailModal from "@/components/ui/modal/coMat/drgtDetailModal";
import type { objSearchType } from "@/components/ui/modal/fcltReg/bdstRegModal/bdstRegModal";
import { ContentsDiv, DateMonthPicker, downloadExcel, SearchDiv, SearchFormLeft, SearchFormRight, SelectBox, Title, UiModal, UiTable, type SelectDataType } from "@common/business_components/ui";
import ListDiv from "@common/business_components/ui/list_div";
import { Button, Label, ScrollArea } from "@common/components/ui";
import { useEffect, useState, useRef } from "react";
import { toast, Toaster } from "react-hot-toast";
export default function DrgtSttn() {
const { code, drgt, drgtSearch, drgtModalSearch, drgtInit } = useWrStore((state) => state);
const { drgtRes, drgtMoRes } = drgt;
const [fromDate, setFromDate] = useState<string>('202506');
const [toDate, setToDate] = useState<string>('202506');
const [selectSgg, setSelectSgg] = useState<SelectDataType[]>([{ val: '0', text: '전체' }]);
const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" });
const [tableData, setTableData] = useState<customDrgt[]>();
const [selectedSgg, setSelectedSgg] = useState<string>('');
const [excelData, setExcelData] = useState<any[]>();
const [drgtModal, setDrgtModal] = useState<{
isOpen: boolean;
data: customDrgt[] | undefined;
}>({ data: undefined, isOpen: false });
const popupRef = useRef<Window | null>(null);
const cellClick = (index: number) => {
if (fromDate && toDate && drgtRes[index]) {
drgtModalSearch(fromDate, toDate, drgtRes[index].sggNm ?? '');
} else {
toast.error("조회기간을 선택해주세요.");
}
}
const excelClick = () => {
downloadExcel({
data: excelData ?? [],
fileName: "우리동네가뭄 현황",
sheetNameArray: ["Sheet1"],
headerRange: "A1:G1"
})
}
useEffect(() => {
if (!drgt.isInit) {
drgtInit();
}
}, [drgt.isInit, drgtInit]);
useEffect(() => {
let resData = Array.isArray(drgtRes) ? drgtRes : [drgtRes];
resData = resData.map((item) => {
if (item.sggNm === '세종시') {
return {
...item,
ctpvCd: '세종특별자치시',
sggNm: ''
}
}
return {
...item,
ctpvCd: code.cityCd.find(ct => (ct.text == item.sggNm || (code.sggCd.find(sgg => sgg.text == item.sggNm)?.val.substring(0, 2) == ct.val)))?.text,
sggNm: code.sggCd.find(sgg => sgg.text == item.sggNm)?.text
}
})
const data = Array.isArray(resData)
? resData.map((item: customDrgt) => {
return {
"시도": item.ctpvCd,
"시군구": item.sggNm,
"정상(횟수)": item.normal,
"관심(횟수)": item.attention,
"주의(횟수)": item.caution,
"관심+주의(횟수)": item.warning,
"가뭄순위": item.ranking,
}
}) : [];
setExcelData(data)
setTableData(resData)
}, [drgtRes])
useEffect(() => {
if (drgtMoRes && drgtMoRes.length > 0) {
setDrgtModal({ isOpen: true, data: drgtMoRes });
}
}, [drgtMoRes]);
const getSelCity = (val: string | number) => {
const cityValue = String(val);
if (cityValue === "0") {
setSelectSgg([{ val: '0', text: '전체' }]);
setSelectedSgg('0');
setObjSearch({ city: cityValue, sgg: '0' });
} else {
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
const firstSggVal = data.find(item => item.val === "0")?.val || (data[0]?.val ?? "");
setSelectedSgg(firstSggVal);
setObjSearch({ city: cityValue, sgg: firstSggVal });
}
};
const getSgg = (val: string | number) => {
setSelectedSgg(String(val));
setObjSearch({ ...objSearch, sgg: String(val) });
};
useEffect(() => {
if (fromDate === undefined && toDate === undefined) {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const formatted = `${year}${month}`;
setFromDate(formatted);
setToDate(formatted);
}
}, [fromDate, toDate])
function onViewMapClick() {
const params = new URLSearchParams({
ctpvCd: String(objSearch.city),
sggCd: String(objSearch.sgg),
fromDate: fromDate || '',
toDate: toDate || ''
});
const popupOptions = `width=${window.screen.availWidth},height=${window.screen.availHeight},left=0,top=0,resizable=yes,scrollbars=yes`;
popupRef.current = window.open(`/mapDrgtPopUp?${params.toString()}`, "가뭄 지도 보기 팝업", popupOptions);
}
return (
<>
<ContentsDiv>
<div className="grid grid-cols-4 gap-4 ">
<div className="col-span-4">
<Title title={"우리동네가뭄"} />
<SearchDiv>
<SearchFormLeft>
<div className="col-span-10 flex flex-row">
<SelectBox
className="col-span-2 w-1/6 h-full text-2xl"
label="시도"
selectClass={""}
selectArray={code.cityCd || []}
onSelectValue={getSelCity}
value={objSearch?.city || code.cityCd[0]?.val || ""}
/>
<SelectBox
className="col-span-2 w-1/6 h-full text-2xl ml-8"
label="시군구"
selectClass={""}
selectArray={selectSgg || [{ val: '0', text: '전체' }]}
onSelectValue={getSgg}
value={selectedSgg || '0'}
/>
<div className="col-span-5 w-auto">
<div className="flex flex-row items-center">
<Label className="text-xl text-gray-600 ml-8">조회기간</Label>
<div className="flex flex-row w-1/4">
<DateMonthPicker
field={{
value: fromDate ?? "",
onChange: (date: string | undefined) => {
const year = date ? date.slice(0, 4) : '';
let month = date?.slice(4);
if (month && month?.length < 2) {
month = month?.padStart(2, "0");
}
const formatted = `${year}${month}`;
setFromDate(formatted);
}
}}
selectClass="ml-4 text-2xl"
/>
<span className="ml-2 text-center">~</span>
<DateMonthPicker
field={{
value: toDate ?? "",
onChange: (date: string | undefined) => {
const year = date ? date.slice(0, 4) : '';
let month = date?.slice(4);
if (month && month.length < 2) {
month = month?.padStart(2, "0");
}
const formatted = `${year}${month}`;
setToDate(formatted);
}
}}
selectClass="ml-4"
/>
</div>
</div>
</div>
</div>
</SearchFormLeft>
<SearchFormRight
className="w-2/12 mx-5 flex flex-col items-center justify-center space-x-2 ">
<div className="flex flex-row space-x-2 items-center">
<Button
size={"sm"}
onClick={() => {
let sidoText: string = '';
let sggText: string | string[] = '';
if (objSearch?.city.toString().length > 0) {
sidoText = code.cityCd.find((item) => item.val === objSearch?.city)?.text ?? '';
}
if (objSearch?.sgg.toString().length > 1) {
sggText = code.sggCd.find((item) => item.val === objSearch?.sgg)?.text ?? '';
} else {
sggText = code.sggCd.filter((item) => item.val.substring(0, 2) === objSearch?.city).map((item) => item.text);
}
if (sidoText === '전체') { sidoText = '' }
if (sidoText === '세종특별자치시') {
sidoText = '세종시';
sggText = sidoText;
}
const searchArr: string[] = [];
if (sidoText) searchArr.push(sidoText);
if (Array.isArray(sggText)) {
searchArr.push(...sggText);
} else if (sggText) {
searchArr.push(sggText);
}
drgtSearch(fromDate ?? "", toDate ?? "", searchArr)
}}
>
조회
</Button>
<Button
size={"sm"}
className={`${btnClass} green`}
onClick={excelClick}
>
다운로드
</Button>
<Button
size={"sm"}
className={btnClass}
onClick={onViewMapClick}
>
지도보기
</Button>
</div>
</SearchFormRight>
</SearchDiv>
</div>
</div>
<div className="grid grid-cols-6 gap-4 ">
<div className="col-span-6">
<ListDiv>
<ScrollArea className="h-[66vh]">
<UiTable
headName={undefined}
tableData={tableData || []}
headlist={drgtHeadListExport}
pageSize={14}
total={0}
cellClick={(index: number | undefined) => {
cellClick(index ?? -1);
}}
onPageChange={() => { }}
></UiTable>
</ScrollArea>
</ListDiv>
</div>
</div>
<UiModal
open={drgtModal.isOpen}
onOpenChange={() => {
setDrgtModal({ ...drgtModal, isOpen: !drgtModal.isOpen });
}}
bodyClass={"w-[50vw] max-w-none h-[80vh]"}
body={<DrgtDetailModal data={drgtModal.data as customDrgt[]} />}
/>
<Toaster position="top-center" />
</ContentsDiv>
</>
)
}