// Subscription.tsx
import React, { useEffect, useState } from "react";
// import { Link } from "react-router-dom";
import AddressSet from "../components/AddressSet";
import Card from "../../common/Card";
import Row from "../../common/Row";
import Input from "../../common/Input";
import Checkbox from "../../common/Checkbox";
import Radio from "../../common/Radio";
import { useNavigate } from "react-router-dom";
// import Select from "../../common/Select";
import Profile, {CreateUserDataType} from "@dscience/profile-manage/src/features/profile/pages/Profile";
import DatePicker from "react-datepicker";
import "react-datepicker/dist/react-datepicker.css";
import AdminMemo from "../../adminmemo/pages/AdminMemo";
import Payment from "../../payment/pages/Payment";
import AddOrder from "../../addorder/pages/AddOrder";
import Volume from "../../volume/pages/Volume";
import { CreateSubscriptionType, GiftType } from "../../../types/Types";
import dayjs from "dayjs";
import PhoneNumber from "../components/PhoneNumber";
import { useMutation, useQuery } from "react-query";
import axios from "axios";
import PageHeader from "../../common/PageHeader";
const defaultSubscriptionData = {
// 구독 상품
product: {},
// 회원 정보
applicant: {},
// 알림 설정
notification: {},
// 구독자 정보
subscriber: {},
// 사은품
gifts: [],
// 샘플
samples: [],
// 구독 기간
period: {
begin: undefined,
end: undefined,
},
// 갱신 여부
extend: false,
// 메모
note: "",
// 구독 권수
amount: 0,
};
interface ProductType {
no: string;
name: string;
introduction: string;
kind: string;
listPrice: number;
salesPrice: number;
active: boolean;
}
const dummyGifts = [
{ name: "선택하세요.", value: "" },
{ name: "사은품1", value: "gift1" },
{ name: "사은품2", value: "gift2" },
{ name: "사은품3", value: "gift3" },
{ name: "사은품4", value: "gift4" },
{ name: "사은품5", value: "gift5" },
];
const dummyAdditionalGifts = [
{ name: "선택하세요.", value: "" },
{ name: "추가사은품1", value: "addGift1" },
{ name: "추가사은품2", value: "addGift2" },
{ name: "추가사은품3", value: "addGift3" },
{ name: "추가사은품4", value: "addGift4" },
{ name: "추가사은품5", value: "addGift5" },
];
let profileId: string = "";
const Subscription = () => {
const [subscriptionData, setSubscriptionData] = useState<CreateSubscriptionType>(defaultSubscriptionData);
const [subscriptionProducts, setSubscriptionProducts] = useState<ProductType[]>();
useEffect(() => {
refetch().then();
}, []);
- props 로 받은 값을 컴포넌트의 로컬상태로 설정
- 외부 API 요청(REST API 등)
- 라이브러리사용
- setInterval 을 통한 반복작업 혹은 setTimeout 을 통한 작업예약
- 컴포넌트가 화면에 가장 처음 렌더링 될 때 한번만 실행하고 싶을 때는 deps위치에 빈 배열을 넣는다.
> useEffect(() => { console.log('마운트 될 때만 실행된다') }, `[]`);
> useEffect(() => { console.log('렌더링 될 때마다 실행된다') }) : 배열 생략하면 리렌더링 될 때마다 실행 됨.
- Component가 update 될 때 (특정 props, state가 바뀔 때)
> useEffect(() => { console.log(name); console.log('업데이트 될 때 실행된다') }, `[name]`)
- 특정값이 업데이트 될 때 실행하고 싶을 때는 deps 위치의 배열 안에 검사하고 싶은 값을 넣어준다.(의존값이 들어있는 배열 deps 라고도 함. dependency)
- 업데이트 될 때만 실행하는 것이 아니라 마운트 될 때도 실행된다. 그래서 업데이트 될 때만 특정 함수를 실행하고 싶다면 ?
> const mounted = useRef(false);
> useEffect(() => { if(!mounted.current){mounted.current = true} else(//ajax) }, `[바뀌는 값]`)
> 컴포넌트가 마운트 될 때는 if문에서 아무것도 실행하지 않고 mounted 값만 바꿔주고, else에서 배열 안의 값이 바뀌면, ajax 서버 통신이라던지 원하는 코드를 실행할 수 있다.
- setInterval, setTimeout 을 사용하여 등록한 작업들을 clear하기 (clearInterval, clearTimeout)
- 라이브러리 인스턴스 제거
> useEffect(() => {console.log('effect'); console.log(name); return () => {console.log('cleanup'); console.log(name);};}, `[]`);
- cleanup 함수 반환 (return 뒤에 나오는 함수이며 useEffect에 대한 뒷정리함수 라고 한다.)
- 언마운트 될 때만 cleanup함수를 실행하고 싶을 때 : 두번째 파라미터로 빈 배열 `[]`을 넣는다.
- 특정 값이 업데이트되기 직전에 cleanup함수를 실행하고 싶을 때 : deps 배열 안에 검사하고 싶은 값을 넣어준다.
- deps 파라미터를 생략한다면, 컴포넌트가 리렌더링 도리 때마다 호출된다.
- 리액트컴포넌트는 기본적으로 부모컴포넌트가 리렌더링되면 자식컴포넌트 또한 리렌더링이 된다. 바뀐 내용이 없더라도//
- deps에 특정 값을 넣게 된다면 : (1)컴포넌트가 처음 마운트 될 때, (2)지정한 값이 바뀔 때, (3)언마운트 될 때, (4)값이 바뀌기 직전에 모두 호출된다.
- useEffect 안에서 사용하는 상태나, props가 있다면 : useEffect 의 deps에 넣어주는 것이 규칙이다.
- 만약 사용하는 값을 넣어주지 않는다면, useEffect 안의 함수가 실행 될 때 최신 상태, props를 가리키지 않는다.
- deps 파라미터를 생략한다면, 컴포넌트가 리렌더링 될 때마다 useEffect 함수가 호출된다.
useRef()
- useRef()함수 사용법
// 설명할 부분 복붙
- 업데이트 될 때만 실행하는 것이 아니라 마운트 될 때도 실행된다. 그래서 업데이트 될 때만 특정 함수를 실행하고 싶다면 ?
const mounted = useRef(false);
useEffect(() => {
if(!mounted.current){
mounted.current = true
} else(
//ajax
)
}, [바뀌는 값]);
- 컴포넌트가 마운트 될 때는 if문에서 아무것도 실행하지 않고 mounted 값만 바꿔주고, else에서 배열 안의 값이 바뀌면, ajax 서버 통신이라던지 원하는 코드를 실행할 수 있다.
DOM Selector
를 사용한다.특정 DOM을 선택해야할 상황
이 있음.// 초기화 버튼 누르면 input태그에 focus 잡히는 기능 구현하기.
// InputTest.js
import React, {useState, useRef} from 'react';
const Input = () => {
const [text, setText] = useState('');
const nameInput = useRef();
const onChange = (e) => {
setText(e.target.value)
};
const onReset = () => {
setText('');
nameInput.current.focus();
};
return (
<div>
<input
name="name"
onChange={onChange}
value={text}
// <input>태그의 value 속성은 <input>요소의 초기값을 명시한다. value속성은 <input>요소의 type속성값에 따라 다른 용도로 사용된다.
// type='button', type='submit', type='reset' : 버튼 내의 텍스트를 정의함.
// type='hidden', type='password', type='text' : 입력 필드의 초기값을 정의 함.
// <input type='text' value='아이디를 입력하세요'> , 단점은 : 사용자가 초기값을 지우고 입력해야한다. placeholder 사용하면 초기값 자동섹제 됨.
// type='checkbox', type='image', type='radio' : 해당 입력 필드를 선택 시 서버로 "제출"되는 값을 정의함.
// <input>요소의 type속성값이 'file'인 경우에는 value 속성을 사용할 수 없다.
Button : <input type='button' value='' onClick='()=>{}'>
- value === 버튼 위애 표시되는 문자
- onClick === 클릭했을 때 실행되는 함수
Input태그와 value값 : <input type='text' id='' value='' />
- value === text박스에 표시되는 글자
- id 값을 준 후, script에서 getElementByID('').value 를 사용하여 value값을 가져올 수 있다.
Radio의 value값 : <input type='radio' name='Group' value=''>
- name === radio의 group이름, name이 같은 버튼 중 하나를 선택할 수 있다.
- value === 각 radio버튼의 value값, getElementsByName('').value 를 사용하여 같은 name을 가지는 value값들을 불러올 수 있음.
CheckBox : <input type='checkbox' name='group' value=''>
- name == radio의 gruop이름. name이 같은 버튼 중 하나를 선택가능
- value == 각 radio버튼의 value값. getElementsByName('').value를 사용하여 같은 name을 가지는 value값들을 불러 올 수 있음.
- useState를 이용하여 input의 value를 가져오기
- 첫번째 아이디 input값의 value, 두번째 비밀번호 input값의 value를 가져오기
//1.
const [idValue, setIdValue] = useState('');
const [pwValue, setPwValue] = useState('');
- 아이디와 비번의 처음은 빈값이기 때문에 useState 안에 ('') 비었다는 표시 해줌,
//2,
const saveUserId = event => {
setIdValue(event.target.value);
//console.log(event.target.value)
}
const saveUserPw = envent => {
setPwValue(event.target.value)
}
1) onChange 함수 정의
const onChange = () => { setNumber(e.target.value) }
2) input태그 안에 value와 onChange 정의
<input value={number} onChange={onChange}/>
- input창에 'ㅔ'라고 글자 입력했을때 onChange함수가 실행되면서 이벤트 객체를 반환한다.
- 반환된 이벤트가 onChange 함수에서 실행될 때 받은 인자
1.e의 객체구조,
2.e.target의 구조,
3.e.target.value의 구조는 아래와 같다
1.e의 객체구조
console.log(e);
//output is
SyntheticBaseEvent {
_reactName: "onChange",
_targetInst: null,
type: "change",
nativeEvent: InputEvent,
target: input,
bubbles: true
cancelable: false
currentTarget: null
defaultPrevented: false
eventPhase: 3
isDefaultPrevented: ƒ
functionThatReturnsFalse()
isPropagationStopped: ƒ
functionThatReturnsFalse()
isTrusted: true
nativeEvent: InputEvent {
isTrusted: true,
data: "ㅇ",
isComposing: true,
inputType: "insertCompositionText",
dataTransfer: null, …}
target: inputtimeStamp: 1090.3649999963818
type: "change"
_reactName: "onChange"
_targetInst: null
proto: Object}
2.e.target의 구조
- 이벤트객체의 target만 가져와서 출력한다. 위 객체에서 target의 value는 input이기 때문에 다음과 같이 출력
console.log(e.target);
//output is
<input placeholder='할일입력' value='ㅔ'>
3.e.target.value의 구조
- input의 value를 가져오므로 입력한 값인 'ㅔ'를 출력한다
console.log(e.target.value);
//output is
ㅔ
- 여러개의 console.log()를 실행하면서 알게 된 것은, console.log(e.target.value)와 console.log(e.nativeEvent.data)가 같은 값 'ㅔ'를 출력한다는 것
273 565 035 18487
10470
ref={nameInput}
/>
<button onClick={onReset}> 초기화 <button>
<div>
<b>내용: <b>
{text}
<div>
<div>
);
};
export default InputTest;
const { isLoading, error, data, isFetching, refetch } = useQuery({
queryKey: ["subscriptionProducts"],
queryFn: () => querySubscriptionProducts(),
});
const querySubscriptionProducts = async () => {
const response = await axios.get(
`/api/product/dsstore/dssdlabs/-/product`,
{
headers: {
"Content-Type": "application/json",
service: "product",
query: "QuerySubscriptionProducts",
},
}
);
return setSubscriptionProducts(response.data);
};
const autoCompleteDateRangeAndAmount = (productId: string) => {
const begin = new Date().getTime();
const end = new Date(
dayjs(new Date()).add(365, "d").format("YYYY-MM-DD")
).getTime();
const period = {
begin,
end,
};
if (productId == "1" || productId == "3") {
setSubscriptionData({ ...subscriptionData, amount: 12, period });
} else {
setSubscriptionData({ ...subscriptionData, amount: 24, period });
}
};
const handleSampleCheck = (checked: boolean, id: string, name: string) => {
if (checked) {
subscriptionData.samples?.push({ id, name });
} else {
const samples = subscriptionData.samples?.filter((f) => f.id !== id);
setSubscriptionData({ ...subscriptionData, samples });
}
};
const handleDatePicker = (date: Date, isBegin: boolean) => {
const period = subscriptionData.period;
const time = date.getTime();
if (isBegin) {
setSubscriptionData({
...subscriptionData,
period: { ...period, begin: time },
});
} else {
setSubscriptionData({
...subscriptionData,
period: { ...period, end: time },
});
}
};
useEffect(() => {
if (subscriptionData.product.no) {
autoCompleteDateRangeAndAmount(subscriptionData.product.no);
}
}, [subscriptionData.product.no]);
const handleSelectAdditionalGift = (gift: GiftType) => {
const defaultGifts = subscriptionData.gifts?.filter(
(f) => f.kind === "Additional"
);
let additionalGifts;
if (defaultGifts && defaultGifts.length > 0) {
additionalGifts = [...defaultGifts, gift];
} else {
additionalGifts = [gift];
}
setSubscriptionData({ ...subscriptionData, gifts: additionalGifts });
};
const handleSelectGift = (gift: GiftType) => {
const currentGifts = subscriptionData.gifts?.filter(
(f) => f.kind === "Default"
);
let gifts;
if (currentGifts && currentGifts.length > 0) {
gifts = [...currentGifts, gift];
} else {
gifts = [gift];
}
setSubscriptionData({ ...subscriptionData, gifts });
};
console.log(subscriptionData);
useEffect(() => {
if (subscriptionData.product.no) {
autoCompleteDateRangeAndAmount(subscriptionData.product.no);
}
}, [subscriptionData.product.no]);
// 신청자 입력 정보
const [copyApplicant, setCopyApplicant] = useState(false);
const [profileData, setProfileData] = useState<CreateUserDataType>();
// const createSession = useMutation(
// () =>
// axios.post(
// "/api/standalone/session?tenantId=6d1decb",
// {},
// {
// headers: {
// command: "CreateStandaloneSession",
// },
// }
// ),
// {
// onSuccess: () => {
// createSubscription.mutate();
// createProfile.mutate();
// },
// }
// );
const navigate = useNavigate();
const createProfile = useMutation(
() =>
axios.post("/api/profile/dsstore/dssdlabs/-/profile", profileData, {
headers: {
"Content-Type": "application/json",
command: "CreateProfile",
withCredentials: true,
method: "POST",
},
}),
{
onSuccess: (data) => {
console.log("profile complete", data);
// 8자리 사용자 식별자 - data.data
profileId = data.data;
console.log("profileId", profileId);
createOrder.mutate();
},
onError: (e) => {
console.log("JSON.stringify(e)", JSON.stringify(e));
},
}
);
const createOrder = useMutation(
() =>
axios.post(
"/api/order/dsstore/dssdlabs/-/order",
{
orderer: {
id: profileId,
name: subscriptionData.applicant.name,
},
items: [
{
itemId: "11111111",
product: {
id: subscriptionData.product.no,
name: subscriptionData.product.name,
},
price: subscriptionData.product.salesPrice,
quantity: 1,
},
],
},
{
headers: {
"Content-Type": "application/json",
command: "CreateOrder",
service: "order",
withCredentials: true,
method: "POST",
},
}
),
{
onSuccess: (data) => {
console.log("create order", data);
createSubscription.mutate();
},
onError: (e) => {
console.log("JSON.stringify(e)", JSON.stringify(e));
},
}
);
const createSubscription = useMutation(
() =>
axios.post(
"/api/subscription/dsstore/dssdlabs/-/subscription",
{
product: {
id: subscriptionData.product.no,
name: subscriptionData.product.name,
},
applicant: {
id: profileId,
name: subscriptionData.applicant.name,
address: {
zipCode: subscriptionData.applicant.address?.zipCode,
basic: subscriptionData.applicant.address?.basic,
detail: subscriptionData.applicant.address?.detail,
},
contacts: [
subscriptionData.applicant.telNo && {
type: "Landline",
number: subscriptionData.applicant.telNo,
},
subscriptionData.applicant.mobileNo && {
type: "Cellular",
number: subscriptionData.applicant.mobileNo,
},
],
email: {
name: subscriptionData.applicant.email?.split("@")[0],
domain: subscriptionData.applicant.email?.split("@")[1],
},
librarianEmail: {
name: subscriptionData.applicant.librarianEmail?.split("@")[0],
domain: subscriptionData.applicant.librarianEmail?.split("@")[1],
},
},
notification: {
notifyEmail: subscriptionData.applicant.emailReception,
notifyMessage: subscriptionData.applicant.smsReception,
},
subscriber: {
name: subscriptionData.subscriber?.name,
address: {
zipCode: subscriptionData.subscriber?.address?.zipCode,
basic: subscriptionData.subscriber?.address?.basic,
detail: subscriptionData.subscriber?.address?.detail,
},
contacts: [
subscriptionData.subscriber?.telNo && {
type: "Landline",
number: subscriptionData.subscriber?.telNo,
},
subscriptionData.subscriber?.mobileNo && {
type: "Cellular",
number: subscriptionData.subscriber?.mobileNo,
},
],
jobName: subscriptionData.subscriber?.jobName,
},
gifts: subscriptionData.gifts,
samples: subscriptionData.samples,
period: {
begin: subscriptionData.period?.begin,
end: subscriptionData.period?.end,
},
extend: subscriptionData.extend,
note: subscriptionData.note,
},
{
headers: {
"Content-Type": "application/json",
command: "CreateSubscription",
withCredentials: true,
method: "POST",
},
}
),
{
onSuccess: (data) => {
console.log("subscription complete", data);
navigate("/dsstore/dssdlabs/-/subscription");
},
onError: (e) => {
console.log("JSON.stringify(e)", JSON.stringify(e));
},
}
);
return (
<>
<PageHeader
pageTitle={"정기구독"}
rightContent={
<button
className="btn btn-sm btn-outline btn-primary"
onClick={() => {
createProfile.mutate();
}}
>
정기구독 신청
</button>
}
/>
<Row style={{ paddingBottom: "100px" }}>
<div className="col-6">
<Profile
setProfileData={(e: CreateUserDataType) => {
setProfileData({ ...e });
setSubscriptionData({ ...subscriptionData, applicant: { ...e } });
}}
handleCopySubscriber={(e: boolean) => {
if (e) {
setSubscriptionData((prev) => {
return {
...prev,
applicant: {
mobileNo: subscriptionData.subscriber?.mobileNo,
telNo: subscriptionData.subscriber?.telNo,
address: {
basic: subscriptionData.subscriber?.address?.basic,
detail: subscriptionData.subscriber?.address?.detail,
zipCode: subscriptionData.subscriber?.address?.zipCode,
},
name: subscriptionData.subscriber?.name,
},
};
});
} else {
setSubscriptionData((prev) => {
return {
...prev,
applicant: {
mobileNo: "",
telNo: "",
address: undefined,
name: "",
},
};
});
}
}}
profileData={{
...subscriptionData.applicant,
address: { ...subscriptionData.applicant?.address },
}}
/>
<Card header={"정기구독 신청"} className="mt-10">
<Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 구독잡지 </span>
</label>
<div className="col-lg-9 fv-row ">
<div className="col-9">
{subscriptionProducts
? subscriptionProducts.map((product) => {
return (
<Radio
checked={subscriptionData.product.no === product.no}
onChange={(e) => {
if (e.target.checked) {
console.log("e >>", product);
setSubscriptionData({
...subscriptionData,
product,
});
}
}}
label={product.name}
className={"form-check-inline"}
key={product.no}
/>
);
})
: null}
</div>
</div>
</Row>
<Row className="mb-2">
<div className="col-md-6">
<label
id="kt_td_picker_linked_1_input"
className="form-label fw-bold"
>
구독시작일
</label>
<div
className="input-group log-event"
id="kt_td_picker_linked_1"
data-td-target-input="nearest"
data-td-target-toggle="nearest"
>
<DatePicker
id="kt_td_picker_linked_1_input"
className="datePicker form-control"
data-td-target="#kt_td_picker_linked_1"
dateFormat={"yyyy-MM-dd"}
value={
subscriptionData.period?.begin
? dayjs(subscriptionData.period?.begin).format(
"YYYY-MM-DD"
)
: undefined
}
onSelect={(e) => {
handleDatePicker(e, true);
}}
onChange={(e) => {
if (e) {
handleDatePicker(e, true);
}
}}
/>
</div>
</div>
<div className="col-md-6">
<label
id="kt_td_picker_linked_2_input"
className="form-label fw-bold"
>
구독종료일
</label>
<div
className="input-group log-event"
id="kt_td_picker_linked_2"
data-td-target-input="nearest"
data-td-target-toggle="nearest"
>
<DatePicker
id="kt_td_picker_linked_1_input"
className="datePicker form-control"
data-td-target="#kt_td_picker_linked_1"
dateFormat={"yyyy-MM-dd"}
value={
subscriptionData.period?.end
? dayjs(subscriptionData.period?.end).format(
"YYYY-MM-DD"
)
: undefined
}
onSelect={(e) => {
handleDatePicker(e, false);
}}
onChange={(e) => {
if (e) {
handleDatePicker(e, false);
}
}}
/>
</div>
</div>
</Row>
<Row className="mb-2" style={{ alignItems: "center" }}>
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 구독권수 </span>
</label>
<div className="col-lg-4 fv-row ">
<Input
type="text"
className="form-control form-control-sm"
placeholder="숫자를 입력해주세요"
name="company"
value={subscriptionData.amount}
onChange={(e) =>
setSubscriptionData({
...subscriptionData,
amount: Number(e.target.value.replace(/[^0-9]/g, "")),
})
}
/>
</div>
권
</Row>
<Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 기본사은품 </span>
</label>
<div className="col-lg-9">
<select
className="form-select form-select-sm"
name="currency"
onChange={(e) =>
handleSelectGift({
productId: e.target.value,
productName: e.target.value,
kind: "Default",
})
}
>
{dummyGifts.map((gift, index) => {
return (
<React.Fragment key={gift.name + index}>
<option value={gift.value}>{gift.name}</option>
</React.Fragment>
);
})}
</select>
</div>
</Row>
<Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 추가사은품 </span>
</label>
<div className="col-lg-9">
<select
className="form-select form-select-sm"
name="currency"
onChange={(e) =>
handleSelectAdditionalGift({
productId: e.target.value,
productName: e.target.value,
kind: "Additional",
})
}
>
{dummyAdditionalGifts.map((addGift, index) => {
return (
<React.Fragment key={addGift.name + index}>
<option value={addGift.value}>{addGift.name}</option>
</React.Fragment>
);
})}
{/* <option value="">선택하세요.</option>
<option value="addgift1">추가사은품1</option>
<option value="addgift2">추가사은품2</option>
<option value="addgift3">추가사은품3</option>
<option value="addgift4">추가사은품4</option>
<option value="addgift5">추가사은품5</option> */}
</select>
</div>
</Row>
<Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 샘플항목 </span>
</label>
<div className="col-lg-9 fv-row ">
<div className="col-9">
{subscriptionProducts
? subscriptionProducts.map((product) => {
return (
<Checkbox
onChange={(e) => {
handleSampleCheck(
e.target.checked,
product.no,
product.name
);
}}
label={product.name.replace("(정기구독)", "")}
className={"form-check-inline"}
key={product.no}
/>
);
})
: null}
</div>
</div>
</Row>
{/* <Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 샘플항목 </span>
</label>
<div className="col-lg-9">
<Row>
<Checkbox
label="과동"
className="col-3"
onChange={(e) =>
handleSampleCheck(e.target.checked, "과동")
}
/>
<Checkbox
label="어동"
className="col-3"
onChange={(e) =>
handleSampleCheck(e.target.checked, "어동")
}
/>
<Checkbox
label="수동"
className="col-3"
onChange={(e) =>
handleSampleCheck(e.target.checked, "수동")
}
/>
<Checkbox
label="어수동"
className="col-3"
onChange={(e) =>
handleSampleCheck(e.target.checked, "어수동")
}
/>
</Row>
</div>
</Row> */}
<Row className="mb-2" style={{ alignItems: "center" }}>
{/* 구독자 정보 */}
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 구독자 </span>
</label>
<div className="col-lg-6 fv-row ">
<Input
type="text"
className="form-control form-control-sm"
placeholder="구독자이름을 입력해주세요"
name="company"
value={subscriptionData.subscriber?.name}
onChange={(e) =>
setSubscriptionData((prev) => {
return { ...prev, subscriber: { name: e.target.value } };
})
}
/>
</div>
<Checkbox
label="신청자 정보와 동일"
className="col-3"
onChange={(e) => {
setCopyApplicant(e.target.checked);
if (e.target.checked) {
setSubscriptionData({
...subscriptionData,
subscriber: {
mobileNo: subscriptionData.applicant.mobileNo,
telNo: subscriptionData.applicant.telNo,
address: { ...subscriptionData.applicant.address },
name: subscriptionData.applicant.name,
},
});
} else {
setSubscriptionData({
...subscriptionData,
subscriber: {
address: undefined,
mobileNo: "",
name: "",
telNo: "",
},
});
}
}}
/>
</Row>
<Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 주소 </span>
</label>
<div className="col-lg-9">
<AddressSet
handleInput={(k, e) =>
setSubscriptionData((prev) => {
return {
...prev,
subscriber: {
...prev.subscriber,
address: { ...prev.subscriber?.address, [k]: e },
},
};
})
}
basic={subscriptionData.subscriber?.address?.basic}
detail={subscriptionData.subscriber?.address?.detail}
zipCode={subscriptionData.subscriber?.address?.zipCode}
/>
</div>
</Row>
<Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 전화번호 </span>
</label>
<div className="col-lg-9">
<PhoneNumber
number={
copyApplicant
? subscriptionData.applicant?.telNo
: subscriptionData.subscriber?.telNo
}
handleNumber={(e) => {
setSubscriptionData({
...subscriptionData,
subscriber: {
...subscriptionData.subscriber,
telNo: e,
},
});
}}
/>
</div>
</Row>
<Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 휴대폰번호 </span>
</label>
<div className="col-lg-9">
<PhoneNumber
number={
copyApplicant
? subscriptionData.applicant.mobileNo
: subscriptionData.subscriber?.mobileNo
}
handleNumber={(e) => {
setSubscriptionData({
...subscriptionData,
subscriber: {
...subscriptionData.subscriber,
mobileNo: e,
},
});
}}
/>
</div>
</Row>
<Row className="mb-2">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 구독자직업 </span>
</label>
<div className="col-lg-9">
<select
className="form-select form-select-sm"
name="currency"
onChange={(e) => {
setSubscriptionData({
...subscriptionData,
subscriber: {
...subscriptionData.subscriber,
jobName: e.target.value,
},
});
}}
>
<option value="">선택하세요.</option>
<option value="teacher">교사</option>
<option value="medicine">의료</option>
<option value="business">사업</option>
<option value="IT">IT</option>
<option value="notSelect">선택안함</option>
</select>
</div>
</Row>
<Row style={{ alignItems: "center" }} className="mb-6">
<label className="col-lg-3 col-form-label fw-bold fs-6">
<span className="required"> 연장여부 </span>
</label>
<div className="col-lg-2">
<a
href="#"
className="btn btn-warning btn-sm"
aria-disabled={true}
>
연장
</a>
</div>
<div className="col-lg-7">
<Input
type="text"
className="form-control form-control-sm"
placeholder="자동입력부분(더블클릭삭제)"
name="company"
value={subscriptionData.extend ? "연장" : "신규"}
readOnly
/>
</div>
</Row>
<label id="" className="form-label">
코멘트
</label>
<textarea
className="form-control form-control"
data-kt-autosize="true"
placeholder="입력해주세요"
onChange={(e) => {
setSubscriptionData({
...subscriptionData,
note: e.target.value,
});
}}
/>
</Card>
</div>
<div className="col-6">
<Payment />
<AddOrder className="mt-6" />
<Volume className="mt-6" />
<AdminMemo className="mt-6" />
</div>
</Row>
</>
);
};
export default Subscription;
```