test
This commit is contained in:
@@ -33,8 +33,10 @@ export interface QnaItem {
|
|||||||
cursorId?: number;
|
cursorId?: number;
|
||||||
seq?: string;
|
seq?: string;
|
||||||
statusCode?: string;
|
statusCode?: string;
|
||||||
|
requestType?: string;
|
||||||
requestDate?: string;
|
requestDate?: string;
|
||||||
requestName?: string;
|
requestName?: string;
|
||||||
|
answerDate?: string;
|
||||||
title?: string;
|
title?: string;
|
||||||
contents?: string;
|
contents?: string;
|
||||||
answer?: string;
|
answer?: string;
|
||||||
@@ -46,7 +48,7 @@ export interface QnaItemProps extends QnaItem {
|
|||||||
|
|
||||||
};
|
};
|
||||||
export interface QnaSaveParams extends SupportParams {
|
export interface QnaSaveParams extends SupportParams {
|
||||||
counselType: string;
|
requestType: string;
|
||||||
requestName: string;
|
requestName: string;
|
||||||
requestTel: string;
|
requestTel: string;
|
||||||
requestEmail: string;
|
requestEmail: string;
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ export const SupportQnaItem = ({
|
|||||||
cursorId,
|
cursorId,
|
||||||
seq,
|
seq,
|
||||||
statusCode,
|
statusCode,
|
||||||
|
requestType,
|
||||||
requestDate,
|
requestDate,
|
||||||
requestName,
|
requestName,
|
||||||
|
answerDate,
|
||||||
title,
|
title,
|
||||||
contents,
|
contents,
|
||||||
answer
|
answer
|
||||||
@@ -20,8 +22,10 @@ export const SupportQnaItem = ({
|
|||||||
navigate(PATHS.support.qna.detail, {
|
navigate(PATHS.support.qna.detail, {
|
||||||
state: {
|
state: {
|
||||||
statusCode,
|
statusCode,
|
||||||
|
requestType,
|
||||||
requestDate,
|
requestDate,
|
||||||
requestName,
|
requestName,
|
||||||
|
answerDate,
|
||||||
title,
|
title,
|
||||||
contents,
|
contents,
|
||||||
answer
|
answer
|
||||||
|
|||||||
@@ -127,6 +127,14 @@
|
|||||||
"01": "Save",
|
"01": "Save",
|
||||||
"02": "Submit Inquiry",
|
"02": "Submit Inquiry",
|
||||||
"03": "Completed"
|
"03": "Completed"
|
||||||
|
},
|
||||||
|
"validation": {
|
||||||
|
"title": "Title is Required.",
|
||||||
|
"requestType": "RequestType is Required.",
|
||||||
|
"requestName": "RequestName is Required.",
|
||||||
|
"requestTel": "Phone number is Required.",
|
||||||
|
"requestEmail": "Invalid Email Type.",
|
||||||
|
"contents": "Contents is Required."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -127,6 +127,14 @@
|
|||||||
"01": "저장",
|
"01": "저장",
|
||||||
"02": "문의",
|
"02": "문의",
|
||||||
"03": "답변완료"
|
"03": "답변완료"
|
||||||
|
},
|
||||||
|
"validation": {
|
||||||
|
"title": "제목은 필수 항목 입니다.",
|
||||||
|
"requestType": "문의유형은 필수 항목 입니다.",
|
||||||
|
"requestName": "요청자명은 필수 항목 입니다.",
|
||||||
|
"requestTel": "휴대폰번호은 필수 항목 입니다.",
|
||||||
|
"requestEmail": "이메일 형식이 맞지 않습니다.",
|
||||||
|
"contents": "문의내용은 필수 항목 입니다."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,19 +10,23 @@ import {
|
|||||||
useSetFooterMode,
|
useSetFooterMode,
|
||||||
useSetOnBack
|
useSetOnBack
|
||||||
} from '@/widgets/sub-layout/use-sub-layout';
|
} from '@/widgets/sub-layout/use-sub-layout';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
export const QnaDetailPage = () => {
|
export const QnaDetailPage = () => {
|
||||||
const { navigate } = useNavigate();
|
const { navigate } = useNavigate();
|
||||||
|
const { t } = useTranslation();
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
const [statusCode, setStatusCode] = useState<string>('');
|
const [statusCode, setStatusCode] = useState<string>('');
|
||||||
const [requestDate, setRequestDate] = useState<string>('');
|
const [requestDate, setRequestDate] = useState<string>('');
|
||||||
const [requestName, setRequestName] = useState<string>('');
|
const [requestName, setRequestName] = useState<string>('');
|
||||||
|
const [requestType, setRequestType] = useState<string>('');
|
||||||
|
const [answerDate, setAnswerDate] = useState<string>('');
|
||||||
const [title, setTitle] = useState<string>('');
|
const [title, setTitle] = useState<string>('');
|
||||||
const [contents, setContents] = useState<string>('');
|
const [contents, setContents] = useState<string>('');
|
||||||
const [answer, setAnswer] = useState<string>('');
|
const [answer, setAnswer] = useState<string>('');
|
||||||
|
|
||||||
useSetHeaderTitle('1:1 문의');
|
useSetHeaderTitle(t('support.qna.title'));
|
||||||
useSetHeaderType(HeaderType.LeftArrow);
|
useSetHeaderType(HeaderType.LeftArrow);
|
||||||
useSetFooterMode(false);
|
useSetFooterMode(false);
|
||||||
useSetOnBack(() => {
|
useSetOnBack(() => {
|
||||||
@@ -31,8 +35,10 @@ export const QnaDetailPage = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setStatusCode(location?.state.statusCode);
|
setStatusCode(location?.state.statusCode);
|
||||||
|
setRequestType(location?.state.requestType);
|
||||||
setRequestDate(location?.state.requestDate);
|
setRequestDate(location?.state.requestDate);
|
||||||
setRequestName(location?.state.requestName);
|
setRequestName(location?.state.requestName);
|
||||||
|
setAnswerDate(location?.state.answerDate);
|
||||||
setTitle(location?.state.title);
|
setTitle(location?.state.title);
|
||||||
setContents(location?.state.contents);
|
setContents(location?.state.contents);
|
||||||
setAnswer(location?.state.answer);
|
setAnswer(location?.state.answer);
|
||||||
@@ -47,11 +53,11 @@ export const QnaDetailPage = () => {
|
|||||||
<div className="inq-detail__head">
|
<div className="inq-detail__head">
|
||||||
<div className="inq-detail__row">
|
<div className="inq-detail__row">
|
||||||
<span className="inq-badge">제목</span>
|
<span className="inq-badge">제목</span>
|
||||||
<span className="inq-head-text bold">{ requestName }</span>
|
<span className="inq-head-text bold">{ title }</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="inq-detail__row">
|
<div className="inq-detail__row">
|
||||||
<span className="inq-badge">유형</span>
|
<span className="inq-badge">유형</span>
|
||||||
<span className="inq-head-text">한도/보증보험 문의</span>
|
<span className="inq-head-text">{ t(`support.qna.categories.${requestType}`) }</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="inq-detail__row">
|
<div className="inq-detail__row">
|
||||||
<span className="inq-badge">등록일</span>
|
<span className="inq-badge">등록일</span>
|
||||||
@@ -59,7 +65,7 @@ export const QnaDetailPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="inq-detail__row">
|
<div className="inq-detail__row">
|
||||||
<span className="inq-badge">답변일</span>
|
<span className="inq-badge">답변일</span>
|
||||||
<span className="inq-head-text">2025.07.31</span>
|
<span className="inq-head-text">{ moment(answerDate).format('YYYY.MM.DD') }</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="inq-detail__divider"></div>
|
<div className="inq-detail__divider"></div>
|
||||||
@@ -70,18 +76,6 @@ export const QnaDetailPage = () => {
|
|||||||
<div className="inq-detail__section">
|
<div className="inq-detail__section">
|
||||||
<div className="inq-detail__section-title">문의 내용</div>
|
<div className="inq-detail__section-title">문의 내용</div>
|
||||||
<div className="inq-detail__body" dangerouslySetInnerHTML={{ __html: contents || '' }}></div>
|
<div className="inq-detail__body" dangerouslySetInnerHTML={{ __html: contents || '' }}></div>
|
||||||
{/*
|
|
||||||
<div className="inq-detail__box">
|
|
||||||
<div className="inq-detail__kv">
|
|
||||||
<div className="k">제목</div>
|
|
||||||
<div className="v">{ title }</div>
|
|
||||||
</div>
|
|
||||||
<div className="inq-detail__kv">
|
|
||||||
<div className="k">내용</div>
|
|
||||||
<div className="v" dangerouslySetInnerHTML={{ __html: contents || '' }}></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
*/}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { ChangeEvent, useEffect, useState } from 'react';
|
import { ChangeEvent, useEffect, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PATHS } from '@/shared/constants/paths';
|
import { PATHS } from '@/shared/constants/paths';
|
||||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||||
import { HeaderType } from '@/entities/common/model/types';
|
import { DefaultRequestPagination, HeaderType } from '@/entities/common/model/types';
|
||||||
import { useQnaListMutation } from '@/entities/support/api/use-qna-list-mutation';
|
import { useQnaListMutation } from '@/entities/support/api/use-qna-list-mutation';
|
||||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
||||||
import { QnaItem, QnaListParams, QnaListResponse } from '@/entities/support/model/types';
|
import { QnaItem, QnaListParams, QnaListResponse } from '@/entities/support/model/types';
|
||||||
@@ -14,18 +14,45 @@ import {
|
|||||||
useSetOnBack
|
useSetOnBack
|
||||||
} from '@/widgets/sub-layout/use-sub-layout';
|
} from '@/widgets/sub-layout/use-sub-layout';
|
||||||
import { useStore } from '@/shared/model/store';
|
import { useStore } from '@/shared/model/store';
|
||||||
|
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||||
|
|
||||||
export const QnaListPage = () => {
|
export const QnaListPage = () => {
|
||||||
const { navigate } = useNavigate();
|
const { navigate } = useNavigate();
|
||||||
|
const [onActionIntersect, setOnActionIntersect] = useState<boolean>(false);
|
||||||
|
|
||||||
|
const onIntersect: IntersectionObserverCallback = (entries: Array<IntersectionObserverEntry>) => {
|
||||||
|
|
||||||
|
entries.forEach((entry: IntersectionObserverEntry) => {
|
||||||
|
if(onActionIntersect){
|
||||||
|
if(entry.isIntersecting){
|
||||||
|
console.log('Element is now intersecting with the root.');
|
||||||
|
callList();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
console.log('Element is no longer intersecting with the root.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const { setTarget } = useIntersectionObserver({
|
||||||
|
threshold: 1,
|
||||||
|
onIntersect
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
const midOptions = useStore.getState().UserStore.selectOptionsMids;
|
const midOptions = useStore.getState().UserStore.selectOptionsMids;
|
||||||
const userMid = useStore.getState().UserStore.mid;
|
const userMid = useStore.getState().UserStore.mid;
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|
||||||
const [mid, setMid] = useState<string>(userMid);
|
const [mid, setMid] = useState<string>(userMid);
|
||||||
const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM);
|
const [pageParam, setPageParam] = useState<DefaultRequestPagination>(DEFAULT_PAGE_PARAM);
|
||||||
|
const [nextCursor, setNextCursor] = useState<string | null>(null);
|
||||||
const [statusCode, setStatusCode] = useState<string>(''); // 02, 03
|
const [statusCode, setStatusCode] = useState<string>(''); // 02, 03
|
||||||
const [resultList, setResultList] = useState<Array<QnaItem>>([]);
|
const [resultList, setResultList] = useState<Array<QnaItem>>([]);
|
||||||
|
|
||||||
|
|
||||||
useSetHeaderTitle(t('support.qna.title'));
|
useSetHeaderTitle(t('support.qna.title'));
|
||||||
useSetHeaderType(HeaderType.LeftArrow);
|
useSetHeaderType(HeaderType.LeftArrow);
|
||||||
useSetFooterMode(false);
|
useSetFooterMode(false);
|
||||||
@@ -35,17 +62,36 @@ export const QnaListPage = () => {
|
|||||||
|
|
||||||
const { mutateAsync: qnaList } = useQnaListMutation();
|
const { mutateAsync: qnaList } = useQnaListMutation();
|
||||||
const callList = () => {
|
const callList = () => {
|
||||||
|
setOnActionIntersect(false);
|
||||||
let listParams: QnaListParams = {
|
let listParams: QnaListParams = {
|
||||||
mid: mid,
|
mid: mid,
|
||||||
statusCode: statusCode,
|
statusCode: statusCode,
|
||||||
...{page: pageParam}
|
...{
|
||||||
|
page: pageParam
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
qnaList(listParams).then((rs: QnaListResponse) => {
|
qnaList(listParams).then((rs: QnaListResponse) => {
|
||||||
setResultList(rs.content);
|
setResultList([
|
||||||
|
...resultList,
|
||||||
|
...rs.content
|
||||||
|
]);
|
||||||
|
if(rs.hasNext){
|
||||||
|
setNextCursor(rs.nextCursor);
|
||||||
|
setPageParam({
|
||||||
|
...pageParam,
|
||||||
|
cursor: rs.nextCursor
|
||||||
|
});
|
||||||
|
setOnActionIntersect(true);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
setNextCursor(null);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const getQnaList = () => {
|
const getQnaList = () => {
|
||||||
let rs = [];
|
let rs = [];
|
||||||
for(let i=0;i<resultList.length;i++){
|
for(let i=0;i<resultList.length;i++){
|
||||||
@@ -55,8 +101,10 @@ export const QnaListPage = () => {
|
|||||||
cursorId={ resultList[i]?.cursorId }
|
cursorId={ resultList[i]?.cursorId }
|
||||||
seq={ resultList[i]?.seq }
|
seq={ resultList[i]?.seq }
|
||||||
statusCode={ resultList[i]?.statusCode }
|
statusCode={ resultList[i]?.statusCode }
|
||||||
|
requestType={ resultList[i]?.requestType }
|
||||||
requestDate={ resultList[i]?.requestDate }
|
requestDate={ resultList[i]?.requestDate }
|
||||||
requestName={ resultList[i]?.requestName }
|
requestName={ resultList[i]?.requestName }
|
||||||
|
answerDate={ resultList[i]?.answerDate }
|
||||||
title={ resultList[i]?.title }
|
title={ resultList[i]?.title }
|
||||||
contents={ resultList[i]?.contents }
|
contents={ resultList[i]?.contents }
|
||||||
answer={ resultList[i]?.answer }
|
answer={ resultList[i]?.answer }
|
||||||
@@ -74,6 +122,10 @@ export const QnaListPage = () => {
|
|||||||
callList();
|
callList();
|
||||||
}, [statusCode]);
|
}, [statusCode]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
}, [resultList]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<main>
|
<main>
|
||||||
@@ -93,7 +145,6 @@ export const QnaListPage = () => {
|
|||||||
<option
|
<option
|
||||||
key={ value.value }
|
key={ value.value }
|
||||||
value={ value.value }
|
value={ value.value }
|
||||||
selected={ (userMid === value.value)? true: false }
|
|
||||||
>{ value.name }</option>
|
>{ value.name }</option>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@@ -113,6 +164,7 @@ export const QnaListPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="inq-list" >
|
<div className="inq-list" >
|
||||||
{ getQnaList() }
|
{ getQnaList() }
|
||||||
|
<div ref={setTarget}></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="apply-row">
|
<div className="apply-row">
|
||||||
@@ -124,6 +176,7 @@ export const QnaListPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -12,10 +12,13 @@ import {
|
|||||||
import { useStore } from '@/shared/model/store';
|
import { useStore } from '@/shared/model/store';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { PatternFormat } from 'react-number-format';
|
import { PatternFormat } from 'react-number-format';
|
||||||
|
import { overlay } from 'overlay-kit';
|
||||||
|
import { Dialog } from '@/shared/ui/dialogs/dialog';
|
||||||
|
import { QnaSaveParams, QnaSaveResponse } from '@/entities/support/model/types';
|
||||||
|
|
||||||
export enum QnaRegisterPropsName {
|
export enum QnaRegisterPropsName {
|
||||||
Mid = 'Mid',
|
Mid = 'Mid',
|
||||||
CounselType = 'CounselType',
|
RequestType = 'RequestType',
|
||||||
RequestName = 'RequestName',
|
RequestName = 'RequestName',
|
||||||
RequestTel = 'RequestTel',
|
RequestTel = 'RequestTel',
|
||||||
RequestEmail = 'RequestEmail',
|
RequestEmail = 'RequestEmail',
|
||||||
@@ -29,7 +32,7 @@ export const QnaRegisterPage = () => {
|
|||||||
const userMid = useStore.getState().UserStore.mid;
|
const userMid = useStore.getState().UserStore.mid;
|
||||||
|
|
||||||
const [mid, setMid] = useState<string>(userMid);
|
const [mid, setMid] = useState<string>(userMid);
|
||||||
const [counselType, setCounselType] = useState<string>('st');
|
const [requestType, setRequestType] = useState<string>('');
|
||||||
const [requestName, setRequestName] = useState<string>('');
|
const [requestName, setRequestName] = useState<string>('');
|
||||||
const [requestTel, setRequestTel] = useState<string>('');
|
const [requestTel, setRequestTel] = useState<string>('');
|
||||||
const [requestEmail, setRequestEmail] = useState<string>('');
|
const [requestEmail, setRequestEmail] = useState<string>('');
|
||||||
@@ -53,8 +56,8 @@ export const QnaRegisterPage = () => {
|
|||||||
if(key === QnaRegisterPropsName.Mid){
|
if(key === QnaRegisterPropsName.Mid){
|
||||||
setMid(value);
|
setMid(value);
|
||||||
}
|
}
|
||||||
else if(key === QnaRegisterPropsName.CounselType){
|
else if(key === QnaRegisterPropsName.RequestType){
|
||||||
setCounselType(value);
|
setRequestType(value);
|
||||||
}
|
}
|
||||||
else if(key === QnaRegisterPropsName.RequestName){
|
else if(key === QnaRegisterPropsName.RequestName){
|
||||||
setRequestName(value);
|
setRequestName(value);
|
||||||
@@ -72,18 +75,67 @@ export const QnaRegisterPage = () => {
|
|||||||
setContents(value);
|
setContents(value);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
const showAlert = (msg: string) => {
|
||||||
|
overlay.open(({
|
||||||
|
isOpen,
|
||||||
|
close,
|
||||||
|
unmount
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<Dialog
|
||||||
|
afterLeave={unmount}
|
||||||
|
open={isOpen}
|
||||||
|
onClose={close}
|
||||||
|
message={ msg }
|
||||||
|
buttonLabel={['확인']}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const checkEmail = (email: string) => {
|
||||||
|
var re = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
|
||||||
|
if(email != '' && email != 'undefined' && re.test(email)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
const callRegister = () => {
|
const callRegister = () => {
|
||||||
let params = {
|
if(!title){
|
||||||
|
showAlert(t('support.qna.validation.title'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(!requestType){
|
||||||
|
showAlert(t('support.qna.validation.requestType'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(!requestName){
|
||||||
|
showAlert(t('support.qna.validation.requestName'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(!requestTel){
|
||||||
|
showAlert(t('support.qna.validation.requestTel'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(requestEmail && !checkEmail(requestEmail)){
|
||||||
|
showAlert(t('support.qna.validation.requestEmail'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if(!contents){
|
||||||
|
showAlert(t('support.qna.validation.contents'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
let params: QnaSaveParams = {
|
||||||
mid: mid,
|
mid: mid,
|
||||||
title: title,
|
title: title,
|
||||||
counselType: counselType,
|
requestType: requestType,
|
||||||
requestName: requestName,
|
requestName: requestName,
|
||||||
requestTel: requestTel,
|
requestTel: requestTel,
|
||||||
requestEmail: requestEmail,
|
requestEmail: requestEmail,
|
||||||
contents: contents,
|
contents: contents,
|
||||||
};
|
};
|
||||||
qnaSave(params).then((rs) => {
|
qnaSave(params).then((rs: QnaSaveResponse) => {
|
||||||
alert('성공');
|
alert('성공');
|
||||||
navigate(PATHS.support.qna.list);
|
navigate(PATHS.support.qna.list);
|
||||||
});
|
});
|
||||||
@@ -118,9 +170,9 @@ export const QnaRegisterPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="inq-control">
|
<div className="inq-control">
|
||||||
<select
|
<select
|
||||||
value={ counselType }
|
value={ requestType }
|
||||||
required= { true }
|
required= { true }
|
||||||
onChange={ (e: ChangeEvent<HTMLSelectElement>) => setInputValue(e, QnaRegisterPropsName.CounselType) }
|
onChange={ (e: ChangeEvent<HTMLSelectElement>) => setInputValue(e, QnaRegisterPropsName.RequestType) }
|
||||||
>
|
>
|
||||||
<option value="">{t('support.qna.categories.choose')}</option>
|
<option value="">{t('support.qna.categories.choose')}</option>
|
||||||
<option value="01">{t('support.qna.categories.01')}</option>
|
<option value="01">{t('support.qna.categories.01')}</option>
|
||||||
@@ -164,7 +216,7 @@ export const QnaRegisterPage = () => {
|
|||||||
<div className="inq-label">이메일 주소</div>
|
<div className="inq-label">이메일 주소</div>
|
||||||
<div className="inq-control">
|
<div className="inq-control">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="email"
|
||||||
placeholder="TEST123@nicepay.com"
|
placeholder="TEST123@nicepay.com"
|
||||||
value={ requestEmail }
|
value={ requestEmail }
|
||||||
onChange={ (e: ChangeEvent<HTMLInputElement>) => setInputValue(e, QnaRegisterPropsName.RequestEmail) }
|
onChange={ (e: ChangeEvent<HTMLInputElement>) => setInputValue(e, QnaRegisterPropsName.RequestEmail) }
|
||||||
|
|||||||
33
src/widgets/intersection-observer/index.ts
Normal file
33
src/widgets/intersection-observer/index.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
interface useIntersectionObserverProps {
|
||||||
|
root?: null;
|
||||||
|
rootMargin?: string;
|
||||||
|
threshold?: number;
|
||||||
|
onIntersect: IntersectionObserverCallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
const useIntersectionObserver = ({
|
||||||
|
root,
|
||||||
|
rootMargin = '0px',
|
||||||
|
threshold = 0,
|
||||||
|
onIntersect
|
||||||
|
}: useIntersectionObserverProps) => {
|
||||||
|
const [target, setTarget] = useState<HTMLElement | null | undefined>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!target) return;
|
||||||
|
|
||||||
|
const observer: IntersectionObserver = new IntersectionObserver(
|
||||||
|
onIntersect,
|
||||||
|
{ root, rootMargin, threshold }
|
||||||
|
);
|
||||||
|
observer.observe(target);
|
||||||
|
|
||||||
|
return () => observer.unobserve(target);
|
||||||
|
}, [onIntersect, root, rootMargin, target, threshold]);
|
||||||
|
|
||||||
|
return { setTarget };
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useIntersectionObserver;
|
||||||
Reference in New Issue
Block a user