← Back to featured work

Role · Lead developer Status · In production

Campaign Manager

Casino marketing ops from planning calendar to Snowflake in one place. A year of campaigns on one dashboard.

60 campaigns a year from one dashboard

Built with React · Vite · Tailwind · Express · Node.js · Snowflake

Campaign Manager monthly drop calendar

The problem

Casino marketing runs twelve to fifteen campaign types in parallel, each with its own tier structure, offer matrix, email cadence, and voyage list. The team was stitching that together across spreadsheets, shared calendars, and a PowerPoint-style creative brief for every drop. Things slipped. Tiers drifted between the brief and the matrix. An email got scheduled against a voyage that had already sold out. The only way to see the whole year was to open four tools and a printed calendar.

What I built

Campaign Manager is a single React app that holds the whole year of casino and HOBS campaigns in one dashboard. A planner sees every email drop for a given month at a glance, jumps to any campaign’s creative brief, and confirms the offer matrix lines up with the master program data before copy goes to the agency.

Six views carry the day-to-day:

  • Monthly drop calendar with every email plotted on the day it hits the inbox. Color-coded by campaign type so overlaps jump out. Click a drop to open its brief without leaving the calendar.
  • Year-long roadmap as a Gantt-style timeline grouped by campaign type. H1, H2, and Full Year presets for leadership reviews. Casino and HOBS stay separate but plot on one canvas.
  • Campaign roster showing every active campaign with dates, tier count, and email count. Brief, Voyages, and Schedule deep-link into the editor. Filter by type or program, search by campaign code.
  • Drop readiness checklist with one row per email drop across every active campaign. Voyage, URL, RM, and Casino checkboxes drive ready vs pending. Past drops hide by default so the queue stays honest.
  • Per-campaign creative brief with six tabs: overview, emails, offer matrix, deal card, key values, voyages. Replaces the standalone brief doc the agency used to chase. The offer matrix pre-populates from the master program data.
  • Admin configuration where campaign types are editable with cat code, prefix, tier count, and color. A CSV paste importer previews data before it lands. Password-gated so planners can view without accidentally editing.

Built on React 18 with Vite for the frontend, served alongside a thin Express backend that talks to Snowflake via the official SDK with external-browser SSO. State lives in memory on the frontend and pushes to Snowflake on save via a MERGE upsert per table: campaigns, emails, offer matrix rows, voyages. No queue, no ORM, no auth service. The whole thing is one App.jsx plus server/index.js, and the UI runs against sample data when the backend is not connected.

Outcome

Built for the two-person casino campaign operations team that owns roughly sixty campaigns a year. The roadmap view is the artifact that goes into leadership reviews. The Snowflake save path means campaign state outlives any one laptop. Briefs, matrices, and calendar now share a single source of truth, so the tier-mismatch and sold-out-voyage surprises that used to surface at the agency hand-off do not surface anymore.

What’s next

  • Read-only access for upstream teams (creative, merch, agency partners) so they pull briefs from the dashboard instead of chasing them by email.
  • Drop-readiness checklist pushed into Teams so signoffs happen where the team already works.
  • Brief pre-screened against brand guidelines using the same pluggable checks the Marketing Check Tool runs, so an agency hand-off lands clean the first time.