6.2.26 • Published 3 years ago

espeakers v6.2.26

Weekly downloads
607
License
MIT
Repository
bitbucket
Last release
3 years ago

React-es

Codecov npm npm NPM

Library of common React components used on the front-end applications developed for eSpeakers.

When developing on a local machine run this

$ yarn run test

When ready to publish a new version. Use Semantic Versioning to determine the version number. i.e.

$ yarn run prod-patch  #for bug fixes, cleanup or other backwards-compatible changes
$ yarn run prod-minor  #adding new features in a backwards compatable way
$ yarn run prod-major  #breaking changes, including things like updating to a react version that has breaking changes

Installation

To install, use yarn or npm

yarn install espeakers

Then you can use the various components in your projects

import { 
  actions,
  reducers,
  redux,
  components,
  exceptions,
  forms,
  utils 
} from 'espeakers';

or

import { Text } from 'espeakers/forms';
import { Constants } from 'espeakers/utils';
import { Balboa } from 'espeakers/actions';
import { BalboaReducer } from 'espeakers/reducers';
import { AsyncComponent } from 'espeakers/components';

Components

AsyncComponent

Loads the component only when it is requested. Useful when building with modules so the browser doesn't have to load every component/page in a single file.

import { AsyncComponent } from 'espeakers/components';
const AsyncHomePage = AsyncComponent(<HomePage />);

Calendar

Displays the date in a calendar icon. Useful for events and calendar items.

import { Calendar } from 'espeakers/components';
<Calendar date={"2019-01-15"} format={"YYYY-MM-DD"} />

LoadingEllipsis

Displays an animated ellipses, useful when loading content on a page

import { LoadingEllipsis } from 'espeakers/components';
<LoadingEllipsis />

LoadingIndicator

Displays an animated loading circle similar to Google

LoadingIndicator

import { LoadingIndicator } from 'espeakers/components';
<LoadingIndicator />

OauthButtons

Implementation of signon buttons for Google, Facebook, LinkedIn, and Mpi. Used to sign on through Oauth

import { Oauth } from 'espeakers/components';
// Define the callback function that will receive the state from the Oauth service
const callback = (service) => (
  window.location.protocol + "//" + window.location.host + "/oauth-callback/" + service + "/"
);
...
// Render the buttons on the page
<Oauth.Google onSuccess={"/home"} redirect={callback}><div className={"btn btn-danger"}>Google</div></Oauth.Google>
<Oauth.Facebook onSuccess={"/home"} redirect={callback}><div className={"btn btn-primary"}>Facebook</div></Oauth.Facebook>
<Oauth.LinkedIn onSuccess={"/home"} redirect={callback}><div className={"btn btn-warning"}>LinkedIn</div></Oauth.Google>
<Oauth.Mpi onSuccess={"/home"} redirect={callback}><div className={"btn btn-default"}>Mpi</div></Oauth.Google>

PopoverMenu

Displays a menu inside a Bootstrap popover. Very useful to show a form field inside a popover

import { PopoverMenu } from 'espeakers/components';
// Render the buttons on the page
<OverlayTrigger trigger="click" placement="bottom" overlay={
    <PopoverMenu>
        <Dropdown.Item>Item #1</Dropdown.Item>
        <Dropdown.Item>Item #2</Dropdown.Item>
        <Dropdown.Item>Item #3</Dropdown.Item>
    </PopoverMenu>
}>
    <Button>Click me</Button>
</OverlayTrigger>

Exceptions

AuthenticationException

Thrown when a username or password is incorrect

import { AuthenticationException } from 'espeakers/exceptions';
throw new AuthenticationException('Invalid username or password');

AuthorizationException

Thrown when a user does not have access to a resource

import { AuthorizationException } from 'espeakers/exceptions';
throw new AuthorizationException('Not authorized');

SpeakerMissingException

Thrown when a speaker is loaded but they do not exist, or their profile is private, or their profile is not linked to the bureau.
It's recommended to show a 404 page or suggestsions for other speakers if this is thrown.

import { SpeakerMissingException } from 'espeakers/exceptions';
throw new SpeakerMissingException('Speaker not found');

TokenException

Thrown when an api token is invalid or expired. It's recommended to have the user login again or refresh their token.

