├── AsyncStorage ├── constants │ └── themes.js ├── navigation │ └── navigation.js └── screens │ ├── home.js │ └── login.js ├── Background └── App.js ├── BottomTabNavigator ├── navigation │ └── navigation.js └── screens │ ├── React.js │ └── ReactNavi.js ├── Chat App ├── README.md ├── components │ ├── bar.js │ └── chatItem.js ├── constants │ └── theme.js ├── navigation │ └── navigation.js └── screens │ ├── Home │ ├── discussions.js │ ├── friends.js │ └── profile.js │ ├── Login │ ├── login.js │ └── register.js │ └── conversation.js ├── Credit Card Input └── App.js ├── Dark Mode └── App.js ├── Google APIs └── search.js ├── Job App ├── App.js ├── README.md └── src │ ├── components │ ├── header.js │ └── jobCard.js │ ├── constants │ └── lightTheme.js │ ├── images │ ├── Etikks.jpg │ ├── Interise.jpg │ ├── blueLogo.png │ ├── docBackground.png │ └── whiteLogo.png │ └── screens │ ├── doc.js │ ├── home.js │ ├── jobPage.js │ ├── login.js │ ├── notifications.js │ ├── profile.js │ └── register.js ├── README.md ├── Simple Calculator ├── calcul.js └── theme.js └── Swiper └── App.js /AsyncStorage/constants/themes.js: -------------------------------------------------------------------------------- 1 | const colors = { 2 | white: '#ffffff', 3 | black: '#000000', 4 | blue: '#3498db' 5 | }; 6 | 7 | export { 8 | colors 9 | }; -------------------------------------------------------------------------------- /AsyncStorage/navigation/navigation.js: -------------------------------------------------------------------------------- 1 | import {createStackNavigator, createAppContainer, createSwitchNavigator} from 'react-navigation'; 2 | import React, {Component} from 'react'; 3 | import { View, ActivityIndicator } from 'react-native'; 4 | import AsyncStorage from '@react-native-community/async-storage'; 5 | 6 | import Home from '../screens/home'; 7 | import Login from '../screens/login'; 8 | 9 | class Loading extends Component { 10 | constructor(props) { 11 | super(props); 12 | this.getEmail(); 13 | } 14 | 15 | getEmail = async () => { 16 | const Email = await AsyncStorage.getItem('Email'); 17 | this.props.navigation.navigate(Email ? 'App' : 'Auth'); 18 | } 19 | render() { 20 | return( 21 | 22 | 23 | 24 | ) 25 | } 26 | } 27 | 28 | const LoginScreen = createStackNavigator({ 29 | Login: { 30 | screen: Login, 31 | navigationOptions: { 32 | header: null 33 | } 34 | }, 35 | }); 36 | 37 | const HomeScreen = createStackNavigator({ 38 | Home: { 39 | screen: Home, 40 | navigationOptions: { 41 | header: null 42 | } 43 | }, 44 | }); 45 | 46 | const NaveScreen = createSwitchNavigator( 47 | { 48 | AuthLoading: Loading, 49 | App: HomeScreen, 50 | Auth: LoginScreen 51 | }, 52 | { 53 | initialRouteName: 'AuthLoading', 54 | } 55 | ); 56 | 57 | export default createAppContainer(NaveScreen); 58 | -------------------------------------------------------------------------------- /AsyncStorage/screens/home.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, StyleSheet, Text, TouchableOpacity} from 'react-native'; 3 | import * as theme from '../constants/themes'; 4 | import AsyncStorage from '@react-native-community/async-storage'; 5 | 6 | export default class Home extends Component { 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | _logOut = async () => { 12 | try { 13 | AsyncStorage.removeItem('Email'); 14 | this.props.navigation.navigate('Login'); 15 | } 16 | catch(error) { 17 | alert(error); 18 | } 19 | } 20 | 21 | render() { 22 | return ( 23 | 24 | Hi 25 | this._logOut()}> 26 | Log Out 27 | 28 | 29 | ); 30 | } 31 | } 32 | 33 | const styles = StyleSheet.create({ 34 | container: { 35 | flex: 1, 36 | backgroundColor: theme.colors.blue, 37 | alignItems: 'center', 38 | justifyContent: 'center' 39 | }, 40 | emailTxt: { 41 | color: theme.colors.white, 42 | fontWeight: 'bold' 43 | }, 44 | btnContainer: { 45 | backgroundColor: theme.colors.white, 46 | padding: 15, 47 | marginTop: 10, 48 | borderRadius: 10, 49 | alignItems: 'center', 50 | justifyContent: 'center' 51 | }, 52 | btnTxt: { 53 | color: theme.colors.blue, 54 | fontWeight: 'bold', 55 | }, 56 | }); 57 | -------------------------------------------------------------------------------- /AsyncStorage/screens/login.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, StyleSheet, Image, Text, TextInput, TouchableOpacity} from 'react-native'; 3 | import * as theme from '../constants/themes'; 4 | import AsyncStorage from '@react-native-community/async-storage'; 5 | 6 | export default class Login extends Component { 7 | constructor(props) { 8 | super(props); 9 | this.state = { 10 | email: '', 11 | password: '', 12 | } 13 | } 14 | 15 | _storateData = async () => { 16 | try { 17 | await AsyncStorage.setItem('Email', this.state.email); 18 | } 19 | catch(error) { 20 | alert(error); 21 | } 22 | } 23 | 24 | _login() { 25 | const { email, password } = this.state; 26 | const correctEmail = 'contact@blaiti.com'; 27 | const correctPassword = 'blaiti'; 28 | 29 | if (email.length != 0 && password.length != 0) { 30 | if (email == correctEmail && password == correctPassword) { 31 | this._storateData(); 32 | this.props.navigation.navigate('Home'); 33 | } 34 | else { 35 | alert('Wrong informations !'); 36 | } 37 | } 38 | else { 39 | alert('Missing informations !'); 40 | } 41 | } 42 | 43 | render() { 44 | return ( 45 | 46 | 47 | 50 | 51 | 52 | this.setState({email})} /> 57 | 58 | this.setState({password})} /> 64 | 65 | this._login()}> 66 | Login 67 | 68 | 69 | 70 | Heve an account? 71 | Forget password? 72 | 73 | 74 | 75 | ); 76 | } 77 | } 78 | 79 | const styles = StyleSheet.create({ 80 | container: { 81 | flex: 1, 82 | backgroundColor: theme.colors.blue, 83 | }, 84 | logoContainer: { 85 | flex: 1, 86 | alignItems: 'center', 87 | justifyContent: 'center' 88 | }, 89 | formContainer: { 90 | flex: 2, 91 | padding: 10 92 | }, 93 | inputTxt: { 94 | backgroundColor: theme.colors.white, 95 | padding: 10, 96 | fontWeight: 'bold', 97 | marginBottom: 15, 98 | borderRadius: 10, 99 | color: theme.colors.blue 100 | }, 101 | btnContainer: { 102 | backgroundColor: theme.colors.white, 103 | padding: 15, 104 | marginTop: 10, 105 | borderRadius: 10, 106 | alignItems: 'center', 107 | justifyContent: 'center' 108 | }, 109 | btnTxt: { 110 | color: theme.colors.blue, 111 | fontWeight: 'bold', 112 | }, 113 | bottomTxtContainer: { 114 | flexDirection: 'row', 115 | justifyContent: 'space-between', 116 | marginTop: 10 117 | }, 118 | bottomTxt: { 119 | color: theme.colors.white, 120 | fontWeight: 'bold' 121 | } 122 | }); 123 | -------------------------------------------------------------------------------- /Background/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, ImageBackground } from 'react-native'; 3 | 4 | export default class App extends React.Component { 5 | render() { 6 | return ( 7 | 8 | 9 | { 10 | // Gradient Color Background 11 | } 12 | {data.map((_, i) => ( 13 | 26 | ))} 27 | 28 | { 29 | // Image Background 30 | } 31 | 34 | 35 | 36 | 37 | ); 38 | } 39 | }; 40 | 41 | const styles = StyleSheet.create({ 42 | container: { 43 | flex: 1, 44 | } 45 | }); 46 | -------------------------------------------------------------------------------- /BottomTabNavigator/navigation/navigation.js: -------------------------------------------------------------------------------- 1 | import {createBottomTabNavigator, createAppContainer} from 'react-navigation'; 2 | import * as theme from '../constants/themes'; 3 | import React from 'react'; 4 | import { Icon } from 'react-native-elements'; 5 | 6 | 7 | // import screens 8 | import ReactHome from '../screens/React'; 9 | import ReactNav from '../screens/ReactNavi'; 10 | 11 | // create bottom rab 12 | const ScreenBottom = createBottomTabNavigator({ 13 | ReactHome: { 14 | screen: ReactHome, 15 | navigationOptions: { 16 | tabBarIcon:({ tintColor }) =>( 17 | 18 | ) 19 | } 20 | }, 21 | ReactNav: { 22 | screen: ReactNav, 23 | navigationOptions: { 24 | tabBarIcon:({ tintColor }) =>( 25 | 26 | ) 27 | } 28 | }, 29 | }, 30 | { 31 | tabBarOptions: { 32 | activeBackground: theme.colors.white, 33 | inactiveBackground: theme.colors.white, 34 | activeTintColor: theme.colors.blue, 35 | inactiveTintColor: theme.colors.gray, 36 | showLabel: false, 37 | showIcon: true 38 | } 39 | }); 40 | 41 | export default createAppContainer(ScreenBottom); 42 | 43 | -------------------------------------------------------------------------------- /BottomTabNavigator/screens/React.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Image, StyleSheet} from 'react-native'; 3 | import * as theme from '../constants/themes'; 4 | 5 | export default class ReactHome extends Component { 6 | render() { 7 | return ( 8 | 9 | 12 | 13 | ); 14 | } 15 | } 16 | 17 | const styles = StyleSheet.create({ 18 | container: { 19 | flex: 1, 20 | alignItems: 'center', 21 | justifyContent: 'center', 22 | backgroundColor: theme.colors.white, 23 | }, 24 | img: { 25 | width: 150, 26 | height: 150 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /BottomTabNavigator/screens/ReactNavi.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import {View, Image, StyleSheet} from 'react-native'; 3 | import * as theme from '../constants/themes'; 4 | 5 | export default class ReactNav extends Component { 6 | render() { 7 | return ( 8 | 9 | 12 | 13 | ); 14 | } 15 | } 16 | 17 | const styles = StyleSheet.create({ 18 | container: { 19 | flex: 1, 20 | alignItems: 'center', 21 | justifyContent: 'center', 22 | backgroundColor: theme.colors.white, 23 | }, 24 | img: { 25 | width: 150, 26 | height: 150 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /Chat App/README.md: -------------------------------------------------------------------------------- 1 | # React-Native 2 | 3 | A chat app using React Native. 4 | 5 | The necessary libraries: 6 | - react-native-gesture-handler 7 | - react-native-elements 8 | - react-navigation 9 | - react-native-vector-icons 10 | -------------------------------------------------------------------------------- /Chat App/components/bar.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View } from 'react-native'; 3 | import * as theme from '../constants/theme'; 4 | 5 | export default class Bar extends React.Component { 6 | render() { 7 | return ( 8 | 9 | 10 | ); 11 | } 12 | } 13 | 14 | const styles = StyleSheet.create({ 15 | container: { 16 | padding:0.5, 17 | backgroundColor: theme.colors.silver, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /Chat App/components/chatItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Text } from 'react-native'; 3 | import { Avatar } from 'react-native-elements'; 4 | import * as theme from '../constants/theme'; 5 | 6 | export default class ChatItem extends React.Component { 7 | ShowAvatar(message) { 8 | if (message.author.id == 1) { 9 | return 10 | } 11 | else { 12 | return ( 13 | 16 | ) 17 | } 18 | } 19 | render() { 20 | const message = this.props.message; 21 | const userID = message.author.id == 1; 22 | const textContainerExtra = userID ? styles.textContainerRight : styles.textContainerLeft; 23 | return ( 24 | 25 | {this.ShowAvatar(message)} 26 | 27 | 28 | {message.text} 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | const styles = StyleSheet.create({ 36 | messageContainer: { 37 | flexDirection: 'row', 38 | padding: 20 39 | }, 40 | textContainer: { 41 | borderRadius: 5, 42 | flex: 1, 43 | paddingHorizontal: 10, 44 | paddingVertical: 5, 45 | marginLeft: 10, 46 | marginRight: 10 47 | }, 48 | textContainerLeft: { 49 | alignItems: 'flex-start', 50 | backgroundColor: theme.colors.silver 51 | }, 52 | textContainerRight: { 53 | alignItems: 'flex-end', 54 | backgroundColor: theme.colors.blueBaby 55 | }, 56 | message: { 57 | fontSize: 16, 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /Chat App/constants/theme.js: -------------------------------------------------------------------------------- 1 | const colors = { 2 | white: '#ffffff', 3 | black: '#000000', 4 | silver: '#bdc3c7', 5 | lightBlack:'#212529', 6 | blueAzure: '#4c82de', 7 | blueBaby: '#9dbafd', 8 | blueElectronic: '#a9e4f0', 9 | } 10 | 11 | export { 12 | colors, 13 | } -------------------------------------------------------------------------------- /Chat App/navigation/navigation.js: -------------------------------------------------------------------------------- 1 | // import React and react native 2 | import React, {Component} from 'react'; 3 | import { View, ActivityIndicator } from 'react-native'; 4 | import { Icon } from 'react-native-elements'; 5 | 6 | // import theme 7 | import * as theme from '../constants/theme'; 8 | 9 | // import react navigation 10 | import { createAppContainer, createBottomTabNavigator, createStackNavigator } from 'react-navigation'; 11 | 12 | // import login screens 13 | import Login from '../screens/Login/login'; 14 | import Register from '../screens/Login/register'; 15 | 16 | // create login navigator 17 | const LoginScreens = createStackNavigator({ 18 | Login: { 19 | screen: Login, 20 | navigationOptions: { 21 | header: null 22 | } 23 | }, 24 | Register: { 25 | screen: Register, 26 | navigationOptions: { 27 | header: null 28 | } 29 | }, 30 | }); 31 | 32 | // import home screens 33 | import Discussions from '../screens/Home/discussions'; 34 | import Friends from '../screens/Home/friends'; 35 | import Profile from '../screens/Home/profile'; 36 | 37 | // create home navigator 38 | const HomeScreens = createBottomTabNavigator({ 39 | Discussions: { 40 | screen: Discussions, 41 | navigationOptions: { 42 | tabBarIcon:({ tintColor }) => ( 43 | 44 | ) 45 | } 46 | }, 47 | Friends: { 48 | screen: Friends, 49 | navigationOptions: { 50 | tabBarIcon:({ tintColor }) => ( 51 | 52 | ) 53 | } 54 | }, 55 | Profile: { 56 | screen: Profile, 57 | navigationOptions: { 58 | tabBarIcon:({ tintColor }) => ( 59 | 60 | ) 61 | } 62 | } 63 | }, 64 | { 65 | tabBarOptions: { 66 | activeBackgroundColor: theme.colors.white, 67 | inactiveBackgroundColor: theme.colors.white, 68 | activeTintColor: theme.colors.lightBlack, 69 | inactiveTintColor: theme.colors.silver, 70 | showLabel: false, 71 | showIcon: true 72 | } 73 | }); 74 | 75 | // import other home screens 76 | import Conversation from '../screens/conversation'; 77 | 78 | const AppScreens = createStackNavigator({ 79 | HomeScreens: { 80 | screen: HomeScreens, 81 | navigationOptions: { 82 | header: null 83 | } 84 | }, 85 | Conversation: { 86 | screen: Conversation, 87 | navigationOptions: { 88 | header: null 89 | } 90 | }, 91 | }); 92 | 93 | // import Asyncstorage 94 | import AsyncStorage from '@react-native-community/async-storage'; 95 | 96 | class Loading extends Component { 97 | constructor(props) { 98 | super(props); 99 | this.getEmail(); 100 | } 101 | 102 | getEmail = async () => { 103 | const Email = await AsyncStorage.getItem('Email'); 104 | this.props.navigation.navigate(Email ? 'App' : 'Auth'); 105 | } 106 | render() { 107 | return( 108 | 109 | 110 | 111 | ) 112 | } 113 | } 114 | 115 | 116 | // create general navigator 117 | const NavigationScreens = createSwitchNavigator( 118 | { 119 | AuthLoading: Loading, 120 | App: AppScreens, 121 | Auth: LoginScreens 122 | }, 123 | { 124 | initialRouteName: 'AuthLoading', 125 | } 126 | ); 127 | 128 | export default createAppContainer(NavigationScreens); -------------------------------------------------------------------------------- /Chat App/screens/Home/discussions.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, ScrollView, Text } from 'react-native'; 3 | import * as theme from '../../constants/theme'; 4 | import { Header, ListItem } from 'react-native-elements'; 5 | import Bar from '../../components/bar'; 6 | 7 | const list = [ 8 | { 9 | name: 'User 1', 10 | username: 'User1', 11 | avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg', 12 | message: 'Hello !', 13 | }, 14 | { 15 | name: 'User 2', 16 | username: 'User2', 17 | avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg', 18 | message: 'Hello Skander !', 19 | }, 20 | { 21 | name: 'User 3', 22 | username: 'User3', 23 | avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg', 24 | message: 'Contacty is a mobile application that provides an instant messaging system.', 25 | }, 26 | { 27 | name: 'User 4', 28 | username: 'User4', 29 | avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg', 30 | message: 'Don\'t need to save your discussions.', 31 | }, 32 | ] 33 | 34 | export default class Messages extends React.Component { 35 | render() { 36 | return ( 37 | 38 |
44 | 45 | 46 | { 47 | list.map((l, i) => ( 48 | {l.name} 53 | } 54 | subtitle={l.message} 55 | onPress={() => this.props.navigation.navigate('Conversation', {name: l.name, avatar: l.avatar_url, message: l.message, username: l.username})} 56 | /> 57 | )) 58 | } 59 | 60 | 61 | ); 62 | } 63 | } 64 | 65 | const styles = StyleSheet.create({ 66 | container: { 67 | flex: 1, 68 | backgroundColor: theme.colors.white, 69 | }, 70 | messagesList: { 71 | flex:1, 72 | padding: 5 73 | } 74 | }); 75 | -------------------------------------------------------------------------------- /Chat App/screens/Home/friends.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, StyleSheet } from 'react-native'; 3 | import { Header, ListItem } from 'react-native-elements'; 4 | import Bar from '../../components/bar'; 5 | import * as theme from '../../constants/theme'; 6 | 7 | const friends = [ 8 | { 9 | name: 'User 1', 10 | avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg', 11 | subtitle: 'UX/UI Designer' 12 | }, 13 | { 14 | name: 'User 2', 15 | avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg', 16 | subtitle: 'Mobile Developer' 17 | }, 18 | ] 19 | 20 | export default class Friends extends React.Component { 21 | render() { 22 | return ( 23 | 24 |
30 | 31 | 32 | 33 | 34 | { 35 | friends.map((l, i) => ( 36 | 42 | )) 43 | } 44 | 45 | 46 | ); 47 | } 48 | }; 49 | 50 | const styles = StyleSheet.create({ 51 | container: { 52 | flex: 1, 53 | backgroundColor: theme.colors.white, 54 | }, 55 | friendsList: { 56 | flex:1, 57 | padding: 5 58 | } 59 | }); 60 | -------------------------------------------------------------------------------- /Chat App/screens/Home/profile.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Image, Text } from 'react-native'; 3 | import { Header, ListItem } from 'react-native-elements'; 4 | import Bar from '../../components/bar'; 5 | import * as theme from '../../constants/theme'; 6 | 7 | 8 | const list = [ 9 | { 10 | title: 'Account', 11 | icon: 'person' 12 | }, 13 | { 14 | title: 'Discussions', 15 | icon: 'message' 16 | }, 17 | { 18 | title: 'notifications', 19 | icon: 'notifications' 20 | }, 21 | { 22 | title: 'help', 23 | icon: 'error' 24 | }, 25 | { 26 | title: 'invite friends', 27 | icon: 'group-add' 28 | }, 29 | ] 30 | 31 | export default class Profile extends React.Component { 32 | render() { 33 | return ( 34 | 35 |
40 | 41 | 42 | 43 | 46 | 47 | Skander Blaiti 48 | @skanderblaiti 49 | 50 | 51 | 52 | 53 | { 54 | list.map((item, i) => ( 55 | 60 | )) 61 | } 62 | 63 | 64 | ); 65 | } 66 | } 67 | 68 | const styles = StyleSheet.create({ 69 | container: { 70 | flex: 1, 71 | backgroundColor: theme.colors.white, 72 | }, 73 | imageContainer: { 74 | flex: 2, 75 | alignItems: 'center', 76 | justifyContent: 'center', 77 | padding: 10, 78 | }, 79 | imageProfile: { 80 | height: 120, 81 | width: 120, 82 | borderRadius: 60, 83 | }, 84 | Name: { 85 | fontSize: 15, 86 | color: theme.colors.lightBlack, 87 | fontWeight: 'bold', 88 | textAlign: 'center', 89 | }, 90 | username: { 91 | fontSize: 11, 92 | color: theme.colors.silver, 93 | textAlign: 'center', 94 | }, 95 | userSettings: { 96 | flex: 4, 97 | } 98 | }); 99 | 100 | -------------------------------------------------------------------------------- /Chat App/screens/Login/login.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, TextInput, TouchableOpacity, Text, StyleSheet } from 'react-native'; 3 | import * as theme from '../../constants/theme'; 4 | 5 | export default class Login extends React.Component { 6 | constructor(props) { 7 | super(props); 8 | this.state = { 9 | email: '', 10 | password: '' 11 | } 12 | } 13 | 14 | Login() { 15 | const {email, password} = this.state 16 | if (email.length !== 0 && password.length !== 0) 17 | { 18 | this.props.navigation.navigate('HomeScreens'); 19 | } 20 | else { 21 | alert('Missing Data !'); 22 | } 23 | } 24 | 25 | render() { 26 | return ( 27 | 28 | this.passwordInput.focus()} 37 | onChangeText={(email) => this.setState({email})} /> 38 | 39 | this.passwordInput = input} 49 | onChangeText={(password) => this.setState({password})} /> 50 | 51 | this.Login()}> 52 | Login 53 | 54 | 55 | 56 | 57 | this.props.navigation.navigate('Register')}>Don't have an account? 58 | 59 | 60 | Forget password? 61 | 62 | 63 | 64 | ); 65 | } 66 | }; 67 | 68 | const styles = StyleSheet.create({ 69 | container: { 70 | flex: 1, 71 | backgroundColor: theme.colors.white, 72 | justifyContent: 'center', 73 | padding: 20 74 | }, 75 | inputForm: 76 | { 77 | backgroundColor: theme.colors.white, 78 | borderRadius: 10, 79 | padding: 10, 80 | color: theme.colors.lightBlack, 81 | fontSize: 15, 82 | marginBottom: 10, 83 | borderTopColor: theme.colors.lightBlack, 84 | borderTopWidth: 1, 85 | borderBottomColor: theme.colors.lightBlack, 86 | borderBottomWidth: 1, 87 | borderLeftColor: theme.colors.lightBlack, 88 | borderLeftWidth: 1, 89 | borderRightColor: theme.colors.lightBlack, 90 | borderRightWidth: 1, 91 | }, 92 | loginButton: 93 | { 94 | backgroundColor: theme.colors.blueAzure, 95 | padding: 15, 96 | alignItems: 'center', 97 | marginTop: 20, 98 | borderRadius: 20, 99 | }, 100 | loginText: 101 | { 102 | color: '#ffffff', 103 | fontSize: 15, 104 | fontWeight: 'bold' 105 | }, 106 | clickTextButton: 107 | { 108 | marginTop: 20, 109 | flexDirection:'row', 110 | justifyContent: 'space-between', 111 | }, 112 | clickText: 113 | { 114 | color: theme.colors.lightBlack, 115 | fontSize: 15, 116 | fontWeight: 'bold' 117 | }, 118 | }); 119 | -------------------------------------------------------------------------------- /Chat App/screens/Login/register.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, TextInput, TouchableOpacity, Text, StyleSheet } from 'react-native'; 3 | import * as theme from '../../constants/theme'; 4 | 5 | export default class Register extends React.Component { 6 | constructor(props) { 7 | super(props); 8 | this.state = { 9 | name: '', 10 | email: '', 11 | password: '' 12 | } 13 | } 14 | 15 | Register() { 16 | const {name, email, password} = this.state 17 | if (name.length != 0 && email.length != 0 && password.length != 0) 18 | { 19 | alert('Hello !'); 20 | } 21 | else { 22 | this.props.navigation.navigate('HomeScreens'); 23 | } 24 | } 25 | 26 | render() { 27 | return ( 28 | 29 | this.emailInput.focus()} 37 | onChangeText={(name) => this.setState({name})} /> 38 | 39 | this.emailInput = input} 48 | onSubmitEditing={() => this.passwordInput.focus()} 49 | onChangeText={(email) => this.setState({email})} /> 50 | 51 | this.passwordInput = input} 61 | onChangeText={(password) => this.setState({password})} /> 62 | 63 | this.Register()}> 64 | Register 65 | 66 | 67 | 68 | 69 | this.props.navigation.navigate('Login')}>Have an account? 70 | 71 | 72 | 73 | ); 74 | } 75 | }; 76 | 77 | const styles = StyleSheet.create({ 78 | container: { 79 | flex: 1, 80 | backgroundColor: theme.colors.white, 81 | justifyContent: 'center', 82 | padding: 20 83 | }, 84 | inputForm: 85 | { 86 | backgroundColor: theme.colors.white, 87 | borderRadius: 10, 88 | padding: 10, 89 | color: theme.colors.lightBlack, 90 | fontSize: 15, 91 | marginBottom: 10, 92 | borderTopColor: theme.colors.lightBlack, 93 | borderTopWidth: 1, 94 | borderBottomColor: theme.colors.lightBlack, 95 | borderBottomWidth: 1, 96 | borderLeftColor: theme.colors.lightBlack, 97 | borderLeftWidth: 1, 98 | borderRightColor: theme.colors.lightBlack, 99 | borderRightWidth: 1, 100 | }, 101 | RegisterButton: 102 | { 103 | backgroundColor: theme.colors.blueAzure, 104 | padding: 15, 105 | alignItems: 'center', 106 | marginTop: 20, 107 | borderRadius: 20, 108 | }, 109 | RegisterText: 110 | { 111 | color: '#ffffff', 112 | fontSize: 15, 113 | fontWeight: 'bold' 114 | }, 115 | clickTextButton: 116 | { 117 | marginTop: 20, 118 | }, 119 | clickText: 120 | { 121 | color: theme.colors.lightBlack, 122 | fontSize: 15, 123 | fontWeight: 'bold' 124 | }, 125 | }); 126 | -------------------------------------------------------------------------------- /Chat App/screens/conversation.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, Keyboard, View, Text, TouchableOpacity, TextInput, FlatList } from 'react-native'; 3 | import { Header, Avatar, Icon } from 'react-native-elements'; 4 | import * as theme from '../constants/theme'; 5 | import Bar from '../components/bar'; 6 | import ChatItem from '../components/chatItem'; 7 | 8 | export default class Conversation extends React.Component { 9 | constructor(props) { 10 | super(props) 11 | this.state = { 12 | texte: '', 13 | messages: [ 14 | { 15 | id: 1, 16 | text: 'Hi', 17 | author: { 18 | id: 2, 19 | username: 'ouael.amdouni', 20 | avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg' 21 | } 22 | }, 23 | { 24 | id: 2, 25 | text: 'Hello !', 26 | author: { 27 | id: 1, 28 | username: 'skander.blaiti', 29 | avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg' 30 | } 31 | }, 32 | ] 33 | } 34 | } 35 | 36 | sendMessage() { 37 | const messages = this.state.messages; 38 | const newMessage = { 39 | text: this.state.texte, 40 | author: { 41 | id: 1, 42 | username: 'skander.blaiti', 43 | avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/adhamdannaway/128.jpg' 44 | } 45 | }; 46 | messages.unshift(newMessage); 47 | this.setState({messages}); 48 | Keyboard.dismiss(); 49 | this.textInput.clear(); 50 | } 51 | 52 | _keyExtractor = (item, index) => index.toString(); 53 | 54 | _renderItem = ({item}) => ( 55 | 57 | ); 58 | 59 | render() { 60 | return ( 61 | 62 |
this.props.navigation.goBack() }} 67 | centerComponent={ 68 | 69 | 72 | 73 | {this.props.navigation.state.params.name} 74 | 75 | 76 | } 77 | rightComponent={{ icon: 'more-vert', color: '#000000' }} /> 78 | 79 | 80 | 81 | 87 | 88 | 89 | 90 | 91 | 92 | { this.textInput = input }} 98 | onChangeText={(texte) => this.setState({texte})} /> 99 | 100 | 101 | this.sendMessage()}> 102 | 103 | 104 | 105 | 106 | 107 | ); 108 | } 109 | } 110 | 111 | const styles = StyleSheet.create({ 112 | container: { 113 | flex: 1, 114 | justifyContent: 'center', 115 | backgroundColor: theme.colors.white, 116 | }, 117 | messageContainer: { 118 | flex: 1, 119 | }, 120 | sendForm: { 121 | flexDirection: 'row', 122 | marginBottom: 0, 123 | padding: 5, 124 | }, 125 | messageInput: { 126 | backgroundColor: theme.colors.clouds, 127 | color: theme.colors.black, 128 | borderRadius: 10, 129 | width: '100%', 130 | borderWidth: 1, 131 | borderColor: theme.colors.silver 132 | } 133 | }); 134 | -------------------------------------------------------------------------------- /Credit Card Input/App.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import { 3 | View, 4 | UIManager, 5 | StyleSheet, 6 | } from 'react-native'; 7 | 8 | import {YellowBox} from 'react-native'; 9 | 10 | YellowBox.ignoreWarnings(['Warning: ...']); 11 | 12 | UIManager.setLayoutAnimationEnabledExperimental(true); 13 | 14 | import{ CreditCardInput } from 'react-native-credit-card-input'; 15 | 16 | export default class App extends Component { 17 | _onFocus = field => console.log('focusing', field) 18 | 19 | _onChange = formData => console.log(JSON.stringify(formData, null , ' ')) 20 | render() { 21 | return ( 22 | 23 | 36 | 37 | ); 38 | } 39 | 40 | }; 41 | 42 | const styles = StyleSheet.create({ 43 | container: { 44 | flex: 1, 45 | marginTop: 5, 46 | backgroundColor: 'white', 47 | }, 48 | }); 49 | -------------------------------------------------------------------------------- /Dark Mode/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Text, TouchableOpacity } from 'react-native'; 3 | 4 | export default class App extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | this.state = { 8 | toggle: true 9 | } 10 | } 11 | 12 | 13 | toggleTheme() { 14 | this.setState({ 15 | toggle: this.state.toggle ? false : true 16 | }) 17 | } 18 | render() { 19 | return ( 20 | 21 | this.toggleTheme()}> 22 | Change Theme 23 | 24 | 25 | ); 26 | } 27 | }; 28 | 29 | const styles = StyleSheet.create({ 30 | container: { 31 | flex: 1, 32 | justifyContent: 'center', 33 | alignItems: 'center' 34 | }, 35 | text: { 36 | fontSize: 20, 37 | fontWeight: 'bold' 38 | } 39 | }); 40 | -------------------------------------------------------------------------------- /Google APIs/search.js: -------------------------------------------------------------------------------- 1 | import React, {Component} from 'react'; 2 | import { View, TouchableOpacity, ActivityIndicator, ScrollView, TextInput, FlatList, Keyboard, StyleSheet } from 'react-native'; 3 | import { Header } from 'react-native-elements'; 4 | import * as theme from '../constants/themes'; 5 | import SearchBookCard from '../components/searchBookCard'; 6 | 7 | export default class Search extends Component { 8 | constructor(props) { 9 | super(props); 10 | this.books = [], 11 | this.state = { 12 | bookTitle: '', 13 | isLoading: false, 14 | errorMessage: '', 15 | }; 16 | } 17 | SearchBook() { 18 | Keyboard.dismiss(); 19 | this.setState({ isLoading: true }) 20 | const bookTitle = this.state.bookTitle; 21 | for (var i=0; i 38 | this.setState({ 39 | isLoading: false, 40 | errorMessage: error 41 | })) 42 | .done(); 43 | } 44 | else { 45 | alert('You must write a book title !'); 46 | } 47 | } 48 | 49 | keyExtractor = (item, index) => index.toString() 50 | 51 | renderItem = ({ item }) => ( 52 | 58 | ) 59 | 60 | render() { 61 | if (this.state.isLoading) { 62 | return ( 63 | 64 |
this.setState({bookTitle})} />} 72 | placement='left' 73 | rightComponent={{ icon: 'search', color: '#FFAEA5', onPress: () => this.SearchBook() }} 74 | statusBarProps={{ translucent: true }} 75 | backgroundColor='#ffffff' 76 | /> 77 | 78 | 79 | 80 | 81 | ); 82 | } 83 | else { 84 | return ( 85 | 86 |
this.setState({bookTitle})} />} 94 | placement='left' 95 | rightComponent={{ icon: 'search', color: '#e74c3c', onPress: () => this.SearchBook() }} 96 | statusBarProps={{ translucent: true }} 97 | backgroundColor='#ffffff' 98 | /> 99 | 100 | 105 | 106 | 107 | ); 108 | } 109 | } 110 | } 111 | 112 | const styles = StyleSheet.create({ 113 | container: { 114 | flex: 1, 115 | backgroundColor: theme.colors.white, 116 | }, 117 | textInput: { 118 | borderColor: '#FFAEA5', 119 | borderWidth: 1, 120 | borderRadius: 15, 121 | padding: 10, 122 | color: theme.colors.black, 123 | backgroundColor: theme.colors.white, 124 | } 125 | }); 126 | -------------------------------------------------------------------------------- /Job App/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | import { NavigationContainer } from '@react-navigation/native'; 4 | import { createStackNavigator } from '@react-navigation/stack'; 5 | import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; 6 | 7 | import Home from './src/screens/home'; 8 | import Profile from './src/screens/profile'; 9 | import Notifications from './src/screens/notifications'; 10 | 11 | import Doc from './src/screens/doc'; 12 | import Login from './src/screens/login'; 13 | import Register from './src/screens/register'; 14 | import JobPage from './src/screens/jobPage'; 15 | 16 | import Icon from 'react-native-vector-icons/Ionicons'; 17 | 18 | import * as theme from './src/constants/lightTheme'; 19 | 20 | import { Badge, withBadge } from 'react-native-elements' 21 | 22 | export default function App() { 23 | return ( 24 | 25 | 26 | 27 | ); 28 | }; 29 | 30 | 31 | 32 | const Stack = createStackNavigator(); 33 | 34 | function MyStack() { 35 | return ( 36 | 37 | 38 | 39 | 40 | 41 | 42 | ); 43 | } 44 | 45 | const Main = createStackNavigator(); 46 | 47 | function MainApp() { 48 | return ( 49 | 50 | 51 | 52 | 53 | ); 54 | } 55 | 56 | const Tab = createBottomTabNavigator(); 57 | 58 | const BadgedIcon = withBadge(6)(Icon) 59 | 60 | function MyTabs() { 61 | return ( 62 | 72 | 73 | ( 79 | 80 | ), 81 | }} /> 82 | ( 88 | 89 | ), 90 | }} /> 91 | ( 97 | 98 | ), 99 | }} /> 100 | 101 | ); 102 | } 103 | -------------------------------------------------------------------------------- /Job App/README.md: -------------------------------------------------------------------------------- 1 | A job application using React Native. 2 | 3 | The necessary libraries: 4 | 5 | - react-native-community/async-storage 6 | - react-native-community/masked-view 7 | - react-navigation/bottom-tabs 8 | - react-navigation/native 9 | - react-navigation/stack 10 | - react-native-animatable 11 | - react-native-elements 12 | - react-native-gesture-handler 13 | - react-native-maps 14 | - react-native-reanimated 15 | - react-native-safe-area-context 16 | - react-native-screens 17 | - react-native-vector-icons 18 | 19 | -------------------------------------------------------------------------------- /Job App/src/components/header.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | } from 'react-native'; 7 | 8 | import * as theme from '../constants/lightTheme'; 9 | import Icon from 'react-native-vector-icons/MaterialIcons'; 10 | 11 | const Header = (props) => { 12 | return ( 13 | 14 | 15 | 16 | 17 | 18 | 19 | {props.center} 20 | 21 | 22 | 23 | {props.right} 24 | 25 | 26 | ); 27 | }; 28 | 29 | const styles = StyleSheet.create({ 30 | container: { 31 | padding: 10, 32 | flexDirection: 'row', 33 | backgroundColor: theme.colors.primaryBlue, 34 | }, 35 | left: { 36 | flex: 1, 37 | padding: 5, 38 | justifyContent: 'center' 39 | }, 40 | center: { 41 | flex: 4, 42 | padding: 5, 43 | alignItems: 'center', 44 | justifyContent: 'center' 45 | }, 46 | right: { 47 | flex: 1, 48 | padding: 5, 49 | alignItems: 'center', 50 | justifyContent: 'center' 51 | }, 52 | headerText: { 53 | color: theme.colors.white, 54 | fontSize: theme.sizes.h3, 55 | fontWeight: '900' 56 | } 57 | }); 58 | 59 | export default Header; -------------------------------------------------------------------------------- /Job App/src/components/jobCard.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { View, StyleSheet, Text, Image } from 'react-native'; 3 | 4 | import * as theme from '../constants/lightTheme'; 5 | 6 | import Icon from 'react-native-vector-icons/MaterialIcons'; 7 | 8 | export default function JobCard ({ item }) { 9 | return ( 10 | 11 | 12 | 13 | {item.company} 14 | {item.poste} 15 | 16 | 17 | 18 | 19 | 20 | 21 | {item.person} 22 | 23 | 24 | 25 | {item.location} 26 | 27 | 28 | 29 | {item.experience} 30 | 31 | 32 | 33 | ) 34 | } 35 | 36 | const styles = StyleSheet.create({ 37 | cardContainer: { 38 | flex: 1, 39 | margin: 5, 40 | padding: 10, 41 | borderRadius: 10, 42 | backgroundColor: theme.colors.primaryBlue, 43 | shadowColor: '#000', 44 | shadowOffset: { width: 0.5, height: 0.5 }, 45 | shadowOpacity: 0.5, 46 | shadowRadius: 3, 47 | elevation: 5, 48 | }, 49 | headerContainer: { 50 | flexDirection: 'row', 51 | justifyContent: 'space-between' 52 | }, 53 | itemTitle: { 54 | fontWeight: 'bold', 55 | fontSize: theme.sizes.h2, 56 | color: theme.colors.white 57 | }, 58 | itemSubTitle: { 59 | fontWeight: '900', 60 | fontSize: theme.sizes.h3, 61 | color: theme.colors.white 62 | }, 63 | bodyContainer: { 64 | marginTop: 10, 65 | }, 66 | itemContainer: { 67 | flexDirection: 'row', 68 | marginTop: 5, 69 | }, 70 | itemText: { 71 | fontSize: theme.sizes.h4, 72 | color: theme.colors.white 73 | } 74 | }); -------------------------------------------------------------------------------- /Job App/src/constants/lightTheme.js: -------------------------------------------------------------------------------- 1 | const colors = { 2 | white: '#ffffff', 3 | black: '#000000', 4 | primaryBlue: '#4C82DE', 5 | concreteGray: '#95a5a6', 6 | silver: '#bdc3c7', 7 | gray: '#7f8c8d' 8 | } 9 | 10 | const sizes = { 11 | h1: 30, 12 | h2: 25, 13 | h3: 22, 14 | h4: 19, 15 | h5: 15, 16 | h6: 10 17 | } 18 | 19 | export { 20 | colors, 21 | sizes 22 | } -------------------------------------------------------------------------------- /Job App/src/images/Etikks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaiti/React-Native/8df4a477b5aac2d3df1e8e15558b95d76c2c0f03/Job App/src/images/Etikks.jpg -------------------------------------------------------------------------------- /Job App/src/images/Interise.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaiti/React-Native/8df4a477b5aac2d3df1e8e15558b95d76c2c0f03/Job App/src/images/Interise.jpg -------------------------------------------------------------------------------- /Job App/src/images/blueLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaiti/React-Native/8df4a477b5aac2d3df1e8e15558b95d76c2c0f03/Job App/src/images/blueLogo.png -------------------------------------------------------------------------------- /Job App/src/images/docBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaiti/React-Native/8df4a477b5aac2d3df1e8e15558b95d76c2c0f03/Job App/src/images/docBackground.png -------------------------------------------------------------------------------- /Job App/src/images/whiteLogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blaiti/React-Native/8df4a477b5aac2d3df1e8e15558b95d76c2c0f03/Job App/src/images/whiteLogo.png -------------------------------------------------------------------------------- /Job App/src/screens/doc.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | Image, 7 | ImageBackground, 8 | Dimensions, 9 | TouchableOpacity 10 | } from 'react-native'; 11 | 12 | import * as theme from '../constants/lightTheme'; 13 | 14 | const dimensions = Dimensions.get('window'); 15 | const imageWidth = dimensions.width; 16 | 17 | export default function Doc(props) { 18 | const { navigation } = props 19 | return ( 20 | 21 | 22 | 26 | 30 | 31 | 32 | 33 | 34 | Bonjour, 35 | Rejoignez-nous et trouvez le travail de vos rêves 36 | 37 | 38 | navigation.navigate('Register')}> 41 | Rejoignez-Nous 42 | 43 | 44 | navigation.navigate('Login')}> 47 | S'identifier 48 | 49 | 50 | 51 | Mot de passe oublié? 52 | 53 | 54 | 55 | 56 | 57 | ); 58 | }; 59 | 60 | const styles = StyleSheet.create({ 61 | container: { 62 | flex: 1, 63 | backgroundColor: theme.colors.primaryBlue 64 | }, 65 | backgroundImage: { 66 | paddingTop: 90, 67 | width: imageWidth, 68 | height: imageWidth - 40, 69 | alignItems: 'center', 70 | }, 71 | blockContainer: { 72 | flex: 1, 73 | padding: 20 74 | }, 75 | helloText: { 76 | fontWeight: 'bold', 77 | fontSize: theme.sizes.h1, 78 | color: theme.colors.white, 79 | }, 80 | joinUsText: { 81 | marginTop: 10, 82 | fontWeight: '800', 83 | fontSize: theme.sizes.h2, 84 | color: theme.colors.white, 85 | }, 86 | butttonsView: { 87 | marginTop: 40 88 | }, 89 | registerButton: { 90 | padding: 15, 91 | borderWidth: 2, 92 | borderRadius: 10, 93 | alignItems: 'center', 94 | justifyContent: 'center', 95 | borderColor: theme.colors.white 96 | }, 97 | loginButton: { 98 | padding: 15, 99 | marginTop: 13, 100 | borderRadius: 10, 101 | alignItems: 'center', 102 | justifyContent: 'center', 103 | backgroundColor: theme.colors.white 104 | }, 105 | registerText: { 106 | fontWeight: 'bold', 107 | fontSize: theme.sizes.h3, 108 | color: theme.colors.white, 109 | }, 110 | loginText: { 111 | fontWeight: 'bold', 112 | fontSize: theme.sizes.h3, 113 | color: theme.colors.primaryBlue, 114 | }, 115 | passwordButton: { 116 | marginTop: 10, 117 | alignItems: 'center', 118 | justifyContent: 'center', 119 | }, 120 | passwordText: { 121 | marginTop: 5, 122 | fontSize: theme.sizes.h5, 123 | color: theme.colors.white 124 | } 125 | }); 126 | -------------------------------------------------------------------------------- /Job App/src/screens/home.js: -------------------------------------------------------------------------------- 1 | import React, { useState, useEffect } from 'react'; 2 | import { 3 | StyleSheet, 4 | SafeAreaView, 5 | View, 6 | FlatList, 7 | TouchableOpacity 8 | } from 'react-native'; 9 | 10 | import * as theme from '../constants/lightTheme'; 11 | 12 | import { SearchBar } from 'react-native-elements'; 13 | 14 | import JobCard from '../components/jobCard'; 15 | 16 | const jobs = [ 17 | { 18 | id:'1', 19 | company: '3oulti', 20 | poste: 'Community Manager', 21 | person: 'H/F', 22 | location: 'Tunis', 23 | experience: '+2 ans', 24 | }, 25 | { 26 | id: '2', 27 | company: 'Etikks', 28 | poste: 'Concepteur Graphique', 29 | person: 'H/F', 30 | location: 'Tunis', 31 | experience: '+2 ans', 32 | }, 33 | 34 | { 35 | id: '3', 36 | company: 'Interise', 37 | poste: 'Référenceur Web', 38 | person: 'H/F', 39 | location: 'Tunis', 40 | experience: '+2 ans', 41 | }, 42 | { 43 | id: '4', 44 | company: 'Tuntek', 45 | poste: 'Rédacteur Web', 46 | person: 'H/F', 47 | location: 'Tunis', 48 | experience: '+2 ans', 49 | }, 50 | { 51 | id: '5', 52 | company: 'Etikks', 53 | poste: 'Concepteur UX', 54 | person: 'H/F', 55 | location: 'Tunis', 56 | experience: '+2 ans', 57 | }, 58 | { 59 | id: '6', 60 | company: 'Interise', 61 | poste: 'Concepteur UI', 62 | person: 'H/F', 63 | location: 'Tunis', 64 | experience: '+2 ans', 65 | }, 66 | ] 67 | 68 | export default function Home({navigation}) { 69 | return ( 70 | 71 | 72 | 76 | 77 | 78 | item.id} 81 | renderItem={({ item }) => { 82 | return ( 83 | navigation.navigate('JobPage', { 84 | company: item.company, 85 | poste: item.poste, 86 | person: item.person, 87 | location: item.location, 88 | experience: item.experience })}> 89 | 90 | 91 | 92 | ) 93 | }} 94 | /> 95 | 96 | 97 | ); 98 | }; 99 | 100 | const styles = StyleSheet.create({ 101 | container: { 102 | flex: 1, 103 | backgroundColor: theme.colors.white 104 | }, 105 | listView: { 106 | paddingBottom: 70, 107 | } 108 | }); 109 | -------------------------------------------------------------------------------- /Job App/src/screens/jobPage.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | ScrollView 7 | } from 'react-native'; 8 | 9 | import MapView, {PROVIDER_GOOGLE, Marker} from 'react-native-maps'; 10 | 11 | import Icon from 'react-native-vector-icons/MaterialIcons'; 12 | 13 | import * as theme from '../constants/lightTheme'; 14 | import Header from '../components/header'; 15 | import { TouchableOpacity, TextInput } from 'react-native-gesture-handler'; 16 | 17 | export default function JobPage ({ route }) { 18 | const {company, poste, person, location, experience } = route.params; 19 | return ( 20 | 21 |
22 | 23 | 32 | 39 | 40 | 41 | 42 | Etikks est une agence de communication atypique fondée sur l’idée d’une communication moderne, innovante et consciente. 43 | 44 | 45 | {person} 46 | 47 | 48 | 49 | {location} 50 | 51 | 52 | 53 | {experience} 54 | 55 | 56 | 57 | Postuler 58 | 59 | 60 | ); 61 | }; 62 | 63 | const styles = StyleSheet.create({ 64 | container: { 65 | flex: 1, 66 | backgroundColor: theme.colors.white, 67 | }, 68 | mapContainer: { 69 | height: 250, 70 | }, 71 | map: { 72 | ...StyleSheet.absoluteFillObject, 73 | }, 74 | bodyContainer: { 75 | padding: 10 76 | }, 77 | detailsText: { 78 | fontSize: theme.sizes.h5, 79 | }, 80 | itemContainer: { 81 | flexDirection: 'row', 82 | marginTop: 10, 83 | }, 84 | itemText: { 85 | fontSize: theme.sizes.h4, 86 | color: theme.colors.black 87 | }, 88 | buttonContainer: { 89 | padding: 12, 90 | alignItems: 'center', 91 | justifyContent: 'center', 92 | backgroundColor: theme.colors.primaryBlue 93 | }, 94 | buttonText: { 95 | fontSize: theme.sizes.h3, 96 | color: theme.colors.white, 97 | }, 98 | }); 99 | -------------------------------------------------------------------------------- /Job App/src/screens/login.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | TextInput, 7 | StatusBar, 8 | Alert, 9 | TouchableOpacity 10 | } from 'react-native'; 11 | 12 | import * as Animatable from 'react-native-animatable'; 13 | import FontAwesome from 'react-native-vector-icons/FontAwesome'; 14 | import Feather from 'react-native-vector-icons/Feather'; 15 | 16 | import * as theme from '../constants/lightTheme'; 17 | 18 | 19 | export default function Login(props) { 20 | const { navigation } = props; 21 | 22 | const [data, setData] = React.useState({ 23 | username: '', 24 | password: '', 25 | check_textInputChange: false, 26 | secureTextEntry: true, 27 | isValidUser: true, 28 | isValidPassword: true, 29 | }); 30 | 31 | const textInputChange = (val) => { 32 | var regex = /^[a-zA-Z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$/; 33 | if( regex.test(val.trim()) ) { 34 | setData({ 35 | ...data, 36 | username: val, 37 | check_textInputChange: true, 38 | isValidUser: true 39 | }); 40 | } else { 41 | setData({ 42 | ...data, 43 | username: val, 44 | check_textInputChange: false, 45 | isValidUser: false 46 | }); 47 | } 48 | } 49 | 50 | const handleValidUser = (val) => { 51 | var regex = /^[a-zA-Z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$/; 52 | if( regex.test(val.trim()) ) { 53 | setData({ 54 | ...data, 55 | isValidUser: true 56 | }); 57 | } else { 58 | setData({ 59 | ...data, 60 | isValidUser: false 61 | }); 62 | } 63 | } 64 | 65 | const updateSecureTextEntry = () => { 66 | setData({ 67 | ...data, 68 | secureTextEntry: !data.secureTextEntry 69 | }); 70 | } 71 | 72 | const handlePasswordChange = (val) => { 73 | if( val.trim().length >= 8 ) { 74 | setData({ 75 | ...data, 76 | password: val, 77 | isValidPassword: true 78 | }); 79 | } else { 80 | setData({ 81 | ...data, 82 | password: val, 83 | isValidPassword: false 84 | }); 85 | } 86 | } 87 | 88 | const loginHandle = (userName, password) => { 89 | 90 | const DUserName = 'skander.blaiti@gmail.com' ; 91 | const DPassword = 'Blaiti'; 92 | 93 | if ( data.username.length == 0 || data.password.length == 0 ) { 94 | Alert.alert('Données manquantes !', 'Le champ de l\'e-mail ou du mot de passe ne peut pas être vide.', [ 95 | {text: 'D\'accord'} 96 | ]); 97 | return; 98 | } 99 | else { 100 | if ( data.username == DUserName && data.password == DPassword ) { 101 | navigation.navigate('MainApp'); 102 | return; 103 | } 104 | else { 105 | Alert.alert('Utilisateur invalide !', 'E-mail ou mot de passe incorrect.', [ 106 | {text: 'D\'accord'} 107 | ]); 108 | return; 109 | } 110 | } 111 | } 112 | 113 | return ( 114 | 115 | 116 | 117 | 118 | Bienvenu ! 119 | 120 | 121 | 122 | {/* Username input */} 123 | Email 124 | 125 | 126 | 127 | 128 | textInputChange(val)} 134 | onEndEditing={(e)=>handleValidUser(e.nativeEvent.text)} /> 135 | 136 | {data.check_textInputChange ? 137 | 138 | 139 | 140 | : null} 141 | 142 | 143 | { data.isValidUser ? null : 144 | 145 | Vous devez saisir un e-mail valide. 146 | 147 | } 148 | 149 | {/* Password input */} 150 | Mot de passe 151 | 152 | 153 | 154 | 155 | handlePasswordChange(val)} 161 | secureTextEntry={data.secureTextEntry ? true : false} /> 162 | 163 | 165 | {data.secureTextEntry ? 166 | 167 | : 168 | 169 | } 170 | 171 | 172 | { data.isValidPassword ? null : 173 | 174 | Le mot de passe doit comporter 8 caractères. 175 | 176 | } 177 | 178 | 179 | {loginHandle( data.username, data.password )}} 182 | > 183 | 184 | S'identifier 185 | 186 | 187 | 188 | navigation.navigate('Register')} 190 | style={[styles.signInButton, { 191 | borderColor: theme.colors.primaryBlue, 192 | borderWidth: 1, 193 | marginTop: 15 194 | }]} 195 | > 196 | 197 | Créer un compte 198 | 199 | 200 | 201 | 202 | Mot de passe oublié? 203 | 204 | 205 | 206 | 207 | ); 208 | }; 209 | 210 | const styles = StyleSheet.create({ 211 | container: { 212 | flex: 1, 213 | backgroundColor: theme.colors.primaryBlue 214 | }, 215 | headerContainer: { 216 | flex: 1, 217 | paddingBottom: 50, 218 | paddingHorizontal: 20, 219 | justifyContent: 'flex-end', 220 | }, 221 | headerText: { 222 | fontSize: theme.sizes.h1, 223 | fontWeight: 'bold', 224 | color: theme.colors.white, 225 | }, 226 | footerContainer: { 227 | flex: 3, 228 | paddingVertical: 30, 229 | paddingHorizontal: 20, 230 | borderTopLeftRadius: 30, 231 | borderTopRightRadius: 30, 232 | backgroundColor: theme.colors.white, 233 | }, 234 | footerText: { 235 | marginTop: 20, 236 | fontWeight: 'bold', 237 | fontSize: theme.sizes.h3, 238 | color: theme.colors.gray 239 | }, 240 | action: { 241 | marginTop: 10, 242 | paddingBottom: 5, 243 | flexDirection: 'row', 244 | borderBottomWidth: 1, 245 | borderBottomColor: theme.colors.gray 246 | }, 247 | textInputContainer: { 248 | flex: 1, 249 | marginTop: -12, 250 | paddingLeft: 10, 251 | fontSize: theme.sizes.h5, 252 | color: theme.colors.gray, 253 | }, 254 | errorMsgText: { 255 | color: '#FF0000', 256 | fontSize: 14, 257 | }, 258 | buttonContainer: { 259 | alignItems: 'center', 260 | marginTop: 50 261 | }, 262 | signInButton: { 263 | height: 50, 264 | width: '100%', 265 | borderRadius: 10, 266 | alignItems: 'center', 267 | justifyContent: 'center', 268 | }, 269 | buttonText: { 270 | fontSize: 18, 271 | fontWeight: 'bold' 272 | } 273 | }); 274 | -------------------------------------------------------------------------------- /Job App/src/screens/notifications.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | ScrollView, 6 | Text, 7 | } from 'react-native'; 8 | 9 | import { ListItem } from 'react-native-elements'; 10 | 11 | import * as theme from '../constants/lightTheme'; 12 | import Header from '../components/header'; 13 | 14 | const notifs = [ 15 | { 16 | company: '3oulti', 17 | picture: 'https://www.interise.tn/wp-content/uploads/2020/05/1.png', 18 | message: 'Si vous êtes intéressé de la community management, ce poste est fait pour vous..' 19 | }, 20 | { 21 | company: 'Etikks', 22 | picture: 'https://www.interise.tn/wp-content/uploads/2020/05/Etikks.jpg', 23 | message: 'Vous êtes accepté pour passer un entretien jeudi prochain.' 24 | }, 25 | 26 | { 27 | company: 'Interise', 28 | picture: 'https://www.interise.tn/wp-content/uploads/2020/04/Blue-Logo-1.jpg', 29 | message: 'Vous êtes accepté pour passer un entretien mardi prochain.' 30 | }, 31 | { 32 | company: 'Tuntek', 33 | picture: 'https://www.interise.tn/wp-content/uploads/2019/11/Tuntek.jpg', 34 | message: 'N\'hésitez pas à envoyer votre CV à Tuntek.' 35 | }, 36 | { 37 | company: 'Etikks', 38 | picture: 'https://www.interise.tn/wp-content/uploads/2020/05/Etikks.jpg', 39 | message: 'Votre CV a été envoyé automatiquement à Etikks.' 40 | }, 41 | { 42 | company: 'Interise', 43 | picture: 'https://www.interise.tn/wp-content/uploads/2020/04/Blue-Logo-1.jpg', 44 | message: 'Un nouveau offre d\'emploi qui peut-être vous intéresse.' 45 | }, 46 | ] 47 | 48 | export default function Notifications () { 49 | return ( 50 | 51 |
52 | 53 | { 54 | notifs.map((item, i) => ( 55 | 62 | )) 63 | } 64 | 65 | 66 | ); 67 | }; 68 | 69 | const styles = StyleSheet.create({ 70 | container: { 71 | flex: 1, 72 | backgroundColor: theme.colors.white 73 | }, 74 | }); 75 | -------------------------------------------------------------------------------- /Job App/src/screens/profile.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | } from 'react-native'; 7 | 8 | import * as theme from '../constants/lightTheme'; 9 | import Header from '../components/header'; 10 | 11 | export default function Profile () { 12 | return ( 13 | 14 |
15 | 16 | 17 | ); 18 | }; 19 | 20 | const styles = StyleSheet.create({ 21 | container: { 22 | flex: 1, 23 | backgroundColor: theme.colors.white 24 | }, 25 | }); 26 | -------------------------------------------------------------------------------- /Job App/src/screens/register.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | StyleSheet, 4 | View, 5 | Text, 6 | TextInput, 7 | StatusBar, 8 | TouchableOpacity 9 | } from 'react-native'; 10 | 11 | import * as Animatable from 'react-native-animatable'; 12 | import FontAwesome from 'react-native-vector-icons/FontAwesome'; 13 | import Feather from 'react-native-vector-icons/Feather'; 14 | 15 | import * as theme from '../constants/lightTheme'; 16 | 17 | 18 | export default function Register(props) { 19 | const { navigation } = props; 20 | 21 | const [data, setData] = React.useState({ 22 | username: '', 23 | password: '', 24 | check_textInputChange: false, 25 | secureTextEntry: true, 26 | isValidUser: true, 27 | isValidPassword: true, 28 | isValidConfirmPassword: true, 29 | }); 30 | 31 | const textInputChange = (val) => { 32 | var regex = /^[a-zA-Z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$/; 33 | if( regex.test(val.trim()) ) { 34 | setData({ 35 | ...data, 36 | username: val, 37 | check_textInputChange: true, 38 | isValidUser: true 39 | }); 40 | } else { 41 | setData({ 42 | ...data, 43 | username: val, 44 | check_textInputChange: false, 45 | isValidUser: false 46 | }); 47 | } 48 | } 49 | 50 | const handleValidUser = (val) => { 51 | var regex = /^[a-zA-Z0-9._-]+@[a-z0-9._-]{2,}\.[a-z]{2,4}$/; 52 | if( regex.test(val.trim()) ) { 53 | setData({ 54 | ...data, 55 | isValidUser: true 56 | }); 57 | } else { 58 | setData({ 59 | ...data, 60 | isValidUser: false 61 | }); 62 | } 63 | } 64 | 65 | const updateSecureTextEntry = () => { 66 | setData({ 67 | ...data, 68 | secureTextEntry: !data.secureTextEntry 69 | }); 70 | } 71 | 72 | const handlePasswordChange = (val) => { 73 | if( val.trim().length >= 8 ) { 74 | setData({ 75 | ...data, 76 | password: val, 77 | isValidPassword: true 78 | }); 79 | } else { 80 | setData({ 81 | ...data, 82 | password: val, 83 | isValidPassword: false 84 | }); 85 | } 86 | } 87 | 88 | const handleConfirmPasswordChange = (val) => { 89 | if( val.trim() == data.password.trim() ) { 90 | setData({ 91 | ...data, 92 | passwordConfirm: val, 93 | isValidConfirmPassword: true 94 | }); 95 | } else { 96 | setData({ 97 | ...data, 98 | passwordConfirm: val, 99 | isValidConfirmPassword: false 100 | }); 101 | } 102 | } 103 | 104 | const loginHandle = (userName, password) => { 105 | 106 | const foundUser = Users.filter( item => { 107 | return userName == item.username && password == item.password; 108 | } ); 109 | 110 | if ( data.username.length == 0 || data.password.length == 0 ) { 111 | Alert.alert('Wrong Input!', 'Username or password field cannot be empty.', [ 112 | {text: 'Okay'} 113 | ]); 114 | return; 115 | } 116 | 117 | if ( foundUser.length == 0 ) { 118 | Alert.alert('Invalid User!', 'Username or password is incorrect.', [ 119 | {text: 'Okay'} 120 | ]); 121 | return; 122 | } 123 | signIn(foundUser); 124 | } 125 | 126 | return ( 127 | 128 | 129 | 130 | 131 | Rejoignez-Nous ! 132 | 133 | 134 | 135 | {/* Username input */} 136 | Email 137 | 138 | 139 | 140 | 141 | textInputChange(val)} 147 | onEndEditing={(e)=>handleValidUser(e.nativeEvent.text)} /> 148 | 149 | {data.check_textInputChange ? 150 | 151 | 152 | 153 | : null} 154 | 155 | 156 | { data.isValidUser ? null : 157 | 158 | Vous devez saisir un e-mail valide. 159 | 160 | } 161 | 162 | {/* Password input */} 163 | Mot de passe 164 | 165 | 166 | 167 | 168 | handlePasswordChange(val)} 174 | secureTextEntry={data.secureTextEntry ? true : false} /> 175 | 176 | 178 | {data.secureTextEntry ? 179 | 180 | : 181 | 182 | } 183 | 184 | 185 | { data.isValidPassword ? null : 186 | 187 | Le mot de passe doit comporter 8 caractères. 188 | 189 | } 190 | 191 | {/* Password confirm input */} 192 | Confirmez votre mot de passe 193 | 194 | 195 | 196 | 197 | handleConfirmPasswordChange(val)} 203 | secureTextEntry={data.secureTextEntry ? true : false} /> 204 | 205 | 207 | {data.secureTextEntry ? 208 | 209 | : 210 | 211 | } 212 | 213 | 214 | { data.isValidConfirmPassword ? null : 215 | 216 | Les deux mot de passe doivent être compatibles. 217 | 218 | } 219 | 220 | 221 | {loginHandle( data.username, data.password )}} 224 | > 225 | 226 | Créer un compte 227 | 228 | 229 | 230 | navigation.navigate('Login')} 232 | style={[styles.signInButton, { 233 | borderColor: theme.colors.primaryBlue, 234 | borderWidth: 1, 235 | marginTop: 15 236 | }]} 237 | > 238 | 239 | S'identifier 240 | 241 | 242 | 243 | 244 | 245 | 246 | ); 247 | }; 248 | 249 | const styles = StyleSheet.create({ 250 | container: { 251 | flex: 1, 252 | backgroundColor: theme.colors.primaryBlue 253 | }, 254 | headerContainer: { 255 | flex: 1, 256 | paddingBottom: 50, 257 | paddingHorizontal: 20, 258 | justifyContent: 'flex-end', 259 | }, 260 | headerText: { 261 | fontSize: theme.sizes.h1, 262 | fontWeight: 'bold', 263 | color: theme.colors.white, 264 | }, 265 | footerContainer: { 266 | flex: 3, 267 | paddingVertical: 30, 268 | paddingHorizontal: 20, 269 | borderTopLeftRadius: 30, 270 | borderTopRightRadius: 30, 271 | backgroundColor: theme.colors.white, 272 | }, 273 | footerText: { 274 | marginTop: 20, 275 | fontWeight: 'bold', 276 | fontSize: theme.sizes.h3, 277 | color: theme.colors.gray 278 | }, 279 | action: { 280 | marginTop: 10, 281 | paddingBottom: 5, 282 | flexDirection: 'row', 283 | borderBottomWidth: 1, 284 | borderBottomColor: theme.colors.gray 285 | }, 286 | textInputContainer: { 287 | flex: 1, 288 | marginTop: -12, 289 | paddingLeft: 10, 290 | fontSize: theme.sizes.h5, 291 | color: theme.colors.gray, 292 | }, 293 | errorMsgText: { 294 | color: '#FF0000', 295 | fontSize: 14, 296 | }, 297 | buttonContainer: { 298 | alignItems: 'center', 299 | marginTop: 30 300 | }, 301 | signInButton: { 302 | height: 50, 303 | width: '100%', 304 | borderRadius: 10, 305 | alignItems: 'center', 306 | justifyContent: 'center', 307 | }, 308 | buttonText: { 309 | fontSize: 18, 310 | fontWeight: 'bold' 311 | } 312 | }); 313 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React-Native 2 | React Native codes. 3 | -------------------------------------------------------------------------------- /Simple Calculator/calcul.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Text, TouchableOpacity } from 'react-native'; 3 | import * as theme from './theme'; 4 | 5 | export default class Calcul extends React.Component{ 6 | constructor(props) { 7 | super(props), 8 | this.state = { 9 | grayText: '', 10 | blueText: '0' 11 | } 12 | } 13 | 14 | calculate() { 15 | const {grayText, blueText} = this.state; 16 | 17 | equation = grayText + blueText; 18 | 19 | this.setState({grayText: equation}); 20 | 21 | result = eval(equation); 22 | this.setState({blueText: result}); 23 | } 24 | 25 | render() { 26 | return( 27 | 28 | 29 | 30 | {this.state.grayText} 31 | 32 | 33 | 34 | {this.state.blueText} 35 | 36 | 37 | 38 | 39 | 40 | this.setState({grayText: '', blueText: '0'})}> 43 | C 44 | 45 | this.setState({grayText: this.state.grayText + this.state.blueText + '/', blueText: '0'})}> 48 | / 49 | 50 | this.setState({grayText: this.state.grayText + this.state.blueText + '%', blueText: '0'})}> 53 | % 54 | 55 | 56 | +- 57 | 58 | 59 | 60 | 61 | this.setState({blueText: this.state.blueText+'7'})}> 64 | 7 65 | 66 | 67 | this.setState({blueText: this.state.blueText+'8'})}> 70 | 8 71 | 72 | 73 | this.setState({blueText: this.state.blueText+'9'})}> 76 | 9 77 | 78 | 79 | this.setState({grayText: this.state.grayText + this.state.blueText + '*', blueText: '0'})}> 82 | x 83 | 84 | 85 | 86 | 87 | this.setState({blueText: this.state.blueText+'4'})}> 90 | 4 91 | 92 | 93 | this.setState({blueText: this.state.blueText+'5'})}> 96 | 5 97 | 98 | 99 | this.setState({blueText: this.state.blueText+'6'})}> 102 | 6 103 | 104 | 105 | this.setState({grayText: this.state.grayText + this.state.blueText + '-', blueText: '0'})}> 108 | - 109 | 110 | 111 | 112 | 113 | this.setState({blueText: this.state.blueText+'1'})}> 116 | 1 117 | 118 | 119 | this.setState({blueText: this.state.blueText+'2'})}> 122 | 2 123 | 124 | 125 | this.setState({blueText: this.state.blueText+'3'})}> 128 | 3 129 | 130 | 131 | this.setState({grayText: this.state.grayText + this.state.blueText + '+', blueText: '0'})}> 134 | + 135 | 136 | 137 | 138 | 139 | this.setState({blueText: this.state.blueText+'.'})}> 142 | . 143 | 144 | 145 | this.setState({blueText: this.state.blueText+'0'})}> 148 | 0 149 | 150 | 151 | this.setState({blueText: this.state.blueText+'00'})}> 154 | 00 155 | 156 | 157 | this.calculate()} > 160 | = 161 | 162 | 163 | 164 | 165 | ) 166 | } 167 | } 168 | 169 | const styles = StyleSheet.create({ 170 | container: { 171 | flex: 1, 172 | }, 173 | resultContainer: { 174 | flex: 1, 175 | backgroundColor: theme.colors.white 176 | }, 177 | grayResultContainer: { 178 | flex: 1, 179 | padding: 10, 180 | alignItems: 'flex-end', 181 | justifyContent: 'center' 182 | }, 183 | grayResultText: { 184 | fontSize: 25, 185 | color: theme.colors.deepKoamaro 186 | }, 187 | blueResultContainer: { 188 | flex: 1, 189 | padding: 10, 190 | alignItems: 'flex-end', 191 | justifyContent: 'center' 192 | }, 193 | blueResultText: { 194 | fontSize: 40, 195 | color: theme.colors.midnightBlue 196 | }, 197 | buttonViewContainer: { 198 | flex: 2, 199 | }, 200 | buttonLineContainer: { 201 | flex: 1, 202 | flexDirection: 'row' 203 | }, 204 | buttonContainer: { 205 | flex: 1, 206 | alignItems: 'center', 207 | justifyContent: 'center' 208 | }, 209 | buttonText: { 210 | color: theme.colors.midnightBlue, 211 | fontSize: 20 212 | } 213 | }); 214 | -------------------------------------------------------------------------------- /Simple Calculator/theme.js: -------------------------------------------------------------------------------- 1 | const colors = { 2 | white: '#ffffff', 3 | midnightBlue: '#1b2139', 4 | wetAsphalt: '#373c4f', 5 | deepKoamaro: '#454a60' 6 | }; 7 | 8 | export { 9 | colors, 10 | }; 11 | -------------------------------------------------------------------------------- /Swiper/App.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { StyleSheet, View, Image } from 'react-native'; 3 | import Swiper from 'react-native-swiper'; 4 | 5 | 6 | export default class App extends React.Component { 7 | render() { 8 | return ( 9 | 10 | 11 | 12 | 14 | 15 | 16 | 17 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | ); 28 | } 29 | }; 30 | 31 | const styles = StyleSheet.create({ 32 | container: { 33 | flex: 1, 34 | } 35 | }); 36 | --------------------------------------------------------------------------------