Merge branch 'iipbs/wr/dev' into iipbs/fo/dev

This commit is contained in:
2026-06-26 11:32:56 +09:00
132 changed files with 2880 additions and 1044 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ type IntroCardItem = {
const INTRO_CARDS: IntroCardItem[] = [
{
title: "물 재이용 법",
title: "물재이용법",
desc: "물의 재이용 촉진 및 지원에 관한 법률을 시행하고, 일부 법률은 개정되었습니다.",
image: card01,
href: "/intro#law-plan",
+8 -8
View File
@@ -83,14 +83,14 @@ const MOCK: Record<TabKey, CaseItem[]> = {
sewage: [
{
id: "sewage-1",
title: "구리시 하수 재이용",
title: "구리시 하수처리수 재이용",
desc: "고농도 미세먼지 발생 및 폭염의 급증에 따라 공공하수처리시설 발생 재이용수 일부를 도로자동청소시스템에 활용하여 미세먼지 저감 및 폭염 취약성 완화",
imageSrc: "/images/landing/business/sewage/guri_01.png",
href: "/example#example-sewage-guri",
},
{
id: "sewage-2",
title: "부천시 하수재이용",
title: "부천시 하수처리수 재이용",
desc: "굴포하수처리시설 하수처리수 재이용수 생산시설 설치 운영을 통해 여월천 등 부천 관내 하천의 건천화 방지, 하천 생태계 보존 및 주민들에게 친수 공간 제공",
imageSrc: "/images/landing/business/sewage/bucheon_01.png",
href: "/example#example-sewage-bucheon",
@@ -104,42 +104,42 @@ const MOCK: Record<TabKey, CaseItem[]> = {
},
{
id: "sewage-4",
title: "파주시 하수 재이용 시설",
title: "파주시 하수처리수 재이용",
desc: "운정 및 금촌하수처리시설의 하수처리수를 막공법으로 재처리하여 파주LCD산업단지 내 3개 업체에 공업용수를 공급(LG디스플레이, 희성전자, 엔비텍)",
imageSrc: "/images/landing/business/sewage/paju_01.png",
href: "/example#example-sewage-paju",
},
{
id: "sewage-5",
title: "포항시 하수 재이용 시설",
title: "포항시 하수처리수 재이용",
desc: "포항시 내 공단 개발 확대로 지속적이고 안정적인 공업용수 공급 추진(포스코, 동국산업 등), 포항하수처리장 하수처리수를 재처리하여 공업용수로 공급",
imageSrc: "/images/landing/business/sewage/pohang_01.png",
href: "/example#example-sewage-pohang",
},
{
id: "sewage-6",
title: "울산광역시 하수 재이용 시설",
title: "울산광역시 하수처리수 재이용",
desc: "18년 갈수기시 낙동강 수질 악화로 울산석유화학단지 용수 공급 부족을 해소하기 위해 미포산단 내 한화케미칼 등 8개사 공업용수 공급",
imageSrc: "/images/landing/business/sewage/ulsan_01.png",
href: "/example#example-sewage-ulsan",
},
{
id: "sewage-7",
title: "여수시 하수 재이용 시설",
title: "여수시 하수처리수 재이용",
desc: "수요자가 원하는 양질의 공업용수를 저렴하게 공급하여 한정된 수자원의 효율적 이용 및 지역적 물 부족 해소, 하수재이용을 통한 오염총량 저감 및 방류수역 수질개선을 위한 여수국가산단 내 공업용수 공급(GS칼텍스, YNCC 등)",
imageSrc: "/images/landing/business/sewage/yeosu_01.png",
href: "/example#example-sewage-yeosu",
},
{
id: "sewage-8",
title: "보령시 하수 재이용 시설",
title: "보령시 하수처리수 재이용",
desc: "한국중부발전(주)의 보령 및 신보령화력발전소에 10,000㎥/일의 탈황용수 공급을 위해 보령하수처리시설의 하수처리수 재이용 사업 추진, 하수처리수 재이용을 통한 수자원 절약 및 지역 물 부족 해소",
imageSrc: "/images/landing/business/sewage/boryeong_01.png",
href: "/example#example-sewage-boryeong",
},
{
id: "sewage-9",
title: "아산시 하수 재이용 시설",
title: "아산시 하수처리수 재이용",
desc: "신도시 개발에 따른 인구 급증으로 발생하는 하수를 재처리하여 탕정산업단지(삼성디스플레이)에 공업용수를 안정적으로 공급함으로써 지역기반 및 활성화를 도모",
imageSrc: "/images/landing/business/sewage/asan_01.png",
href: "/example#example-sewage-asan",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

After

Width:  |  Height:  |  Size: 60 KiB

@@ -237,7 +237,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
onSelectValue={(val) => setFlowPanel(val.toString())}
className="mx-3 w-[150px]"
label=""
selectClass="w-full p-1 border rounded bg-white"
selectClass="w-full rounded border border-input bg-form p-1"
/>
</div>
</TableCell>
@@ -251,7 +251,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
mode="single"
selected={startDate}
onSelect={(date) => handleStartDateSelect(date as Date)}
className="w-full p-1 border rounded bg-white"
className="w-full rounded border border-input bg-form p-1 text-foreground"
disabled={(date) => !isDateInRanges(date)}
defaultMonth={startDate}
/>
@@ -262,7 +262,7 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
mode="single"
selected={endDate}
onSelect={(date) => handleEndDateSelect(date as Date)}
className="w-full p-1 border rounded bg-white"
className="w-full rounded border border-input bg-form p-1 text-foreground"
disabled={(date) => !isDateInRanges(date)}
defaultMonth={endDate}
/>
@@ -275,4 +275,4 @@ export default function FacilityTermModalHeader<T extends { msrDt: string }>({
</div>
</ListDiv>
);
}
}
@@ -219,7 +219,7 @@ export default function FacilityTermModalHeaderMonth<T extends { msrDt: string }
return (
<ListDiv className="!h-[100px]">
<div className="card !m-[1.2rem] max-h-[40rem] overflow-auto !p-0r">
<div className="card !m-[1.2rem] max-h-[40rem] overflow-auto !p-0">
<Table>
<thead>
<TableRow>
@@ -237,7 +237,7 @@ export default function FacilityTermModalHeaderMonth<T extends { msrDt: string }
onSelectValue={(val) => setFlowPanel(val.toString())}
className="mx-3 w-[150px]"
label=""
selectClass="w-full p-1 border rounded bg-white"
selectClass="w-full rounded border border-input bg-form p-1"
/>
</div>
</TableCell>
@@ -251,7 +251,7 @@ export default function FacilityTermModalHeaderMonth<T extends { msrDt: string }
mode="single"
selected={startDate}
onSelect={(date) => handleStartDateSelect(date as Date)}
className="w-full p-1 border rounded bg-white"
className="w-full rounded border border-input bg-form p-1 text-foreground"
defaultMonth={startDate}
/>
</div>
@@ -261,7 +261,7 @@ export default function FacilityTermModalHeaderMonth<T extends { msrDt: string }
mode="single"
selected={endDate}
onSelect={(date) => handleEndDateSelect(date as Date)}
className="w-full p-1 border rounded bg-white"
className="w-full rounded border border-input bg-form p-1 text-foreground"
defaultMonth={endDate}
/>
</div>
@@ -273,4 +273,4 @@ export default function FacilityTermModalHeaderMonth<T extends { msrDt: string }
</div>
</ListDiv>
);
}
}
@@ -5,55 +5,55 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
return (
layoutNum === 'A' ? (
<>
<TableRow className="bg-gray-50">{upHeadList.map((head: TableUpperProps) =>
<TableRow className="bg-secondary">{upHeadList.map((head: TableUpperProps) =>
(head.id === 'trtFrfNm' ? <TableHead className="w-1/12" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.id === 'laeNm' ? <TableHead className="w-1/12" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.id == 'fctCpc' || head.id == 'planInputWaterQlty' || head.id == 'designInputWaterQlty' ? <TableHead rowSpan={2} className="w-40" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> :
head.id === 'trstOprEtpNm' ? <TableHead className="w-1/15" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.upName === 'upChangeRe' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={2}>{'행정구역'}</TableHead> :
!head.upName ? <TableHead rowSpan={2} className="w-1/20 bg-gray-20" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
head.upName === 'upChangeRe' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={2}>{'행정구역'}</TableHead> :
!head.upName ? <TableHead rowSpan={2} className="w-1/20 bg-accent text-accent-foreground" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if (head.upName === 'upChangeRe') {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-secondary">{head.title}</TableHead>;
}
})}
</TableRow>
</>
) : layoutNum === 'R' ? (
<>
<TableRow className="bg-gray-50">{upHeadList.map((head: TableUpperProps) =>
<TableRow className="bg-secondary">{upHeadList.map((head: TableUpperProps) =>
(head.id === 'trtFrfNm' ? <TableHead className="w-1/12" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.id === 'laeNm' ? <TableHead className="w-1/12" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.id == 'fctCpc' || head.id == 'planInputWaterQlty' || head.id == 'designInputWaterQlty' ? <TableHead rowSpan={2} className="w-40" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> :
head.id === 'trstOprEtpNm' ? <TableHead className="w-1/15" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.upName === 'upChangeRe' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={3}>{'유역'}</TableHead> :
!head.upName ? <TableHead rowSpan={2} className="w-1/20 bg-gray-20" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
head.upName === 'upChangeRe' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={3}>{'유역'}</TableHead> :
!head.upName ? <TableHead rowSpan={2} className="w-1/20 bg-accent text-accent-foreground" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if (head.upName === 'upChangeRe') {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-secondary">{head.title}</TableHead>;
}
})}
</TableRow>
</>
) : (
<>
<TableRow className="bg-gray-50">{upHeadList.map((head: TableUpperProps) =>
<TableRow className="bg-secondary">{upHeadList.map((head: TableUpperProps) =>
(head.id === 'trtFrfNm' ? <TableHead className="w-1/12" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.id === 'laeNm' ? <TableHead className="w-1/12" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.id == 'fctCpc' || head.id == 'planInputWaterQlty' || head.id == 'designInputWaterQlty' ? <TableHead rowSpan={2} className="w-40" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> :
head.id === 'trstOprEtpNm' ? <TableHead className="w-1/15" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.upName === 'upChangeRe1' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={3}>{'권역'}</TableHead> :
head.upName === 'upChangeRe2' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={2}>{'행정구역'}</TableHead> :
!head.upName ? <TableHead rowSpan={2} className="w-1/20 bg-gray-20" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
head.upName === 'upChangeRe1' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={3}>{'권역'}</TableHead> :
head.upName === 'upChangeRe2' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={2}>{'행정구역'}</TableHead> :
!head.upName ? <TableHead rowSpan={2} className="w-1/20 bg-accent text-accent-foreground" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if (head.upName === 'upChangeRe1' || head.upName === 'upChangeRe2') {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-secondary">{head.title}</TableHead>;
}
})}
</TableRow>
@@ -99,22 +99,22 @@ export default function SearchInputText({label=undefined, setValue=()=>{}, sidoS
return (
<div className={'relative'} ref={wrapperRef}>
{label && <Label className="w-20 text-xl text-gray-600 justify-self-center">{label}</Label>}
{label && <Label className="w-20 justify-self-center text-xl text-label">{label}</Label>}
<input
type="text"
value={textValue}
onChange={handleInputChange}
onFocus={onInputFocus}
className="w-[200px] ml-6 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
className="ml-6 w-[200px] rounded-md border border-input bg-form px-3 py-2 text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
placeholder={`${label}을(를) 입력하세요`}
/>
{isOpen && processFacilityList.length > 0 && (
<div className="absolute z-10 w-[300px] px-2 py-1 !mt-5 ml-20 bg-white border border-gray-300 rounded-md shadow-lg h-90 overflow-auto">
<div className="absolute z-10 ml-20 !mt-5 h-[90px] w-[300px] overflow-auto rounded-md border border-border bg-popover px-2 py-1 text-popover-foreground shadow-lg">
<div className="max-h-72">
{processFacilityList.map((item : facilityListProps, index : number) => (
<div
key={index}
className="w-full text-left pl-1 pr-10 py-2 hover:bg-gray-100 cursor-pointer overflow-auto"
className="w-full cursor-pointer overflow-auto py-2 pl-1 pr-10 text-left hover:bg-accent hover:text-accent-foreground"
onClick={() => handleSuggestionClick(item.bscFctCd, item.bscFctNm, Number(item.fctCpc), item.trtFrfNm, item.efflWqltStndrdNm)}
role="button"
tabIndex={0}
@@ -17,7 +17,7 @@ function UnderComment({commentStartPoint="☞", commentArray=[], divHeight="14"}
<div className={"mt-"+divHeight}>
{commentArray.map((item, index) => (
<React.Fragment key={"comment" + index}>
<span className="text-2xl font-bold text-gray-500">
<span className="text-2xl font-bold text-muted-foreground">
{commentStartPoint} {item}
</span>
<br/>
@@ -28,4 +28,4 @@ function UnderComment({commentStartPoint="☞", commentArray=[], divHeight="14"}
}
}
export default UnderComment;
export default UnderComment;
+7 -4
View File
@@ -127,15 +127,18 @@ const Map = () => {
}
const el = overlayContainerRef.current;
el.className =
"ol-custom-overlay shadow-xl rounded-2xl bg-white/95 backdrop-blur p-3 border border-gray-200 min-w-[220px] max-w-[350px] ";
"ol-custom-overlay shadow-xl rounded-2xl backdrop-blur p-3 min-w-[220px] max-w-[350px]";
el.style.backgroundColor = "color-mix(in srgb, var(--popover) 95%, transparent)";
el.style.color = "var(--popover-foreground)";
el.style.border = "1px solid var(--border)";
el.innerHTML = `
<div class="font-semibold text-lg text-gray-800 mb-2 text-center bg-green-400">${title}</div>
<table class="w-full text-base text-gray-800">
<div class="mb-2 rounded-md px-2 py-1 text-center text-lg font-semibold" style="background-color: var(--secondary); color: var(--secondary-foreground);">${title}</div>
<table class="w-full text-base" style="color: var(--foreground);">
${Object.entries(props)
.map(
([k, v]) => `
<tr>
<td class="py-1 pr-2 text-gray-500 whitespace-nowrap">${k}</td>
<td class="whitespace-nowrap py-1 pr-2" style="color: var(--muted-foreground);">${k}</td>
<td class="py-1 font-medium">${safe(v)}</td>
</tr>`
)
@@ -54,23 +54,23 @@ export default function DrainageEquipment({searchYear = '', fcltyList = []}: Dra
const HeadMakeColSpan = ({ upHeadList }: { upHeadList: TableUpperProps[] }) => {
return (
<>
<TableRow className="bg-gray-50">{upHeadList.map((head: TableUpperProps) =>
<TableRow className="bg-secondary">{upHeadList.map((head: TableUpperProps) =>
(head.id === 'part1' ? <TableHead rowSpan={3} className='w-60' key={head.id}>구분</TableHead> :
head.id === 'part2' ? <TableHead rowSpan={3} className='w-60' key={head.id}>구분</TableHead> :
head.id == 'nowSum' ? <TableHead rowSpan={2} colSpan={3} key={head.id} style={{ whiteSpace: 'pre-line' }}>{'현재\n(기준년도)'}</TableHead> :
head.id == 'stepOneSum' ? <TableHead rowSpan={1} colSpan={12} key={head.id} style={{ whiteSpace: 'pre-line' }}>{'변경(금회계획)'}</TableHead> :
head.id == 'etc' ? <TableHead rowSpan={3} key={head.id}>비고</TableHead> : null))}
</TableRow>
<TableRow className="bg-gray-50">{upHeadList.map((head: TableUpperProps) =>
<TableRow className="bg-secondary">{upHeadList.map((head: TableUpperProps) =>
(head.id === 'stepOneSum' ? <TableHead rowSpan={1} colSpan={3} key={head.id}>1단계</TableHead> :
head.id === 'stepTwoSum' ? <TableHead rowSpan={1} colSpan={3} key={head.id}>2단계</TableHead> :
head.id === 'stepThreeSum' ? <TableHead rowSpan={1} colSpan={3} key={head.id}>3단계</TableHead> :
head.id === 'stepFourSum' ? <TableHead rowSpan={1} colSpan={3} key={head.id}>4단계</TableHead> : null))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if (head.upName === 'upChangeRe2' || head.upName === 'upChangeRe3' || head.upName === 'upChangeRe4' || head.upName === 'upChangeRe5' || head.upName === 'upChangeRe6') {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-secondary">{head.title}</TableHead>;
}
})}
</TableRow>
@@ -147,7 +147,7 @@ export default function DashBoardChartModal({item='', period='', title='',modalD
if (label) {
config[label] = {
label: label,
color : "hsl(var(--chart-1))"
color : "var(--chart-1)"
};
}
return config;
@@ -32,12 +32,12 @@ const headMakeColSpanPlanFclty = (upHeadList: TableUpperProps[], planYearList: s
return ( <>
<TableRow>{
upHeadList.map((head: TableUpperProps) =>
(!head.upSequnce?<TableHead rowSpan={2}key={head.id}>{head.title}</TableHead>:
head.upName === 'upChangeRe'&& head.upSequnce=== 1?<TableHead key={head.id} rowSpan={1} colSpan={7} style={{ whiteSpace: 'pre-line' }}>{'시설계획\n(금회)'}</TableHead>:null))}
(!head.upSequnce?<TableHead className="fo-facility-info-header-surface" rowSpan={2}key={head.id}>{head.title}</TableHead>:
head.upName === 'upChangeRe'&& head.upSequnce=== 1?<TableHead className="fo-facility-info-header-surface" key={head.id} rowSpan={1} colSpan={7} style={{ whiteSpace: 'pre-line' }}>{'시설계획\n(금회)'}</TableHead>:null))}
</TableRow>
<TableRow>
{upHeadList.map((head: TableUpperProps, index: number) =>
(head.upName === 'upChangeRe'?<TableHead key={head.id} style={{ whiteSpace: 'pre-line' }}>{index===0?head.title:head.title+'\n('+planYearList[index-1]+')'}</TableHead>:null))}
(head.upName === 'upChangeRe'?<TableHead className="fo-facility-info-header-surface" key={head.id} style={{ whiteSpace: 'pre-line' }}>{index===0?head.title:head.title+'\n('+planYearList[index-1]+')'}</TableHead>:null))}
</TableRow>
</> )
}
@@ -52,20 +52,20 @@ const headMakeColSpanPlanFclty = (upHeadList: TableUpperProps[], planYearList: s
const headMakeColSpanOperationStatus = (upHeadList: TableUpperProps[], searchYear: string) => {
return ( <>
<TableRow>
<TableHead rowSpan={1} colSpan={17} style={{ whiteSpace: 'pre-line' }}>{searchYear+'년도 운영실태'}</TableHead>
<TableHead className="fo-facility-info-header-surface" rowSpan={1} colSpan={17} style={{ whiteSpace: 'pre-line' }}>{searchYear+'년도 운영실태'}</TableHead>
</TableRow>
<TableRow>{
upHeadList.map((head: TableUpperProps) =>
(head.upName === 'upChangeRe1'&&head.upSequnce===1?<TableHead key={head.id} rowSpan={2}colSpan={2} style={{ whiteSpace: 'pre-line' }}>{head.title}</TableHead>:
!head.upSequnce?<TableHead style={{ whiteSpace: 'pre-line' }} rowSpan={2}key={head.id}>{head.title}</TableHead>:
head.upName === 'upChangeRe2'&&head.upSequnce===1?<TableHead key={head.id} colSpan={3} style={{ whiteSpace: 'pre-line' }}>{'연간 운영실태'}</TableHead>:
head.upName === 'upChangeRe3'&&head.upSequnce===1?<TableHead key={head.id} colSpan={3} style={{ whiteSpace: 'pre-line' }}>{'하절기 운영실태\n(6~8월)'}</TableHead>:
head.upName === 'upChangeRe4'&&head.upSequnce===1?<TableHead key={head.id} colSpan={4} style={{ whiteSpace: 'pre-line' }}>{'동절기 운영실태\n(1~2월)'}</TableHead>:
head.upName === 'upChangeRe5'&&head.upSequnce===1?<TableHead key={head.id} colSpan={3} style={{ whiteSpace: 'pre-line' }}>{'지하수 유입량 추정'}</TableHead>:null))}
(head.upName === 'upChangeRe1'&&head.upSequnce===1?<TableHead className="fo-facility-info-header-surface" key={head.id} rowSpan={2}colSpan={2} style={{ whiteSpace: 'pre-line' }}>{head.title}</TableHead>:
!head.upSequnce?<TableHead className="fo-facility-info-header-surface" style={{ whiteSpace: 'pre-line' }} rowSpan={2}key={head.id}>{head.title}</TableHead>:
head.upName === 'upChangeRe2'&&head.upSequnce===1?<TableHead className="fo-facility-info-header-surface" key={head.id} colSpan={3} style={{ whiteSpace: 'pre-line' }}>{'연간 운영실태'}</TableHead>:
head.upName === 'upChangeRe3'&&head.upSequnce===1?<TableHead className="fo-facility-info-header-surface" key={head.id} colSpan={3} style={{ whiteSpace: 'pre-line' }}>{'하절기 운영실태\n(6~8월)'}</TableHead>:
head.upName === 'upChangeRe4'&&head.upSequnce===1?<TableHead className="fo-facility-info-header-surface" key={head.id} colSpan={4} style={{ whiteSpace: 'pre-line' }}>{'동절기 운영실태\n(1~2월)'}</TableHead>:
head.upName === 'upChangeRe5'&&head.upSequnce===1?<TableHead className="fo-facility-info-header-surface" key={head.id} colSpan={3} style={{ whiteSpace: 'pre-line' }}>{'지하수 유입량 추정'}</TableHead>:null))}
</TableRow>
<TableRow>
{upHeadList.map((head: TableUpperProps) =>
(head.upName === 'upChangeRe2'||head.upName === 'upChangeRe3'||head.upName === 'upChangeRe4'||head.upName === 'upChangeRe5'?<TableHead style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>:null))}
(head.upName === 'upChangeRe2'||head.upName === 'upChangeRe3'||head.upName === 'upChangeRe4'||head.upName === 'upChangeRe5'?<TableHead className="fo-facility-info-header-surface" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>:null))}
</TableRow>
</> )
}
@@ -239,18 +239,18 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
:((index === 6 || index === 7 || index === 8) && (head.id === 'now' || head.id === 'stepOne' || head.id === 'stepThree' || head.id === 'stepFour'))?
null
:((index === 5) && (head.id === 'provisionalApproval' || head.id === 'stepTwo'))?
<TableCell colSpan={3} className="text-center border border-[var(--border)] bg-[rgb(234,243,251)] text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
<TableCell colSpan={3} className="fo-facility-info-header-surface text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
:((index === 5) && (head.id === 'now' || head.id === 'stepOne' || head.id === 'stepThree'|| head.id === 'stepFour'))?
null
:(index < 5 || index > 5)&& (index!= 4) && (head.id ==='provisionalApproval'||head.id ==='now'||head.id ==='stepOne'||head.id ==='stepTwo'||head.id ==='stepThree'||head.id ==='stepFour')
?<TableCell className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
:(head.id === "provisionalApproval" && index === 4)
?<TableCell colSpan={6} className="text-right border border-[var(--border)] text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{roundNumber(String((Number(waterUsage1)+Number(waterUsage2)+Number(waterUsage3))/3), 0)}</TableCell>
?<TableCell colSpan={6} className="text-right border border-border text-label" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{roundNumber(String((Number(waterUsage1)+Number(waterUsage2)+Number(waterUsage3))/3), 0)}</TableCell>
:((head.id ==='now'||head.id ==='stepOne'||head.id ==='stepTwo'||head.id ==='stepThree'||head.id ==='stepFour') )
?null
:(head.id === 'item' && index != 5)?
<TableCell className="text-center text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
:<TableCell className="text-center border border-[var(--border)] bg-[rgb(234,243,251)] text-[rgb(100,119,132)]" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
<TableCell className="text-center text-label" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
:<TableCell className="fo-facility-info-header-surface text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>
))}
</TableRow>
))}
@@ -278,15 +278,15 @@ export default function ProcessFacilitySearch({searchYear = '', fcltyList = []}:
(head.id === 'rdiRain'&&index === 0)?<TableCell rowSpan={7} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el['rdiRain']}</TableCell>:
(head.id === 'rdiRain'&&index === 7)?<TableCell rowSpan={6} className="text-right" style={{ whiteSpace: 'pre-line' }} key={head.id+index}></TableCell>:
(head.id === 'waterQlty')?<TableCell className="text-center" style={{ whiteSpace: 'pre-line' }} key={head.id+index}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=0 && index<=4))?<TableCell className="bg-yellow-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=5 && index<=10))?<TableCell className="bg-green-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=11 && index<=12))?<TableCell className="bg-blue-50 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=0 && index<=4))?<TableCell className="bg-yellow-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=5 && index<=10))?<TableCell className="bg-green-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=11 && index<=12))?<TableCell className="bg-blue-100 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=0 && index<=4))?<TableCell className="bg-yellow-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=5 && index<=10))?<TableCell className="bg-green-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=11 && index<=12))?<TableCell className="bg-blue-200 text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=0 && index<=4))?<TableCell className="fo-facility-info-flow-year text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=5 && index<=10))?<TableCell className="fo-facility-info-water-year text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'yearAvg' || head.id === 'yearMax' || head.id === 'yearMin') && (index>=11 && index<=12))?<TableCell className="fo-facility-info-phosphorus-year text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'year', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=0 && index<=4))?<TableCell className="fo-facility-info-flow-summer text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=5 && index<=10))?<TableCell className="fo-facility-info-water-summer text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'summerAll' || head.id === 'summerThree' || head.id === 'summerRain') && (index>=11 && index<=12))?<TableCell className="fo-facility-info-phosphorus-summer text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'summer', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=0 && index<=4))?<TableCell className="fo-facility-info-flow-winter text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('flowRate', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=5 && index<=10))?<TableCell className="fo-facility-info-water-winter text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('waterQlty', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
((head.id === 'winterAll' || head.id === 'winterSunnyAvg' || head.id === 'winterSunnyMax' || head.id === 'winterSunnyMin') && (index>=11 && index<=12))?<TableCell className="fo-facility-info-phosphorus-winter text-right cursor-pointer" style={{ whiteSpace: 'pre-line' }} key={head.id+index} onClick={()=>{fncLoadModal('chongin', 'winter', el['waterQlty'] as string);}}>{el[head.id]}</TableCell>:
null
))}
</TableRow>
@@ -60,7 +60,14 @@ export default function DashBoardChart({searchYear = '', fcltyList = []}: facili
/**
* 차트 Config
*/
const colors = ["#FF6B6B", "#4ECDC4", "#45B7D1", "#96CEB4", "#00b50c", "#D4A5A5"];
const colors = [
"var(--chart-5)",
"var(--chart-2)",
"var(--chart-1)",
"var(--chart-3)",
"var(--primary)",
"var(--chart-6)",
];
//유입하수량-강수량
const chartConfig_inflowRain = {
@@ -50,7 +50,7 @@ export default function RainManageTab({ searchYear = '', fcltyList = [] }: facil
widthFixed={true}
>
</UiTable>
<span className="text-2xl font-bold text-gray-500">☞ 일수에 강우영향일 포함됨</span>
<span className="text-2xl font-bold text-muted-foreground">☞ 일수에 강우영향일 포함됨</span>
</div>
)
}
@@ -1,5 +1,5 @@
/**
* 대시보드 - 표로보기 상단구역 페에지
* 대시보드 - 표로보기 상단구역 페이지
*
* - 대시보드 - 표로보기의 3개의 탭 상단에 조회년도, 행정정보, 시설명의 구역을 컴포넌트
*/
@@ -198,7 +198,7 @@ export default function PrecipitationModal(props: PrecipitationModalProps) {
mode="single"
selected={startDate}
onSelect={(date) => handleStartDateSelect(date as Date)}
className="w-full p-1 border rounded bg-white"
className="w-full rounded border border-input bg-form p-1 text-foreground"
disabled={(date) => !isDateInRanges(date)}
defaultMonth={startDate}
/>
@@ -209,7 +209,7 @@ export default function PrecipitationModal(props: PrecipitationModalProps) {
mode="single"
selected={endDate}
onSelect={(date) => handleEndDateSelect(date as Date)}
className="w-full p-1 border rounded bg-white"
className="w-full rounded border border-input bg-form p-1 text-foreground"
disabled={(date) => !isDateInRanges(date)}
defaultMonth={endDate}
/>
@@ -239,4 +239,4 @@ export default function PrecipitationModal(props: PrecipitationModalProps) {
</ListDiv>
</>
);
}
}
@@ -17,27 +17,27 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
return (
layoutNum === 0 ? (
<>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if(!head.upName) {
return <TableHead className="bg-gray-50" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
return <TableHead className="bg-secondary" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
}else if(head.upName==="upChangeRe1"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>행정구역</TableHead>
return <TableHead className="bg-secondary" colSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>행정구역</TableHead>
}else if(head.upName==="upChangeRe3"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
return <TableHead className="bg-secondary" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
}else if(head.upName==="upChangeRe4"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유출</TableHead>
return <TableHead className="bg-secondary" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유출</TableHead>
}
})}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps, idx: number) => {
if (head.upName === 'upChangeRe1' || head.upName === 'upChangeRe3' || head.upName === 'upChangeRe4') {
if (idx == 1 || idx == 2 || idx == 3) {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
else {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
}
})}
@@ -45,27 +45,27 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
</>
) : layoutNum === 1 ? (
<>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if(!head.upName) {
return <TableHead className="bg-gray-50" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
return <TableHead className="bg-secondary" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
}else if(head.upName==="upChangeRe1"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={3} style={{ whiteSpace: 'pre-line' }} key={head.id}>권역</TableHead>
return <TableHead className="bg-secondary" colSpan={3} style={{ whiteSpace: 'pre-line' }} key={head.id}>권역</TableHead>
}else if(head.upName==="upChangeRe3"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
return <TableHead className="bg-secondary" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
}else if(head.upName==="upChangeRe4"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유출</TableHead>
return <TableHead className="bg-secondary" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유출</TableHead>
}
})}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps, idx: number) => {
if (head.upName === 'upChangeRe1' || head.upName === 'upChangeRe3' || head.upName === 'upChangeRe4') {
if (idx == 1 || idx == 2 || idx == 3) {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
else {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
}
})}
@@ -73,29 +73,29 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
</>
) : layoutNum === 2 ? (
<>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if(!head.upName) {
return <TableHead className="bg-gray-50" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
return <TableHead className="bg-secondary" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
}else if(head.upName==="upChangeRe1"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={3} style={{ whiteSpace: 'pre-line' }} key={head.id}>권역</TableHead>
return <TableHead className="bg-secondary" colSpan={3} style={{ whiteSpace: 'pre-line' }} key={head.id}>권역</TableHead>
}else if(head.upName==="upChangeRe2"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>행정구역</TableHead>
return <TableHead className="bg-secondary" colSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>행정구역</TableHead>
}else if(head.upName==="upChangeRe3"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
return <TableHead className="bg-secondary" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
}else if(head.upName==="upChangeRe4"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유출</TableHead>
return <TableHead className="bg-secondary" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유출</TableHead>
}
})}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps, idx: number) => {
if (head.upName === 'upChangeRe1' || head.upName === 'upChangeRe2' || head.upName === 'upChangeRe3' || head.upName === 'upChangeRe4') {
if (idx == 1 || idx == 2 || idx == 3) {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
else {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
}
})}
@@ -103,25 +103,25 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
</>
) : layoutNum === 3 ? (
<>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if(!head.upName) {
return <TableHead className="bg-gray-50" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
return <TableHead className="bg-secondary" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
}else if(head.upName==="upChangeRe1"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
return <TableHead className="bg-secondary" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
}else if(head.upName==="upChangeRe2"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>방류</TableHead>
return <TableHead className="bg-secondary" colSpan={5} style={{ whiteSpace: 'pre-line' }} key={head.id}>방류</TableHead>
}
})}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps, idx: number) => {
if (head.upName === 'upChangeRe1' || head.upName === 'upChangeRe2') {
if (idx == 1 || idx == 2 || idx == 3) {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
else {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
}
})}
@@ -129,23 +129,23 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
</>
) : layoutNum === 4 ? (
<>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if(!head.upName) {
return <TableHead className="bg-gray-50" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
return <TableHead className="bg-secondary" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
}else if(head.upName==="upChangeRe"&&head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={4} style={{ whiteSpace: 'pre-line' }} key={head.id}>방류</TableHead>
return <TableHead className="bg-secondary" colSpan={4} style={{ whiteSpace: 'pre-line' }} key={head.id}>방류</TableHead>
}
})}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps, idx: number) => {
if (head.upName === 'upChangeRe') {
if (idx == 1 || idx == 2 || idx == 3) {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
else {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
}
})}
@@ -153,21 +153,21 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
</>
) : layoutNum === 5 ? ( // 총인설비 수질현황 헤더
<>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if(!head.upName) {
return <TableHead className="w-[180px] bg-gray-50" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
return <TableHead className="w-[180px] bg-secondary" rowSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead>
}else if(head.upName==="upChangeRe1" && head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
return <TableHead className="bg-secondary" colSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>유입</TableHead>
}else if(head.upName==="upChangeRe2" && head.upSequnce===1) {
return <TableHead className="bg-gray-50" colSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>방류</TableHead>
return <TableHead className="bg-secondary" colSpan={2} style={{ whiteSpace: 'pre-line' }} key={head.id}>방류</TableHead>
}
})}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if (head.upName === 'upChangeRe1' || head.upName === 'upChangeRe2') {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-1/8 bg-secondary">{head.title}</TableHead>;
}
})}
</TableRow>
@@ -237,7 +237,7 @@ export default function FlowRateModal(props: { fcltyName: string; facilityCd: st
const raw = row.infoRnDay;
const value = typeof raw === "string" ? Number(raw.replace(/,/g, "").trim()) : Number(raw);
if (!Number.isFinite(value)) return "";
return value > 3 ? "bg-slate-50" : "";
return value > 3 ? "fo-rain-impact-row" : "";
},
[activeTab],
);
@@ -5,77 +5,77 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
return (
layoutNum === 0 ? (
<>
<TableRow className="bg-gray-50">{upHeadList.map((head: TableUpperProps) =>
<TableRow className="bg-secondary">{upHeadList.map((head: TableUpperProps) =>
(head.id === 'trtFrfNm' ? <TableHead className="w-1/12" rowSpan={3} key={head.id}>{head.title}</TableHead> :
head.id === 'laeNm' ? <TableHead className="w-1/12" rowSpan={3} key={head.id}>{head.title}</TableHead> :
head.id == 'fctCpc' || head.id == 'planInputWaterQlty' || head.id == 'designInputWaterQlty' ? <TableHead rowSpan={3} className="w-40" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> :
head.id === 'trstOprEtpNm' ? <TableHead className="w-1/15" rowSpan={3} key={head.id}>{head.title}</TableHead> :
head.upName === 'upChangeRe' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={2} colSpan={2}>{'행정구역'}</TableHead> :
head.upName === 'upChangeRe3' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={2} colSpan={6}>{'증설계획'}</TableHead> :
head.upName === 'upChangeRe4' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={19}>{'시설계획'}</TableHead> :
!head.upName ? <TableHead rowSpan={3} className="w-1/20 bg-gray-20" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
head.upName === 'upChangeRe' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={2} colSpan={2}>{'행정구역'}</TableHead> :
head.upName === 'upChangeRe3' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={2} colSpan={6}>{'증설계획'}</TableHead> :
head.upName === 'upChangeRe4' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={19}>{'시설계획'}</TableHead> :
!head.upName ? <TableHead rowSpan={3} className="w-1/20 bg-accent text-accent-foreground" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => (
head.upName === 'upChangeRe4' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'증설계획(m³/일)'}</TableHead> :
head.upName === 'upChangeRe5' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'처리인구(인)'}</TableHead> :
head.upName === 'upChangeRe6' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={7}>{'처리구역(k㎡)'}</TableHead> :
head.upName === 'upChangeRe4' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'증설계획(m³/일)'}</TableHead> :
head.upName === 'upChangeRe5' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'처리인구(인)'}</TableHead> :
head.upName === 'upChangeRe6' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={7}>{'처리구역(k㎡)'}</TableHead> :
null
))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if (head.upName === 'upChangeRe' || head.upName === 'upChangeRe1' || head.upName === 'upChangeRe2' || head.upName === 'upChangeRe3' || head.upName === 'upChangeRe4' || head.upName === 'upChangeRe5' || head.upName === 'upChangeRe6') {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-secondary">{head.title}</TableHead>;
}
})}
</TableRow>
</>
) : layoutNum === 1 ? (
<>
<TableRow className="bg-gray-50">{upHeadList.map((head: TableUpperProps) =>
<TableRow className="bg-secondary">{upHeadList.map((head: TableUpperProps) =>
(head.id === 'trtFrfNm' ? <TableHead className="w-1/12" rowSpan={3} key={head.id}>{head.title}</TableHead> :
head.id === 'laeNm' ? <TableHead className="w-1/12" rowSpan={3} key={head.id}>{head.title}</TableHead> :
head.id == 'fctCpc' || head.id == 'planInputWaterQlty' || head.id == 'designInputWaterQlty' ? <TableHead rowSpan={3} className="w-40" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> :
head.id === 'trstOprEtpNm' ? <TableHead className="w-1/15" rowSpan={3} key={head.id}>{head.title}</TableHead> :
head.upName === 'upChangeRe' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={2} colSpan={3}>{'유역'}</TableHead> :
head.upName === 'upChangeRe3' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={2} colSpan={6}>{'증설계획'}</TableHead> :
!head.upName ? <TableHead rowSpan={3} className="w-1/20 bg-gray-20" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
head.upName === 'upChangeRe' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={2} colSpan={3}>{'유역'}</TableHead> :
head.upName === 'upChangeRe3' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={2} colSpan={6}>{'증설계획'}</TableHead> :
!head.upName ? <TableHead rowSpan={3} className="w-1/20 bg-accent text-accent-foreground" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => (
head.upName === 'upChangeRe4' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'증설계획(m³/일)'}</TableHead> :
head.upName === 'upChangeRe5' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'처리인구(인)'}</TableHead> :
head.upName === 'upChangeRe6' && head.upSequnce === 1 ? <TableHead className="bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={7}>{'처리구역(k㎡)'}</TableHead> :
head.upName === 'upChangeRe4' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'증설계획(m³/일)'}</TableHead> :
head.upName === 'upChangeRe5' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'처리인구(인)'}</TableHead> :
head.upName === 'upChangeRe6' && head.upSequnce === 1 ? <TableHead className="bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={7}>{'처리구역(k㎡)'}</TableHead> :
null
))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if (head.upName === 'upChangeRe' || head.upName === 'upChangeRe1' || head.upName === 'upChangeRe2' || head.upName === 'upChangeRe3' || head.upName === 'upChangeRe4' || head.upName === 'upChangeRe5' || head.upName === 'upChangeRe6') {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-secondary">{head.title}</TableHead>;
}
})}
</TableRow>
</>
) : (
<>
<TableRow className="bg-gray-50">{upHeadList.map((head: TableUpperProps) =>
<TableRow className="bg-secondary">{upHeadList.map((head: TableUpperProps) =>
(head.id === 'trtFrfNm' ? <TableHead className="w-1/12" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.id === 'laeNm' ? <TableHead className="w-1/12" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.id == 'fctCpc' || head.id == 'planInputWaterQlty' || head.id == 'designInputWaterQlty' ? <TableHead rowSpan={2} className="w-40" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> :
head.id === 'trstOprEtpNm' ? <TableHead className="w-1/15" rowSpan={2} key={head.id}>{head.title}</TableHead> :
head.upName === 'upChangeRe1' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={3}>{'권역'}</TableHead> :
head.upName === 'upChangeRe2' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={2}>{'환경청'}</TableHead> :
head.upName === 'upChangeRe3' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'증설계획(m³/일)'}</TableHead> :
head.upName === 'upChangeRe5' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'처리인구(인)'}</TableHead> :
head.upName === 'upChangeRe6' && head.upSequnce === 1 ? <TableHead className="w-75 bg-gray-50" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={7}>{'처리구역(k㎡)'}</TableHead> :
!head.upName ? <TableHead rowSpan={2} className="w-1/20 bg-gray-20" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
head.upName === 'upChangeRe1' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={3}>{'권역'}</TableHead> :
head.upName === 'upChangeRe2' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={2}>{'환경청'}</TableHead> :
head.upName === 'upChangeRe3' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'증설계획(m³/일)'}</TableHead> :
head.upName === 'upChangeRe5' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={6}>{'처리인구(인)'}</TableHead> :
head.upName === 'upChangeRe6' && head.upSequnce === 1 ? <TableHead className="w-75 bg-secondary" style={{ whiteSpace: 'pre-line' }} key={head.id} rowSpan={1} colSpan={7}>{'처리구역(k㎡)'}</TableHead> :
!head.upName ? <TableHead rowSpan={2} className="w-1/20 bg-accent text-accent-foreground" style={{ whiteSpace: 'pre-line' }} key={head.id}>{head.title}</TableHead> : null))}
</TableRow>
<TableRow className="bg-gray-50">
<TableRow className="bg-secondary">
{upHeadList.map((head: TableUpperProps) => {
if (head.upName === 'upChangeRe1' || head.upName === 'upChangeRe2' ||head.upName === 'upChangeRe3' || head.upName === 'upChangeRe4' || head.upName === 'upChangeRe5' || head.upName === 'upChangeRe6') {
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-gray-50">{head.title}</TableHead>;
return <TableHead key={head.id} style={{ whiteSpace: 'pre-line' }} className="w-40 bg-secondary">{head.title}</TableHead>;
}
})}
</TableRow>
@@ -84,4 +84,4 @@ const HeadMakeColSpan = ({ upHeadList, layoutNum }: { upHeadList: TableUpperProp
);
}
export { HeadMakeColSpan };
export { HeadMakeColSpan };
@@ -116,7 +116,7 @@ export function SearchBar({ onFeatureSelect, gisMaps }: SearchBarProps) {
<SelectBox
labelClass="w-[40px]"
className="mr-10 w-[200px]"
selectClass="rounded-lg bg-white"
selectClass="rounded-lg"
label="시도"
selectArray={sidoData}
onSelectValue={(val) => onSelectValue(val.toString(), "ctpvCd")}
@@ -125,7 +125,7 @@ export function SearchBar({ onFeatureSelect, gisMaps }: SearchBarProps) {
<SelectBox
labelClass="w-[65px]"
className="mr-10 w-[200px]"
selectClass="rounded-lg bg-white"
selectClass="rounded-lg"
label="시군구"
selectArray={filteredSigunData}
onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")}
@@ -134,7 +134,7 @@ export function SearchBar({ onFeatureSelect, gisMaps }: SearchBarProps) {
<SelectBox
labelClass="w-[140px]"
className="mr-3 w-[250px]"
selectClass="rounded-lg bg-white"
selectClass="rounded-lg"
label="하수처리시설"
selectArray={facilityData}
onSelectValue={(val) => onSelectValue(val.toString(), "fcltCd")}
@@ -0,0 +1,164 @@
# apps/fo 테마 적용 작업계획
작성일: 2026-06-25
대상 앱: `D:\iipbs\frontend\apps\fo`
## 1. 목적
- `apps/fo` 프로그램 페이지 내부에 직접 박혀 있는 색상 하드코딩을 식별한다.
- 가능한 범위는 `packages/common/assets/src/styles/base.css`의 CSS 변수 영향권으로 옮긴다.
- 즉 `bg-white`, `text-gray-*`, `border-gray-*`, `bg-blue-*`, `bg-green-*`, `bg-red-*` 같은 직접 색상 표현을 `background`, `foreground`, `label`, `border`, `secondary`, `accent`, `primary`, `destructive` 계열 토큰으로 치환한다.
## 2. 전제
- `apps/fo`는 [tailwind.config.ts](D:/iipbs/frontend/apps/fo/tailwind.config.ts:1)에서 공통 preset을 사용한다.
- 공통 토큰은 [packages/common/assets/src/styles/base.css](D:/iipbs/frontend/packages/common/assets/src/styles/base.css:1)에 정의되어 있다.
- `packages/common/components`, `packages/common/assets`는 기준 레이어이며, 앱 작업은 이 기준을 따르는 방향으로 진행한다.
- 단, 이번 요청의 1차 목표는 `apps/fo` 내부 코드에 박혀 있는 색상을 줄이는 것이다.
## 3. 확인된 하드코딩 유형
현재 `apps/fo`에서 확인된 대표 패턴은 아래와 같다.
- 검색 입력/선택 UI
- `apps/fo/app/components/common/SearchInput.tsx`
- `apps/fo/app/pages/map/searchBar/searchBar.tsx`
- `apps/fo/app/components/common/FacilityTermModalHeader.tsx`
- `apps/fo/app/components/common/FacilityTermModalHeaderMonth.tsx`
- 대시보드/안내문구
- `apps/fo/app/components/common/UnderComment.tsx`
- `apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx`
- 대시보드 표 셀 상태색
- `apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/page.tsx`
이 페이지는 특별한 페이지로, 연간, 하절기, 동절기 색을 구분하여 보여주어야 한다. 따라서 text-foreground 가 보이도록 하되 연간, 하절기, 동절기 색을 apps\fo\src\app\styles 아래 테마별 css에 정의해서 보여주어야 한다.
- 지도 오버레이/팝업
- `apps/fo/app/pages/(map-layout)/map/page.tsx`
- 테스트/샘플성 버튼
- `apps/fo/app/pages/(with-layout)/test/page.tsx`
- 모달 입력창
- `apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx`
## 4. 기본 원칙
### 4.1 바로 토큰 치환 가능한 경우
아래는 우선 토큰으로 바로 바꾼다.
- `bg-white` -> `bg-background` 또는 `bg-card` 또는 `bg-popover`
- `text-gray-900`, `text-gray-800` -> `text-foreground`
- `text-gray-700`, `text-gray-600` -> `text-label` 또는 `text-foreground`
- `text-gray-500` -> `text-muted-foreground` 또는 `text-placeholder`
- `border-gray-200`, `border-gray-300` -> `border-border`
- `focus:ring-blue-500` -> `focus:ring-ring`
- `text-blue-500`, `text-blue-600` -> `text-primary`
- `bg-blue-500`, `bg-blue-600` -> `bg-primary`
- `text-red-500`, `text-red-600` -> `text-destructive`
- `bg-red-50` 등 경고 계열 -> `bg-accent` 또는 별도 위험 상태 규칙 검토
### 4.2 바로 토큰 치환하면 안 되는 경우
아래는 의미색일 가능성이 높아 바로 토큰화하지 않는다.
- 범례 색상
- 데이터 구분용 heatmap/구간 색상
- 수질/계절/유형별 비교 색상
- 지도 오버레이에서 정보 카테고리 의미를 나타내는 색
이 경우는 다음 중 하나로 처리한다.
- 유지
- 별도 의미 클래스 부여
- 앱 전용 CSS로 상태 클래스를 만든 뒤 theme-safe surface만 토큰화
## 5. 우선순위
### 5.1 1순위: 일반 UI surface
가장 먼저 처리한다.
- 검색 입력창 배경/보더/텍스트
- 검색 결과 dropdown 배경/hover
- 팝업/모달 wrapper 배경/보더
- 제목/라벨/안내문구 색
- 버튼의 직접 blue/red/white 색상
이 영역은 theme 적용 체감이 가장 크고, 토큰 치환도 안전하다.
### 5.2 2순위: 테이블/리스트
- `selectedFcltList`
- `facilityInfo`
- modal 내부 표
- overlay 내 표 구조
이 영역은 `bg-secondary`, `bg-accent`, `text-secondary-foreground`, `border-border` 계열로 정리한다.
### 5.3 3순위: 의미색 데이터 표현
- `facilityInfo`의 계절/항목별 `bg-green-*`, `bg-blue-*`
- 지도 범례 색상
- 지도 feature overlay 강조색
- 대시보드 표 셀 상태색
- `apps/fo/app/pages/(with-layout)/dashboard/facilityInfo/page.tsx`
이 페이지는 특별한 페이지로, 연간, 하절기, 동절기 색을 구분하여 보여주어야 한다. 따라서 text-foreground 가 보이도록 하되 연간, 하절기, 동절기 색을 apps\fo\src\app\styles 아래 테마별 css에 정의해서 보여주어야 한다.
이 영역은 “없애는 것”보다 “역할을 분리하는 것”이 중요하다.
## 6. 실제 작업 순서
1. `apps/fo` 내부 하드코딩 색상 파일 목록 확정
2. 공통 UI와 데이터 의미색을 분리
3. 일반 UI 색상부터 `base.css` 토큰으로 치환
4. 필요 시 `apps/fo/app/styles/*.css`에 앱 전용 의미 클래스 추가
5. `dashboard`, `map`, `modal`, `search` 대표 화면 점검
6. 남은 의미색 영역은 별도 상태색 정책으로 정리
## 7. 권장 치환 전략
### 7.1 JSX 안에서 바로 치환
아래처럼 className을 직접 토큰 기반으로 변경한다.
- `bg-white` -> `bg-background`
- `text-gray-600` -> `text-label`
- `border-gray-300` -> `border-border`
이 방식은 빠르지만 반복이 많으면 유지보수성이 떨어진다.
### 7.2 반복되는 UI는 앱 전용 클래스 도입
예:
- `fo-search-panel`
- `fo-search-input`
- `fo-popup-card`
- `fo-empty-text`
반복되는 구조는 `apps/fo/app/styles/components*.css`에 올리고, JSX에서는 의미 클래스만 사용한다.
이 방식이 장기적으로 더 좋다.
## 8. 예상 주의사항
- `h-90` 같은 Tailwind v3 미지원 클래스가 섞여 있을 수 있다.
- `bg-white`를 `bg-background`로 바꾸면 black theme에서 contrast가 크게 달라질 수 있으므로 텍스트 색도 같이 바꿔야 한다.
- `bg-blue-*`, `bg-green-*`는 실제 status color인지 단순 강조색인지 구분하고 바꿔야 한다.
- 지도 오버레이는 HTML string으로 만드는 부분이 있으면 className 치환만으로 끝나지 않을 수 있다.
## 9. 1차 적용 추천 대상
우선 아래 파일부터 적용하는 것이 효율적이다.
1. `apps/fo/app/components/common/SearchInput.tsx`
2. `apps/fo/app/pages/map/searchBar/searchBar.tsx`
3. `apps/fo/app/components/common/UnderComment.tsx`
4. `apps/fo/app/pages/(with-layout)/dashboard/rainManage/page.tsx`
5. `apps/fo/app/components/common/FacilityTermModalHeader.tsx`
6. `apps/fo/app/components/common/FacilityTermModalHeaderMonth.tsx`
7. `apps/fo/app/pages/(with-layout)/facilityPrecipitation/modal/page.tsx`
## 10. 결론
- `apps/fo`도 `apps/wr`와 동일하게 `base.css` 토큰 중심으로 정리 가능하다.
- 1차는 일반 UI 하드코딩 제거에 집중하고, 데이터 의미색은 유지 또는 별도 정책으로 분리하는 것이 맞다.
- 가장 안전한 방향은 “반복 UI는 앱 전용 의미 클래스”, “일회성은 JSX에서 직접 토큰 치환”의 혼합 방식이다.
+4
View File
@@ -1,5 +1,9 @@
import "./styles/base.css";
import "./styles/components.css";
import "./styles/components-black.css";
import "./styles/components-blue.css";
import "./styles/components-green.css";
import "./styles/components-red.css";
import "@fontsource-variable/noto-sans-kr";
import { AppProvider } from "./providers";
@@ -0,0 +1,43 @@
@tailwind components;
@layer components {
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
.card-border {
@apply border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)] shadow-blur;
}
.card-header {
@apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4;
}
.card-footer {
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="black"] {
--fo-facility-info-flow-year-bg: color-mix(in srgb, var(--chart-4) 20%, var(--secondary));
--fo-facility-info-water-year-bg: color-mix(in srgb, var(--chart-3) 20%, var(--secondary));
--fo-facility-info-phosphorus-year-bg: color-mix(in srgb, var(--chart-1) 20%, var(--secondary));
--fo-facility-info-flow-summer-bg: color-mix(in srgb, var(--chart-4) 28%, var(--secondary));
--fo-facility-info-water-summer-bg: color-mix(in srgb, var(--chart-3) 28%, var(--secondary));
--fo-facility-info-phosphorus-summer-bg: color-mix(in srgb, var(--chart-1) 28%, var(--secondary));
--fo-facility-info-flow-winter-bg: color-mix(in srgb, var(--chart-4) 36%, var(--secondary));
--fo-facility-info-water-winter-bg: color-mix(in srgb, var(--chart-3) 36%, var(--secondary));
--fo-facility-info-phosphorus-winter-bg: color-mix(in srgb, var(--chart-1) 36%, var(--secondary));
--fo-rain-impact-row-bg: color-mix(in srgb, var(--chart-1) 16%, var(--secondary));
--fo-facility-info-header-bg: #5e7b9c;
--fo-facility-info-header-fg: #ffffff;
--fo-facility-info-header-border: var(--border);
.card-border {
@apply border-[#3f4042] bg-[rgba(255,255,255,0.065)];
}
.card-header {
@apply border-b-[#3f4042];
}
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
}
@@ -0,0 +1,95 @@
@tailwind components;
@layer components {
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
.card-border {
@apply border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)] shadow-blur;
}
.card-header {
@apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4;
}
.card-footer {
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="blue"] {
--fo-facility-info-flow-year-bg: color-mix(in srgb, var(--chart-4) 16%, var(--background));
--fo-facility-info-water-year-bg: color-mix(in srgb, var(--chart-3) 16%, var(--background));
--fo-facility-info-phosphorus-year-bg: color-mix(in srgb, var(--chart-1) 16%, var(--background));
--fo-facility-info-flow-summer-bg: color-mix(in srgb, var(--chart-4) 24%, var(--background));
--fo-facility-info-water-summer-bg: color-mix(in srgb, var(--chart-3) 24%, var(--background));
--fo-facility-info-phosphorus-summer-bg: color-mix(in srgb, var(--chart-1) 24%, var(--background));
--fo-facility-info-flow-winter-bg: color-mix(in srgb, var(--chart-4) 32%, var(--background));
--fo-facility-info-water-winter-bg: color-mix(in srgb, var(--chart-3) 32%, var(--background));
--fo-facility-info-phosphorus-winter-bg: color-mix(in srgb, var(--chart-1) 32%, var(--background));
--fo-rain-impact-row-bg: color-mix(in srgb, var(--chart-1) 12%, var(--background));
--fo-facility-info-header-bg: #eaf3fb;
--fo-facility-info-header-fg: #647784;
--fo-facility-info-header-border: #e5e5e5;
.card-border {
@apply border-[#d8e3eb] bg-white shadow-blur;
}
.card-header {
@apply border-b-[#d8e3eb];
}
.card {
@apply text-[#4b5563];
}
.card.card-border {
box-shadow: 0 1px 8px rgba(15, 23, 42, 0.06);
}
.card.card-border .card.card-border {
@apply border-[#dde6ed] bg-white;
box-shadow: none;
}
.card.card-border input,
.card.card-border button[role="combobox"] {
@apply border-[#d8e3eb] bg-white text-[#737373];
}
.card.card-border label {
@apply text-[#666666];
}
nav[aria-label="pagination"] li a {
border-color: transparent !important;
background-color: transparent !important;
color: #0a0a0a !important;
}
nav[aria-label="pagination"] li a:hover {
background-color: #f6f6f6 !important;
color: #0a0a0a !important;
}
nav[aria-label="pagination"] li a[aria-current="page"] {
border-color: #2094fa !important;
background-color: #2094fa !important;
color: #fafafa !important;
}
nav[aria-label="pagination"] li a[aria-label="Go to previous page"],
nav[aria-label="pagination"] li a[aria-label="Go to next page"] {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
border: 1px solid #e5e7eb !important;
color: #666666 !important;
}
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
}
@@ -0,0 +1,43 @@
@tailwind components;
@layer components {
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
.card-border {
@apply border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)] shadow-blur;
}
.card-header {
@apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4;
}
.card-footer {
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="green"] {
--fo-facility-info-flow-year-bg: color-mix(in srgb, var(--chart-4) 15%, var(--background));
--fo-facility-info-water-year-bg: color-mix(in srgb, var(--chart-3) 15%, var(--background));
--fo-facility-info-phosphorus-year-bg: color-mix(in srgb, var(--chart-1) 15%, var(--background));
--fo-facility-info-flow-summer-bg: color-mix(in srgb, var(--chart-4) 23%, var(--background));
--fo-facility-info-water-summer-bg: color-mix(in srgb, var(--chart-3) 23%, var(--background));
--fo-facility-info-phosphorus-summer-bg: color-mix(in srgb, var(--chart-1) 23%, var(--background));
--fo-facility-info-flow-winter-bg: color-mix(in srgb, var(--chart-4) 31%, var(--background));
--fo-facility-info-water-winter-bg: color-mix(in srgb, var(--chart-3) 31%, var(--background));
--fo-facility-info-phosphorus-winter-bg: color-mix(in srgb, var(--chart-1) 31%, var(--background));
--fo-rain-impact-row-bg: color-mix(in srgb, var(--chart-3) 12%, var(--background));
--fo-facility-info-header-bg: #ebf7f7;
--fo-facility-info-header-fg: #64908f;
--fo-facility-info-header-border: var(--border);
.card-border {
@apply border-[#3f4042] bg-[rgba(255,255,255,0.065)];
}
.card-header {
@apply border-b-[#3f4042];
}
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
}
+36
View File
@@ -0,0 +1,36 @@
@tailwind components;
@layer components {
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
.card-border {
@apply border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)] shadow-blur;
}
.card-header {
@apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4;
}
.card-footer {
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="red"] {
--fo-facility-info-flow-year-bg: color-mix(in srgb, var(--chart-4) 14%, var(--background));
--fo-facility-info-water-year-bg: color-mix(in srgb, var(--chart-3) 14%, var(--background));
--fo-facility-info-phosphorus-year-bg: color-mix(in srgb, var(--chart-1) 14%, var(--background));
--fo-facility-info-flow-summer-bg: color-mix(in srgb, var(--chart-4) 22%, var(--background));
--fo-facility-info-water-summer-bg: color-mix(in srgb, var(--chart-3) 22%, var(--background));
--fo-facility-info-phosphorus-summer-bg: color-mix(in srgb, var(--chart-1) 22%, var(--background));
--fo-facility-info-flow-winter-bg: color-mix(in srgb, var(--chart-4) 30%, var(--background));
--fo-facility-info-water-winter-bg: color-mix(in srgb, var(--chart-3) 30%, var(--background));
--fo-facility-info-phosphorus-winter-bg: color-mix(in srgb, var(--chart-1) 30%, var(--background));
--fo-rain-impact-row-bg: color-mix(in srgb, var(--destructive) 12%, var(--background));
--fo-facility-info-header-bg: #f6f6f9;
--fo-facility-info-header-fg: #808080;
--fo-facility-info-header-border: var(--border);
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
}
+73 -7
View File
@@ -1,6 +1,22 @@
@tailwind components;
@layer components {
:root {
--fo-facility-info-flow-year-bg: color-mix(in srgb, var(--chart-4) 18%, var(--background));
--fo-facility-info-water-year-bg: color-mix(in srgb, var(--chart-3) 18%, var(--background));
--fo-facility-info-phosphorus-year-bg: color-mix(in srgb, var(--chart-1) 18%, var(--background));
--fo-facility-info-flow-summer-bg: color-mix(in srgb, var(--chart-4) 28%, var(--background));
--fo-facility-info-water-summer-bg: color-mix(in srgb, var(--chart-3) 28%, var(--background));
--fo-facility-info-phosphorus-summer-bg: color-mix(in srgb, var(--chart-1) 28%, var(--background));
--fo-facility-info-flow-winter-bg: color-mix(in srgb, var(--chart-4) 38%, var(--background));
--fo-facility-info-water-winter-bg: color-mix(in srgb, var(--chart-3) 38%, var(--background));
--fo-facility-info-phosphorus-winter-bg: color-mix(in srgb, var(--chart-1) 38%, var(--background));
--fo-rain-impact-row-bg: color-mix(in srgb, var(--chart-1) 10%, var(--background));
--fo-facility-info-header-bg: #eaf3fb;
--fo-facility-info-header-fg: #647784;
--fo-facility-info-header-border: var(--border);
}
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
@@ -14,13 +30,63 @@
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="black"] {
.card-border {
@apply border-[#3f4042] bg-[rgba(255,255,255,0.065)];
}
.card-header {
@apply border-b-[#3f4042];
}
.fo-facility-info-flow-year,
.fo-facility-info-water-year,
.fo-facility-info-phosphorus-year,
.fo-facility-info-flow-summer,
.fo-facility-info-water-summer,
.fo-facility-info-phosphorus-summer,
.fo-facility-info-flow-winter,
.fo-facility-info-water-winter,
.fo-facility-info-phosphorus-winter {
color: var(--foreground);
}
.fo-facility-info-flow-year {
background-color: var(--fo-facility-info-flow-year-bg);
}
.fo-facility-info-water-year {
background-color: var(--fo-facility-info-water-year-bg);
}
.fo-facility-info-phosphorus-year {
background-color: var(--fo-facility-info-phosphorus-year-bg);
}
.fo-facility-info-flow-summer {
background-color: var(--fo-facility-info-flow-summer-bg);
}
.fo-facility-info-water-summer {
background-color: var(--fo-facility-info-water-summer-bg);
}
.fo-facility-info-phosphorus-summer {
background-color: var(--fo-facility-info-phosphorus-summer-bg);
}
.fo-facility-info-flow-winter {
background-color: var(--fo-facility-info-flow-winter-bg);
}
.fo-facility-info-water-winter {
background-color: var(--fo-facility-info-water-winter-bg);
}
.fo-facility-info-phosphorus-winter {
background-color: var(--fo-facility-info-phosphorus-winter-bg);
}
.fo-rain-impact-row td {
background-color: var(--fo-rain-impact-row-bg);
}
.fo-facility-info-header-surface {
border: 1px solid var(--fo-facility-info-header-border);
background-color: var(--fo-facility-info-header-bg);
color: var(--fo-facility-info-header-fg);
}
input[type="file"] {
+6
View File
@@ -1,3 +1,9 @@
import "./styles/base.css";
import "./styles/components.css";
import "./styles/components-black.css";
import "./styles/components-blue.css";
import "./styles/components-green.css";
import "./styles/components-red.css";
import { AppProvider } from "./providers";
import { cookies } from "next/headers";
@@ -0,0 +1,29 @@
@tailwind components;
@layer components {
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
.card-border {
@apply border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)] shadow-blur;
}
.card-header {
@apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4;
}
.card-footer {
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="black"] {
.card-border {
@apply border-[#3f4042] bg-[rgba(255,255,255,0.065)];
}
.card-header {
@apply border-b-[#3f4042];
}
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
}
@@ -0,0 +1,29 @@
@tailwind components;
@layer components {
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
.card-border {
@apply border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)] shadow-blur;
}
.card-header {
@apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4;
}
.card-footer {
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="blue"] {
.card-border {
@apply border-[#3f4042] bg-[rgba(255,255,255,0.065)];
}
.card-header {
@apply border-b-[#3f4042];
}
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
}
@@ -0,0 +1,29 @@
@tailwind components;
@layer components {
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
.card-border {
@apply border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)] shadow-blur;
}
.card-header {
@apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4;
}
.card-footer {
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="green"] {
.card-border {
@apply border-[#3f4042] bg-[rgba(255,255,255,0.065)];
}
.card-header {
@apply border-b-[#3f4042];
}
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
}
+29
View File
@@ -0,0 +1,29 @@
@tailwind components;
@layer components {
.card {
@apply relative m-[0.6rem] box-border min-h-[2rem] rounded-[0.5rem] p-[0.6rem] text-[1.3rem] text-[#666];
}
.card-border {
@apply border border-[#dbe2e6] bg-[rgba(255,255,255,0.6)] shadow-blur;
}
.card-header {
@apply -mx-[0.6rem] flex items-center justify-between border-b border-b-[#e1e7eb] p-4;
}
.card-footer {
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="red"] {
.card-border {
@apply border-[#3f4042] bg-[rgba(255,255,255,0.065)];
}
.card-header {
@apply border-b-[#3f4042];
}
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
}
-9
View File
@@ -14,15 +14,6 @@
@apply -mx-[0.6rem] mt-2 flex items-center justify-center border-t border-t-[#e1e7eb] py-4;
}
[data-theme="black"] {
.card-border {
@apply border-[#3f4042] bg-[rgba(255,255,255,0.065)];
}
.card-header {
@apply border-b-[#3f4042];
}
}
input[type="file"] {
@apply w-[200px] h-[40px] px-3 py-2 border border-[#d1d5db] rounded-md bg-white text-sm cursor-pointer;
}
@@ -15,34 +15,34 @@ export function DrgtLegend() {
<div className="flex items-center gap-2 w-full">
<span
className="inline-block w-16 h-6"
style={{ backgroundColor: color, border: "1px solid #ccc" }}
style={{ backgroundColor: color, border: "1px solid var(--border)" }}
/>
<span className="text-xl text-gray-900 font-bold">{label}</span>
<span className="text-xl font-bold text-foreground">{label}</span>
</div>
);
}
return (
<div className="bg-white rounded-lg shadow-lg border border-gray-200 w-[160px] px-4 py-3">
<div className="w-[160px] rounded-lg border border-border bg-popover px-4 py-3 text-popover-foreground shadow-lg">
<div className="flex items-center justify-between mx-2 my-4">
<Label className="text-3xl text-gray-900 font-bold">가뭄정보 범례</Label>
<Label className="text-3xl font-bold text-foreground">가뭄정보 범례</Label>
</div>
<div className="mb-3">
<div className="w-full bg-gray-200 rounded-full h-1">
<div className="h-1 w-full rounded-full bg-secondary">
<div className="bg-blue-900 h-1 rounded-full transition-all duration-300 ease-in-out" />
</div>
</div>
<div className="w-[140px] mx-auto flex flex-col items-center">
<div className="bg-blue-900 text-white text-2xl text-center py-1 mb-2 rounded w-full">가 뭄 정 보</div>
<div className="space-y-1 w-full">
<Label className="text-xl text-gray-900 font-bold">관심</Label>
<Label className="text-xl font-bold text-foreground">관심</Label>
<LegendItem color="rgba(222,235,247, 1)" label="1회 미만" /> {/* 관심 - 1회 미만 */}
<LegendItem color="rgba(46, 117, 182, 1)" label="1회 이상" /> {/* 관심 - 1회 이상 */}
<Label className="text-xl text-gray-900 font-bold">주의</Label>
<Label className="text-xl font-bold text-foreground">주의</Label>
<LegendItem color="rgba(255, 242, 204, 1)" label="1회 미만" /> {/* 주의 - 1회 미만 */}
<LegendItem color="rgba(255, 217, 102, 1)" label="1회 이상" /> {/* 주의 - 1회 이상 */}
<Label className="text-xl text-gray-900 font-bold">관심 + 주의</Label>
<Label className="text-xl font-bold text-foreground">관심 + 주의</Label>
<LegendItem color="rgba(251, 229, 214, 1)" label="1회 미만" /> {/* 관심+주의 - 1회 미만 */}
<LegendItem color="rgba(237, 125, 49, 1)" label="1회 이상" /> {/* 관심+주의 - 1회 이상 */}
</div>
@@ -50,4 +50,4 @@ export function DrgtLegend() {
</div>
</div>
);
}
}
@@ -172,12 +172,12 @@ export function SearchBar({ gisMaps, ctpvCode, sggCode }: CtpvSggPrcsFcltSelectB
return (
<div className="flex items-center gap-4 bg-white min-h-[48px] min-w-[430px] px-5 py-3 rounded-lg shadow">
<div className="flex min-h-[48px] min-w-[430px] items-center gap-4 rounded-lg bg-card px-5 py-3 text-card-foreground shadow">
<div className={`flex items-center justify-center mr-8`}>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시도</Label>
<Label className="mr-2 whitespace-nowrap text-xl font-medium text-label">시도</Label>
<SelectBox
className="w-60 mr-8"
selectClass="rounded-lg bg-white"
selectClass="rounded-lg"
label=""
selectArray={[DEFAULT_OPTION, ...ctpv]}
value={ctpvCd}
@@ -187,10 +187,10 @@ export function SearchBar({ gisMaps, ctpvCode, sggCode }: CtpvSggPrcsFcltSelectB
}}
selectContentClass="z-[101]"
/>
<Label className="text-xl text-gray-600 font-medium whitespace-nowrap mr-2">시군구</Label>
<Label className="mr-2 whitespace-nowrap text-xl font-medium text-label">시군구</Label>
<SelectBox
className="w-48"
selectClass="w-48 rounded-lg bg-white truncate"
selectClass="w-48 truncate rounded-lg"
label=""
selectArray={
[DEFAULT_OPTION,
@@ -207,4 +207,4 @@ export function SearchBar({ gisMaps, ctpvCode, sggCode }: CtpvSggPrcsFcltSelectB
</div>
</div>
);
}
}
@@ -1,3 +1,6 @@
/**
* 지도에서 feature 선택시 팝업
*/
"use client";
import { useWrStore } from "@/app/store";
import CoSttnDetailPopup from "@/components/ui/map/detailPopup/coSttnDetailPopup/coSttnDetailPopup";
@@ -20,7 +23,7 @@ export default function MapFeaturePopup() {
coSttnMapDetail
} = useWrStore((state) => state);
const { pbnMapHeadList } = pbnMap;
const [isDetail, setIsDetail] = useState<any>(undefined);
const [isDetail, setIsDetail] = useState<any>(undefined); // isFeatureCd && layerNm
const [layerNm, setLayerNm] = useState<string>();
const searchParams = useSearchParams();
@@ -57,32 +60,32 @@ export default function MapFeaturePopup() {
useEffect(() => {
console.log(' layerNm ' , layerNm)
if (isFeatureCd && layerNm) {
if (layerNm === "tb_wr_bdst_ruse_fclt") {
if (layerNm === "tb_wr_bdst_ruse_fclt") { // 하수재이용시설
setIsDetail(isFeatureCd);
} else if (layerNm === "tb_il_swage_prcs_fclt") {
} else if (layerNm === "tb_il_swage_prcs_fclt") { // 하수처리시설
pbnMapDetaile(isFeatureCd).then((res) => {
console.log('res', res)
setIsDetail([res]);
});
} else if (layerNm === "tb_wr_rnwtr_utztn_fclt") {
} else if (layerNm === "tb_wr_rnwtr_utztn_fclt") { // 빗물이용시설
rainMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
} else if (layerNm === "tb_wr_rswtr_fclt") {
} else if (layerNm === "tb_wr_rswtr_fclt") { // 중수도시설
rswtMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
} else if (layerNm === "tb_wr_htdfl_fclt") {
} else if (layerNm === "tb_wr_htdfl_fclt") { // 온배수시설
htdfMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
}else if(layerNm ==='tb_wr_ruse_fclt_dmd_co'){
}else if(layerNm ==='tb_wr_ruse_fclt_dmd_co'){ // 수요처
coSttnMapDetail(isFeatureCd).then((res) => {
console.log('tb_wr_ruse_fclt_dmd_co ', res)
setIsDetail(res);
});
} else if (layerNm === "tb_wr_tmpr_dmd_co") {
} else if (layerNm === "tb_wr_tmpr_dmd_co") { // 잠재수요처
ldrmntMapDetile(isFeatureCd).then((res) => {
setIsDetail(res);
});
@@ -94,7 +97,7 @@ export default function MapFeaturePopup() {
return (
<>
{isDetail ? (
<div className="m-0 bg-white p-4 md:p-6 pb-24 box-border">
<div className="box-border m-0 bg-background p-4 pb-24 text-foreground md:p-6">
{layerNm === "tb_wr_bdst_ruse_fclt" ? (
<RuseDetailPopup bscFctCd={isDetail} />
) : layerNm === "tb_il_swage_prcs_fclt" ? (
@@ -94,7 +94,7 @@ export default function SearchInputText({
value={textValue || ""}
onChange={handleInputChange}
onKeyDown={handleKeyDown}
className="w-full h-[3.2rem] !text-xl pl-3 text-gray-600 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
className="h-[3.2rem] w-full rounded-md border border-input pl-3 !text-xl text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
placeholder={`${label}을(를) 입력하세요`}
onClick={() => {
setTextValue("");
@@ -103,7 +103,7 @@ export default function SearchInputText({
}}
/>
{isOpen && (
<div className="absolute top-full left-0 z-50 mb-2 max-h-72 w-full overflow-auto rounded-md border border-gray-300 bg-white shadow-lg">
<div className="absolute left-0 top-full z-50 mb-2 max-h-72 w-full overflow-auto rounded-md border border-border bg-popover text-popover-foreground shadow-lg">
<div className="max-h-72">
{searchList.length > 0 ? (
searchList.map((item, index) => (
@@ -111,8 +111,8 @@ export default function SearchInputText({
key={index}
className={`w-full cursor-pointer overflow-auto px-5 py-3 text-left !text-xl ${
highlightIndex === index
? "bg-blue-100"
: "hover:bg-gray-100"
? "bg-accent text-accent-foreground"
: "hover:bg-accent hover:text-accent-foreground"
}`}
onClick={() => handleSuggestionClick(item.bscFctNm)}
role="button"
@@ -127,7 +127,7 @@ export default function SearchInputText({
</div>
))
) : (
<div className="!text-xl w-full px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto">
<div className="w-full cursor-pointer overflow-auto px-5 py-3 !text-xl text-muted-foreground hover:bg-accent hover:text-accent-foreground">
검색 결과가 없습니다.
</div>
)}
@@ -200,17 +200,17 @@ const Map = () => {
// HTML 또는 React 오버레이 컴포넌트 구성
const overlayContent = `
<div class="rounded-md border border-gray-300 bg-white shadow-md text-sm w-[120px]">
<div class="w-[120px] rounded-md border border-border bg-popover text-sm text-popover-foreground shadow-md">
<!-- 헤더 -->
<div class="bg-cyan-700 text-white px-3 py-2 text-[11px] font-semibold text-center rounded-t-md">
<div class="rounded-t-md bg-primary px-3 py-2 text-center text-[11px] font-semibold text-primary-foreground">
${feature.get("swtrmt_fclt_nm") || "-"}
</div>
<!-- 테이블 -->
<table class="w-full text-sm text-gray-800 border-t border-gray-200">
<table class="w-full border-t border-border text-sm text-foreground">
<tbody>
<tr class="border-b border-gray-200">
<th class="bg-gray-100 text-gray-600 font-semibold text-[10px] text-left">용량(m³/일)</th>
<tr class="border-b border-border">
<th class="bg-secondary text-secondary-foreground font-semibold text-[10px] text-left">용량(m³/일)</th>
<td class="text-right text-[10px] font-bold">${formatNumber(feature.get("fclt_cpct"))}</td>
</tr>
</tbody>
@@ -60,12 +60,12 @@ export function SearchBar({
return (
<div className="flex justify-center w-full px-4 py-3">
<div className="flex items-center w-full max-w-screen-lg rounded-xl bg-white shadow-md px-6 py-4 space-x-3">
<div className="flex w-full max-w-screen-lg items-center space-x-3 rounded-xl bg-card px-6 py-4 text-card-foreground shadow-md">
<SelectBox
labelClass="w-[40px]"
className="w-[200px]"
label="시도"
selectClass="rounded-lg bg-white"
selectClass="rounded-lg"
selectArray={code.cityCd || []}
onSelectValue={(val) => onSelectValue(val.toString(), "ctpvCd")}
value={sidoValue}
@@ -74,12 +74,12 @@ export function SearchBar({
labelClass="w-[65px]"
className="w-[200px]"
label="시군구"
selectClass="rounded-lg bg-white"
selectClass="rounded-lg"
selectArray={filteredSigunData || []}
onSelectValue={(val) => onSelectValue(val.toString(), "sggCd")}
value={sigunValue}
/>
<Label className="text-gray-600">하수재이용시설</Label>
<Label className="text-label">하수재이용시설</Label>
<SearchInputText
label="시설명"
initValue={undefined}
@@ -101,7 +101,7 @@ export function SearchBar({
/>
<Button
color="sky"
className="ml-2 text-white"
className="ml-2"
size="sm"
onClick={() => {
onApply();
@@ -24,13 +24,13 @@ export default function SelectedFcltList({
};
return (
<div className="fixed right-40 top-[8rem] w-[40rem] max-h-[130rem] overflow-auto bg-white shadow-lg rounded p-4 border border-gray-300 z-50">
<h3 className="bg-cyan-700 text-white text-xl font-bold mb-2 p-2">
<div className="fixed right-40 top-[8rem] z-50 max-h-[130rem] w-[40rem] overflow-auto rounded border border-border bg-popover p-4 text-popover-foreground shadow-lg">
<h3 className="mb-2 bg-primary p-2 text-xl font-bold text-primary-foreground">
선택된 시설
</h3>
<div className="overflow-x-auto">
<table className="w-full text-sm text-gray-800 border border-gray-200">
<thead className="bg-gray-100 text-gray-700 text-[13px]">
<table className="w-full border border-border text-sm text-foreground">
<thead className="bg-secondary text-[13px] text-secondary-foreground">
<tr>
<th className="px-3 py-2 text-left border-b">시설명</th>
<th className="px-3 py-2 text-right border-b">
@@ -60,7 +60,7 @@ export default function SelectedFcltList({
<td className="px-3 py-2 text-center">
<button
onClick={() => handleDelete(item.pbnstRuseFcltId)}
className="text-red-500 hover:text-red-700 text-sm font-bold"
className="text-sm font-bold text-destructive hover:opacity-80"
aria-label="삭제"
title="삭제"
>
@@ -71,7 +71,7 @@ export default function SelectedFcltList({
))
) : (
<tr>
<td colSpan={4} className="px-3 py-6 text-center text-[12px] text-gray-500">
<td colSpan={4} className="px-3 py-6 text-center text-[12px] text-muted-foreground">
선택된 시설이 없습니다.
</td>
</tr>
@@ -93,7 +93,7 @@ const EMPTY_DETAIL_FORM: Partial<DmdCoReqType> = {
};
export default function CoMatRvw() {
const readOnlyInputClass = "bg-slate-50 text-gray-700";
const readOnlyInputClass = "bg-secondary text-secondary-foreground";
const { auth, code, coRvw, coMatRvwInit, coMatRvwSearch, coMatRvwInqua } =
useWrStore((state) => state);
const { coMatRvwRes, coMatRvwCount } = coRvw;
@@ -305,7 +305,7 @@ export default function CoMatRvw() {
/>
<div className="col-span-7 w-full">
<div className="flex flex-row items-center">
<Label className="text-xl text-gray-600 mx-6">
<Label className="mx-6 text-xl text-label">
수요신청년도
</Label>
<SelectBox
@@ -522,7 +522,7 @@ export default function CoMatRvw() {
/>
{/* TODO: 총대장균군수 확인 필요*/}
{field.value != -1 ? (
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
) : (
@@ -549,7 +549,7 @@ export default function CoMatRvw() {
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이상
</span>
</div>
@@ -573,7 +573,7 @@ export default function CoMatRvw() {
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className=" text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -601,7 +601,7 @@ export default function CoMatRvw() {
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -643,7 +643,7 @@ export default function CoMatRvw() {
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -670,7 +670,7 @@ export default function CoMatRvw() {
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -697,7 +697,7 @@ export default function CoMatRvw() {
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -748,7 +748,7 @@ export default function CoMatRvw() {
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -775,7 +775,7 @@ export default function CoMatRvw() {
value={formatNumberWithComma(field.value)}
readOnly
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -347,7 +347,7 @@ export default function RuseCaseMng() {
}}
resetPageNo={resetPage}
/>
<span className="text-2xl font-bold text-gray-500">
<span className="text-2xl font-bold text-muted-foreground">
☞ 본 사례의 사업비는 재원협의 단계의 정보이므로, 최종확정된 비용이 아닙니다.
</span>
</div>
@@ -250,7 +250,7 @@ export default function RuseRvwHstry() {
</SelectBox>
<div className="col-span-4 w-full">
<div className="flex flex-row items-center">
<Label className="text-xl text-gray-600 ml-4 mr-4">
<Label className="ml-4 mr-4 text-xl text-label">
수요신청년도
</Label>
<div className="flex flex-row mt-2">
@@ -363,7 +363,7 @@ export default function CoSttn() {
getDemandCompList(searchText, pageCnt);
}}
rtnInputData={handleRtnInputData}
bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"}
bodyClassNm={"w-full mx-auto bg-background rounded-lg shadow-md p-6"}
updateList={updateData}
openNetwork={true}
></SdmInsertForm>
@@ -171,7 +171,7 @@ export default function DrgtSttn() {
/>
<div className="col-span-5 w-auto">
<div className="flex flex-row items-center">
<Label className="text-xl text-gray-600 ml-8">조회기간</Label>
<Label className="ml-8 text-xl text-label">조회기간</Label>
<div className="flex flex-row w-1/4">
<DateMonthPicker
field={{
@@ -154,6 +154,7 @@ export default function Home() {
onPageChange={setPageNation}
index={htdfTableIndex}
resetPageNo={resetPageNo}
widthFixed={true}
></UiTable>
</ScrollArea>
</ListDiv>
@@ -376,6 +376,7 @@ export default function PublicReuseFaciltyInsert() {
resetSelection={resetSelection}
index={selectedRowIndex}
curPage={pageNation}
widthFixed={true}
/>
</ScrollArea>
</ListDiv>
@@ -431,7 +432,7 @@ export default function PublicReuseFaciltyInsert() {
<div className="card-header text-2xl">
등록된 재이용시설 정보가 없습니다.
</div>
<div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 border rounded-md">
<div className="!mx-[1.6rem] !p-0 flex flex-col items-center justify-center h-64 border rounded-md">
<p className="text-3xl mb-4">
신규등록 버튼을 클릭하여 재이용시설을 등록해주세요.
</p>
@@ -167,6 +167,7 @@ export default function Home() {
onPageChange={setPageNation}
index={rainTableIndex}
resetPageNo={resetPageNo}
widthFixed={true}
></UiTable>
</ScrollArea>
</ListDiv>
@@ -171,6 +171,7 @@ export default function Home() {
onPageChange={setPageNation}
index={rswtTableIndex}
resetPageNo={resetPageNo}
widthFixed={true}
></UiTable>
</ScrollArea>
</ListDiv>
@@ -40,11 +40,10 @@ import { useTranslation } from "react-i18next";
const defaultSigunOptions: SelectDataType[] = [{ text: "전체", val: "0" }];
export default function HtdflSttn() {
const { auth, code, htdflSttn, htdflSttnSearch, initHtdfl, getLaeSeCdCheck } = useWrStore((state) => state);
const { auth, code, htdflSttn, htdflSttnSearch, getLaeSeCdCheck } = useWrStore((state) => state);
const { laeSeCd } = auth; // 지자체구분코드
const { htdflSttnRes, htdflSttnResCount } = htdflSttn;
const isDownloadTriggered = useRef(false);
const skipNextSearchRef = useRef(true);
const initializedSearchKeyRef = useRef<string | null>(null);
const { t } = useTranslation('base');
const [pageNation, setPageNation] = useState(1);
const [isChHead, setIsChHead] = useState(false);
@@ -61,6 +60,10 @@ export default function HtdflSttn() {
// chBuilding: chgBuilding[];
// }>({ isOpen: false, chBuilding: [] });
const [fcltNm, setFcltNm] = useState<string>("");
const [appliedSearch, setAppliedSearch] = useState<{
conValue: string;
fcltNm: string;
} | null>(null);
const alert = useAlertStore((state) => state.setMessage);
const isAllAreaUser = laeSeCd === "0";
const isLaeSeCdReady =
@@ -89,7 +92,7 @@ export default function HtdflSttn() {
setObjSearch({ ...objSearch, sgg: String(val) })
};
const getConValue = (): string => {
const getConValue = useCallback((): string => {
if (!objSearch.city || objSearch.city === "0") {
return "0";
}
@@ -97,7 +100,7 @@ export default function HtdflSttn() {
return String(objSearch.sgg);
}
return String(objSearch.city);
};
}, [objSearch]);
const getFixedConValue = useCallback((): string => {
if (laeSeCd === undefined || laeSeCd === "0") {
@@ -105,7 +108,7 @@ export default function HtdflSttn() {
}
return laeSeCd.length === 5 ? laeSeCd : laeSeCd.slice(0, 2);
}, [laeSeCd, objSearch]);
}, [laeSeCd, getConValue]);
const cellClick = (index: number | undefined, headId: string) => {
if (
@@ -117,14 +120,39 @@ export default function HtdflSttn() {
}
};
const excelClick = useCallback(() => {
if (!isLaeSeCdReady) {
const excelClick = useCallback(async () => {
if (!isLaeSeCdReady || !appliedSearch) {
return;
}
isDownloadTriggered.current = true;
htdflSttnSearch(true, 1, htdflSttnResCount, String(getFixedConValue()), fcltNm, code.cityCd, code.sggCd);
}, [htdflSttnSearch, fcltNm, htdflSttnResCount, code.cityCd, code.sggCd, getFixedConValue, isLaeSeCdReady]);
const excelData = await htdflSttnSearch(
true,
1,
htdflSttnResCount,
appliedSearch.conValue,
appliedSearch.fcltNm,
code.cityCd,
code.sggCd
);
if (excelData && excelData.length > 0) {
const sheetArray: SheetParameter[] = [{
data: excelData,
headerNum: 3,
headerRange: "A1:R3",
sheetName: "sheet1",
startCol: "A",
decimalArray0: [6, 11, 13, 15],
}];
excelDownloadNumStyle(
"온배수시설 현황",
"sample_htdflSttn.xlsx",
sheetArray
);
return;
}
alert(t("excelDownErrMsg"));
}, [htdflSttnSearch, htdflSttnResCount, appliedSearch, code.cityCd, code.sggCd, isLaeSeCdReady, alert, t]);
useEffect(() => {
getLaeSeCdCheck();
@@ -150,52 +178,39 @@ export default function HtdflSttn() {
});
}, [laeSeCd, code.sggCd, isLaeSeCdReady]);
useEffect(() => {
if (!isDownloadTriggered.current) {
return;
}
if (htdflSttn.excelList.length > 0) {
const sheetArray: SheetParameter[] = [{
data: htdflSttn.excelList,
headerNum: 3,
headerRange: "A1:R3",
sheetName: 'sheet1',
startCol: 'A',
decimalArray0: [6,11,13,15], // 0부터 시작
}];
excelDownloadNumStyle(
"온배수시설 현황",
"sample_htdflSttn.xlsx",
sheetArray
);
} else {
alert(t('excelDownErrMsg'));
}
isDownloadTriggered.current = false;
}, [htdflSttn.excelList, code]);
useEffect(() => {
if (!isLaeSeCdReady || htdflSttn.isInit) {
return;
}
skipNextSearchRef.current = true;
initHtdfl(false, 1, htdflSttnSize, String(getFixedConValue()), fcltNm, code.cityCd, code.sggCd);
}, [htdflSttn.isInit, initHtdfl, fcltNm, code.cityCd, code.sggCd, getFixedConValue, isLaeSeCdReady]);
useEffect(() => {
if (!isLaeSeCdReady) {
return;
}
if (skipNextSearchRef.current) {
skipNextSearchRef.current = false;
const initialSearchKey = laeSeCd ?? "0";
if (initializedSearchKeyRef.current === initialSearchKey) {
return;
}
htdflSttnSearch(false, pageNation, htdflSttnSize, String(getFixedConValue()), fcltNm, code.cityCd, code.sggCd);
const initialConValue =
laeSeCd === undefined || laeSeCd === "0"
? "0"
: laeSeCd.length === 5
? laeSeCd
: laeSeCd.slice(0, 2);
initializedSearchKeyRef.current = initialSearchKey;
setAppliedSearch({
conValue: initialConValue,
fcltNm: "",
});
setPageNation(1);
}, [isLaeSeCdReady, laeSeCd]);
useEffect(() => {
if (!isLaeSeCdReady || !appliedSearch) {
return;
}
htdflSttnSearch(false, pageNation, htdflSttnSize, appliedSearch.conValue, appliedSearch.fcltNm, code.cityCd, code.sggCd);
isResetPage(false)
}, [pageNation, htdflSttnSearch, fcltNm, code.cityCd, code.sggCd, getFixedConValue, isLaeSeCdReady]);
}, [pageNation, htdflSttnSearch, appliedSearch, code.cityCd, code.sggCd, isLaeSeCdReady]);
useEffect(() => {
const data = tableData(htdflSttnRes, { code });
@@ -215,6 +230,19 @@ export default function HtdflSttn() {
setBdstTable(chData);
}, [code, htdflSttnRes, htdflSttn.htdflSttHeadList]);
const handleSearch = useCallback(() => {
if (!isLaeSeCdReady) {
return;
}
setAppliedSearch({
conValue: String(getFixedConValue()),
fcltNm,
});
isResetPage(true);
setPageNation(1);
}, [fcltNm, getFixedConValue, isLaeSeCdReady]);
return (
<>
<ContentsDiv>
@@ -266,13 +294,7 @@ export default function HtdflSttn() {
<div className="flex flex-row space-x-2 items-center">
<Button
className={btnClass}
onClick={() => {
if (!isLaeSeCdReady) {
return;
}
htdflSttnSearch(false, 1,htdflSttnSize, String(getFixedConValue()), fcltNm, code.cityCd, code.sggCd);
isResetPage(true)
}}
onClick={handleSearch}
>
조회
</Button>
@@ -244,7 +244,7 @@ export default function PbnstSttn() {
setSearchYear(String(val))
}
/>
<Label className="w-full ml-4 text-xl text-gray-600">
<Label className="ml-4 w-full text-xl text-label">
{"하수처리시설명"}
</Label>
<SearchInput
@@ -1,5 +1,5 @@
/**
* 빗물이용시설 현황
* 재이용시설 현황 > 빗물이용시설 현황
*/
"use client";
import { useWrStore } from "@/app/store";
@@ -38,7 +38,7 @@ import { useTranslation } from "react-i18next";
const defaultSigunOptions: SelectDataType[] = [{ text: "전체", val: "0" }];
export default function RainSttn() {
const { auth, code, rainSttn, rainSttnSearch, rainSttnInit, getLaeSeCdCheck } = useWrStore(
const { auth, code, rainSttn, rainSttnSearch, getLaeSeCdCheck } = useWrStore(
(state) => state
);
const { rainSttnRes, rainSttnResCount } = rainSttn;
@@ -49,7 +49,6 @@ export default function RainSttn() {
const [bdstTable, setBdstTable] = useState<customRainBdst[]>();
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>(defaultSigunOptions);
const [resetPage, isResetPage] = useState(false);
const [isDownloadTriggered, setIsDownloadTriggered] = useState(false);
const [objSearch, setObjSearch] = useState<objSearchType>({
sgg: "",
city: "",
@@ -60,14 +59,13 @@ export default function RainSttn() {
}>({ data: undefined, isOpen: false });
const [fcltNm, setFcltNm] = useState<string>("");
const [appliedSearch, setAppliedSearch] = useState({
conValue: "0",
fcltNm: "",
});
const [searchTrigger, setSearchTrigger] = useState(0);
const [appliedSearch, setAppliedSearch] = useState<{
conValue: string;
fcltNm: string;
} | null>(null);
const { t } = useTranslation("base");
const alert = useAlertStore((state) => state.setMessage);
const skipNextSearchRef = useRef(true);
const initializedSearchKeyRef = useRef<string | null>(null);
const isAllAreaUser = laeSeCd === "0";
const isLaeSeCdReady =
laeSeCd === "0" || laeSeCd.length === 2 || laeSeCd.length === 5;
@@ -100,7 +98,7 @@ export default function RainSttn() {
setObjSearch({ ...objSearch, sgg: String(val) });
};
const getConValue = (): string => {
const getConValue = useCallback((): string => {
if (!objSearch.city || objSearch.city === "0") {
return "0";
}
@@ -108,7 +106,7 @@ export default function RainSttn() {
return String(objSearch.sgg);
}
return String(objSearch.city);
};
}, [objSearch]);
const getFixedConValue = useCallback((): string => {
if (laeSeCd === undefined || laeSeCd === "0") {
@@ -116,7 +114,7 @@ export default function RainSttn() {
}
return laeSeCd.length === 5 ? laeSeCd : laeSeCd.slice(0, 2);
}, [laeSeCd, objSearch]);
}, [laeSeCd, getConValue]);
useEffect(() => {
getLaeSeCdCheck();
@@ -143,7 +141,12 @@ export default function RainSttn() {
}, [laeSeCd, code.sggCd, isLaeSeCdReady]);
useEffect(() => {
if (!isLaeSeCdReady || rainSttn.isInit) {
if (!isLaeSeCdReady) {
return;
}
const initialSearchKey = laeSeCd ?? "0";
if (initializedSearchKeyRef.current === initialSearchKey) {
return;
}
@@ -154,32 +157,16 @@ export default function RainSttn() {
? laeSeCd
: laeSeCd.slice(0, 2);
skipNextSearchRef.current = true;
initializedSearchKeyRef.current = initialSearchKey;
setAppliedSearch({
conValue: initialConValue,
fcltNm: "",
});
rainSttnInit(
false,
1,
rainSttnSize,
initialConValue,
"",
code as unknown as Record<string, SelectDataType[]>
);
}, [rainSttn.isInit, rainSttnInit, code, isLaeSeCdReady, laeSeCd]);
setPageNation(1);
}, [isLaeSeCdReady, laeSeCd]);
useEffect(() => {
if (!isLaeSeCdReady) {
return;
}
if (skipNextSearchRef.current) {
skipNextSearchRef.current = false;
return;
}
if (searchTrigger === 0) {
if (!isLaeSeCdReady || !appliedSearch) {
return;
}
@@ -194,49 +181,18 @@ export default function RainSttn() {
isResetPage(false);
}, [
pageNation,
searchTrigger,
rainSttnSearch,
code,
appliedSearch.conValue,
appliedSearch.fcltNm,
appliedSearch,
isLaeSeCdReady,
]);
useEffect(() => {
if (!isLaeSeCdReady) {
const excelClick = useCallback(async () => {
if (!isLaeSeCdReady || !appliedSearch) {
return;
}
if (!isDownloadTriggered) {
return;
}
if (rainSttn.excelList.length > 0) {
const sheetArray: SheetParameter[] = [{
data: rainSttn.excelList,
headerNum: 3,
headerRange: "A1:W3",
sheetName: 'sheet1',
startCol: 'A',
decimalArray0: [6,10,12,14,16] // 0부터 시작
}];
excelDownloadNumStyle(
"빗물이용시설 현황",
"sample_rainSttn.xlsx", // public 폴더에 있는 template 파일 경로
sheetArray
);
} else {
alert(t("excelDownErrMsg"));
}
setIsDownloadTriggered(false);
}, [rainSttn.excelList, isDownloadTriggered, alert, t, isLaeSeCdReady]);
const excelClick = useCallback(() => {
if (!isLaeSeCdReady) {
return;
}
setIsDownloadTriggered(true);
rainSttnSearch(
const excelData = await rainSttnSearch(
true,
1,
rainSttnResCount,
@@ -244,16 +200,39 @@ export default function RainSttn() {
appliedSearch.fcltNm,
code as unknown as Record<string, SelectDataType[]>
);
if (excelData && excelData.length > 0) {
const sheetArray: SheetParameter[] = [{
data: excelData,
headerNum: 3,
headerRange: "A1:W3",
sheetName: "sheet1",
startCol: "A",
decimalArray0: [6, 10, 12, 14, 16],
}];
excelDownloadNumStyle(
"빗물이용시설 현황",
"sample_rainSttn.xlsx",
sheetArray
);
return;
}
alert(t("excelDownErrMsg"));
}, [
rainSttnSearch,
rainSttnResCount,
code,
appliedSearch.conValue,
appliedSearch.fcltNm,
appliedSearch,
isLaeSeCdReady,
alert,
t,
]);
const handleSearch = useCallback(() => {
if (!isLaeSeCdReady) {
return;
}
const nextSearch = {
conValue: String(getFixedConValue()),
fcltNm,
@@ -262,8 +241,7 @@ export default function RainSttn() {
setAppliedSearch(nextSearch);
isResetPage(true);
setPageNation(1);
setSearchTrigger((prev) => prev + 1);
}, [fcltNm, getFixedConValue]);
}, [fcltNm, getFixedConValue, isLaeSeCdReady]);
useEffect(() => {
const data = tableData(rainSttnRes, { code });
@@ -38,7 +38,7 @@ import { useTranslation } from "react-i18next";
const defaultSigunOptions: SelectDataType[] = [{ text: "전체", val: "0" }];
export default function RswtSttn() {
const { auth, code, rswtSttn, rswtSttnSearch, rswtSttnInit, getLaeSeCdCheck } = useWrStore(
const { auth, code, rswtSttn, rswtSttnSearch, getLaeSeCdCheck } = useWrStore(
(state) => state
);
@@ -49,17 +49,15 @@ export default function RswtSttn() {
const [isChHead, setIsChHead] = useState(false);
const [resetPage, isResetPage] = useState(false);
const [bdstTable, setBdstTable] = useState<customRswtBdst[]>();
const isDownloadTriggered = useRef(false);
const skipNextSearchRef = useRef(true);
const initializedSearchKeyRef = useRef<string | null>(null);
const [selectSgg, setSelectSgg] = useState<SelectDataType[] | []>(defaultSigunOptions)
const [objSearch, setObjSearch] = useState<objSearchType>({ sgg: "", city: "" });
const [detailModal, setDetailModal] = useState<{ isOpen: boolean, data: customRswtBdst | undefined }>({ data: undefined, isOpen: false })
const [fcltNm, setFcltNm] = useState<string>("");
const [appliedSearch, setAppliedSearch] = useState({
conValue: "0",
fcltNm: "",
});
const [searchTrigger, setSearchTrigger] = useState(0);
const [appliedSearch, setAppliedSearch] = useState<{
conValue: string;
fcltNm: string;
} | null>(null);
const { t } = useTranslation('base');
const alert = useAlertStore((state) => state.setMessage);
const isAllAreaUser = laeSeCd === "0";
@@ -95,7 +93,7 @@ export default function RswtSttn() {
setObjSearch({ ...objSearch, sgg: String(val) })
};
const getConValue = (): string => {
const getConValue = useCallback((): string => {
if (!objSearch.city || objSearch.city === "0") {
return "0";
}
@@ -103,7 +101,7 @@ export default function RswtSttn() {
return String(objSearch.sgg);
}
return String(objSearch.city);
};
}, [objSearch]);
const getFixedConValue = useCallback((): string => {
if (laeSeCd === undefined || laeSeCd === "0") {
@@ -111,7 +109,7 @@ export default function RswtSttn() {
}
return laeSeCd.length === 5 ? laeSeCd : laeSeCd.slice(0, 2);
}, [laeSeCd, objSearch]);
}, [laeSeCd, getConValue]);
useEffect(() => {
getLaeSeCdCheck();
@@ -138,7 +136,12 @@ export default function RswtSttn() {
}, [laeSeCd, code.sggCd, isLaeSeCdReady]);
useEffect(() => {
if (!isLaeSeCdReady || rswtSttn.isInit) {
if (!isLaeSeCdReady) {
return;
}
const initialSearchKey = laeSeCd ?? "0";
if (initializedSearchKeyRef.current === initialSearchKey) {
return;
}
@@ -149,20 +152,13 @@ export default function RswtSttn() {
? laeSeCd
: laeSeCd.slice(0, 2);
skipNextSearchRef.current = true;
initializedSearchKeyRef.current = initialSearchKey;
setAppliedSearch({
conValue: initialConValue,
fcltNm: "",
});
rswtSttnInit(
false,
1,
rswtSttnSize,
initialConValue,
"",
code as unknown as Record<string, SelectDataType[]>
);
}, [rswtSttn.isInit, rswtSttnInit, code, isLaeSeCdReady, laeSeCd]);
setPageNation(1);
}, [isLaeSeCdReady, laeSeCd]);
useEffect(() => {
const data = tableData(rswtSttnRes, { code });
@@ -194,56 +190,47 @@ export default function RswtSttn() {
setBdstTable(chData);
}, [code, rswtSttnRes]);
useEffect(() => {
if (!isDownloadTriggered.current) {
const excelClick = useCallback(async () => {
if (!isLaeSeCdReady || !appliedSearch) {
return;
}
if (rswtSttn.excelList.length > 0) {
const excelData = await rswtSttnSearch(
true,
1,
rswtSttnResCount,
appliedSearch.conValue,
appliedSearch.fcltNm,
code as unknown as Record<string, SelectDataType[]>
);
if (excelData && excelData.length > 0) {
const sheetArray: SheetParameter[] = [{
data: rswtSttn.excelList,
data: excelData,
headerNum: 3,
headerRange: "A1:W3",
sheetName: 'sheet1',
startCol: 'A',
decimalArray0: [6,10,12,16], // 0부터 시작
sheetName: "sheet1",
startCol: "A",
decimalArray0: [6, 10, 12, 16],
}];
excelDownloadNumStyle(
"중수도시설 현황",
"sample_rswtSttn.xlsx",
sheetArray
);
} else {
alert(t('excelDownErrMsg'));
}
isDownloadTriggered.current = false;
}, [rswtSttn.excelList]);
const excelClick = useCallback(() => {
if (!isLaeSeCdReady) {
return;
}
isDownloadTriggered.current = true;
rswtSttnSearch(true, 1, rswtSttnResCount, appliedSearch.conValue, appliedSearch.fcltNm, code as unknown as Record<string, SelectDataType[]>);
}, [rswtSttnSearch, rswtSttnResCount, code, appliedSearch.conValue, appliedSearch.fcltNm, isLaeSeCdReady]);
alert(t("excelDownErrMsg"));
}, [rswtSttnSearch, rswtSttnResCount, code, appliedSearch, isLaeSeCdReady, alert, t]);
useEffect(() => {
if (!isLaeSeCdReady) {
return;
}
if (skipNextSearchRef.current) {
skipNextSearchRef.current = false;
return;
}
if (searchTrigger === 0) {
if (!isLaeSeCdReady || !appliedSearch) {
return;
}
rswtSttnSearch(false, pageNation, rswtSttnSize, appliedSearch.conValue, appliedSearch.fcltNm, code as unknown as Record<string, SelectDataType[]>);
isResetPage(false)
}, [pageNation, searchTrigger, rswtSttnSearch, code, appliedSearch.conValue, appliedSearch.fcltNm, isLaeSeCdReady]);
}, [pageNation, rswtSttnSearch, code, appliedSearch, isLaeSeCdReady]);
const handleSearch = useCallback(() => {
if (!isLaeSeCdReady) {
@@ -258,7 +245,6 @@ export default function RswtSttn() {
setAppliedSearch(nextSearch);
isResetPage(true);
setPageNation(1);
setSearchTrigger((prev) => prev + 1);
}, [fcltNm, getFixedConValue, isLaeSeCdReady]);
return (
@@ -14,7 +14,7 @@ export const headMakeprfmnc = (
.map((head: TableUpperProps) =>
!head.upSequnce ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
className={`border border-border px-2 py-1 `}
rowSpan={2}
key={head.id}
style={{ width: head.widthPercent ? `${head.widthPercent}%` : undefined }}
@@ -23,7 +23,7 @@ export const headMakeprfmnc = (
</TableHead>
) : head.upSequnce === 1 ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
className={`border border-border px-2 py-1 `}
key={head.id}
rowSpan={1}
colSpan={
@@ -43,7 +43,7 @@ export const headMakeprfmnc = (
.map((head: TableUpperProps) =>
makeHeadNm?.find((ch) => ch.headNm === head.upName) ? (
<TableHead
className={`border border-gray-600 px-2 py-1 `}
className={`border border-border px-2 py-1 `}
key={head.id}
style={{ width: head.widthPercent ? `${head.widthPercent}%` : undefined }}
>
@@ -250,7 +250,7 @@ export default function Page() {
<SearchDiv>
<SearchFormLeft>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-gray-600">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-label">
{"지도점검년도"}
</Label>
<SelectBox
@@ -265,7 +265,7 @@ export default function Page() {
/>
</div>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-gray-600 ">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-label ">
{"시설구분"}
</Label>
<SelectBox
@@ -281,7 +281,7 @@ export default function Page() {
/>
</div>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-gray-600 ">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-label ">
{"시설명"}
</Label>
<SearchInput
@@ -378,7 +378,7 @@ export default function Page() {
readonly={mdfcnAuthrtYn === 'N'}
/>
)}
<span className="text-2xl font-bold text-gray-500">
<span className="text-2xl font-bold text-muted-foreground">
☞ 연도별 점검일 최종 데이터를 기준으로 통계 작성합니다.
</span>
</ListDiv>
@@ -240,7 +240,7 @@ export default function PrfmncPrfmncReg() {
<SearchDiv>
<SearchFormLeft>
<div className="col-span-3 flex flex-row space-x-2">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-gray-600 ">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-label ">
{"실적등록년도"}
</Label>
<SelectBox
@@ -255,7 +255,7 @@ export default function PrfmncPrfmncReg() {
/>
</div>
<div className="col-span-3 flex flex-row space-x-2">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-gray-600">
<Label className="w-fit shrink-0 whitespace-nowrap self-center text-xl text-label">
{"시설명"}
</Label>
<SearchInput
@@ -301,7 +301,7 @@ export default function Page() {
<SearchDiv>
<SearchFormLeft>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-28 mt-2 text-xl text-gray-600">
<Label className="mt-2 w-28 text-xl text-label">
{"시도"}
</Label>
<SelectBox
@@ -318,7 +318,7 @@ export default function Page() {
/>
</div>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-28 mt-2 text-xl text-gray-600">
<Label className="mt-2 w-28 text-xl text-label">
{"시군구"}
</Label>
<SelectBox
@@ -337,7 +337,7 @@ export default function Page() {
/>
</div>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-48 mt-2 text-xl text-gray-600">
<Label className="mt-2 w-48 text-xl text-label">
{"지도점검년도"}
</Label>
<SelectBox
@@ -352,7 +352,7 @@ export default function Page() {
/>
</div>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-28 mt-2 text-xl text-gray-600">
<Label className="mt-2 w-28 text-xl text-label">
{"시설구분"}
</Label>
<SelectBox
@@ -368,7 +368,7 @@ export default function Page() {
/>
</div>
<div className="col-span-2 flex flex-row space-x-2">
<Label className="w-28 mt-2 text-xl text-gray-600">
<Label className="mt-2 w-28 text-xl text-label">
{"시설명"}
</Label>
<SearchInput
@@ -626,7 +626,7 @@ export default function PbnstPrfmncSttn() {
{/* <div className="flex flex-row items-center"> */}
<div className="flex flex-row items-center gap-x-4 flex-nowrap">
{/* <Label className="w-full text-xl text-gray-600"> */}
<Label className="flex-none whitespace-nowrap text-xl text-gray-600">
<Label className="flex-none whitespace-nowrap text-xl text-label">
하수 재이용년도</Label>
<SelectBox
// className="w-full h-full text-2xl mx-4"
+1 -1
View File
@@ -11,7 +11,7 @@ import {
ruseSeCd,
yn,
} from "./basicCode";
export const btnClass = "p-4 m-2 text-white rounded-sm text-lg font-medium ";
export const btnClass = "p-4 m-2 rounded-sm text-lg font-medium text-primary-foreground ";
const laeSecd = "41";
export const lwCds: Record<string, SelectDataType[]> = {};
@@ -1,10 +1,10 @@
import type { TableUpperProps } from "@/app/store/common/type/header";
export const htdTableHeadList: TableUpperProps[] = [
{ id: "cityText", title: "시도" },
{ id: "sggText", title: "시군구" },
{ id: "bdstNm", title: "시설명" },
{ id: "daddr", title: "위치" },
{ id: "frstArchPrmsnDt", title: "준공년도" },
{ id: "archArea", title: "건축면적(㎡)" },
{ id: "cityText", title: "시도", widthPercent: 12 },
{ id: "sggText", title: "시군구", widthPercent: 10 },
{ id: "bdstNm", title: "시설명", widthPercent: 20 },
{ id: "daddr", title: "위치", widthPercent: 30 },
{ id: "frstArchPrmsnDt", title: "준공년도", widthPercent: 13 },
{ id: "archArea", title: "건축면적(㎡)", widthPercent: 15 },
];
@@ -3,14 +3,14 @@ import type { TableUpperProps } from "@/app/store/common/type/header";
import type { chHeadType } from "@/app/store/prfmncReg/chkgdnReg/rainChkgdn/headList";
export const pubFacHeadListExport: TableUpperProps[] = [
{ id: "sido", title: "시도" },
{ id: "gugun", title: "시군구" },
{ id: "bscFctNm", title: "시설명" },
{ id: "addr", title: "위치" },
{ id: "efflWqltStndrdNm", title: "지역구분" },
{ id: "fctCpc", title: "시설용량(m³/일)" },
{ id: "ruse", title: "재이용여부" },
{ id: "rswtrYn", title: "등록여부" },
{ id: "sido", title: "시도", widthPercent: 8 },
{ id: "gugun", title: "시군구", widthPercent: 8 },
{ id: "bscFctNm", title: "시설명", widthPercent: 18 },
{ id: "addr", title: "위치", widthPercent: 24 },
{ id: "efflWqltStndrdNm", title: "지역구분", widthPercent: 15 },
{ id: "fctCpc", title: "시설용량(m³/일)", widthPercent: 12 },
{ id: "ruse", title: "재이용\n여부", widthPercent: 8 },
{ id: "rswtrYn", title: "등록\n여부", widthPercent: 6 },
];
export const pbnstMngUpHeadListExport: TableUpperProps[] = [
@@ -69,15 +69,15 @@ export type chgBuilding = {
export type customRainBdst = z.infer<typeof rainZod>;
export const upHeadList: TableUpperProps[] = [
{ id: "cityText", title: "시도" },
{ id: "sggText", title: "시군구" },
{ id: "bdstNm", title: "시설명" },
{ id: "daddr", title: "위치" },
{ id: "bdsgUsgText", title: "건축물용도" },
{ id: "frstArchPrmsnDt", title: "최초건축허가일" },
{ id: "archArea", title: "건축면적(㎡)" },
{ id: "lawTrgtYn", title: "법적의무대상여부" },
{ id: "bdstChgYn", title: "건축물변경여부" },
{ id: "cityText", title: "시도", widthPercent: 10 },
{ id: "sggText", title: "시군구", widthPercent: 8 },
{ id: "bdstNm", title: "시설명", widthPercent: 15 },
{ id: "daddr", title: "위치", widthPercent: 22 },
{ id: "bdsgUsgText", title: "건축물용도", widthPercent: 12 },
{ id: "frstArchPrmsnDt", title: "최초\n건축허가일", widthPercent: 9 },
{ id: "archArea", title: "건축면적(㎡)", widthPercent: 9 },
{ id: "lawTrgtYn", title: "법적의무대상여부", widthPercent: 8 },
{ id: "bdstChgYn", title: "건축물변경여부", widthPercent: 7 },
];
const rainRes: customRainBdst[] = [];
@@ -1,5 +1,5 @@
import { deleteFectch, getFetchWithCount, postFectch, putFectch } from "@/components/lib/api";
import { upHeadList, type chgBuilding } from "../rainReg";
import { type chgBuilding } from "../rainReg";
import { DEFAULT_LIST_SIZE } from "@/src/shared/config";
import type { TableUpperProps } from "@/app/store/common/type/header";
@@ -57,6 +57,19 @@ export type customRswtBdst = z.infer<typeof rswtZod>;
const rswtRes: customRswtBdst[] = [];
export const rswtUpHeadList: TableUpperProps[] = [
{ id: "cityText", title: "시도", widthPercent: 8 },
{ id: "sggText", title: "시군구", widthPercent: 7 },
{ id: "bdstNm", title: "건축물명", widthPercent: 14 },
{ id: "daddr", title: "위치", widthPercent: 20 },
{ id: "bdstUsgText", title: "건축물용도", widthPercent: 11 },
{ id: "frstArchPrmsnDt", title: "최초\n건축허가일", widthPercent: 9 },
{ id: "archArea", title: "건축면적(㎡)", widthPercent: 8 },
{ id: "lawTrgtYn", title: "법적의무대상여부", widthPercent: 8 },
{ id: "chBuildingYn", title: "증축/개축/재축여부", widthPercent: 8 },
{ id: "instlCmptnDt", title: "설치완료일시", widthPercent: 7 },
];
export type rswtFacState = {
rswt: {
upHeadList: TableUpperProps[];
@@ -83,7 +96,7 @@ export type rswtFacType = rswtFacState & rswtFacSActions;
export const rswtFacStateExport: rswtFacState = {
rswt: {
upHeadList: upHeadList,
upHeadList: rswtUpHeadList,
rswtRes: rswtRes,
rswtResCount: 1,
},
@@ -1,5 +1,5 @@
import type { CommonTableProps } from "@/app/store/common/type/header";
import { fetchType, getFetchWithCount } from "@/components/lib/api";
import { getFetchWithCount } from "@/components/lib/api";
import type { SelectDataType } from "@common/business_components/ui";
import type { z } from "zod";
import type { customHtdflBdst } from "../../fcltReg/htdflReg";
@@ -26,10 +26,10 @@ export type htdflSttnState = {
type htdflSttnActions = {
initHtdfl: (isExcel: boolean, page: number, total: number, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
sggCode: SelectDataType[]) => Promise<string[][] | void>;
htdflSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => void;
sggCode: SelectDataType[]) => Promise<string[][] | void>;
htdflChSttnHead: (
headList: z.infer<typeof sttnHeadListType>,
) => void;
@@ -63,36 +63,51 @@ const initFetch = async (page: number, total: number, con: string, txt: string)
export const htdflSttnActionsExport: (set: any) => htdflSttnActions = (
set: any
) => {
const fetchHtdflSttn = async (
isExcel: boolean,
page: number,
total: number,
con: string,
txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]
): Promise<string[][] | void> => {
const htdflSttnRes = await initFetch(page, total, con, txt);
if (isExcel) {
const htdflExcel = excelHtdflSttnParsing(htdflSttnRes, sidoCode, sggCode);
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
excelList: htdflExcel,
htdflSttnResCount: htdflSttnRes.count,
},
};
});
return htdflExcel;
}
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
htdflSttnRes: htdflSttnRes.data,
htdflSttnResCount: htdflSttnRes.count,
isInit: false,
},
};
});
return;
};
return {
initHtdfl: async (isExcel: boolean, page: number, total: number, con: string, txt: string,
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
const htdflSttnRes = await initFetch(page, total, con, txt);
if (isExcel) {
const htdflExcel = excelHtdflSttnParsing(htdflSttnRes, sidoCode, sggCode);
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
excelList: htdflExcel,
},
};
});
} else {
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
htdflSttnRes: htdflSttnRes.data,
htdflSttnResCount: htdflSttnRes.count,
isInit: false,
},
};
});
}
return await fetchHtdflSttn(isExcel, page, total, con, txt, sidoCode, sggCode);
} catch (error) {
console.log(error);
}
@@ -101,38 +116,7 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = (
sidoCode: SelectDataType[],
sggCode: SelectDataType[]) => {
try {
const htdflSttnRes = await getFetchWithCount(
fetchType.WR,
`/drain/facilityList` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/20") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const htdflExcel = excelHtdflSttnParsing(htdflSttnRes, sidoCode, sggCode);
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
excelList: htdflExcel,
},
};
});
} else
set((state: htdflSttnState) => {
return {
...state,
htdflSttn: {
...state.htdflSttn,
htdflSttnRes: htdflSttnRes.data,
htdflSttnResCount: htdflSttnRes.count,
isInit: false,
},
};
});
return await fetchHtdflSttn(isExcel, page, total, con, txt, sidoCode, sggCode);
} catch (erTxt) {
console.log("error", erTxt);
}
@@ -154,4 +138,4 @@ export const htdflSttnActionsExport: (set: any) => htdflSttnActions = (
}
}
}
@@ -102,8 +102,8 @@ export type rainSttnState = {
};
};
type rainSttnActions = {
rainSttnInit: (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record<string, SelectDataType[]> ) => void
rainSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record<string, SelectDataType[]>) => void;
rainSttnInit: (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record<string, SelectDataType[]> ) => Promise<string[][] | void>
rainSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record<string, SelectDataType[]>) => Promise<string[][] | void>;
rainChSttnHead: (
headList: z.infer<typeof sttnHeadListType>,
) => void;
@@ -129,81 +129,63 @@ export const rainSttnStateExport: rainSttnState = {
export const rainSttnActionsExport: (set: any) => rainSttnActions = (
set: any
) => {
const fetchRainSttn = async (
isExcel: boolean,
page: number,
total: number,
con: string,
txt: string,
code: Record<string, SelectDataType[]>
): Promise<string[][] | void> => {
const rainSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/rainyInfoList` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/15") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const rainExcel = excelRainSttnParsing(rainSttnRes, code);
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
excelList: rainExcel,
rainSttnResCount: rainSttnRes.count,
},
};
});
return rainExcel;
}
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
rainSttnRes: rainSttnRes.data,
rainSttnResCount: rainSttnRes.count,
isInit: false,
},
};
});
return;
};
return {
rainSttnInit: async (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record<string, SelectDataType[]>) => {
try {
const rainSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/rainyInfoList` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/15") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const rainExcel = excelRainSttnParsing(rainSttnRes, code);
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
excelList: rainExcel,
rainSttnResCount: rainSttnRes.count,
},
};
});
} else {
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
rainSttnRes: rainSttnRes.data,
rainSttnResCount: rainSttnRes.count,
isInit: false,
},
};
});
}
return await fetchRainSttn(isExcel, page, total, con, txt, code);
} catch (e) {
console.log(e)
}
},
rainSttnSearch: async (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record<string, SelectDataType[]>) => {
try {
const rainSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/rainyInfoList` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/15") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const rainExcel = excelRainSttnParsing(rainSttnRes,code);
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
excelList: rainExcel,
rainSttnResCount: rainSttnRes.count,
},
};
});
} else
set((state: rainSttnState) => {
return {
...state,
rainSttn: {
...state.rainSttn,
rainSttnRes: rainSttnRes.data,
rainSttnResCount: rainSttnRes.count,
isInit: false,
},
};
});
return await fetchRainSttn(isExcel, page, total, con, txt, code);
} catch (erTxt) {
console.log("error", erTxt);
}
@@ -30,8 +30,8 @@ export type rswtSttnState = {
};
type rswtSttnActions = {
rswtSttnInit: (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record<string,SelectDataType[]>) => void;
rswtSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record<string,SelectDataType[]>) => void;
rswtSttnInit: (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record<string,SelectDataType[]>) => Promise<string[][] | void>;
rswtSttnSearch: (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record<string,SelectDataType[]>) => Promise<string[][] | void>;
rswtChSttnHead: (
headList: z.infer<typeof sttnHeadListType>,
) => void;
@@ -55,79 +55,62 @@ export const rswtSttnStateExport: rswtSttnState = {
export const rswtSttnActionsExport: (set: any) => rswtSttnActions = (
set: any
) => {
const fetchRswtSttn = async (
isExcel: boolean,
page: number,
total: number,
con: string,
txt: string,
code: Record<string, SelectDataType[]>
): Promise<string[][] | void> => {
const rswtSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/waterreuseFc` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/10") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, code);
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
excelList: rswtExcel,
rswtSttnResCount: rswtSttnRes.count,
},
};
});
return rswtExcel;
}
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
rswtSttnRes: rswtSttnRes.data,
rswtSttnResCount: rswtSttnRes.count,
isInit: false,
},
};
});
return;
};
return {
rswtSttnInit: async (isExcel: boolean, page: number, total: number, con: string, txt: string, code: Record<string,SelectDataType[]>) => {
try {
const rswtSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/waterreuseFc` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/10") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, code);
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
excelList: rswtExcel,
},
};
});
}
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
rswtSttnRes: rswtSttnRes.data,
rswtSttnResCount: rswtSttnRes.count,
isInit: false,
},
};
});
return await fetchRswtSttn(isExcel, page, total, con, txt, code);
} catch (e) {
console.log(e)
}
},
rswtSttnSearch: async (isExcel: boolean, page: number, total: number, con: string, txt: string,code: Record<string,SelectDataType[]>) => {
try {
const rswtSttnRes = await getFetchWithCount(
fetchType.WR,
`/reuseFc/waterreuseFc` +
(page ? `/${page}` : "/1") +
(total ? `/${total}` : "/10") +
(con ? `/${con}` : "/0") +
(txt ? `/${txt}` : "")
);
if (isExcel) {
const rswtExcel = excelRSwtSttnParsing(rswtSttnRes, code);
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
excelList: rswtExcel,
},
};
});
} else
set((state: rswtSttnState) => {
return {
...state,
rswtSttn: {
...state.rswtSttn,
rswtSttnRes: rswtSttnRes.data,
rswtSttnResCount: rswtSttnRes.count,
isInit: false,
},
};
});
return await fetchRswtSttn(isExcel, page, total, con, txt, code);
} catch (erTxt) {
console.log("error", erTxt);
}
+1 -1
View File
@@ -1,4 +1,4 @@
export const formTableName = 'text-xl my-4 font-bold'
export const commonButonSize = "sm"
export const formH1Class = "bg-[#eaf3fb] text-xl text-center border-2 p-2 mt-4 font-medium text-gray-500"
export const formH1Class = "form-section-title"
export const formH2Class = "text-xl my-4 underline font-bold"
+12 -12
View File
@@ -252,7 +252,7 @@ export const chRowspanTable = (
"splyUswtrUtztnQnt",
"ruseFcltUtztnQnt",
].includes(head.id)
? "underline text-blue-600 cursor-pointer"
? "cursor-pointer underline text-primary"
: ""
}
>
@@ -270,7 +270,7 @@ export const chRowspanTable = (
<TableRow>
<TableCell
colSpan={headList.length}
className="h-24 text-center text-gray-500"
className="h-24 text-center text-muted-foreground"
>
조회된 결과가 없습니다.
</TableCell>
@@ -361,9 +361,9 @@ export const InputTableBody = (
const isTotal = data["구분"] === 0;
const bgClass = isTotal
? "bg-[#d5e1eb] font-bold"
? "bg-accent text-accent-foreground font-bold"
: isSubTotal
? "bg-[#e6eef5] font-semibold"
? "bg-secondary text-secondary-foreground font-semibold"
: "";
return (
@@ -381,7 +381,7 @@ export const InputTableBody = (
<TableCell
key={head.id + headIndex}
colSpan={2}
className="font-bold text-center bg-[#d5e1eb]"
className="bg-accent text-accent-foreground font-bold text-center"
>
총합계
</TableCell>
@@ -397,7 +397,7 @@ export const InputTableBody = (
return (
<TableCell
key={head.id + headIndex}
className="bg-[#d5e1eb] font-bold text-right"
className="bg-accent text-accent-foreground font-bold text-right"
>
{Number(data[head.id])
? formatCommaNumber(data[head.id as keyof any])
@@ -482,7 +482,7 @@ export const InputTableBody = (
<TableRow>
<TableCell
colSpan={headList.length}
className="h-24 text-center text-gray-500"
className="h-24 text-center text-muted-foreground"
>
조회된 결과가 없습니다.
</TableCell>
@@ -519,9 +519,9 @@ export const pbnstTableBody = (
const isTotal = data["구분"] === 0;
const bgClass = isTotal
? "bg-[#d5e1eb] font-bold"
? "bg-accent text-accent-foreground font-bold"
: isSubTotal
? "bg-[#e6eef5] font-semibold"
? "bg-secondary text-secondary-foreground font-semibold"
: "";
return (
@@ -552,7 +552,7 @@ export const pbnstTableBody = (
<TableCell
key={head.id + headIndex}
colSpan={2}
className="font-bold text-center bg-[#d5e1eb]"
className="bg-accent text-accent-foreground font-bold text-center"
>
총합계
</TableCell>
@@ -571,7 +571,7 @@ export const pbnstTableBody = (
return (
<TableCell
key={head.id + headIndex}
className="bg-[#d5e1eb] font-bold text-right"
className="bg-accent text-accent-foreground font-bold text-right"
>
{Number(data[head.id])
? formatCommaNumber(data[head.id as keyof any])
@@ -645,7 +645,7 @@ export const pbnstTableBody = (
<TableRow>
<TableCell
colSpan={headList.length}
className="h-24 text-center text-gray-500"
className="h-24 text-center text-muted-foreground"
>
조회된 결과가 없습니다.
</TableCell>
+3 -3
View File
@@ -291,16 +291,16 @@ export const showConfirmToast = (message: string) => {
toast.custom(
(t) => (
<div
className={`w-[500px] min-h-[140px] bg-white shadow-lg rounded-xl p-6 border border-gray-200
className={`min-h-[140px] w-[500px] rounded-xl border border-border bg-card p-6 text-card-foreground shadow-lg
${t.visible ? "animate-enter" : "animate-leave"}`}
>
<div className="text-3xl font-extrabold text-red-600 bg-yellow-100 px-4 py-2 rounded-md shadow-md">
<div className="rounded-md bg-accent px-4 py-2 text-3xl font-extrabold text-destructive shadow-md">
{message}
</div>{" "}
<div className="flex justify-end gap-2">
<Button
size={"sm"}
className="px-4 py-1.5 rounded bg-gray-200 text-sm hover:bg-gray-300"
className="rounded bg-secondary px-4 py-1.5 text-sm text-secondary-foreground hover:bg-accent"
onClick={() => toast.dismiss(t.id)}
>
확인완료
@@ -1,4 +1,7 @@
"use client";
/**
* 표준공사비
*/
import { useWrStore } from "@/app/store";
import { usageProcData } from "@/app/store/matDmd/coMatRvw/headList";
import type {
@@ -76,7 +79,7 @@ export default function ConCostForm({
const activeForm = form || localForm;
const isSim = type === "simulation";
const readOnlyInputClass = "bg-slate-50 text-gray-700";
const readOnlyInputClass = "bg-secondary text-secondary-foreground";
const {
constCostRes, // 표준사업비
rateFeeRes, // 부대경비요율
@@ -59,14 +59,14 @@ export default function BdstAdd({ form, readonly }: { form: any; readonly?: bool
<>
<h1 className={formH1Class}>증축, 개축, 재축</h1>
{!readonly && (
<div className="flex justify-end gap-2 mt-4">
<div className="rainreg_actions">
<Button type="button" className="" size={"sm"} onClick={plusHist}>
이력추가
</Button>
<Button
type="button"
className="!bg-red-500 text-white"
variant="destructive"
size={"sm"}
onClick={removeSelected}
>
@@ -151,7 +151,7 @@ export default function BdstAdd({ form, readonly }: { form: any; readonly?: bool
</div>
</div>
))}
<div ref={bottomRef} className="border-b border-gray-300 my-4"> </div>
<div ref={bottomRef} className="rainreg_divider"> </div>
</>
)
}
@@ -266,12 +266,12 @@ export default function HtdflRegForm({
}, [isPowerPlant, form]);
return (
<div className="!mx-[1.6rem] !p-0r">
<div className="!mx-[1.6rem] !p-0">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
{/* <div className="flex justify-between items-center mx-3"> */}
<div>
<h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1">
<h1 className="mt-3 ml-1 text-2xl font-bold text-foreground">
{readonly && `(시설명 : ${htdflForm?.bdstNm})`}
</h1>
<div className="grid grid-cols-12 flex items-center card-header">
@@ -289,7 +289,7 @@ export default function HtdflRegForm({
</Button>
<Button
type="button"
className="!bg-red-500 text-white"
variant="destructive"
size={"sm"}
onClick={onDelete}
>
@@ -619,7 +619,7 @@ export default function HtdflRegForm({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -649,7 +649,7 @@ export default function HtdflRegForm({
readOnly={readonly}
maxLength={6}
/>{" "}
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -704,7 +704,7 @@ export default function HtdflRegForm({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -739,7 +739,7 @@ export default function HtdflRegForm({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이상
</span>
</div>
@@ -768,7 +768,7 @@ export default function HtdflRegForm({
readOnly={readonly}
maxLength={numSize}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이상
</span>
</div>
@@ -800,7 +800,7 @@ export default function HtdflRegForm({
readOnly={readonly}
maxLength={numSize}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -830,7 +830,7 @@ export default function HtdflRegForm({
readOnly={readonly}
maxLength={7}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -886,7 +886,7 @@ export default function HtdflRegForm({
readOnly={readonly}
maxLength={numSize}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-placeholder">
이하
</span>
</div>
@@ -0,0 +1,27 @@
@tailwind components;
@layer components {
.pbnstbuse_sum_input {
@apply w-32 rounded-md border border-input pr-8;
}
.pbnstbuse_demand_row {
@apply mt-3 grid grid-cols-12 gap-4 border-b border-border pb-3;
}
.pbnstbuse_modal_body {
@apply mx-auto w-full rounded-lg border border-border bg-background p-6 shadow-md;
}
.pbnstbuse_empty {
@apply !mx-[1.6rem] !p-0 flex h-64 flex-col items-center justify-center rounded-md border border-border text-label;
}
.pbnstbuse_empty_title {
@apply text-lg text-foreground;
}
.pbnstbuse_empty_desc {
@apply mb-4 text-sm text-label;
}
}
@@ -1,4 +1,5 @@
"use client";
import "./bugRegForm.css";
import { useWrStore } from "@/app/store";
import {
@@ -325,7 +326,7 @@ export function PbnstBuseForm({
return (
<>
{pbnstBiz && pbnstBiz?.length > 0 ? (
<div className=" !mx-[1.6rem] !p-0r">
<div className=" !mx-[1.6rem] !p-0">
{/* 차수별 등록 현황 폼 */}
<div className="justify-between">
<Form {...form}>
@@ -465,7 +466,7 @@ export function PbnstBuseForm({
type="text"
value={formatCommaNumber(sumCpct)}
readOnly={true}
className="w-32 border-gray-300 rounded pr-8 "
className="pbnstbuse_sum_input"
/>
{ppiYn === "Y" ? (
<>
@@ -481,7 +482,8 @@ export function PbnstBuseForm({
<Button
type="button"
size={commonButonSize}
className="!text-xl !bg-red-500 !text-white ml-1"
variant="destructive"
className="!text-xl ml-1"
onClick={removeSelected}
disabled={readonly}
>
@@ -563,7 +565,7 @@ export function PbnstBuseForm({
{fcDemands.map((field, index) => (
<div
key={field.id} // useFieldArray의 고유 id를 key로 사용
className="grid grid-cols-12 gap-4 mt-3 border-b border-gray-400 pb-3"
className="pbnstbuse_demand_row"
>
<div key={index + "keySon1"} className="col-span-4">
<FormField
@@ -787,7 +789,7 @@ export function PbnstBuseForm({
data: data as DemandCompType,
});
}}
bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"}
bodyClassNm={"pbnstbuse_modal_body"}
openNetwork={true}
></SdmInsertForm>
}
@@ -795,9 +797,9 @@ export function PbnstBuseForm({
></UiModal>
</div>
) : (
<div className="!mx-[1.6rem] !p-0r flex flex-col items-center justify-center h-64 text-gray-500 border rounded-md">
<p className="text-lg">등록된 차수별 정보가 없습니다.</p>
<p className="text-sm mb-4">
<div className="pbnstbuse_empty">
<p className="pbnstbuse_empty_title">등록된 차수별 정보가 없습니다.</p>
<p className="pbnstbuse_empty_desc">
아래 버튼을 눌러 신규 차수 정보를 등록해주세요.
</p>
<Button
@@ -0,0 +1,19 @@
@tailwind components;
@layer components {
.busewq_input {
@apply w-full rounded-md border border-input py-2 pr-16 text-right;
}
.busewq_suffix {
@apply pointer-events-none absolute inset-y-0 right-3 flex items-center text-xl text-label;
}
.busewq_ph_input {
@apply w-28 !text-xl;
}
.busewq_ph_range {
@apply text-xl text-foreground;
}
}
@@ -1,3 +1,5 @@
import "./buseWaterQulity.css";
import type { PbnstRegArrrayType } from "@/app/store/ruseFcltMng/fcltReg/pbnstReg/type";
import { formH1Class } from "@/components/lib/class/comClass";
import { FormField, FormUi, SelectBox } from "@common/business_components/ui";
@@ -119,7 +121,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -133,7 +135,7 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이하
</span>
</div>
@@ -156,7 +158,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -171,7 +173,7 @@ export function BuseWaterQulity({
maxLength={6}
/>
{/* TODO: 총대장균군수 확인 필요*/}
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이하
</span>
</div>
@@ -191,7 +193,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -205,7 +207,7 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이상
</span>
</div>
@@ -225,7 +227,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -239,7 +241,7 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이상
</span>
</div>
@@ -298,7 +300,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -312,7 +314,7 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이하
</span>
</div>
@@ -332,7 +334,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -346,7 +348,7 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이하
</span>
</div>
@@ -367,7 +369,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -381,7 +383,7 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={6}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이하
</span>
</div>
@@ -401,7 +403,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -415,7 +417,7 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={7}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이하
</span>
</div>
@@ -436,7 +438,7 @@ export function BuseWaterQulity({
<div className="relative flex-1 min-w-0">
<Input
type="text"
className="w-full pr-16 border py-2 text-right rounded-md"
className="busewq_input"
placeholder=""
onChange={(e) => {
const inputValue = e.target.value.replace(/[^0-9.]/g, ""); // 숫자만 저장
@@ -450,7 +452,7 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={7}
/>
<span className="text-xl absolute inset-y-0 right-3 flex items-center text-gray-500 pointer-events-none">
<span className="busewq_suffix">
이하
</span>
</div>
@@ -463,7 +465,7 @@ export function BuseWaterQulity({
<Label className="text-xl">수소이온농도(pH)</Label>
<div className="flex flex-row items-center gap-2">
<Input
className="!text-xl w-28"
className="busewq_ph_input"
placeholder=""
type="text"
onChange={(e) =>
@@ -474,9 +476,9 @@ export function BuseWaterQulity({
readOnly={readonly}
maxLength={3}
/>
<span className="text-xl">~</span>
<span className="busewq_ph_range">~</span>
<Input
className="!text-xl w-28"
className="busewq_ph_input"
placeholder=""
type="text"
onChange={(e) => {
@@ -0,0 +1,7 @@
@tailwind components;
@layer components {
.pbnstmng_file_link {
@apply block cursor-pointer text-2xl text-primary hover:underline;
}
}
@@ -1,4 +1,5 @@
"use client";
import "./mngRegForm.css";
import { useWrStore } from "@/app/store";
import {
@@ -265,7 +266,7 @@ export function PbnstMngForm({
return (
<div className=" !mx-[1.6rem] !p-0r">
<div className=" !mx-[1.6rem] !p-0">
<div>
<Form {...form}>
{/* <form onSubmit={form.handleSubmit()}> */}
@@ -332,13 +333,14 @@ export function PbnstMngForm({
>
추가등록
</Button>
<Button
type="button"
size={commonButonSize}
className="!text-xl !bg-red-500 !text-white ml-1"
onClick={removeSelected}
disabled={readonly}
>
<Button
type="button"
size={commonButonSize}
variant="destructive"
className="!text-xl ml-1"
onClick={removeSelected}
disabled={readonly}
>
삭제
</Button>
</div>
@@ -442,7 +444,7 @@ export function PbnstMngForm({
{relationfiles?.map((item, index) => (
<span
key={index + "plan"}
className="text-2xl block cursor-pointer text-blue-600 hover:underline"
className="pbnstmng_file_link"
onClick={() => fileDownLoadName(item.atflCd, item.file.name)}
>
{item.file.name}
@@ -481,7 +483,7 @@ export function PbnstMngForm({
{planFiles?.map((item, index) => (
<span
key={index + "plan"}
className="text-2xl block cursor-pointer text-blue-600 hover:underline"
className="pbnstmng_file_link"
onClick={() => fileDownLoadName(item.atflCd, item.file.name)}
>
{item.file.name}
@@ -0,0 +1,23 @@
@tailwind components;
@layer components {
.rainreg_header_note {
@apply mt-3 ml-1 text-2xl font-bold text-foreground;
}
.rainreg_header_title {
@apply col-span-10 text-2xl font-medium text-label;
}
.rainreg_section_note {
@apply col-span-10 mt-4 pl-3 text-xl text-foreground;
}
.rainreg_actions {
@apply mt-4 flex justify-end gap-2;
}
.rainreg_divider {
@apply my-4 border-b border-border;
}
}
@@ -1,5 +1,7 @@
"use client";
import "./rainRegForm.css";
import { useWrStore } from "@/app/store";
import {
rainZod,
@@ -180,19 +182,19 @@ export default function RainRegForm({
}, [rainForm]);
return (
<div className="!mx-[1.6rem] !p-0r">
<div className="!mx-[1.6rem] !p-0">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
<div>
<h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1">
<h1 className="rainreg_header_note">
{readonly && `(시설명 : ${rainForm?.bdstNm})`}
</h1>
<div className="grid grid-cols-12 flex items-center card-header">
<h1 className="text-2xl font-medium text-label col-span-10">
<h1 className="rainreg_header_title">
{isModal ? "건축물 정보" : "빗물이용시설 정보"}
</h1>
{!readonly && (
<div className="flex justify-end gap-2 mt-4">
<div className="rainreg_actions">
<Button
type="submit"
className="col-start-12 col-span-1"
@@ -202,7 +204,7 @@ export default function RainRegForm({
</Button>
<Button
type="button"
className="!bg-red-500 text-white"
variant="destructive"
size={"sm"}
onClick={onDelete}
>
@@ -215,7 +217,7 @@ export default function RainRegForm({
{/* <ScrollArea className={divStyle}> */}
{isModal && rainForm != undefined ? <BdstReg form={form} /> : <></>}
{isModal ? (
<h1 className="pl-3 text-xl col-span-10 mt-4">
<h1 className="rainreg_section_note">
빗물이용시설 정보{" "}
</h1>
) : (
@@ -455,7 +457,7 @@ export default function RainRegForm({
// <div className="flex items-center gap-2">
<FormUi label="처리공정">
<Input
className={" h-full !text-xl col-span-4"}
className={selectClass}
placeholder="처리공정 입력"
type="text"
value={field.value ?? ""}
@@ -174,12 +174,12 @@ export default function RswtrRegForm({
return (
<div className="!mx-[1.6rem] !p-0r">
<div className="!mx-[1.6rem] !p-0">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
{/* <div className="flex justify-between items-center mx-3"> */}
<div>
<h1 className="text-2xl font-bold text-gray-900 mt-3 ml-1">
<h1 className="mt-3 ml-1 text-2xl font-bold text-foreground">
{readonly && `(시설명 : ${rswtForm?.bdstNm})`}
</h1>
<div className="grid grid-cols-12 flex items-center card-header">
@@ -197,7 +197,7 @@ export default function RswtrRegForm({
</Button>
<Button
type="button"
className="!bg-red-500 text-white"
variant="destructive"
size={"sm"}
onClick={onDelete}
>
@@ -81,7 +81,7 @@ export function HasuFacility({rtnFeature}:{rtnFeature:(feature:any)=>void } ) {
rightChildren={<></>}
leftChildren={
<div className="col-span-3 flex items-center">
<Label className="w-full mt-2 ml-4 text-xl text-gray-600">
<Label className="mt-2 ml-4 w-full text-xl text-label">
{"하수처리시설명"}
</Label>
<SearchInput
@@ -109,7 +109,7 @@ export function RuseFacility({
className={""}
selectContentClass={''}
/>
<Label className="w-full mt-2 ml-4 text-xl text-gray-600">
<Label className="mt-2 ml-4 w-full text-xl text-label">
{"하수처리시설명"}
</Label>
<SearchInput
@@ -20,7 +20,7 @@ export default function CoSttnDetailPopup({isDetail} :{isDetail:DemandCompType})
rtnInputData={async (data) => {
console.log(data)
}}
bodyClassNm={"w-full mx-auto bg-white rounded-lg shadow-md p-6"}
bodyClassNm={"w-full mx-auto bg-background rounded-lg shadow-md p-6"}
updateList={isDetail}
readOnly={true}
openNetwork={false}
@@ -28,4 +28,4 @@ export default function CoSttnDetailPopup({isDetail} :{isDetail:DemandCompType})
</div>
)
}
}
@@ -11,14 +11,14 @@ export default function WrOverLayTable({overLayData}:{overLayData:any,}){
<TableBody>
{Object.entries(overLayData).map(([key, value]) => (
<TableRow key={key}>
<TableCell className=" w-1/3 bg-slate-100 text-slate-800 font-medium text-sm align-middle border border-slate-300">
<TableCell className="w-1/3 border border-border bg-secondary text-secondary-foreground font-medium text-sm align-middle">
{" "}
{key}{" "}
</TableCell>
<TableCell
className={
"w-1/3 bg-white text-right pr-3 text-sm align-middle border border-slate-300"
"w-1/3 border border-border bg-background pr-3 text-right text-sm align-middle text-foreground"
}
>
{" "}
@@ -30,4 +30,4 @@ export default function WrOverLayTable({overLayData}:{overLayData:any,}){
</Table>
</>
)
}
}
@@ -43,16 +43,16 @@ export default function WrOverLay({
onDrag={(e, data) => setPos({ x: data.x, y: data.y })}
>
<div ref={dragRef}>
<Card className="w-[320px] p-0 shadow-md rounded-xl overflow-hidden border border-slate-300 relative">
<Card className="relative w-[320px] overflow-hidden rounded-xl border border-border bg-card p-0 text-card-foreground shadow-md">
{/* 헤더: 제목 바 + 우측 정렬 버튼 (절대배치 제거, 타이틀 중앙 정렬 유지) */}
<div className="bg-sky-600 text-white font-semibold py-2 text-xl">
<div className="bg-primary py-2 text-xl font-semibold text-primary-foreground">
<div className="grid grid-cols-[auto_1fr_auto] items-center gap-2 px-2">
{/* 좌측 스페이서: 우측 버튼과 동일한 너비를 차지하도록 동일 버튼을 투명하게 복제 */}
<div className="opacity-0 pointer-events-none">
<div className="flex gap-2">
<button
onClick={() => setPos({ x: 0, y: 0 })}
className="p-2 bg-gray-200 text-gray-700 shadow hover:bg-gray-300 hover:shadow-md transition"
className="bg-secondary p-2 text-secondary-foreground shadow transition hover:bg-accent hover:text-accent-foreground hover:shadow-md"
title="원위치"
>
↺
@@ -62,7 +62,7 @@ export default function WrOverLay({
onClick={() => setOpen(false)}
aria-label="축소"
title="축소"
className="p-2 bg-gray-200 text-gray-700 shadow hover:bg-gray-300 hover:shadow-md transition"
className="bg-secondary p-2 text-secondary-foreground shadow transition hover:bg-accent hover:text-accent-foreground hover:shadow-md"
>
–
</button>
@@ -78,7 +78,7 @@ export default function WrOverLay({
<div className="flex gap-2 justify-end">
<button
onClick={() => setPos({ x: 0, y: 0 })}
className="p-2 bg-gray-200 text-gray-700 shadow hover:bg-gray-300 hover:shadow-md transition"
className="bg-secondary p-2 text-secondary-foreground shadow transition hover:bg-accent hover:text-accent-foreground hover:shadow-md"
title="원위치"
>
↺
@@ -88,7 +88,7 @@ export default function WrOverLay({
onClick={() => setOpen(false)}
aria-label="축소"
title="축소"
className="p-2 bg-gray-200 text-gray-700 shadow hover:bg-gray-300 hover:shadow-md transition"
className="bg-secondary p-2 text-secondary-foreground shadow transition hover:bg-accent hover:text-accent-foreground hover:shadow-md"
>
–
</button>
@@ -110,7 +110,7 @@ export default function WrOverLay({
onClick={() => setOpen(true)}
aria-label="확장"
title={title || "정보 보기"}
className="w-[30px] h-[30px] bg-white font-bold shadow flex items-center justify-center border border-slate-300"
className="flex h-[30px] w-[30px] items-center justify-center border border-border bg-popover font-bold text-popover-foreground shadow"
>
{bubbleLabel}
</button>
@@ -265,7 +265,7 @@ export default function ChkgdExcel({
></Title>
</div>
<div className="flex justify-between">
<h3 className="text-2xl font-bold text-gray-900 mt-1 ml-7">
<h3 className="mt-1 ml-7 text-2xl font-bold text-foreground">
{"점검정보 입력"}
</h3>
@@ -289,7 +289,7 @@ export default function ChkgdModal({
<></>
)}
</div>
<h3 className="text-2xl font-bold text-gray-900 mt-2 ml-6">
<h3 className="mt-2 ml-6 text-2xl font-bold text-foreground">
{type === "RNB"
? `시설명 : (${obj.bdstNm})`
: `시설명 : (${obj.building.bdstNm})`}
@@ -102,7 +102,7 @@ export default function PbnPrfExcelModal({
저장
</Button>
</div>
<h3 className="text-2xl font-bold text-gray-900 my-3 ml-7">
<h3 className="my-3 ml-7 text-2xl font-bold text-foreground">
{"점검정보 입력"}
</h3>
@@ -106,7 +106,7 @@ export function ConstCostFeeTable() {
<hr className="mt-4 mb-4"/>
<div className="col-span-5 flex items-center justify-between">
<div className="flex items-center">
<Label className="mr-1 text-xl text-gray-600">기준년도</Label>
<Label className="mr-1 text-xl text-label">기준년도</Label>
<SelectBox
className="h-full w-32 text-2xl"
label=""
@@ -117,7 +117,7 @@ export function ConstCostFeeTable() {
}
/>
</div>
<span className="mr-2 text-xl text-gray-600">단위: 백만원</span>
<span className="mr-2 text-xl text-label">단위: 백만원</span>
</div>
<UiTable
headName={""}
@@ -128,7 +128,7 @@ export function ConstCostFeeTable() {
cellClick={undefined}
onPageChange={() => { }}
/>
<div className="px-3 text-lg text-gray-700 leading-relaxed">
<div className="px-3 text-lg leading-relaxed text-foreground">
시설용량 구간내 공사비는 직선보간법에 의하여 산출
</div>
</div>
@@ -104,14 +104,14 @@ export function RateFeeTableModal() {
return (
<ListDiv className="min-w-[460px] h-[50vh] overflow-auto">
<div className="sticky top-0 z-10 grid grid-cols-6 gap-4 p-4 bg-white">
<div className="sticky top-0 z-10 grid grid-cols-6 gap-4 bg-background p-4">
<h3 className="col-span-6 text-2xl font-medium text-label">
시설부대경비 요율(%)
</h3>
<hr className="col-span-6 border-gray-300" />
<hr className="col-span-6 border-border" />
<div className="col-span-5 flex items-center">
<Label className="mr-1 text-xl text-gray-600">기준년도</Label>
<Label className="mr-1 text-xl text-label">기준년도</Label>
<SelectBox
className="h-full w-32 text-2xl"
label=""
@@ -135,7 +135,7 @@ export function RateFeeTableModal() {
cellClick={undefined}
/>
</div>
<div className="col-span-6 px-3 text-lg text-gray-700 leading-relaxed">
<div className="col-span-6 px-3 text-lg leading-relaxed text-foreground">
출처 : 하수도분야 보조금 편성 및 실무요령
<br />
시설부대경비 및 감리비 요율적용시 공사비가 요율표의 중간에 있을 때는 직선보간법에 의하여 산출
@@ -185,7 +185,7 @@ export default function RuseCaseMngExcel({setIsExcelOpen}:{setIsExcelOpen: (isOp
<Title title={"물재이용 사례 등록"}></Title>
</div>
<div className="flex justify-between">
<h3 className="text-2xl font-bold text-gray-900 mt-1 ml-7">
<h3 className="mt-1 ml-7 text-2xl font-bold text-foreground">
{"물재이용 사례 파일"}
</h3>
<Button className="" type="submit" size={"sm"}>
@@ -108,7 +108,7 @@ export default function CoRegExcel({
<Title title={"잠재수요처 등록"}></Title>
</div>
<div className="flex justify-between">
<h3 className="text-2xl font-bold text-gray-900 mt-1 ml-7">
<h3 className="mt-1 ml-7 text-2xl font-bold text-foreground">
{"잠재수요처 파일"}
</h3>
<div className="flex gap-2">
@@ -177,7 +177,7 @@ export function BdstReg<T extends MoType>({
>
{" "}
</SelectBox>
<Label className="w-full text-xl text-gray-600 text-right">
<Label className="w-full text-right text-xl text-label">
시설명
</Label>
<Input
@@ -196,11 +196,11 @@ export function BdstReg<T extends MoType>({
조회
</Button>
</div>
<div className="border-t border-gray-300 my-4"></div>
<div className="my-4 border-t border-border"></div>
<div className="h-auto">
<h1 className="text-2xl font-medium text-label pl-8">
건축물 목록
<span className="!text-2xl text-base text-blue-500">
<span className="text-base !text-2xl text-primary">
(유의 사항: 신규등록하려는 건축물이 목록에 없을 경우 하단 건축물
정보에 추가하여 주시기 바랍니다.)
</span>
@@ -221,7 +221,7 @@ export function BdstReg<T extends MoType>({
></UiTable>
</div>
</ScrollArea>
<div className="border-t border-gray-300 my-4"></div>
<div className="my-4 border-t border-border"></div>
<ScrollArea className="h-[40vh]">
<div>
{moType === "RNB" ? (
@@ -105,14 +105,14 @@ export default function FcOrgwtsRegModal({
return (
<div className="flex flex-col h-[80vh]">
<div className="shrink-0 p-4 border-b z-10 bg-white">
<div className="z-10 shrink-0 border-b border-border bg-background p-4">
<div className="flex items-center">
<Title title="취수하수처리장 추가" />
<div className="flex items-center gap-2 mt-8">
<Label className="text-xl text-gray-600">시설명</Label>
<Label className="text-xl text-label">시설명</Label>
<Input
className="w-48 text-xl"
type="text"
@@ -144,7 +144,7 @@ export default function FcOrgwtsRegModal({
{/* 왼쪽 테이블 */}
<div className="w-5/12 min-w-[400px]">
<Label className="text-2xl text-gray-600 mb-2 block text-right">
<Label className="mb-2 block text-right text-2xl text-label">
공공하수처리시설 목록
</Label>
<RuseMngTable
@@ -170,7 +170,7 @@ export default function FcOrgwtsRegModal({
}
setbdstTable(unchecked ?? []);
}}
className="w-8 h-8 text-gray-500 cursor-pointer"
className="h-8 w-8 cursor-pointer text-muted-foreground"
/>
<ArrowLeft
onClick={() => {
@@ -187,13 +187,13 @@ export default function FcOrgwtsRegModal({
}
setRightData(unchecked ?? []);
}}
className="w-8 h-8 text-gray-500 cursor-pointer"
className="h-8 w-8 cursor-pointer text-muted-foreground"
/>
</div>
{/* 오른쪽 테이블 */}
<div className="w-5/12 min-w-[400px]">
<Label className="text-2xl text-gray-600 mb-2 block text-right">
<Label className="mb-2 block text-right text-2xl text-label">
취수하수처리장 목록
</Label>
<RuseMngTable
@@ -72,7 +72,7 @@ export function PbnstRegModal({
하수재이용 시설 신규등록
</h1>
<div className="border-t border-gray-300 my-4"></div>
<div className="my-4 border-t border-border"></div>
<Tabs defaultValue="mng" onValueChange={handleTabChange}>
<div className="flex justify-between items-center">
@@ -0,0 +1,19 @@
@tailwind components;
@layer components {
.wrsearchinput_field {
@apply h-[3.2rem] w-full rounded-md border border-input pl-3 !text-xl text-label focus:outline-none focus:ring-2 focus:ring-ring;
}
.wrsearchinput_list {
@apply z-10 mt-2 h-[90px] w-full overflow-auto rounded-md border border-border bg-popover shadow-lg;
}
.wrsearchinput_item {
@apply w-full cursor-pointer overflow-auto px-5 py-3 text-left !text-xl text-foreground hover:bg-accent;
}
.wrsearchinput_empty {
@apply w-full overflow-auto px-5 py-3 !text-xl text-label;
}
}
@@ -1,3 +1,5 @@
import "./searchInput.css";
import { Input } from "@common/components/ui";
import React, { useCallback, useEffect, useRef, useState } from "react";
@@ -73,18 +75,18 @@ export default function SearchInputText({
value={textValue}
onChange={handleInputChange}
/* onFocus={() => setIsOpen(true)} */
className="w-full h-[3.2rem] !text-xl pl-3 text-gray-600 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500"
className="wrsearchinput_field"
placeholder={`${label}을(를) 입력하세요`}
readOnly={readonly} // readonly 상태 적용
/>
{isOpen && (
<div className=" z-1 w-full mt-2 bg-white border border-gray-300 rounded-md shadow-lg h-90 overflow-auto">
<div className="wrsearchinput_list">
<div className="max-h-72">
{searchList && searchList.length > 0 ? (
searchList.map((item: SearchType, index: number) => (
<div
key={index}
className="!text-xl w-full text-left px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto"
className="wrsearchinput_item"
onClick={() => handleSuggestionClick(item.searchNm)}
role="button"
tabIndex={0}
@@ -99,7 +101,7 @@ export default function SearchInputText({
</div>
))
) : (
<div className="!text-xl w-full px-5 py-3 hover:bg-gray-100 cursor-pointer overflow-auto">
<div className="wrsearchinput_empty">
검색 결과가 없습니다.
</div>
)}
@@ -43,7 +43,7 @@ export function GuideDetailsTable({
return (
<>
<div className={`card !m-[1.2rem] !p-0r `}>
<div className={`card !m-[1.2rem] !p-0 `}>
<Table variant="secondary" className="table-fixed">
<colgroup>
{headList
@@ -60,7 +60,7 @@ const RuseMngTable = React.forwardRef<any, RuseMngTableProps>(
{headList.map((head) => (
<TableHead
key={"table-head-row " + head.id}
className={`border border-gray-600 px-2 py-1 `}
className={`border border-border px-2 py-1 `}
>
{head.title}
</TableHead>

Some files were not shown because too many files have changed in this diff Show More