Skip to Content
InsightsInsights — UI Screens

Insights — UI Screens

Status: [To Build] App: apps/dashboard Auth: Tenant-scoped


Add to the persistent left sidebar in apps/dashboard/src/app/(dashboard)/layout.tsx:

RouteLabelIconPosition
/insightsInsightsSparkles (lucide-react)After /channels

Screen I1 — Insights List

Route: /insights Purpose: Overview of all generated insights across all connected channels for the tenant.

  • Title: “Insights”
  • Subtitle: “AI-powered analysis of your connected channel data”
  • Right side: “Last refreshed: {relative time}” + Refresh All button (triggers generation for all connected channels)

Channel Filter Strip

Horizontally scrollable pill buttons:

[ All ] [ GSC ] [ Google Analytics ] [ Google Ads ] [ Meta Ads ] [ Facebook ] [ Instagram ] [ LinkedIn ] [ GBP ]

Selecting a pill filters the card grid below.

Insights Card Grid

Responsive grid — 2 columns desktop, 1 column mobile. One card per connected channel, showing the most recent insight.

Insight Card (normal state)

┌──────────────────────────────────────────────────┐ │ [Channel icon] Google Search Console │ │ Last generated: 3 days ago │ │ │ │ ✓ 3 Strengths ✗ 2 Weaknesses │ │ ◆ 4 Opportunities → 5 Recommendations │ │ │ │ [View Insights] [Regenerate] │ └──────────────────────────────────────────────────┘

Insight Card (generating state)

┌──────────────────────────────────────────────────┐ │ [Channel icon] Google Analytics │ │ ⟳ Generating insights... │ │ │ │ [────────────] [──────────────] │ ← skeleton bars │ [─────────────────────────────] │ └──────────────────────────────────────────────────┘

Insight Card (failed state)

┌──────────────────────────────────────────────────┐ │ [Channel icon] Google Ads │ │ ⚠ Generation failed │ │ │ │ Could not fetch data from Google Ads. │ │ │ │ [Retry] │ └──────────────────────────────────────────────────┘

Insight Card (no insight yet)

┌──────────────────────────────────────────────────┐ │ [Channel icon] LinkedIn │ │ No insights yet │ │ │ │ Generate your first insight to see │ │ AI-powered analysis of this channel. │ │ │ │ [Generate Insights] │ └──────────────────────────────────────────────────┘

Empty State (no channels connected)

┌────────────────────────────────────────────────────────┐ │ [Sparkles icon — large] │ │ No channels connected │ │ │ │ Connect a channel to start generating insights │ │ from your marketing data. │ │ │ │ [Connect a Channel →] │ └────────────────────────────────────────────────────────┘

The button links to /channels.


Screen I2 — Insight Detail

Route: /insights/[insightId] Purpose: Full insight report for a single channel and period.

Insights › Google Search Console [GSC icon] Google Search Console Period: Last 6 months · Generated: Apr 13, 2026 [Regenerate]

Period Selector

Segmented control (top right of content area):

[ 3 months ] [ 6 months ✓ ] [ 12 months ]

Changing the period triggers POST /tenant/v1/insights/generate with the new period value. The detail view transitions to the generating skeleton while the new insight is processed.

Insight Sections

Four stacked card groups, each expandable. All items are expanded by default.

Strengths (green accent)

┌── ✓ Strong branded keyword performance ─────────────────────────────┐ │ "acme plumbing" and "acme services" hold positions 1.2 and 1.4 │ │ with CTRs of 18% and 15% — well above the 3% average for │ │ branded terms. │ └──────────────────────────────────────────────────────────────────────┘ ┌── ✓ Organic impressions up 22% period-over-period ──────────────────┐ │ ... │ └──────────────────────────────────────────────────────────────────────┘

Weaknesses (amber accent)

┌── ✗ High-impression queries with poor CTR ──────────────────────────┐ │ "emergency plumber sydney" receives 4,200 impressions/month │ │ but only a 0.8% CTR from position 7. A meta title update │ │ could double click volume. │ └──────────────────────────────────────────────────────────────────────┘

Opportunities (blue accent)

┌── ◆ 12 keywords sitting in positions 4–10 ──────────────────────────┐ │ These are within 1–2 optimisation cycles of page 1. Combined │ │ they represent ~800 additional clicks/month if moved up. │ └──────────────────────────────────────────────────────────────────────┘

Recommendations (purple accent, with priority badge)

┌── [HIGH] Update meta title on /services/emergency ─────────────────┐ │ Improve CTR from 0.8% toward the 3% benchmark on │ │ "emergency plumber sydney" (4,200 impressions/month, pos. 7). │ └──────────────────────────────────────────────────────────────────────┘ ┌── [MED] Add FAQ schema to top 5 ranking pages ────────────────────┐ │ ... │ └──────────────────────────────────────────────────────────────────────┘ ┌── [LOW] Publish a dedicated page for "plumber north sydney" ──────┐ │ ... │ └──────────────────────────────────────────────────────────────────────┘

Priority badge colours: HIGH = red, MED = amber, LOW = grey.

Summary Section

Full-width card with a subtle background, rendered as markdown.

┌─ Analyst Summary ────────────────────────────────────────────────────┐ │ │ │ Your Google Search Console performance over the past 6 months │ │ shows strong branded visibility but a clear opportunity in │ │ non-branded local terms... │ │ │ │ [2–4 paragraphs of markdown narrative] │ │ │ └───────────────────────────────────────────────────────────────────────┘

Screen I3 — Channel Detail: Insights Tab

Route: /channels/[id] → Insights tab Purpose: Embeds the latest insight for this specific channel directly within the channel detail view.

Tab Strip Addition

Add “Insights” to the existing tab strip on the channel detail page:

Overview | Analytics | Insights | Settings

Tab States

No insight yet:

┌─────────────────────────────────────────────────────────────┐ │ [Sparkles icon] │ │ No insights generated yet │ │ │ │ Get AI-powered analysis of your last 6 months of data. │ │ │ │ [Generate Insights] │ └─────────────────────────────────────────────────────────────┘

Generating:

⟳ Generating insights, this may take up to a minute... [skeleton card rows]

Done: Renders the same 4-section card layout as Screen I2 (strengths / weaknesses / opportunities / recommendations + summary), with:

  • Period selector (3 / 6 / 12 months) in the top right
  • “View full report” link → /insights/[insightId]

Failed:

⚠ Failed to generate insights [errorMessage text] [Retry]

Real-Time Updates

When the agent worker emits insight:completed via publishAgentEvent():

  • The generating skeleton on Screen I1 and Screen I3 replaces itself with the populated insight cards — no page refresh
  • The generatedAt timestamp on the I1 card updates
  • Uses the existing Socket.io connection in the dashboard’s SocketProvider

Event payload delivered to the client:

{ event: "insight:completed", insightId: string; connectedChannelId: string; channelType: string; status: "done" | "failed"; }

The dashboard fetches the full insight by insightId on receipt of this event.

© 2026 Leadmetrics — Internal use only