Stash

Stash

Managing personal finances doesn’t have to be a daunting task, yet so many of us find ourselves juggling multiple apps, spreadsheets, and mental notes just to stay afloat. Enter Stash, the ultimate personal finance app designed to bring clarity and control to your financial world.

With Stash, you can wave goodbye to financial guesswork and hello to a beautifully organized overview of your money. Whether you’re monitoring your spending, building budgets, or saving for that dream vacation, Stash makes it effortless to keep everything in check.

Core Functionalities

πŸ–₯️ Aggregated dashboard on the overview page

πŸͺ΄ Create, read, update, delete (CRUD) budgets and saving pots

πŸ“‡ View the latest three transactions for each budget category created

πŸͺœ View progress towards each pot

πŸ’Έ Add money to and withdraw money from pots

My Role

As a full-stack developer, I developed both the frontend and backend for the project to come to life.

Technologies

For this project, I decided to use the following technologies to learn these technologies in depth.

🎨 Frontend

TypeScript | React | React Query | React Router | React ChartJS | React Hot Toast | Zod | Vanilla CSS | Media Queries | Vercel.com (hosting)

πŸ€– Backend

Express with Typescript | Prisma ORM | PostgreSQL | JSON Web Token(Authentication) | Render.com (hosting)

Pain Points

🎭 Replacing Redux with React Query

Redux is my goto state management library however for this particular project I wanted to see if I could leverage React Query this presented its own set of challenge.

πŸ“Š Working with React Charts and React Hot Toast

This wasn't a pain point per se, since I had not used these libraries before and wasn't sure how long it would take me to integrate them to the project.

πŸ€Ήβ€β™‚οΈ Finding the balance developing both frontend and backend

Developing full stack is fun but, this also means more work on both sides, this constant backend forth was at times a mess.

πŸͺ¨ Working with Compound Components

Compound Components bring a layer of challenge but, the result outweighs the complexity.

Spotlights

πŸ”Œ React Query to the rescue

I initially started off the project using the actions and loaders available with react router. Which is great however this meant that i was making a request to the server every time and I also needed to make sure to follow the CRUD operations in separate routes. It is no doubt it is possible to make all these feature working with the router but for the sake of simplicity and efficiency I decided to make use of Redux to have my data centrally. This code something like below.

The Loader Loader

Using loader in the router using loader

Switching to Redux Redux setup

What I didn't like personally is that i had to do the fetch using loader and then save to Redux and then use it all across, I wanted to see what other ways was avaialable this when i came to read about React Query. Let's look at the only code needed as hook that is allows for data fetching.

react query

Here is the code above would be used. using react query

To go from multiple files and using several tools this simple approach was far more streamlined for this app, bear in mind that data caching and invalidating which automatically refetchs data makes everything sync with ease.

Here is what invalidation looks like when a pot is edited. nvalidation

For my current implementation where I need the data to be in sync with server this feels like much easier approach. For this instance I have removed all the code relating to Redux and loaders/actions for react router but, again this is specific to this implementation. Having said that, I am mesmerized with the heavy lifting that React query does so far πŸ™Œ

πŸ₯· One feature at a time front and back

I found when developing full stack now is to develop one feature at a time and not to jump to far ahead. I generally forget about the frontend implementation until my backend API is working perfectly with postman. Once I see the implementation work only then I start the frontend implementation. The biggest advantage with this for me is the sense of progress and separation of concern.

πŸͺž Compound Component Pattern

Imagine making a component dynamic in the sense that you can choose what you want to keep and what you want to exclude from the component. This is what the compound component enables the secret lies in creating a dynamic context from which the contents can get their values and lastly attaching property our main component. Here is the breakdown.

Creating context and passing the using the content in the main component compound component Note that children has to be used so that another function/component can be passed down.

Adding a child component compound component open

Adding another child component compound component window

Last step to add the components as property that can later be used accordingly. Make compound

Here is the final usage of the compound component. Make compound

I am very keen to take this and apply this to the transactions page to make the transactions table dynamic πŸ“‹

Current Status

The project is still in progress some of the features that I am currently working on are mentioned below:

    • View all transactions on the transaction's page with pagination for every ten transactions
    • Search, sort, and filter transactions
    • View recurring bills and the status of each for the current month
    • Search and sort recurring bills

Lesson Learned

The developing Stash offered key lessons in simplifying workflows, adopting new technologies, and balancing full-stack responsibilities. Transitioning from Redux to React Query streamlined data fetching and syncing while reducing boilerplate code. Tackling one feature at a time, starting with backend APIs, reinforced the value of iterative development and clear separation of concerns. Mastering libraries like React ChartJS, React Hot Toast, and the compound component pattern highlighted the benefits of adaptability and reusable design. Overall, this project underscored the importance of simplicity, efficient workflows, and continuous learning for effective software development.

You can check out the live demo below.

πŸ”— Demo

← Back Home