From b910b54b012ca4518d3680198c7af7721f18e382 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Tue, 18 Mar 2025 09:04:01 +0000 Subject: [PATCH] Visual edit in Lovable Edited UI in Lovable --- src/components/RecentTransactionsSection.tsx | 86 +++++++------------- 1 file changed, 29 insertions(+), 57 deletions(-) diff --git a/src/components/RecentTransactionsSection.tsx b/src/components/RecentTransactionsSection.tsx index bd8b525..b093f20 100644 --- a/src/components/RecentTransactionsSection.tsx +++ b/src/components/RecentTransactionsSection.tsx @@ -1,4 +1,3 @@ - import React, { useState, useCallback, useRef } from 'react'; import { Transaction } from './TransactionCard'; import TransactionEditDialog from './TransactionEditDialog'; @@ -8,12 +7,10 @@ import { Link } from 'react-router-dom'; import { categoryIcons } from '@/constants/categoryIcons'; import TransactionIcon from './transaction/TransactionIcon'; import { toast } from '@/hooks/useToast.wrapper'; - interface RecentTransactionsSectionProps { transactions: Transaction[]; onUpdateTransaction?: (transaction: Transaction) => void; } - const RecentTransactionsSection: React.FC = ({ transactions, onUpdateTransaction @@ -21,22 +18,23 @@ const RecentTransactionsSection: React.FC = ({ const [selectedTransaction, setSelectedTransaction] = useState(null); const [isDialogOpen, setIsDialogOpen] = useState(false); const [isDeleting, setIsDeleting] = useState(false); - const { updateTransaction, deleteTransaction } = useBudget(); - + const { + updateTransaction, + deleteTransaction + } = useBudget(); + // 삭제 중인 ID 추적 const deletingIdRef = useRef(null); - + // 타임아웃 추적 const timeoutRef = useRef(null); - + // 삭제 요청 타임스탬프 추적 (급발진 방지) const lastDeleteTimeRef = useRef>({}); - const handleTransactionClick = (transaction: Transaction) => { setSelectedTransaction(transaction); setIsDialogOpen(true); }; - const handleUpdateTransaction = useCallback((updatedTransaction: Transaction) => { if (onUpdateTransaction) { onUpdateTransaction(updatedTransaction); @@ -47,7 +45,7 @@ const RecentTransactionsSection: React.FC = ({ // 완전히 새로운 삭제 처리 함수 const handleDeleteTransaction = useCallback(async (id: string): Promise => { - return new Promise((resolve) => { + return new Promise(resolve => { try { // 삭제 진행 중인지 확인 if (isDeleting || deletingIdRef.current === id) { @@ -55,50 +53,49 @@ const RecentTransactionsSection: React.FC = ({ resolve(true); return; } - + // 급발진 방지 (300ms) const now = Date.now(); - if (lastDeleteTimeRef.current[id] && (now - lastDeleteTimeRef.current[id] < 300)) { + if (lastDeleteTimeRef.current[id] && now - lastDeleteTimeRef.current[id] < 300) { console.warn('삭제 요청이 너무 빠릅니다. 무시합니다.'); resolve(true); return; } - + // 타임스탬프 업데이트 lastDeleteTimeRef.current[id] = now; - + // 삭제 상태 설정 setIsDeleting(true); deletingIdRef.current = id; - + // 먼저 다이얼로그 닫기 (UI 응답성 확보) setIsDialogOpen(false); - + // 안전장치: 타임아웃 설정 (최대 900ms) if (timeoutRef.current) { clearTimeout(timeoutRef.current); } - timeoutRef.current = setTimeout(() => { console.warn('삭제 타임아웃 - 상태 초기화'); setIsDeleting(false); deletingIdRef.current = null; resolve(true); // UI 응답성 위해 성공 간주 }, 900); - + // 삭제 함수 호출 (Promise 래핑) try { // 비동기 작업을 동기적으로 처리하여 UI 블로킹 방지 setTimeout(async () => { try { deleteTransaction(id); - + // 안전장치 타임아웃 제거 if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } - + // 상태 초기화 (지연 적용) setTimeout(() => { setIsDeleting(false); @@ -108,48 +105,44 @@ const RecentTransactionsSection: React.FC = ({ console.error('삭제 처리 오류:', err); } }, 0); - + // 즉시 성공 반환 (UI 응답성 향상) resolve(true); } catch (error) { console.error('deleteTransaction 호출 오류:', error); - + // 타임아웃 제거 if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } - + // 상태 초기화 setIsDeleting(false); deletingIdRef.current = null; - resolve(true); // UI 응답성 위해 성공 간주 } } catch (error) { console.error('삭제 처리 전체 오류:', error); - + // 항상 상태 정리 setIsDeleting(false); deletingIdRef.current = null; - if (timeoutRef.current) { clearTimeout(timeoutRef.current); timeoutRef.current = null; } - toast({ title: "오류 발생", description: "처리 중 문제가 발생했습니다.", variant: "destructive", duration: 1500 }); - resolve(false); } }); }, [deleteTransaction, isDeleting]); - + // 컴포넌트 언마운트 시 타임아웃 정리 React.useEffect(() => { return () => { @@ -158,13 +151,10 @@ const RecentTransactionsSection: React.FC = ({ } }; }, []); - const formatCurrency = (amount: number) => { return amount.toLocaleString('ko-KR') + '원'; }; - - return ( -
+ return

최근 지출

@@ -173,12 +163,7 @@ const RecentTransactionsSection: React.FC = ({
- {transactions.length > 0 ? transactions.map(transaction => ( -
handleTransactionClick(transaction)} - className="flex justify-between py-3 cursor-pointer hover:bg-gray-50 px-[5px]" - > + {transactions.length > 0 ? transactions.map(transaction =>
handleTransactionClick(transaction)} className="flex justify-between py-3 cursor-pointer px-[5px] bg-transparent">
@@ -190,25 +175,12 @@ const RecentTransactionsSection: React.FC = ({

-{formatCurrency(transaction.amount)}

{transaction.category}

-
- )) : ( -
+
) :
지출 내역이 없습니다 -
- )} +
}
- {selectedTransaction && ( - - )} -
- ); + {selectedTransaction && } +
; }; - -export default RecentTransactionsSection; +export default RecentTransactionsSection; \ No newline at end of file