Specifications
RankFlow AI — Admin Dashboard UI Specifications
│ Admin Shell (src/app/(admin)/layout.tsx) │
docs/specs/admin-dashboard-ui.mdOn this page
- 1. Layout Architecture
- Shell Components
- 2. Route Map
- 3. Page Specifications
- 3.1 /admin — KPI Overview
- 3.2 /admin/clients — Client List
- 3.3 /admin/clients/[id] — Client Detail
- 3.4 /admin/directory — Directory Overview
- 3.5 /admin/directory-profiles — Profile Management
- 3.6 /admin/directory-profiles/[id] — Profile Detail
- 3.7 /admin/social-connections — Social Accounts
- 3.8 /admin/jobs — Job Monitor
- 3.9 /admin/content — AI Content Review
- 3.10 /admin/billing — Billing Overview
- 3.11 /admin/reports — System Reports
- 4. Component Hierarchy
- Reusable Admin Components
- 5. Data Requirements
- tRPC Queries per Page
- 6. Access Control
- Role Gate
- API Protection
- Impersonation
- 7. Responsive Behavior
- Mobile Adaptations
Version: 1.1.0
Route Prefix: /admin
Auth Required: ADMIN role only
Layout: Admin shell with sidebar navigation
Status: Post-Pivot (Directory Model)
1. Layout Architecture#
┌─────────────────────────────────────────────────────────────┐
│ Admin Shell (src/app/(admin)/layout.tsx) │
│ ┌──────────┐ ┌─────────────────────────────────────────┐ │
│ │ Sidebar │ │ Header Bar │ │
│ │ │ │ ───────────────────────────────────── │ │
│ │ • KPI │ │ │ │
│ │ • Clients│ │ Main Content Area │ │
│ │ • Directory│ │ (page-specific) │ │
│ │ • Profiles│ │ │ │
│ │ • Social │ │ │ │
│ │ • Jobs │ │ │ │
│ │ • Content│ │ │ │
│ │ • Billing│ │ │ │
│ │ • Reports│ │ │ │
│ └──────────┘ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
Shell Components#
| Component | Path | Purpose |
|---|---|---|
AdminLayout |
src/app/(admin)/layout.tsx |
Route group layout, auth gate |
AdminSidebar |
src/components/admin/Sidebar.tsx |
Navigation, collapsible |
AdminHeader |
src/components/admin/Header.tsx |
Breadcrumbs, user menu, notifications |
AdminShell |
src/components/admin/Shell.tsx |
Sidebar + Header wrapper |
2. Route Map#
| Route | Page Component | Primary Data | Skill |
|---|---|---|---|
/admin |
AdminKPIPage |
System KPIs | 39-admin-kpi |
/admin/clients |
ClientListPage |
All practices | 01-practice-onboard |
/admin/clients/[id] |
ClientDetailPage |
Practice + relations | All |
/admin/directory |
DirectoryOverviewPage |
Directory stats, approval queue | 20-directory-mgmt |
/admin/directory-profiles |
DirectoryProfileListPage |
All directory profiles | 20-directory-mgmt |
/admin/directory-profiles/[id] |
DirectoryProfileDetailPage |
Single profile + preview | 20-directory-mgmt |
/admin/social-connections |
SocialConnectionsPage |
All social accounts | 10-social-connect |
/admin/jobs |
JobMonitorPage |
Job queue | 40-admin-job-monitor |
/admin/content |
ContentReviewPage |
AI content queue | 31-prompt-manage |
/admin/billing |
BillingOverviewPage |
Subscriptions, invoices | 36, 37, 38 |
/admin/reports |
SystemReportsPage |
Revenue, churn, costs | 39-admin-kpi |
3. Page Specifications#
3.1 /admin — KPI Overview#
Purpose: System-wide health dashboard for the admin
Layout: Full-width grid of stat cards + charts
Sections:
| Section | Component | Data |
|---|---|---|
| Stat Row | KPICards |
Total clients, MRR, active jobs, citation health |
| Revenue Chart | RevenueChart |
Monthly recurring revenue over 12 months |
| Client Status | ClientStatusChart |
Trial vs Active vs Churned pie chart |
| Job Health | JobHealthChart |
Completed vs Failed vs Running |
| API Costs | ApiCostChart |
Claude, GPT-4o, DataForSEO costs |
| Recent Activity | ActivityFeed |
Last 20 audit log entries |
Data Requirements:
interface AdminKPIs {
totalClients: number;
activeClients: number;
trialClients: number;
churnedClients: number;
mrr: number; // Monthly recurring revenue (INR)
arr: number; // Annual recurring revenue (INR)
activeJobs: number;
failedJobs24h: number;
citationHealth: number; // % verified citations
apiCosts7d: {
claude: number;
openai: number;
dataforseo: number;
serpapi: number;
hyperbrowser: number;
firecrawl: number;
};
recentActivity: AuditLogEntry[];
}
3.2 /admin/clients — Client List#
Purpose: CRUD management of all practices
Layout: Data table with filters + action bar
Table Columns:
| Column | Sortable | Filterable | Width |
|---|---|---|---|
| Name | ✅ | ✅ (search) | 200px |
| Slug | ✅ | ❌ | 150px |
| Type | ✅ | ✅ (dropdown) | 120px |
| Tier | ✅ | ✅ (dropdown) | 120px |
| Status | ✅ | ✅ (dropdown) | 120px |
| Locations | ✅ | ❌ | 100px |
| Created | ✅ | ✅ (date) | 150px |
| Trial Ends | ✅ | ✅ (date) | 150px |
| Actions | ❌ | ❌ | 120px |
Actions per Row:
- View →
/admin/clients/[id] - Edit → Inline modal
- Suspend → Confirmation dialog
- Delete → Confirmation dialog (soft delete)
Bulk Actions:
- Change tier
- Export CSV
- Send email
3.3 /admin/clients/[id] — Client Detail#
Purpose: Deep-dive into a single practice
Layout: Tabbed interface
Tabs:
| Tab | Content | Data |
|---|---|---|
| Overview | Profile card, subscription status, quick stats | Practice + members |
| Locations | Location cards with GBP status | Location[] + GbpLocation[] |
| GBP | Account status, posts, reviews, insights | GbpAccount + GbpPost + Review[] |
| Social | Connected accounts, post history | SocialAccount + SocialPost[] |
| Citations | Directory list, NAP status, screenshots | Citation[] |
| Profile | Directory profile status, URL, views | DirectoryProfile |
| Jobs | All jobs for this practice | Job[] |
| Billing | Invoices, payment history | Invoice[] |
| Audit Log | All actions by this practice | AuditLog[] |
Overview Card:
┌────────────────────────────────────────┐
│ [Logo] Practice Name │
│ Type: Clinic | Tier: Premium │
│ Status: ACTIVE │
│ Members: 3 | Locations: 2 │
│ │
│ [Edit] [Impersonate] [Suspend] │
└────────────────────────────────────────┘
3.4 /admin/directory — Directory Overview#
Purpose: High-level view of the directory health, coverage, and approval queue
Layout: Stat cards + approval queue + charts
Stat Cards (top row):
| Card | Metric | Value |
|---|---|---|
| Total Profiles | Published / Draft / Pending | Count |
| Cities Covered | Unique cities with profiles | Count |
| Specialties | Unique specialties | Count |
| Total Views | Profile views (last 30 days) | Count |
Approval Queue (middle section):
| Column | Description |
|---|---|
| Profile | Doctor/clinic name |
| City | Location |
| Specialty | Medical specialty |
| Submitted | Date/time content was generated |
| Compliance Status | ✅ Pass / ⚠️ Warning / ❌ Failed |
| Actions | Review, Approve, Reject |
Charts (bottom section):
| Chart | Data |
|---|---|
| Profiles by City | Bar chart — top 10 cities by profile count |
| Profiles by Specialty | Pie chart — specialty distribution |
| Views Trend | Line chart — daily profile views over 30 days |
| Approval Queue Trend | Line chart — pending approvals over time |
Filters:
- City dropdown
- Specialty dropdown
- Status multi-select (DRAFT, PENDING_REVIEW, PUBLISHED, PAUSED, ARCHIVED)
- Date range
3.5 /admin/directory-profiles — Profile Management#
Purpose: Manage all directory profiles in a single table
Layout: Data table with filters, bulk actions, and inline editing
Table Columns:
| Column | Description | Sortable | Filterable |
|---|---|---|---|
| Profile | Doctor/clinic name + photo | ✅ | ✅ (search) |
| City | Location (e.g., Kochi) | ✅ | ✅ (dropdown) |
| Specialty | Medical specialty | ✅ | ✅ (dropdown) |
| Status | DRAFT / PENDING_REVIEW / PUBLISHED / PAUSED / ARCHIVED | ✅ | ✅ (dropdown) |
| Views | Profile views (last 30 days) | ✅ | ❌ |
| Compliance | ✅ Pass / ⚠️ Warning / ❌ Failed | ✅ | ✅ (dropdown) |
| Last Updated | Timestamp | ✅ | ✅ (date) |
| Actions | Edit, Preview, Publish, Unpublish | ❌ | ❌ |
Filters:
- Status multi-select
- City dropdown
- Specialty dropdown
- Compliance status
- Date range
- Search (profile name)
Bulk Actions:
- Publish selected
- Unpublish selected
- Refresh content (triggers AI rewrite)
- Export CSV
- Delete (soft delete)
Actions per Row:
- Edit →
/admin/directory-profiles/[id](edit tab) - Preview →
/admin/directory-profiles/[id](preview tab) - Publish → Confirmation + ISR revalidation
- Unpublish → Confirmation + ISR revalidation
3.6 /admin/directory-profiles/[id] — Profile Detail#
Purpose: Deep-dive into a single directory profile with preview, editing, and publishing tools
Layout: Tabbed interface with live preview
Tabs:
| Tab | Content | Data |
|---|---|---|
| Preview | Live rendered profile (as patients see it) | DirectoryProfile + schema |
| Edit | Content editor (bio, services, FAQs, media, contact) | DirectoryProfile |
| SEO | Meta tags, schema markup, keywords, canonical URL | DirectoryProfile |
| GBP | GBP sync status, Place ID, URL mapping | GbpAccount |
| Analytics | Views, click-to-call, WhatsApp clicks, rank tracking | Analytics[] |
| History | Content refresh log, approval history, audit log | AuditLog[] |
Preview Tab:
┌────────────────────────────────────────────────────────────┐
│ 👁️ Live Preview │
│ https://indiandoctors.in/clinics/kochi/dr-smith-dental │
│ [ Open in New Tab ] [ Copy Public URL ] │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ [Live iframe or screenshot of the profile page] │ │
│ │ Hero, Bio, Services, Reviews, FAQ, Map, Contact │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ [ ✅ Publish ] [ ⏸️ Unpublish ] [ 🔄 Revalidate ISR ] │
│ [ 📝 Edit Content ] [ 📋 Request Approval ] │
└────────────────────────────────────────────────────────────┘
Edit Tab:
| Section | Fields | Editable |
|---|---|---|
| Bio | Textarea (300–500 words) | ✅ |
| Services | Repeater: name + description | ✅ (add/remove/edit) |
| FAQs | Repeater: question + answer | ✅ (add/remove/edit) |
| Media | Photo, logo, gallery (3–5 images) | ✅ (upload/replace) |
| Contact | Phone, WhatsApp, email, address, hours | ✅ |
| Schema | JSON-LD preview (read-only) | ❌ |
SEO Tab:
| Field | Value | Editable |
|---|---|---|
| Meta Title | Generated from profile | ✅ |
| Meta Description | Generated from profile | ✅ |
| Canonical URL | Full directory URL | ❌ |
| Keywords | Target keywords | ✅ |
| JSON-LD Schema | Full schema preview | ❌ (auto-generated) |
| OG Image | Generated 1200×630 image | ✅ (regenerate) |
GBP Tab:
| Field | Status |
|---|---|
| GBP Connected | ✅ / ❌ |
| Place ID | ChIJ... |
| Website URL | https://indiandoctors.in/clinics/kochi/dr-smith-dental |
| Sync Status | Last synced 2 hours ago |
| [ Force Sync ] | Button |
Analytics Tab:
| Metric | Value | Period |
|---|---|---|
| Profile Views | 1,247 | Last 30 days |
| Click-to-Call | 89 | Last 30 days |
| WhatsApp Clicks | 56 | Last 30 days |
| Avg. Time on Page | 2:34 | Last 30 days |
| Google Rank | #3 | "dentist in kochi" |
History Tab:
| Event | Date | User | Details |
|---|---|---|---|
| Content Refreshed | 2026-06-01 | System (AI) | Bio + 3 FAQs rewritten |
| Doctor Approved | 2026-05-28 | Dr. Smith | Approved with minor edits |
| Published | 2026-05-28 | System | ISR revalidation triggered |
| Profile Created | 2026-05-20 | System | AI-generated content |
ISR Revalidation Button:
A prominent action button on the Preview tab that triggers Next.js ISR revalidation for this profile's route:
// Action: Revalidate ISR
await fetch('/api/revalidate', {
method: 'POST',
body: JSON.stringify({ citySlug, slug }),
});
Content Compliance Check Status:
A persistent status indicator on the Edit tab showing whether the current content passes MCI compliance checks:
| Status | Icon | Meaning |
|---|---|---|
| ✅ Pass | Green | No promotional claims, disclaimer present |
| ⚠️ Warning | Yellow | Minor issues (e.g., missing disclaimer) |
| ❌ Fail | Red | Forbidden words/patterns detected |
If failed, the specific violations are listed with inline suggestions.
3.7 /admin/social-connections — Social Accounts#
Purpose: Overview of all connected social accounts across clients
Table Columns:
| Column | Description |
|---|---|
| Platform | Facebook, Instagram, LinkedIn, Twitter |
| Account Name | Profile name |
| Practice | Client |
| Status | ✅ Active / ❌ Expired / ⏳ Pending |
| Followers | Count |
| Last Sync | Date |
| Actions | Disconnect, refresh token |
3.8 /admin/jobs — Job Monitor#
Purpose: Real-time monitoring of the job queue
Layout: Stat cards + live-updating data table
Stat Cards (top row):
| Card | Color | Value |
|---|---|---|
| Pending | Yellow | Count |
| Running | Blue | Count |
| Completed | Green | Count |
| Failed | Red | Count |
Table Columns:
| Column | Description |
|---|---|
| Job ID | Short ID |
| Skill | Skill name + ID |
| Practice | Client name |
| Status | Badge: PENDING / RUNNING / COMPLETED / FAILED |
| Duration | e.g., "12.3s" |
| Cost | USD amount |
| Started | Timestamp |
| Actions | Retry (if failed), View logs |
Filters:
- Status multi-select
- Practice dropdown
- Skill dropdown
- Date range
Auto-refresh: Every 10 seconds
3.9 /admin/content — AI Content Review#
Purpose: Review and manage AI-generated content across all clients
Layout: Split view — list left, preview right
List Columns:
| Column | Description |
|---|---|
| Title/Type | Content title or type |
| Practice | Client |
| Status | DRAFT / PENDING_REVIEW / APPROVED / PUBLISHED |
| AI Provider | Claude / GPT-4o |
| Cost | USD |
| Created | Date |
Preview Panel:
- Rendered content (HTML)
- SEO score
- Readability score
- Compliance check status (Pass / Warning / Fail)
- Approve / Reject / Edit buttons
Prompt Management Tab:
- List all prompt templates
- Edit system prompt
- Edit user prompt template
- A/B test variants
- Performance scores
3.10 /admin/billing — Billing Overview#
Purpose: Subscription and payment management
Layout: Revenue cards + tables
Revenue Cards:
| Card | Metric |
|---|---|
| MRR | Current monthly recurring revenue |
| ARR | Annual run rate |
| Active Subscriptions | Count by tier |
| Failed Payments | Last 7 days |
Tables:
- Subscriptions: Practice, tier, status, next billing, amount
- Invoices: Invoice ID, practice, amount, status, paid date
- Failed Charges: Practice, amount, failure reason, retry count
3.11 /admin/reports — System Reports#
Purpose: Historical analytics and exportable reports
Available Reports:
| Report | Period | Export |
|---|---|---|
| Revenue by Month | Monthly | CSV, PDF |
| Client Churn | Monthly | CSV |
| Citation Success Rate | Weekly | CSV |
| API Cost Breakdown | Daily | CSV |
| Content Generation Volume | Weekly | CSV |
| Directory Profile Performance | Weekly | CSV |
| Support Ticket Summary | Monthly | CSV |
4. Component Hierarchy#
AdminLayout
├── AdminShell
│ ├── AdminSidebar
│ │ ├── NavGroup "Overview"
│ │ │ └── NavItem "KPI Dashboard" → /admin
│ │ ├── NavGroup "Clients"
│ │ │ ├── NavItem "All Clients" → /admin/clients
│ │ │ └── NavItem "Social Accounts" → /admin/social-connections
│ │ ├── NavGroup "Directory"
│ │ │ ├── NavItem "Directory Overview" → /admin/directory
│ │ │ └── NavItem "Directory Profiles" → /admin/directory-profiles
│ │ ├── NavGroup "Operations"
│ │ │ ├── NavItem "Job Monitor" → /admin/jobs
│ │ │ └── NavItem "Content Review" → /admin/content
│ │ └── NavGroup "Finance"
│ │ ├── NavItem "Billing" → /admin/billing
│ │ └── NavItem "Reports" → /admin/reports
│ ├── AdminHeader
│ │ ├── Breadcrumbs
│ │ ├── GlobalSearch
│ │ ├── NotificationBell
│ │ └── UserMenu
│ └── PageContent
│ ├── (page-specific components)
│ └── DataTable / Form / Chart
Reusable Admin Components#
| Component | Path | Used In |
|---|---|---|
DataTable |
src/components/admin/DataTable.tsx |
All list pages |
StatCard |
src/components/admin/StatCard.tsx |
KPI, Jobs, Billing, Directory |
StatusBadge |
src/components/admin/StatusBadge.tsx |
Tables |
ConfirmDialog |
src/components/admin/ConfirmDialog.tsx |
Delete, suspend, publish, unpublish |
FilterBar |
src/components/admin/FilterBar.tsx |
List pages |
DateRangePicker |
src/components/admin/DateRangePicker.tsx |
Reports, Jobs, Directory |
PracticeSelect |
src/components/admin/PracticeSelect.tsx |
Filter by client |
JsonViewer |
src/components/admin/JsonViewer.tsx |
Job payload, audit logs, schema preview |
ComplianceBadge |
src/components/admin/ComplianceBadge.tsx |
Directory profiles, content review |
IRevalidateButton |
src/components/admin/IRevalidateButton.tsx |
Profile detail page |
ProfilePreview |
src/components/admin/ProfilePreview.tsx |
Profile detail page |
5. Data Requirements#
tRPC Queries per Page#
| Page | Queries | Mutations |
|---|---|---|
/admin |
admin.getKPIs, admin.getSystemHealth |
— |
/admin/clients |
admin.listClients |
admin.updateClient |
/admin/clients/[id] |
admin.getClient, practice.get, location.list, gbp.listAccounts, social.listAccounts, citation.list, directoryProfile.getByPractice, job.list, billing.listInvoices |
admin.updateClient |
/admin/directory |
directoryProfile.getStats, directoryProfile.listPendingApprovals |
directoryProfile.approve, directoryProfile.reject |
/admin/directory-profiles |
directoryProfile.list, directoryProfile.getStats |
directoryProfile.publish, directoryProfile.unpublish, directoryProfile.bulkRefresh |
/admin/directory-profiles/[id] |
directoryProfile.getById, directoryProfile.getAnalytics, directoryProfile.getHistory |
directoryProfile.update, directoryProfile.publish, directoryProfile.unpublish, directoryProfile.revalidate, gbp.forceSync |
/admin/social-connections |
admin.listSocialConnections |
social.disconnect |
/admin/jobs |
admin.listJobs |
admin.retryJob |
/admin/content |
admin.listContent, content.list |
admin.approveContent, admin.updatePrompt |
/admin/billing |
admin.getRevenue, billing.listInvoices |
— |
/admin/reports |
admin.getRevenue |
— |
6. Access Control#
Role Gate#
// src/app/(admin)/layout.tsx
export default async function AdminLayout({ children }) {
const session = await getServerSession();
if (session?.user?.role !== "ADMIN") {
redirect("/dashboard");
}
return <AdminShell>{children}</AdminShell>;
}
API Protection#
All admin endpoints use adminProcedure which enforces:
- User is authenticated
- User role === "ADMIN"
- Returns 403 FORBIDDEN otherwise
Impersonation#
Admin can "impersonate" a client to see their dashboard:
- Sets
x-practice-idheader - Temporarily gains
practiceProcedureaccess - Audit log records impersonation
7. Responsive Behavior#
| Breakpoint | Sidebar | Table |
|---|---|---|
| Desktop (>1024px) | Fixed, 240px | Full columns |
| Tablet (768-1024px) | Collapsible | Reduced columns |
| Mobile (<768px) | Hidden, hamburger | Card list view |
Mobile Adaptations#
- Sidebar becomes drawer
- Data tables become card lists
- Filters collapse into sheet
- Charts stack vertically
End of Admin Dashboard UI Specifications