import { TokenException } from 'espeakers/exceptions';
throw new TokenException('Token expired');

Forms

Many redux-forms components that can be used when building forms

Amount

Displays an amount with a $. Also validates that only numbers are entered

import { Amount } from 'espeakers/forms';
<Field
  name="name"
  component={Amount} 
/>

Checkbox

Displays an chekbox

import { Checkbox } from 'espeakers/forms';
<Field
  name="name"
  component={Checkbox} 
/>

CheckboxDropdown

Displays an list of checkboxes using PopoverMenu

import { CheckboxDropdown } from 'espeakers/forms';
<Field
  name="name"
  component={CheckboxDropdown} 
/>

ColorPicker

Displays a button that opens the system color picker

import { ColorPicker } from 'espeakers/forms';
<Field
  name="name"
  component={ColorPicker} 
/>

DateRangePickerField

Displays an instance of the bootstrap-daterangepicker component

import { DateRangePickerField } from 'espeakers/forms';
<Field
  name="name"
  type={text|button}
  startDate={"01/01/2019"}
  format={"MM/DD/YYYY"}
  component={DateRangePickerField} 
/>

EmailConsent

Displays checkbox agreeing to receive emails

import { EmailConsent } from 'espeakers/forms';
<Field
  name="name"
  component={EmailConsent} 
/>

FileUpoad

Displays file upload control using react-dropzone

import { FileUpoad } from 'espeakers/forms';
<Field
  name="name"
  component={FileUpoad} 
/>

Initials

Displays a textbox for user initials, along with their name and date

import { Initials } from 'espeakers/forms';
<Field
  name="name"
  component={Initials} 
/>

Message

Displays a textarea

import { Message } from 'espeakers/forms';
<Field
  name="name"
  rows={5}
  component={Message} 
/>

OfferAmount

Displays an <Amount /> with $ USD in the input-group-addon

import { OfferAmount } from 'espeakers/forms';
<Field
  name="name"
  component={OfferAmount} 
/>

Password

Displays a password field

import { Password } from 'espeakers/forms';
<Field
  name="name"
  component={Password} 
/>

Phone

Displays a phone nubmer field that automatically formats domestic and international phone numbers

import { Phone } from 'espeakers/forms';
<Field
  name="name"
  component={Phone} 
/>

Radio

Displays a radio button field

import { Radio } from 'espeakers/forms';
<Field
  name="name"
  component={Radio} 
/>

Rating

Displays multiple stars for saving a rating

import { Rating } from 'espeakers/forms';
<Field
    placeholder="Select a rating"
    label="Rate me"
    count={7}
    value={5}
    help_text="Click on a star to rate"
    component={Rating}
    size={"5x"}
    name="rating"
/>

Reason

Displays radio buttons in a group

import { Reason } from 'espeakers/forms';
<Field
  name="color" 
  component={Reason} 
  label="Red" 
/>
<Field 
  name="color"
  component={Reason} 
  label="Green" 
/>
<Field 
  name="color"
  component={Reason}  
  label="Blue" 
/>

SearchSort

Displays a dropdown to select sorting

import { SearchSort } from 'espeakers/forms';
<Field
  name="sort"
  component={SearchSort} 
/>

Selectize

Displays a select component using react-select

import { Selectize } from 'espeakers/forms';
const countries = [
  {label: "United States", value: "US"},
  {label: "Canada", value: "CA"},
  {label: "Mexico", value: "MX"},
];

...

<Field
  name="country"
  component={Selectize} 
  options={countries}
  normalize={(value) => (_.get(value, ["value"], value))}
  format={(value) => ({
    label: _.get(_.keyBy(countries, "value"), [value, "label"], value),
    value: value
  })}
/>

SliderDropdown

Displays a slider within a PopoverMenu

import { SliderDropdown } from 'espeakers/forms';
const marks = {
    0: "Free",
    2: "$1,000",
    5: "$2,500",
    10: "$5,000",
    15: "$7,500",
    20: "$10,000",
    30: "$15,000",
    40: "$20,000",
    50: "$20,000+"
};

...

