<commit_before>// @flow

import React from 'react';
import metrics from "../../utils/metrics.js";
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
import Form from 'react-bootstrap/Form';
import ProjectAPIUtils from '../../utils/ProjectAPIUtils.js'
import CurrentUser from "../../utils/CurrentUser.js";
import ConfirmationModal from '../../common/confirmation/ConfirmationModal.jsx';
import TagCategory from "../tags/TagCategory.jsx";
import TagSelector,{tagOptionDisplay} from "../tags/TagSelector.jsx";
import {TagDefinition} from "../../utils/ProjectAPIUtils.js";
import {SelectOption} from "../../types/SelectOption.jsx";
import Select from 'react-select'
import moment from 'moment';
import _ from 'lodash';

type Props = {|
  projectId: number,
  positions: $ReadOnlyArray<PositionInfo>,
  positionToJoin: ?PositionInfo,
  showModal: boolean,
  handleClose: () => void
|};
type State = {|
  showModal: boolean,
  isSending: boolean,
  message: string,
  daysToVolunteerForOption: ?SelectOption,
  positionOptions: $ReadOnlyArray<SelectOption>,
  initialPositionSelection: ?SelectOption,
  existingPositionOption: ?SelectOption,
  roleTag: ?TagDefinition,
  showConfirmationModal: boolean
|};

const volunteerPeriodsInDays: $ReadOnlyArray<SelectOption> = [
  ["Less than 1 week",7],
  ["1 week - 1 month",30],
  ["1 month - 3 months",90],
  ["3 months - 6 months",180],
  ["6 months - 1 year",365]
].map((textDaysPair) => ({label:textDaysPair[0], value:textDaysPair[1]}));

const OtherRoleOption: SelectOption = {label:"Other", value:"Other"};

/**
 * Modal for volunteering to join a project
 */

