상세 수정
This commit is contained in:
@@ -16,6 +16,23 @@ export const DEFAULT_PAGE_PARAM = {
|
||||
sortType: SortTypeKeys.LATEST,
|
||||
};
|
||||
|
||||
export const DetailMotionVariants = {
|
||||
hidden: {
|
||||
x: '100%'
|
||||
},
|
||||
visible: {
|
||||
x: '0%'
|
||||
},
|
||||
};
|
||||
export const DetailMotionDuration = {
|
||||
duration: 0.3
|
||||
};
|
||||
export const DetailMotionStyle = {
|
||||
width: '100%',
|
||||
height: '100%'
|
||||
};
|
||||
|
||||
|
||||
export const FilterMotionVariants = {
|
||||
hidden: {
|
||||
x: '100%'
|
||||
|
||||
@@ -6,21 +6,19 @@ import { useTranslation } from 'react-i18next';
|
||||
import { IMAGE_ROOT } from '@/shared/constants/common';
|
||||
|
||||
export const HomeNoticeItem = ({
|
||||
seq,
|
||||
title,
|
||||
informCl,
|
||||
regDt,
|
||||
noticeItem,
|
||||
setDetailData,
|
||||
}: NoticeItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const onClickToDetail = () => {
|
||||
navigate(PATHS.support.notice.detail, {
|
||||
state: {
|
||||
seq: seq,
|
||||
from: PATHS.home
|
||||
}
|
||||
})
|
||||
if(setDetailData){
|
||||
setDetailData({
|
||||
seq: noticeItem.seq,
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -30,8 +28,8 @@ export const HomeNoticeItem = ({
|
||||
onClick={ () => onClickToDetail() }
|
||||
>
|
||||
<div className="notice-content">
|
||||
<div className="notice-title">{ title }</div>
|
||||
<div className="notice-meta">{ t(`support.notice.categories.${informCl}`) }<span>{ moment(regDt).format('YY년 MM월 DD일') }</span></div>
|
||||
<div className="notice-title">{ noticeItem.title }</div>
|
||||
<div className="notice-meta">{ t(`support.notice.categories.${noticeItem.informCl}`) }<span>{ noticeItem.regDt? moment(noticeItem.regDt).format('YY년 MM월 DD일'): '' }</span></div>
|
||||
</div>
|
||||
<div className="notice-arrow">
|
||||
<img
|
||||
|
||||
@@ -1,31 +1,43 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useNoticeListMutation } from '@/entities/support/api/use-notice-list-mutation';
|
||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
||||
import { NoticeItem } from '@/entities/support/model/types';
|
||||
import { DetailData, NoticeItem } from '@/entities/support/model/types';
|
||||
import { HomeNoticeItem } from './home-notice-item';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { NoticeDetail } from '@/entities/support/ui/detail/notice-detail';
|
||||
|
||||
export const HomeNoticeList = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM);
|
||||
const [resultList, setResultList] = useState<Array<NoticeItem>>([]);
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailSeq, setDetailSeq] = useState<number>(0);
|
||||
|
||||
const { mutateAsync: noticeList } = useNoticeListMutation();
|
||||
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
if(detailData?.seq){
|
||||
setDetailSeq(detailData?.seq);
|
||||
}
|
||||
};
|
||||
|
||||
const getItems = () => {
|
||||
let rs = [];
|
||||
let maxCnt = (!!resultList && resultList.length < 4)? resultList.length: 4;
|
||||
for(let i=0;i<maxCnt;i++){
|
||||
rs.push(
|
||||
<HomeNoticeItem
|
||||
key={ `key-home-notice-item-${i}` }
|
||||
seq={ resultList[i]?.seq }
|
||||
title={ resultList[i]?.title }
|
||||
informCl={ resultList[i]?.informCl }
|
||||
regDt={ resultList[i]?.regDt }
|
||||
></HomeNoticeItem>
|
||||
);
|
||||
let noticeItem = resultList[i];
|
||||
if(noticeItem){
|
||||
rs.push(
|
||||
<HomeNoticeItem
|
||||
key={ `key-home-notice-item-${i}` }
|
||||
noticeItem={ noticeItem }
|
||||
setDetailData={ setDetailData }
|
||||
></HomeNoticeItem>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
@@ -56,6 +68,11 @@ export const HomeNoticeList = () => {
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<NoticeDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
seq={ detailSeq }
|
||||
></NoticeDetail>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
0
src/entities/settlement/ui/detail/list-detail.tsx
Normal file
0
src/entities/settlement/ui/detail/list-detail.tsx
Normal file
@@ -21,9 +21,10 @@ export interface FaqListResponse extends DefaulResponsePagination {
|
||||
hasNext: boolean;
|
||||
nextCursor: string | null;
|
||||
};
|
||||
export interface FaqItemProps extends FaqItem {
|
||||
|
||||
}
|
||||
export interface FaqItemProps {
|
||||
faqItem: FaqItem,
|
||||
setDetailData?: (detailData: DetailData) => void;
|
||||
};
|
||||
export interface QnaListParams extends SupportParams {
|
||||
statusCode?: string;
|
||||
page?: DefaultRequestPagination;
|
||||
@@ -45,8 +46,15 @@ export interface QnaItem {
|
||||
export interface QnaListResponse extends DefaulResponsePagination {
|
||||
content: Array<QnaItem>
|
||||
};
|
||||
export interface QnaItemProps extends QnaItem {
|
||||
|
||||
export interface DetailData {
|
||||
qnaItem?: QnaItem;
|
||||
faqItem?: FaqItem;
|
||||
seq?: number;
|
||||
detailOn: boolean;
|
||||
};
|
||||
export interface QnaItemProps {
|
||||
qnaItem: QnaItem;
|
||||
setDetailData?: (detailData: DetailData) => void;
|
||||
};
|
||||
export interface QnaSaveParams extends SupportParams {
|
||||
requestType: string;
|
||||
@@ -100,6 +108,7 @@ export interface NoticeDetailParams {
|
||||
export interface NoticeDetailResponse extends NoticeItem {
|
||||
|
||||
};
|
||||
export interface NoticeItemProps extends NoticeItem {
|
||||
|
||||
}
|
||||
export interface NoticeItemProps {
|
||||
noticeItem: NoticeItem;
|
||||
setDetailData?: (detailData: DetailData) => void;
|
||||
};
|
||||
71
src/entities/support/ui/detail/faq-detail.tsx
Normal file
71
src/entities/support/ui/detail/faq-detail.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FaqItem } from '../../model/types';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
|
||||
export interface FaqDetaillProps {
|
||||
detailOn: boolean;
|
||||
setDetailOn: (detailOn: boolean) => void;
|
||||
faqItem: FaqItem
|
||||
};
|
||||
export const FaqDetail = ({
|
||||
detailOn,
|
||||
setDetailOn,
|
||||
faqItem
|
||||
}: FaqDetaillProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [cursorId, setCursorId] = useState<number>();
|
||||
const [seq, setSeq] = useState<string>();
|
||||
const [category, setCategory] = useState<string>();
|
||||
const [title, setTitle] = useState<string>();
|
||||
const [contents, setContents] = useState<string>();
|
||||
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setCursorId(faqItem?.cursorId);
|
||||
setSeq(faqItem?.seq);
|
||||
setCategory(faqItem?.category);
|
||||
setTitle(faqItem?.title);
|
||||
setContents(faqItem?.contents);
|
||||
}, [faqItem]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
>
|
||||
{ contents &&
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('support.qna.title') }</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane sub active">
|
||||
<div className="faq-detail">
|
||||
<div className="faq-detail__title">{ title }</div>
|
||||
<div className="faq-detail__divider"></div>
|
||||
<div className="faq-detail__body" dangerouslySetInnerHTML={{ __html: contents || '' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
81
src/entities/support/ui/detail/notice-detail.tsx
Normal file
81
src/entities/support/ui/detail/notice-detail.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useLocation } from 'react-router';
|
||||
import { NoticeDetailParams, NoticeDetailResponse, NoticeItem } from '../../model/types';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useNoticeDetailMutation } from '../../api/use-notice-detail-mutation';
|
||||
import moment from 'moment';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
|
||||
export interface NoticeDetaillProps {
|
||||
detailOn: boolean;
|
||||
setDetailOn: (detailOn: boolean) => void;
|
||||
seq: number;
|
||||
};
|
||||
export const NoticeDetail = ({
|
||||
detailOn,
|
||||
setDetailOn,
|
||||
seq
|
||||
}: NoticeDetaillProps) => {
|
||||
const location = useLocation();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [result, setResult] = useState<NoticeItem>({});
|
||||
|
||||
const { mutateAsync: noticeDetail } = useNoticeDetailMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let detailParams: NoticeDetailParams = {
|
||||
seq: seq,
|
||||
};
|
||||
noticeDetail(detailParams).then((rs: NoticeDetailResponse) => {
|
||||
setResult(rs);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callDetail();
|
||||
}, [seq]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
>
|
||||
{ result.informCl &&
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('support.notice.title') }</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className="notice-detail">
|
||||
<div className="notice-detail__title">{ result.title }</div>
|
||||
<div className="notice-detail__meta">{ result.regDt? moment(result.regDt).format('YYYY.MM.DD'): '' } | { t(`support.notice.categories.${result.informCl}`) }</div>
|
||||
<div className="notice-detail__divider"></div>
|
||||
<div className="notice-detail__body" dangerouslySetInnerHTML={{ __html: result.contents || '' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
110
src/entities/support/ui/detail/qna-detail.tsx
Normal file
110
src/entities/support/ui/detail/qna-detail.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import moment from 'moment';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { QnaItem } from '../../model/types';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
|
||||
export interface qnaDetaillProps {
|
||||
detailOn: boolean;
|
||||
setDetailOn: (detailOn: boolean) => void;
|
||||
qnaItem: QnaItem;
|
||||
};
|
||||
export const QnaDetail = ({
|
||||
detailOn,
|
||||
setDetailOn,
|
||||
qnaItem
|
||||
}: qnaDetaillProps) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [answer, setAnswer] = useState<string>();
|
||||
const [answerDate, setAnswerDate] = useState<string>();
|
||||
const [contents, setContents] = useState<string>();
|
||||
const [corpName, setCorpName] = useState<string | null>();
|
||||
const [cursorId, setCursorId] = useState<number>();
|
||||
const [requestDate, setRequestDate] = useState<string>();
|
||||
const [requestName, setRequestName] = useState<string>();
|
||||
const [requestType, setRequestType] = useState<string>();
|
||||
const [sendEmail, setSendEmail] = useState<string | null>();
|
||||
const [seq, setSeq] = useState<string>();
|
||||
const [statusCode, setStatusCode] = useState<string>();
|
||||
const [title, setTitle] = useState<string>();
|
||||
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setAnswer(qnaItem?.answer);
|
||||
setAnswerDate(qnaItem?.answerDate);
|
||||
setContents(qnaItem?.contents);
|
||||
setCorpName(qnaItem?.corpName);
|
||||
setCursorId(qnaItem?.cursorId);
|
||||
setRequestDate(qnaItem?.requestDate);
|
||||
setRequestName(qnaItem?.requestName);
|
||||
setRequestType(qnaItem?.requestType);
|
||||
setSendEmail(qnaItem?.sendEmail);
|
||||
setSeq(qnaItem?.seq);
|
||||
setStatusCode(qnaItem?.statusCode);
|
||||
setTitle(qnaItem?.title);
|
||||
}, [qnaItem]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
>
|
||||
{ statusCode &&
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('support.qna.title') }</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane active">
|
||||
<div className="inq-detail">
|
||||
<div className="inq-detail__head">
|
||||
<div className="inq-detail__row">
|
||||
<span className="inq-badge">{t('support.qna.detailLabels.title')}</span>
|
||||
<span className="inq-head-text bold">{ title }</span>
|
||||
</div>
|
||||
<div className="inq-detail__row">
|
||||
<span className="inq-badge">{t('support.qna.detailLabels.type')}</span>
|
||||
<span className="inq-head-text">{ t(`support.qna.categories.${requestType}`) }</span>
|
||||
</div>
|
||||
<div className="inq-detail__row">
|
||||
<span className="inq-badge">{t('support.qna.detailLabels.registrationDate')}</span>
|
||||
<span className="inq-head-text">{ !!requestDate? moment(requestDate).format('YYYY.MM.DD'): '' }</span>
|
||||
</div>
|
||||
<div className="inq-detail__row">
|
||||
<span className="inq-badge">{t('support.qna.detailLabels.answerDate')}</span>
|
||||
<span className="inq-head-text">{ !!answerDate? moment(answerDate).format('YYYY.MM.DD'): '' }</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="inq-detail__divider"></div>
|
||||
<div className="inq-detail__section">
|
||||
<div className="inq-detail__section-title">{t('support.qna.detailLabels.inquiryAnswer')}</div>
|
||||
<div className="inq-detail__body" dangerouslySetInnerHTML={{ __html: answer || '' }}></div>
|
||||
</div>
|
||||
<div className="inq-detail__section">
|
||||
<div className="inq-detail__section-title">{t('support.qna.detailLabels.inquiryContents')}</div>
|
||||
<div className="inq-detail__body" dangerouslySetInnerHTML={{ __html: contents || '' }}></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -4,36 +4,29 @@ import { FaqItemProps } from '../model/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const SupportFaqItem = ({
|
||||
cursorId,
|
||||
seq,
|
||||
category,
|
||||
title,
|
||||
contents,
|
||||
faqItem,
|
||||
setDetailData
|
||||
}: FaqItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const onClickToDetail = () => {
|
||||
navigate(PATHS.support.faq.detail, {
|
||||
state: {
|
||||
cursorId,
|
||||
seq,
|
||||
category,
|
||||
title,
|
||||
contents
|
||||
}
|
||||
});
|
||||
if(setDetailData){
|
||||
setDetailData({
|
||||
faqItem: faqItem,
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="faq-row"
|
||||
onClick={ () => onClickToDetail() }
|
||||
onClick={ onClickToDetail }
|
||||
>
|
||||
<div className="faq-txt">
|
||||
<div className="faq-title">{ title }</div>
|
||||
<div className="faq-tag">{ t('support.faq.categories.' + category) }</div>
|
||||
<div className="faq-title">{ faqItem.title }</div>
|
||||
<div className="faq-tag">{ t('support.faq.categories.' + faqItem.category) }</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -5,21 +5,19 @@ import { NoticeItemProps } from '../model/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const SupportNoticeItem = ({
|
||||
seq,
|
||||
title,
|
||||
informCl,
|
||||
regDt,
|
||||
noticeItem,
|
||||
setDetailData,
|
||||
}: NoticeItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const onClickToDetail = () => {
|
||||
navigate(PATHS.support.notice.detail, {
|
||||
state: {
|
||||
seq: seq,
|
||||
from: PATHS.support.notice.list
|
||||
}
|
||||
})
|
||||
if(setDetailData){
|
||||
setDetailData({
|
||||
seq: noticeItem.seq,
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -29,9 +27,9 @@ export const SupportNoticeItem = ({
|
||||
onClick={ () => onClickToDetail() }
|
||||
>
|
||||
<div className="notice-txt">
|
||||
<div className="notice-title-114">{ title }</div>
|
||||
<div className="notice-title-114">{ noticeItem.title }</div>
|
||||
<div className="notice-meta-114">
|
||||
<span className="blue">{ t(`support.notice.categories.${informCl}`) }</span> ㅣ <span>{ moment(regDt).format('YYYY.MM.DD HH:mm:ss') }</span>
|
||||
<span className="blue">{ t(`support.notice.categories.${noticeItem.informCl}`) }</span> ㅣ <span>{ noticeItem.regDt? moment(noticeItem.regDt).format('YYYY.MM.DD HH:mm:ss'): '' }</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,42 +1,19 @@
|
||||
import moment from 'moment';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { QnaItemProps } from '../model/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const SupportQnaItem = ({
|
||||
answer,
|
||||
answerDate,
|
||||
contents,
|
||||
corpName,
|
||||
cursorId,
|
||||
requestDate,
|
||||
requestName,
|
||||
requestType,
|
||||
sendEmail,
|
||||
seq,
|
||||
statusCode,
|
||||
title
|
||||
qnaItem,
|
||||
setDetailData
|
||||
}: QnaItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const onClickToDetail = () => {
|
||||
navigate(PATHS.support.qna.detail, {
|
||||
state: {
|
||||
answer: answer,
|
||||
answerDate: answerDate,
|
||||
contents: contents,
|
||||
corpName: corpName,
|
||||
cursorId: cursorId,
|
||||
requestDate: requestDate,
|
||||
requestName: requestName,
|
||||
requestType: requestType,
|
||||
sendEmail: sendEmail,
|
||||
seq: seq,
|
||||
statusCode: statusCode,
|
||||
title: title
|
||||
}
|
||||
});
|
||||
if(setDetailData){
|
||||
setDetailData({
|
||||
qnaItem: qnaItem,
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -46,12 +23,12 @@ export const SupportQnaItem = ({
|
||||
onClick={ () => onClickToDetail() }
|
||||
>
|
||||
<div className="inq-line">
|
||||
<div className="inq-title-text">{ title }</div>
|
||||
<div className="inq-title-text">{ qnaItem.title }</div>
|
||||
<div className="inq-meta">
|
||||
{t('support.qna.registrationDate')}<span>{ moment(requestDate).format('YYYY.MM.DD') }</span>
|
||||
<span className="sai">ㅣ</span>{t('support.qna.status')} <span>[{t(`support.qna.statusCode.${statusCode}`)}]</span>
|
||||
{t('support.qna.registrationDate')}<span>{ qnaItem.requestDate? moment(qnaItem.requestDate).format('YYYY.MM.DD'): '' }</span>
|
||||
<span className="sai">ㅣ</span>{t('support.qna.status')} <span>[{t(`support.qna.statusCode.${qnaItem.statusCode}`)}]</span>
|
||||
</div>
|
||||
<span className={`dot ${(statusCode === '03')? 'blue': 'gray'}`}></span>
|
||||
<span className={`dot ${(qnaItem.statusCode === '03')? 'blue': 'gray'}`}></span>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -136,29 +136,40 @@ export enum BillingPaymentMethod {
|
||||
MOBILE_PAYMENT = 'MOBILE_PAYMENT'
|
||||
};
|
||||
|
||||
export interface DetailData {
|
||||
tid: string;
|
||||
serviceCode?: string;
|
||||
detailOn: boolean;
|
||||
}
|
||||
export interface ListItemProps extends AllTransactionListItem, CashReceiptListItem, EscrowListItem, BillingListItem {
|
||||
transactionCategory?: TransactionCategory;
|
||||
setDetailData?: (detailData: DetailData) => void;
|
||||
};
|
||||
export interface ListDateGroupProps {
|
||||
transactionCategory?: TransactionCategory;
|
||||
date?: string;
|
||||
items?: Array<ListItemProps>;
|
||||
setDetailData?: (detailData: DetailData) => void;
|
||||
};
|
||||
export interface AllTransactionListProps {
|
||||
transactionCategory: TransactionCategory;
|
||||
listItems: Array<ListItemProps>;
|
||||
setDetailData: (detailData: DetailData) => void;
|
||||
};
|
||||
export interface CashReceiptListProps {
|
||||
transactionCategory: TransactionCategory;
|
||||
listItems: Array<ListItemProps>;
|
||||
setDetailData: (detailData: DetailData) => void;
|
||||
};
|
||||
export interface EscrowListProps {
|
||||
transactionCategory: TransactionCategory;
|
||||
listItems: Array<ListItemProps>;
|
||||
setDetailData: (detailData: DetailData) => void;
|
||||
};
|
||||
export interface BillingListProps {
|
||||
transactionCategory: TransactionCategory;
|
||||
listItems: Array<ListItemProps>;
|
||||
setDetailData: (detailData: DetailData) => void;
|
||||
};
|
||||
export interface AllTransactionListItem {
|
||||
tid?: string;
|
||||
|
||||
@@ -28,12 +28,7 @@ export const AllTransactionCancelPreventBond = ({
|
||||
const { navigate } = useNavigate();
|
||||
const [item, setItem] = useState<DebtPreventionCancelDisplayInfo | null | undefined>(debtPreventionCancelDisplayInfo);
|
||||
const onClickToClose = () => {
|
||||
navigate(PATHS.transaction.allTransaction.detail, {
|
||||
state: {
|
||||
serviceCode: serviceCode,
|
||||
tid: tid
|
||||
}
|
||||
});
|
||||
setCancelPreventBondOn(false);
|
||||
};
|
||||
const callTransactionCancel = () => {
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ import { ListDateGroup } from './list-date-group';
|
||||
|
||||
export const AllTransactionList = ({
|
||||
transactionCategory,
|
||||
listItems
|
||||
listItems,
|
||||
setDetailData
|
||||
}: AllTransactionListProps) => {
|
||||
const getListDateGroup = () => {
|
||||
let rs = [];
|
||||
@@ -26,6 +27,7 @@ export const AllTransactionList = ({
|
||||
key={ date + '-' + i }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
@@ -43,6 +45,7 @@ export const AllTransactionList = ({
|
||||
key={ date + '-last' }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,10 +6,9 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const BillingList = ({
|
||||
transactionCategory,
|
||||
listItems
|
||||
listItems,
|
||||
setDetailData
|
||||
}: BillingListProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const getListDateGroup = () => {
|
||||
let rs = [];
|
||||
@@ -31,6 +30,7 @@ export const BillingList = ({
|
||||
key={ date + '-' + i }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
@@ -48,27 +48,20 @@ export const BillingList = ({
|
||||
key={ date + '-last' }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.transaction.billing.charge);
|
||||
};
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="transaction-list">
|
||||
{ getListDateGroup() }
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigate() }
|
||||
>{ t('transaction.list.paymentRequest') }</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -6,7 +6,8 @@ import { useTranslation } from 'react-i18next';
|
||||
|
||||
export const CashReceiptList = ({
|
||||
transactionCategory,
|
||||
listItems
|
||||
listItems,
|
||||
setDetailData
|
||||
}: CashReceiptListProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
@@ -31,6 +32,7 @@ export const CashReceiptList = ({
|
||||
key={ date + '-' + i }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
@@ -48,27 +50,19 @@ export const CashReceiptList = ({
|
||||
key={ date + '-last' }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.transaction.cashReceipt.handWrittenIssuance);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="transaction-list">
|
||||
{ getListDateGroup() }
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigate() }
|
||||
>{ t('transaction.list.manualIssuance') }</button>
|
||||
</div>
|
||||
|
||||
</>
|
||||
);
|
||||
};
|
||||
238
src/entities/transaction/ui/detail/all-transaction-detail.tsx
Normal file
238
src/entities/transaction/ui/detail/all-transaction-detail.tsx
Normal file
@@ -0,0 +1,238 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { Dialog } from '@/shared/ui/dialogs/dialog';
|
||||
import { overlay } from 'overlay-kit';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useAllTransactionDetailMutation } from '@/entities/transaction/api/use-all-transaction-detail-mutation';
|
||||
import { AmountInfoSection } from '@/entities/transaction/ui/section/amount-info-section';
|
||||
import { ImportantInfoSection } from '@/entities/transaction/ui/section/important-info-section';
|
||||
import { PaymentInfoSection } from '@/entities/transaction/ui/section/payment-info-section';
|
||||
import { TransactionInfoSection } from '@/entities/transaction/ui/section/transaction-info-section';
|
||||
import { SettlementInfoSection } from '@/entities/transaction/ui/section/settlement-info-section';
|
||||
import { PartCancelInfoSection } from '@/entities/transaction/ui/section/part-cancel-info-section';
|
||||
import {
|
||||
TransactionCategory,
|
||||
AllTransactionDetailParams,
|
||||
DetailResponse,
|
||||
AmountInfo,
|
||||
ImportantInfo,
|
||||
PaymentInfo,
|
||||
TransactionInfo,
|
||||
SettlementInfo,
|
||||
PartCancelInfo,
|
||||
InfoSectionKeys
|
||||
} from '@/entities/transaction/model/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
DetailMotionDuration,
|
||||
DetailMotionStyle,
|
||||
DetailMotionVariants
|
||||
} from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
|
||||
export interface AllTransactionDetailProps {
|
||||
detailOn: boolean;
|
||||
setDetailOn: (detailOn: boolean) => void;
|
||||
tid: string;
|
||||
serviceCode: string;
|
||||
};
|
||||
|
||||
export const AllTransactionDetail = ({
|
||||
detailOn,
|
||||
setDetailOn,
|
||||
tid,
|
||||
serviceCode
|
||||
}: AllTransactionDetailProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [amountInfo, setAmountInfo] = useState<AmountInfo>();
|
||||
const [importantInfo, setImportantInfo] = useState<ImportantInfo>();
|
||||
const [paymentInfo, setPaymentInfo] = useState<PaymentInfo>();
|
||||
const [transactionInfo, setTransactionInfo] = useState<TransactionInfo>();
|
||||
const [settlementInfo, setSettlementInfo] = useState<SettlementInfo>();
|
||||
const [partCancelInfo, setPartCancelInfo] = useState<PartCancelInfo>();
|
||||
const [showAmountInfo, setShowAmountInfo] = useState<boolean>(false);
|
||||
const [showPaymentInfo, setShowPaymentInfo] = useState<boolean>(false);
|
||||
const [showTransactionInfo, setShowTransactionInfo] = useState<boolean>(false);
|
||||
const [showSettlementInfo, setShowSettlementInfo] = useState<boolean>(false);
|
||||
const [showPartCancelInfo, setShowPartCancelInfo] = useState<boolean>(false);
|
||||
|
||||
const { mutateAsync: allTransactionDetail } = useAllTransactionDetailMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let allTransactionDetailParams: AllTransactionDetailParams = {
|
||||
serviceCode: serviceCode,
|
||||
tid: tid
|
||||
};
|
||||
allTransactionDetail(allTransactionDetailParams).then((rs: DetailResponse) => {
|
||||
setAmountInfo(rs.amountInfo);
|
||||
setImportantInfo(rs.importantInfo);
|
||||
setPaymentInfo(rs.paymentInfo);
|
||||
setTransactionInfo(rs.transactionInfo);
|
||||
setSettlementInfo(rs.settlementInfo);
|
||||
setPartCancelInfo(rs.partCancelInfo);
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if(!!detailOn && serviceCode && tid){
|
||||
callDetail();
|
||||
}
|
||||
}, [detailOn]);
|
||||
|
||||
const onClickToNavigate = (path: string) => {
|
||||
let timeout = setTimeout(() => {
|
||||
clearTimeout(timeout);
|
||||
navigate(PATHS.transaction.allTransaction.cancel, {
|
||||
state: {
|
||||
serviceCode: serviceCode,
|
||||
tid: tid
|
||||
}
|
||||
});
|
||||
}, 10)
|
||||
};
|
||||
|
||||
const onClickToCancel = () => {
|
||||
let msg = t('transaction.confirmCancel');
|
||||
|
||||
overlay.open(({
|
||||
isOpen,
|
||||
close,
|
||||
unmount
|
||||
}) => {
|
||||
return (
|
||||
<Dialog
|
||||
afterLeave={ unmount }
|
||||
open={ isOpen }
|
||||
onClose={ close }
|
||||
onConfirmClick={ () => onClickToNavigate(PATHS.transaction.allTransaction.cancel) }
|
||||
// onConfirmClick={ () => callCancelInfo() }
|
||||
message={ msg }
|
||||
buttonLabel={[t('common.cancel'), t('common.confirm')]}
|
||||
/>
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
|
||||
const onClickToOpenInfo = (infoSectionKey: InfoSectionKeys) => {
|
||||
if(infoSectionKey === InfoSectionKeys.Amount){
|
||||
setShowAmountInfo(!showAmountInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Payment){
|
||||
setShowPaymentInfo(!showPaymentInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Transaction){
|
||||
setShowTransactionInfo(!showTransactionInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Settlement){
|
||||
setShowSettlementInfo(!showSettlementInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.PartCancel){
|
||||
setShowPartCancelInfo(!showPartCancelInfo);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('transaction.detailTitle') }</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list pb-86">
|
||||
<div className="txn-detail">
|
||||
<AmountInfoSection
|
||||
transactionCategory={ TransactionCategory.AllTransaction }
|
||||
amountInfo={ amountInfo }
|
||||
isOpen={ showAmountInfo }
|
||||
tid={ tid }
|
||||
serviceCode={ serviceCode }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></AmountInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<ImportantInfoSection
|
||||
transactionCategory={ TransactionCategory.AllTransaction }
|
||||
importantInfo={ importantInfo }
|
||||
serviceCode={ serviceCode }
|
||||
></ImportantInfoSection>
|
||||
{ !!paymentInfo &&
|
||||
<>
|
||||
<div className="txn-divider"></div>
|
||||
<PaymentInfoSection
|
||||
transactionCategory={ TransactionCategory.AllTransaction }
|
||||
paymentInfo={ paymentInfo }
|
||||
serviceCode={ serviceCode }
|
||||
isOpen={ showPaymentInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></PaymentInfoSection>
|
||||
</>
|
||||
}
|
||||
{ !!transactionInfo &&
|
||||
<>
|
||||
<div className="txn-divider"></div>
|
||||
<TransactionInfoSection
|
||||
transactionCategory={ TransactionCategory.AllTransaction }
|
||||
transactionInfo={ transactionInfo }
|
||||
serviceCode={ serviceCode }
|
||||
isOpen={ showTransactionInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></TransactionInfoSection>
|
||||
</>
|
||||
}
|
||||
{ !!settlementInfo &&
|
||||
<>
|
||||
<div className="txn-divider"></div>
|
||||
<SettlementInfoSection
|
||||
transactionCategory={ TransactionCategory.AllTransaction }
|
||||
settlementInfo={ settlementInfo }
|
||||
serviceCode={ serviceCode }
|
||||
isOpen={ showSettlementInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></SettlementInfoSection>
|
||||
</>
|
||||
}
|
||||
{ !!partCancelInfo &&
|
||||
<>
|
||||
<div className="txn-divider"></div>
|
||||
<PartCancelInfoSection
|
||||
transactionCategory={ TransactionCategory.AllTransaction }
|
||||
partCancelInfo={ partCancelInfo }
|
||||
serviceCode={ serviceCode }
|
||||
isOpen={ showPartCancelInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></PartCancelInfoSection>
|
||||
</>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToCancel() }
|
||||
>{t('transaction.cancelTransaction')}</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
107
src/entities/transaction/ui/detail/billing-detail.tsx
Normal file
107
src/entities/transaction/ui/detail/billing-detail.tsx
Normal file
@@ -0,0 +1,107 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useBillingDetailMutation } from '@/entities/transaction/api/use-billing-detail-mutation';
|
||||
import { BillingInfoSection } from '@/entities/transaction/ui/section/billing-info-section';
|
||||
import {
|
||||
TransactionCategory,
|
||||
BillingDetailParams,
|
||||
BillingDetailResponse,
|
||||
BillingInfo,
|
||||
AmountInfo
|
||||
} from '@/entities/transaction/model/types';
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
|
||||
export interface BillingDetailProps {
|
||||
detailOn: boolean;
|
||||
setDetailOn: (detailOn: boolean) => void;
|
||||
tid: string;
|
||||
};
|
||||
|
||||
export const BillingDetail = ({
|
||||
detailOn,
|
||||
setDetailOn,
|
||||
tid
|
||||
}: BillingDetailProps) => {
|
||||
const { t, i18n } = useTranslation();
|
||||
|
||||
const [billingInfo, setBillingInfo] = useState<BillingInfo>();
|
||||
const [amountInfo, setAmountInfo] = useState<AmountInfo>();
|
||||
|
||||
const { mutateAsync: billingDetail } = useBillingDetailMutation();
|
||||
|
||||
const callDetail = () => {
|
||||
let billingDetailParams: BillingDetailParams = {
|
||||
tid: tid
|
||||
};
|
||||
billingDetail(billingDetailParams).then((rs: BillingDetailResponse) => {
|
||||
setBillingInfo(rs);
|
||||
setAmountInfo({
|
||||
transactionAmount: rs.transactionAmount,
|
||||
buyerName: rs.buyerName
|
||||
})
|
||||
});
|
||||
};
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
useEffect(() => {
|
||||
if(!!detailOn && tid){
|
||||
callDetail();
|
||||
}
|
||||
}, [detailOn]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('billing.detailTitle') }</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className="txn-detail">
|
||||
<div className="txn-num-group">
|
||||
<div className="txn-amount">
|
||||
<div className="value">
|
||||
{ i18n.language === 'en' && <span className="unit">{ t('home.currencySymbol') }</span> }
|
||||
<NumericFormat
|
||||
value={ amountInfo?.transactionAmount }
|
||||
thousandSeparator
|
||||
displayType="text"
|
||||
></NumericFormat>
|
||||
{ i18n.language !== 'en' && <span className="unit">{ t('home.currencyWon') }</span> }
|
||||
</div>
|
||||
</div>
|
||||
<div className="txn-mid">
|
||||
<span className="value">{ amountInfo?.buyerName }</span>
|
||||
</div>
|
||||
<div className="txn-doc"></div>
|
||||
</div>
|
||||
<div className="txn-divider"></div>
|
||||
<BillingInfoSection
|
||||
billingInfo={ billingInfo }
|
||||
></BillingInfoSection>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
178
src/entities/transaction/ui/detail/cash-receit-detail.tsx
Normal file
178
src/entities/transaction/ui/detail/cash-receit-detail.tsx
Normal file
@@ -0,0 +1,178 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useCashReceiptDetailMutation } from '@/entities/transaction/api/use-cash-receipt-detail-mutation';
|
||||
import { IssueInfoSection } from '@/entities/transaction/ui/section/issue-info-section';
|
||||
import { DetailInfoSection } from '@/entities/transaction/ui/section/detail-info-section';
|
||||
import {
|
||||
TransactionCategory,
|
||||
CashReceiptDetailParams,
|
||||
DetailResponse,
|
||||
IssueInfo,
|
||||
DetailInfo,
|
||||
InfoSectionKeys,
|
||||
CashReceiptPurposeType,
|
||||
AmountInfo,
|
||||
CashReceiptPurposeUpdateParams,
|
||||
CashReceiptTransactionType
|
||||
} from '@/entities/transaction/model/types';
|
||||
import { CashReceitPurposeUpdateBottomSheet } from '@/entities/transaction/ui/cash-receit-purpose-update-bottom-sheet';
|
||||
import { useCashReceiptPurposeUpdateMutation } from '@/entities/transaction/api/use-cash-receipt-purpose-update-mutation';
|
||||
import { AmountInfoSection } from '@/entities/transaction/ui/section/amount-info-section';
|
||||
import { snackBar } from '@/shared/lib';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
|
||||
export interface CashReceiptDetailProps {
|
||||
detailOn: boolean;
|
||||
setDetailOn: (detailOn: boolean) => void;
|
||||
tid: string;
|
||||
};
|
||||
|
||||
export const CashReceiptDetail = ({
|
||||
detailOn,
|
||||
setDetailOn,
|
||||
tid
|
||||
}: CashReceiptDetailProps) => {
|
||||
const { navigate, reload } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
|
||||
const [amountInfo, setAmountInfo] = useState<AmountInfo>();
|
||||
const [issueInfo, setIssueInfo] = useState<IssueInfo>();
|
||||
const [detailInfo, setDetailInfo] = useState<DetailInfo>();
|
||||
const [showAmountInfo, setShowAmountInfo] = useState<boolean>(false);
|
||||
const [showDetailInfo, setShowDetailInfo] = useState<boolean>(false);
|
||||
const [bottomSheetOn, setBottomSheetOn] = useState<boolean>(false);
|
||||
const [purposeType, setPurposeType] = useState<string>();
|
||||
const [canDownloadReceipt, setCanDownloadReceipt] = useState<boolean>(false);
|
||||
|
||||
const { mutateAsync: cashReceiptDetail } = useCashReceiptDetailMutation();
|
||||
const { mutateAsync: cashReceiptPurposeUpdate } = useCashReceiptPurposeUpdateMutation();
|
||||
|
||||
const callPurposeUpdate = () => {
|
||||
let newPurpose = (purposeType === CashReceiptPurposeType.EXPENSE_PROOF)
|
||||
? CashReceiptPurposeType.INCOME_DEDUCTION: CashReceiptPurposeType.EXPENSE_PROOF;
|
||||
let params: CashReceiptPurposeUpdateParams = {
|
||||
tid: tid,
|
||||
newPurpose: newPurpose
|
||||
};
|
||||
cashReceiptPurposeUpdate(params).then((rs) => {
|
||||
setPurposeType(rs.afterPurposeType);
|
||||
setBottomSheetOn(false);
|
||||
snackBar('용도 변경을 성공하였습니다.', function(){
|
||||
reload();
|
||||
}, 2000);
|
||||
});
|
||||
};
|
||||
|
||||
const callDetail = () => {
|
||||
let cashReceitDetailParams: CashReceiptDetailParams = {
|
||||
tid: tid
|
||||
};
|
||||
cashReceiptDetail(cashReceitDetailParams).then((rs: DetailResponse) => {
|
||||
if(rs.amountDetail){
|
||||
rs.amountDetail.customerName = rs.customerName;
|
||||
}
|
||||
setAmountInfo(rs.amountDetail || {});
|
||||
setIssueInfo(rs.issueInfo || {});
|
||||
setDetailInfo(rs.detailInfo || {});
|
||||
setCanDownloadReceipt(rs.detailInfo?.canDownloadReceipt || false);
|
||||
if(rs.issueInfo){
|
||||
setPurposeType(rs.issueInfo.purpose);
|
||||
}
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if(!!detailOn && tid){
|
||||
callDetail();
|
||||
}
|
||||
}, [tid]);
|
||||
|
||||
const onClickToOpenInfo = (infoSectionKey: InfoSectionKeys) => {
|
||||
if(infoSectionKey === InfoSectionKeys.Amount){
|
||||
setShowAmountInfo(!showAmountInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Detail){
|
||||
setShowDetailInfo(!showDetailInfo);
|
||||
}
|
||||
};
|
||||
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
|
||||
const onClickToPurposeUpdate = () => {
|
||||
setBottomSheetOn(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('cashReceipt.detailTitle') }</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane sub active">
|
||||
<div className={ `option-list ${(detailInfo?.canDownloadReceipt)? 'pb-86': ''}` }>
|
||||
<div className="txn-detail">
|
||||
<AmountInfoSection
|
||||
transactionCategory={ TransactionCategory.CashReceipt }
|
||||
amountInfo={ amountInfo }
|
||||
isOpen={ showAmountInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
purposeType={ purposeType }
|
||||
canDownloadReceipt={ canDownloadReceipt }
|
||||
></AmountInfoSection>
|
||||
<div className="txn-divider"></div>
|
||||
<IssueInfoSection
|
||||
transactionCategory={ TransactionCategory.CashReceipt }
|
||||
issueInfo={ issueInfo }
|
||||
purposeType={ purposeType }
|
||||
></IssueInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
{ !!detailInfo &&
|
||||
<DetailInfoSection
|
||||
transactionCategory={ TransactionCategory.CashReceipt }
|
||||
detailInfo={ detailInfo }
|
||||
isOpen={ showDetailInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></DetailInfoSection>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
{ (issueInfo?.transactionType === CashReceiptTransactionType.APPROVAL) &&
|
||||
(issueInfo?.processResult === '발급완료') &&
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToPurposeUpdate() }
|
||||
>{ t('cashReceipt.changePurpose') }</button>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
<CashReceitPurposeUpdateBottomSheet
|
||||
setBottomSheetOn={ setBottomSheetOn }
|
||||
bottomSheetOn={ bottomSheetOn }
|
||||
callPurposeUpdate={ callPurposeUpdate }
|
||||
></CashReceitPurposeUpdateBottomSheet>
|
||||
</>
|
||||
);
|
||||
};
|
||||
225
src/entities/transaction/ui/detail/escrow-detail.tsx
Normal file
225
src/entities/transaction/ui/detail/escrow-detail.tsx
Normal file
@@ -0,0 +1,225 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { motion } from 'framer-motion';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useEscrowDetailMutation } from '@/entities/transaction/api/use-escrow-detail-mutation';
|
||||
import { ImportantInfoSection } from '@/entities/transaction/ui/section/important-info-section';
|
||||
import { EscrowInfoSection } from '@/entities/transaction/ui/section/escrow-info-section';
|
||||
import { PaymentInfoSection } from '@/entities/transaction/ui/section/payment-info-section';
|
||||
import { TransactionInfoSection } from '@/entities/transaction/ui/section/transaction-info-section';
|
||||
import { SettlementInfoSection } from '@/entities/transaction/ui/section/settlement-info-section';
|
||||
import {
|
||||
TransactionCategory,
|
||||
EscrowDetailParams,
|
||||
DetailResponse,
|
||||
ImportantInfo,
|
||||
EscrowInfo,
|
||||
PaymentInfo,
|
||||
TransactionInfo,
|
||||
SettlementInfo,
|
||||
InfoSectionKeys,
|
||||
MerchantInfo,
|
||||
AmountInfo
|
||||
} from '@/entities/transaction/model/types';
|
||||
import { useEscrowMailResendMutation } from '@/entities/transaction/api/use-escrow-mail-resend-mutation';
|
||||
import { MerchantInfoSection } from '@/entities/transaction/ui/section/merchant-info-section';
|
||||
import { AmountInfoSection } from '@/entities/transaction/ui/section/amount-info-section';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
|
||||
export interface EscrowDetailProps {
|
||||
detailOn: boolean;
|
||||
setDetailOn: (detailOn: boolean) => void;
|
||||
tid: string;
|
||||
serviceCode: string;
|
||||
};
|
||||
|
||||
export const EscrowDetail = ({
|
||||
detailOn,
|
||||
setDetailOn,
|
||||
tid,
|
||||
serviceCode
|
||||
}: EscrowDetailProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [amountInfo, setAmountInfo] = useState<AmountInfo>();
|
||||
const [importantInfo, setImportantInfo] = useState<ImportantInfo>();
|
||||
const [escrowInfo, setEscrowInfo] = useState<EscrowInfo>();
|
||||
const [paymentInfo, setPaymentInfo] = useState<PaymentInfo>();
|
||||
const [transactionInfo, setTransactionInfo] = useState<TransactionInfo>();
|
||||
const [settlementInfo, setSettlementInfo] = useState<SettlementInfo>();
|
||||
const [merchantInfo, setMerchantInfo] = useState<MerchantInfo>();
|
||||
|
||||
const [showAmountInfo, setShowAmountInfo] = useState<boolean>(false);
|
||||
const [showImportantInfo, setShowImportantInfo] = useState<boolean>(false);
|
||||
const [showEscroInfo, setShowEscroInfo] = useState<boolean>(false);
|
||||
const [showPaymentInfo, setShowPaymentInfo] = useState<boolean>(false);
|
||||
const [showTransactionInfo, setShowTransactionInfo] = useState<boolean>(false);
|
||||
const [showSettlementInfo, setShowSettlementInfo] = useState<boolean>(false);
|
||||
const [showMerchantInfo, setShowMerchantInfo] = useState<boolean>(false);
|
||||
|
||||
const [bottomSheetOn, setBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const [orderNumber, setOrderNumber] = useState<string>();
|
||||
|
||||
const { mutateAsync: escrowDetail } = useEscrowDetailMutation();
|
||||
const { mutateAsync: escrowMailResend } = useEscrowMailResendMutation()
|
||||
|
||||
const callDetail = () => {
|
||||
let escroDetailParams: EscrowDetailParams = {
|
||||
tid: tid,
|
||||
};
|
||||
escrowDetail(escroDetailParams).then((rs: DetailResponse) => {
|
||||
setAmountInfo(rs.paymentInfo || {});
|
||||
setImportantInfo(rs.importantInfo || {});
|
||||
setEscrowInfo(rs.escrowInfo || {});
|
||||
setPaymentInfo(rs.paymentInfo || {});
|
||||
setTransactionInfo(rs.transactionInfo || {});
|
||||
setSettlementInfo(rs.settlementInfo || {});
|
||||
setMerchantInfo(rs.merchantInfo || {});
|
||||
|
||||
setOrderNumber(rs.importantInfo?.orderNumber);
|
||||
});
|
||||
};
|
||||
useEffect(() => {
|
||||
if(!!detailOn && serviceCode && tid){
|
||||
callDetail();
|
||||
}
|
||||
}, [detailOn]);
|
||||
|
||||
|
||||
const onClickToShowMailResend = () => {
|
||||
setBottomSheetOn(true);
|
||||
};
|
||||
|
||||
const callMailResend = () => {
|
||||
let params = {
|
||||
orderNumber: orderNumber,
|
||||
tid: tid,
|
||||
};
|
||||
escrowMailResend(params).then((rs: any) => {
|
||||
console.log(rs);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
|
||||
const onClickToOpenInfo = (infoSectionKey: InfoSectionKeys) => {
|
||||
if(infoSectionKey === InfoSectionKeys.Amount){
|
||||
setShowAmountInfo(!showAmountInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Important){
|
||||
setShowImportantInfo(!showImportantInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Escrow){
|
||||
setShowEscroInfo(!showEscroInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Payment){
|
||||
setShowPaymentInfo(!showPaymentInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Transaction){
|
||||
setShowTransactionInfo(!showTransactionInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Settlement){
|
||||
setShowSettlementInfo(!showSettlementInfo);
|
||||
}
|
||||
else if(infoSectionKey === InfoSectionKeys.Merchant){
|
||||
setShowMerchantInfo(!showMerchantInfo);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('escrow.detailTitle') }</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className="txn-detail">
|
||||
<AmountInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
amountInfo={ amountInfo }
|
||||
isOpen={ showAmountInfo }
|
||||
tid={ tid }
|
||||
serviceCode={ serviceCode }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></AmountInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<ImportantInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
importantInfo={ importantInfo }
|
||||
></ImportantInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<EscrowInfoSection
|
||||
escrowInfo={ escrowInfo }
|
||||
isOpen={ showEscroInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></EscrowInfoSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<PaymentInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
paymentInfo={ paymentInfo }
|
||||
isOpen={ showPaymentInfo }
|
||||
serviceCode={ serviceCode }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></PaymentInfoSection>
|
||||
<div className="txn-divider"></div>
|
||||
<TransactionInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
transactionInfo={ transactionInfo }
|
||||
isOpen={ showTransactionInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></TransactionInfoSection>
|
||||
<div className="txn-divider"></div>
|
||||
<SettlementInfoSection
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
settlementInfo={ settlementInfo }
|
||||
isOpen={ showSettlementInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></SettlementInfoSection>
|
||||
<div className="txn-divider"></div>
|
||||
<MerchantInfoSection
|
||||
merchantInfo={ merchantInfo }
|
||||
isOpen={ showMerchantInfo }
|
||||
onClickToOpenInfo={ (infoSectionKey) => onClickToOpenInfo(infoSectionKey) }
|
||||
></MerchantInfoSection>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToShowMailResend() }
|
||||
>메일 재발송</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
<EmailBottomSheet
|
||||
setBottomSheetOn={ setBottomSheetOn }
|
||||
bottomSheetOn={ bottomSheetOn }
|
||||
imageSave={ false }
|
||||
sendEmail={ true }
|
||||
sendRequest={ callMailResend }
|
||||
></EmailBottomSheet>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -3,7 +3,8 @@ import { ListDateGroup } from './list-date-group';
|
||||
|
||||
export const EscrowList = ({
|
||||
transactionCategory,
|
||||
listItems
|
||||
listItems,
|
||||
setDetailData
|
||||
}: EscrowListProps) => {
|
||||
|
||||
const getListDateGroup = () => {
|
||||
@@ -26,6 +27,7 @@ export const EscrowList = ({
|
||||
key={ date + '-' + i }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
@@ -43,6 +45,7 @@ export const EscrowList = ({
|
||||
key={ date + '-last' }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import { useTranslation } from 'react-i18next';
|
||||
export const ListDateGroup = ({
|
||||
transactionCategory,
|
||||
date,
|
||||
items
|
||||
items,
|
||||
setDetailData
|
||||
}: ListDateGroupProps) => {
|
||||
const { t, i18n } = useTranslation();
|
||||
|
||||
@@ -93,6 +94,8 @@ export const ListDateGroup = ({
|
||||
|
||||
billKey={ items[i]?.billKey }
|
||||
orderNumber={ items[i]?.orderNumber }
|
||||
|
||||
setDetailData={ setDetailData }
|
||||
></ListItem>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { BillingRequestStatus, CashReceiptTransactionType, EscrowDeliveryStatus, ListItemProps, TransactionCategory } from '../model/types';
|
||||
import moment from 'moment';
|
||||
import { useStore } from '@/shared/model/store';
|
||||
import { getAllTransactionStatusCode, getPaymentMethodName } from '../model/contant';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
@@ -16,9 +13,9 @@ export const ListItem = ({
|
||||
paymentMethod, processResult, transactionType,
|
||||
transactionDateTime, transactionAmount,
|
||||
deliveryStatus, settlementStatus,
|
||||
cancelStatus, billKey, orderNumber, requestStatus
|
||||
cancelStatus, billKey, orderNumber, requestStatus,
|
||||
setDetailData
|
||||
}: ListItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
const { t } = useTranslation();
|
||||
const getItemClass = () => {
|
||||
let rs = '';
|
||||
@@ -88,34 +85,38 @@ export const ListItem = ({
|
||||
|
||||
const onClickToNavigate = () => {
|
||||
if(transactionCategory === TransactionCategory.AllTransaction){
|
||||
navigate(PATHS.transaction.allTransaction.detail, {
|
||||
state: {
|
||||
if(setDetailData && tid){
|
||||
setDetailData({
|
||||
tid: tid,
|
||||
serviceCode: serviceCode
|
||||
}
|
||||
});
|
||||
serviceCode: serviceCode,
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
}
|
||||
else if(transactionCategory === TransactionCategory.CashReceipt){
|
||||
navigate(PATHS.transaction.cashReceipt.detail, {
|
||||
state: {
|
||||
tid: tid
|
||||
}
|
||||
});
|
||||
if(setDetailData && tid){
|
||||
setDetailData({
|
||||
tid: tid,
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
}
|
||||
else if(transactionCategory === TransactionCategory.Escrow){
|
||||
navigate(PATHS.transaction.escrow.detail, {
|
||||
state: {
|
||||
tid: tid,
|
||||
serviceCode: serviceCode
|
||||
}
|
||||
});
|
||||
if(setDetailData && tid){
|
||||
setDetailData({
|
||||
tid: tid,
|
||||
serviceCode: serviceCode,
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
}
|
||||
else if(transactionCategory === TransactionCategory.Billing){
|
||||
navigate(PATHS.transaction.billing.detail, {
|
||||
state: {
|
||||
if(setDetailData && tid){
|
||||
setDetailData({
|
||||
tid: tid,
|
||||
}
|
||||
});
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
}
|
||||
else{
|
||||
alert(t('common.error'));
|
||||
|
||||
@@ -51,7 +51,8 @@ export interface VatReturnListResponse extends DefaulResponsePagination {
|
||||
};
|
||||
|
||||
export interface VatReturnListContent {
|
||||
id?: number
|
||||
id?: number;
|
||||
taxInvoiceNumber?: string;
|
||||
companyName?: string;
|
||||
mid?: string;
|
||||
issueDate?: string;
|
||||
@@ -61,15 +62,22 @@ export interface VatReturnListContent {
|
||||
|
||||
export interface ListDateGroupProps {
|
||||
date?: string;
|
||||
items?: Array<VatReturnListContent>
|
||||
}
|
||||
items?: Array<VatReturnListContent>;
|
||||
setDetailData?: (detailData: DetailData) => void;
|
||||
};
|
||||
|
||||
export interface DetailData {
|
||||
taxInvoiceNumber: string;
|
||||
detailOn: boolean;
|
||||
};
|
||||
export interface ListItemProps {
|
||||
id?: number;
|
||||
taxInvoiceNumber?: string;
|
||||
companyName?: string;
|
||||
mid?: string;
|
||||
issueDate?: string;
|
||||
paymentMethod?: string;
|
||||
amount?: number;
|
||||
setDetailData?: (detailData: DetailData) => void;
|
||||
}
|
||||
export interface VatReturnDetailParams {
|
||||
taxInvoiceNumber?: string;
|
||||
|
||||
162
src/entities/vat-return/ui/detail/tax-invoice-detail.tsx
Normal file
162
src/entities/vat-return/ui/detail/tax-invoice-detail.tsx
Normal file
@@ -0,0 +1,162 @@
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { motion } from 'framer-motion';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useLocation } from 'react-router';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useVatReturnDetailMutation } from '@/entities/vat-return/api/use-vat-return-detail-mutation';
|
||||
import { HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
Breakdown,
|
||||
VatReturnBreakdownParams,
|
||||
VatReturnBreakdownResponse,
|
||||
VatReturnDetailParams,
|
||||
VatReturnDetailResponse
|
||||
} from '@/entities/vat-return/model/types';
|
||||
import {
|
||||
useSetOnBack,
|
||||
useSetHeaderTitle,
|
||||
useSetHeaderType,
|
||||
useSetFooterMode
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { SupplierSection } from '@/entities/vat-return/ui/section/supplier-section';
|
||||
import { ReceiverSection } from '@/entities/vat-return/ui/section/receiver-section';
|
||||
import { IssueSection } from '@/entities/vat-return/ui/section/issue-section';
|
||||
import { AmountSection } from '@/entities/vat-return/ui/section/amount-section';
|
||||
import { useVatReturnTaxInvoiceMutation } from '@/entities/vat-return/api/use-vat-return-tax-invoice-mutation';
|
||||
import { VatReturnListDetailBottomSheet } from '@/entities/vat-return/ui/list-detail-bottom-sheet';
|
||||
import { useVatReturnBreakdownMutation } from '@/entities/vat-return/api/use-vat-return-breakdown-mutation';
|
||||
import { DetailMotionDuration, DetailMotionStyle, DetailMotionVariants } from '@/entities/common/model/constant';
|
||||
import { FullMenuClose } from '@/entities/common/ui/full-menu-close';
|
||||
|
||||
export interface TaxInvoiceDetailProps {
|
||||
detailOn: boolean;
|
||||
setDetailOn: (detailOn: boolean) => void;
|
||||
taxInvoiceNumber: string;
|
||||
};
|
||||
|
||||
export const TaxInvoiceDetail = ({
|
||||
detailOn,
|
||||
setDetailOn,
|
||||
taxInvoiceNumber
|
||||
}: TaxInvoiceDetailProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
const location = useLocation();
|
||||
|
||||
// taxInvoiceNumber = 'TAX202506300001';
|
||||
|
||||
const [openAmount, setOpenAmount] = useState<boolean>(false);
|
||||
const [bottomSheetOn, setBottomSheetOn] = useState<boolean>(false);
|
||||
const [detail, setDetail] = useState<VatReturnDetailResponse>({});
|
||||
const [breakdown, setBreakdown] = useState<Array<Breakdown>>([]);
|
||||
|
||||
useSetHeaderTitle(t('vatReturn.taxInvoiceDetail'));
|
||||
useSetHeaderType(HeaderType.RightClose);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.vatReturn.list);
|
||||
});
|
||||
useSetFooterMode(false);
|
||||
|
||||
const { mutateAsync: vatReturnTaxInvoice } = useVatReturnTaxInvoiceMutation();
|
||||
const { mutateAsync: vatReturnDetail } = useVatReturnDetailMutation();
|
||||
const { mutateAsync: vatReturnBreakdown } = useVatReturnBreakdownMutation();
|
||||
|
||||
const callTaxInvoice = () => {
|
||||
if(taxInvoiceNumber){
|
||||
let params: VatReturnDetailParams = {
|
||||
taxInvoiceNumber: taxInvoiceNumber,
|
||||
};
|
||||
vatReturnDetail(params).then((rs: VatReturnDetailResponse) => {
|
||||
setDetail(rs);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
const callVatReturnBreakdown = async() => {
|
||||
let params: VatReturnBreakdownParams = {
|
||||
taxInvoiceNumber: taxInvoiceNumber,
|
||||
};
|
||||
vatReturnBreakdown(params).then((rs: VatReturnBreakdownResponse) => {
|
||||
setBreakdown(rs.breakdown);
|
||||
});
|
||||
};
|
||||
|
||||
const onClickToOpenBottomSheet = () => {
|
||||
setBottomSheetOn(true);
|
||||
};
|
||||
|
||||
const onClickToClose = () => {
|
||||
setDetailOn(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if(!!detailOn && taxInvoiceNumber){
|
||||
callTaxInvoice();
|
||||
callVatReturnBreakdown();
|
||||
}
|
||||
}, [detailOn]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<motion.div
|
||||
className="full-menu-modal"
|
||||
initial="hidden"
|
||||
animate={ (detailOn)? 'visible': 'hidden' }
|
||||
variants={ DetailMotionVariants }
|
||||
transition={ DetailMotionDuration }
|
||||
style={ DetailMotionStyle }
|
||||
>
|
||||
<div className="full-menu-container pdw-16">
|
||||
<div className="full-menu-header">
|
||||
<div className="full-menu-title center">{ t('transaction.detailTitle') }</div>
|
||||
<div className="full-menu-actions">
|
||||
<FullMenuClose
|
||||
addClass="full-menu-close"
|
||||
onClickToCallback={ onClickToClose }
|
||||
></FullMenuClose>
|
||||
</div>
|
||||
</div>
|
||||
<div className="tab-pane sub active">
|
||||
<div className="option-list">
|
||||
<div className="txn-detail">
|
||||
<AmountSection
|
||||
detail={ detail }
|
||||
></AmountSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<IssueSection
|
||||
detail={ detail }
|
||||
></IssueSection>
|
||||
<div className="txn-divider minus"></div>
|
||||
<ReceiverSection
|
||||
detail={ detail }
|
||||
></ReceiverSection>
|
||||
<div className="txn-divider"></div>
|
||||
<SupplierSection
|
||||
detail={ detail }
|
||||
></SupplierSection>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ onClickToOpenBottomSheet }
|
||||
>{t('vatReturn.viewDetails')}</button>
|
||||
</div>
|
||||
</motion.div>
|
||||
{ !!bottomSheetOn &&
|
||||
<VatReturnListDetailBottomSheet
|
||||
bottomSheetOn={ bottomSheetOn }
|
||||
setBottomSheetOn={ setBottomSheetOn }
|
||||
breakdown={ breakdown }
|
||||
transactionAmount={ detail?.transactionAmount }
|
||||
supplyAmount={ detail?.supplyAmount }
|
||||
vatAmount={ detail?.vatAmount }
|
||||
totalAmount={ detail?.totalAmount }
|
||||
></VatReturnListDetailBottomSheet>
|
||||
}
|
||||
</>
|
||||
)
|
||||
};
|
||||
@@ -5,7 +5,8 @@ import { ListItem } from './list-item';
|
||||
|
||||
export const ListDateGroup = ({
|
||||
date,
|
||||
items
|
||||
items,
|
||||
setDetailData
|
||||
}: ListDateGroupProps) => {
|
||||
moment.locale('ko');
|
||||
const getStateDate = () => {
|
||||
@@ -21,12 +22,13 @@ export const ListDateGroup = ({
|
||||
rs.push(
|
||||
<ListItem
|
||||
key={ key }
|
||||
id={ items[i]?.id || 0 }
|
||||
taxInvoiceNumber={ items[i]?.taxInvoiceNumber || '' }
|
||||
companyName={ items[i]?.companyName || '' }
|
||||
mid={ items[i]?.mid || '' }
|
||||
issueDate={ items[i]?.issueDate || '' }
|
||||
paymentMethod={ items[i]?.paymentMethod || '' }
|
||||
amount={ items[i]?.amount || 0 }
|
||||
setDetailData={ setDetailData }
|
||||
></ListItem>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
import { NumericFormat } from 'react-number-format';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { ListItemProps } from '../model/types';
|
||||
import moment from 'moment';
|
||||
|
||||
export const ListItem = ({
|
||||
id,
|
||||
taxInvoiceNumber,
|
||||
companyName,
|
||||
mid,
|
||||
issueDate,
|
||||
paymentMethod,
|
||||
amount
|
||||
amount,
|
||||
setDetailData
|
||||
}: ListItemProps) => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.vatReturn.detail, {
|
||||
state: {
|
||||
taxInvoiceNumber: id
|
||||
}
|
||||
});
|
||||
if(setDetailData && taxInvoiceNumber){
|
||||
setDetailData({
|
||||
taxInvoiceNumber: taxInvoiceNumber,
|
||||
detailOn: true
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
@@ -7,6 +7,7 @@ import { SortTypeBox } from '@/entities/common/ui/sort-type-box';
|
||||
import { DefaultRequestPagination, SortTypeKeys } from '@/entities/common/model/types';
|
||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
||||
import {
|
||||
DetailData,
|
||||
VatReturnListContent,
|
||||
VatReturnListParams,
|
||||
VatReturnListResponse,
|
||||
@@ -18,6 +19,7 @@ import { ListDateGroup } from './list-date-group';
|
||||
import { useStore } from '@/shared/model/store';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { TaxInvoiceDetail } from './detail/tax-invoice-detail';
|
||||
|
||||
export const ListWrap = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -36,7 +38,10 @@ export const ListWrap = () => {
|
||||
|
||||
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailTaxInvoiceNumber, setDetailTaxInvoiceNumber] = useState<string>('');
|
||||
const { mutateAsync: vatReturnList } = useVatReturnListMutation();
|
||||
|
||||
const onIntersect: IntersectionObserverCallback = (entries: Array<IntersectionObserverEntry>) => {
|
||||
entries.forEach((entry: IntersectionObserverEntry) => {
|
||||
if(entry.isIntersecting){
|
||||
@@ -122,6 +127,11 @@ export const ListWrap = () => {
|
||||
mid, startMonth, endMonth,
|
||||
receiptType, targetType, sortType
|
||||
]);
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
setDetailTaxInvoiceNumber(detailData.taxInvoiceNumber);
|
||||
};
|
||||
|
||||
|
||||
const getListDateGroup = () => {
|
||||
let rs = [];
|
||||
@@ -144,6 +154,7 @@ export const ListWrap = () => {
|
||||
key={ date + '-' + i }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
@@ -160,6 +171,7 @@ export const ListWrap = () => {
|
||||
key={ date + '-last' }
|
||||
date={ date }
|
||||
items={ list }
|
||||
setDetailData={ setDetailData }
|
||||
></ListDateGroup>
|
||||
);
|
||||
}
|
||||
@@ -220,6 +232,12 @@ export const ListWrap = () => {
|
||||
setReceiptType={ setReceiptType }
|
||||
setTargetType={ setTargetType }
|
||||
></ListFilter>
|
||||
<TaxInvoiceDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
taxInvoiceNumber={ detailTaxInvoiceNumber }
|
||||
>
|
||||
</TaxInvoiceDetail>
|
||||
{ !!emailBottomSheetOn &&
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={ emailBottomSheetOn }
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { DefaultRequestPagination, HeaderType } from '@/entities/common/model/types';
|
||||
import { useFaqListMutation } from '@/entities/support/api/use-faq-list-mutation';
|
||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
||||
import { FaqItem, FaqListParams, FaqListResponse, SearchCl } from '@/entities/support/model/types';
|
||||
import { DetailData, FaqItem, FaqListParams, FaqListResponse, SearchCl } from '@/entities/support/model/types';
|
||||
import { SupportFaqItem } from '@/entities/support/ui/faq-item';
|
||||
import {
|
||||
useSetHeaderTitle,
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { FaqDetail } from '@/entities/support/ui/detail/faq-detail';
|
||||
|
||||
export const FaqListPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -24,6 +25,8 @@ export const FaqListPage = () => {
|
||||
const [searchValue, setSearchValue] = useState<string>('');
|
||||
const [selectedCategory, setSelectedCategory] = useState<string>('');
|
||||
const [resultList, setResultList] = useState<Array<FaqItem>>([]);
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailFaqItem, setDetailFaqItem] = useState<FaqItem>({});
|
||||
|
||||
useSetHeaderTitle(t('support.faq.title'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
@@ -103,19 +106,26 @@ export const FaqListPage = () => {
|
||||
callList();
|
||||
};
|
||||
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
if(detailData?.faqItem){
|
||||
setDetailFaqItem(detailData?.faqItem);
|
||||
}
|
||||
};
|
||||
|
||||
const getFaqList = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<resultList.length;i++){
|
||||
rs.push(
|
||||
<SupportFaqItem
|
||||
key={ `key-support-faq-item-${i}` }
|
||||
cursorId={ resultList[i]?.cursorId }
|
||||
seq={ resultList[i]?.seq }
|
||||
category={ resultList[i]?.category }
|
||||
title={ resultList[i]?.title }
|
||||
contents={ resultList[i]?.contents }
|
||||
></SupportFaqItem>
|
||||
)
|
||||
let faqItem = resultList[i];
|
||||
if(faqItem){
|
||||
rs.push(
|
||||
<SupportFaqItem
|
||||
key={ `key-support-faq-item-${i}` }
|
||||
faqItem={ faqItem }
|
||||
setDetailData={ setDetailData }
|
||||
></SupportFaqItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
@@ -175,15 +185,20 @@ export const FaqListPage = () => {
|
||||
</div>
|
||||
<div ref={ setTarget }></div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigation() }
|
||||
>{t('support.faq.inquiryButton')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigation() }
|
||||
>{t('support.faq.inquiryButton')}</button>
|
||||
</div>
|
||||
</main>
|
||||
<FaqDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
faqItem={ detailFaqItem }
|
||||
></FaqDetail>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -4,7 +4,7 @@ import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { useNoticeListMutation } from '@/entities/support/api/use-notice-list-mutation';
|
||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
||||
import { InformCl, NoticeItem, NoticeListParams, NoticeListResponse, SearchCl } from '@/entities/support/model/types';
|
||||
import { DetailData, InformCl, NoticeItem, NoticeListParams, NoticeListResponse, SearchCl } from '@/entities/support/model/types';
|
||||
import { SupportNoticeItem } from '@/entities/support/ui/notice-item';
|
||||
import { DefaultRequestPagination, HeaderType } from '@/entities/common/model/types';
|
||||
import {
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { NoticeDetail } from '@/entities/support/ui/detail/notice-detail';
|
||||
|
||||
export const NoticeListPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -24,6 +25,8 @@ export const NoticeListPage = () => {
|
||||
const [informCl, setInformCl] = useState<InformCl | string>('');
|
||||
const [searchKeyword, setSearchKeyword] = useState<string>('');
|
||||
const [resultList, setResultList] = useState<Array<NoticeItem>>([]);
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailSeq, setDetailSeq] = useState<number>(0);
|
||||
|
||||
useSetHeaderTitle(t('support.notice.title'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
@@ -102,19 +105,27 @@ export const NoticeListPage = () => {
|
||||
}
|
||||
callList();
|
||||
};
|
||||
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
if(detailData?.seq){
|
||||
setDetailSeq(detailData?.seq);
|
||||
}
|
||||
};
|
||||
|
||||
const getNoticeList = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<resultList.length;i++){
|
||||
rs.push(
|
||||
<SupportNoticeItem
|
||||
key={ `key-support-notice-item-${i}` }
|
||||
seq={ resultList[i]?.seq }
|
||||
title={ resultList[i]?.title }
|
||||
informCl={ resultList[i]?.informCl }
|
||||
regDt={ resultList[i]?.regDt }
|
||||
></SupportNoticeItem>
|
||||
)
|
||||
let noticeItem = resultList[i];
|
||||
if(noticeItem){
|
||||
rs.push(
|
||||
<SupportNoticeItem
|
||||
key={ `key-support-notice-item-${i}` }
|
||||
noticeItem={ noticeItem }
|
||||
setDetailData={ setDetailData }
|
||||
></SupportNoticeItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
@@ -173,6 +184,11 @@ export const NoticeListPage = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<NoticeDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
seq={ detailSeq }
|
||||
></NoticeDetail>
|
||||
</main>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { DefaultRequestPagination, HeaderType } from '@/entities/common/model/types';
|
||||
import { useQnaListMutation } from '@/entities/support/api/use-qna-list-mutation';
|
||||
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
|
||||
import { QnaItem, QnaListParams, QnaListResponse } from '@/entities/support/model/types';
|
||||
import { DetailData, QnaItem, QnaListParams, QnaListResponse } from '@/entities/support/model/types';
|
||||
import { SupportQnaItem } from '@/entities/support/ui/qna-item';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import {
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
useSetFooterMode,
|
||||
useSetOnBack
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { QnaDetail } from '@/entities/support/ui/detail/qna-detail';
|
||||
|
||||
export const QnaListPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -31,6 +32,8 @@ export const QnaListPage = () => {
|
||||
const [pageParam, setPageParam] = useState<DefaultRequestPagination>(DEFAULT_PAGE_PARAM);
|
||||
const [statusCode, setStatusCode] = useState<string>(''); // 02, 03
|
||||
const [resultList, setResultList] = useState<Array<QnaItem>>([]);
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailQnaItem, setDetailQnaItem] = useState<QnaItem>({});
|
||||
|
||||
useSetHeaderTitle(t('support.qna.title'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
@@ -102,27 +105,27 @@ export const QnaListPage = () => {
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
if(detailData?.qnaItem){
|
||||
setDetailQnaItem(detailData?.qnaItem);
|
||||
}
|
||||
};
|
||||
|
||||
const getQnaList = () => {
|
||||
let rs = [];
|
||||
for(let i=0;i<resultList.length;i++){
|
||||
rs.push(
|
||||
<SupportQnaItem
|
||||
key={ `key-support-faq-item-${i}` }
|
||||
answer={ resultList[i]?.answer }
|
||||
answerDate={ resultList[i]?.answerDate }
|
||||
contents={ resultList[i]?.contents }
|
||||
corpName={ resultList[i]?.corpName }
|
||||
cursorId={ resultList[i]?.cursorId }
|
||||
requestDate={ resultList[i]?.requestDate }
|
||||
requestName={ resultList[i]?.requestName }
|
||||
requestType={ resultList[i]?.requestType }
|
||||
sendEmail={ resultList[i]?.sendEmail }
|
||||
seq={ resultList[i]?.seq }
|
||||
statusCode={ resultList[i]?.statusCode }
|
||||
title={ resultList[i]?.title }
|
||||
></SupportQnaItem>
|
||||
);
|
||||
let qnaItem = resultList[i];
|
||||
if(qnaItem){
|
||||
rs.push(
|
||||
<SupportQnaItem
|
||||
key={ `key-support-faq-item-${i}` }
|
||||
qnaItem={ qnaItem }
|
||||
setDetailData={ setDetailData }
|
||||
></SupportQnaItem>
|
||||
);
|
||||
}
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
@@ -176,16 +179,20 @@ export const QnaListPage = () => {
|
||||
</div>
|
||||
<div ref={ setTarget }></div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigation() }
|
||||
>{t('support.qna.inquiryButton')}</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigation() }
|
||||
>{t('support.qna.inquiryButton')}</button>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<QnaDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
qnaItem={ detailQnaItem }
|
||||
></QnaDetail>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -13,7 +13,8 @@ import {
|
||||
ListItemProps,
|
||||
AllTransactionListSummaryParams,
|
||||
AllTransactionListResponse,
|
||||
AllTransactionListSummaryResponse
|
||||
AllTransactionListSummaryResponse,
|
||||
DetailData
|
||||
} from '@/entities/transaction/model/types';
|
||||
import { useAllTransactionListMutation } from '@/entities/transaction/api/use-all-transaction-list-mutation';
|
||||
import { useAllTransactionListSummaryMutation } from '@/entities/transaction/api/use-all-transaction-list-summary-mutation';
|
||||
@@ -31,6 +32,7 @@ import {
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AllTransactionDetail } from '@/entities/transaction/ui/detail/all-transaction-detail';
|
||||
|
||||
export const AllTransactionListPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -65,6 +67,10 @@ export const AllTransactionListPage = () => {
|
||||
const [totalAmount, setTotalAmount] = useState<number>(0);
|
||||
|
||||
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailTid, setDetailTid] = useState<string>('');
|
||||
const [detailServiceCode, setDetailServiceCode] = useState<string>('');
|
||||
|
||||
useSetHeaderTitle(t('transaction.listTitle'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
@@ -209,6 +215,14 @@ export const AllTransactionListPage = () => {
|
||||
return rs;
|
||||
};
|
||||
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
setDetailTid(detailData.tid);
|
||||
if(detailData?.serviceCode){
|
||||
setDetailServiceCode(detailData?.serviceCode);
|
||||
}
|
||||
};
|
||||
|
||||
const getLocalizedServiceCodeName = (name?: string): string => {
|
||||
if (!name) return '';
|
||||
|
||||
@@ -307,6 +321,7 @@ export const AllTransactionListPage = () => {
|
||||
<AllTransactionList
|
||||
listItems={ listItems }
|
||||
transactionCategory={ TransactionCategory.AllTransaction }
|
||||
setDetailData={ setDetailData }
|
||||
></AllTransactionList>
|
||||
<div ref={ setTarget }></div>
|
||||
</div>
|
||||
@@ -341,7 +356,12 @@ export const AllTransactionListPage = () => {
|
||||
setSearchValue={ setSearchValue }
|
||||
serviceCodeOptions={ serviceCodeOptions }
|
||||
></AllTransactionFilter>
|
||||
|
||||
<AllTransactionDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
tid={ detailTid }
|
||||
serviceCode={ detailServiceCode }
|
||||
></AllTransactionDetail>
|
||||
{ !!emailBottomSheetOn &&
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={ emailBottomSheetOn }
|
||||
|
||||
@@ -14,7 +14,8 @@ import {
|
||||
BillingSearchType,
|
||||
ListItemProps,
|
||||
BillingListParams,
|
||||
BillingListResponse
|
||||
BillingListResponse,
|
||||
DetailData
|
||||
} from '@/entities/transaction/model/types';
|
||||
import { useBillingListMutation } from '@/entities/transaction/api/use-billing-list-mutation';
|
||||
import { useDownloadExcelMutation } from '@/entities/transaction/api/use-download-excel-mutation';
|
||||
@@ -31,6 +32,7 @@ import {
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { BillingDetail } from '@/entities/transaction/ui/detail/billing-detail';
|
||||
|
||||
export const BillingListPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -55,6 +57,8 @@ export const BillingListPage = () => {
|
||||
const [maxAmount, setMaxAmount] = useState<number>();
|
||||
|
||||
const [downloadBottomSheetOn, setDownloadBottomSheetOn] = useState<boolean>(false);
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailTid, setDetailTid] = useState<string>('');
|
||||
|
||||
useSetHeaderTitle(t('billing.title'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
@@ -149,10 +153,17 @@ export const BillingListPage = () => {
|
||||
const onClickToRequestStatus = (val: BillingRequestStatus) => {
|
||||
setRequestStatus(val);
|
||||
};
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.transaction.billing.charge);
|
||||
};
|
||||
|
||||
const onRequestDownload = (userEmail?: string) => {
|
||||
|
||||
};
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
setDetailTid(detailData.tid);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callList();
|
||||
@@ -217,11 +228,18 @@ export const BillingListPage = () => {
|
||||
<BillingList
|
||||
listItems={ listItems }
|
||||
transactionCategory={ TransactionCategory.Billing }
|
||||
setDetailData={ setDetailData }
|
||||
></BillingList>
|
||||
<div ref={ setTarget }></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigate() }
|
||||
>{ t('transaction.list.paymentRequest') }</button>
|
||||
</div>
|
||||
<BillingFilter
|
||||
filterOn={ filterOn }
|
||||
setFilterOn={ setFilterOn }
|
||||
@@ -246,6 +264,11 @@ export const BillingListPage = () => {
|
||||
setMinAmount={ setMinAmount }
|
||||
setMaxAmount={ setMaxAmount }
|
||||
></BillingFilter>
|
||||
<BillingDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
tid={ detailTid }
|
||||
></BillingDetail>
|
||||
{ !!downloadBottomSheetOn &&
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={ downloadBottomSheetOn }
|
||||
|
||||
@@ -16,7 +16,8 @@ import {
|
||||
CashReceiptSearchNumberType,
|
||||
CashReceiptSummaryParams,
|
||||
CashReceiptListResponse,
|
||||
CashReceiptSummaryResponse
|
||||
CashReceiptSummaryResponse,
|
||||
DetailData
|
||||
} from '@/entities/transaction/model/types';
|
||||
import { useCashReceiptListMutation } from '@/entities/transaction/api/use-cash-receipt-list-mutation';
|
||||
import { useDownloadExcelMutation } from '@/entities/transaction/api/use-download-excel-mutation';
|
||||
@@ -35,6 +36,7 @@ import { useStore } from '@/shared/model/store';
|
||||
import { useCashReceiptSummaryMutation } from '@/entities/transaction/api/use-cash-receipt-summary-mutation';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { CashReceiptDetail } from '@/entities/transaction/ui/detail/cash-receit-detail';
|
||||
|
||||
export const CashReceiptListPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -62,12 +64,16 @@ export const CashReceiptListPage = () => {
|
||||
|
||||
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailTid, setDetailTid] = useState<string>('');
|
||||
const [detailServiceCode, setDetailServiceCode] = useState<string>('');
|
||||
|
||||
useSetHeaderTitle(t('cashReceipt.title'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
useSetOnBack(() => {
|
||||
navigate(PATHS.home);
|
||||
});
|
||||
useSetFooterMode(false);
|
||||
useSetFooterMode(false);
|
||||
|
||||
const { mutateAsync: cashReceiptList } = useCashReceiptListMutation();
|
||||
const { mutateAsync: cashReceiptSummary } = useCashReceiptSummaryMutation();
|
||||
@@ -157,6 +163,14 @@ export const CashReceiptListPage = () => {
|
||||
setEmailBottomSheetOn(true);
|
||||
};
|
||||
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
setDetailTid(detailData.tid);
|
||||
if(detailData?.serviceCode){
|
||||
setDetailServiceCode(detailData?.serviceCode);
|
||||
}
|
||||
};
|
||||
|
||||
const onClickToOpenFilter = () => {
|
||||
setFilterOn(!filterOn);
|
||||
};
|
||||
@@ -175,6 +189,9 @@ export const CashReceiptListPage = () => {
|
||||
const onClickToTransactionType = (val: CashReceiptTransactionType) => {
|
||||
setTransactionType(val);
|
||||
};
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.transaction.cashReceipt.handWrittenIssuance);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callList();
|
||||
@@ -271,11 +288,18 @@ export const CashReceiptListPage = () => {
|
||||
<CashReceiptList
|
||||
listItems={ listItems }
|
||||
transactionCategory={ TransactionCategory.CashReceipt }
|
||||
setDetailData={ setDetailData }
|
||||
></CashReceiptList>
|
||||
<div ref={ setTarget }></div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={ () => onClickToNavigate() }
|
||||
>{ t('transaction.list.manualIssuance') }</button>
|
||||
</div>
|
||||
<CashReceiptFilter
|
||||
filterOn={ filterOn }
|
||||
setFilterOn={ setFilterOn }
|
||||
@@ -296,6 +320,11 @@ export const CashReceiptListPage = () => {
|
||||
setSearchNumberType={ setSearchNumberType }
|
||||
setSearchNumber={ setSearchNumber }
|
||||
></CashReceiptFilter>
|
||||
<CashReceiptDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
tid={ detailTid }
|
||||
></CashReceiptDetail>
|
||||
{ !!emailBottomSheetOn &&
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={ emailBottomSheetOn }
|
||||
|
||||
@@ -13,7 +13,8 @@ import {
|
||||
EscrowSettlementStatus,
|
||||
ListItemProps,
|
||||
EscrowListParams,
|
||||
EscrowListResponse
|
||||
EscrowListResponse,
|
||||
DetailData
|
||||
} from '@/entities/transaction/model/types';
|
||||
import { useEscrowListMutation } from '@/entities/transaction/api/use-escrow-list-mutation';
|
||||
import { useDownloadExcelMutation } from '@/entities/transaction/api/use-download-excel-mutation';
|
||||
@@ -30,6 +31,7 @@ import {
|
||||
} from '@/widgets/sub-layout/use-sub-layout';
|
||||
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
|
||||
import useIntersectionObserver from '@/widgets/intersection-observer';
|
||||
import { EscrowDetail } from '@/entities/transaction/ui/detail/escrow-detail';
|
||||
|
||||
export const EscrowListPage = () => {
|
||||
const { navigate } = useNavigate();
|
||||
@@ -54,6 +56,10 @@ export const EscrowListPage = () => {
|
||||
const [maxAmount, setMaxAmount] = useState<number>();
|
||||
|
||||
const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
|
||||
|
||||
const [detailOn, setDetailOn] = useState<boolean>(false);
|
||||
const [detailTid, setDetailTid] = useState<string>('');
|
||||
const [detailServiceCode, setDetailServiceCode] = useState<string>('');
|
||||
|
||||
useSetHeaderTitle(t('escrow.title'));
|
||||
useSetHeaderType(HeaderType.LeftArrow);
|
||||
@@ -150,6 +156,15 @@ export const EscrowListPage = () => {
|
||||
});
|
||||
*/
|
||||
};
|
||||
|
||||
const setDetailData = (detailData: DetailData) => {
|
||||
setDetailOn(detailData.detailOn);
|
||||
setDetailTid(detailData.tid);
|
||||
if(detailData?.serviceCode){
|
||||
setDetailServiceCode(detailData?.serviceCode);
|
||||
}
|
||||
};
|
||||
|
||||
const onClickToSort = (sort: SortTypeKeys) => {
|
||||
setSortType(sort);
|
||||
};
|
||||
@@ -221,6 +236,7 @@ export const EscrowListPage = () => {
|
||||
<EscrowList
|
||||
listItems={ listItems }
|
||||
transactionCategory={ TransactionCategory.Escrow }
|
||||
setDetailData={ setDetailData }
|
||||
></EscrowList>
|
||||
<div ref={ setTarget }></div>
|
||||
</div>
|
||||
@@ -248,6 +264,12 @@ export const EscrowListPage = () => {
|
||||
setMinAmount={ setMinAmount }
|
||||
setMaxAmount={ setMaxAmount }
|
||||
></EscrowFilter>
|
||||
<EscrowDetail
|
||||
detailOn={ detailOn }
|
||||
setDetailOn={ setDetailOn }
|
||||
tid={ detailTid }
|
||||
serviceCode={ detailServiceCode }
|
||||
></EscrowDetail>
|
||||
{ !!emailBottomSheetOn &&
|
||||
<EmailBottomSheet
|
||||
bottomSheetOn={ emailBottomSheetOn }
|
||||
|
||||
@@ -2,39 +2,30 @@ import { Route } from 'react-router-dom';
|
||||
import { SentryRoutes } from '@/shared/configs/sentry';
|
||||
import { ROUTE_NAMES } from '@/shared/constants/route-names';
|
||||
import { AllTransactionListPage } from './all-transaction/list-page';
|
||||
import { AllTransactionDetailPage } from './all-transaction/detail-page';
|
||||
import { AllTransactionCancelPage } from './all-transaction/cancel-page';
|
||||
import { CashReceiptListPage } from './cash-receipt/list-page';
|
||||
import { CashReceiptDetailPage } from './cash-receipt/detail-page';
|
||||
import { CashReceitHandWrittenIssuancePage } from './cash-receipt/hand-written-issuance-page';
|
||||
import { EscrowListPage } from './escrow/list-page';
|
||||
import { EscrowDetailPage } from './escrow/detail-page';
|
||||
import { BillingListPage } from './billing/list-page';
|
||||
import { BillingDetailPage } from './billing/detail-page';
|
||||
import { BillingChargePage } from './billing/charge-page';
|
||||
|
||||
|
||||
export const TransactionPages = () => {
|
||||
return (
|
||||
<>
|
||||
<SentryRoutes>
|
||||
<Route path={ROUTE_NAMES.transaction.allTransaction.base}>
|
||||
<Route path={ROUTE_NAMES.transaction.allTransaction.list} element={<AllTransactionListPage />} />
|
||||
<Route path={ROUTE_NAMES.transaction.allTransaction.detail} element={<AllTransactionDetailPage />} />
|
||||
<Route path={ROUTE_NAMES.transaction.allTransaction.cancel} element={<AllTransactionCancelPage />} />
|
||||
</Route>
|
||||
<Route path={ROUTE_NAMES.transaction.cashReceipt.base}>
|
||||
<Route path={ROUTE_NAMES.transaction.cashReceipt.list} element={<CashReceiptListPage />} />
|
||||
<Route path={ROUTE_NAMES.transaction.cashReceipt.detail} element={<CashReceiptDetailPage />} />
|
||||
<Route path={ROUTE_NAMES.transaction.cashReceipt.handWrittenIssuance} element={<CashReceitHandWrittenIssuancePage />} />
|
||||
</Route>
|
||||
<Route path={ROUTE_NAMES.transaction.escrow.base}>
|
||||
<Route path={ROUTE_NAMES.transaction.escrow.list} element={<EscrowListPage />} />
|
||||
<Route path={ROUTE_NAMES.transaction.escrow.detail} element={<EscrowDetailPage />} />
|
||||
</Route>
|
||||
<Route path={ROUTE_NAMES.transaction.billing.base}>
|
||||
<Route path={ROUTE_NAMES.transaction.billing.list} element={<BillingListPage />} />
|
||||
<Route path={ROUTE_NAMES.transaction.billing.detail} element={<BillingDetailPage />} />
|
||||
<Route path={ROUTE_NAMES.transaction.billing.charge} element={<BillingChargePage />} />
|
||||
</Route>
|
||||
</SentryRoutes>
|
||||
|
||||
@@ -20,10 +20,6 @@ export const PATHS: RouteNamesType = {
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.allTransaction.base}`,
|
||||
ROUTE_NAMES.transaction.allTransaction.list,
|
||||
),
|
||||
detail: generatePath(
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.allTransaction.base}`,
|
||||
ROUTE_NAMES.transaction.allTransaction.detail,
|
||||
),
|
||||
cancel: generatePath(
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.allTransaction.base}`,
|
||||
ROUTE_NAMES.transaction.allTransaction.cancel,
|
||||
@@ -35,10 +31,6 @@ export const PATHS: RouteNamesType = {
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.cashReceipt.base}`,
|
||||
ROUTE_NAMES.transaction.cashReceipt.list,
|
||||
),
|
||||
detail: generatePath(
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.cashReceipt.base}`,
|
||||
ROUTE_NAMES.transaction.cashReceipt.detail,
|
||||
),
|
||||
handWrittenIssuance: generatePath(
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.cashReceipt.base}`,
|
||||
ROUTE_NAMES.transaction.cashReceipt.handWrittenIssuance,
|
||||
@@ -50,10 +42,6 @@ export const PATHS: RouteNamesType = {
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.escrow.base}`,
|
||||
ROUTE_NAMES.transaction.escrow.list,
|
||||
),
|
||||
detail: generatePath(
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.escrow.base}`,
|
||||
ROUTE_NAMES.transaction.escrow.detail,
|
||||
),
|
||||
},
|
||||
billing: {
|
||||
base: generatePath(`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.billing.base}`),
|
||||
@@ -61,10 +49,6 @@ export const PATHS: RouteNamesType = {
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.billing.base}`,
|
||||
ROUTE_NAMES.transaction.billing.list,
|
||||
),
|
||||
detail: generatePath(
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.billing.base}`,
|
||||
ROUTE_NAMES.transaction.billing.detail,
|
||||
),
|
||||
charge: generatePath(
|
||||
`${ROUTE_NAMES.transaction.base}${ROUTE_NAMES.transaction.billing.base}`,
|
||||
ROUTE_NAMES.transaction.billing.charge,
|
||||
|
||||
@@ -5,24 +5,20 @@ export const ROUTE_NAMES = {
|
||||
allTransaction: {
|
||||
base: '/all-transaction/*',
|
||||
list: 'list',
|
||||
detail: 'detail',
|
||||
cancel: 'cancel',
|
||||
},
|
||||
cashReceipt: {
|
||||
base: '/cash-receipt/*',
|
||||
list: 'list',
|
||||
detail: 'detail',
|
||||
handWrittenIssuance: 'hand-written-issuance',
|
||||
},
|
||||
escrow: {
|
||||
base: '/escrow/*',
|
||||
list: 'list',
|
||||
detail: 'detail',
|
||||
},
|
||||
billing: {
|
||||
base: '/billing/*',
|
||||
list: 'list',
|
||||
detail: 'detail',
|
||||
charge: 'charge',
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user