- 부가서비스 공통 ListDateGroupProps,ListItemProps 추가

This commit is contained in:
HyeonJongKim
2025-09-17 11:17:06 +09:00
parent 56ef85e3f3
commit 4f97767999
29 changed files with 407 additions and 191 deletions

View File

@@ -68,6 +68,92 @@ export interface SortOptionsBoxProps {
sortBy: SortByKeys;
onClickToSort: (sortBy: SortByKeys) => void;
};
// 부가서비스 카테고리 enum
export enum AdditionalServiceCategory {
KeyInPayment = 'KeyInPayment',
AccountHolderSearch = 'AccountHolderSearch',
LinkPaymentShipping = 'LinkPaymentShipping',
LinkPaymentPending = 'LinkPaymentPending',
FundTransfer = 'FundTransfer',
SettlementAgency = 'SettlementAgency',
}
// 각 서비스별 개별 타입들
export interface KeyInPaymentListItem {
tid?: string;
mid?: string;
stateDate?: string;
stateCode?: string;
stateName?: string;
installmentMonth?: string;
serviceCode?: string;
serviceName?: string;
serviceDetailName?: string;
goodsAmount?: number;
}
export interface AccountHolderSearchListItem {
requestId?: string;
requestDate?: string;
bank?: string;
accountNumber?: string;
accountHolder?: string;
processResult?: string;
}
export interface LinkPaymentShippingListItem {
transactionId?: string;
customerName?: string;
status?: string;
channel?: string;
amount?: number;
sendDate?: string;
transactionDate?: string;
}
export interface LinkPaymentPendingListItem {
transactionId?: string;
customerName?: string;
status?: string;
channel?: string;
amount?: number;
requestDate?: string;
}
// 공통 ListItemProps (transaction과 동일한 패턴)
export interface ListItemProps extends KeyInPaymentListItem, AccountHolderSearchListItem, LinkPaymentShippingListItem, LinkPaymentPendingListItem {
additionalServiceCategory?: AdditionalServiceCategory;
}
// 공통 ListDateGroupProps
export interface ListDateGroupProps {
additionalServiceCategory?: AdditionalServiceCategory;
date?: string;
items?: Array<ListItemProps>;
}
// 공통 리스트 Props
export interface AdditionalServiceListProps {
additionalServiceCategory: AdditionalServiceCategory;
listItems: Record<string, Array<ListItemProps>>;
}
export interface LinkPaymentShippingListProps {
additionalServiceCategory: AdditionalServiceCategory;
listItems: Record<string, Array<ListItemProps>>;
}
export interface LinkPaymentPendingListProps {
additionalServiceCategory: AdditionalServiceCategory;
listItems: Record<string, Array<ListItemProps>>;
}
export interface AccountHolderSearchListProps {
additionalServiceCategory: AdditionalServiceCategory;
listItems: Record<string, Array<ListItemProps>>;
}
export interface KeyInPaymentListProps {
additionalServiceCategory: AdditionalServiceCategory;
listItems: Record<string, Array<ListItemProps>>;
}
export interface SettlementAgencyTabProps {
activeTab: SettlementAgencyTabKeys;
};

View File

@@ -3,7 +3,7 @@ import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import {
FundTransferTabKeys,
FundTransferTabProps
} from '../model/types';
} from '../../model/types';
export const FundTransferTab = ({
activeTab
}: FundTransferTabProps) => {

View File

@@ -11,7 +11,7 @@ import { FilterRangeAmount } from '@/shared/ui/filter/range-amount';
import {
KeyInPaymentFilterProps,
KeyInPaymentTransactionStatus
} from '../../model/types';
} from '../../../model/types';
export const KeyInPaymentFilter = ({
filterOn,

View File

@@ -1,58 +0,0 @@
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()}
</>
);
};

View File

@@ -1,41 +0,0 @@
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>
</>
)
};

View File

@@ -1,56 +0,0 @@
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()}
</>
);
};

View File

