instantjob-recruiter-client
Version:
a set of tools for creating an instantjob recruiter react client
214 lines (200 loc) • 7.42 kB
JSX
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))
}