My birthday is coming up soon (or was. I am writing this note later), and Naqu has planned for the NPG India group to come over so we can play some “tasks” from the Taskmaster- The Board Game & Card game she gave me. Like, the main event of the day will be TaskMaster themed, sorta.
For scoring, her plan was to have a Whiteboard sorta thing where then everyone’s score will update accordigly. Not a bad idea, considering she got a sheet of paper that is like a whiteboard, so moving the “Potraits” based on score order would be easy too.
Buuuut, since I love complicating stuff, and I also wanted to make the main event MORE themed, I decided to make a small Website to track the scores that’ll be entered by Naqu after each task.
Goals
- Have a functioning web page where scores of each player can be visualised.
- Folks should find it cute and add to the zest of the event.
- DO NOT SPEND MORE THAN A DAY ON THIS.
- Spoiler Alert: I did.
Logs
Since I am writing this AFTER I’m done with everything, there’s not many “logs” here. In fact, there aren’t any. I will describe the flow of work I did and some basic here and there about the project. More details will obviously be in the README of that repo.
I wanted this to be done very very fast. So I used Cursor to work with me and build out features the way I wanted it to be built. Of course the boilerplate I made on my own, I don’t trust AI to make full on boilerplate code properly.
Opted to go with React since that’s the one LLMs can output the easiest, and as usual TailwindCSS as my styling library. Vite has made life quite simple tbh, so the first scaffold was made in like 10 mins or so. Trouble was, I asked Cursor to integrate tailwind, and it did try to do it. It really did. But it fucking failed. I seem to remember in some other project also Tailwind integration was a doozy, when done via LLMs. I think I used Claude Code back then.
Anyway, I did the tailwind integration by hand, and asked Cursor to quickly make a 2 row, 4 column grid layout to show everyone’s picture frame and score below it.
I scraped the background and some assets (like the stickers behind the score text) from the official taskmaster website, to give a nice authentic feel to what I was making. I got the font also identified and added to my site, Veteran Typewriter.
Then the data source had to be integrated.
Naqu is most comfortable with Google Sheets. It’s the easiest to fill in relational data for non-tech folks, and I could also integrate it into the React App to just read from that sheet. Idea was, during the gameplay Naqu will update scores in the sheet, and then press a button on the web app to refresh the scores and re-arrange everyone ka portraits in ascending order of scores.
First I tried a quick and easy method, by publishing the Google Sheet to the Web as a CSV file, and then reading that CSV file directly in the web app. Found a nice library called PapaParse that aided with the CSV ka parsing. But the publishing of the CSV would take upwards of 1-2 minutes, and only then would I be able to pull latest scores from it.
Too slow for me.
Created an API Key for Google Sheets on my GCP console, stopped the publish to web thing, and simply made the Google Sheet “public” (Anyone with the link can view). Then used this library to fetch the sheet and got Cursor to write parsing logic to get a proper array of fields that I can use to display the scores on the UI. Clicking the “update” button also would reload the sheet, thereby getting me latest data.
Here’s a basic Arch Diagram to demonstrate everything I said above.
Player portraits… well… the way they’re handled now “works”, but even I know it’s quite finicky. Basically, there are .png files in the public folder of the app, and these .png files have the same names as the ones in the Google Sheet. I’ve got a small hook that injects these png files as per the names that are “gotten” from the Google Sheet. Also, for the parsing logic to work correctly, I also need the players ka names in an array. Maybe in the future I can make this entire piece work directly from Google Sheet somehow.
Lastly, for the animations, I used Framer Motion. It’s a nice React-y library, and while I have limited experience with it, it’s always a delight to see the animations I can whip up easily using it.
So yeah, all in all, was a blast making this. There’ll be more work to do on this hopefully in the future, but for now…
GREAT SUCCESS