Merge branch 'iipbs/wr/dev'
This commit is contained in:
@@ -6,22 +6,13 @@ import {
|
||||
Card,
|
||||
CardContent
|
||||
} from "./lib/card";
|
||||
import { ChartContainer, ChartTooltip } from "./lib/chart";
|
||||
import { ChartContainer, ChartTooltip, type ChartConfig } from "./lib/chart";
|
||||
|
||||
type ChartDataItem = {
|
||||
label: string;
|
||||
val: number;
|
||||
};
|
||||
|
||||
type ChartConfigItem = {
|
||||
label: string;
|
||||
fill: string;
|
||||
};
|
||||
|
||||
type ChartConfig = {
|
||||
[key: string]: ChartConfigItem;
|
||||
};
|
||||
|
||||
type TooltipPayloadItem = {
|
||||
name: string;
|
||||
value: number;
|
||||
@@ -47,20 +38,6 @@ type LegendProps = {
|
||||
payload?: LegendEntry[];
|
||||
};
|
||||
|
||||
/** 차트 기본 스타일 */
|
||||
/*
|
||||
const customStyles = {
|
||||
legendContainer: {
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
gap: "20px",
|
||||
fontSize: "9px",
|
||||
fontWeight: "bold",
|
||||
marginTop: "10px",
|
||||
} as CSSProperties,
|
||||
};
|
||||
*/
|
||||
|
||||
/** 차트 기본 스타일 (라인차트와 동일하게) */
|
||||
const customStyles = {
|
||||
legendContainer: {
|
||||
@@ -99,25 +76,6 @@ const CustomTooltip = ({ active, payload, label }: {
|
||||
return null;
|
||||
};
|
||||
|
||||
// 커스텀 범례
|
||||
/*
|
||||
const CustomLegend = (props: LegendProps) => {
|
||||
const { payload } = props;
|
||||
if (!payload) return null;
|
||||
|
||||
return (
|
||||
<div style={customStyles.legendContainer}>
|
||||
{payload.map((entry: LegendEntry, index: number) => (
|
||||
<div key={`legend-${index}`} className="flex items-center gap-2">
|
||||
<div className="w-[14px] h-[14px] ml-10" style={{ backgroundColor: entry.fill }}></div>
|
||||
<span className="text-[12px]">{entry.value}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
*/
|
||||
|
||||
const CustomLegend = (props: LegendProps) => {
|
||||
const { payload } = props;
|
||||
if (!payload) return null;
|
||||
@@ -154,14 +112,20 @@ const CustomLegend = (props: LegendProps) => {
|
||||
};
|
||||
|
||||
export default function DoughnutChart(props: {
|
||||
chartConfig: any;
|
||||
chartConfig: ChartConfig;
|
||||
chartData: ChartDataItem[] | undefined;
|
||||
chartTitle: string
|
||||
}) {
|
||||
const legendData = props.chartData?.map(item => ({
|
||||
value: item.label,
|
||||
fill: props.chartConfig?.[item.label]?.fill || 'blue',
|
||||
fill: props.chartConfig?.[item.label]?.color || 'blue',
|
||||
payload: {
|
||||
label: item.label,
|
||||
val: item.val,
|
||||
fill: props.chartConfig?.[item.label]?.color || 'blue'
|
||||
}
|
||||
})) ?? [];
|
||||
|
||||
return (
|
||||
<Card className="flex flex-col">
|
||||
<CardContent className="flex-1 pb-0">
|
||||
@@ -183,7 +147,7 @@ export default function DoughnutChart(props: {
|
||||
<Pie
|
||||
data={props.chartData?.map(item => ({
|
||||
...item,
|
||||
fill: props.chartConfig[item.label]?.fill || 'blue'
|
||||
fill: props.chartConfig[item.label]?.color || 'blue'
|
||||
}))}
|
||||
dataKey="val"
|
||||
nameKey="label"
|
||||
|
||||
@@ -128,7 +128,7 @@ export default function LineBarchart({
|
||||
tickCount={6}
|
||||
orientation="left"
|
||||
domain={[0, Math.ceil(lineMaxValue * 1)]}
|
||||
label={{ value: yFieldText, angle: -90, position: 'insideLeft' }}
|
||||
label={{ value: yFieldText, angle: -90, position: 'insideLeft', offset: -8 }}
|
||||
/>}
|
||||
{/* 오른쪽 Y축: barVal */}
|
||||
{yFieldText2 && <YAxis
|
||||
|
||||
@@ -8,6 +8,7 @@ import * as olProj from 'ol/proj';
|
||||
import { register } from 'ol/proj/proj4';
|
||||
import proj4 from 'proj4';
|
||||
import React, { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import GisLonLat from './GisLonLat';
|
||||
import GisMapToggle from './GisMapToggle';
|
||||
import GisSelect from './GisSelect';
|
||||
@@ -90,11 +91,11 @@ function Gis({
|
||||
if (layerName === '하수재이용시설') {
|
||||
featureId = data.searchPk;
|
||||
} else if (layerName === '빗물이용시설'|| layerName == '중수도시설') {
|
||||
featureId = data.bdstInfoPk;
|
||||
featureId = data.bdstInfoSn;
|
||||
} else if (layerName === '하수처리시설') {
|
||||
featureId = data.bscFctCd;
|
||||
} else if (layerName === '온배수시설' ) {
|
||||
featureId = data.bdstRuseFcltPk;
|
||||
featureId = data.bdstRuseFcltSn;
|
||||
} else {
|
||||
console.warn('해당 레이어에 대한 featureId 매핑 없음', layerNm);
|
||||
featureId = data.fid || data.id || data.ftrIdn;
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
import React from 'react';
|
||||
import { FormField } from "../form";
|
||||
import { SelectBox } from "../select";
|
||||
import { Input } from "@common/components";
|
||||
import { FormUi } from "../form_ui";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import { Input } from "@common/components";
|
||||
import { AsYouType } from "libphonenumber-js";
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import type { ControllerRenderProps, UseFormReturn } from "react-hook-form";
|
||||
import { FormField } from "../form";
|
||||
import { FormUi } from "../form_ui";
|
||||
import { SelectBox } from "../select";
|
||||
import { SdmSearchForm } from "./sdmNameBox";
|
||||
|
||||
// 수요처 정보
|
||||
export type DemandCompType = {
|
||||
index : number | '';
|
||||
dmdInfoPk : string | '';
|
||||
dmdInfoFk : string | '';
|
||||
dmdInfoId : string | '';
|
||||
bzmnNo : string | '';
|
||||
dmdCoNm : string | '';
|
||||
daddr : string | '';
|
||||
@@ -50,11 +48,11 @@ interface FormSchema {
|
||||
ctpvCd: string;
|
||||
sggCd: string;
|
||||
dmdCoNm: string;
|
||||
dmdInfoPk: string;
|
||||
dmdInfoId: string;
|
||||
daddr: string;
|
||||
telno: string;
|
||||
bznmTotNo?: string;
|
||||
rgtr?: string;
|
||||
rgtr?: string | '';
|
||||
dmdAplyPswd?: string;
|
||||
dmdAplyPswdConfirm?: string;
|
||||
}
|
||||
@@ -128,19 +126,19 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
type: string,
|
||||
field: ControllerRenderProps<FormSchema, keyof FormSchema> | undefined
|
||||
) => {
|
||||
if(!updateList?.dmdInfoPk)
|
||||
if(!updateList?.dmdInfoId)
|
||||
switch (type) {
|
||||
case "ctpvCd":
|
||||
initializeSigunData(val);
|
||||
setSidoValue(val);
|
||||
field?.onChange(val);
|
||||
form.setValue('dmdInfoPk', '');
|
||||
form.setValue('dmdInfoId', '');
|
||||
form.setValue('bznmTotNo', '');
|
||||
break;
|
||||
case "sggCd":
|
||||
setSigunValue(val);
|
||||
field?.onChange(val);
|
||||
form.setValue('dmdInfoPk', '');
|
||||
form.setValue('dmdInfoId', '');
|
||||
form.setValue('bznmTotNo', '');
|
||||
break;
|
||||
}
|
||||
@@ -159,11 +157,11 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
const rtnCompData = item;
|
||||
|
||||
form.setValue('dmdCoNm', rtnCompData?.dmdCoNm || '');
|
||||
form.setValue('dmdInfoPk', rtnCompData?.dmdInfoPk.substring(0,10) || '');
|
||||
form.setValue('bznmTotNo', rtnCompData?.dmdInfoPk.substring(10,14)==='0000' ? '' : rtnCompData?.dmdInfoPk.substring(10,14));
|
||||
form.setValue('dmdInfoId', rtnCompData?.dmdInfoId.substring(0,10) || '');
|
||||
form.setValue('bznmTotNo', rtnCompData?.dmdInfoId.substring(10,14)==='0000' ? '' : rtnCompData?.dmdInfoId.substring(10,14));
|
||||
|
||||
// 수요처 불러온 후 사업자번호를 바꿀경우를 대비함
|
||||
setOrgBznmNo(rtnCompData?.dmdInfoPk);
|
||||
setOrgBznmNo(rtnCompData?.dmdInfoId);
|
||||
const sidoCd = rtnCompData?.ctpvCd.trim() || '';
|
||||
setSidoValue(sidoCd);
|
||||
form.setValue('ctpvCd', sidoCd);
|
||||
@@ -175,7 +173,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
form.setValue('sggCd', sigunCd);
|
||||
}, 100);
|
||||
|
||||
if(rtnCompData?.dmdInfoPk.substring(10,14) === '0000') {
|
||||
if(rtnCompData?.dmdInfoId.substring(10,14) === '0000') {
|
||||
handleCheckboxChange(true);
|
||||
} else {
|
||||
handleCheckboxChange(false);
|
||||
@@ -195,7 +193,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
const bznNoChange = useCallback((e: React.ChangeEvent<HTMLInputElement>, noType: string, field?: ControllerRenderProps<FormSchema, keyof FormSchema>) => {
|
||||
const value = e.target.value;
|
||||
|
||||
if(noType === 'dmdInfoPk') {
|
||||
if(noType === 'dmdInfoId') {
|
||||
// 숫자만 추출하여 저장 (포맷팅 제거)
|
||||
const digitsOnly = value.replace(/\D/g, "");
|
||||
|
||||
@@ -217,15 +215,15 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if(updateList?.dmdInfoPk){
|
||||
if(updateList?.dmdInfoId){
|
||||
form.reset(updateList)
|
||||
if(updateList?.dmdInfoPk.slice(10,14) !== '0000') {
|
||||
if(updateList?.dmdInfoId.slice(10,14) !== '0000') {
|
||||
handleCheckboxChange( false);
|
||||
form.setValue('bznmTotNo', updateList?.dmdInfoPk.slice(10,14));
|
||||
form.setValue('bznmTotNo', updateList?.dmdInfoId.slice(10,14));
|
||||
} else {
|
||||
handleCheckboxChange( true);
|
||||
}
|
||||
form.setValue('dmdInfoPk', updateList?.dmdInfoPk.slice(0,10));
|
||||
form.setValue('dmdInfoId', updateList?.dmdInfoId.slice(0,10));
|
||||
setUpdateNm(updateList?.dmdCoNm)
|
||||
// setSigunValue(updateList?.sggCd)
|
||||
}else{
|
||||
@@ -246,14 +244,14 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
name: "ctpvCd",
|
||||
label: "시도",
|
||||
component: (field) => (
|
||||
updateList?.dmdInfoPk ? (
|
||||
updateList?.dmdInfoId ? (
|
||||
<Input
|
||||
placeholder="시도"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
onChange={(e) =>{field.onChange(e.target.value)} }
|
||||
value={ selectSidoData.find(item => item.val === field.value?.trim() )?.text??''}
|
||||
readOnly={!!updateList?.dmdInfoPk}
|
||||
readOnly={!!updateList?.dmdInfoId}
|
||||
/>
|
||||
) : (
|
||||
<SelectBox
|
||||
@@ -271,14 +269,14 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
name: "sggCd",
|
||||
label: "시군구",
|
||||
component: (field) => (
|
||||
updateList?.dmdInfoPk ? (
|
||||
updateList?.dmdInfoId ? (
|
||||
<Input
|
||||
placeholder="시도"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
onChange={(e) =>{field.onChange(e.target.value)} }
|
||||
value={selectSigunData.find(item => item.val === field.value?.trim() )?.text??''}
|
||||
readOnly={!!updateList?.dmdInfoPk}
|
||||
readOnly={!!updateList?.dmdInfoId}
|
||||
/>
|
||||
) : (
|
||||
<SelectBox
|
||||
@@ -309,16 +307,16 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
)
|
||||
},
|
||||
{
|
||||
name: "dmdInfoPk",
|
||||
name: "dmdInfoId",
|
||||
label: "사업자등록번호",
|
||||
component: (field) => (
|
||||
<Input
|
||||
placeholder="사업자등록번호를 입력하세요"
|
||||
type="text"
|
||||
className="!text-xl text-gray-600"
|
||||
onChange={(e) => bznNoChange(e, 'dmdInfoPk', field)}
|
||||
onChange={(e) => bznNoChange(e, 'dmdInfoId', field)}
|
||||
value={formatBusinessNumber(field.value || '')}
|
||||
readOnly={!!updateList?.dmdInfoPk}
|
||||
readOnly={!!updateList?.dmdInfoId}
|
||||
/>
|
||||
)
|
||||
},
|
||||
@@ -339,7 +337,7 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
onChange={(e) => bznNoChange(e, 'bznmTotNo', field)}
|
||||
// {...field}
|
||||
value={ field.value}
|
||||
readOnly={!!updateList?.dmdInfoPk}
|
||||
readOnly={!!updateList?.dmdInfoId}
|
||||
/>
|
||||
</FormUi>
|
||||
)
|
||||
@@ -407,12 +405,12 @@ export function SdmRegForm({ form, onCheckboxChange, selectSidoData, selectSigun
|
||||
return (
|
||||
<>
|
||||
{formFields
|
||||
.filter(({ name }) => !(updateList?.dmdInfoPk && (name === "dmdAplyPswd" || name === "dmdAplyPswdConfirm")))
|
||||
.filter(({ name }) => !(updateList?.dmdInfoId && (name === "dmdAplyPswd" || name === "dmdAplyPswdConfirm")))
|
||||
.map(({ name, label, component }) => {
|
||||
const error = form.formState.errors[name];
|
||||
const inputId = `${name}-input`;
|
||||
const errorId = `${name}-error`;
|
||||
const isRequired = ["ctpvCd", "sggCd", "dmdCoNm", "dmdInfoPk", "daddr", "telno", "dmdAplyPswd", "dmdAplyPswdConfirm"].includes(name);
|
||||
const isRequired = ["ctpvCd", "sggCd", "dmdCoNm", "dmdInfoId", "daddr", "telno", "dmdAplyPswd", "dmdAplyPswdConfirm"].includes(name);
|
||||
|
||||
return (
|
||||
<FormField
|
||||
|
||||
@@ -25,7 +25,7 @@ const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean ,up
|
||||
dmdCoNm: z.string()
|
||||
.min(1, "회사명을 입력해주세요")
|
||||
.max(20, "회사명은 20자 이내로 입력해주세요"),
|
||||
dmdInfoPk: z.string()
|
||||
dmdInfoId: z.string()
|
||||
.min(1, "사업자등록번호를 입력해주세요")
|
||||
.regex(/^\d{10}$/, "사업자등록번호는 10자리 숫자만 입력 가능합니다")
|
||||
.refine(() => isBznmTotNoDisabled ? !isDuplicate : true, "이미 등록된 사업자등록번호입니다"),
|
||||
@@ -42,12 +42,12 @@ const createFormSchema = (isBznmTotNoDisabled: boolean, isDuplicate: boolean ,up
|
||||
.min(8, "전화번호는 8자 이상 입력해주세요")
|
||||
.max(11, "전화번호는 11자 이내로 입력해주세요")
|
||||
.regex(/^[0-9]+$/, "전화번호는 숫자만 입력 가능합니다"),
|
||||
rgtr: z.string().nullish(),
|
||||
dmdAplyPswd : updateList?.dmdInfoPk // 업데이트일경우
|
||||
rgtr: z.string().optional(),
|
||||
dmdAplyPswd : updateList?.dmdInfoId // 업데이트일경우
|
||||
? z.string().optional() // 패스워드는 선택 사항이며 길이 제한 없음
|
||||
: z.string().optional()
|
||||
.refine((val) => !val || (val.length >= 8 && val.length <= 16), "패스워드는 8자 이상 16자 이내로 입력해주세요"),
|
||||
dmdAplyPswdConfirm: updateList?.dmdInfoPk // 업데이트일경우
|
||||
dmdAplyPswdConfirm: updateList?.dmdInfoId // 업데이트일경우
|
||||
? z.string().optional() // 패스워드는 선택 사항이며 길이 제한 없음
|
||||
:z.string()
|
||||
.min(1, "패스워드확인을 입력해주세요"),
|
||||
@@ -68,7 +68,7 @@ const defaultValues: FormSchema = {
|
||||
ctpvCd: '',
|
||||
sggCd: '',
|
||||
dmdCoNm: '',
|
||||
dmdInfoPk: '',
|
||||
dmdInfoId: '',
|
||||
bznmTotNo: '',
|
||||
daddr: '',
|
||||
telno: '',
|
||||
@@ -152,11 +152,11 @@ export default function SdmInsertForm({selectSidoData, selectSigunData, dataList
|
||||
return;
|
||||
}
|
||||
|
||||
const dmdInfoPk = data.dmdInfoPk + (data.bznmTotNo || '0000');
|
||||
const dmdInfoId = data.dmdInfoId + (data.bznmTotNo || '0000');
|
||||
const formData = {
|
||||
...data,
|
||||
dmdInfoPk,
|
||||
bzmnNo: data.dmdInfoPk,
|
||||
dmdInfoId,
|
||||
bzmnNo: data.dmdInfoId,
|
||||
};
|
||||
|
||||
console.log(' formData ', formData)
|
||||
|
||||
@@ -102,19 +102,19 @@ export const SdmSearchForm = ({
|
||||
}
|
||||
}}
|
||||
>
|
||||
{item.dmdInfoPk.substring(10, 14) !== "0000" ? (
|
||||
{item.dmdInfoId.substring(10, 14) !== "0000" ? (
|
||||
<>
|
||||
<span className="text-gray-500">사업자번호 : </span>{" "}
|
||||
{item.dmdInfoPk.substring(0, 10)}
|
||||
{item.dmdInfoId.substring(0, 10)}
|
||||
<span className="text-gray-500">
|
||||
종사업자번호 :{" "}
|
||||
</span>{" "}
|
||||
{item.dmdInfoPk.substring(10, 14)}
|
||||
{item.dmdInfoId.substring(10, 14)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-gray-500">사업자번호 : </span>{" "}
|
||||
{item.dmdInfoPk.substring(0, 10)}
|
||||
{item.dmdInfoId.substring(0, 10)}
|
||||
</>
|
||||
)}
|
||||
<span className="float-right">{item.dmdCoNm}</span>
|
||||
|
||||
@@ -9,7 +9,7 @@ interface TabItem {
|
||||
interface UITabProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'dir'> {
|
||||
defaultValue?: string;
|
||||
tabList: TabItem[];
|
||||
children: React.ReactNode;
|
||||
children?: React.ReactNode;
|
||||
onValueChange?: (value: string) => void;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,13 @@ export function UiTable({ tableData, headlist, pageSize, total, headName, childr
|
||||
)
|
||||
))}
|
||||
</TableRow>
|
||||
)) : <></>}
|
||||
)) : (
|
||||
<TableRow>
|
||||
<TableCell colSpan={headlist.filter((item) => item.visible != false).length} className="h-24 text-center text-gray-500">
|
||||
조회된 결과가 없습니다.
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{total <= 0 ? <></> : <UiPageNations total={total} cur={cur} pageSize={pageSize} onPageChange={handlePageChange} />}
|
||||
|
||||
Reference in New Issue
Block a user