Skip to content

Latest commit

 

History

History
194 lines (163 loc) · 5.76 KB

File metadata and controls

194 lines (163 loc) · 5.76 KB

Insights Display Implementation ✨

What Was Built

Insights Card Component

A minimal, dark-themed card that displays intelligent insights about your DailyOS data above the chat interface.

┌─────────────────────────────────────────────────┐
│ ACTIVE INSIGHTS                        [Header] │
├─────────────────────────────────────────────────┤
│ 📋 You have 3 pending tasks. Start by focus... │
│ ⏰ Alert: "Meeting" in 30 minutes.             │
│ 🚀 2 active projects in progress.              │
│ 💡 2 ideas waiting to be converted into tasks.│
└─────────────────────────────────────────────────┘

Features

Automatic Loading: Fetches insights on page mount
Clean Design: Dark background (zinc-900) with minimal styling
Small & Compact: text-xs/text-sm sizing, fits seamlessly
Smart Insights: Shows 4 types of contextual alerts
No Manual Refresh: Works automatically on load

Insights Types

Icon Type Logic
📋 Pending Tasks Counts tasks where done === false
Upcoming Events Finds events within 1 hour window
🚀 Active Projects Filters projects with status === 'active'
💡 Ideas Counts ideas awaiting conversion

Files Modified

1. /apps/web/app/ai/page.tsx

// Added insights state
const [insights, setInsights] = useState<string[]>([])

// Added fetch on mount
useEffect(() => {
  const fetchInsights = async () => {
    const response = await fetch('/api/ai', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ message: 'GET_INSIGHTS' }),
    })
    const data = await response.json()
    if (data.insights && Array.isArray(data.insights)) {
      setInsights(data.insights)
    }
  }
  fetchInsights()
}, [])

// Added display above messages
{insights.length > 0 && (
  <div className="nova-msg-in" style={{
    background: 'rgba(24,24,27,0.8)',
    border: '1px solid rgba(39,39,42,0.8)',
    borderRadius: '6px',
    padding: '10px 12px',
  }}>
    <span className="nova-mono">ACTIVE INSIGHTS</span>
    {insights.map((insight, idx) => (
      <div key={idx} className="nova-mono">{insight}</div>
    ))}
  </div>
)}

2. /apps/web/app/api/ai/route.ts

// Handle GET_INSIGHTS request
if (message === 'GET_INSIGHTS') {
  const { data: events } = await supabase.from('events').select('*')
  const { data: tasks } = await supabase.from('tasks').select('*')
  const { data: projects } = await supabase.from('projects').select('*')
  const { data: ideas } = await supabase.from('ideas').select('*')
  
  const insightsList = generateInsights(
    tasks || [], 
    events || [], 
    projects || [], 
    ideas || []
  )
  
  return new Response(
    JSON.stringify({ insights: insightsList }),
    { status: 200, headers: { 'Content-Type': 'application/json' } }
  )
}

Styling Details

Property Value
Background rgba(24,24,27,0.8) (zinc-900)
Border 1px solid rgba(39,39,42,0.8)
Border Radius 6px
Padding 10px 12px
Label Font Size 8px (text-xs)
Insight Font Size 11px (text-sm)
Label Color #52525b (zinc-500)
Text Color #a1a1aa (zinc-400)
Font Family JetBrains Mono

User Flow

1. User navigates to /ai
   ↓
2. AIPage component mounts
   ↓
3. useEffect triggers fetch('/api/ai', { message: 'GET_INSIGHTS' })
   ↓
4. API route fetches tasks, events, projects, ideas from Supabase
   ↓
5. generateInsights() processes data
   ↓
6. Returns array of insight strings with emoji prefixes
   ↓
7. Insights card renders above chat messages
   ↓
8. User sees contextual alerts about their data

Integration Points

Frontend

  • Component: AIPage in /apps/web/app/ai/page.tsx
  • State: insights (string[])
  • Hook: useEffect on mount
  • Display: Conditional render above messages

Backend

  • Route: POST /api/ai
  • Trigger: message === 'GET_INSIGHTS'
  • Data Source: Supabase tables (tasks, events, projects, ideas)
  • Response: { insights: string[] }

Data Flow

Supabase Tables → generateInsights() → API Response → State Update → UI Render

Example Output

With sample data:

  • 3 pending tasks
  • 1 event in 30 minutes
  • 2 active projects
  • 2 ideas

The insights card displays:

ACTIVE INSIGHTS
📋 You have 3 pending tasks. Start by focusing on the most important one.
⏰ Alert: "Team Standup" in 30 minutes.
🚀 2 active projects in progress.
💡 2 ideas waiting to be converted into tasks.

Git Commit

commit 6e78cf0
feat: add insights display card above chat

- Fetch insights on component mount from AI endpoint
- Display insights in minimal dark card (zinc-900) with text-xs/text-sm
- Shows active insights with emoji prefixes (📋, ⏰, 🚀, 💡)
- API route handles GET_INSIGHTS request to aggregate data
- Clean, minimal design matches NOVA interface

Next Steps

Optional Enhancements

  1. Auto-refresh: Update insights every 5 minutes
  2. Interactions: Click insights to navigate to relevant sections
  3. Animations: Smooth transitions when insights change
  4. Dismiss: Add "X" button to hide specific insights
  5. Persistence: Remember dismissed insights in localStorage

Related Features

  • Action execution (create_task, create_event) already works
  • Message persistence to Supabase active
  • Conversation history loading implemented
  • Real-time subscriptions (not yet implemented)