# 0.1% Dashboard Build Plan

## Overview
A time-aware, motivational dashboard that adapts to the salesperson's workday and provides actionable insights at a glance.

**Status:** COMPLETE
**Last Updated:** 2026-01-16
**Progress:** 12/12 steps complete

---

## Time-Aware Modes

| Time | Mode | Focus |
|------|------|-------|
| Before 10am | Morning | "Today's Mission" - what to accomplish |
| 10am - 5pm | Work Hours | Live progress + urgent actions |
| After 5pm | End of Day | Stats recap + tomorrow preview |

---

## Component Architecture

```
Dashboard.jsx (refactored)
├── DashboardHeader.jsx        # Greeting, streak, notifications
├── TimeAwareSection.jsx       # Switches content based on time
│   ├── MorningMission.jsx     # Before 10am
│   ├── LiveProgress.jsx       # 10am-5pm
│   └── DayRecap.jsx           # After 5pm
├── TodaysMission.jsx          # Calls to target, callbacks, hot leads
├── LiveStats.jsx              # Calls/target, conversions, pipeline
├── UrgentActions.jsx          # Red alerts for overdue items
├── RecentWins.jsx             # Last 3 conversions (dopamine!)
├── MarketplaceHealth.jsx      # Workers vs Contractors (stub)
├── AIInsightsWidget.jsx       # Already exists - keep it
└── QuickActions.jsx           # START CALLING, View Inbox
```

---

## Implementation Steps

### Step 1: API Endpoint - Dashboard Stats
**File:** `src/routes/dashboard.js` (NEW)

Create dedicated dashboard endpoint with all required data:

```javascript
GET /api/dashboard/stats

Response:
{
  // Time context
  timeMode: "morning" | "work" | "evening",
  serverTime: "2026-01-16T09:30:00Z",

  // Today's Mission
  mission: {
    callsToTarget: 8,        // target - calls made
    callTarget: 15,          // configurable target
    callsMade: 7,
    callbacksToday: 3,       // scheduled for today
    hotLeadsWaiting: 5,      // score >= 70, not contacted today
    smsRepliesWaiting: 2,    // unread inbound SMS
  },

  // Live Stats
  stats: {
    callsToday: 7,
    conversationsToday: 4,   // connected calls
    winsToday: 1,
    winsThisWeek: 3,
    streak: 12,              // consecutive days
    pipelineValue: null,     // Phase 2
  },

  // Urgent Actions (red alerts)
  urgent: {
    overdueCallbacks: [      // scheduled_at < now, status = pending
      { id, leadName, scheduledAt, hoursPastDue }
    ],
    hotLeadsStale: [         // score >= 70, last_contact > 48hrs
      { id, leadName, hoursSinceContact }
    ],
    smsWaitingLong: [        // inbound SMS > 4hrs ago, no response
      { id, leadName, message, hoursWaiting }
    ],
  },

  // Recent Wins
  recentWins: [              // last 3 conversions
    { id, leadName, company, convertedAt }
  ],

  // Marketplace Health (stub)
  marketplace: {
    enabled: false,
    workersCount: null,
    contractorsCount: null,
  }
}
```

**Queries needed:**
1. Callbacks where `scheduled_at <= now` and `status = 'pending'`
2. Leads where `score >= 70` and `last_contact_at < 48hrs ago`
3. Communications where `type = 'sms_inbound'` and no outbound after
4. Leads where `status = 'converted'` ordered by `updated_at` desc, limit 3
5. Today's communications count by type

---

### Step 2: DashboardHeader Component
**File:** `admin/src/components/DashboardHeader.jsx` (NEW)

Props:
- `userName: string`
- `streak: number`
- `unreadCount: number`
- `isConnected: boolean`
- `onNotificationClick: () => void`

Features:
- Time-based greeting (already exists, extract)
- Streak badge (lightning bolt)
- Notification bell with badge
- Realtime connection indicator

---

### Step 3: TodaysMission Component
**File:** `admin/src/components/TodaysMission.jsx` (NEW)

Props:
- `callsToTarget: number`
- `callTarget: number`
- `callbacksToday: number`
- `hotLeadsWaiting: number`
- `smsRepliesWaiting: number`

