import React, { useState } from 'react'; import { PlusIcon } from 'lucide-react'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from './ui/dialog'; import { toast } from '@/hooks/useToast.wrapper'; // 래퍼 사용 import { useBudget } from '@/contexts/BudgetContext'; import { supabase } from '@/lib/supabase'; import { isSyncEnabled, setLastSyncTime, trySyncAllData } from '@/utils/syncUtils'; import ExpenseForm, { ExpenseFormValues } from './expenses/ExpenseForm'; import { Transaction } from '@/components/TransactionCard'; import { normalizeDate } from '@/utils/sync/transaction/dateUtils'; import useNotifications from '@/hooks/useNotifications'; const AddTransactionButton = () => { const [showExpenseDialog, setShowExpenseDialog] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const { addTransaction } = useBudget(); const { addNotification } = useNotifications(); // Format number with commas const formatWithCommas = (value: string): string => { // Remove commas first to avoid duplicates when typing const numericValue = value.replace(/[^0-9]/g, ''); return numericValue.replace(/\B(?=(\d{3})+(?!\d))/g, ','); }; const onSubmit = async (data: ExpenseFormValues) => { // 중복 제출 방지 if (isSubmitting) return; try { setIsSubmitting(true); // Remove commas before processing the amount const numericAmount = data.amount.replace(/,/g, ''); // 현재 날짜와 시간을 가져옵니다 const now = new Date(); const formattedDate = `오늘, ${now.getHours()}:${now.getMinutes() < 10 ? '0' + now.getMinutes() : now.getMinutes()} ${now.getHours() >= 12 ? 'PM' : 'AM'}`; const newExpense: Transaction = { id: Date.now().toString(), title: data.title, amount: parseInt(numericAmount), date: formattedDate, category: data.category, type: 'expense' }; console.log('새 지출 추가:', newExpense); // BudgetContext를 통해 지출 추가 addTransaction(newExpense); try { const { data: { user } } = await supabase.auth.getUser(); if (isSyncEnabled() && user) { // ISO 형식으로 날짜 변환 const isoDate = normalizeDate(formattedDate); const { error } = await supabase.from('transactions').insert({ user_id: user.id, title: data.title, amount: parseInt(numericAmount), date: isoDate, // ISO 형식 사용 category: data.category, type: 'expense', transaction_id: newExpense.id }); if (error) throw error; // 지출 추가 후 자동 동기화 실행 console.log('지출 추가 후 자동 동기화 시작'); const syncResult = await trySyncAllData(user.id); if (syncResult.success) { // 동기화 성공 시 마지막 동기화 시간 업데이트 const currentTime = new Date().toISOString(); console.log('자동 동기화 성공, 시간 업데이트:', currentTime); setLastSyncTime(currentTime); // 동기화 성공 알림 추가 addNotification( '동기화 완료', '방금 추가하신 지출 데이터가 클라우드에 동기화되었습니다.' ); } } } catch (error) { console.error('Supabase에 지출 추가 실패:', error); // 실패 시 알림 추가 addNotification( '동기화 실패', '지출 데이터 동기화 중 문제가 발생했습니다. 나중에 다시 시도됩니다.' ); } // 다이얼로그를 닫습니다 setShowExpenseDialog(false); // 이벤트 발생 처리 - 단일 이벤트로 통합 window.dispatchEvent(new CustomEvent('transactionChanged', { detail: { type: 'add', transaction: newExpense } })); // 토스트는 한 번만 표시 (지연 제거하여 래퍼에서 처리되도록) toast({ title: "지출이 추가되었습니다", description: `${data.title} 항목이 ${formatWithCommas(numericAmount)}원으로 등록되었습니다.`, duration: 3000 }); } catch (error) { console.error('지출 추가 중 오류 발생:', error); toast({ title: "지출 추가 실패", description: "지출을 추가하는 도중 오류가 발생했습니다.", variant: "destructive", duration: 4000 }); } finally { setIsSubmitting(false); } }; return ( <>