<Field
  component={SliderDropdown}
  name="budget"
  placeholder="- Any budget -"
  width="medium"
  defaultValue={[10,20]} 
  any_placeholder="Any Budget"
  min={0}
  max={50}
  step={5}
  dots={true}
  marks={marks}
/>

Text

Displays a standard text field

import { Text } from 'espeakers/forms';
<Field
  component={Text}
  name="name"
  label="Name:"
/>

TextWithInputGroup

Displays a standard text field with an input-group-addon before and/or after it

import { TextWithInputGroup } from 'espeakers/forms';
<Field
  component={TextWithInputGroup}
  name="amount"
  label="Amount:"
  input_group_before={<span className="input-group-addon">$</span>}
  input_group_after={<span className="input-group-addon">.00</span>}
/>

Toggle

Displays a toggle for on/off fields using react-toggle

import { Toggle } from 'espeakers/forms';
<Field
  component={Toggle}
  name="option"
  label="Enable:"
/>

ToggleJustified

Displays a toggle for on/off fields using react-toggle to the right

import { ToggleJustified } from 'espeakers/forms';
<Field
  component={ToggleJustified}
  name="option"
  label="Enable:"
  help_text="Click to enable this option"
/>

Username

Displays a username field

import { Username } from 'espeakers/forms';
<Field
  component={Username}
  label="Username:"
/>

Redux Actions

Login.OauthSignin

Used to login to eSpeakers using an Oauth token

import { Oauth } from 'espeakers/actions';
handleSubmit(values, dispatch) {
  // values contains:
  // { 
  //   service: "google|facebook|linkedin|mpi",
  //   access_token|code: "",
  //   state: "buyer[$]1375[$]/home" // user type (buyer, speaker, oauth), bureau, redirect url
  // }
  let state_parts = _.split(_.get(values, ["state"]), "[$]");
  let redir = _.last(state_parts);
  
  if (_.get(values, ["service"]) === "google") {
    return dispatch(Oauth.Google.signin(_.get(values, ["access_token"]), _.join(state_parts, "[$]"), Oauth.Google.getCallbackUrl("google")))
      .then((response) => {
        ownProps.history.push(redir);
      })
      .catch((err) => {
        throw err;
      });
  } else if (_.get(values, ["service"]) === "facebook") {
    return dispatch(Oauth.Facebook.signin(_.get(values, ["code"]), _.join(state_parts, "[$]"), Oauth.Facebook.getCallbackUrl("facebook")))
      .then((response) => {
        ownProps.history.push(redir);
      })
      .catch((err) => {
        throw err;
      });
  } else if (_.get(values, ["service"]) === "linkedin") {
    return dispatch(Oauth.LinkedIn.signin(_.get(values, ["code"]), _.join(state_parts, "[$]"), Oauth.LinkedIn.getCallbackUrl("linkedin")))
      .then((response) => {
        ownProps.history.push(redir);
      })
      .catch((err) => {
        throw err;
      });
  } else if (_.get(values, ["service"]) === "mpi") {
    return dispatch(Oauth.Mpi.signin(_.get(values, ["code"]), _.join(state_parts, "[$]"), Oauth.Mpi.getCallbackUrl("mpi")))
      .then((response) => {
        ownProps.history.push(redir);
      })
      .catch((err) => {
        throw err;
      });
    } else {
      return new Promise((resolve, reject) => {
        return reject("Cannot authenticate without a service");
      });
    }
}

Login.Signin

Used to login to eSpeakers using a username and password

import { Login } from 'espeakers/actions';
handleSubmit(values, dispatch) {
   // values contains:
   // { 
   //   username: "",
   //   password: "",
   //   redir: "/dashboard"
   // }
  return dispatch(Login.Signin(values))
    .catch((err) => {
        throw new SubmissionError({_error: err});
    });
}

Login.TokenSignin

Used to login to eSpeakers using an eSpeakers Authentication token

import { Login } from 'espeakers/actions';
handleSubmit(values, dispatch) {
  // values contains:
  // { 
  //   estoken: "",
  //   redir: "/dashboard"
  // }
  return dispatch(Login.TokenSignin(values))
    .catch((err) => {
        throw new SubmissionError({_error: err});
    });
}

Oauth.Facebook

