Work / Lead generation Stato portal

Case study · Operations platforms

Lead generation Stato portal.

The system Lead Generation runs on. Clients, campaigns, lead delivery, buyer caps and pricing, ad spend, invoices, creatives, agreements and team tasks, in one place.

React 19 + ViteTailwind CSSNode.js / Express 5PostgreSQL (Drizzle)BullMQ + Redis
Lead generation Stato portal
The problem

What needed solving.

Running lead generation for many buyers meant juggling LeadByte, ad accounts, Xero and spreadsheets. Nobody could see revenue, ad spend and profit side by side, or which buyer was near their cap.

Who uses it
  • The owner, who watches revenue, spend and profit
  • Finance, who raise and chase invoices and reconcile the bank feed
  • Operations, who manage campaigns, buyers, rejections, creatives and tasks
Walkthrough

The software, screen by screen.

Every screen here is the real software, run on its own throwaway local database with made-up demo records (Demo Buyer Ltd, Demo Skips Ltd, Test Lead 01 and so on, example.com emails, ZZ postcodes and reserved 07700 900 test numbers). All outside services were blocked. Every figure is demo data, not a real price, spend or invoice.

Desktop · 1440pxDashboard at desktop width
Mobile · 390pxDashboard at mobile width
Demo data Dashboard. Revenue for the month, active clients and campaigns, leads this month, ad spend across Meta and Google, net profit and margin, plus revenue and lead charts.
Desktop · 1440pxCampaign detail at desktop width
Mobile · 390pxCampaign detail at mobile width
Demo data Campaign detail. Revenue, profit and margin for one campaign, today to all time, with cost per lead, buyers and their caps, and daily lead volume.
Desktop · 1440pxClients at desktop width
Mobile · 390pxClients at mobile width
Demo data Clients. Every client with contact, status, agreement and document flags, credit, campaigns and revenue, with filters and CSV export.
Desktop · 1440pxInvoices at desktop width
Mobile · 390pxInvoices at mobile width
Demo data Invoices. Draft, authorised and paid invoices synced with Xero, with overdue chasing and auto-invoicing runs.
Desktop · 1440pxAd accounts at desktop width
Mobile · 390pxAd accounts at mobile width
Demo data Ad accounts. Meta and Google ad accounts linked to clients and campaigns, with a warning when spend is not linked to anyone.
Desktop · 1440pxLead rejections at desktop width
Mobile · 390pxLead rejections at mobile width
Demo data Lead rejections. Rejection requests raised by buyers in their portal, reviewed and accepted or declined here.
Desktop · 1440pxCreatives at desktop width
Mobile · 390pxCreatives at mobile width
Demo data Creatives. Every ad image, video and landing page, by client, platform and campaign, with an approval flow.
Desktop · 1440pxTasks at desktop width
Mobile · 390pxTasks at mobile width
Demo data Tasks. Team tasks with owners, priorities and due dates, alongside SOPs, staff, workflows and an org chart.
How it works

Workflows, integrations and stack.

Workflows & automations

  • Leads from LeadByte are recorded against buyers and campaigns, with delivery prices and price history
  • Buyer caps and pinned deliveries per client
  • Ad spend synced daily from Meta and Google and matched to clients
  • Profit and margin worked out from revenue and spend
  • Auto-invoice runs and overdue chasing through Xero, plus a bank feed
  • Agreements built from templates and sent for signature
  • Workflows, tasks and SOPs for the team
  • Background jobs on a queue, so slow work never blocks the screen

Integrations

  • LeadByte
  • Xero
  • Meta and Google Ads
  • Resend (email)
  • Companies House and credit checks

Tech stack

  • React 19, Vite and Tailwind CSS
  • Express 5 REST API in TypeScript
  • PostgreSQL with Drizzle ORM
  • BullMQ and Redis for background jobs
  • JWT with role-based access (owner, finance, operations, client)

How it was built and tested

  • Built in reviewed pull requests, with staging before production
  • Automated tests with Vitest
  • Every change gets a UX check at 390px and 1440px in Chromium and WebKit, with synthetic test data
  • A backup and rollback plan before every database change
Results

Outcomes

Results for this project will be published once the figures have been checked against our own data.

Next case study

Client portal

Read it →

Got a project in mind?

Tell us what you need to run better. We'll come back with how we'd build it.

Start a project →