From 18f7b413bd0e0b3a3205877d42787a331c54cf1f Mon Sep 17 00:00:00 2001
From: dallasjc <39286778+dallasjc@users.noreply.github.com>
Date: Thu, 26 Sep 2019 18:20:29 -0500
Subject: [PATCH 03/16] Make searchAuthor form functional
---
effects/import.js | 101 ++++++++++++++++++++++++++++++++++++++
models/import.js | 6 +++
views/import-author.js | 47 +++++++++---------
views/import-vote-page.js | 3 +-
4 files changed, 133 insertions(+), 24 deletions(-)
diff --git a/effects/import.js b/effects/import.js
index 53bcd76..5ce79a2 100644
--- a/effects/import.js
+++ b/effects/import.js
@@ -1,4 +1,5 @@
const { api } = require('../helpers')
+const fetch = require('isomorphic-fetch')
exports.searchAuthor = ({ event, ...formData }, user) => (dispatch) => {
const terms = formData.add_author && formData.add_author.search && formData.add_author.search
@@ -15,3 +16,103 @@ exports.searchAuthor = ({ event, ...formData }, user) => (dispatch) => {
})
.catch(error => dispatch({ type: 'error', error }))
}
+exports.addAuthorViaEmail = ({ event, ...formData }, proxies, user) => (dispatch) => {
+ if (!formData.add_author) return
+
+ const name = formData.add_author.name.trim().split(' ')
+
+ if (name.length < 2) {
+ return dispatch({ type: 'error', error: Object.assign(new Error('Please enter a first and last name'), { name: true }) })
+ } else if (name.length > 5) {
+ return dispatch({ type: 'error', error: Object.assign(new Error('Please enter only a first and last name'), { name: true }) })
+ }
+
+ const first_name = formData.add_author.name.trim().split(' ')[0]
+ const last_name = formData.add_author.name.trim().split(' ').slice(1).join(' ')
+
+ return api(dispatch, '/delegations', {
+ method: 'POST',
+ headers: { Prefer: 'return=representation' }, // returns created delegation in response
+ body: JSON.stringify({
+ from_id: user.id,
+ first_name,
+ last_name,
+ email: formData.add_author.email ? formData.add_author.email.toLowerCase().trim() : null,
+ }),
+ user,
+ })
+ .then((delegations) => {
+ if (event) event.target.reset()
+ return api(dispatch, `/delegations_detailed?id=eq.${delegations[0].id}`, { user }).then(profiles => {
+ return dispatch({
+ type: 'proxy:proxiesUpdated',
+ proxies: (proxies || []).concat(profiles[0] || delegations[0]),
+ })
+ })
+ })
+ .catch(errorHandler(dispatch))
+}
+
+exports.addAuthorViaTwitter = ({ event, ...formData }, proxies, user) => (dispatch) => {
+ if (!formData.add_author) return
+
+ let twitter_username = null
+ if (formData.add_author.twitter_username) {
+ twitter_username = formData.add_author.twitter_username.trim().replace(/@/g, '')
+ }
+
+ return fetch('/rpc/twitter_username_search', {
+ headers: {
+ 'Content-Type': 'application/json',
+ 'Accept': 'application/json',
+ },
+ method: 'POST',
+ body: JSON.stringify({ twitter_username }),
+ })
+ .then(res => {
+ if (res.status === 404) {
+ return res.json().then(json => {
+ return Promise.reject(new Error(json.message))
+ })
+ }
+ return res.json()
+ })
+ .then((twitter_user) => {
+ return api(dispatch, '/delegations', {
+ method: 'POST',
+ headers: { Prefer: 'return=representation' }, // returns created delegation in response
+ body: JSON.stringify({
+ from_id: user.id,
+ twitter_username: twitter_user.twitter_username.replace(/@/g, ''),
+ twitter_displayname: twitter_user.name,
+ twitter_avatar: twitter_user.avatar,
+ bio: twitter_user.description,
+ delegate_rank: 0,
+ }),
+ user,
+ })
+ .then((newProxies) => {
+ if (event) event.target.reset()
+ return api(dispatch, `/delegations_detailed?id=eq.${newProxies[0].id}`, { user }).then(profiles => {
+ return dispatch({
+ type: 'proxy:proxiesUpdated',
+ proxies: (proxies || []).concat(profiles[0] || newProxies[0]),
+ })
+ })
+ })
+ })
+ .catch(errorHandler(dispatch))
+}
+
+exports.addAuthorViaSearch = ({ event, ...formData }) => (dispatch) => {
+ dispatch({ type: 'cookieSet', key: 'author_id', value: formData.author_id })
+ dispatch({ type: 'cookieSet', key: 'author_username', value: formData.author_username })
+}
+const errorHandler = (error) => {
+ if (error.code === 23514) {
+ if (~error.message.indexOf('email')) {
+ error.email = true
+ error.message = 'Invalid email address'
+ }
+ }
+}
diff --git a/models/import.js b/models/import.js
index 2d89d5b..ae0165a 100644
--- a/models/import.js
+++ b/models/import.js
@@ -18,6 +18,12 @@ module.exports = (event, state) => {
...state,
loading: { ...state.loading, proxySearch: true },
}, combineEffects([preventDefault(event.event), importEffect('searchAuthor', event, state.user)])]
+ case 'import:addedAuthorViaEmail':
+ return [state, combineEffects([preventDefault(event.event), importEffect('addAuthorViaEmail', event, state.user)])]
+ case 'import:addedAuthorViaTwitter':
+ return [state, combineEffects([preventDefault(event.event), importEffect('addAuthorViaTwitter', event, state.user)])]
+ case 'import:addedAuthorViaSearch':
+ return [state, combineEffects([preventDefault(event.event), importEffect('addAuthorViaSearch', event, state.user)])]
case 'import:authorSearchResultsUpdated':
return [{
...state,
diff --git a/views/import-author.js b/views/import-author.js
index 58bffb0..3bd36c4 100644
--- a/views/import-author.js
+++ b/views/import-author.js
@@ -4,8 +4,8 @@ const { icon } = require('@fortawesome/fontawesome-svg-core')
const { faUser } = require('@fortawesome/free-solid-svg-icons/faUser')
const { faTwitter } = require('@fortawesome/free-brands-svg-icons/faTwitter')
const { faExclamationTriangle } = require('@fortawesome/free-solid-svg-icons/faExclamationTriangle')
+const { faEdit } = require('@fortawesome/free-solid-svg-icons/faEdit')
const { faEnvelope } = require('@fortawesome/free-solid-svg-icons/faEnvelope')
-const { faHandshake } = require('@fortawesome/free-solid-svg-icons/faHandshake')
const { faPlus } = require('@fortawesome/free-solid-svg-icons/faPlus')
module.exports = (state, dispatch) => {
@@ -34,7 +34,7 @@ const addAuthorByEmailForm = (state, dispatch) => {
return html`