diff --git a/.gitignore b/.gitignore old mode 100644 new mode 100755 diff --git a/App/android/app/build.gradle b/App/android/app/build.gradle index 3e1eaff7..b07108a7 100755 --- a/App/android/app/build.gradle +++ b/App/android/app/build.gradle @@ -115,9 +115,20 @@ android { universalApk false // If true, also generate a universal APK include "armeabi-v7a", "x86" } + } + signingConfigs { + release { + if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) { + storeFile file(MYAPP_RELEASE_STORE_FILE) + storePassword MYAPP_RELEASE_STORE_PASSWORD + keyAlias MYAPP_RELEASE_KEY_ALIAS + keyPassword MYAPP_RELEASE_KEY_PASSWORD + } + } } buildTypes { release { + signingConfig signingConfigs.release minifyEnabled enableProguardInReleaseBuilds proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" } diff --git a/App/android/app/src/main/res/drawable-hdpi/icon.png b/App/android/app/src/main/res/drawable-hdpi/icon.png new file mode 100755 index 00000000..bb58ec1b Binary files /dev/null and b/App/android/app/src/main/res/drawable-hdpi/icon.png differ diff --git a/App/android/app/src/main/res/drawable-ldpi/icon.png b/App/android/app/src/main/res/drawable-ldpi/icon.png new file mode 100755 index 00000000..08ead39a Binary files /dev/null and b/App/android/app/src/main/res/drawable-ldpi/icon.png differ diff --git a/App/android/app/src/main/res/drawable-mdpi/icon.png b/App/android/app/src/main/res/drawable-mdpi/icon.png new file mode 100755 index 00000000..d7d5010a Binary files /dev/null and b/App/android/app/src/main/res/drawable-mdpi/icon.png differ diff --git a/App/android/app/src/main/res/drawable-xhdpi/icon.png b/App/android/app/src/main/res/drawable-xhdpi/icon.png new file mode 100755 index 00000000..478a2c57 Binary files /dev/null and b/App/android/app/src/main/res/drawable-xhdpi/icon.png differ diff --git a/App/android/app/src/main/res/drawable-xxhdpi/icon.png b/App/android/app/src/main/res/drawable-xxhdpi/icon.png new file mode 100755 index 00000000..5a16987c Binary files /dev/null and b/App/android/app/src/main/res/drawable-xxhdpi/icon.png differ diff --git a/App/android/app/src/main/res/drawable-xxxhdpi/icon.png b/App/android/app/src/main/res/drawable-xxxhdpi/icon.png new file mode 100755 index 00000000..f8f7db9c Binary files /dev/null and b/App/android/app/src/main/res/drawable-xxxhdpi/icon.png differ diff --git a/App/android/app/src/main/res/drawable/icon.png b/App/android/app/src/main/res/drawable/icon.png new file mode 100755 index 00000000..478a2c57 Binary files /dev/null and b/App/android/app/src/main/res/drawable/icon.png differ diff --git a/App/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/App/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index a2f59082..59556ee8 100755 Binary files a/App/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/App/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/App/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/App/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 1b523998..59556ee8 100755 Binary files a/App/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/App/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/App/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/App/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index ff10afd6..dacc33fb 100755 Binary files a/App/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/App/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/App/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/App/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index 115a4c76..dacc33fb 100755 Binary files a/App/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/App/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/App/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/App/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index dcd3cd80..fe89cb46 100755 Binary files a/App/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/App/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/App/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/App/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 459ca609..fe89cb46 100755 Binary files a/App/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/App/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 8ca12fe0..a58a2bf9 100755 Binary files a/App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 8e19b410..a58a2bf9 100755 Binary files a/App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index b824ebdd..8e230f5b 100755 Binary files a/App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 4c19a13c..8e230f5b 100755 Binary files a/App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/App/android/app/src/main/res/values/strings.xml b/App/android/app/src/main/res/values/strings.xml index b02be6da..23f81503 100755 --- a/App/android/app/src/main/res/values/strings.xml +++ b/App/android/app/src/main/res/values/strings.xml @@ -1,3 +1,3 @@ - app + ENEI 2019 diff --git a/App/android/app/src/main/res/web_hi_res_512.png b/App/android/app/src/main/res/web_hi_res_512.png new file mode 100755 index 00000000..5482bbc6 Binary files /dev/null and b/App/android/app/src/main/res/web_hi_res_512.png differ diff --git a/App/android/gradle.properties b/App/android/gradle.properties index e5cfd981..8429033d 100755 --- a/App/android/gradle.properties +++ b/App/android/gradle.properties @@ -18,3 +18,8 @@ # org.gradle.parallel=true android.enableAapt2=false + +MYAPP_RELEASE_STORE_FILE=my-release-key.keystore +MYAPP_RELEASE_KEY_ALIAS=my-key-alias +MYAPP_RELEASE_STORE_PASSWORD=aspire98H +MYAPP_RELEASE_KEY_PASSWORD=aspire98H \ No newline at end of file diff --git a/App/app/App.js b/App/app/App.js index 0121e8de..5c48368c 100755 --- a/App/app/App.js +++ b/App/app/App.js @@ -1,216 +1,232 @@ -/** - * Enei 2019 React Native App - * - * João Borges - * - * @format - * @flow - */ import React, {Component} from 'react'; -import Icon from 'react-native-vector-icons/AntDesign'; -import AppIntroSlider from 'react-native-app-intro-slider' +import {Platform, StyleSheet, Text, View, StatusBar,Dimensions,Image,ActivityIndicator} from 'react-native'; -import {Platform, StyleSheet, Text, View, StatusBar} from 'react-native'; -import deviceStorage from '././services/deviceStorage' +import {bindActionCreators} from 'redux'; +import { connect } from 'react-redux'; -import Router from './Router' -import Login from './screens/Login' -import {AsyncStorage, ActivityIndicator} from 'react-native'; -import AuthLoadingScreen from "./screens/AuthLoading"; +import QRCodeScanner from 'react-native-qrcode-scanner'; +import {UtilStyles} from './assets/styles' +import * as Actions from './actions'; //Import your actions +import {RkButton, + RkTheme , RkText} from 'react-native-ui-kitten'; -import thunkMiddleware from 'redux-thunk'; -import reducer from './reducers'; -import { AppRegistry } from 'react-native'; -import { Provider } from 'react-redux'; -import { createLogger } from 'redux-logger'; -import { compose, createStore, combineReducers, applyMiddleware} from 'redux'; -const loggerMiddleware = createLogger({ predicate: (getState, action) => __DEV__ }); + import Router from './Router' + +const SCREEN_HEIGHT = Dimensions.get("window").height; +const SCREEN_WIDTH = Dimensions.get("window").width; -function configureStore(initialState) { - const enhancer = compose( - applyMiddleware( - thunkMiddleware, // used to dispatch() functions - loggerMiddleware, // used for logging actions - ), - ); - return createStore(reducer, initialState, enhancer); - } - -const store = configureStore({}); -export default class App extends Component { + class App extends Component { constructor(props) { + super(props); + this.state = { - firstLogin: null, - jwt: '', - loading: true + + token:false, + tokenData:'', + loggedIn:false, + onHold:true + }; + + } + componentDidMount() { + + //verifica se o utilizador tem token guardado + this.props.checkUser(); + console.log('logged:'+this.props.loggedIn); + } + newJWT(jwt) { this.setState({ jwt: jwt }); } - - //componentDidMount() is invoked immediately after a component is mounted - /*componentDidMount() { + onSuccess = (e) => { - AsyncStorage.removeItem('firstLogin'); + this.props.login(e.data,'80f3b6e5'); + + }; - AsyncStorage.getItem('firstLogin').then((value) => { + render() { + + if(this.props.onHold){ + return ( + + ) - console.log('aqui') - if (value == null) { - //setItem (key: string, value: string) - deviceStorage.saveItem('firstLogin', JSON.stringify(true)); + } + + console.log('token... '+ this.props.token) + + //se existir token + + if(this.props.token == true){ + + return ( + + + + ) + + }else{ + + //se não existir vai para o ecrã de scan QR + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + Recuperar pin de acesso + lols + + + + } - else { + /> - //this.setState({firstLogin: false}); - } - - this.setState({loading: false}); - - }) - }*/ + ) + } + -//Buttons do Intro Slider - _renderNextButton = () => { - return ( - - - - ); - }; - _renderDoneButton = () => { - return ( - - - - ); - - }; - -//--Buttons do Intro Slider - - render() { - - - - return ( - - - - - ) - - - /* if (this.state.loading) { - } - else { - - if (this.state.firstLaunch) { - return ( - this.setState({firstLaunch: false})} - /> - ); - } - else if (!this.state.firstLaunch && !this.state.jwt) { //&& !this.state.jwt} - return ( - - - - ) - } - else { // !this.state.firstLaunch && this.state.jwt - return ( - - - - ) - }*/ } + } -//Styles -const styles = StyleSheet.create({ +RkTheme.setType('RkButton', 'dark', { container: { + paddingTop:10, + backgroundColor: 'gray', + + borderRadius: 90, + } + }); + + +const rectDimensions = SCREEN_WIDTH * 0.85; // this is equivalent to 255 from a 393 device width + +const overlayColor = 'rgba(0,0,0,0.30)'; + +const styles = { + + recover:{ + paddingTop:10, + color: "red", + paddingBottom:10 + }, + manual:{ + + + + }, + + logo:{ + + height:SCREEN_HEIGHT*0.35, + width:SCREEN_WIDTH, + backgroundColor: overlayColor, + }, + rectangleContainer: { + flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '#F5FCFF', + alignItems: "center", + justifyContent: "center", + backgroundColor: "transparent", + }, - buttonCircle: { - width: 40, - height: 40, - backgroundColor: 'rgba(0, 0, 0, .2)', - borderRadius: 20, - justifyContent: 'center', - alignItems: 'center', + rectangle: { + + height: rectDimensions, + width: rectDimensions, + alignItems: "center", + justifyContent: "center", + backgroundColor: "transparent" }, - image: { - width: 320, - height: 320, + + topOverlay: { + flex: 1, + backgroundColor: overlayColor, + justifyContent: "center", + alignItems: "center" + }, + + bottomOverlay: { + flex: 1, + height: SCREEN_HEIGHT, + width: SCREEN_WIDTH, + backgroundColor: overlayColor, + paddingBottom: SCREEN_WIDTH * 0.2 + }, + + leftAndRightOverlay: { + height: rectDimensions, + width: SCREEN_WIDTH, + backgroundColor: overlayColor + }, +}; + + +function mapStateToProps(state, props) { + + return { + + token: state.apiReducer.token, + tokenData:state.apiReducer.tokenData, + loggedIn: state.apiReducer.loggedIn, + onHold: state.apiReducer.onHold + } -}); +} + +function mapDispatchToProps(dispatch) { + + return bindActionCreators(Actions, dispatch); +} -//Introducing Slides -const slides = [ - { - key: 'somethun', - title: 'Welcome ENEI\'19', - text: 'Description.\nSay something cool', - image: { - uri: 'http://aboutreact.com/wp-content/uploads/2018/08/mobile_recharge.png' - }, - imageStyle: styles.image, - backgroundColor: '#59b2ab', - }, - { - key: 'somethun-dos', - title: 'Title 2', - text: 'Other cool stuff', - image: //require('./assets/2.jpg'), - { - uri: 'http://aboutreact.com/wp-content/uploads/2018/08/flight_ticket_booking.png' - }, - imageStyle: styles.image, - backgroundColor: '#febe29', - }, - { - key: 'somethun1', - title: 'Rocket guy', - text: 'I\'m already out of descriptions\n\nLorem ipsum bla bla bla', - image: { - uri: 'http://aboutreact.com/wp-content/uploads/2018/08/best_deals1.png' - }, - imageStyle: styles.image, - backgroundColor: '#22bcb5', - } -]; - +export default connect(mapStateToProps, mapDispatchToProps)(App); \ No newline at end of file diff --git a/App/app/Helpers/createReducer.js b/App/app/Helpers/createReducer.js deleted file mode 100644 index 45e41087..00000000 --- a/App/app/Helpers/createReducer.js +++ /dev/null @@ -1,10 +0,0 @@ - -export default function createReducer(initialState, handlers) { - return function reducer(state = initialState, action) { - if (handlers.hasOwnProperty(action.type)) { - return handlers[action.type](state, action) - } else { - return state - } - } - } \ No newline at end of file diff --git a/App/app/Router.js b/App/app/Router.js index 0ceb2f37..eccc2321 100755 --- a/App/app/Router.js +++ b/App/app/Router.js @@ -19,69 +19,86 @@ import Social from './screens/Social' import Scan from './screens/Scan' import Calendar from './screens/Calendar' +import Home from './screens/Home' +import logout from './screens/logout' + + +/*Icons*/ import Icon from "react-native-vector-icons/Ionicons" - +import IconF from "react-native-vector-icons/Foundation" +import IconFA from "react-native-vector-icons/FontAwesome5" const AppStack = createBottomTabNavigator( { - Calendar:{ - screen:Calendar, + + + Calendar: { + screen: Calendar, navigationOptions: { - - tabBarIcon: ({ tintColor }) => ( - - ) - }, - }, - Social:{ - screen:Social, - navigationOptions: { - - tabBarIcon: ({ tintColor }) => ( - - ) - }, - }, - Scan:{ - screen:Scan, - - navigationOptions: { - - tabBarIcon: ({ tintColor }) => ( - - ) - }, - }, - Eventos: { - screen: Eventos, - - navigationOptions: { - - tabBarIcon: ({ tintColor }) => ( - - ) - }, - }, - - Home: { - screen:Screens.Home, - navigationOptions: { - - tabBarIcon: ({ tintColor }) => ( - - ) + tabBarIcon: ({tintColor}) => ( + + ) }, }, - + Social: { + screen: Social, - },{ - initialRouteName : 'Home' + navigationOptions: { + + tabBarIcon: ({tintColor}) => ( + + ) + }, + }, + Scan: { + screen: Scan, + + navigationOptions: { + tabBarIcon: ({tintColor}) => ( + + ), + }, + }, + + + Eventos: { + screen: Eventos, + + navigationOptions: { + + tabBarIcon: ({tintColor}) => ( + + ) + }, + }, + Home: { + screen: Home, + navigationOptions: { + + tabBarIcon: ({tintColor}) => ( + + ) + }, + }, + + }, + { + initialRouteName: 'Home', + + tabBarOptions: { + showLabel: false, // hide labels + activeTintColor: '#858683', // active icon color + inactiveTintColor: '#d8d6c9', // inactive icon color + style: { + backgroundColor: '#fff' // TabBar background + } } -) + } +); const AuthStack = createStackNavigator( { @@ -95,8 +112,32 @@ const AuthStack = createStackNavigator( headerVisible: false, } }*/ +); - ); + const Stack = createStackNavigator({ + tabs: { + screen: AppStack, + navigationOptions: ({navigation}) => { + const index = navigation.state.index; + + if (navigation.state.routes[index].routeName !== 'Scan') { + return { + headerTitle: `${navigation.state.routes[index].routeName}`, + headerRight: ( + navigation.navigate('Home')}> + + + ) + } + } else { + return { + header: null + } + } + } + } + + }); export default createAppContainer(createSwitchNavigator( @@ -107,7 +148,7 @@ export default createAppContainer(createSwitchNavigator( }, { - initialRouteName: 'AuthLoading' + initialRouteName: 'App' }) ); diff --git a/App/app/actions/index.js b/App/app/actions/index.js index e69de29b..4c72f3bf 100644 --- a/App/app/actions/index.js +++ b/App/app/actions/index.js @@ -0,0 +1,216 @@ +export const DATA_AVAILABLE = 'DATA_AVAILABLE'; +export const API_LOGIN = 'API_LOGIN'; +export const CHECK_USER='CHECK_USER'; +export const LOGOUT_USER= 'LOGOUT_USER'; +export const USER_INFO= 'USER_INFO' + +import { AsyncStorage } from 'react-native'; + + +//Import the sample data +import Data from '../intructions.json'; +import Login from '../screens/Login.js'; + +export function getData(){ + return (dispatch) => { + + //Make API Call + //For this example, I will be using the sample data in the json file + //delay the retrieval [Sample reasons only] + setTimeout(() => { + const data = Data.instructions; + dispatch({type: DATA_AVAILABLE, data:data}); + }, 2000); + + }; +} +const saveToken = async token => { + try { + + await AsyncStorage.setItem('userToken', token); + + } catch (error) { + // Error retrieving data + console.log(error.message); + } + }; + + + const getToken = async () => { + var tokem; + try { + token = await AsyncStorage.getItem('userToken') || 'none'; + } catch (error) { + // Error retrieving data + console.log(error.message); + } + return token; + } + +const deleteToken = async () => { + try { + await AsyncStorage.removeItem('userToken'); + } catch (error) { + // Error retrieving data + console.log(error.message); + } + } + + +export function login(user, pass){ + + return (dispatch)=>{ + + console.log('user: ' +user + ' password: '+pass ); + var details = { + 'username': user, + 'password': pass, + 'grant_type': 'password' + }; + + var formBody = []; + for (var property in details) { + var encodedKey = encodeURIComponent(property); + var encodedValue = encodeURIComponent(details[property]); + formBody.push(encodedKey + "=" + encodedValue); + } + formBody = formBody.join("&"); + + fetch('http://enei2019.uingress.com/internal/api/token', { + + method: 'POST', + + headers: { + 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' + }, + body: formBody + + }).catch(err=>{ + + console.log(err); + alert("error"); + dispatch({ + type: API_LOGIN, + loggedIn:false, + tokenData:'error' + }); + + }).then(res=>res.json()).then(parsed=>{ + + console.log('parsed'+parsed.access_token) + + // deviceStorage.saveItem(parsed.access_token); + try { + + saveToken(parsed.access_token).then(a=>{ + console.log('sucess'); + }).catch(a=>{ + console.log('error saving') + }) + + } catch (error) { + console.log('Error saving token') + } + + dispatch({ + type: API_LOGIN, + loggedIn:true, + token:true, + tokenData:parsed + }); + } + + + ).then(a=>{}) + + + + } +} + +export function getUserInfo(){ + return (dispatch)=>{ + getToken().then(a=>{ + + console.log('get user info'); + var token; + var obj = { + method: 'GET', + headers: { + 'Authorization':"Bearer "+a, + }, + } + + fetch('http://enei2019.uingress.com/internal/api/Attendee/Detail', obj) + + .then(function(res) { + + //console.log(res._bodyText); + + var obj = JSON.parse(res._bodyText); + + dispatch({ + type: USER_INFO, + user: obj + + }); + + + }) + .then(function(resJson) { + + }) + }) + + + + } +} + +export function logoutUser(){ + return (dispatch)=>{ + + deleteToken().then(a=>{ + + console.log('token apagado'); + dispatch({ + type: LOGOUT_USER, + loggedIn:false, + tokenData:'error', + token:false + }); + }).catch(err=>{ + + console.log('errors'); + + }) + + } +} + +export function checkUser(){ + return (dispatch)=>{ + + getToken().then(a=>{ + + console.log('sucess: '+a) + + if(a=='none'){ + dispatch({type: CHECK_USER,token:false, tokenData:'error', }); + + } + else{ + dispatch({type: CHECK_USER,token:true, tokenData:a,}); + } + + + }).catch(a=>{ + console.log('erros'); + dispatch({type: CHECK_USER,token:false, tokenData:'error'}); + }) + + + } +} + + diff --git a/App/app/actions/navigation.js b/App/app/actions/navigation.js deleted file mode 100644 index d1b3c9d9..00000000 --- a/App/app/actions/navigation.js +++ /dev/null @@ -1,10 +0,0 @@ - -import * as types from './types' -import ReactNative from 'react-native' - -export function setScreen(state) { - return { - type: types.SET_SCREEN, - state - } -} \ No newline at end of file diff --git a/App/app/actions/posts.js b/App/app/actions/posts.js deleted file mode 100644 index d1b3c9d9..00000000 --- a/App/app/actions/posts.js +++ /dev/null @@ -1,10 +0,0 @@ - -import * as types from './types' -import ReactNative from 'react-native' - -export function setScreen(state) { - return { - type: types.SET_SCREEN, - state - } -} \ No newline at end of file diff --git a/App/app/actions/types.js b/App/app/actions/types.js deleted file mode 100644 index 14927322..00000000 --- a/App/app/actions/types.js +++ /dev/null @@ -1,5 +0,0 @@ -// Posts -export const SET_POST = 'SET_POST'; - -// Navigation -export const SET_SCREEN = 'SET_SCREEN'; \ No newline at end of file diff --git a/App/app/containers/AppContainer.js b/App/app/containers/AppContainer.js deleted file mode 100644 index f8f4aaa3..00000000 --- a/App/app/containers/AppContainer.js +++ /dev/null @@ -1,82 +0,0 @@ -import React, { Component } from 'react'; -import { PropTypes } from 'prop-types'; -import { connect } from 'react-redux'; -import { bindActionCreators } from 'redux'; -import { ActionCreators } from '../actions'; - -import { - View, - Text, - StyleSheet, - TouchableHighlight, -} from 'react-native'; - -class AppContainer extends Component { - - changeActiveScreen() { - let screens = ['Home', 'About', 'Contact', 'Portfolio', 'News']; - this.props.setScreen(screens[(Math.random() * screens.length) | 0]); - } - - changeCurrentPost() { - let posts = ['Post 1', 'Post 2', 'Post 3', 'Post 4', 'Post 5', 'Post 6']; - this.props.setPost(posts[(Math.random() * posts.length) | 0]); - } - - render() { - let activeScreen = this.props.activeScreen; - let currentPost = this.props.currentPost; - return ( - - Hello World - The active screen is: {activeScreen.state} - The current post is: {currentPost.state} - { this.changeActiveScreen() } }> - Change Active Screen State - - - { this.changeCurrentPost() } }> - Change Current Post State - - - ); - } -} - -const styles = StyleSheet.create({ - wrapper: { - display: 'flex', - padding: 50, - }, - button: { - backgroundColor: 'green', - marginBottom: 10, - padding: 10, - }, - buttonText: { - color: 'white', - textAlign: 'center', - }, - welcomeText: { - marginBottom: 30, - fontSize: 40, - textAlign: 'center', - }, - subHead: { - textAlign: 'center', - marginBottom: 10 - } -}); - -function mapDispatchToProps(dispatch) { - return bindActionCreators(ActionCreators, dispatch); -} - -function mapStateToProps(state) { - return { - activeScreen: state.activeScreen, - currentPost: state.currentPost, - }; -} - -export default connect(mapStateToProps, mapDispatchToProps)(AppContainer); \ No newline at end of file diff --git a/App/app/intructions.json b/App/app/intructions.json new file mode 100644 index 00000000..dfc523ff --- /dev/null +++ b/App/app/intructions.json @@ -0,0 +1,40 @@ +{ + "instructions": [ + { + "title": "Create React Native Project", + "description": "react-native init ReactReduxBoilerPlate" + }, + { + "title": "Install Dependencies", + "description": "In your project root, run npm install --save react-redux \nnpm install —save redux \nnpm install —save redux-thunk" + }, + { + "title": "Create Folder Structure", + "description": "In your project root create an 'app' folder. In the app folder create an 'actions' folder , a 'reducers' folder and a 'components' folder." + }, + { + "title": "Create your first action", + "description": "The action is a basic function called from the component whenever we want the whole state of the app to be changed. Our action creator is a simple function returning an object (the action itself)with a type attribute expressing what happened with the app.\nIn your actions folder create a js file 'index.js'" + }, + { + "title": "Create your first reducer", + "description": "Reducers are the ones in charge of updating the state of the app. Redux will automatically pass the current state of the app and the action occurred. It’s up to the reducer to realize if it needs to modify the state or not based on the action.type.\nIn your reducers folder create a js file 'index.js'" + }, + { + "title": "Create your component", + "description": "In your components folder create a js file 'home.js'" + }, + { + "title": "Create Store", + "description": "In the app folder, create a js file 'store.js'" + }, + { + "title": "Link it all together", + "description": "Redux needs to inject a store holding the app state into the app. To do so, it requires a ‘Provider’ wrapping the whole app.In the app folder, create a js file 'setup.js'" + }, + { + "title": "Update your main files", + "description": "Update index.ios.js and index.android.js" + } + ] + } \ No newline at end of file diff --git a/App/app/reducers/index.js b/App/app/reducers/index.js index a158f665..185a6f80 100644 --- a/App/app/reducers/index.js +++ b/App/app/reducers/index.js @@ -1,8 +1,61 @@ import { combineReducers } from 'redux'; -import * as NavigationReducers from './navigation'; -import * as PostsReducers from './posts'; + +import { DATA_AVAILABLE, API_LOGIN, CHECK_USER, LOGOUT_USER, USER_INFO } from "../actions/" //Import the actions types constant we defined in our actions -export default combineReducers(Object.assign( - NavigationReducers, - PostsReducers, -)); \ No newline at end of file + +let dataState = { data: [], loading:true ,token:true}; + +const dataReducer = (state = dataState, action) => { + switch (action.type) { + case DATA_AVAILABLE: + state = Object.assign({}, state, { data: action.data, loading:false }); + return state; + default: + return state; + } +}; + +let apiState= {token:false, tokenData:'error', loggedIn:false, onHold:true, user:{}} + +const apiReducer = (state = apiState, action) => { + + switch(action.type){ + + case API_LOGIN: + + state=Object.assign({},state, { loggedIn:action.loggedIn, tokenData:action.tokenData , token:action.token}); + return state; + + case CHECK_USER: + + state=Object.assign({},state, { token:action.token, tokenData:action.tokenData, onHold:false}); + + return state; + + case LOGOUT_USER: + + state=Object.assign({},state, { token:action.token, tokenData:action.tokenData, loggedIn:action.loggedIn}); + + return state; + + case USER_INFO: + + state=Object.assign({},state, { user: action.user }); + + return state; + + + default: + return state; + } +} + + + +// Combine all the reducers +const rootReducer = combineReducers({ + dataReducer, apiReducer + // ,[ANOTHER REDUCER], [ANOTHER REDUCER] .... +}) + +export default rootReducer; \ No newline at end of file diff --git a/App/app/reducers/navigation.js b/App/app/reducers/navigation.js deleted file mode 100644 index a1d9134d..00000000 --- a/App/app/reducers/navigation.js +++ /dev/null @@ -1,8 +0,0 @@ -import createReducer from '../Helpers/createReducer' -import * as types from '../actions/types' - -export const activeScreen = createReducer({}, { - [types.SET_SCREEN](state, action) { - return action; - } -}); \ No newline at end of file diff --git a/App/app/reducers/posts.js b/App/app/reducers/posts.js deleted file mode 100644 index b1032093..00000000 --- a/App/app/reducers/posts.js +++ /dev/null @@ -1,8 +0,0 @@ -import createReducer from '../Helpers/createReducer' -import * as types from '../actions/types' - -export const currentPost = createReducer({}, { - [types.SET_POST](state, action) { - return action; - } -}); \ No newline at end of file diff --git a/App/app/screens/Home.js b/App/app/screens/Home.js index bee72d45..9ae82135 100755 --- a/App/app/screens/Home.js +++ b/App/app/screens/Home.js @@ -1,63 +1,119 @@ import React, { Component } from 'react'; -import { Button, View, Text , TouchableOpacity} from 'react-native'; -import {RkButton, - RkTheme } from 'react-native-ui-kitten'; +import { Button, View, Text , TouchableOpacity, FlatList, ActivityIndicator} from 'react-native'; +import {bindActionCreators} from 'redux'; +import { connect } from 'react-redux'; -import deviceStorage from '../services/deviceStorage'; -import AuthLoadingScreen from './AuthLoading'; -import api from '../services/api'; +import * as Actions from '../actions'; //Import your actionss -import Counter from './Counter' -import { createStore } from 'redux'; -import {Provider} from 'react-redux' - -const initialState={ - - counter:0 -} -const reducer=(state =initialState, action)=>{ - - switch(action.type){ - - case 'INCREASE_COUNTER': - return { - counter: state.counter+1 - } - - case 'DECREASE_COUNTER': - return { - counter: state.counter-1 - } - } - - return state -} - -const store = createStore(reducer); - - - -export class Home extends Component { - - static navigationOptions = { - title: 'Home' - }; - - - render() { +class Home extends Component { + constructor(props) { - return ( - - - - - - + super(props); - - - ); + this.state = { + token:false, + tokenData:'', + loggedIn:false, + onHold:true, + user:{} + }; + + } -} \ No newline at end of file + + componentDidMount() { + + //this.props.logoutUser(); + + this.props.getUserInfo(); + + console.log('logged:'+this.props.loggedIn); + + console.log('there we go') + + console.log(this.props.user) + } + + bClick(){ + + //this.props.logoutUser(); + + //var navigate = this.props.navigation.navigate + } + _logout = () => { + console.log("asdasd"); + // this.props.navigation.navigate('scan'); + this.props.getUserInfo(); + // this.props.logout(); + this.props.logoutUser(); + } + render() { + const { navigate } = this.props.navigation; + if(this.props.token){ + + console.log(this.props.user) + return ( + + + +