feat: implementation du role Gestionnaire RH et refonte de la gestion des offres
This commit is contained in:
@@ -12,7 +12,7 @@ const props = defineProps({
|
||||
|
||||
const page = usePage();
|
||||
const user = computed(() => page.props.auth.user);
|
||||
const isAdmin = computed(() => ['admin', 'super_admin'].includes(user.value?.role));
|
||||
const isAdmin = computed(() => ['admin', 'super_admin', 'gestionnaire_rh'].includes(user.value?.role));
|
||||
const layout = computed(() => isAdmin.value ? AdminLayout : AuthenticatedLayout);
|
||||
|
||||
import axios from 'axios';
|
||||
@@ -59,7 +59,7 @@ const triggerMassAssignmentHoneypot = async () => {
|
||||
|
||||
<div v-if="isAdmin" class="space-y-8 font-sans text-anthracite">
|
||||
<!-- KPI Cards -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-5 gap-6">
|
||||
<div :class="['grid gap-6', user.role === 'gestionnaire_rh' ? 'grid-cols-1 max-w-sm mx-auto' : 'grid-cols-1 md:grid-cols-2 lg:grid-cols-5']">
|
||||
<!-- Total Candidats -->
|
||||
<div class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-primary/5 transition-all duration-300 relative overflow-hidden group">
|
||||
<div class="text-[10px] font-subtitle font-black uppercase tracking-widest text-anthracite/40">Total Candidats</div>
|
||||
@@ -68,7 +68,7 @@ const triggerMassAssignmentHoneypot = async () => {
|
||||
</div>
|
||||
|
||||
<!-- Candidats Retenus -->
|
||||
<div class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-highlight/20 transition-all duration-300 relative overflow-hidden group">
|
||||
<div v-if="user.role !== 'gestionnaire_rh'" class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-highlight/20 transition-all duration-300 relative overflow-hidden group">
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-highlight/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
||||
<div class="relative z-10">
|
||||
<div class="text-highlight text-[10px] font-subtitle font-black uppercase tracking-widest flex items-center gap-1.5">
|
||||
@@ -82,21 +82,21 @@ const triggerMassAssignmentHoneypot = async () => {
|
||||
</div>
|
||||
|
||||
<!-- Tests terminés -->
|
||||
<div class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-emerald-500/10 transition-all duration-300 relative overflow-hidden group">
|
||||
<div v-if="user.role !== 'gestionnaire_rh'" class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-emerald-500/10 transition-all duration-300 relative overflow-hidden group">
|
||||
<div class="text-[10px] font-subtitle font-black uppercase tracking-widest text-anthracite/40">Tests terminés</div>
|
||||
<div class="text-4xl font-black mt-3 text-emerald-500">{{ stats.finished_tests }}</div>
|
||||
<div class="absolute bottom-0 right-0 w-24 h-24 bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-emerald-500/10 to-transparent"></div>
|
||||
</div>
|
||||
|
||||
<!-- Moyenne Générale -->
|
||||
<div class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-sky/10 transition-all duration-300 relative overflow-hidden group">
|
||||
<div v-if="user.role !== 'gestionnaire_rh'" class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-sky/10 transition-all duration-300 relative overflow-hidden group">
|
||||
<div class="text-[10px] font-subtitle font-black uppercase tracking-widest text-anthracite/40">Moyenne Générale</div>
|
||||
<div class="text-4xl font-black mt-3 text-sky">{{ stats.average_score }} <span class="text-lg opacity-50 font-bold">/ 20</span></div>
|
||||
<div class="absolute bottom-0 right-0 w-24 h-24 bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-sky/10 to-transparent"></div>
|
||||
</div>
|
||||
|
||||
<!-- Meilleur Score -->
|
||||
<div class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-accent/10 transition-all duration-300 relative overflow-hidden group">
|
||||
<div v-if="user.role !== 'gestionnaire_rh'" class="bg-white p-6 rounded-3xl shadow-sm border border-anthracite/5 hover:-translate-y-1 hover:shadow-xl hover:shadow-accent/10 transition-all duration-300 relative overflow-hidden group">
|
||||
<div class="text-[10px] font-subtitle font-black uppercase tracking-widest text-anthracite/40">Meilleur Score</div>
|
||||
<div class="text-4xl font-black mt-3 text-accent">{{ stats.best_score }} <span class="text-lg opacity-50 font-bold">/ 20</span></div>
|
||||
<div class="absolute bottom-0 right-0 w-24 h-24 bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-accent/10 to-transparent"></div>
|
||||
@@ -108,7 +108,7 @@ const triggerMassAssignmentHoneypot = async () => {
|
||||
<div class="px-8 py-6 border-b border-anthracite/5 flex justify-between items-center bg-sand/30">
|
||||
<h3 class="text-xl font-serif font-black text-primary capitalize tracking-tight flex items-center gap-3">
|
||||
<div class="w-1.5 h-6 bg-highlight rounded-full hidden md:block"></div>
|
||||
Top 10 Candidats
|
||||
{{ user.role === 'gestionnaire_rh' ? 'Dernières candidatures' : 'Top 10 Candidats' }}
|
||||
</h3>
|
||||
<Link :href="route('admin.candidates.index')" class="text-xs font-subtitle font-bold uppercase tracking-widest text-primary hover:text-highlight transition-colors flex items-center gap-1">
|
||||
Voir tous <span class="hidden sm:inline">les candidats</span> →
|
||||
@@ -119,8 +119,8 @@ const triggerMassAssignmentHoneypot = async () => {
|
||||
<thead>
|
||||
<tr class="bg-neutral/50">
|
||||
<th class="px-8 py-4 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40">Candidat</th>
|
||||
<th class="px-8 py-4 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40">Score Pondéré</th>
|
||||
<th class="px-8 py-4 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40">Adéquation IA</th>
|
||||
<th v-if="user.role !== 'gestionnaire_rh'" class="px-8 py-4 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40">Score Pondéré</th>
|
||||
<th v-if="user.role !== 'gestionnaire_rh'" class="px-8 py-4 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40">Adéquation IA</th>
|
||||
<th class="px-8 py-4 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40">Statut</th>
|
||||
<th class="px-8 py-4 text-[10px] font-subtitle font-black uppercase tracking-[0.2em] text-anthracite/40 text-right">Actions</th>
|
||||
</tr>
|
||||
@@ -131,12 +131,12 @@ const triggerMassAssignmentHoneypot = async () => {
|
||||
<div class="font-bold text-primary group-hover:text-highlight transition-colors block">{{ candidate.name }}</div>
|
||||
<div class="text-xs text-anthracite/50 font-subtitle tracking-wide mt-0.5">{{ candidate.email }}</div>
|
||||
</td>
|
||||
<td class="px-8 py-5">
|
||||
<td v-if="user.role !== 'gestionnaire_rh'" class="px-8 py-5">
|
||||
<div class="inline-flex items-center gap-2 px-4 py-1.5 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-xs">/ 20</span>
|
||||
</div>
|
||||
</td>
|
||||
<td class="px-8 py-5">
|
||||
<td v-if="user.role !== 'gestionnaire_rh'" class="px-8 py-5">
|
||||
<div v-if="candidate.ai_analysis" class="flex items-center gap-2">
|
||||
<div
|
||||
class="px-3 py-1 rounded-lg text-xs font-black shadow-sm"
|
||||
|
||||
Reference in New Issue
Block a user