Merge commit '1422319f4e17063f433f8a5f7dd2a737cdd9770e' into iipbs/wr/dev
iipbs_wr / build (push) Has been cancelled

This commit is contained in:
leedj312
2025-04-07 17:55:28 +09:00
30 changed files with 853 additions and 2573 deletions
+7 -67
View File
@@ -1,70 +1,10 @@
@import "../../../packages/common/components/src/base.css";
@import "@common/assets/styles/base.css";
@import "@common/assets/styles/diveicon.css";
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--radius: 0.5rem
}
.dark {
--background: 0 0% 3.9%;
--foreground: 0 0% 98%;
--card: 0 0% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 0 0% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 0 0% 9%;
--secondary: 0 0% 14.9%;
--secondary-foreground: 0 0% 98%;
--muted: 0 0% 14.9%;
--muted-foreground: 0 0% 63.9%;
--accent: 0 0% 14.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 14.9%;
--input: 0 0% 14.9%;
--ring: 0 0% 83.1%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
html,
body {
font-family: "Noto Sans KR", sans-serif;
font-size: 10px;
}
+10
View File
@@ -0,0 +1,10 @@
export default function loading (){
return(
<>
<div>
'test'
</div>
</>
)
}
+2 -2
View File
@@ -19,9 +19,9 @@ export default function Home() {
<Button className="place-self-auto">
<Link href="matMng/matDmd/coReg">수요처 등록</Link>
</Button>
{/* <Button className="place-self-auto">
<Button className="place-self-auto">
<Link href="ruseFcltMng/fcltReg/htdflReg">온배수 등록</Link>
</Button> */}
</Button>
</div>
</>
);
@@ -1,64 +0,0 @@
"use client";
import { useWrStore } from "@/app/store";
import {
ScrollArea,
SearchDiv,
SearchInput,
UiTable,
} from "@common/business_components";
import { Button } from "@common/components";
import { headMakeColSpan } from "../rainReg/page";
import { HtdflRegForm } from "@/components/ui/form/fcltReg/htdflReg/component";
export default function Home() {
const { htdfl } = useWrStore((state) => state);
const nodeList = headMakeColSpan(htdfl.upHeadList);
const headName = () => {
return (
<>
<h1 className="pl-3 text-xl">○건축물 목록</h1>
</>
);
};
return (
<>
<div className="grid grid-cols-2 gap-4 ">
<div className="col-span-2">
<h1 className="pl-3 text-2xl">온배수시설 등록 </h1>
<div className="m-8">
<SearchDiv>
<div className="w-4/5 grid grid-cols-12 gap-1 mx-4">
<SearchInput className="col-span-3 my-7" label="건물명" />
</div>
<div className="w-1/5 flex items-center justify-end">
<Button className="mr-4 rounded-lg">조회</Button>
<Button className="mr-4 rounded-lg">저장</Button>
<Button className="mr-4 rounded-lg">신규등록</Button>
</div>
</SearchDiv>
</div>
</div>
<div className="colsapn-1 pl-11">
<UiTable
tableData={htdfl.htdflOfObject}
headlist={htdfl.upHeadList}
pageSize={100}
total={10}
headName={headName()}
>
{nodeList}
</UiTable>
</div>
<div className="colsapn-1 pr-11 max-h-full ovreflow-y-scroll">
<ScrollArea>
<HtdflRegForm></HtdflRegForm>
</ScrollArea>
</div>
</div>
</>
);
}
@@ -0,0 +1,104 @@
"use client";
import { useWrStore } from "@/app/store";
import {
ContentsDiv,
ScrollArea,
SearchDiv,
SearchFormLeft,
SearchFormRight,
SearchInput,
Title,
UiTable,
} from "@common/business_components";
import { Button } from "@common/components";
import { headMakeColSpan } from "../rainReg/page";
import ListDiv from "@common/business_components/ui/list_div";
import { useEffect, useState } from "react";
import { tableData } from "@/components/lib/func/commom";
import { HtdflRegForm } from "@/components/ui/form/fcltReg/htdflReg/component";
import type { customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
export default function Home() {
const { code, htdfl, initHtdfl } = useWrStore((state) => state);
const nodeList = headMakeColSpan(htdfl.upHeadList);
const [searchTxt, setSearchTxt] = useState("");
const [rswtForm, setRswtForm] = useState<customHtdflBdst>();
const [bdstTable, setbdstTable] = useState<customHtdflBdst[]>();
const { htdflRes } = htdfl;
useEffect(() => {
if (!htdfl.isInit) {
initHtdfl(undefined);
}
}, [htdfl.isInit, initHtdfl]);
useEffect(() => {
if (code.sggCd.length > 0) {
setbdstTable(tableData(htdflRes, { code }));
}
}, [code, htdflRes]);
const cellClick: (val: number | undefined) => void = (val) => {
if ((bdstTable ?? []).length > 0 && val !== undefined) {
{
setRswtForm(htdflRes[val]);
}
}
};
return (
<>
<ContentsDiv>
<div className="grid grid-cols-2 gap-4 ">
<div className="col-span-2">
<Title title={"온배수시설 등록 "} />
<SearchDiv>
<SearchFormLeft>
<SearchInput
className="col-span-3 my-7"
label="건물명:"
textValue={searchTxt || ""}
setText={(e) => {
setSearchTxt(e);
}}
/>
</SearchFormLeft>
<SearchFormRight>
<Button className="mr-4 rounded-lg">조회</Button>
<Button className="mr-4 rounded-lg">신규등록</Button>
</SearchFormRight>
</SearchDiv>
</div>
</div>
<div className="grid grid-cols-6 gap-4 ">
<div className="col-span-4">
<ListDiv>
<UiTable
tableData={bdstTable || []}
headlist={htdfl.upHeadList}
pageSize={100}
total={10}
headName={"○건축물 목록"}
cellClick={cellClick}
>
{nodeList}
</UiTable>
</ListDiv>
</div>
<div className="col-span-2 max-h-full ovreflow-y-scroll">
<ListDiv>
<ScrollArea>
<HtdflRegForm
htdflForm={rswtForm ?? ({} as customRswtBdst)}
isModal={false}
/>
</ScrollArea>
</ListDiv>
</div>
</div>
</ContentsDiv>
</>
);
}
@@ -1,9 +1,10 @@
"use client";
import { useWrStore } from "@/app/store";
import type {
RainyBuilding,
customRainBdst,
TableUpperProps,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { tableData } from "@/components/lib/func/commom";
import { RainRegForm } from "@/components/ui/form/fcltReg/rainReg/component";
import { BdstReg } from "@/components/ui/modal/bdstReg/component";
import {
@@ -58,8 +59,8 @@ export default function Home() {
return state;
});
const { rainRes } = rain;
const [rainForm, setRainForm] = useState<RainyBuilding>();
const [bdstTable, setbdstTable] = useState<RainyBuilding[]>();
const [rainForm, setRainForm] = useState<customRainBdst>();
const [bdstTable, setbdstTable] = useState<customRainBdst[]>();
const [searchTxt , setSearchTxt] = useState<string>()
const nodeList = headMakeColSpan(rain.upHeadList);
@@ -71,22 +72,8 @@ export default function Home() {
useEffect(() => {
if (code.sggCd.length > 0) {
const table = rainRes.map((item) => {
const sggText = code.sggCd.find(
(cd) => cd.val === Number(item.sggCd)
)?.text;
const cityText = code.cityCd.find(
(cd) => cd.val === Number(item.ctpvCd)
)?.text;
const bdstusgText = code.bdstUsgCd.find(
(cd) =>cd.val === item?.reuseBuilding[0]?.bdstUsgCd
)
return { ...item, sggText: sggText, cityText: cityText ,bdsgUsgText:bdstusgText };
});
setbdstTable(table);
setbdstTable( tableData(rainRes, { code }));
}
}, [code, rainRes]);
const cellClick: (val: number | undefined) => void = (val) => {
@@ -117,7 +104,7 @@ export default function Home() {
<UiModal
butNm="신규등록"
title="건축물 시설 등록(빗물이용시설)"
body={<BdstReg moType="rain"></BdstReg>}
body={<BdstReg moType="RNB"></BdstReg>}
bodyClass="sm:max-w-7xl"
/>
</SearchFormRight>
@@ -1,7 +1,5 @@
"use client";
import { useWrStore } from "@/app/store";
import type { TableUpperProps } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { RswtrRegForm } from "@/components/ui/form/fcltReg/rswtrReg/component";
import { BdstReg } from "@/components/ui/modal/bdstReg/component";
import {
ContentsDiv,
@@ -18,13 +16,18 @@ import ListDiv from "@common/business_components/ui/list_div";
import { Button} from "@common/components";
import { headMakeColSpan } from "../rainReg/page";
import { useEffect, useState } from "react";
import type { RswtBuilding } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import { tableData } from "@/components/lib/func/commom";
import { RswtrRegForm } from "@/components/ui/form/fcltReg/rswtrReg/RswtrRegForm";
export default function Home() {
const { code,rswt,initRswt } = useWrStore((state) => state);
const nodeList = headMakeColSpan(rswt.upHeadList);
const [bdstTable, setbdstTable] = useState<RswtBuilding[]>();
const [rswtForm, setRswtForm] = useState<customRswtBdst>();
const [searchTxt , setSearchTxt] = useState<string>()
const [bdstTable, setbdstTable] = useState<customRswtBdst[]>();
const {rswtRes} = rswt;
@@ -37,20 +40,20 @@ export default function Home() {
}, [rswt.isInit, initRswt]);
useEffect(() => {
if (code.sggCd.length > 0) {
console.log(rswtRes)
const table = rswtRes?.map((item) => {
const sggText = code.sggCd.find(
(cd) => cd.val === Number(item.sggCd)
)?.text;
const cityText = code.cityCd.find(
(cd) => cd.val === Number(item.ctpvCd)
)?.text;
return { ...item, sggText: sggText, cityText: cityText };
});
setbdstTable(table);
setbdstTable( tableData(rswtRes, { code }));
}
}, [code, rswtRes]);
const cellClick: (val: number | undefined) => void = (val) => {
console.log(" val ", val)
if ((bdstTable ?? []).length > 0 && val !== undefined) {
{
console.log(" val ", val)
setRswtForm(rswtRes[val]);
}
}
};
return (
<>
@@ -63,19 +66,16 @@ export default function Home() {
<SearchInput
className="col-span-3 my-7"
label="건물명:"
textValue={""}
setText={function (val: string): void {
throw new Error("Function not implemented.");
}}
textValue={searchTxt||""}
setText={(e)=>{setSearchTxt(e)}}
/>
</SearchFormLeft>
<SearchFormRight>
<Button className="mr-4 rounded-lg">조회</Button>
<Button className="mr-4 rounded-lg">저장</Button>
<Button className="mr-4 rounded-lg" onClick={(e)=>{initRswt(searchTxt||"")} }>조회</Button>
<UiModal
butNm="신규등록"
title="건축물 시설 등록(중수도시설)"
body={<BdstReg moType={"rswt"}></BdstReg>}
body={<BdstReg moType={"RST"}></BdstReg>}
bodyClass="sm:max-w-7xl"
/>
</SearchFormRight>
@@ -92,7 +92,7 @@ export default function Home() {
pageSize={100}
total={10}
headName={"○건축물 목록"}
cellClick={undefined}
cellClick={cellClick}
>
{nodeList}
</UiTable>
@@ -101,7 +101,11 @@ export default function Home() {
<div className="col-span-2 max-h-full ovreflow-y-scroll">
<ListDiv>
<ScrollArea>
<RswtrRegForm></RswtrRegForm>
<RswtrRegForm
rswtForm={rswtForm ?? {} as customRswtBdst}
isModal={false}
/>
</ScrollArea>
</ListDiv>
</div>
+31 -33
View File
@@ -43,41 +43,39 @@ export const rainFcltCd = [
{ val: "9", text: "기타" },
{ val: "10", text: "확인불가" },
];
//중수도 필수 원수종류
export const rswtBdstType :selectArray[]= [
{ text: "숙박업", val: "17" },
{ text: "목욕장업", val: "18" },
{ text: "공장", val: "19" },
{ text: "발전시설", val: "20" },
{ text: "관광단지개발사업", val: "21" },
{ text: "도시개발사업", val: "22" },
{ text: "산업단지개발사업", val: "23" },
{ text: "택지개발사업", val: "24" },
{ text: "대규모점포(대형마트)", val: "25" },
{ text: "대규모점포(전문점)", val: "26" },
{ text: "대규모점포(백화점)", val: "27" },
{ text: "대규모점포(쇼핑센터)", val: "28" },
{ text: "대규모점포(복합쇼핑몰)", val: "29" },
{ text: "물류시설", val: "30" },
{ text: "운수시설(여객자동차터미널)", val: "31" },
{ text: "운수시설(철도시설)", val: "32" },
{ text: "운수시설(공항시설)", val: "33" },
{ text: "운수시설(항만시설)", val: "34" },
{ text: "업무시설(공공업무시설)", val: "35" },
{ text: "업무시설(금융업소)", val: "36" },
{ text: "업무시설(사무소)", val: "37" },
{ text: "업무시설(결혼상담소 등 소개업소)", val: "38" },
{ text: "업무시설(출판사)", val: "39" },
{ text: "업무시설(신문사)", val: "40" },
{ text: "업무시설(오피스텔)", val: "41" },
{ text: "교정시설", val: "42" },
{ text: "방송국", val: "43" },
{ text: "전신전화국", val: "44" },
{ text: "기타", val: "45" },
// 중수도 필수 원수종류
export const rswtBdstType: selectArray[] = [
{ text: "숙박업", val: 17 },
{ text: "목욕장업", val: 18 },
{ text: "공장", val: 19 },
{ text: "발전시설", val: 20 },
{ text: "관광단지개발사업", val: 21 },
{ text: "도시개발사업", val: 22 },
{ text: "산업단지개발사업", val: 23 },
{ text: "택지개발사업", val: 24 },
{ text: "대규모점포(대형마트)", val: 25 },
{ text: "대규모점포(전문점)", val: 26 },
{ text: "대규모점포(백화점)", val: 27 },
{ text: "대규모점포(쇼핑센터)", val: 28 },
{ text: "대규모점포(복합쇼핑몰)", val: 29 },
{ text: "물류시설", val: 30 },
{ text: "운수시설(여객자동차터미널)", val: 31 },
{ text: "운수시설(철도시설)", val: 32 },
{ text: "운수시설(공항시설)", val: 33 },
{ text: "운수시설(항만시설)", val: 34 },
{ text: "업무시설(공공업무시설)", val: 35 },
{ text: "업무시설(금융업소)", val: 36 },
{ text: "업무시설(사무소)", val: 37 },
{ text: "업무시설(결혼상담소 등 소개업소)", val: 38 },
{ text: "업무시설(출판사)", val: 39 },
{ text: "업무시설(신문사)", val: 40 },
{ text: "업무시설(오피스텔)", val: 41 },
{ text: "교정시설", val: 42 },
{ text: "방송국", val: 43 },
{ text: "전신전화국", val: 44 },
{ text: "기타", val: 45 },
];
const orgwtKndCd = [
{ text: "오수(변기 오수 제외)", val: "1" },
{ text: "오수", val: "2" },
@@ -1,5 +1,5 @@
import { getFectch } from "@/components/lib/api";
import type { RainyBuilding } from "../rainReg";
import type { bdstAll } from "../rainReg";
type TableUpperProps = {
id: string;
@@ -19,7 +19,7 @@ type TableUpperProps = {
{ id: "archChgArea", title: "면적", upName: "upChangeRe", upSequnce: 3 },
];
const bdstBase: RainyBuilding[] = [];
const bdstBase: bdstAll[] = [];
@@ -28,7 +28,7 @@ export type bdstFulType = bdstState & bdstActions;
export type bdstState = {
bdst: {
bdstBase: RainyBuilding[];
bdstBase: any[];
moUpHeadList:TableUpperProps[]
};
};
@@ -59,11 +59,17 @@ export const bdstActionsExport: (set: any) => bdstActions = (
try{
const bdst = await findBdstInfo(sggCd, searchTxt, flg);
const makeBdst = bdst.map((item:any) => {
return {
...item,
reuseBuilding:[]
};
})
return set((state:bdstState) =>({
...state,
bdst:{
...state.bdst,
bdstBase:bdst
bdstBase:makeBdst
}
}))
@@ -1,89 +1,191 @@
import { getFectch } from "@/components/lib/api";
import {
upHeadList,
type bdstType,
type TableUpperProps,
} from "../rainReg";
const htdflOfObject: bdstType[] = [
{
sido: "서울",
sigungo: "종로구",
facilityName: "그랑서울",
location: "종로 33",
locationgubun: "업무시설",
firstConstructionPermission: "2024-10-10",
buildingArea: "50",
facilityCapacity: "800,000",
reuse: "Y",
permissionDay: "2024-10-10",
register: "Y",
legalTargetYn: "Y",
},
{
sido: "서울",
sigungo: "종로구",
facilityName: "그랑서울",
location: "종로 33",
locationgubun: "업무시설",
firstConstructionPermission: "2024-10-10",
buildingArea: "50",
facilityCapacity: "800,000",
reuse: "Y",
permissionDay: "2024-10-10",
register: "Y",
legalTargetYn: "Y",
},
{
sido: "서울",
sigungo: "종로구",
facilityName: "그랑서울",
location: "종로 33",
locationgubun: "업무시설",
firstConstructionPermission: "2024-10-10",
buildingArea: "50",
facilityCapacity: "800,000",
reuse: "Y",
permissionDay: "2024-10-10",
register: "Y",
legalTargetYn: "Y",
},
];
import { z } from "zod";
export const hdtflZod = z.object({
bdstInfoPk: z.number().nullish().default(0),
ctpvCd: z.number().default(0),
sggCd: z.number().default(0),
daddr: z.string().default(""),
bdstNm: z.string().default(""),
frstArchPrmsnDt: z.date().default(() => new Date()),
archChgPrmsnDt: z.coerce.date().nullish().default(null),
archArea: z.number().default(0),
archChgArea: z.number().nullish().default(0),
reuseBuilding: z.array(
z.object({
bdstRuseFcltPk: z.number().nullish().default(0),
bdstInfoFk: z.number().nullish().default(0),
instlCmptnDt: z.coerce.date().default(() => new Date()),
instlCst: z.number().nullish().default(0),
operMngCd: z.string().nullish().default(""),
anlOperCst: z.number().default(0),
instlCstSprtYn: z.string().default(""),
instlCstSprtAmt: z.number().nullish().default(0),
grntchBdstCertYn: z.string().default(""),
grntchBdstCertYr: z.string()
.max(4, "4자리 연도를 입력하세요")
.regex(/^\d{4}$/, "4자리 연도를 입력하세요")
.nullish()
.default(""),
grntchBdstCertNo: z.string().nullish().default(""),
grntchBdstCertGrd: z.string().nullish().default(""),
crgRdctYn: z.string().default(""),
crgRdctBss: z.string().nullish().default(""),
crgRdctAmt: z.number().nullish().default(0),
ruseFcltFlg: z.string().nullish().default(""),
bdstUsgCd: z.number().default(0),
lawTrgtYn: z.string().default(""),
// htdflObj 매핑
htdfObj: z.object({
htdflFcltPk: z.number().nullish().default(0),
bdstRuseFcltFk: z.number().nullish().default(0),
etgtType: z.string().default(""),
fclCpct: z.number().default(0),
plwtYn: z.string().default(""),
orgwtWtritSpt: z.number().default(0),
orgwtOcrnProcs: z.string().default(""),
wtritEntrcTp: z.number().default(0),
amtgnr: z.number().default(0),
prcsProcsYn: z.string().default(""),
prcsFcltCpct: z.number().default(0),
fmYn: z.string().default(""),
utztnCpct: z.number().default(0),
utztnUsg: z.string().default(""),
grssClfg: z.number().default(0),
combResdch: z.number().default(0),
trbt: z.number().default(0),
bod: z.number().default(0),
smll: z.number().default(0),
crmty: z.number().default(0),
tn: z.number().default(0),
tph: z.number().default(0),
ph: z.number().default(0),
clIonQnt: z.number().default(0),
cdtnv: z.number().default(0),
emsnExitTp: z.number().default(0)
}).default({})
})
).default([])
});
// export type customHtdfBdst = Omit<bdstAll, 'reuseBuilding'> & {
// reuseBuilding: htdfReuseBuilding[];
// };
export type customHtdflBdst =z.infer<typeof hdtflZod>;
// 타입을 조드로 만들어가 하는ㅓㄹ로 테트
export type htdflReuseBuilding={
bdstRuseFcltPk: number|undefined
bdstInfoFk: number|undefined
instlCmptnDt: Date| undefined;
instlCst: number|undefined
operMngCd: string,
anlOperCst: number|undefined
instlCstSprtYn:string| undefined;
instlCstSprtAmt: number|undefined
grntchBdstCertYn:string| undefined;
grntchBdstCertYr: string| undefined;
grntchBdstCertNo:string| undefined;
grntchBdstCertGrd:string| undefined;
crgRdctYn:string
crgRdctBss:string| undefined;
crgRdctAmt: number|undefined
ruseFcltFlg:string
bdstUsgCd: number|undefined
lawTrgtYn:string
htdflObj:htdflObj
}
export type htdflObj = {
htdflFcltPk: number
bdstRuseFcltFk: number
etgtType: string
fclCpct: number|undefined
plwtYn: string
orgwtWtritSpt: number | undefined
orgwtOcrnProcs: string
wtritEntrcTp: number | undefined
amtgnr: number | undefined
prcsProcsYn: string
prcsFcltCpct: number | undefined
fmYn: string
utztnCpct: number | undefined
utztnUsg: string
grssClfg: number | undefined
combResdch: number | undefined
trbt: number| undefined
bod: number| undefined
smll: number| undefined
crmty: number| undefined
tn: number| undefined
tph: number| undefined
ph: number| undefined
clIonQnt: number| undefined
cdtnv: number| undefined
emsnExitTp:number| undefined
}
export type htdflFacState = {
htdfl: {
isInit: boolean;
upHeadList: TableUpperProps[];
htdflOfObject: bdstType[];
htdflRes: customHtdflBdst[];
};
};
type htdflFacSActions = {
decrementList: () => void;
initHtdfl: (txt:string|undefined) => void;
};
const htdflRes: customHtdflBdst[] = [];
export type htdflFacType = htdflFacState & htdflFacSActions;
export const htdflFacStateExport: htdflFacState = {
htdfl: {
isInit: false,
upHeadList: upHeadList,
htdflOfObject: htdflOfObject,
htdflRes: htdflRes,
},
};
const initFetch = async (txt: string | undefined) => {
return await getFectch(
"wr",
`/drain/facilityList/1/20/0` //+ (txt ? `/${txt}` : "")
);
};
export const htdflFacActionsExport: (set: any) => htdflFacSActions = (
set: any
) => {
return {
decrementList: () =>
set((state: htdflFacState) => {
return {
htdfl: {
upHeadList: state.htdfl.upHeadList,
rainOfObject: state.htdfl.htdflOfObject.slice(
0,
state.htdfl.htdflOfObject.length - 1
),
},
};
}),
initHtdfl: async (txt: string|undefined) =>{
try {
const res = await initFetch(txt);
set((state: htdflFacState) => {
return {
...state,
htdfl: {
...state.htdfl,
htdflRes: res,
isInit: false,
},
};
})
} catch (error) {
console.log(error);
}
},
};
};
@@ -91,7 +91,7 @@ export type chgBuilding={
}
export type RainyBuilding = {
export type bdstAll = {
bdstInfoPk: number|null;
ctpvCd: number;
sggCd: number;
@@ -100,11 +100,16 @@ export type RainyBuilding = {
frstArchPrmsnDt: Date;
archArea: string;
archChgArea: number;
reuseBuilding: reuseBuilding[];
reuseBuilding: rainReuseBuilding[];
chgBuilding:chgBuilding[]
};
export type reuseBuilding = {
export type customRainBdst = Omit<bdstAll, 'reuseBuilding'> & {
reuseBuilding: rainReuseBuilding[];
};
export type rainReuseBuilding = {
lawTrgtYn: string|undefined;
bdstUsgCd: number|undefined;
bdstRuseFcltPk: number;
@@ -146,7 +151,7 @@ export const upHeadList: TableUpperProps[] = [
{ id: "sggText", title: "시군구" },
{ id: "bdstNm", title: "시설명" },
{ id: "daddr", title: "위치" },
{ id: "bdstUsgText", title: "건축물용도" },
{ id: "bdsgUsgText", title: "건축물용도" },
// { id: "bdstUsgCd", title: "건축물용도" },
{ id: "frstArchPrmsnDt", title: "최초건축허가일" },
{ id: "archArea", title: "건축면적" },
@@ -156,10 +161,10 @@ export const upHeadList: TableUpperProps[] = [
{ id: "archChgArea", title: "면적", upName: "upChangeRe", upSequnce: 3 },
];
const rainRes: RainyBuilding[] = [];
const rainRes: customRainBdst[] = [];
const regRainForm:RainyBuilding = {
const regRainForm:customRainBdst = {
ctpvCd: 0,
sggCd: 0,
bdstNm: "",
@@ -218,16 +223,16 @@ export type rainFacState = {
isInit: boolean;
upHeadList: TableUpperProps[];
selectYN: selectArray[];
rainRes: RainyBuilding[];
regRainForm:RainyBuilding,
rainRes: customRainBdst[];
regRainForm:customRainBdst,
};
};
type rainFacSActions = {
init: (txt:string|undefined) => void;
rainSearTxt: (txt:string) => void;
rainReg: (data: RainyBuilding) => void;
rainUpdate: (data: RainyBuilding) => void;
rainReg: (data: customRainBdst) => void;
rainUpdate: (data: customRainBdst) => void;
};
export type rainFacType = rainFacState & rainFacSActions;
@@ -288,7 +293,7 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
console.log("error", erTxt)
}
},
rainReg: async (data: RainyBuilding) => {
rainReg: async (data: customRainBdst) => {
try {
const res = await postFectch("/reuseFc/rainyInfo", data);
if(res.ok){
@@ -309,7 +314,7 @@ export const rainFacActionsExport: (set: any) => rainFacSActions = (
} finally {
}
},
rainUpdate: async (data: RainyBuilding) => {
rainUpdate: async (data: customRainBdst) => {
try {
console.log("data ", data)
const res = await putFectch("/reuseFc/rainyInfo", data);
@@ -1,19 +1,72 @@
import { getFectch } from "@/components/lib/api";
import { upHeadList, type chgBuilding, type TableUpperProps } from "../rainReg";
import { getFectch, postFectch, putFectch } from "@/components/lib/api";
import { upHeadList, type bdstAll, type chgBuilding, type TableUpperProps } from "../rainReg";
import { rswtBdstType } from "@/app/store/common/code";
export type RswtBuilding = {
bdstInfoPk: number;
ctpvCd: number;
sggCd: number;
bdstNm: string;
daddr: string;
frstArchPrmsnDt: Date;
archArea: string;
archChgArea: number;
import { z } from "zod";
export const rswtZod = z.object({
bdstInfoPk: z.number().default(0),
ctpvCd: z.number().default(0),
sggCd: z.number().default(0),
daddr: z.string().default(""),
bdstNm: z.string().default(""),
frstArchPrmsnDt: z.date().default(() => new Date()),
archChgPrmsnDt: z.coerce.date().nullish().default(null),
archArea: z.number().default(0),
archChgArea: z.number().default(0),
reuseBuilding: z.array(
z.object({
bdstRuseFcltPk: z.number().default(0),
bdstInfoFk: z.number().default(0),
instlCmptnDt: z.coerce.date().default(() => new Date()),
instlCst: z.number().default(0),
operMngCd: z.string().nullish().default(""),
anlOperCst: z.number().default(0),
instlCstSprtYn: z.string().default(""),
instlCstSprtAmt: z.number().default(0),
grntchBdstCertYn: z.string().default(""),
grntchBdstCertYr: z.string().max(4, "4자리 연도를 입력하세요")
.regex(/^\d{4}$/, "4자리 연도를 입력하세요")
.default(""),
grntchBdstCertNo: z.string().default(""),
grntchBdstCertGrd: z.string().default(""),
crgRdctYn: z.string().default(""),
crgRdctBss: z.string().default(""),
crgRdctAmt: z.number().default(0),
ruseFcltFlg: z.string().default(""),
bdstUsgCd: z.number().default(0),
lawTrgtYn: z.string().default(""),
rswtrObj: z.object({
bdstRuseFcltFk: z.number().default(0),
wtrUsqty: z.number().default(0),
oblgTrgtWtrUsqty: z.number().default(0),
orgwtKndCd: z.string().default(""),
filtrTrtmfctProcs: z.string().default(""),
filtrTrtmfctUsgCd: z.string().default(""),
rswtrUsqty: z.number().default(0),
altUswtrUtztnYn: z.string().default(""),
altUswtrKndCd: z.string().default(""),
altUswtrUtztnQnt: z.number().default(0),
altUswtrIdntyMthdCd: z.string().default("")
}).default({})
})
).default([])
});
export type customRswtBdst = Omit<bdstAll, 'reuseBuilding'> & {
reuseBuilding: rswtReuseBuilding[];
chgBuilding: chgBuilding[];
};
export type rswtReuseBuilding = {
bdstRuseFcltPk: number;
bdstInfoFk: number;
@@ -45,17 +98,20 @@ export type rswtrObj = {
altUswtrIdntyMthdCd: string;
};
const rswtRes: RswtBuilding[] = [];
const rswtRes: customRswtBdst[] = [];
export type rswtFacState = {
rswt: {
isInit: boolean;
upHeadList: TableUpperProps[];
rswtRes: RswtBuilding[];
rswtRes: customRswtBdst[];
};
};
type rswtFacSActions = {
initRswt: (txt: string | undefined) => void;
rswtUpdate: (data: customRswtBdst) => void;
rswtReg: (data: customRswtBdst) => void;
};
export type rswtFacType = rswtFacState & rswtFacSActions;
@@ -71,7 +127,7 @@ export const rswtFacStateExport: rswtFacState = {
const initFetch = async (txt: string | undefined) => {
return await getFectch(
"wr",
`/reuseFc/waterreuseFc/1/20/01` + (txt ? `/${txt}` : "")
`/reuseFc/waterreuseFc/1/20/41` + (txt ? `/${txt}` : "")
);
};
export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
@@ -93,5 +149,48 @@ export const rswtFacActionsExport: (set: any) => rswtFacSActions = (
console.log(error);
}
},
rswtUpdate: async (data: customRswtBdst) => {
try {
const res = await putFectch("/reuseFc/waterreuseFc", data);
if(res.ok){
alert(" 수정이 완료되었습니다.")
}
const rswtRes = await initFetch(undefined);
set((state: rswtFacState) => ({
...state,
rain: {
...state.rswt,
rswtRes: rswtRes,
isInit: false,
},
}));
} catch (errorUpdate) {
alert("업데이트 오류입니다. " + (errorUpdate instanceof Error ? errorUpdate.message : ""));
} finally {
}
},
rswtReg: async (data: customRswtBdst) => {
try {
const res = await postFectch("/reuseFc/waterreuseFc", data);
if(res.ok){
alert(" 등록이 완료되었습니다.")
}
const rainRes = await initFetch(undefined);
set((state: rswtFacState) => ({
...state,
rain: {
...state.rswt,
rswtRes: rswtRes,
isInit: false,
},
}));
} catch (e) {
console.log("e", e);
alert("등록 오류입니다.");
} finally {
}
},
};
};
@@ -1,9 +0,0 @@
.formInsideTitle{
background-color: gray;
text-align: center;
}
.smallTitle{
}
+1 -1
View File
@@ -3,7 +3,7 @@ const LOCAL_PORT = "3000";
const DEV_PORT = "11080";
const DEV_PORT_COMMON = "11081"; // common
const DEV_PORT_COMMON = "11082"; // common
export const LOCAL_URL_WR = `http://localhost:${LOCAL_PORT}/api/v1`;
export const DEV_URL_WR = `http://con.mind-one.co.kr:${DEV_PORT}/api/v1`;
+33 -1
View File
@@ -1,4 +1,5 @@
import type { selectArray } from "@/app/store/common/code";
import type { comCodeState, selectArray } from "@/app/store/common/code";
import type { bdstAll } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
@@ -14,3 +15,34 @@ export const getCity = (val: string, sggCd: selectArray[]) => {
return data
};
// cd text 넣기
export const tableData = ( data: any,code:comCodeState)=>{
const chCode = code.code;
return data?.map((item: { sggCd: string; ctpvCd: string; reuseBuilding: { lawTrgtYn: any , bdstUsgCd:any}[]; }) => {
let returnData = {};
const sggText = chCode.sggCd.find(
(cd) => cd.val === Number(item.sggCd)
)?.text;
const cityText = chCode.cityCd.find(
(cd) => cd.val === Number(item.ctpvCd)
)?.text;
if (item?.reuseBuilding?.length >0) {
const bdsgUsgText = chCode.bdstUsgCd.find(
(cd) =>cd.val === item?.reuseBuilding[0]?.bdstUsgCd
)?.text
const lawTrgtYn = item?.reuseBuilding[0]?.lawTrgtYn
returnData= { ...item, sggText: sggText, cityText: cityText ,bdsgUsgText:bdsgUsgText ,lawTrgtYn:lawTrgtYn};
}else{
returnData= { ...item, sggText: sggText, cityText: cityText};
}
return returnData;
});
}
@@ -1,6 +1,6 @@
import { useWrStore } from "@/app/store";
import type { selectArray } from "@/app/store/common/code";
import { selectClass, type RainyBuilding } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { selectClass, type bdstAll } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { getCity } from "@/components/lib/func/commom";
import type { objSearchType } from "@/components/ui/modal/bdstReg/component";
import { FormField, FormUi, DatePicker, SelectBox } from "@common/business_components";
@@ -8,7 +8,7 @@ import { Button, Input } from "@common/components";
import { useEffect, useRef, useState } from "react";
import { useFieldArray } from "react-hook-form";
export default function BdstReg({ form, ud }: { form: any, ud: RainyBuilding }) {
export default function BdstReg({ form }: { form: any }) {
const { code } = useWrStore((state) => {
return state;
});
@@ -50,21 +50,7 @@ export default function BdstReg({ form, ud }: { form: any, ud: RainyBuilding })
setObjSearch({...objSearch,sgg: val!=''?String(val):sgg })
};
// useEffect(()=>{
// console.log("18", ud);
// console.log("form", form.getValues());
// const city =form?.getValues('ctpvCd')
// const sgg =form?.getValues('sggCd')
// console.log('city ㄴㄴㄴ ', city)
// console.log('sgg ', sgg)
// if(city>0 && sgg>0){
// console.log(' if city ', city)
// // form?.setValue('ctpvCd' , city)
// //form?.setValue('sggCd' , sgg)
// //setSelectSgg(getCity(city,code.sggCd))
// }
// },[ud])
useEffect(()=>{
const city =form.getValues('ctpvCd')
const sgg =form.getValues('sggCd')
@@ -73,12 +59,13 @@ export default function BdstReg({ form, ud }: { form: any, ud: RainyBuilding })
}, [selectSgg])
useEffect(() => {
const subscription = form.form?.watch((value) => {
console.log("form", form.getValues());
const subscription = form.form?.watch((value: any) => {
console.log('vale', value)
});
return () => subscription?.unsubscribe();
}, [form]);
}, [form.form]);
const safeDate = (value: any): Date | undefined => {
@@ -203,7 +190,7 @@ export default function BdstReg({ form, ud }: { form: any, ud: RainyBuilding })
<DatePicker
mode={"single"}
field={{
value: new Date(field.value),
value: field.value|| new Date(),
onChange: (date: Date | undefined) =>
field.onChange(date),
}}
@@ -6,104 +6,82 @@ import {
FormUi,
SelectBox,
} from "@common/business_components/ui";
import { Input } from "@common/components/ui";
import { Button, Input } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { useWrStore } from "@/app/store";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { hdtflZod, type customHtdflBdst } from "@/app/store/ruseFcltMng/fcltReg/htdflReg";
import { useEffect } from "react";
const formSchema = z.object({
etgtType: z.string().min(2).max(50),
fclCpct: z.string(),
plwtYn: z.string(),
orgwtwtritspt: z.string(),
orgwtocrnprocs: z.string(),
wtritentrctp: z.string(),
amtgnr: z.string(),
prcsfcltcpct: z.string(),
utztnqnt: z.string(),
utztnusgcd: z.string(),
wntUntprc: z.string().min(1),
grssClfg: z.string().min(1),
tn: z.string().min(1).optional(),
combResdch: z.string().min(1).optional(),
tp: z.string().min(1).optional(),
trbt: z.string().min(1).optional(),
ph: z.string().min(1).optional(),
bod: z.string().min(1).optional(),
clIonQnt: z.string().min(1).optional(),
smll: z.string().min(1).optional(),
cdtnv: z.string().min(1).optional(),
crmty: z.string().min(1).optional(),
emsnexittp: z.string(),
});
export function HtdflRegForm() {
const { rswt } = useWrStore((state) => state);
export function HtdflRegForm({
htdflForm,
isModal
} :{
htdflForm:customHtdflBdst;
isModal: boolean;
} ) {
const {code} = useWrStore((state) => state);
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
etgtType: "",
fclCpct: "",
plwtYn: "",
orgwtwtritspt: "",
orgwtocrnprocs: "",
wtritentrctp: "",
amtgnr: "",
prcsfcltcpct: "",
utztnqnt: "",
utztnusgcd: "",
wntUntprc: "",
grssClfg: "",
tn: "",
combResdch: "",
tp: "",
trbt: "",
ph: "",
bod: "",
clIonQnt: "",
smll: "",
cdtnv: "",
crmty: "",
emsnexittp: "",
},
const defaultValues: z.infer<typeof hdtflZod> = hdtflZod.parse({});
const form = useForm<z.infer<typeof hdtflZod>>({
resolver: zodResolver(hdtflZod),
defaultValues:defaultValues,
});
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof formSchema>) {
// 2. Define a submit handler.hdtflZod
function onSubmit(values: z.infer<typeof hdtflZod>) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values);
}
const onSelectValue = (val: string) => {
const onSelectValue = (val: string | number) => {
console.log(val);
};
useEffect(() => {
if(hdtflZod)
console.log("hdtflZod", hdtflZod);
const parsedData = hdtflZod.safeParse(htdflForm);
if (parsedData.success) {
form.reset(parsedData.data);
} else {
console.error("Invalid data for form reset", parsedData.error);
}
}, [htdflForm]);
return (
<div className="">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
{/* <div className="flex justify-between items-center mx-3"> */}
<div>
<div>
<h1 className="pl-3 text-xl ">○온배수 시설 정보</h1>
<div className="grid grid-cols-12">
<h1 className="pl-3 text-xl col-span-10">
○온배수 시설 정보
</h1>
<Button type="submit" className="mr-4 rounded-lg col-span-2">
저장
</Button>
</div>
</div>
<h1 className="bg-gray-400 text-xl text-center border-2 p-2 mt-4 ">
시설현황
</h1>
<div className="grid grid-cols-6 gap-2 mt-4 pl-6">
<div className="col-span-2">
<FormField
control={form.control}
name="etgtType"
name="reuseBuilding.0.htdflObj.etgtType"
render={({ field }) => (
<FormUi label="발전유형">
<SelectBox
selectClass={selectClass}
selectArray={rswt.selectYN}
selectArray={code.yn}
onSelectValue={onSelectValue}
{...field}
/>
@@ -115,14 +93,16 @@ export function HtdflRegForm() {
<div className="col-span-2">
<FormField
control={form.control}
name="fclCpct"
name="reuseBuilding.0.htdfObj.fclCpct" // 이름 이상함.
render={({ field }) => (
<FormUi label="설비용량">
<Input
className=""
placeholder="1,000,000"
type=""
type="text"
{...field}
value={field.value ?? ""}
onChange={(e) => field.onChange(Number(e.target.value))}
/>
</FormUi>
)}
@@ -131,12 +111,12 @@ export function HtdflRegForm() {
<div className="col-span-2">
<FormField
control={form.control}
name="plwtYn"
name="reuseBuilding.0.htdfObj.plwtYn"
render={({ field }) => (
<FormUi label="담수화 여부">
<SelectBox
selectClass={selectClass}
selectArray={rswt.selectYN}
selectArray={code.yn}
onSelectValue={onSelectValue}
{...field}
/>
@@ -155,12 +135,12 @@ export function HtdflRegForm() {
<div className="col-span-5 pl-6">
<FormField
control={form.control}
name="orgwtwtritspt"
name="reuseBuilding.0.htdfObj.orgwtwtritspt"
render={({ field }) => (
<FormUi label="원수취수 지점">
<SelectBox
selectClass={selectClass}
selectArray={rswt.selectYN}
selectArray={code.yn}
onSelectValue={onSelectValue}
{...field}
/>
@@ -190,11 +170,10 @@ export function HtdflRegForm() {
name="wtritentrctp"
render={({ field }) => (
<FormUi label="취수구 온도">
<SelectBox
selectClass={selectClass}
label={""}
selectArray={rswt.selectYN}
onSelectValue={onSelectValue}
<Input
className=""
placeholder="1,000,000"
type=""
{...field}
/>
</FormUi>
@@ -258,7 +237,7 @@ export function HtdflRegForm() {
<SelectBox
selectClass={selectClass}
label={""}
selectArray={rswt.selectYN}
selectArray={code.yn}
onSelectValue={onSelectValue}
{...field}
/>
@@ -291,7 +270,7 @@ export function HtdflRegForm() {
<SelectBox
selectClass={selectClass}
label={""}
selectArray={rswt.selectYN}
selectArray={code.yn}
onSelectValue={onSelectValue}
{...field}
/>
@@ -464,6 +443,5 @@ export function HtdflRegForm() {
</div>
</form>
</Form>
</div>
);
}
@@ -6,7 +6,7 @@ import {
bdstDefZod,
rainDefZod,
rainZod,
type RainyBuilding,
type customRainBdst,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { DatePicker, FormUi } from "@common/business_components";
import { Form, FormField, SelectBox } from "@common/business_components/ui";
@@ -15,7 +15,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useEffect, useState } from "react";
import { useForm, type UseFormReturn } from "react-hook-form";
import { z } from "zod";
import BdstReg from "../bdstReg/component";
import BdstReg from "../bdstReg/bdstReg";
export const formToObj = (
isModal: boolean,
@@ -41,7 +41,7 @@ export function RainRegForm({
rainForm,
isModal,
}: {
rainForm: RainyBuilding;
rainForm: customRainBdst;
isModal: boolean;
}) {
@@ -93,7 +93,7 @@ export function RainRegForm({
}, [form]);
const objToForm = (raw: z.infer<typeof formSchema>) => {
let regRainForm: RainyBuilding;
let regRainForm: customRainBdst;
// 1. 기본 정보 정리
const obj = !rainForm ? rain.regRainForm : rainForm;
@@ -175,10 +175,10 @@ export function RainRegForm({
</Button>
</div>
</div>
{isModal&&rainForm!=undefined ? <BdstReg form={form} ud={rainForm}/> : <></>}
{isModal&&rainForm!=undefined ? <BdstReg form={form}/> : <></>}
{isModal ? (
<h1 className="pl-3 text-xl col-span-10 mt-4 ">
○ 빗물이용시설 운영정보{" "}
○ 빗물이용시설 정보{" "}
</h1>
) : (
<></>
@@ -1,82 +1,121 @@
"use client";
import {
DatePicker,
Form,
FormField,
FormUi,
SelectBox,
} from "@common/business_components/ui";
import { Input } from "@common/components/ui";
import { Button, Input } from "@common/components/ui";
import { zodResolver } from "@hookform/resolvers/zod";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { useFieldArray, useForm } from "react-hook-form";
import { number, z } from "zod";
import { useWrStore } from "@/app/store";
import { selectClass } from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import {
rswtZod,
type customRswtBdst,
} from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
import { useEffect } from "react";
import BdstReg from "../bdstReg/bdstReg";
const formSchema = z.object({
facilityName: z.string().min(2).max(50),
instlCmptnDt: z.string(),
instlCst: z.string(),
wtrUsqty: z.string(),
oblgTrgtwtrUsqty: z.string(),
rswtrKndCd: z.string(),
rswrtProcs: z.string(),
utztmUsgCd: z.string(),
instlCstSprtYn: z.string(),
instlCstSprtAmt: z.string(),
grntchCstSprtYn: z.string(),
grntchCstSprtCst: z.string(),
grntchBdstCertYn: z.string(),
grntchBdstCertYr: z.string(),
grntchBdstCertNo: z.string(),
grntchBdstCertGrd: z.string(),
});
export function RswtrRegForm({
rswtForm,
isModal,
}: {
rswtForm: customRswtBdst;
isModal: boolean;
}) {
const { rswt, code ,rswtUpdate,rswtReg} = useWrStore((state) => state);
export function RswtrRegForm() {
const { rswt,code } = useWrStore((state) => state);
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
facilityName: "",
instlCmptnDt: "",
instlCst: "",
wtrUsqty: "",
oblgTrgtwtrUsqty: "",
rswtrKndCd: "",
rswrtProcs: "",
utztmUsgCd: "",
instlCstSprtYn: "",
instlCstSprtAmt: "",
grntchCstSprtYn: "",
grntchCstSprtCst: "",
grntchBdstCertYn: "",
grntchBdstCertYr: "",
grntchBdstCertNo: "",
grntchBdstCertGrd: "",
},
});
const defaultValues: z.infer<typeof rswtZod> = rswtZod.parse({});
const form = useForm<z.infer<typeof rswtZod>>({
resolver: zodResolver(rswtZod),
defaultValues: defaultValues,
})
// 2. Define a submit handler.
function onSubmit(values: z.infer<typeof formSchema>) {
function onSubmit(values: z.infer<typeof rswtZod>) {
// Do something with the form values.
// ✅ This will be type-safe and validated.
console.log(values);
if (isModal) {
// regRainForm.bdstInfoPk = null;
rswtReg(values);
} else {
rswtUpdate(values);
}
}
const onSelectValue = (val: string) => {
const onSelectValue = (val: string | number) => {
console.log(val);
};
function cleanRswtData(raw: any): z.infer<typeof rswtZod> {
return {
...raw,
frstArchPrmsnDt: new Date(raw?.frstArchPrmsnDt||null),
archChgPrmsnDt: raw?.archChgPrmsnDt ? new Date(raw?.archChgPrmsnDt) : null,
reuseBuilding: (raw?.reuseBuilding || []).map((item: any) => ({
...item,
instlCmptnDt: new Date(item?.instlCmptnDt),
operMngCd: item?.operMngCd ?? "", // null → ""
grntchBdstCertYr: typeof item?.grntchBdstCertYr === "string"
? item?.grntchBdstCertYr
: "", // null → ""
rswtrObj: {
...item?.rswtrObj
}
}))
};
}
useEffect(() => {
if(rswtZod)
console.log("rswtForm", rswtForm);
form.reset( cleanRswtData(rswtForm))
}, [rswtForm]);
return (
<div className="">
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)}>
{/* <div className="flex justify-between items-center mx-3"> */}
<div>
<div>
<h1 className="pl-3 text-xl ">○ 중수도 시설 운영정보</h1>
<div className="grid grid-cols-12">
<h1 className="pl-3 text-xl col-span-10">
○ 중수도 시설 운영정보
</h1>
<Button type="submit" className="mr-4 rounded-lg col-span-2">
저장
</Button>
</div>
</div>
{isModal && rswtForm != undefined ? (
<BdstReg form={form} />
) : (
<></>
)}
{isModal ? (
<h1 className="pl-3 text-xl col-span-10 mt-4 ">
○ 중수도 시설 정보{" "}
</h1>
) : (
<></>
)}
<h1 className="bg-gray-400 text-xl text-center border-2 p-2 mt-4 ">
기본정보
</h1>
@@ -84,14 +123,19 @@ export function RswtrRegForm() {
<div className="col-span-2">
<FormField
control={form.control}
name="instlCmptnDt"
name="reuseBuilding.0.instlCmptnDt"
render={({ field }) => (
<FormUi label="설치완료일">
<Input
className=""
placeholder="1,000,000"
type=""
{...field}
<DatePicker
mode="single"
field={{
value:
field.value && !isNaN(new Date(field.value).getTime())
? new Date(field.value)
: new Date(), // Provide a default Date value
onChange: (date) => field.onChange(date),
}}
selectClass={""}
/>
</FormUi>
)}
@@ -101,14 +145,15 @@ export function RswtrRegForm() {
<div className="col-span-2">
<FormField
control={form.control}
name="instlCst"
name="reuseBuilding.0.instlCst"
render={({ field }) => (
<FormUi label="설치비">
<Input
className=""
placeholder="1,000,000"
type=""
{...field}
type="text"
value={field.value ?? ""}
onChange={(e) => field.onChange(Number(e.target.value))}
/>
</FormUi>
)}
@@ -119,14 +164,15 @@ export function RswtrRegForm() {
<div className="col-span-2">
<FormField
control={form.control}
name="wtrUsqty"
name="reuseBuilding.0.rswtrObj.wtrUsqty"
render={({ field }) => (
<FormUi label="물사용량(m³)">
<Input
className=""
placeholder="1,000,000"
type=""
{...field}
value={field.value ?? 0}
onChange={(e) => field.onChange(Number(e.target.value))}
/>
</FormUi>
)}
@@ -136,14 +182,15 @@ export function RswtrRegForm() {
<div className="col-span-2">
<FormField
control={form.control}
name="oblgTrgtwtrUsqty"
name="reuseBuilding.0.rswtrObj.oblgTrgtWtrUsqty"
render={({ field }) => (
<FormUi label="의무대상 물사용량(m³)">
<Input
className=""
placeholder="1,000,000"
type=""
{...field}
type="text"
value={field.value ?? 0}
onChange={(e) => field.onChange(Number(e.target.value))}
/>
</FormUi>
)}
@@ -160,14 +207,16 @@ export function RswtrRegForm() {
<div className="col-span-5 pl-6">
<FormField
control={form.control}
name="rswtrKndCd"
name="reuseBuilding.0.rswtrObj.orgwtKndCd"
render={({ field }) => (
<FormUi label="필수 종류">
<FormUi label="원수 종류">
<SelectBox
className={""}
label={""}
selectClass={selectClass}
selectArray={code.orgwtKndCd}
onSelectValue={onSelectValue}
{...field}
onSelectValue={field.onChange}
value={field.value ?? code.orgwtKndCd[0]?.val}
/>
</FormUi>
)}
@@ -176,20 +225,20 @@ export function RswtrRegForm() {
<div className="col-span-5">
<FormField
control={form.control}
name="rswrtProcs"
name="reuseBuilding.0.rswtrObj.filtrTrtmfctProcs"
render={({ field }) => (
<FormUi label="주요처리공정">
<Input
className=""
placeholder="1,000,000"
type=""
{...field}
value={field.value ?? ""}
onChange={field.onChange}
/>
</FormUi>
)}
/>
</div>
</div>
<div className=" my-2">
@@ -204,15 +253,16 @@ export function RswtrRegForm() {
<div className="col-span-1 pl-6">
<FormField
control={form.control}
name="instlCstSprtYn"
name="reuseBuilding.0.instlCstSprtYn"
render={({ field }) => (
<FormUi label="설치비 지원여부">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={onSelectValue}
{...field}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
/>
</FormUi>
)}
@@ -221,14 +271,17 @@ export function RswtrRegForm() {
<div className="col-span-1">
<FormField
control={form.control}
name="instlCstSprtAmt"
name="reuseBuilding.0.instlCstSprtAmt"
render={({ field }) => (
<FormUi label="지원금액(원)">
<Input
className=""
placeholder="1,000,000"
type=""
{...field}
value={field.value ?? ""}
onChange={(e) => {
field.onChange(Number(e.target.value));
}}
/>
</FormUi>
)}
@@ -243,15 +296,16 @@ export function RswtrRegForm() {
<div className="col-span-3 pl-6">
<FormField
control={form.control}
name="grntchCstSprtYn"
name="reuseBuilding.0.grntchBdstCertYn"
render={({ field }) => (
<FormUi label="인증여부">
<SelectBox
className={""}
selectClass={selectClass}
label={""}
selectArray={code.yn}
onSelectValue={onSelectValue}
{...field}
onSelectValue={field.onChange}
value={field.value ?? code.yn[0]?.val}
/>
</FormUi>
)}
@@ -260,10 +314,17 @@ export function RswtrRegForm() {
<div className="col-span-3">
<FormField
control={form.control}
name="grntchBdstCertYr"
name="reuseBuilding.0.grntchBdstCertYr"
render={({ field }) => (
<FormUi label="인증년도">
<Input className="" placeholder="2024" type="" {...field} />
<Input
className=""
placeholder="2024"
type=""
{...field}
value={field.value ?? ""}
onChange={field.onChange}
/>
</FormUi>
)}
/>
@@ -271,14 +332,15 @@ export function RswtrRegForm() {
<div className="col-span-3 pl-6">
<FormField
control={form.control}
name="grntchBdstCertNo"
name="reuseBuilding.0.grntchBdstCertNo"
render={({ field }) => (
<FormUi label="인증번호">
<Input
className=""
placeholder="ab1234678"
type=""
{...field}
value={field.value ?? ""}
onChange={field.onChange}
/>
</FormUi>
)}
@@ -287,10 +349,16 @@ export function RswtrRegForm() {
<div className="col-span-3">
<FormField
control={form.control}
name="grntchBdstCertGrd"
name="reuseBuilding.0.grntchBdstCertGrd"
render={({ field }) => (
<FormUi label="인증등급">
<Input className="" placeholder="A" type="" {...field} />
<Input
className=""
placeholder="A"
type=""
value={field.value ?? ""}
onChange={field.onChange}
/>
</FormUi>
)}
/>
@@ -3,40 +3,52 @@ import { headMakeColSpan } from "@/app/ruseFcltMng/fcltReg/rainReg/page";
import { useWrStore } from "@/app/store";
import {
selectClass,
type RainyBuilding,
type bdstAll,
type customRainBdst,
} from "@/app/store/ruseFcltMng/fcltReg/rainReg";
import { ScrollArea, SearchInput, SelectBox, UiTable } from "@common/business_components";
import { Button, Input, Label } from "@common/components";
import { useEffect, useState } from "react";
import { RainRegForm } from "../../form/fcltReg/rainReg/component";
import { getCityCd, type selectArray } from "@/app/store/common/code";
import { getCity } from "@/components/lib/func/commom";
import { RswtrRegForm } from "../../form/fcltReg/rswtrReg/component";
import { getCity, tableData } from "@/components/lib/func/commom";
import { RswtrRegForm } from "../../form/fcltReg/rswtrReg/RswtrRegForm";
import { HtdflRegForm } from "../../form/fcltReg/htdflReg/component";
import type { customRswtBdst } from "@/app/store/ruseFcltMng/fcltReg/rswtReg";
export type objSearchType = {
sgg: string|number;
city: string|number;
};
//RNB(빗물), RST(중수도), HTB(온배수)
type MoType = 'RNB' | 'RST' | 'HTB'; // 여기에 'htdf' 추가
type BdstTypeMap = {
RNB: customRainBdst;
RST: customRswtBdst;
HTB: customRswtBdst; // 해야해// 아직 아노딤
};
export function BdstReg({moType}:{moType:string} ) {
interface BdstRegProps<T extends MoType> {
moType: T;
}
export function BdstReg<T extends MoType>({ moType }: BdstRegProps<T>) {
const { rain, code, bdst,findBdst } = useWrStore((state) => {
return state;
});
const [bdstTable, setbdstTable] = useState<RainyBuilding[]>();
const [rainBdstForm, setRainBdstForm] = useState<RainyBuilding>({} as RainyBuilding);
const [bdstTable, setbdstTable] = useState<BdstTypeMap[T][]>();
const [rainBdstForm, setRainBdstForm] = useState<BdstTypeMap[T]>({} as BdstTypeMap[T]);
const [searchTxt, setSearchTxt] = useState<string>()
const [selectSgg, setSelectSgg] = useState<selectArray[] | undefined>()
const [selectSgg, setSelectSgg] = useState<selectArray[] | []>()
const [objSearch, setObjSearch] = useState<objSearchType>({sgg:"",city:""});
const getSelCity = (val: string) => {
const data= getCity(val,code.sggCd)
setSelectSgg(data);
setObjSearch({ city:val , sgg:''})
const getSelCity = (val: string | number) => {
const cityValue = String(val); // Ensure val is treated as a string
const data = getCity(cityValue, code.sggCd);
setSelectSgg(data);
setObjSearch({ city: cityValue, sgg: '' });
};
const getSgg = (val: string | number) => {
@@ -54,33 +66,26 @@ export function BdstReg({moType}:{moType:string} ) {
data = objSearch.sgg
}
findBdst(String(data), searchTxt || "","RNB" )
//RNB(빗물), RST(중수도), HTB(온배수)
findBdst(String(data), searchTxt || "",moType )
}
useEffect(() => {
if (code.sggCd.length > 0) {
const table = bdst?.bdstBase?.map((item) => {
const sggText = code.sggCd.find(
(cd) => cd.val === Number(item.sggCd)
)?.text;
const cityText = code.cityCd.find(
(cd) => cd.val === Number(item.ctpvCd)
)?.text;
return { ...item, sggText: sggText, cityText: cityText };
});
setbdstTable(table);
}
setbdstTable( tableData(bdst.bdstBase, { code }));
}
}, [code, bdst]);
const tableClick: (val: number | undefined) => void = (val) => {
if(val!==undefined && bdst?.bdstBase.length>0){
const data =bdst?.bdstBase[val]
setRainBdstForm(data);
const data:BdstTypeMap[T] =bdst?.bdstBase[val]
if (data) {
setRainBdstForm(data);
}
}
}
const nodeList = headMakeColSpan(bdst.moUpHeadList);
@@ -91,7 +96,7 @@ export function BdstReg({moType}:{moType:string} ) {
className="col-span-3 "
label={"시도"}
selectClass={selectClass}
selectArray={code.cityCd}
selectArray={code.cityCd || []}
onSelectValue={getSelCity}
>
{""}
@@ -107,13 +112,7 @@ export function BdstReg({moType}:{moType:string} ) {
</SelectBox>
<Label className="w-20 text-base text-gray-600 mt-4 text-right">건축물명</Label>
<Input className="w-full h-full text-2xl col-span-2 col-start-8" type="text" value={searchTxt || ''} onChange={(e) => setSearchTxt(e.target.value)}/>
{/* <SearchInput
className="col-span-3 col-start-8"
label="건물명"
textValue={searchTxt}
setText={ setSearchTxt}
/> */}
<Button className="rounded-lg" onClick={()=>{searchBdst(searchTxt)}}>조회</Button>
</div>
<div className="border-t border-gray-300 my-4"></div>
@@ -135,9 +134,9 @@ export function BdstReg({moType}:{moType:string} ) {
<div className="border-t border-gray-300 my-4"></div>
<ScrollArea className="h-[60vh]">
<div>
{moType === 'rain'?
{ moType === 'RNB'?
<RainRegForm rainForm={rainBdstForm} isModal={true} />
:moType==='rswt'?<RswtrRegForm></RswtrRegForm>
:moType==='RST'?<RswtrRegForm rswtForm={rainBdstForm } isModal={true}></RswtrRegForm>
:<HtdflRegForm></HtdflRegForm>
}
+1
View File
@@ -11,6 +11,7 @@
"dependencies": {
"@common/business_components": "workspace:*",
"@common/components": "workspace:*",
"@common/assets": "workspace:*",
"@hookform/resolvers": "^4.1.3",
"@tanstack/react-table": "^8.21.2",
"class-variance-authority": "^0.7.1",
+14 -59
View File
@@ -1,66 +1,21 @@
import baseConfig from "../../packages/common/components/tailwind.config";
import type { Config } from "tailwindcss";
import tailwindcssAnimate from "tailwindcss-animate";
import presetConfig from "../../tailwind.config.preset";
export default {
darkMode: ["class"],
presets: [baseConfig],
presets: [presetConfig],
content: [
"./app/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"./src/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}",
"../../packages/common/components/src/ui/**/*.{js,ts,jsx,tsx,mdx}",
"../../packages/common/business_components/src/ui/**/*.{js,ts,jsx,tsx,mdx}",
],
plugins: [require("tailwindcss-animate")],
theme: {
extend: {
borderRadius: {
lg: 'var(--radius)',
md: 'calc(var(--radius) - 2px)',
sm: 'calc(var(--radius) - 4px)'
},
colors: {
background: 'hsl(var(--background))',
foreground: 'hsl(var(--foreground))',
card: {
DEFAULT: 'hsl(var(--card))',
foreground: 'hsl(var(--card-foreground))'
},
popover: {
DEFAULT: 'hsl(var(--popover))',
foreground: 'hsl(var(--popover-foreground))'
},
primary: {
DEFAULT: 'hsl(var(--primary))',
foreground: 'hsl(var(--primary-foreground))'
},
secondary: {
DEFAULT: 'hsl(var(--secondary))',
foreground: 'hsl(var(--secondary-foreground))'
},
muted: {
DEFAULT: 'hsl(var(--muted))',
foreground: 'hsl(var(--muted-foreground))'
},
accent: {
DEFAULT: 'hsl(var(--accent))',
foreground: 'hsl(var(--accent-foreground))'
},
destructive: {
DEFAULT: 'hsl(var(--destructive))',
foreground: 'hsl(var(--destructive-foreground))'
},
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
ring: 'hsl(var(--ring))',
chart: {
'1': 'hsl(var(--chart-1))',
'2': 'hsl(var(--chart-2))',
'3': 'hsl(var(--chart-3))',
'4': 'hsl(var(--chart-4))',
'5': 'hsl(var(--chart-5))'
}
}
}
}
} satisfies Config;
theme: {
extend: {
boxShadow: {
blur: "0 0 10px -1px rgba(0, 0, 0, 0.06)",
},
},
},
plugins: [tailwindcssAnimate],
} satisfies Config;
@@ -63,7 +63,7 @@
"eslint-plugin-react-refresh": "^0.4.16",
"eslint-plugin-storybook": "^0.11.2",
"globals": "^15.14.0",
"postcss": "^8.5.1",
"postcss": "^8.5.3",
"prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.11",
"storybook": "^8.5.3",
@@ -1,69 +1,10 @@
@import "@common/assets/styles/base.css";
@import "@common/assets/styles/diveicon.css";
@import "@common/assets/styles/components.css";
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: #ffffff;
--foreground: #0a0a0a;
--card: #ffffff;
--card-foreground: #0a0a0a;
--popover: #ffffff;
--popover-foreground: #0a0a0a;
--primary: #2094fa;
--primary-foreground: #fafafa;
--secondary: #f5f5f5;
--secondary-foreground: #0f1e33;
--muted: #f5f5f5;
--muted-foreground: #737373;
--accent: #f5f5f5;
--accent-foreground: #0f1e33;
--destructive: #ff4141;
--destructive-foreground: #fafafa;
--border: #e5e5e5;
--input: #e5e5e5;
--label: #666666;
--ring: #0a0a0a;
--chart-1: #d95b43;
--chart-2: #299392;
--chart-3: #263e4d;
--chart-4: #dfb938;
--chart-5: #f08634;
--radius: 1rem;
}
[data-mode="dark"] {
--background: #0a0a0a;
--foreground: #fafafa;
--card: #0a0a0a;
--card-foreground: #fafafa;
--popover: #0a0a0a;
--popover-foreground: #fafafa;
--primary: #2094fa;
--primary-foreground: #171717;
--secondary: #262626;
--secondary-foreground: #fafafa;
--muted: #262626;
--muted-foreground: #a2a2a2;
--accent: #262626;
--accent-foreground: #fafafa;
--destructive: #b22222;
--destructive-foreground: #fafafa;
--border: #262626;
--input: #262626;
--label: #f1f1f1;
--ring: #d4d4d4;
--chart-1: #3399ff;
--chart-2: #339966;
--chart-3: #ff9933;
--chart-4: #cc66ff;
--chart-5: #ff3399;
}
}
@layer base {
* {
@apply border-border;
@@ -74,4 +15,4 @@
body {
@apply bg-background text-foreground;
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,11 +0,0 @@
@layer base {}
@layer base {
* {
@apply border-border outline-ring/50;
}
body {
@apply bg-background text-foreground;
}
}
@@ -10,12 +10,22 @@ import { Button, Calendar, Popover, PopoverContent, PopoverTrigger } from "@comm
import { cn } from "../../lib/utils";
import { FormControl } from "../form";
import { ko } from "date-fns/locale";
import { useState } from "react";
type DatePickerProps = DayPickerSingleProps & { field: { value: Date; onChange: (date: Date | undefined) => void } ,selectClass:string|undefined };
export function DatePicker({ field, selectClass }: DatePickerProps) {
const [open, setOpen] = useState(false);
const handleSelect = (date: Date | undefined) => {
field.onChange(date); // React Hook Form 업데이트
setOpen(false);
};
return (
<Popover>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<FormControl>
<Button
@@ -28,7 +38,12 @@ export function DatePicker({ field, selectClass }: DatePickerProps) {
):selectClass}
>
{field?.value ? (
format(field?.value, "PPP")
format(
field.value instanceof Date && !isNaN(field.value.getTime())
? field.value
: new Date()
, "PPP", { locale: ko })
) : (
<span>Pick a date</span>
)}
@@ -40,7 +55,7 @@ export function DatePicker({ field, selectClass }: DatePickerProps) {
<Calendar
mode="single"
selected={field?.value}
onSelect={field?.onChange}
onSelect={handleSelect}
initialFocus
locale={ko}
/>
@@ -1,8 +1,8 @@
import React from 'react'
function ListDiv(props: {children: React.ReactNode}) {
function ListDiv(props: {children: React.ReactNode, className?: string|undefined}) {
return (
<div className="card card-border h-full">
<div className={`card card-border ${props.className}`}>
{props.children}
</div>
)
@@ -1,5 +1,5 @@
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@common/components";
import { useState } from "react";
import { useEffect, useState } from "react";
import UiPageNations from "./uiPageNations";
type UiTableProps = {
@@ -11,6 +11,7 @@ type UiTableProps = {
children: React.ReactNode | undefined;
cellClick : ((index:number|undefined)=>void) | undefined;
onPageChange: (page: number) => void;
className?: string;
}
type UiHeadProps = {
@@ -18,18 +19,33 @@ type UiHeadProps = {
title: string;
}
export function UiTable({ tableData, headlist, pageSize, total, children, headName, cellClick, onPageChange }: UiTableProps) {
export function UiTable({ tableData, headlist, pageSize, total, children, headName, cellClick, onPageChange, className = '' }: UiTableProps) {
const [cur, setCur] = useState<number>(1);
const [idx, setIdx] = useState<number>(0);
const handlePageChange = (page: number) => {
setCur(page);
onPageChange(page);
}
const handleCellClick = (index: number) => {
if (cellClick) {
console.log("cellClick", index);
cellClick(index);
setIdx(index);
}
};
useEffect(() => {
console.log("idx", idx);
console.log("idx", idx);
},[idx])
return (
<>
{headName ? <div className="card-header">
<h3 className="text-2xl font-medium text-label">{headName}</h3>
</div> : <></>}
<div className="card !m-[1.2rem] overflow-auto !p-0r">
<div className={`card !m-[1.2rem] !p-0r ${className}`}>
<Table>
<TableHeader>
{children ? <>{children}</> : <TableRow>
@@ -39,10 +55,11 @@ export function UiTable({ tableData, headlist, pageSize, total, children, headNa
</TableRow>}
</TableHeader>
<TableBody className='text-center'>
{tableData?.map((el: { [key: string]: string | number | boolean | object}, index) => (
<TableRow key={index + "row"} >
{tableData?.map((el: { [key: string]: any}, index) => (
<TableRow key={index + "row"} >
{headlist?.map((head) => (
<TableCell className="cursor-pointer" onClick={()=>cellClick && cellClick(index)} key={head.id + index}>{el[head.id]}</TableCell>
// <TableCell className={cellClick&&idx==index?"bg-black/10 cursor-pointer":cellClick?"cursor-pointer":""} onClick={()=>handleCellClick(index)} key={head.id + index}>{el[head.id]}</TableCell>
<TableCell className={cellClick&&idx==index?"opacity-40 cursor-pointer":cellClick?"cursor-pointer":""} onClick={()=>handleCellClick(index)} key={head.id + index}>{el[head.id]}</TableCell>
))}
</TableRow>
))}
@@ -52,4 +69,4 @@ export function UiTable({ tableData, headlist, pageSize, total, children, headNa
</div>
</>
);
}
}
@@ -1,93 +1,8 @@
import presetConfig from "../../../tailwind.config.preset";
/** @type {import('tailwindcss').Config} */
export default {
darkMode: ["class", "[data-mode='dark']"],
content: ["./src/**/*.{ts,tsx,js,jsx}", "./.storybook/**/*.{ts,tsx,js,jsx}"],
theme: {
extend: {
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
colors: {
background: "var(--background)",
foreground: "var(--foreground)",
card: {
DEFAULT: "var(--card)",
foreground: "var(--card-foreground)",
},
popover: {
DEFAULT: "var(--popover)",
foreground: "var(--popover-foreground)",
},
primary: {
DEFAULT: "var(--primary)",
foreground: "var(--primary-foreground)",
},
secondary: {
DEFAULT: "var(--secondary)",
foreground: "var(--secondary-foreground)",
},
muted: {
DEFAULT: "var(--muted)",
foreground: "var(--muted-foreground)",
},
accent: {
DEFAULT: "var(--accent)",
foreground: "var(--accent-foreground)",
},
destructive: {
DEFAULT: "var(--destructive)",
foreground: "var(--destructive-foreground)",
},
border: "var(--border)",
input: "var(--input)",
label: "var(--label)",
ring: "var(--ring)",
chart: {
1: "var(--chart-1)",
2: "var(--chart-2)",
3: "var(--chart-3)",
4: "var(--chart-4)",
5: "var(--chart-5)",
},
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
"spin-parent": {
from: { transform: "translate(-50%,-50%) rotate(0deg)" },
to: { transform: "translate(-50%,-50%) rotate(360deg)" },
},
"spin-child": {
from: { transform: "translate(0,0) rotate(0deg)" },
to: { transform: "translate(0,0) rotate(360deg)" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
"spin-parent": "spin-parent 6s linear infinite",
"spin-child": "spin-child 1s ease-in-out infinite",
},
backgroundImage: {
"gradient-blue": "linear-gradient(.25turn, #2094fa, #00e5dd)",
"gradient-blue-hover":
"linear-gradient(.25turn, #2298ff, #01dcda, #00e8b4)",
"gradient-green": "linear-gradient(.25turn, #00bad0, #00eb6f)",
"gradient-green-hover": "linear-gradient(.25turn, #00bad0, #12fe81)",
"gradient-red": "linear-gradient(.25turn, #ff487c, #ffc425)",
"gradient-red-hover": "linear-gradient(.25turn, #ff487c, #ffea3a)",
"gradient-purple": "linear-gradient(.25turn, #be30d7, #ff9264)",
"gradient-purple-hover": "linear-gradient(.25turn, #be30d7, #ffaf5a)",
},
},
},
presets: [presetConfig],
content: ["./src/**/*.{ts,tsx,js,jsx}"],
plugins: [require("tailwindcss-animate")],
};