immortal tracker

An app to track completion progress in Total War: Warhammer 3

TECH STACK

  • React
  • Styled Components
  • Framer Motion

FEATURES

  • Modal
  • Tooltip
  • React Context
  • Auto-complete Search
  • Toast Notifications

lessons learned

  • As my first app working from a database, there are too many learning moments to count. Here are just a few:

    • Components: how to structure them components so they would be easy to use when being consumed. I leaned heavily into using the children prop, and also feel like I've started developing my understanding of when to give more control to the consumer (e.g. using a delegated prop), and which aspects of a component need to be set in stone.
    • State management: I realized part way through this project that there were multiple pieces of state that were required in multiple components, and passing them down as props was becoming unwieldy. This lead to me learning and implementing React context throughout my entire app to manage state.
    • UI updating from state: I had a lot of fun implementing specific colour schemes for each race; it felt like a fun touch to bring the mood of each race into the UI in this way.
  • In my career, I’ve been guilty of overthinking my work and trying to lay perfect foundations before jumping in. This leads to analysis paralysis, and the work suffers as a result.

    I felt that urge in this project, so I decided to run a little experiment: I consciously decided to start building the app without preparing any extensive foundations first (e.g. a design system, what kind of data structure to use etc).

    This lead to growing pains as the project progressed, such as having to re-write my data structure multiple times to support functionality.

    I don’t regret this choice: quickly iterating and prototyping different data structures helped me build a better understanding of what will be required for future projects.

    What I did come to regret, however, was not putting other basics in place: for example, I didn’t implement a consistent design token system until most of the components were already built. This lead to hours of labourious work as I went back over my app and removed all the magic numbers that were sprinkled in everywhere.

  • For the majority of the interactable components (modals, tooltips, select inputs etc), I set a challenge to get as far as possible building them myself. When I reached my limits (mostly around accessibility), I then turned to headless libraries like Radix UI.

    I built them with the view that I would be re-using them later in future portfolio projects, so the investment now would save time later.

    I had moments where I invested a lot of time building something myself, only to realize I couldn’t implement something in a complete way (for example, a tooltip that is aware of collisions). I also had moments where learning the API of a component library felt like it was taking more time than just trying to build something myself.

    I have no regrets at trying to build things myself: failing at something is the best way to learn. But I also understand why so many developers, with actual time/resource constraints in real projects, would turn to these libraries. They’re great.

A stylised cariacuture of Sam's handsome dog, Rupert, waiting patiently for treats.

hire me so I can buy more treats for rupert.

That's right, I'm not above taking advantage of the fact that my dog is outrageously handsome to try and snag a job.

I'd be happy to tell you more about him (and, answer any questions you might have about me, of course).