learning_ai_invt_trdg/mobile/components/dashboard/ActiveAlerts.tsx

133 lines
3.5 KiB
TypeScript

import React from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { Colors, Fonts, FontSize, BorderRadius } from '@/constants/theme';
import AnimatedCard from '@/components/AnimatedCard';
import { useTradingData } from '@/providers/TradingDataProvider';
type AlertType = 'signal' | 'error' | 'pulse' | 'info';
const ALERT_COLORS: Record<AlertType, string> = {
signal: Colors.accent.green,
pulse: '#4da6ff',
error: Colors.accent.red,
info: '#888888',
};
const ALERT_ICONS: Record<AlertType, string> = {
signal: '\u{1F680}',
pulse: '\u{23F0}',
error: '\u{26A0}\u{FE0F}',
info: '\u{2139}\u{FE0F}',
};
export default function ActiveAlerts() {
const { botState } = useTradingData();
const alerts = (botState?.alerts || []).slice(0, 5).map((alert, index) => ({
id: `${alert.symbol}-${alert.timestamp}-${index}`,
...alert,
timestampLabel: formatTimeAgo(alert.timestamp),
}));
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.title}>RECENT ALERTS</Text>
<View style={styles.countBadge}>
<Text style={styles.countText}>{alerts.length}</Text>
</View>
</View>
{alerts.map((alert, index) => (
<AnimatedCard key={alert.id} index={index} style={styles.alertCard}>
<View style={[styles.leftBorder, { backgroundColor: ALERT_COLORS[alert.type] }]} />
<View style={styles.alertContent}>
<View style={styles.alertHeader}>
<Text style={styles.icon}>{ALERT_ICONS[alert.type]}</Text>
<Text style={styles.symbol}>{alert.symbol}</Text>
<Text style={styles.timestamp}>{alert.timestampLabel}</Text>
</View>
<Text style={styles.message}>{alert.message}</Text>
</View>
</AnimatedCard>
))}
</View>
);
}
function formatTimeAgo(timestamp: number) {
const deltaSeconds = Math.max(0, Math.floor((Date.now() - timestamp) / 1000));
if (deltaSeconds < 60) return `${deltaSeconds}s ago`;
if (deltaSeconds < 3600) return `${Math.floor(deltaSeconds / 60)}m ago`;
return `${Math.floor(deltaSeconds / 3600)}h ago`;
}
const styles = StyleSheet.create({
container: {
gap: 10,
},
header: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
marginBottom: 4,
},
title: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.micro,
color: Colors.text.secondary,
letterSpacing: 3,
},
countBadge: {
backgroundColor: 'rgba(0,255,136,0.15)',
paddingHorizontal: 8,
paddingVertical: 2,
borderRadius: 6,
},
countText: {
fontFamily: Fonts.mono.bold,
fontSize: FontSize.micro,
color: Colors.accent.green,
},
alertCard: {
backgroundColor: 'rgba(255,255,255,0.03)',
borderRadius: BorderRadius.small,
borderWidth: 1,
borderColor: Colors.border.subtle,
flexDirection: 'row',
overflow: 'hidden',
},
leftBorder: {
width: 3,
},
alertContent: {
flex: 1,
padding: 14,
gap: 6,
},
alertHeader: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
},
icon: {
fontSize: 14,
},
symbol: {
fontFamily: Fonts.inter.extraBold,
fontSize: FontSize.badge,
color: Colors.text.primary,
},
timestamp: {
fontFamily: Fonts.inter.medium,
fontSize: FontSize.micro,
color: Colors.text.secondary,
marginLeft: 'auto',
},
message: {
fontFamily: Fonts.inter.medium,
fontSize: FontSize.body,
color: Colors.text.primary,
lineHeight: 18,
},
});