Income
$0.00
Expense
$0.00
For one of my projects I have made an expense tracker with Next.js. I have then decided to take that component, simplify it a bit and create a separate React component for it. Here is the final code with a few adjustments.
import { useState } from "react";
import "./expenseTracker.css";
function ExpenseTracker() {
const [balance, setBalance] = useState(0);
const [income, setIncome] = useState(0);
const [expense, setExpense] = useState(0);
const [transaction, setTransaction] = useState({ amount: "" });
function handleChange(e) {
const { name, value } = e.target;
setTransaction((prevTransaction) => ({
...prevTransaction,
[name]: value,
}));
}
function handleSubmit(e) {
e.preventDefault();
const amount = parseFloat(transaction.amount);
if (amount > 0) {
setIncome((prevIncome) => prevIncome + amount);
} else if (amount < 0) {
setExpense((prevExpense) => prevExpense + Math.abs(amount));
}
if (amount > 0 || amount < 0) {
setBalance((prevBalance) => prevBalance + amount);
}
setTransaction({ amount: "" });
}
return (
<main className="expenseTracker-main">
<section>
<h3>Your Balance:</h3>
<h2>${balance.toFixed(2)}</h2>
</section>
<section>
<article>
<h4>Income</h4>
<p>${income.toFixed(2)}</p>
</article>
<article>
<h4>Expense</h4>
<p>${expense.toFixed(2)}</p>
</article>
</section>
<section>
<form onSubmit={handleSubmit}>
<article className="expenseTracker-article">
<label htmlFor="amount">Amount*</label>
<input
type="number"
name="amount"
id="amount"
placeholder="Enter amount"
min={-9999999}
max={9999999}
step="0.01"
value={transaction.amount}
onChange={handleChange}
/>
<span>*negative - expense; positive - income</span>
</article>
<button type="submit" aria-label="Add transaction">
Add transaction
</button>
</form>
</section>
</main>
);
}
export default ExpenseTracker;
@import url("https://fonts.googleapis.com/css2?family=Play:wght@400;700&display=swap");
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
}
body {
background: #0d1b2a;
color: #e0e1dd;
font-family: "Play", sans-serif;
}
.expenseTracker-main,
.expenseTracker-article {
display: flex;
flex-flow: column nowrap;
gap: 1rem;
max-width: 200px;
margin: 1.5rem auto;
text-align: center;
}
.expenseTracker-main section article {
margin-top: 1rem;
}
.expenseTracker-main button,
.expenseTracker-article input {
padding: 0.5rem;
border: none;
border-radius: 5px;
}
.expenseTracker-main button {
border: 3px solid #e0e1dd;
margin: 10px auto;
background: #415a77;
color: #e0e1dd;
font-weight: bold;
text-transform: uppercase;
cursor: pointer;
}
Styling has been slightly modified to match the design of the current site.
$0.00
$0.00
If you want to get more details about making this expense tracker, check this post on my Medium blog.
Thank you for reading.
I write every Friday and share what I work on and learn.