0% found this document useful (0 votes)
38 views

Project Report 09 43

The document describes a personal finance management project that allows users to track income, expenses and savings over time. It includes sections on project description, overview, diagrams, code output and future enhancements. The project allows adding, viewing and filtering transactions and generates visualizations of balance changes and spending categories.

Uploaded by

Ajay Rank
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
38 views

Project Report 09 43

The document describes a personal finance management project that allows users to track income, expenses and savings over time. It includes sections on project description, overview, diagrams, code output and future enhancements. The project allows adding, viewing and filtering transactions and generates visualizations of balance changes and spending categories.

Uploaded by

Ajay Rank
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

Faculty of Technology

Degree Engineering in

Information and Communication Technology

Advance Web Technology

Report Writing

Personal Finance

Submitted by

Sahil Patel(92100133009)

Heet Chothani(92100133043)
Information and Communication Technology

2023-24

CERTIFICATE

This is to certify that the project entitled Personal Finance has been carried
out by Sahil Patel(92100133009)and Heet Chothani(92100133043) under
my guidance in partial fulfillment of the degree of Bachelor Engineering in
Information and Communication Technology (6th Semester) of Marwadi
University, Rajkot during the academic year 2023-24.

Date : 03-05-2024

Internal Guide Head of the Department

Mr. Shamsagazarzoo Alam Prof . C. D. Parmar

Subject Co-ordinator Head of Department ICT


Engineering
C.T.O. Ally Soft Solutions
Index:

1 Project Description

2 Overview

3 Diagram

4 Output

5 Future Enhancement

Project Description:

Personal finance encompasses managing one's or a family's financial resources


through budgeting, saving, investing, and debt management to achieve stability
and goals. It's influenced by economic factors, personal aspirations, and life
events. Establishing good habits, staying informed, and seeking professional
guidance are crucial for financial well-being.
Overview:

➢ Debt Management
Understanding different types of debt.
Strategies for paying off high-interest debt.
Responsible use of credit cards.

➢ Limiting the expenses

➢ Calculating Income vs Expenses Graph Based on a from


Diagram:
Code: DashBoard.js
import React, { useEffect, useState } from "react";
import { Card, Row, Button } from "antd";
import { Line, Pie } from "@ant-design/charts";
import moment from "moment";
import TransactionSearch from "./TransactionSearch";
import Header from "./Header";
import AddIncomeModal from "./Modals/AddIncome";
import AddExpenseModal from "./Modals/AddExpense";
import Cards from "./Cards";
import NoTransactions from "./NoTransactions";
import { useAuthState } from "react-firebase-hooks/auth";
import { auth, db } from "../firebase";
import { addDoc, collection, getDocs, query } from "firebase/firestore";
import Loader from "./Loader";
import { toast } from "react-toastify";
import { useNavigate } from "react-router-dom";
import { unparse } from "papaparse";
import {
Document,
Page,
Text,
StyleSheet,
PDFViewer,
View,
Font,
} from "@react-pdf/renderer";

