Merge remote-tracking branch 'origin/iipbs/dm/dev'

This commit is contained in:
yschoi
2025-08-04 08:24:10 +09:00
8 changed files with 234 additions and 142 deletions
@@ -123,33 +123,33 @@ export default function SdmApplyList({}: SdmApplyProps) {
</TableRow>
<TableRow>
<TableCell colSpan={1} className={TABLE_STYLES.header}>총대장균군수(개/100ml)</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.grssClfg ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{ sdmApplyDetail?.grssClfg!=-1?<TransValueFormat value={sdmApplyDetail?.grssClfg ?? ''} format="number"/>:''} {sdmApplyDetail?.grssClfg?sdmApplyDetail.grssClfg!=-1? '이하':'불검출':'-'} </TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.header}>결합잔류염소(mg/L)​</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.combResdch ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.combResdch ?? ''} format="number"/>} {sdmApplyDetail?.combResdch?'이하':'-'}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.header}>탁도(NTU)</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.trbt ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.trbt ?? ''} format="number"/>} {sdmApplyDetail?.trbt?'이하':'-'}</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={1} className={TABLE_STYLES.header}>생물학적 산소요구량(BOD)(mg/L)</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.blgcOxygDmndQnt ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.blgcOxygDmndQnt ?? ''} format="number"/>} {sdmApplyDetail?.blgcOxygDmndQnt?'이하':'-'}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.header}>냄새</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.smll} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.smll} format="number"/>} {sdmApplyDetail?.smll?'이하':'-'}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.header}>색도(도)</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.crmty ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.crmty ?? ''} format="number"/>} {sdmApplyDetail?.crmty?'이하':'-'}</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={1} className={TABLE_STYLES.header}>총질소(T-N)(mg/L)</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.tn ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.tn ?? ''} format="number"/>} {sdmApplyDetail?.tn?'이하':'-'}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.header}>총인(T-P)(mg/L)​</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.tph ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.tph ?? ''} format="number"/>} {sdmApplyDetail?.tph?'이하':'-'}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.header}>수소이온농도(pH)​</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.ph} format="number"/>}</TableCell>
</TableRow>
<TableRow>
<TableCell colSpan={1} className={TABLE_STYLES.header}>염화물(mgCL/L)​</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.clIonQnt ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.clIonQnt ?? ''} format="number"/>} {sdmApplyDetail?.clIonQnt?'이하':'-'}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.header}>전기전도도(㎲/cm)​</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.cdtnv ?? ''} format="number"/>}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{<TransValueFormat value={sdmApplyDetail?.cdtnv ?? ''} format="number"/>} {sdmApplyDetail?.cdtnv?'이하':'-'}</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.header}>비고</TableCell>
<TableCell colSpan={1} className={TABLE_STYLES.cell}>{sdmApplyDetail?.rmrk}</TableCell>
</TableRow>
@@ -1,7 +1,7 @@
"use client";
import { useDmStore } from "@/app/store";
import type { DemandCompBizType } from "@/app/store/sdmMng";
import { sdmInfoFormSchema, type DemandCompBizType, type SdmInfoFormData } from "@/app/store/sdmMng";
import { SdmInfoRegForm } from "@/components/ui/sdmInfoInsertForm/component";
import { UiModal } from "@common/business_components/ui/dialog_ui";
import { Button } from "@common/components/ui";
@@ -9,49 +9,10 @@ import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter, useSearchParams } from "next/navigation";
import { Suspense, useEffect, useState } from "react";
import { FormProvider, useForm, type SubmitHandler } from "react-hook-form";
import { Toaster } from "react-hot-toast";
import * as z from "zod";
import toast, { Toaster } from "react-hot-toast";
import SdmLogin from "../sdmLogin/page";
const sdmInfoFormSchema = z.object({
sdmNm: z.string().min(1, "수요처를 선택해주세요"),
demandYmd: z.date().optional(),
demandQnty: z
.string()
.min(1, "요구수량을 입력해주세요")
.regex(/^[0-9]+$/, "요구수량은 숫자만 입력 가능합니다"),
usePurpose: z.string().optional(),
money: z.string().regex(/^[0-9]+$/, "희망단가는 숫자만 입력 가능합니다"),
/**요구수질 */
reqWaterQlty: z.string().optional(),
grssClfg: z.number().nullish(),
tn: z.number().nullish(),
combResdch: z.number().nullish(),
tph: z.number().nullish(),
trbt: z.number().nullish(),
ph: z.string().nullish(),
bod: z.number().nullish(),
/**컬럼확인필요 */
clIonQnt: z.number().nullish(),
smll: z.string(),
cdtnv: z.number().nullish(),
crmty: z.number().nullish(),
rmrk: z.string().optional(),
/* telno: z.string()
.min(8, "전화번호는 8자 이상 입력해주세요")
.max(12, "전화번호는 12자 이내로 입력해주세요")
.regex(/^[0-9-]+$/, "전화번호는 숫자와 하이픈(-)만 입력 가능합니다"), */
candidateTitle: z
.array(
z.object({
ruseUtztnFcltNm: z.string(),
ruseUtztnFcltCd: z.string(),
})
)
.optional(),
});
export type FormData = z.infer<typeof sdmInfoFormSchema>;
function SdmInfoInsertContent() {
const searchParams = useSearchParams();
@@ -62,7 +23,7 @@ function SdmInfoInsertContent() {
const [isLogin, setIsLogin] = useState(false);
const [facilityName, setFacilityName] = useState<string>("");
const [defaultValues, setDefaultValues] = useState<FormData>({
const [defaultValues, setDefaultValues] = useState<SdmInfoFormData>({
sdmNm: "",
demandYmd: new Date(),
demandQnty: "",
@@ -109,10 +70,10 @@ function SdmInfoInsertContent() {
setSubsInfo([]); // subsInfo 초기화 후보지 처음 화면 들어올때 초기화(스토어내 객체만)
}, [setSubsInfo]);
const form = useForm<FormData>({
const form = useForm<SdmInfoFormData>({
resolver: zodResolver(formSchema),
defaultValues,
mode: "onChange",
mode: "onSubmit",
});
const subsInfo = useDmStore((state) => state.map.subsInfo);
@@ -167,7 +128,7 @@ function SdmInfoInsertContent() {
}
}, [ismoneyDisabled, form]);
const router = useRouter();
const onSubmit: SubmitHandler<FormData> = async (data) => {
const onSubmit: SubmitHandler<SdmInfoFormData> = async (data) => {
try {
const dmSubsInfo = data.candidateTitle?.filter(
(item) => item.ruseUtztnFcltNm && item.ruseUtztnFcltCd
@@ -291,6 +252,7 @@ function SdmInfoInsertContent() {
open={!isLogin}
onOpenChange={(open) => {
if (!open) {
toast.dismiss();
router.push("/");
}
}}
@@ -131,7 +131,7 @@ export default function WrAboutPage() {
물재이용 필요성
</h2>
<section aria-labelledby="card2-desc" className="bg-white border border-gray-300 rounded-xl p-[60px] pt-[70px] pb-[70px] ">
<h1 id="card2-desc" className="font-NotoSansKR text-[#ED5534] text-5xl font-semibold mb-8">물 재이용, 왜 필요한가요?</h1>
<h1 id="card2-desc" className="font-NotoSansKR text-[#D63F1F] text-5xl font-semibold mb-8">물 재이용, 왜 필요한가요?</h1>
<p className="font-NotoSansKR text-2xl font-normal mb-10 leading-relaxed">
빗물, 중수, 하수처리수는 지속적으로 이용 가능한 순환자원입니다.<br />
물 재이용을 통한 효율적인 수자원 활용은 물 스트레스국가인 우리나라에서<br />가뭄대응능력 향상 및 하천수질보전을 위해 반드시 필요한 일입니다.
@@ -237,7 +237,7 @@ export default function WrAboutPage() {
하수 재이용
</h2>
<section aria-labelledby="card5-desc" className="bg-white border border-gray-300 rounded-xl p-[60px] pt-[70px] pb-[70px] ">
<h1 id="card5-desc" className="font-NotoSansKR leading-snug text-[#0099A4] text-5xl font-bold mb-6">아직 할 일이 많은 하수처리수,<br />풍족하게 재이용할 수 있어요!</h1>
<h1 id="card5-desc" className="font-NotoSansKR leading-snug text-[#00818A] text-5xl font-bold mb-6">아직 할 일이 많은 하수처리수,<br />풍족하게 재이용할 수 있어요!</h1>
<p className="font-NotoSansKR text-2xl mb-10 leading-relaxed">사용하고 버려져 공공하수처리장으로 모여든 물은<br />용도에 맞는 처리 후 재이용 할 수 있습니다.</p>
<Image
src="/img/wrAbout/img_05_1.png"
+3
View File
@@ -8,6 +8,9 @@ export default function RootLayout({
}>) {
return (
<html lang="ko">
<head>
<title>물재이용 대민</title>
</head>
<body>
{children}
</body>
+106 -4
View File
@@ -3,10 +3,105 @@ import type { SelectDataType } from "@common/business_components/ui";
import type { TableUpperProps } from "../common";
import toast from "react-hot-toast";
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
import { z } from "zod";
/**====================================
* Store - 타입
=====================================*/
export const sdmInfoFormSchema = z.object({
sdmNm: z.string().min(1, "수요처를 선택해주세요"),
demandYmd: z.date().optional(),
demandQnty: z
.string()
.min(1, "요구수량을 입력해주세요")
.regex(/^[0-9]+$/, "요구수량은 숫자만 입력 가능합니다"),
usePurpose: z.string().optional(),
money: z.string().regex(/^[0-9]+$/, "희망단가는 숫자만 입력 가능합니다"),
/**요구수질 */
reqWaterQlty: z.string().optional(),
grssClfg: z.number().nullish(),
tn: z.number().nullish(),
combResdch: z.number().nullish(),
tph: z.number().nullish(),
trbt: z.number().nullish(),
ph: z.string().nullish(),
bod: z.number().nullish(),
/**컬럼확인필요 */
clIonQnt: z.number().nullish(),
smll: z.string(),
cdtnv: z.number().nullish(),
crmty: z.number().nullish(),
rmrk: z.string().optional(),
/* telno: z.string()
.min(8, "전화번호는 8자 이상 입력해주세요")
.max(12, "전화번호는 12자 이내로 입력해주세요")
.regex(/^[0-9-]+$/, "전화번호는 숫자와 하이픈(-)만 입력 가능합니다"), */
candidateTitle: z
.array(
z.object({
ruseUtztnFcltNm: z.string(),
ruseUtztnFcltCd: z.string(),
})
)
.optional(),
}).superRefine((data, ctx) => {
const disabledFields = disableRules[data.usePurpose ?? ""] || [];
// 모든 수질 관련 필드
// 총대장균군수는 null 값을 불검출로 표시하기때문에 해당 검사에서 제외함.
const allFields: (keyof typeof data)[] = [
"tn", "combResdch", "tph",
"trbt", "ph", "bod", "clIonQnt",
"smll", "cdtnv", "crmty",
];
const allFieldsName: Record<string, string> = {
tn: "총질소(T-N)(mg/L)",
combResdch: "결합잔류염소(mg/L)",
tph: "총인(T-P)(mg/L)",
trbt: "탁도(NTU)",
ph: "수소이온농도(pH)",
bod: "생물학적 산소요구량(BOD)(mg/L)",
clIonQnt: "염화물(mgCL/L)",
smll: "냄새",
cdtnv: "전기전도도(㎲/cm)",
crmty: "색도(도)",
};
allFields.forEach((field) => {
const isDisabled = disabledFields.includes(field);
if (!isDisabled) {
// disabled가 아닌 필드는 반드시 값이 있어야 함
const value = data[field];
if (typeof value === "string") {
if (value.trim().length === 0) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: [field],
message: `${allFieldsName[field]} 을 입력해주세요.`,
});
}
} else if (typeof value === "number") {
if (value <= 0 || Number.isNaN(value)) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: [field],
message: `${allFieldsName[field]} 을 입력해주세요.`,
});
}
} else if (value == null) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
path: [field],
message: `${allFieldsName[field]} 을 입력해주세요.`,
});
}
}
});
});
export type SdmInfoFormData = z.infer<typeof sdmInfoFormSchema>;
// 수요처 정보
export type DemandCompBizType = {
index : number | '';
@@ -167,8 +262,8 @@ const demandCompList : DemandCompType[] = [
const disableRules: DisableRulesType = {
"청소": ["tn", 'tph',"clIonQnt" ,'cdtnv'],
"화장실용수": ["tn", 'tph',"clIonQnt" ,'cdtnv'],
"세척": ["combResdch", "crmty",'tph',"clIonQnt",'cdtnv'],
"살수": ["combResdch", "crmty",'tph',"clIonQnt",'cdtnv'],
"세척": ["combResdch", "crmty",'tph','tn',"clIonQnt",'cdtnv'],
"살수": ["combResdch", "crmty",'tph','tn',"clIonQnt",'cdtnv'],
"조경": ["combResdch", "crmty",'tph','cdtnv'],
"농업_간접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'],
"농업_직접용수": ["combResdch", "crmty",'tn','tph','clIonQnt'],
@@ -184,6 +279,7 @@ const disableRules: DisableRulesType = {
bod: 5,
crmty: 20,
ph: "5.8~8.5",
smll:'불쾌하지않을것',
tn:null,
tph: null,
clIonQnt: null,
@@ -196,6 +292,7 @@ const disableRules: DisableRulesType = {
trbt: 2,
bod: 5,
crmty: 20,
smll:'불쾌하지않을것',
ph: "5.8~8.5",
tn:null,
tph: null,
@@ -208,6 +305,7 @@ const disableRules: DisableRulesType = {
bod: 5,
ph: "5.8~8.5",
combResdch:null,
smll:'불쾌하지않을것',
crmty:null,
tn:null,
tph: null,
@@ -219,6 +317,7 @@ const disableRules: DisableRulesType = {
trbt: 2,
bod: 5,
ph: "5.8~8.5",
smll:'불쾌하지않을것',
combResdch:null,
crmty:null,
tn:null,
@@ -231,6 +330,7 @@ const disableRules: DisableRulesType = {
trbt: 2,
bod: 5,
ph: "5.8~8.5",
smll:'불쾌하지않을것',
clIonQnt:250,
combResdch:null,
crmty:null,
@@ -254,6 +354,7 @@ const disableRules: DisableRulesType = {
grssClfg: null,
trbt: 2,
bod: 8,
smll:'불쾌하지않을것',
ph: "5.8~8.5",
cdtnv:700,
combResdch:null,
@@ -267,6 +368,7 @@ const disableRules: DisableRulesType = {
bod: 5,
tn: 10,
tph: 0.5,
smll:'불쾌하지않을것',
ph: "5.8~8.5",
combResdch:null,
trbt:null,
@@ -274,13 +376,14 @@ const disableRules: DisableRulesType = {
clIonQnt: null,
cdtnv:null
},
공업:{
'공업':{
grssClfg: null,
bod: null,
tn: null,
tph: null,
ph: "~",
combResdch:null,
smll:'불쾌하지않을것',
trbt:null,
crmty:null,
clIonQnt: null,
@@ -298,7 +401,6 @@ const useTypesData : SelectDataType[] = [
{ text: "농업_간접용수", val: "농업_간접용수" },
{ text: "농업_직접용수", val: "농업_직접용수" },
{ text: "하천", val: "하천" },
{ text: "지하수", val: "지하수" },
{ text: "공업", val: "공업" },
];
@@ -1,5 +1,4 @@
import ModalSimilarPage from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/modalSimilar/page";
import type { FormData } from "@/app/(base-layout)/pages/sdmMng/sdmInfoInsert/page";
import { useDmStore } from "@/app/store";
import {
CANDIDATE,
@@ -25,15 +24,16 @@ import SearchInputText from "../common/searhDemandInput/component";
import React from "react";
import { sanitizeInput } from "../common/utils/utils";
import type { DemandCompType } from "@common/business_components/ui/sdmInsertForm/form";
import type { SdmInfoFormData } from "@/app/store/sdmMng";
export interface SdmInfoRegFormProps {
form: UseFormReturn<FormData>;
form: UseFormReturn<SdmInfoFormData>;
onCheckboxChange?: (checked: boolean) => void;
facilityName?: string;
}
type FieldComponent = (
field: ControllerRenderProps<FormData, keyof FormData>
field: ControllerRenderProps<SdmInfoFormData, keyof SdmInfoFormData>
) => JSX.Element;
export function SdmInfoRegForm({
@@ -159,11 +159,9 @@ export function SdmInfoRegForm({
// Apply default values
const defaults = defaultRules[usePurpose];
console.log("usePurpose", usePurpose);
console.log("defaults", defaults);
if (defaults) {
Object.entries(defaults).forEach(([field, value]) => {
form.setValue(field as keyof FormData, value, { shouldDirty: true });
form.setValue(field as keyof SdmInfoFormData, value, { shouldDirty: true });
});
}
}, [form.getValues("usePurpose")]);
@@ -178,7 +176,7 @@ export function SdmInfoRegForm({
);
const formFields: Array<{
name: keyof FormData;
name: keyof SdmInfoFormData;
label: string;
component: FieldComponent | undefined;
formIndex: number;
@@ -348,9 +346,7 @@ export function SdmInfoRegForm({
const normalFields = formFields.filter(
(f) => f.formIndex === 0 && f.component
);
// const groupFields = formFields.filter(
// (f) => f.formIndex === 1 && f.component
// );
const candidateFields = formFields.filter(
(f) => f.formIndex === 2 && f.component
);
@@ -365,8 +361,13 @@ export function SdmInfoRegForm({
name={name}
render={({ field }) =>
name === "money" ? (
// component(field)
<FormUi label={label + "*"}>{component(field)}</FormUi>
<div>
<Label className="text-black" >
희망단가*
</Label>
{ component(field)}
</div>
// <FormUi label={label + "*"}>{component(field)}</FormUi>
) : (
<AccessibleFormField
field={field}
@@ -771,7 +772,7 @@ export function SdmInfoRegForm({
onSelectValue={(val: string | number) => {
field.onChange(val.toString());
}}
value={field.value || "불쾌하지않을것"}
value={field.value }
readOnly={isDisabled}
onBlur={field.onBlur}
ref={field.ref}
@@ -4,8 +4,9 @@ import type { DemandCompType } from "@common/business_components/ui/sdmInsertFor
import { Button, Input } from "@common/components";
import { zodResolver } from "@hookform/resolvers/zod";
import { sha512 } from 'js-sha512';
import { useEffect, useState, useMemo } from "react";
import { useEffect, useMemo, useState } from "react";
import { FormProvider, useForm, type ControllerRenderProps } from "react-hook-form";
import toast from "react-hot-toast";
import * as z from "zod";
export function SdmLoginForm() {
@@ -15,10 +16,10 @@ export function SdmLoginForm() {
const formatBusinessNumber = (value: string) => {
// 숫자만 추출
const digitsOnly = value.replace(/\D/g, "");
// 10자리까지만 처리
const limitedDigits = digitsOnly.slice(0, 10);
// 3-2-5 형식으로 포맷팅
if (limitedDigits.length <= 3) {
return limitedDigits;
@@ -28,33 +29,33 @@ export function SdmLoginForm() {
return `${limitedDigits.slice(0, 3)}-${limitedDigits.slice(3, 5)}-${limitedDigits.slice(5)}`;
}
};
// 스키마를 useMemo로 최적화
const sdmLoginFormSchema = useMemo(() => z.object({
dmdInfoId: z.string()
.min(1, "사업자등록번호를 입력해주세요")
.regex(/^\d{10}$/, "사업자등록번호는 10자리 숫자만 입력 가능합니다"),
bznmTotNo: isBznmTotNoDisabled
bznmTotNo: isBznmTotNoDisabled
? z.string().optional()
: z.string().length(4, "종사업자등록번호는 4자리 숫자만 입력 가능합니다"),
password: z.string()
.min(1, "비밀번호를 입력해주세요")
.min(8, "비밀번호는 8자 이상 입력해주세요")
.min(8, "비밀번호는 8자 이상 입력해주세요")
.max(16, "비밀번호는 16자 이내로 입력해주세요"),
rgtr: z.string().optional(),
dmdAplyPswd: z.string().optional(),
}), [isBznmTotNoDisabled]);
type FormData = z.infer<typeof sdmLoginFormSchema>;
type FieldComponent = (field: ControllerRenderProps<FormData, keyof FormData>) => JSX.Element;
type SdmLoginForm = z.infer<typeof sdmLoginFormSchema>;
type FieldComponent = (field: ControllerRenderProps<SdmLoginForm, keyof SdmLoginForm>) => JSX.Element;
const formSchema = sdmLoginFormSchema;
useEffect(() => {
initializeCommonData();
}, [initializeCommonData]);
const defaultValues: FormData = {
const defaultValues: SdmLoginForm = {
dmdInfoId: '',
bznmTotNo: '',
password: '',
@@ -62,7 +63,7 @@ export function SdmLoginForm() {
dmdAplyPswd: '',
};
const form = useForm<FormData>({
const form = useForm<SdmLoginForm>({
resolver: zodResolver(formSchema),
defaultValues,
mode: "onChange",
@@ -72,6 +73,26 @@ export function SdmLoginForm() {
setIsBznmTotNoDisabled(checked);
};
const initPassword = () => {
toast(
(t) => (
<div className="flex flex-col items-center">
<div className="text-2xl mb-2">
관리자(031-0000-0000)에게 비밀번호 초기화 요청을 유선으로 하시기 바랍니다.
</div>
<Button size={"sm"} onClick={() => toast.dismiss(t.id)}>
확인
</Button>
</div>
),
{
id: "pwd-reset",
duration: Infinity,
position: "top-center",
}
);
}
const handleLogin = () => {
const data = form.getValues();
const passwordStr = sha512.hex(data.password)
@@ -82,61 +103,61 @@ export function SdmLoginForm() {
}
actionLogin(param as unknown as DemandCompType);
};
const formFields: Array<{
name: keyof FormData;
name: keyof SdmLoginForm;
label: string;
component: FieldComponent | undefined;
}> = [
{
name: "dmdInfoId",
label: "사업자등록번호",
component: (field) => (
<Input
placeholder="사업자등록번호를 입력하세요"
type="text"
className="!mt-5 !mb-5 !text-xl text-gray-600"
{...field}
value={formatBusinessNumber(field.value as string)}
onChange={(e) => {
const dmdId = e.target.value.replace(/\D/g, "").slice(0, 10);
field.onChange(dmdId);
}}
/>
)
},
{
name: "bznmTotNo",
label: BZNM_TOT_NO || "종사업자등록번호",
component: (field) => (
<FormUi
label="종사업자등록번호"
onCheckboxChange={handleCheckboxChange}
isDisabled={isBznmTotNoDisabled}
>
<Input
placeholder="여러사업장이 있을 경우 입력해주세요"
{
name: "dmdInfoId",
label: "사업자등록번호",
component: (field) => (
<Input
placeholder="사업자등록번호를 입력하세요"
type="text"
className="!mt-5 !text-xl text-gray-600"
disabled={isBznmTotNoDisabled}
className="!mt-5 !mb-5 !text-xl text-gray-600"
{...field}
value={formatBusinessNumber(field.value as string)}
onChange={(e) => {
const dmdId = e.target.value.replace(/\D/g, "").slice(0, 10);
field.onChange(dmdId);
}}
/>
)
},
{
name: "bznmTotNo",
label: BZNM_TOT_NO || "종사업자등록번호",
component: (field) => (
<FormUi
label="종사업자등록번호"
onCheckboxChange={handleCheckboxChange}
isDisabled={isBznmTotNoDisabled}
>
<Input
placeholder="여러사업장이 있을 경우 입력해주세요"
type="text"
className="!mt-5 !text-xl text-gray-600"
disabled={isBznmTotNoDisabled}
{...field}
/>
</FormUi>
)
},
{
name: "password",
label: "비밀번호",
component: (field) => (
<Input
placeholder="비밀번호를 입력하세요"
type="password"
className="!mt-5 !mb-5 !text-xl text-gray-600"
{...field}
/>
</FormUi>
)
},
{
name: "password",
label: "비밀번호",
component: (field) => (
<Input
placeholder="비밀번호를 입력하세요"
type="password"
className="!mt-5 !mb-5 !text-xl text-gray-600"
{...field}
/>
)
}
];
)
}
];
return (
<>
@@ -148,11 +169,11 @@ export function SdmLoginForm() {
control={form.control}
name={name}
render={({ field }) => (
label==='종사업자등록번호' ?
<>
label === '종사업자등록번호' ?
<>
{component && component(field)}
</>
: <FormUi label={label}>
: <FormUi label={label}>
{component && component(field)}
</FormUi>
)}
@@ -160,12 +181,15 @@ export function SdmLoginForm() {
))}
</FormProvider>
<div className="flex justify-center pt-4">
<Button
onClick={handleLogin}
className="w-32 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-md transition-colors duration-200"
>
로그인
</Button>
<div className="flex flex-col items-center">
<Button
onClick={handleLogin}
className="w-32 bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-4 rounded-md transition-colors duration-200"
>
로그인
</Button>
<div className="text-xl mt-2 text-gray-400 cursor-pointer" onClick={initPassword}>비밀번호 초기화 요청</div>
</div>
</div>
</div>
</>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 35 KiB