Used to exchange and Oauth state from Facebook to a profile and later a token for signin into eSpeakers

See Login.OauthSignin above

Oauth.Google

Used to exchange and Oauth state from Google to a profile and later a token for signin into eSpeakers

See Login.OauthSignin above

Oauth.LinkedIn

Used to exchange and Oauth state from LinkedIn to a profile and later a token for signin into eSpeakers

See Login.OauthSignin above

Oauth.Mpi

Used to exchange and Oauth state from Mpi to a profile and later a token for signin into eSpeakers

See Login.OauthSignin above

Balboa

Thunk used in Redux Actions to send an API Request to the Balboa API on eSpeakers

import { Balboa } from "espeakers/actions";

return function(dispatch, getState) {
  return Balboa(dispatch, getState)
    .get(key, "/record/" + id, {})
    .then((response) => {
      dispatch({
        type: RECORD_GET,
        id: id,
        data: _.get(response, ["data"])
      });
      return response;
    });
}

Rest

Implementation of REST actions within an action. You should extend this object in any Redux Actions

import { Rest, Balboa } from "espeakers/actions";

export const RECORD_GET = 'RECORD_GET';
export const RECORD_GET_ALL = 'RECORD_GET_ALL';
export const RECORD_POST = 'RECORD_POST';
export const RECORD_PUT = 'RECORD_PUT';
export const RECORD_DELETE = 'RECORD_DELETE';

export default _.assign({}, Rest, {
  /**
   * Retrieves a single record.
   * @param id
   * @returns {Function}
   */
  get: function(id) {
    let key = [RECORD_GET];
    return (dispatch, getState) => {
      return this.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .get(key, "/record/" + id, {})
          .then((response) => {
            dispatch({
              type: RECORD_GET,
              id: id,
              data: _.get(response, ["data"])
            });
            return response;
          })
      );
    };
  },

  /**
   * Retrieves all the records.
   * @param params
   * @returns {Function}
   */
  find: function(params) {
    let key = [RECORD_GET_ALL];
    return (dispatch, getState) => {
      return this.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .get(key, "/record", params)
          .then((response) => {
            dispatch({
              type: RECORD_GET_ALL,
              data: _.get(response, ["data"])
            });
            return response;
          })
      );
    };
  },

  /**
   * Inserts a record.  Leave {params.id} 0, otherwise it will be updated
   * @param params
   * @returns {Function}
   */
  add: function(params) {
    let key = [RECORD_POST];
    return (dispatch, getState) => {
      return this.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .post(key, "/record", params)
          .then((response) => {
            dispatch({
              type: RECORD_POST,
              data: _.get(response, ["data"])
            });
            return response;
          })
      );
    };
  },

  /**
   * Updates a record.  Pass in {params.id} to specify the record to update, otherwise it will be added
   * @param params
   * @returns {Function}
   */
  update: function(params) {
    let key = [RECORD_PUT];
    return (dispatch, getState) => {
      return this.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .put(key, "/record/" + _.get(params, ["id"]), params)
          .then((response) => {
            dispatch({
              type: RECORD_PUT,
              data: _.get(response, ["data"])
            });
            return response;
          })
      );
    };
  },

  /**
   * Removes a record.  Pass in {params.id} to specify the record to remove
   * @param params
   * @returns {Function}
   */
  remove: function(id) {
    let key = [RECORD_DELETE];
    return (dispatch, getState) => {
      return self.api(
        dispatch,
        key,
        Balboa(dispatch, getState)
          .del(key, "/record/" + id, {})
          .then((response) => {
              dispatch({
                type: RECORD_DELETE,
                id: id,
                data: _.get(response, ["data"])
              });
              return response;
          })
      );
    };
  }
});

Redux Reducers

BalboaReducer

Adds the appropriate reducers to the Redux Store to be used by the Balboa Redux Action

import { BalboaReducer } from "espeakers/reducers";

export default combineReducers({
  //...
  // Global App reducers
  balboa3: BalboaReducer,
  //...
});

Utils

Balboa3

Wrapper for fetch that connects to the Balboa API used by eSpeakers

import { Balboa3 } from "espeakers/utils";

