refactor(coach): 重构教练组件,统一导入并简化UI实现与类型定义

This commit is contained in:
richarjiang
2025-08-28 09:46:14 +08:00
parent ba2d829e02
commit 5a59508b88
17 changed files with 2400 additions and 866 deletions

View File

@@ -0,0 +1,147 @@
import { Ionicons } from '@expo/vector-icons';
import React from 'react';
import {
Dimensions,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
interface NumberKeyboardProps {
onNumberPress: (number: string) => void;
onDeletePress: () => void;
onDecimalPress: () => void;
hasDecimal?: boolean;
maxLength?: number;
currentValue?: string;
}
const { width } = Dimensions.get('window');
const keyWidth = (width - 80) / 3; // 减去左右边距和间隙
export default function NumberKeyboard({
onNumberPress,
onDeletePress,
onDecimalPress,
hasDecimal = false,
maxLength = 6,
currentValue = '',
}: NumberKeyboardProps) {
const handleNumberPress = (number: string) => {
if (currentValue.length >= maxLength) return;
// 防止输入多个0开头
if (currentValue === '0' && number === '0') return;
// 如果当前是0输入非0数字时替换
if (currentValue === '0' && number !== '0') {
// 这里不需要replace直接传递number即可
return;
}
onNumberPress(number);
};
const handleDecimalPress = () => {
if (hasDecimal || currentValue.includes('.')) return;
onDecimalPress();
};
const renderKey = (
value: string,
onPress: () => void,
style?: any,
textStyle?: any,
disabled?: boolean
) => (
<TouchableOpacity
style={[
styles.key,
{ width: keyWidth },
style,
disabled && styles.keyDisabled
]}
onPress={onPress}
disabled={disabled}
activeOpacity={0.7}
>
{value === 'delete' ? (
<Ionicons name="backspace-outline" size={24} color="#374151" />
) : (
<Text style={[styles.keyText, textStyle, disabled && styles.keyTextDisabled]}>
{value}
</Text>
)}
</TouchableOpacity>
);
return (
<View style={styles.container}>
<View style={styles.row}>
{renderKey('1', () => handleNumberPress('1'))}
{renderKey('2', () => handleNumberPress('2'))}
{renderKey('3', () => handleNumberPress('3'))}
</View>
<View style={styles.row}>
{renderKey('4', () => handleNumberPress('4'))}
{renderKey('5', () => handleNumberPress('5'))}
{renderKey('6', () => handleNumberPress('6'))}
</View>
<View style={styles.row}>
{renderKey('7', () => handleNumberPress('7'))}
{renderKey('8', () => handleNumberPress('8'))}
{renderKey('9', () => handleNumberPress('9'))}
</View>
<View style={styles.row}>
{renderKey(
'.',
handleDecimalPress,
undefined,
undefined,
hasDecimal || currentValue.includes('.')
)}
{renderKey('0', () => handleNumberPress('0'))}
{renderKey('delete', onDeletePress)}
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: '#F9FAFB',
paddingVertical: 20,
paddingHorizontal: 20,
borderTopWidth: 1,
borderTopColor: '#E5E7EB',
},
row: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 12,
},
key: {
height: 50,
backgroundColor: '#FFFFFF',
borderRadius: 12,
alignItems: 'center',
justifyContent: 'center',
shadowColor: '#000',
shadowOffset: { width: 0, height: 1 },
shadowOpacity: 0.05,
shadowRadius: 2,
elevation: 1,
borderWidth: 1,
borderColor: '#E5E7EB',
},
keyDisabled: {
backgroundColor: '#F3F4F6',
opacity: 0.5,
},
keyText: {
fontSize: 20,
fontWeight: '600',
color: '#374151',
},
keyTextDisabled: {
color: '#9CA3AF',
},
});