Browse Source

merge

Borges
henrydays 3 years ago
parent
commit
f982d8c158
  1. 0
      .gitignore
  2. 11
      App/android/app/build.gradle
  3. BIN
      App/android/app/src/main/res/drawable-hdpi/icon.png
  4. BIN
      App/android/app/src/main/res/drawable-ldpi/icon.png
  5. BIN
      App/android/app/src/main/res/drawable-mdpi/icon.png
  6. BIN
      App/android/app/src/main/res/drawable-xhdpi/icon.png
  7. BIN
      App/android/app/src/main/res/drawable-xxhdpi/icon.png
  8. BIN
      App/android/app/src/main/res/drawable-xxxhdpi/icon.png
  9. BIN
      App/android/app/src/main/res/drawable/icon.png
  10. BIN
      App/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
  11. BIN
      App/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  12. BIN
      App/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
  13. BIN
      App/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  14. BIN
      App/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
  15. BIN
      App/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  16. BIN
      App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  17. BIN
      App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  18. BIN
      App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  19. BIN
      App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  20. 2
      App/android/app/src/main/res/values/strings.xml
  21. BIN
      App/android/app/src/main/res/web_hi_res_512.png
  22. 5
      App/android/gradle.properties
  23. 358
      App/app/App.js
  24. 10
      App/app/Helpers/createReducer.js
  25. 127
      App/app/Router.js
  26. 216
      App/app/actions/index.js
  27. 10
      App/app/actions/navigation.js
  28. 10
      App/app/actions/posts.js
  29. 5
      App/app/actions/types.js
  30. 82
      App/app/containers/AppContainer.js
  31. 40
      App/app/intructions.json
  32. 65
      App/app/reducers/index.js
  33. 8
      App/app/reducers/navigation.js
  34. 8
      App/app/reducers/posts.js
  35. 142
      App/app/screens/Home.js
  36. 4
      App/app/screens/Scan.js
  37. 72
      App/app/screens/logout.js
  38. 7
      App/app/store.js
  39. 14
      App/index.js
  40. 5
      App/package-lock.json
  41. 1
      App/package.json
  42. 2
      README.md
  43. 0
      api/.gitignore
  44. 0
      api/.vscode/launch.json
  45. 0
      api/.vscode/tasks.json
  46. 0
      api/Controllers/AdminController.cs
  47. 0
      api/Controllers/AuthController.cs
  48. 0
      api/Controllers/TalksController.cs
  49. 0
      api/Controllers/UsersController.cs
  50. 0
      api/Controllers/ValuesController.cs
  51. 0
      api/Controllers/errorController.cs
  52. 0
      api/Controllers/mvcController.cs
  53. 0
      api/Data/AuthRepository.cs
  54. 0
      api/Data/DataContext.cs
  55. 0
      api/Data/IAuthRepository.cs
  56. 0
      api/Data/IUsersRepository.cs
  57. 0
      api/Data/UsersRepository.cs
  58. 0
      api/Dtos/PhotosForDetailedDto.cs
  59. 0
      api/Dtos/RoleEditDto.cs
  60. 0
      api/Dtos/UserForDetailedDto.cs
  61. 0
      api/Dtos/UserForListDto.cs
  62. 0
      api/Dtos/UserForLoginDto.cs
  63. 0
      api/Dtos/UserForRegisterDto.cs
  64. 0
      api/Dtos/UserForUpdateDto.cs
  65. 0
      api/Dtos/setRoleDto.cs
  66. 0
      api/Helpers/AutoMapperProfiles.cs
  67. 0
      api/Helpers/Extensions.cs
  68. 0
      api/Migrations/20180829184152_update.Designer.cs
  69. 0
      api/Migrations/20180829184152_update.cs
  70. 0
      api/Migrations/DataContextModelSnapshot.cs
  71. 0
      api/Models/Event.cs
  72. 0
      api/Models/EventLoc.cs
  73. 0
      api/Models/EventLocVisited.cs
  74. 0
      api/Models/EventQR.cs
  75. 0
      api/Models/Photo.cs
  76. 0
      api/Models/Role.cs
  77. 0
      api/Models/Team.cs
  78. 0
      api/Models/User.cs
  79. 0
      api/Models/UserRole.cs
  80. 0
      api/Models/Value.cs
  81. 0
      api/Program.cs
  82. 0
      api/Properties/launchSettings.json
  83. 0
      api/Startup.cs
  84. 0
      api/Views/Landing/404.cshtml
  85. 0
      api/Views/Landing/index.cshtml
  86. 0
      api/api.csproj
  87. 0
      api/api.db
  88. 0
      api/appsettings.Development.json
  89. 0
      api/appsettings.json
  90. 0
      api/readme.md
  91. 0
      api/wwwroot/.gitignore
  92. 0
      api/wwwroot/error-page.html
  93. 0
      api/wwwroot/group-ticket.html
  94. 0
      api/wwwroot/single-ticket.html

