[PULSE-11] Add Campaigns report to dashboard #6

Merged
uz1mani merged 3 commits from staging into main 2026-02-04 18:46:42 +00:00
uz1mani commented 2026-02-04 18:36:07 +00:00 (Migrated from github.com)

Work Item

PULSE-11

Summary

Added a new "Campaigns" section to the site dashboard to visualize marketing performance based on UTM parameters.

Changes

  • UI: Created Campaigns component to display a list of campaigns (Source, Medium, Campaign) with visitor counts.
  • Dashboard: Integrated the Campaigns component into the main site dashboard (/sites/[id]).
  • API Client: Added getCampaigns function to fetch data from the new backend endpoint.
  • UX: Added a helpful empty state with instructions on how to use UTM parameters when no data is available.

Test Plan

[ ] Visit a site dashboard with existing campaign data and verify the table renders correctly.
[ ] Visit a site dashboard with NO campaign data and verify the empty state (megaphone icon + instructions) appears.
[ ] Click "View All" (if enough data exists) to verify the modal opens and displays the full list.

## Work Item PULSE-11 ## Summary Added a new "Campaigns" section to the site dashboard to visualize marketing performance based on UTM parameters. ## Changes - **UI:** Created `Campaigns` component to display a list of campaigns (Source, Medium, Campaign) with visitor counts. - **Dashboard:** Integrated the `Campaigns` component into the main site dashboard (`/sites/[id]`). - **API Client:** Added `getCampaigns` function to fetch data from the new backend endpoint. - **UX:** Added a helpful empty state with instructions on how to use UTM parameters when no data is available. ## Test Plan [ ] Visit a site dashboard with existing campaign data and verify the table renders correctly. [ ] Visit a site dashboard with NO campaign data and verify the empty state (megaphone icon + instructions) appears. [ ] Click "View All" (if enough data exists) to verify the modal opens and displays the full list.
greptile-apps[bot] commented 2026-02-04 18:38:23 +00:00 (Migrated from github.com)

Greptile Overview

Greptile Summary

This PR adds a new Campaigns section to the site dashboard for tracking marketing performance via UTM parameters (utm_source, utm_medium, utm_campaign).

Key Changes:

  • Created Campaigns component displaying campaign statistics in a table format with source, medium, campaign name, and visitor counts
  • Added getCampaigns() and getPublicCampaigns() API functions following existing patterns in the codebase
  • Integrated the component into the main dashboard page between TechSpecs and GoalStats sections
  • Included helpful empty state with icon, instructions, and documentation link when no campaign data exists

Implementation Quality:
The implementation follows established patterns from similar components like TopReferrers and ContentStats. The component properly handles loading states, modal views for expanded data, and gracefully displays an informative empty state with user guidance.

Confidence Score: 4.5/5

  • This PR is safe to merge with minimal risk
  • The implementation follows existing codebase patterns consistently and adds a well-structured feature. The code quality is good with proper TypeScript typing, error handling, and user experience considerations including loading states and empty states. A previous review comment about modal data fetching was already addressed by implementing the standard pattern of fetching more records (limit=100) in the modal versus initial load (limit=10).
  • No files require special attention

Important Files Changed

Filename Overview
components/dashboard/Campaigns.tsx New component displaying campaign statistics with UTM parameter data; includes modal view and helpful empty state guidance
lib/api/stats.ts Added getCampaigns and getPublicCampaigns API functions with proper TypeScript typing and URLSearchParams handling
app/sites/[id]/page.tsx Integrated Campaigns component into dashboard layout between TechSpecs and GoalStats sections

Sequence Diagram

sequenceDiagram
    participant User
    participant Dashboard as SiteDashboardPage
    participant Campaigns as Campaigns Component
    participant API as stats.ts API Client
    participant Backend as Backend API

    User->>Dashboard: Navigate to /sites/[id]
    Dashboard->>Campaigns: Render <Campaigns siteId dateRange />
    
    activate Campaigns
    Campaigns->>API: getCampaigns(siteId, start, end, 10)
    API->>Backend: GET /sites/{siteId}/campaigns?start_date&end_date&limit=10
    Backend-->>API: { campaigns: CampaignStat[] }
    API-->>Campaigns: CampaignStat[]
    Campaigns->>Campaigns: setData(result)
    Campaigns-->>User: Display campaign table or empty state
    deactivate Campaigns

    opt User clicks "View All"
    User->>Campaigns: Click "View All" button
    Campaigns->>Campaigns: setIsModalOpen(true)
    activate Campaigns
    Campaigns->>API: getCampaigns(siteId, start, end, 100)
    API->>Backend: GET /sites/{siteId}/campaigns?start_date&end_date&limit=100
    Backend-->>API: { campaigns: CampaignStat[] }
    API-->>Campaigns: CampaignStat[]
    Campaigns->>Campaigns: setFullData(result)
    Campaigns-->>User: Display modal with full data
    deactivate Campaigns
    end
