import { router } from "expo-router"; import { Pressable, RefreshControl, StyleSheet, Text, View } from "react-native"; import { Screen } from "@/components/Screen"; import { TabPage } from "@/components/TabPage"; import { TabScrollView } from "@/components/TabScrollView"; import { AppBackground } from "@/components/AppBackground"; import { PageHeader } from "@/components/PageHeader"; import { GlassSurface } from "@/components/GlassSurface"; import { LoadingScreen } from "@/components/LoadingScreen"; import { StatCard } from "@/components/StatCard"; import { StatusBadge } from "@/components/StatusBadge"; import { Button } from "@/components/ui/Button"; import { Card } from "@/components/ui/Card"; import { fonts, radii, spacing } from "@/constants/theme"; import { useAppTheme } from "@/contexts/ThemeContext"; import { formatCurrency, formatDate } from "@/lib/format"; import type { ThemeColors } from "@/lib/theme-palette"; import { useThemedStyles } from "@/lib/use-themed-styles"; import { getInvoiceStatus } from "@/lib/invoice-status"; import { formatElapsedHoursMinutes, resolveClockDescription } from "@/lib/time-clock"; import { useRunningElapsed } from "@/lib/use-running-elapsed"; import { api } from "@/lib/trpc"; export default function DashboardScreen() { const { colors } = useAppTheme(); const styles = useThemedStyles(createDashboardStyles); const statsQuery = api.dashboard.getStats.useQuery(); const runningQuery = api.timeEntries.getRunning.useQuery(undefined, { refetchInterval: 30_000, }); const runningElapsed = useRunningElapsed(runningQuery.data?.startedAt); if (statsQuery.isLoading) { return ; } if (statsQuery.error) { return ( Could not load dashboard {statsQuery.error.message} ); } const stats = statsQuery.data; if (!stats) { return ; } const running = runningQuery.data; const revenueChange = stats.revenueChange > 0 ? `+${stats.revenueChange.toFixed(0)}% vs last month` : stats.revenueChange < 0 ? `${stats.revenueChange.toFixed(0)}% vs last month` : "No change vs last month"; const maxRevenue = Math.max(...stats.revenueChartData.map((d) => d.revenue), 1); return ( } refreshControl={ { void statsQuery.refetch(); void runningQuery.refetch(); }} tintColor={colors.primary} /> } > {running ? ( router.push("/(app)/timer")}> {resolveClockDescription(running.description)} {running.client?.name ?? "No client"} {running.invoice ? ` · ${running.invoice.invoicePrefix ?? "#"}${running.invoice.invoiceNumber}` : ""} {formatElapsedHoursMinutes(runningElapsed)} ) : null} {stats.overdueCount > 0 ? ( {stats.overdueCount} overdue {stats.overdueCount === 1 ? "invoice" : "invoices"} Follow up on outstanding payments from the Invoices tab. ) : null}