0
.gitignore

11
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"
}

BIN
App/android/app/src/main/res/drawable-hdpi/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
App/android/app/src/main/res/drawable-ldpi/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
App/android/app/src/main/res/drawable-mdpi/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
App/android/app/src/main/res/drawable-xhdpi/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
App/android/app/src/main/res/drawable-xxhdpi/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
App/android/app/src/main/res/drawable-xxxhdpi/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
App/android/app/src/main/res/drawable/icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
App/android/app/src/main/res/mipmap-hdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
App/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
App/android/app/src/main/res/mipmap-mdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
App/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
App/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
App/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
App/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 11 KiB

BIN
App/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 11 KiB

2
App/android/app/src/main/res/values/strings.xml

@ -1,3 +1,3 @@
<resources>
<string name="app_name">app</string>
<string name="app_name">ENEI 2019</string>
</resources>

BIN
App/android/app/src/main/res/web_hi_res_512.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

5
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

358
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
});
}
onSuccess = (e) => {
this.props.login(e.data,'80f3b6e5');
};
render() {
if(this.props.onHold){
return (
<ActivityIndicator size="large" color="#0000ff" />
)
}
console.log('token... '+ this.props.token)
//se existir token
if(this.props.token == true){
return (
<Router></Router>
)
}else{
//se não existir vai para o ecrã de scan QR
return (
<QRCodeScanner
showMarker
onRead={this.onSuccess.bind(this)}
cameraStyle={{ height: SCREEN_HEIGHT }}
customMarker={
<View style={styles.rectangleContainer}>
<View style={styles.logo}>
<Image style={UtilStyles.loginImage}
source={require('./assets/img/logo.png')}
/>
</View>
<View style={{ flexDirection: "row" }}>
<View style={styles.leftAndRightOverlay}>
</View>
<View style={styles.rectangle}>
</View>
<View style={styles.leftAndRightOverlay}>
</View>
</View>
<View style={styles.bottomOverlay}>
<View style={{flex:1, alignItems: 'center', alignContent: 'center'}}>
<RkText rkType='primary' style={styles.recover}>Recuperar pin de acesso</RkText>
<RkButton rkType='dark' style={styles.manual}>lols</RkButton>
</View>
</View>
</View>
}
/>
//componentDidMount() is invoked immediately after a component is mounted
/*componentDidMount() {
)
}
AsyncStorage.removeItem('firstLogin');
AsyncStorage.getItem('firstLogin').then((value) => {
}
console.log('aqui')
if (value == null) {
//setItem (key: string, value: string)
deviceStorage.saveItem('firstLogin', JSON.stringify(true));
}
}
else {
//this.setState({firstLogin: false});
}
RkTheme.setType('RkButton', 'dark', {
container: {
paddingTop:10,
backgroundColor: 'gray',
borderRadius: 90,
}
});
this.setState({loading: false});
})
}*/
const rectDimensions = SCREEN_WIDTH * 0.85; // this is equivalent to 255 from a 393 device width
const overlayColor = 'rgba(0,0,0,0.30)';
//Buttons do Intro Slider
_renderNextButton = () => {
return (
<View style={styles.buttonCircle}>
<Icon
name='right'
color='rgba(255, 255, 255, .9)'
size={24}
style={{backgroundColor: 'transparent'}}/>
</View>
);
};
const styles = {
recover:{
paddingTop:10,
color: "red",
paddingBottom:10
},
manual:{
_renderDoneButton = () => {
return (
<View style={styles.buttonCircle}>
<Icon
name='check'
color='rgba(255, 255, 255, .9)'
size={24}
style={{backgroundColor: 'transparent'}}
/>
</View>
);
},
logo:{
};
height:SCREEN_HEIGHT*0.35,
width:SCREEN_WIDTH,
backgroundColor: overlayColor,
},
rectangleContainer: {
flex: 1,
alignItems: "center",
justifyContent: "center",
backgroundColor: "transparent",
},
//--Buttons do Intro Slider
rectangle: {
height: rectDimensions,
width: rectDimensions,
alignItems: "center",
justifyContent: "center",
backgroundColor: "transparent"
},
render() {
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 {
return (
<Provider store={store}>
<Router />
</Provider>
)
/* if (this.state.loading) {
}
else {
if (this.state.firstLaunch) {
return (
<AppIntroSlider
slides={slides}
renderDoneButton={this._renderDoneButton}
renderNextButton={this._renderNextButton}
onDone={() => this.setState({firstLaunch: false})}
/>
);
}
else if (!this.state.firstLaunch && !this.state.jwt) { //&& !this.state.jwt}
return (
<View style={{flex: 1}}>
<Login/>
</View>
)
}
else { // !this.state.firstLaunch && this.state.jwt
return (
<View style={{flex: 1}}>
<Routes />
</View>
)
}*/
token: state.apiReducer.token,
tokenData:state.apiReducer.tokenData,
loggedIn: state.apiReducer.loggedIn,
onHold: state.apiReducer.onHold
}
}
function mapDispatchToProps(dispatch) {
//Styles
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
return bindActionCreators(Actions, dispatch);
}
buttonCircle: {
width: 40,
height: 40,
backgroundColor: 'rgba(0, 0, 0, .2)',
borderRadius: 20,
justifyContent: 'center',
alignItems: 'center',
},
image: {
width: 320,
height: 320,
}
});
//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);

10
App/app/Helpers/createReducer.js

@ -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
}
}
}

