diff --git a/oldhomepage.txt b/oldhomepage.txt
new file mode 100644
index 0000000..c4b731d
--- /dev/null
+++ b/oldhomepage.txt
@@ -0,0 +1,477 @@
+import React, { useState, useEffect } from 'react';
+import { Pie } from 'react-chartjs-2';
+import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js';
+import { doc, getDoc, setDoc, updateDoc, deleteDoc } from 'firebase/firestore';
+import { getAuth, onAuthStateChanged, signOut, deleteUser, reauthenticateWithCredential, EmailAuthProvider } from 'firebase/auth';
+import { db } from './firebase-config';
+import './homepage.css';
+import Modal from './Modal.js';
+import { set } from 'lodash';
+
+ChartJS.register(ArcElement, Tooltip, Legend);
+
+const Homepage = () => {
+ const [catData, setCatData] = useState([]);
+ const [catLabels, setCatLabels] = useState([]);
+ const [showModal, setShowModal] = useState({ log: false, update: false, new: false, income: false, deleteAccount: false });
+ const [formData, setFormData] = useState({ amount: '', category: '', memo: '', oldCategory: '', newCategory: { name: '', amount: 0 }, income: '' });
+ const [userId, setUserId] = useState(null);
+ const [user, setUser] = useState(null);
+ const [tutorial, setTutorial] = useState(false);
+ const [currentStep, setCurrentStep] = useState(0);
+ const [income, setIncome] = useState(0);
+ const [password, setPassword] = useState('');
+ const [transactionHistory, setTransactionHistory] = useState([]);
+
+ const tutorialSteps = [
+ {
+ title: 'Step 1: Set Up Income',
+ content: 'To set up your income, go to the income section and enter your monthly income.',
+ },
+ {
+ title: 'Step 2: Create a Category',
+ content: 'To create a new category, click on the "New Category" button and fill in the details.',
+ },
+ {
+ title: 'Step 3: Log a Transaction',
+ content: 'To log a transaction, click on the "Log Transaction" button and enter the transaction details.',
+ },
+ ];
+
+ useEffect(() => {
+ const auth = getAuth();
+
+ const unsubscribe = onAuthStateChanged(auth, async (user) => {
+ if (user) {
+ setUser(user);
+ setUserId(user.uid);
+ const userId = user.uid;
+ const userDocRef = doc(db, 'users', userId);
+
+ try {
+ const userDoc = await getDoc(userDocRef);
+ if (!userDoc.exists()) {
+ await setDoc(
+ userDocRef,
+ {
+ email: user.email,
+ name: user.displayName,
+ createdAt: new Date(),
+ budgetData: [],
+ tutorial: false,
+ },
+ { merge: true }
+ );
+ console.log('User document created with initial data');
+ } else {
+ console.log('User document already exists. Data fetched successfully.');
+ }
+
+ const userData = userDoc.data();
+ const budgetData = userData.budgetData || [];
+ const incomeEntry = budgetData.find(entry => entry.category === 'Income');
+ const incomeAmount = incomeEntry ? incomeEntry.amount : 0;
+ setIncome(incomeAmount);
+
+ const categories = budgetData.filter(entry => entry.type === 'category').map((entry) => entry.category);
+ const amounts = budgetData.filter(entry => entry.type === 'category').map((entry) => entry.amount);
+
+ setCatData(amounts);
+ setCatLabels(categories);
+ setTutorial(userData.tutorial || false);
+
+ const transactions = budgetData
+ .filter(entry => entry.type === 'category')
+ .flatMap(entry => entry.transactions || [])
+ .map(transaction => ({
+ category: transaction.category,
+ memo: transaction.memo,
+ amount: transaction.amount,
+ date: transaction.date,
+ time: transaction.time
+ }))
+ .sort((a, b) => new Date(b.date + ' ' + b.time) - new Date(a.date + ' ' + a.time));
+ setTransactionHistory(transactions);
+ } catch (error) {
+ console.error('Error checking or creating user document:', error);
+ }
+ } else {
+ console.log('No user is currently logged in');
+ }
+ });
+
+ return unsubscribe;
+ }, []);
+
+ const handleOpenModal = (type) => {
+ setShowModal({ ...showModal, [type]: true });
+ };
+
+ const handleCloseModal = () => {
+ setShowModal({ log: false, update: false, new: false, income: false, deleteAccount: false });
+ setFormData({ amount: '', category: '', memo: '', oldCategory: '', newCategory: { name: '', amount: 0 }, income: '' });
+ };
+
+ const handleInputChange = (e) => {
+ const { name, value } = e.target;
+ const keys = name.split('.');
+ setFormData((prevState) => {
+ let newState = { ...prevState };
+ let current = newState;
+ for (let i = 0; i < keys.length - 1; i++) {
+ current = current[keys[i]];
+ }
+ current[keys[keys.length - 1]] = value;
+ return newState;
+ });
+ };
+
+ const handleFormSubmit = async (event, type) => {
+ event.preventDefault();
+
+ if (user && userId) {
+ const userDocRef = doc(db, 'users', userId);
+
+ try {
+ const userDoc = await getDoc(userDocRef);
+ let updatedData;
+
+ if (userDoc.exists()) {
+ const currentData = userDoc.data().budgetData || [];
+
+ if (type === 'log') {
+ const newTransaction = {
+ amount: parseInt(formData.amount),
+ memo: formData.memo,
+ type: 'transaction',
+ date: new Date().toLocaleDateString(),
+ time: new Date().toLocaleTimeString(),
+ category: formData.category
+ };
+ updatedData = currentData.map((entry) => {
+ if (entry.category === formData.category && entry.type === 'category') {
+ return { ...entry, transactions: [newTransaction, ...(entry.transactions || [])] };
+ }
+ return entry;
+ });
+
+ await setDoc(userDocRef, { budgetData: updatedData }, { merge: true });
+ setFormData({...formData, amount: '', memo: ''});
+
+ setTransactionHistory(prevHistory => [{ ...newTransaction }, ...prevHistory]);
+ } else if (type === 'update') {
+ updatedData = currentData.map((entry) =>
+ entry.category === formData.oldCategory ? { ...entry, category: formData.newCategory.name, amount: parseInt(formData.newCategory.amount), type: 'category' } : entry
+ );
+ updatedData = updatedData.filter((entry, index, self) =>
+ index === self.findIndex((e) => e.category === entry.category)
+ );
+ await updateDoc(userDocRef, { budgetData: updatedData });
+ } else if (type === 'new') {
+ const newEntry = { category: formData.newCategory.name, amount: parseInt(formData.newCategory.amount), type: 'category', transactions: [] };
+ updatedData = [...currentData, newEntry];
+ await updateDoc(userDocRef, { budgetData: updatedData });
+ } else if (type === 'income') {
+ const incomeEntry = { category: 'Income', amount: parseInt(formData.income), type: 'income' };
+ updatedData = currentData.filter(entry => entry.category !== 'Income');
+ updatedData.push(incomeEntry);
+ await updateDoc(userDocRef, { budgetData: updatedData });
+ setIncome(incomeEntry.amount);
+ }
+
+ setCatData(updatedData.filter(entry => entry.type === 'category').map((entry) => entry.amount));
+ setCatLabels(updatedData.filter(entry => entry.type === 'category').map((entry) => entry.category));
+ console.log('Data updated successfully');
+ } else {
+ const newEntry = {
+ category: formData.category,
+ memo: formData.memo,
+ amount: parseInt(formData.amount),
+ type: 'transaction',
+ date: new Date().toLocaleDateString(),
+ time: new Date().toLocaleTimeString()
+ };
+ updatedData = [newEntry];
+
+ await setDoc(
+ userDocRef,
+ {
+ email: user.email,
+ name: user.displayName,
+ createdAt: new Date(),
+ budgetData: updatedData,
+ },
+ { merge: true }
+ );
+ setCatData(updatedData.filter(entry => entry.type === 'category').map((entry) => entry.amount));
+ setCatLabels(updatedData.filter(entry => entry.type === 'category').map((entry) => entry.category));
+ }
+
+ handleCloseModal();
+ } catch (error) {
+ console.error('Error updating Firestore:', error);
+ }
+ } else {
+ console.error('No user is currently authenticated');
+ }
+ };
+
+ const handleNextStep = () => {
+ if (currentStep < tutorialSteps.length - 1) {
+ setCurrentStep(currentStep + 1);
+ }
+ };
+
+ const handlePrevStep = () => {
+ if (currentStep > 0) {
+ setCurrentStep(currentStep - 1);
+ }
+ };
+
+ const handleTutorialClick = async () => {
+ if (user && userId) {
+ const userDocRef = doc(db, 'users', userId);
+ try {
+ await updateDoc(userDocRef, { tutorial: true });
+ setTutorial(true);
+ console.log('Tutorial status updated successfully');
+ } catch (error) {
+ console.error('Error updating tutorial status:', error);
+ }
+ } else {
+ console.error('No user is currently authenticated');
+ }
+ };
+
+ const handleExitTutorial = async () => {
+ if (user && userId) {
+ const userDocRef = doc(db, 'users', userId);
+ try {
+ await updateDoc(userDocRef, { tutorial: false });
+ setTutorial(false);
+ console.log('Tutorial status updated successfully');
+ } catch (error) {
+ console.error('Error updating tutorial status:', error);
+ }
+ } else {
+ console.error('No user is currently authenticated');
+ }
+ };
+
+ const handleClearData = async () => {
+ if (user && userId) {
+ const userDocRef = doc(db, 'users', userId);
+ try {
+ await updateDoc(userDocRef, { budgetData: [] });
+ setCatData([]);
+ setCatLabels([]);
+ setTransactionHistory([]);
+ console.log('Data cleared successfully');
+ } catch (error) {
+ console.error('Error clearing data:', error);
+ }
+ } else {
+ console.error('No user is currently authenticated');
+ }
+ };
+
+ const handleLogout = async () => {
+ const auth = getAuth();
+ try {
+ await signOut(auth);
+ console.log('User logged out successfully');
+ window.location.href = '/';
+ } catch (error) {
+ console.error('Logout error:', error.message);
+ alert('Logout failed');
+ }
+ };
+
+ const handleDeleteAccount = async () => {
+ if (user && userId) {
+ const userDocRef = doc(db, 'users', userId);
+ try {
+ await deleteDoc(userDocRef);
+ await deleteUser(user);
+ console.log('Account and data deleted successfully');
+ window.location.href = '/';
+ } catch (error) {
+ console.error('Account deletion error:', error.message);
+ alert('Account deletion failed');
+ }
+ } else {
+ console.error('No user is currently authenticated');
+ }
+ };
+
+ const totalCategoryAmount = catData.reduce((a, b) => a + b, 0);
+ const remainingAmount = Math.max(0, income - totalCategoryAmount);
+
+ const pieData = {
+ labels: [...catLabels, 'Remaining'],
+ datasets: [
+ {
+ label: 'Dollars Spent',
+ data: [...catData, remainingAmount],
+ backgroundColor: [...catLabels.map(() => '#66AA11'), '#CCCCCC'],
+ hoverBackgroundColor: [...catLabels.map(() => '#66AA11'), '#CCCCCC'],
+ },
+ ],
+ };
+
+ const options = {
+ plugins: {
+ legend: {
+ labels: {
+ color: 'white',
+ },
+ },
+ },
+ };
+
+ const tutorialBoxStyle = {
+ position: 'fixed',
+ top: '20%',
+ left: '50%',
+ transform: 'translate(-50%, -20%)',
+ width: '80%',
+ maxWidth: '600px',
+ padding: '20px',
+ backgroundColor: 'white',
+ boxShadow: '0 4px 8px rgba(0, 0, 0, 0.1)',
+ zIndex: 1000,
+ };
+
+ return (
+
+
Money Gremlin
+
+
+
Budget Dashboard
+
+ {catData.length > 0 ? (
+
+ ) : (
+
No data available to display
+ )}
+
+
+
+
handleOpenModal('log')}>
+ Log Transaction
+
+
handleOpenModal('update')}>
+ Update Category
+
+
handleOpenModal('new')}>
+ New Category
+
+
handleOpenModal('income')}>
+ Change Income
+
+
handleOpenModal('history')}>
+ Transaction History
+
+
+
+
+
+ Log Transaction
+
+
+
+
+ Update Category
+
+
+
+
+ New Category
+
+
+
+
+ Change Income
+
+
+
+
+ Transaction History
+
+
+
+ | Date |
+ Time |
+ Category |
+ Memo |
+ Amount |
+
+
+
+ {transactionHistory.map((transaction, index) => (
+
+ | {transaction.date} |
+ {transaction.time} |
+ {transaction.category} |
+ {transaction.memo} |
+ {transaction.amount} |
+
+ ))}
+
+
+
+
+
+ Delete Account
+ Are you sure you want to delete your account? This will erase all data associated with the account and is irreversible.
+
+
+
+
+
+
+ );
+};
+
+export default Homepage;
\ No newline at end of file
diff --git a/src/components/ActionButtons/ActionButtons.js b/src/components/ActionButtons/ActionButtons.js
index 933ae74..2c5a407 100644
--- a/src/components/ActionButtons/ActionButtons.js
+++ b/src/components/ActionButtons/ActionButtons.js
@@ -16,6 +16,9 @@ const ActionButtons = ({ onActionClick }) => {
onActionClick('income')}>
Change Income
+ onActionClick('transactionHistory')}>
+ Transaction History
+
);
};
diff --git a/src/components/Modals/LogTransactionModal.js b/src/components/Modals/LogTransactionModal.js
index 4b05d7f..1027281 100644
--- a/src/components/Modals/LogTransactionModal.js
+++ b/src/components/Modals/LogTransactionModal.js
@@ -2,15 +2,20 @@ import React from 'react';
import Modal from './Modal';
export const LogTransactionModal = ({ show, onClose, onSubmit, categories }) => {
- const handleSubmit = (e) => {
+ const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData(e.target);
- onSubmit({
- category: formData.get('category'),
- memo: formData.get('memo'),
- amount: parseFloat(formData.get('amount'))
- }, 'log');
- onClose();
+ try {
+ await onSubmit({
+ category: formData.get('category'),
+ memo: formData.get('memo'),
+ amount: parseFloat(formData.get('amount'))
+ }, 'log');
+ onClose();
+ } catch (error) {
+ console.error('Failed to log transaction:', error);
+ alert('Failed to update budget data');
+ }
};
return (
diff --git a/src/components/Modals/Modal.css b/src/components/Modals/Modal.css
index bca0f5b..eef1827 100644
--- a/src/components/Modals/Modal.css
+++ b/src/components/Modals/Modal.css
@@ -66,4 +66,46 @@
.modal-form button:hover {
background-color: #558800;
- }
\ No newline at end of file
+ }
+
+/* Transaction History Table Styles */
+.transaction-table-container {
+ max-height: 400px;
+ overflow-y: auto;
+ margin-top: 1rem;
+}
+
+.transaction-table {
+ width: 100%;
+ border-collapse: collapse;
+ background-color: #1a1d23;
+ color: white;
+}
+
+.transaction-table th,
+.transaction-table td {
+ padding: 8px;
+ text-align: left;
+ border-bottom: 1px solid #444;
+}
+
+.transaction-table th {
+ background-color: #66AA11;
+ color: white;
+ position: sticky;
+ top: 0;
+}
+
+.transaction-table tr:nth-child(even) {
+ background-color: #282c34;
+}
+
+.transaction-table tr:hover {
+ background-color: #333842;
+}
+
+.no-transactions {
+ text-align: center;
+ padding: 20px;
+ color: #888;
+}
\ No newline at end of file
diff --git a/src/components/Modals/TransactionHistoryModal.js b/src/components/Modals/TransactionHistoryModal.js
new file mode 100644
index 0000000..1c5b632
--- /dev/null
+++ b/src/components/Modals/TransactionHistoryModal.js
@@ -0,0 +1,39 @@
+import React from 'react';
+import Modal from './Modal';
+import './Modal.css';
+
+export const TransactionHistoryModal = ({ show, onClose, transactions }) => {
+ return (
+
+ Transaction History
+
+ {transactions && transactions.length > 0 ? (
+
+
+
+ | Date |
+ Time |
+ Category |
+ Memo |
+ Amount |
+
+
+
+ {transactions.map((transaction, index) => (
+
+ | {transaction.date} |
+ {transaction.time} |
+ {transaction.category} |
+ {transaction.memo} |
+ ${transaction.amount.toFixed(2)} |
+
+ ))}
+
+
+ ) : (
+
No transactions to display
+ )}
+
+
+ );
+};
\ No newline at end of file
diff --git a/src/components/Modals/index.js b/src/components/Modals/index.js
index d4b829a..5cbe298 100644
--- a/src/components/Modals/index.js
+++ b/src/components/Modals/index.js
@@ -3,11 +3,13 @@ import { NewCategoryModal } from './NewCategoryModal';
import { IncomeModal } from './IncomeModal';
import { DeleteAccountModal } from './DeleteAccountModal';
import { UpdateCategoryModal } from './UpdateCategoryModal';
+import { TransactionHistoryModal } from './TransactionHistoryModal';
export {
LogTransactionModal,
NewCategoryModal,
IncomeModal,
DeleteAccountModal,
- UpdateCategoryModal
+ UpdateCategoryModal,
+ TransactionHistoryModal
};
\ No newline at end of file
diff --git a/src/hooks/useBudgetData.js b/src/hooks/useBudgetData.js
index 645ebce..8db46fa 100644
--- a/src/hooks/useBudgetData.js
+++ b/src/hooks/useBudgetData.js
@@ -10,24 +10,39 @@ export const useBudgetData = (userId) => {
const fetchData = async () => {
if (userId) {
- const userDocRef = doc(db, 'users', userId);
- const userDoc = await getDoc(userDocRef);
- if (userDoc.exists()) {
- const userData = userDoc.data();
- const budgetData = userData.budgetData || [];
- const transactions = userData.transactions || [];
-
- // Set income
- const incomeEntry = budgetData.find(entry => entry.category === 'Income');
- setIncome(incomeEntry ? incomeEntry.amount : 0);
-
- // Set categories and amounts
- const categories = budgetData.filter(entry => entry.type === 'category');
- setCatData(categories.map(entry => entry.amount));
- setCatLabels(categories.map(entry => entry.category));
-
- // Set transactions
- setTransactions(transactions);
+ try {
+ const userDocRef = doc(db, 'users', userId);
+ const userDoc = await getDoc(userDocRef);
+
+ if (userDoc.exists()) {
+ const userData = userDoc.data();
+ const budgetData = userData.budgetData || [];
+
+ // Set income
+ const incomeEntry = budgetData.find(entry => entry.category === 'Income');
+ setIncome(incomeEntry ? incomeEntry.amount : 0);
+
+ // Set categories and amounts
+ const categories = budgetData
+ .filter(entry => entry.type === 'category')
+ .map(entry => entry.category);
+ const amounts = budgetData
+ .filter(entry => entry.type === 'category')
+ .map(entry => entry.amount);
+
+ setCatData(amounts);
+ setCatLabels(categories);
+
+ // Set transactions
+ const allTransactions = budgetData
+ .filter(entry => entry.type === 'category')
+ .flatMap(entry => entry.transactions || [])
+ .sort((a, b) => new Date(b.date + ' ' + b.time) - new Date(a.date + ' ' + a.time));
+
+ setTransactions(allTransactions);
+ }
+ } catch (error) {
+ console.error('Error fetching budget data:', error);
}
}
};
@@ -39,82 +54,78 @@ export const useBudgetData = (userId) => {
const handleFormSubmit = async (formData, type) => {
if (!userId) return;
- const userDocRef = doc(db, 'users', userId);
- const userDoc = await getDoc(userDocRef);
- let budgetData = userDoc.exists() ? userDoc.data().budgetData || [] : [];
- let transactions = userDoc.exists() ? userDoc.data().transactions || [] : [];
-
try {
+ const userDocRef = doc(db, 'users', userId);
+ const userDoc = await getDoc(userDocRef);
+ const currentData = userDoc.exists() ? userDoc.data().budgetData || [] : [];
+ let updatedData;
+
switch (type) {
- case 'new':
- // Add new category
- budgetData.push({
+ case 'log':
+ const newTransaction = {
category: formData.category,
- amount: formData.amount,
- type: 'category'
+ memo: formData.memo,
+ amount: parseFloat(formData.amount),
+ date: new Date().toLocaleDateString(),
+ time: new Date().toLocaleTimeString(),
+ type: 'transaction'
+ };
+
+ updatedData = currentData.map(entry => {
+ if (entry.category === formData.category && entry.type === 'category') {
+ return {
+ ...entry,
+ transactions: [newTransaction, ...(entry.transactions || [])]
+ };
+ }
+ return entry;
});
+
+ await updateDoc(userDocRef, { budgetData: updatedData });
+ setTransactions(prevTransactions => [newTransaction, ...prevTransactions]);
break;
- case 'update':
- // Update existing category
- const categoryIndex = budgetData.findIndex(
- item => item.category === formData.oldCategory
- );
- if (categoryIndex !== -1) {
- budgetData[categoryIndex] = {
- category: formData.newCategory || formData.oldCategory,
- amount: formData.amount,
- type: 'category'
- };
- // Update category name in transactions if it changed
- if (formData.newCategory && formData.newCategory !== formData.oldCategory) {
- transactions = transactions.map(t => ({
- ...t,
- category: t.category === formData.oldCategory ? formData.newCategory : t.category
- }));
- }
- }
+ case 'new':
+ const newCategory = {
+ category: formData.name,
+ amount: formData.amount,
+ type: 'category',
+ transactions: []
+ };
+ updatedData = [...currentData, newCategory];
+ await updateDoc(userDocRef, { budgetData: updatedData });
+ await fetchData();
break;
- case 'income':
- // Update income
- const incomeIndex = budgetData.findIndex(
- item => item.category === 'Income'
+ case 'update':
+ updatedData = currentData.map(entry =>
+ entry.category === formData.oldCategory
+ ? { ...entry, category: formData.name, amount: formData.amount }
+ : entry
);
- if (incomeIndex !== -1) {
- budgetData[incomeIndex].amount = formData.amount;
- } else {
- budgetData.push({
- category: 'Income',
- amount: formData.amount,
- type: 'income'
- });
- }
+ await updateDoc(userDocRef, { budgetData: updatedData });
+ await fetchData();
break;
- case 'log':
- // Log a transaction without changing category amount
- transactions.push({
- category: formData.category,
+ case 'income':
+ const incomeEntry = {
+ category: 'Income',
amount: formData.amount,
- memo: formData.memo,
- date: new Date().toISOString()
- });
+ type: 'income'
+ };
+ updatedData = currentData.filter(entry => entry.category !== 'Income');
+ updatedData.push(incomeEntry);
+ await updateDoc(userDocRef, { budgetData: updatedData });
+ setIncome(formData.amount);
break;
- }
-
- // Update Firestore
- await updateDoc(userDocRef, {
- budgetData,
- transactions
- });
- // Refresh the local state
- await fetchData();
+ default:
+ return;
+ }
} catch (error) {
console.error('Error updating budget data:', error);
- alert('Failed to update budget data');
+ throw error;
}
};
@@ -123,10 +134,8 @@ export const useBudgetData = (userId) => {
try {
const userDocRef = doc(db, 'users', userId);
await updateDoc(userDocRef, {
- budgetData: [{ category: 'Income', amount: 0, type: 'income' }],
- transactions: []
+ budgetData: [{ category: 'Income', amount: 0, type: 'income' }]
});
- // Reset local state
setCatData([]);
setCatLabels([]);
setIncome(0);
diff --git a/src/pages/Homepage/Homepage.js b/src/pages/Homepage/Homepage.js
index d68f91a..28c3d28 100644
--- a/src/pages/Homepage/Homepage.js
+++ b/src/pages/Homepage/Homepage.js
@@ -1,4 +1,4 @@
-import React, { useState} from 'react';
+import React, { useState } from 'react';
import Header from '../../components/Header';
import BudgetDashboard from '../../components/BudgetDashboard';
import ActionButtons from '../../components/ActionButtons';
@@ -9,8 +9,9 @@ import {
UpdateCategoryModal,
NewCategoryModal,
IncomeModal,
- DeleteAccountModal
- } from '../../components/Modals';
+ DeleteAccountModal,
+ TransactionHistoryModal
+} from '../../components/Modals';
import { useAuth } from '../../hooks/useAuth';
import { useBudgetData } from '../../hooks/useBudgetData';
import { useTutorial } from '../../hooks/useTutorial';
@@ -19,19 +20,29 @@ import './Homepage.css';
const Homepage = () => {
const [activeModal, setActiveModal] = useState(null);
const { user, handleLogout, handleDeleteAccount } = useAuth();
+
+ const {
+ catData,
+ catLabels,
+ income,
+ transactions,
+ handleFormSubmit,
+ handleClearData
+ } = useBudgetData(user?.uid);
+ const { tutorial, currentStep, handleTutorialActions } = useTutorial(user?.uid);
const { catData, catLabels, income, transactions, handleFormSubmit, handleClearData } = useBudgetData(user?.uid);
- const {tutorial, currentStep, handleTutorialActions } = useTutorial(user?.uid);
+
return (
- {
}
+
{tutorial && (
- )}
+ )}
- {/* Modal components */}
setActiveModal(null)}
onSubmit={handleFormSubmit}
categories={catLabels}
/>
+
setActiveModal(null)}
onSubmit={handleFormSubmit}
categories={catLabels}
/>
+
setActiveModal(null)}
onSubmit={handleFormSubmit}
/>
+
setActiveModal(null)}
onSubmit={handleFormSubmit}
/>
+
setActiveModal(null)}
onConfirm={handleDeleteAccount}
/>
- {
);
};