Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event Registration and Checkin #65

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions App/actions/Login.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,68 @@ export function populateEvents(events) {
}
}

export function getRegistrations(id) {
return (dispatch) => {
dispatch(isLoading());
fetch(AMAZON_API + '/registration/queryStudent?id=' + id)
.then((response) => response.json())
.then((response) => {
console.log('getRegistration success');
dispatch(getRegistrationSuccess(response));
})
.catch(err => {
console.log('getRegistration failed');
dispatch(registrationFailed(err));
})
}
}

export function getRegistrationSuccess(response) {
return {
type: 'registrationSuccess',
response
}
}

export function registrationFailed(err) {
return {
type: 'registrationFailed',
err
}
}

export function registerUser(id, eventID) {
return (dispatch) => {
dispatch(isLoading());
const body = JSON.stringify({
id,
eventID,
registrationStatus: 'registered'
})
fetch(AMAZON_API + '/registration/create', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will need authentication headers as well

body: body
})
.then((response) => response.json())
.then((response) => {
console.log(response)
if (response.message == 'Update succeeded') {
dispatch(getRegistrations(id));
} else {
dispatch(registrationFailed(err));
}
})
.catch(err => {
console.log('registration failed');
dispatch(registrationFailed(err));
})
}
}

export function hideSuccess() {
return {
type: 'hideSuccess'
Expand Down
2 changes: 1 addition & 1 deletion App/components/EventCard.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export default class EventCard extends Component {

<View >
<Image
source={{ uri: this.props.event.img }}
source={{ uri: this.props.event.imageUrl }}
style={{
width: width - 20,
height: 240,
Expand Down
13 changes: 12 additions & 1 deletion App/reducers/LoginReducers.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ const initialState = {
user: null,
error: undefined,
isVerified: false,
showSuccess: false
showSuccess: false,
registration: null
}

export default function loginReducer(state = initialState, action) {
Expand Down Expand Up @@ -62,6 +63,16 @@ export default function loginReducer(state = initialState, action) {
return Object.assign({}, state, {
showSuccess: true
})
case 'registrationSuccess':
return Object.assign({}, state, {
registration: action.response,
isLoading: false
})
case 'registrationFailed':
return Object.assign({}, state, {
isLoading: false,
error: action.err
})
default:
return state
}
Expand Down
126 changes: 69 additions & 57 deletions App/screens/CheckinScreen.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ import { Alert, View, TextInput } from 'react-native';
import { withNavigation } from 'react-navigation';
import { AMAZON_API } from 'react-native-dotenv';
import { connect } from 'react-redux';
import { getRegistrations } from '../actions/Login';

// styling
import styles from '../styles/Styles';
import Text from '../components/Text'
import Button from '../components/Button'


class CheckinScreen extends Component {
constructor() {
super();
this.state = {
checkinCode: '',
}
state = { checkinCode: '' }

componentDidMount() {
this.props.getRegistrations(this.props.userData.id);
};

doAlert(message) {
Expand All @@ -28,66 +27,64 @@ class CheckinScreen extends Component {

goHome() {
this.props.navigation.navigate('Home');
}
};

checkRegistrationStatus(eventID) {
const entry = this.props.registration.data.filter(entry => entry.eventID == eventID);
if (entry.length == 1) {
return entry[0].registrationStatus;
}
return '';
};

handleCheckin() {
console.log(this.state.checkinCode);
if (this.state.checkinCode.length != 4) {
Alert.alert('Not a valid code!');
this.doAlert('Not a valid code!');
return;
}
fetch(AMAZON_API + '/events/scan?code=' + this.state.checkinCode)
.then((response) => response.json())
.then((response) => {
console.log(response);
if (Object.keys(response).length == 1) {
if (response[0].opened) {
const studentID = this.props.userData.id;
let users = response[0].users;
if (users.hasOwnProperty(studentID)) {
if (users[studentID] == 'R') {
console.log('checkin success');
const body = JSON.stringify({
'id': response[0].id,
'userID': studentID,
'status': 'C'
});
let update = fetch(AMAZON_API + '/events/userupdate',
{
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: body
})
.then((update) => update.json())
.then((update) => {
console.log(update)
})
.done();
console.log('user check in success');
this.doAlert('You have successfully checked in. Hang tight!');

} else if (users[studentID] == 'C') {
console.log('user already checked in');
this.doAlert('You have already checked in. Sit tight!');
} else if (users[studentID] == 'W') {
console.log('user on waitlist');
this.doAlert('You are on the waitlist.');
} else if (users[studentID] == 'Can') {
console.log('user cancelled');
this.doAlert('You have cancelled your registration for this event.');
}
} else {
console.log('user not registered');
this.doAlert('You have not registered for this event.');
}
} else {
console.log('event not opened');
this.doAlert('Check-in for this event has not been opened yet.');
if (response.size == 1) {
const status = this.checkRegistrationStatus(response.data[0].id);
if (status == "checkedin") {
this.doAlert('You have already checked in to this event.');
return;
} else if (status != "registered") {
this.doAlert('You have not yet registered for this event.');
return;
}
} else if (Object.keys(response).length == 0) {
const body = JSON.stringify({
id: this.props.userData.id,
eventID: response.data[0].id,
registrationStatus: 'checkedin'
});
fetch(AMAZON_API + '/registration/create', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: body
})
.then((response) => response.json())
.then((response) => {
console.log(response)
if (response.registrationStatus == 'checkedin') {
this.doAlert('Checked in!');
} else {
this.doAlert('Checkin failed, the event may be full.');
}
})
.catch(err => {
this.doAlert('An error occured.');
})
// TODO: Readd functionality to open/close event checkin
// console.log('event not opened');
// this.doAlert('Check-in for this event has not been opened yet.');

} else if (response.size == 0) {
console.log('no event found.');
this.doAlert('No event with given code.');
} else {
Expand All @@ -104,6 +101,13 @@ class CheckinScreen extends Component {
};

render() {
if (this.props.isLoading) {
return (
<View style={styles.container}>
<Text style={styles.h1}>Loading Screen</Text>
</View>
)
}
return (
<View style={styles.widgetContainer}>
<Text style={styles.h1}>Event Check-in</Text>
Expand Down Expand Up @@ -134,7 +138,15 @@ class CheckinScreen extends Component {
const mapStateToProps = (state) => {
return {
userData: state.login.user,
registration: state.login.registration,
isLoading: state.login.isLoading
};
};

const mapDispatchToProps = (dispatch) => {
return {
getRegistrations: (id) => dispatch(getRegistrations(id))
};
};

export default withNavigation(connect(mapStateToProps)(CheckinScreen));
export default withNavigation(connect(mapStateToProps, mapDispatchToProps)(CheckinScreen));
71 changes: 64 additions & 7 deletions App/screens/EventScreen.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,98 @@
import React, { Component } from 'react';
import { View, Dimensions, Image } from 'react-native';
import { connect } from 'react-redux';
import { getRegistrations, registerUser } from '../actions/Login';

const { width, height } = Dimensions.get('window');
//styling
import styles from '../styles/Styles';
import Text from '../components/Text'

import Button from '../components/Button'

export default class EventScreen extends Component {

class EventScreen extends Component {

componentDidMount() {
this.props.getRegistrations(this.props.userData.id);
};

state = { disableButton: false };

getDescription(event) {
if (event.description) {
return event.description
return event.description;
} else {
return "It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like)."
}
}
};

getRegistrationStatus(eventID) {
const entry = this.props.registration.data.filter(entry => entry.eventID == eventID);
if (entry.length == 1) {
this.state.disableButton = true;
if (entry[0].registrationStatus == 'registered') {
return 'You have registered for this event!';
} else if (entry[0].registrationStatus == 'waitlist') {
return 'You have been added to the waitlist for this event.';
} else if (entry[0].registrationStatus == 'checkedin') {
return "You've checked into this event!";
}
} else {
return 'Click below to register!';
}
};

handleRegistration(eventID) {
if (!this.state.disableButton) {
this.props.registerUser(this.props.userData.id, eventID);
}
};


render() {
if (this.props.isLoading) {
return (
<View style={styles.container}>
<Text style={styles.h1}>Loading Screen</Text>
</View>
)
}
const { navigation } = this.props
const event = navigation.getParam('event')
return (
<View>
<Image
source={{ uri: event.img }}
source={{ uri: event.imageUrl }}
style={{ width: width, height: 240, marginBottom: 10 }}
resizeMode="cover"
resizeMode='cover'
/>
<View style={styles.widgetContainer}>
<Text style={styles.h1}>{event.ename}</Text>
<Text style={styles.colour} >{event.edate}</Text>
<Text>{this.getDescription(event)}</Text>
<Button title='Sign Up' />
<Text style={styles.h3}>{this.getRegistrationStatus(event.id)}</Text>
<Button title='Sign Up'
disabled={this.state.disableButton}
onPress={this.handleRegistration.bind(this, event.id)} />
</View>
</View>
)
}
}

const mapStateToProps = (state) => {
return {
userData: state.login.user,
registration: state.login.registration,
isLoading: state.login.isLoading
}
};

const mapDispatchToProps = (dispatch) => {
return {
getRegistrations: (id) => dispatch(getRegistrations(id)),
registerUser: (id, eventID) => dispatch(registerUser(id, eventID))
};
};

export default connect(mapStateToProps, mapDispatchToProps)(EventScreen);
Empty file modified android/gradlew
100644 → 100755
Empty file.