부가서비스 : 링크결제 발송내역,발송대기 상세페이지 추가
This commit is contained in:
@@ -1,158 +0,0 @@
|
||||
import { IMAGE_ROOT } from "@/shared/constants/common";
|
||||
import { useState } from "react";
|
||||
import { LinkPaymentFilter } from "./link-payment-filter";
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { PATHS } from "@/shared/constants/paths";
|
||||
|
||||
|
||||
export const LinkPaymentDispatchListWrap = () => {
|
||||
const { navigate } = useNavigate();
|
||||
const [filterOn, setFilterOn] = useState<boolean>(false);
|
||||
const onClickToOpenFilter = () => {
|
||||
setFilterOn(!filterOn);
|
||||
};
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.additionalService.linkPayment.request)
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="summary-section">
|
||||
<div className="credit-controls">
|
||||
<div>
|
||||
<input
|
||||
className="credit-period"
|
||||
type="text"
|
||||
value="2025.06.01 ~ 2025.06.30"
|
||||
readOnly={true}
|
||||
/>
|
||||
<button
|
||||
className="filter-btn"
|
||||
aria-label="필터"
|
||||
>
|
||||
<img
|
||||
src={IMAGE_ROOT + '/ico_setting.svg'}
|
||||
alt="검색옵션"
|
||||
onClick={() => onClickToOpenFilter()}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
className="download-btn"
|
||||
aria-label="다운로드"
|
||||
>
|
||||
<img
|
||||
src={IMAGE_ROOT + '/ico_download.svg'}
|
||||
alt="다운로드"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="filter-section">
|
||||
<div className="sort-options">
|
||||
<button className="sort-btn active">최신순</button>
|
||||
<span className="sort-divider">|</span>
|
||||
<button className="sort-btn">고액순</button>
|
||||
</div>
|
||||
<div className="excrow">
|
||||
<div className="full-menu-keywords no-padding">
|
||||
<span className="keyword-tag active">전체</span>
|
||||
<span className="keyword-tag">성공</span>
|
||||
<span className="keyword-tag">실패</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="transaction-list">
|
||||
<div className="date-header">25.06.08(일)</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot blue"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>결제완료</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>SMS</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>신용카드</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot blue"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>결제완료</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>이메일</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>신용카드</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot blue"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>입금요청</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>이메일</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>신용카드</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot gray"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>결제중단</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>SMS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot gray"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>결제실패</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>SMS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToNavigate()}
|
||||
>결제 신청</button>
|
||||
</div>
|
||||
<LinkPaymentFilter
|
||||
filterOn={filterOn}
|
||||
setFilterOn={setFilterOn}
|
||||
></LinkPaymentFilter>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
import { IMAGE_ROOT } from "@/shared/constants/common";
|
||||
import { useState } from "react";
|
||||
import { LinkPaymentFilter } from "./link-payment-filter";
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { PATHS } from "@/shared/constants/paths";
|
||||
|
||||
export const LinkPaymentPendingSendWrap = () => {
|
||||
const { navigate } = useNavigate();
|
||||
const [filterOn, setFilterOn] = useState<boolean>(false);
|
||||
const onClickToOpenFilter = () => {
|
||||
setFilterOn(!filterOn);
|
||||
};
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.additionalService.linkPayment.request)
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<section className="summary-section">
|
||||
<div className="credit-controls">
|
||||
<div>
|
||||
<input
|
||||
className="credit-period"
|
||||
type="text"
|
||||
value="2025.06.01 ~ 2025.06.30"
|
||||
readOnly={true}
|
||||
/>
|
||||
<button
|
||||
className="filter-btn"
|
||||
aria-label="필터"
|
||||
>
|
||||
<img
|
||||
src={IMAGE_ROOT + '/ico_setting.svg'}
|
||||
alt="검색옵션"
|
||||
onClick={() => onClickToOpenFilter()}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
className="download-btn"
|
||||
aria-label="다운로드"
|
||||
>
|
||||
<img
|
||||
src={IMAGE_ROOT + '/ico_download.svg'}
|
||||
alt="다운로드"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="filter-section">
|
||||
<div className="sort-options">
|
||||
<button className="sort-btn active">최신순</button>
|
||||
<span className="sort-divider">|</span>
|
||||
<button className="sort-btn">고액순</button>
|
||||
</div>
|
||||
<div className="excrow">
|
||||
<div className="full-menu-keywords no-padding">
|
||||
<span className="keyword-tag active">전체</span>
|
||||
<span className="keyword-tag">성공</span>
|
||||
<span className="keyword-tag">실패</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="transaction-list">
|
||||
<div className="date-header">25.06.08(일)</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot blue"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>발송요청</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>SMS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot blue"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>발송요청</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>SMS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot blue"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>발송요청</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>이메일</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot gray"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>발송취소</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>SMS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
<div className="transaction-item approved">
|
||||
<div className="transaction-status">
|
||||
<div className="status-dot gray"></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">김*환(7000)</div>
|
||||
<div className="transaction-details">
|
||||
<span>발송취소</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>SMS</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">5,254,000원</div>
|
||||
</div>
|
||||
</section>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToNavigate()}
|
||||
>결제 신청</button>
|
||||
</div>
|
||||
<LinkPaymentFilter
|
||||
filterOn={filterOn}
|
||||
setFilterOn={setFilterOn}
|
||||
></LinkPaymentFilter>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
interface DetailDeetsInfoSectionProps {
|
||||
deetsInfo?: any;
|
||||
show?: boolean;
|
||||
onClickToShowInfo?: () => void;
|
||||
}
|
||||
|
||||
export const DetailDeetsInfoSection = ({
|
||||
deetsInfo,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: DetailDeetsInfoSectionProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="txn-section">
|
||||
<div className="section-title">상세 정보</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">이메일</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">휴대폰번호</span>
|
||||
<span className="v">01073937470</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">상품명</span>
|
||||
<span className="v">곰돌이</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">주문번호</span>
|
||||
<span className="v">mod201705545050</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
interface DetailPaymentInfoSectionProps {
|
||||
paymentInfo?: any;
|
||||
show?: boolean;
|
||||
onClickToShowInfo?: () => void;
|
||||
}
|
||||
|
||||
export const DetailPaymentInfoSection = ({
|
||||
paymentInfo,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: DetailPaymentInfoSectionProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="txn-section">
|
||||
<div className="section-title">결제 정보</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">구매자명</span>
|
||||
<span className="v">김*환</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">발송수단</span>
|
||||
<span className="v">SMS</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">발송일자</span>
|
||||
<span className="v">2025.06.08</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">결제상태(실패횟수)</span>
|
||||
<span className="v">미완료(2)</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">결제수단</span>
|
||||
<span className="v">신용카드</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">결제일자</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">결제유효일자</span>
|
||||
<span className="v">2025.06.08</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
interface DetailPendingPaymentInfoSectionProps {
|
||||
paymentInfo?: any;
|
||||
show?: boolean;
|
||||
onClickToShowInfo?: () => void;
|
||||
}
|
||||
|
||||
export const DetailPaymentInfoSection = ({
|
||||
paymentInfo,
|
||||
show,
|
||||
onClickToShowInfo
|
||||
}: DetailPendingPaymentInfoSectionProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="txn-section">
|
||||
<div className="section-title">결제 정보</div>
|
||||
<ul className="kv-list">
|
||||
<li className="kv-row">
|
||||
<span className="k">진행상태</span>
|
||||
<span className="v">발송요청</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">요청일자</span>
|
||||
<span className="v">2025.06.05</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">결제유효일자</span>
|
||||
<span className="v">2025.06.08</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">발송수단</span>
|
||||
<span className="v">SMS</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">구매자명</span>
|
||||
<span className="v">김*환</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">이메일</span>
|
||||
<span className="v"></span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">휴대폰번호</span>
|
||||
<span className="v">01073937470</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">상품명</span>
|
||||
<span className="v">곰돌이</span>
|
||||
</li>
|
||||
<li className="kv-row">
|
||||
<span className="k">주문번호</span>
|
||||
<span className="v">moid201705545050</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
import moment from 'moment';
|
||||
import 'moment/dist/locale/ko';
|
||||
import { LinkPaymentItem } from './link-payment-item';
|
||||
import { JSX } from 'react';
|
||||
|
||||
interface LinkPaymentTransaction {
|
||||
transactionId: string;
|
||||
customerName: string;
|
||||
status: string;
|
||||
channel: string;
|
||||
paymentMethod: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
interface LinkPaymentDateGroupProps {
|
||||
date: string;
|
||||
items: LinkPaymentTransaction[];
|
||||
}
|
||||
|
||||
export const LinkPaymentDateGroup = ({
|
||||
date,
|
||||
items
|
||||
}: LinkPaymentDateGroupProps) => {
|
||||
moment.locale('ko');
|
||||
const getStateDate = () => {
|
||||
let stateDate = moment(date).format('YY.MM.DD(ddd)');
|
||||
return stateDate;
|
||||
};
|
||||
|
||||
const getLinkPaymentItem = () => {
|
||||
const rs: JSX.Element[] = [];
|
||||
if (items && items.length > 0) {
|
||||
items.forEach((item, index) => {
|
||||
const key = 'LinkPaymentItem-' + index;
|
||||
rs.push(
|
||||
<LinkPaymentItem
|
||||
key={key}
|
||||
transactionId={item.transactionId}
|
||||
customerName={item.customerName}
|
||||
status={item.status}
|
||||
channel={item.channel}
|
||||
paymentMethod={item.paymentMethod}
|
||||
amount={item.amount}
|
||||
/>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="date-header">{getStateDate()}</div>
|
||||
{getLinkPaymentItem()}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,143 @@
|
||||
import { IMAGE_ROOT } from "@/shared/constants/common";
|
||||
import { useState, useEffect } from "react";
|
||||
import { LinkPaymentFilter } from "./link-payment-filter";
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { PATHS } from "@/shared/constants/paths";
|
||||
import { LinkPaymentList } from "./link-payment-list";
|
||||
import { SortOptionsBox } from "./sort-options-box";
|
||||
import { SortByKeys } from "../../model/types";
|
||||
|
||||
|
||||
export const LinkPaymentDispatchListWrap = () => {
|
||||
const { navigate } = useNavigate();
|
||||
const [filterOn, setFilterOn] = useState<boolean>(false);
|
||||
const [sortBy, setSortBy] = useState<SortByKeys>(SortByKeys.New);
|
||||
const [listItems, setListItems] = useState({});
|
||||
|
||||
const onClickToOpenFilter = () => {
|
||||
setFilterOn(!filterOn);
|
||||
};
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.additionalService.linkPayment.request)
|
||||
}
|
||||
const onClickToSort = (sort: SortByKeys) => {
|
||||
setSortBy(sort);
|
||||
callList({ sortBy: sort });
|
||||
};
|
||||
|
||||
const callList = (option?: {sortBy?: string, val?: string}) => {
|
||||
setListItems({
|
||||
'20250608': [
|
||||
{
|
||||
transactionId: 'txn1',
|
||||
customerName: '김*환(7000)',
|
||||
status: '결제완료',
|
||||
channel: 'SMS',
|
||||
paymentMethod: '신용카드',
|
||||
amount: 5254000
|
||||
},
|
||||
{
|
||||
transactionId: 'txn2',
|
||||
customerName: '김*환(7000)',
|
||||
status: '결제완료',
|
||||
channel: '이메일',
|
||||
paymentMethod: '신용카드',
|
||||
amount: 5254000
|
||||
},
|
||||
{
|
||||
transactionId: 'txn3',
|
||||
customerName: '김*환(7000)',
|
||||
status: '입금요청',
|
||||
channel: '이메일',
|
||||
paymentMethod: '신용카드',
|
||||
amount: 5254000
|
||||
},
|
||||
{
|
||||
transactionId: 'txn4',
|
||||
customerName: '김*환(7000)',
|
||||
status: '결제중단',
|
||||
channel: 'SMS',
|
||||
paymentMethod: '',
|
||||
amount: 5254000
|
||||
},
|
||||
{
|
||||
transactionId: 'txn5',
|
||||
customerName: '김*환(7000)',
|
||||
status: '결제실패',
|
||||
channel: 'SMS',
|
||||
paymentMethod: '',
|
||||
amount: 5254000
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callList();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className="summary-section">
|
||||
<div className="credit-controls">
|
||||
<div>
|
||||
<input
|
||||
className="credit-period"
|
||||
type="text"
|
||||
value="2025.06.01 ~ 2025.06.30"
|
||||
readOnly={true}
|
||||
/>
|
||||
<button
|
||||
className="filter-btn"
|
||||
aria-label="필터"
|
||||
>
|
||||
<img
|
||||
src={IMAGE_ROOT + '/ico_setting.svg'}
|
||||
alt="검색옵션"
|
||||
onClick={() => onClickToOpenFilter()}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
className="download-btn"
|
||||
aria-label="다운로드"
|
||||
>
|
||||
<img
|
||||
src={IMAGE_ROOT + '/ico_download.svg'}
|
||||
alt="다운로드"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="filter-section">
|
||||
<SortOptionsBox
|
||||
sortBy={sortBy}
|
||||
onClickToSort={onClickToSort}
|
||||
>
|
||||
</SortOptionsBox>
|
||||
<div className="excrow">
|
||||
<div className="full-menu-keywords no-padding">
|
||||
<span className="keyword-tag active">전체</span>
|
||||
<span className="keyword-tag">성공</span>
|
||||
<span className="keyword-tag">실패</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<LinkPaymentList
|
||||
listItems={listItems}
|
||||
/>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToNavigate()}
|
||||
>결제 신청</button>
|
||||
</div>
|
||||
<LinkPaymentFilter
|
||||
filterOn={filterOn}
|
||||
setFilterOn={setFilterOn}
|
||||
></LinkPaymentFilter>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import moment from 'moment';
|
||||
|
||||
interface LinkPaymentItemProps {
|
||||
transactionId: string;
|
||||
customerName: string;
|
||||
status: string;
|
||||
channel: string;
|
||||
paymentMethod: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export const LinkPaymentItem = ({
|
||||
transactionId,
|
||||
customerName,
|
||||
status,
|
||||
channel,
|
||||
paymentMethod,
|
||||
amount
|
||||
}: LinkPaymentItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.additionalService.linkPayment.detail, {
|
||||
state: {
|
||||
transactionId: transactionId
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getStatusDotClass = () => {
|
||||
if (status === '결제완료' || status === '입금요청') {
|
||||
return 'status-dot blue';
|
||||
}
|
||||
return 'status-dot gray';
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="transaction-item approved"
|
||||
onClick={() => onClickToNavigate()}
|
||||
>
|
||||
<div className="transaction-status">
|
||||
<div className={getStatusDotClass()}></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">{customerName}</div>
|
||||
<div className="transaction-details">
|
||||
<span>{status}</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>{channel}</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>{paymentMethod}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">{amount.toLocaleString()}원</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,41 @@
|
||||
import { LinkPaymentDateGroup } from './link-payment-date-group';
|
||||
|
||||
interface LinkPaymentTransaction {
|
||||
transactionId: string;
|
||||
customerName: string;
|
||||
status: string;
|
||||
channel: string;
|
||||
paymentMethod: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
interface LinkPaymentListProps {
|
||||
listItems: Record<string, LinkPaymentTransaction[]>;
|
||||
}
|
||||
|
||||
export const LinkPaymentList = ({
|
||||
listItems
|
||||
}: LinkPaymentListProps) => {
|
||||
|
||||
const getListDateGroup = () => {
|
||||
let rs = [];
|
||||
for (const [key, value] of Object.entries(listItems)) {
|
||||
rs.push(
|
||||
<LinkPaymentDateGroup
|
||||
key={key}
|
||||
date={key}
|
||||
items={value}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="transaction-list">
|
||||
{getListDateGroup()}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
};
|
||||
@@ -0,0 +1,56 @@
|
||||
import moment from 'moment';
|
||||
import 'moment/dist/locale/ko';
|
||||
import { LinkPaymentPendingItem } from './link-payment-pending-item';
|
||||
import { JSX } from 'react';
|
||||
|
||||
interface LinkPaymentPendingTransaction {
|
||||
transactionId: string;
|
||||
customerName: string;
|
||||
status: string;
|
||||
channel: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
interface LinkPaymentPendingDateGroupProps {
|
||||
date: string;
|
||||
items: LinkPaymentPendingTransaction[];
|
||||
}
|
||||
|
||||
export const LinkPaymentPendingDateGroup = ({
|
||||
date,
|
||||
items
|
||||
}: LinkPaymentPendingDateGroupProps) => {
|
||||
moment.locale('ko');
|
||||
const getStateDate = () => {
|
||||
let stateDate = moment(date).format('YY.MM.DD(ddd)');
|
||||
return stateDate;
|
||||
};
|
||||
|
||||
const getLinkPaymentPendingItem = () => {
|
||||
const rs: JSX.Element[] = [];
|
||||
if (items && items.length > 0) {
|
||||
items.forEach((item, index) => {
|
||||
const key = 'LinkPaymentPendingItem-' + index;
|
||||
rs.push(
|
||||
<LinkPaymentPendingItem
|
||||
key={key}
|
||||
transactionId={item.transactionId}
|
||||
customerName={item.customerName}
|
||||
status={item.status}
|
||||
channel={item.channel}
|
||||
amount={item.amount}
|
||||
/>
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="date-header">{getStateDate()}</div>
|
||||
{getLinkPaymentPendingItem()}
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,57 @@
|
||||
import { PATHS } from '@/shared/constants/paths';
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
|
||||
interface LinkPaymentPendingItemProps {
|
||||
transactionId: string;
|
||||
customerName: string;
|
||||
status: string;
|
||||
channel: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
export const LinkPaymentPendingItem = ({
|
||||
transactionId,
|
||||
customerName,
|
||||
status,
|
||||
channel,
|
||||
amount
|
||||
}: LinkPaymentPendingItemProps) => {
|
||||
const { navigate } = useNavigate();
|
||||
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.additionalService.linkPayment.pendingDetail, {
|
||||
state: {
|
||||
transactionId: transactionId
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getStatusDotClass = () => {
|
||||
if (status === '발송요청') {
|
||||
return 'status-dot blue';
|
||||
}
|
||||
return 'status-dot gray';
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className="transaction-item approved"
|
||||
onClick={() => onClickToNavigate()}
|
||||
>
|
||||
<div className="transaction-status">
|
||||
<div className={getStatusDotClass()}></div>
|
||||
</div>
|
||||
<div className="transaction-content">
|
||||
<div className="transaction-title">{customerName}</div>
|
||||
<div className="transaction-details">
|
||||
<span>{status}</span>
|
||||
<span className="separator">ㅣ</span>
|
||||
<span>{channel}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="transaction-amount">{amount.toLocaleString()}원</div>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
import { LinkPaymentPendingDateGroup } from './link-payment-pending-date-group';
|
||||
|
||||
interface LinkPaymentPendingTransaction {
|
||||
transactionId: string;
|
||||
customerName: string;
|
||||
status: string;
|
||||
channel: string;
|
||||
amount: number;
|
||||
}
|
||||
|
||||
interface LinkPaymentPendingListProps {
|
||||
listItems: Record<string, LinkPaymentPendingTransaction[]>;
|
||||
}
|
||||
|
||||
export const LinkPaymentPendingList = ({
|
||||
listItems
|
||||
}: LinkPaymentPendingListProps) => {
|
||||
|
||||
const getListDateGroup = () => {
|
||||
let rs = [];
|
||||
for (const [key, value] of Object.entries(listItems)) {
|
||||
rs.push(
|
||||
<LinkPaymentPendingDateGroup
|
||||
key={key}
|
||||
date={key}
|
||||
items={value}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return rs;
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="transaction-list">
|
||||
{getListDateGroup()}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
};
|
||||
@@ -0,0 +1,129 @@
|
||||
import { IMAGE_ROOT } from "@/shared/constants/common";
|
||||
import { useState, useEffect } from "react";
|
||||
import { LinkPaymentFilter } from "./link-payment-filter";
|
||||
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import { PATHS } from "@/shared/constants/paths";
|
||||
import { LinkPaymentPendingList } from "./link-payment-pending-list";
|
||||
|
||||
export const LinkPaymentPendingSendWrap = () => {
|
||||
const { navigate } = useNavigate();
|
||||
const [filterOn, setFilterOn] = useState<boolean>(false);
|
||||
const [listItems, setListItems] = useState({});
|
||||
|
||||
const onClickToOpenFilter = () => {
|
||||
setFilterOn(!filterOn);
|
||||
};
|
||||
const onClickToNavigate = () => {
|
||||
navigate(PATHS.additionalService.linkPayment.request)
|
||||
}
|
||||
|
||||
const callList = () => {
|
||||
setListItems({
|
||||
'20250608': [
|
||||
{
|
||||
transactionId: 'pending1',
|
||||
customerName: '김*환(7000)',
|
||||
status: '발송요청',
|
||||
channel: 'SMS',
|
||||
amount: 5254000
|
||||
},
|
||||
{
|
||||
transactionId: 'pending2',
|
||||
customerName: '김*환(7000)',
|
||||
status: '발송요청',
|
||||
channel: 'SMS',
|
||||
amount: 5254000
|
||||
},
|
||||
{
|
||||
transactionId: 'pending3',
|
||||
customerName: '김*환(7000)',
|
||||
status: '발송요청',
|
||||
channel: '이메일',
|
||||
amount: 5254000
|
||||
},
|
||||
{
|
||||
transactionId: 'pending4',
|
||||
customerName: '김*환(7000)',
|
||||
status: '발송취소',
|
||||
channel: 'SMS',
|
||||
amount: 5254000
|
||||
},
|
||||
{
|
||||
transactionId: 'pending5',
|
||||
customerName: '김*환(7000)',
|
||||
status: '발송취소',
|
||||
channel: 'SMS',
|
||||
amount: 5254000
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
callList();
|
||||
}, []);
|
||||
return (
|
||||
<>
|
||||
<section className="summary-section">
|
||||
<div className="credit-controls">
|
||||
<div>
|
||||
<input
|
||||
className="credit-period"
|
||||
type="text"
|
||||
value="2025.06.01 ~ 2025.06.30"
|
||||
readOnly={true}
|
||||
/>
|
||||
<button
|
||||
className="filter-btn"
|
||||
aria-label="필터"
|
||||
>
|
||||
<img
|
||||
src={IMAGE_ROOT + '/ico_setting.svg'}
|
||||
alt="검색옵션"
|
||||
onClick={() => onClickToOpenFilter()}
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
<button
|
||||
className="download-btn"
|
||||
aria-label="다운로드"
|
||||
>
|
||||
<img
|
||||
src={IMAGE_ROOT + '/ico_download.svg'}
|
||||
alt="다운로드"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="filter-section">
|
||||
<div className="sort-options">
|
||||
<button className="sort-btn active">최신순</button>
|
||||
<span className="sort-divider">|</span>
|
||||
<button className="sort-btn">고액순</button>
|
||||
</div>
|
||||
<div className="excrow">
|
||||
<div className="full-menu-keywords no-padding">
|
||||
<span className="keyword-tag active">전체</span>
|
||||
<span className="keyword-tag">성공</span>
|
||||
<span className="keyword-tag">실패</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<LinkPaymentPendingList
|
||||
listItems={listItems}
|
||||
/>
|
||||
<div className="apply-row">
|
||||
<button
|
||||
className="btn-50 btn-blue flex-1"
|
||||
onClick={() => onClickToNavigate()}
|
||||
>결제 신청</button>
|
||||
</div>
|
||||
<LinkPaymentFilter
|
||||
filterOn={filterOn}
|
||||
setFilterOn={setFilterOn}
|
||||
></LinkPaymentFilter>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { useNavigate } from '@/shared/lib/hooks/use-navigate';
|
||||
import {
|
||||
LinkPaymentTabKeys,
|
||||
LinkPaymentTabProps
|
||||
} from '../model/types'
|
||||
} from '../../model/types'
|
||||
|
||||
export const LinkPaymentTab = ({
|
||||
activeTab
|
||||
@@ -0,0 +1,25 @@
|
||||
import {
|
||||
SortByKeys,
|
||||
SortOptionsBoxProps
|
||||
} from '../../model/types';
|
||||
export const SortOptionsBox = ({
|
||||
sortBy,
|
||||
onClickToSort
|
||||
}: SortOptionsBoxProps) => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="sort-options">
|
||||
<button
|
||||
className={ `sort-btn ${(sortBy === SortByKeys.New)? 'active': ''}` }
|
||||
onClick={ () => onClickToSort(SortByKeys.New) }
|
||||
>최신순</button>
|
||||
<span className="sort-divider">|</span>
|
||||
<button
|
||||
className={ `sort-btn ${(sortBy === SortByKeys.Amount)? 'active': ''}` }
|
||||
onClick={ () => onClickToSort(SortByKeys.Amount) }
|
||||
>고액순</button>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user