import React, { useState, useEffect } from 'react'; import { View, Text, StyleSheet, ScrollView, TouchableOpacity, Modal, TextInput, SafeAreaView, Animated, } from 'react-native'; import { LinearGradient } from 'expo-linear-gradient'; import { Ionicons, Feather, MaterialCommunityIcons, FontAwesome5 } from '@expo/vector-icons'; import { colors, typography, spacing, borderRadius, shadows } from '../theme/colors'; import { VaultAsset, VaultAssetType } from '../types'; import BiometricModal from '../components/common/BiometricModal'; // Asset type configuration with nautical theme const assetTypeConfig: Record = { game_account: { icon: 'gamepad', iconType: 'fontawesome5', label: 'Digital Account' }, private_key: { icon: 'key', iconType: 'fontawesome5', label: 'Secret Key' }, document: { icon: 'scroll', iconType: 'fontawesome5', label: 'Document' }, photo: { icon: 'image', iconType: 'ionicons', label: 'Sealed Photo' }, will: { icon: 'file-signature', iconType: 'fontawesome5', label: 'Testament' }, custom: { icon: 'gem', iconType: 'fontawesome5', label: 'Treasure' }, }; // Mock data const initialAssets: VaultAsset[] = [ { id: '1', type: 'private_key', label: 'ETH Main Wallet Key', createdAt: new Date('2024-01-10'), updatedAt: new Date('2024-01-10'), isEncrypted: true, }, { id: '2', type: 'game_account', label: 'Steam Account Credentials', createdAt: new Date('2024-01-08'), updatedAt: new Date('2024-01-08'), isEncrypted: true, }, { id: '3', type: 'document', label: 'Insurance Policy Scan', createdAt: new Date('2024-01-05'), updatedAt: new Date('2024-01-05'), isEncrypted: true, }, { id: '4', type: 'will', label: 'Testament Draft v2', createdAt: new Date('2024-01-02'), updatedAt: new Date('2024-01-15'), isEncrypted: true, }, ]; const renderAssetTypeIcon = (config: typeof assetTypeConfig[VaultAssetType], size: number, color: string) => { switch (config.iconType) { case 'ionicons': return ; case 'feather': return ; case 'material': return ; case 'fontawesome5': return ; } }; export default function VaultScreen() { const [isUnlocked, setIsUnlocked] = useState(false); const [showBiometric, setShowBiometric] = useState(false); const [assets, setAssets] = useState(initialAssets); const [showAddModal, setShowAddModal] = useState(false); const [selectedType, setSelectedType] = useState('custom'); const [newLabel, setNewLabel] = useState(''); const [showUploadSuccess, setShowUploadSuccess] = useState(false); const [fadeAnim] = useState(new Animated.Value(0)); const [pulseAnim] = useState(new Animated.Value(1)); useEffect(() => { if (!isUnlocked) { const timer = setTimeout(() => { setShowBiometric(true); }, 500); return () => clearTimeout(timer); } }, []); useEffect(() => { if (isUnlocked) { Animated.timing(fadeAnim, { toValue: 1, duration: 600, useNativeDriver: true, }).start(); } }, [isUnlocked]); useEffect(() => { if (!isUnlocked) { Animated.loop( Animated.sequence([ Animated.timing(pulseAnim, { toValue: 1.05, duration: 1500, useNativeDriver: true, }), Animated.timing(pulseAnim, { toValue: 1, duration: 1500, useNativeDriver: true, }), ]) ).start(); } }, [isUnlocked]); const handleUnlock = () => { setShowBiometric(false); setIsUnlocked(true); }; const handleAddAsset = () => { if (!newLabel.trim()) return; const newAsset: VaultAsset = { id: Date.now().toString(), type: selectedType, label: newLabel, createdAt: new Date(), updatedAt: new Date(), isEncrypted: true, }; setAssets([newAsset, ...assets]); setNewLabel(''); setSelectedType('custom'); setShowAddModal(false); setShowUploadSuccess(true); setTimeout(() => setShowUploadSuccess(false), 2500); }; const formatDate = (date: Date) => { return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric', }); }; // Lock screen if (!isUnlocked) { return ( THE DEEP VAULT Where treasures rest in silence setShowBiometric(true)} activeOpacity={0.8} > Captain's Verification setShowBiometric(false)} title="Enter the Vault" message="Verify your identity to access your treasures" isDark /> ); } return ( {/* Header */} THE VAULT SEALED {assets.length} treasures ยท Encrypted at rest {/* Asset List */} {assets.map((asset) => { const config = assetTypeConfig[asset.type]; return ( {renderAssetTypeIcon(config, 22, colors.vault.primary)} {config.label} {asset.label} Sealed {formatDate(asset.createdAt)} ); })} {/* Add Button */} setShowAddModal(true)} activeOpacity={0.9} > Add Treasure {/* Upload Success Toast */} {showUploadSuccess && ( Treasure sealed successfully )} {/* Add Modal */} setShowAddModal(false)} > Add New Treasure TREASURE TYPE {(Object.keys(assetTypeConfig) as VaultAssetType[]).map((type) => { const config = assetTypeConfig[type]; const isSelected = selectedType === type; return ( setSelectedType(type)} > {renderAssetTypeIcon(config, 22, isSelected ? colors.nautical.teal : colors.nautical.sage)} {config.label} ); })} TREASURE NAME Your treasure will be encrypted and sealed. Original data will be securely destroyed. { setShowAddModal(false); setNewLabel(''); }} > Cancel Seal Treasure ); } const styles = StyleSheet.create({ container: { flex: 1, }, gradient: { flex: 1, }, safeArea: { flex: 1, }, content: { flex: 1, }, lockContainer: { flex: 1, }, lockGradient: { flex: 1, }, lockSafeArea: { flex: 1, }, lockContent: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingHorizontal: spacing.xl, }, lockIconContainer: { marginBottom: spacing.lg, }, lockIconGradient: { width: 130, height: 130, borderRadius: 65, justifyContent: 'center', alignItems: 'center', ...shadows.glow, }, lockTitle: { fontSize: typography.fontSize.xxl, fontWeight: '700', color: colors.vault.text, letterSpacing: typography.letterSpacing.widest, marginBottom: spacing.sm, fontFamily: typography.fontFamily.serif, }, lockSubtitle: { fontSize: typography.fontSize.base, color: colors.vault.textSecondary, marginBottom: spacing.xl, textAlign: 'center', fontStyle: 'italic', }, waveContainer: { marginBottom: spacing.xl, }, unlockButton: { borderRadius: borderRadius.lg, overflow: 'hidden', }, unlockButtonGradient: { flexDirection: 'row', alignItems: 'center', paddingVertical: spacing.md, paddingHorizontal: spacing.xl, gap: spacing.sm, }, unlockButtonText: { fontSize: typography.fontSize.base, color: colors.vault.background, fontWeight: '600', }, header: { paddingHorizontal: spacing.lg, paddingTop: spacing.lg, paddingBottom: spacing.md, }, headerTop: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', marginBottom: spacing.xs, }, headerTitleRow: { flexDirection: 'row', alignItems: 'center', gap: spacing.sm, }, title: { fontSize: typography.fontSize.xl, fontWeight: '700', color: colors.vault.text, letterSpacing: typography.letterSpacing.wider, fontFamily: typography.fontFamily.serif, }, securityBadge: { flexDirection: 'row', alignItems: 'center', backgroundColor: `${colors.vault.success}20`, paddingHorizontal: spacing.sm, paddingVertical: spacing.xs, borderRadius: borderRadius.full, gap: spacing.xs, }, securityText: { fontSize: typography.fontSize.xs, color: colors.vault.success, fontWeight: '700', letterSpacing: 1, }, subtitle: { fontSize: typography.fontSize.sm, color: colors.vault.textSecondary, }, assetList: { flex: 1, }, assetListContent: { padding: spacing.lg, paddingTop: spacing.sm, }, assetCard: { flexDirection: 'row', alignItems: 'center', backgroundColor: colors.vault.cardBackground, borderRadius: borderRadius.xl, padding: spacing.base, marginBottom: spacing.md, borderWidth: 1, borderColor: colors.vault.cardBorder, }, assetIconContainer: { width: 52, height: 52, borderRadius: 26, backgroundColor: `${colors.vault.primary}15`, justifyContent: 'center', alignItems: 'center', marginRight: spacing.base, }, assetInfo: { flex: 1, }, assetType: { fontSize: typography.fontSize.xs, color: colors.vault.textSecondary, textTransform: 'uppercase', letterSpacing: 1, marginBottom: 2, fontWeight: '600', }, assetLabel: { fontSize: typography.fontSize.base, color: colors.vault.text, fontWeight: '600', marginBottom: 4, }, assetMetaRow: { flexDirection: 'row', alignItems: 'center', gap: spacing.xs, }, assetMeta: { fontSize: typography.fontSize.xs, color: colors.vault.textSecondary, }, encryptedBadge: { width: 36, height: 36, borderRadius: 18, backgroundColor: colors.vault.success, justifyContent: 'center', alignItems: 'center', }, addButton: { position: 'absolute', bottom: 100, left: spacing.lg, right: spacing.lg, borderRadius: borderRadius.lg, overflow: 'hidden', }, addButtonGradient: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: spacing.md, gap: spacing.sm, }, addButtonText: { fontSize: typography.fontSize.base, color: colors.vault.background, fontWeight: '700', }, successToast: { position: 'absolute', bottom: 170, left: spacing.lg, right: spacing.lg, flexDirection: 'row', alignItems: 'center', justifyContent: 'center', backgroundColor: colors.vault.success, paddingVertical: spacing.md, borderRadius: borderRadius.lg, gap: spacing.sm, }, successText: { fontSize: typography.fontSize.base, color: '#fff', fontWeight: '600', }, modalOverlay: { flex: 1, backgroundColor: 'rgba(26, 58, 74, 0.8)', justifyContent: 'flex-end', }, modalContent: { backgroundColor: colors.nautical.cream, borderTopLeftRadius: borderRadius.xxl, borderTopRightRadius: borderRadius.xxl, padding: spacing.lg, paddingBottom: spacing.xxl, }, modalHandle: { width: 40, height: 4, backgroundColor: colors.nautical.lightMint, borderRadius: 2, alignSelf: 'center', marginBottom: spacing.lg, }, modalHeader: { flexDirection: 'row', alignItems: 'center', gap: spacing.sm, marginBottom: spacing.lg, }, modalTitle: { fontSize: typography.fontSize.lg, fontWeight: '600', color: colors.nautical.navy, }, modalLabel: { fontSize: typography.fontSize.xs, color: colors.nautical.sage, marginBottom: spacing.sm, letterSpacing: typography.letterSpacing.wider, fontWeight: '600', }, typeScroll: { marginBottom: spacing.lg, }, typeScrollContent: { gap: spacing.sm, }, typeButton: { alignItems: 'center', paddingVertical: spacing.sm, paddingHorizontal: spacing.base, borderRadius: borderRadius.lg, backgroundColor: colors.nautical.paleAqua, borderWidth: 2, borderColor: 'transparent', minWidth: 100, }, typeButtonActive: { borderColor: colors.nautical.teal, backgroundColor: colors.nautical.lightMint, }, typeIconContainer: { width: 44, height: 44, borderRadius: 22, backgroundColor: colors.nautical.cream, justifyContent: 'center', alignItems: 'center', marginBottom: spacing.xs, }, typeIconContainerActive: { backgroundColor: `${colors.nautical.teal}15`, }, typeButtonLabel: { fontSize: typography.fontSize.xs, color: colors.nautical.sage, textAlign: 'center', fontWeight: '500', }, typeButtonLabelActive: { color: colors.nautical.teal, fontWeight: '600', }, input: { backgroundColor: colors.nautical.paleAqua, borderRadius: borderRadius.lg, padding: spacing.base, fontSize: typography.fontSize.base, color: colors.nautical.navy, marginBottom: spacing.md, borderWidth: 1, borderColor: colors.nautical.lightMint, }, encryptionNote: { flexDirection: 'row', alignItems: 'center', backgroundColor: colors.nautical.lightMint, borderRadius: borderRadius.lg, padding: spacing.md, marginBottom: spacing.lg, gap: spacing.sm, }, encryptionNoteText: { flex: 1, fontSize: typography.fontSize.sm, color: colors.nautical.teal, lineHeight: typography.fontSize.sm * 1.4, }, modalButtons: { flexDirection: 'row', gap: spacing.md, }, cancelButton: { flex: 1, paddingVertical: spacing.md, borderRadius: borderRadius.lg, backgroundColor: colors.nautical.paleAqua, alignItems: 'center', borderWidth: 1, borderColor: colors.nautical.lightMint, }, cancelButtonText: { fontSize: typography.fontSize.base, color: colors.nautical.sage, fontWeight: '600', }, confirmButton: { flex: 1, borderRadius: borderRadius.lg, overflow: 'hidden', }, confirmButtonGradient: { flexDirection: 'row', alignItems: 'center', justifyContent: 'center', paddingVertical: spacing.md, gap: spacing.sm, }, confirmButtonText: { fontSize: typography.fontSize.base, color: '#fff', fontWeight: '600', }, });