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.│
└─────────────────────────────────────────────────┘
✅ 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
| 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 |
// 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>
)}// 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' } }
)
}| 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 |
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
- Component:
AIPagein/apps/web/app/ai/page.tsx - State:
insights(string[]) - Hook:
useEffecton mount - Display: Conditional render above messages
- Route:
POST /api/ai - Trigger:
message === 'GET_INSIGHTS' - Data Source: Supabase tables (tasks, events, projects, ideas)
- Response:
{ insights: string[] }
Supabase Tables → generateInsights() → API Response → State Update → UI Render
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.
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
- Auto-refresh: Update insights every 5 minutes
- Interactions: Click insights to navigate to relevant sections
- Animations: Smooth transitions when insights change
- Dismiss: Add "X" button to hide specific insights
- Persistence: Remember dismissed insights in localStorage
- Action execution (create_task, create_event) already works
- Message persistence to Supabase active
- Conversation history loading implemented
- Real-time subscriptions (not yet implemented)