feat: 添加日历功能和进度条组件

- 在项目中引入 dayjs 库以处理日期
- 新增 PlanCard 和 ProgressBar 组件,分别用于展示训练计划和进度条
- 更新首页以显示推荐的训练计划
- 优化个人中心页面的底部留白处理
- 本地化界面文本为中文
This commit is contained in:
richarjiang
2025-08-12 09:16:59 +08:00
parent 1646085428
commit 9796c614ed
11 changed files with 680 additions and 159 deletions

View File

@@ -1,7 +1,9 @@
import { Colors } from '@/constants/Colors';
import { getTabBarBottomPadding } from '@/constants/TabBar';
import { useColorScheme } from '@/hooks/useColorScheme';
import { Ionicons } from '@expo/vector-icons';
import React, { useState } from 'react';
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
import React, { useMemo, useState } from 'react';
import {
SafeAreaView,
ScrollView,
@@ -12,18 +14,19 @@ import {
TouchableOpacity,
View
} from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
export default function PersonalScreen() {
const insets = useSafeAreaInsets();
const tabBarHeight = useBottomTabBarHeight();
const bottomPadding = useMemo(() => {
// 统一的页面底部留白TabBar 高度 + TabBar 与底部的额外间距 + 安全区底部
return getTabBarBottomPadding(tabBarHeight) + (insets?.bottom ?? 0);
}, [tabBarHeight, insets?.bottom]);
const [notificationEnabled, setNotificationEnabled] = useState(true);
const colorScheme = useColorScheme();
const colors = Colors[colorScheme ?? 'light'];
const ProfileHeader = () => (
<View style={styles.headerContainer}>
{/* 标题 */}
<Text style={styles.headerTitle}>Profile</Text>
</View>
);
const UserInfoSection = () => (
<View style={styles.userInfoCard}>
@@ -47,10 +50,10 @@ export default function PersonalScreen() {
<Text style={styles.userProgram}>Lose a Fat Program</Text>
</View>
{/* 编辑按钮 */}
<TouchableOpacity style={dynamicStyles.editButton}>
<Text style={dynamicStyles.editButtonText}>Edit</Text>
</TouchableOpacity>
{/* 编辑按钮 */}
<TouchableOpacity style={dynamicStyles.editButton}>
<Text style={dynamicStyles.editButtonText}>Edit</Text>
</TouchableOpacity>
</View>
</View>
);
@@ -198,8 +201,11 @@ export default function PersonalScreen() {
<View style={styles.container}>
<StatusBar barStyle="dark-content" backgroundColor="transparent" translucent />
<SafeAreaView style={styles.safeArea}>
<ScrollView style={styles.scrollView} showsVerticalScrollIndicator={false}>
<ProfileHeader />
<ScrollView
style={styles.scrollView}
contentContainerStyle={{ paddingBottom: bottomPadding }}
showsVerticalScrollIndicator={false}
>
<UserInfoSection />
<StatsSection />
<MenuSection title="Account" items={accountItems} />
@@ -207,7 +213,7 @@ export default function PersonalScreen() {
<MenuSection title="Other" items={otherItems} />
{/* 底部浮动按钮 */}
<View style={styles.floatingButtonContainer}>
<View style={[styles.floatingButtonContainer, { bottom: Math.max(30, tabBarHeight / 2) + (insets?.bottom ?? 0) }]}>
<TouchableOpacity style={dynamicStyles.floatingButton}>
<Ionicons name="search" size={24} color="#192126" />
</TouchableOpacity>
@@ -231,21 +237,6 @@ const styles = StyleSheet.create({
paddingHorizontal: 20,
backgroundColor: '#F5F5F5',
},
// 头部导航
headerContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
paddingTop: 10,
paddingBottom: 20,
},
headerTitle: {
fontSize: 20,
fontWeight: 'bold',
color: '#000',
},
// 用户信息区域
userInfoCard: {
borderRadius: 16,