dynamic/silverstripe-locator-frontend-react

View on GitHub
client/src/js/containers/list/Location.jsx

Summary

Maintainability
A
0 mins
Test Coverage
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { loadComponent } from 'lib/Injector';

import {categoriesToClasses} from 'generalFunctions';

/**
 * The Location component.
 * Used in the location list.
 */
class Location extends Component {
  /**
   * Replaces any trailing '+' and whitespace and any spaces left with '+'
   *
   * @param address
   * @returns String
   */
  static cleanAddress(address) {
    if (address) {
      if (typeof address === 'string') {
        return address.replace(/([+\s]+$)/g, '').replace(/(\s)/g, '+');
      }
    }
    return '';
  }

  /**
   * Rounds the distance
   *
   * @return Boolean | String
   */
  getDistance() {
    const { location } = this.props;
    const distance = location.Distance;

    if (distance === -1) {
      return false;
    }

    return distance.toFixed(2);
  }

  /**
   * Gets the daddr string for google maps directions
   * @returns {string}
   */
  getDaddr() {
    const { location } = this.props;
    let daddr = '';

    if (location.Address) {
      daddr += `${location.Address}+`;
    }

    if (location.Address2) {
      daddr += `${location.Address2}+`;
    }

    if (location.City) {
      daddr += `${location.City}+`;
    }

    if (location.State) {
      daddr += `${location.State}+`;
    }

    if (location.PostalCode) {
      daddr += location.PostalCode;
    }

    return Location.cleanAddress(daddr);
  }

  /**
   * Gets the class for the rendered component
   * @return {string}
   */
  getClassName() {
    const {
      index, current, location
    } = this.props;
    let className = 'list-location';
    // if it should be focused
    if (current) {
      className += ' focus';
    }
    // if it is even (needed because the list acts odd with :nth-child)
    if (index % 2 === 0) {
      className += ' even';
    }
    // if it is first (needed because the list acts odd with :nth-child)
    if (index === 0) {
      className += ' first';
    }

    if (location.hasOwnProperty('Categories') && categoriesToClasses(location.Categories) !== '') {
      className += ' ' + categoriesToClasses(location.Categories);
    }

    return className;
  }

  /**
   * renders the component
   * @returns {XML}
   */
  render() {
    const {location, index, search, unit, onClick} = this.props;
    const ListLocationContent = loadComponent('ListLocationContent');

    const loc = {
      ...location,
      Distance: this.getDistance(),
      DirectionsLink: `http://maps.google.com/maps?saddr=${Location.cleanAddress(search)}&daddr=${this.getDaddr()}`,
      DirectionsText: ss.i18n._t('Locator.DIRECTIONS_TEXT', 'Directions'),
      EmailText: ss.i18n._t('Locator.EMAIL_TEXT', 'Email'),
      WebsiteText: ss.i18n._t('Locator.WEBSITE_TEXT', 'Website'),
      Unit: ss.i18n._t(`Locator.UNIT.${unit}`, 'mi'),
      Number: index + 1,
    };

    const id = `loc-${location.ID}`;
    const className = this.getClassName();

    return (
      // eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions, jsx-a11y/click-events-have-key-events
      <div
        id={id}
        data-markerid={index}
        className={className}
        onClick={() => onClick(location.ID)}
        role="listitem"
      >
        <ListLocationContent location={loc}/>
      </div>
    );
  }
}

/**
 * defines the prop types
 * @type {{location, index: *}}
 */
Location.propTypes = {
  location: PropTypes.shape({
    Title: PropTypes.string,
    Address: PropTypes.string,
    Address2: PropTypes.string,
    City: PropTypes.string,
    State: PropTypes.string,
    PostalCode: PropTypes.string,
    Website: PropTypes.string,
    Phone: PropTypes.string,
    Email: PropTypes.string,
    Distance: PropTypes.number,
  }).isRequired,
  index: PropTypes.number.isRequired,
  current: PropTypes.bool.isRequired,
  search: PropTypes.string.isRequired,
  unit: PropTypes.string.isRequired,
  onClick: PropTypes.func.isRequired,
};

/**
 * Exports the Location components
 */
export default Location;