learning_ai_invt_trdg/mobile/app/(tabs)/settings.tsx

454 lines
13 KiB
TypeScript

import React, { useState } from 'react';
import { View, Text, ScrollView, Switch, TextInput, StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { LinearGradient } from 'expo-linear-gradient';
import { ChevronRight, Lock, Check, X } from 'lucide-react-native';
import { Colors, Fonts, FontSize, BorderRadius, Spacing } from '@/constants/theme';
import SegmentedControl from '@/components/SegmentedControl';
import AnimatedCard from '@/components/AnimatedCard';
import PressableScale from '@/components/PressableScale';
export default function SettingsScreen() {
const insets = useSafeAreaInsets();
const [executionMode, setExecutionMode] = useState(1);
const [riskPercent, setRiskPercent] = useState(1);
const [maxOpenTrades, setMaxOpenTrades] = useState(3);
const [notifications, setNotifications] = useState({
priceAlerts: true,
tradeExecuted: true,
stopLoss: true,
dailySummary: false,
});
const [oledBlack, setOledBlack] = useState(false);
const modeColors = [Colors.text.secondary, Colors.accent.blue, Colors.accent.orange];
return (
<View style={[styles.container, { paddingTop: insets.top }]}>
<View style={styles.headerSection}>
<Text style={styles.sectionLabel}>CONFIGURATION</Text>
<Text style={styles.pageTitle}>Settings</Text>
</View>
<ScrollView
style={styles.scroll}
contentContainerStyle={styles.content}
showsVerticalScrollIndicator={false}
>
<AnimatedCard index={0}>
<View style={styles.section}>
<Text style={styles.sectionHeader}>ACCOUNT</Text>
<View style={styles.accountRow}>
<LinearGradient
colors={['#00ff88', '#00cc6a']}
style={styles.avatar}
>
<Text style={styles.avatarText}>SK</Text>
</LinearGradient>
<View style={styles.accountInfo}>
<Text style={styles.accountName}>Saravana Kumar</Text>
<Text style={styles.accountEmail}>saravana@bytelyst.ai</Text>
</View>
<View style={styles.tierBadge}>
<Text style={styles.tierText}>ELITE</Text>
</View>
</View>
</View>
</AnimatedCard>
<AnimatedCard index={1}>
<View style={styles.section}>
<Text style={styles.sectionHeader}>EXECUTION MODE</Text>
<SegmentedControl
segments={['Alerts', 'Paper', 'Live']}
activeIndex={executionMode}
onPress={setExecutionMode}
activeColor={modeColors[executionMode]}
activeTextColor={executionMode === 2 ? '#fff' : '#000'}
/>
{executionMode === 2 && (
<View style={styles.warningBanner}>
<Text style={styles.warningText}>
Real money trading enabled. Use caution.
</Text>
</View>
)}
</View>
</AnimatedCard>
<AnimatedCard index={2}>
<View style={styles.section}>
<Text style={styles.sectionHeader}>RISK CONFIGURATION</Text>
<SettingRow label="Risk Per Trade">
<View style={styles.sliderRow}>
<View style={styles.sliderTrack}>
<View style={[styles.sliderFill, { width: `${((riskPercent - 0.5) / 4.5) * 100}%` as any }]} />
</View>
<Text style={styles.sliderValue}>{riskPercent.toFixed(1)}%</Text>
</View>
</SettingRow>
<SettingRow label="Max Open Trades">
<View style={styles.stepperRow}>
<PressableScale
style={styles.stepperBtn}
onPress={() => setMaxOpenTrades(Math.max(1, maxOpenTrades - 1))}
>
<Text style={styles.stepperBtnText}>-</Text>
</PressableScale>
<Text style={styles.stepperValue}>{maxOpenTrades}</Text>
<PressableScale
style={styles.stepperBtn}
onPress={() => setMaxOpenTrades(Math.min(10, maxOpenTrades + 1))}
>
<Text style={styles.stepperBtnText}>+</Text>
</PressableScale>
</View>
</SettingRow>
<SettingRow label="Total Capital">
<Text style={styles.capitalValue}>$25,000</Text>
</SettingRow>
</View>
</AnimatedCard>
<AnimatedCard index={3}>
<View style={styles.section}>
<Text style={styles.sectionHeader}>BROKER CONNECTION</Text>
<View style={styles.brokerRow}>
<Text style={styles.brokerName}>Alpaca</Text>
<View style={styles.connectedBadge}>
<Check size={12} color={Colors.accent.green} />
<Text style={styles.connectedText}>Connected</Text>
</View>
</View>
<Text style={styles.apiKeyHint}>API Key: k3xR</Text>
</View>
</AnimatedCard>
<AnimatedCard index={4}>
<View style={styles.section}>
<Text style={styles.sectionHeader}>NOTIFICATIONS</Text>
<ToggleRow
label="Price Alerts"
value={notifications.priceAlerts}
onChange={(v) => setNotifications(n => ({ ...n, priceAlerts: v }))}
/>
<ToggleRow
label="Trade Executed"
value={notifications.tradeExecuted}
onChange={(v) => setNotifications(n => ({ ...n, tradeExecuted: v }))}
/>
<ToggleRow
label="Stop Loss Hit"
value={notifications.stopLoss}
onChange={(v) => setNotifications(n => ({ ...n, stopLoss: v }))}
/>
<ToggleRow
label="Daily Summary"
value={notifications.dailySummary}
onChange={(v) => setNotifications(n => ({ ...n, dailySummary: v }))}
/>
</View>
</AnimatedCard>
<AnimatedCard index={5}>
<View style={styles.section}>
<Text style={styles.sectionHeader}>APPEARANCE</Text>
<View style={styles.toggleRow}>
<View style={styles.toggleLabel}>
<Text style={styles.toggleText}>Dark Mode</Text>
<Lock size={14} color={Colors.text.muted} />
</View>
<Switch
value={true}
disabled
trackColor={{ false: Colors.background.elevated, true: 'rgba(0,255,136,0.3)' }}
thumbColor={Colors.accent.green}
/>
</View>
<ToggleRow
label="OLED Black"
value={oledBlack}
onChange={setOledBlack}
/>
</View>
</AnimatedCard>
<AnimatedCard index={6}>
<View style={styles.section}>
<Text style={styles.sectionHeader}>ABOUT</Text>
<View style={styles.aboutRow}>
<Text style={styles.aboutLabel}>Version</Text>
<Text style={styles.aboutValue}>v2.3</Text>
</View>
<PressableScale style={styles.linkRow}>
<Text style={styles.linkText}>Terms of Service</Text>
<ChevronRight size={16} color={Colors.text.muted} />
</PressableScale>
<PressableScale style={styles.linkRow}>
<Text style={styles.linkText}>Support</Text>
<ChevronRight size={16} color={Colors.text.muted} />
</PressableScale>
</View>
</AnimatedCard>
</ScrollView>
</View>
);
}
function SettingRow({ label, children }: { label: string; children: React.ReactNode }) {
return (
<View style={styles.settingRow}>
<Text style={styles.settingLabel}>{label}</Text>
{children}
</View>
);
}
function ToggleRow({ label, value, onChange }: { label: string; value: boolean; onChange: (v: boolean) => void }) {
return (
<View style={styles.toggleRow}>
<Text style={styles.toggleText}>{label}</Text>
<Switch
value={value}
onValueChange={onChange}
trackColor={{ false: Colors.background.elevated, true: 'rgba(0,255,136,0.3)' }}
thumbColor={value ? Colors.accent.green : '#666'}
/>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.background.primary,
},
headerSection: {
padding: Spacing.screenPadding,
paddingBottom: 0,
},
sectionLabel: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.micro,
color: Colors.accent.green,
letterSpacing: 4,
marginBottom: 8,
},
pageTitle: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.hero,
color: Colors.text.primary,
letterSpacing: -0.5,
marginBottom: 16,
},
scroll: {
flex: 1,
},
content: {
padding: Spacing.screenPadding,
gap: 16,
paddingBottom: 120,
},
section: {
backgroundColor: Colors.background.card,
borderRadius: BorderRadius.large,
padding: Spacing.cardPadding,
borderWidth: 1,
borderColor: Colors.border.default,
gap: 14,
},
sectionHeader: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.micro,
color: Colors.text.secondary,
letterSpacing: 3,
},
accountRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 14,
},
avatar: {
width: 48,
height: 48,
borderRadius: 24,
alignItems: 'center',
justifyContent: 'center',
},
avatarText: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.subheading,
color: '#000',
},
accountInfo: {
flex: 1,
},
accountName: {
fontFamily: Fonts.inter.extraBold,
fontSize: FontSize.subheading,
color: Colors.text.primary,
},
accountEmail: {
fontFamily: Fonts.inter.medium,
fontSize: FontSize.body,
color: Colors.text.secondary,
},
tierBadge: {
backgroundColor: 'rgba(0,255,136,0.1)',
borderWidth: 1,
borderColor: 'rgba(0,255,136,0.2)',
paddingHorizontal: 10,
paddingVertical: 4,
borderRadius: 6,
},
tierText: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.micro,
color: Colors.accent.green,
letterSpacing: 1,
},
warningBanner: {
backgroundColor: 'rgba(230,126,34,0.1)',
borderWidth: 1,
borderColor: 'rgba(230,126,34,0.2)',
borderRadius: BorderRadius.xs,
padding: 12,
marginTop: 4,
},
warningText: {
fontFamily: Fonts.inter.semiBold,
fontSize: FontSize.bodySmall,
color: Colors.accent.orange,
},
settingRow: {
gap: 10,
},
settingLabel: {
fontFamily: Fonts.inter.semiBold,
fontSize: FontSize.body,
color: Colors.text.primary,
},
sliderRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
sliderTrack: {
flex: 1,
height: 6,
borderRadius: 3,
backgroundColor: Colors.background.elevated,
overflow: 'hidden',
},
sliderFill: {
height: 6,
borderRadius: 3,
backgroundColor: Colors.accent.green,
},
sliderValue: {
fontFamily: Fonts.mono.bold,
fontSize: FontSize.bodyLarge,
color: Colors.accent.green,
minWidth: 40,
textAlign: 'right',
},
stepperRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 16,
},
stepperBtn: {
width: 36,
height: 36,
borderRadius: 10,
backgroundColor: Colors.background.elevated,
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: Colors.border.subtle,
},
stepperBtnText: {
fontFamily: Fonts.inter.bold,
fontSize: FontSize.heading,
color: Colors.text.primary,
},
stepperValue: {
fontFamily: Fonts.mono.bold,
fontSize: FontSize.heading,
color: Colors.text.primary,
minWidth: 30,
textAlign: 'center',
},
capitalValue: {
fontFamily: Fonts.mono.bold,
fontSize: FontSize.subheading,
color: Colors.text.primary,
},
brokerRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
brokerName: {
fontFamily: Fonts.inter.bold,
fontSize: FontSize.bodyLarge,
color: Colors.text.primary,
},
connectedBadge: {
flexDirection: 'row',
alignItems: 'center',
gap: 6,
},
connectedText: {
fontFamily: Fonts.inter.semiBold,
fontSize: FontSize.bodySmall,
color: Colors.accent.green,
},
apiKeyHint: {
fontFamily: Fonts.mono.regular,
fontSize: FontSize.bodySmall,
color: Colors.text.muted,
},
toggleRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
toggleLabel: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
},
toggleText: {
fontFamily: Fonts.inter.semiBold,
fontSize: FontSize.body,
color: Colors.text.primary,
},
aboutRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
aboutLabel: {
fontFamily: Fonts.inter.medium,
fontSize: FontSize.body,
color: Colors.text.secondary,
},
aboutValue: {
fontFamily: Fonts.mono.medium,
fontSize: FontSize.body,
color: Colors.text.primary,
},
linkRow: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
paddingVertical: 4,
},
linkText: {
fontFamily: Fonts.inter.semiBold,
fontSize: FontSize.body,
color: Colors.text.primary,
},
});