import React, { useState, useEffect } from 'react';
import { BrowserRouter as Router, Routes, Route, Link, Navigate, useNavigate } from 'react-router-dom';
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts';
import { AlertCircle, Calendar, CheckCircle, DollarSign, Home, LogOut, Menu, User, Users, X } from 'lucide-react';
// Mock data - in a real application, this would come from an API
const initialBabysitters = [
{ id: 1, firstName: 'Jane', lastName: 'Doe', email: 'jane@example.com', phone: '0771234567', nin: 'CM12345678ABCDE', age: 25, nextOfKin: 'John Doe (Brother) - 0779876543' },
{ id: 2, firstName: 'Mary', lastName: 'Smith', email: 'mary@example.com', phone: '0782345678', nin: 'CM87654321FGHIJ', age: 28, nextOfKin: 'James Smith (Husband) - 0788765432' },
];
const initialChildren = [
{ id: 1, fullName: 'Emma Johnson', age: 3, parentName: 'Sarah Johnson', parentPhone: '0701234567', specialNeeds: 'Allergic to peanuts', duration: 'full-day' },
{ id: 2, fullName: 'Noah Williams', age: 2, parentName: 'Michael Williams', parentPhone: '0712345678', specialNeeds: 'None', duration: 'half-day' },
];
const initialFinances = {
income: [
{ id: 1, date: '2023-05-01', source: 'Parent Payment', amount: 50000, description: 'Emma Johnson - Full day (10 days)' },
{ id: 2, date: '2023-05-02', source: 'Parent Payment', amount: 25000, description: 'Noah Williams - Half day (10 days)' },
],
expenses: [
{ id: 1, date: '2023-05-15', category: 'Salaries', amount: 30000, description: 'Jane Doe - May first half' },
{ id: 2, date: '2023-05-15', category: 'Salaries', amount: 25000, description: 'Mary Smith - May first half' },
{ id: 3, date: '2023-05-10', category: 'Toys', amount: 15000, description: 'New educational toys' },
{ id: 4, date: '2023-05-05', category: 'Utilities', amount: 10000, description: 'Electricity bill - May' },
],
budgets: [
{ category: 'Salaries', budgeted: 120000, spent: 55000 },
{ category: 'Toys', budgeted: 30000, spent: 15000 },
{ category: 'Utilities', budgeted: 25000, spent: 10000 },
{ category: 'Maintenance', budgeted: 20000, spent: 0 },
]
};
const initialAttendance = {
children: [
{ id: 1, childId: 1, date: '2023-05-01', status: 'present', duration: 'full-day' },
{ id: 2, childId: 2, date: '2023-05-01', status: 'present', duration: 'half-day' },
{ id: 3, childId: 1, date: '2023-05-02', status: 'absent', duration: 'full-day' },
{ id: 4, childId: 2, date: '2023-05-02', status: 'present', duration: 'half-day' },
],
babysitters: [
{ id: 1, babysitterId: 1, date: '2023-05-01', status: 'present' },
{ id: 2, babysitterId: 2, date: '2023-05-01', status: 'present' },
{ id: 3, babysitterId: 1, date: '2023-05-02', status: 'present' },
{ id: 4, babysitterId: 2, date: '2023-05-02', status: 'absent' },
]
};
const initialIncidents = [
{ id: 1, childId: 1, date: '2023-05-01', description: 'Minor fall during playtime. No injury observed.', reportedBy: 1 },
{ id: 2, childId: 2, date: '2023-05-02', description: 'Refused to eat lunch. Parents notified.', reportedBy: 2 },
];
const initialPayments = [
{ id: 1, babysitterId: 1, date: '2023-05-15', amount: 30000, childrenCount: 6, sessionType: 'full-day', status: 'cleared' },
{ id: 2, babysitterId: 2, date: '2023-05-15', amount: 25000, childrenCount: 5, sessionType: 'half-day', status: 'cleared' },
];
// Main App Component
function App() {
const [user, setUser] = useState(null);
const [babysitters, setBabysitters] = useState(initialBabysitters);
const [children, setChildren] = useState(initialChildren);
const [finances, setFinances] = useState(initialFinances);
const [attendance, setAttendance] = useState(initialAttendance);
const [incidents, setIncidents] = useState(initialIncidents);
const [payments, setPayments] = useState(initialPayments);
const [sidebarOpen, setSidebarOpen] = useState(true);
// Mock login function
const login = (username, password, role) => {
// In a real app, this would validate credentials against a backend
setUser({ username, role });
return true;
};
// Mock logout function
const logout = () => {
setUser(null);
};
// Add babysitter function
const addBabysitter = (babysitter) => {
const newBabysitter = {
...babysitter,
id: babysitters.length + 1,
};
setBabysitters([...babysitters, newBabysitter]);
};
// Add child function
const addChild = (child) => {
const newChild = {
...child,
id: children.length + 1,
};
setChildren([...children, newChild]);
};
// Add income function
const addIncome = (income) => {
const newIncome = {
...income,
id: finances.income.length + 1,
date: new Date().toISOString().split('T')[0],
};
setFinances({
...finances,
income: [...finances.income, newIncome],
});
};
// Add expense function
const addExpense = (expense) => {
const newExpense = {
...expense,
id: finances.expenses.length + 1,
date: new Date().toISOString().split('T')[0],
};
setFinances({
...finances,
expenses: [...finances.expenses, newExpense],
});
};
// Add child attendance function
const addChildAttendance = (attendance) => {
const newAttendance = {
...attendance,
id: initialAttendance.children.length + 1,
date: new Date().toISOString().split('T')[0],
};
setAttendance({
...attendance,
children: [...attendance.children, newAttendance],
});
};
// Add babysitter attendance function
const addBabysitterAttendance = (attendance) => {
const newAttendance = {
...attendance,
id: initialAttendance.babysitters.length + 1,
date: new Date().toISOString().split('T')[0],
};
setAttendance({
...attendance,
babysitters: [...attendance.babysitters, newAttendance],
});
};
// Add incident function
const addIncident = (incident) => {
const newIncident = {
...incident,
id: incidents.length + 1,
date: new Date().toISOString().split('T')[0],
};
setIncidents([...incidents, newIncident]);
};
// Add payment function
const addPayment = (payment) => {
const newPayment = {
...payment,
id: payments.length + 1,
date: new Date().toISOString().split('T')[0],
status: 'pending',
};
setPayments([...payments, newPayment]);
};
// Clear payment function
const clearPayment = (id) => {
const updatedPayments = payments.map(payment =>
payment.id === id ? { ...payment, status: 'cleared' } : payment
);
setPayments(updatedPayments);
};
return (
{user ? (
{/* Sidebar */}
{sidebarOpen &&
Daystar Daycare
}
{/* Main Content */}
{user && `Welcome, ${user.username} (${user.role})`}
{new Date().toLocaleDateString('en-US', { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' })}
} />
} />
} />
} />
} />
} />
) : (
)}
);
}
// Login Page Component
function LoginPage({ login }) {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [role, setRole] = useState('manager');
const [error, setError] = useState('');
const navigate = useNavigate();
const handleSubmit = (e) => {
e.preventDefault();
if (!username || !password) {
setError('Please enter both username and password');
return;
}
const success = login(username, password, role);
if (success) {
navigate('/dashboard');
} else {
setError('Invalid credentials');
}
};
return (
Daystar Daycare
Sign in to access the management system
);
}
// Dashboard Component
function Dashboard({ finances, children, babysitters, incidents }) {
// Calculate total income
const totalIncome = finances.income.reduce((sum, item) => sum + item.amount, 0);
// Calculate total expenses
const totalExpenses = finances.expenses.reduce((sum, item) => sum + item.amount, 0);
// Calculate balance
const balance = totalIncome - totalExpenses;
// Prepare data for expense by category chart
const expensesByCategory = finances.expenses.reduce((acc, expense) => {
if (!acc[expense.category]) {
acc[expense.category] = 0;
}
acc[expense.category] += expense.amount;
return acc;
}, {});
const expenseChartData = Object.keys(expensesByCategory).map(category => ({
name: category,
value: expensesByCategory[category]
}));
// Colors for pie chart
const COLORS = ['#4F7CAC', '#F9C784', '#E88873', '#9DD9D2', '#7F7EFF'];
// Recent incidents
const recentIncidents = [...incidents].sort((a, b) => new Date(b.date) - new Date(a.date)).slice(0, 3);
return (
Dashboard
{/* Summary Cards */}
Total Children
{children.length}
Full-day:
{children.filter(child => child.duration === 'full-day').length}
Half-day:
{children.filter(child => child.duration === 'half-day').length}
Total Babysitters
{babysitters.length}
Child to babysitter ratio: {(children.length / babysitters.length).toFixed(1)}
Financial Summary
{balance.toLocaleString()} UGX
Income:
{totalIncome.toLocaleString()} UGX
Expenses:
{totalExpenses.toLocaleString()} UGX
{/* Charts */}
Expenses by Category
`${name} ${(percent * 100).toFixed(0)}%`}
>
{expenseChartData.map((entry, index) => (
|
))}
`${value.toLocaleString()} UGX`} />
Budget vs Actual
`${value.toLocaleString()} UGX`} />
{/* Recent Incidents */}
Recent Incidents
{recentIncidents.length > 0 ? (
{recentIncidents.map(incident => {
const child = children.find(c => c.id === incident.childId);
const babysitter = babysitters.find(b => b.id === incident.reportedBy);
return (
{child ? child.fullName : 'Unknown Child'}
{new Date(incident.date).toLocaleDateString()}
{incident.description}
Reported by: {babysitter ? `${babysitter.firstName} ${babysitter.lastName}` : 'Unknown'}
);
})}
) : (
No recent incidents reported.
)}
);
}
// Babysitters Management Component
function BabysittersManagement({ babysitters, addBabysitter, payments, addPayment, clearPayment }) {
const [showAddForm, setShowAddForm] = useState(false);
const [showPaymentForm, setShowPaymentForm] = useState(false);
const [activeTab, setActiveTab] = useState('list');
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
phone: '',
nin: '',
age: '',
nextOfKin: ''
});
const [paymentData, setPaymentData] = useState({
babysitterId: '',
childrenCount: '',
sessionType: 'full-day',
amount: 0
});
const [errors, setErrors] = useState({});
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
};
const handlePaymentInputChange = (e) => {
const { name, value } = e.target;
// Calculate amount based on children count and session type
let newPaymentData = {
...paymentData,
[name]: value
};
if (name === 'childrenCount' || name === 'sessionType') {
const rate = newPaymentData.sessionType === 'full-day' ? 5000 : 2000;
newPaymentData.amount = newPaymentData.childrenCount ? parseInt(newPaymentData.childrenCount) * rate : 0;
}
setPaymentData(newPaymentData);
};
const validateForm = () => {
const newErrors = {};
if (!formData.firstName) newErrors.firstName = 'First name is required';
if (!formData.lastName) newErrors.lastName = 'Last name is required';
if (!formData.phone) newErrors.phone = 'Phone number is required';
if (!formData.nin) newErrors.nin = 'NIN is required';
if (!formData.age) {
newErrors.age = 'Age is required';
} else if (parseInt(formData.age) < 21 || parseInt(formData.age) > 35) {
newErrors.age = 'Age must be between 21 and 35';
}
if (!formData.nextOfKin) newErrors.nextOfKin = 'Next of kin information is required';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const validatePaymentForm = () => {
const newErrors = {};
if (!paymentData.babysitterId) newErrors.babysitterId = 'Babysitter is required';
if (!paymentData.childrenCount) newErrors.childrenCount = 'Number of children is required';
if (parseInt(paymentData.childrenCount) <= 0) newErrors.childrenCount = 'Number of children must be greater than 0';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = (e) => {
e.preventDefault();
if (validateForm()) {
addBabysitter({
...formData,
age: parseInt(formData.age)
});
setFormData({
firstName: '',
lastName: '',
email: '',
phone: '',
nin: '',
age: '',
nextOfKin: ''
});
setShowAddForm(false);
}
};
const handlePaymentSubmit = (e) => {
e.preventDefault();
if (validatePaymentForm()) {
addPayment({
...paymentData,
childrenCount: parseInt(paymentData.childrenCount),
amount: parseInt(paymentData.amount)
});
setPaymentData({
babysitterId: '',
childrenCount: '',
sessionType: 'full-day',
amount: 0
});
setShowPaymentForm(false);
}
};
return (
Babysitters Management
{activeTab === 'list' && (
<>
{showAddForm && (
)}
| Name |
Contact |
NIN |
Age |
Next of Kin |
{babysitters.map(babysitter => (
|
{babysitter.firstName} {babysitter.lastName}
|
{babysitter.phone}
{babysitter.email && {babysitter.email} }
|
{babysitter.nin}
|
{babysitter.age}
|
{babysitter.nextOfKin}
|
))}
>
)}
{activeTab === 'payments' && (
<>
{showPaymentForm && (
)}
| Date |
Babysitter |
Children |
Session |
Amount |
Status |
Actions |
{payments.map(payment => {
const babysitter = babysitters.find(b => b.id === parseInt(payment.babysitterId));
return (
|
{new Date(payment.date).toLocaleDateString()}
|
{babysitter ? `${babysitter.firstName} ${babysitter.lastName}` : 'Unknown'}
|
{payment.childrenCount}
|
{payment.sessionType === 'full-day' ? 'Full Day' : 'Half Day'}
|
{payment.amount.toLocaleString()} UGX
|
{payment.status === 'cleared' ? 'Cleared' : 'Pending'}
|
{payment.status === 'pending' && (
)}
|
);
})}
>
)}
);
}
// Children Management Component
function ChildrenManagement({ children, addChild, incidents, addIncident, babysitters }) {
const [showAddForm, setShowAddForm] = useState(false);
const [showIncidentForm, setShowIncidentForm] = useState(false);
const [activeTab, setActiveTab] = useState('list');
const [formData, setFormData] = useState({
fullName: '',
age: '',
parentName: '',
parentPhone: '',
specialNeeds: '',
duration: 'full-day'
});
const [incidentData, setIncidentData] = useState({
childId: '',
description: '',
reportedBy: ''
});
const [errors, setErrors] = useState({});
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value
});
};
const handleIncidentInputChange = (e) => {
const { name, value } = e.target;
setIncidentData({
...incidentData,
[name]: value
});
};
const validateForm = () => {
const newErrors = {};
if (!formData.fullName) newErrors.fullName = 'Full name is required';
if (!formData.age) newErrors.age = 'Age is required';
if (parseInt(formData.age) < 0) newErrors.age = 'Age must be a positive number';
if (!formData.parentName) newErrors.parentName = 'Parent name is required';
if (!formData.parentPhone) newErrors.parentPhone = 'Parent phone is required';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const validateIncidentForm = () => {
const newErrors = {};
if (!incidentData.childId) newErrors.childId = 'Child is required';
if (!incidentData.description) newErrors.description = 'Description is required';
if (!incidentData.reportedBy) newErrors.reportedBy = 'Reporter is required';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleSubmit = (e) => {
e.preventDefault();
if (validateForm()) {
addChild({
...formData,
age: parseInt(formData.age)
});
setFormData({
fullName: '',
age: '',
parentName: '',
parentPhone: '',
specialNeeds: '',
duration: 'full-day'
});
setShowAddForm(false);
}
};
const handleIncidentSubmit = (e) => {
e.preventDefault();
if (validateIncidentForm()) {
addIncident({
...incidentData,
childId: parseInt(incidentData.childId),
reportedBy: parseInt(incidentData.reportedBy)
});
setIncidentData({
childId: '',
description: '',
reportedBy: ''
});
setShowIncidentForm(false);
}
};
return (
Children Management
{activeTab === 'list' && (
<>
{showAddForm && (
)}
| Name |
Age |
Parent/Guardian |
Special Needs |
Duration |
{children.map(child => (
|
{child.fullName}
|
{child.age}
|
{child.parentName}
{child.parentPhone}
|
{child.specialNeeds || 'None'}
|
{child.duration === 'full-day' ? 'Full Day' : 'Half Day'}
|
))}
>
)}
{activeTab === 'incidents' && (
<>
{showIncidentForm && (
Report New Incident
)}
| Date |
Child |
Description |
Reported By |
{incidents.map(incident => {
const child = children.find(c => c.id === incident.childId);
const babysitter = babysitters.find(b => b.id === incident.reportedBy);
return (
|
{new Date(incident.date).toLocaleDateString()}
|
{child ? child.fullName : 'Unknown Child'}
|
{incident.description}
|
{babysitter ? `${babysitter.firstName} ${babysitter.lastName}` : 'Unknown'}
|
);
})}
>
)}
);
}
// Attendance Management Component
function AttendanceManagement({ attendance, children, babysitters, addChildAttendance, addBabysitterAttendance }) {
const [activeTab, setActiveTab] = useState('children');
const [selectedDate, setSelectedDate] = useState(new Date().toISOString().split('T')[0]);
const [childAttendanceData, setChildAttendanceData] = useState({
childId: '',
status: 'present',
duration: 'full-day'
});
const [babysitterAttendanceData, setBabysitterAttendanceData] = useState({
babysitterId: '',
status: 'present'
});
const [errors, setErrors] = useState({});
const handleChildInputChange = (e) => {
const { name, value } = e.target;
setChildAttendanceData({
...childAttendanceData,
[name]: value
});
};
const handleBabysitterInputChange = (e) => {
const { name, value } = e.target;
setBabysitterAttendanceData({
...babysitterAttendanceData,
[name]: value
});
};
const validateChildForm = () => {
const newErrors = {};
if (!childAttendanceData.childId) newErrors.childId = 'Child is required';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const validateBabysitterForm = () => {
const newErrors = {};
if (!babysitterAttendanceData.babysitterId) newErrors.babysitterId = 'Babysitter is required';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleChildSubmit = (e) => {
e.preventDefault();
if (validateChildForm()) {
addChildAttendance({
...childAttendanceData,
childId: parseInt(childAttendanceData.childId),
date: selectedDate
});
setChildAttendanceData({
childId: '',
status: 'present',
duration: 'full-day'
});
}
};
const handleBabysitterSubmit = (e) => {
e.preventDefault();
if (validateBabysitterForm()) {
addBabysitterAttendance({
...babysitterAttendanceData,
babysitterId: parseInt(babysitterAttendanceData.babysitterId),
date: selectedDate
});
setBabysitterAttendanceData({
babysitterId: '',
status: 'present'
});
}
};
// Filter attendance records by selected date
const filteredChildAttendance = attendance.children.filter(record => record.date === selectedDate);
const filteredBabysitterAttendance = attendance.babysitters.filter(record => record.date === selectedDate);
return (
Attendance Management
{activeTab === 'children' && (
<>
| Child |
Status |
Duration |
{filteredChildAttendance.map(record => {
const child = children.find(c => c.id === record.childId);
return (
|
{child ? child.fullName : 'Unknown Child'}
|
{record.status === 'present' ? 'Present' : 'Absent'}
|
{record.duration === 'full-day' ? 'Full Day' : 'Half Day'}
|
);
})}
{filteredChildAttendance.length === 0 && (
|
No attendance records for this date.
|
)}
>
)}
{activeTab === 'babysitters' && (
<>
| Babysitter |
Status |
{filteredBabysitterAttendance.map(record => {
const babysitter = babysitters.find(b => b.id === record.babysitterId);
return (
|
{babysitter ? `${babysitter.firstName} ${babysitter.lastName}` : 'Unknown Babysitter'}
|
{record.status === 'present' ? 'Present' : 'Absent'}
|
);
})}
{filteredBabysitterAttendance.length === 0 && (
|
No attendance records for this date.
|
)}
>
)}
);
}
// Finances Management Component
function FinancesManagement({ finances, addIncome, addExpense }) {
const [activeTab, setActiveTab] = useState('overview');
const [showAddIncomeForm, setShowAddIncomeForm] = useState(false);
const [showAddExpenseForm, setShowAddExpenseForm] = useState(false);
const [incomeData, setIncomeData] = useState({
source: 'Parent Payment',
amount: '',
description: ''
});
const [expenseData, setExpenseData] = useState({
category: 'Salaries',
amount: '',
description: ''
});
const [errors, setErrors] = useState({});
// Calculate total income
const totalIncome = finances.income.reduce((sum, item) => sum + item.amount, 0);
// Calculate total expenses
const totalExpenses = finances.expenses.reduce((sum, item) => sum + item.amount, 0);
// Calculate balance
const balance = totalIncome - totalExpenses;
// Prepare data for expense by category chart
const expensesByCategory = finances.expenses.reduce((acc, expense) => {
if (!acc[expense.category]) {
acc[expense.category] = 0;
}
acc[expense.category] += expense.amount;
return acc;
}, {});
const expenseChartData = Object.keys(expensesByCategory).map(category => ({
name: category,
value: expensesByCategory[category]
}));
// Colors for pie chart
const COLORS = ['#4F7CAC', '#F9C784', '#E88873', '#9DD9D2', '#7F7EFF'];
const handleIncomeInputChange = (e) => {
const { name, value } = e.target;
setIncomeData({
...incomeData,
[name]: value
});
};
const handleExpenseInputChange = (e) => {
const { name, value } = e.target;
setExpenseData({
...expenseData,
[name]: value
});
};
const validateIncomeForm = () => {
const newErrors = {};
if (!incomeData.source) newErrors.source = 'Source is required';
if (!incomeData.amount) {
newErrors.amount = 'Amount is required';
} else if (isNaN(incomeData.amount) || parseInt(incomeData.amount) <= 0) {
newErrors.amount = 'Amount must be a positive number';
}
if (!incomeData.description) newErrors.description = 'Description is required';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const validateExpenseForm = () => {
const newErrors = {};
if (!expenseData.category) newErrors.category = 'Category is required';
if (!expenseData.amount) {
newErrors.amount = 'Amount is required';
} else if (isNaN(expenseData.amount) || parseInt(expenseData.amount) <= 0) {
newErrors.amount = 'Amount must be a positive number';
}
if (!expenseData.description) newErrors.description = 'Description is required';
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleIncomeSubmit = (e) => {
e.preventDefault();
if (validateIncomeForm()) {
addIncome({
...incomeData,
amount: parseInt(incomeData.amount)
});
setIncomeData({
source: 'Parent Payment',
amount: '',
description: ''
});
setShowAddIncomeForm(false);
}
};
const handleExpenseSubmit = (e) => {
e.preventDefault();
if (validateExpenseForm()) {
addExpense({
...expenseData,
amount: parseInt(expenseData.amount)
});
setExpenseData({
category: 'Salaries',
amount: '',
description: ''
});
setShowAddExpenseForm(false);
}
};
return (
Financial Management
{activeTab === 'overview' && (
Total Income
{totalIncome.toLocaleString()} UGX
Total Expenses
{totalExpenses.toLocaleString()} UGX
Balance
= 0 ? 'text-green-600' : 'text-red-600'}`}>
{balance.toLocaleString()} UGX
Expenses by Category
`${name} ${(percent * 100).toFixed(0)}%`}
>
{expenseChartData.map((entry, index) => (
|
))}
`${value.toLocaleString()} UGX`} />
Budget vs Actual
`${value.toLocaleString()} UGX`} />
Recent Transactions
| Date |
Type |
Category |
Description |
Amount |
{[...finances.income.map(item => ({ ...item, type: 'Income', category: item.source })),
...finances.expenses.map(item => ({ ...item, type: 'Expense' }))]
.sort((a, b) => new Date(b.date) - new Date(a.date))
.slice(0, 5)
.map((transaction, index) => (
|
{new Date(transaction.date).toLocaleDateString()}
|
{transaction.type}
|
{transaction.category}
|
{transaction.description}
|
{transaction.type === 'Income' ? '+' : '-'}{transaction.amount.toLocaleString()} UGX
|
))}
)}
{activeTab === 'income' && (
<>
{showAddIncomeForm && (
Add New Income
)}
| Date |
Source |
Description |
Amount |
{finances.income.map(income => (
|
{new Date(income.date).toLocaleDateString()}
|
{income.source}
|
{income.description}
|
{income.amount.toLocaleString()} UGX
|
))}
|
Total Income:
|
{totalIncome.toLocaleString()} UGX
|
>
)}
{activeTab === 'expenses' && (
<>
{showAddExpenseForm && (
Add New Expense
)}
| Date |
Category |
Description |
Amount |
{finances.expenses.map(expense => (
|
{new Date(expense.date).toLocaleDateString()}
|
{expense.category}
|
{expense.description}
|
{expense.amount.toLocaleString()} UGX
|
))}
|
Total Expenses:
|
{totalExpenses.toLocaleString()} UGX
|
>
)}
{activeTab === 'budget' && (
Budget Management
| Category |
Budgeted Amount |
Actual Spent |
Remaining |
Status |
{finances.budgets.map((budget, index) => {
const remaining = budget.budgeted - budget.spent;
const percentSpent = (budget.spent / budget.budgeted) * 100;
return (
|
{budget.category}
|
{budget.budgeted.toLocaleString()} UGX
|
{budget.spent.toLocaleString()} UGX
|
{remaining.toLocaleString()} UGX
|
90 ? 'bg-red-600' : percentSpent > 70 ? 'bg-yellow-500' : 'bg-green-600'}`}
style={{ width: `${Math.min(percentSpent, 100)}%` }}
>
{percentSpent.toFixed(0)}%
|
);
})}
`${value.toLocaleString()} UGX`} />
)}
);
}
export default App;