SumOfUs/Champaign

View on GitHub
app/javascript/plugins/email_pension/EmailRepresentativeView.js

Summary

Maintainability
D
2 days
Test Coverage
import React, { Component } from 'react';
import { isEmpty, find, template, merge, each, pick } from 'lodash';

import Input from '../../components/SweetInput/SweetInput';
import Button from '../../components/Button/Button';
import FormGroup from '../../components/Form/FormGroup';
import EmailEditor from '../../components/EmailEditor/EmailEditor';
import SelectTarget from './SelectTarget';
import SelectCountry from '../../components/SelectCountry/SelectCountry';
import { FormattedMessage, injectIntl } from 'react-intl';
import './EmailPensionView.scss';
import { MailerClient } from '../../util/ChampaignClient';

class EmailRepresentativeView extends Component {
  constructor(props) {
    super(props);

    this.handleChange = this.handleChange.bind(this);

    this.defaultTemplateVars = {
      targets_names: this.props.intl.formatMessage({
        id: 'email_tool.template_defaults.target_full_name',
      }),
      constituency: this.props.intl.formatMessage({
        id: 'email_tool.template_defaults.constituency_name',
      }),
      name: this.props.intl.formatMessage({
        id: 'email_tool.template_defaults.name',
      }),
    };

    this.state = {
      errors: {},
      targets: [],
      name: '',
      email: '',
      subject: '',
      country: '',
      target_name: '',
      target_email: '',
      ...props,
    };
  }

  validateForm() {
    const errors = {};

    const fields = ['country', 'subject', 'name', 'email', 'targets'];

    fields.forEach(field => {
      if (isEmpty(this.state[field])) {
        const location = `email_tool.form.errors.${field}`;
        const message = <FormattedMessage id={location} />;
        errors[field] = message;
      }
    });

    this.setState({ errors: errors });
    return isEmpty(errors);
  }

  templateVars() {
    let vars = pick(this.state, ['name', 'email', 'constituency']);

    if (this.state.targets) {
      vars.targets_names = this.state.targets
        .map(
          target => `${target.title} ${target.first_name} ${target.last_name}`
        )
        .join(', ');
    }

    each(this.defaultTemplateVars, (val, key) => {
      if (vars[key] === undefined || vars[key] === '') {
        vars[key] = val;
      }
    });

    return vars;
  }

  onEmailEditorUpdate = ({ subject, body }) => {
    this.setState(state => ({ ...state, body, subject }));
  };

  errorNotice = () => {
    if (!isEmpty(this.state.errors)) {
      return (
        <span className="error-msg left-align">
          <FormattedMessage id="email_tool.form.errors.message" />
        </span>
      );
    }
  };

  onSubmission = e => {
    e.preventDefault();

    const valid = this.validateForm();
    if (!valid) return;

    const payload = {
      body: this.state.body,
      country: this.state.country,
      subject: this.state.subject,
      from_name: this.state.name,
      from_email: this.state.email,
      postcode: this.state.postcode.trim(),
      plugin_id: this.props.pluginId,
    };

    merge(payload, this.props.formValues);
    this.setState({ isSubmitting: true });

    MailerClient.sendPensionEmail({ page_id: this.props.pageId, payload }).then(
      response => {
        window.location.href = URI(`${response.data.follow_up_page}`);
      },
      ({ errors }) => {
        this.setState(s => ({ ...s, errors }));
      }
    );
  };

  handleTargetSelection(data) {
    this.setState({
      constituency: data.targets[0].constituency,
      targets: data.targets,
      postcode: data.postcode,
    });
  }

  handleChange(data) {
    this.setState(data);
  }

  render() {
    return (
      <div className="email-target">
        <div className="email-target-form">
          <form
            onSubmit={e => e.preventDefault()}
            className="action-form form--big"
          >
            <FormGroup>
              <SelectCountry
                value={this.state.country}
                name="country"
                label={
                  <FormattedMessage
                    id="email_tool.form.select_country"
                    defaultMessage="Select country (default)"
                  />
                }
                className="form-control"
                errorMessage={this.state.errors.country}
                onChange={value => {
                  this.handleChange({ country: value });
                }}
              />
            </FormGroup>
            <SelectTarget
              handler={this.handleTargetSelection.bind(this)}
              endpoint={this.props.targetEndpoint}
              error={this.state.errors.targets}
            />

            <div className="email-target-action">
              <h3>
                <FormattedMessage
                  id="email_tool.section.compose"
                  defaultMessage="Compose Your Email"
                />
              </h3>

              <FormGroup>
                <Input
                  name="name"
                  label={
                    <FormattedMessage
                      id="email_tool.form.your_name"
                      defaultMessage="Your name (default)"
                    />
                  }
                  value={this.state.name}
                  errorMessage={this.state.errors.name}
                  onChange={value => {
                    this.handleChange({ name: value });
                  }}
                />
              </FormGroup>

              <FormGroup>
                <Input
                  name="email"
                  type="email"
                  label={
                    <FormattedMessage
                      id="email_tool.form.your_email"
                      defaultMessage="Your email (default)"
                    />
                  }
                  value={this.state.email}
                  errorMessage={this.state.errors.email}
                  onChange={value => {
                    this.handleChange({ email: value });
                  }}
                />
              </FormGroup>

              <EmailEditor
                errors={this.state.errors}
                body={this.props.emailBody}
                header={this.props.emailHeader}
                footer={this.props.emailFooter}
                subject={this.props.emailSubject}
                templateVars={this.templateVars()}
                onUpdate={this.onEmailEditorUpdate}
              />
            </div>

            <div className="form__group">
              <Button
                onClick={this.onSubmission}
                disabled={this.state.isSubmitting}
                type="button"
                className="button action-form__submit-button"
              >
                <FormattedMessage
                  id="email_tool.form.send_email"
                  defaultMessage="Send email (default)"
                />
              </Button>
              {this.errorNotice()}
            </div>
          </form>
        </div>
      </div>
    );
  }
}

export default injectIntl(EmailRepresentativeView);