diff --git a/App.jsx b/App.jsx index c62452e..9f3cd54 100644 --- a/App.jsx +++ b/App.jsx @@ -23,10 +23,12 @@ import { AuthProvider, useContextHook } from './components/AuthContext/index'; import Login from '@/views/Login/index'; +import Signup from '@/views/Signup/index'; import Guide from '@/views/Guide/index'; import HomeIndex from '@/views/Home/Index/index'; import HomeInventory from '@/views/Home/Inventory/index'; import HomeProfile from '@/views/Home/Profile/index'; +import AccountInfo from '@/views/AccountInfo/index'; const Tab = createBottomTabNavigator(); @@ -107,6 +109,13 @@ function RootStack() { }} component={Login} /> + + ); } diff --git a/assets/images/logo.png b/assets/images/logo.png index 3031eaa..039b2e2 100644 Binary files a/assets/images/logo.png and b/assets/images/logo.png differ diff --git a/assets/styles/css.js b/assets/styles/css.js index 6bdd9d1..90ec73f 100644 --- a/assets/styles/css.js +++ b/assets/styles/css.js @@ -82,13 +82,14 @@ export const positionFixed = useStyles({ 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 brandPrimaryTap = color.brandPrimaryTap || '#1284d6'; + const brandPrimaryTap = color.brandPrimaryTap || '#1284d6'; return { - transparent: 'transparent', - brandPrimary, - brandPrimaryTap, + brandPrimary, + brandPrimaryTap, // 文字色 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, 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_tap: color.warning_button_fill_tap || '#d24747', diff --git a/locales/en.json b/locales/en.json index c2be406..babf7ae 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1,10 +1,28 @@ { - "welcome": "Welcome", - "greeting": "Hello, {{name}}!", - "login": "Login123", - "username": "Username", - "password": "Password", + "Welcome_Back": "Welcome Back!", + "Sign_in_to_your_account": "Sign in to your account", + "Sign_In": "Sign In", + "Remember_me": "Remember me", + "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_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" } diff --git a/locales/zh.json b/locales/zh.json index 5180482..93842b6 100644 --- a/locales/zh.json +++ b/locales/zh.json @@ -1,10 +1,21 @@ { - "welcome": "欢迎", - "greeting": "你好, {{name}}!", - "login": "登录", - "username": "用户名", - "password": "密码", - "login_success": "登录成功", - "login_failed": "登录失败", - "login_error_message": "登录失败,请重试" + "Welcome_Back": "Welcome Back!", + "Sign_in_to_your_account": "Sign in to your account", + "Sign_In": "Sign In", + "Remember_me": "Remember me", + "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_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" } diff --git a/package.json b/package.json index fb2cc43..43fbc0c 100644 --- a/package.json +++ b/package.json @@ -53,5 +53,8 @@ }, "engines": { "node": ">=18" + }, + "volta": { + "node": "22.12.0" } } diff --git a/views/AccountInfo/Components/Citizenship.jsx b/views/AccountInfo/Components/Citizenship.jsx new file mode 100644 index 0000000..8091f66 --- /dev/null +++ b/views/AccountInfo/Components/Citizenship.jsx @@ -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 ( + + + {t('What’s_your_citizenship')}? + + + {t('If_you’re_a_citizen_of_more_than_one_country,_please_pick_one')} + + + + {t('Citizenship')}? + + + + {t('Citizenship')}? + + + + + + + + {t('Do_not_have_an_account')} + linkTo('Login')}> + {t('Sign_In')} + + + + ); +}; +export default Index; diff --git a/views/AccountInfo/index.jsx b/views/AccountInfo/index.jsx new file mode 100644 index 0000000..7a72797 --- /dev/null +++ b/views/AccountInfo/index.jsx @@ -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 ( + + + + + + + + + + + Carousel 2 + + + + ); +}; +export default LoginScreen; diff --git a/views/Guide/index.jsx b/views/Guide/index.jsx index 611cb7e..cbeabf3 100644 --- a/views/Guide/index.jsx +++ b/views/Guide/index.jsx @@ -51,7 +51,7 @@ const Index = () => { if (user && user.token) { resetAllRoutes('Home'); } else { - resetAllRoutes('Login'); + resetAllRoutes('AccountInfo'); } }, 1000); }, [isFocused]); @@ -65,21 +65,25 @@ const Index = () => { alignItemsCenter, flexRow ]}> + - login111 + Finix - ); diff --git a/views/Login/index.jsx b/views/Login/index.jsx index e641e61..8eb004c 100644 --- a/views/Login/index.jsx +++ b/views/Login/index.jsx @@ -1,20 +1,30 @@ import { useState, useEffect } from 'react'; import { - View, - Text, TextInput, TouchableOpacity, Image, StyleSheet, Alert, + StatusBar, } 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 { useContextHook } from '@/components/AuthContext'; import { useTranslation } from 'react-i18next'; +import { useRouter } from '@/hooks/useRouter'; import { statusBarHeight, @@ -42,13 +52,11 @@ import { const inputItem = useStyles({ - width: '80%', - height: 40, - borderColor: 'gray', - borderWidth: 1, - borderRadius: 5, - paddingHorizontal: 10, - marginBottom: 20, + height: 56, + width: '100%', + borderRadius: 10, + paddingHorizontal: 16, + paddingVertical: 8, }); const LoginScreen = () => { @@ -56,22 +64,18 @@ const LoginScreen = () => { const { t, i18n } = useTranslation(); console.log('🚀 ~ LoginScreen ~ i18n:', i18n) - const router = useNavigation(); + const { linkTo } = useRouter(); const [language, setLanguage] = useState('en'); - const isFocused = useIsFocused(); - - const [username, setUsername] = useState(''); + const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); - useEffect(() => { - - }, [isFocused]); + const [showPassword, setShowPassword] = useState(false); const handleLogin = () => { - if (!username) { + if (!email) { Toast.show({ - content: t('Please enter user name'), + content: t('Please enter email'), position: 'center', mask: true, }); @@ -92,7 +96,7 @@ const LoginScreen = () => { mask: true, duration: 0, }); - console.log(123,123); + console.log(123, 123); // login({ username, password }) // .then(res => { // Toast.remove(key); @@ -108,7 +112,7 @@ const LoginScreen = () => { // appToken: res.token, // user: res.user, // }).then(() => { - // router.replace('Home'); + // linkTo('Home'); // }); // }, // }); @@ -131,64 +135,96 @@ const LoginScreen = () => { - - + + + + + + + + {t('Welcome_Back')} + + + {t('Sign_in_to_your_account')} + + + + + - - {t('login')} - - - - - + setShowPassword(!showPassword)}> + + + } + /> + + + + + + + + {t('Remember_me')} + + + + linkTo('ForgotPassword')}> + {t('Forgot_password')} + + + + {/* + + {t('Or_sign_in_with')} + + */} + + + + {t('Do_not_have_an_account')} + linkTo('Signup')}> + {t('Sign_up')} + + ); }; diff --git a/views/Signup/index.jsx b/views/Signup/index.jsx new file mode 100644 index 0000000..8876c56 --- /dev/null +++ b/views/Signup/index.jsx @@ -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 ( + + + + + + + + {t('Create_your_account')} + + + {t('Let_us_get_started_with_a_free_Financy_account')} + + + + + + + + + + setShowPassword(!showPassword)}> + + + } + /> + + + + + + + + + + {setChecked(!checked)}}> + {t('I_certify_that_I_am_18_years_of_age_or_older')} + + + {t('agree_to_the')} + linkTo('UserAgreement')}> + {t('User_Agreement')} + + {t('and')} + linkTo('UserAgreement')}> + {t('Privacy_Policy')} + + + + + + + + + {t('Do_not_have_an_account')} + linkTo('Login')}> + {t('Sign_In')} + + + + ); +}; +export default LoginScreen;