Display:
```
┌─────────────────────────────────────┐
│ 📋 TODAY'S MISSION                  │
│                                     │
│ 🎯 8 calls to hit target            │
│    ████████░░░░░░ 7/15              │
│                                     │
│ 📞 3 callbacks scheduled            │
│ 🔥 5 hot leads need action          │
│ 💬 2 SMS replies waiting            │
└─────────────────────────────────────┘
```

---

### Step 4: LiveStats Component
**File:** `admin/src/components/LiveStats.jsx` (NEW)

Props:
- `callsToday: number`
- `callTarget: number`
- `conversationsToday: number`
- `winsToday: number`
- `winsThisWeek: number`
- `streak: number`

Display: Grid of stat cards (reuse existing StatCard)
- Calls: X / target (with progress ring)
- Convos: X
- Wins Today: X
- Wins Week: X

---

### Step 5: UrgentActions Component
**File:** `admin/src/components/UrgentActions.jsx` (NEW)

Props:
- `overdueCallbacks: Array`
- `hotLeadsStale: Array`
- `smsWaitingLong: Array`
- `onActionClick: (type, item) => void`

Display (only shows if items exist):
```
┌─────────────────────────────────────┐
│ 🚨 URGENT                           │
│                                     │
│ ⏰ Callback overdue: Tony M (2hrs)  │
│ 🔥 Hot lead stale: Sarah K (52hrs)  │
│ 💬 SMS waiting: John D (5hrs)       │
└─────────────────────────────────────┘
```

Clicking an item navigates to lead profile.

---

### Step 6: RecentWins Component
**File:** `admin/src/components/RecentWins.jsx` (NEW)

Props:
- `wins: Array<{ id, leadName, company, convertedAt }>`

Display:
```
┌─────────────────────────────────────┐
│ 🏆 RECENT WINS                      │
│                                     │
│ ✅ Sarah K - ABC Concrete (Today)   │
│ ✅ Mike T - BuildRight (Yesterday)  │
│ ✅ James L - FormPro (2 days ago)   │
└─────────────────────────────────────┘
```

Small, motivational. Shows "No wins yet this week" if empty.

---

### Step 7: MarketplaceHealth Component (Stub)
**File:** `admin/src/components/MarketplaceHealth.jsx` (NEW)

Props:
- `enabled: boolean`
- `workersCount: number | null`
- `contractorsCount: number | null`

Display (Phase 2 stub):
```
┌─────────────────────────────────────┐
│ 📊 MARKETPLACE HEALTH               │
│                                     │
│      Coming Soon                    │
│  Workers vs Contractors ratio       │
└─────────────────────────────────────┘
```

Greyed out, non-interactive for now.

---

### Step 8: QuickActions Component
**File:** `admin/src/components/QuickActions.jsx` (NEW)

Props:
- `leadsWaiting: number`
- `smsRepliesWaiting: number`
- `onStartCalling: () => void`
- `onViewInbox: () => void`

Display:
- Large "START CALLING" button (primary)
- "View Inbox (X)" button if replies waiting (secondary)

---

### Step 9: TimeAwareSection Component
**File:** `admin/src/components/TimeAwareSection.jsx` (NEW)

Logic:
```javascript
function getTimeMode() {
  const hour = new Date().getHours();
  if (hour < 10) return 'morning';
  if (hour < 17) return 'work';
  return 'evening';
}
```

**Morning Mode (before 10am):**
- TodaysMission (prominent)
- UrgentActions
- QuickActions
- AI Insights (collapsed)

**Work Mode (10am-5pm):**
- LiveStats (prominent)
- UrgentActions
- TodaysMission (compact)
- QuickActions
- AI Insights

**Evening Mode (after 5pm):**
- DayRecap stats (calls, convos, wins)
- RecentWins
- Tomorrow preview (callbacks scheduled)
- AI Insights

---

### Step 10: Refactor Dashboard.jsx
**File:** `admin/src/pages/Dashboard.jsx` (MODIFY)

Replace current implementation with component composition:

