feat: settingmodal

This commit is contained in:
jinyaqiu 2025-08-04 15:26:39 +08:00
parent b266b6646d
commit 84e1263981
10 changed files with 58 additions and 64 deletions

View File

@ -5,13 +5,12 @@ import CarouselComponent from '@/components/owner/carousel';
import CreateCountComponent from '@/components/owner/createCount'; import CreateCountComponent from '@/components/owner/createCount';
import Ranking from '@/components/owner/ranking'; import Ranking from '@/components/owner/ranking';
import MemberCard from '@/components/owner/rights/memberCard'; import MemberCard from '@/components/owner/rights/memberCard';
import SettingModal from '@/components/owner/setting';
import SkeletonOwner from '@/components/owner/SkeletonOwner'; import SkeletonOwner from '@/components/owner/SkeletonOwner';
import UserInfo from '@/components/owner/userName'; import UserInfo from '@/components/owner/userName';
import { checkAuthStatus } from '@/lib/auth'; import { checkAuthStatus } from '@/lib/auth';
import { fetchApi } from '@/lib/server-api-util'; import { fetchApi } from '@/lib/server-api-util';
import { CountData, UserInfoDetails } from '@/types/user'; import { CountData, UserInfoDetails } from '@/types/user';
import { useFocusEffect, usePathname, useRouter } from 'expo-router'; import { useFocusEffect, useRouter } from 'expo-router';
import { useCallback, useEffect, useState } from 'react'; import { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { FlatList, StyleSheet, View } from 'react-native'; import { FlatList, StyleSheet, View } from 'react-native';
@ -21,7 +20,6 @@ export default function OwnerPage() {
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
const { t } = useTranslation(); const { t } = useTranslation();
const router = useRouter(); const router = useRouter();
const pathname = usePathname();
// 添加页面挂载状态 // 添加页面挂载状态
const [isMounted, setIsMounted] = useState(false); const [isMounted, setIsMounted] = useState(false);
@ -36,10 +34,6 @@ export default function OwnerPage() {
checkAuth(); checkAuth();
}, [router]); }, [router]);
// 设置弹窗
const [modalVisible, setModalVisible] = useState(false);
// 数据统计 // 数据统计
const [countData, setCountData] = useState<CountData>({} as CountData); const [countData, setCountData] = useState<CountData>({} as CountData);
@ -147,10 +141,6 @@ export default function OwnerPage() {
{ length: 1000, offset: 1000 * index, index } { length: 1000, offset: 1000 * index, index }
)} )}
/> />
{/* 设置弹窗 - 使用条件渲染避免层级冲突 */}
{modalVisible && (
<SettingModal modalVisible={modalVisible} setModalVisible={setModalVisible} userInfo={userInfoDetails.user_info} />
)}
</View> </View>
); );
} }

View File

@ -34,12 +34,12 @@ const ResetPassword = () => {
} }
if (password !== confirmPassword) { if (password !== confirmPassword) {
setError(t('auth.signup.passwordNotMatch', { ns: 'login' })); setError(t('auth.forgetPwd.passwordNotMatch', { ns: 'login' }));
return; return;
} }
if (password?.length < 6) { if (password?.length < 6) {
setError(t('auth.signup.pwdLengthError', { ns: 'login' })); setError(t('auth.forgetPwd.pwdLengthError', { ns: 'login' }));
return; return;
} }

View File

