import { Ionicons } from "@expo/vector-icons"; import { router } from "expo-router"; import { useMemo, useState } from "react"; import { RefreshControl, ScrollView, StyleSheet, Text, View, } from "react-native"; import type { AppRouter } from "beenvoice/server/api/root"; import type { inferRouterOutputs } from "@trpc/server"; import { AppBackground } from "@/components/AppBackground"; import { FilterChip } from "@/components/FilterChip"; import { LoadingScreen } from "@/components/LoadingScreen"; import { PageHeader } from "@/components/PageHeader"; import { SwipeableRow } from "@/components/SwipeableRow"; import { TabPage } from "@/components/TabPage"; import { TabScrollView } from "@/components/TabScrollView"; import { Button } from "@/components/ui/Button"; import { fonts, radii, spacing } from "@/constants/theme"; import { useAppTheme } from "@/contexts/ThemeContext"; import { formatCurrency, formatDate } from "@/lib/format"; import { api } from "@/lib/trpc"; import { formatTrpcErrorMessage } from "@/lib/trpc-errors"; import type { ThemeColors } from "@/lib/theme-palette"; import { useThemedStyles } from "@/lib/use-themed-styles"; type ExpenseFilter = "all" | "billable" | "receipts"; type Expense = inferRouterOutputs["expenses"]["getAll"][number]; export default function ExpensesScreen() { const { colors } = useAppTheme(); const styles = useThemedStyles(createStyles); const utils = api.useUtils(); const [filter, setFilter] = useState("all"); const expensesQuery = api.expenses.getAll.useQuery(); const deleteExpense = api.expenses.delete.useMutation({ onSuccess: () => void utils.expenses.getAll.invalidate(), }); const expenses = expensesQuery.data ?? []; const filteredExpenses = useMemo( () => expenses.filter((expense) => { if (filter === "billable") return expense.billable; if (filter === "receipts") return expense.receiptCount > 0; return true; }), [expenses, filter], ); const summary = useMemo(() => { const total = filteredExpenses.reduce( (sum, expense) => sum + expense.amount, 0, ); const billable = filteredExpenses.reduce( (sum, expense) => sum + (expense.billable ? expense.amount : 0), 0, ); const receiptCount = filteredExpenses.reduce( (sum, expense) => sum + (expense.receiptCount ?? 0), 0, ); return { total, billable, receiptCount }; }, [filteredExpenses]); const groupedExpenses = useMemo( () => groupExpensesByMonth(filteredExpenses), [filteredExpenses], ); if (expensesQuery.isLoading) { return ; } if (expensesQuery.error) { return ( Could not load expenses {formatTrpcErrorMessage(expensesQuery.error)} ); } return (