mirror of
https://bitbucket.org/tagfer_team/tagfer-app.git
synced 2025-12-25 03:37:41 +00:00
Merged in UPS23-Create-Signup-Screen4-Create-Initial-Profile-Screen (pull request #4)
UPS23 Create Signup Screen4 Create Initial Profile Screen
* UPS23: Added SignupScreen4 + LinkedIn Integration
- still some bugs when dealing with oauth, not as similar as the twitter api
* UPS23: Camera and Image Picker working
- still need to test on physical device since emulator will not allow for testing of camera
* UPS23-Fixed Styling for Signup Screen#4
* UPS23- adding package lock file
* UPS23: Disable linked in button
- currently we are not able to get the information we need back to populate the initial profile form
- we only have access to v1 apis which will be deprecated in 2 months
- awaiting access from linkedin's partner program
* UPS23: Change screen routing order
* UPS23: Remove LinkedInData state object
* UPS23: Flatten profileInfo object to seperate state attributes
Approved-by: Omar Mihilmy <mihilmy@gmail.com>
This commit is contained in:
parent
588f9cc92d
commit
f10c5dfbe1
5
.gitignore
vendored
5
.gitignore
vendored
@ -29,12 +29,14 @@ build/
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
.vscode
|
||||
|
||||
# node.js
|
||||
#
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
yarn-error.log
|
||||
.envrc
|
||||
|
||||
# BUCK
|
||||
buck-out/
|
||||
@ -54,3 +56,6 @@ buck-out/
|
||||
|
||||
# Bundle artifact
|
||||
*.jsbundle
|
||||
|
||||
#Storybook
|
||||
storybook
|
||||
|
||||
@ -138,6 +138,7 @@ android {
|
||||
|
||||
dependencies {
|
||||
compile project(':react-native-app-settings')
|
||||
compile project(':react-native-image-picker')
|
||||
compile project(':react-native-contacts')
|
||||
compile project(':react-native-webview')
|
||||
compile project(':react-native-vector-icons')
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
|
||||
<uses-permission android:name="android.permission.READ_PROFILE" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<application
|
||||
android:name=".MainApplication"
|
||||
|
||||
@ -4,6 +4,7 @@ import android.app.Application;
|
||||
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.krazylabs.OpenAppSettingsPackage;
|
||||
import com.imagepicker.ImagePickerPackage;
|
||||
import com.rt2zz.reactnativecontacts.ReactNativeContacts;
|
||||
import com.reactnativecommunity.webview.RNCWebViewPackage;
|
||||
import com.oblador.vectoricons.VectorIconsPackage;
|
||||
@ -30,6 +31,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||
return Arrays.<ReactPackage>asList(
|
||||
new MainReactPackage(),
|
||||
new OpenAppSettingsPackage(),
|
||||
new ImagePickerPackage(),
|
||||
new ReactNativeContacts(),
|
||||
new RNCWebViewPackage(),
|
||||
new VectorIconsPackage(),
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
rootProject.name = 'Tagfer'
|
||||
include ':react-native-app-settings'
|
||||
project(':react-native-app-settings').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-app-settings/android')
|
||||
include ':react-native-image-picker'
|
||||
project(':react-native-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-picker/android')
|
||||
include ':react-native-contacts'
|
||||
project(':react-native-contacts').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-contacts/android')
|
||||
include ':react-native-webview'
|
||||
|
||||
@ -55,8 +55,9 @@
|
||||
CCFF320D8D3B429E98A05055 /* MaterialCommunityIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AC4E3A77FB9C4C96AC304034 /* MaterialCommunityIcons.ttf */; };
|
||||
D9DE5DDB1B7D4D3A97259D9B /* Octicons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F025858B6C364BB985AFD241 /* Octicons.ttf */; };
|
||||
E42DCC4F98F24BC99A74B29B /* SimpleLineIcons.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 05246261280A4D30B02BFE85 /* SimpleLineIcons.ttf */; };
|
||||
5732A1A6497B4CAD966524D3 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 75B79A57F6EF4FE2A21CEE97 /* libReactNativePermissions.a */; };
|
||||
864F29A547984CC590F11FA6 /* libRNOpenAppSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E5E2957596074A7C85333B68 /* libRNOpenAppSettings.a */; };
|
||||
B4C9A4F1EFED483EBDF40E81 /* libRNImagePicker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = D6ECD8F725BA458AB7A1D23E /* libRNImagePicker.a */; };
|
||||
992B84F904804663A133A734 /* libReactNativePermissions.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 8D4B30BFC017424A8C7AD988 /* libReactNativePermissions.a */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@ -420,10 +421,12 @@
|
||||
DB6CE8411CF34300A2ED791F /* Foundation.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Foundation.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Foundation.ttf"; sourceTree = "<group>"; };
|
||||
E76DD57CF0E846F0B388335E /* libz.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
F025858B6C364BB985AFD241 /* Octicons.ttf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = Octicons.ttf; path = "../node_modules/react-native-vector-icons/Fonts/Octicons.ttf"; sourceTree = "<group>"; };
|
||||
E335F09B945C4E2391D1FCD3 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; name = "ReactNativePermissions.xcodeproj"; path = "../node_modules/react-native-permissions/ios/ReactNativePermissions.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
|
||||
75B79A57F6EF4FE2A21CEE97 /* libReactNativePermissions.a */ = {isa = PBXFileReference; name = "libReactNativePermissions.a"; path = "libReactNativePermissions.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
|
||||
92557FC291AB42ADB5028635 /* RNOpenAppSettings.xcodeproj */ = {isa = PBXFileReference; name = "RNOpenAppSettings.xcodeproj"; path = "../node_modules/react-native-app-settings/ios/RNOpenAppSettings.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
|
||||
E5E2957596074A7C85333B68 /* libRNOpenAppSettings.a */ = {isa = PBXFileReference; name = "libRNOpenAppSettings.a"; path = "libRNOpenAppSettings.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
|
||||
54F9E00CCF864C30A5B82943 /* RNImagePicker.xcodeproj */ = {isa = PBXFileReference; name = "RNImagePicker.xcodeproj"; path = "../node_modules/react-native-image-picker/ios/RNImagePicker.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
|
||||
D6ECD8F725BA458AB7A1D23E /* libRNImagePicker.a */ = {isa = PBXFileReference; name = "libRNImagePicker.a"; path = "libRNImagePicker.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
|
||||
CCA4530A7D6748FE88A55EA2 /* ReactNativePermissions.xcodeproj */ = {isa = PBXFileReference; name = "ReactNativePermissions.xcodeproj"; path = "../node_modules/react-native-permissions/ios/ReactNativePermissions.xcodeproj"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = wrapper.pb-project; explicitFileType = undefined; includeInIndex = 0; };
|
||||
8D4B30BFC017424A8C7AD988 /* libReactNativePermissions.a */ = {isa = PBXFileReference; name = "libReactNativePermissions.a"; path = "libReactNativePermissions.a"; sourceTree = "<group>"; fileEncoding = undefined; lastKnownFileType = archive.ar; explicitFileType = undefined; includeInIndex = 0; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -458,8 +461,9 @@
|
||||
054B5176D9D541119DF55198 /* libRNVectorIcons.a in Frameworks */,
|
||||
AD3198E72354473C9CFBB5F9 /* libRNCWebView.a in Frameworks */,
|
||||
1BF10613A6304DD5B4189358 /* libRCTContacts.a in Frameworks */,
|
||||
5732A1A6497B4CAD966524D3 /* libReactNativePermissions.a in Frameworks */,
|
||||
864F29A547984CC590F11FA6 /* libRNOpenAppSettings.a in Frameworks */,
|
||||
B4C9A4F1EFED483EBDF40E81 /* libRNImagePicker.a in Frameworks */,
|
||||
992B84F904804663A133A734 /* libReactNativePermissions.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@ -705,8 +709,9 @@
|
||||
2DACAA5CB9F345B5888D681E /* RNVectorIcons.xcodeproj */,
|
||||
A6904FF8C83444048D6F2AF5 /* RNCWebView.xcodeproj */,
|
||||
90515674F3834203B1DE6531 /* RCTContacts.xcodeproj */,
|
||||
E335F09B945C4E2391D1FCD3 /* ReactNativePermissions.xcodeproj */,
|
||||
92557FC291AB42ADB5028635 /* RNOpenAppSettings.xcodeproj */,
|
||||
54F9E00CCF864C30A5B82943 /* RNImagePicker.xcodeproj */,
|
||||
CCA4530A7D6748FE88A55EA2 /* ReactNativePermissions.xcodeproj */,
|
||||
);
|
||||
name = Libraries;
|
||||
sourceTree = "<group>";
|
||||
@ -1415,8 +1420,9 @@
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-webview/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-app-settings/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = TagferTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
@ -1453,8 +1459,9 @@
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-webview/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-app-settings/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = TagferTests/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
@ -1492,8 +1499,9 @@
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-webview/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-app-settings/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = Tagfer/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
@ -1520,8 +1528,9 @@
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-webview/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-app-settings/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = Tagfer/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
@ -1555,8 +1564,9 @@
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-webview/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-app-settings/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = "Tagfer-tvOS/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
@ -1601,8 +1611,9 @@
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-webview/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-app-settings/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = "Tagfer-tvOS/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
|
||||
@ -1646,8 +1657,9 @@
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-webview/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-app-settings/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = "Tagfer-tvOSTests/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
@ -1691,8 +1703,9 @@
|
||||
"$(SRCROOT)/../node_modules/react-native-vector-icons/RNVectorIconsManager",
|
||||
"$(SRCROOT)/../node_modules/react-native-webview/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-contacts/ios/RCTContacts",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
"$(SRCROOT)/../node_modules/react-native-app-settings/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-image-picker/ios",
|
||||
"$(SRCROOT)/../node_modules/react-native-permissions/ios/**",
|
||||
);
|
||||
INFOPLIST_FILE = "Tagfer-tvOSTests/Info.plist";
|
||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
|
||||
|
||||
11774
package-lock.json
generated
11774
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -18,13 +18,15 @@
|
||||
"react-native-flash-message": "^0.1.10",
|
||||
"react-native-gesture-handler": "^1.0.12",
|
||||
"react-native-masked-text": "^1.9.2",
|
||||
"react-native-permissions": "^1.1.1",
|
||||
"react-native-vector-icons": "^4.6.0",
|
||||
"react-native-webview": "^2.14.3",
|
||||
"react-navigation": "^3.0.9",
|
||||
"react-native-image-picker": "^0.28.0",
|
||||
"react-native-permissions": "^1.1.1",
|
||||
"realm": "^2.21.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@storybook/react-native": "^4.1.6",
|
||||
"babel-jest": "23.6.0",
|
||||
"eslint": "^3.19.0",
|
||||
"eslint-config-rallycoding": "^3.2.0",
|
||||
|
||||
@ -1,17 +1,14 @@
|
||||
/** Contains the base fields for Profile reuse **/
|
||||
import { AuthSession } from 'expo';
|
||||
import React, { Component } from 'react';
|
||||
import { Alert, Animated, Dimensions, ScrollView, Text, View } from 'react-native';
|
||||
import { Button, Card, CheckBox, Divider, FormInput, Icon } from 'react-native-elements';
|
||||
import { connect } from 'react-redux';
|
||||
import { profileUpdate, propertyUpdate } from '../../actions';
|
||||
import ProfileAvatar from '../ProfileAvatar';
|
||||
import BizCard from '../BizCard';
|
||||
import { Confirm, FormLabel, FormMessage, Keyword, Spacer, TextButton } from '../common';
|
||||
import { PROFILE_FORM } from '../FormTypes';
|
||||
import colors from '../../config/colors.json';
|
||||
import privateKeys from '../../../private_keys.json';
|
||||
import { strings } from '../../locales/i18n';
|
||||
import { toQueryString } from '../../utils/aux';
|
||||
|
||||
const SCREEN_WIDTH = Dimensions.get('window').width;
|
||||
const DOTS_SIZE = ['first', 'second'];
|
||||
@ -20,15 +17,6 @@ const scrollX = new Animated.Value(0);
|
||||
let addedExperience = [{ jobTitle: '', jobCompany: '', jobDates: '', jobLocation: '', jobSummary: '' }];
|
||||
let addedEducation = [{ school: '', degree: '', fieldOfStudy: '', schoolDates: '', educationSummary: '' }];
|
||||
|
||||
/**
|
||||
* Converts an object to a query string.
|
||||
*/
|
||||
function toQueryString(params) {
|
||||
return '?' + Object.entries(params)
|
||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||
.join('&');
|
||||
}
|
||||
|
||||
class ProfileForm extends Component {
|
||||
state = {
|
||||
keyword: '',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
const baseurl = 'http://127.0.0.1:3000';
|
||||
const baseurl = 'http://192.168.1.201:3000';
|
||||
const endpoints = {
|
||||
login: {
|
||||
method: 'POST',
|
||||
@ -31,6 +31,22 @@ const endpoints = {
|
||||
findUsersByPhone: {
|
||||
method: 'POST',
|
||||
url: `${baseurl}/users/by/phone`
|
||||
},
|
||||
signup: {
|
||||
method: 'PUT',
|
||||
url: `${baseurl}/auth/signup`
|
||||
},
|
||||
retrieveLinkedInInfo: (linkedInQS) => ({
|
||||
method: 'GET',
|
||||
url: `${baseurl}/auth/linkedin/get/profile${linkedInQS}`
|
||||
}),
|
||||
linkedInToken: {
|
||||
method: 'GET',
|
||||
url: `${baseurl}/auth/linkedin/token`
|
||||
},
|
||||
linkedInLogin: {
|
||||
method: 'GET',
|
||||
url: `${baseurl}/auth/linkedin/login`
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -8,9 +8,14 @@ const errors = {
|
||||
AUTH_PHONE_ALREADY_EXISTS: 'auth/phone-number-already-exists',
|
||||
AUTH_PHONE_NOT_CACHED: 'auth/phone-number-not-cached',
|
||||
AUTH_VERIFICATION_CODE_MISMATCH: 'auth/phone-verification-code-mismatch',
|
||||
AUTH_LINKEDIN_REQUEST_TOKEN_FAILURE: 'auth/linkedin-request-token-failure',
|
||||
AUTH_LINKEDIN_ACCESS_TOKEN_FAILURE: 'auth/linkedin-access-token-failure',
|
||||
AUTH_LINKEDIN_PROFILE_REQUEST_FAILURE: 'auth/linkedin-profile-request-failure',
|
||||
AUTH_LINKEDIN_TOKEN_SCOPE_INVALID_REQUEST_FAILURE: 'auth/linkedin-token-scope-invalid-request-failure',
|
||||
APP_NETWORK_ERROR: 'app/network-error',
|
||||
APP_NETWORK_TIMEOUT: 'app/network-timeout',
|
||||
APP_UNABLE_TO_PARSE_RESPONSE: 'app/unable-to-parse-response',
|
||||
APP_FIREBASE_DATABASE_ERROR: 'app/firebase-database-error',
|
||||
MISSING_BODY_ATTRIBUTES: 'request/missing-body-attributes'
|
||||
};
|
||||
|
||||
|
||||
@ -5,8 +5,10 @@ import SignupScreenOne from '../screens/auth/SignupScreen1';
|
||||
import SignupScreenTwo from '../screens/auth/SignupScreen2';
|
||||
import SignupScreenThreeA from '../screens/auth/SignupScreen3a';
|
||||
import SignupScreenThreeB from '../screens/auth/SignupScreen3b';
|
||||
import SignupScreenFour from '../screens/auth/SignupScreen4/SignupScreen4';
|
||||
import SignupScreenFive from '../screens/auth/SignupScreen5';
|
||||
import TwitterWebView from '../screens/auth/TwitterWebView';
|
||||
import LinkedInWebView from '../screens/auth/LinkedInWebView';
|
||||
import ForgotPasswordScreen from '../screens/auth/ForgotPasswordScreen';
|
||||
|
||||
const MainNavigator = createStackNavigator({
|
||||
@ -17,6 +19,7 @@ const MainNavigator = createStackNavigator({
|
||||
signup2: SignupScreenTwo,
|
||||
signup3a: SignupScreenThreeA,
|
||||
signup3b: SignupScreenThreeB,
|
||||
signup4: SignupScreenFour,
|
||||
signup5: SignupScreenFive
|
||||
});
|
||||
|
||||
@ -26,7 +29,8 @@ const RootNavigator = createStackNavigator(
|
||||
screen: MainNavigator,
|
||||
navigationOptions: { header: null }
|
||||
},
|
||||
twitterWebView: TwitterWebView
|
||||
twitterWebView: TwitterWebView,
|
||||
linkedInWebView: LinkedInWebView
|
||||
},
|
||||
{
|
||||
mode: 'modal'
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
"sendInvitation": "Send Invitation",
|
||||
"share": "Share Now",
|
||||
"skip": "Skip",
|
||||
"uploadImage": "Upload Image",
|
||||
"uploadPhoto": "Upload Photo",
|
||||
"takePhoto": "Take Photo",
|
||||
"saveAndContinue": "Save and Continue"
|
||||
},
|
||||
@ -77,6 +77,14 @@
|
||||
"lastName_labelText": "Last Name",
|
||||
"lastName_placeholder": "Last Name",
|
||||
"linkedIn_import": "Import data from LinkedIn",
|
||||
"company_number_labelText": "Company Number",
|
||||
"company_number_placeholder": "0000000000",
|
||||
"company_title_labelText": "Title Profession",
|
||||
"company_title_placeholder": "E.g.: CEO, UX Designer",
|
||||
"company_name_labelText": "Company Name",
|
||||
"company_name_placeholder": "Your company name",
|
||||
"company_address_labelText": "Company Email Address",
|
||||
"company_address_placeholder": "Your company email address",
|
||||
"location_labelText": "Location",
|
||||
"location_placeholder": "Santa Clara, CA",
|
||||
"notes_labelText": "Notes",
|
||||
@ -568,6 +576,11 @@
|
||||
"title": "Sign Up",
|
||||
"urgencyMessage": "Claim your Tagfer ID before it's taken."
|
||||
},
|
||||
"defaultProfileCreate": {
|
||||
"title": "Profile Creation",
|
||||
"instructions": "The profile you're creating is called Business Profile. You can edit its name and create more profiles either after signing up.",
|
||||
"no_verification_needed": "(no phone verification needed)"
|
||||
},
|
||||
"termsAndConditions": {
|
||||
"example": "These are the terms and conditions",
|
||||
"title": "Terms and Conditions"
|
||||
|
||||
31
src/screens/auth/LinkedInWebView.js
Normal file
31
src/screens/auth/LinkedInWebView.js
Normal file
@ -0,0 +1,31 @@
|
||||
import React from 'react';
|
||||
import { Button } from 'react-native';
|
||||
import { WebView } from 'react-native-webview';
|
||||
|
||||
export default class LinkedInWebView extends React.Component {
|
||||
static navigationOptions = ({ navigation }) => ({
|
||||
headerLeft: null,
|
||||
headerRight: <Button title="Done" onPress={() => navigation.goBack()} />
|
||||
});
|
||||
|
||||
/**
|
||||
* This the bridge connecting the WebView and ReactNative. The data you see here is sent by postMessage from
|
||||
* within the DOM in the WebView.
|
||||
*/
|
||||
onComplete(data) {
|
||||
const result = JSON.parse(data);
|
||||
if (result) {
|
||||
this.props.navigation.state.params.onSuccess(result);
|
||||
}
|
||||
this.props.navigation.goBack();
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<WebView
|
||||
source={{ uri: this.props.navigation.state.params.result.uri }}
|
||||
onMessage={(event) => this.onComplete(event.nativeEvent.data)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
284
src/screens/auth/SignupScreen4/SignupScreen4.js
Normal file
284
src/screens/auth/SignupScreen4/SignupScreen4.js
Normal file
@ -0,0 +1,284 @@
|
||||
/** Screen for creating default User Profile **/
|
||||
import React from 'react';
|
||||
import { Icon, FormInput, Alert, Linking } from 'react-native-elements';
|
||||
import { Image, KeyboardAvoidingView, Platform, ScrollView, Text, View, Button, TouchableOpacity } from 'react-native';
|
||||
import ImagePicker from 'react-native-image-picker';
|
||||
import Permissions from 'react-native-permissions';
|
||||
|
||||
import { strings } from '../../../locales/i18n';
|
||||
import { showFlashErrorMessage } from '../../../utils/errorHandler';
|
||||
import { fetchAuth } from '../../../utils/fetch';
|
||||
|
||||
import endpoints from '../../../config/apiEndpoints';
|
||||
import { toQueryString } from '../../../utils/aux';
|
||||
import { FormLabel, Spacer, TextButton } from '../../../components/common';
|
||||
import styles from './styles';
|
||||
|
||||
export default class SignupScreenFour extends React.Component {
|
||||
static navigationOptions = {
|
||||
title: strings('userCreateFlow.defaultProfileCreate.title'),
|
||||
headerStyle: { borderBottomWidth: 0 },
|
||||
headerTintColor: '#0D497E',
|
||||
headerRight: <Text style={styles.navigationHeaderRightStyle}>4/6</Text>
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
base64Img: null,
|
||||
cameraRollStatus: '',
|
||||
cameraStatus: '',
|
||||
loading: false,
|
||||
jobTitle: '',
|
||||
companyName: '',
|
||||
companyAddress: '',
|
||||
companyNumber: ''
|
||||
|
||||
};
|
||||
|
||||
this.openLinkedInWebView = this.openLinkedInWebView.bind(this);
|
||||
this.getLinkedInData = this.getLinkedInData.bind(this);
|
||||
this.getLinkedInAuthURL = this.getLinkedInAuthURL.bind(this);
|
||||
this.renderAvatarPhoto = this.renderAvatarPhoto.bind(this);
|
||||
this.launchPicker = this.launchPicker.bind(this);
|
||||
}
|
||||
|
||||
onSaveButtonPress() {
|
||||
//this will be replaced with realm once it has been added so that we can persist the user data
|
||||
//and send the object in this request
|
||||
this.props.navigation.navigate('signup5', {
|
||||
jobTitle: this.state.jobTitle,
|
||||
companyName: this.state.companyName,
|
||||
companyAddress: this.state.companyAddress,
|
||||
companyNumber: this.state.companyNumber
|
||||
});
|
||||
}
|
||||
|
||||
async onImageButtonPress(pickerMethod, pickerTypeState) {
|
||||
try {
|
||||
if (this.state[pickerTypeState] !== 'authorized') {
|
||||
const response = await Permissions.request('photo');
|
||||
if (response !== 'authorized') {
|
||||
Alert.alert(strings(`common.error.permissionDenied_camera${pickerTypeState === 'cameraRollStatus' ? 'Roll' : ''}`));
|
||||
Linking.openURL('app-settings:');
|
||||
this.setState({ [pickerTypeState]: response });
|
||||
return;
|
||||
} else if (response === 'authorized') {
|
||||
const status = await Permissions.check('photo');
|
||||
await this.launchPicker(pickerMethod, pickerTypeState, status);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
}
|
||||
|
||||
// Network request to our API to get an OAuth token
|
||||
async getLinkedInAuthURL() {
|
||||
console.log('getting linkedin auth info');
|
||||
this.setState({ loading: true });
|
||||
console.log('sending fetch request');
|
||||
const result = await fetchAuth(endpoints.linkedInLogin);
|
||||
|
||||
if (result.error) {
|
||||
showFlashErrorMessage(result.error);
|
||||
return null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async getLinkedInData(linkedInAuthData) {
|
||||
try {
|
||||
const result = await fetchAuth(endpoints.retrieveLinkedInInfo(toQueryString(linkedInAuthData)));
|
||||
if (result.error) {
|
||||
showFlashErrorMessage(result.error);
|
||||
} else {
|
||||
//this call will be altered once we gefull linkedin partner api access
|
||||
//this.setState({ profileInfo: result, loading: false });
|
||||
}
|
||||
} catch (error) {
|
||||
showFlashErrorMessage(error);
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
}
|
||||
|
||||
// Navigates to a LinkedIn webview modal, when the auth creds are fetched successfully it will execute onSuccess
|
||||
async openLinkedInWebView() {
|
||||
console.log('linkedWebview Func hit');
|
||||
this.setState({ loading: true });
|
||||
|
||||
try {
|
||||
const result = await this.getLinkedInAuthURL();
|
||||
this.setState({ loading: false });
|
||||
console.log('navigating to linkedin webview');
|
||||
this.props.navigation.navigate('linkedInWebView', { result, onSuccess: this.getLinkedInData });
|
||||
} catch (error) {
|
||||
showFlashErrorMessage(error);
|
||||
this.setState({ loading: false });
|
||||
}
|
||||
}
|
||||
|
||||
async launchPicker(pickerMethod, pickerTypeState, status) {
|
||||
await ImagePicker[pickerMethod]({
|
||||
allowsEditing: true,
|
||||
mediaTypes: 'photo'
|
||||
}, (libraryResponse) => {
|
||||
if (libraryResponse.didCancel) {
|
||||
console.log('User cancelled image picker');
|
||||
} else if (libraryResponse.error) {
|
||||
console.log('ImagePicker Error: ', libraryResponse.error);
|
||||
} else if (libraryResponse.customButton) {
|
||||
console.log('User tapped custom button: ', libraryResponse.customButton);
|
||||
}
|
||||
this.setState({
|
||||
base64Img: libraryResponse.data,
|
||||
[pickerTypeState]: status
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
renderLinkedInButtons() {
|
||||
return (
|
||||
<TextButton
|
||||
rightText={strings('common.contactFields.linkedIn_import')}
|
||||
rightTextStyle={{ fontSize: 20, fontWeight: 'normal', color: styles.colors.grey }}
|
||||
containerStyle={{ marginLeft: -2, marginTop: 15 }}
|
||||
onPress={this.openLinkedInWebView}
|
||||
disabled
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the avatar cirle on profiles
|
||||
**/
|
||||
renderAvatarPhoto() {
|
||||
if (this.state.base64Img) {
|
||||
return (
|
||||
<View style={styles.avatarStyle}>
|
||||
<Image
|
||||
source={{ uri: this.state.base64Img }}
|
||||
style={styles.avatarStyle}
|
||||
/>
|
||||
{this.renderPhotoButtons()}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
// No profile Image
|
||||
return (
|
||||
<View style={styles.noAvatarStyle}>
|
||||
<Icon
|
||||
name='account-circle'
|
||||
size={150}
|
||||
color={styles.colors.lightTeal}
|
||||
/>
|
||||
{this.renderPhotoButtons()}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the photo buttons
|
||||
**/
|
||||
renderPhotoButtons() {
|
||||
const self = this;
|
||||
return (
|
||||
<View style={styles.buttonContainerStyle}>
|
||||
<TouchableOpacity
|
||||
onPress={this.onImageButtonPress.bind(self, 'launchImageLibrary', 'cameraRollStatus')}
|
||||
disabled={this.props.loading}
|
||||
>
|
||||
<Text style={styles.textButtonStyle}>{strings('common.buttons.uploadPhoto')}</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<Text style={styles.photoButtonsOrTextStyle}>{strings('profile.or')}</Text>
|
||||
|
||||
<TouchableOpacity
|
||||
onPress={this.onImageButtonPress.bind(self, 'launchCamera', 'cameraStatus')}
|
||||
disabled={this.props.loading}
|
||||
>
|
||||
<Text style={styles.textButtonStyle}>{strings('common.buttons.takePhoto')}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
renderInputComponents(labelString, inputPlaceholderText, onChangeInput) {
|
||||
return (
|
||||
<View>
|
||||
<FormLabel
|
||||
bold
|
||||
labelText={labelString}
|
||||
textStyle={styles.labelStyle}
|
||||
/>
|
||||
<FormInput
|
||||
underlineColorAndroid={styles.colors.greyBlue}
|
||||
placeholder={inputPlaceholderText}
|
||||
onChangeText={value => this.setState({ [onChangeInput]: value })}
|
||||
style={styles.inputTextStyle}
|
||||
autoCorrect={false}
|
||||
autoCapitalize='none'
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
renderContent() {
|
||||
return (
|
||||
<ScrollView contentContainerStyle={styles.parentContentScrollViewStyle} keyboardShouldPersistTaps="handled">
|
||||
<View style={{ flex: 1 }}>
|
||||
{/* INSTRUCTIONS */}
|
||||
<Text style={styles.instructions}>{strings('userCreateFlow.defaultProfileCreate.instructions')}</Text>
|
||||
<Spacer />
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center'
|
||||
}}
|
||||
>
|
||||
{this.renderAvatarPhoto()}
|
||||
<Spacer />
|
||||
{this.renderLinkedInButtons()}
|
||||
{this.renderInputComponents(strings('common.contactFields.company_title_labelText'), strings('common.contactFields.company_title_placeholder'), 'jobTitle')}
|
||||
{this.renderInputComponents(strings('common.contactFields.company_name_labelText'), strings('common.contactFields.company_name_placeholder'), 'companyName')}
|
||||
{this.renderInputComponents(strings('common.contactFields.company_address_labelText'), strings('common.contactFields.company_address_placeholder'), 'companyAddress')}
|
||||
{this.renderInputComponents(strings('common.contactFields.company_number_labelText'), strings('common.contactFields.company_number_placeholder'), 'companyNumber')}
|
||||
<Text>{strings('userCreateFlow.defaultProfileCreate.no_verification_needed')}</Text>
|
||||
<Spacer />
|
||||
</View>
|
||||
</View>
|
||||
{/* SAVE AND CONTINUE BUTTON */}
|
||||
<Button
|
||||
onPress={this.onSaveButtonPress.bind(this)}
|
||||
title={strings('common.buttons.saveAndContinue')}
|
||||
loading={this.state.loading}
|
||||
style={styles.buttonStyle}
|
||||
fontSize={20}
|
||||
/>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render method
|
||||
**/
|
||||
render() {
|
||||
if (Platform.OS === 'android') {
|
||||
return this.renderContent();
|
||||
}
|
||||
|
||||
// IOS
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={{ flex: 1 }}
|
||||
keyboardVerticalOffset={90}
|
||||
behavior="padding"
|
||||
>
|
||||
{this.renderContent()}
|
||||
</KeyboardAvoidingView>
|
||||
);
|
||||
}
|
||||
}
|
||||
95
src/screens/auth/SignupScreen4/styles.js
Normal file
95
src/screens/auth/SignupScreen4/styles.js
Normal file
@ -0,0 +1,95 @@
|
||||
import { SCREEN_WIDTH, colors } from '../../styleVars';
|
||||
|
||||
const styles = {
|
||||
logoContainerStyle: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
},
|
||||
logoStyle: {
|
||||
marginTop: 20,
|
||||
width: 120,
|
||||
height: 120,
|
||||
borderWidth: 1,
|
||||
borderRadius: 60
|
||||
},
|
||||
buttonStyle: {
|
||||
width: SCREEN_WIDTH * 0.9,
|
||||
marginTop: 15,
|
||||
marginBottom: 30,
|
||||
borderRadius: 5,
|
||||
backgroundColor: colors.buttonBlue
|
||||
},
|
||||
inputTextStyle: {
|
||||
marginLeft: 15,
|
||||
color: colors.black,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: colors.black,
|
||||
},
|
||||
instructions: {
|
||||
fontSize: 16,
|
||||
fontFamily: 'Sans Serif',
|
||||
textAlign: 'left',
|
||||
color: colors.darkGrey,
|
||||
marginBottom: 5,
|
||||
marginHorizontal: 10
|
||||
},
|
||||
freeTextStyle: {
|
||||
left: 20,
|
||||
marginTop: 10,
|
||||
fontSize: 18
|
||||
},
|
||||
navigationHeaderRightStyle: {
|
||||
color: colors.middleGrey,
|
||||
marginRight: 5
|
||||
},
|
||||
parentContentScrollViewStyle: {
|
||||
flexGrow: 1,
|
||||
backgroundColor: colors.white
|
||||
},
|
||||
buttonContainerStyle: {
|
||||
flex: 2,
|
||||
marginTop: 15,
|
||||
flexDirection: 'column',
|
||||
justifyContent: 'center'
|
||||
},
|
||||
photoButtonsOrTextStyle: {
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
color: colors.lightGrey,
|
||||
marginTop: 5,
|
||||
marginBottom: 5,
|
||||
marginLeft: 15
|
||||
},
|
||||
avatarStyle: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginLeft: 25
|
||||
},
|
||||
noAvatarStyle: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
marginLeft: 10
|
||||
},
|
||||
textButtonStyle: {
|
||||
fontSize: 20,
|
||||
fontWeight: 'bold',
|
||||
color: colors.labelBlue,
|
||||
marginTop: 5,
|
||||
marginBottom: 5,
|
||||
marginLeft: 0
|
||||
},
|
||||
labelStyle: {
|
||||
fontWeight: 'bold',
|
||||
color: colors.labelBlue,
|
||||
marginTop: 5,
|
||||
marginLeft: 0
|
||||
},
|
||||
colors
|
||||
};
|
||||
|
||||
export default styles;
|
||||
6
src/screens/styleVars.js
Normal file
6
src/screens/styleVars.js
Normal file
@ -0,0 +1,6 @@
|
||||
import { Dimensions } from 'react-native';
|
||||
import colors from '../config/colors.json';
|
||||
|
||||
const SCREEN_WIDTH = Dimensions.get('window').width;
|
||||
|
||||
module.exports = { SCREEN_WIDTH, colors };
|
||||
@ -4,5 +4,17 @@ export function isEmail(email) {
|
||||
}
|
||||
|
||||
export function isEmpty(value) {
|
||||
if (typeof value === 'object') {
|
||||
return Object.keys(value).length === 0 && value.constructor === Object;
|
||||
}
|
||||
return !value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an object to a query string.
|
||||
*/
|
||||
export function toQueryString(params) {
|
||||
return '?' + Object.entries(params)
|
||||
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||
.join('&');
|
||||
}
|
||||
|
||||
@ -40,6 +40,22 @@ export function getErrorObject(error) {
|
||||
type: 'Authentication Error',
|
||||
desc: 'Verification code mismatch'
|
||||
};
|
||||
case errors.AUTH_LINKEDIN_REQUEST_TOKEN_FAILURE: return {
|
||||
type: 'Authentication Error',
|
||||
desc: 'Could not retrieve your login info'
|
||||
};
|
||||
case errors.AUTH_LINKEDIN_ACCESS_TOKEN_FAILURE: return {
|
||||
type: 'Authentication Error',
|
||||
desc: 'Could not log into your account'
|
||||
};
|
||||
case errors.AUTH_LINKEDIN_PROFILE_REQUEST_FAILURE: return {
|
||||
type: 'Authentication Error',
|
||||
desc: 'Could not retrieve your profile info'
|
||||
};
|
||||
case errors.AUTH_LINKEDIN_TOKEN_SCOPE_INVALID_REQUEST_FAILURE: return {
|
||||
type: 'Authentication Error',
|
||||
desc: 'There was a problem connecting to linkedin login, if you have previously authenticated Tagfer with your account please remove the tagfer app from account and reconnect tagfer.'
|
||||
};
|
||||
case errors.APP_NETWORK_ERROR: return {
|
||||
type: 'Network Error',
|
||||
desc: 'Request failed, check your internet connection.'
|
||||
@ -52,6 +68,12 @@ export function getErrorObject(error) {
|
||||
type: 'Network Error',
|
||||
desc: 'Unable to get the response.'
|
||||
};
|
||||
|
||||
case errors.APP_FIREBASE_DATABASE_ERROR: return {
|
||||
type: 'Network Error',
|
||||
desc: 'Unable to save data to our servers.'
|
||||
};
|
||||
|
||||
default: return {
|
||||
type: 'Error',
|
||||
desc: 'Oops, an error occured! Please try again.'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user