diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..7a934a1
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,33 @@
+{
+ "env": {
+ "browser": true,
+ "es2021": true
+ },
+ "extends": [
+ "standard-with-typescript",
+ "plugin:react/recommended"
+ ],
+ "parserOptions": {
+ "ecmaVersion": "latest",
+ "sourceType": "module",
+ "project": "./tsconfig.json"
+ },
+ "plugins": [
+ "react"
+ ],
+ "rules": {
+ "@typescript-eslint/consistent-type-imports": "off",
+ "@typescript-eslint/strict-boolean-expressions": "off",
+ "@typescript-eslint/no-misused-promises": "off",
+ "@typescript-eslint/explicit-function-return-type": "off",
+ "react/react-in-jsx-scope": "off",
+ "@typescript-eslint/consistent-type-assertions": "off",
+ "@typescript-eslint/ban-ts-comment": "off",
+ "@typescript-eslint/no-var-requires": "off",
+ "react/no-unescaped-entities": "off",
+ "@typescript-eslint/prefer-reduce-type-parameter": "off",
+ "@typescript-eslint/no-floating-promises": "off",
+ "@typescript-eslint/no-unused-expressions": "off",
+ "@typescript-eslint/restrict-plus-operands": "off"
+ }
+}
diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml
new file mode 100644
index 0000000..03d9549
--- /dev/null
+++ b/.idea/inspectionProfiles/Project_Default.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jsLinters/eslint.xml b/.idea/jsLinters/eslint.xml
new file mode 100644
index 0000000..e94fc66
--- /dev/null
+++ b/.idea/jsLinters/eslint.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/App.tsx b/App.tsx
index 96a1316..f2952da 100644
--- a/App.tsx
+++ b/App.tsx
@@ -1,12 +1,12 @@
-import { AuthProvider } from './app/providers/AuthProvider';
-import { Navigation } from './app/navigation/Navigation';
-import { useFonts } from './app/hooks/useFonts';
-import { DataProvider } from './app/providers/DataProvider';
-import { StoryContainer } from './app/components/screens/home/stories/StoryContainer';
-import { GeneratePasswordProvider } from './app/providers/GeneratePasswordProvider';
+import { AuthProvider } from './app/providers/AuthProvider'
+import { Navigation } from './app/navigation/Navigation'
+import { useFonts } from './app/hooks/useFonts'
+import { DataProvider } from './app/providers/DataProvider'
+import { StoryContainer } from './app/components/screens/home/stories/StoryContainer'
+import { GeneratePasswordProvider } from './app/providers/GeneratePasswordProvider'
-export default function App() {
- const { fontLoaded } = useFonts();
+export default function App () {
+ const { fontLoaded } = useFonts()
if (fontLoaded) {
return (
@@ -19,6 +19,6 @@ export default function App() {
- );
+ )
}
}
diff --git a/app/components/layout/Layout.tsx b/app/components/layout/Layout.tsx
index 02f8eb9..7cb03c5 100644
--- a/app/components/layout/Layout.tsx
+++ b/app/components/layout/Layout.tsx
@@ -1,22 +1,23 @@
-import { View, ScrollView, StyleSheet } from 'react-native';
-import { FC, ReactNode } from 'react';
+import { View, ScrollView, StyleSheet } from 'react-native'
+import { FC, ReactNode } from 'react'
interface Props {
- isScrollView?: boolean,
- children: ReactNode,
+ isScrollView?: boolean
+ children: ReactNode
}
export const Layout: FC = ({ children, isScrollView = true }) => {
-
return (
- {isScrollView ? (
+ {isScrollView
+ ? (
{children}
- ) : (
- children
- )}
+ )
+ : (
+ children
+ )}
)
}
diff --git a/app/components/layout/footer/Footer.tsx b/app/components/layout/footer/Footer.tsx
index 14e5f42..9f220ea 100644
--- a/app/components/layout/footer/Footer.tsx
+++ b/app/components/layout/footer/Footer.tsx
@@ -1,17 +1,17 @@
-import { StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { Padding } from '../../ui/Padding';
-import { menu } from './menu';
-import { NavItem } from './NavItem/NavItem';
-import { TypeRootStackParamList } from '../../../navigation/types';
+import { StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { Padding } from '../../ui/Padding'
+import { menu } from './menu'
+import { NavItem } from './NavItem/NavItem'
+import { TypeRootStackParamList } from '../../../navigation/types'
interface Props {
- navigate: (screenName: keyof TypeRootStackParamList) => void,
- currentRoute: string,
+ navigate: (screenName: keyof TypeRootStackParamList) => void
+ currentRoute: string
}
export const Footer: FC = (props) => {
- const { navigate, currentRoute } = props;
+ const { navigate, currentRoute } = props
return (
@@ -38,6 +38,6 @@ const styles = StyleSheet.create({
paddingBottom: 20,
paddingTop: 8,
borderTopColor: '#E1E1E1',
- borderTopWidth: 1,
+ borderTopWidth: 1
}
})
diff --git a/app/components/layout/footer/NavItem/NavItem.tsx b/app/components/layout/footer/NavItem/NavItem.tsx
index 7d59c43..48ffc77 100644
--- a/app/components/layout/footer/NavItem/NavItem.tsx
+++ b/app/components/layout/footer/NavItem/NavItem.tsx
@@ -1,24 +1,24 @@
-import { Text, Pressable, StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { IFooterItem } from '../../../../typedefs/typedefs';
-import { AntDesign } from '@expo/vector-icons';
-import { TypeRootStackParamList } from '../../../../navigation/types';
+import { Text, Pressable, StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { IFooterItem } from '../../../../typedefs/typedefs'
+import { AntDesign } from '@expo/vector-icons'
+import { TypeRootStackParamList } from '../../../../navigation/types'
interface Props {
- item: IFooterItem,
- navigate: (screenName: keyof TypeRootStackParamList) => void,
- currentRoute: string,
+ item: IFooterItem
+ navigate: (screenName: keyof TypeRootStackParamList) => void
+ currentRoute: string
}
export const NavItem: FC = (props) => {
- const { item, navigate, currentRoute } = props;
+ const { item, navigate, currentRoute } = props
- const isActive = currentRoute === item.title;
+ const isActive = currentRoute === item.title
return (
navigate(item.title)}
+ onPress={() => { navigate(item.title) }}
>
{
- const [data, setData] = useState({} as IData);
- const [isReg, setIsReg] = useState(false);
- const [isSecure, setIsSecure] = useState(true);
+ const [data, setData] = useState({} as IData)
+ const [isReg, setIsReg] = useState(false)
+ const [isSecure, setIsSecure] = useState(true)
const {
isLoading,
login,
register
- } = useAuth();
+ } = useAuth()
- const { password, isClicked } = useGeneratePassword();
+ const { password, isClicked } = useGeneratePassword()
- const { isModalVisible, handleChangeModalVisible } = useGeneratePassword();
+ const { isModalVisible, handleChangeModalVisible } = useGeneratePassword()
const authHandler = async () => {
- const { email, password } = data;
+ const { email, password } = data
if (isReg) {
- await register(email, password);
+ await register(email, password)
} else {
- await login(email, password);
+ await login(email, password)
}
- setData({} as IData);
- navigation.navigate('Home');
- };
+ setData({} as IData)
+ navigation.navigate('Home')
+ }
const handleChangeSecure = useCallback(() => {
- setIsSecure((prevState => !prevState))
+ setIsSecure(prevState => !prevState)
}, [])
useEffect(() => {
- setData({...data, password: password});
+ setData({ ...data, password })
}, [isClicked])
return (
-
+
{isReg ? 'Sign Up' : 'Sign in'}
- {isLoading ? (
+ {isLoading
+ ? (
- ) : (
+ )
+ : (
<>
setData({...data, email: val})}
+ onChange={val => { setData({ ...data, email: val }) }}
/>
setData({...data, password: val})}
+ onChange={val => { setData({ ...data, password: val }) }}
isSecure={isSecure}
onChangeSecure={handleChangeSecure}
/>
- handleChangeModalVisible()}>
+ { handleChangeModalVisible() }}>
{isReg ? 'Generate password' : ''}
@@ -80,16 +82,16 @@ export const Auth: FC = ({ navigation }: any) => {
- setIsReg(!isReg)}>
+ { setIsReg(!isReg) }}>
{isReg ? 'Login' : 'Register'}
>
- )}
+ )}
@@ -99,12 +101,12 @@ export const Auth: FC = ({ navigation }: any) => {
const styles = StyleSheet.create({
main: {
height: '100%',
- width: '100%',
+ width: '100%'
},
block: {
justifyContent: 'center',
alignItems: 'center',
- height: '100%',
+ height: '100%'
},
text: {
textAlign: 'center',
@@ -116,5 +118,5 @@ const styles = StyleSheet.create({
textAlign: 'right',
opacity: 30,
marginTop: 3
- },
+ }
})
diff --git a/app/components/screens/auth/AuthModal/AuthModal.tsx b/app/components/screens/auth/AuthModal/AuthModal.tsx
index 7ec7713..31b7f76 100644
--- a/app/components/screens/auth/AuthModal/AuthModal.tsx
+++ b/app/components/screens/auth/AuthModal/AuthModal.tsx
@@ -1,29 +1,29 @@
-import { FC } from 'react';
+import { FC } from 'react'
import {
Modal,
StyleSheet,
View,
TextInput
-} from 'react-native';
-import { useGeneratePassword } from '../../../../hooks/useGeneratePassword';
-import { Button } from '../../../../components/ui/Button';
-import { PasswordSettings } from '../../../ui/PasswordSettings';
-import { usePassword } from '../../../../hooks/usePassword';
+} from 'react-native'
+import { useGeneratePassword } from '../../../../hooks/useGeneratePassword'
+import { Button } from '../../../../components/ui/Button'
+import { PasswordSettings } from '../../../ui/PasswordSettings'
+import { usePassword } from '../../../../hooks/usePassword'
interface Props {
- isVisible: boolean,
+ isVisible: boolean
}
export const AuthModal: FC = (props) => {
- const { isVisible } = props;
+ const { isVisible } = props
const {
password,
createNewPassword,
- handleChangeModalVisible,
- } = useGeneratePassword();
+ handleChangeModalVisible
+ } = useGeneratePassword()
- const { passwordSettings } = usePassword();
+ const { passwordSettings } = usePassword()
return (
@@ -36,7 +36,7 @@ export const AuthModal: FC = (props) => {
{passwordSettings.map(input => {
- const { isCondition, condition, handleChange } = input;
+ const { isCondition, condition, handleChange } = input
return (
= (props) => {
@@ -79,7 +79,7 @@ const styles = StyleSheet.create({
modalContainer: {
flex: 1,
justifyContent: 'center',
- alignItems: 'center',
+ alignItems: 'center'
},
item: {
width: '100%',
@@ -93,7 +93,7 @@ const styles = StyleSheet.create({
backgroundColor: '#EDF2EF',
marginTop: 10,
padding: 10,
- flex: 1,
+ flex: 1
},
buttonsFlex: {
flexDirection: 'row',
@@ -101,6 +101,6 @@ const styles = StyleSheet.create({
gap: 10
},
createButton: {
- width: '90%',
+ width: '90%'
}
})
diff --git a/app/components/screens/home/Header.tsx b/app/components/screens/home/Header.tsx
index 889d3ea..5429775 100644
--- a/app/components/screens/home/Header.tsx
+++ b/app/components/screens/home/Header.tsx
@@ -1,23 +1,25 @@
-import { Text, StyleSheet, TouchableOpacity } from 'react-native';
-import { FC } from 'react';
-import { Padding } from '../../../components/ui/Padding';
-import { Avatar } from '../../../components/ui/Avatar';
-import { Entypo } from '@expo/vector-icons';
-import { useNavigation } from '@react-navigation/native';
-import { useProfile } from '../../../hooks/useProfile';
-import { Loader } from '../../../components/ui/Loader';
+import { Text, StyleSheet, TouchableOpacity } from 'react-native'
+import { FC } from 'react'
+import { Padding } from '../../../components/ui/Padding'
+import { Entypo } from '@expo/vector-icons'
+import { useNavigation } from '@react-navigation/native'
+import { useProfile } from '../../../hooks/useProfile'
+import { Loader } from '../../../components/ui/Loader'
+import { ModifyAvatar } from '../../../components/ui/ModifyAvatar'
export const Header: FC = () => {
- const { isLoading, name } = useProfile();
- const { navigate } = useNavigation();
+ const { isLoading, name, realAvatar } = useProfile()
+ const { navigate } = useNavigation()
const navigateToProfile = () => {
- navigate('Profile');
+ navigate('Profile')
}
- return isLoading ? : (
+ return isLoading
+ ?
+ : (
-
+
{
/>
- )
+ )
}
const styles = StyleSheet.create({
@@ -44,7 +46,7 @@ const styles = StyleSheet.create({
},
name: {
flexDirection: 'row',
- alignItems: 'flex-end',
+ alignItems: 'flex-end'
},
text: {
fontFamily: 'mt-bold',
@@ -52,6 +54,6 @@ const styles = StyleSheet.create({
},
icon: {
color: 'grey',
- fontWeight: 'bold',
+ fontWeight: 'bold'
}
})
diff --git a/app/components/screens/home/Home.tsx b/app/components/screens/home/Home.tsx
index a647f67..01c4de5 100644
--- a/app/components/screens/home/Home.tsx
+++ b/app/components/screens/home/Home.tsx
@@ -1,26 +1,25 @@
-import { BackHandler } from 'react-native';
-import { FC, useEffect } from 'react';
-import { Header } from '../../../components/screens/home/Header';
-import { Stories } from '../../../components/screens/home/stories/Stories';
-import { useIsFocused, useNavigation } from '@react-navigation/native';
-import { Accounts } from './accounts/Accounts';
-import { ApplyNewProduct } from './apply-new-product/ApplyNewProduct';
-import { Layout } from '../../layout/Layout';
+import { BackHandler } from 'react-native'
+import { FC, useEffect } from 'react'
+import { Header } from '../../../components/screens/home/Header'
+import { Stories } from '../../../components/screens/home/stories/Stories'
+import { useIsFocused } from '@react-navigation/native'
+import { Accounts } from './accounts/Accounts'
+import { ApplyNewProduct } from './apply-new-product/ApplyNewProduct'
+import { Layout } from '../../layout/Layout'
export const Home: FC = () => {
- const navigation = useNavigation();
- const isFocused = useIsFocused();
+ const isFocused = useIsFocused()
useEffect(() => {
const backAction = () => {
- return true;
- };
+ return true
+ }
if (isFocused) {
- const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction);
- return () => backHandler.remove();
+ const backHandler = BackHandler.addEventListener('hardwareBackPress', backAction)
+ return () => { backHandler.remove() }
}
- }, [isFocused]);
+ }, [isFocused])
return (
diff --git a/app/components/screens/home/accounts/Accounts.tsx b/app/components/screens/home/accounts/Accounts.tsx
index 26cb309..3ec9448 100644
--- a/app/components/screens/home/accounts/Accounts.tsx
+++ b/app/components/screens/home/accounts/Accounts.tsx
@@ -1,19 +1,22 @@
-import { View, Text } from 'react-native';
-import { FC, Fragment } from 'react';
-import { useAccounts } from '../../../../hooks/useAccounts';
-import { Padding } from '../../../../components/ui/Padding';
-import { Loader } from '../../../../components/ui/Loader';
-import { AccountsItem } from './AccountsItem/AccountItem';
+import { View, Text } from 'react-native'
+import { FC, Fragment } from 'react'
+import { useAccounts } from '../../../../hooks/useAccounts'
+import { Padding } from '../../../../components/ui/Padding'
+import { Loader } from '../../../../components/ui/Loader'
+import { AccountsItem } from './AccountsItem/AccountItem'
-export const Accounts: FC = ({ navigation }: any) => {
- const { accounts, isLoading } = useAccounts();
+export const Accounts: FC = () => {
+ const { accounts, isLoading } = useAccounts()
return (
- {isLoading ? (
+ {isLoading
+ ? (
- ) : accounts.length ? (
- accounts.map((account, index) => (
+ )
+ : accounts.length
+ ? (
+ accounts.map((account, index) => (
@@ -28,10 +31,11 @@ export const Accounts: FC = ({ navigation }: any) => {
/>
)}
- ))
- ) : (
+ ))
+ )
+ : (
You don't have cards
- )}
+ )}
)
}
diff --git a/app/components/screens/home/accounts/AccountsItem/AccountItem.tsx b/app/components/screens/home/accounts/AccountsItem/AccountItem.tsx
index 9e7fc32..f45ec15 100644
--- a/app/components/screens/home/accounts/AccountsItem/AccountItem.tsx
+++ b/app/components/screens/home/accounts/AccountsItem/AccountItem.tsx
@@ -1,16 +1,16 @@
-import { View, Text, StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { IAccount } from '../../../../../typedefs/typedefs';
-import { Currency } from './Currency';
-import { Balance } from './Balance';
-import { ImageCard } from './ImageCard';
+import { View, StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { IAccount } from '../../../../../typedefs/typedefs'
+import { Currency } from './Currency'
+import { Balance } from './Balance'
+import { ImageCard } from './ImageCard'
interface Props {
- account: IAccount,
+ account: IAccount
}
export const AccountsItem: FC = (props) => {
- const { account } = props;
+ const { account } = props
return (
diff --git a/app/components/screens/home/accounts/AccountsItem/Balance.tsx b/app/components/screens/home/accounts/AccountsItem/Balance.tsx
index 4216e11..1bb72e8 100644
--- a/app/components/screens/home/accounts/AccountsItem/Balance.tsx
+++ b/app/components/screens/home/accounts/AccountsItem/Balance.tsx
@@ -1,18 +1,18 @@
-import { Text, View, StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { IAccount } from '../../../../../typedefs/typedefs';
+import { Text, View, StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { IAccount } from '../../../../../typedefs/typedefs'
interface Props {
- account: IAccount,
+ account: IAccount
}
export const Balance: FC = (props) => {
- const { account } = props;
+ const { account } = props
const {
balance,
currency,
name
- } = account;
+ } = account
return (
@@ -20,7 +20,7 @@ export const Balance: FC = (props) => {
{Intl.NumberFormat(undefined, {
currency,
- style: 'currency',
+ style: 'currency'
}).format(balance)}
@@ -29,14 +29,14 @@ export const Balance: FC = (props) => {
const styles = StyleSheet.create({
container: {
- width: '66%',
+ width: '66%'
},
text: {
- fontSize: 15,
+ fontSize: 15
},
text2: {
fontSize: 15,
marginTop: 4,
- fontWeight: 'bold',
- },
+ fontWeight: 'bold'
+ }
})
diff --git a/app/components/screens/home/accounts/AccountsItem/Currency.tsx b/app/components/screens/home/accounts/AccountsItem/Currency.tsx
index 76c829a..7a1f974 100644
--- a/app/components/screens/home/accounts/AccountsItem/Currency.tsx
+++ b/app/components/screens/home/accounts/AccountsItem/Currency.tsx
@@ -1,14 +1,14 @@
-import { View, StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { TypeCurrency } from '../../../../../typedefs/typedefs';
-import { FontAwesome } from '@expo/vector-icons';
+import { View, StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { TypeCurrency } from '../../../../../typedefs/typedefs'
+import { FontAwesome } from '@expo/vector-icons'
interface Props {
- currency: TypeCurrency,
+ currency: TypeCurrency
}
export const Currency: FC = (props) => {
- const { currency } = props;
+ const { currency } = props
return (
@@ -30,7 +30,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
width: 36,
- height: 36,
+ height: 36
},
secondCircle: {
borderRadius: 50,
@@ -38,6 +38,6 @@ const styles = StyleSheet.create({
alignItems: 'center',
justifyContent: 'center',
width: 20,
- height: 20,
- },
+ height: 20
+ }
})
diff --git a/app/components/screens/home/accounts/AccountsItem/ImageCard.tsx b/app/components/screens/home/accounts/AccountsItem/ImageCard.tsx
index ecb7f9c..a64ec20 100644
--- a/app/components/screens/home/accounts/AccountsItem/ImageCard.tsx
+++ b/app/components/screens/home/accounts/AccountsItem/ImageCard.tsx
@@ -2,31 +2,48 @@ import {
ImageBackground,
ImageSourcePropType,
StyleSheet,
- Text
-} from 'react-native';
-import { FC } from 'react';
-import { IAccount } from '../../../../../typedefs/typedefs';
+ Text,
+ TouchableOpacity
+} from 'react-native'
+import { FC, useCallback, useState } from 'react'
+import { IAccount } from '../../../../../typedefs/typedefs'
+import { ModalWindow } from '../ModalWindow/ModalWindow'
interface Props {
- account: IAccount,
+ account: IAccount
}
export const ImageCard: FC = (props) => {
- const { account } = props;
- const { name, cardNumber } = account;
+ const { account } = props
+ const { name, cardNumber } = account
+ const [showModal, setShowModal] = useState(false)
- const imageBlack: ImageSourcePropType = require('../../../../../../assets/monobank_mc-word.png');
- const imageWhite: ImageSourcePropType = require('../../../../../../assets/bila-n.jpg');
+ const imageBlack: ImageSourcePropType = require('../../../../../../assets/monobank_mc-word.png')
+ const imageWhite: ImageSourcePropType = require('../../../../../../assets/bila-n.jpg')
+
+ const handleChangeModal = useCallback(() => {
+ setShowModal(prevState => !prevState)
+ }, [setShowModal])
return (
<>
-
- {cardNumber.slice(-4)}
-
+
+
+ {cardNumber.slice(-4)}
+
+
+
+
>
)
}
@@ -46,5 +63,5 @@ const styles = StyleSheet.create({
bottom: 5,
left: 5,
fontWeight: '600'
- },
+ }
})
diff --git a/app/components/screens/home/accounts/ModalWindow/ModalWindow.tsx b/app/components/screens/home/accounts/ModalWindow/ModalWindow.tsx
new file mode 100644
index 0000000..651feff
--- /dev/null
+++ b/app/components/screens/home/accounts/ModalWindow/ModalWindow.tsx
@@ -0,0 +1,123 @@
+import { FC } from 'react'
+import {
+ ImageBackground,
+ Modal,
+ Text,
+ View,
+ StyleSheet,
+ ImageSourcePropType,
+ TouchableWithoutFeedback
+} from 'react-native'
+import { IAccount } from '../../../../../typedefs/typedefs'
+import { useProfile } from '../../../../../hooks/useProfile'
+
+interface Props {
+ account: IAccount
+ handleChangeModal: () => void
+ showModal: boolean
+ imageBlack: ImageSourcePropType
+ imageWhite: ImageSourcePropType
+}
+
+export const ModalWindow: FC = (props) => {
+ const {
+ account,
+ handleChangeModal,
+ showModal,
+ imageWhite,
+ imageBlack
+ } = props
+
+ const { name, cardNumber } = account
+ const { name: userName } = useProfile()
+
+ return (
+
+
+
+
+
+
+
+
+ {cardNumber.split(' ').join(' ')}
+
+
+
+
+
+ {userName}
+
+
+
+ Expiry: 12/24
+
+
+
+
+
+
+ )
+}
+
+const styles = StyleSheet.create({
+ modalContainer: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center'
+ },
+ cardContainer: {
+ width: 430,
+ height: '100%',
+ borderRadius: 10,
+ backgroundColor: '#ffffff',
+ padding: 20,
+ justifyContent: 'center',
+ alignItems: 'center'
+ },
+ cardBackground: {
+ position: 'relative',
+ width: '100%',
+ height: 230,
+ resizeMode: 'cover',
+ borderRadius: 10
+ },
+ cardNumber: {
+ fontSize: 28,
+ fontWeight: '900'
+ },
+ cardHolder: {
+ fontSize: 16,
+ fontWeight: 'bold',
+ position: 'absolute',
+ left: 50,
+ bottom: '40%',
+ display: 'flex',
+ width: 230,
+ flexDirection: 'row',
+ justifyContent: 'space-between'
+ },
+ container: {
+ position: 'absolute',
+ left: 50,
+ opacity: 0.9
+ },
+ text: {
+ fontFamily: 'mt-bold',
+ fontSize: 16
+ }
+})
diff --git a/app/components/screens/home/apply-new-product/ApplyNewProduct.tsx b/app/components/screens/home/apply-new-product/ApplyNewProduct.tsx
index 57df2eb..6303aec 100644
--- a/app/components/screens/home/apply-new-product/ApplyNewProduct.tsx
+++ b/app/components/screens/home/apply-new-product/ApplyNewProduct.tsx
@@ -1,16 +1,16 @@
-import { View, Text, Alert } from 'react-native';
-import { FC } from 'react';
-import { Padding } from '../../../../components/ui/Padding';
-import { Button } from '../../../../components/ui/Button';
-import { asyncAlert } from './asyncAlert';
-import { useAuth } from '../../../../hooks/useAuth';
-import { addDoc, serverTimestamp } from 'firebase/firestore';
-import { collection } from '@firebase/firestore';
-import { db } from '../../../../utils/firebase';
-import { getRandomCardNumber } from '../../../../utils/getRandomCardNumber';
+import { View, Text, Alert } from 'react-native'
+import { FC } from 'react'
+import { Padding } from '../../../../components/ui/Padding'
+import { Button } from '../../../../components/ui/Button'
+import { asyncAlert } from './asyncAlert'
+import { useAuth } from '../../../../hooks/useAuth'
+import { addDoc, serverTimestamp } from 'firebase/firestore'
+import { collection } from '@firebase/firestore'
+import { db } from '../../../../utils/firebase'
+import { getRandomCardNumber } from '../../../../utils/getRandomCardNumber'
export const ApplyNewProduct: FC = () => {
- const { user } = useAuth();
+ const { user } = useAuth()
const registerHandler = async () => {
try {
@@ -22,7 +22,7 @@ export const ApplyNewProduct: FC = () => {
resolveValue: 'UAH',
textSecond: 'USD',
resolveValueSecond: 'USD'
- },
+ }
})
const cardType = await asyncAlert({
@@ -33,7 +33,7 @@ export const ApplyNewProduct: FC = () => {
resolveValue: 'Mono Black',
textSecond: 'White',
resolveValueSecond: 'Mono White'
- },
+ }
})
await addDoc(collection(db, 'accounts'), {
@@ -47,7 +47,7 @@ export const ApplyNewProduct: FC = () => {
} catch (error: any) {
Alert.alert('Error apply new product', error.message)
}
- };
+ }
return (
diff --git a/app/components/screens/home/apply-new-product/asyncAlert.ts b/app/components/screens/home/apply-new-product/asyncAlert.ts
index 8920c41..fad5889 100644
--- a/app/components/screens/home/apply-new-product/asyncAlert.ts
+++ b/app/components/screens/home/apply-new-product/asyncAlert.ts
@@ -1,8 +1,8 @@
-import { IAsyncAlert } from '../../../../typedefs/typedefs';
-import { Alert } from 'react-native';
+import { IAsyncAlert } from '../../../../typedefs/typedefs'
+import { Alert } from 'react-native'
-export const asyncAlert = ({ title, message, buttons }: IAsyncAlert) =>
- new Promise(resolve => {
+export const asyncAlert = async ({ title, message, buttons }: IAsyncAlert) =>
+ await new Promise(resolve => {
Alert.alert(title, message, [
{
text: buttons.text,
@@ -15,6 +15,6 @@ export const asyncAlert = ({ title, message, buttons }: IAsyncAlert) =>
onPress: () => {
resolve(buttons.resolveValueSecond)
}
- },
+ }
], { cancelable: false })
})
diff --git a/app/components/screens/home/stories/Stories.tsx b/app/components/screens/home/stories/Stories.tsx
index b515491..e19a803 100644
--- a/app/components/screens/home/stories/Stories.tsx
+++ b/app/components/screens/home/stories/Stories.tsx
@@ -1,13 +1,15 @@
-import { StyleSheet, ScrollView } from 'react-native';
-import { FC } from 'react';
-import { useStories } from '../../../../hooks/useStories';
-import { Loader } from '../../../../components/ui/Loader';
-import { StoryItem } from './StoryItem';
+import { StyleSheet, ScrollView } from 'react-native'
+import { FC } from 'react'
+import { useStories } from '../../../../hooks/useStories'
+import { Loader } from '../../../../components/ui/Loader'
+import { StoryItem } from './StoryItem'
export const Stories: FC = ({ navigation }: any) => {
- const { stories, isLoading } = useStories();
+ const { stories, isLoading } = useStories()
- return isLoading ? : (
+ return isLoading
+ ?
+ : (
{
))}
- )
+ )
}
const styles = StyleSheet.create({
diff --git a/app/components/screens/home/stories/StoryContainer.tsx b/app/components/screens/home/stories/StoryContainer.tsx
index bfe6de0..0ec4a3d 100644
--- a/app/components/screens/home/stories/StoryContainer.tsx
+++ b/app/components/screens/home/stories/StoryContainer.tsx
@@ -1,12 +1,10 @@
-import { FC } from 'react';
-import { useData } from '../../../../hooks/useData';
-// @ts-ignore
-import { StoryContainer as SC } from 'react-native-stories-view';
-import { useAuth } from '../../../../hooks/useAuth';
+import { FC } from 'react'
+import { useData } from '../../../../hooks/useData'
+// @ts-expect-error
+import { StoryContainer as SC } from 'react-native-stories-view'
export const StoryContainer: FC = () => {
- const { activeStories, setActiveStories } = useData();
- const { user } = useAuth();
+ const { activeStories, setActiveStories } = useData()
return (
activeStories && (
@@ -15,11 +13,11 @@ export const StoryContainer: FC = () => {
enableProgress={true}
images={activeStories.images}
duration={20}
- onComplete={() => setActiveStories(null)}
+ onComplete={() => { setActiveStories(null) }}
containerStyle={{
top: 20,
width: '100%',
- height: '100%',
+ height: '100%'
}}
imageStyle={{
height: 900,
diff --git a/app/components/screens/home/stories/StoryItem.tsx b/app/components/screens/home/stories/StoryItem.tsx
index be0608d..4437126 100644
--- a/app/components/screens/home/stories/StoryItem.tsx
+++ b/app/components/screens/home/stories/StoryItem.tsx
@@ -4,31 +4,31 @@ import {
Pressable,
StyleSheet,
ImageBackground
-} from 'react-native';
-import { FC } from 'react';
-import { IStory } from '../../../../typedefs/typedefs';
-import { useData } from '../../../../hooks/useData';
+} from 'react-native'
+import { FC } from 'react'
+import { IStory } from '../../../../typedefs/typedefs'
+import { useData } from '../../../../hooks/useData'
interface Props {
- story: IStory,
+ story: IStory
}
export const StoryItem: FC = (props) => {
- const { story } = props;
+ const { story } = props
- const { setActiveStories } = useData();
+ const { setActiveStories } = useData()
return (
setActiveStories(story)}
+ onPress={() => { setActiveStories(story) }}
>
{story.heading}
@@ -43,14 +43,13 @@ const styles = StyleSheet.create({
height: 100,
borderRadius: 12,
marginLeft: 16,
- borderWidth: 1,
- borderColor: '#00f',
- padding: 5
+ borderWidth: 3,
+ borderColor: '#00f'
},
image: {
width: '100%',
height: '100%',
- justifyContent: 'flex-end',
+ justifyContent: 'flex-end'
},
text: {
color: 'white',
diff --git a/app/components/screens/more/ExchangeRate/ExchangeRate.tsx b/app/components/screens/more/ExchangeRate/ExchangeRate.tsx
index 8d783dd..465aed7 100644
--- a/app/components/screens/more/ExchangeRate/ExchangeRate.tsx
+++ b/app/components/screens/more/ExchangeRate/ExchangeRate.tsx
@@ -1,51 +1,48 @@
-import { FC, useCallback, useEffect, useState } from 'react';
+import { FC, useCallback, useEffect, useState } from 'react'
import {
View,
StyleSheet,
- Text,
-} from 'react-native';
-import { Base, Rates, TypeCurrency } from '../../../../typedefs/typedefs';
-import { getCurrencyCode } from '../../../../utils/convertCurrency';
-import { BOX_SHADOW } from '../../../../utils/styles';
+ Text
+} from 'react-native'
+import { Base, Rates, TypeCurrency } from '../../../../typedefs/typedefs'
+import { getCurrencyCode } from '../../../../utils/convertCurrency'
+import { BOX_SHADOW } from '../../../../utils/styles'
export const ExchangeRate: FC = () => {
- const [base, setBase] = useState([]);
- const [realRates, setRealRates] = useState({} as Omit);//{"EUR": 41.2507, "PLN": 0, "USD": 37.4406}
+ const [base, setBase] = useState([])
+ const [realRates, setRealRates] = useState({} as Omit)
+ const values: TypeCurrency[] = ['USD', 'EUR', 'PLN']
const fetchExchangeRate = useCallback(async () => {
try {
- const response = await fetch('https://api.monobank.ua/bank/currency');
- const data = await response.json();
+ const response = await fetch('https://api.monobank.ua/bank/currency')
+ const data = await response.json()
- setBase(data);
+ setBase(data)
} catch (error) {
- console.error('Error fetching exchange rate:', error);
+ console.error('Error fetching exchange rate:', error)
}
- }, []);
+ }, [])
const findExchangeRate = useCallback(() => {
- const rates = {} as Rates;
+ const rates = values.reduce((acc, el) => {
+ const ISO = getCurrencyCode(el)
- values.forEach((el) => {
- const ISO = getCurrencyCode(el);
+ const rate = base.find((el) => el.currencyCodeA === ISO && el.currencyCodeB === 980)
- const rate = base.find((el) => el.currencyCodeA === ISO && el.currencyCodeB === 980);
-
- rates[el] = rate?.rateSell || 0;
- });
-
- setRealRates(rates);
- }, [base]);
+ acc[el] = rate?.rateSell ?? 0
+ return acc
+ }, {} as Rates)
+ setRealRates(rates)
+ }, [base])
useEffect(() => {
- fetchExchangeRate();
- }, []);
-
- const values: TypeCurrency[] = ['USD' , 'EUR' , 'PLN']
+ fetchExchangeRate()
+ }, [])
useEffect(() => {
- findExchangeRate();
+ findExchangeRate()
}, [base])
return (
@@ -56,7 +53,7 @@ export const ExchangeRate: FC = () => {
{String(key)}
{String(value)}
- );
+ )
})}
)
@@ -68,7 +65,7 @@ const styles = StyleSheet.create({
backgroundColor: 'white',
padding: 16,
justifyContent: 'space-between',
- borderRadius: 20,
+ borderRadius: 20
},
item: {
flexDirection: 'column',
diff --git a/app/components/screens/more/Menu/Menu.tsx b/app/components/screens/more/Menu/Menu.tsx
index 41fc622..11ec610 100644
--- a/app/components/screens/more/Menu/Menu.tsx
+++ b/app/components/screens/more/Menu/Menu.tsx
@@ -1,7 +1,7 @@
-import { View } from 'react-native';
-import { FC } from 'react';
-import { menu } from '../menu';
-import { MenuItem } from './MenuItem/MenuItem';
+import { View } from 'react-native'
+import { FC } from 'react'
+import { menu } from '../menu'
+import { MenuItem } from './MenuItem/MenuItem'
export const Menu: FC = () => {
return (
diff --git a/app/components/screens/more/Menu/MenuItem/MenuItem.tsx b/app/components/screens/more/Menu/MenuItem/MenuItem.tsx
index 7d101d8..d2c3ef0 100644
--- a/app/components/screens/more/Menu/MenuItem/MenuItem.tsx
+++ b/app/components/screens/more/Menu/MenuItem/MenuItem.tsx
@@ -3,23 +3,23 @@ import {
Text,
Pressable,
StyleSheet, Linking
-} from 'react-native';
-import { FC } from 'react';
-import { IMoreItem } from '../../../../../typedefs/typedefs';
-import { BOX_SHADOW } from '../../../../../utils/styles';
-import { MaterialIcons } from '@expo/vector-icons';
+} from 'react-native'
+import { FC } from 'react'
+import { IMoreItem } from '../../../../../typedefs/typedefs'
+import { BOX_SHADOW } from '../../../../../utils/styles'
+import { MaterialIcons } from '@expo/vector-icons'
interface Props {
- item: IMoreItem,
+ item: IMoreItem
}
export const MenuItem: FC = (props) => {
- const { item } = props;
+ const { item } = props
return (
Linking.openURL(item.link)}
+ onPress={async () => await Linking.openURL(item.link)}
>
{item.title}
@@ -44,10 +44,10 @@ const styles = StyleSheet.create({
backgroundColor: 'white',
padding: 16,
justifyContent: 'space-between',
- borderRadius: 20,
+ borderRadius: 20
},
containerTwo: {
- width: '83.3%',
+ width: '83.3%'
},
containerThree: {
borderRadius: 50,
@@ -55,7 +55,7 @@ const styles = StyleSheet.create({
width: 36,
height: 36,
alignItems: 'center',
- justifyContent: 'center',
+ justifyContent: 'center'
},
textOne: {
fontSize: 20,
@@ -65,6 +65,6 @@ const styles = StyleSheet.create({
textTwo: {
marginTop: 4,
opacity: 0.9,
- color: '#718096',
+ color: '#718096'
}
})
diff --git a/app/components/screens/more/More.tsx b/app/components/screens/more/More.tsx
index dfaf1a8..56949a7 100644
--- a/app/components/screens/more/More.tsx
+++ b/app/components/screens/more/More.tsx
@@ -1,8 +1,8 @@
-import { StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { Menu } from './Menu/Menu';
-import { SafeAreaView } from 'react-native-safe-area-context';
-import { ExchangeRate } from './ExchangeRate/ExchangeRate';
+import { StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { Menu } from './Menu/Menu'
+import { SafeAreaView } from 'react-native-safe-area-context'
+import { ExchangeRate } from './ExchangeRate/ExchangeRate'
export const More: FC = () => {
return (
diff --git a/app/components/screens/more/menu.ts b/app/components/screens/more/menu.ts
index a0e21a1..b4fda2b 100644
--- a/app/components/screens/more/menu.ts
+++ b/app/components/screens/more/menu.ts
@@ -1,42 +1,42 @@
-import { IMoreItem } from '../../../typedefs/typedefs';
+import { IMoreItem } from '../../../typedefs/typedefs'
-const url = 'https://www.monobank.ua';
+const url = 'https://www.monobank.ua'
export const menu: IMoreItem[] = [
{
title: 'Our site',
description: 'Search official monobank site',
iconName: 'account-balance',
- link: `${url}`,
+ link: `${url}`
},
{
title: 'Ordering certificates',
description: 'Account statements by e-mail and in paper form',
iconName: 'find-in-page',
- link: `${url}`,
+ link: `${url}`
},
{
title: 'For business',
description: 'Online banking for small business',
iconName: 'business',
- link: `${url}/military-bonds`,
+ link: `${url}/military-bonds`
},
{
title: 'International transfers',
description: 'Transfer cash to another country',
iconName: 'send-to-mobile',
- link: `${url}/international`,
+ link: `${url}/international`
},
{
title: 'Deposits',
description: 'Make a deposit',
iconName: 'wallet-travel',
- link: `${url}/deposit`,
+ link: `${url}/deposit`
},
{
title: 'About us',
description: 'A little about us and how to contact us',
iconName: 'people',
- link: `${url}/fop`,
- },
+ link: `${url}/fop`
+ }
]
diff --git a/app/components/screens/payments/Payments.tsx b/app/components/screens/payments/Payments.tsx
index 5843064..5cf6042 100644
--- a/app/components/screens/payments/Payments.tsx
+++ b/app/components/screens/payments/Payments.tsx
@@ -1,14 +1,11 @@
-import { FC } from 'react';
-import { Layout } from '../../layout/Layout';
-import { Heading } from '../../ui/Heading';
-import { Contacts } from './contacts/Contacts';
-import { Other } from './other/Other';
+import { FC } from 'react'
+import { Layout } from '../../layout/Layout'
+import { Contacts } from './contacts/Contacts'
+import { Other } from './other/Other'
export const Payments: FC = () => {
return (
-
-
diff --git a/app/components/screens/payments/contacts/ContactItem/ContactItem.tsx b/app/components/screens/payments/contacts/ContactItem/ContactItem.tsx
index 09e2dce..819cb0a 100644
--- a/app/components/screens/payments/contacts/ContactItem/ContactItem.tsx
+++ b/app/components/screens/payments/contacts/ContactItem/ContactItem.tsx
@@ -2,40 +2,48 @@ import {
Text,
Pressable,
StyleSheet,
- View,
-} from 'react-native';
-import { FC, useState } from 'react';
-import { IContact } from '../../../../../typedefs/typedefs';
-import { Avatar } from '../../../../ui/Avatar';
-import { useAccounts } from '../../../../../hooks/useAccounts';
-import { handleTransfer } from '../../handleTransfer';
-import { ModalWindow } from '../../../../ui/ModalWindow';
+ View
+} from 'react-native'
+import { FC, useCallback, useState } from 'react'
+import { IContact } from '../../../../../typedefs/typedefs'
+import { useAccounts } from '../../../../../hooks/useAccounts'
+import { handleTransfer } from '../../handleTransfer'
+import { ModalWindow } from '../../../../ui/ModalWindow'
+import { useSendMoney } from '../../../../../hooks/useSendMoney'
+import { ModifyAvatar } from '../../../../../components/ui/ModifyAvatar'
interface Props {
- contact: IContact,
+ contact: IContact
}
export const ContactItem: FC = (props) => {
- const { contact } = props;
- const { accounts } = useAccounts();
- const [transferAmount, setTransferAmount] = useState('');
- const [showModal, setShowModal] = useState(false);
+ const { contact } = props
+ const { accounts } = useAccounts()
+ const [transferAmount, setTransferAmount] = useState('')
- const handleTransferPress = () => {
- setShowModal(true);
- };
+ const {
+ setCardName,
+ cardName,
+ setShowModal,
+ showModal,
+ sendMoney
+ } = useSendMoney()
- const handleTransferConfirm = async () => {
- await handleTransfer(accounts[0], contact.cardNumber, transferAmount);
+ const handleTransferConfirm = useCallback(async (transferAmount: string) => {
+ const cardNumber = accounts.find(el => el.name === cardName)
- setTransferAmount('');
- setShowModal(false);
- };
+ if (cardNumber) {
+ await handleTransfer(cardNumber, contact.cardNumber, transferAmount)
+ }
+
+ setTransferAmount('')
+ setShowModal(false)
+ }, [cardName, setCardName])
return (
-
-
+
+
{contact.displayName}
@@ -45,26 +53,26 @@ export const ContactItem: FC = (props) => {
setShowModal={setShowModal}
setTransferAmount={setTransferAmount}
transferAmount={transferAmount}
- handleTransferConfirm={handleTransferConfirm}
+ handleTransferConfirm={async () => { await handleTransferConfirm(transferAmount) }}
/>
- );
-};
+ )
+}
const styles = StyleSheet.create({
container: {
marginLeft: 16,
marginRight: 4,
- alignContent: 'center',
+ alignContent: 'center'
},
text: {
marginTop: 4,
- fontSize: 14,
+ fontSize: 14
},
input: {
width: '80%',
borderWidth: 1,
padding: 10,
- marginVertical: 10,
- },
-});
+ marginVertical: 10
+ }
+})
diff --git a/app/components/screens/payments/contacts/Contacts.tsx b/app/components/screens/payments/contacts/Contacts.tsx
index 69bceea..4b83b0e 100644
--- a/app/components/screens/payments/contacts/Contacts.tsx
+++ b/app/components/screens/payments/contacts/Contacts.tsx
@@ -1,23 +1,25 @@
-import { View, Text, StyleSheet, ScrollView } from 'react-native';
-import { FC } from 'react';
-import { useContacts } from '../../../../hooks/useContacts';
+import { View, StyleSheet, ScrollView } from 'react-native'
+import { FC } from 'react'
+import { useContacts } from '../../../../hooks/useContacts'
import { SubHeading } from '../../../ui/SubHeading'
-import { Loader } from '../../../ui/Loader';
-import { ContactItem } from './ContactItem/ContactItem';
-import { TransferByCardNumber } from './TransferByCardNumber/TransferByCardNumber';
+import { Loader } from '../../../ui/Loader'
+import { ContactItem } from './ContactItem/ContactItem'
+import { TransferByCardNumber } from './TransferByCardNumber/TransferByCardNumber'
export const Contacts: FC = () => {
- const { contacts, isLoading } = useContacts();
+ const { contacts, isLoading } = useContacts()
return (
-
+
- {isLoading ? (
+ {isLoading
+ ? (
- ) : (
+ )
+ : (
{
/>
))}
- )}
+ )}
)
}
const styles = StyleSheet.create({
- main: {
- marginVertical: 32,
- },
scroll: {
- marginTop: 20,
+ marginTop: 20
}
})
diff --git a/app/components/screens/payments/contacts/TransferByCardNumber/TransferByCardNumber.tsx b/app/components/screens/payments/contacts/TransferByCardNumber/TransferByCardNumber.tsx
index 4a39204..1ef01fe 100644
--- a/app/components/screens/payments/contacts/TransferByCardNumber/TransferByCardNumber.tsx
+++ b/app/components/screens/payments/contacts/TransferByCardNumber/TransferByCardNumber.tsx
@@ -1,44 +1,49 @@
-import { FC, useState } from 'react';
-import { StyleSheet, View } from 'react-native';
-import { handleTransfer } from '../../../payments/handleTransfer';
-import { useAccounts } from '../../../../../hooks/useAccounts';
-import { Button } from '../../../../../components/ui/Button';
-import { ModalWindow } from '../../../../ui/ModalWindow';
+import { FC, useCallback, useState } from 'react'
+import { StyleSheet, View } from 'react-native'
+import { handleTransfer } from '../../../payments/handleTransfer'
+import { useAccounts } from '../../../../../hooks/useAccounts'
+import { Button } from '../../../../../components/ui/Button'
+import { ModalWindow } from '../../../../ui/ModalWindow'
+import { useSendMoney } from '../../../../../hooks/useSendMoney'
export const TransferByCardNumber: FC = () => {
- const [transferAmount, setTransferAmount] = useState('');
- const [cardNumber, setCardNumber] = useState('');
- const [showModal, setShowModal] = useState(false);
+ const [transferAmount, setTransferAmount] = useState('')
+ const [cardNumber, setCardNumber] = useState('')
- const { accounts } = useAccounts();
+ const { accounts } = useAccounts()
+ const {
+ setCardName,
+ cardName,
+ setShowModal,
+ showModal,
+ sendMoney
+ } = useSendMoney()
- const addSpacesToCardNumber = (cardNumber: string) => {
- const cardNumberArray = Array.from(cardNumber);
+ const handleCardNumberChange = (text: string) => {
+ const inputText = text.replace(/\D/g, '').substring(0, 16)
+ const splitText = inputText.match(/.{1,4}/g)
+ const formattedText = splitText ? splitText.join(' ') : ''
+ setCardNumber(formattedText)
+ }
- return cardNumberArray.map((el, index) => {
- if ((index + 1) % 4 === 0 && index !== cardNumberArray.length - 1) {
- return el + ' ';
- } else {
- return el;
- }
- }).join('');
- };
+ const handleTransferConfirm = useCallback(async (cardNumber: string, transferAmount: string) => {
+ const cardN = accounts.find(el => el.name === cardName)
- const handleTransferConfirm = async () => {
- const cardNumberWithSpaces = addSpacesToCardNumber(cardNumber);
- await handleTransfer(accounts[0], cardNumberWithSpaces, transferAmount);
+ if (cardN) {
+ await handleTransfer(cardN, cardNumber, transferAmount)
+ }
- setCardNumber('');
- setTransferAmount('');
- setShowModal(false);
- };
+ setCardNumber('')
+ setTransferAmount('')
+ setShowModal(false)
+ }, [cardName, setCardName])
return (
<>
@@ -49,20 +54,15 @@ export const TransferByCardNumber: FC = () => {
transferAmount={transferAmount}
setCardNumber={setCardNumber}
cardNumber={cardNumber}
- handleTransferConfirm={handleTransferConfirm}
+ handleTransferConfirm={async () => { await handleTransferConfirm(cardNumber, transferAmount) }}
needTwo={true}
+ handleCardNumberChange={handleCardNumberChange}
/>
>
)
}
const styles = StyleSheet.create({
- input: {
- width: '80%',
- borderWidth: 1,
- padding: 10,
- marginVertical: 10,
- },
button: {
width: '100%',
alignItems: 'center'
diff --git a/app/components/screens/payments/handleTransfer.ts b/app/components/screens/payments/handleTransfer.ts
index da8c898..901e6e1 100644
--- a/app/components/screens/payments/handleTransfer.ts
+++ b/app/components/screens/payments/handleTransfer.ts
@@ -1,4 +1,4 @@
-import { Alert } from 'react-native';
+import { Alert } from 'react-native'
import {
collection,
doc,
@@ -6,65 +6,63 @@ import {
getDocs,
limit,
query,
+ UpdateData,
updateDoc,
where
-} from '@firebase/firestore';
-import { db } from '../../../utils/firebase';
-import { IAccount } from '../../../typedefs/typedefs';
+} from '@firebase/firestore'
+import { db } from '../../../utils/firebase'
+import { IAccount } from '../../../typedefs/typedefs'
-import { convertCurrency } from '../../../utils/convertCurrency';
+import { convertCurrency } from '../../../utils/convertCurrency'
export const handleTransfer = async (fromAccount: IAccount, cardNumber: string, transferAmount: string) => {
try {
- let accountToId = '';
- let currentToBalance = '';
- let accountFromCurrency = fromAccount.currency;
- let convertAmount = '';
+ let accountToId = ''
+ let currentToBalance = ''
+ const accountFromCurrency = fromAccount.currency
+ let convertAmount = ''
const querySnapshot = await getDocs(
query(collection(db, 'accounts'), where('cardNumber', '==', cardNumber), limit(1))
- );
+ )
querySnapshot.docs.forEach((doc) => {
- accountToId = doc.id;
- });
+ accountToId = doc.id
+ })
- const docRefTo = doc(db, 'accounts', accountToId);
- const docSnapTo = await getDoc(docRefTo);
+ const docRefTo = doc(db, 'accounts', accountToId)
+ const docSnapTo = await getDoc(docRefTo)
if (docSnapTo.exists()) {
- currentToBalance = docSnapTo.data().balance;
- const accountToCurrency = docSnapTo.data().currency;
+ currentToBalance = docSnapTo.data().balance
+ const accountToCurrency = docSnapTo.data().currency
if (accountFromCurrency !== accountToCurrency) {
- const convertedAmount = await convertCurrency(Number(transferAmount), accountFromCurrency, accountToCurrency);
- convertAmount = convertedAmount.toString();
+ const convertedAmount = await convertCurrency(Number(transferAmount), accountFromCurrency, accountToCurrency)
+ convertAmount = convertedAmount.toString()
} else {
- convertAmount = transferAmount;
+ convertAmount = transferAmount
}
} else {
- Alert.alert('The card where you are sending money was not found');
- return;
+ Alert.alert('The card where you are sending money was not found')
+ return
}
if (fromAccount.balance < Number(transferAmount)) {
- Alert.alert('Insufficient funds in your account');
- return;
+ Alert.alert('Insufficient funds in your account')
+ return
}
await updateDoc(docRefTo, {
- balance: currentToBalance + Number(convertAmount),
- });
+ balance: Number(currentToBalance) + Number(convertAmount)
+ } as UpdateData<{ balance: string }>)
- const docRefFrom = doc(db, 'accounts', fromAccount._id);
+ const docRefFrom = doc(db, 'accounts', fromAccount._id)
await updateDoc(docRefFrom, {
- balance: fromAccount.balance - Number(transferAmount),
- });
-
- return;
+ balance: fromAccount.balance - Number(transferAmount)
+ } as UpdateData<{ balance: string }>)
} catch (error: any) {
- Alert.alert('Error transfer', error.message);
+ Alert.alert('Error transfer', error.message)
}
-};
-
+}
diff --git a/app/components/screens/payments/other/Other.tsx b/app/components/screens/payments/other/Other.tsx
index 6008ce5..2e0d966 100644
--- a/app/components/screens/payments/other/Other.tsx
+++ b/app/components/screens/payments/other/Other.tsx
@@ -1,8 +1,8 @@
-import { View, StyleSheet, ScrollView } from 'react-native';
-import { FC } from 'react';
-import { SubHeading } from '../../../ui/SubHeading';
-import { otherItems } from './data';
-import { OtherItem } from './OtherItem/OtherItem';
+import { View, StyleSheet, ScrollView } from 'react-native'
+import { FC } from 'react'
+import { SubHeading } from '../../../ui/SubHeading'
+import { otherItems } from './data'
+import { OtherItem } from './OtherItem/OtherItem'
export const Other: FC = () => {
return (
@@ -24,6 +24,6 @@ export const Other: FC = () => {
const styles = StyleSheet.create({
scroll: {
- paddingVertical: 20,
+ paddingVertical: 20
}
})
diff --git a/app/components/screens/payments/other/OtherItem/Icon.tsx b/app/components/screens/payments/other/OtherItem/Icon.tsx
index 7974f1e..a1c7b8e 100644
--- a/app/components/screens/payments/other/OtherItem/Icon.tsx
+++ b/app/components/screens/payments/other/OtherItem/Icon.tsx
@@ -1,12 +1,12 @@
-import { FC } from 'react';
-import { View, StyleSheet } from 'react-native';
-import { IFooterItem } from '../../../../../typedefs/typedefs';
+import { FC } from 'react'
+import { View, StyleSheet } from 'react-native'
+import { IFooterItem } from '../../../../../typedefs/typedefs'
import { AntDesign } from '@expo/vector-icons'
-interface Props extends Pick{}
+interface Props extends Pick {}
export const Icon: FC = (props) => {
- const { iconName } = props;
+ const { iconName } = props
return (
diff --git a/app/components/screens/payments/other/OtherItem/OtherItem.tsx b/app/components/screens/payments/other/OtherItem/OtherItem.tsx
index 0e8cb7b..4afa22e 100644
--- a/app/components/screens/payments/other/OtherItem/OtherItem.tsx
+++ b/app/components/screens/payments/other/OtherItem/OtherItem.tsx
@@ -1,37 +1,37 @@
-import { FC, useState } from 'react';
+import { FC, useState } from 'react'
import {
Text,
Pressable,
StyleSheet,
- View,
-} from 'react-native';
-import { IOtherItem } from '../../../../../typedefs/typedefs';
-import { Icon } from './Icon';
-import { BOX_SHADOW } from '../../../../../utils/styles';
-import { handleTransfer } from '../../handleTransfer';
-import { useAccounts } from '../../../../../hooks/useAccounts';
-import { ModalWindow } from '../../../../ui/ModalWindow';
+ View
+} from 'react-native'
+import { IOtherItem } from '../../../../../typedefs/typedefs'
+import { Icon } from './Icon'
+import { BOX_SHADOW } from '../../../../../utils/styles'
+import { handleTransfer } from '../../handleTransfer'
+import { useAccounts } from '../../../../../hooks/useAccounts'
+import { ModalWindow } from '../../../../ui/ModalWindow'
interface Props {
- item: IOtherItem,
+ item: IOtherItem
}
export const OtherItem: FC = (props) => {
- const { item } = props;
- const { accounts } = useAccounts();
- const [showModal, setShowModal] = useState(false);
- const [transferAmount, setTransferAmount] = useState('');
+ const { item } = props
+ const { accounts } = useAccounts()
+ const [showModal, setShowModal] = useState(false)
+ const [transferAmount, setTransferAmount] = useState('')
const handleTransferPress = () => {
- setShowModal(true);
- };
+ setShowModal(true)
+ }
const handleTransferConfirm = async () => {
- await handleTransfer(accounts[0], '5111 8234 5714 1749', transferAmount);
+ await handleTransfer(accounts[0], '5111 8234 5714 1749', transferAmount)
- setTransferAmount('');
- setShowModal(false);
- };
+ setTransferAmount('')
+ setShowModal(false)
+ }
return (
@@ -52,8 +52,8 @@ export const OtherItem: FC = (props) => {
handleTransferConfirm={handleTransferConfirm}
/>
- );
-};
+ )
+}
const styles = StyleSheet.create({
main: {
@@ -64,12 +64,12 @@ const styles = StyleSheet.create({
height: 96,
backgroundColor: 'white',
alignItems: 'center',
- justifyContent: 'center',
+ justifyContent: 'center'
},
input: {
width: '80%',
borderWidth: 1,
padding: 10,
- marginVertical: 10,
- },
-});
+ marginVertical: 10
+ }
+})
diff --git a/app/components/screens/payments/other/data.ts b/app/components/screens/payments/other/data.ts
index 863c8db..5f4f986 100644
--- a/app/components/screens/payments/other/data.ts
+++ b/app/components/screens/payments/other/data.ts
@@ -1,24 +1,24 @@
-import { IOtherItem } from '../../../../typedefs/typedefs';
+import { IOtherItem } from '../../../../typedefs/typedefs'
export const otherItems: IOtherItem[] = [
{
iconName: 'mobile1',
- title: 'Mobile',
+ title: 'Mobile'
},
{
iconName: 'home',
- title: 'Housing',
+ title: 'Housing'
},
{
iconName: 'wifi',
- title: 'Internet',
+ title: 'Internet'
},
{
iconName: 'iconfontdesktop',
- title: 'TV',
+ title: 'TV'
},
{
iconName: 'car',
- title: 'Transport',
+ title: 'Transport'
}
]
diff --git a/app/components/screens/profile/AvatarsItem/AvatarsItem.tsx b/app/components/screens/profile/AvatarsItem/AvatarsItem.tsx
new file mode 100644
index 0000000..b148f8a
--- /dev/null
+++ b/app/components/screens/profile/AvatarsItem/AvatarsItem.tsx
@@ -0,0 +1,38 @@
+import { FC } from 'react'
+import { StyleSheet, View } from 'react-native'
+import { Avatar as IAvatar } from '../../../../typedefs/typedefs'
+import { Avatar } from '../../../ui/Avatar'
+
+interface Props {
+ icon: IAvatar
+ onChangeAvatar: (uri: string) => void
+}
+
+export const AvatarsItem: FC = (props) => {
+ const { icon, onChangeAvatar } = props
+
+ return (
+
+
+
+
+
+ )
+}
+
+const styles = StyleSheet.create({
+ container: {
+ marginBottom: 16
+ },
+ item: {
+ borderRadius: 12,
+ overflow: 'hidden',
+ width: 56,
+ height: 56,
+ marginHorizontal: 16
+ }
+})
diff --git a/app/components/screens/profile/ModalWindow/ModalWindow.tsx b/app/components/screens/profile/ModalWindow/ModalWindow.tsx
new file mode 100644
index 0000000..89e0b2d
--- /dev/null
+++ b/app/components/screens/profile/ModalWindow/ModalWindow.tsx
@@ -0,0 +1,33 @@
+import { FC } from 'react'
+import { Layout } from '../../../../components/layout/Layout'
+import { FlatList, Modal } from 'react-native'
+import { avatars } from '../avatars'
+import { AvatarsItem } from '../AvatarsItem/AvatarsItem'
+
+interface Props {
+ showModal: boolean
+ handleChangeAvatar: (uri: string) => void
+}
+
+export const ModalWindow: FC = (props) => {
+ const { showModal, handleChangeAvatar } = props
+
+ return (
+
+
+ (
+
+ )}
+ keyExtractor={item => String(item.id)}
+ numColumns={4}
+ style={{ paddingHorizontal: 20 }}
+ />
+
+
+ )
+}
diff --git a/app/components/screens/profile/Profile.tsx b/app/components/screens/profile/Profile.tsx
index 174bd3d..e23d5b2 100644
--- a/app/components/screens/profile/Profile.tsx
+++ b/app/components/screens/profile/Profile.tsx
@@ -1,29 +1,39 @@
-import { View, Text, StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { Layout } from '../../../components/layout/Layout';
-import { Heading } from '../../../components/ui/Heading';
-import { Padding } from '../../../components/ui/Padding';
-import { useProfile } from '../../../hooks/useProfile';
-import { Loader } from '../../../components/ui/Loader';
-import { Field } from '../../../components/ui/Field';
-import { Button } from '../../../components/ui/Button';
-import { useAuth } from '../../../hooks/useAuth';
-import { useUpdateProfile } from '../../../hooks/useUpdateProfile';
+import { View, Text, StyleSheet } from 'react-native'
+import { FC, useCallback, useState } from 'react'
+import { Layout } from '../../../components/layout/Layout'
+import { Heading } from '../../../components/ui/Heading'
+import { Padding } from '../../../components/ui/Padding'
+import { useProfile } from '../../../hooks/useProfile'
+import { Loader } from '../../../components/ui/Loader'
+import { useUpdateProfile } from '../../../hooks/useUpdateProfile'
+import { ProfileContent } from './ProfileContent/ProfileContent'
+
+export const Profile: FC = () => {
+ const [showModal, setShowModal] = useState(false)
-export const Profile: FC = ({ navigation }: any) => {
- const { logout } = useAuth();
const {
name,
setName,
profile,
- isLoading: isProfileLoading
- } = useProfile();
+ isLoading: isProfileLoading,
+ realAvatar,
+ setRealAvatar
+ } = useProfile()
const {
isLoading,
isSuccess,
- updateProfile,
- } = useUpdateProfile(name, profile.docId);
+ updateProfile
+ } = useUpdateProfile(name, realAvatar, profile.docId)
+
+ const handleShowModal = useCallback(() => {
+ setShowModal(prevState => !prevState)
+ }, [])
+
+ const handleChangeAvatar = useCallback((uri: string) => {
+ setRealAvatar(uri)
+ handleShowModal()
+ }, [])
return (
@@ -38,28 +48,22 @@ export const Profile: FC = ({ navigation }: any) => {
)}
- {(isProfileLoading || isLoading) ? (
+ {(isProfileLoading || isLoading)
+ ? (
- ) : (
- <>
-
-
-
-
-
- >
- )}
+ )
+ : (
+
+ )}
)
@@ -69,10 +73,10 @@ const styles = StyleSheet.create({
alert: {
backgroundColor: 'green',
padding: 12,
- borderRadius: 12,
+ borderRadius: 12
},
text: {
color: 'white',
textAlign: 'center'
- },
+ }
})
diff --git a/app/components/screens/profile/ProfileContent/ProfileContent.tsx b/app/components/screens/profile/ProfileContent/ProfileContent.tsx
new file mode 100644
index 0000000..f41a50b
--- /dev/null
+++ b/app/components/screens/profile/ProfileContent/ProfileContent.tsx
@@ -0,0 +1,68 @@
+import { Dispatch, FC, SetStateAction } from 'react'
+import { Field } from '../../../../components/ui/Field'
+import { Button } from '../../../../components/ui/Button'
+import { ModalWindow } from '../ModalWindow/ModalWindow'
+import { useAuth } from '../../../../hooks/useAuth'
+
+interface Props {
+ handleShowModal: () => void
+ updateProfile: () => Promise
+ showModal: boolean
+ handleChangeAvatar: (uri: string) => void
+ name: string
+ setName: Dispatch>
+ realAvatar: string
+ setRealAvatar: (uri: string) => void
+}
+
+export const ProfileContent: FC = (props) => {
+ const {
+ handleShowModal,
+ updateProfile,
+ showModal,
+ handleChangeAvatar,
+ setName,
+ name,
+ setRealAvatar,
+ realAvatar
+ } = props
+
+ const { logout } = useAuth()
+
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
diff --git a/app/components/screens/profile/avatars.ts b/app/components/screens/profile/avatars.ts
new file mode 100644
index 0000000..5f4a8c5
--- /dev/null
+++ b/app/components/screens/profile/avatars.ts
@@ -0,0 +1,244 @@
+import { Avatar } from '../../../typedefs/typedefs'
+
+export const avatars: Avatar[] = [
+ {
+ id: 1,
+ avatar: 'https://media.gettyimages.com/id/1227618801/vector/human-face-avatar-icon-profile-for-social-network-man-vector-illustration.jpg?s=1024x1024&w=gi&k=20&c=jmyg6H4d9kkHPr4cA-w2ZYwcD9Hw2QXe61I-bYOEXgk='
+ },
+ {
+ id: 2,
+ avatar: 'https://static.vecteezy.com/system/resources/previews/000/439/863/original/vector-users-icon.jpg'
+ },
+ {
+ id: 3,
+ avatar: 'https://cdn.icon-icons.com/icons2/2121/PNG/512/girl_woman_braids_people_avatar_icon_131277.png'
+ },
+ {
+ id: 4,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQgxpLyp8g617m3Jan7xXXw3rMVCMxJLs0CGw&usqp=CAU'
+ },
+ {
+ id: 5,
+ avatar: 'https://img.freepik.com/premium-vector/person-avatar-icon-design-vector-for-multiple-use-vector-illustration_625349-280.jpg?w=2000'
+ },
+ {
+ id: 6,
+ avatar: 'https://image.pngaaa.com/408/81408-middle.png'
+ },
+ {
+ id: 7,
+ avatar: 'https://cdn1.iconfinder.com/data/icons/avatars-55/100/avatar_profile_user_music_headphones_shirt_cool-512.png'
+ },
+ {
+ id: 8,
+ avatar: 'https://w7.pngwing.com/pngs/687/440/png-transparent-avatar-face-girl-female-woman-profile-smiley-avatar-icon.png'
+ },
+ {
+ id: 9,
+ avatar: 'https://cdn.icon-icons.com/icons2/2643/PNG/512/female_woman_person_people_avatar_icon_159367.png'
+ },
+ {
+ id: 10,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTv1vgdYWHDUkyYYYxV4RV78Q4AHDtagK2GRQ&usqp=CAU'
+ },
+ {
+ id: 11,
+ avatar: 'https://e7.pngegg.com/pngimages/312/283/png-clipart-man-s-face-avatar-computer-icons-user-profile-business-user-avatar-blue-face.png'
+ },
+ {
+ id: 12,
+ avatar: 'https://w7.pngwing.com/pngs/193/660/png-transparent-computer-icons-woman-avatar-avatar-girl.png'
+ },
+ {
+ id: 13,
+ avatar: 'https://creazilla-store.fra1.digitaloceanspaces.com/icons/7913014/avatar-icon-sm.png'
+ },
+ {
+ id: 14,
+ avatar: 'https://cdn-icons-png.flaticon.com/512/3781/3781973.png'
+ },
+ {
+ id: 15,
+ avatar: 'https://t4.ftcdn.net/jpg/02/45/28/17/360_F_245281783_3zeOLu7mhjUmYbFlBwSNsfwQmQZzukWo.jpg'
+ },
+ {
+ id: 16,
+ avatar: 'https://png.pngitem.com/pimgs/s/78-786293_1240-x-1240-0-avatar-profile-icon-png.png'
+ },
+ {
+ id: 17,
+ avatar: 'https://icon-library.com/images/avatar-icon-images/avatar-icon-images-17.jpg'
+ },
+ {
+ id: 18,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSw83BrS_8REWsfOm3mx8hQxpqbv7-crMVLXHiYQluPySkm6F7Z7tczd6-01YTI5NP8eRg&usqp=CAU'
+ },
+ {
+ id: 19,
+ avatar: 'https://cdn.icon-icons.com/icons2/1371/PNG/512/batman_90804.png'
+ },
+ {
+ id: 20,
+ avatar: 'https://static.vecteezy.com/system/resources/thumbnails/002/002/403/small_2x/man-with-beard-avatar-character-isolated-icon-free-vector.jpg'
+ },
+ {
+ id: 21,
+ avatar: 'https://creazilla-store.fra1.digitaloceanspaces.com/icons/7914927/man-icon-md.png'
+ },
+ {
+ id: 22,
+ avatar: 'https://cdn.icon-icons.com/icons2/2643/PNG/512/male_man_boy_black_tone_people_person_avatar_icon_159356.png'
+ },
+ {
+ id: 23,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRgLZal2ngrRXdEebFSXKENv_Joj38zpGXhwA&usqp=CAU'
+ },
+ {
+ id: 24,
+ avatar: 'https://st3.depositphotos.com/19428878/37071/v/450/depositphotos_370714622-stock-illustration-businessman-icon-vector-male-avatar.jpg'
+ },
+ {
+ id: 25,
+ avatar: 'https://cdn.icon-icons.com/icons2/3708/PNG/512/man_person_people_avatar_icon_230017.png'
+ },
+ {
+ id: 26,
+ avatar: 'https://www.shutterstock.com/image-vector/avatar-girls-icon-vector-woman-260nw-433429546.jpg'
+ },
+ {
+ id: 27,
+ avatar: 'https://cdn.iconscout.com/icon/free/png-256/free-avatar-370-456322.png?f=webp'
+ },
+ {
+ id: 28,
+ avatar: 'https://static.vecteezy.com/system/resources/previews/002/002/297/original/beautiful-woman-avatar-character-icon-free-vector.jpg'
+ },
+ {
+ id: 29,
+ avatar: 'https://static.vecteezy.com/system/resources/previews/002/002/257/original/beautiful-woman-avatar-character-icon-free-vector.jpg'
+ },
+ {
+ id: 30,
+ avatar: 'https://as1.ftcdn.net/v2/jpg/01/16/24/44/1000_F_116244459_pywR1e0T3H7FPk3LTMjG6jsL3UchDpht.jpg'
+ },
+ {
+ id: 31,
+ avatar: 'https://media.istockphoto.com/id/1331335536/vector/female-avatar-icon.jpg?s=170667a&w=0&k=20&c=-iyD_53ZEeZPc4SmvmGB1FJXZcHy_fvbJBv6O8HblHs='
+ },
+ {
+ id: 32,
+ avatar: 'https://cdn.pixabay.com/photo/2020/07/14/13/07/icon-5404125_1280.png'
+ },
+ {
+ id: 33,
+ avatar: 'https://icon-library.com/images/anonymous-avatar-icon/anonymous-avatar-icon-13.jpg'
+ },
+ {
+ id: 34,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQI3vvVZ-pOGsyhaNEm9s-tm96lh7OGxJrpPQ&usqp=CAU'
+ },
+ {
+ id: 35,
+ avatar: 'https://fiverr-res.cloudinary.com/images/q_auto,f_auto/gigs/21760012/original/d4c0c142f91f012c9a8a9c9aeef3bac28036f15b/create-your-cartoon-style-flat-avatar-or-icon.jpg'
+ },
+ {
+ id: 36,
+ avatar: 'https://as1.ftcdn.net/v2/jpg/01/87/17/86/1000_F_187178666_GyusuEACf98LSRUmYiUOvIPKv6X4MErT.jpg'
+ },
+ {
+ id: 37,
+ avatar: 'https://static.vecteezy.com/system/resources/previews/014/194/198/original/avatar-icon-human-a-person-s-badge-social-media-profile-symbol-the-symbol-of-a-person-vector.jpg'
+ },
+ {
+ id: 38,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRn883CaC7zhcCCr4a_RxUaJ6pns4INvy5zYZIjRC7OkJPvFRPxZNCHJpptgAK7fHFg0uo&usqp=CAU'
+ },
+ {
+ id: 39,
+ avatar: 'https://icon-library.com/images/avatar-icon-free/avatar-icon-free-15.jpg'
+ },
+ {
+ id: 40,
+ avatar: 'https://us.123rf.com/450wm/branche/branche1409/branche140900055/31266295-freelancer-avatar-icon.jpg'
+ },
+ {
+ id: 41,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS3Z9rMHYtAHW14fQYWqzPoARdimFbyhm0Crw&usqp=CAU'
+ },
+ {
+ id: 42,
+ avatar: 'https://banner2.cleanpng.com/20181128/gif/kisspng-ninja-portable-network-graphics-computer-icons-ava-macmacmac-5bfea49c377331.5470002815434149402271.jpg'
+ },
+ {
+ id: 43,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSQ05u-QowqQM3rHaIswHji0CGGldrL1VHwOA&usqp=CAU'
+ },
+ {
+ id: 44,
+ avatar: 'https://e7.pngegg.com/pngimages/674/524/png-clipart-professional-computer-icons-avatar-job-avatar-heroes-computer.png'
+ },
+ {
+ id: 45,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSGs85L6VnAjWyJwi8u5v6K2N765HnHV-pVxQ&usqp=CAU'
+ },
+ {
+ id: 46,
+ avatar: 'https://i.pinimg.com/originals/49/3f/a0/493fa0f13970ab3ef29375669f670451.jpg'
+ },
+ {
+ id: 47,
+ avatar: 'https://thumbs.dreamstime.com/z/female-avatar-icon-women-clipart-png-vector-girl-avatar-women-clipart-bor-bisiness-icon-png-vector-233362315.jpg'
+ },
+ {
+ id: 48,
+ avatar: 'https://cdn.icon-icons.com/icons2/2438/PNG/512/girl_avatar_icon_148456.png'
+ },
+ {
+ id: 49,
+ avatar: 'https://cdn.icon-icons.com/icons2/2438/PNG/512/girl_avatar_icon_148461.png'
+ },
+ {
+ id: 50,
+ avatar: 'https://cdn.icon-icons.com/icons2/2438/PNG/512/boy_avatar_icon_148455.png'
+ },
+ {
+ id: 51,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTv1vgdYWHDUkyYYYxV4RV78Q4AHDtagK2GRQ&usqp=CAU'
+ },
+ {
+ id: 52,
+ avatar: 'https://static.vecteezy.com/system/resources/thumbnails/004/607/806/small/man-face-emotive-icon-smiling-bearded-male-character-in-yellow-flat-illustration-isolated-on-white-happy-human-psychological-portrait-positive-emotions-user-avatar-for-app-web-design-vector.jpg'
+ },
+ {
+ id: 53,
+ avatar: 'https://cdn.icon-icons.com/icons2/1371/PNG/512/robot02_90810.png'
+ },
+ {
+ id: 54,
+ avatar: 'https://cdn-icons-png.flaticon.com/512/1068/1068549.png'
+ },
+ {
+ id: 55,
+ avatar: 'https://cdn-icons-png.flaticon.com/512/1058/1058432.png'
+ },
+ {
+ id: 56,
+ avatar: 'https://icons.iconarchive.com/icons/diversity-avatars/avatars/256/robot-01-icon.png'
+ },
+ {
+ id: 57,
+ avatar: 'https://cdn4.iconfinder.com/data/icons/avatars-21/512/avatar-circle-human-male-3-512.png'
+ },
+ {
+ id: 58,
+ avatar: 'https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTS4aC4cPo8HWhUVKG2iKUxhOAl9aGKqflRBg&usqp=CAU'
+ },
+ {
+ id: 59,
+ avatar: 'https://img.freepik.com/premium-vector/woman-girl-female-cartoon-avatar-icon_25030-13347.jpg?w=2000'
+ },
+ {
+ id: 60,
+ avatar: 'https://media.istockphoto.com/id/612520134/zh/%E5%90%91%E9%87%8F/girl-icon-cartoon-single-avatar-people-icon.jpg?s=612x612&w=0&k=20&c=EB6F35bD0vqwZNN_oaY-R_lBuK8zKv_JRlhBE3tpRgg='
+ }
+]
diff --git a/app/components/screens/services/ServiceItem/Percent.tsx b/app/components/screens/services/ServiceItem/Percent.tsx
index d30d04e..dd729dd 100644
--- a/app/components/screens/services/ServiceItem/Percent.tsx
+++ b/app/components/screens/services/ServiceItem/Percent.tsx
@@ -2,15 +2,15 @@ import {
View,
Text,
StyleSheet
-} from 'react-native';
-import { FC } from 'react';
+} from 'react-native'
+import { FC } from 'react'
interface Props {
- percent: number,
+ percent: number
}
export const Percent: FC = (props) => {
- const { percent } = props;
+ const { percent } = props
return (
@@ -34,7 +34,7 @@ const styles = StyleSheet.create({
borderTopWidth: 27,
borderRightColor: 'transparent',
borderTopColor: '#AAEF00',
- transform: [{ rotate: '90deg' }],
+ transform: [{ rotate: '90deg' }]
},
text: {
width: 40,
@@ -43,6 +43,6 @@ const styles = StyleSheet.create({
fontSize: 10,
transform: [{ rotate: '-40deg' }],
top: -34,
- left: 7,
- },
+ left: 7
+ }
})
diff --git a/app/components/screens/services/ServiceItem/ServiceItem.tsx b/app/components/screens/services/ServiceItem/ServiceItem.tsx
index 4ef0597..07698d3 100644
--- a/app/components/screens/services/ServiceItem/ServiceItem.tsx
+++ b/app/components/screens/services/ServiceItem/ServiceItem.tsx
@@ -1,17 +1,17 @@
-import { View, Text, StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { IService } from '../../../../typedefs/typedefs';
-import { MaterialIcons } from '@expo/vector-icons';
-import { Percent } from './Percent';
-import { LinearGradient } from 'expo-linear-gradient';
-import { getRandomGradient } from '../../../../utils/getRandomGradient';
+import { View, Text, StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { IService } from '../../../../typedefs/typedefs'
+import { MaterialIcons } from '@expo/vector-icons'
+import { Percent } from './Percent'
+import { LinearGradient } from 'expo-linear-gradient'
+import { getRandomGradient } from '../../../../utils/getRandomGradient'
interface Props {
- service: IService,
+ service: IService
}
export const ServiceItem: FC = (props) => {
- const { service } = props;
+ const { service } = props
return (
@@ -37,7 +37,7 @@ export const ServiceItem: FC = (props) => {
const styles = StyleSheet.create({
container: {
- marginBottom: 16,
+ marginBottom: 16
},
item: {
borderRadius: 12,
diff --git a/app/components/screens/services/Services.tsx b/app/components/screens/services/Services.tsx
index 2c94e3c..edfc9bd 100644
--- a/app/components/screens/services/Services.tsx
+++ b/app/components/screens/services/Services.tsx
@@ -1,18 +1,15 @@
import {
View,
- Text,
StyleSheet
-} from 'react-native';
-import { FC } from 'react';
-import { Layout } from '../../../components/layout/Layout';
-import { services } from './data';
-import { ServiceItem } from './ServiceItem/ServiceItem';
+} from 'react-native'
+import { FC } from 'react'
+import { Layout } from '../../../components/layout/Layout'
+import { services } from './data'
+import { ServiceItem } from './ServiceItem/ServiceItem'
export const Services: FC = () => {
return (
- Lviv
-
{services.map(service => (
{
- const { user } = useAuth();
- const [message, setMessage] = useState('');
+ const { user } = useAuth()
+ const [message, setMessage] = useState('')
+ const [isKeyPress, setIsKeyPress] = useState(false)
+
+ const handleChangeKeyPress = useCallback(() => {
+ setIsKeyPress((prevState) => !prevState)
+ }, [])
const handleSendMessage = async () => {
try {
await addDoc(collection(db, 'messages'), {
timestamp: serverTimestamp(),
userId: user?.uid,
- text: message,
+ text: message
})
-
} catch (error: any) {
Alert.alert('Error add new message', error.message)
}
- setMessage('');
- };
+ setMessage('')
+ }
return (
-
+
@@ -58,17 +64,16 @@ const styles = StyleSheet.create({
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
- paddingVertical: 4,
- bottom: 40
+ paddingVertical: 4
},
input: {
backgroundColor: '#f7fafc',
borderRadius: 16,
padding: 12,
width: '83.333333%',
- height: 40,
+ height: 40
},
icon: {
- color: '#A7F3D0',
+ color: '#A7F3D0'
}
})
diff --git a/app/components/screens/support/Header/Header.tsx b/app/components/screens/support/Header/Header.tsx
index 7f7309f..bc17c17 100644
--- a/app/components/screens/support/Header/Header.tsx
+++ b/app/components/screens/support/Header/Header.tsx
@@ -3,7 +3,7 @@ import {
Text,
StyleSheet,
Image
-} from 'react-native';
+} from 'react-native'
export const Header = () => {
return (
@@ -27,7 +27,7 @@ const styles = StyleSheet.create({
alignItems: 'center',
paddingVertical: 4,
marginBottom: 8,
- marginTop: 16,
+ marginTop: 16
},
icon: {
height: 60,
@@ -41,5 +41,5 @@ const styles = StyleSheet.create({
textH4: {
fontFamily: 'mt-light',
fontSize: 14
- },
+ }
})
diff --git a/app/components/screens/support/Message/Message.tsx b/app/components/screens/support/Message/Message.tsx
index 4f51afe..ed3597f 100644
--- a/app/components/screens/support/Message/Message.tsx
+++ b/app/components/screens/support/Message/Message.tsx
@@ -2,28 +2,28 @@ import {
View,
Text,
StyleSheet
-} from 'react-native';
-import { FC } from 'react';
-import { IMessage } from '../../../../typedefs/typedefs';
-import { useAuth } from '../../../../hooks/useAuth';
+} from 'react-native'
+import { FC } from 'react'
+import { IMessage } from '../../../../typedefs/typedefs'
+import { useAuth } from '../../../../hooks/useAuth'
interface Props {
- message: IMessage,
+ message: IMessage
}
export const Message: FC = (props) => {
- const { message } = props;
+ const { message } = props
- const { user } = useAuth();
+ const { user } = useAuth()
- const isMessageByAuthUser = user?.uid === message.userId;
+ const isMessageByAuthUser = user?.uid === message.userId
return (
{
- const { messages } = useMessages();
+ const { messages } = useMessages()
return (
diff --git a/app/components/ui/Avatar.tsx b/app/components/ui/Avatar.tsx
index 04682ee..be2e036 100644
--- a/app/components/ui/Avatar.tsx
+++ b/app/components/ui/Avatar.tsx
@@ -1,25 +1,26 @@
-import { View, StyleSheet, Text } from 'react-native';
-import { FC } from 'react';
-import { IAvatar } from '../../typedefs/typedefs';
+import { View, StyleSheet, Image, TouchableWithoutFeedback } from 'react-native'
+import { FC } from 'react'
+import { IAvatar } from '../../typedefs/typedefs'
export const Avatar: FC = (props) => {
- const { name, size = 'small' } = props;
+ const { size = 'small', icon, onChangeAvatar } = props
- const isSmall = size === 'small';
+ const isSmall = size === 'small'
return (
-
- {name?.slice(0, 1)}
-
+ {icon && (
+ { onChangeAvatar ? onChangeAvatar(icon) : '' }}>
+
+
+ )}
)
}
@@ -35,5 +36,10 @@ const styles = StyleSheet.create({
text: {
color: 'white',
fontWeight: '800'
+ },
+ image: {
+ width: '100%',
+ height: '100%',
+ borderRadius: 50
}
})
diff --git a/app/components/ui/Button.tsx b/app/components/ui/Button.tsx
index 1fd25ac..5a2dd33 100644
--- a/app/components/ui/Button.tsx
+++ b/app/components/ui/Button.tsx
@@ -2,16 +2,16 @@ import {
Text,
TouchableHighlight,
StyleSheet
-} from 'react-native';
-import { FC } from 'react';
-import { IButton } from '../../typedefs/typedefs';
+} from 'react-native'
+import { FC } from 'react'
+import { IButton } from '../../typedefs/typedefs'
export const Button: FC = (props) => {
const {
title,
onPress,
- colors = ['yellow', '#FBBF24'],
- } = props;
+ colors = ['yellow', '#FBBF24']
+ } = props
return (
= (props) => {
const {
@@ -11,9 +11,9 @@ export const Field: FC = (props) => {
isSecure,
keyboardType,
onChangeSecure
- } = props;
+ } = props
- const isVisible = isSecure !== undefined;
+ const isVisible = isSecure !== undefined
return (
@@ -38,13 +38,13 @@ export const Field: FC = (props) => {
/>
)}
- );
-};
+ )
+}
const styles = StyleSheet.create({
inputContainer: {
flexDirection: 'row',
- alignItems: 'center',
+ alignItems: 'center'
},
input: {
position: 'relative',
@@ -53,12 +53,12 @@ const styles = StyleSheet.create({
backgroundColor: '#EDF2EF',
marginTop: 15,
padding: 15,
- flex: 1,
+ flex: 1
},
icon: {
marginLeft: 10,
position: 'absolute',
top: '50%',
right: 20
- },
-});
+ }
+})
diff --git a/app/components/ui/Heading.tsx b/app/components/ui/Heading.tsx
index 05496be..a600bbf 100644
--- a/app/components/ui/Heading.tsx
+++ b/app/components/ui/Heading.tsx
@@ -1,14 +1,14 @@
-import { Text, StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { Padding } from '../../components/ui/Padding';
+import { Text, StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { Padding } from '../../components/ui/Padding'
interface Props {
- text: string,
- isCenter?: boolean,
+ text: string
+ isCenter?: boolean
}
export const Heading: FC = (props) => {
- const { isCenter = false, text } = props;
+ const { isCenter = false, text } = props
return (
@@ -26,6 +26,6 @@ export const Heading: FC = (props) => {
const styles = StyleSheet.create({
text: {
fontSize: 26,
- fontWeight: 'bold',
+ fontWeight: 'bold'
}
})
diff --git a/app/components/ui/Loader.tsx b/app/components/ui/Loader.tsx
index 3a72820..c830526 100644
--- a/app/components/ui/Loader.tsx
+++ b/app/components/ui/Loader.tsx
@@ -1,5 +1,5 @@
-import { View, Text, ActivityIndicator } from 'react-native';
-import { FC } from 'react';
+import { ActivityIndicator } from 'react-native'
+import { FC } from 'react'
export const Loader: FC = () => {
return (
diff --git a/app/components/ui/ModalWindow.tsx b/app/components/ui/ModalWindow.tsx
index c780f64..86ac8ea 100644
--- a/app/components/ui/ModalWindow.tsx
+++ b/app/components/ui/ModalWindow.tsx
@@ -1,17 +1,18 @@
-import { Dispatch, FC, SetStateAction } from 'react';
-import { Modal, View, StyleSheet } from 'react-native';
-import { Field } from '../../components/ui/Field';
-import { Button } from '../../components/ui/Button';
+import React, { Dispatch, FC, SetStateAction } from 'react'
+import { Modal, View, StyleSheet } from 'react-native'
+import { Field } from '../../components/ui/Field'
+import { Button } from '../../components/ui/Button'
interface Props {
- needTwo?: boolean,
- showModal: boolean,
- setShowModal: (value: boolean) => void,
- cardNumber?: string,
- setCardNumber?: Dispatch>,
- transferAmount: string,
- setTransferAmount: Dispatch>,
- handleTransferConfirm: () => void,
+ needTwo?: boolean
+ showModal: boolean
+ setShowModal: (value: boolean) => void
+ cardNumber?: string
+ setCardNumber?: Dispatch>
+ transferAmount: string
+ setTransferAmount: Dispatch>
+ handleTransferConfirm: () => void
+ handleCardNumberChange: (text: string) => void
}
export const ModalWindow: FC = (props) => {
@@ -20,11 +21,11 @@ export const ModalWindow: FC = (props) => {
showModal,
cardNumber,
setShowModal,
- setCardNumber,
transferAmount,
setTransferAmount,
handleTransferConfirm,
- } = props;
+ handleCardNumberChange
+ } = props
return (
@@ -32,8 +33,8 @@ export const ModalWindow: FC = (props) => {
{needTwo && (
)}
@@ -51,7 +52,10 @@ export const ModalWindow: FC = (props) => {
-
@@ -70,5 +74,5 @@ const styles = StyleSheet.create({
display: 'flex',
flexDirection: 'row',
gap: 10
- },
+ }
})
diff --git a/app/components/ui/ModifyAvatar.tsx b/app/components/ui/ModifyAvatar.tsx
new file mode 100644
index 0000000..3a15397
--- /dev/null
+++ b/app/components/ui/ModifyAvatar.tsx
@@ -0,0 +1,43 @@
+import { View, StyleSheet, Image } from 'react-native'
+import { FC } from 'react'
+import { IAvatar } from '../../typedefs/typedefs'
+
+export const ModifyAvatar: FC = (props) => {
+ const { size = 'small', icon } = props
+
+ const isSmall = size === 'small'
+
+ return (
+
+ {icon && (
+
+ )}
+
+ )
+}
+
+const styles = StyleSheet.create({
+ avatar: {
+ borderRadius: 50,
+ backgroundColor: '#D4D4D4',
+ marginRight: 12,
+ alignItems: 'center',
+ justifyContent: 'center'
+ },
+ text: {
+ color: 'white',
+ fontWeight: '800'
+ },
+ image: {
+ width: '100%',
+ height: '100%',
+ borderRadius: 50
+ }
+})
diff --git a/app/components/ui/Padding.tsx b/app/components/ui/Padding.tsx
index ca1ab7a..47e5475 100644
--- a/app/components/ui/Padding.tsx
+++ b/app/components/ui/Padding.tsx
@@ -1,17 +1,17 @@
-import { View, StyleSheet, ViewStyle } from 'react-native';
-import { FC, ReactNode } from 'react';
-import { SafeAreaView } from 'react-native-safe-area-context';
+import { StyleSheet, ViewStyle } from 'react-native'
+import { FC, ReactNode } from 'react'
+import { SafeAreaView } from 'react-native-safe-area-context'
interface Props {
- children?: ReactNode,
- style?: ViewStyle,
+ children?: ReactNode
+ style?: ViewStyle
}
export const Padding: FC = (props) => {
- const { children, style } = props;
+ const { children, style } = props
return (
-
+
{children}
)
@@ -20,6 +20,6 @@ export const Padding: FC = (props) => {
const styles = StyleSheet.create({
main: {
paddingLeft: 16,
- paddingRight: 16,
- },
+ paddingRight: 16
+ }
})
diff --git a/app/components/ui/PasswordSettings.tsx b/app/components/ui/PasswordSettings.tsx
index d0a6d23..384ad5d 100644
--- a/app/components/ui/PasswordSettings.tsx
+++ b/app/components/ui/PasswordSettings.tsx
@@ -3,13 +3,13 @@ import {
TextInput,
View,
StyleSheet
-} from 'react-native';
-import { FC } from 'react';
+} from 'react-native'
+import { FC } from 'react'
interface Props {
- isCondition: boolean,
- condition: string,
- handleChange: () => void,
+ isCondition: boolean
+ condition: string
+ handleChange: () => void
}
export const PasswordSettings: FC = (props) => {
@@ -17,7 +17,7 @@ export const PasswordSettings: FC = (props) => {
isCondition,
condition,
handleChange
- } = props;
+ } = props
return (
@@ -28,7 +28,7 @@ export const PasswordSettings: FC = (props) => {
@@ -39,7 +39,7 @@ const styles = StyleSheet.create({
item: {
width: '100%',
flexDirection: 'row',
- paddingHorizontal: 20,
+ paddingHorizontal: 20
},
input: {
fontFamily: 'mt-light',
@@ -47,6 +47,6 @@ const styles = StyleSheet.create({
backgroundColor: '#EDF2EF',
marginTop: 10,
padding: 10,
- flex: 1,
- },
+ flex: 1
+ }
})
diff --git a/app/components/ui/SubHeading.tsx b/app/components/ui/SubHeading.tsx
index 7c75636..1519ac4 100644
--- a/app/components/ui/SubHeading.tsx
+++ b/app/components/ui/SubHeading.tsx
@@ -1,13 +1,13 @@
-import { Text, StyleSheet } from 'react-native';
-import { FC } from 'react';
-import { Padding } from '../../components/ui/Padding';
+import { Text, StyleSheet } from 'react-native'
+import { FC } from 'react'
+import { Padding } from '../../components/ui/Padding'
interface Props {
- text: string,
+ text: string
}
export const SubHeading: FC = (props) => {
- const { text } = props;
+ const { text } = props
return (
@@ -18,8 +18,7 @@ export const SubHeading: FC = (props) => {
const styles = StyleSheet.create({
text: {
- marginTop: 20,
fontSize: 22,
- fontWeight: 'bold',
+ fontWeight: 'bold'
}
})
diff --git a/app/hooks/useAccounts.ts b/app/hooks/useAccounts.ts
index 73070f6..6445071 100644
--- a/app/hooks/useAccounts.ts
+++ b/app/hooks/useAccounts.ts
@@ -1,25 +1,25 @@
-import { useEffect, useState } from 'react';
-import { IAccount } from '../typedefs/typedefs';
-import { onSnapshot, query, collection, orderBy, where } from '@firebase/firestore';
-import { db } from '../utils/firebase';
-import { useAuth } from '../hooks/useAuth';
+import { useEffect, useState } from 'react'
+import { IAccount } from '../typedefs/typedefs'
+import { onSnapshot, query, collection, where } from '@firebase/firestore'
+import { db } from '../utils/firebase'
+import { useAuth } from '../hooks/useAuth'
export const useAccounts = () => {
- const { user } = useAuth();
+ const { user } = useAuth()
- const [accounts, setAccounts] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
+ const [accounts, setAccounts] = useState([])
+ const [isLoading, setIsLoading] = useState(true)
useEffect(() => onSnapshot(query(collection(db, 'accounts'),
- where('userId', '==', user?.uid)),
- snapshot => {
- setAccounts(snapshot.docs.map(el => ({
- _id: el.id,
- ...el.data()
- }) as IAccount))
+ where('userId', '==', user?.uid)),
+ snapshot => {
+ setAccounts(snapshot.docs.map(el => ({
+ _id: el.id,
+ ...el.data()
+ }) as IAccount))
- setIsLoading(false);
- }), [])
+ setIsLoading(false)
+ }), [])
return {
accounts,
diff --git a/app/hooks/useAuth.ts b/app/hooks/useAuth.ts
index 04e2578..b2c80e0 100644
--- a/app/hooks/useAuth.ts
+++ b/app/hooks/useAuth.ts
@@ -1,4 +1,4 @@
-import { useContext } from 'react';
-import { AuthContext } from '../providers/AuthProvider';
+import { useContext } from 'react'
+import { AuthContext } from '../providers/AuthProvider'
-export const useAuth = () => useContext(AuthContext);
+export const useAuth = () => useContext(AuthContext)
diff --git a/app/hooks/useContacts.ts b/app/hooks/useContacts.ts
index d2c1d6a..2c53d68 100644
--- a/app/hooks/useContacts.ts
+++ b/app/hooks/useContacts.ts
@@ -1,20 +1,20 @@
-import { useEffect, useState } from 'react';
-import { IContact, IProfile } from '../typedefs/typedefs';
-import { useAuth } from './useAuth';
+import { useEffect, useState } from 'react'
+import { IContact, IProfile } from '../typedefs/typedefs'
+import { useAuth } from './useAuth'
import {
collection,
getDocs,
onSnapshot,
query,
where
-} from '@firebase/firestore';
-import { db } from '../utils/firebase';
+} from '@firebase/firestore'
+import { db } from '../utils/firebase'
export const useContacts = () => {
- const [contacts, setContacts] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
+ const [contacts, setContacts] = useState([])
+ const [isLoading, setIsLoading] = useState(true)
- const { user } = useAuth();
+ const { user } = useAuth()
useEffect(() => {
onSnapshot(
@@ -23,41 +23,43 @@ export const useContacts = () => {
const contactsFire = await Promise.all(
snapshot.docs.map(async (d) => {
const data = d.data() as IContact & {
- userId: string;
- };
+ userId: string
+ }
- let displayName = '';
+ let displayName = ''
+ let avatar = ''
const q = query(
collection(db, 'users'),
where('_id', '==', data.userId)
- );
+ )
- const querySnapshot = await getDocs(q);
+ const querySnapshot = await getDocs(q)
querySnapshot.forEach((doc) => {
- displayName = (doc.data() as IProfile).displayName;
- });
+ displayName = (doc.data() as IProfile).displayName
+ avatar = (doc.data() as IProfile).avatar
+ })
return {
...data,
_id: d.id,
displayName,
- };
+ avatar
+ }
})
- );
+ )
setContacts(contactsFire.filter((v, i, a) => (
a.findIndex(t => t.displayName === v.displayName) === i
- )).filter(i => i.displayName));
+ )).filter(i => i.displayName))
- setIsLoading(false);
+ setIsLoading(false)
}
- );
- }, []);
+ )
+ }, [])
return {
contacts,
- isLoading,
- };
-};
-
+ isLoading
+ }
+}
diff --git a/app/hooks/useData.ts b/app/hooks/useData.ts
index a5ab403..40c7c02 100644
--- a/app/hooks/useData.ts
+++ b/app/hooks/useData.ts
@@ -1,4 +1,4 @@
-import { useContext } from 'react';
-import { DataContext } from '../providers/DataProvider';
+import { useContext } from 'react'
+import { DataContext } from '../providers/DataProvider'
-export const useData = () => useContext(DataContext);
+export const useData = () => useContext(DataContext)
diff --git a/app/hooks/useFonts.ts b/app/hooks/useFonts.ts
index ee13bee..21570e3 100644
--- a/app/hooks/useFonts.ts
+++ b/app/hooks/useFonts.ts
@@ -1,42 +1,41 @@
-import * as Font from 'expo-font';
-import * as SplashScreen from 'expo-splash-screen';
-import { useEffect, useState } from 'react';
+import * as Font from 'expo-font'
+import * as SplashScreen from 'expo-splash-screen'
+import { useEffect, useState } from 'react'
export const useFonts = () => {
- const [fontLoaded, setFontLoaded] = useState(false);
+ const [fontLoaded, setFontLoaded] = useState(false)
const loadFonts = async () => {
try {
await Font.loadAsync({
'mt-bold': require('../../assets/fonts/Montserrat-Bold.ttf'),
- 'mt-light': require('../../assets/fonts/Montserrat-Light.ttf'),
- });
+ 'mt-light': require('../../assets/fonts/Montserrat-Light.ttf')
+ })
} catch (error) {
- console.log(error);
+ console.log(error)
}
- };
-
+ }
useEffect(() => {
const loadApp = async () => {
try {
- await SplashScreen.preventAutoHideAsync();
- await loadFonts();
+ await SplashScreen.preventAutoHideAsync()
+ await loadFonts()
- setFontLoaded(true);
+ setFontLoaded(true)
- await SplashScreen.hideAsync();
+ await SplashScreen.hideAsync()
} catch (error) {
- console.log(error);
+ console.log(error)
}
};
(async () => {
- await loadApp();
- })();
- }, []);
+ await loadApp()
+ })()
+ }, [])
return {
- fontLoaded,
+ fontLoaded
}
}
diff --git a/app/hooks/useGeneratePassword.ts b/app/hooks/useGeneratePassword.ts
index 22e6851..41fcbd6 100644
--- a/app/hooks/useGeneratePassword.ts
+++ b/app/hooks/useGeneratePassword.ts
@@ -1,4 +1,4 @@
-import { useContext } from 'react';
-import { GeneratePasswordContext } from '../providers/GeneratePasswordProvider';
+import { useContext } from 'react'
+import { GeneratePasswordContext } from '../providers/GeneratePasswordProvider'
-export const useGeneratePassword = () => useContext(GeneratePasswordContext);
+export const useGeneratePassword = () => useContext(GeneratePasswordContext)
diff --git a/app/hooks/useMessages.ts b/app/hooks/useMessages.ts
index 58fa82b..72b6730 100644
--- a/app/hooks/useMessages.ts
+++ b/app/hooks/useMessages.ts
@@ -1,33 +1,34 @@
-import { useEffect, useState } from 'react';
-import { IMessage } from '../typedefs/typedefs';
-import { onSnapshot, query, collection, orderBy } from '@firebase/firestore';
-import { db } from '../utils/firebase';
-import dayjs from 'dayjs';
+import { useEffect, useState } from 'react'
+import { IMessage } from '../typedefs/typedefs'
+import { onSnapshot, query, collection, orderBy } from '@firebase/firestore'
+import { db } from '../utils/firebase'
+import dayjs from 'dayjs'
export const useMessages = () => {
- const [messages, setMessages] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
+ const [messages, setMessages] = useState([])
+ const [isLoading, setIsLoading] = useState(true)
useEffect(() => onSnapshot(
query(collection(db, 'messages'), orderBy('timestamp', 'asc')),
snapshot => {
setMessages(snapshot.docs.map(d =>
- d.data()?.timestamp ? (
- {
- _id: d.id,
- ...d.data(),
- timestamp: dayjs.unix(d.data().timestamp.seconds).format('HH:mm'),
- } as IMessage
- ) : (
- {
- _id: d.id,
- ...d.data(),
- } as IMessage
- )
- ));
- setIsLoading(false);
- }), []);
-
+ d.data()?.timestamp
+ ? (
+ {
+ _id: d.id,
+ ...d.data(),
+ timestamp: dayjs.unix(d.data().timestamp.seconds).format('HH:mm')
+ } as IMessage
+ )
+ : (
+ {
+ _id: d.id,
+ ...d.data()
+ } as IMessage
+ )
+ ))
+ setIsLoading(false)
+ }), [])
return {
messages,
diff --git a/app/hooks/usePassword.ts b/app/hooks/usePassword.ts
index a58b73b..a94b9f9 100644
--- a/app/hooks/usePassword.ts
+++ b/app/hooks/usePassword.ts
@@ -1,5 +1,5 @@
-import { PasswordsType } from '../typedefs/typedefs';
-import { useGeneratePassword } from '../hooks/useGeneratePassword';
+import { PasswordsType } from '../typedefs/typedefs'
+import { useGeneratePassword } from '../hooks/useGeneratePassword'
export const usePassword = () => {
const {
@@ -10,8 +10,8 @@ export const usePassword = () => {
handleChangeUpperInput,
handleChangeLowerInput,
handleChangeNumbersInput,
- handleChangeSpecialCharsInput,
- } = useGeneratePassword();
+ handleChangeSpecialCharsInput
+ } = useGeneratePassword()
const passwordSettings: PasswordsType[] = [
{
@@ -34,9 +34,9 @@ export const usePassword = () => {
condition: '1234567890',
handleChange: handleChangeNumbersInput
}
- ];
+ ]
return {
- passwordSettings,
- };
+ passwordSettings
+ }
}
diff --git a/app/hooks/useProfile.ts b/app/hooks/useProfile.ts
index cfd7790..78a1a5d 100644
--- a/app/hooks/useProfile.ts
+++ b/app/hooks/useProfile.ts
@@ -1,40 +1,51 @@
-import { useEffect, useMemo, useState } from 'react';
-import { useAuth } from '../hooks/useAuth';
+import { useEffect, useMemo, useState } from 'react'
+import { useAuth } from '../hooks/useAuth'
import {
limit,
onSnapshot,
query,
where,
collection
-} from '@firebase/firestore';
-import { db } from '../utils/firebase';
-import { IProfile } from '../typedefs/typedefs';
+} from '@firebase/firestore'
+import { db } from '../utils/firebase'
+import { IProfile } from '../typedefs/typedefs'
export const useProfile = () => {
- const [isLoading, setIsLoading] = useState(true);
- const [profile, setProfile] = useState({} as IProfile);
- const [name, setName] = useState('');
+ const [isLoading, setIsLoading] = useState(true)
+ const [profile, setProfile] = useState({} as IProfile)
+ const [name, setName] = useState('')
+ const [realAvatar, setRealAvatar] = useState('')
- const { user } = useAuth();
+ const { user } = useAuth()
useEffect(() => onSnapshot(query(collection(db, 'users'),
where('_id', '==', user?.uid), limit(1)), snapshot => {
- const profile = snapshot.docs.map(el => ({
- ...(el.data() as IProfile),
- docId: el.id
- }))[0]
+ const profile = snapshot.docs.map(el => ({
+ ...(el.data() as IProfile),
+ docId: el.id
+ }))[0]
- setProfile(profile);
- setName(profile.displayName);
- setIsLoading(false);
+ setProfile(profile)
+ setName(profile.displayName)
+ setIsLoading(false)
+ setRealAvatar(profile.avatar)
}), [])
const value = useMemo(() => ({
+ realAvatar,
+ setRealAvatar,
profile,
isLoading,
name,
setName
- }), [profile, isLoading, name, setName])
+ }), [
+ profile,
+ isLoading,
+ name,
+ setName,
+ realAvatar,
+ setRealAvatar
+ ])
- return value;
+ return value
}
diff --git a/app/hooks/useSendMoney.ts b/app/hooks/useSendMoney.ts
new file mode 100644
index 0000000..7a57047
--- /dev/null
+++ b/app/hooks/useSendMoney.ts
@@ -0,0 +1,41 @@
+import { asyncAlert } from '../components/screens/home/apply-new-product/asyncAlert'
+import { Alert } from 'react-native'
+import { useState } from 'react'
+import { TypeName } from '../typedefs/typedefs'
+
+export const useSendMoney = () => {
+ const [showModal, setShowModal] = useState(false)
+ const [cardName, setCardName] = useState({} as TypeName)
+
+ const handleTransferPress = () => {
+ setShowModal(true)
+ }
+
+ const sendMoney = async () => {
+ try {
+ const cardType = await asyncAlert({
+ title: 'Credit cards',
+ message: 'Select card:',
+ buttons: {
+ text: 'Mono Black',
+ resolveValue: 'Mono Black',
+ textSecond: 'Mono White',
+ resolveValueSecond: 'Mono White'
+ }
+ })
+
+ setCardName(cardType as TypeName)
+ handleTransferPress()
+ } catch (error: any) {
+ Alert.alert('Error selecting', error.message)
+ }
+ }
+
+ return {
+ showModal,
+ setShowModal,
+ cardName,
+ setCardName,
+ sendMoney
+ }
+}
diff --git a/app/hooks/useStories.ts b/app/hooks/useStories.ts
index d616758..d636ef8 100644
--- a/app/hooks/useStories.ts
+++ b/app/hooks/useStories.ts
@@ -1,21 +1,21 @@
-import { useEffect, useState } from 'react';
-import { IStory } from '../typedefs/typedefs';
-import { onSnapshot, query, collection, orderBy } from '@firebase/firestore';
-import { db } from '../utils/firebase';
+import { useEffect, useState } from 'react'
+import { IStory } from '../typedefs/typedefs'
+import { onSnapshot, query, collection } from '@firebase/firestore'
+import { db } from '../utils/firebase'
export const useStories = () => {
- const [stories, setStories] = useState([]);
- const [isLoading, setIsLoading] = useState(true);
+ const [stories, setStories] = useState([])
+ const [isLoading, setIsLoading] = useState(true)
useEffect(() => onSnapshot(query(collection(db, 'stories')),
- snapshot => {
- setStories(snapshot.docs.map(el => ({
- _id: el.id,
- ...el.data()
- }) as IStory))
+ snapshot => {
+ setStories(snapshot.docs.map(el => ({
+ _id: el.id,
+ ...el.data()
+ }) as IStory))
- setIsLoading(false);
- }), [])
+ setIsLoading(false)
+ }), [])
return {
stories,
diff --git a/app/hooks/useTimer.ts b/app/hooks/useTimer.ts
index a846413..e98b5e0 100644
--- a/app/hooks/useTimer.ts
+++ b/app/hooks/useTimer.ts
@@ -1,23 +1,23 @@
-import { useEffect } from 'react';
+import { useEffect } from 'react'
interface Options {
- isClicked: boolean,
- setIsClicked: (value: boolean) => void,
- delay: number,
+ isClicked: boolean
+ setIsClicked: (value: boolean) => void
+ delay: number
}
export const useTimer = (options: Options) => {
- const { setIsClicked, isClicked, delay } = options;
+ const { setIsClicked, isClicked, delay } = options
useEffect(() => {
- let timer: NodeJS.Timeout;
+ let timer: NodeJS.Timeout
if (isClicked) {
timer = setTimeout(() => {
- setIsClicked(false);
- }, delay);
+ setIsClicked(false)
+ }, delay)
}
- return () => clearTimeout(timer);
- }, [delay, isClicked, setIsClicked]);
-};
+ return () => { clearTimeout(timer) }
+ }, [delay, isClicked, setIsClicked])
+}
diff --git a/app/hooks/useUpdateProfile.ts b/app/hooks/useUpdateProfile.ts
index 45ab056..9e588b2 100644
--- a/app/hooks/useUpdateProfile.ts
+++ b/app/hooks/useUpdateProfile.ts
@@ -1,44 +1,45 @@
-import { useAuth } from '../hooks/useAuth';
-import { useState } from 'react';
-import { db } from '../utils/firebase';
-import { doc, updateDoc } from '@firebase/firestore';
-import { Alert } from 'react-native';
+import { useAuth } from '../hooks/useAuth'
+import { useState } from 'react'
+import { db } from '../utils/firebase'
+import { doc, DocumentReference, updateDoc } from '@firebase/firestore'
+import { Alert } from 'react-native'
-export const useUpdateProfile = (name: string, docId: string) => {
- const { user } = useAuth();
+export const useUpdateProfile = (name: string, realAvatar: string, docId: string) => {
+ const { user } = useAuth()
- const [isLoading, setIsLoading] = useState(false);
- const [isSuccess, setIsSuccess] = useState(false);
+ const [isLoading, setIsLoading] = useState(false)
+ const [isSuccess, setIsSuccess] = useState(false)
const updateProfile = async () => {
- setIsLoading(true);
+ setIsLoading(true)
if (!user) {
- return;
+ return
}
try {
- const docRef = doc(db, 'users', docId);
+ const docRef = doc(db, 'users', docId)
await updateDoc(docRef, {
displayName: name,
- })
+ avatar: realAvatar
+ } as DocumentReference<{ displayName: string, avatar: string }>)
- setIsSuccess(true);
+ setIsSuccess(true)
setTimeout(() => {
- setIsLoading(false);
- setIsSuccess(false);
- }, 3000);
+ setIsLoading(false)
+ setIsSuccess(false)
+ }, 3000)
} catch (error: any) {
- Alert.alert('Error update profile', error.message);
+ Alert.alert('Error update profile', error.message)
} finally {
- setIsLoading(false);
+ setIsLoading(false)
}
}
return {
isLoading,
isSuccess,
- updateProfile,
+ updateProfile
}
}
diff --git a/app/navigation/Navigation.tsx b/app/navigation/Navigation.tsx
index 165c97d..192e982 100644
--- a/app/navigation/Navigation.tsx
+++ b/app/navigation/Navigation.tsx
@@ -1,60 +1,76 @@
-import { FC, useEffect, useState } from 'react';
-import { createStackNavigator } from '@react-navigation/stack';
-import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
-import { useAuth } from '../hooks/useAuth';
-import { Auth } from '../components/screens/auth/Auth';
-import { Services } from '../components/screens/services/Services';
-import { More } from '../components/screens/more/More';
-import { Support } from '../components/screens/support/support';
-import { Payments } from '../components/screens/payments/Payments';
-import { Home } from '../components/screens/home/Home';
-import { Profile } from '../components/screens/profile/Profile';
-import { Footer } from '../components/layout/footer/Footer';
+import { FC, useEffect, useState } from 'react'
+import { createStackNavigator } from '@react-navigation/stack'
+import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native'
+import { useAuth } from '../hooks/useAuth'
+import { Auth } from '../components/screens/auth/Auth'
+import { Services } from '../components/screens/services/Services'
+import { More } from '../components/screens/more/More'
+import { Support } from '../components/screens/support/support'
+import { Payments } from '../components/screens/payments/Payments'
+import { Home } from '../components/screens/home/Home'
+import { Profile } from '../components/screens/profile/Profile'
+import { Footer } from '../components/layout/footer/Footer'
-const Stack = createStackNavigator();
+const Stack = createStackNavigator()
export const Navigation: FC = () => {
- const [name, setName] = useState(undefined);
+ const [name, setName] = useState(undefined)
- const { user } = useAuth();
- const ref = useNavigationContainerRef();
+ const { user } = useAuth()
+ const ref = useNavigationContainerRef()
useEffect(() => {
- const timeout = setTimeout(() => setName(
- ref.getCurrentRoute()?.name
- ), 100)
+ const timeout = setTimeout(() => {
+ setName(
+ ref.getCurrentRoute()?.name
+ )
+ }, 100)
- return () => clearTimeout(timeout);
+ return () => { clearTimeout(timeout) }
}, [])
useEffect(() => {
- const listener = ref.addListener('state', () => setName(
- ref.getCurrentRoute()?.name,
- ))
+ const listener = ref.addListener('state', () => {
+ setName(
+ ref.getCurrentRoute()?.name
+ )
+ })
return () => {
- ref.removeListener('state', listener);
+ ref.removeListener('state', listener)
}
}, [])
return (
<>
-
- {user ? (
+
+ {user
+ ? (
<>
-
-
+
+
+
+
+
>
- ) : (
+ )
+ : (
- )
- }
+ )}
@@ -65,5 +81,5 @@ export const Navigation: FC = () => {
/>
)}
>
- );
+ )
}
diff --git a/app/navigation/types.ts b/app/navigation/types.ts
index 1337cd7..f880ee8 100644
--- a/app/navigation/types.ts
+++ b/app/navigation/types.ts
@@ -1,4 +1,4 @@
-export type TypeRootStackParamList = {
+export interface TypeRootStackParamList {
Auth: undefined
Home: undefined
Profile: undefined
diff --git a/app/providers/AuthProvider.tsx b/app/providers/AuthProvider.tsx
index 7e01914..269cdc7 100644
--- a/app/providers/AuthProvider.tsx
+++ b/app/providers/AuthProvider.tsx
@@ -1,11 +1,10 @@
-import { createContext, useEffect, useMemo, useState, ReactNode } from 'react';
-import firebase from 'firebase/compat';
-import User = firebase.User;
-import { Alert } from 'react-native';
-import { auth, db, login, logout, register } from '../utils/firebase';
-import { collection, addDoc } from 'firebase/firestore';
-import { onAuthStateChanged } from 'firebase/auth';
-import { FC } from 'react';
+import { createContext, useEffect, useMemo, useState, ReactNode, FC } from 'react'
+import firebase from 'firebase/compat'
+import User = firebase.User
+import { Alert } from 'react-native'
+import { auth, db, login, logout, register } from '../utils/firebase'
+import { collection, addDoc } from 'firebase/firestore'
+import { onAuthStateChanged } from 'firebase/auth'
interface IContext {
user: User | null
@@ -18,72 +17,73 @@ interface IContext {
export const AuthContext = createContext({} as IContext)
export const AuthProvider: FC<{ children: ReactNode }> = ({ children }) => {
- const [user, setUser] = useState(null);
- const [isLoadingInitial, setIsLoadingInitial] = useState(true);
- const [isLoading, setIsLoading] = useState(false);
+ const [user, setUser] = useState(null)
+ const [isLoadingInitial, setIsLoadingInitial] = useState(true)
+ const [isLoading, setIsLoading] = useState(false)
const registerHandler = async (email: string, password: string) => {
- setIsLoading(true);
+ setIsLoading(true)
try {
- const { user } = await register(email, password);
-
+ const { user } = await register(email, password)
+ // @ts-expect-error
await addDoc(collection(db, 'users'), {
_id: user.uid,
- displayName: 'Noname'
+ displayName: 'Noname',
+ avatar: 'https://static-00.iconduck.com/assets.00/user-avatar-icon-512x512-vufpcmdn.png'
})
} catch (error: any) {
Alert.alert('Error reg:', error.message)
} finally {
- setIsLoading(false);
+ setIsLoading(false)
}
}
const loginHandler = async (email: string, password: string) => {
- setIsLoading(true);
+ setIsLoading(true)
try {
- await login(email, password);
+ await login(email, password)
} catch (error: any) {
Alert.alert('Error login:', error.message)
} finally {
- setIsLoading(false);
+ setIsLoading(false)
}
}
const logoutHandler = async () => {
- setIsLoading(true);
+ setIsLoading(true)
try {
- await logout();
+ await logout()
} catch (error: any) {
Alert.alert('Error logout:', error)
} finally {
- setIsLoading(false);
+ setIsLoading(false)
}
}
useEffect(() => {
const unsubscribe = onAuthStateChanged(auth, (user) => {
- setUser(user as User);
+ setUser(user as User)
- setIsLoadingInitial(false);
- });
+ setIsLoadingInitial(false)
+ })
- return unsubscribe;
- }, []);
+ return unsubscribe
+ }, [])
const value = useMemo(() => ({
user,
isLoading,
login: loginHandler,
logout: logoutHandler,
- register: registerHandler,
+ register: registerHandler
}), [user, isLoading])
return (
{!isLoadingInitial && children}
- );
+ )
}
diff --git a/app/providers/DataProvider.tsx b/app/providers/DataProvider.tsx
index 2876954..d0a7131 100644
--- a/app/providers/DataProvider.tsx
+++ b/app/providers/DataProvider.tsx
@@ -6,18 +6,18 @@ import {
SetStateAction,
useMemo,
useState
-} from 'react';
-import { ActiveStories } from '../typedefs/typedefs';
+} from 'react'
+import { ActiveStories } from '../typedefs/typedefs'
interface IContext {
- activeStories: ActiveStories | null,
+ activeStories: ActiveStories | null
setActiveStories: Dispatch>
}
-export const DataContext = createContext({} as IContext);
+export const DataContext = createContext({} as IContext)
export const DataProvider: FC<{ children: ReactNode }> = ({ children }) => {
- const [activeStories, setActiveStories] = useState(null);
+ const [activeStories, setActiveStories] = useState(null)
const value = useMemo(() => ({
activeStories, setActiveStories
diff --git a/app/providers/GeneratePasswordProvider.tsx b/app/providers/GeneratePasswordProvider.tsx
index 207e9e1..f12ce98 100644
--- a/app/providers/GeneratePasswordProvider.tsx
+++ b/app/providers/GeneratePasswordProvider.tsx
@@ -5,69 +5,68 @@ import {
useCallback,
useMemo,
useState
-} from 'react';
-import { generatePassword } from '../utils/generatePassword';
-import { useTimer } from '../hooks/useTimer';
+} from 'react'
+import { generatePassword } from '../utils/generatePassword'
+import { useTimer } from '../hooks/useTimer'
export interface IContext {
- password: string,
- isClicked: boolean,
- isNumbers: boolean,
- isUpperLetters: boolean,
- isLowerLetters: boolean,
- isSpecialChars: boolean,
- isModalVisible: boolean,
- createNewPassword: () => void,
- handleChangeNumbersInput: () => void,
- handleChangeUpperInput: () => void,
- handleChangeLowerInput: () => void,
- handleChangeModalVisible: (v?: boolean) => void,
- handleChangeSpecialCharsInput: () => void,
+ password: string
+ isClicked: boolean
+ isNumbers: boolean
+ isUpperLetters: boolean
+ isLowerLetters: boolean
+ isSpecialChars: boolean
+ isModalVisible: boolean
+ createNewPassword: () => void
+ handleChangeNumbersInput: () => void
+ handleChangeUpperInput: () => void
+ handleChangeLowerInput: () => void
+ handleChangeModalVisible: (v?: boolean) => void
+ handleChangeSpecialCharsInput: () => void
}
-export const GeneratePasswordContext = createContext({} as IContext);
+export const GeneratePasswordContext = createContext({} as IContext)
export const GeneratePasswordProvider: FC<{ children: ReactNode }> = ({ children }) => {
- const [isModalVisible, setIsModalVisible] = useState(false);
- const [isUpperLetters, setIsUpperLetters] = useState(true);
- const [isLowerLetters, setIsLowerLetters] = useState(true);
- const [isSpecialChars, setIsSpecialChars] = useState(true);
- const [isNumbers, setIsNumbers] = useState(true);
- const [password, setPassword] = useState('');
- const [isClicked, setIsClicked] = useState(false);
+ const [isModalVisible, setIsModalVisible] = useState(false)
+ const [isUpperLetters, setIsUpperLetters] = useState(true)
+ const [isLowerLetters, setIsLowerLetters] = useState(true)
+ const [isSpecialChars, setIsSpecialChars] = useState(true)
+ const [isNumbers, setIsNumbers] = useState(true)
+ const [password, setPassword] = useState('')
+ const [isClicked, setIsClicked] = useState(false)
-
- const delay = 1000;
- useTimer({isClicked, setIsClicked, delay });
+ const delay = 1000
+ useTimer({ isClicked, setIsClicked, delay })
const createNewPassword = useCallback(() => {
- const generate = generatePassword(10, isUpperLetters, isLowerLetters, isNumbers, isSpecialChars);
+ const generate = generatePassword(10, isUpperLetters, isLowerLetters, isNumbers, isSpecialChars)
- setPassword(generate);
- }, [isUpperLetters, isLowerLetters, isSpecialChars, isNumbers]);
+ setPassword(generate)
+ }, [isUpperLetters, isLowerLetters, isSpecialChars, isNumbers])
- const handleChangeModalVisible = useCallback((confirm : boolean = false) => {
- setIsModalVisible((prevState) => !prevState);
+ const handleChangeModalVisible = useCallback((confirm: boolean = false) => {
+ setIsModalVisible((prevState) => !prevState)
if (confirm) {
- setIsClicked(true);
+ setIsClicked(true)
}
- }, []);
+ }, [])
const handleChangeUpperInput = useCallback(() => {
- setIsUpperLetters((prevState) => !prevState);
- }, [isUpperLetters]);
+ setIsUpperLetters((prevState) => !prevState)
+ }, [isUpperLetters])
const handleChangeLowerInput = useCallback(() => {
- setIsLowerLetters((prevState) => !prevState);
- }, [isLowerLetters]);
+ setIsLowerLetters((prevState) => !prevState)
+ }, [isLowerLetters])
const handleChangeSpecialCharsInput = useCallback(() => {
- setIsSpecialChars((prevState => !prevState))
+ setIsSpecialChars(prevState => !prevState)
}, [isSpecialChars])
const handleChangeNumbersInput = useCallback(() => {
- setIsNumbers((prevState => !prevState))
+ setIsNumbers(prevState => !prevState)
}, [isNumbers])
const value = useMemo(() => ({
@@ -83,7 +82,7 @@ export const GeneratePasswordProvider: FC<{ children: ReactNode }> = ({ children
handleChangeLowerInput,
handleChangeModalVisible,
handleChangeNumbersInput,
- handleChangeSpecialCharsInput,
+ handleChangeSpecialCharsInput
}), [
password,
isNumbers,
@@ -91,12 +90,12 @@ export const GeneratePasswordProvider: FC<{ children: ReactNode }> = ({ children
isUpperLetters,
isLowerLetters,
isSpecialChars,
- isModalVisible,
- ]);
+ isModalVisible
+ ])
return (
{children}
- );
+ )
}
diff --git a/app/typedefs/typedefs.ts b/app/typedefs/typedefs.ts
index abef140..c04dbe2 100644
--- a/app/typedefs/typedefs.ts
+++ b/app/typedefs/typedefs.ts
@@ -1,131 +1,139 @@
-import { AntDesign } from '@expo/vector-icons';
-import { TypeRootStackParamList } from '../navigation/types';
-import { KeyboardTypeOptions } from 'react-native';
-import { MaterialIcons } from '@expo/vector-icons';
+import { AntDesign, MaterialIcons } from '@expo/vector-icons'
+import { TypeRootStackParamList } from '../navigation/types'
+import { KeyboardTypeOptions } from 'react-native'
export type TypeName = 'Mono Black' | 'Mono White'
export type TypeCurrency = 'UAH' | 'USD' | 'EUR' | 'PLN'
export interface IStory {
- _id: string,
- heading: string,
+ _id: string
+ heading: string
images: string[]
}
export interface IData {
- email: string,
- password: string,
+ email: string
+ password: string
}
export interface IAvatar {
- name?: string | null,
- size: 'small' | 'large',
+ name?: string | null
+ size: 'small' | 'large'
+ icon?: string
+ onChangeAvatar?: (uri: string | undefined) => void
}
export interface IButton {
- onPress: () => void,
- title: string,
- colors?: [string, string],
+ onPress: () => void
+ title: string
+ colors?: [string, string]
}
export interface IField {
- onChange?: (val: string) => void,
- val?: string,
- placeholder: string,
- isSecure?: boolean,
- keyboardType?: KeyboardTypeOptions | undefined,
- onChangeSecure?: () => void,
+ onChange?: (val: string) => void
+ val?: string
+ placeholder: string
+ isSecure?: boolean
+ keyboardType?: KeyboardTypeOptions | undefined
+ onChangeSecure?: () => void
}
export interface IProfile {
- _id: string,
- displayName: string,
+ _id: string
+ displayName: string
docId: string
+ avatar: string
}
export interface ActiveStories {
- _id: string,
- heading: string,
- images: string[],
+ _id: string
+ heading: string
+ images: string[]
}
export interface IAccount {
- _id: string,
- userId: string,
- balance: number,
- cardNumber: string,
+ _id: string
+ userId: string
+ balance: number
+ cardNumber: string
currency: TypeCurrency
name: TypeName
}
export interface IButtons {
- text: string,
- resolveValue: string,
- textSecond: string,
- resolveValueSecond: string,
+ text: string
+ resolveValue: string
+ textSecond: string
+ resolveValueSecond: string
}
export interface IAsyncAlert {
- title: string,
- message?: string,
- buttons: IButtons,
+ title: string
+ message?: string
+ buttons: IButtons
}
export interface IFooterItem {
- iconName: keyof typeof AntDesign.glyphMap,
- title: keyof TypeRootStackParamList,
+ iconName: keyof typeof AntDesign.glyphMap
+ title: keyof TypeRootStackParamList
+}
+
+export interface Avatar {
+ id: number
+ avatar: string
}
export interface IContact {
- _id: string,
- displayName: string,
- cardNumber: string,
+ _id: string
+ displayName: string
+ cardNumber: string
+ avatar: string
}
export interface PasswordsType {
- isCondition: boolean,
- condition: string,
- handleChange: () => void,
+ isCondition: boolean
+ condition: string
+ handleChange: () => void
}
export interface IService {
- iconName: keyof typeof MaterialIcons.glyphMap,
- title: string,
- percent: number,
+ iconName: keyof typeof MaterialIcons.glyphMap
+ title: string
+ percent: number
}
export interface IMessage {
- _id: string,
- text: string,
- userId: string,
- timestamp: any,
+ _id: string
+ text: string
+ userId: string
+ timestamp: any
}
export interface IMoreItem {
- title: string,
- description: string,
- iconName: keyof typeof MaterialIcons.glyphMap,
+ title: string
+ description: string
+ iconName: keyof typeof MaterialIcons.glyphMap
link: string
}
export interface Base {
- currencyCodeA: number,
- currencyCodeB: number,
- date: number,
- rateBuy: number,
- rateCross: number,
+ currencyCodeA: number
+ currencyCodeB: number
+ date: number
+ rateBuy: number
+ rateCross: number
rateSell: number
}
export interface Rates {
- USD: number,
- EUR: number,
- PLN: number,
+ USD: number
+ EUR: number
+ PLN: number
UAH: number
}
export interface IOtherItem extends Pick {
- title: string,
+ title: string
}
export interface IIcon extends Pick {}
diff --git a/app/utils/convertCurrency.ts b/app/utils/convertCurrency.ts
index 934d2d6..fe0b6a6 100644
--- a/app/utils/convertCurrency.ts
+++ b/app/utils/convertCurrency.ts
@@ -1,50 +1,47 @@
-import { TypeCurrency } from '../typedefs/typedefs';
+import { TypeCurrency } from '../typedefs/typedefs'
export const getCurrencyCode = (currency: TypeCurrency): number => {
switch (currency) {
case 'USD':
- return 840;
+ return 840
case 'UAH':
- return 980;
+ return 980
case 'EUR':
- return 978;
+ return 978
case 'PLN':
- return 985;
+ return 985
default:
- throw new Error('Невідома валюта');
+ throw new Error('Невідома валюта')
}
-};
+}
const findExchangeRate = (data: any, fromCurrency: TypeCurrency, toCurrency: TypeCurrency) => {
- const currencyCodeA = getCurrencyCode(fromCurrency);
- const currencyCodeB = getCurrencyCode(toCurrency);
-
- for(const item of data) {
- if ((item.currencyCodeA === currencyCodeA || item.currencyCodeA === currencyCodeB)
- && (item.currencyCodeB === currencyCodeA || item.currencyCodeB === currencyCodeB)) {
+ const currencyCodeA = getCurrencyCode(fromCurrency)
+ const currencyCodeB = getCurrencyCode(toCurrency)
- return item.rateSell;
+ for (const item of data) {
+ if ((item.currencyCodeA === currencyCodeA || item.currencyCodeA === currencyCodeB) &&
+ (item.currencyCodeB === currencyCodeA || item.currencyCodeB === currencyCodeB)) {
+ return item.rateSell
}
}
- return null;
+ return null
}
export const convertCurrency = async (amount: number, fromCurrency: TypeCurrency, toCurrency: TypeCurrency) => {
- const response = await fetch('https://api.monobank.ua/bank/currency');
+ const response = await fetch('https://api.monobank.ua/bank/currency')
- const data = await response.json();
- const exchangeRate = findExchangeRate(data, fromCurrency, toCurrency);
+ const data = await response.json()
+ const exchangeRate = findExchangeRate(data, fromCurrency, toCurrency)
if (fromCurrency === 'USD' && toCurrency === 'UAH') {
-
- return amount * exchangeRate;
+ return amount * exchangeRate
}
if (fromCurrency === 'UAH' && toCurrency === 'USD') {
-
- return amount / exchangeRate;
+ return amount / exchangeRate
}
- return amount;
-};
+ return amount
+}
diff --git a/app/utils/firebase.ts b/app/utils/firebase.ts
index d8fb296..ab7ae56 100644
--- a/app/utils/firebase.ts
+++ b/app/utils/firebase.ts
@@ -1,33 +1,32 @@
-import { initializeApp } from "firebase/app";
+import { initializeApp } from 'firebase/app'
import {
getAuth,
signOut,
signInWithEmailAndPassword,
- createUserWithEmailAndPassword,
-} from "firebase/auth";
-import { getFirestore } from "@firebase/firestore";
+ createUserWithEmailAndPassword
+} from 'firebase/auth'
+import { getFirestore } from '@firebase/firestore'
const firebaseConfig = {
- apiKey: "AIzaSyAjuZz0fcQu7lBdkHGL4UBtu9wNPlP-pcs",
- authDomain: "bankapp-a4be8.firebaseapp.com",
- projectId: "bankapp-a4be8",
- storageBucket: "bankapp-a4be8.appspot.com",
- messagingSenderId: "252339679582",
- appId: "1:252339679582:web:2a9f622f35f41d0e081fcf",
- measurementId: "G-Q6J5N0GLPQ"
-};
+ apiKey: 'AIzaSyAjuZz0fcQu7lBdkHGL4UBtu9wNPlP-pcs',
+ authDomain: 'bankapp-a4be8.firebaseapp.com',
+ projectId: 'bankapp-a4be8',
+ storageBucket: 'bankapp-a4be8.appspot.com',
+ messagingSenderId: '252339679582',
+ appId: '1:252339679582:web:2a9f622f35f41d0e081fcf',
+ measurementId: 'G-Q6J5N0GLPQ'
+}
-initializeApp(firebaseConfig);
+initializeApp(firebaseConfig)
-export const auth = getAuth();
+export const auth = getAuth()
-export const register = (email: string, password: string) =>
- createUserWithEmailAndPassword(auth, email, password);
+export const register = async (email: string, password: string) =>
+ await createUserWithEmailAndPassword(auth, email, password)
-export const login = (email: string, password: string) =>
- signInWithEmailAndPassword(auth, email, password);
+export const login = async (email: string, password: string) =>
+ await signInWithEmailAndPassword(auth, email, password)
-export const logout = () => signOut(auth);
-
-export const db = getFirestore();
+export const logout = async () => { await signOut(auth) }
+export const db = getFirestore()
diff --git a/app/utils/generatePassword.ts b/app/utils/generatePassword.ts
index 485237d..45877e9 100644
--- a/app/utils/generatePassword.ts
+++ b/app/utils/generatePassword.ts
@@ -3,35 +3,35 @@ export const generatePassword = (
includeUpperCase: boolean,
includeLowerCase: boolean,
includeNumbers: boolean,
- includeSpecialChars: boolean,
+ includeSpecialChars: boolean
) => {
- let charset = '';
- let password = '';
+ let charset = ''
+ let password = ''
if (includeUpperCase) {
- charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
+ charset += 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
}
if (includeLowerCase) {
- charset += 'abcdefghijklmnopqrstuvwxyz';
+ charset += 'abcdefghijklmnopqrstuvwxyz'
}
if (includeNumbers) {
- charset += '0123456789';
+ charset += '0123456789'
}
if (includeSpecialChars) {
- charset += '!@#$%^&*';
+ charset += '!@#$%^&*'
}
if (charset === '') {
- return 'At least one character set must be included.';
+ return 'At least one character set must be included.'
}
for (let i = 0; i < length; i++) {
- let randomIndex = Math.floor(Math.random() * charset.length);
- password += charset.charAt(randomIndex);
+ const randomIndex = Math.floor(Math.random() * charset.length)
+ password += charset.charAt(randomIndex)
}
- return password;
+ return password
}
diff --git a/app/utils/getRandomCardNumber.ts b/app/utils/getRandomCardNumber.ts
index bbedafa..003229d 100644
--- a/app/utils/getRandomCardNumber.ts
+++ b/app/utils/getRandomCardNumber.ts
@@ -1,11 +1,11 @@
export const getRandomCardNumber = () => {
- const firstDigit = Math.floor(Math.random() * 10);
- let otherDigits = "";
+ const firstDigit = Math.floor(Math.random() * 10)
+ let otherDigits = ''
for (let i = 0; i < 15; i++) {
- otherDigits += Math.floor(Math.random() * 10);
+ otherDigits += Math.floor(Math.random() * 10)
}
- let creditCardNumber = firstDigit + otherDigits;
- return creditCardNumber.replace(/(\d{4})(?=\d)/g, '$1 ');
+ const creditCardNumber = firstDigit + otherDigits
+ return creditCardNumber.replace(/(\d{4})(?=\d)/g, '$1 ')
}
diff --git a/app/utils/getRandomGradient.ts b/app/utils/getRandomGradient.ts
index f5ae46e..cad9aa8 100644
--- a/app/utils/getRandomGradient.ts
+++ b/app/utils/getRandomGradient.ts
@@ -10,14 +10,14 @@ const gradients = [
['#FF4270', '#FE0040'],
['#F641AE', '#C11B80'],
['#D74339', '#B9271D'],
- ['#FFBE01', '#FE5A00'],
+ ['#FFBE01', '#FE5A00']
]
export const getRandomGradient = () => {
- const min = 0;
- const max = gradients.length - 1;
+ const min = 0
+ const max = gradients.length - 1
- const randomNumber = Math.floor(Math.random() * (max - min) + min);
+ const randomNumber = Math.floor(Math.random() * (max - min) + min)
- return gradients[randomNumber];
+ return gradients[randomNumber]
}
diff --git a/app/utils/styles.ts b/app/utils/styles.ts
index 09ebd73..3b92d32 100644
--- a/app/utils/styles.ts
+++ b/app/utils/styles.ts
@@ -2,9 +2,9 @@ export const BOX_SHADOW = {
shadowColor: '#000',
shadowOffset: {
width: 0,
- height: 2,
+ height: 2
},
shadowOpacity: 0.15,
shadowRadius: 10,
- elevation: 5,
+ elevation: 5
}
diff --git a/package.json b/package.json
index e9ced49..e4412a0 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
"@ant-design/icons-react-native": "^2.3.2",
"@firebase/auth": "^0.23.2",
"@firebase/firestore": "^3.12.1",
+ "@react-native-community/blur": "^4.3.2",
"@react-native-picker/picker": "^2.4.10",
"@react-navigation/native": "^6.1.6",
"@react-navigation/native-stack": "^6.9.12",
@@ -20,6 +21,7 @@
"axios": "^1.4.0",
"dayjs": "^1.11.7",
"expo": "~48.0.15",
+ "expo-blur": "~12.2.2",
"expo-font": "^11.1.1",
"expo-linear-gradient": "~12.1.2",
"expo-splash-screen": "^0.18.2",
@@ -27,6 +29,8 @@
"firebase": "^9.22.1",
"react": "18.2.0",
"react-native": "0.71.8",
+ "react-native-image-picker": "^5.6.0",
+ "react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-safe-area-context": "4.5.0",
"react-native-screens": "~3.20.0",
"react-native-stories-view": "^1.0.9",
@@ -37,8 +41,15 @@
"@babel/core": "^7.20.0",
"@types/react": "~18.0.14",
"@types/react-native-vector-icons": "^6.4.13",
+ "@typescript-eslint/eslint-plugin": "^5.60.1",
+ "eslint": "^8.43.0",
+ "eslint-config-standard-with-typescript": "^35.0.0",
+ "eslint-plugin-import": "^2.27.5",
+ "eslint-plugin-n": "^15.7.0",
+ "eslint-plugin-promise": "^6.1.1",
+ "eslint-plugin-react": "^7.32.2",
"react-native-checkbox": "^2.0.0",
- "typescript": "^4.9.4"
+ "typescript": "^5.1.5"
},
"private": true
}