127
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'
import Icon from "react-native-vector-icons/Ionicons"
/*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 }) => (
<Icon name="ios-beer" size={30}/>
)
},
tabBarIcon: ({tintColor}) => (
<IconF name="calendar" color={tintColor} size={30}/>
)
},
},
Social:{
screen:Social,
Social: {
screen: Social,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-mail" size={30}/>
)
},
tabBarIcon: ({tintColor}) => (
<Icon name="ios-mail" color={tintColor} size={30}/>
)
},
},
Scan:{
screen:Scan,
Scan: {
screen: Scan,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-qr-scanner" size={30}/>
)
},
tabBarIcon: ({tintColor}) => (
<Icon name="ios-qr-scanner" color={tintColor} size={45}/>
),
},
},
Eventos: {
screen: Eventos,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-beer" size={30}/>
)
},
Eventos: {
screen: Eventos,
navigationOptions: {
tabBarIcon: ({tintColor}) => (
<Icon name="ios-beer" color={tintColor} size={30}/>
)
},
},
Home: {
screen:Screens.Home,
screen: Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="md-person" size={30}/>
)
tabBarIcon: ({tintColor}) => (
<Icon name="md-home" color={tintColor} size={30}/>
)
},
},
},{
initialRouteName : 'Home'
},
{
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: (
<TouchableOpacity style={{marginRight: 20}} onPress={() => navigation.navigate('Home')}>
<IconFA name="user-edit" size={22}/>
</TouchableOpacity>
)
}
} else {
return {
header: null
}
}
}
}
});
export default createAppContainer(createSwitchNavigator(
@ -107,7 +148,7 @@ export default createAppContainer(createSwitchNavigator(
},
{
initialRouteName: 'AuthLoading'
initialRouteName: 'App'
})
);

216
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'});
})
}
}

10
App/app/actions/navigation.js

@ -1,10 +0,0 @@
import * as types from './types'
import ReactNative from 'react-native'
export function setScreen(state) {
return {
type: types.SET_SCREEN,
state
}
}

10
App/app/actions/posts.js

@ -1,10 +0,0 @@
import * as types from './types'
import ReactNative from 'react-native'
export function setScreen(state) {
return {
type: types.SET_SCREEN,
state
}
}

5
App/app/actions/types.js

@ -1,5 +0,0 @@
// Posts
export const SET_POST = 'SET_POST';
// Navigation
export const SET_SCREEN = 'SET_SCREEN';

82
App/app/containers/AppContainer.js

@ -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 (
<View style={styles.wrapper}>
<Text style={styles.welcomeText}>Hello World</Text>
<Text style={styles.subHead}>The active screen is: {activeScreen.state}</Text>
<Text style={styles.subHead}>The current post is: {currentPost.state}</Text>
<TouchableHighlight style={styles.button} onPress={ () => { this.changeActiveScreen() } }>
<Text style={styles.buttonText}>Change Active Screen State</Text>
</TouchableHighlight>
<TouchableHighlight style={styles.button} onPress={ () => { this.changeCurrentPost() } }>
<Text style={styles.buttonText}>Change Current Post State</Text>
</TouchableHighlight>
</View>
);
}
}
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);

40
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"
}
]
}

65
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,
));
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;

8
App/app/reducers/navigation.js

@ -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;
}
});

8
App/app/reducers/posts.js

@ -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;
}
});

142
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'
class Home extends Component {
const initialState={
constructor(props) {
super(props);
counter:0
}
const reducer=(state =initialState, action)=>{
this.state = {
token:false,
tokenData:'',
loggedIn:false,
onHold:true,
user:{}
};
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);
componentDidMount() {
//this.props.logoutUser();
this.props.getUserInfo();
console.log('logged:'+this.props.loggedIn);
export class Home extends Component {
console.log('there we go')
static navigationOptions = {
title: 'Home'
};
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 (
<View >
<Button onPress={this._logout} title="LOGOUT"/>
<Text></Text>
<Text>Nome: {this.props.user.Email}</Text>
<Text>city: {this.props.user.City}</Text>
<Text>phone: {this.props.user.Mobile}</Text>
</View>
);
}
else{
return (
<View >
<Text>sem permissões para aceder aqui</Text>
</View>
);
}
}
renderItem({item, index}) {
return (
<Provider store={store}>
<View style={{flex:1, alignItems: 'center', alignContent: 'center'}}>
<Counter></Counter>
</View>
</Provider>
);
<View>
<Text >
{(parseInt(index) + 1)}{". "}{item.title}
</Text>
<Text >
{item.description}
</Text>
</View>
)
}
}
}
function mapStateToProps(state, props) {
return {
token: state.apiReducer.token,
user: state.apiReducer.user
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(Actions, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(Home);

4
App/app/screens/Scan.js

@ -12,13 +12,12 @@ import {RkButton,
export default class Scan extends React.Component {
onSuccess = (e) => {
// console.log(e.data);
console.log(e);
console.log(e.data);
@ -38,6 +37,7 @@ export default class Scan extends React.Component {
render() {
return (
<View style={{flex: 1}}>
<Text> Camera Loading....</Text>
{ this.state.isRender &&
<QRCodeScanner />
}

72
App/app/screens/logout.js

@ -0,0 +1,72 @@
import React, { Component } from 'react';
import { Button, View, Text , TouchableOpacity, FlatList, ActivityIndicator} from 'react-native';
import {bindActionCreators} from 'redux';
import { connect } from 'react-redux';
import * as Actions from '../actions'; //Import your actionss
class logout extends Component {
constructor(props) {
super(props);
this.state = {
token:false,
tokenData:'',
loggedIn:false,
onHold:true
};
}
componentDidMount() {
console.log('logout')
this.props.logoutUser();
//this.props.navigation.navigate('Home');
}
render() {
const { navigate } = this.props.navigation;
return (
<View >
<Text>LOGGED OUT</Text>
</View>
);
}
}
function mapStateToProps(state, props) {
return {
token: state.apiReducer.token,
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(Actions, dispatch);
}
export default connect(mapStateToProps, mapDispatchToProps)(logout);

7
App/app/store.js

@ -0,0 +1,7 @@
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import reducers from './reducers/index'; //Import the reducer
// Connect our store to the reducers
export default createStore(reducers, applyMiddleware(thunk));

14
App/index.js

@ -2,10 +2,20 @@
import React from 'react';
import {AppRegistry} from 'react-native';
import {Provider} from 'react-redux';
import App from './app/App';
import {name as appName} from './app.json';
import store from './app/store'; //Import the store
import App from './app/App' //Import the component file
const RNRedux = () => (
<Provider store={store}>
<App />
</Provider>
);
AppRegistry.registerComponent(appName, () => RNRedux);
AppRegistry.registerComponent(appName, () => App);

5
App/package-lock.json

@ -6838,6 +6838,11 @@
"resolved": "https://registry.npmjs.org/react-native-ionicons/-/react-native-ionicons-4.5.5.tgz",
"integrity": "sha512-Pj1jFcwcOPG62EzWpLfu7UQwByd3SjTfjbs2WMPjmnfBuA6xiR8hh1+fflhpQ7Yv4j5cQuCSiR53uLbasxH/6Q=="
},
"react-native-loader": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/react-native-loader/-/react-native-loader-1.2.1.tgz",
"integrity": "sha1-4IWJqJz80HZZW5MBwdYY9U2nMyk="
},
"react-native-permissions": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/react-native-permissions/-/react-native-permissions-1.1.1.tgz",

1
App/package.json

@ -15,6 +15,7 @@
"react-native-confirmation-code-input": "^1.0.4",
"react-native-gesture-handler": "^1.0.15",
"react-native-ionicons": "^4.5.5",
"react-native-loader": "^1.2.1",
"react-native-qrcode-scanner": "^1.1.2",
"react-native-ui-kitten": "^3.1.2",
"react-native-vector-icons": "^6.1.0",