@@ -1,16 +1,5 @@
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[]>;
}
import { LinkPaymentPendingListProps } from '../../model/types';
import { ListDateGroup } from '../list-date-group';
export const LinkPaymentPendingList = ({
listItems
@@ -20,7 +9,7 @@ export const LinkPaymentPendingList = ({
let rs = [];
for (const [key, value] of Object.entries(listItems)) {
rs.push(
<LinkPaymentPendingDateGroup
<ListDateGroup
key={key}
date={key}
items={value}

View File

@@ -5,7 +5,7 @@ import { LinkPaymentPendingSendFilter } from "./filter/link-payment-pending-send
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { PATHS } from "@/shared/constants/paths";
import { LinkPaymentPendingList } from "./link-payment-pending-list";
import { LinkPaymentSearchType, LinkPaymentSendingStatus, LinkPaymentSendMethod, SortByKeys } from "../../model/types";
import { AdditionalServiceCategory, LinkPaymentSearchType, LinkPaymentSendingStatus, LinkPaymentSendMethod, SortByKeys } from "../../model/types";
import { SortOptionsBox } from './sort-options-box';
const sendingStatusBtnGrouup = [
@@ -148,7 +148,8 @@ export const LinkPaymentPendingSendWrap = () => {
<LinkPaymentPendingList
listItems={listItems}
/>
additionalServiceCategory={AdditionalServiceCategory.LinkPaymentPending}
></LinkPaymentPendingList>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"

View File

@@ -0,0 +1,29 @@
import { LinkPaymentShippingListProps } from '../../model/types';
import { ListDateGroup } from '../list-date-group';
export const LinkPaymentSHippingHistoryList = ({
listItems
}: LinkPaymentShippingListProps) => {
const getListDateGroup = () => {
let rs = [];
for (const [key, value] of Object.entries(listItems)) {
rs.push(
<ListDateGroup
key={key}
date={key}
items={value}
/>
);
}
return rs;
};
return (
<>
<div className="transaction-list">
{getListDateGroup()}
</div>
</>
)
};

View File

@@ -4,9 +4,9 @@ import { useState, useEffect } from "react";
import { LinkPaymentShippingHistoryFilter } from "./filter/link-payment-shipping-history-filter";
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { PATHS } from "@/shared/constants/paths";
import { LinkPaymentList } from "./link-payment-list";
import { LinkPaymentSHippingHistoryList } from "./link-payment-shipping-history-list";
import { SortOptionsBox } from "./sort-options-box";
import { LinkPaymentSendMethod, LinkPaymentTransactionStatus, ProcessResult, SortByKeys } from "../../model/types";
import { AdditionalServiceCategory, LinkPaymentSendMethod, LinkPaymentTransactionStatus, ProcessResult, SortByKeys } from "../../model/types";
import { LinkPaymentSearchType, } from "../../model/types";
const processResultBtnGroup = [
@@ -149,9 +149,10 @@ export const LinkPaymentShippingHistoryWrap = () => {
</div>
</div>
<LinkPaymentList
<LinkPaymentSHippingHistoryList
listItems={listItems}
/>
additionalServiceCategory={ AdditionalServiceCategory.LinkPaymentShipping }
></LinkPaymentSHippingHistoryList>
<div className="apply-row">
<button
className="btn-50 btn-blue flex-1"

View File

@@ -0,0 +1,67 @@
import moment from 'moment';
import 'moment/dist/locale/ko';
import { ListDateGroupProps } from '../model/types';
import { ListItem } from '../ui/list-item';
export const ListDateGroup = ({
additionalServiceCategory,
date,
items
}: ListDateGroupProps) => {
moment.locale('ko');
const getStateDate = () => {
let stateDate = moment(date).format('YY.MM.DD(ddd)');
return stateDate;
};
const getListItem = () => {
let rs = [];
if(!!items && items.length>0){
for(let i=0;i<items.length;i++){
let key = 'ListItem-'+i;
rs.push(
<ListItem
additionalServiceCategory={ additionalServiceCategory }
key={ key }
tid={ items[i]?.tid }
mid={ items[i]?.mid }
stateDate={ items[i]?.stateDate }
stateCode={ items[i]?.stateCode }
stateName={ items[i]?.stateName }
installmentMonth={ items[i]?.installmentMonth }
serviceCode={ items[i]?.serviceCode }
serviceName={ items[i]?.serviceName }
serviceDetailName={ items[i]?.serviceDetailName }
goodsAmount={ items[i]?.goodsAmount }
requestId={ items[i]?.requestId }
requestDate={ items[i]?.requestDate }
bank={ items[i]?.bank }
accountNumber={ items[i]?.accountNumber }
accountHolder={ items[i]?.accountHolder }
processResult={ items[i]?.processResult }
transactionId={ items[i]?.transactionId }
customerName={ items[i]?.customerName }
status={ items[i]?.status }
channel={ items[i]?.channel }
amount={ items[i]?.amount }
sendDate={ items[i]?.sendDate }
transactionDate={ items[i]?.transactionDate }
></ListItem>
)
}
}
return rs;
};
return (
<>
<div className="date-group">
<div className="date-header">{ getStateDate() }</div>
{ getListItem() }
</div>
</>
);
};

View File

@@ -0,0 +1,198 @@
import { NumericFormat } from 'react-number-format';
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { ListItemProps, AdditionalServiceCategory } from '../model/types';
import moment from 'moment';
export const ListItem = ({
additionalServiceCategory,
tid, mid, stateDate, stateCode, stateName,
installmentMonth, serviceCode, serviceName,
serviceDetailName, goodsAmount,
requestId, requestDate, bank, accountNumber,
accountHolder, processResult,
transactionId, customerName, status, channel,
amount, sendDate, transactionDate
}: ListItemProps) => {
const { navigate } = useNavigate();
const getItemClass = () => {
let rs = '';
if(stateCode === '0'){
rs = '';
}
else if(stateCode === '1'){
rs = 'approved';
}
else if(stateCode === '2'){
rs = 'refund';
}
return rs;
};
const getDotClass = (str?: string) => {
let rs = '';
if(stateCode === '0'){
rs = '';
}
else if(stateCode === '1'){
rs = 'blue';
}
else if(stateCode === '2'){
rs = 'gray';
}
return rs;
};
const onClickToNavigate = () => {
if(additionalServiceCategory === AdditionalServiceCategory.KeyInPayment){
navigate(PATHS.additionalService.keyInPayment, {
state: {
tid: tid,
serviceCode: serviceCode
}
});
}
else if(additionalServiceCategory === AdditionalServiceCategory.AccountHolderSearch){
navigate(PATHS.additionalService.accountHolderSearch.detail, {
state: {
requestId: requestId
}
});
}
else if(additionalServiceCategory === AdditionalServiceCategory.LinkPaymentShipping){
navigate(PATHS.additionalService.linkPayment.detail, {
state: {
transactionId: transactionId
}
});
}
else if(additionalServiceCategory === AdditionalServiceCategory.LinkPaymentPending){
navigate(PATHS.additionalService.linkPayment.detail, {
state: {
transactionId: transactionId
}
});
}
else{
alert('additionalServiceCategory가 존재하지 않습니다.');
}
};
const getTime = () => {
let timeStr = '';
if(additionalServiceCategory === AdditionalServiceCategory.KeyInPayment){
let time = stateDate?.substring(8, 12);
timeStr = time?.substring(0, 2) + ':' + time?.substring(2, 4);
}
else if(additionalServiceCategory === AdditionalServiceCategory.AccountHolderSearch){
timeStr = moment(requestDate).format('HH:mm');
}
else if(additionalServiceCategory === AdditionalServiceCategory.LinkPaymentShipping){
timeStr = moment(transactionDate).format('HH:mm');
}
else if(additionalServiceCategory === AdditionalServiceCategory.LinkPaymentPending){
timeStr = moment(sendDate).format('HH:mm');
}
return timeStr
};
const getTitle = () => {
let str = '';
if(additionalServiceCategory === AdditionalServiceCategory.KeyInPayment){
str = `${serviceName}(${serviceDetailName})`;
}
else if(additionalServiceCategory === AdditionalServiceCategory.AccountHolderSearch){
str = `${accountHolder}(${accountNumber})`
}
else if(additionalServiceCategory === AdditionalServiceCategory.LinkPaymentShipping){
str = `${customerName}(${transactionId})`
}
else if(additionalServiceCategory === AdditionalServiceCategory.LinkPaymentPending){
str = `${customerName}(${transactionId})`
}
return str;
};
const getDetail = () => {
let rs = [];
if(additionalServiceCategory === AdditionalServiceCategory.KeyInPayment){
rs.push(
<div className="transaction-details">
<span>{ getTime() }</span>
<span className="separator">|</span>
<span>{ stateName }</span>
<span className="separator">|</span>
<span>{ mid }</span>
{
(!!installmentMonth && parseInt(installmentMonth) > 1) &&
<>
<span className="separator">|</span>
<span>{ installmentMonth } </span>
</>
}
</div>
);
}
else if(additionalServiceCategory === AdditionalServiceCategory.AccountHolderSearch){
rs.push(
<div className="transaction-details">
<span>{ getTime() }</span>
<span className="separator">|</span>
<span>{ bank }</span>
<span className="separator">|</span>
<span>{ processResult }</span>
</div>
);
}
else if(additionalServiceCategory === AdditionalServiceCategory.LinkPaymentShipping){
rs.push(
<div className="transaction-details">
<span>{ getTime() }</span>
<span className="separator">|</span>
<span>{ status }</span>
<span className="separator">|</span>
<span>{ channel }</span>
</div>
);
}
else if(additionalServiceCategory === AdditionalServiceCategory.LinkPaymentPending){
rs.push(
<div className="transaction-details">
<span>{ getTime() }</span>
<span className="separator">|</span>
<span>{ status }</span>
<span className="separator">|</span>
<span>{ channel }</span>
</div>
);
}
return rs;
};
return (
<>
<div
className={ `transaction-item ${getItemClass()}` }
onClick={ () => onClickToNavigate() }
>
<div className="transaction-status">
<div className={ `status-dot ${getDotClass()}`}></div>
</div>
<div className="transaction-content">
<div className="transaction-title">{ getTitle() }</div>
{ getDetail() }
</div>
<div className="transaction-amount">
<NumericFormat
value={ goodsAmount || amount }
thousandSeparator
displayType="text"
suffix={ '원' }
></NumericFormat>
</div>
</div>
</>
);
};

View File

@@ -1,5 +1,5 @@
import { motion } from 'framer-motion';
import { SettlementAgencyBottomAgreeProps } from '../model/types';
import { SettlementAgencyBottomAgreeProps } from '../../model/types';
import { IMAGE_ROOT } from '@/shared/constants/common';
export const SettlementAgencyBottomAgree = ({
bottomAgreeOn,

View File

@@ -3,7 +3,7 @@ import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import {
SettlementAgencyTabKeys,
SettlementAgencyTabProps
} from '../model/types';
} from '../../model/types';
export const SettlementAgencyTab = ({
activeTab