From 5c53ec6bc1425cc50bfff93e1089d21601255384 Mon Sep 17 00:00:00 2001 From: Lindsay Morales <87027508+lindsaymoralesb@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:18:23 -0600 Subject: [PATCH] refactor login and signup styles (#387) * refactor login and signup styles * refactor login & signup styles mobile * refactor styles create account --- apps/mobile/src/app/Router.tsx | 1 + apps/mobile/src/assets/icons.tsx | 9 ++ apps/mobile/src/assets/nostr.svg | 9 ++ apps/mobile/src/assets/starknet.svg | 9 ++ apps/mobile/src/modules/Auth/index.tsx | 10 +- apps/mobile/src/modules/Auth/styles.ts | 11 +- .../src/modules/Login/StarknetLogin.tsx | 34 ++++- apps/mobile/src/modules/Login/index.tsx | 102 +++++++++----- apps/mobile/src/modules/Login/styles.ts | 120 ++++++++++++++++ .../src/screens/Auth/nostr/CreateAccount.tsx | 128 ++++++++++++++---- apps/mobile/src/screens/Auth/nostr/styles.ts | 89 ++++++++++++ apps/mobile/src/styles/Colors.tsx | 4 +- apps/mobile/src/types/routes.ts | 3 + 13 files changed, 456 insertions(+), 73 deletions(-) create mode 100644 apps/mobile/src/assets/nostr.svg create mode 100644 apps/mobile/src/assets/starknet.svg diff --git a/apps/mobile/src/app/Router.tsx b/apps/mobile/src/app/Router.tsx index aba79799a..a3bb84d59 100644 --- a/apps/mobile/src/app/Router.tsx +++ b/apps/mobile/src/app/Router.tsx @@ -418,6 +418,7 @@ const linking = { ImportKeys: 'import-keys', DappBrowser: 'browser', Oauth: 'oauth', + Profile: 'profile' }, }, MainStack: { diff --git a/apps/mobile/src/assets/icons.tsx b/apps/mobile/src/assets/icons.tsx index 997726506..7944be078 100644 --- a/apps/mobile/src/assets/icons.tsx +++ b/apps/mobile/src/assets/icons.tsx @@ -882,3 +882,12 @@ export const ViewIcon: React.FC = (props) => ( /> ); + +export const EyeIcon: React.FC = (props) => ( + + + +); diff --git a/apps/mobile/src/assets/nostr.svg b/apps/mobile/src/assets/nostr.svg new file mode 100644 index 000000000..49c0de09c --- /dev/null +++ b/apps/mobile/src/assets/nostr.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/mobile/src/assets/starknet.svg b/apps/mobile/src/assets/starknet.svg new file mode 100644 index 000000000..26859b36f --- /dev/null +++ b/apps/mobile/src/assets/starknet.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/apps/mobile/src/modules/Auth/index.tsx b/apps/mobile/src/modules/Auth/index.tsx index 6a98b5f18..ae0538c7b 100644 --- a/apps/mobile/src/modules/Auth/index.tsx +++ b/apps/mobile/src/modules/Auth/index.tsx @@ -1,8 +1,9 @@ import {Image, KeyboardAvoidingView, ScrollView, View} from 'react-native'; import {Text} from '../../components'; -import {useStyles} from '../../hooks'; +import {useStyles, useWindowDimensions} from '../../hooks'; import stylesheet from './styles'; +import { useMemo } from 'react'; export type AuthProps = { title: string; @@ -12,6 +13,11 @@ export type AuthProps = { export const Auth: React.FC = ({title, children}) => { const styles = useStyles(stylesheet); + const dimensions = useWindowDimensions(); + const isDesktop = useMemo(() => { + return dimensions.width >= 1024; + }, [dimensions]); + return ( @@ -31,7 +37,7 @@ export const Auth: React.FC = ({title, children}) => { {/* */} - + {title} diff --git a/apps/mobile/src/modules/Auth/styles.ts b/apps/mobile/src/modules/Auth/styles.ts index 3b6c913d2..68472c365 100644 --- a/apps/mobile/src/modules/Auth/styles.ts +++ b/apps/mobile/src/modules/Auth/styles.ts @@ -42,7 +42,15 @@ export default ThemedStyleSheet((theme) => ({ borderRadius: 999, }, title: { - marginVertical: Spacing.large, + marginBottom: Spacing.xxxlarge, + color: theme.colors.primary, + width: '100%', + maxWidth: 556, + textAlign: 'left', + }, + titleMobile: { + paddingHorizontal: 15, + marginBottom: Spacing.small, }, contentContainer: { @@ -52,7 +60,6 @@ export default ThemedStyleSheet((theme) => ({ content: { flex: 1, alignItems: 'center', - gap: Spacing.medium, paddingHorizontal: Spacing.medium, backgroundColor: theme.colors.surface, }, diff --git a/apps/mobile/src/modules/Login/StarknetLogin.tsx b/apps/mobile/src/modules/Login/StarknetLogin.tsx index 77546c3e3..b544a245d 100644 --- a/apps/mobile/src/modules/Login/StarknetLogin.tsx +++ b/apps/mobile/src/modules/Login/StarknetLogin.tsx @@ -1,22 +1,27 @@ -import {useState} from 'react'; -import {TouchableOpacity, View} from 'react-native'; +import {useMemo, useState} from 'react'; +import {TouchableOpacity, View, Image} from 'react-native'; import {useAccount} from 'wagmi'; -import {TextButton} from '../../components'; +import {Button, TextButton} from '../../components'; import {StarkConnectModal} from './StarkModal'; import {SignMessageModal} from './StarknetSigner'; +import {useStyles, useWindowDimensions} from '../../hooks'; +import stylesheet from './styles'; export const LoginStarknet = ({ handleNavigation, btnText = 'Starknet Login', children, triggerConnect = true, + useCustomBtn = false, }: { handleNavigation: () => void; btnText?: string; children?: React.ReactNode; triggerConnect?: boolean; + useCustomBtn?: boolean; }) => { + const styles = useStyles(stylesheet); const {address} = useAccount(); const [showSignModal, setShowSignModal] = useState(false); const [showConnect, setShow] = useState(false); @@ -36,8 +41,13 @@ export const LoginStarknet = ({ } }; + const dimensions = useWindowDimensions(); + const isDesktop = useMemo(() => { + return dimensions.width >= 1024; + }, [dimensions]); + return ( - + {showConnect && ( setShowSignModal(!showSignModal)} @@ -60,6 +70,22 @@ export const LoginStarknet = ({ ) : ( children ) + ) : useCustomBtn ? ( + ) : ( { diff --git a/apps/mobile/src/modules/Login/index.tsx b/apps/mobile/src/modules/Login/index.tsx index 9b0fa2c28..03aa37d49 100644 --- a/apps/mobile/src/modules/Login/index.tsx +++ b/apps/mobile/src/modules/Login/index.tsx @@ -1,12 +1,11 @@ -import {deriveSeedFromMnemonic} from '@cashu/cashu-ts'; +import {mnemonicToSeedSync} from '@scure/bip39'; import {useAuth, useCashu, useCashuStore, useNip07Extension} from 'afk_nostr_sdk'; import {canUseBiometricAuthentication} from 'expo-secure-store'; -import {useEffect, useState} from 'react'; -import {Platform, View} from 'react-native'; +import {useEffect, useMemo, useState} from 'react'; +import {Platform, TextInput, View, Image, Text} from 'react-native'; -import {LockIcon} from '../../assets/icons'; -import {Button, Input, TextButton} from '../../components'; -import {useTheme} from '../../hooks'; +import {Button, Icon} from '../../components'; +import {useStyles, useTheme, useWindowDimensions} from '../../hooks'; import {useDialog, useToast} from '../../hooks/modals'; import {Auth} from '../../modules/Auth'; import {MainStackNavigationProps} from '../../types'; @@ -21,6 +20,8 @@ import { storeCashuSeed, } from '../../utils/storage'; import {LoginStarknet} from './StarknetLogin'; +import stylesheet from './styles'; +import {TouchableOpacity} from 'react-native-gesture-handler'; interface ILoginNostr { isNavigationAfterLogin?: boolean; @@ -35,6 +36,7 @@ export const LoginNostrModule: React.FC = ({ handleSuccessCreateAccount, }: ILoginNostr) => { const {theme} = useTheme(); + const styles = useStyles(stylesheet); const setAuth = useAuth((state) => state.setAuth); const publicKey = useAuth((state) => state.publicKey); @@ -91,7 +93,7 @@ export const LoginNostrModule: React.FC = ({ if (!mnemonicSaved) { const mnemonic = await generateMnemonic(); await storeCashuMnemonic(mnemonic, password); - const seed = await deriveSeedFromMnemonic(mnemonic); + const seed = await mnemonicToSeedSync(mnemonic); const seedHex = Buffer.from(seed).toString('hex'); @@ -108,7 +110,7 @@ export const LoginNostrModule: React.FC = ({ const mnemonic = Buffer.from(mnemonicSaved).toString('hex'); console.log('mnemonic', mnemonic); - const seed = await deriveSeedFromMnemonic(mnemonic); + const seed = await mnemonicToSeedSync(mnemonic); const seedHex = Buffer.from(seed).toString('hex'); console.log('seedHex', seedHex); @@ -190,6 +192,11 @@ export const LoginNostrModule: React.FC = ({ }); }; + const dimensions = useWindowDimensions(); + const isDesktop = useMemo(() => { + return dimensions.width >= 1024; + }, [dimensions]); + // const handleGoDegenApp = () => { // // Brind dialog // navigation.navigate('DegensStack', { screen: 'Games' }); @@ -212,43 +219,66 @@ export const LoginNostrModule: React.FC = ({ // }; return ( - - } - value={password} - onChangeText={setPassword} - secureTextEntry - placeholder="Enter your password" - /> + + + + navigationProps?.navigate('Feed')} + btnText={'Starknet Account'} + useCustomBtn + /> + + Password + + + + + + It must be a combination of minimum 8 letters, numbers, and symbols. + + + + Forgot Password? Import Account + + + {isDesktop ?
: null} - Create Account - {/* */} - - Import Account - Nostr extension - navigationProps?.navigate('Feed')} /> + + + No account yet? Sign Up + - - {/* Go degen app */}
); }; diff --git a/apps/mobile/src/modules/Login/styles.ts b/apps/mobile/src/modules/Login/styles.ts index efd358bb9..5dd8649d0 100644 --- a/apps/mobile/src/modules/Login/styles.ts +++ b/apps/mobile/src/modules/Login/styles.ts @@ -227,4 +227,124 @@ export default ThemedStyleSheet((theme) => ({ borderColor: theme.colors.divider, borderRadius: 5, }, + + // login + loginMethodsContainer: { + flexDirection: 'row', + gap: 16, + width: '100%', + maxWidth: 556, + flexWrap: 'wrap' + }, + loginMethodsContainerDesktop: { + flexWrap: 'nowrap' + }, + loginMethodBtn: { + borderRadius: 32, + paddingVertical: 10, + paddingHorizontal: 12, + borderWidth: 2, + borderColor: theme.colors.primary, + maxWidth: '100%', + backgroundColor: theme.colors.bg, + flexGrow: 1 + }, + loginMethodBtnDesktop: { + width: 270, + }, + btnInnerContainer: { + width: '100%', + height: '100%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + gap: 8 + }, + loginMethodBtnText: { + color: theme.colors.primary, + fontWeight: 500, + height: '100%' + }, + loginMethodBtnImg: { + width: 20, + height: 20 + }, + passwordLabel: { + color: theme.colors.textPrimary, + marginTop: 40, + textAlign: 'left', + width: '100%', + maxWidth: 550, + fontSize: 14, + marginBottom: 10 + }, + passwordInputContainer: { + position: 'relative', + width: '100%', + maxWidth: 556, + }, + passwordInput: { + paddingLeft: 16, + paddingRight: 48, + paddingVertical: 13, + color: theme.colors.grayInput, + backgroundColor: theme.colors.white, + borderRadius: 32, + borderColor: theme.colors.grayInput, + borderWidth: 1 + }, + passwordInstruction: { + color: theme.colors.grayInput, + textAlign: 'left', + width: '100%', + maxWidth: 550, + fontSize: 12, + marginTop: 5 + }, + eyeIcon: { + position: 'absolute', + top: 10, + right: 16, + }, + importAccountBtnContainer: { + maxWidth: 556, + width: '100%', + }, + importAccountBtn: { + width: 215, + padding: 0, + fontWeight: 500, + fontSize: 12, + color: theme.colors.primary, + marginLeft: 'auto', + marginTop: 16, + textAlign: 'right', + cursor: 'pointer' + }, + loginBtn: { + maxWidth: 556, + width: '100%', + marginTop: 16 + }, + divider: { + maxWidth: 556, + width: '100%', + marginTop: 40, + marginBottom: 40, + }, + noAccountBtnContainer: { + maxWidth: 556, + width: '100%', + }, + noAccountBtn: { + width: 215, + padding: 0, + fontWeight: 500, + fontSize: 12, + color: theme.colors.primary, + marginRight: 'auto', + marginVertical: 16, + textAlign: 'left', + cursor: 'pointer' + }, })); diff --git a/apps/mobile/src/screens/Auth/nostr/CreateAccount.tsx b/apps/mobile/src/screens/Auth/nostr/CreateAccount.tsx index de4252765..53f2dc9ff 100644 --- a/apps/mobile/src/screens/Auth/nostr/CreateAccount.tsx +++ b/apps/mobile/src/screens/Auth/nostr/CreateAccount.tsx @@ -1,16 +1,18 @@ -import {useCashu, useCashuStore, useNostrContext} from 'afk_nostr_sdk'; -import {useState} from 'react'; +import {useCashu, useCashuStore, useNip07Extension, useNostrContext} from 'afk_nostr_sdk'; +import {useMemo, useState} from 'react'; -import {LockIcon} from '../../../assets/icons'; -import {Button, Input, TextButton} from '../../../components'; -import {useTheme} from '../../../hooks'; +import {Button, Icon} from '../../../components'; +import {useStyles, useTheme, useWindowDimensions} from '../../../hooks'; import {useInternalAccount} from '../../../hooks/account/useInternalAccount'; import {useDialog, useToast} from '../../../hooks/modals'; import {Auth} from '../../../modules/Auth'; import {AuthCreateAccountScreenProps} from '../../../types'; +import stylesheet from './styles'; +import {View, Text, TextInput, TouchableOpacity, Image} from 'react-native'; export const CreateAccount: React.FC = ({navigation}) => { const {theme} = useTheme(); + const styles = useStyles(stylesheet); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); @@ -27,6 +29,7 @@ export const CreateAccount: React.FC = ({navigatio handleGenerateNostrWalletOld, handleSavedNostrWalletOld, } = useInternalAccount(); + const {getPublicKey} = useNip07Extension(); const handleCreateAccount = async () => { if (!username) { @@ -117,30 +120,99 @@ export const CreateAccount: React.FC = ({navigatio navigation.navigate('ImportKeys'); }; + const handleNavigateLogin = () => { + navigation.navigate('Login'); + }; + + const handleExtensionConnect = () => { + showDialog({ + title: 'WARNING', + description: 'Used your Nostr extension.', + buttons: [ + { + type: 'primary', + label: 'Continue', + onPress: async () => { + const publicKey = await getPublicKey(); + // navigation.navigate('ImportKeys'); + hideDialog(); + // if (handleSuccess) { + // handleSuccess(); + // } + if (publicKey && navigation) { + navigation.navigate('Profile', {publicKey}); + } + }, + }, + {type: 'default', label: 'Cancel', onPress: hideDialog}, + ], + }); + }; + + const dimensions = useWindowDimensions(); + const isDesktop = useMemo(() => { + return dimensions.width >= 1024; + }, [dimensions]); + return ( - - - - } - value={password} - onChangeText={setPassword} - secureTextEntry - placeholder="Password" - /> - - - - Import account - - + + + + + Username + + + + Password + + + + + + + + + {isDesktop ?
: null} + + + + Already have an account? + + + + {/* Import account */}
); }; diff --git a/apps/mobile/src/screens/Auth/nostr/styles.ts b/apps/mobile/src/screens/Auth/nostr/styles.ts index f410ef708..25ea04910 100644 --- a/apps/mobile/src/screens/Auth/nostr/styles.ts +++ b/apps/mobile/src/screens/Auth/nostr/styles.ts @@ -16,4 +16,93 @@ export default ThemedStyleSheet((theme) => ({ paddingVertical: Spacing.small, borderRadius: 99, }, + + // create account + formContainer: { + flexDirection: 'column', + gap: 16, + width: '100%', + maxWidth: 556, + }, + methodBtn: { + borderRadius: 32, + paddingVertical: 10, + paddingHorizontal: 12, + borderWidth: 2, + borderColor: theme.colors.primary, + maxWidth: '100%', + backgroundColor: theme.colors.bg, + flexGrow: 1 + }, + btnInnerContainer: { + width: '100%', + height: '100%', + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + gap: 8 + }, + methodBtnText: { + color: theme.colors.primary, + fontWeight: 500, + height: '100%' + }, + methodBtnImg: { + width: 20, + height: 20, + }, + inputLabel: { + color: theme.colors.primary, + textAlign: 'left', + maxWidth: 550, + width: '100%', + fontSize: 14, + marginBottom: 10, + }, + passwordInputContainer: { + position: 'relative', + maxWidth: 556, + width: '100%', + }, + input: { + paddingLeft: 16, + paddingRight: 48, + paddingVertical: 13, + color: theme.colors.grayInput, + backgroundColor: theme.colors.white, + borderRadius: 32, + borderColor: theme.colors.grayInput, + borderWidth: 1 + }, + eyeIcon: { + position: 'absolute', + top: 10, + right: 16, + }, + formBtn: { + maxWidth: 556, + width: '100%', + }, + divider: { + maxWidth: 556, + width: '100%', + marginTop: 40, + marginBottom: 40, + }, + accountBtnContainer: { + maxWidth: 556, + width: '100%' + }, + accountBtn: { + width: 215, + padding: 0, + fontWeight: 500, + fontSize: 12, + color: theme.colors.primary, + marginRight: 'auto', + textAlign: 'left', + cursor: 'pointer', + fontFamily: 'Arial', + marginVertical: 16, + }, })); diff --git a/apps/mobile/src/styles/Colors.tsx b/apps/mobile/src/styles/Colors.tsx index 661c413ab..f94412a6e 100644 --- a/apps/mobile/src/styles/Colors.tsx +++ b/apps/mobile/src/styles/Colors.tsx @@ -26,6 +26,7 @@ export const LightTheme = { textSecondary: '#0B0B0B', textTertiary: '#0B0B0B', overlay70: 'rgba(0, 0, 0, 0.7)', + grayInput: '#697077', cardBorder: '#C4C3D3', greenLike: '#ADCF00', @@ -143,6 +144,7 @@ export const DarkTheme = { textSecondary: '#E9F2EA', textTertiary: '#FBFBFB', overlay70: 'rgba(0, 0, 0, 0.7)', + grayInput: '#697077', cardBorder: '#C4C3D3', greenLike: '#ADCF00', @@ -206,7 +208,7 @@ export const DarkTheme = { secondaryLight: 'rgba(12,12,79, 0.1)', background: '#000000', - surface: '#242424', + surface: '#000000', elevated: '#FFFFFF', overlay: 'rgba(0, 0, 0, 0.5)', shadow: 'rgba(13, 13, 29, 0.2)', diff --git a/apps/mobile/src/types/routes.ts b/apps/mobile/src/types/routes.ts index e453e1419..27255cd5c 100644 --- a/apps/mobile/src/types/routes.ts +++ b/apps/mobile/src/types/routes.ts @@ -22,6 +22,9 @@ export type AuthStackParams = { }; ImportKeys: undefined; LoginNostr: undefined; + Profile: { + publicKey: string; + }; }; export type MainStackParams = {