expenese quá ưng

import React, { useState, useEffect } from 'react'; import axios from 'axios'; import numberToWords from '../utils/numberToWords'; function Expenses() { const [amount, setAmount] = useState(''); const [category, setCategory] = useState(''); const [date, setDate] = useState(''); const [purpose, setPurpose] = useState(''); const [location, setLocation] = useState(''); const [initialBudget, setInitialBudget] = useState(null); const [newBudget, setNewBudget] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const [allocations, setAllocations] = useState({ essentials: 0, savings: 0, selfInvestment: 0, charity: 0, emergency: 0, }); const [expenses, setExpenses] = useState([]); const [error, setError] = useState(''); const [isDarkMode, setIsDarkMode] = useState(false); const token = localStorage.getItem('token'); const categories = [ 'Tiêu dùng thiết yếu Vv', 'Tiết kiệm bắt buộc', 'Đầu tư bản thân', 'Từ thiện', 'Dự phòng linh hoạt', ]; useEffect(() => { const fetchData = async () => { try { const [budgetRes, expensesRes, allocationsRes] = await Promise.all([ axios.get('https://backend-rockefeller-finance.onrender.com/api/initial-budget', { headers: { Authorization: `Bearer ${token}` }, }), axios.get('https://backend-rockefeller-finance.onrender.com/api/expenses', { headers: { Authorization: `Bearer ${token}` }, }), axios.get('https://backend-rockefeller-finance.onrender.com/api/allocations', { headers: { Authorization: `Bearer ${token}` }, }), ]); setInitialBudget(budgetRes.data.initialBudget); setExpenses(expensesRes.data); setAllocations(allocationsRes.data); } catch (err) { setError(err.response?.data?.error || 'Lỗi lấy dữ liệu'); } }; if (token) fetchData(); }, [token]); const handleBudgetSubmit = async (e) => { e.preventDefault(); const parsedBudget = parseFloat(newBudget); if (parsedBudget <= 0) { setError('Vui lòng nhập số tiền hợp lệ!'); return; } setIsSubmitting(true); try { const response = await axios.post( 'https://backend-rockefeller-finance.onrender.com/api/initial-budget', { initialBudget: parsedBudget }, { headers: { Authorization: `Bearer ${token}` } } ); setInitialBudget(response.data.initialBudget); setAllocations(response.data.allocations); setNewBudget(''); setError(''); } catch (err) { setError(err.response?.data?.error || 'Lỗi lưu ngân sách'); } finally { setIsSubmitting(false); } }; const handleExpenseSubmit = async (e) => { e.preventDefault(); const parsedAmount = parseFloat(amount); if (parsedAmount <= 0) { setError('Vui lòng nhập số tiền hợp lệ!'); return; } if (!purpose || !location) { setError('Vui lòng nhập mục đích và vị trí!'); return; } setIsSubmitting(true); try { const response = await axios.post( 'https://backend-rockefeller-finance.onrender.com/api/expenses', { amount: parsedAmount, category, purpose, location, date: date || new Date().toLocaleDateString('vi-VN') }, { headers: { Authorization: `Bearer ${token}` } } ); setExpenses(response.data); // Cập nhật allocations và initialBudget const budgetRes = await axios.get('https://backend-rockefeller-finance.onrender.com/api/initial-budget', { headers: { Authorization: `Bearer ${token}` }, }); const allocRes = await axios.get('https://backend-rockefeller-finance.onrender.com/api/allocations', { headers: { Authorization: `Bearer ${token}` }, }); setInitialBudget(budgetRes.data.initialBudget); setAllocations(allocRes.data); setAmount(''); setCategory(''); setPurpose(''); setLocation(''); setDate(''); setError(''); } catch (err) { setError(err.response?.data?.error || 'Lỗi thêm chi tiêu'); } finally { setIsSubmitting(false); } }; const handleDeleteExpense = async (index) => { try { const response = await axios.delete( `https://backend-rockefeller-finance.onrender.com/api/expenses/${index}`, { headers: { Authorization: `Bearer ${token}` } } ); setExpenses(response.data); // Cập nhật initialBudget và allocations const budgetRes = await axios.get('https://backend-rockefeller-finance.onrender.com/api/initial-budget', { headers: { Authorization: `Bearer ${token}` }, }); const allocRes = await axios.get('https://backend-rockefeller-finance.onrender.com/api/allocations', { headers: { Authorization: `Bearer ${token}` }, }); setInitialBudget(budgetRes.data.initialBudget); setAllocations(allocRes.data); } catch (err) { setError(err.response?.data?.error || 'Lỗi xóa chi tiêu'); } }; const toggleDarkMode = () => { setIsDarkMode(!isDarkMode); }; const formatVND = (value) => { return new Intl.NumberFormat('vi-VN', { style: 'currency', currency: 'VND' }).format(value); }; const totalAmount = parseFloat(allocations.essentials) + parseFloat(allocations.savings) + parseFloat(allocations.selfInvestment) + parseFloat(allocations.charity) + parseFloat(allocations.emergency); return (

Quản lý chi tiêu

{error &&

{error}

} {initialBudget === null || initialBudget === 0 ? (

Nhập ngân sách ban đầu

setNewBudget(e.target.value)} className={`w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 transition ${ isDarkMode ? 'bg-gray-800 text-white border-gray-600' : 'bg-white text-gray-800 border-gray-300' }`} placeholder="Nhập ngân sách ban đầu" required min="1" />
) : ( <>

Nạp thêm ngân sách

setNewBudget(e.target.value)} className={`w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 transition ${ isDarkMode ? 'bg-gray-800 text-white border-gray-600' : 'bg-white text-gray-800 border-gray-300' }`} placeholder="Nhập số tiền nạp thêm" min="1" />

Số dư ngân sách

{formatVND(initialBudget)}

Thêm chi tiêu

setAmount(e.target.value)} className={`w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 transition ${ isDarkMode ? 'bg-gray-800 text-white border-gray-600' : 'bg-white text-gray-800 border-gray-300' }`} placeholder="Nhập số tiền" required min="1" />
setPurpose(e.target.value)} className={`w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 transition ${ isDarkMode ? 'bg-gray-800 text-white border-gray-600' : 'bg-white text-gray-800 border-gray-300' }`} placeholder="Nhập mục đích (ví dụ: Mua thực phẩm)" required />
setLocation(e.target.value)} className={`w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 transition ${ isDarkMode ? 'bg-gray-800 text-white border-gray-600' : 'bg-white text-gray-800 border-gray-300' }`} placeholder="Nhập vị trí (ví dụ: Siêu thị VinMart)" required />
setDate(e.target.value)} className={`w-full p-2 border rounded focus:outline-none focus:ring-2 focus:ring-blue-500 transition ${ isDarkMode ? 'bg-gray-800 text-white border-gray-600' : 'bg-white text-gray-800 border-gray-300' }`} />

Lịch sử chi tiêu

{expenses.map((expense, index) => ( ))}
Ngày Danh mục Số tiền (VND) Mục đích Vị trí Hành động
{expense.date} {expense.category} {formatVND(expense.amount)} {expense.purpose} {expense.location}

Phân bổ ngân sách

Tiêu dùng thiết yếu (50%)

{formatVND(allocations.essentials)}

Tiết kiệm bắt buộc (20%)

{formatVND(allocations.savings)}

Đầu tư bản thân (15%)

{formatVND(allocations.selfInvestment)}

Từ thiện (5%)

{formatVND(allocations.charity)}

Dự phòng linh hoạt (10%)

{formatVND(allocations.emergency)}

{totalAmount > 0 && (

Tổng số tiền phân bổ

{formatVND(totalAmount)}

{numberToWords(totalAmount)}

)} )}
); } export default Expenses;
Huyền

Một Blog Anime chia sẻ những bộ anime hay download về để xem chất lượng cao nhất. neyuhv.blogspot.com does not host any files, it merely links to 3rd party services. Legal issues should be taken up with the file hosts and providers. neyuhv.blogspot.com is not responsible for any media files shown by the video providers.

Mới hơn Cũ hơn