mirror of
https://github.com/pezkuwichain/pwap.git
synced 2026-04-22 06:47:55 +00:00
Integrate Polkadot.js blockchain with mobile wallet (FAZ 1)
This commit implements the complete blockchain integration for the mobile app's wallet functionality: **Polkadot.js Integration:** - Created PolkadotContext for mobile with full blockchain connectivity - Implemented wallet creation with mnemonic seed phrases - Added secure key management with AsyncStorage - Connected to Pezkuwi testnet (wss://beta-rpc.pezkuwi.art) **WalletScreen Enhancements:** - Live blockchain balance fetching for HEZ (native token) - Live balance fetching for PEZ and wUSDT (assets) - Real-time balance updates every 30 seconds - Actual send transactions using api.tx.balances.transfer (HEZ) - Actual send transactions using api.tx.assets.transfer (PEZ, wUSDT) - Transaction signing with user's keypair - Loading states and error handling - Wallet creation flow for new users - Connect/disconnect wallet functionality **Bottom Navigation:** - Created BottomTabNavigator with 5 tabs - Added WalletScreen with live blockchain integration - Added BeCitizenScreen (citizenship application) - Added ReferralScreen (referral program) - Renamed SettingsScreen to ProfileScreen - Custom center button for "Be Citizen" feature **App Structure:** - Wrapped app with PolkadotProvider in App.tsx - Updated AppNavigator to use BottomTabNavigator - Integrated language selection flow with blockchain features All wallet features now use live blockchain data instead of mock data.
This commit is contained in:
@@ -0,0 +1,309 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
StatusBar,
|
||||
Alert,
|
||||
} from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useLanguage } from '../contexts/LanguageContext';
|
||||
import { languages } from '../i18n';
|
||||
import AppColors, { KurdistanColors } from '../theme/colors';
|
||||
|
||||
interface SettingsScreenProps {
|
||||
onBack: () => void;
|
||||
onLogout: () => void;
|
||||
}
|
||||
|
||||
const SettingsScreen: React.FC<SettingsScreenProps> = ({ onBack, onLogout }) => {
|
||||
const { t } = useTranslation();
|
||||
const { currentLanguage, changeLanguage } = useLanguage();
|
||||
|
||||
const handleLanguageChange = async (languageCode: string) => {
|
||||
if (languageCode === currentLanguage) return;
|
||||
|
||||
Alert.alert(
|
||||
'Change Language',
|
||||
`Switch to ${languages.find(l => l.code === languageCode)?.nativeName}?`,
|
||||
[
|
||||
{ text: t('common.cancel'), style: 'cancel' },
|
||||
{
|
||||
text: t('common.confirm'),
|
||||
onPress: async () => {
|
||||
await changeLanguage(languageCode);
|
||||
Alert.alert(
|
||||
t('common.success'),
|
||||
'Language updated successfully! The app will now use your selected language.'
|
||||
);
|
||||
},
|
||||
},
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
const handleLogout = () => {
|
||||
Alert.alert(
|
||||
t('settings.logout'),
|
||||
'Are you sure you want to logout?',
|
||||
[
|
||||
{ text: t('common.cancel'), style: 'cancel' },
|
||||
{
|
||||
text: t('settings.logout'),
|
||||
style: 'destructive',
|
||||
onPress: onLogout,
|
||||
},
|
||||
]
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<StatusBar barStyle="dark-content" />
|
||||
|
||||
{/* Header */}
|
||||
<View style={styles.header}>
|
||||
<TouchableOpacity onPress={onBack} style={styles.backButton}>
|
||||
<Text style={styles.backButtonText}>←</Text>
|
||||
</TouchableOpacity>
|
||||
<Text style={styles.headerTitle}>{t('settings.title')}</Text>
|
||||
<View style={styles.placeholder} />
|
||||
</View>
|
||||
|
||||
<ScrollView showsVerticalScrollIndicator={false}>
|
||||
{/* Language Section */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{t('settings.language')}</Text>
|
||||
{languages.map((language) => (
|
||||
<TouchableOpacity
|
||||
key={language.code}
|
||||
style={[
|
||||
styles.languageItem,
|
||||
currentLanguage === language.code && styles.languageItemActive,
|
||||
]}
|
||||
onPress={() => handleLanguageChange(language.code)}
|
||||
>
|
||||
<View style={styles.languageInfo}>
|
||||
<Text style={[
|
||||
styles.languageName,
|
||||
currentLanguage === language.code && styles.languageNameActive,
|
||||
]}>
|
||||
{language.nativeName}
|
||||
</Text>
|
||||
<Text style={styles.languageSubtext}>{language.name}</Text>
|
||||
</View>
|
||||
{currentLanguage === language.code && (
|
||||
<View style={styles.checkmark}>
|
||||
<Text style={styles.checkmarkText}>✓</Text>
|
||||
</View>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{/* Theme Section */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{t('settings.theme')}</Text>
|
||||
<TouchableOpacity style={styles.settingItem}>
|
||||
<Text style={styles.settingText}>Dark Mode</Text>
|
||||
<Text style={styles.settingValue}>Off</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Notifications Section */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{t('settings.notifications')}</Text>
|
||||
<TouchableOpacity style={styles.settingItem}>
|
||||
<Text style={styles.settingText}>Push Notifications</Text>
|
||||
<Text style={styles.settingValue}>Enabled</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.settingItem}>
|
||||
<Text style={styles.settingText}>Transaction Alerts</Text>
|
||||
<Text style={styles.settingValue}>Enabled</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Security Section */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{t('settings.security')}</Text>
|
||||
<TouchableOpacity style={styles.settingItem}>
|
||||
<Text style={styles.settingText}>Biometric Login</Text>
|
||||
<Text style={styles.settingValue}>Disabled</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.settingItem}>
|
||||
<Text style={styles.settingText}>Change Password</Text>
|
||||
<Text style={styles.settingValue}>→</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* About Section */}
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>{t('settings.about')}</Text>
|
||||
<View style={styles.settingItem}>
|
||||
<Text style={styles.settingText}>Version</Text>
|
||||
<Text style={styles.settingValue}>1.0.0</Text>
|
||||
</View>
|
||||
<TouchableOpacity style={styles.settingItem}>
|
||||
<Text style={styles.settingText}>Terms of Service</Text>
|
||||
<Text style={styles.settingValue}>→</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity style={styles.settingItem}>
|
||||
<Text style={styles.settingText}>Privacy Policy</Text>
|
||||
<Text style={styles.settingValue}>→</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
{/* Logout Button */}
|
||||
<TouchableOpacity
|
||||
style={styles.logoutButton}
|
||||
onPress={handleLogout}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
<Text style={styles.logoutButtonText}>{t('settings.logout')}</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={styles.footer}>
|
||||
<Text style={styles.footerText}>
|
||||
Pezkuwi Blockchain • {new Date().getFullYear()}
|
||||
</Text>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: '#F5F5F5',
|
||||
},
|
||||
header: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
padding: 20,
|
||||
backgroundColor: KurdistanColors.spi,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#E0E0E0',
|
||||
},
|
||||
backButton: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
backButtonText: {
|
||||
fontSize: 24,
|
||||
color: KurdistanColors.kesk,
|
||||
},
|
||||
headerTitle: {
|
||||
fontSize: 18,
|
||||
fontWeight: '600',
|
||||
color: KurdistanColors.reş,
|
||||
},
|
||||
placeholder: {
|
||||
width: 40,
|
||||
},
|
||||
section: {
|
||||
marginTop: 20,
|
||||
paddingHorizontal: 20,
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 14,
|
||||
fontWeight: '600',
|
||||
color: '#999',
|
||||
marginBottom: 12,
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
languageItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: KurdistanColors.spi,
|
||||
padding: 16,
|
||||
borderRadius: 12,
|
||||
marginBottom: 8,
|
||||
borderWidth: 2,
|
||||
borderColor: 'transparent',
|
||||
},
|
||||
languageItemActive: {
|
||||
borderColor: KurdistanColors.kesk,
|
||||
backgroundColor: '#F0FAF5',
|
||||
},
|
||||
languageInfo: {
|
||||
flex: 1,
|
||||
},
|
||||
languageName: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: KurdistanColors.reş,
|
||||
marginBottom: 4,
|
||||
},
|
||||
languageNameActive: {
|
||||
color: KurdistanColors.kesk,
|
||||
},
|
||||
languageSubtext: {
|
||||
fontSize: 14,
|
||||
color: '#999',
|
||||
},
|
||||
checkmark: {
|
||||
width: 24,
|
||||
height: 24,
|
||||
borderRadius: 12,
|
||||
backgroundColor: KurdistanColors.kesk,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
checkmarkText: {
|
||||
color: KurdistanColors.spi,
|
||||
fontSize: 14,
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
settingItem: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
backgroundColor: KurdistanColors.spi,
|
||||
padding: 16,
|
||||
borderRadius: 12,
|
||||
marginBottom: 8,
|
||||
},
|
||||
settingText: {
|
||||
fontSize: 16,
|
||||
color: KurdistanColors.reş,
|
||||
},
|
||||
settingValue: {
|
||||
fontSize: 16,
|
||||
color: '#999',
|
||||
},
|
||||
logoutButton: {
|
||||
backgroundColor: KurdistanColors.sor,
|
||||
margin: 20,
|
||||
padding: 16,
|
||||
borderRadius: 12,
|
||||
alignItems: 'center',
|
||||
shadowColor: KurdistanColors.sor,
|
||||
shadowOffset: { width: 0, height: 4 },
|
||||
shadowOpacity: 0.3,
|
||||
shadowRadius: 6,
|
||||
elevation: 6,
|
||||
},
|
||||
logoutButtonText: {
|
||||
fontSize: 16,
|
||||
fontWeight: 'bold',
|
||||
color: KurdistanColors.spi,
|
||||
},
|
||||
footer: {
|
||||
alignItems: 'center',
|
||||
paddingVertical: 20,
|
||||
},
|
||||
footerText: {
|
||||
fontSize: 12,
|
||||
color: '#999',
|
||||
},
|
||||
});
|
||||
|
||||
export default SettingsScreen;
|
||||
Reference in New Issue
Block a user