Add login. Fetch user data. Learned basic React + Redux. Needs work.

This commit is contained in:
ponas committed 2017-08-06 21:33:48 +02:00
1 parent cc6c9e4973
commit d4d3f12aea
13 files changed
+433 -47

No files matched your search

+48 -18
View File
@@ -1,20 +1,38 @@
import React, { Component } from 'react';
import {Button, Image, StyleSheet, Text, TextInput, View} from 'react-native';
import { Spinner } from 'native-base';
import { loginStart } from "../../actions";
// import { login } from "../../actions";
export default class Login extends Component {
constructor(props) {
super(props);
this.state = {
loggedIn: false
isAuthenticated: false,
isLoggingIn: false,
errorMessage: null,
email: '',
password: ''
}
}
componentWillReceiveProps(nextProps) {
if(this.state.loggedIn !== nextProps.loggedIn) {
if(this.state.isAuthenticated !== nextProps.isAuthenticated) {
this.setState({
loggedIn: nextProps.loggedIn
isAuthenticated: nextProps.isAuthenticated
})
if (nextProps.isAuthenticated) {
this.onLogin();
}
}
if(this.state.isLoggingIn !== nextProps.isLoggingIn) {
this.setState({
isLoggingIn: nextProps.isLoggingIn
})
}
if(this.state.errorMessage !== nextProps.errorMessage) {
this.setState({
errorMessage: nextProps.errorMessage
})
}
}
@@ -25,48 +43,60 @@ export default class Login extends Component {
};
return (
<View style={styles.container}>
<Text style={styles.text}>The Norwegian Student Society</Text>
<Text style={styles.text}>Det Norske Studentersamfund</Text>
<Text style={styles.text}>Chateau Neuf</Text>
<Image source={pic} style={{width: 200, height: 150, marginBottom: 40}} resizeMode='contain' />
<TextInput
placeholder="Email"
placeholder="E-post"
style={styles.input}
keyboardType="email-address"
autoCapitalize="none"
returnKeyType="next"
onChangeText={this.handleEmail}
onSubmitEditing={(event) => {
this.refs.passwordInput.focus();
}}
/>
<TextInput
placeholder="Password"
placeholder="Passord"
style={styles.input}
secureTextEntry={true}
autoCapitalize="none"
ref='passwordInput'
onChangeText={this.handlePassword}
onSubmitEditing={this.onLoginPress}
/>
<View style={styles.button}>
<Button
title="Log in"
title="Logg inn"
onPress={this.onLoginPress}
/>
</View>
<Text style={{paddingTop: 10}}>{this.loginState()}</Text>
{this.spinIfLoggingIn}
</View>
);
}
onLoginPress = () => {
console.log("YO from onLoginPress");
this.props.dispatch(loginStart())
spinIfLoggingIn = () => {
if (this.state.isLoggingIn) {
return <Spinner color="#f58220"></Spinner>
}
}
handleEmail = (text) => {
this.setState({ email: text })
};
loginState() {
if(this.state.loggedIn) {
return 'LOGGED IN'
}
return 'NOT YET'
handlePassword = (text) => {
this.setState({ password: text })
};
onLoginPress = () => {
this.props.requestLogin(this.state.email, this.state.password)
};
onLogin = () => {
this.props.onLogin();
}
}
@@ -78,7 +108,7 @@ const styles = StyleSheet.create({
backgroundColor: '#F5FCFF',
},
input: {
width: 240,
width: 320,
fontSize: 20,
height: 52,
},
+9 -4
View File
@@ -1,8 +1,13 @@
import {connect} from "react-redux";
import { bindActionCreators } from "redux";
import Login from "./Login";
import { requestLogin } from "../../actions";
export default connect(
state => ({
loggedIn: state.loggedIn
})
)(Login);
(state) => ({
isAuthenticated: state.isAuthenticated,
isLoggingIn: state.isLoggingIn,
errorMessage: state.errorMessage,
}),
{ requestLogin }
)(Login);
+10 -2
View File
@@ -7,6 +7,10 @@ export default class Membership extends Component {
return (
<ScrollView>
<View style={styles.card}>
<View style={styles.button}>
<Button onPress={this.onLoginPress} full><NBText>Logg inn</NBText></Button>
</View>
<Text style={styles.paragraph}>Siden 1813 har Det Norske Studentersamfund samlet studenter til kulturell, politisk, faglig og ikke minst sosial aktivitet. Som medlem i DNS er du med på å understreke viktigheten til en felles møteplass for alle Oslos studenter, uavhengig av utdanningsinstitusjon, studie og hvem de er.</Text>
<Text style={styles.paragraph}>Vi setter pris på felleskapet som er med på å bygge Chateau Neuf. DNS er en organisasjon av og for medlemmene. Derfor sørger vi for at det blir litt lettere å være student ved å ta en del av kaka for medlemmene våre. Med medlemskap får billigere inngang og servering på alt som skjer på Chateau Neuf.</Text>
@@ -23,12 +27,16 @@ export default class Membership extends Component {
</View>
</ScrollView>
)
}
};
onPurchasePress() {
// FIXME: Move this to process.env.DUSKEN_URL and use babel thing to do search replace
Linking.openURL('https://medlem.neuf.no');
}
};
onLoginPress = () => {
this.props.onLoginPress();
};
}
+58 -1
View File
@@ -1,5 +1,62 @@
import React from 'react';
import {connect} from "react-redux";
import Membership from "./Membership";
import MembershipProof from "./MembershipProof";
import { requestUserData } from "../../actions";
export default connect()(Membership);
class MembershipContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
isAuthenticated: props.isAuthenticated,
userToken: props.userToken,
isFetchingUserData: props.isFetchingUserData,
user: props.user,
}
}
componentDidMount() {
this.fetchUser();
}
componentWillReceiveProps(nextProps) {
if(this.state.isAuthenticated !== nextProps.isAuthenticated) {
this.setState({isAuthenticated: nextProps.isAuthenticated})
}
if(this.state.userToken !== nextProps.userToken) {
this.setState({userToken: nextProps.userToken})
this.fetchUser();
}
if(this.state.user !== nextProps.user) {
this.setState({user: nextProps.user})
}
}
fetchUser = () => {
if (!this.state.userToken) { return; }
this.props.requestUserData(this.state.userToken)
}
onLoginPress = () => {
this.props.onLoginPress();
}
render() {
if (this.state.user) {
return (<MembershipProof user={this.state.user} fetchUser={this.fetchUser}/>)
}
return (<Membership onLoginPress={this.onLoginPress}/>)
}
}
export default connect(
(state) => ({
isAuthenticated: state.isAuthenticated,
isFetchingUserData: state.isFetchingUserData,
userToken: state.userToken,
user: state.user,
}),
{ requestUserData }
)(MembershipContainer);
+90
View File
@@ -0,0 +1,90 @@
import React, {Component} from 'react';
import {StyleSheet, Platform, RefreshControl} from "react-native";
import {Card, CardItem, Text, Content} from 'native-base';
export default class MembershipProof extends Component {
constructor(props) {
super(props);
this.state = {
user: props.user,
refreshing: false,
}
};
componentWillReceiveProps(nextProps) {
if(this.state.user !== nextProps.user) {
this.setState({user: nextProps.user})
}
}
validTo() {
if (this.state.user.last_membership.membership_type == 'lifelong') {
return 'Livsvarig'
}
return this.state.user.last_membership.end_date;
}
statusText() {
if (!this.state.user.is_member) {
if (!this.state.user.last_membership) {
return 'Ikke medlem'
}
return 'Utløpt'
}
if (this.state.user.is_volunteer) {
return 'Aktiv'
}
return 'Medlem'
}
fetchUser = () => {
this.props.fetchUser()
};
// fetchUser = () => {
// this.props.fetchUser().then(() => {
// this.setState({refreshing: false});
// });
// };
// _onRefresh() {
// console.log('onRefresh')
// this.setState({refreshing: true});
// this.fetchUser()
// }
// refreshControl() {
// return (
// <RefreshControl
// refreshing={this.state.refreshing}
// onRefresh={this._onRefresh.bind(this)}
// />)
// }
render() {
return (
<Content>
<Card>
<CardItem>
<Text style={styles.nameText}>{this.state.user.first_name} {this.state.user.last_name}</Text>
</CardItem>
<CardItem>
<Text>{this.statusText()}</Text>
</CardItem>
<CardItem>
<Text>Gyldig til: {this.validTo()}</Text>
</CardItem>
</Card>
</Content>
)
};
}
const styles = StyleSheet.create({
nameText: {
flex: 1,
textAlign: 'center',
fontSize: 20,
fontWeight: 'bold',
},
});