learning_ai_invt_trdg/mobile/app/marketplace.tsx

230 lines
6.4 KiB
TypeScript

import React from 'react';
import { View, Text, ScrollView, Pressable, StyleSheet } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { useRouter } from 'expo-router';
import { LinearGradient } from 'expo-linear-gradient';
import { ArrowLeft } from 'lucide-react-native';
import { Colors, Fonts, FontSize, BorderRadius, Shadows, Spacing } from '@/constants/theme';
import { marketplacePresets } from '@/constants/mockData';
import AnimatedCard from '@/components/AnimatedCard';
import PillBadge from '@/components/PillBadge';
import PressableScale from '@/components/PressableScale';
const RISK_COLORS: Record<string, { color: string; label: string }> = {
aggressive: { color: Colors.accent.orange, label: 'Aggressive' },
balanced: { color: Colors.accent.green, label: 'Balanced' },
safe: { color: Colors.accent.blue, label: 'Conservative' },
};
export default function MarketplaceScreen() {
const insets = useSafeAreaInsets();
const router = useRouter();
return (
<View style={[styles.container, { paddingTop: insets.top }]}>
<View style={styles.headerSection}>
<Pressable onPress={() => router.back()} style={styles.backBtn}>
<ArrowLeft size={22} color={Colors.text.primary} />
</Pressable>
<View>
<Text style={styles.sectionLabel}>MARKETPLACE</Text>
<Text style={styles.pageTitle}>
Strategy <Text style={{ color: Colors.accent.green }}>Marketplace</Text>
</Text>
</View>
</View>
<ScrollView
style={styles.scroll}
contentContainerStyle={styles.content}
showsVerticalScrollIndicator={false}
>
{marketplacePresets.map((preset, index) => {
const risk = RISK_COLORS[preset.risk];
return (
<AnimatedCard key={preset.id} index={index} style={[Shadows.card, { borderRadius: 28 }]}>
<PressableScale style={styles.cardOuter}>
<View style={styles.card}>
{preset.isPopular && (
<View style={styles.popularBadge}>
<Text style={styles.popularText}>Popular</Text>
</View>
)}
<Text style={styles.presetName}>{preset.name}</Text>
<Text style={styles.presetDesc}>{preset.description}</Text>
<View style={styles.metaRow}>
<PillBadge label={risk.label} color={risk.color} bgColor={`${risk.color}20`} />
<Text style={styles.tradesPerDay}>{preset.trades}</Text>
</View>
<View style={styles.assetPills}>
{preset.assets.map(a => (
<View key={a} style={styles.assetPill}>
<Text style={styles.assetText}>{a}</Text>
</View>
))}
</View>
<View style={styles.tagRow}>
<Text style={styles.tagText}>{preset.tag}</Text>
</View>
<PressableScale
haptic="medium"
style={styles.ctaWrapper}
>
<LinearGradient
colors={['#00ff88', '#00cc6a']}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={styles.ctaButton}
>
<Text style={styles.ctaText}>USE STRATEGY</Text>
</LinearGradient>
</PressableScale>
</View>
</PressableScale>
</AnimatedCard>
);
})}
</ScrollView>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: Colors.background.primary,
},
headerSection: {
padding: Spacing.screenPadding,
flexDirection: 'row',
alignItems: 'center',
gap: 14,
},
backBtn: {
width: 40,
height: 40,
borderRadius: 12,
backgroundColor: Colors.background.card,
alignItems: 'center',
justifyContent: 'center',
borderWidth: 1,
borderColor: Colors.border.default,
},
sectionLabel: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.micro,
color: Colors.accent.green,
letterSpacing: 4,
marginBottom: 4,
},
pageTitle: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.heading,
color: Colors.text.primary,
},
scroll: {
flex: 1,
},
content: {
padding: Spacing.screenPadding,
gap: 20,
paddingBottom: 60,
},
cardOuter: {
borderRadius: 28,
},
card: {
backgroundColor: Colors.background.card,
borderRadius: 28,
padding: 32,
borderWidth: 1,
borderColor: Colors.border.default,
gap: 14,
},
popularBadge: {
alignSelf: 'flex-start',
backgroundColor: 'rgba(0,255,136,0.05)',
borderWidth: 1,
borderColor: 'rgba(0,255,136,0.1)',
paddingHorizontal: 12,
paddingVertical: 4,
borderRadius: 8,
},
popularText: {
fontFamily: Fonts.inter.bold,
fontSize: FontSize.badge,
color: Colors.accent.green,
},
presetName: {
fontFamily: Fonts.inter.black,
fontSize: 18,
color: Colors.text.primary,
},
presetDesc: {
fontFamily: Fonts.inter.medium,
fontSize: FontSize.body,
color: Colors.text.secondary,
lineHeight: 20,
},
metaRow: {
flexDirection: 'row',
alignItems: 'center',
gap: 12,
},
tradesPerDay: {
fontFamily: Fonts.mono.medium,
fontSize: FontSize.bodySmall,
color: Colors.text.secondary,
},
assetPills: {
flexDirection: 'row',
gap: 6,
flexWrap: 'wrap',
},
assetPill: {
backgroundColor: 'rgba(255,255,255,0.05)',
paddingHorizontal: 10,
paddingVertical: 4,
borderRadius: BorderRadius.xs,
},
assetText: {
fontFamily: Fonts.mono.medium,
fontSize: FontSize.micro,
color: Colors.text.secondary,
},
tagRow: {
marginTop: 2,
},
tagText: {
fontFamily: Fonts.mono.bold,
fontSize: FontSize.body,
color: Colors.accent.green,
},
ctaWrapper: {
marginTop: 6,
borderRadius: 18,
shadowColor: 'rgba(0,255,136,0.4)',
shadowOffset: { width: 0, height: 12 },
shadowOpacity: 1,
shadowRadius: 36,
elevation: 8,
},
ctaButton: {
height: 56,
borderRadius: 18,
alignItems: 'center',
justifyContent: 'center',
},
ctaText: {
fontFamily: Fonts.inter.black,
fontSize: FontSize.bodySmall,
color: '#000',
letterSpacing: 2,
},
});