From d2b477e7bd73a455e6d00e01fd7c9275f5a08ac9 Mon Sep 17 00:00:00 2001 From: "focp212@naver.com" Date: Mon, 3 Nov 2025 20:57:55 +0900 Subject: [PATCH] =?UTF-8?q?=EC=83=81=EC=84=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/entities/common/model/constant.ts | 17 ++ src/entities/home/ui/home-notice-item.tsx | 22 +- src/entities/home/ui/home-notice-list.tsx | 37 ++- .../settlement/ui/detail/list-detail.tsx | 0 src/entities/support/model/types.ts | 25 +- src/entities/support/ui/detail/faq-detail.tsx | 71 ++++++ .../support/ui/detail/notice-detail.tsx | 81 ++++++ src/entities/support/ui/detail/qna-detail.tsx | 110 ++++++++ src/entities/support/ui/faq-item.tsx | 29 +-- src/entities/support/ui/notice-item.tsx | 22 +- src/entities/support/ui/qna-item.tsx | 47 +--- src/entities/transaction/model/types.ts | 11 + .../all-transaction-cancel-prevent-bond.tsx | 7 +- .../transaction/ui/all-transaction-list.tsx | 5 +- src/entities/transaction/ui/billing-list.tsx | 17 +- .../transaction/ui/cash-receipt-list.tsx | 16 +- .../ui/detail/all-transaction-detail.tsx | 238 ++++++++++++++++++ .../transaction/ui/detail/billing-detail.tsx | 107 ++++++++ .../ui/detail/cash-receit-detail.tsx | 178 +++++++++++++ .../transaction/ui/detail/escrow-detail.tsx | 225 +++++++++++++++++ src/entities/transaction/ui/escrow-list.tsx | 5 +- .../transaction/ui/list-date-group.tsx | 5 +- src/entities/transaction/ui/list-item.tsx | 51 ++-- src/entities/vat-return/model/types.ts | 16 +- .../ui/detail/tax-invoice-detail.tsx | 162 ++++++++++++ .../vat-return/ui/list-date-group.tsx | 6 +- src/entities/vat-return/ui/list-item.tsx | 20 +- src/entities/vat-return/ui/list-wrap.tsx | 18 ++ src/pages/support/faq/list-page.tsx | 49 ++-- src/pages/support/notice/list-page.tsx | 36 ++- src/pages/support/qna/list-page.tsx | 57 +++-- .../transaction/all-transaction/list-page.tsx | 24 +- src/pages/transaction/billing/list-page.tsx | 25 +- .../transaction/cash-receipt/list-page.tsx | 33 ++- src/pages/transaction/escrow/list-page.tsx | 24 +- src/pages/transaction/transaction-pages.tsx | 9 - src/shared/constants/paths.ts | 16 -- src/shared/constants/route-names.ts | 4 - 38 files changed, 1569 insertions(+), 256 deletions(-) create mode 100644 src/entities/settlement/ui/detail/list-detail.tsx create mode 100644 src/entities/support/ui/detail/faq-detail.tsx create mode 100644 src/entities/support/ui/detail/notice-detail.tsx create mode 100644 src/entities/support/ui/detail/qna-detail.tsx create mode 100644 src/entities/transaction/ui/detail/all-transaction-detail.tsx create mode 100644 src/entities/transaction/ui/detail/billing-detail.tsx create mode 100644 src/entities/transaction/ui/detail/cash-receit-detail.tsx create mode 100644 src/entities/transaction/ui/detail/escrow-detail.tsx create mode 100644 src/entities/vat-return/ui/detail/tax-invoice-detail.tsx diff --git a/src/entities/common/model/constant.ts b/src/entities/common/model/constant.ts index a70127a..18bcdf4 100644 --- a/src/entities/common/model/constant.ts +++ b/src/entities/common/model/constant.ts @@ -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%' diff --git a/src/entities/home/ui/home-notice-item.tsx b/src/entities/home/ui/home-notice-item.tsx index 0cbe040..d2f8840 100644 --- a/src/entities/home/ui/home-notice-item.tsx +++ b/src/entities/home/ui/home-notice-item.tsx @@ -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() } >
-
{ title }
-
{ t(`support.notice.categories.${informCl}`) }{ moment(regDt).format('YY년 MM월 DD일') }
+
{ noticeItem.title }
+
{ t(`support.notice.categories.${noticeItem.informCl}`) }{ noticeItem.regDt? moment(noticeItem.regDt).format('YY년 MM월 DD일'): '' }
{ const { t } = useTranslation(); const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM); const [resultList, setResultList] = useState>([]); + const [detailOn, setDetailOn] = useState(false); + const [detailSeq, setDetailSeq] = useState(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 - ); + let noticeItem = resultList[i]; + if(noticeItem){ + rs.push( + + ); + } + } return rs; }; @@ -56,6 +68,11 @@ export const HomeNoticeList = () => { }
+ ); }; diff --git a/src/entities/settlement/ui/detail/list-detail.tsx b/src/entities/settlement/ui/detail/list-detail.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/entities/support/model/types.ts b/src/entities/support/model/types.ts index 430a589..cd16562 100644 --- a/src/entities/support/model/types.ts +++ b/src/entities/support/model/types.ts @@ -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 }; -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 { - -} \ No newline at end of file +export interface NoticeItemProps { + noticeItem: NoticeItem; + setDetailData?: (detailData: DetailData) => void; +}; \ No newline at end of file diff --git a/src/entities/support/ui/detail/faq-detail.tsx b/src/entities/support/ui/detail/faq-detail.tsx new file mode 100644 index 0000000..746b831 --- /dev/null +++ b/src/entities/support/ui/detail/faq-detail.tsx @@ -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(); + const [seq, setSeq] = useState(); + const [category, setCategory] = useState(); + const [title, setTitle] = useState(); + const [contents, setContents] = useState(); + + const onClickToClose = () => { + setDetailOn(false); + }; + + useEffect(() => { + setCursorId(faqItem?.cursorId); + setSeq(faqItem?.seq); + setCategory(faqItem?.category); + setTitle(faqItem?.title); + setContents(faqItem?.contents); + }, [faqItem]); + + return ( + <> + + { contents && +
+
+
{ t('support.qna.title') }
+
+ +
+
+
+
+
{ title }
+
+
+
+
+
+ } +
+ + ); +}; \ No newline at end of file diff --git a/src/entities/support/ui/detail/notice-detail.tsx b/src/entities/support/ui/detail/notice-detail.tsx new file mode 100644 index 0000000..a9ece91 --- /dev/null +++ b/src/entities/support/ui/detail/notice-detail.tsx @@ -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({}); + + 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 ( + <> + + { result.informCl && +
+
+
{ t('support.notice.title') }
+
+ +
+
+
+
+
+
{ result.title }
+
{ result.regDt? moment(result.regDt).format('YYYY.MM.DD'): '' } | { t(`support.notice.categories.${result.informCl}`) }
+
+
+
+
+
+
+ } +
+ + ); +}; \ No newline at end of file diff --git a/src/entities/support/ui/detail/qna-detail.tsx b/src/entities/support/ui/detail/qna-detail.tsx new file mode 100644 index 0000000..79eb8be --- /dev/null +++ b/src/entities/support/ui/detail/qna-detail.tsx @@ -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(); + const [answerDate, setAnswerDate] = useState(); + const [contents, setContents] = useState(); + const [corpName, setCorpName] = useState(); + const [cursorId, setCursorId] = useState(); + const [requestDate, setRequestDate] = useState(); + const [requestName, setRequestName] = useState(); + const [requestType, setRequestType] = useState(); + const [sendEmail, setSendEmail] = useState(); + const [seq, setSeq] = useState(); + const [statusCode, setStatusCode] = useState(); + const [title, setTitle] = useState(); + + 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 ( + <> + + { statusCode && +
+
+
{ t('support.qna.title') }
+
+ +
+
+
+
+
+
+ {t('support.qna.detailLabels.title')} + { title } +
+
+ {t('support.qna.detailLabels.type')} + { t(`support.qna.categories.${requestType}`) } +
+
+ {t('support.qna.detailLabels.registrationDate')} + { !!requestDate? moment(requestDate).format('YYYY.MM.DD'): '' } +
+
+ {t('support.qna.detailLabels.answerDate')} + { !!answerDate? moment(answerDate).format('YYYY.MM.DD'): '' } +
+
+
+
+
{t('support.qna.detailLabels.inquiryAnswer')}
+
+
+
+
{t('support.qna.detailLabels.inquiryContents')}
+
+
+
+
+
+ } +
+ + ); +}; \ No newline at end of file diff --git a/src/entities/support/ui/faq-item.tsx b/src/entities/support/ui/faq-item.tsx index 1f8abcd..a738a8a 100644 --- a/src/entities/support/ui/faq-item.tsx +++ b/src/entities/support/ui/faq-item.tsx @@ -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 ( <>
onClickToDetail() } + onClick={ onClickToDetail } >
-
{ title }
-
{ t('support.faq.categories.' + category) }
+
{ faqItem.title }
+
{ t('support.faq.categories.' + faqItem.category) }
diff --git a/src/entities/support/ui/notice-item.tsx b/src/entities/support/ui/notice-item.tsx index dfbd150..2e1f961 100644 --- a/src/entities/support/ui/notice-item.tsx +++ b/src/entities/support/ui/notice-item.tsx @@ -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() } >
-
{ title }
+
{ noticeItem.title }
- { t(`support.notice.categories.${informCl}`) }{ moment(regDt).format('YYYY.MM.DD HH:mm:ss') } + { t(`support.notice.categories.${noticeItem.informCl}`) }{ noticeItem.regDt? moment(noticeItem.regDt).format('YYYY.MM.DD HH:mm:ss'): '' }
diff --git a/src/entities/support/ui/qna-item.tsx b/src/entities/support/ui/qna-item.tsx index f28cd3e..8f62d36 100644 --- a/src/entities/support/ui/qna-item.tsx +++ b/src/entities/support/ui/qna-item.tsx @@ -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() } >
-
{ title }
+
{ qnaItem.title }
- {t('support.qna.registrationDate')}{ moment(requestDate).format('YYYY.MM.DD') } - {t('support.qna.status')} [{t(`support.qna.statusCode.${statusCode}`)}] + {t('support.qna.registrationDate')}{ qnaItem.requestDate? moment(qnaItem.requestDate).format('YYYY.MM.DD'): '' } + {t('support.qna.status')} [{t(`support.qna.statusCode.${qnaItem.statusCode}`)}]
- +
diff --git a/src/entities/transaction/model/types.ts b/src/entities/transaction/model/types.ts index 1139f06..400d758 100644 --- a/src/entities/transaction/model/types.ts +++ b/src/entities/transaction/model/types.ts @@ -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; + setDetailData?: (detailData: DetailData) => void; }; export interface AllTransactionListProps { transactionCategory: TransactionCategory; listItems: Array; + setDetailData: (detailData: DetailData) => void; }; export interface CashReceiptListProps { transactionCategory: TransactionCategory; listItems: Array; + setDetailData: (detailData: DetailData) => void; }; export interface EscrowListProps { transactionCategory: TransactionCategory; listItems: Array; + setDetailData: (detailData: DetailData) => void; }; export interface BillingListProps { transactionCategory: TransactionCategory; listItems: Array; + setDetailData: (detailData: DetailData) => void; }; export interface AllTransactionListItem { tid?: string; diff --git a/src/entities/transaction/ui/all-transaction-cancel-prevent-bond.tsx b/src/entities/transaction/ui/all-transaction-cancel-prevent-bond.tsx index 602c8eb..ade84b0 100644 --- a/src/entities/transaction/ui/all-transaction-cancel-prevent-bond.tsx +++ b/src/entities/transaction/ui/all-transaction-cancel-prevent-bond.tsx @@ -28,12 +28,7 @@ export const AllTransactionCancelPreventBond = ({ const { navigate } = useNavigate(); const [item, setItem] = useState(debtPreventionCancelDisplayInfo); const onClickToClose = () => { - navigate(PATHS.transaction.allTransaction.detail, { - state: { - serviceCode: serviceCode, - tid: tid - } - }); + setCancelPreventBondOn(false); }; const callTransactionCancel = () => { diff --git a/src/entities/transaction/ui/all-transaction-list.tsx b/src/entities/transaction/ui/all-transaction-list.tsx index 8564283..15d0628 100644 --- a/src/entities/transaction/ui/all-transaction-list.tsx +++ b/src/entities/transaction/ui/all-transaction-list.tsx @@ -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 } > ); } @@ -43,6 +45,7 @@ export const AllTransactionList = ({ key={ date + '-last' } date={ date } items={ list } + setDetailData={ setDetailData } > ); } diff --git a/src/entities/transaction/ui/billing-list.tsx b/src/entities/transaction/ui/billing-list.tsx index e50aebd..97e236c 100644 --- a/src/entities/transaction/ui/billing-list.tsx +++ b/src/entities/transaction/ui/billing-list.tsx @@ -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 } > ); } @@ -48,27 +48,20 @@ export const BillingList = ({ key={ date + '-last' } date={ date } items={ list } + setDetailData={ setDetailData } > ); } return rs; }; - const onClickToNavigate = () => { - navigate(PATHS.transaction.billing.charge); - }; + return ( <>
{ getListDateGroup() }
-
- -
); }; \ No newline at end of file diff --git a/src/entities/transaction/ui/cash-receipt-list.tsx b/src/entities/transaction/ui/cash-receipt-list.tsx index 1b5007c..cf7c8b3 100644 --- a/src/entities/transaction/ui/cash-receipt-list.tsx +++ b/src/entities/transaction/ui/cash-receipt-list.tsx @@ -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 } > ); } @@ -48,27 +50,19 @@ export const CashReceiptList = ({ key={ date + '-last' } date={ date } items={ list } + setDetailData={ setDetailData } > ); } return rs; }; - const onClickToNavigate = () => { - navigate(PATHS.transaction.cashReceipt.handWrittenIssuance); - }; - return ( <>
{ getListDateGroup() }
-
- -
+ ); }; \ No newline at end of file diff --git a/src/entities/transaction/ui/detail/all-transaction-detail.tsx b/src/entities/transaction/ui/detail/all-transaction-detail.tsx new file mode 100644 index 0000000..47e732c --- /dev/null +++ b/src/entities/transaction/ui/detail/all-transaction-detail.tsx @@ -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(); + const [importantInfo, setImportantInfo] = useState(); + const [paymentInfo, setPaymentInfo] = useState(); + const [transactionInfo, setTransactionInfo] = useState(); + const [settlementInfo, setSettlementInfo] = useState(); + const [partCancelInfo, setPartCancelInfo] = useState(); + const [showAmountInfo, setShowAmountInfo] = useState(false); + const [showPaymentInfo, setShowPaymentInfo] = useState(false); + const [showTransactionInfo, setShowTransactionInfo] = useState(false); + const [showSettlementInfo, setShowSettlementInfo] = useState(false); + const [showPartCancelInfo, setShowPartCancelInfo] = useState(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 ( + 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 ( + <> + +
+
+
{ t('transaction.detailTitle') }
+
+ +
+
+
+
+
+ onClickToOpenInfo(infoSectionKey) } + > +
+ + { !!paymentInfo && + <> +
+ onClickToOpenInfo(infoSectionKey) } + > + + } + { !!transactionInfo && + <> +
+ onClickToOpenInfo(infoSectionKey) } + > + + } + { !!settlementInfo && + <> +
+ onClickToOpenInfo(infoSectionKey) } + > + + } + { !!partCancelInfo && + <> +
+ onClickToOpenInfo(infoSectionKey) } + > + + } +
+
+
+
+
+ +
+
+ + ); +}; \ No newline at end of file diff --git a/src/entities/transaction/ui/detail/billing-detail.tsx b/src/entities/transaction/ui/detail/billing-detail.tsx new file mode 100644 index 0000000..f3c6130 --- /dev/null +++ b/src/entities/transaction/ui/detail/billing-detail.tsx @@ -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(); + const [amountInfo, setAmountInfo] = useState(); + + 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 ( + <> + +
+
+
{ t('billing.detailTitle') }
+
+ +
+
+
+
+
+
+
+
+ { i18n.language === 'en' && { t('home.currencySymbol') } } + + { i18n.language !== 'en' && { t('home.currencyWon') } } +
+
+
+ { amountInfo?.buyerName } +
+
+
+
+ +
+
+
+
+
+ + ); +}; \ No newline at end of file diff --git a/src/entities/transaction/ui/detail/cash-receit-detail.tsx b/src/entities/transaction/ui/detail/cash-receit-detail.tsx new file mode 100644 index 0000000..296a58e --- /dev/null +++ b/src/entities/transaction/ui/detail/cash-receit-detail.tsx @@ -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(); + const [issueInfo, setIssueInfo] = useState(); + const [detailInfo, setDetailInfo] = useState(); + const [showAmountInfo, setShowAmountInfo] = useState(false); + const [showDetailInfo, setShowDetailInfo] = useState(false); + const [bottomSheetOn, setBottomSheetOn] = useState(false); + const [purposeType, setPurposeType] = useState(); + const [canDownloadReceipt, setCanDownloadReceipt] = useState(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 ( + <> + +
+
+
{ t('cashReceipt.detailTitle') }
+
+ +
+
+
+
+
+ onClickToOpenInfo(infoSectionKey) } + purposeType={ purposeType } + canDownloadReceipt={ canDownloadReceipt } + > +
+ +
+ { !!detailInfo && + onClickToOpenInfo(infoSectionKey) } + > + } +
+
+ { (issueInfo?.transactionType === CashReceiptTransactionType.APPROVAL) && + (issueInfo?.processResult === '발급완료') && +
+ +
+ } +
+
+
+ + + ); +}; \ No newline at end of file diff --git a/src/entities/transaction/ui/detail/escrow-detail.tsx b/src/entities/transaction/ui/detail/escrow-detail.tsx new file mode 100644 index 0000000..b03e8cf --- /dev/null +++ b/src/entities/transaction/ui/detail/escrow-detail.tsx @@ -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(); + const [importantInfo, setImportantInfo] = useState(); + const [escrowInfo, setEscrowInfo] = useState(); + const [paymentInfo, setPaymentInfo] = useState(); + const [transactionInfo, setTransactionInfo] = useState(); + const [settlementInfo, setSettlementInfo] = useState(); + const [merchantInfo, setMerchantInfo] = useState(); + + const [showAmountInfo, setShowAmountInfo] = useState(false); + const [showImportantInfo, setShowImportantInfo] = useState(false); + const [showEscroInfo, setShowEscroInfo] = useState(false); + const [showPaymentInfo, setShowPaymentInfo] = useState(false); + const [showTransactionInfo, setShowTransactionInfo] = useState(false); + const [showSettlementInfo, setShowSettlementInfo] = useState(false); + const [showMerchantInfo, setShowMerchantInfo] = useState(false); + + const [bottomSheetOn, setBottomSheetOn] = useState(false); + + const [orderNumber, setOrderNumber] = useState(); + + 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 ( + <> + +
+
+
{ t('escrow.detailTitle') }
+
+ +
+
+
+
+
+ onClickToOpenInfo(infoSectionKey) } + > +
+ +
+ onClickToOpenInfo(infoSectionKey) } + > +
+ onClickToOpenInfo(infoSectionKey) } + > +
+ onClickToOpenInfo(infoSectionKey) } + > +
+ onClickToOpenInfo(infoSectionKey) } + > +
+ onClickToOpenInfo(infoSectionKey) } + > +
+
+
+
+
+ +
+
+ + + ); +}; \ No newline at end of file diff --git a/src/entities/transaction/ui/escrow-list.tsx b/src/entities/transaction/ui/escrow-list.tsx index 84272c8..1993970 100644 --- a/src/entities/transaction/ui/escrow-list.tsx +++ b/src/entities/transaction/ui/escrow-list.tsx @@ -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 } > ); } @@ -43,6 +45,7 @@ export const EscrowList = ({ key={ date + '-last' } date={ date } items={ list } + setDetailData={ setDetailData } > ); } diff --git a/src/entities/transaction/ui/list-date-group.tsx b/src/entities/transaction/ui/list-date-group.tsx index 40f912b..879bff1 100644 --- a/src/entities/transaction/ui/list-date-group.tsx +++ b/src/entities/transaction/ui/list-date-group.tsx @@ -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 } > ) } diff --git a/src/entities/transaction/ui/list-item.tsx b/src/entities/transaction/ui/list-item.tsx index d0420b2..3799cdb 100644 --- a/src/entities/transaction/ui/list-item.tsx +++ b/src/entities/transaction/ui/list-item.tsx @@ -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')); diff --git a/src/entities/vat-return/model/types.ts b/src/entities/vat-return/model/types.ts index dfe24b6..91ca674 100644 --- a/src/entities/vat-return/model/types.ts +++ b/src/entities/vat-return/model/types.ts @@ -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 -} + items?: Array; + 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; diff --git a/src/entities/vat-return/ui/detail/tax-invoice-detail.tsx b/src/entities/vat-return/ui/detail/tax-invoice-detail.tsx new file mode 100644 index 0000000..ef76c96 --- /dev/null +++ b/src/entities/vat-return/ui/detail/tax-invoice-detail.tsx @@ -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(false); + const [bottomSheetOn, setBottomSheetOn] = useState(false); + const [detail, setDetail] = useState({}); + const [breakdown, setBreakdown] = useState>([]); + + 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 ( + <> + +
+
+
{ t('transaction.detailTitle') }
+
+ +
+
+
+
+
+ +
+ +
+ +
+ +
+
+
+
+
+ +
+
+ { !!bottomSheetOn && + + } + + ) +}; \ No newline at end of file diff --git a/src/entities/vat-return/ui/list-date-group.tsx b/src/entities/vat-return/ui/list-date-group.tsx index 4a83ca4..20522e0 100644 --- a/src/entities/vat-return/ui/list-date-group.tsx +++ b/src/entities/vat-return/ui/list-date-group.tsx @@ -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( ) } diff --git a/src/entities/vat-return/ui/list-item.tsx b/src/entities/vat-return/ui/list-item.tsx index 955f429..42d1e51 100644 --- a/src/entities/vat-return/ui/list-item.tsx +++ b/src/entities/vat-return/ui/list-item.tsx @@ -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 ( diff --git a/src/entities/vat-return/ui/list-wrap.tsx b/src/entities/vat-return/ui/list-wrap.tsx index 0cab181..a677358 100644 --- a/src/entities/vat-return/ui/list-wrap.tsx +++ b/src/entities/vat-return/ui/list-wrap.tsx @@ -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(false); + const [detailOn, setDetailOn] = useState(false); + const [detailTaxInvoiceNumber, setDetailTaxInvoiceNumber] = useState(''); const { mutateAsync: vatReturnList } = useVatReturnListMutation(); + const onIntersect: IntersectionObserverCallback = (entries: Array) => { 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 } > ); } @@ -160,6 +171,7 @@ export const ListWrap = () => { key={ date + '-last' } date={ date } items={ list } + setDetailData={ setDetailData } > ); } @@ -220,6 +232,12 @@ export const ListWrap = () => { setReceiptType={ setReceiptType } setTargetType={ setTargetType } > + + { !!emailBottomSheetOn && { const { navigate } = useNavigate(); @@ -24,6 +25,8 @@ export const FaqListPage = () => { const [searchValue, setSearchValue] = useState(''); const [selectedCategory, setSelectedCategory] = useState(''); const [resultList, setResultList] = useState>([]); + const [detailOn, setDetailOn] = useState(false); + const [detailFaqItem, setDetailFaqItem] = useState({}); 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 - ) + let faqItem = resultList[i]; + if(faqItem){ + rs.push( + + ); + } } return rs; }; @@ -175,15 +185,20 @@ export const FaqListPage = () => {
-
- -
+
+ +
+ ); }; \ No newline at end of file diff --git a/src/pages/support/notice/list-page.tsx b/src/pages/support/notice/list-page.tsx index 36f4e8a..8448aba 100644 --- a/src/pages/support/notice/list-page.tsx +++ b/src/pages/support/notice/list-page.tsx @@ -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(''); const [searchKeyword, setSearchKeyword] = useState(''); const [resultList, setResultList] = useState>([]); + const [detailOn, setDetailOn] = useState(false); + const [detailSeq, setDetailSeq] = useState(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 - ) + let noticeItem = resultList[i]; + if(noticeItem){ + rs.push( + + ); + } } return rs; }; @@ -173,6 +184,11 @@ export const NoticeListPage = () => { + ); diff --git a/src/pages/support/qna/list-page.tsx b/src/pages/support/qna/list-page.tsx index 0c10b2e..77ac667 100644 --- a/src/pages/support/qna/list-page.tsx +++ b/src/pages/support/qna/list-page.tsx @@ -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(DEFAULT_PAGE_PARAM); const [statusCode, setStatusCode] = useState(''); // 02, 03 const [resultList, setResultList] = useState>([]); + const [detailOn, setDetailOn] = useState(false); + const [detailQnaItem, setDetailQnaItem] = useState({}); 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 - ); + let qnaItem = resultList[i]; + if(qnaItem){ + rs.push( + + ); + } } return rs; }; @@ -176,16 +179,20 @@ export const QnaListPage = () => {
-
- -
+
+ +
- + ); }; \ No newline at end of file diff --git a/src/pages/transaction/all-transaction/list-page.tsx b/src/pages/transaction/all-transaction/list-page.tsx index c9892a1..6680d2c 100644 --- a/src/pages/transaction/all-transaction/list-page.tsx +++ b/src/pages/transaction/all-transaction/list-page.tsx @@ -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(0); const [emailBottomSheetOn, setEmailBottomSheetOn] = useState(false); + + const [detailOn, setDetailOn] = useState(false); + const [detailTid, setDetailTid] = useState(''); + const [detailServiceCode, setDetailServiceCode] = useState(''); 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 = () => {
@@ -341,7 +356,12 @@ export const AllTransactionListPage = () => { setSearchValue={ setSearchValue } serviceCodeOptions={ serviceCodeOptions } > - + { !!emailBottomSheetOn && { const { navigate } = useNavigate(); @@ -55,6 +57,8 @@ export const BillingListPage = () => { const [maxAmount, setMaxAmount] = useState(); const [downloadBottomSheetOn, setDownloadBottomSheetOn] = useState(false); + const [detailOn, setDetailOn] = useState(false); + const [detailTid, setDetailTid] = useState(''); 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 = () => {
+
+ +
{ setMinAmount={ setMinAmount } setMaxAmount={ setMaxAmount } > + { !!downloadBottomSheetOn && { const { navigate } = useNavigate(); @@ -62,12 +64,16 @@ export const CashReceiptListPage = () => { const [emailBottomSheetOn, setEmailBottomSheetOn] = useState(false); + const [detailOn, setDetailOn] = useState(false); + const [detailTid, setDetailTid] = useState(''); + const [detailServiceCode, setDetailServiceCode] = useState(''); + 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 = () => {
+
+ +
{ setSearchNumberType={ setSearchNumberType } setSearchNumber={ setSearchNumber } > + { !!emailBottomSheetOn && { const { navigate } = useNavigate(); @@ -54,6 +56,10 @@ export const EscrowListPage = () => { const [maxAmount, setMaxAmount] = useState(); const [emailBottomSheetOn, setEmailBottomSheetOn] = useState(false); + + const [detailOn, setDetailOn] = useState(false); + const [detailTid, setDetailTid] = useState(''); + const [detailServiceCode, setDetailServiceCode] = useState(''); 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 = () => {
@@ -248,6 +264,12 @@ export const EscrowListPage = () => { setMinAmount={ setMinAmount } setMaxAmount={ setMaxAmount } > + { !!emailBottomSheetOn && { return ( <> } /> - } /> } /> } /> - } /> } /> } /> - } /> } /> - } /> } /> diff --git a/src/shared/constants/paths.ts b/src/shared/constants/paths.ts index b996555..6230cf3 100644 --- a/src/shared/constants/paths.ts +++ b/src/shared/constants/paths.ts @@ -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, diff --git a/src/shared/constants/route-names.ts b/src/shared/constants/route-names.ts index 9e2800d..8912021 100644 --- a/src/shared/constants/route-names.ts +++ b/src/shared/constants/route-names.ts @@ -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', } },