Files
digital-pilates/app/(tabs)/index.tsx
richarjiang 00ddec25c5 feat: 集成 Redux 状态管理和用户目标管理功能
- 添加 Redux 状态管理,支持用户登录和个人信息的持久化
- 新增目标管理页面,允许用户设置每日卡路里和步数目标
- 更新首页,移除旧的活动展示,改为固定的热点功能卡片
- 修改布局以适应新功能的展示和交互
- 更新依赖,添加 @reduxjs/toolkit 和 react-redux 库以支持状态管理
- 新增 API 服务模块,处理与后端的交互
2025-08-12 22:22:30 +08:00

194 lines
5.6 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { PlanCard } from '@/components/PlanCard';
import { SearchBox } from '@/components/SearchBox';
import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
// Removed WorkoutCard import since we no longer use the horizontal carousel
import { getChineseGreeting } from '@/utils/date';
import { useRouter } from 'expo-router';
import React, { useEffect, useRef } from 'react';
import { Pressable, SafeAreaView, ScrollView, StyleSheet, View } from 'react-native';
// 移除旧的“热门活动”滑动数据,改为固定的“热点功能”卡片
export default function HomeScreen() {
const router = useRouter();
const hasOpenedLoginRef = useRef(false);
useEffect(() => {
// 仅在本次会话首次进入首页时打开登录页,可返回关闭
if (!hasOpenedLoginRef.current) {
hasOpenedLoginRef.current = true;
router.push('/auth/login');
}
}, [router]);
return (
<SafeAreaView style={styles.safeArea}>
<ThemedView style={styles.container}>
<ScrollView showsVerticalScrollIndicator={false}>
{/* Header Section */}
<View style={styles.header}>
<ThemedText style={styles.greeting}>{getChineseGreeting()} 🔥</ThemedText>
<ThemedText style={styles.userName}></ThemedText>
</View>
{/* Search Box */}
<SearchBox placeholder="搜索" />
{/* Hot Features Section */}
<View style={styles.sectionContainer}>
<ThemedText style={styles.sectionTitle}></ThemedText>
<View style={styles.featureGrid}>
<Pressable
style={[styles.featureCard, styles.featureCardPrimary]}
onPress={() => router.push('/ai-posture-assessment')}
>
<ThemedText style={styles.featureTitle}>AI体态评估</ThemedText>
<ThemedText style={styles.featureSubtitle}>3</ThemedText>
<View style={styles.featureCta}>
<ThemedText style={styles.featureCtaText}></ThemedText>
</View>
</Pressable>
<Pressable
style={[styles.featureCard, styles.featureCardSecondary]}
onPress={() => router.push('/health-consultation' as any)}
>
<ThemedText style={styles.featureTitle}>线</ThemedText>
<ThemedText style={styles.featureSubtitle}> · 11</ThemedText>
<View style={styles.featureCta}>
<ThemedText style={styles.featureCtaText}></ThemedText>
</View>
</Pressable>
</View>
</View>
{/* Today Plan Section */}
<View style={styles.sectionContainer}>
<ThemedText style={styles.sectionTitle}></ThemedText>
<View style={styles.planList}>
<PlanCard
image={'https://plates-1251306435.cos.ap-guangzhou.myqcloud.com/images/Imagettpg.png'}
title="体态评估"
subtitle="评估你的体态,制定训练计划"
level="初学者"
progress={0}
/>
<PlanCard
image={'https://plates-1251306435.cos.ap-guangzhou.myqcloud.com/images/Image30play@2x.png'}
title="30日训练打卡"
subtitle="坚持30天养成训练习惯"
level="初学者"
progress={0.75}
/>
</View>
</View>
{/* Add some spacing at the bottom */}
<View style={styles.bottomSpacing} />
</ScrollView>
</ThemedView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
safeArea: {
flex: 1,
backgroundColor: '#F7F8FA',
},
container: {
flex: 1,
backgroundColor: '#F7F8FA',
},
header: {
paddingHorizontal: 24,
paddingTop: 16,
paddingBottom: 8,
},
greeting: {
fontSize: 16,
color: '#8A8A8E',
fontWeight: '400',
marginBottom: 6,
},
userName: {
fontSize: 30,
fontWeight: 'bold',
color: '#1A1A1A',
lineHeight: 36,
},
sectionContainer: {
marginTop: 24,
},
sectionTitle: {
fontSize: 24,
fontWeight: 'bold',
color: '#1A1A1A',
paddingHorizontal: 24,
marginBottom: 18,
},
featureGrid: {
paddingHorizontal: 24,
flexDirection: 'row',
justifyContent: 'space-between',
},
featureCard: {
width: '48%',
borderRadius: 16,
padding: 16,
backgroundColor: '#FFFFFF',
// iOS shadow
shadowColor: '#000',
shadowOpacity: 0.08,
shadowRadius: 12,
shadowOffset: { width: 0, height: 6 },
// Android shadow
elevation: 4,
},
featureCardPrimary: {
backgroundColor: '#EEF2FF', // 柔和的靛蓝背景
},
featureCardSecondary: {
backgroundColor: '#F0FDFA', // 柔和的青绿背景
},
featureIcon: {
fontSize: 28,
marginBottom: 8,
},
featureTitle: {
fontSize: 18,
fontWeight: '700',
color: '#0F172A',
marginBottom: 6,
},
featureSubtitle: {
fontSize: 12,
color: '#6B7280',
lineHeight: 16,
marginBottom: 12,
},
featureCta: {
alignSelf: 'flex-start',
backgroundColor: '#0F172A',
paddingHorizontal: 10,
paddingVertical: 6,
borderRadius: 999,
},
featureCtaText: {
color: '#FFFFFF',
fontSize: 12,
fontWeight: '600',
},
planList: {
paddingHorizontal: 24,
},
// 移除旧的滑动样式
bottomSpacing: {
height: 120,
},
});