14c880123c
Expo app with dashboard, time clock, invoices, and settings — native tabs, glass UI, theme-aware components, and iOS Live Activities. Co-authored-by: Cursor <cursoragent@cursor.com>
65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
import { router } from "expo-router";
|
|
import { Platform, Pressable, StyleSheet, Text, View } from "react-native";
|
|
|
|
import { fonts } from "@/constants/theme";
|
|
import { useAppTheme } from "@/contexts/ThemeContext";
|
|
import { formatElapsedHoursMinutes } from "@/lib/time-clock";
|
|
import { useRunningElapsed } from "@/lib/use-running-elapsed";
|
|
import { api } from "@/lib/trpc";
|
|
|
|
/** Green dot + elapsed time when a timer is running; tappable to open the clock. */
|
|
export function ClockedInIndicator() {
|
|
const { colors } = useAppTheme();
|
|
const runningQuery = api.timeEntries.getRunning.useQuery(undefined, {
|
|
refetchInterval: 30_000,
|
|
});
|
|
const running = runningQuery.data;
|
|
const elapsed = useRunningElapsed(running?.startedAt);
|
|
|
|
if (!running) return null;
|
|
|
|
const label = formatElapsedHoursMinutes(elapsed);
|
|
|
|
return (
|
|
<Pressable
|
|
accessibilityRole="button"
|
|
accessibilityLabel={`Clocked in, ${label}`}
|
|
hitSlop={8}
|
|
onPress={() => router.push("/(app)/timer")}
|
|
style={styles.hit}
|
|
>
|
|
<View style={[styles.row, { backgroundColor: colors.successBg }]}>
|
|
<View style={[styles.dot, { backgroundColor: colors.success }]} />
|
|
<Text style={[styles.time, { color: colors.foreground }]}>{label}</Text>
|
|
</View>
|
|
</Pressable>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
hit: {
|
|
flexShrink: 0,
|
|
},
|
|
row: {
|
|
flexDirection: "row",
|
|
alignItems: "center",
|
|
justifyContent: "center",
|
|
gap: 6,
|
|
paddingHorizontal: 10,
|
|
minHeight: 28,
|
|
borderRadius: 999,
|
|
},
|
|
dot: {
|
|
width: 7,
|
|
height: 7,
|
|
borderRadius: 4,
|
|
},
|
|
time: {
|
|
fontFamily: fonts.mono,
|
|
fontSize: 14,
|
|
lineHeight: 18,
|
|
fontVariant: ["tabular-nums"],
|
|
...(Platform.OS === "android" ? { includeFontPadding: false } : null),
|
|
},
|
|
});
|