feat: 集成 Redux 状态管理和用户目标管理功能
- 添加 Redux 状态管理,支持用户登录和个人信息的持久化 - 新增目标管理页面,允许用户设置每日卡路里和步数目标 - 更新首页,移除旧的活动展示,改为固定的热点功能卡片 - 修改布局以适应新功能的展示和交互 - 更新依赖,添加 @reduxjs/toolkit 和 react-redux 库以支持状态管理 - 新增 API 服务模块,处理与后端的交互
This commit is contained in:
@@ -2,17 +2,21 @@ import { Ionicons } from '@expo/vector-icons';
|
||||
import * as AppleAuthentication from 'expo-apple-authentication';
|
||||
import { useRouter } from 'expo-router';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Alert, Pressable, SafeAreaView, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
||||
import { Alert, 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 { Colors } from '@/constants/Colors';
|
||||
import { useAppDispatch } from '@/hooks/redux';
|
||||
import { useColorScheme } from '@/hooks/useColorScheme';
|
||||
import { login } from '@/store/userSlice';
|
||||
|
||||
export default function LoginScreen() {
|
||||
const router = useRouter();
|
||||
const scheme = (useColorScheme() ?? 'light') as 'light' | 'dark';
|
||||
const color = Colors[scheme];
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const [hasAgreed, setHasAgreed] = useState<boolean>(false);
|
||||
const [appleAvailable, setAppleAvailable] = useState<boolean>(false);
|
||||
@@ -40,11 +44,13 @@ export default function LoginScreen() {
|
||||
AppleAuthentication.AppleAuthenticationScope.EMAIL,
|
||||
],
|
||||
});
|
||||
// TODO: 将 credential 发送到后端换取应用会话。这里先直接返回上一页。
|
||||
const identityToken = (credential as any)?.identityToken;
|
||||
await dispatch(login({ appleIdentityToken: identityToken })).unwrap();
|
||||
router.back();
|
||||
} catch (err: any) {
|
||||
if (err?.code === 'ERR_CANCELED') return;
|
||||
Alert.alert('登录失败', '请稍后再试');
|
||||
const message = err?.message || '登录失败,请稍后再试';
|
||||
Alert.alert('登录失败', message);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
@@ -58,7 +64,7 @@ export default function LoginScreen() {
|
||||
const disabledStyle = useMemo(() => ({ opacity: hasAgreed ? 1 : 0.5 }), [hasAgreed]);
|
||||
|
||||
return (
|
||||
<SafeAreaView style={[styles.safeArea, { backgroundColor: color.background }]}>
|
||||
<SafeAreaView edges={['top']} style={[styles.safeArea, { backgroundColor: color.background }]}>
|
||||
<ThemedView style={styles.container}>
|
||||
{/* 自定义头部,与其它页面风格一致 */}
|
||||
<View style={styles.header}>
|
||||
@@ -71,7 +77,7 @@ export default function LoginScreen() {
|
||||
|
||||
<ScrollView contentContainerStyle={styles.content} showsVerticalScrollIndicator={false}>
|
||||
<View style={styles.headerWrap}>
|
||||
<ThemedText style={[styles.title, { color: color.text }]}>Digital Pilates</ThemedText>
|
||||
<ThemedText style={[styles.title, { color: color.text }]}>数字普拉提</ThemedText>
|
||||
<ThemedText style={[styles.subtitle, { color: color.textMuted }]}>欢迎登录</ThemedText>
|
||||
</View>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user