UNPKG

instantjob-recruiter-client

Version:

a set of tools for creating an instantjob recruiter react client

214 lines (200 loc) 7.42 kB
import React from 'react' import Fuse from 'fuse.js' import {MdThumbDown, MdEmail, MdClear, MdGroup} from 'react-icons/lib/md' import InstantJob from 'components/instant_job' import {Blacklist, Whitelist} from 'components/popovers/blacklist' import request from 'common/request' import store from 'common/store' import moment from 'common/moment' import {color} from 'common/constants' import { make_memoized, array_from_set, empty_object, map_hash, create_hash, human_plural, } from 'common/utilities' import {alert_info, alert_success, show_popover, dismiss_popover} from 'actions/display' import {update_users, update_user, set_current_recipient} from 'actions/users' export const new_users_fuse = () => { let fuses = ["first_name", "last_name", "email"].map((field) => new Fuse([], { keys: [field], include: ["score"], id: "id", threshold: 0.2, })) return { set: (users) => { fuses.forEach((fuse) => fuse.set(users)) }, search: (query) => { let querys = query.split(" ").filter(Boolean) let scores = {} fuses.forEach((fuse) => querys.forEach((query) => { let results = fuse.search(query) let results_count = results.length results.forEach((result) => { let item = result.item if (!scores[item]) { scores[item] = 0 } scores[item] += (1 - result.score) / results_count }) })) let r = array_from_set(scores).sort((a, b) => scores[b] - scores[a]) return r }, } } const email_validation = /^[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/ export const is_valid_email = (email) => email_validation.test(email) export function action_invite_users(users) { return request.asynchronous("users/import", {users}) .then((categories) => { let agency_name = store.getState().profile.agency.name if (categories.already_existing.length > 0) { store.dispatch(alert_info(human_plural(categories.already_existing.length, "%% candidat était déjà présent dans notre base de donnée et a reçu votre invitation directement dans son application.", "%% candidats étaient déjà présents dans notre base de donnée et ont reçu votre invitation directement dans leur application."))) } if (categories.already_invited.length > 0) { store.dispatch(alert_info(`${human_plural(categories.already_invited.length, "%% candidat avait déjà été invité", "%% candidats avaient déjà été invités")} à rejoindre ${agency_name}.`)) } if (categories.already_added.length > 0) { store.dispatch(alert_info(`${human_plural(categories.already_added.length, `%% candidat avait déjà rejoint ${agency_name}. Nous ne lui`, `%% candidats avaient déjà rejoint ${agency_name}. Nous ne leur`)} avons pas renvoyé de mail d'invitation.`)) } if (categories.newly_invited.length > 0) { store.dispatch(alert_success(`${human_plural(categories.newly_invited.length, "%% nouveau candidat a reçu", "%% nouveaux candidats ont reçu")} un mail d'invitation à installer l'application InstantJob.`)) } [ "already_added", "already_invited", "already_existing", "newly_invited", ].map((group) => { users = categories[group].map((user) => ({...user, active: true})) store.dispatch(update_users(users)) }) }) } export function make_user_status(status) { let user_status = make_user_statuses()[status] return { status, description: user_status.name, icon: user_status.icon, } } export function get_user_status(user) { if (!user || empty_object(user)) { return {status: 'nonexistent', description: '', icon: null} } function get_status_name() { let {blacklisted_at, invitation_accepted_at, app_name, active, invitation_rejected_at, invitation_sent_at, temporary} = user if (blacklisted_at) { return 'blacklisted' } if (invitation_accepted_at) { if (app_name) { if (active) { return 'active' } else { return 'inactive' } } else { return 'mail' } } else { if (invitation_rejected_at) { return 'rejected' } else { if (invitation_sent_at) { // return 'pending' return 'mail' } else { if (temporary) { return } else { return 'applied' } } } } } return make_user_status(get_status_name()) } export function make_user_statuses(custom_color = "") { const make_user_statuses_elements = make_memoized((custom_color) => { const make_color = ({name, tone}) => color(custom_color || name, tone) const icon_colors = map_hash({ active: {name: 'primary'}, mail: {name: 'primary', tone: 'light'}, pending: {name: 'attention'}, rejected: {name: 'important'}, inactive: {name: 'black', tone: 'light'}, blacklisted: {name: 'black'}, invited: {name: 'black'}, applied: {name: 'primary'}, new: {name: 'action'}, }, make_color) const names = { active: 'Actif sur l\'application', mail: 'Connecté par mail', pending: 'Invitation en attente', rejected: 'Invitation refusée', inactive: 'Inactif', blacklisted: 'Blacklisté', invited: 'Invitation envoyée', applied: 'Candidat', new: 'Pas encore importé', } const get_style_props = (status) => ({style: {color: icon_colors[status]}}) const icons = create_hash(Object.keys(icon_colors), (status) => { let props = get_style_props(status) switch (status) { case 'active': return <div {...props}><InstantJob/></div> case 'mail': return <MdEmail {...props} /> case 'pending': return <span {...props}>{"?"}</span> case 'rejected': return <MdClear {...props} /> case 'inactive': return <div {...props}><InstantJob/></div> case 'blacklisted': return <MdThumbDown {...props} /> case 'invited': return <MdGroup {...props} /> case 'applied': return <div {...props}><InstantJob /></div> case 'new': return null } }) return create_hash(Object.keys(names), (status) => ({ name: names[status], icon_color: icon_colors[status], icon: icons[status], })) }) return make_user_statuses_elements(custom_color) } export const user_full_name = ({first_name, last_name, email}) => `${first_name || ""} ${last_name || ""}`.trim() || email export function action_update_user(user) { store.dispatch(update_user(user)) request.put(`users/${user.id}`, {user}) } export function action_toggle_blacklist_user(user) { const {blacklisted_at, id} = user store.dispatch(show_popover( blacklisted_at ? Whitelist : Blacklist, { id, on_dismiss: () => { const action = blacklisted_at ? 'whitelist' : 'blacklist' request.put(`users/${id}/${action}`) store.dispatch(update_user({id, blacklisted_at: blacklisted_at ? null : moment()})) store.dispatch(dismiss_popover()) } }, blacklisted_at ? 'Re-intégrer' : 'Blacklister', )) } export function action_open_chat({id}) { store.dispatch(set_current_recipient(id)) }