feat: 添加训练计划和打卡功能
- 新增训练计划页面,允许用户制定个性化的训练计划 - 集成打卡功能,用户可以记录每日的训练情况 - 更新 Redux 状态管理,添加训练计划相关的 reducer - 在首页中添加训练计划卡片,支持用户点击跳转 - 更新样式和布局,以适应新功能的展示和交互 - 添加日期选择器和相关依赖,支持用户选择训练日期
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import * as AppleAuthentication from 'expo-apple-authentication';
|
||||
import { useRouter } from 'expo-router';
|
||||
import { useLocalSearchParams, useRouter } from 'expo-router';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Alert, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
@@ -14,6 +14,7 @@ import { login } from '@/store/userSlice';
|
||||
|
||||
export default function LoginScreen() {
|
||||
const router = useRouter();
|
||||
const searchParams = useLocalSearchParams<{ redirectTo?: string; redirectParams?: string }>();
|
||||
const scheme = (useColorScheme() ?? 'light') as 'light' | 'dark';
|
||||
const color = Colors[scheme];
|
||||
const dispatch = useAppDispatch();
|
||||
@@ -46,7 +47,18 @@ export default function LoginScreen() {
|
||||
});
|
||||
const identityToken = (credential as any)?.identityToken;
|
||||
await dispatch(login({ appleIdentityToken: identityToken })).unwrap();
|
||||
router.back();
|
||||
// 登录成功后处理重定向
|
||||
const to = searchParams?.redirectTo as string | undefined;
|
||||
const paramsJson = searchParams?.redirectParams as string | undefined;
|
||||
let parsedParams: Record<string, any> | undefined;
|
||||
if (paramsJson) {
|
||||
try { parsedParams = JSON.parse(paramsJson); } catch { }
|
||||
}
|
||||
if (to) {
|
||||
router.replace({ pathname: to, params: parsedParams } as any);
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err?.code === 'ERR_CANCELED') return;
|
||||
const message = err?.message || '登录失败,请稍后再试';
|
||||
@@ -54,12 +66,22 @@ export default function LoginScreen() {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}, [appleAvailable, router]);
|
||||
}, [appleAvailable, router, searchParams?.redirectParams, searchParams?.redirectTo]);
|
||||
|
||||
const onGuestLogin = useCallback(() => {
|
||||
// TODO: 标记为游客身份,可在此写入本地状态/上报统计
|
||||
router.back();
|
||||
}, [router]);
|
||||
// 游客继续:若有 redirect 则前往,无则返回
|
||||
const to = searchParams?.redirectTo as string | undefined;
|
||||
const paramsJson = searchParams?.redirectParams as string | undefined;
|
||||
let parsedParams: Record<string, any> | undefined;
|
||||
if (paramsJson) {
|
||||
try { parsedParams = JSON.parse(paramsJson); } catch { }
|
||||
}
|
||||
if (to) {
|
||||
router.replace({ pathname: to, params: parsedParams } as any);
|
||||
} else {
|
||||
router.back();
|
||||
}
|
||||
}, [router, searchParams?.redirectParams, searchParams?.redirectTo]);
|
||||
|
||||
const disabledStyle = useMemo(() => ({ opacity: hasAgreed ? 1 : 0.5 }), [hasAgreed]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user