class ProjectVolunteerModal extends React.PureComponent<Props, State> {
  constructor(props: Props): void {
    super(props);
    this.state = {
      showModal: false,
      isSending: false,
      message: "",
      positionToJoin: null,
      daysToVolunteerForOption: null,
      roleTag: null,
      showConfirmationModal: false
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.askForSendConfirmation = this.askForSendConfirmation.bind(this);
    this.receiveSendConfirmation = this.receiveSendConfirmation.bind(this);
    this._fieldsFilled = this._fieldsFilled.bind(this);
  }

  componentWillReceiveProps(nextProps: Props): void {
    const noPositionOption: SelectOption = {value:"", label:"---"};
    const positionOptions: $ReadOnlyArray<SelectOption> =
      [noPositionOption].concat(
      nextProps.positions.map( (position: PositionInfo) => ({value:position.roleTag.tag_name, label:tagOptionDisplay(position.roleTag)})).concat(
      OtherRoleOption));

    let state: State = {
      showModal: nextProps.showModal,
      positionOptions: positionOptions
    };

    if(nextProps.positionToJoin) {
      const initialPositionSelection: SelectOption = nextProps.positionToJoin && positionOptions.find(
        (option) => option.value === nextProps.positionToJoin.roleTag.tag_name);
      state.existingPositionOption = state.initialPositionSelection = initialPositionSelection;
    } else {
      state.existingPositionOption = noPositionOption;
    }
    this.setState(state);
    this.forceUpdate();
  }

  handleChange(event: SyntheticInputEvent<HTMLInputElement>): void {
      this.setState({message: event.target.value});
  }

  onRoleChange(role: $ReadOnlyArray<TagDefinition>): void {
    //this fixes an Uncaught TypeError: Cannot read property '0' of null if the user clicks the X to clear the field in the role selector
    if(role && role.length) {
      this.state.roleTag = role[0];
    } else {
      this.state.roleTag = null
    }
    this.forceUpdate();
  }

  askForSendConfirmation(): void {
    metrics.logVolunteerClickVolunteerSubmit(CurrentUser.userID(), this.props.projectId);
    this.setState({showConfirmationModal:true});
  }

  receiveSendConfirmation(confirmation: boolean): void {<commit_msg>clean up if/else to use isEmpty<commit_after>// @flow

import React from 'react';
import metrics from "../../utils/metrics.js";
import Button from 'react-bootstrap/Button';
import Modal from 'react-bootstrap/Modal';
import Form from 'react-bootstrap/Form';
import ProjectAPIUtils from '../../utils/ProjectAPIUtils.js'
import CurrentUser from "../../utils/CurrentUser.js";
import ConfirmationModal from '../../common/confirmation/ConfirmationModal.jsx';
import TagCategory from "../tags/TagCategory.jsx";
import TagSelector,{tagOptionDisplay} from "../tags/TagSelector.jsx";
import {TagDefinition} from "../../utils/ProjectAPIUtils.js";
import {SelectOption} from "../../types/SelectOption.jsx";
import Select from 'react-select'
import moment from 'moment';
import _ from 'lodash';

type Props = {|
  projectId: number,
  positions: $ReadOnlyArray<PositionInfo>,
  positionToJoin: ?PositionInfo,
  showModal: boolean,
  handleClose: () => void
|};
type State = {|
  showModal: boolean,
  isSending: boolean,
  message: string,
  daysToVolunteerForOption: ?SelectOption,
  positionOptions: $ReadOnlyArray<SelectOption>,
  initialPositionSelection: ?SelectOption,
  existingPositionOption: ?SelectOption,
  roleTag: ?TagDefinition,
  showConfirmationModal: boolean
|};

const volunteerPeriodsInDays: $ReadOnlyArray<SelectOption> = [
  ["Less than 1 week",7],
  ["1 week - 1 month",30],
  ["1 month - 3 months",90],
  ["3 months - 6 months",180],
  ["6 months - 1 year",365]
].map((textDaysPair) => ({label:textDaysPair[0], value:textDaysPair[1]}));

const OtherRoleOption: SelectOption = {label:"Other", value:"Other"};

/**
 * Modal for volunteering to join a project
 */

class ProjectVolunteerModal extends React.PureComponent<Props, State> {
  constructor(props: Props): void {
    super(props);
    this.state = {
      showModal: false,
      isSending: false,
      message: "",
      positionToJoin: null,
      daysToVolunteerForOption: null,
      roleTag: null,
      showConfirmationModal: false
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.askForSendConfirmation = this.askForSendConfirmation.bind(this);
    this.receiveSendConfirmation = this.receiveSendConfirmation.bind(this);
    this._fieldsFilled = this._fieldsFilled.bind(this);
  }

  componentWillReceiveProps(nextProps: Props): void {
    const noPositionOption: SelectOption = {value:"", label:"---"};
    const positionOptions: $ReadOnlyArray<SelectOption> =
      [noPositionOption].concat(
      nextProps.positions.map( (position: PositionInfo) => ({value:position.roleTag.tag_name, label:tagOptionDisplay(position.roleTag)})).concat(
      OtherRoleOption));

    let state: State = {
      showModal: nextProps.showModal,
      positionOptions: positionOptions
    };

    if(nextProps.positionToJoin) {
      const initialPositionSelection: SelectOption = nextProps.positionToJoin && positionOptions.find(
        (option) => option.value === nextProps.positionToJoin.roleTag.tag_name);
      state.existingPositionOption = state.initialPositionSelection = initialPositionSelection;
    } else {
      state.existingPositionOption = noPositionOption;
    }
    this.setState(state);
    this.forceUpdate();
  }

  handleChange(event: SyntheticInputEvent<HTMLInputElement>): void {
      this.setState({message: event.target.value});
  }

  onRoleChange(role: $ReadOnlyArray<TagDefinition>): void {
    //this fixes an Uncaught TypeError: Cannot read property '0' of null if the user clicks the X to clear the field in the role selector
    this.state.roleTag = !_.isEmpty(role) ? role[0] : null;
    this.forceUpdate();
  }

  askForSendConfirmation(): void {
    metrics.logVolunteerClickVolunteerSubmit(CurrentUser.userID(), this.props.projectId);
    this.setState({showConfirmationModal:true});
  }

  receiveSendConfirmation(confirmation: boolean): void {
{'fraction_non_alphanumeric': 0.12860225974355718, 'fraction_numerical': 0.006093690491303796, 'mean_word_length': 4.425619834710743, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 25, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2494087', 'n_tokens_mistral': 2326, 'n_tokens_neox': 2285, 'n_words': 514}