DP
View all posts
Making Expense Tracker with React

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.

Main structure and functionality

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;

Basic styling

@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;
}

Live version

Styling has been slightly modified to match the design of the current site.

Your Balance:

$0.00

Income

$0.00

Expense

$0.00

*negative - expense; positive - income

If you want to get more details about making this expense tracker, check this post on my Medium blog.

Thank you for reading.


Read my stories on Medium

I write every Friday and share what I work on and learn.

@Dimterion
Visit my blog