정산 달력

This commit is contained in:
focp212@naver.com
2025-09-18 18:20:50 +09:00
parent 93b38d3f42
commit 44aa613609
6 changed files with 225 additions and 90 deletions

View File

@@ -36,6 +36,11 @@ export enum SettlementPaymentMethod {
CULTURE_VOUCHER = 'CULTURE_VOUCHER',
TMONEY_PAY = 'TMONEY_PAY',
};
export enum SettlementStatus {
COMPLETED = 'COMPLETED',
SCHEDULED = 'SCHEDULED'
};
export interface SettlementsTransactionSummaryParams {
mid: string;
periodType: SettlementPeriodType;
@@ -172,7 +177,7 @@ export interface SettlementDays {
settlementDate: string;
completedAmount: number;
scheduledAmount: number;
settlementStatus: string;
settlementStatus: SettlementStatus;
};
export interface ListDateGroupProps {
date?: string;

View File

@@ -0,0 +1,40 @@
import { NumericFormat } from 'react-number-format';
import { SettlementStatus } from '../model/types';
export interface CalendarAmountRowProps {
amount: number;
settlementStatus: SettlementStatus;
};
export const CalendarAmountRow = ({
amount,
settlementStatus
}: CalendarAmountRowProps) => {
const makeTitle = () => {
let rs = [];
if(settlementStatus === SettlementStatus.SCHEDULED){
rs.push(<span className="scheduled"></span>)
}
else if(settlementStatus === SettlementStatus.COMPLETED){
rs.push(<span className="complete"></span>)
}
return rs;
};
return (
<>
<div className="amount-row">
<div className="amount-label"> { makeTitle() } </div>
<div className="amount-value">
<NumericFormat
value={ amount }
thousandSeparator
displayType="text"
suffix='원'
></NumericFormat>
</div>
</div>
</>
);
};

View File

@@ -1,10 +1,65 @@
import { NumericFormat } from 'react-number-format';
import moment from 'moment';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { useSettlementsCalendarMutation } from '../api/use-settlements-calendar-mutation';
import { useEffect, useState } from 'react';
import {
SettlementDays,
SettlementsCalendarParams,
SettlementsCalendarResponse,
SettlementStatus
} from '../model/types';
import { CalendarAmountRow } from './calandar-amount-row';
import { CalendarSettlementItem } from './calendar-settlement-item';
export const CalendarWrap = () => {
moment.locale('ko');
const [mid, setMid] = useState<string>('nictest001m');
const [yearMonth, setYearMonth] = useState<string>(moment().format('YYYY-MM'));
const [totalCompletedAmount, setTotalCompletedAmount] = useState<number>(0);
const [totalScheduledAmount, setTotalScheduledAmount] = useState<number>(0);
const [scheduledList, setScheduledList] = useState<Array<SettlementDays | undefined>>([]);
const [completedList, setCompletedList] = useState<Array<SettlementDays | undefined>>([]);
const { mutateAsync: settlementsCalendar } = useSettlementsCalendarMutation();
const callCalendar = () => {
let params: SettlementsCalendarParams = {
mid: mid,
yearMonth: yearMonth
};
settlementsCalendar(params).then((rs: SettlementsCalendarResponse) => {
console.log(rs);
setTotalCompletedAmount(rs.totalCompletedAmount);
setTotalScheduledAmount(rs.totalScheduledAmount);
setYearMonth(rs.yearMonth);
let scheduleArr = [];
let completedArr = [];
if(!!rs.settlementDays && rs.settlementDays.length > 0){
for(let i=0;i<rs.settlementDays.length;i++){
if(rs.settlementDays[i]?.settlementStatus === SettlementStatus.SCHEDULED){
scheduleArr.push(rs.settlementDays[i]);
}
else if(rs.settlementDays[i]?.settlementStatus === SettlementStatus.COMPLETED){
completedArr.push(rs.settlementDays[i]);
}
}
setScheduledList(scheduleArr);
setCompletedList(completedArr);
}
});
};
const makeCalendarSettlementDate = () => {
};
useEffect(() => {
callCalendar();
}, []);
return (
<>
<div className="calendar-wrap">
<div className="calendar-wrap pt-30">
<div className="input-wrapper top-select">
<select>
<option value="1">nicetest00g</option>
@@ -23,7 +78,7 @@ export const CalendarWrap = () => {
alt="이전"
/>
</button>
<div className="month-title">2024 3</div>
<div className="month-title">{ moment(yearMonth).format('YYYY년 MM월') }</div>
<button
className="month-btn"
aria-label="다음 달"
@@ -36,28 +91,14 @@ export const CalendarWrap = () => {
</div>
<div className="amount-group">
<div className="amount-row">
<div className="amount-label"> <span className="complete"></span> </div>
<div className="amount-value">
<NumericFormat
value={ '734723983000' }
thousandSeparator
displayType="text"
suffix={ '원' }
></NumericFormat>
</div>
</div>
<div className="amount-row">
<div className="amount-label"> <span className="scheduled"></span> </div>
<div className="amount-value">
<NumericFormat
value={ '465323000' }
thousandSeparator
displayType="text"
suffix={ '원' }
></NumericFormat>
</div>
</div>
<CalendarAmountRow
amount={ totalCompletedAmount }
settlementStatus={ SettlementStatus.COMPLETED }
></CalendarAmountRow>
<CalendarAmountRow
amount={ totalScheduledAmount }
settlementStatus={ SettlementStatus.SCHEDULED }
></CalendarAmountRow>
</div>
<div className="legend-group">
@@ -121,66 +162,18 @@ export const CalendarWrap = () => {
</div>
<div className="settlement-list">
<div className="settlement-item">
<div className="settlement-tag scheduled"></div>
<div className="settlement-date">03.29 ()</div>
<div className="settlement-amount">
<NumericFormat
value={ '34837000' }
thousandSeparator
displayType="text"
suffix={ ' 원' }
></NumericFormat>
</div>
</div>
<div className="settlement-item">
<div className="settlement-tag scheduled"></div>
<div className="settlement-date">03.28 ()</div>
<div className="settlement-amount">
<NumericFormat
value={ '834374000' }
thousandSeparator
displayType="text"
suffix={ ' 원' }
></NumericFormat>
</div>
</div>
<div className="settlement-item">
<div className="settlement-tag complete"></div>
<div className="settlement-date">03.27 ()</div>
<div className="settlement-amount">
<NumericFormat
value={ '23345000' }
thousandSeparator
displayType="text"
suffix={ ' 원' }
></NumericFormat>
</div>
</div>
<div className="settlement-item">
<div className="settlement-tag complete"></div>
<div className="settlement-date">03.25 ()</div>
<div className="settlement-amount">
<NumericFormat
value={ '84847000' }
thousandSeparator
displayType="text"
suffix={ ' 원' }
></NumericFormat>
</div>
</div>
<div className="settlement-item">
<div className="settlement-tag complete"></div>
<div className="settlement-date">03.19 ()</div>
<div className="settlement-amount">
<NumericFormat
value={ '57235000' }
thousandSeparator
displayType="text"
suffix={ ' 원' }
></NumericFormat>
</div>
</div>
{ (!!scheduledList && scheduledList.length > 0) &&
<CalendarSettlementItem
list={ scheduledList }
settlementStatus={ SettlementStatus.SCHEDULED }
></CalendarSettlementItem>
}
{ (!!completedList && completedList.length > 0) &&
<CalendarSettlementItem
list={ completedList }
settlementStatus={ SettlementStatus.COMPLETED }
></CalendarSettlementItem>
}
</div>
</div>
</>

View File

@@ -0,0 +1,81 @@
import moment from 'moment';
import { NumericFormat } from 'react-number-format';
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { SettlementDays, SettlementStatus } from '../model/types';
export interface CalendarSettlementItemProps {
list: Array<SettlementDays | undefined>;
settlementStatus: SettlementStatus;
};
export const CalendarSettlementItem = ({
list,
settlementStatus
}: CalendarSettlementItemProps) => {
const { navigate } = useNavigate();
const getAmount = (
scheduledAmount: number | undefined,
completedAmount: number | undefined
) => {
let amount = 0;
if(settlementStatus === SettlementStatus.SCHEDULED){
amount = scheduledAmount || 0;
}
else if(settlementStatus === SettlementStatus.COMPLETED){
amount = completedAmount || 0;
}
return amount;
};
const getClassName = () => {
let className = '';
if(settlementStatus === SettlementStatus.SCHEDULED){
className = 'scheduled';
}
else if(settlementStatus === SettlementStatus.COMPLETED){
className = 'complete';
}
return className;
};
const onClickToMoveList = (settlementDate?: string) => {
if(!!settlementDate){
navigate(PATHS.settlement.list, {
state: {
startDate: settlementDate,
endDate: settlementDate
}
});
}
};
return (
<>
{ list.map((value, index) => (
<div
key={ `settlement-item-${index}` }
className="settlement-item"
onClick={ () => onClickToMoveList(value?.settlementDate) }
>
<div className={ `settlement-tag ${getClassName()}` }>{ value?.settlementStatus }</div>
<div className="settlement-date">
{ moment(value?.settlementDate).format('MM.DD(ddd)') }
</div>
<div className="settlement-amount">
<NumericFormat
value={ getAmount(value?.scheduledAmount, value?.completedAmount) }
thousandSeparator
displayType="text"
suffix='원'
></NumericFormat>
</div>
</div>
))
}
</>
)
};

View File

@@ -26,7 +26,15 @@ import 'react-slidedown/lib/slidedown.css';
import { ListFilter } from './filter/list-filter';
import { useDownloadExcelMutation } from '@/entities/transaction/api/use-download-excel-mutation';
export const ListWrap = () => {
export interface ListWrapProps {
startDateFromCalendar?: string;
endDateFromCalendar?: string;
};
export const ListWrap = ({
startDateFromCalendar,
endDateFromCalendar
}: ListWrapProps) => {
const { navigate } = useNavigate();
const [sortBy, setSortBy] = useState<SortByKeys>(SortByKeys.New);
@@ -36,8 +44,8 @@ export const ListWrap = () => {
const [pageParam, setPageParam] = useState(DEFAULT_PAGE_PARAM);
const [mid, setMid] = useState<string>('nictest001m');
const [periodType, setPeriodType] = useState<SettlementPeriodType>(SettlementPeriodType.SETTLEMENT_DATE);
const [startDate, setStartDate] = useState(moment().format('YYYY-MM-DD'));
const [endDate, setEndDate] = useState(moment().format('YYYY-MM-DD'));
const [startDate, setStartDate] = useState(startDateFromCalendar? moment(startDateFromCalendar).format('YYYY-MM-DD'): moment().format('YYYY-MM-DD'));
const [endDate, setEndDate] = useState(endDateFromCalendar? moment(endDateFromCalendar).format('YYYY-MM-DD'): moment().format('YYYY-MM-DD'));
const [paymentMethod, setPaymentMethod] = useState<SettlementPaymentMethod>(SettlementPaymentMethod.ALL);
const [settlementAmount, setSettlementAmount] = useState<number>();

View File

@@ -1,4 +1,5 @@
import { useState } from 'react';
import { useLocation } from 'react-router';
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { SettlementTab } from '@/entities/settlement/ui/settlement-tab';
@@ -16,6 +17,10 @@ import {
export const ListPage = () => {
const { navigate } = useNavigate();
const location = useLocation();
const startDate: string | undefined = location?.state?.startDate;
const endDate: string | undefined = location?.state?.endDate;
const [activeTab, setActiveTab] = useState<SettlementTabKeys>(SettlementTabKeys.List);
@@ -33,7 +38,10 @@ export const ListPage = () => {
<div className="tab-content">
<div className="tab-pane pt-46 active">
<SettlementTab activeTab={ activeTab }></SettlementTab>
<ListWrap></ListWrap>
<ListWrap
startDateFromCalendar={ startDate }
endDateFromCalendar={ endDate }
></ListWrap>
</div>
</div>
</main>