Skip to content

feat(campaigns): integrate sequences frontend with create/edit/detail UI#147

Merged
anujeet98 merged 10 commits into
mainfrom
feat/integrate-sequences-for-fe
Jun 3, 2026
Merged

feat(campaigns): integrate sequences frontend with create/edit/detail UI#147
anujeet98 merged 10 commits into
mainfrom
feat/integrate-sequences-for-fe

Conversation

@Rishavraaj

Copy link
Copy Markdown
Contributor

Summary

Integrates the frontend for Apollo sequence management, building on the backend added in #146. Adds a full Campaigns section to the app — list,
create, detail, and edit — all wired to the existing /integrations/apollo/sequences API.

What's new

Frontend

  • Campaigns nav item — added to the sidebar between ICPs and Tasks (EnvelopeIcon)
  • /campaigns list page — infinite-scroll table showing all Apollo sequences (active + inactive) with columns: Name, Status, Steps, Open
    Rate, Reply Rate, Delivered, Created. Includes search, a manual refresh button, and inline Approve / Deactivate actions per row
  • Create Sheet — "New Campaign" opens a right-side Sheet with a sequence builder: campaign name, permissions, email schedule selector, and one
    or more step cards (type, wait time/unit, email subject + HTML body). Steps can be added or removed dynamically
  • /campaigns/[id] detail page — shows Apollo stats (Steps, Open Rate, Reply Rate, Delivered), Approve / Deactivate buttons, and a read-only
    step list with email body preview
  • Edit Sheet — the Edit button on the detail page opens the same sequence builder pre-filled from the Zuko DB record, preserving Apollo
    step/touch/template IDs so updates patch existing steps rather than recreating them
  • getZukoCampaign query option — new React Query option that fetches the stored Zuko campaign (with IDs) for edit pre-fill

Backend fixes

  • buildSequenceSteps — added ?? [] null safety on emailer_steps, emailer_touches, and emailer_templates in case the Apollo MCP response
    omits any of them
  • createSequence — guarded the DB upsert behind result?.emailer_campaign?.id so a partial MCP response doesn't crash the endpoint; sequence is
    still created in Apollo regardless
  • searchSequences — added q_active: false so inactive (draft) sequences are included in list results

How to test

  1. Navigate to Campaigns in the sidebar
  2. Click New Campaign → fill in name, add a step with subject + body → Create Campaign → campaign appears in the list within ~3 seconds
  3. Click Approve on an inactive campaign → status badge turns green
  4. Click a campaign row → detail page shows stats and step preview
  5. Click Edit → Sheet opens pre-filled → modify email body → Save Changes → detail page reflects the update
  6. Click Deactivate on an active campaign → status badge turns grey

Rishavraaj and others added 8 commits June 2, 2026 16:18
- Add Campaigns nav item to sidebar
- Add campaigns list page with infinite scroll, search, approve/deactivate actions
- Add campaign create Sheet with sequence builder (steps + email templates)
- Add campaign detail page with stats, step preview, approve/deactivate buttons
- Add campaign edit Sheet pre-filled from Zuko DB (preserves Apollo step IDs)
- Fix buildSequenceSteps null safety for missing emailer_steps/touches/templates
- Fix createSequence null safety for missing emailer_campaign in MCP response
- Include inactive sequences in search (q_active: false)
- Add getZukoCampaign query option for fetching stored campaign with step IDs

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Full-page editor layout matching the Apollo UI design
- Step cards with Auto/Manual Email toggle, inline wait time inputs,
  subject/body fields, variable chips ({{first_name}}, {{company}}, etc.),
  and Switch toggles for include signature, approved, AI personalised opener
- Editor/Analytics tab split: editor shows step builder + settings sidebar,
  analytics shows stat grid (open rate, reply rate, bounce, click, opt-out)
- Right sidebar: ACCESS permissions dropdown + CAMPAIGN DETAILS stats panel
- Update Campaign button saves all step changes in-place via Apollo update API
- Prefetch both Apollo and Zuko campaign data on page load
- Extend ApolloSequence type with additional stat fields for analytics tab

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Rename /campaigns/new → /campaigns/add
- Navigate to /campaigns/add on "New Campaign" click instead of opening a Sheet
- Remove Sheet/CampaignForm import from CampaignsList
- Swap EnvelopeIcon for MegaphoneIcon in sidebar nav and empty state

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace old FieldGroup layout with Apollo-style inline editor matching CampaignDetail
- Editable heading input, step cards with segmented type toggle, variable chips, Switch toggles
- Use ui-kit Field/Label/Input/Textarea/ErrorMessage for all form fields
- Add validation for subject and body per step with inline error display
- Fix post-create navigation to seed query cache and redirect to detail page
- Add stable step keys, fix a11y label associations, use cn for dynamic classes
- Fix resizable prop warning by using [&_textarea]:resize-none CSS selector

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…invalid on controls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
const approveMutation = useMutation({
mutationFn: (id: string) => apolloSequencesApi.approve(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['campaigns', 'infinite'] });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

missing search in the key

const deactivateMutation = useMutation({
mutationFn: (id: string) => apolloSequencesApi.deactivate(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ['campaigns', 'infinite'] });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same, missing search param in the key

}
}

const EditCampaignPage = async ({ params }: EditCampaignPageProps) => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This edit page is not needed I guess, as we are already showing edit inside the details page.

disabled: boolean;
}

function StepCard({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move all the reusable components as a separate component and reuse it in CampaignForm to avoid code duplication

};
}

function formatRate(value: number | string): string {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this to a common util and reuse it in campaignList.

Rishavraaj and others added 2 commits June 3, 2026 14:03
…mments

- Extract StepFormState, StepCard, VariableChips, formatRate, helpers
  into campaign-shared.tsx to eliminate duplication between CampaignDetail
  and CampaignForm
- Remove edit page as editing is inline on the detail page
- Fix mutation invalidation keys to include search param in CampaignsList
- Add Apollo API usage stats endpoint (backend + frontend)
- Show Apollo API usage stats card in org connections settings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@anujeet98 anujeet98 merged commit 809e4b2 into main Jun 3, 2026
2 of 3 checks passed
@anujeet98 anujeet98 deleted the feat/integrate-sequences-for-fe branch June 3, 2026 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants