Skip to content
All projects
Frontend2022

Dashboards that made AI output reviewable

React and Next.js dashboards surfacing AI metrics and generated responses for client decision-making — increasing engagement 28% by making the model's work inspectable rather than opaque.

Role
Senior Full Stack Engineer · Scorch iProspect
Stack
ReactNext.jsTypeScriptData visualisationGraphQL
  • 28% increase in client engagement with the platform
  • AI-generated responses reviewable and editable before publishing
  • Sentiment and volume trends readable at a glance, drillable on demand

The problem

Clients were paying for AI-driven reputation work and receiving a monthly PDF. The system knew far more than the PDF said — sentiment trends, response latency, which locations were dragging an average down — and none of it was reachable without asking someone.

The engagement problem and the trust problem turned out to be the same problem. People don't act on numbers they can't interrogate, and they don't trust AI output they can't see before it goes out.

What the interface had to do

Three jobs, in priority order:

  1. Answer "is this working?" in one glance. Sentiment and volume over time, with the current period compared against the last.
  2. Let someone drill into why. Every aggregate is a way into the underlying reviews — by location, by platform, by sentiment band.
  3. Put the AI's output under human review. Generated responses shown before publishing, editable in place, with the review they answer beside them.

That third one drove the engagement number more than the charts did. Giving people approval over the model's work is what turned the dashboard from a report into somewhere they had a reason to be.

Keeping it quick with real data

Aggregates over a year of reviews across dozens of locations are not something to compute in the browser. The pattern that held up:

// The expensive rollup is computed server-side and arrives finished.
// The chart is a client island because it needs pointer events — not
// because it needs the ability to fetch.
export default async function OverviewPage({ params }: Props) {
  const { accountId } = await params;
 
  const [trend, pending] = await Promise.all([
    getSentimentTrend(accountId),      // pre-aggregated, cached per account
    getPendingResponses(accountId),    // small, always fresh
  ]);
 
  return (
    <>
      <SentimentChart data={trend} />
      <ResponseQueue items={pending} />
    </>
  );
}

Details that carried weight

  • Empty and loading states designed, not defaulted. A new account sees an explanation of what will appear, not an empty grid.
  • Stale sources labelled. When an upstream platform is behind, the affected figure says so rather than quietly under-reporting.
  • Keyboard-navigable review queue. The people using this move through dozens of items in a sitting; reaching for the mouse each time is a tax on the workflow the product depends on.

Outcome

Client engagement with the platform rose 28%. The reason, as far as I can tell from how the product was actually used: the dashboard stopped being a place to confirm the work happened and became the place the work got done.