←

mayfest bookings

mayfest bookings icon

overview

internal bookings tool for mayfest productions. the bookings team used to keep quotes, contacts, and history in spreadsheets. this is a shared app instead: a quote catalog, a lineup builder, and a searchable archive of past campus bookings.

not a public product. only people on the team can get in. i built the frontend, backend, and database for the current festival cycle.

what it does

  • one catalog for artists, quotes, agencies, and notes, instead of a pile of sheets
  • new quotes entered by hand, with room for ranges or an exact number
  • listener counts and genres next to each artist, so the team can compare without leaving the app
  • a shortlist that can be arranged into a festival lineup
  • a running total against the team's budget, with a warning when a quote is old or incomplete
  • searchable history of who has played campus before, so repeats are obvious before anyone books them again

access

sign-in is limited to the bookings team. the page and every api route check the same permission, so a session that is not on the team gets nothing back.

technical details

  • next.js app router frontend in typescript and react, styled with tailwind
  • separate express api in typescript, with request validation and auth on every route
  • artist records, quotes, agencies, shortlist, and lineup slots persist in a database
  • quotes store a year plus an optional min and max, so a range, an exact number, or no price can all live on the same record
  • lineup builder is drag and drop: starred artists move into festival slots, occupied slots swap, and the running total uses the midpoint of complete quote ranges
  • history matching uses normalized names and explicit aliases, not substrings, so a warning only fires on a real repeat
  • listener counts refresh from a script against existing catalog rows, and newer manual numbers are left alone
  • the original spreadsheet catalog is merged into the database once per version so custom records and shortlist picks survive an import