From e684c495ee11d9a7930eeebfe77d35d7fe7f8137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B6=8C=ED=98=81=EC=84=B1?= Date: Mon, 2 Feb 2026 00:58:18 +0900 Subject: [PATCH] =?UTF-8?q?feat(WEB):=20=EB=8C=80=EC=8B=9C=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EA=B8=88=EC=95=A1=20=ED=95=9C=EA=B5=AD=EC=8B=9D=20?= =?UTF-8?q?=EC=B6=95=EC=95=BD=20=ED=8F=AC=EB=A7=B7=20=EC=A0=81=EC=9A=A9=20?= =?UTF-8?q?(=EB=A7=8C/=EC=96=B5=20=EB=8B=A8=EC=9C=84)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - formatKoreanAmount 유틸 함수 추가 (1만 미만: 원, 1만~1억: 만, 1억 이상: 억+만) - CEO 대시보드 일일일보, 당월 지출, 금액카드에 적용 - 기존 formatBillion 로컬 함수 제거 후 공통 유틸로 통합 --- .../business/CEODashboard/components.tsx | 7 ++-- .../sections/EnhancedSections.tsx | 29 +++++---------- src/utils/formatAmount.ts | 35 +++++++++++++++++++ 3 files changed, 48 insertions(+), 23 deletions(-) diff --git a/src/components/business/CEODashboard/components.tsx b/src/components/business/CEODashboard/components.tsx index 356d8065..f3cdf130 100644 --- a/src/components/business/CEODashboard/components.tsx +++ b/src/components/business/CEODashboard/components.tsx @@ -12,6 +12,7 @@ import { import { Card, CardContent } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { cn } from '@/lib/utils'; +import { formatKoreanAmount } from '@/utils/formatAmount'; import type { CheckPoint, CheckPointType, AmountCard, HighlightColor } from './types'; // 섹션별 컬러 테마 타입 @@ -245,7 +246,7 @@ export const AmountCardItem = ({ if (card.currency === 'USD') { return formatUSD(amount); } - return formatBillion(amount); + return formatKoreanAmount(amount); }; // 테마 적용 시 스타일 @@ -338,7 +339,7 @@ export const AmountCardItem = ({ {card.subItems.map((item, idx) => (
{item.label} - {typeof item.value === 'number' ? formatAmount(item.value, false) : item.value} + {typeof item.value === 'number' ? formatKoreanAmount(item.value) : item.value}
))} @@ -348,7 +349,7 @@ export const AmountCardItem = ({ {!showTrend && !card.subItems && (card.subAmount !== undefined || card.previousAmount !== undefined || card.subLabel || card.previousLabel) && (
{card.subAmount !== undefined && card.subLabel && ( - {card.subLabel}: {card.unit === '건' ? `${card.subAmount}건` : formatAmount(card.subAmount)} + {card.subLabel}: {card.unit === '건' ? `${card.subAmount}건` : formatKoreanAmount(card.subAmount)} )} {card.previousLabel && ( diff --git a/src/components/business/CEODashboard/sections/EnhancedSections.tsx b/src/components/business/CEODashboard/sections/EnhancedSections.tsx index d205343c..83112176 100644 --- a/src/components/business/CEODashboard/sections/EnhancedSections.tsx +++ b/src/components/business/CEODashboard/sections/EnhancedSections.tsx @@ -25,24 +25,13 @@ import { import { useRouter } from 'next/navigation'; import { Card, CardContent } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; +import { formatKoreanAmount } from '@/utils/formatAmount'; import type { DailyReportData, MonthlyExpenseData, TodayIssueItem, TodayIssueSettings } from '../types'; // ============================================================ // 유틸리티 함수 // ============================================================ -const formatBillion = (amount: number): string => { - const billion = amount / 100000000; - if (billion >= 1) { - return billion.toFixed(1) + '억원'; - } - const man = amount / 10000; - if (man >= 1) { - return Math.floor(man).toLocaleString() + '만원'; - } - return amount.toLocaleString() + '원'; -}; - const formatUSD = (amount: number): string => { return '$ ' + new Intl.NumberFormat('en-US').format(amount); }; @@ -106,7 +95,7 @@ export function EnhancedDailyReportSection({ data, onClick }: EnhancedDailyRepor
- {formatBillion(data.cards[0]?.amount || 0)} + {formatKoreanAmount(data.cards[0]?.amount || 0)} {data.cards[0]?.changeRate && ( {data.cards[1]?.currency === 'USD' ? formatUSD(data.cards[1]?.amount || 0) - : formatBillion(data.cards[1]?.amount || 0)} + : formatKoreanAmount(data.cards[1]?.amount || 0)} {data.cards[1]?.changeRate && (
- {formatBillion(data.cards[2]?.amount || 0)} + {formatKoreanAmount(data.cards[2]?.amount || 0)} {data.cards[2]?.changeRate && (
- {formatBillion(data.cards[3]?.amount || 0)} + {formatKoreanAmount(data.cards[3]?.amount || 0)} {data.cards[3]?.changeRate && (
- {formatBillion(data.cards[0]?.amount || 0)} + {formatKoreanAmount(data.cards[0]?.amount || 0)}
{data.cards[0]?.previousLabel && (
@@ -449,7 +438,7 @@ export function EnhancedMonthlyExpenseSection({ data, onCardClick }: EnhancedMon
- {formatBillion(data.cards[1]?.amount || 0)} + {formatKoreanAmount(data.cards[1]?.amount || 0)}
{data.cards[1]?.previousLabel && (
@@ -474,7 +463,7 @@ export function EnhancedMonthlyExpenseSection({ data, onCardClick }: EnhancedMon
- {formatBillion(data.cards[2]?.amount || 0)} + {formatKoreanAmount(data.cards[2]?.amount || 0)}
{data.cards[2]?.previousLabel && (
@@ -499,7 +488,7 @@ export function EnhancedMonthlyExpenseSection({ data, onCardClick }: EnhancedMon
- {formatBillion(totalAmount)} + {formatKoreanAmount(totalAmount)}
diff --git a/src/utils/formatAmount.ts b/src/utils/formatAmount.ts index 3f1f4950..01534872 100644 --- a/src/utils/formatAmount.ts +++ b/src/utils/formatAmount.ts @@ -40,4 +40,39 @@ export function formatAmountManwon(amount: number): string { } const manwon = Math.round(amount / 10000); return `${manwon.toLocaleString("ko-KR")}만원`; +} + +/** + * 한국식 금액 축약 포맷 + * + * - 1만 미만: 원 단위 (예: "5,000원") + * - 1만 ~ 1억 미만: 만 단위 (예: "5,320만") + * - 1억 이상: 억 + 만 단위 (예: "1억 5,000만", "12억 3,453만") + * - 만원 나머지가 0이면 "10억" + */ +export function formatKoreanAmount(amount: number): string { + if (amount == null || isNaN(amount)) return "0원"; + + const absAmount = Math.abs(amount); + const sign = amount < 0 ? "-" : ""; + + if (absAmount < 10000) { + // 만원 미만: 원 단위 + return sign + absAmount.toLocaleString("ko-KR") + "원"; + } + + if (absAmount < 100000000) { + // 만원 ~ 억 미만: 만 단위 + const manwon = Math.round(absAmount / 10000); + return sign + manwon.toLocaleString("ko-KR") + "만"; + } + + // 억 이상: 억 + 만 단위 + const eok = Math.floor(absAmount / 100000000); + const remainder = Math.round((absAmount % 100000000) / 10000); + + if (remainder === 0) { + return sign + eok.toLocaleString("ko-KR") + "억"; + } + return sign + eok.toLocaleString("ko-KR") + "억 " + remainder.toLocaleString("ko-KR") + "만"; } \ No newline at end of file