Stabilize mobile auth session handling
This commit is contained in:
+37
-2
@@ -20,6 +20,7 @@ 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 { formatTrpcErrorMessage } from "@/lib/trpc-errors";
|
||||
import { api } from "@/lib/trpc";
|
||||
|
||||
export default function DashboardScreen() {
|
||||
@@ -41,7 +42,7 @@ export default function DashboardScreen() {
|
||||
<Screen>
|
||||
<View style={styles.errorBox}>
|
||||
<Text style={styles.errorTitle}>Could not load dashboard</Text>
|
||||
<Text style={styles.errorText}>{statsQuery.error.message}</Text>
|
||||
<Text style={styles.errorText}>{formatTrpcErrorMessage(statsQuery.error)}</Text>
|
||||
</View>
|
||||
</Screen>
|
||||
</AppBackground>
|
||||
@@ -62,7 +63,7 @@ export default function DashboardScreen() {
|
||||
: "No change vs last month";
|
||||
|
||||
const maxRevenue = Math.max(...stats.revenueChartData.map((d) => d.revenue), 1);
|
||||
const sendReminderDue = stats.sendReminderDue ?? [];
|
||||
const sendReminderDue = stats.recentInvoices.filter((inv) => inv.status === "draft");
|
||||
|
||||
return (
|
||||
<AppBackground>
|
||||
@@ -146,8 +147,31 @@ export default function DashboardScreen() {
|
||||
variant="secondary"
|
||||
onPress={() => router.push("/(app)/invoices")}
|
||||
/>
|
||||
<Button
|
||||
title="Reports"
|
||||
variant="secondary"
|
||||
onPress={() => router.push("/(app)/more/reports" as never)}
|
||||
/>
|
||||
</View>
|
||||
|
||||
{stats.currentDraft ? (
|
||||
<GlassSurface style={styles.alertGlass}>
|
||||
<Pressable
|
||||
style={styles.alertBanner}
|
||||
onPress={() => router.push(`/(app)/invoices/${stats.currentDraft!.id}`)}
|
||||
>
|
||||
<Text style={styles.alertTitle}>
|
||||
Draft {stats.currentDraft.invoiceNumber}
|
||||
</Text>
|
||||
<Text style={styles.alertText}>
|
||||
{stats.currentDraft.client?.name ?? "Client"} ·{" "}
|
||||
{formatCurrency(stats.currentDraft.totalAmount)} ·{" "}
|
||||
{stats.currentDraft.totalHours.toFixed(1)}h logged
|
||||
</Text>
|
||||
</Pressable>
|
||||
</GlassSurface>
|
||||
) : null}
|
||||
|
||||
<View style={styles.statsGrid}>
|
||||
<View style={styles.statCell}>
|
||||
<StatCard label="Total revenue" value={formatCurrency(stats.totalRevenue)} />
|
||||
@@ -190,6 +214,17 @@ export default function DashboardScreen() {
|
||||
</View>
|
||||
</Card>
|
||||
|
||||
<Card title="Invoice status">
|
||||
{(stats.statusChartData ?? []).map((item) => (
|
||||
<View key={item.status} style={styles.invoiceRow}>
|
||||
<Text style={styles.invoiceClient}>{item.name}</Text>
|
||||
<Text style={styles.invoiceDate}>
|
||||
{item.count} · {formatCurrency(item.value)}
|
||||
</Text>
|
||||
</View>
|
||||
))}
|
||||
</Card>
|
||||
|
||||
<Card title="Recent invoices">
|
||||
{stats.recentInvoices.length === 0 ? (
|
||||
<Text style={styles.empty}>No invoices yet. Create one from the Invoices tab.</Text>
|
||||
|
||||
Reference in New Issue
Block a user