添加注册和账户信息页面,更新登录页面,修改样式和国际化文本,调整导航逻辑,更新 package.json 以支持 Node 22.12.0,替换 logo 图片。
This commit is contained in:
16
App.jsx
16
App.jsx
@@ -23,10 +23,12 @@ import { AuthProvider, useContextHook } from './components/AuthContext/index';
|
|||||||
|
|
||||||
|
|
||||||
import Login from '@/views/Login/index';
|
import Login from '@/views/Login/index';
|
||||||
|
import Signup from '@/views/Signup/index';
|
||||||
import Guide from '@/views/Guide/index';
|
import Guide from '@/views/Guide/index';
|
||||||
import HomeIndex from '@/views/Home/Index/index';
|
import HomeIndex from '@/views/Home/Index/index';
|
||||||
import HomeInventory from '@/views/Home/Inventory/index';
|
import HomeInventory from '@/views/Home/Inventory/index';
|
||||||
import HomeProfile from '@/views/Home/Profile/index';
|
import HomeProfile from '@/views/Home/Profile/index';
|
||||||
|
import AccountInfo from '@/views/AccountInfo/index';
|
||||||
|
|
||||||
|
|
||||||
const Tab = createBottomTabNavigator();
|
const Tab = createBottomTabNavigator();
|
||||||
@@ -107,6 +109,13 @@ function RootStack() {
|
|||||||
}}
|
}}
|
||||||
component={Login}
|
component={Login}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="Signup"
|
||||||
|
options={{
|
||||||
|
headerShown: false,
|
||||||
|
}}
|
||||||
|
component={Signup}
|
||||||
|
/>
|
||||||
<Stack.Screen
|
<Stack.Screen
|
||||||
name="Home"
|
name="Home"
|
||||||
component={HomeTabs}
|
component={HomeTabs}
|
||||||
@@ -114,6 +123,13 @@ function RootStack() {
|
|||||||
headerShown: false,
|
headerShown: false,
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
<Stack.Screen
|
||||||
|
name="AccountInfo"
|
||||||
|
component={AccountInfo}
|
||||||
|
options={{
|
||||||
|
headerShown: false,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 1.7 KiB |
@@ -82,13 +82,14 @@ export const positionFixed = useStyles({
|
|||||||
position: 'fixed',
|
position: 'fixed',
|
||||||
});
|
});
|
||||||
|
|
||||||
export const getColor = (color = {brandPrimary: '#ff6600', brandPrimaryTap: '#ff6600' }) => {
|
export const getColor = (
|
||||||
|
color = { brandPrimary: '#6B39F4', brandPrimaryTap: '#ff6600', checkbox_border: '#888888', fill_body: '#ffffff',fill_base: '#f5f5f9' },
|
||||||
|
) => {
|
||||||
const brandPrimary = color.brandPrimary || '#108ee9';
|
const brandPrimary = color.brandPrimary || '#108ee9';
|
||||||
const brandPrimaryTap = color.brandPrimaryTap || '#1284d6';
|
const brandPrimaryTap = color.brandPrimaryTap || '#1284d6';
|
||||||
return {
|
return {
|
||||||
transparent: 'transparent',
|
brandPrimary,
|
||||||
brandPrimary,
|
brandPrimaryTap,
|
||||||
brandPrimaryTap,
|
|
||||||
|
|
||||||
// 文字色
|
// 文字色
|
||||||
color_text_base: color.color_text_base || '#000000', // 基本
|
color_text_base: color.color_text_base || '#000000', // 基本
|
||||||
@@ -124,7 +125,7 @@ export const getColor = (color = {brandPrimary: '#ff6600', brandPrimaryTap: '#ff
|
|||||||
primary_button_fill_tap: color.primary_button_fill_tap || brandPrimaryTap,
|
primary_button_fill_tap: color.primary_button_fill_tap || brandPrimaryTap,
|
||||||
|
|
||||||
ghost_button_color: color.ghost_button_color || brandPrimary, // 同时应用于背景、文字颜色、边框色
|
ghost_button_color: color.ghost_button_color || brandPrimary, // 同时应用于背景、文字颜色、边框色
|
||||||
ghost_button_fill_tap: color.ghost_button_fill_tap || `${brandPrimary}99`, // alpha 60%
|
ghost_button_fill_tap: color.ghost_button_fill_tap || `${brandPrimary}99`, // alpha 60%
|
||||||
|
|
||||||
warning_button_fill: color.warning_button_fill || '#e94f4f',
|
warning_button_fill: color.warning_button_fill || '#e94f4f',
|
||||||
warning_button_fill_tap: color.warning_button_fill_tap || '#d24747',
|
warning_button_fill_tap: color.warning_button_fill_tap || '#d24747',
|
||||||
|
|||||||
@@ -1,10 +1,28 @@
|
|||||||
{
|
{
|
||||||
"welcome": "Welcome",
|
"Welcome_Back": "Welcome Back!",
|
||||||
"greeting": "Hello, {{name}}!",
|
"Sign_in_to_your_account": "Sign in to your account",
|
||||||
"login": "Login123",
|
"Sign_In": "Sign In",
|
||||||
"username": "Username",
|
"Remember_me": "Remember me",
|
||||||
"password": "Password",
|
"Forgot_password": "Forgot password?",
|
||||||
|
"Do_not_have_an_account": "Don’t have an account?",
|
||||||
|
"Sign_Up": "Sign Up",
|
||||||
|
"Or_sign_in_with": "Or sign in with",
|
||||||
|
"Email": "Email",
|
||||||
|
"Password": "Password",
|
||||||
|
"Please_enter_email": "Please enter email",
|
||||||
|
"Please_enter_password": "Please enter password",
|
||||||
|
"loading": "Loading...",
|
||||||
"login_success": "Login Success",
|
"login_success": "Login Success",
|
||||||
"login_failed": "Login Failed",
|
"login_failed": "Login Failed",
|
||||||
"login_error_message": "Login Failed, Please Try Again"
|
"login_error_message": "Login Failed, Please Try Again",
|
||||||
|
"Create_your_account": "Create your account",
|
||||||
|
"Let_us_get_started_with_a_free_Financy_account": "Let us get started with a free Financy account.",
|
||||||
|
"Full_name": "Full name",
|
||||||
|
"I_certify_that_I_am_18_years_of_age_or_older": "I certify that I’m 18 years of age or older",
|
||||||
|
"agree_to_the": "agree to the",
|
||||||
|
"User_Agreement": "User Agreement",
|
||||||
|
"Privacy_Policy": "Privacy Policy.",
|
||||||
|
"What’s_your_citizenship": "What’s your citizenship?",
|
||||||
|
"If_you’re_a_citizen_of_more_than_one_country,_please_pick_one": "If you’re a citizen of more than one country, please pick one.",
|
||||||
|
"Citizenship": "Citizenship"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,21 @@
|
|||||||
{
|
{
|
||||||
"welcome": "欢迎",
|
"Welcome_Back": "Welcome Back!",
|
||||||
"greeting": "你好, {{name}}!",
|
"Sign_in_to_your_account": "Sign in to your account",
|
||||||
"login": "登录",
|
"Sign_In": "Sign In",
|
||||||
"username": "用户名",
|
"Remember_me": "Remember me",
|
||||||
"password": "密码",
|
"Forgot_password": "Forgot password?",
|
||||||
"login_success": "登录成功",
|
"Do_not_have_an_account": "Don't have an account?",
|
||||||
"login_failed": "登录失败",
|
"Sign_up": "Sign up",
|
||||||
"login_error_message": "登录失败,请重试"
|
"Or_sign_in_with": "Or sign in with",
|
||||||
|
"Email": "Email",
|
||||||
|
"Password": "Password",
|
||||||
|
"Please_enter_email": "Please enter email",
|
||||||
|
"Please_enter_password": "Please enter password",
|
||||||
|
"loading": "Loading...",
|
||||||
|
"login_success": "Login Success",
|
||||||
|
"login_failed": "Login Failed",
|
||||||
|
"login_error_message": "Login Failed, Please Try Again",
|
||||||
|
"Create_your_account": "Create your account",
|
||||||
|
"Let_us_get_started_with_a_free_Financy_account": "Let us get started with a free Financy account",
|
||||||
|
"Full_name": "Full name"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,5 +53,8 @@
|
|||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"volta": {
|
||||||
|
"node": "22.12.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
96
views/AccountInfo/Components/Citizenship.jsx
Normal file
96
views/AccountInfo/Components/Citizenship.jsx
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import {
|
||||||
|
TouchableOpacity,
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Checkbox,
|
||||||
|
Input,
|
||||||
|
Grid,
|
||||||
|
Icon,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Toast,
|
||||||
|
Button,
|
||||||
|
Carousel
|
||||||
|
} from '@ant-design/react-native';
|
||||||
|
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useContextHook } from '@/components/AuthContext/index';
|
||||||
|
|
||||||
|
import AsyncStorage from '@/storage/index';
|
||||||
|
import { useRouter } from '@/hooks/useRouter';
|
||||||
|
|
||||||
|
import {
|
||||||
|
statusBarHeight,
|
||||||
|
paddingTopStatusBarHeight,
|
||||||
|
flexRow,
|
||||||
|
flexColumn,
|
||||||
|
flexSub,
|
||||||
|
flexShrink,
|
||||||
|
flexWrap,
|
||||||
|
flexnoWrap,
|
||||||
|
justifyStart,
|
||||||
|
justifyEnd,
|
||||||
|
justifyCenter,
|
||||||
|
justifyBetween,
|
||||||
|
justifyAround,
|
||||||
|
justifyEvenly,
|
||||||
|
alignItemsStart,
|
||||||
|
alignItemsEnd,
|
||||||
|
alignItemsCenter,
|
||||||
|
alignItemsStretch,
|
||||||
|
positionRelative,
|
||||||
|
positionAbsolute,
|
||||||
|
useStyles,
|
||||||
|
} from '@/assets/styles/css';
|
||||||
|
|
||||||
|
const inputItem = useStyles({
|
||||||
|
height: 56,
|
||||||
|
width: '100%',
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 8,
|
||||||
|
});
|
||||||
|
|
||||||
|
const Index = () => {
|
||||||
|
|
||||||
|
const { themeColor } = useContextHook();
|
||||||
|
const { t, i18n } = useTranslation();
|
||||||
|
|
||||||
|
const { linkTo, resetAllRoutes, isFocused } = useRouter();
|
||||||
|
useEffect(() => {
|
||||||
|
// 这里请求配置后,再跳转
|
||||||
|
}, [isFocused]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={[flexSub]}>
|
||||||
|
<View style={[flexRow, { paddingHorizontal: 24 }]}>
|
||||||
|
<Text style={{ fontSize: 24, fontWeight: 'bold', color: themeColor.color_text_base, lineHeight: 38 }}>{t('What’s_your_citizenship')}?</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[flexRow, { paddingLeft: 24, paddingRight: 100 }]}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_caption, lineHeight: 24 }}>{t('If_you’re_a_citizen_of_more_than_one_country,_please_pick_one')}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={[flexRow, { padding: 24 }]}>
|
||||||
|
<Text style={{ fontSize: 18, fontWeight: 'bold', color: themeColor.color_text_base, lineHeight: 24 }}>{t('Citizenship')}?</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={[flexRow, { padding: 24 }]}>
|
||||||
|
<Text style={{ fontSize: 18, fontWeight: 'bold', color: themeColor.color_text_base, lineHeight: 24 }}>{t('Citizenship')}?</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<View style={[flexSub]}></View>
|
||||||
|
|
||||||
|
<View style={[flexRow, alignItemsCenter, justifyCenter, { padding: 24 }]}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_caption, lineHeight: 24 }}>{t('Do_not_have_an_account')}</Text>
|
||||||
|
<TouchableOpacity onPress={() => linkTo('Login')}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.brandPrimary, lineHeight: 24 }}>{t('Sign_In')}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default Index;
|
||||||
176
views/AccountInfo/index.jsx
Normal file
176
views/AccountInfo/index.jsx
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
import { useState, useEffect, useRef } from 'react';
|
||||||
|
import {
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
StyleSheet,
|
||||||
|
Alert,
|
||||||
|
StatusBar,
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Checkbox,
|
||||||
|
Input,
|
||||||
|
Grid,
|
||||||
|
Icon,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Toast,
|
||||||
|
Button,
|
||||||
|
Carousel
|
||||||
|
} from '@ant-design/react-native';
|
||||||
|
|
||||||
|
|
||||||
|
import { useContextHook } from '@/components/AuthContext';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useRouter } from '@/hooks/useRouter';
|
||||||
|
|
||||||
|
import Citizenship from './Components/Citizenship';
|
||||||
|
|
||||||
|
import {
|
||||||
|
statusBarHeight,
|
||||||
|
paddingTopStatusBarHeight,
|
||||||
|
flexRow,
|
||||||
|
flexColumn,
|
||||||
|
flexSub,
|
||||||
|
flexShrink,
|
||||||
|
flexWrap,
|
||||||
|
flexnoWrap,
|
||||||
|
justifyStart,
|
||||||
|
justifyEnd,
|
||||||
|
justifyCenter,
|
||||||
|
justifyBetween,
|
||||||
|
justifyAround,
|
||||||
|
justifyEvenly,
|
||||||
|
alignItemsStart,
|
||||||
|
alignItemsEnd,
|
||||||
|
alignItemsCenter,
|
||||||
|
alignItemsStretch,
|
||||||
|
positionRelative,
|
||||||
|
positionAbsolute,
|
||||||
|
useStyles,
|
||||||
|
} from '@/assets/styles/css';
|
||||||
|
|
||||||
|
|
||||||
|
const inputItem = useStyles({
|
||||||
|
height: 56,
|
||||||
|
width: '100%',
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 8,
|
||||||
|
});
|
||||||
|
|
||||||
|
const LoginScreen = () => {
|
||||||
|
const { themeColor } = useContextHook();
|
||||||
|
const { t, i18n } = useTranslation();
|
||||||
|
console.log('🚀 ~ LoginScreen ~ i18n:', i18n)
|
||||||
|
|
||||||
|
const { linkTo } = useRouter();
|
||||||
|
const [language, setLanguage] = useState('en');
|
||||||
|
|
||||||
|
|
||||||
|
const [fullName, setFullName] = useState('');
|
||||||
|
const [email, setEmail] = useState('');
|
||||||
|
const [password, setPassword] = useState('');
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
|
const [checked, setChecked] = useState(false);
|
||||||
|
const onChangeCheckbox = (e) => {
|
||||||
|
console.log('checked = ', e.target.checked)
|
||||||
|
setChecked(e.target.checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLogin = () => {
|
||||||
|
if (!email) {
|
||||||
|
Toast.show({
|
||||||
|
content: t('Please enter email'),
|
||||||
|
position: 'center',
|
||||||
|
mask: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!password) {
|
||||||
|
Toast.show({
|
||||||
|
content: t('Please enter password'),
|
||||||
|
position: 'center',
|
||||||
|
mask: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const key = Toast.show({
|
||||||
|
icon: 'loading',
|
||||||
|
content: t('loading'),
|
||||||
|
position: 'center',
|
||||||
|
mask: true,
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
console.log(123, 123);
|
||||||
|
// login({ username, password })
|
||||||
|
// .then(res => {
|
||||||
|
// Toast.remove(key);
|
||||||
|
// setTimeout(() => {
|
||||||
|
// Toast.show({
|
||||||
|
// content: t('login success'), //i18n.t('login_success'),
|
||||||
|
// position: 'center',
|
||||||
|
// mask: true,
|
||||||
|
// onClose: () => {
|
||||||
|
// // 设置全局的用户信息
|
||||||
|
// setUser(res.user)
|
||||||
|
// AsyncStorage.setItem('appToken', {
|
||||||
|
// appToken: res.token,
|
||||||
|
// user: res.user,
|
||||||
|
// }).then(() => {
|
||||||
|
// linkTo('Home');
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }, 200);
|
||||||
|
// })
|
||||||
|
// .catch(err => {
|
||||||
|
// Toast.remove(key);
|
||||||
|
// setTimeout(() => {
|
||||||
|
// Toast.show({
|
||||||
|
// content: t('login_failed'), // i18n.t('login_failed'),
|
||||||
|
// position: 'center',
|
||||||
|
// mask: true,
|
||||||
|
// });
|
||||||
|
// }, 200);
|
||||||
|
// // i18n.t('login_error_message')
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
|
||||||
|
const carouselRef = useRef(null);
|
||||||
|
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
flexSub,
|
||||||
|
justifyStart,
|
||||||
|
alignItemsStretch,
|
||||||
|
{
|
||||||
|
backgroundColor: themeColor.fill_body,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<View style={[{ paddingTop: 20 }]}>
|
||||||
|
<View style={[{ paddingHorizontal: 24, paddingVertical: 16 }]}>
|
||||||
|
<Icon name="close" size={24} color={themeColor.color_text_base} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<Carousel
|
||||||
|
selectedIndex={selectedIndex}
|
||||||
|
autoplay={false}
|
||||||
|
ref={carouselRef}
|
||||||
|
style={[flexSub, {}]}
|
||||||
|
>
|
||||||
|
<Citizenship />
|
||||||
|
<View style={[flexSub]}>
|
||||||
|
<Text>Carousel 2</Text>
|
||||||
|
</View>
|
||||||
|
</Carousel>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default LoginScreen;
|
||||||
@@ -51,7 +51,7 @@ const Index = () => {
|
|||||||
if (user && user.token) {
|
if (user && user.token) {
|
||||||
resetAllRoutes('Home');
|
resetAllRoutes('Home');
|
||||||
} else {
|
} else {
|
||||||
resetAllRoutes('Login');
|
resetAllRoutes('AccountInfo');
|
||||||
}
|
}
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}, [isFocused]);
|
}, [isFocused]);
|
||||||
@@ -65,21 +65,25 @@ const Index = () => {
|
|||||||
alignItemsCenter,
|
alignItemsCenter,
|
||||||
flexRow
|
flexRow
|
||||||
]}>
|
]}>
|
||||||
|
<Image
|
||||||
|
source={require('@/assets/images/logo.png')}
|
||||||
|
style={[
|
||||||
|
{
|
||||||
|
width: 52,
|
||||||
|
height: 52,
|
||||||
|
resizeMode: 'contain',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
<Text
|
<Text
|
||||||
style={{
|
style={{
|
||||||
fontSize: 24,
|
fontSize: 32,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
backgroundColor: 'red',
|
marginLeft: 10,
|
||||||
|
color: themeColor.color_text_base,
|
||||||
}}>
|
}}>
|
||||||
login111
|
Finix
|
||||||
</Text>
|
</Text>
|
||||||
<Button type="primary" onPress={() => {
|
|
||||||
Toast.show({
|
|
||||||
content: 'Please enter user name',
|
|
||||||
position: 'center',
|
|
||||||
mask: true,
|
|
||||||
});
|
|
||||||
}}>Click me</Button>
|
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,20 +1,30 @@
|
|||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
import {
|
import {
|
||||||
View,
|
|
||||||
Text,
|
|
||||||
TextInput,
|
TextInput,
|
||||||
TouchableOpacity,
|
TouchableOpacity,
|
||||||
Image,
|
Image,
|
||||||
StyleSheet,
|
StyleSheet,
|
||||||
Alert,
|
Alert,
|
||||||
|
StatusBar,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { Provider, Toast } from '@ant-design/react-native';
|
|
||||||
|
|
||||||
|
|
||||||
import AsyncStorage from '@/storage/index';
|
import {
|
||||||
|
Checkbox,
|
||||||
|
Input,
|
||||||
|
Grid,
|
||||||
|
Icon,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Toast,
|
||||||
|
Button,
|
||||||
|
} from '@ant-design/react-native';
|
||||||
|
|
||||||
|
|
||||||
|
import AsyncStorage from '@/storage/index';
|
||||||
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
import { useNavigation, useIsFocused } from '@react-navigation/native';
|
||||||
import { useContextHook } from '@/components/AuthContext';
|
import { useContextHook } from '@/components/AuthContext';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useRouter } from '@/hooks/useRouter';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
statusBarHeight,
|
statusBarHeight,
|
||||||
@@ -42,13 +52,11 @@ import {
|
|||||||
|
|
||||||
|
|
||||||
const inputItem = useStyles({
|
const inputItem = useStyles({
|
||||||
width: '80%',
|
height: 56,
|
||||||
height: 40,
|
width: '100%',
|
||||||
borderColor: 'gray',
|
borderRadius: 10,
|
||||||
borderWidth: 1,
|
paddingHorizontal: 16,
|
||||||
borderRadius: 5,
|
paddingVertical: 8,
|
||||||
paddingHorizontal: 10,
|
|
||||||
marginBottom: 20,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const LoginScreen = () => {
|
const LoginScreen = () => {
|
||||||
@@ -56,22 +64,18 @@ const LoginScreen = () => {
|
|||||||
const { t, i18n } = useTranslation();
|
const { t, i18n } = useTranslation();
|
||||||
console.log('🚀 ~ LoginScreen ~ i18n:', i18n)
|
console.log('🚀 ~ LoginScreen ~ i18n:', i18n)
|
||||||
|
|
||||||
const router = useNavigation();
|
const { linkTo } = useRouter();
|
||||||
const [language, setLanguage] = useState('en');
|
const [language, setLanguage] = useState('en');
|
||||||
|
|
||||||
const isFocused = useIsFocused();
|
const [email, setEmail] = useState('');
|
||||||
|
|
||||||
const [username, setUsername] = useState('');
|
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
useEffect(() => {
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
}, [isFocused]);
|
|
||||||
|
|
||||||
const handleLogin = () => {
|
const handleLogin = () => {
|
||||||
if (!username) {
|
if (!email) {
|
||||||
Toast.show({
|
Toast.show({
|
||||||
content: t('Please enter user name'),
|
content: t('Please enter email'),
|
||||||
position: 'center',
|
position: 'center',
|
||||||
mask: true,
|
mask: true,
|
||||||
});
|
});
|
||||||
@@ -92,7 +96,7 @@ const LoginScreen = () => {
|
|||||||
mask: true,
|
mask: true,
|
||||||
duration: 0,
|
duration: 0,
|
||||||
});
|
});
|
||||||
console.log(123,123);
|
console.log(123, 123);
|
||||||
// login({ username, password })
|
// login({ username, password })
|
||||||
// .then(res => {
|
// .then(res => {
|
||||||
// Toast.remove(key);
|
// Toast.remove(key);
|
||||||
@@ -108,7 +112,7 @@ const LoginScreen = () => {
|
|||||||
// appToken: res.token,
|
// appToken: res.token,
|
||||||
// user: res.user,
|
// user: res.user,
|
||||||
// }).then(() => {
|
// }).then(() => {
|
||||||
// router.replace('Home');
|
// linkTo('Home');
|
||||||
// });
|
// });
|
||||||
// },
|
// },
|
||||||
// });
|
// });
|
||||||
@@ -131,64 +135,96 @@ const LoginScreen = () => {
|
|||||||
<View
|
<View
|
||||||
style={[
|
style={[
|
||||||
flexSub,
|
flexSub,
|
||||||
justifyCenter,
|
justifyStart,
|
||||||
alignItemsCenter,
|
alignItemsStretch,
|
||||||
{
|
{
|
||||||
backgroundColor: themeColor.colorBgBase,
|
backgroundColor: themeColor.fill_body,
|
||||||
},
|
},
|
||||||
]}>
|
]}>
|
||||||
<View style={[{ padding: 20 }]}>
|
<View style={[{ backgroundColor: themeColor.color_text_base, height: 240, paddingTop: 20 }]}>
|
||||||
<Image
|
<View style={[{ paddingHorizontal: 24, paddingVertical: 16 }]}>
|
||||||
source={require('@/assets/images/logo.png')}
|
<Icon name="close" size={24} color={themeColor.color_text_base_inverse} />
|
||||||
style={[
|
</View>
|
||||||
{
|
<View style={[flexRow, alignItemsCenter, justifyCenter]}>
|
||||||
width: 300,
|
<Image
|
||||||
height: 150,
|
source={require('@/assets/images/logo.png')}
|
||||||
resizeMode: 'contain',
|
style={[
|
||||||
},
|
{
|
||||||
]}
|
width: 64,
|
||||||
|
height: 64,
|
||||||
|
resizeMode: 'contain',
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={[flexRow, alignItemsCenter, justifyCenter]}>
|
||||||
|
<Text style={{ fontSize: 24, fontWeight: 'bold', color: themeColor.color_text_base_inverse, lineHeight: 38 }}>{t('Welcome_Back')}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[flexRow, alignItemsCenter, justifyCenter]}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_caption, lineHeight: 24 }}>{t('Sign_in_to_your_account')}</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={[{ paddingHorizontal: 24, marginBottom: 16, paddingTop: 24 }]}>
|
||||||
|
<Input
|
||||||
|
style={[inputItem, { backgroundColor: themeColor.fill_base }]}
|
||||||
|
placeholder={t('Email')}
|
||||||
|
value={email}
|
||||||
|
onChangeText={setEmail}
|
||||||
|
autoCapitalize="none"
|
||||||
|
keyboardType="default"
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<Text
|
<View style={[{ paddingHorizontal: 24, marginBottom: 16 }]}>
|
||||||
style={{
|
<Input
|
||||||
fontSize: 24,
|
style={[inputItem, { backgroundColor: themeColor.fill_base }]}
|
||||||
fontWeight: 'bold',
|
placeholder={t('Password')}
|
||||||
marginBottom: 20,
|
value={password}
|
||||||
}}>
|
onChangeText={setPassword}
|
||||||
{t('login')}
|
type={!showPassword ? 'password' : 'text'}
|
||||||
</Text>
|
suffix={
|
||||||
<TextInput
|
<TouchableOpacity onPress={() => setShowPassword(!showPassword)}>
|
||||||
style={[inputItem]}
|
<Icon name={!showPassword ? 'eye-invisible' : 'eye'} size={24} color={themeColor.color_text_placeholder} />
|
||||||
placeholder={t('username')}
|
</TouchableOpacity>
|
||||||
value={username}
|
}
|
||||||
onChangeText={setUsername}
|
/>
|
||||||
autoCapitalize="none"
|
</View>
|
||||||
keyboardType="default"
|
<View style={[{ paddingHorizontal: 24, marginBottom: 16 }]}>
|
||||||
/>
|
<Button
|
||||||
<TextInput
|
type="primary"
|
||||||
style={[inputItem]}
|
|
||||||
placeholder={t('password')}
|
|
||||||
value={password}
|
|
||||||
onChangeText={setPassword}
|
|
||||||
secureTextEntry
|
|
||||||
/>
|
|
||||||
<TouchableOpacity
|
|
||||||
style={{
|
|
||||||
width: '80%',
|
|
||||||
backgroundColor: '#7ac0f6',
|
|
||||||
borderRadius: 5,
|
|
||||||
paddingVertical: 10,
|
|
||||||
}}
|
|
||||||
onPress={handleLogin}>
|
|
||||||
<Text
|
|
||||||
style={{
|
style={{
|
||||||
color: '#fff',
|
height: 56,
|
||||||
textAlign: 'center',
|
borderRadius: 10,
|
||||||
fontSize: 18,
|
}}
|
||||||
}}>
|
onPress={handleLogin}>
|
||||||
{t('login')}
|
{t('Sign_In')}
|
||||||
</Text>
|
</Button>
|
||||||
</TouchableOpacity>
|
</View>
|
||||||
|
|
||||||
|
<View style={[flexRow, alignItemsCenter, justifyBetween, { paddingHorizontal: 24, marginBottom: 16 }]}>
|
||||||
|
<Checkbox>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_base, lineHeight: 24 }}>{t('Remember_me')}</Text>
|
||||||
|
</Checkbox>
|
||||||
|
|
||||||
|
<View style={[{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }]}>
|
||||||
|
<TouchableOpacity onPress={() => linkTo('ForgotPassword')}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.brandPrimary, lineHeight: 24, fontWeight: 'bold' }}>{t('Forgot_password')}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
{/* <View style={[{ paddingHorizontal: 24, marginBottom: 16 }]}>
|
||||||
|
<View style={[{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }]}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_caption, lineHeight: 24 }}>{t('Or_sign_in_with')}</Text>
|
||||||
|
</View>
|
||||||
|
</View> */}
|
||||||
|
<View style={[flexSub]}></View>
|
||||||
|
|
||||||
|
<View style={[{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center', padding: 24 }]}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_caption, lineHeight: 24 }}>{t('Do_not_have_an_account')}</Text>
|
||||||
|
<TouchableOpacity onPress={() => linkTo('Signup')}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.brandPrimary, lineHeight: 24 }}>{t('Sign_up')}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
240
views/Signup/index.jsx
Normal file
240
views/Signup/index.jsx
Normal file
@@ -0,0 +1,240 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import {
|
||||||
|
TextInput,
|
||||||
|
TouchableOpacity,
|
||||||
|
Image,
|
||||||
|
StyleSheet,
|
||||||
|
Alert,
|
||||||
|
StatusBar,
|
||||||
|
} from 'react-native';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Checkbox,
|
||||||
|
Input,
|
||||||
|
Grid,
|
||||||
|
Icon,
|
||||||
|
View,
|
||||||
|
Text,
|
||||||
|
Toast,
|
||||||
|
Button,
|
||||||
|
} from '@ant-design/react-native';
|
||||||
|
|
||||||
|
|
||||||
|
import AsyncStorage from '@/storage/index';
|
||||||
|
import { useContextHook } from '@/components/AuthContext';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useRouter } from '@/hooks/useRouter';
|
||||||
|
|
||||||
|
import {
|
||||||
|
statusBarHeight,
|
||||||
|
paddingTopStatusBarHeight,
|
||||||
|
flexRow,
|
||||||
|
flexColumn,
|
||||||
|
flexSub,
|
||||||
|
flexShrink,
|
||||||
|
flexWrap,
|
||||||
|
flexnoWrap,
|
||||||
|
justifyStart,
|
||||||
|
justifyEnd,
|
||||||
|
justifyCenter,
|
||||||
|
justifyBetween,
|
||||||
|
justifyAround,
|
||||||
|
justifyEvenly,
|
||||||
|
alignItemsStart,
|
||||||
|
alignItemsEnd,
|
||||||
|
alignItemsCenter,
|
||||||
|
alignItemsStretch,
|
||||||
|
positionRelative,
|
||||||
|
positionAbsolute,
|
||||||
|
useStyles,
|
||||||
|
} from '@/assets/styles/css';
|
||||||
|
|
||||||
|
|
||||||
|
const inputItem = useStyles({
|
||||||
|
height: 56,
|
||||||
|
width: '100%',
|
||||||
|
borderRadius: 10,
|
||||||
|
paddingHorizontal: 16,
|
||||||
|
paddingVertical: 8,
|
||||||
|
});
|
||||||
|
|
||||||
|
const LoginScreen = () => {
|
||||||
|
const { themeColor } = useContextHook();
|
||||||
|
const { t, i18n } = useTranslation();
|
||||||
|
console.log('🚀 ~ LoginScreen ~ i18n:', i18n)
|
||||||
|
|
||||||
|
const { linkTo } = useRouter();
|
||||||
|
const [language, setLanguage] = useState('en');
|
||||||
|
|
||||||
|
|
||||||
|
const [fullName, setFullName] = useState('');
|
||||||
|
const [email, setEmail] = useState('');
|
||||||
|
const [password, setPassword] = useState('');
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [showPassword, setShowPassword] = useState(false);
|
||||||
|
|
||||||
|
const [checked, setChecked] = useState(false);
|
||||||
|
const onChangeCheckbox = (e) => {
|
||||||
|
console.log('checked = ', e.target.checked)
|
||||||
|
setChecked(e.target.checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleLogin = () => {
|
||||||
|
if (!email) {
|
||||||
|
Toast.show({
|
||||||
|
content: t('Please enter email'),
|
||||||
|
position: 'center',
|
||||||
|
mask: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!password) {
|
||||||
|
Toast.show({
|
||||||
|
content: t('Please enter password'),
|
||||||
|
position: 'center',
|
||||||
|
mask: true,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const key = Toast.show({
|
||||||
|
icon: 'loading',
|
||||||
|
content: t('loading'),
|
||||||
|
position: 'center',
|
||||||
|
mask: true,
|
||||||
|
duration: 0,
|
||||||
|
});
|
||||||
|
console.log(123, 123);
|
||||||
|
// login({ username, password })
|
||||||
|
// .then(res => {
|
||||||
|
// Toast.remove(key);
|
||||||
|
// setTimeout(() => {
|
||||||
|
// Toast.show({
|
||||||
|
// content: t('login success'), //i18n.t('login_success'),
|
||||||
|
// position: 'center',
|
||||||
|
// mask: true,
|
||||||
|
// onClose: () => {
|
||||||
|
// // 设置全局的用户信息
|
||||||
|
// setUser(res.user)
|
||||||
|
// AsyncStorage.setItem('appToken', {
|
||||||
|
// appToken: res.token,
|
||||||
|
// user: res.user,
|
||||||
|
// }).then(() => {
|
||||||
|
// linkTo('Home');
|
||||||
|
// });
|
||||||
|
// },
|
||||||
|
// });
|
||||||
|
// }, 200);
|
||||||
|
// })
|
||||||
|
// .catch(err => {
|
||||||
|
// Toast.remove(key);
|
||||||
|
// setTimeout(() => {
|
||||||
|
// Toast.show({
|
||||||
|
// content: t('login_failed'), // i18n.t('login_failed'),
|
||||||
|
// position: 'center',
|
||||||
|
// mask: true,
|
||||||
|
// });
|
||||||
|
// }, 200);
|
||||||
|
// // i18n.t('login_error_message')
|
||||||
|
// });
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View
|
||||||
|
style={[
|
||||||
|
flexSub,
|
||||||
|
justifyStart,
|
||||||
|
alignItemsStretch,
|
||||||
|
{
|
||||||
|
backgroundColor: themeColor.fill_body,
|
||||||
|
},
|
||||||
|
]}>
|
||||||
|
<View style={[{ paddingTop: 20 }]}>
|
||||||
|
<View style={[{ paddingHorizontal: 24, paddingVertical: 16 }]}>
|
||||||
|
<Icon name="close" size={24} color={themeColor.color_text_base} />
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={[flexRow, { paddingHorizontal: 24 }]}>
|
||||||
|
<Text style={{ fontSize: 24, fontWeight: 'bold', color: themeColor.color_text_base, lineHeight: 38 }}>{t('Create_your_account')}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={[flexRow, { paddingHorizontal: 24 }]}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_caption, lineHeight: 24 }}>{t('Let_us_get_started_with_a_free_Financy_account')}</Text>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={[{ paddingHorizontal: 24, marginBottom: 16, paddingTop: 24 }]}>
|
||||||
|
<Input
|
||||||
|
style={[inputItem, { backgroundColor: themeColor.fill_base }]}
|
||||||
|
placeholder={t('Full_name')}
|
||||||
|
value={fullName}
|
||||||
|
onChangeText={setFullName}
|
||||||
|
autoCapitalize="none"
|
||||||
|
keyboardType="default"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={[{ paddingHorizontal: 24, marginBottom: 16 }]}>
|
||||||
|
<Input
|
||||||
|
style={[inputItem, { backgroundColor: themeColor.fill_base }]}
|
||||||
|
placeholder={t('Email')}
|
||||||
|
value={email}
|
||||||
|
onChangeText={setEmail}
|
||||||
|
autoCapitalize="none"
|
||||||
|
keyboardType="default"
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={[{ paddingHorizontal: 24, marginBottom: 16 }]}>
|
||||||
|
<Input
|
||||||
|
style={[inputItem, { backgroundColor: themeColor.fill_base }]}
|
||||||
|
placeholder={t('Password')}
|
||||||
|
value={password}
|
||||||
|
onChangeText={setPassword}
|
||||||
|
type={!showPassword ? 'password' : 'text'}
|
||||||
|
suffix={
|
||||||
|
<TouchableOpacity onPress={() => setShowPassword(!showPassword)}>
|
||||||
|
<Icon name={!showPassword ? 'eye-invisible' : 'eye'} size={24} color={themeColor.color_text_placeholder} />
|
||||||
|
</TouchableOpacity>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View style={[{ paddingHorizontal: 24, marginBottom: 16 }]}>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
style={{
|
||||||
|
height: 56,
|
||||||
|
borderRadius: 10,
|
||||||
|
}}
|
||||||
|
onPress={handleLogin}>
|
||||||
|
{t('Sign_Up')}
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View style={[flexRow, alignItemsStart, justifyStart, { paddingLeft: 24, marginBottom: 16 }]}>
|
||||||
|
<Checkbox checked={checked} onChange={onChangeCheckbox} style={[{ width: 22 }]}>
|
||||||
|
</Checkbox>
|
||||||
|
<View style={[flexSub]}>
|
||||||
|
<TouchableOpacity onPress={() => {setChecked(!checked)}}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_base, lineHeight: 20 }}>{t('I_certify_that_I_am_18_years_of_age_or_older')}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<View style={[flexRow]}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_base, lineHeight: 20 }}>{t('agree_to_the')}</Text>
|
||||||
|
<TouchableOpacity onPress={() => linkTo('UserAgreement')}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.brandPrimary, lineHeight: 20 }}>{t('User_Agreement')}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_base, lineHeight: 20 }}> {t('and')} </Text>
|
||||||
|
<TouchableOpacity onPress={() => linkTo('UserAgreement')}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.brandPrimary, lineHeight: 20 }}>{t('Privacy_Policy')}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={[flexSub]}></View>
|
||||||
|
|
||||||
|
<View style={[flexRow, alignItemsCenter, justifyCenter, { padding: 24 }]}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.color_text_caption, lineHeight: 24 }}>{t('Do_not_have_an_account')}</Text>
|
||||||
|
<TouchableOpacity onPress={() => linkTo('Login')}>
|
||||||
|
<Text style={{ fontSize: 14, color: themeColor.brandPrimary, lineHeight: 24 }}>{t('Sign_In')}</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default LoginScreen;
|
||||||
Reference in New Issue
Block a user