import React from "react"; import { ActivityIndicator, Pressable, ScrollView, StyleSheet, Text, View, } from "react-native"; import { useSafeAreaInsets } from "react-native-safe-area-context"; import { fonts, text } from "../theme/tokens"; import { useTheme } from "../theme/useTheme"; import { Button } from "../components/Button"; import { Icon } from "../components/Icon"; import { Card, Divider, Mono, SectionLabel, StatusDot, } from "../components/primitives"; import { TabBar } from "../components/TabBar"; import { useAppState, type RecentItem, type WaitingItem, } from "../state/AppState"; export function FleetScreen() { const { colors } = useTheme(); const insets = useSafeAreaInsets(); const { go, openAnswer, openDetail, waiting, recent, counts, loading, error, refresh } = useAppState(); const empty = waiting.length === 0 && recent.length === 0; const stats = [ { label: "Running", value: counts.running, tint: colors.textHeading }, { label: "Waiting", value: counts.waiting, tint: colors.warning }, { label: "Done", value: counts.done, tint: colors.textHeading }, ]; return ( Fleet {counts.running} running · {counts.waiting} waiting on you {stats.map((s) => ( {s.label} {s.value} ))} {loading && empty && !error ? ( ) : error && empty ? ( Couldn’t load fleet {error} ) : ( <> Waiting on you {waiting.length === 0 ? ( Nothing waiting on you. ) : ( waiting.map((a, i) => ( {i > 0 && } openAnswer(a.project, a.name)} /> )) )} Recent checkmarks {recent.length === 0 ? ( No checkmarks yet. ) : ( recent.map((c, i) => ( {i > 0 && } openDetail(c.project, c.name)} /> )) )} )} ); } function WaitingRow({ agent, onAnswer, }: { agent: WaitingItem; onAnswer: () => void; }) { const { colors } = useTheme(); return ( {agent.name} {agent.project} {agent.question} ); } function CheckmarkRow({ checkmark, onPress, }: { checkmark: RecentItem; onPress: () => void; }) { const { colors } = useTheme(); const dot = checkmark.tone === "positive" ? colors.positive : colors.danger; return ( [ styles.checkmarkRow, pressed && { backgroundColor: colors.surfaceSunken }, ]} > {checkmark.title} {checkmark.meta} ); } const styles = StyleSheet.create({ page: { flex: 1 }, content: { paddingTop: 8, paddingHorizontal: 20, paddingBottom: 20 }, headerRow: { flexDirection: "row", alignItems: "center", gap: 12, marginTop: 12, marginBottom: 20, }, statsRow: { flexDirection: "row", gap: 12, marginBottom: 20 }, statCard: { flex: 1, paddingVertical: 14, paddingHorizontal: 16 }, statValue: { fontFamily: fonts.monoSemiBold, fontSize: 24, lineHeight: 28, marginTop: 4, }, centered: { paddingVertical: 48, alignItems: "center", justifyContent: "center" }, errorCard: { padding: 16, alignItems: "flex-start" }, overline: { marginBottom: 10 }, section: { marginBottom: 20 }, rowPad: { paddingVertical: 14, paddingHorizontal: 16 }, waitingTop: { flexDirection: "row", alignItems: "center", gap: 8 }, waitingBottom: { flexDirection: "row", alignItems: "center", gap: 10, marginTop: 8, }, rowTitle: { fontFamily: fonts.bodySemiBold, fontSize: 13, lineHeight: 16, }, checkmarkRow: { flexDirection: "row", alignItems: "center", gap: 12, paddingVertical: 14, paddingHorizontal: 16, minHeight: 44, }, });