installation du module RH
This commit is contained in:
@@ -25,8 +25,11 @@ const form = useForm({
|
||||
ai_bypass_base_prompt: false,
|
||||
tenant_id: '',
|
||||
quiz_ids: [],
|
||||
fpt_metadata: null,
|
||||
});
|
||||
|
||||
const isGeneratingFpt = ref(false);
|
||||
|
||||
const openModal = (position = null) => {
|
||||
editingPosition.value = position;
|
||||
if (position) {
|
||||
@@ -37,12 +40,36 @@ const openModal = (position = null) => {
|
||||
form.ai_bypass_base_prompt = !!position.ai_bypass_base_prompt;
|
||||
form.tenant_id = position.tenant_id || '';
|
||||
form.quiz_ids = position.quizzes ? position.quizzes.map(q => q.id) : [];
|
||||
form.fpt_metadata = position.fpt_metadata || null;
|
||||
} else {
|
||||
form.reset();
|
||||
}
|
||||
showingModal.value = true;
|
||||
};
|
||||
|
||||
const generateFpt = async () => {
|
||||
if (!form.title || !form.description) {
|
||||
alert("Veuillez remplir le titre et la description avant de générer.");
|
||||
return;
|
||||
}
|
||||
isGeneratingFpt.value = true;
|
||||
try {
|
||||
const response = await axios.post(route('admin.job-positions.ai-fpt'), {
|
||||
title: form.title,
|
||||
description: form.description
|
||||
});
|
||||
form.fpt_metadata = response.data;
|
||||
if (response.data.fiche_synthese) {
|
||||
form.description = response.data.fiche_synthese;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
alert("Une erreur est survenue lors de la génération IA.");
|
||||
} finally {
|
||||
isGeneratingFpt.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const closeModal = () => {
|
||||
showingModal.value = false;
|
||||
form.reset();
|
||||
@@ -215,6 +242,59 @@ const copyLink = (position) => {
|
||||
<InputError :message="form.errors.description" />
|
||||
</div>
|
||||
|
||||
<div class="flex justify-between items-center bg-indigo-50 dark:bg-indigo-900/10 p-4 rounded-2xl border border-indigo-100 dark:border-indigo-800/50">
|
||||
<div>
|
||||
<h4 class="text-xs font-black text-indigo-700 dark:text-indigo-400 uppercase tracking-widest mb-1">Assistant RH FPT (IA)</h4>
|
||||
<p class="text-[10px] text-indigo-500 font-bold">Génère automatiquement les mentions réglementaires et catégorise le poste (CGFP).</p>
|
||||
</div>
|
||||
<PrimaryButton type="button" @click="generateFpt" :disabled="isGeneratingFpt || !form.title || !form.description" class="whitespace-nowrap text-xs py-2 px-4 bg-indigo-600 hover:bg-indigo-700">
|
||||
<svg v-if="isGeneratingFpt" class="animate-spin -ml-1 mr-2 h-4 w-4 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
<svg v-else xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
|
||||
</svg>
|
||||
{{ isGeneratingFpt ? 'Génération...' : 'Structurer l\'offre' }}
|
||||
</PrimaryButton>
|
||||
</div>
|
||||
|
||||
<div v-if="form.fpt_metadata" class="bg-slate-50 dark:bg-slate-800/50 rounded-2xl p-4 border border-slate-200 dark:border-slate-700 space-y-4">
|
||||
<div>
|
||||
<h5 class="text-[10px] font-black uppercase tracking-widest text-slate-400 mb-2">Informations Statutaires</h5>
|
||||
<div class="grid grid-cols-2 gap-2 text-xs font-bold">
|
||||
<div class="bg-white dark:bg-slate-900 p-2 rounded-xl">
|
||||
<span class="text-slate-400 block text-[9px] uppercase">Catégorie</span>
|
||||
{{ form.fpt_metadata.infos_poste?.categorie }}
|
||||
</div>
|
||||
<div class="bg-white dark:bg-slate-900 p-2 rounded-xl">
|
||||
<span class="text-slate-400 block text-[9px] uppercase">Cadre d'emplois</span>
|
||||
{{ form.fpt_metadata.infos_poste?.cadre_emplois }}
|
||||
</div>
|
||||
<div class="bg-white dark:bg-slate-900 p-2 rounded-xl">
|
||||
<span class="text-slate-400 block text-[9px] uppercase">Grade Mini</span>
|
||||
{{ form.fpt_metadata.infos_poste?.grade_mini }}
|
||||
</div>
|
||||
<div class="bg-white dark:bg-slate-900 p-2 rounded-xl">
|
||||
<span class="text-slate-400 block text-[9px] uppercase">Grade Maxi</span>
|
||||
{{ form.fpt_metadata.infos_poste?.grade_maxi }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h5 class="text-[10px] font-black uppercase tracking-widest text-slate-400 mb-2">Conformité CGFP</h5>
|
||||
<div class="bg-white dark:bg-slate-900 p-3 rounded-xl text-xs font-bold text-slate-600 dark:text-slate-300">
|
||||
<p class="mb-2"><span class="text-indigo-500">Fondement :</span> {{ form.fpt_metadata.conformite?.fondement_juridique_recrutement }}</p>
|
||||
<ul class="list-disc list-inside space-y-1">
|
||||
<li v-for="(mention, i) in form.fpt_metadata.conformite?.mentions_legales_obligatoires" :key="i">
|
||||
{{ mention }}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-indigo-50/50 dark:bg-indigo-900/10 p-6 rounded-3xl border border-indigo-100 dark:border-indigo-800/50">
|
||||
<label class="block text-xs font-black uppercase tracking-widest text-indigo-600 dark:text-indigo-400 mb-2">IA Context & Prompt Personnalisé</label>
|
||||
<p class="text-[10px] text-indigo-400 mb-4 font-bold uppercase tracking-tight">Utilisez cette zone pour donner des instructions spécifiques à l'IA (priorités, contexte entreprise, ton de l'analyse...)</p>
|
||||
|
||||
@@ -48,6 +48,9 @@ defineProps({
|
||||
<span v-if="job.tenant" class="px-3 py-1 bg-highlight/20 text-[#3a2800] rounded-full text-xs font-bold uppercase tracking-wider">
|
||||
{{ job.tenant.name }}
|
||||
</span>
|
||||
<span v-if="job.fpt_metadata?.infos_poste?.categorie" class="text-xs font-bold text-anthracite/50 uppercase tracking-widest bg-neutral px-2 py-1 rounded">
|
||||
Catégorie {{ job.fpt_metadata.infos_poste.categorie }}
|
||||
</span>
|
||||
<span class="text-xs font-bold text-anthracite/50 uppercase tracking-widest">Temps plein</span>
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold font-serif text-primary group-hover:text-highlight transition-colors mb-4">
|
||||
|
||||
@@ -61,6 +61,9 @@ const submit = () => {
|
||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg>
|
||||
Offre d'emploi
|
||||
</span>
|
||||
<span v-if="jobPosition.fpt_metadata?.infos_poste?.categorie" class="px-3 py-1 bg-white/50 rounded-full font-bold uppercase tracking-widest text-[10px]">
|
||||
Catégorie {{ jobPosition.fpt_metadata.infos_poste.categorie }} - {{ jobPosition.fpt_metadata.infos_poste.cadre_emplois }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -69,7 +72,8 @@ const submit = () => {
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<h2 class="text-xl font-bold font-subtitle text-anthracite mb-3 border-b pb-2">Description du poste</h2>
|
||||
<div class="prose prose-sm prose-neutral text-anthracite/80 whitespace-pre-line">{{ jobPosition.description }}</div>
|
||||
<div v-if="jobPosition.description_html" class="prose prose-sm prose-indigo text-anthracite/80 max-w-none" v-html="jobPosition.description_html"></div>
|
||||
<div v-else class="prose prose-sm prose-neutral text-anthracite/80 whitespace-pre-line">{{ jobPosition.description }}</div>
|
||||
</div>
|
||||
|
||||
<div v-if="jobPosition.requirements && jobPosition.requirements.length > 0">
|
||||
@@ -78,6 +82,26 @@ const submit = () => {
|
||||
<li v-for="(req, i) in jobPosition.requirements" :key="i">{{ req }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div v-if="jobPosition.fpt_metadata" class="bg-neutral/30 rounded-xl p-5 border border-anthracite/10 mt-8">
|
||||
<h2 class="text-sm font-bold font-subtitle uppercase tracking-widest text-primary mb-4 flex items-center gap-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3" />
|
||||
</svg>
|
||||
Informations Statutaires (FPT)
|
||||
</h2>
|
||||
<div class="space-y-3 text-sm text-anthracite/80">
|
||||
<p><strong class="text-anthracite">Grade(s) recherché(s) :</strong> {{ jobPosition.fpt_metadata.infos_poste?.grade_mini }} à {{ jobPosition.fpt_metadata.infos_poste?.grade_maxi }}</p>
|
||||
<p><strong class="text-anthracite">Fondement :</strong> {{ jobPosition.fpt_metadata.conformite?.fondement_juridique_recrutement }}</p>
|
||||
|
||||
<div class="pt-3 border-t border-anthracite/10">
|
||||
<strong class="text-anthracite block mb-2 text-xs uppercase tracking-wider">Mentions Légales :</strong>
|
||||
<ul class="list-disc list-inside space-y-1 text-xs">
|
||||
<li v-for="(mention, idx) in jobPosition.fpt_metadata.conformite?.mentions_legales_obligatoires" :key="idx">{{ mention }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Application Form -->
|
||||
|
||||
Reference in New Issue
Block a user