Backlinks — UI
Backlinks surface in three portals. The dashboard gives clients a unified view of all backlink types (outreach + opportunities) and lets them self-serve directory submissions. The DM portal manages outreach campaigns and reviews opportunities. The Manage portal lets superadmins control the directory database.
Dashboard Portal (Client)
Backlinks List
Route: /seo/backlinks
File: apps/dashboard/src/app/(dashboard)/seo/backlinks/
Status: [Live]
Unified list of all Backlink rows for the tenant. Both outreach-type and opportunity-type rows appear here.
Columns: Site, Type badge (Directory / Outreach / Competitor Gap), Category, DR, Link type, Status.
Row click navigates to the detail page. No action buttons on row hover.
Backlink Detail — Outreach Mode (Dashboard)
Route: /seo/backlinks/[id]
File: apps/dashboard/src/app/(dashboard)/seo/backlinks/[id]/BacklinkDetailClient.tsx
Renders when: sourceType === "outreach"
Status: [Live]
Read-only view for the client. Two-column layout:
- Left: Prospect details (domain, targetUrl, anchor text, relevance score, pitch rationale), outreach timeline (Identified → Outreach Sent → Responded → Agreed → Link Live)
- Right: Campaign card with “View Campaign” link; Outreach Email card (subject + body preview, read-only)
Backlink Detail — Opportunity Mode (Dashboard)
Route: /seo/backlinks/[id]
Renders when: sourceType === "directory_opportunity" or "competitor_gap"
Status: [Live]
Two-column layout:
- Left: Submission Steps (numbered list from
steps[]), “Why This Directory” (pitchRationale+ relevance bar), Status & Notes (read-only display) - Right: Directory Info (URL, DR, link type), Completion card (if
completedAtset)
Campaign Detail (Dashboard)
Route: /seo/link-building/[id]
File: apps/dashboard/src/app/(dashboard)/seo/link-building/[id]/LinkBuildingDetailClient.tsx
Status: [Live]
Read-only campaign view for clients. Filter tabs (All / Pending / Sent). Each email card shows subject, body preview (truncated at 6 lines), and an “Edit”/“View” button that navigates to the dedicated per-email page.
Per-Email Edit/Send Page (Dashboard)
Route: /seo/link-building/[id]/emails/[emailId]/edit
File: apps/dashboard/src/app/(dashboard)/seo/link-building/[id]/emails/[emailId]/edit/
Status: [Live]
Dedicated single-email composer. Fields: From (read-only — sender name/email from session), To Name, To Email, Subject, Body (18-row textarea). Actions: “Save Draft” (no navigation) and “Send Email” (saves first, sends via notification infra, redirects to campaign page). All fields disabled when status = "sent". Uses server actions in actions.ts.
DM Portal
Backlinks List
Route: /seo/backlinks
File: apps/dm/src/app/(dm)/seo/backlinks/BacklinksClient.tsx
Status: [Live]
Same unified list as the dashboard. Additional columns: Source type badge, Notes indicator. Type filter dropdown (All / Outreach / Directory / Competitor Gap). Row click → detail page.
Backlink Detail — DM Outreach Mode
Route: /seo/backlinks/[id]
File: apps/dm/src/app/(dm)/seo/backlinks/[id]/BacklinkDetailDMClient.tsx → OutreachDetailDM
Status: [Live]
Two-column editable layout:
| Panel | Content |
|---|---|
| Prospect Details | sourceDomain, sourceUrl, targetUrl, anchorText, relevanceScore, pitchRationale |
| Outreach Timeline | 5-step timeline: Identified → Outreach Sent → Responded → Agreed → Link Live |
| Outreach Email | Subject + body preview; “Edit & Send” link → /seo/link-building/[campaignId]/emails/[emailId] |
| Update Status & Notes | outreachStatus dropdown (prospecting/outreach_sent/responded/agreed/published/rejected/no_response) + notes textarea + Save button |
| Campaign | Campaign name, status, email count; “View Campaign” link |
Backlink Detail — DM Opportunity Mode
Route: /seo/backlinks/[id]
File: apps/dm/src/app/(dm)/seo/backlinks/[id]/BacklinkDetailDMClient.tsx → OpportunityDetailDM
Renders when: sourceType !== "outreach"
Status: [Live]
Two-column layout:
- Left: Submission Steps, Why This Directory (pitchRationale), Update Status & Notes (opportunity statuses only: opportunity/in_progress/completed/not_applicable)
- Right: Directory Info, Completion card, Quick Actions (Mark Complete / Mark N/A / Start Working)
Dispatcher: BacklinkDetailDMClient is a thin wrapper that checks sourceType and renders the correct component — no hooks of its own (avoids hooks-before-return violation).
Campaign Detail (DM)
Route: /seo/link-building/[id]
File: apps/dm/src/app/(dm)/seo/link-building/[id]/LinkBuildingDetailClient.tsx
Status: [Live]
Campaign view with filter tabs (All / Pending / Sent). Matches dashboard design. Each card shows email preview (body truncated at 6 lines) with an “Edit & Send”/“View” button that navigates to the per-email page. No inline editing.
Per-Email Edit/Send Page (DM)
Route: /seo/link-building/[id]/emails/[emailId]
File: apps/dm/src/app/(dm)/seo/link-building/[id]/emails/[emailId]/
Status: [Live]
Dedicated single-email composer. Identical layout to dashboard’s page. Fields: From (read-only — name/email from decoded JWT payload.name/payload.email), To Name, To Email, Subject, Body. Actions: “Save Draft” (PATCH proxy) and “Send Email” (PATCH then POST proxy, redirects on success). All fields disabled when status = "sent".
Send flow: PATCH /api/campaigns/[campaignId]/emails/[emailId] first (saves edits) → POST /api/campaigns/[campaignId]/emails/[emailId]/send (marks sent + triggers notification).
Manage Portal — Directory Management
Route: /directories
File: apps/manage/src/app/(manage)/directories/
Status: [Live]
Superadmin CRUD for the BacklinkDirectory table. Sidebar entry uses Link2 icon.
| Screen | Route | Description |
|---|---|---|
| Directory list | /directories | Stats (total/active/free/dofollow), search by name/URL, DR badge, difficulty badge, link type; row click → detail |
| Add directory | /directories/new | All BacklinkDirectory fields + steps builder + regions multi-select with common presets |
| Edit directory | /directories/[id] | Same form; soft-delete button (sets isActive = false); note: changes do NOT update existing Backlink.steps copies |
Proxy routes: apps/manage/src/app/api/admin/directories/ — POST (create), GET/PATCH/DELETE [id] (single entry). Reads manage_access_token cookie, forwards as Bearer.
Status Badge Colour Scheme
sourceType | Status | Badge colour |
|---|---|---|
directory_opportunity / competitor_gap | opportunity | Cyan |
directory_opportunity / competitor_gap | in_progress | Violet |
directory_opportunity / competitor_gap | completed | Emerald |
directory_opportunity / competitor_gap | not_applicable | Slate (muted) |
outreach | prospecting | Slate |
outreach | outreach_sent | Blue |
outreach | responded | Amber |
outreach | agreed | Violet |
outreach | published | Emerald |
outreach | rejected | Red |
outreach | no_response | Muted |