const balboa3 = new Balboa3({
  default_params: {
    estoken: token // estoken used for authentication, throws TokenException if invalid
  }
});

...

balboa3.ajax(url, params, method)
  .then((response) => {
    // process response here
  });

Constants

Various site constants used within the system

import { Constants } from 'espeakers/utils';

console.log(Constants);
console.log(Constants.TRUNK_BUREAU_ID);

formatCurrency

Formats the text as USD

import { formatCurrency } from 'espeakers/utils';

console.log(formatCurrency(5)); // $5.00

formatNumber

Formats the text as a number

import { formatNumber } from 'espeakers/utils';

console.log(formatNumber(5)); // 5
console.log(formatNumber(5, 2)); // 5.00
console.log(formatNumber(5.275, 1)); // 5.3
console.log(formatNumber("5", 1)); // 5.0
console.log(formatNumber("abc", 1)); // 0.0

formatPhone

Formats the text as a domestic or international phone number

import { formatPhone } from 'espeakers/utils';

console.log(formatPhone("8005551212")); // (800) 555-1212
console.log(formatPhone("18005551212")); // 1 (800) 555-1212
console.log(formatPhone("1425551212")); // 1425551212
console.log(formatPhone("5551212")); // 555-1212

formatPriceRange

Formats a 2-element array as a price range in the format of $min - $max

import { formatPriceRange } from 'espeakers/utils';

console.log(formatPriceRange([0,1000], "Free")); // Free - $1000
console.log(formatPriceRange([1,1000], "Free")); // $1 - $1000
console.log(formatPriceRange([1000,Infinity], "Free")); // More than $1000
6.2.26

3 years ago

6.2.20

3 years ago

6.2.24

3 years ago

6.2.25

3 years ago

6.2.22

3 years ago

6.2.23

3 years ago

6.2.18

3 years ago

6.2.17

3 years ago

6.2.15

3 years ago

6.2.10

3 years ago

6.2.13

3 years ago

6.2.14

3 years ago

6.2.11

3 years ago

6.2.12

3 years ago

6.2.5

3 years ago

6.2.4

3 years ago

6.2.7

3 years ago

6.2.6

3 years ago

6.2.9

3 years ago

6.2.8

3 years ago

6.2.1

3 years ago

6.2.3

3 years ago

6.2.2

3 years ago

6.1.74

3 years ago

6.1.73

3 years ago

6.1.72

4 years ago

6.1.71

4 years ago

6.1.70

4 years ago

6.1.69

4 years ago

6.1.68

4 years ago

6.1.67

4 years ago

6.1.66

4 years ago

6.1.65

4 years ago

6.1.64

5 years ago

6.1.63

5 years ago

6.1.62

5 years ago

6.1.61

5 years ago

6.1.60

5 years ago

6.1.59

5 years ago

6.1.58

5 years ago

6.1.57

5 years ago

6.1.56

5 years ago

6.1.55

5 years ago

6.1.54

5 years ago

6.1.53

5 years ago

6.1.52

5 years ago

6.1.51

5 years ago

6.1.50

5 years ago

6.1.49

5 years ago

6.1.48

5 years ago

6.1.47

5 years ago

6.1.46

5 years ago

6.1.45

5 years ago

6.1.44

5 years ago

6.1.43

5 years ago

6.1.42

5 years ago

6.1.41

5 years ago

6.1.40

5 years ago

6.1.39

5 years ago

6.1.38

5 years ago

6.1.37

5 years ago

6.1.36

5 years ago

6.1.35

5 years ago

6.1.34

5 years ago

6.1.33

5 years ago

6.1.32

5 years ago

6.1.31

5 years ago

6.1.30

5 years ago

6.1.29

5 years ago

6.1.28

5 years ago

6.1.27

5 years ago

6.1.26

5 years ago

6.1.25

5 years ago

6.1.23

5 years ago

6.1.22

5 years ago

6.1.21

5 years ago

6.1.20

5 years ago

6.1.19

5 years ago

6.1.18

5 years ago

6.1.17

5 years ago

6.1.16

5 years ago

6.1.15

5 years ago

6.1.14

5 years ago

6.1.13

5 years ago

6.1.12

5 years ago

6.1.11

5 years ago

6.1.10

5 years ago