This commit is contained in:
henrydays 2019-01-31 00:46:49 +00:00
parent 15df6375b8
commit f982d8c158
94 changed files with 825 additions and 427 deletions

0
.gitignore vendored Normal file → Executable file
View File

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

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

View File

@ -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 (
<ActivityIndicator size="large" color="#0000ff" />
)
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 (
<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>
}
else {
/>
//this.setState({firstLogin: false});
}
this.setState({loading: false});
})
}*/
)
}
//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>
);
};
_renderDoneButton = () => {
return (
<View style={styles.buttonCircle}>
<Icon
name='check'
color='rgba(255, 255, 255, .9)'
size={24}
style={{backgroundColor: 'transparent'}}
/>
</View>
);
};
//--Buttons do Intro Slider
render() {
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>
)
}*/
}
}
//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);

View File

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

View File

@ -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 }) => (
<Icon name="ios-beer" size={30}/>
)
},
},
Social:{
screen:Social,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-mail" size={30}/>
)
},
},
Scan:{
screen:Scan,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-qr-scanner" size={30}/>
)
},
},
Eventos: {
screen: Eventos,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-beer" size={30}/>
)
},
},
Home: {
screen:Screens.Home,
navigationOptions: {
tabBarIcon: ({ tintColor }) => (
<Icon name="md-person" size={30}/>
)
tabBarIcon: ({tintColor}) => (
<IconF name="calendar" color={tintColor} size={30}/>
)
},
},
Social: {
screen: Social,
},{
initialRouteName : 'Home'
navigationOptions: {
tabBarIcon: ({tintColor}) => (
<Icon name="ios-mail" color={tintColor} size={30}/>
)
},
},
Scan: {
screen: Scan,
navigationOptions: {
tabBarIcon: ({tintColor}) => (
<Icon name="ios-qr-scanner" color={tintColor} size={45}/>
),
},
},
Eventos: {
screen: Eventos,
navigationOptions: {
tabBarIcon: ({tintColor}) => (
<Icon name="ios-beer" color={tintColor} size={30}/>
)
},
},
Home: {
screen: Home,
navigationOptions: {
tabBarIcon: ({tintColor}) => (
<Icon name="md-home" color={tintColor} size={30}/>
)
},
},
},
{
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'
})
);

View File

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

View File

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

View File

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

View File

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

View File

@ -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 Normal file
View File

@ -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. Its 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"
}
]
}

View File

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

View File

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

View File

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

View File

@ -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 (
<Provider store={store}>
<View style={{flex:1, alignItems: 'center', alignContent: 'center'}}>
<Counter></Counter>
</View>
super(props);
</Provider>
);
this.state = {
token:false,
tokenData:'',
loggedIn:false,
onHold:true,
user:{}
};
}
}
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 (
<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 (
<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);

View File

@ -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 Normal file
View File

@ -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 Normal file
View File

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

View File

@ -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 generated
View File

@ -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",

View File

@ -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",

2
README.md Normal file → Executable file
View File

@ -7,8 +7,6 @@
- [Henrique Dias]()
- [Filipe Pinho]()
- [João Borges]()
- [Zé Valdeviesso]()

0
api/.gitignore vendored Normal file → Executable file
View File

0
api/.vscode/launch.json vendored Normal file → Executable file
View File

0
api/.vscode/tasks.json vendored Normal file → Executable file
View File

0
api/Controllers/AdminController.cs Normal file → Executable file
View File

0
api/Controllers/AuthController.cs Normal file → Executable file
View File

0
api/Controllers/TalksController.cs Normal file → Executable file
View File

0
api/Controllers/UsersController.cs Normal file → Executable file
View File

0
api/Controllers/ValuesController.cs Normal file → Executable file
View File

0
api/Controllers/errorController.cs Normal file → Executable file
View File

0
api/Controllers/mvcController.cs Normal file → Executable file
View File

0
api/Data/AuthRepository.cs Normal file → Executable file
View File

0
api/Data/DataContext.cs Normal file → Executable file
View File

0
api/Data/IAuthRepository.cs Normal file → Executable file
View File

0
api/Data/IUsersRepository.cs Normal file → Executable file
View File

0
api/Data/UsersRepository.cs Normal file → Executable file
View File

0
api/Dtos/PhotosForDetailedDto.cs Normal file → Executable file
View File

0
api/Dtos/RoleEditDto.cs Normal file → Executable file
View File

0
api/Dtos/UserForDetailedDto.cs Normal file → Executable file
View File

0
api/Dtos/UserForListDto.cs Normal file → Executable file
View File

0
api/Dtos/UserForLoginDto.cs Normal file → Executable file
View File

0
api/Dtos/UserForRegisterDto.cs Normal file → Executable file
View File

0
api/Dtos/UserForUpdateDto.cs Normal file → Executable file
View File

0
api/Dtos/setRoleDto.cs Normal file → Executable file
View File

0
api/Helpers/AutoMapperProfiles.cs Normal file → Executable file
View File

0
api/Helpers/Extensions.cs Normal file → Executable file
View File

0
api/Migrations/20180829184152_update.Designer.cs generated Normal file → Executable file
View File

0
api/Migrations/20180829184152_update.cs Normal file → Executable file
View File

0
api/Migrations/DataContextModelSnapshot.cs Normal file → Executable file
View File

0
api/Models/Event.cs Normal file → Executable file
View File

0
api/Models/EventLoc.cs Normal file → Executable file
View File

0
api/Models/EventLocVisited.cs Normal file → Executable file
View File

0
api/Models/EventQR.cs Normal file → Executable file
View File

0
api/Models/Photo.cs Normal file → Executable file
View File

0
api/Models/Role.cs Normal file → Executable file
View File

0
api/Models/Team.cs Normal file → Executable file
View File

0
api/Models/User.cs Normal file → Executable file
View File

0
api/Models/UserRole.cs Normal file → Executable file
View File

0
api/Models/Value.cs Normal file → Executable file
View File

0
api/Program.cs Normal file → Executable file
View File

0
api/Properties/launchSettings.json Normal file → Executable file
View File

0
api/Startup.cs Normal file → Executable file
View File

0
api/Views/Landing/404.cshtml Normal file → Executable file
View File

0
api/Views/Landing/index.cshtml Normal file → Executable file
View File

0
api/api.csproj Normal file → Executable file
View File

0
api/api.db Normal file → Executable file
View File

0
api/appsettings.Development.json Normal file → Executable file
View File

0
api/appsettings.json Normal file → Executable file
View File

0
api/readme.md Normal file → Executable file
View File

0
api/wwwroot/.gitignore vendored Normal file → Executable file
View File

0
api/wwwroot/error-page.html Normal file → Executable file
View File

0
api/wwwroot/group-ticket.html Normal file → Executable file
View File

0
api/wwwroot/single-ticket.html Normal file → Executable file
View File