```jsx
export default function Dashboard() {
  const [data, setData] = useState(null);
  const { user } = useAuth();
  const navigate = useNavigate();

  useEffect(() => {
    loadDashboardData();
  }, []);

  // ... realtime subscriptions ...

  return (
    <div className="px-4 py-6 pb-24 max-w-lg mx-auto">
      <DashboardHeader
        userName={user?.displayName}
        streak={data?.stats.streak}
        unreadCount={data?.mission.smsRepliesWaiting}
        isConnected={isConnected}
        onNotificationClick={() => navigate('/inbox')}
      />

      <TimeAwareSection
        timeMode={data?.timeMode}
        mission={data?.mission}
        stats={data?.stats}
        urgent={data?.urgent}
        recentWins={data?.recentWins}
        marketplace={data?.marketplace}
        onStartCalling={() => navigate('/calls')}
        onViewInbox={() => navigate('/inbox')}
        onLeadClick={(id) => navigate(`/leads/${id}`)}
      />

      <AIInsightsWidget />
    </div>
  );
}
```

---

### Step 11: API Client Update
**File:** `admin/src/api/client.js` (MODIFY)

Add dashboard API methods:

```javascript
export const dashboardApi = {
  getStats: () => request('/api/dashboard/stats'),
};
```

---

### Step 12: Wire Up Realtime Updates
**File:** `admin/src/pages/Dashboard.jsx` (MODIFY)

Keep existing realtime subscriptions:
- `sms_inbound` -> refresh dashboard
- `call_logged` -> refresh dashboard
- `lead_converted` -> refresh dashboard + show celebration

---

## Database Changes

**No new tables required.**

Queries use existing tables:
- `leads` - for hot leads, conversions
- `communications` - for today's activity, SMS replies
- `callbacks` - for scheduled/overdue callbacks

---

## Files to Create

| File | Type | Description |
|------|------|-------------|
| `src/routes/dashboard.js` | Backend | Dashboard stats API |
| `admin/src/components/DashboardHeader.jsx` | Frontend | Header with greeting/streak |
| `admin/src/components/TodaysMission.jsx` | Frontend | Mission targets |
| `admin/src/components/LiveStats.jsx` | Frontend | Live statistics |
| `admin/src/components/UrgentActions.jsx` | Frontend | Red alert items |
| `admin/src/components/RecentWins.jsx` | Frontend | Conversion history |
| `admin/src/components/MarketplaceHealth.jsx` | Frontend | Stub for Phase 2 |
| `admin/src/components/QuickActions.jsx` | Frontend | CTA buttons |
| `admin/src/components/TimeAwareSection.jsx` | Frontend | Time-based layout |

## Files to Modify

| File | Changes |
|------|---------|
| `admin/src/pages/Dashboard.jsx` | Refactor to use new components |
| `admin/src/api/client.js` | Add dashboardApi |
| `src/index.js` | Add dashboard routes |
| `BUILD-GUIDE.md` | Document changes |

---

## Build Order

1. ✅ Create plan (this document)
2. ✅ Step 2: Backend API endpoint (`src/routes/dashboard.js`)
3. ✅ Step 3: DashboardHeader component
4. ✅ Step 4: TodaysMission component
5. ✅ Step 5: LiveStats component
6. ✅ Step 6: UrgentActions component
7. ✅ Step 7: RecentWins component
8. ✅ Step 8: MarketplaceHealth stub
9. ✅ Step 9: QuickActions component
10. ✅ Step 10: TimeAwareSection component
11. ✅ Step 11: Refactor Dashboard.jsx
12. ✅ Step 12: API client update + realtime wired

---

## Testing Checklist

- [ ] Morning mode shows correct content (before 10am)
- [ ] Work mode shows correct content (10am-5pm)
- [ ] Evening mode shows correct content (after 5pm)
- [ ] Urgent actions appear when criteria met
- [ ] Recent wins populate correctly
- [ ] Realtime updates refresh dashboard
- [ ] START CALLING navigates to call list
- [ ] All click handlers navigate correctly
- [ ] Mobile responsive layout
- [ ] Loading states work properly

---

## Notes for Context Continuation

If context runs low during build:
1. This file will contain progress checkmarks
2. Last step completed will be marked with ✅
3. Current step in progress will be noted
4. Any blockers or decisions will be documented here

**Current Status:** BUILD COMPLETE - All 12 steps finished. Ready for testing and deploy.