const Dashboard = () => {


const [user] = useAuthState(auth);
const [isPDFVisible, setIsPDFVisible] = useState(false);
const [isExpenseModalVisible, setIsExpenseModalVisible] = useState(false);
const [isIncomeModalVisible, setIsIncomeModalVisible] = useState(false);
const [transactions, setTransactions] = useState([]);
const [loading, setLoading] = useState(false);
const [currentBalance, setCurrentBalance] = useState(0);
const [income, setIncome] = useState(0);
const [expenses, setExpenses] = useState(0);
const navigate = useNavigate();

const processChartData = () => {


const balanceData = [];
const spendingData = {};

transactions.forEach((transaction) => {
const monthYear = moment(transaction.date).format("MMM YYYY");
const tag = transaction.tag;

if (transaction.type === "income") {


if (balanceData.some((data) => data.month === monthYear)) {
balanceData.find((data) => data.month === monthYear).balance +=
transaction.amount;
} else {
balanceData.push({ month: monthYear, balance: transaction.amount });
}
} else {
if (balanceData.some((data) => data.month === monthYear)) {
balanceData.find((data) => data.month === monthYear).balance -=
transaction.amount;
} else {
balanceData.push({ month: monthYear, balance: -transaction.amount });
}

if (spendingData[tag]) {
spendingData[tag] += transaction.amount;
} else {
spendingData[tag] = transaction.amount;
}
}
});

const spendingDataArray = Object.keys(spendingData).map((key) => ({


category: key,
value: spendingData[key],
}));
return { balanceData, spendingDataArray };
};

const { balanceData, spendingDataArray } = processChartData();


const showExpenseModal = () => {
setIsExpenseModalVisible(true);
};

const showIncomeModal = () => {


setIsIncomeModalVisible(true);
};

const handleExpenseCancel = () => {


setIsExpenseModalVisible(false);
};

const handleIncomeCancel = () => {


setIsIncomeModalVisible(false);
};

useEffect(() => {
fetchTransactions();
}, []);

const onFinish = (values, type) => {


const newTransaction = {
type: type,
date: moment(values.date).format("YYYY-MM-DD"),
amount: parseFloat(values.amount),
tag: values.tag,
name: values.name,
};

setTransactions([...transactions, newTransaction]);
setIsExpenseModalVisible(false);
setIsIncomeModalVisible(false);
addTransaction(newTransaction);
calculateBalance();
};

const calculateBalance = () => {


let incomeTotal = 0;
let expensesTotal = 0;

transactions.forEach((transaction) => {
if (transaction.type === "income") {
incomeTotal += transaction.amount;
} else {
expensesTotal += transaction.amount;
}
});

setIncome(incomeTotal);
setExpenses(expensesTotal);
setCurrentBalance(incomeTotal - expensesTotal);
};

useEffect(() => {
calculateBalance();
}, [transactions]);

async function addTransaction(transaction, many) {


try {
const docRef = await addDoc(
collection(db, `users/${user.uid}/transactions`),
transaction
);
console.log("Document written with ID: ", docRef.id);
if (!many) {
toast.success("Transaction Added!");
}
} catch (e) {
console.error("Error adding document: ", e);
if (!many) {
toast.error("Couldn't add transaction");
}
}
}

async function fetchTransactions() {


setLoading(true);
if (user) {
const q = query(collection(db, `users/${user.uid}/transactions`));
const querySnapshot = await getDocs(q);
let transactionsArray = [];
querySnapshot.forEach((doc) => {
transactionsArray.push(doc.data());
});
setTransactions(transactionsArray);
toast.success("Transactions Fetched!");
}
setLoading(false);
}

const balanceConfig = {
data: balanceData,
xField: "month",
yField: "balance",
};

const spendingConfig = {
data: spendingDataArray,
angleField: "value",
colorField: "category",
};

function reset() {
console.log("resetting");
}
const cardStyle = {
boxShadow: "0px 0px 30px 8px rgba(3, 127, 127, 0.75)",
margin: "2rem",
borderRadius: "0.5rem",
minWidth: "400px",
flex: 1,
};

function exportToCsv() {
const csv = unparse(transactions, {
fields: ["name", "type", "date", "amount", "tag"],
});
const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = "transactions.csv";
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}

const styles = StyleSheet.create({


page: {
flexDirection: "column",
backgroundColor: "#ffffff",
padding: "20px",
},
section: {
flexDirection: "row",
marginBottom: "10px",
},
item: {
flexGrow: 1,
textAlign: "center",
border: "1px solid #000000",
padding: "5px",
},
});

const TransactionTable = () => (


<>
<View style={styles.section}>
<View style={{ ...styles.item, flex: 2 }}>
<Text>Name</Text>
</View>
<View style={styles.item}>
<Text>Type</Text>
</View>
<View style={styles.item}>
<Text>Date</Text>
</View>
<View style={styles.item}>
<Text>Amount</Text>
</View>
<View style={{ ...styles.item, flex: 2 }}>
<Text>Tag</Text>
</View>
</View>
{transactions.map((transaction, index) => (
<View style={styles.section} key={index}>
<View style={{ ...styles.item, flex: 2 }}>
<Text>{transaction.name}</Text>
</View>
<View style={styles.item}>
<Text>{transaction.type}</Text>
</View>
<View style={styles.item}>
<Text>{transaction.date}</Text>
</View>
<View style={styles.item}>
<Text>{transaction.amount}</Text>
</View>
<View style={{ ...styles.item, flex: 2 }}>
<Text>{transaction.tag}</Text>
</View>
</View>
))}
</>
);
return (
<div className="dashboard-container">
<Header />
{loading ? (
<Loader />
):(
<>
<Cards
currentBalance={currentBalance}
income={income}
expenses={expenses}
showExpenseModal={showExpenseModal}
showIncomeModal={showIncomeModal}
cardStyle={cardStyle}
reset={reset}
/>

<AddExpenseModal
isExpenseModalVisible={isExpenseModalVisible}
handleExpenseCancel={handleExpenseCancel}
onFinish={onFinish}
/>
<AddIncomeModal
isIncomeModalVisible={isIncomeModalVisible}
handleIncomeCancel={handleIncomeCancel}
onFinish={onFinish}
/>
{transactions.length === 0 ? (
<NoTransactions />
):(
<>
<Row gutter={16}>
<Card bordered={true} style={cardStyle}>
<h2>Financial Statistics</h2>
<Line {...{ ...balanceConfig, data: balanceData }} />
</Card>
<Card bordered={true} style={{ ...cardStyle, flex: 0.45 }}>
<h2>Total Spending</h2>
{spendingDataArray.length == 0 ? (
<p>Seems like you haven't spent anything till now...</p>
):(
<Pie {...{ ...spendingConfig, data: spendingDataArray }} />
)}
</Card>
</Row>
</>
)}
<TransactionSearch
transactions={transactions}
exportToCsv={exportToCsv}
fetchTransactions={fetchTransactions}
addTransaction={addTransaction}
/>
{/* PDF Viewer */}
{isPDFVisible && (
<PDFViewer style={{ width: "100%", height: "100vh" }}>
<Document>
<Page size="A4" style={styles.page}>
<Text>Transaction History PDF</Text>
<TransactionTable />
</Page>
</Document>
</PDFViewer>
)}

{/* Button to toggle PDF visibility */}


{!isPDFVisible && (
<Button onClick={() => setIsPDFVisible(!isPDFVisible)}>
Generate PDF
</Button>
)}
</>
)}
</div>
);
};