@ -11,17 +11,17 @@ import { checkNotificationPermission, getLocationPermission, getPermissions, req
import { ThemedText } from '@/components/ThemedText'; import { ThemedText } from '@/components/ThemedText';
import { useAuth } from '@/contexts/auth-context'; import { useAuth } from '@/contexts/auth-context';
import { fetchApi } from '@/lib/server-api-util'; import { fetchApi } from '@/lib/server-api-util';
import { Address, User } from '@/types/user'; import { Address } from '@/types/user';
import * as Location from 'expo-location'; import * as Location from 'expo-location';
import { useRouter } from 'expo-router'; import { useFocusEffect, useRouter } from 'expo-router';
import * as SecureStore from 'expo-secure-store'; import * as SecureStore from 'expo-secure-store';
import React, { useEffect, useState } from 'react'; import React, { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { Linking, Platform, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native'; import { Linking, Platform, Pressable, ScrollView, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
import { useSafeAreaInsets } from "react-native-safe-area-context"; import { useSafeAreaInsets } from "react-native-safe-area-context";
const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: boolean) => void, userInfo: User }) => { const Setting = (props: { userInfo: any }) => {
const { modalVisible, setModalVisible, userInfo } = props; const { userInfo } = props;
const insets = useSafeAreaInsets(); const insets = useSafeAreaInsets();
const { t } = useTranslation(); const { t } = useTranslation();
// 判断当前语言环境 // 判断当前语言环境
@ -59,7 +59,6 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
.then((granted: boolean | ((prevState: boolean) => boolean)) => { .then((granted: boolean | ((prevState: boolean) => boolean)) => {
setNotificationsEnabled(granted); setNotificationsEnabled(granted);
}); });
setModalVisible(false);
} }
}; };
@ -74,7 +73,6 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
.then((granted: boolean | ((prevState: boolean) => boolean)) => { .then((granted: boolean | ((prevState: boolean) => boolean)) => {
setAlbumEnabled(granted); setAlbumEnabled(granted);
}); });
setModalVisible(false);
} }
} }
@ -90,7 +88,6 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
.then((granted: boolean | ((prevState: boolean) => boolean)) => { .then((granted: boolean | ((prevState: boolean) => boolean)) => {
setLocationEnabled(granted); setLocationEnabled(granted);
}); });
setModalVisible(false);
} }
}; };
// 正在获取位置信息 // 正在获取位置信息
@ -166,7 +163,6 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
}) })
.then(async (res) => { .then(async (res) => {
await logout(); await logout();
setModalVisible(false);
router.replace('/login'); router.replace('/login');
}) })
.catch(() => { .catch(() => {
@ -174,22 +170,32 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
}); });
}; };
// 检查是否有权限 // 检查是否有权限
useEffect(() => { useFocusEffect(
if (modalVisible) { useCallback(() => {
// 位置权限 let isActive = true;
getLocationPermission().then((res: boolean | ((prevState: boolean) => boolean)) => {
setLocationEnabled(res); const checkPermissions = async () => {
}) // 位置权限
// 媒体库权限 const locationRes = await getLocationPermission();
getPermissions().then((res: boolean | ((prevState: boolean) => boolean)) => { // 媒体库权限
setAlbumEnabled(res); const albumRes = await getPermissions();
}) // 通知权限
// 通知权限 const notificationRes = await checkNotificationPermission();
checkNotificationPermission().then((res: boolean | ((prevState: boolean) => boolean)) => {
setNotificationsEnabled(res); if (isActive) {
}) setLocationEnabled(locationRes);
} setAlbumEnabled(albumRes);
}, [modalVisible]) setNotificationsEnabled(notificationRes);
}
};
checkPermissions();
return () => {
isActive = false;
};
}, [])
);
// 获取语言环境 // 获取语言环境
useEffect(() => { useEffect(() => {
@ -215,8 +221,6 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
{/* 用户信息 */} {/* 用户信息 */}
<UserInfo <UserInfo
userInfo={userInfo} userInfo={userInfo}
setModalVisible={setModalVisible}
modalVisible={modalVisible}
setCurrentLocation={setCurrentLocation} setCurrentLocation={setCurrentLocation}
getCurrentLocation={getCurrentLocation} getCurrentLocation={getCurrentLocation}
isLoading={isLoading} isLoading={isLoading}
@ -387,7 +391,7 @@ const Setting = (props: { modalVisible: boolean, setModalVisible: (visible: bool
</Pressable> </Pressable>
<PrivacyModal modalVisible={privacyModalVisible} setModalVisible={setPrivacyModalVisible} type={modalType} /> <PrivacyModal modalVisible={privacyModalVisible} setModalVisible={setPrivacyModalVisible} type={modalType} />
<LcensesModal modalVisible={lcensesModalVisible} setModalVisible={setLcensesModalVisible} /> <LcensesModal modalVisible={lcensesModalVisible} setModalVisible={setLcensesModalVisible} />
<DeleteModal modalVisible={deleteModalVisible} setModalVisible={setDeleteModalVisible} setSettingModalVisible={setModalVisible} /> <DeleteModal modalVisible={deleteModalVisible} setModalVisible={setDeleteModalVisible} />
</View> </View>
); );
}; };

View File

@ -51,7 +51,7 @@ const ForgetPwd = ({ setIsSignUp, updateUrlParam, setError }: LoginProps) => {
setCountdown(60); setCountdown(60);
}) })
.catch((error) => { .catch((error) => {
setError(t('auth.forgetPwd.sendEmailError', { ns: 'login' })); setError(error.message || t('auth.forgetPwd.sendEmailError', { ns: 'login' }));
}) })
.finally(() => { .finally(() => {
setLocading(false); setLocading(false);

View File

@ -52,7 +52,7 @@ const Login = ({ updateUrlParam, setError, setShowPassword, showPassword }: Logi
router.replace('/user-message'); router.replace('/user-message');
} }
} catch (error) { } catch (error) {
// Handle error setError(error.message || t('auth.login.loginError', { ns: 'login' }));
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }

View File

@ -6,8 +6,8 @@ import { useTranslation } from 'react-i18next';
import { Modal, Pressable, StyleSheet, View } from 'react-native'; import { Modal, Pressable, StyleSheet, View } from 'react-native';
import { ThemedText } from '../ThemedText'; import { ThemedText } from '../ThemedText';
const DeleteModal = (props: { modalVisible: boolean, setModalVisible: (visible: boolean) => void, setSettingModalVisible: (visible: boolean) => void }) => { const DeleteModal = (props: { modalVisible: boolean, setModalVisible: (visible: boolean) => void }) => {
const { modalVisible, setModalVisible, setSettingModalVisible } = props; const { modalVisible, setModalVisible } = props;
const { logout } = useAuth(); const { logout } = useAuth();
const { t } = useTranslation(); const { t } = useTranslation();
const router = useRouter(); const router = useRouter();
@ -22,7 +22,6 @@ const DeleteModal = (props: { modalVisible: boolean, setModalVisible: (visible:
.then(async (res) => { .then(async (res) => {
await logout(); await logout();
setModalVisible(false); setModalVisible(false);
setSettingModalVisible(false);
router.replace('/login'); router.replace('/login');
}) })
.catch(() => { .catch(() => {

View File

@ -19,6 +19,9 @@ import { checkNotificationPermission, getLocationPermission, getPermissions, req
const SettingModal = (props: { modalVisible: boolean, setModalVisible: (visible: boolean) => void, userInfo: User }) => { const SettingModal = (props: { modalVisible: boolean, setModalVisible: (visible: boolean) => void, userInfo: User }) => {
const { modalVisible, setModalVisible, userInfo } = props; const { modalVisible, setModalVisible, userInfo } = props;
console.log(111111111111111111111111);
console.log("hjhkkkkkkkkkkkkkkkkkkkkkkkkkkk111111111", setModalVisible);
const { t } = useTranslation(); const { t } = useTranslation();
const [modalType, setModalType] = useState<'ai' | 'terms' | 'privacy' | 'user'>('ai'); const [modalType, setModalType] = useState<'ai' | 'terms' | 'privacy' | 'user'>('ai');
@ -213,8 +216,6 @@ const SettingModal = (props: { modalVisible: boolean, setModalVisible: (visible:
{/* 用户信息 */} {/* 用户信息 */}
<UserInfo <UserInfo
userInfo={userInfo} userInfo={userInfo}
setModalVisible={setModalVisible}
modalVisible={modalVisible}
setCurrentLocation={setCurrentLocation} setCurrentLocation={setCurrentLocation}
getCurrentLocation={getCurrentLocation} getCurrentLocation={getCurrentLocation}
isLoading={isLoading} isLoading={isLoading}

View File

@ -12,8 +12,6 @@ import { ThemedText } from "../ThemedText";
interface UserInfoProps { interface UserInfoProps {
userInfo: User; userInfo: User;
setModalVisible: (visible: boolean) => void;
modalVisible: boolean;
getCurrentLocation: () => void; getCurrentLocation: () => void;
isLoading: boolean; isLoading: boolean;
isRefreshing: boolean; isRefreshing: boolean;
@ -21,7 +19,8 @@ interface UserInfoProps {
setCurrentLocation: (location: Address) => void; setCurrentLocation: (location: Address) => void;
} }
const UserInfo = (props: UserInfoProps) => { const UserInfo = (props: UserInfoProps) => {
const { userInfo, setModalVisible, modalVisible, getCurrentLocation, isLoading, isRefreshing, currentLocation, setCurrentLocation } = props; const { userInfo, getCurrentLocation, isLoading, isRefreshing, currentLocation, setCurrentLocation } = props;
const router = useRouter(); const router = useRouter();
const { t } = useTranslation(); const { t } = useTranslation();
// 获取本地存储的location // 获取本地存储的location
@ -71,13 +70,11 @@ const UserInfo = (props: UserInfoProps) => {
// 在组件挂载时自动获取位置(可选) // 在组件挂载时自动获取位置(可选)
useEffect(() => { useEffect(() => {
if (modalVisible) { getLocation();
getLocation(); if (currentLocation && Object?.keys(currentLocation)?.length === 0) {
if (currentLocation && Object?.keys(currentLocation)?.length === 0) { getCurrentLocation();
getCurrentLocation();
}
} }
}, [modalVisible]) }, [])
return ( return (
<View style={styles.container}> <View style={styles.container}>
@ -124,7 +121,6 @@ const UserInfo = (props: UserInfoProps) => {
<UserSvg width={80} height={80} /> <UserSvg width={80} height={80} />
} }
<TouchableOpacity style={styles.edit} onPress={() => { <TouchableOpacity style={styles.edit} onPress={() => {
setModalVisible(false);
// 携带参数跳转 // 携带参数跳转
router.push({ router.push({
pathname: '/user-message', pathname: '/user-message',

View File

@ -66,8 +66,7 @@
"accountPlaceholder": "Enter your account or email", "accountPlaceholder": "Enter your account or email",
"signUpMessage": "Dont have an account?", "signUpMessage": "Dont have an account?",
"signUp": "Sign up", "signUp": "Sign up",
"phoneLogin": "Phone Login", "phoneLogin": "Phone Login"
"passwordNotMatch": "Passwords do not match"
}, },
"agree": { "agree": {
"logintext": "By logging in, you agree to our", "logintext": "By logging in, you agree to our",
@ -87,7 +86,10 @@
"sendEmailBtn": "Send email", "sendEmailBtn": "Send email",
"goback": "Go back", "goback": "Go back",
"success": "Email sent successfully, please check your email", "success": "Email sent successfully, please check your email",
"sendEmailBtnDisabled": "Email sent" "sendEmailBtnDisabled": "Email sent",
"sendEmailError": "Failed to send email, please try again",
"passwordNotMatch": "Passwords do not match",
"pwdLengthError": "Password length must be at least 6 characters"
}, },
"resetPwd": { "resetPwd": {
"title": "Reset password", "title": "Reset password",

View File

@ -66,8 +66,7 @@
"accountPlaceholder": "请输入您的账号或邮箱", "accountPlaceholder": "请输入您的账号或邮箱",
"signUpMessage": "还没有账号?", "signUpMessage": "还没有账号?",
"signUp": "注册", "signUp": "注册",
"phoneLogin": "手机号登录", "phoneLogin": "手机号登录"
"passwordNotMatch": "密码不一致"
}, },
"agree": { "agree": {
"logintext": "登录即表示您同意我们的", "logintext": "登录即表示您同意我们的",
@ -87,7 +86,10 @@
"sendEmailBtn": "发送邮件", "sendEmailBtn": "发送邮件",
"signupButton": "注册", "signupButton": "注册",
"goback": "返回登录", "goback": "返回登录",
"sendEmailBtnDisabled": "已发送" "sendEmailBtnDisabled": "已发送",
"sendEmailError": "发送失败,请重试",
"passwordNotMatch": "密码不一致",
"pwdLengthError": "密码长度至少为6位"
}, },
"resetPwd": { "resetPwd": {
"title": "重置密码", "title": "重置密码",