feat: 添加教练功能和更新用户界面

- 新增教练页面,用户可以与教练进行互动和咨询
- 更新首页,切换到教练 tab 并传递名称参数
- 优化个人信息页面,添加注销帐号和退出登录功能
- 更新隐私政策和用户协议的链接,确保用户在使用前同意相关条款
- 修改今日训练页面标题为“开始训练”,提升用户体验
- 删除不再使用的进度条组件,简化代码结构
This commit is contained in:
2025-08-15 21:38:19 +08:00
parent 97e89b9bf0
commit 3312250f2d
13 changed files with 1385 additions and 130 deletions

View File

@@ -3,11 +3,12 @@ import * as AppleAuthentication from 'expo-apple-authentication';
import { LinearGradient } from 'expo-linear-gradient';
import { useLocalSearchParams, useRouter } from 'expo-router';
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { Alert, Animated, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { Alert, Animated, Linking, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { SafeAreaView } from 'react-native-safe-area-context';
import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
import { PRIVACY_POLICY_URL, USER_AGREEMENT_URL } from '@/constants/Agree';
import { Colors } from '@/constants/Colors';
import { useAppDispatch } from '@/hooks/redux';
import { useColorScheme } from '@/hooks/useColorScheme';
@@ -230,8 +231,8 @@ export default function LoginScreen() {
<ScrollView contentContainerStyle={styles.content} showsVerticalScrollIndicator={false}>
<View style={styles.headerWrap}>
<ThemedText style={[styles.title, { color: color.text }]}></ThemedText>
<ThemedText style={[styles.subtitle, { color: color.textMuted }]}></ThemedText>
<ThemedText style={[styles.title, { color: color.text }]}></ThemedText>
<ThemedText style={[styles.subtitle, { color: color.textMuted }]}></ThemedText>
</View>
{/* Apple 登录 */}
@@ -252,22 +253,6 @@ export default function LoginScreen() {
</Pressable>
)}
{/* 游客登录(弱化样式) */}
<Pressable
accessibilityRole="button"
onPress={() => guardAgreement(onGuestLogin)}
disabled={loading}
style={({ pressed }) => [
styles.guestButton,
{ borderColor: color.border, backgroundColor: color.surface },
loading && { opacity: 0.7 },
pressed && { transform: [{ scale: 0.98 }] },
]}
>
<Ionicons name="person-circle-outline" size={22} color={color.neutral200} style={{ marginRight: 8 }} />
<Text style={[styles.guestText, { color: color.neutral200 }]}></Text>
</Pressable>
{/* 协议勾选 */}
<View style={styles.agreementRow}>
<Pressable onPress={() => setHasAgreed((v) => !v)} style={styles.checkboxWrap} accessibilityRole="checkbox" accessibilityState={{ checked: hasAgreed }}>
@@ -281,11 +266,11 @@ export default function LoginScreen() {
</View>
</Pressable>
<Text style={[styles.agreementText, { color: color.textMuted }]}></Text>
<Pressable onPress={() => router.push('/legal/privacy-policy')}>
<Pressable onPress={() => Linking.openURL(PRIVACY_POLICY_URL)}>
<Text style={[styles.link, { color: color.primary }]}></Text>
</Pressable>
<Text style={[styles.agreementText, { color: color.textMuted }]}></Text>
<Pressable onPress={() => router.push('/legal/user-agreement')}>
<Pressable onPress={() => Linking.openURL(USER_AGREEMENT_URL)}>
<Text style={[styles.link, { color: color.primary }]}></Text>
</Pressable>
</View>