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,
},
});