UNPKG

instantjob-recruiter-client

Version:

a set of tools for creating an instantjob recruiter react client

344 lines (314 loc) 9.81 kB
import React, {Component} from 'react' import classNames from 'classnames/bind' import {MdDone, MdFace, MdCheckBox, MdCheckBoxOutlineBlank} from 'react-icons/lib/md' import Button from 'components/utils/button' import ExclusiveField from 'components/exclusive_field' import {color} from 'common/styles' import {array_contains, array_from_hash, property_toggler, create_hash} from 'common/utilities' import store from 'common/store' import auto_bind from 'common/auto_bind' import {alert_warning} from 'actions/display' import {show_popover, dismiss_popover} from 'actions/display' const examples = { user: { comment: `Ex: Numéro de dossier, Commentaire suite à l'entretien, Date de naissance ...`, non_exclusive: `Ex: Langue, Compétences, Établissement préféré ...`, exclusive: `Ex: Équipe, Dossier validé, Qualification ...`, file: `Ex: Titre de séjour, Carte vitale, RIB ...`, }, mission: { comment: `Ex: Référence de la mission, Précisions sur l'accès au lieu, Données de contact ...`, non_exclusive: `Ex: Matériel requis, Personnes à contacter ...`, exclusive: `Ex: Client, Tenue vestimentaire ...`, computed: `Ex: Montant HT, Montant TTC ...`, }, mission_proposal: { comment: `Ex: Chiffre d'affaire réalisé, Appréciation suite à la mission ...`, non_exclusive: `Ex: Compétences validées ...`, exclusive: `Ex: Note sur la mission, Tenue ...`, template: `Ex: Contrat de travail, Autorisation d'accès au lieu de la mission ...`, computed: `Ex: Nom du contact, Salaire, ...`, }, shift: { comment: `Ex: Commentaire, Nombre de clients servis, Bonus ...`, non_exclusive: `Ex: Pause, Primes ...`, exclusive: `Ex: Panier repas ...`, computed: `Ex: Salaire, Prime de dimanche, ...`, }, value: { comment: `Ex: Numéro de téléphone ...`, non_exclusive: `Ex: Matériel demandé ...`, exclusive: `Ex: Type de client ...`, computed: `Ex: Adresse complète ...`, }, workplace: { comment: `Ex: Numéro de téléphone ...`, non_exclusive: `Ex: Équipements présents ...`, exclusive: `Ex: Client ...`, }, deal: { computed: `Ex: Total HT, Total TTC ...`, template: `Ex: Devis, Facture ...` }, } let cx = classNames.bind(require('styles/new_field_form.scss')) class NewFieldForm extends Component { constructor(props) { super(props) this.state = { kind: this.props.type == "mission" && array_from_hash(this.props.existing_fields).length > 0 ? "" : "new" } auto_bind(this) } render() { switch (this.state.kind) { case "new": return ( <New {...this.props} /> ) case "recycled": return ( <Recycled {...this.props} /> ) default: return ( <div className={cx('new-field-form')}> <div className={cx('new-field-form__mission', 'new-field-form__mission_choice')}> <span>Quel genre de champ voulez-vous créer ?</span> <div className={cx('new-field-form__mission__buttons')}> <div className={cx('new-field-form__mission__buttons__button')}> <Button onClick={() => this.setState({kind: "new"})}> Créer un champ mission spécifique </Button> </div> <div className={cx('new-field-form__mission__buttons__description')}> Vous pourrez ainsi renseigner des informations sur vos missions et choisir de les partager avec les candidats. </div> </div> <div className={cx('new-field-form__mission__buttons')}> <div className={cx('new-field-form__mission__buttons__button')}> <Button onClick={() => this.setState({kind: "recycled"})}> Réutiliser un champ candidat </Button> </div> <div className={cx('new-field-form__mission__buttons__description')}> Cela permet de réutiliser dans la fiche descriptive de la mission un champ utilisé pour filtrer vos candidats </div> </div> </div> </div> ) } } } class Recycled extends Component { constructor(props) { super(props) this.state = { id: false, shared_with_user: false, } auto_bind(this) } toggle_shared_with_user() { this.setState(property_toggler("shared_with_user")) } create_field() { this.props.recycle_field(this.state) } render() { return ( <div className={cx('new-field-form__mission')}> <div> <ExclusiveField values={array_from_hash(this.props.existing_fields)} selected={this.state.id} on_clear={() => this.setState({id: false})} name={"Quel champ voulez-vous réutiliser ?"} on_select_value={(id) => this.setState({id})} allow_creating_values={false} /> </div> <Setting label="Visible par le candidat" toggle={this.toggle_shared_with_user} /> <div className={cx('new-field-form__create-button')}> <Button disabled={!this.state.id} onClick={this.create_field} icon={MdDone}> Créer le nouveau champ </Button> </div> </div> ) } } class New extends Component { constructor(props) { super(props) this.state = { name: "", category: "non_exclusive", shared_with_user: true, shared_by_user: true, } auto_bind(this) } componentDidMount() { this.name_input.focus() } create_field() { this.props.create_field(this.state) } update_field(state) { this.setState(state) } get_settings() { switch (this.props.type) { case "user": return [{ label: "Renseigné par le candidat", initial: this.state.shared_by_user, toggle: () => this.setState(property_toggler("shared_by_user")), }] case "mission": return [{ label: "Visible par le candidat", initial: this.state.shared_with_user, toggle: () => this.setState(property_toggler("shared_with_user")), }] default: return [] } } render_setting(setting, index) { return <Setting key={index} {...setting} /> } render() { let {type} = this.props let {name, category} = this.state return ( <div className={cx('new-field-form', 'new-field-form_new')}> <div className={cx('new-field-form__parameters')}> <FieldNameInput ref={(name_input) => this.name_input = name_input} on_change={this.update_field} /> <FieldCategorySelection on_change={this.update_field} options={Object.keys(examples[type])} examples={examples[type][category]} /> </div> {this.get_settings().map(this.render_setting)} <div className={cx('new-field-form__create-button')}> <Button disabled={name.trim().length == 0} onClick={this.create_field} icon={MdDone}> Créer le nouveau champ </Button> </div> </div> ) } } class FieldNameInput extends Component { constructor(props) { super(props) this.state = { name: "" } auto_bind(this) } focus() { this.input.focus() } onChange({target: {value: name}}) { let state = {name} this.setState(state) this.props.on_change(state) } render() { return ( <input ref={(input) => this.input = input} className={cx('new-field-form__name-input')} type="text" placeholder={"Nom"} value={this.state.name} onChange={this.onChange} /> ) } } class FieldCategorySelection extends Component { constructor(props) { super(props) this.state = { category: 'non_exclusive', } auto_bind(this) } on_change(category) { let state = {category} this.setState(state) this.props.on_change(state) } make_option(id) { let names = { comment: 'Texte libre', non_exclusive: 'Multi-valeur à choix multiples', exclusive: 'Multi-valeur à choix unique', file: 'Document stocké', template: `Document généré à partir d'un modèle`, computed: 'Valeur calculée', } return {id, name: names[id]} } render() { let {options, examples} = this.props return ( <div className={cx('new-field-form__category-selection')}> <ExclusiveField values={options.map(this.make_option)} selected={this.state.category} name={"Catégorie"} on_select_value={this.on_change} allow_creating_values={false} searchable={false} /> <div className={cx('new-field-form__category-selection-examples')}> {examples} </div> </div> ) } } class Setting extends Component { constructor(props) { super(props) this.state = { checked: props.initial, } auto_bind(this) } toggle() { this.setState(property_toggler('checked')) this.props.toggle() } render() { let {label} = this.props return ( <div onClick={this.toggle} className={cx('new-field-form__setting', {'new-field-form__setting_checked': this.state.checked})}> {this.state.checked ? ( <MdCheckBox /> ) : ( <MdCheckBoxOutlineBlank /> )} <div className={cx('new-field-form__setting-label')}> {label} </div> </div> ) } } NewFieldForm.defaultProps = { create_field() {}, existing_fields: {}, type: 'mission', } export default NewFieldForm