291 lines
14 KiB
TypeScript
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>
|
|
</>
|
|
)
|
|
} |