Skip to content

Commit f579205

Browse files
jeremyederAmbient Code Botclaude
authored
feat: Implement The Commuter demo screens (#31)
Implement 4 new screens for "The Commuter" demo showcasing async-first workflows with transparent session mobility. This implementation includes: **Screens Implemented:** - ACP Inbox (app/(tabs)/inbox.tsx) - Homescreen with summary stats, stuck agent banner, decision queue card, overnight results, and forecast - Decision Queue (app/decisions/index.tsx) - List of pending decisions - Review Flow (app/decisions/[id].tsx) - 3-step review process with soft gates, accordion tracking, quick response chips - Notification History (app/notifications/history.tsx) - Date-grouped notifications with restore functionality **Components Created:** - Inbox: InboxHeader, StuckAgentBanner, DecisionQueueCard, OvernightResultsCard, ForecastCard - Decisions: DecisionCard - UI: AgentAvatar, NotificationStatusBadge **Types & Mock Data:** - types/inbox.ts: InboxSummary, StuckAgent, OvernightResult, Forecast, Notification, AgentName, AGENT_COLORS - types/decisions.ts: PendingDecision, DecisionDetails, AccordionSection, ReviewFlow - utils/mockInboxData.ts: Complete mock data for all 4 screens with easter egg (RFE #67) **Navigation:** - Added Inbox tab to main navigation - Created decisions stack navigation - All screens support pull-to-refresh **Features:** - No one-click approvals (enforced via "Start Review" flow) - 3-step review process with soft gate (must view all sections) - Quick response chips ("Looks good", "Needs discussion", "Try different") - Notification restore functionality (DISMISSED → RESTORED) - Agent-colored avatars (Parker=blue, Archie=purple, Taylor=green, Phoenix=orange, Morgan=red) - Responsive to light/dark theme Implements: #28 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Ambient Code Bot <bot@ambient-code.local> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 57bfb48 commit f579205

File tree

17 files changed

+1658
-1
lines changed

17 files changed

+1658
-1
lines changed

app/(tabs)/_layout.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,17 @@ export default function TabLayout() {
3737
<Tabs.Screen
3838
name="index"
3939
options={{
40-
title: 'Home',
40+
title: 'Sessions',
4141
tabBarIcon: ({ color }) => <IconSymbol size={28} name="house.fill" color={color} />,
4242
}}
4343
/>
44+
<Tabs.Screen
45+
name="inbox"
46+
options={{
47+
title: 'Inbox',
48+
tabBarIcon: ({ color }) => <IconSymbol size={28} name="tray.fill" color={color} />,
49+
}}
50+
/>
4451
<Tabs.Screen
4552
name="explore"
4653
options={{

app/(tabs)/inbox.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import React, { useState } from 'react'
2+
import { View, ScrollView, RefreshControl, StyleSheet } from 'react-native'
3+
import { InboxHeader } from '@/components/inbox/InboxHeader'
4+
import { StuckAgentBanner } from '@/components/inbox/StuckAgentBanner'
5+
import { DecisionQueueCard } from '@/components/inbox/DecisionQueueCard'
6+
import { OvernightResultsCard } from '@/components/inbox/OvernightResultsCard'
7+
import { ForecastCard } from '@/components/inbox/ForecastCard'
8+
import { mockInboxData, mockPendingDecisions } from '@/utils/mockInboxData'
9+
import { useTheme } from '@/hooks/useTheme'
10+
11+
export default function InboxScreen() {
12+
const { colors } = useTheme()
13+
const [refreshing, setRefreshing] = useState(false)
14+
15+
const onRefresh = async () => {
16+
setRefreshing(true)
17+
// Simulate fetch delay
18+
await new Promise((resolve) => setTimeout(resolve, 500))
19+
setRefreshing(false)
20+
}
21+
22+
const { user, summary, stuckAgents, overnightResults, forecast } = mockInboxData
23+
24+
// Calculate total minutes for decision queue
25+
const totalMinutes = mockPendingDecisions.reduce(
26+
(sum, decision) => sum + decision.estimatedMinutes,
27+
0
28+
)
29+
30+
return (
31+
<ScrollView
32+
style={[styles.container, { backgroundColor: colors.bg }]}
33+
refreshControl={
34+
<RefreshControl refreshing={refreshing} onRefresh={onRefresh} tintColor={colors.accent} />
35+
}
36+
showsVerticalScrollIndicator={false}
37+
>
38+
<InboxHeader userName={user.name} summary={summary} />
39+
40+
<StuckAgentBanner agents={stuckAgents} />
41+
42+
<DecisionQueueCard count={summary.pendingDecisions} totalMinutes={totalMinutes} />
43+
44+
<OvernightResultsCard results={overnightResults} />
45+
46+
<ForecastCard forecast={forecast} />
47+
48+
{/* Bottom padding */}
49+
<View style={{ height: 24 }} />
50+
</ScrollView>
51+
)
52+
}
53+
54+
const styles = StyleSheet.create({
55+
container: {
56+
flex: 1,
57+
},
58+
})

0 commit comments

Comments
 (0)