feat: implementation du role Gestionnaire RH et refonte de la gestion des offres
This commit is contained in:
@@ -74,7 +74,9 @@ const getNestedValue = (obj, path) => {
|
||||
return path.split('.').reduce((o, i) => (o ? o[i] : null), obj);
|
||||
};
|
||||
|
||||
const selectedJobPosition = ref('');
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const initialJobPositionParam = urlParams.get('job_position');
|
||||
const selectedJobPosition = ref(initialJobPositionParam === 'none' ? 'none' : (initialJobPositionParam ? parseInt(initialJobPositionParam) : ''));
|
||||
const showOnlySelected = ref(false);
|
||||
|
||||
const filteredCandidates = computed(() => {
|
||||
@@ -181,7 +183,7 @@ const batchAnalyze = async () => {
|
||||
Liste des Candidats
|
||||
</h3>
|
||||
<div class="flex flex-col sm:flex-row items-center gap-4">
|
||||
<div class="flex items-center gap-3 bg-white p-2 rounded-xl border border-anthracite/5 shadow-sm min-w-max">
|
||||
<div v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" class="flex items-center gap-3 bg-white p-2 rounded-xl border border-anthracite/5 shadow-sm min-w-max">
|
||||
<label class="flex items-center gap-2 cursor-pointer px-2">
|
||||
<input type="checkbox" v-model="showOnlySelected" class="rounded border-highlight/50 text-highlight focus:ring-highlight/20 cursor-pointer">
|
||||
<span class="text-xs font-bold text-primary uppercase tracking-widest">Retenus uniquement</span>
|
||||
@@ -202,7 +204,7 @@ const batchAnalyze = async () => {
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center gap-4 w-full md:w-auto justify-end">
|
||||
<div v-if="selectedIds.length > 0" class="flex items-center gap-3 animate-in fade-in slide-in-from-right-4 duration-300">
|
||||
<div v-if="selectedIds.length > 0 && $page.props.auth.user.role !== 'gestionnaire_rh'" class="flex items-center gap-3 animate-in fade-in slide-in-from-right-4 duration-300">
|
||||
<span class="text-xs font-black uppercase tracking-widest text-primary/50">{{ selectedIds.length }} sélectionné(s)</span>
|
||||
<PrimaryButton
|
||||
@click="batchAnalyze"
|
||||
@@ -246,7 +248,7 @@ const batchAnalyze = async () => {
|
||||
<table class="w-full text-left border-collapse">
|
||||
<thead class="bg-neutral/50 border-b border-anthracite/5">
|
||||
<tr>
|
||||
<th class="w-12 px-8 py-5">
|
||||
<th v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" class="w-12 px-8 py-5">
|
||||
<input
|
||||
type="checkbox"
|
||||
:checked="selectedIds.length === sortedCandidates.length && sortedCandidates.length > 0"
|
||||
@@ -254,7 +256,7 @@ const batchAnalyze = async () => {
|
||||
class="rounded border-anthracite/20 text-primary focus:ring-primary/20 cursor-pointer"
|
||||
>
|
||||
</th>
|
||||
<th class="w-12 px-4 py-5"></th>
|
||||
<th v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" class="w-12 px-4 py-5"></th>
|
||||
<th @click="sortBy('user.name')" class="px-8 py-5 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40 cursor-pointer hover:text-primary transition-colors">
|
||||
<div class="flex items-center gap-2">
|
||||
Nom
|
||||
@@ -291,13 +293,13 @@ const batchAnalyze = async () => {
|
||||
<svg v-show="sortKey === 'status'" xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" :class="{ 'rotate-180': sortOrder === -1 }" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /></svg>
|
||||
</div>
|
||||
</th>
|
||||
<th @click="sortBy('weighted_score')" class="px-8 py-5 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40 cursor-pointer hover:text-primary transition-colors">
|
||||
<th v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" @click="sortBy('weighted_score')" class="px-8 py-5 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40 cursor-pointer hover:text-primary transition-colors">
|
||||
<div class="flex items-center gap-2">
|
||||
Score
|
||||
<svg v-show="sortKey === 'weighted_score'" xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" :class="{ 'rotate-180': sortOrder === -1 }" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /></svg>
|
||||
</div>
|
||||
</th>
|
||||
<th @click="sortBy('ai_analysis.match_score')" class="px-8 py-5 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40 cursor-pointer hover:text-primary transition-colors">
|
||||
<th v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" @click="sortBy('ai_analysis.match_score')" class="px-8 py-5 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40 cursor-pointer hover:text-primary transition-colors">
|
||||
<div class="flex items-center gap-2">
|
||||
IA Match
|
||||
<svg v-show="sortKey === 'ai_analysis.match_score'" xmlns="http://www.w3.org/2000/svg" class="h-3 w-3" :class="{ 'rotate-180': sortOrder === -1 }" viewBox="0 0 20 20" fill="currentColor"><path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" /></svg>
|
||||
@@ -309,7 +311,7 @@ const batchAnalyze = async () => {
|
||||
</thead>
|
||||
<tbody class="divide-y divide-anthracite/5">
|
||||
<tr v-for="candidate in sortedCandidates" :key="candidate.id" class="hover:bg-sand/30 transition-colors group" :class="{ 'bg-primary/5': selectedIds.includes(candidate.id) }">
|
||||
<td class="px-8 py-5">
|
||||
<td v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" class="px-8 py-5">
|
||||
<input
|
||||
type="checkbox"
|
||||
:value="candidate.id"
|
||||
@@ -317,7 +319,7 @@ const batchAnalyze = async () => {
|
||||
class="rounded border-anthracite/20 text-primary focus:ring-primary/20 cursor-pointer"
|
||||
>
|
||||
</td>
|
||||
<td class="px-4 py-5 text-center">
|
||||
<td v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" class="px-4 py-5 text-center">
|
||||
<button @click="toggleSelection(candidate.id)" class="text-anthracite/20 hover:text-highlight hover:-translate-y-0.5 transition-all focus:outline-none" :class="{ '!text-highlight drop-shadow-sm scale-110': candidate.is_selected }" :title="candidate.is_selected ? 'Retirer des retenus' : 'Marquer comme retenu'">
|
||||
<svg v-if="candidate.is_selected" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />
|
||||
@@ -358,12 +360,12 @@ const batchAnalyze = async () => {
|
||||
{{ candidate.status }}
|
||||
</span>
|
||||
</td>
|
||||
<td class="px-8 py-5">
|
||||
<td v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" class="px-8 py-5">
|
||||
<div class="inline-flex items-center gap-2 px-3 py-1 bg-primary/5 text-primary rounded-xl font-black text-sm border border-primary/10 shadow-sm">
|
||||
{{ candidate.weighted_score }} <span class="opacity-50 text-[10px]">/ 20</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-8 py-5">
|
||||
<td v-if="$page.props.auth.user.role !== 'gestionnaire_rh'" class="px-8 py-5">
|
||||
<div v-if="candidate.ai_analysis" class="flex items-center gap-2">
|
||||
<div
|
||||
class="px-2 py-0.5 rounded-lg text-[10px] font-black shadow-sm"
|
||||
@@ -458,7 +460,7 @@ const batchAnalyze = async () => {
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
|
||||
<div v-if="$page.props.auth.user.role === 'super_admin'">
|
||||
<div v-if="$page.props.auth.user.role === 'super_admin' || $page.props.auth.user.role === 'gestionnaire_rh'">
|
||||
<InputLabel for="tenant_id" value="Structure de rattachement" />
|
||||
<select id="tenant_id" v-model="form.tenant_id" class="mt-1 block w-full rounded-md border-slate-300 dark:border-slate-700 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm dark:bg-slate-900">
|
||||
<option value="">Aucune</option>
|
||||
|
||||
Reference in New Issue
Block a user