<h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR adds a new Campaigns section to the site dashboard for tracking marketing performance via UTM parameters (`utm_source`, `utm_medium`, `utm_campaign`). **Key Changes:** - Created `Campaigns` component displaying campaign statistics in a table format with source, medium, campaign name, and visitor counts - Added `getCampaigns()` and `getPublicCampaigns()` API functions following existing patterns in the codebase - Integrated the component into the main dashboard page between TechSpecs and GoalStats sections - Included helpful empty state with icon, instructions, and documentation link when no campaign data exists **Implementation Quality:** The implementation follows established patterns from similar components like `TopReferrers` and `ContentStats`. The component properly handles loading states, modal views for expanded data, and gracefully displays an informative empty state with user guidance. <h3>Confidence Score: 4.5/5</h3> - This PR is safe to merge with minimal risk - The implementation follows existing codebase patterns consistently and adds a well-structured feature. The code quality is good with proper TypeScript typing, error handling, and user experience considerations including loading states and empty states. A previous review comment about modal data fetching was already addressed by implementing the standard pattern of fetching more records (limit=100) in the modal versus initial load (limit=10). - No files require special attention <details><summary><h3>Important Files Changed</h3></summary> | Filename | Overview | |----------|----------| | components/dashboard/Campaigns.tsx | New component displaying campaign statistics with UTM parameter data; includes modal view and helpful empty state guidance | | lib/api/stats.ts | Added `getCampaigns` and `getPublicCampaigns` API functions with proper TypeScript typing and URLSearchParams handling | | app/sites/[id]/page.tsx | Integrated Campaigns component into dashboard layout between TechSpecs and GoalStats sections | </details> </details> <h3>Sequence Diagram</h3> ```mermaid sequenceDiagram participant User participant Dashboard as SiteDashboardPage participant Campaigns as Campaigns Component participant API as stats.ts API Client participant Backend as Backend API User->>Dashboard: Navigate to /sites/[id] Dashboard->>Campaigns: Render <Campaigns siteId dateRange /> activate Campaigns Campaigns->>API: getCampaigns(siteId, start, end, 10) API->>Backend: GET /sites/{siteId}/campaigns?start_date&end_date&limit=10 Backend-->>API: { campaigns: CampaignStat[] } API-->>Campaigns: CampaignStat[] Campaigns->>Campaigns: setData(result) Campaigns-->>User: Display campaign table or empty state deactivate Campaigns opt User clicks "View All" User->>Campaigns: Click "View All" button Campaigns->>Campaigns: setIsModalOpen(true) activate Campaigns Campaigns->>API: getCampaigns(siteId, start, end, 100) API->>Backend: GET /sites/{siteId}/campaigns?start_date&end_date&limit=100 Backend-->>API: { campaigns: CampaignStat[] } API-->>Campaigns: CampaignStat[] Campaigns->>Campaigns: setFullData(result) Campaigns-->>User: Display modal with full data deactivate Campaigns end ```
greptile-apps[bot] (Migrated from github.com) reviewed 2026-02-04 18:38:28 +00:00
greptile-apps[bot] (Migrated from github.com) left a comment

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

<sub>3 files reviewed, 1 comment</sub> <sub>[Edit Code Review Agent Settings](https://app.greptile.com/review/github) | [Greptile](https://greptile.com?utm_source=greptile_expert&utm_medium=github&utm_campaign=code_reviews)</sub>
@@ -0,0 +53,4 @@
} else {
setFullData([])
}
}, [isModalOpen, siteId, dateRange])
greptile-apps[bot] (Migrated from github.com) commented 2026-02-04 18:38:27 +00:00

The modal fetches the same data that's already loaded in data. Either reuse the existing data state, or if you need to fetch more records (with a higher limit), modify getCampaigns to accept a limit parameter like other API functions in the codebase (getTopReferrers, getTopPages, etc.).

Prompt To Fix With AI
This is a comment left during a code review.
Path: components/dashboard/Campaigns.tsx
Line: 39:56

Comment:
The modal fetches the same data that's already loaded in `data`. Either reuse the existing `data` state, or if you need to fetch more records (with a higher limit), modify `getCampaigns` to accept a `limit` parameter like other API functions in the codebase (`getTopReferrers`, `getTopPages`, etc.).

How can I resolve this? If you propose a fix, please make it concise.
The modal fetches the same data that's already loaded in `data`. Either reuse the existing `data` state, or if you need to fetch more records (with a higher limit), modify `getCampaigns` to accept a `limit` parameter like other API functions in the codebase (`getTopReferrers`, `getTopPages`, etc.). <details><summary>Prompt To Fix With AI</summary> `````markdown This is a comment left during a code review. Path: components/dashboard/Campaigns.tsx Line: 39:56 Comment: The modal fetches the same data that's already loaded in `data`. Either reuse the existing `data` state, or if you need to fetch more records (with a higher limit), modify `getCampaigns` to accept a `limit` parameter like other API functions in the codebase (`getTopReferrers`, `getTopPages`, etc.). How can I resolve this? If you propose a fix, please make it concise. ````` </details>
Sign in to join this conversation.
No description provided.