feat: 更新标签页和新增探索页面
- 将标签页中的“首页”改为“探索”,并更新相关逻辑 - 新增探索页面,展示推荐文章和训练计划 - 优化教练页面的导航,确保用户体验一致性 - 移除不再使用的代码,简化项目结构 - 更新路由常量,确保路径管理集中化
This commit is contained in:
@@ -19,7 +19,7 @@ export default function TabLayout() {
|
||||
initialRouteName="coach"
|
||||
screenOptions={({ route }) => {
|
||||
const routeName = route.name;
|
||||
const isSelected = (routeName === 'index' && pathname === ROUTES.TAB_HOME) ||
|
||||
const isSelected = (routeName === 'explore' && pathname === ROUTES.TAB_EXPLORE) ||
|
||||
(routeName === 'coach' && pathname === ROUTES.TAB_COACH) ||
|
||||
(routeName === 'statistics' && pathname === ROUTES.TAB_STATISTICS) ||
|
||||
pathname.includes(routeName);
|
||||
@@ -40,7 +40,7 @@ export default function TabLayout() {
|
||||
// 基于 routeName 设置图标与标题,避免 tabBarIcon 的包装导致文字裁剪
|
||||
const getIconAndTitle = () => {
|
||||
switch (routeName) {
|
||||
case 'index':
|
||||
case 'explore':
|
||||
return { icon: 'magnifyingglass.circle.fill', title: '发现' } as const;
|
||||
case 'coach':
|
||||
return { icon: 'person.3.fill', title: 'Bot' } as const;
|
||||
@@ -157,7 +157,7 @@ export default function TabLayout() {
|
||||
}}
|
||||
/>
|
||||
<Tabs.Screen
|
||||
name="index"
|
||||
name="explore"
|
||||
options={{
|
||||
title: '发现',
|
||||
tabBarIcon: ({ color }) => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ThemedText } from '@/components/ThemedText';
|
||||
import { ThemedView } from '@/components/ThemedView';
|
||||
import { ROUTES } from '@/constants/Routes';
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { useThemeColor } from '@/hooks/useThemeColor';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
@@ -13,7 +14,6 @@ import {
|
||||
TouchableOpacity,
|
||||
View
|
||||
} from 'react-native';
|
||||
import { ROUTES } from '@/constants/Routes';
|
||||
|
||||
const { width, height } = Dimensions.get('window');
|
||||
|
||||
@@ -30,10 +30,10 @@ export default function WelcomeScreen() {
|
||||
const handleSkip = async () => {
|
||||
try {
|
||||
await AsyncStorage.setItem('@onboarding_completed', 'true');
|
||||
router.replace(ROUTES.TAB_HOME);
|
||||
router.replace(ROUTES.TAB_COACH);
|
||||
} catch (error) {
|
||||
console.error('保存引导状态失败:', error);
|
||||
router.replace(ROUTES.TAB_HOME);
|
||||
router.replace(ROUTES.TAB_COACH);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { HeaderBar } from '@/components/ui/HeaderBar';
|
||||
import { Colors } from '@/constants/Colors';
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import AsyncStorage from '@react-native-async-storage/async-storage';
|
||||
import * as Haptics from 'expo-haptics';
|
||||
import { useRouter } from 'expo-router';
|
||||
@@ -305,50 +304,6 @@ export default function GoalsScreen() {
|
||||
<Text style={[styles.rangeHint, { color: colors.textMuted }]}>建议范围 {STEPS_RANGE.min.toLocaleString()}-{STEPS_RANGE.max.toLocaleString()},步进 {STEPS_RANGE.step}</Text>
|
||||
</SectionCard>
|
||||
|
||||
<SectionCard
|
||||
title="练习普拉提是为了什么"
|
||||
subtitle="可多选"
|
||||
>
|
||||
<View style={styles.grid}>
|
||||
{PURPOSE_OPTIONS.map((opt) => {
|
||||
const active = purposes.includes(opt.id);
|
||||
return (
|
||||
<TouchableOpacity
|
||||
key={opt.id}
|
||||
style={[
|
||||
styles.optionCard,
|
||||
{
|
||||
backgroundColor: active ? colors.primary : colors.card,
|
||||
borderColor: active ? colors.primary : colors.border,
|
||||
},
|
||||
]}
|
||||
activeOpacity={0.9}
|
||||
onPress={() => togglePurpose(opt.id)}
|
||||
>
|
||||
<View style={styles.optionIconWrap}>
|
||||
<Ionicons
|
||||
name={opt.icon}
|
||||
size={20}
|
||||
color={active ? colors.onPrimary : colors.text}
|
||||
/>
|
||||
</View>
|
||||
<Text
|
||||
numberOfLines={2}
|
||||
style={[
|
||||
styles.optionLabel,
|
||||
{ color: active ? colors.onPrimary : colors.text },
|
||||
]}
|
||||
>
|
||||
{opt.label}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
{purposes.length > 0 && (
|
||||
<Text style={[styles.selectedHint, { color: colors.textSecondary }]}>已选择 {purposes.length} 项</Text>
|
||||
)}
|
||||
</SectionCard>
|
||||
</ScrollView>
|
||||
</SafeAreaView>
|
||||
</View>
|
||||
|
||||
@@ -1,38 +1,38 @@
|
||||
// 应用路由常量定义
|
||||
export const ROUTES = {
|
||||
// Tab路由
|
||||
TAB_HOME: '/',
|
||||
TAB_EXPLORE: '/explore',
|
||||
TAB_COACH: '/coach',
|
||||
TAB_STATISTICS: '/statistics',
|
||||
TAB_PERSONAL: '/personal',
|
||||
|
||||
|
||||
// 训练相关路由
|
||||
WORKOUT_TODAY: '/workout/today',
|
||||
WORKOUT_CREATE_SESSION: '/workout/create-session',
|
||||
WORKOUT_SESSION: '/workout/session',
|
||||
|
||||
|
||||
// 训练计划相关路由
|
||||
TRAINING_PLAN: '/training-plan',
|
||||
|
||||
|
||||
// 体态评估路由
|
||||
AI_POSTURE_ASSESSMENT: '/ai-posture-assessment',
|
||||
|
||||
|
||||
// 挑战路由
|
||||
CHALLENGE: '/challenge',
|
||||
CHALLENGE_DAY: '/challenge/day',
|
||||
|
||||
|
||||
// 文章路由
|
||||
ARTICLE: '/article',
|
||||
|
||||
|
||||
// 用户相关路由
|
||||
AUTH_LOGIN: '/auth/login',
|
||||
PROFILE_EDIT: '/profile/edit',
|
||||
PROFILE_GOALS: '/profile/goals',
|
||||
|
||||
|
||||
// 法律相关路由
|
||||
LEGAL_USER_AGREEMENT: '/legal/user-agreement',
|
||||
LEGAL_PRIVACY_POLICY: '/legal/privacy-policy',
|
||||
|
||||
|
||||
// 引导页路由
|
||||
ONBOARDING: '/onboarding',
|
||||
ONBOARDING_PERSONAL_INFO: '/onboarding/personal-info',
|
||||
@@ -42,17 +42,17 @@ export const ROUTES = {
|
||||
export const ROUTE_PARAMS = {
|
||||
// 训练会话参数
|
||||
WORKOUT_SESSION_ID: 'id',
|
||||
|
||||
|
||||
// 训练计划参数
|
||||
TRAINING_PLAN_ID: 'planId',
|
||||
TRAINING_PLAN_TAB: 'tab',
|
||||
|
||||
|
||||
// 挑战日参数
|
||||
CHALLENGE_DAY: 'day',
|
||||
|
||||
|
||||
// 文章参数
|
||||
ARTICLE_ID: 'id',
|
||||
|
||||
|
||||
// 重定向参数
|
||||
REDIRECT_TO: 'redirectTo',
|
||||
REDIRECT_PARAMS: 'redirectParams',
|
||||
@@ -62,7 +62,7 @@ export const ROUTE_PARAMS = {
|
||||
export const QUERY_PARAMS = {
|
||||
// 训练计划查询参数
|
||||
TRAINING_PLAN_TAB_SCHEDULE: 'schedule',
|
||||
|
||||
|
||||
// 教练页面参数
|
||||
COACH_NAME: 'name',
|
||||
} as const;
|
||||
Reference in New Issue
Block a user