import React from 'react'; import { View, TextInput, TouchableOpacity, Text, StyleSheet, ActivityIndicator, } from 'react-native'; import { WalletType } from 'rnwalletman'; import { useOTPBind } from '../hooks/useOTPBind'; interface OTPBindUIProps { walletType: WalletType; title: string; otpLength?: number; mobileLength?: number; onRequestOTP: (walletType: WalletType, params: any) => Promise; onVerifyOTP: (walletType: WalletType, params: any) => Promise; onSuccess: (result: any) => void; onError: (error: string) => void; isDebug: boolean; additionalParams?: any; initialMobile?: string; } export const OTPBindUI: React.FC = ({ walletType, title, otpLength = 6, mobileLength = 10, onRequestOTP, onVerifyOTP, onSuccess, onError, isDebug, additionalParams = {}, initialMobile = '', }) => { const [state, actions] = useOTPBind( walletType, { onRequestOTP, onVerifyOTP, onSuccess, onError, isDebug }, { otpLength, mobileLength, additionalParams, initialMobile } ); const isLoading = state.loading || state.step === 'processing'; const showOtp = state.step === 'otp' || state.step === 'processing'; return ( {title} {state.step === 'mobile' && ( <> {!!state.errorMessage && ( {state.errorMessage} )} 手机号 { actions.setMobile(t); if (state.errorMessage) actions.clearError(); }} editable={!isLoading} /> {isLoading ? ( ) : ( 获取验证码 )} )} {showOtp && ( <> {state.needPassword ? `验证码已发送至 ${state.mobile},该账号需输入密码` : `验证码已发送至 ${state.mobile}`} {!!state.errorMessage && ( {state.errorMessage} )} {state.needPassword && ( <> Amazon 密码 { actions.setPassword(t); if (state.errorMessage) actions.clearError(); }} editable={!isLoading} /> )} 验证码 { actions.setOtp(t); if (state.errorMessage) actions.clearError(); }} editable={!isLoading} /> {isLoading ? ( ) : ( 验证并绑定 )} 重新输入手机号 )} ); }; const styles = StyleSheet.create({ overlay: { flex: 1, backgroundColor: 'rgba(0,0,0,0.6)', justifyContent: 'center', alignItems: 'center', }, card: { width: '88%', backgroundColor: '#fff', borderRadius: 16, padding: 22, alignSelf: 'center', }, title: { fontSize: 18, fontWeight: '700', textAlign: 'center', color: '#111', marginBottom: 18, }, label: { fontSize: 13, color: '#666', marginBottom: 5, fontWeight: '500', }, hint: { fontSize: 13, color: '#555', textAlign: 'center', marginBottom: 14, }, input: { borderWidth: 1.5, borderColor: '#e0e0e0', borderRadius: 10, paddingHorizontal: 12, paddingVertical: 11, fontSize: 16, color: '#111', marginBottom: 14, backgroundColor: '#fafafa', }, inputError: { borderColor: '#ff3b30', backgroundColor: '#fff8f7', }, errorText: { color: '#ff3b30', fontSize: 12, marginBottom: 10, textAlign: 'center', lineHeight: 17, }, btn: { backgroundColor: '#007AFF', borderRadius: 10, paddingVertical: 13, alignItems: 'center', marginTop: 2, }, btnDisabled: { backgroundColor: '#a0c4ff', }, btnText: { color: '#fff', fontSize: 16, fontWeight: '600', }, linkBtn: { marginTop: 12, alignItems: 'center', paddingVertical: 4, }, linkText: { color: '#007AFF', fontSize: 13, }, });