export default Dashboard;

Expenses Page:
import React, { useEffect, useRef, useState } from "react";
import styled from "styled-components";
import OverViewComponent from "./OverViewComponent";
import TransactionsComponent from "./TransactionsComponent";
import Chart from "chart.js/auto";
import { motion } from "framer-motion";

const Container = styled.div`


display: flex;
flex-direction: column;
align-items: center;
`;

const ChartContainer = styled.canvas`


width: 80%;
height: 300px;
margin-bottom: 20px;
`;

const AlertContainer = styled.div`


position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
`;

const HomeComponent = () => {


const [transactions, setTransactions] = useState([]);
const [expense, setExpense] = useState(0);
const [income, setIncome] = useState(0);
const [showAlert, setShowAlert] = useState(false);
const chartRef = useRef(null);

useEffect(() => {
const calculateBalance = () => {
let totalExpense = 0;
let totalIncome = 0;
transactions.forEach((transaction) => {
if (transaction.type === "EXPENSE") {
totalExpense += transaction.amount;
} else {
totalIncome += transaction.amount;
}
});
setExpense(totalExpense);
setIncome(totalIncome);

// Check if expense exceeds income


if (totalExpense > totalIncome) {
setShowAlert(true);
setTimeout(() => {
setShowAlert(false);
// Redirect to dashboard after 5 seconds
window.location.href = "/dashboard";
}, 5000); // Hide alert after 5 seconds and redirect
}
};
calculateBalance();
}, [transactions]);

const addTransaction = (newTransaction) => {


setTransactions([...transactions, newTransaction]);
};

useEffect(() => {
if (chartRef.current) {
chartRef.current.destroy();
}
const ctx = document.getElementById("myChart");
chartRef.current = new Chart(ctx, {
type: "bar", // Change the chart type to bar
data: {
labels: ["Income", "Expense"],
datasets: [
{
label: "Amount",
data: [income, expense],
backgroundColor: [
"rgba(75, 192, 192, 0.2)",
"rgba(255, 99, 132, 0.2)",
],
borderColor: ["rgba(75, 192, 192, 1)", "rgba(255, 99, 132, 1)"],
borderWidth: 1,
},
],
},
options: {
scales: {
y: {
beginAtZero: true,
},
},
},
});
}, [income, expense]);

return (
<Container>
<OverViewComponent
expense={expense}
income={income}
addTransaction={addTransaction}
/>
{transactions.length > 0 && (
<TransactionsComponent transactions={transactions} />
)}
<ChartContainer id="myChart" />
<AlertContainer>
{showAlert && (
<motion.div
initial={{ opacity: 0, y: -50 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -50 }}
transition={{ duration: 0.5 }}
style={{
backgroundColor: "red",
color: "white",
padding: "10px 20px",
borderRadius: "8px",
boxShadow: "0px 4px 6px rgba(0, 0, 0, 0.1)",
}}
>
Expense exceeds income! Redirecting to dashboard...
</motion.div>
)}
</AlertContainer>
</Container>
);
};

export default HomeComponent;


Output:
Future Enhancement: I twill be used in Buisness Needs and also will be useful for
controliing expenses to avoid loss of money and time.

You might also like