Commit f846183a authored by Wietse Kuipers's avatar Wietse Kuipers
Browse files

Merge branch 'feature-navigation' into 'master'

Feature navigation

See merge request !7
parents 90bce05a 668c87d0
export const LOGIN = 'LOGIN';
export const NAVIGATE = 'NAVIGATE';
export const BACK = 'BACK';
export const LOGINPROGRESS = 'LOGINPROGRESS';
export const LOGINSUCCESS = 'LOGINSUCCESS';
export const LOGINFAILURE = 'LOGINFAILURE';
export const OPENDRAWER = 'OPENDRAWER';
import * as types from './actionTypes';
export function login(username, password) {
export function loginSuccess(username, token) {
return {
type: types.LOGIN,
success: password === '42',
type: types.LOGINSUCCESS,
loginState: 'loggedIn',
username,
token,
};
}
export function loginProgress() {
return {
type: types.LOGINPROGRESS,
loginState: 'progress',
};
}
export function loginFailure() {
return {
type: types.LOGINFAILURE,
loginState: 'failure',
};
}
export function login(username, password) {
return (dispatch) => {
dispatch(loginProgress());
const data = {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
password,
}),
};
return fetch('http://localhost:8000/api/token-auth/', data)
.then(
response => response.json())
.then(
(responseJson) => {
if (responseJson.token) {
return dispatch(loginSuccess(username, responseJson.token));
}
return dispatch(loginFailure());
})
.catch(() => dispatch(loginFailure()));
};
}
......@@ -12,3 +12,10 @@ export function back() {
type: types.BACK,
};
}
export function updateDrawer(drawerState) {
return {
type: types.OPENDRAWER,
drawerOpen: drawerState,
};
}
import React from 'react';
import { Text, View } from 'react-native';
const Agenda = () =>
<View>
<Text>
Algemene Ledenvergadering
</Text>
<Text>
Lunchlezing Rijksoverheid
</Text>
<Text>
Benefietborrel
</Text>
</View>
;
export default Agenda;
......@@ -4,6 +4,17 @@ import { connect } from 'react-redux';
import * as actions from '../actions/login';
const loginResult = (status) => {
switch (status) {
case 'progress':
return 'Logging in';
case 'failure':
return 'Login failed';
default:
return '';
}
};
class Login extends Component {
constructor(props) {
super(props);
......@@ -14,7 +25,7 @@ class Login extends Component {
}
render() {
const { loginError, login } = this.props;
const { loginState, login } = this.props;
return (
<View>
<TextInput
......@@ -27,15 +38,15 @@ class Login extends Component {
onChangeText={password => this.setState({ password })}
/>
<Button title="Log in" onPress={() => login(this.state.username, this.state.password)} />
<Text>{ loginError ? 'Login faal' : '' }</Text>
<Text>{loginResult(loginState)}</Text>
</View>
);
}
}
Login.propTypes = {
loginState: React.PropTypes.string.isRequired,
login: React.PropTypes.func.isRequired,
loginError: React.PropTypes.bool.isRequired,
};
const mapStateToProps = state => state.login;
......
......@@ -10,8 +10,8 @@ const Sidebar = props =>
style={styles.sidebar}
>
<Text style={styles.header}>MENU</Text>
<Text onPress={() => props.navigate('login')} style={styles.button} >Log in</Text>
<Text onPress={() => props.navigate('welcome')} style={styles.button} >Welcome</Text>
<Text onPress={() => props.navigate('agenda')} style={styles.button} >Agenda</Text>
</View>
;
......
import React from 'react';
import { connect } from 'react-redux';
import Drawer from 'react-native-drawer';
import * as actions from '../actions/navigation';
import Login from './Login';
import Welcome from './Welcome';
import Sidebar from './Sidebar';
import Agenda from './Agenda';
// const mapStateToProps = state => state.currentScene;
import * as actions from '../actions/navigation';
const mapStateToProps = state => (
{ currentScene: state.navigation.currentScene }
);
const mapStateToProps = state => ({
currentScene: state.navigation.currentScene,
loggedIn: state.navigation.loggedIn,
drawerOpen: state.navigation.drawerOpen,
});
const mapDispatchToProps = dispatch => ({
navigate: scene => dispatch(actions.navigate(scene)),
updateDrawer: isOpen => dispatch(actions.updateDrawer(isOpen)),
});
const sceneToComponent = (scene) => {
switch (scene) {
case 'login':
return <Login />;
case 'welcome':
return <Welcome />;
case 'agenda':
return <Agenda />;
default:
return <Login />;
return <Welcome />;
}
};
const ReduxNavigator = props => (
<Drawer
type="displace"
content={<Sidebar />}
openDrawerOffset={0.4}
panOpenMask={0.2}
panCloseMask={0.2}
panThreshold={0.3}
tweenHandler={ratio => ({ main: { opacity: (2 - ratio) / 2 } })}
tapToClose
>
{sceneToComponent(props.currentScene)}
</Drawer>
);
const ReduxNavigator = (props) => {
const { currentScene, loggedIn, drawerOpen, updateDrawer } = props;
if (loggedIn) {
return (<Drawer
type="displace"
content={<Sidebar />}
openDrawerOffset={0.4}
panOpenMask={0.2}
panCloseMask={0.2}
panThreshold={0.3}
tweenHandler={ratio => ({ main: { opacity: (2 - ratio) / 2 } })}
open={drawerOpen}
onOpen={() => updateDrawer(true)}
onClose={() => updateDrawer(false)}
tapToClose
>
{sceneToComponent(currentScene)}
</Drawer>);
}
return <Login />;
};
ReduxNavigator.propTypes = {
currentScene: React.PropTypes.string.isRequired,
loggedIn: React.PropTypes.bool.isRequired,
drawerOpen: React.PropTypes.bool.isRequired,
updateDrawer: React.PropTypes.func.isRequired,
};
export default connect(mapStateToProps, mapDispatchToProps)(ReduxNavigator);
import * as types from '../actions/actionTypes';
const initialState = {
loggedIn: false,
loginError: false,
loginState: '',
token: '',
username: '',
};
export default function login(state = initialState, action = {}) {
switch (action.type) {
case types.LOGIN:
if (action.success) {
return { ...state, loginError: false, loggedIn: true };
}
return { ...state, loginError: true };
case types.LOGINSUCCESS:
return { ...state, loginState: 'success', username: action.username, token: action.token };
case types.LOGINFAILURE:
return { ...state, loginState: 'failure' };
case types.LOGINPROGRESS:
return { ...state, loginState: 'progress' };
default:
return { ...state };
}
......
......@@ -2,38 +2,57 @@ import * as types from '../actions/actionTypes';
const initialState = {
previousScenes: [],
currentScene: 'login',
currentScene: 'welcome',
loggedIn: false,
drawerOpen: false,
};
export default function navigate(state = initialState, action = {}) {
const { currentScene, previousScenes } = state;
const { currentScene, previousScenes, loggedIn, drawerOpen } = state;
switch (action.type) {
case types.LOGIN:
if (action.success) {
case types.LOGINSUCCESS: {
return {
...initialState,
loggedIn: true,
};
}
case types.BACK: {
if (drawerOpen) {
return {
previousScenes: [
...previousScenes,
currentScene,
],
currentScene: 'welcome',
...state,
drawerOpen: false,
};
}
return { ...state };
case types.BACK: {
const scene = previousScenes.pop();
return {
previousScenes,
currentScene: scene,
loggedIn,
drawerOpen,
};
}
case types.NAVIGATE: {
if (action.scene === currentScene) {
return state;
}
return {
previousScenes: [],
previousScenes: [
...previousScenes,
currentScene,
],
currentScene: action.scene,
loggedIn,
drawerOpen: false,
};
}
case types.OPENDRAWER: {
return {
...state,
drawerOpen: action.drawerOpen,
};
}
default:
return { ...state };
return state;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment