import React, { useState, useEffect, useContext, useRef } from 'react'; import { useHistory } from 'react-router-dom'; import axios from 'axios'; import { NotificationDispatchContext } from '../../contexts/NotificationContext'; import Form from '../elements/Form'; import Input from '../elements/Input'; import Label from '../elements/Label'; import Select from '../elements/Select'; import InputGroup from '../elements/InputGroup'; import PasswordInput from '../elements/PasswordInput'; import FormError from '../blocks/FormError'; import Button from '../elements/Button'; import SpeechSynthesisLanguageGoogle from '../../data/SpeechSynthesisLanguageGoogle'; import SpeechSynthesisLanguageAws from '../../data/SpeechSynthesisLanguageAws'; import SpeechRecognizerLanguageGoogle from '../../data/SpeechRecognizerLanguageGoogle'; import SpeechRecognizerLanguageAws from '../../data/SpeechRecognizerLanguageAws'; import Loader from '../blocks/Loader'; import CopyableText from '../elements/CopyableText'; const ApplicationForm = props => { let history = useHistory(); const dispatch = useContext(NotificationDispatchContext); // Refs const refName = useRef(null); const refAccount = useRef(null); const refCallWebhook = useRef(null); const refCallWebhookUser = useRef(null); const refCallWebhookPass = useRef(null); const refStatusWebhook = useRef(null); const refStatusWebhookUser = useRef(null); const refStatusWebhookPass = useRef(null); const refMessagingWebhookUser = useRef(null); const refMessagingWebhookPass = useRef(null); // Form inputs const [ name, setName ] = useState(''); const [ accountSid, setAccountSid ] = useState(''); const [ callWebhook, setCallWebhook ] = useState(''); const [ callWebhookMethod, setCallWebhookMethod ] = useState('POST'); const [ callWebhookUser, setCallWebhookUser ] = useState(''); const [ callWebhookPass, setCallWebhookPass ] = useState(''); const [ statusWebhook, setStatusWebhook ] = useState(''); const [ statusWebhookMethod, setStatusWebhookMethod ] = useState('POST'); const [ statusWebhookUser, setStatusWebhookUser ] = useState(''); const [ statusWebhookPass, setStatusWebhookPass ] = useState(''); const [ messagingWebhook, setMessagingWebhook ] = useState(''); const [ messagingWebhookMethod, setMessagingWebhookMethod ] = useState('POST'); const [ messagingWebhookUser, setMessagingWebhookUser ] = useState(''); const [ messagingWebhookPass, setMessagingWebhookPass ] = useState(''); const [ speechSynthesisVendor, setSpeechSynthesisVendor ] = useState('google'); const [ speechSynthesisLanguage, setSpeechSynthesisLanguage ] = useState('en-US'); const [ speechSynthesisVoice, setSpeechSynthesisVoice ] = useState('en-US-Standard-C'); const [ speechRecognizerVendor, setSpeechRecognizerVendor ] = useState('google'); const [ speechRecognizerLanguage, setSpeechRecognizerLanguage ] = useState('en-US'); // Invalid form inputs const [ invalidName, setInvalidName ] = useState(false); const [ invalidAccount, setInvalidAccount ] = useState(false); const [ invalidCallWebhook, setInvalidCallWebhook ] = useState(false); const [ invalidCallWebhookUser, setInvalidCallWebhookUser ] = useState(false); const [ invalidCallWebhookPass, setInvalidCallWebhookPass ] = useState(false); const [ invalidStatusWebhook, setInvalidStatusWebhook ] = useState(false); const [ invalidStatusWebhookUser, setInvalidStatusWebhookUser ] = useState(false); const [ invalidStatusWebhookPass, setInvalidStatusWebhookPass ] = useState(false); const [ invalidMessagingWebhookUser, setInvalidMessagingWebhookUser ] = useState(false); const [ invalidMessagingWebhookPass, setInvalidMessagingWebhookPass ] = useState(false); const [ showLoader, setShowLoader ] = useState(true); const [ errorMessage, setErrorMessage ] = useState(''); const [ showCallAuth, setShowCallAuth ] = useState(false); const toggleCallAuth = () => setShowCallAuth(!showCallAuth); const [ showStatusAuth, setShowStatusAuth ] = useState(false); const toggleStatusAuth = () => setShowStatusAuth(!showStatusAuth); const [ showMessagingAuth, setShowMessagingAuth ] = useState(false); const toggleMessagingAuth = () => setShowMessagingAuth(!showMessagingAuth); const [ accounts, setAccounts ] = useState([]); const [ applications, setApplications ] = useState([]); const [ applicationSid, setApplicationSid ] = useState([]); // See if user logged in useEffect(() => { const getAPIData = async () => { try { if (!localStorage.getItem('token')) { history.push('/'); dispatch({ type: 'ADD', level: 'error', message: 'You must log in to view that page.', }); return; } const accountsPromise = axios({ method: 'get', baseURL: process.env.REACT_APP_API_BASE_URL, url: '/Accounts', headers: { Authorization: `Bearer ${localStorage.getItem('token')}`, }, }); const applicationsPromise = axios({ method: 'get', baseURL: process.env.REACT_APP_API_BASE_URL, url: '/Applications', headers: { Authorization: `Bearer ${localStorage.getItem('token')}`, }, }); const promiseAllValues = await Promise.all([ accountsPromise, applicationsPromise, ]); const accounts = promiseAllValues[0].data; const applications = promiseAllValues[1].data; setAccounts(accounts); setApplications(applications); if (accounts.length === 0) { history.push('/internal/accounts'); dispatch({ type: 'ADD', level: 'error', message: 'You must create an account before you can create an application.', }); return; } if ( (props.type === 'setup' && accounts.length > 1) || (props.type === 'setup' && applications.length > 1) ) { history.push('/internal/applications'); dispatch({ type: 'ADD', level: 'error', message: 'That page is only accessible during setup.', }); } if (props.type === 'add' && accounts.length === 1) { setAccountSid(accounts[0].account_sid); } if (props.type === 'setup' || props.type === 'edit') { const currentApplication = props.type === 'edit' ? applications.filter(a => a.application_sid === props.application_sid) : applications; if (props.type === 'edit' && !currentApplication.length) { history.push('/internal/applications'); dispatch({ type: 'ADD', level: 'error', message: 'That application does not exist.', }); return; } if (!currentApplication.length) { setName('default application'); setAccountSid(accounts[0].account_sid); } else { const app = currentApplication[0]; setName( app.name || ''); setCallWebhook( (app.call_hook && app.call_hook.url) || ''); setCallWebhookMethod( (app.call_hook && app.call_hook.method) || 'post'); setCallWebhookUser( (app.call_hook && app.call_hook.username) || ''); setCallWebhookPass( (app.call_hook && app.call_hook.password) || ''); setStatusWebhook( (app.call_status_hook && app.call_status_hook.url) || ''); setStatusWebhookMethod( (app.call_status_hook && app.call_status_hook.method) || 'post'); setStatusWebhookUser( (app.call_status_hook && app.call_status_hook.username) || ''); setStatusWebhookPass( (app.call_status_hook && app.call_status_hook.password) || ''); setMessagingWebhook( (app.messaging_hook && app.messaging_hook.url) || ''); setMessagingWebhookMethod( (app.messaging_hook && app.messaging_hook.method) || 'post'); setMessagingWebhookUser( (app.messaging_hook && app.messaging_hook.username) || ''); setMessagingWebhookPass( (app.messaging_hook && app.messaging_hook.password) || ''); setSpeechSynthesisVendor( app.speech_synthesis_vendor || ''); setSpeechSynthesisLanguage( app.speech_synthesis_language || ''); setSpeechSynthesisVoice( app.speech_synthesis_voice || ''); setSpeechRecognizerVendor( app.speech_recognizer_vendor || ''); setSpeechRecognizerLanguage( app.speech_recognizer_language || ''); setAccountSid( app.account_sid || ''); setApplicationSid( app.application_sid); if ( (app.call_hook && app.call_hook.username) || (app.call_hook && app.call_hook.password) ) { setShowCallAuth(true); } if ( (app.call_status_hook && app.call_status_hook.username) || (app.call_status_hook && app.call_status_hook.password) ) { setShowStatusAuth(true); } if ( (app.messaging_hook && app.messaging_hook.username) || (app.messaging_hook && app.messaging_hook.password) ) { setShowMessagingAuth(true); } } } setShowLoader(false); } catch (err) { if (err.response && err.response.status === 401) { localStorage.removeItem('token'); sessionStorage.clear(); history.push('/'); dispatch({ type: 'ADD', level: 'error', message: 'Your session has expired. Please log in and try again.', }); } else { dispatch({ type: 'ADD', level: 'error', message: (err.response && err.response.data && err.response.data.msg) || 'Unable to get accounts', }); console.log(err.response || err); } setShowLoader(false); } }; getAPIData(); // eslint-disable-next-line }, []); const handleSubmit = async (e) => { let isMounted = true; try { setShowLoader(true); e.preventDefault(); setErrorMessage(''); setInvalidName(false); setInvalidAccount(false); setInvalidCallWebhook(false); setInvalidCallWebhookUser(false); setInvalidCallWebhookPass(false); setInvalidStatusWebhook(false); setInvalidStatusWebhookUser(false); setInvalidStatusWebhookPass(false); setInvalidMessagingWebhookUser(false); setInvalidMessagingWebhookPass(false); let errorMessages = []; let focusHasBeenSet = false; if ((props.type === 'add' || props.type === 'edit') && !name) { errorMessages.push('Please provide a name.'); setInvalidName(true); if (!focusHasBeenSet) { refName.current.focus(); focusHasBeenSet = true; } } // check if name is already in use if ((props.type === 'add' || props.type === 'edit') && !accountSid) { errorMessages.push('Please choose an account for this application to be associated with.'); setInvalidAccount(true); if (!focusHasBeenSet) { refAccount.current.focus(); focusHasBeenSet = true; } } if (!callWebhook) { errorMessages.push('Please enter a Calling Webhook.'); setInvalidCallWebhook(true); if (!focusHasBeenSet) { refCallWebhook.current.focus(); focusHasBeenSet = true; } } if (!statusWebhook) { errorMessages.push('Please enter a Call Status Webhook.'); setInvalidStatusWebhook(true); if (!focusHasBeenSet) { refStatusWebhook.current.focus(); focusHasBeenSet = true; } } if ((callWebhookUser && !callWebhookPass) || (!callWebhookUser && callWebhookPass)) { errorMessages.push('Calling Webhook username and password must be either both filled out or both empty.'); setInvalidCallWebhookUser(true); setInvalidCallWebhookPass(true); if (!focusHasBeenSet) { if (!callWebhookUser) { refCallWebhookUser.current.focus(); } else { refCallWebhookPass.current.focus(); } focusHasBeenSet = true; } } if ((statusWebhookUser && !statusWebhookPass) || (!statusWebhookUser && statusWebhookPass)) { errorMessages.push('Call Status Webhook username and password must be either both filled out or both empty.'); setInvalidStatusWebhookUser(true); setInvalidStatusWebhookPass(true); if (!focusHasBeenSet) { if (!statusWebhookUser) { refStatusWebhookUser.current.focus(); } else { refStatusWebhookPass.current.focus(); } focusHasBeenSet = true; } } if ((messagingWebhookUser && !messagingWebhookPass) || (!messagingWebhookUser && messagingWebhookPass)) { errorMessages.push('Messaging Webhook username and password must be either both filled out or both empty.'); setInvalidMessagingWebhookUser(true); setInvalidMessagingWebhookPass(true); if (!focusHasBeenSet) { if (!messagingWebhookUser) { refMessagingWebhookUser.current.focus(); } else { refMessagingWebhookPass.current.focus(); } focusHasBeenSet = true; } } if (errorMessages.length > 1) { setErrorMessage(errorMessages); return; } else if (errorMessages.length === 1) { setErrorMessage(errorMessages[0]); return; } //============================================================================= // Submit //============================================================================= const shouldCreateNew = props.type === 'add' || (props.type === 'setup' && !applications.length); const method = shouldCreateNew ? 'post' : 'put'; const url = shouldCreateNew ? '/Applications' : `/Applications/${applicationSid}`; const data = { account_sid: accountSid, name: name.trim(), call_hook: { url: callWebhook.trim(), method: callWebhookMethod, username: callWebhookUser.trim() || null, password: callWebhookPass || null, }, call_status_hook: { url: statusWebhook.trim(), method: statusWebhookMethod, username: statusWebhookUser.trim() || null, password: statusWebhookPass || null, }, messaging_hook: { url: messagingWebhook.trim(), method: messagingWebhookMethod, username: messagingWebhookUser.trim() || null, password: messagingWebhookPass || null, }, speech_synthesis_vendor: speechSynthesisVendor, speech_synthesis_language: speechSynthesisLanguage, speech_synthesis_voice: speechSynthesisVoice, speech_recognizer_vendor: speechRecognizerVendor, speech_recognizer_language: speechRecognizerLanguage, }; await axios({ method, baseURL: process.env.REACT_APP_API_BASE_URL, url, headers: { Authorization: `Bearer ${localStorage.getItem('token')}`, }, data, }); if (props.type === 'setup') { isMounted = false; history.push('/configure-sip-trunk'); } else { isMounted = false; history.push('/internal/applications'); const dispatchMessage = props.type === 'add' ? 'Application created successfully' : 'Application updated successfully'; dispatch({ type: 'ADD', level: 'success', message: dispatchMessage }); } } catch (err) { if (err.response && err.response.status === 401) { localStorage.removeItem('token'); sessionStorage.clear(); isMounted = false; history.push('/'); dispatch({ type: 'ADD', level: 'error', message: 'Your session has expired. Please log in and try again.', }); } else { setErrorMessage((err.response && err.response.data && err.response.data.msg) || 'Something went wrong, please try again.'); console.log(err.response || err); } } finally { if (isMounted) { setShowLoader(false); } } }; return ( showLoader ? :
{props.type === 'edit' && ( )} {(props.type === 'add' || props.type === 'edit') && ( setName(e.target.value)} placeholder="Application name" invalid={invalidName} autoFocus ref={refName} />

)} setCallWebhook(e.target.value)} placeholder="URL for your web application that will handle calls" invalid={invalidCallWebhook} ref={refCallWebhook} autoFocus={props.type === 'setup'} /> {showCallAuth ? ( setCallWebhookUser(e.target.value)} placeholder="Optional" invalid={invalidCallWebhookUser} ref={refCallWebhookUser} /> ) : ( )}
setStatusWebhook(e.target.value)} placeholder="URL for your web application that will receive call status" invalid={invalidStatusWebhook} ref={refStatusWebhook} /> {showStatusAuth ? ( setStatusWebhookUser(e.target.value)} placeholder="Optional" invalid={invalidStatusWebhookUser} ref={refStatusWebhookUser} /> ) : ( )}
setMessagingWebhook(e.target.value)} placeholder="URL for your web application that will receive SMS" /> {showMessagingAuth ? ( setMessagingWebhookUser(e.target.value)} placeholder="Optional" invalid={invalidMessagingWebhookUser} ref={refMessagingWebhookUser} /> ) : ( )}

{errorMessage && ( )} {props.type === 'edit' && ( )} ); }; export default ApplicationForm;