189 lines
4.8 KiB
TypeScript
189 lines
4.8 KiB
TypeScript
import { FloatingSelectionModal, SelectionItem } from '@/components/ui/FloatingSelectionModal';
|
|
import { useAppDispatch, useAppSelector } from '@/hooks/redux';
|
|
import { useAuthGuard } from '@/hooks/useAuthGuard';
|
|
import { selectUserProfile, updateUserBodyMeasurements } from '@/store/userSlice';
|
|
import React, { useState } from 'react';
|
|
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
|
|
|
interface CircumferenceCardProps {
|
|
style?: any;
|
|
}
|
|
|
|
const CircumferenceCard: React.FC<CircumferenceCardProps> = ({ style }) => {
|
|
const dispatch = useAppDispatch();
|
|
const userProfile = useAppSelector(selectUserProfile);
|
|
|
|
|
|
console.log('userProfile', userProfile);
|
|
|
|
|
|
const { ensureLoggedIn } = useAuthGuard()
|
|
|
|
const [modalVisible, setModalVisible] = useState(false);
|
|
const [selectedMeasurement, setSelectedMeasurement] = useState<{
|
|
key: string;
|
|
label: string;
|
|
currentValue?: number;
|
|
} | null>(null);
|
|
|
|
const measurements = [
|
|
{
|
|
key: 'chestCircumference',
|
|
label: '胸围',
|
|
value: userProfile?.chestCircumference,
|
|
},
|
|
{
|
|
key: 'waistCircumference',
|
|
label: '腰围',
|
|
value: userProfile?.waistCircumference,
|
|
},
|
|
{
|
|
key: 'upperHipCircumference',
|
|
label: '上臀围',
|
|
value: userProfile?.upperHipCircumference,
|
|
},
|
|
{
|
|
key: 'armCircumference',
|
|
label: '臂围',
|
|
value: userProfile?.armCircumference,
|
|
},
|
|
{
|
|
key: 'thighCircumference',
|
|
label: '大腿围',
|
|
value: userProfile?.thighCircumference,
|
|
},
|
|
{
|
|
key: 'calfCircumference',
|
|
label: '小腿围',
|
|
value: userProfile?.calfCircumference,
|
|
},
|
|
];
|
|
|
|
// Generate circumference options (30-150 cm)
|
|
const circumferenceOptions: SelectionItem[] = Array.from({ length: 121 }, (_, i) => {
|
|
const value = i + 30;
|
|
return {
|
|
label: `${value} cm`,
|
|
value: value,
|
|
};
|
|
});
|
|
|
|
const handleMeasurementPress = async (measurement: typeof measurements[0]) => {
|
|
const isLoggedIn = await ensureLoggedIn();
|
|
if (!isLoggedIn) {
|
|
// 如果未登录,用户会被重定向到登录页面
|
|
return;
|
|
}
|
|
|
|
setSelectedMeasurement({
|
|
key: measurement.key,
|
|
label: measurement.label,
|
|
currentValue: measurement.value,
|
|
});
|
|
setModalVisible(true);
|
|
};
|
|
|
|
const handleUpdateMeasurement = (value: string | number) => {
|
|
if (!selectedMeasurement) return;
|
|
|
|
const updateData = {
|
|
[selectedMeasurement.key]: Number(value),
|
|
};
|
|
|
|
dispatch(updateUserBodyMeasurements(updateData));
|
|
setModalVisible(false);
|
|
setSelectedMeasurement(null);
|
|
};
|
|
|
|
return (
|
|
<View style={[styles.container, style]}>
|
|
<Text style={styles.title}>围度 (cm)</Text>
|
|
|
|
<View style={styles.measurementsContainer}>
|
|
{measurements.map((measurement, index) => (
|
|
<TouchableOpacity
|
|
key={index}
|
|
style={styles.measurementItem}
|
|
onPress={() => handleMeasurementPress(measurement)}
|
|
activeOpacity={0.7}
|
|
>
|
|
<Text style={styles.label}>{measurement.label}</Text>
|
|
<View style={styles.valueContainer}>
|
|
<Text style={styles.value}>
|
|
{measurement.value ? measurement.value.toString() : '--'}
|
|
</Text>
|
|
</View>
|
|
</TouchableOpacity>
|
|
))}
|
|
</View>
|
|
|
|
<FloatingSelectionModal
|
|
visible={modalVisible}
|
|
onClose={() => {
|
|
setModalVisible(false);
|
|
setSelectedMeasurement(null);
|
|
}}
|
|
title={selectedMeasurement ? `设置${selectedMeasurement.label}` : '设置围度'}
|
|
items={circumferenceOptions}
|
|
selectedValue={selectedMeasurement?.currentValue}
|
|
onValueChange={() => { }} // Real-time update not needed
|
|
onConfirm={handleUpdateMeasurement}
|
|
confirmButtonText="确认"
|
|
pickerHeight={180}
|
|
/>
|
|
</View>
|
|
);
|
|
};
|
|
|
|
const styles = StyleSheet.create({
|
|
container: {
|
|
backgroundColor: '#FFFFFF',
|
|
borderRadius: 16,
|
|
padding: 20,
|
|
shadowColor: '#000',
|
|
shadowOffset: {
|
|
width: 0,
|
|
height: 4,
|
|
},
|
|
shadowOpacity: 0.12,
|
|
shadowRadius: 12,
|
|
elevation: 6,
|
|
},
|
|
title: {
|
|
fontSize: 14,
|
|
fontWeight: '600',
|
|
color: '#192126',
|
|
marginBottom: 16,
|
|
},
|
|
measurementsContainer: {
|
|
flexDirection: 'row',
|
|
justifyContent: 'space-between',
|
|
flexWrap: 'nowrap',
|
|
},
|
|
measurementItem: {
|
|
alignItems: 'center',
|
|
},
|
|
label: {
|
|
fontSize: 12,
|
|
color: '#888',
|
|
marginBottom: 8,
|
|
textAlign: 'center',
|
|
},
|
|
valueContainer: {
|
|
backgroundColor: '#F5F5F7',
|
|
borderRadius: 10,
|
|
paddingHorizontal: 8,
|
|
paddingVertical: 6,
|
|
minWidth: 20,
|
|
alignItems: 'center',
|
|
justifyContent: 'center',
|
|
},
|
|
value: {
|
|
fontSize: 14,
|
|
fontWeight: '600',
|
|
color: '#192126',
|
|
textAlign: 'center',
|
|
},
|
|
});
|
|
|
|
export default CircumferenceCard; |