前端界面优化
This commit is contained in:
@@ -45,126 +45,134 @@ export const OTPBindUI: React.FC<OTPBindUIProps> = ({
|
||||
const showOtp = state.step === 'otp' || state.step === 'processing';
|
||||
|
||||
return (
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
<View style={styles.overlay}>
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.title}>{title}</Text>
|
||||
|
||||
{state.step === 'mobile' && (
|
||||
<>
|
||||
{!!state.errorMessage && (
|
||||
<Text style={styles.errorText}>{state.errorMessage}</Text>
|
||||
)}
|
||||
<Text style={styles.label}>手机号</Text>
|
||||
<TextInput
|
||||
style={[styles.input, !!state.errorMessage && styles.inputError]}
|
||||
placeholder={`请输入 ${mobileLength} 位手机号`}
|
||||
placeholderTextColor="#aaa"
|
||||
keyboardType="phone-pad"
|
||||
maxLength={mobileLength}
|
||||
value={state.mobile}
|
||||
onChangeText={t => {
|
||||
actions.setMobile(t);
|
||||
if (state.errorMessage) actions.clearError();
|
||||
}}
|
||||
editable={!isLoading}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={[styles.btn, isLoading && styles.btnDisabled]}
|
||||
onPress={actions.requestOTP}
|
||||
disabled={isLoading}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color="#fff" />
|
||||
) : (
|
||||
<Text style={styles.btnText}>获取验证码</Text>
|
||||
{state.step === 'mobile' && (
|
||||
<>
|
||||
{!!state.errorMessage && (
|
||||
<Text style={styles.errorText}>{state.errorMessage}</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
)}
|
||||
<Text style={styles.label}>手机号</Text>
|
||||
<TextInput
|
||||
style={[styles.input, !!state.errorMessage && styles.inputError]}
|
||||
placeholder={`请输入 ${mobileLength} 位手机号`}
|
||||
placeholderTextColor="#aaa"
|
||||
keyboardType="phone-pad"
|
||||
maxLength={mobileLength}
|
||||
value={state.mobile}
|
||||
onChangeText={t => {
|
||||
actions.setMobile(t);
|
||||
if (state.errorMessage) actions.clearError();
|
||||
}}
|
||||
editable={!isLoading}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={[styles.btn, isLoading && styles.btnDisabled]}
|
||||
onPress={actions.requestOTP}
|
||||
disabled={isLoading}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color="#fff" />
|
||||
) : (
|
||||
<Text style={styles.btnText}>获取验证码</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
)}
|
||||
|
||||
{showOtp && (
|
||||
<>
|
||||
<Text style={styles.hint}>验证码已发送至 {state.mobile}</Text>
|
||||
{!!state.errorMessage && (
|
||||
<Text style={styles.errorText}>{state.errorMessage}</Text>
|
||||
)}
|
||||
<Text style={styles.label}>验证码</Text>
|
||||
<TextInput
|
||||
style={[styles.input, !!state.errorMessage && styles.inputError]}
|
||||
placeholder={`请输入 ${otpLength} 位验证码`}
|
||||
placeholderTextColor="#aaa"
|
||||
keyboardType="number-pad"
|
||||
maxLength={otpLength}
|
||||
value={state.otp}
|
||||
onChangeText={t => {
|
||||
actions.setOtp(t);
|
||||
if (state.errorMessage) actions.clearError();
|
||||
}}
|
||||
editable={!isLoading}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={[styles.btn, isLoading && styles.btnDisabled]}
|
||||
onPress={actions.verifyOTP}
|
||||
disabled={isLoading}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color="#fff" />
|
||||
) : (
|
||||
<Text style={styles.btnText}>验证并绑定</Text>
|
||||
{showOtp && (
|
||||
<>
|
||||
<Text style={styles.hint}>验证码已发送至 {state.mobile}</Text>
|
||||
{!!state.errorMessage && (
|
||||
<Text style={styles.errorText}>{state.errorMessage}</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.linkBtn}
|
||||
onPress={actions.resetToMobile}
|
||||
disabled={isLoading}
|
||||
>
|
||||
<Text style={[styles.linkText, isLoading && { opacity: 0.4 }]}>
|
||||
重新输入手机号
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
)}
|
||||
<Text style={styles.label}>验证码</Text>
|
||||
<TextInput
|
||||
style={[styles.input, !!state.errorMessage && styles.inputError]}
|
||||
placeholder={`请输入 ${otpLength} 位验证码`}
|
||||
placeholderTextColor="#aaa"
|
||||
keyboardType="number-pad"
|
||||
maxLength={otpLength}
|
||||
value={state.otp}
|
||||
onChangeText={t => {
|
||||
actions.setOtp(t);
|
||||
if (state.errorMessage) actions.clearError();
|
||||
}}
|
||||
editable={!isLoading}
|
||||
/>
|
||||
<TouchableOpacity
|
||||
style={[styles.btn, isLoading && styles.btnDisabled]}
|
||||
onPress={actions.verifyOTP}
|
||||
disabled={isLoading}
|
||||
activeOpacity={0.8}
|
||||
>
|
||||
{isLoading ? (
|
||||
<ActivityIndicator color="#fff" />
|
||||
) : (
|
||||
<Text style={styles.btnText}>验证并绑定</Text>
|
||||
)}
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.linkBtn}
|
||||
onPress={actions.resetToMobile}
|
||||
disabled={isLoading}
|
||||
>
|
||||
<Text style={[styles.linkText, isLoading && { opacity: 0.4 }]}>
|
||||
重新输入手机号
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
};
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
overlay: {
|
||||
flex: 1,
|
||||
backgroundColor: 'rgba(0,0,0,0.6)',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
card: {
|
||||
width: '92%',
|
||||
width: '88%',
|
||||
backgroundColor: '#fff',
|
||||
borderRadius: 20,
|
||||
padding: 28,
|
||||
borderRadius: 16,
|
||||
padding: 22,
|
||||
alignSelf: 'center',
|
||||
},
|
||||
title: {
|
||||
fontSize: 22,
|
||||
fontSize: 18,
|
||||
fontWeight: '700',
|
||||
textAlign: 'center',
|
||||
color: '#111',
|
||||
marginBottom: 24,
|
||||
marginBottom: 18,
|
||||
},
|
||||
label: {
|
||||
fontSize: 13,
|
||||
color: '#666',
|
||||
marginBottom: 6,
|
||||
marginBottom: 5,
|
||||
fontWeight: '500',
|
||||
},
|
||||
hint: {
|
||||
fontSize: 14,
|
||||
fontSize: 13,
|
||||
color: '#555',
|
||||
textAlign: 'center',
|
||||
marginBottom: 18,
|
||||
marginBottom: 14,
|
||||
},
|
||||
input: {
|
||||
borderWidth: 1.5,
|
||||
borderColor: '#e0e0e0',
|
||||
borderRadius: 10,
|
||||
paddingHorizontal: 14,
|
||||
paddingVertical: 14,
|
||||
fontSize: 17,
|
||||
paddingHorizontal: 12,
|
||||
paddingVertical: 11,
|
||||
fontSize: 16,
|
||||
color: '#111',
|
||||
marginBottom: 18,
|
||||
marginBottom: 14,
|
||||
backgroundColor: '#fafafa',
|
||||
},
|
||||
inputError: {
|
||||
@@ -173,34 +181,33 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
errorText: {
|
||||
color: '#ff3b30',
|
||||
fontSize: 13,
|
||||
marginBottom: 12,
|
||||
fontSize: 12,
|
||||
marginBottom: 10,
|
||||
textAlign: 'center',
|
||||
lineHeight: 18,
|
||||
lineHeight: 17,
|
||||
},
|
||||
btn: {
|
||||
backgroundColor: '#007AFF',
|
||||
borderRadius: 12,
|
||||
paddingVertical: 16,
|
||||
borderRadius: 10,
|
||||
paddingVertical: 13,
|
||||
alignItems: 'center',
|
||||
marginTop: 4,
|
||||
marginTop: 2,
|
||||
},
|
||||
btnDisabled: {
|
||||
backgroundColor: '#a0c4ff',
|
||||
},
|
||||
btnText: {
|
||||
color: '#fff',
|
||||
fontSize: 17,
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
letterSpacing: 0.3,
|
||||
},
|
||||
linkBtn: {
|
||||
marginTop: 16,
|
||||
marginTop: 12,
|
||||
alignItems: 'center',
|
||||
paddingVertical: 4,
|
||||
},
|
||||
linkText: {
|
||||
color: '#007AFF',
|
||||
fontSize: 14,
|
||||
fontSize: 13,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user