Refactor RecentTransactionsSection

Further refactors RecentTransactionsSection to separate remaining logic. Creates additional hooks and utility files as needed.
This commit is contained in:
gpt-engineer-app[bot]
2025-03-22 13:22:33 +00:00
parent ff4afb0880
commit 78da23abe6
5 changed files with 90 additions and 14 deletions

View File

@@ -1,11 +1,12 @@
import React, { useState } from 'react';
import React from 'react';
import { Transaction } from '@/contexts/budget/types';
import TransactionEditDialog from './TransactionEditDialog';
import { ChevronRight } from 'lucide-react';
import { useBudget } from '@/contexts/budget/BudgetContext';
import { Link } from 'react-router-dom';
import { useRecentTransactions } from '@/hooks/transactions/useRecentTransactions';
import { useRecentTransactionsDialog } from '@/hooks/transactions/useRecentTransactionsDialog';
import RecentTransactionItem from './recent-transactions/RecentTransactionItem';
interface RecentTransactionsSectionProps {
@@ -17,17 +18,18 @@ const RecentTransactionsSection: React.FC<RecentTransactionsSectionProps> = ({
transactions,
onUpdateTransaction
}) => {
const [selectedTransaction, setSelectedTransaction] = useState<Transaction | null>(null);
const [isDialogOpen, setIsDialogOpen] = useState(false);
const { updateTransaction, deleteTransaction } = useBudget();
// 트랜잭션 삭제 관련 로직은 커스텀 훅으로 분리
const { handleDeleteTransaction, isDeleting } = useRecentTransactions(deleteTransaction);
const handleTransactionClick = (transaction: Transaction) => {
setSelectedTransaction(transaction);
setIsDialogOpen(true);
};
// 다이얼로그 관련 로직 분리
const {
selectedTransaction,
isDialogOpen,
handleTransactionClick,
setIsDialogOpen
} = useRecentTransactionsDialog();
const handleUpdateTransaction = (updatedTransaction: Transaction) => {
if (onUpdateTransaction) {

View File

@@ -2,6 +2,7 @@
import React from 'react';
import { Transaction } from '@/contexts/budget/types';
import TransactionIcon from '../transaction/TransactionIcon';
import { formatCurrency } from '@/utils/currencyFormatter';
interface RecentTransactionItemProps {
transaction: Transaction;
@@ -12,10 +13,6 @@ const RecentTransactionItem: React.FC<RecentTransactionItemProps> = ({
transaction,
onClick
}) => {
const formatCurrency = (amount: number) => {
return amount.toLocaleString('ko-KR') + '원';
};
return (
<div
onClick={onClick}

View File

@@ -4,7 +4,7 @@ import { toast } from '@/hooks/useToast.wrapper';
/**
* 최근 거래내역 관련 로직을 처리하는 커스텀 훅
* 삭제 로직과 상태 관리 등을 담당
* 삭제 로직과 상태 관리 담당
*/
export const useRecentTransactions = (
deleteTransaction: (id: string) => void
@@ -58,8 +58,9 @@ export const useRecentTransactions = (
}, 900);
// 비동기 작업을 동기적으로 처리하여 UI 블로킹 방지
setTimeout(async () => {
setTimeout(() => {
try {
// BudgetContext의 deleteTransaction 함수 호출
deleteTransaction(id);
// 안전장치 타임아웃 제거
@@ -73,8 +74,23 @@ export const useRecentTransactions = (
setIsDeleting(false);
deletingIdRef.current = null;
}, 100);
// 성공 메시지 표시
toast({
title: "항목이 삭제되었습니다",
description: "지출 내역이 성공적으로 삭제되었습니다.",
duration: 1500
});
} catch (err) {
console.error('삭제 처리 오류:', err);
// 에러 메시지 표시
toast({
title: "삭제 실패",
description: "항목을 삭제하는 중 오류가 발생했습니다.",
variant: "destructive",
duration: 1500
});
}
}, 0);

View File

@@ -0,0 +1,32 @@
import { useState } from 'react';
import { Transaction } from '@/contexts/budget/types';
/**
* 최근 거래내역의 다이얼로그 상태를 관리하는 커스텀 훅
*/
export const useRecentTransactionsDialog = () => {
const [selectedTransaction, setSelectedTransaction] = useState<Transaction | null>(null);
const [isDialogOpen, setIsDialogOpen] = useState(false);
const handleTransactionClick = (transaction: Transaction) => {
setSelectedTransaction(transaction);
setIsDialogOpen(true);
};
const handleCloseDialog = () => {
setIsDialogOpen(false);
// 약간의 딜레이 후 선택된 트랜잭션 초기화 (애니메이션 완료 후)
setTimeout(() => {
setSelectedTransaction(null);
}, 300);
};
return {
selectedTransaction,
isDialogOpen,
handleTransactionClick,
handleCloseDialog,
setIsDialogOpen
};
};

View File

@@ -0,0 +1,29 @@
/**
* 숫자를 한국 통화 형식으로 변환합니다.
* 1000 -> 1,000원
*/
export const formatCurrency = (amount: number): string => {
return amount.toLocaleString('ko-KR') + '원';
};
/**
* 문자열에서 숫자만 추출합니다.
* "1,000원" -> 1000
*/
export const extractNumber = (value: string): number => {
const numericValue = value.replace(/[^\d]/g, '');
return numericValue ? parseInt(numericValue, 10) : 0;
};
/**
* 입력값을 통화 형식으로 변환합니다. (입력 필드용)
* 1000 -> "1,000"
*/
export const formatInputCurrency = (value: string): string => {
const numericValue = value.replace(/[^\d]/g, '');
if (!numericValue) return '';
const number = parseInt(numericValue, 10);
return number.toLocaleString('ko-KR');
};