Skip to content
This repository has been archived by the owner on Nov 8, 2018. It is now read-only.

Commit

Permalink
Added member authentication, working more with user ids, used alerts …
Browse files Browse the repository at this point in the history
…instead of android toasts, and simplified import and export statements
  • Loading branch information
mohitkewalramani7 committed Apr 29, 2018
1 parent 95305ae commit 89e9ddd
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 100 deletions.
62 changes: 16 additions & 46 deletions YesVancouverApp/src/components/Login/LoginForm.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

import React, { Component } from 'react';
import {StyleSheet, View, TextInput, TouchableOpacity, Text, StatusBar, Button} from 'react-native';
import {getContactEventRegistrationList, getIndividualContactsList} from '../Profile/FetchUserDetails'
import {StyleSheet, View, TextInput, TouchableOpacity, Text, StatusBar, Button, Alert} from 'react-native';
import {getIndividualContactsList, authenticateContactLogin, getContactEventRegistrationList,
retrieveCurrentContactDetails} from '../Profile/FetchUserDetails'

let clientEmail = "";
let clientPassword = "";
Expand All @@ -14,56 +15,25 @@ export default class LoginForm extends Component {

async authenticateLogin(){
let {navigate} = this.props.navigation;
let contactsListArray = await getIndividualContactsList(clientEmail);
if (contactsListArray.length === 1){
let contact = contactsListArray[0];
let contactEventRegistrationDetails = await getContactEventRegistrationList(contact["Id"]);
navigate("NavBar", {'userData' : contact,
let contactAuthenticationToken = await authenticateContactLogin(clientEmail, clientPassword);
if (contactAuthenticationToken !== null){
let currentUserDetails = await retrieveCurrentContactDetails(contactAuthenticationToken);
let contactsListArray = await getIndividualContactsList(currentUserDetails["Id"]);
let contactEventRegistrationDetails = await getContactEventRegistrationList(currentUserDetails["Id"]);
await navigate("NavBar", {'userData' : contactsListArray[0],
'upcomingEvents' : contactEventRegistrationDetails});
}
else{
console.log("Invalid Email Supplied");
Alert.alert(
'Incorrect Credentials',
'Either your username or password is incorrect',
[
{text: "Ok", style:'cancel'}
]
)
}
}

// async authenticateLogin(){
// let {navigate} = this.props.navigation;
// let contactsListArray = await getIndividualContactsList();
//
// let resultsList = [];
// for (let e in contactsListArray) {
// resultsList.push(new Promise(function (resolve, reject) {
// if (contactsListArray[e]["Email"] === clientEmail) {
// resolve(contactsListArray[e]);
// }
// resolve();
// }));
// }
// Promise.all(resultsList)
// .then(function (values) {
// let definedValues = values.filter(value => value !== undefined);
// if (definedValues.length === 1){
// let retrieveEventDetails = new Promise(function (resolve, reject) {
// let contactRegistrationDetails = getContactEventRegistrationList(definedValues[0]["Id"]);
// resolve(contactRegistrationDetails );
// });
// retrieveEventDetails.then(function (contactRegistrationDetails ) {
// navigate("NavBar", {'userData' : definedValues[0],
// 'upcomingEvents' : contactRegistrationDetails });
// }).catch(function (error) {
// console.log("ERROR: " + error)
// });
// }
// else{
// console.log("Invalid Email Supplied");
// }
// })
// .catch(function (error) {
// console.log("ERROR Occured");
// console.log(error);
// });
// }

render() {
let {navigate} = this.props.navigation;
return (
Expand Down
31 changes: 23 additions & 8 deletions YesVancouverApp/src/components/Profile/EditProfile.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { Component } from 'react';
import {StyleSheet, ScrollView, View, Image, Text, TextInput, ToastAndroid,
Button } from 'react-native';
import {ScrollView, View, Text, TextInput, Button, Alert} from 'react-native';
import {styles} from './ProfileStyleSheet'
import {updateContactDetails, getContactEventRegistrationList, getIndividualContactsList} from './FetchUserDetails'

Expand All @@ -14,8 +13,6 @@ export default class EditProfile extends Component{
newContactLinkedIn = '';

async updateProfileDetails(){
// go back to profile screen, show updated data

let {navigate} = this.props.navigation;
let apiDetails = {
"Id" : this.userID,
Expand All @@ -36,15 +33,27 @@ export default class EditProfile extends Component{

let updateResult = await updateContactDetails(this.userID, apiDetails);
if (updateResult !== null){
ToastAndroid.show("Details Updated" ,ToastAndroid.SHORT);
let contact = await getIndividualContactsList(this.newContactEmail);
Alert.alert(
'Details Updated',
'Your profile details have been updated',
[
{text: "Ok", style:'cancel'}
]
);
let contact = await getIndividualContactsList(this.userID);
contact = contact[0];
let contactEventRegistrationDetails = await getContactEventRegistrationList(contact["Id"]);
navigate("NavBar", {'userData' : contact,
'upcomingEvents' : contactEventRegistrationDetails});
}
else{
ToastAndroid.show("Update Failed, Try Again" ,ToastAndroid.SHORT)
Alert.alert(
'Update Failed',
'Please try to update your details again',
[
{text: "Ok", style:'cancel'}
]
);
}
}

Expand Down Expand Up @@ -126,7 +135,13 @@ export default class EditProfile extends Component{
</View>
<View>
<Button color="#ED4969" title="Cancel" style={styles.buttonView} onPress={
()=> ToastAndroid.show("Click Back...." ,ToastAndroid.SHORT)
()=> Alert.alert(
'Click Back',
'Click the back button',
[
{text: "Ok", style:'cancel'}
]
)
}/>
</View>
</View>
Expand Down
87 changes: 67 additions & 20 deletions YesVancouverApp/src/components/Profile/FetchUserDetails.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
import { ClientSecrets } from '../../../config/config'
import ApiUtils from '../../utils/ApiUtils'

/*
/**
* Takes in the users entered email address and password on the login screen
* and checks for authentication in the members database
*
* @param username: The users entered email address
* @param password: The users entered password
* @returns {Promise.<*>}
*/
async function authenticateContactLogin(username, password){
try {
let base64 = require('base-64');
basicAuthHeaderValue = 'Basic ' + base64.encode(username + ":" + password);
let basicAuthHeaderValue = 'Basic ' +
base64.encode(ClientSecrets.CLIENT_ID + ":" + ClientSecrets.CLIENT_SECRET);
let requestAuthTokenBody = {
'grant_type': 'password',
'scope': 'contacts finances events event_registrations_view'
'username': username,
'password': password,
'scope': 'auto'
};
let response = await fetch('https://oauth.wildapricot.org/auth/token',
{
Expand All @@ -19,19 +29,21 @@ async function authenticateContactLogin(username, password){
},
body: ApiUtils.constructFormUrlEncodedBody(requestAuthTokenBody)
});
if (response.status !== 200){
return null;
}
let responseJson = await response.json();
return responseJson;
//return responseJson['access_token']
return responseJson['access_token'];
} catch(error) {
console.error(error);
return null
}
}
*/

/**
* Retrieves an authentication token based on the API details that are listed in the
* config.js file
* config.js file (NOT THE USER LOGIN TOKEN, AS IT'S SCOPE ISN'T AS WIDE AS THE GENERAL
* API ONE)
*
* @returns {Promise.<*>}
*/
Expand Down Expand Up @@ -65,22 +77,52 @@ async function getBearerToken() {
// Contacts Data Retrieval
// ------------------------------------------------------------------------------

/**
* Returns details for the currently logged in contact
*
* @param bearerToken: Token retrieved after contact authentication
* @returns {Promise.<*>}
*/
async function retrieveCurrentContactDetails(bearerToken){
try {
let getUrl = "https://api.wildapricot.org/v2/Accounts/" + ClientSecrets.ACCOUNT_NUM +
"/Contacts/me/";
let response = await fetch(getUrl,
{
method: 'GET',
headers: {
'Authorization': 'Bearer ' + bearerToken
}
});

if(response.status !== 200) {
console.log(response.status);
return null
}
return response.json();

} catch(error) {
console.error(error);
return null
}
}

/**
* Retrieves data for all contacts stored in the contact database for
* the current email address provided
* the ID provided
*
* @param userEmail: The email address to search for
* @param userID: The user ID to search for
* @returns {Promise.<*>}
*/

async function getIndividualContactsList(userEmail){
async function getIndividualContactsList(userID){
let bearerToken = await getBearerToken();
if(!bearerToken) {
console.log("Failed to get bearer token");
this.setState({isEventListLoading: false});
return
}
let resultURLObject = await getResultURL(bearerToken, userEmail);
let resultURLObject = await getResultURL(bearerToken, userID);
let resultURLString = resultURLObject["ResultUrl"];
let contactsList = await getContactsList(bearerToken, resultURLString);
return contactsList["Contacts"];
Expand All @@ -91,13 +133,13 @@ async function getIndividualContactsList(userEmail){
* This will be used to further query data from the contacts table
*
* @param bearerToken: The authentication token
* @param userId: The user ID for which to retrieve the Result URL for
* @returns {Promise.<*>}
*/
async function getResultURL(bearerToken, userEmail) {
async function getResultURL(bearerToken, userId) {
try {
//let getUrl = 'https://api.wildapricot.org/v2/Accounts/' + ClientSecrets.ACCOUNT_NUM + '/Contacts';
let getUrl = 'https://api.wildapricot.org/v2/Accounts/' + ClientSecrets.ACCOUNT_NUM +
'/Contacts?$filter=Email eq ' + userEmail;
let getUrl = 'https://api.wildapricot.org/v2.1/Accounts/' + ClientSecrets.ACCOUNT_NUM +
'/Contacts?$filter=Id eq ' + userId;
let response = await fetch(getUrl,
{
method: 'GET',
Expand All @@ -119,9 +161,13 @@ async function getResultURL(bearerToken, userEmail) {
}

/**
*
* Retrieves data from the contacts table for a specified contact
* whose details will be composed in the resultURL. This returns
* ALL details for the user, for display on the Profile Screen
*
* @param bearerToken: The authentication token
* @param resultURL: The Result URL for accessing data from the contacts table
* @param resultURL: The Result URL constructed for accessing data from the contacts table
* @returns {Promise.<*>}
*/
async function getContactsList(bearerToken, resultURL) {
Expand All @@ -148,8 +194,8 @@ async function getContactsList(bearerToken, resultURL) {

/**
*
* Updates new contact details for a given contact ID given a bearer
* token
* Updates new contact details for a given contact ID given the ID and its
* new contact details
*
* @param contactId
* @param newContactDetails
Expand Down Expand Up @@ -246,7 +292,7 @@ async function getUpcomingEvents(upcomingEventsList){
let upcomingEventsDictionaryList = [];
await upcomingEventsList.forEach(function (value) {
upcomingEventsDictionaryList.push(
{key: value["Id"], // ["Event"]["Id"]
{key: value["Id"],
name: value["Event"]["Name"],
date: value["Event"]["StartDate"].substring(0, 10)}
);
Expand All @@ -257,4 +303,5 @@ async function getUpcomingEvents(upcomingEventsList){
// ------------------------------------------------------------------------------

export {getBearerToken, getResultURL, getContactsList,
getIndividualContactsList, getContactEventRegistrationList, getUpcomingEvents, updateContactDetails};
getIndividualContactsList, getContactEventRegistrationList, getUpcomingEvents, updateContactDetails,
authenticateContactLogin, retrieveCurrentContactDetails};
39 changes: 16 additions & 23 deletions YesVancouverApp/src/components/Profile/ProfileView.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { Component } from 'react';
import {Text, View, Image, ScrollView, Button, ToastAndroid, FlatList} from 'react-native';
import {Text, View, Image, ScrollView, Button, FlatList, Alert} from 'react-native';
import {styles} from './ProfileStyleSheet'

export default class ProfileView extends Component {
Expand Down Expand Up @@ -55,7 +55,7 @@ export default class ProfileView extends Component {
}

returnProfileScreenView(userID, userFirstName, userLastName, userEmail, userPhone, userMemberSince, userRenewalDue,
userLinkedIn, userCreationDate, upcomingEventsList){
userLinkedIn, userCreationDate, upcomingEventsList, userProfilePictureUrl){
let {navigate} = this.props.navigation;
return (
<ScrollView contentContainerStyle={styles.container}>
Expand All @@ -75,7 +75,13 @@ export default class ProfileView extends Component {
<Text style={styles.paragraph}>Upto : {userRenewalDue.substring(0, 10)} </Text>
<View style={styles.extendMembershipButtonView}>
<Button color="#ED4969" title="Extend membership" onPress={
()=> ToastAndroid.show("Extended membership" ,ToastAndroid.SHORT)
()=> Alert.alert(
'Extended membership',
'Your membership has been extended',
[
{text: "Ok", style:'cancel'}
]
)
}/>
</View>

Expand Down Expand Up @@ -110,7 +116,13 @@ export default class ProfileView extends Component {
</View>
<View style={styles.buttonView}>
<Button color="#ED4969" title="Change Password" onPress={
()=> ToastAndroid.show("Password Changed...." ,ToastAndroid.SHORT)
()=> Alert.alert(
'Password Changed',
'Your password has been changed',
[
{text: "Ok", style:'cancel'}
]
)
}/>
</View>
<Text style={styles.dropDown}>
Expand All @@ -128,22 +140,3 @@ export default class ProfileView extends Component {
);
}
}

/*
Past Events documentation
<Text style={styles.dropDown}>
<Image
style={styles.imageLogo}
source={require('../../images/Settings/Arrow-open.png')}/>
My past events
</Text>
<FlatList
style = {styles.flatList}
data={[{key: 'February 19 | Sample Event 1'},
{key: 'March 24 | Sample Event 2'},
{key: 'April 20 | Sample Event 3'}]}
renderItem={({item}) => <Text>{item.key}</Text>}
/>
*/
Loading

0 comments on commit 89e9ddd

Please sign in to comment.