diff --git a/package.json b/package.json index f1786e0c3..fcb6b280d 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "amplitude-js": "^4.0.0", "bluebird": "^3.5.1", "classnames": "^2.2.5", + "country-data": "^0.0.31", "electron-dl": "^1.6.0", "formik": "^0.10.4", "from2": "^2.3.0", diff --git a/src/renderer/component/userPhoneNew/index.js b/src/renderer/component/userPhoneNew/index.js new file mode 100644 index 000000000..3033a3c2c --- /dev/null +++ b/src/renderer/component/userPhoneNew/index.js @@ -0,0 +1,15 @@ +import React from 'react'; +import { connect } from 'react-redux'; +import { doUserPhoneNew } from 'redux/actions/user'; +import { selectPhoneNewErrorMessage } from 'redux/selectors/user'; +import UserPhoneNew from './view'; + +const select = state => ({ + phoneErrorMessage: selectPhoneNewErrorMessage(state), +}); + +const perform = dispatch => ({ + addUserPhone: (phone, country_code) => dispatch(doUserPhoneNew(phone, country_code)), +}); + +export default connect(select, perform)(UserPhoneNew); diff --git a/src/renderer/component/userPhoneNew/view.jsx b/src/renderer/component/userPhoneNew/view.jsx new file mode 100644 index 000000000..b9999c746 --- /dev/null +++ b/src/renderer/component/userPhoneNew/view.jsx @@ -0,0 +1,109 @@ +import React from 'react'; +import { Form, FormRow, Submit } from 'component/form.js'; +import FormField from 'component/formField'; + +const os = require('os').type(); +const countryCodes = require('country-data') + .callingCountries.all.filter(_ => _.emoji) + .reduce( + (acc, cur) => acc.concat(cur.countryCallingCodes.map(_ => ({ ...cur, countryCallingCode: _ }))), + [] + ) + .sort((a, b) => { + if (a.countryCallingCode < b.countryCallingCode) { + return -1; + } + if (a.countryCallingCode > b.countryCallingCode) { + return 1; + } + return 0; + }); + +class UserPhoneNew extends React.PureComponent { + constructor(props) { + super(props); + + this.state = { + phone: '', + country_code: '+1', + }; + + this.formatPhone = this.formatPhone.bind(this); + } + + formatPhone(value) { + const { country_code } = this.state; + value = value.replace(/\D/g, ''); + if (country_code === '+1') { + if (!value) { + return ''; + } else if (value.length < 4) { + return value; + } else if (value.length < 7) { + return `(${value.substring(0, 3)}) ${value.substring(3)}`; + } + const fullNumber = `(${value.substring(0, 3)}) ${value.substring(3, 6)}-${value.substring( + 6 + )}`; + return fullNumber.length <= 14 ? fullNumber : fullNumber.substring(0, 14); + } + return value; + } + + handleChanged(event) { + this.setState({ + phone: this.formatPhone(event.target.value), + }); + } + + handleSelect(event) { + this.setState({ country_code: event.target.value }); + } + + handleSubmit() { + const { phone, country_code } = this.state; + this.props.addUserPhone(phone.replace(/\D/g, ''), country_code.substring(1)); + } + + render() { + const { cancelButton, phoneErrorMessage, isPending } = this.props; + + return ( +
+ {__( + 'Enter your phone number and we will send you a verification code. We will not share your phone number with third parties.' + )} +
+ +
@@ -96,7 +119,7 @@ class UserVerify extends React.PureComponent {
diff --git a/src/renderer/constants/action_types.js b/src/renderer/constants/action_types.js
index 861957d36..f0602c1f2 100644
--- a/src/renderer/constants/action_types.js
+++ b/src/renderer/constants/action_types.js
@@ -109,6 +109,13 @@ export const USER_EMAIL_NEW_FAILURE = 'USER_EMAIL_NEW_FAILURE';
export const USER_EMAIL_VERIFY_STARTED = 'USER_EMAIL_VERIFY_STARTED';
export const USER_EMAIL_VERIFY_SUCCESS = 'USER_EMAIL_VERIFY_SUCCESS';
export const USER_EMAIL_VERIFY_FAILURE = 'USER_EMAIL_VERIFY_FAILURE';
+export const USER_PHONE_RESET = 'USER_PHONE_RESET';
+export const USER_PHONE_NEW_STARTED = 'USER_PHONE_NEW_STARTED';
+export const USER_PHONE_NEW_SUCCESS = 'USER_PHONE_NEW_SUCCESS';
+export const USER_PHONE_NEW_FAILURE = 'USER_PHONE_NEW_FAILURE';
+export const USER_PHONE_VERIFY_STARTED = 'USER_PHONE_VERIFY_STARTED';
+export const USER_PHONE_VERIFY_SUCCESS = 'USER_PHONE_VERIFY_SUCCESS';
+export const USER_PHONE_VERIFY_FAILURE = 'USER_PHONE_VERIFY_FAILURE';
export const USER_IDENTITY_VERIFY_STARTED = 'USER_IDENTITY_VERIFY_STARTED';
export const USER_IDENTITY_VERIFY_SUCCESS = 'USER_IDENTITY_VERIFY_SUCCESS';
export const USER_IDENTITY_VERIFY_FAILURE = 'USER_IDENTITY_VERIFY_FAILURE';
diff --git a/src/renderer/constants/modal_types.js b/src/renderer/constants/modal_types.js
index 9c6d457f9..19b86238e 100644
--- a/src/renderer/constants/modal_types.js
+++ b/src/renderer/constants/modal_types.js
@@ -7,6 +7,7 @@ export const INSUFFICIENT_CREDITS = 'insufficient_credits';
export const UPGRADE = 'upgrade';
export const WELCOME = 'welcome';
export const EMAIL_COLLECTION = 'email_collection';
+export const PHONE_COLLECTION = 'phone_collection';
export const FIRST_REWARD = 'first_reward';
export const AUTHENTICATION_FAILURE = 'auth_failure';
export const TRANSACTION_FAILED = 'transaction_failed';
diff --git a/src/renderer/modal/modalPhoneCollection/index.js b/src/renderer/modal/modalPhoneCollection/index.js
new file mode 100644
index 000000000..d3ae17bc6
--- /dev/null
+++ b/src/renderer/modal/modalPhoneCollection/index.js
@@ -0,0 +1,22 @@
+import React from 'react';
+import * as settings from 'constants/settings';
+import { connect } from 'react-redux';
+import { doCloseModal } from 'redux/actions/app';
+import { doSetClientSetting } from 'redux/actions/settings';
+import { selectPhoneToVerify, selectUser } from 'redux/selectors/user';
+import ModalPhoneCollection from './view';
+import { doNavigate } from 'redux/actions/navigation';
+
+const select = state => ({
+ phone: selectPhoneToVerify(state),
+ user: selectUser(state),
+});
+
+const perform = dispatch => () => ({
+ closeModal: () => {
+ dispatch(doCloseModal());
+ dispatch(doNavigate('/rewards'));
+ },
+});
+
+export default connect(select, perform)(ModalPhoneCollection);
diff --git a/src/renderer/modal/modalPhoneCollection/view.jsx b/src/renderer/modal/modalPhoneCollection/view.jsx
new file mode 100644
index 000000000..bf1ead9f6
--- /dev/null
+++ b/src/renderer/modal/modalPhoneCollection/view.jsx
@@ -0,0 +1,40 @@
+import React from 'react';
+import { Modal } from 'modal/modal';
+import Link from 'component/link/index';
+import UserPhoneNew from 'component/userPhoneNew';
+import UserPhoneVerify from 'component/userPhoneVerify';
+
+class ModalPhoneCollection extends React.PureComponent {
+ renderInner() {
+ const { closeModal, phone, user } = this.props;
+
+ const cancelButton = ;
+
+ if (!user.phone_number && !phone) {
+ return {__('3) Proof via Chat')}
+ {__('4) Proof via Chat')}
Verify Your Phone
+ {this.renderInner()}
+