Polish mobile and web experience
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { router } from "expo-router";
|
||||
import { Pressable, RefreshControl, StyleSheet, Text, View } from "react-native";
|
||||
import { Pressable, StyleSheet, Text, View } from "react-native";
|
||||
|
||||
import { AppBackground } from "@/components/AppBackground";
|
||||
import { GlassSurface } from "@/components/GlassSurface";
|
||||
import { LoadingScreen } from "@/components/LoadingScreen";
|
||||
import { PageHeader } from "@/components/PageHeader";
|
||||
import { PullToRefresh } from "@/components/PullToRefresh";
|
||||
import { Screen } from "@/components/Screen";
|
||||
import { StatCard } from "@/components/StatCard";
|
||||
import { StatusBadge } from "@/components/StatusBadge";
|
||||
@@ -152,12 +153,8 @@ export default function DashboardScreen() {
|
||||
<TabScrollView
|
||||
header={<PageHeader title={`Hello, ${firstName}`} subtitle="What needs attention now" />}
|
||||
refreshControl={
|
||||
<RefreshControl
|
||||
refreshing={statsQuery.isRefetching || runningQuery.isRefetching}
|
||||
onRefresh={() => {
|
||||
void statsQuery.refetch();
|
||||
void runningQuery.refetch();
|
||||
}}
|
||||
<PullToRefresh
|
||||
onRefresh={() => Promise.all([statsQuery.refetch(), runningQuery.refetch()])}
|
||||
tintColor={colors.primary}
|
||||
/>
|
||||
}
|
||||
@@ -221,7 +218,10 @@ export default function DashboardScreen() {
|
||||
</Card>
|
||||
|
||||
{running ? (
|
||||
<Pressable onPress={() => router.push("/(app)/timer")}>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
onPress={() => router.push("/(app)/timer")}
|
||||
>
|
||||
<GlassSurface style={styles.runningGlass}>
|
||||
<View style={styles.runningRow}>
|
||||
<View style={styles.runningDot} />
|
||||
@@ -299,6 +299,11 @@ export default function DashboardScreen() {
|
||||
{stats.currentDraft ? (
|
||||
<GlassSurface style={styles.draftGlass}>
|
||||
<Pressable
|
||||
accessible
|
||||
accessibilityLabel={`Current draft, ${
|
||||
stats.currentDraft.client?.name ?? "Client"
|
||||
}, ${formatCurrency(stats.currentDraft.totalAmount)}, ${stats.currentDraft.totalHours.toFixed(1)} hours logged`}
|
||||
accessibilityRole="button"
|
||||
style={styles.draftBanner}
|
||||
onPress={() => router.push(`/(app)/invoices/${stats.currentDraft!.id}`)}
|
||||
>
|
||||
@@ -325,7 +330,12 @@ export default function DashboardScreen() {
|
||||
<View style={styles.statCell}>
|
||||
<StatCard label="Overdue" value={String(stats.overdueCount)} />
|
||||
</View>
|
||||
<Pressable style={styles.statCell} onPress={() => router.push("/(app)/entities")}>
|
||||
<Pressable
|
||||
accessibilityRole="button"
|
||||
accessibilityLabel={`Clients, ${stats.totalClients}`}
|
||||
style={styles.statCell}
|
||||
onPress={() => router.push("/(app)/entities")}
|
||||
>
|
||||
<StatCard label="Clients" value={String(stats.totalClients)} />
|
||||
</Pressable>
|
||||
</View>
|
||||
@@ -354,6 +364,14 @@ export default function DashboardScreen() {
|
||||
const status = getInvoiceStatus(invoice);
|
||||
return (
|
||||
<Pressable
|
||||
accessible
|
||||
accessibilityLabel={`${invoice.invoicePrefix}${invoice.invoiceNumber}, ${
|
||||
invoice.client?.name ?? "Client"
|
||||
}, ${formatDate(invoice.issueDate)}, ${formatCurrency(
|
||||
invoice.totalAmount,
|
||||
invoice.currency,
|
||||
)}, ${status}`}
|
||||
accessibilityRole="button"
|
||||
key={invoice.id}
|
||||
style={({ pressed }) => [styles.recentRow, pressed && styles.pressed]}
|
||||
onPress={() => router.push(`/(app)/invoices/${invoice.id}`)}
|
||||
|
||||
Reference in New Issue
Block a user