diff --git a/src/components/BudgetInputCard.tsx b/src/components/BudgetInputCard.tsx new file mode 100644 index 0000000..9c40b84 --- /dev/null +++ b/src/components/BudgetInputCard.tsx @@ -0,0 +1,122 @@ + +import React, { useState, useEffect } from 'react'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; +import { Input } from '@/components/ui/input'; +import { Button } from '@/components/ui/button'; +import { Check } from 'lucide-react'; + +interface BudgetGoalProps { + initialBudgets: { + daily: number; + weekly: number; + monthly: number; + }; + onSave: (type: 'daily' | 'weekly' | 'monthly', amount: number) => void; +} + +const BudgetInputCard: React.FC = ({ initialBudgets, onSave }) => { + const [selectedTab, setSelectedTab] = useState<'daily' | 'weekly' | 'monthly'>('daily'); + const [budgetInputs, setBudgetInputs] = useState({ + daily: initialBudgets.daily.toString(), + weekly: initialBudgets.weekly.toString(), + monthly: initialBudgets.monthly.toString(), + }); + + // Format for display without commas + const formatForInput = (amount: number) => { + return amount.toString(); + }; + + // Format with commas for display + const formatWithCommas = (amount: string) => { + return amount.replace(/\B(?=(\d{3})+(?!\d))/g, ','); + }; + + useEffect(() => { + setBudgetInputs({ + daily: formatForInput(initialBudgets.daily), + weekly: formatForInput(initialBudgets.weekly), + monthly: formatForInput(initialBudgets.monthly), + }); + }, [initialBudgets]); + + const handleInputChange = (value: string, type: 'daily' | 'weekly' | 'monthly') => { + // Remove all non-numeric characters + const numericValue = value.replace(/[^0-9]/g, ''); + + setBudgetInputs(prev => ({ + ...prev, + [type]: numericValue + })); + }; + + const handleSave = () => { + const amount = parseInt(budgetInputs[selectedTab], 10) || 0; + onSave(selectedTab, amount); + }; + + return ( +
+ setSelectedTab(value as 'daily' | 'weekly' | 'monthly')} className="w-full"> + + + 일일 목표 + + + 주간 목표 + + + 월간 목표 + + + + +
+ handleInputChange(e.target.value, 'daily')} + placeholder="목표 금액 입력" + className="neuro-pressed" + /> + +
+

현재 일일 목표: {formatWithCommas(budgetInputs.daily)}원

+
+ + +
+ handleInputChange(e.target.value, 'weekly')} + placeholder="목표 금액 입력" + className="neuro-pressed" + /> + +
+

현재 주간 목표: {formatWithCommas(budgetInputs.weekly)}원

+
+ + +
+ handleInputChange(e.target.value, 'monthly')} + placeholder="목표 금액 입력" + className="neuro-pressed" + /> + +
+

현재 월간 목표: {formatWithCommas(budgetInputs.monthly)}원

+
+
+
+ ); +}; + +export default BudgetInputCard; diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index c7e4b09..6b85834 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -1,39 +1,44 @@ import React, { useState } from 'react'; import NavBar from '@/components/NavBar'; import BudgetCard from '@/components/BudgetCard'; +import BudgetInputCard from '@/components/BudgetInputCard'; import TransactionCard, { Transaction } from '@/components/TransactionCard'; import AddTransactionButton from '@/components/AddTransactionButton'; import { Wallet, TrendingUp, Bell } from 'lucide-react'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; +import { toast } from '@/components/ui/use-toast'; + const Index = () => { const [selectedTab, setSelectedTab] = useState("daily"); // Sample data - in a real app, this would come from a data source - const transactions: Transaction[] = [{ - id: '1', - title: '식료품 구매', - amount: 25000, - date: '오늘, 12:30 PM', - category: 'shopping', - type: 'expense' - }, { - id: '2', - title: '주유소', - amount: 50000, - date: '어제, 3:45 PM', - category: 'transportation', - type: 'expense' - }, { - id: '3', - title: '월급', - amount: 2500000, - date: '2일전, 9:00 AM', - category: 'income', - type: 'income' - }]; + const transactions: Transaction[] = [ + { + id: '1', + title: '식료품 구매', + amount: 25000, + date: '오늘, 12:30 PM', + category: 'shopping', + type: 'expense' + }, { + id: '2', + title: '주유소', + amount: 50000, + date: '어제, 3:45 PM', + category: 'transportation', + type: 'expense' + }, { + id: '3', + title: '월급', + amount: 2500000, + date: '2일전, 9:00 AM', + category: 'income', + type: 'income' + } + ]; // 예산 데이터 - 실제 앱에서는 백엔드에서 가져와야 함 - const budgetData = { + const [budgetData, setBudgetData] = useState({ daily: { targetAmount: 30000, spentAmount: 15000, @@ -49,7 +54,8 @@ const Index = () => { spentAmount: 750000, remainingAmount: 450000 } - }; + }); + const formatCurrency = (amount: number) => { return new Intl.NumberFormat('ko-KR', { style: 'currency', @@ -62,6 +68,28 @@ const Index = () => { const calculatePercentage = (spent: number, target: number) => { return Math.min(Math.round(spent / target * 100), 100); }; + + // 예산 목표 업데이트 함수 + const handleBudgetGoalUpdate = (type: 'daily' | 'weekly' | 'monthly', amount: number) => { + setBudgetData(prev => { + const remainingAmount = Math.max(0, amount - prev[type].spentAmount); + + return { + ...prev, + [type]: { + ...prev[type], + targetAmount: amount, + remainingAmount: remainingAmount + } + }; + }); + + toast({ + title: "목표 업데이트 완료", + description: `${type === 'daily' ? '일일' : type === 'weekly' ? '주간' : '월간'} 목표가 ${amount.toLocaleString()}원으로 설정되었습니다.` + }); + }; + return
{/* Header */} @@ -182,6 +210,17 @@ const Index = () => {
+ {/* 목표 입력 */} +

목표 입력

+ + {/* Budget Progress */}

예산 현황

@@ -205,4 +244,4 @@ const Index = () => {
; }; -export default Index; \ No newline at end of file +export default Index;