Skip to content

Smashboards

Smash Creative's project dashboard, joining Asana projects with Harvest time and invoices. I inherited it in 2023 and modernized it: TypeScript, React Query, Clerk auth, Vitest.

role: sole developer · apr – aug 2023 · internal tool
Smashboards
102commits, apr to aug 2023
8project stages derived from asana
100projects per harvest query, was all at once

Overview

Smashboards is Smash Creative's internal dashboard. It reads projects out of Asana and time and invoices out of Harvest, and puts the two together so the studio's leadership could see where every project stood: what stage it was in, whether it had slipped, and how its hours were tracking against its budget.

The repo had been quiet since early 2021 when it was handed to me in April 2023, and I worked on it into that August. It is not running any more.

Modernizing it

The first day was maintenance: convert Create React App to Vite, rename the JavaScript to JSX, upgrade every dependency. After that came the real work. TypeScript across the components, Mantine for the UI, TanStack Query behind query-key factories instead of scattered fetching, Clerk for auth, Vitest with faker and zod-mock for fixtures, Doppler holding the environment variables. 102 commits between April and August 2023.

Joining Asana to Harvest

Asana and Harvest do not know about each other, and the dashboard had been matching a project in one to a project in the other by name, which broke every time someone renamed something. I changed it to match on a project code written into both.

The rest is derived from Asana's tasks: which of the studio's eight stages a project is in (strategy, design, development, styling, QA, approval, training, launch), whether it is late, and hours against budget. Fixed-fee and hourly projects bill differently, and the dashboard tells them apart from a prefix on the Asana project name. Stage detection is the one piece I put a unit test on.

The rate limiter

The last thing I did to it, that August, was fix the support view timing out. It asked Harvest for the time entries of every support project in a single query, and the rate limiter cut it off. Splitting that into parallel queries of a hundred project ids each, with a loading state in front of them, brought it back.

Screenshots

company totals
hourly project
fixed-fee project