Skip to content

[Feature] Inbox Management — Connect Email Accounts & Build Unified Inbox UI #11

@hasnaintypes

Description

@hasnaintypes

Overview

The inboxes table is defined in the schema but there is no UI or backend logic to connect, manage, or monitor email sending accounts. Inboxes are a core primitive — campaigns can't send without them. This issue covers both the Convex backend and the full /inboxes UI.


Current State

  • convex/inboxes/schema.ts — table defined, no queries or mutations
  • No /inboxes route exists
  • Campaign creation form has no inbox selector
  • No inbox health/status tracking

Tasks

1. Convex Backend (Queries & Mutations)

  • convex/inboxes/queries.ts
    • list — returns all inboxes for the current user, ordered by createdAt
    • get — returns a single inbox by ID (with ownership check)
    • getStats — returns sent count, bounce rate, last-sent timestamp per inbox
  • convex/inboxes/mutations.ts
    • create — creates a new inbox record (SMTP/IMAP credentials stored encrypted, or OAuth token reference)
    • update — update display name, daily send limit, reply-to address
    • remove — soft-delete with a deletedAt timestamp, disallow if active campaigns reference it
    • setStatus — toggle active | paused | error status
  • convex/inboxes/actions.ts
    • testConnection — sends a test email via the stored credentials to verify connectivity; updates lastTestedAt and connectionStatus

2. /inboxes Page — Inbox List View

  • Create src/app/(auth)/inboxes/page.tsx
  • InboxCard component — shows:
    • Provider logo (Gmail, Outlook, SMTP generic icon)
    • Email address + display name
    • Status badge: active (green) / paused (yellow) / error (red)
    • Daily send limit + emails sent today (progress bar)
    • Last activity timestamp
    • Actions: Edit, Pause/Resume, Test Connection, Remove
  • Empty state with a prominent "Connect your first inbox" CTA
  • Add /inboxes link to the sidebar nav

3. Connect Inbox Flow (Modal/Drawer)

  • ConnectInboxDialog — multi-step drawer:
    • Step 1 — Provider select: Gmail (OAuth), Outlook (OAuth), Custom SMTP
    • Step 2 — Credentials: For SMTP: host, port, username, password, TLS toggle. For OAuth: redirect to provider.
    • Step 3 — Settings: Display name, daily send limit (default 50), reply-to address, warmup mode toggle
    • Step 4 — Verify: Trigger testConnection action and show result before saving
  • Form validation with inline errors (no submission until connection test passes)
  • Framer Motion slide transitions between steps (consistent with NewCampaignForm pattern)

4. Inbox Detail & Edit

  • EditInboxSheet — side sheet (not full page) for editing an existing inbox
    • Editable: display name, reply-to, daily limit, warmup toggle
    • Read-only: email address, provider, connected date
    • Danger zone: Remove inbox (confirmation dialog, warns if used in active campaigns)

5. Wire Inbox into Campaign Creation

  • Add inbox selector step to NewCampaignForm — shows connected inboxes with status badges
  • Disable campaign creation if user has zero active inboxes; show inline prompt to connect one
  • Store selected inboxId on the campaign record when creating

Acceptance Criteria

  • User can connect a custom SMTP inbox end-to-end (credentials → test → save)
  • Connected inboxes appear on /inboxes with live status and send stats
  • User can pause, resume, and delete inboxes
  • Deleting an inbox used by an active campaign is blocked with an error message
  • Campaign creation requires an inbox to be selected
  • All inbox credential fields are never returned in queries (backend strips them)

Design Notes

  • Follow the same two-panel / framer-motion step pattern used in NewCampaignForm
  • Use Sheet (not Dialog) for the edit flow — it's less disruptive for a settings-like surface
  • Status badges and progress bars should use the existing shadcn Badge and Progress components
  • Keep provider logos as simple SVG icons, not third-party image CDN URLs

References

  • convex/inboxes/schema.ts — existing table definition
  • convex/campaigns/schema.ts — campaigns reference inboxId
  • src/components/pages/(auth)/campaigns/new/NewCampaignForm.tsx — step pattern to follow
  • src/app/(auth)/campaigns/layout.tsx — layout pattern for new auth route

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions