122 lines
3.0 KiB
TypeScript
122 lines
3.0 KiB
TypeScript
import { useFocusEffect } from '@react-navigation/native';
|
|
import React from 'react';
|
|
import { Pressable, SafeAreaView, ScrollView, StyleSheet, Text, View } from 'react-native';
|
|
|
|
import { useApp } from '@/src/app-context';
|
|
|
|
export default function ActivityScreen() {
|
|
const { state, actions } = useApp();
|
|
|
|
useFocusEffect(
|
|
React.useCallback(() => {
|
|
actions.setPage('activity');
|
|
return undefined;
|
|
}, [actions]),
|
|
);
|
|
|
|
return (
|
|
<SafeAreaView style={styles.safe}>
|
|
<View style={styles.header}>
|
|
<Text style={styles.title}>Activity History</Text>
|
|
<Pressable style={styles.clearButton} onPress={actions.clearNotifications}>
|
|
<Text style={styles.clearButtonText}>Clear Read</Text>
|
|
</Pressable>
|
|
</View>
|
|
|
|
<ScrollView contentContainerStyle={styles.content}>
|
|
{state.motionNotifications.length === 0 ? (
|
|
<View style={styles.emptyState}>
|
|
<Text style={styles.emptyText}>All quiet. No notifications yet.</Text>
|
|
</View>
|
|
) : (
|
|
state.motionNotifications.map((notification) => (
|
|
<Pressable
|
|
key={notification.id}
|
|
style={[styles.item, notification.isRead ? styles.readItem : styles.unreadItem]}
|
|
onPress={() =>
|
|
void actions.openMotionNotificationTarget(notification.id, notification.cameraDeviceId)
|
|
}>
|
|
<Text style={styles.itemMessage}>{notification.message}</Text>
|
|
<Text style={styles.itemDate}>{new Date(notification.createdAt).toLocaleString()}</Text>
|
|
</Pressable>
|
|
))
|
|
)}
|
|
</ScrollView>
|
|
</SafeAreaView>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
safe: {
|
|
flex: 1,
|
|
backgroundColor: '#0a0a0c',
|
|
},
|
|
header: {
|
|
paddingHorizontal: 14,
|
|
paddingTop: 8,
|
|
paddingBottom: 10,
|
|
flexDirection: 'row',
|
|
alignItems: 'center',
|
|
justifyContent: 'space-between',
|
|
},
|
|
title: {
|
|
color: '#f9fafb',
|
|
fontSize: 22,
|
|
fontWeight: '700',
|
|
},
|
|
clearButton: {
|
|
borderRadius: 10,
|
|
borderWidth: 1,
|
|
borderColor: 'rgba(255,255,255,0.16)',
|
|
paddingHorizontal: 10,
|
|
height: 34,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
clearButtonText: {
|
|
color: '#d1d5db',
|
|
fontSize: 12,
|
|
fontWeight: '600',
|
|
},
|
|
content: {
|
|
padding: 14,
|
|
gap: 10,
|
|
},
|
|
emptyState: {
|
|
borderRadius: 16,
|
|
borderWidth: 1,
|
|
borderStyle: 'dashed',
|
|
borderColor: 'rgba(255,255,255,0.2)',
|
|
backgroundColor: '#111218',
|
|
padding: 26,
|
|
alignItems: 'center',
|
|
},
|
|
emptyText: {
|
|
color: '#6b7280',
|
|
fontSize: 13,
|
|
},
|
|
item: {
|
|
borderRadius: 12,
|
|
borderWidth: 1,
|
|
padding: 12,
|
|
gap: 6,
|
|
},
|
|
unreadItem: {
|
|
backgroundColor: '#14213d',
|
|
borderColor: '#1d4ed8',
|
|
},
|
|
readItem: {
|
|
backgroundColor: '#111218',
|
|
borderColor: 'rgba(255,255,255,0.08)',
|
|
},
|
|
itemMessage: {
|
|
color: '#e5e7eb',
|
|
fontSize: 12,
|
|
fontWeight: '500',
|
|
},
|
|
itemDate: {
|
|
color: '#6b7280',
|
|
fontSize: 11,
|
|
},
|
|
});
|