import { RefreshControl, StyleSheet, Text, View } from "react-native"; import { AppBackground } from "@/components/AppBackground"; 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 { fonts, spacing } from "@/constants/theme"; import { useAppTheme } from "@/contexts/ThemeContext"; import { formatCurrency, formatDate } from "@/lib/format"; import { api } from "@/lib/trpc"; export default function RecurringScreen() { const { colors } = useAppTheme(); const utils = api.useUtils(); const query = api.recurringInvoices.getAll.useQuery(); const pause = api.recurringInvoices.pause.useMutation({ onSuccess: () => void query.refetch(), }); const resume = api.recurringInvoices.resume.useMutation({ onSuccess: () => void query.refetch(), }); const generateNow = api.recurringInvoices.generateNow.useMutation({ onSuccess: () => { void utils.invoices.getAll.invalidate(); void query.refetch(); }, }); if (query.isLoading) { return ; } const items = query.data ?? []; return ( } refreshControl={ void query.refetch()} tintColor={colors.primary} /> } > {items.length === 0 ? ( No recurring invoices yet. Create them on the web dashboard for now. ) : ( items.map((item) => ( generateNow.mutate({ id: item.id }), }, { key: "toggle", label: item.status === "active" ? "Pause" : "Resume", icon: item.status === "active" ? "pause-outline" : "play-outline", color: "#fff", backgroundColor: colors.mutedForeground, onPress: () => item.status === "active" ? pause.mutate({ id: item.id }) : resume.mutate({ id: item.id }), }, ]} > {item.name} {item.client?.name ?? "Client"} · {item.schedule} · {item.status} Next due {formatDate(item.nextDueAt)} {formatCurrency( item.items.reduce((sum, line) => sum + line.hours * line.rate, 0), item.currency, )} )) )} ); } const styles = StyleSheet.create({ row: { flexDirection: "row", gap: spacing.md, paddingVertical: spacing.md, borderBottomWidth: 1, borderBottomColor: "rgba(0,0,0,0.08)", }, title: { fontFamily: fonts.bodySemiBold, fontSize: 15, }, });