From 8327cd0ccef05d1e215346575f138b1cbe5ef662 Mon Sep 17 00:00:00 2001 From: Jeton Kadrija Date: Sat, 28 Sep 2019 18:26:55 +0200 Subject: [PATCH] Integrate Apollo, Wireup Github API, Handle Response, Handle Errors, Form Validation, Handle Keyboard Search --- .gitignore | 1 + api/apollo.js | 4 ++-- api/getUser.js | 3 ++- babel.config.js | 6 ++++- config/index.js | 4 ---- containers/Home/index.js | 47 +++++++++++++++++++++++++++++++-------- containers/Home/styles.js | 3 +++ package.json | 1 + yarn.lock | 19 ++++++++++++++++ 9 files changed, 71 insertions(+), 17 deletions(-) delete mode 100644 config/index.js diff --git a/.gitignore b/.gitignore index 4820714..e33361a 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ npm-debug.* *.orig.* web-build/ web-report/ +.env \ No newline at end of file diff --git a/api/apollo.js b/api/apollo.js index 769fd1f..80b9e22 100644 --- a/api/apollo.js +++ b/api/apollo.js @@ -1,5 +1,5 @@ -import ApolloClient, { gql } from 'apollo-boost'; -import { API_URL, GITHUB_API_TOKEN } from 'app/config'; +import ApolloClient from 'apollo-boost'; +import { API_URL, GITHUB_API_TOKEN } from 'react-native-dotenv'; const client = new ApolloClient({ uri: API_URL, diff --git a/api/getUser.js b/api/getUser.js index 643a17c..d4b9b48 100644 --- a/api/getUser.js +++ b/api/getUser.js @@ -23,7 +23,8 @@ const getUserQuery = async search => { const getUser = async search => { const result = await getUserQuery(search).catch(async err => { - return { error: true, message: err.message }; + const message = err.graphQLErrors.length > 0 ? err.graphQLErrors[0].message : err.message; + return { error: true, message }; }); return result; }; diff --git a/babel.config.js b/babel.config.js index 2900afe..1897ece 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,6 +1,10 @@ module.exports = function(api) { api.cache(true); return { - presets: ['babel-preset-expo'], + presets: [ + 'babel-preset-expo', + 'module:metro-react-native-babel-preset', + 'module:react-native-dotenv', + ], }; }; diff --git a/config/index.js b/config/index.js deleted file mode 100644 index a579b66..0000000 --- a/config/index.js +++ /dev/null @@ -1,4 +0,0 @@ -const API_URL = 'https://api.github.com/graphql'; -const GITHUB_API_TOKEN = 'c6c245bc149f2d0a0c4e49c711af42905b5cb958'; - -export { API_URL, GITHUB_API_TOKEN }; diff --git a/containers/Home/index.js b/containers/Home/index.js index 126db2c..a9db571 100644 --- a/containers/Home/index.js +++ b/containers/Home/index.js @@ -1,5 +1,5 @@ import React from 'react'; -import { StatusBar } from 'react-native'; +import { StatusBar, TouchableOpacity } from 'react-native'; import PropTypes from 'prop-types'; import getUser from 'app/api/getUser'; import { @@ -17,6 +17,7 @@ import { Item, Input, Text, + Spinner, } from 'native-base'; import styles from './styles'; @@ -26,21 +27,44 @@ export default class Home extends React.Component { }; state = { + loading: false, search: '', - user: {}, + response: {}, }; searchUser = async () => { const { search } = this.state; - const user = await getUser(search); - this.setState({ user }); + if (search !== '') { + this.setState({ loading: true }); + const response = await getUser(search); + this.setState({ response, loading: false }); + } }; - renderUserNotFound = user => {user.message}; + renderError = response => { + if (response.error) { + return ( + + + + {response.message} + + + + ); + } + }; + + showSpinner = () => { + const { loading } = this.state; + if (loading) { + return ; + } + }; render() { const { navigation } = this.props; - const { search, user } = this.state; + const { search, response } = this.state; return (
@@ -62,13 +86,18 @@ export default class Home extends React.Component { placeholder="Search" value={search} onChangeText={val => this.setState({ search: val })} + returnKeyType="search" + onSubmitEditing={this.searchUser} /> - - + - {this.renderUserNotFound(user)} + {this.renderError(response)} + {this.showSpinner()} ); diff --git a/containers/Home/styles.js b/containers/Home/styles.js index 6e10c3a..b732984 100644 --- a/containers/Home/styles.js +++ b/containers/Home/styles.js @@ -7,5 +7,8 @@ const styles = StyleSheet.create({ inputSearch: { width: '70%', }, + errorMsg: { + color: 'red', + }, }); export default styles; diff --git a/package.json b/package.json index 9712cd2..a054af9 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "react-apollo": "3.0.0", "react-dom": "16.8.3", "react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz", + "react-native-dotenv": "^0.2.0", "react-native-gesture-handler": "~1.3.0", "react-native-web": "^0.11.7", "react-navigation": "^4.0.10", diff --git a/yarn.lock b/yarn.lock index b7b0b36..99bd08e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1424,6 +1424,13 @@ babel-eslint@^10.0.3: eslint-visitor-keys "^1.0.0" resolve "^1.12.0" +babel-plugin-dotenv@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-dotenv/-/babel-plugin-dotenv-0.1.1.tgz#9c8faea67a7c034fe7e94099187ab2e7573400bc" + integrity sha1-nI+upnp8A0/n6UCZGHqy51c0ALw= + dependencies: + dotenv "^2.0.0" + babel-plugin-dynamic-import-node@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" @@ -2143,6 +2150,11 @@ dom-walk@^0.1.0: resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= +dotenv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-2.0.0.tgz#bd759c357aaa70365e01c96b7b0bec08a6e0d949" + integrity sha1-vXWcNXqqcDZeAclrewvsCKbg2Uk= + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -5163,6 +5175,13 @@ react-native-branch@~3.0.1: resolved "https://registry.yarnpkg.com/react-native-branch/-/react-native-branch-3.0.1.tgz#5b07b61cbd290168cd3c3662e017ebe0f356d2ca" integrity sha512-vbcYxPZlpF5f39GAEUF8kuGQqCNeD3E6zEdvtOq8oCGZunHXlWlKgAS6dgBKCvsHvXgHuMtpvs39VgOp8DaKig== +react-native-dotenv@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/react-native-dotenv/-/react-native-dotenv-0.2.0.tgz#311551cb6a35a3dcfede648bded55c0e3ece579d" + integrity sha1-MRVRy2o1o9z+3mSL3tVcDj7OV50= + dependencies: + babel-plugin-dotenv "0.1.1" + react-native-drawer@2.5.1: version "2.5.1" resolved "https://registry.yarnpkg.com/react-native-drawer/-/react-native-drawer-2.5.1.tgz#08b9314184f48c724f1b467f8859797369798654"