402 lines
17 KiB
PHP
402 lines
17 KiB
PHP
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
|
|
<title>Dossier Candidat - {{ $candidate->user->name }}</title>
|
|
<style>
|
|
@page {
|
|
margin: 0cm;
|
|
}
|
|
body {
|
|
font-family: 'Helvetica', 'Arial', sans-serif;
|
|
color: #2d3748;
|
|
line-height: 1.5;
|
|
margin: 0;
|
|
padding: 0;
|
|
background-color: #ffffff;
|
|
}
|
|
.header-stripe {
|
|
height: 15px;
|
|
background: linear-gradient(to right, #004f82, #e0b04c);
|
|
}
|
|
.container {
|
|
padding: 40px;
|
|
}
|
|
.page-break {
|
|
page-break-after: always;
|
|
}
|
|
|
|
/* Typography */
|
|
h1, h2, h3, h4 {
|
|
color: #004f82;
|
|
margin-bottom: 15px;
|
|
text-transform: uppercase;
|
|
letter-spacing: 1px;
|
|
}
|
|
h1 { font-size: 28px; border-bottom: 3px solid #e0b04c; padding-bottom: 10px; }
|
|
h2 { font-size: 20px; border-left: 5px solid #004f82; padding-left: 15px; margin-top: 30px; }
|
|
h3 { font-size: 16px; color: #4a5568; }
|
|
|
|
/* Candidate Details Card */
|
|
.card {
|
|
background-color: #f8f9fa;
|
|
border-radius: 15px;
|
|
padding: 20px;
|
|
margin-bottom: 30px;
|
|
border: 1px solid #e2e8f0;
|
|
}
|
|
.detail-row {
|
|
display: table;
|
|
width: 100%;
|
|
margin-bottom: 8px;
|
|
}
|
|
.detail-label {
|
|
display: table-cell;
|
|
width: 200px;
|
|
font-weight: bold;
|
|
color: #718096;
|
|
text-transform: uppercase;
|
|
font-size: 10px;
|
|
}
|
|
.detail-value {
|
|
display: table-cell;
|
|
font-weight: 500;
|
|
}
|
|
|
|
/* AI Section */
|
|
.ai-verdict {
|
|
display: inline-block;
|
|
padding: 8px 15px;
|
|
border-radius: 8px;
|
|
font-weight: bold;
|
|
font-size: 14px;
|
|
margin-bottom: 20px;
|
|
}
|
|
.verdict-positive { background-color: #def7ec; color: #03543f; }
|
|
.verdict-neutral { background-color: #fef3c7; color: #92400e; }
|
|
.verdict-negative { background-color: #fde8e8; color: #9b1c1c; }
|
|
|
|
.ai-box {
|
|
background-color: #f0f7ff;
|
|
border-left: 5px solid #004f82;
|
|
padding: 15px;
|
|
margin-bottom: 20px;
|
|
font-style: italic;
|
|
}
|
|
|
|
/* Tables & Lists */
|
|
table {
|
|
width: 100%;
|
|
border-collapse: collapse;
|
|
margin-bottom: 20px;
|
|
}
|
|
th {
|
|
background-color: #004f82;
|
|
color: white;
|
|
text-align: left;
|
|
padding: 10px;
|
|
font-size: 12px;
|
|
text-transform: uppercase;
|
|
}
|
|
td {
|
|
padding: 10px;
|
|
border-bottom: 1px solid #e2e8f0;
|
|
font-size: 12px;
|
|
}
|
|
.badge {
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
font-size: 10px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
/* Evaluation Grid */
|
|
.grid-cell {
|
|
height: 30px;
|
|
border: 1px solid #cbd5e0;
|
|
}
|
|
.notes-box {
|
|
height: 100px;
|
|
border: 1px solid #cbd5e0;
|
|
margin-top: 5px;
|
|
}
|
|
|
|
/* Footer */
|
|
.footer {
|
|
position: fixed;
|
|
bottom: 0px;
|
|
left: 0px;
|
|
right: 0px;
|
|
height: 50px;
|
|
text-align: center;
|
|
font-size: 10px;
|
|
color: #a0aec0;
|
|
border-top: 1px solid #e2e8f0;
|
|
padding-top: 10px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header-stripe"></div>
|
|
|
|
<div class="container">
|
|
<!-- HEADER SECTION -->
|
|
<div style="text-align: center; margin-bottom: 40px;">
|
|
<div style="font-size: 12px; font-weight: bold; color: #e0b04c; margin-bottom: 5px; text-transform: uppercase; letter-spacing: 2px;">CABM - Dossier de Synthèse</div>
|
|
<h1>{{ $candidate->user->name }}</h1>
|
|
<div style="font-size: 14px; color: #4a5568;">Candidature au poste de : <strong>{{ $candidate->jobPosition->title ?? 'Poste non défini' }}</strong></div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="detail-row">
|
|
<div class="detail-label">Score Global Pondéré</div>
|
|
<div class="detail-value" style="font-size: 24px; color: #004f82; font-weight: 900;">{{ $candidate->weighted_score }}/20</div>
|
|
</div>
|
|
<div class="detail-row">
|
|
<div class="detail-label">Contact</div>
|
|
<div class="detail-value">{{ $candidate->user->email }} @if($candidate->phone) | {{ $candidate->phone }} @endif</div>
|
|
</div>
|
|
<div class="detail-row">
|
|
<div class="detail-label">Structure</div>
|
|
<div class="detail-value">{{ $candidate->tenant->name ?? 'N/A' }}</div>
|
|
</div>
|
|
@if($candidate->linkedin_url)
|
|
<div class="detail-row">
|
|
<div class="detail-label">LinkedIn</div>
|
|
<div class="detail-value">{{ $candidate->linkedin_url }}</div>
|
|
</div>
|
|
@endif
|
|
</div>
|
|
|
|
<!-- AI ANALYSIS -->
|
|
@if($candidate->ai_analysis)
|
|
<h2>Analyse Decisionnelle</h2>
|
|
<div class="ai-verdict {{ $candidate->ai_analysis['match_score'] >= 75 ? 'verdict-positive' : ($candidate->ai_analysis['match_score'] >= 50 ? 'verdict-neutral' : 'verdict-negative') }}">
|
|
Verdict : {{ $candidate->ai_analysis['verdict'] ?? 'N/A' }} ({{ $candidate->ai_analysis['match_score'] }}%)
|
|
</div>
|
|
<div class="ai-box">
|
|
{{ $candidate->ai_analysis['summary'] }}
|
|
</div>
|
|
|
|
<div style="display: table; width: 100%; margin-top: 20px;">
|
|
<div style="display: table-cell; width: 48%; padding-right: 2%;">
|
|
<h4 style="color: #057a55; font-size: 12px;">Points Forts</h4>
|
|
<ul style="font-size: 11px; padding-left: 20px; color: #03543f;">
|
|
@foreach($candidate->ai_analysis['strengths'] ?? [] as $s)
|
|
<li>{{ $s }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
<div style="display: table-cell; width: 48%;">
|
|
<h4 style="color: #9b1c1c; font-size: 12px;">Points de Vigilance</h4>
|
|
<ul style="font-size: 11px; padding-left: 20px; color: #9b1c1c;">
|
|
@foreach($candidate->ai_analysis['gaps'] ?? [] as $g)
|
|
<li>{{ $g }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
@if(!empty($candidate->ai_analysis['scores_detailles']))
|
|
<h4 style="margin-top: 20px; font-size: 12px; color: #004f82;">Détail des scores par dimension</h4>
|
|
<table style="margin-top: 10px;">
|
|
<thead style="background-color: #edf2f7;">
|
|
<tr>
|
|
<th style="color: #4a5568; background: #edf2f7; width: 30%;">Dimension</th>
|
|
<th style="color: #4a5568; background: #edf2f7; width: 15%; text-align: center;">Score</th>
|
|
<th style="color: #4a5568; background: #edf2f7; width: 55%;">Justification</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@foreach($candidate->ai_analysis['scores_detailles'] as $key => $details)
|
|
<tr>
|
|
<td style="font-weight: bold; text-transform: capitalize;">{{ str_replace('_', ' ', $key) }}</td>
|
|
<td style="text-align: center;">
|
|
<span style="font-weight: bold; color: #004f82;">{{ $details['score'] }}%</span>
|
|
</td>
|
|
<td style="font-size: 10px; color: #4a5568;">{{ $details['justification'] ?? '' }}</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
@endif
|
|
|
|
@if(!empty($candidate->ai_analysis['elements_bloquants']) && count($candidate->ai_analysis['elements_bloquants']) > 0 && $candidate->ai_analysis['elements_bloquants'][0] !== '')
|
|
<div style="margin-top: 20px; padding: 15px; background-color: #fff5f5; border: 1px dashed #feb2b2; border-radius: 10px;">
|
|
<h4 style="color: #c53030; font-size: 12px; margin-top: 0;">Signaux Critiques / Filtres Bloquants</h4>
|
|
<ul style="font-size: 11px; padding-left: 20px; color: #c53030; font-weight: bold;">
|
|
@foreach($candidate->ai_analysis['elements_bloquants'] as $item)
|
|
<li>{{ $item }}</li>
|
|
@endforeach
|
|
</ul>
|
|
</div>
|
|
@endif
|
|
@endif
|
|
|
|
<div class="page-break"></div>
|
|
|
|
<!-- TEST RESULTS -->
|
|
<h2>Résultats des Tests Techniques</h2>
|
|
@forelse($candidate->attempts as $attempt)
|
|
<div style="background-color: #f7fafc; padding: 15px; border-radius: 10px; margin-bottom: 25px;">
|
|
<h3 style="margin-top: 0;">{{ $attempt->quiz->title }} <span style="font-weight: normal; color: #a0aec0; font-size: 12px;">(Fait le {{ $attempt->finished_at->format('d/m/Y H:i') }})</span></h3>
|
|
<div style="font-size: 14px; font-weight: bold; margin-bottom: 15px;">Score : {{ $attempt->score }} / {{ $attempt->max_score }}</div>
|
|
|
|
<table style="background: white;">
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 60%">Question</th>
|
|
<th style="width: 40%">Réponse / Score</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@php
|
|
$quizQuestions = $attempt->quiz->questions;
|
|
$answers = $attempt->answers->keyBy('question_id');
|
|
@endphp
|
|
@foreach($quizQuestions as $question)
|
|
@php $answer = $answers->get($question->id); @endphp
|
|
<tr>
|
|
<td>
|
|
<strong>{{ $question->label }}</strong>
|
|
@if($question->description)
|
|
<div style="font-size: 9px; color: #718096; margin-top: 4px;">{{ $question->description }}</div>
|
|
@endif
|
|
</td>
|
|
<td>
|
|
@if($answer)
|
|
@if($question->type === 'qcm')
|
|
<div style="color: {{ $answer->option?->is_correct ? '#057a55' : '#9b1c1c' }}; font-weight: bold;">
|
|
{{ $answer->option?->option_text ?? 'N/A' }}
|
|
({{ $answer->option?->is_correct ? 'Correct' : 'Incorrect' }})
|
|
</div>
|
|
@else
|
|
<div style="font-style: italic; color: #4a5568;">"{{ $answer->text_content }}"</div>
|
|
<div style="margin-top: 5px; font-weight: bold;">Note : {{ $answer->score }} / {{ $question->points }}</div>
|
|
@endif
|
|
@else
|
|
<span style="color: #a0aec0; font-style: italic;">Pas de réponse</span>
|
|
@endif
|
|
</td>
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
@empty
|
|
<p style="font-style: italic; color: #a0aec0;">Aucun test technique effectué.</p>
|
|
@endforelse
|
|
|
|
<div class="page-break"></div>
|
|
|
|
<!-- GRILLE D'EVALUATION PAPIER -->
|
|
<h2 style="background-color: #004f82; color: white; padding: 10px; border: none;">Grille d'Évaluation (Entretien)</h2>
|
|
<p style="font-size: 10px; color: #718096; margin-bottom: 20px;">Support pour prise de notes manuelle durant l'échange. Échelle de 0 à 10.</p>
|
|
|
|
<h3>1. Compétences Métier & Pré-requis</h3>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 40%">Critères</th>
|
|
@for($i=0; $i<=10; $i++) <th style="width: 4%; font-size: 8px; text-align: center;">{{ $i }}</th> @endfor
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@php
|
|
$requirements = $candidate->jobPosition->requirements ?? ['Compétences techniques générales', 'Expérience domaine', 'Outils & Méthodes'];
|
|
@endphp
|
|
@foreach($requirements as $req)
|
|
<tr>
|
|
<td><strong>{{ $req }}</strong></td>
|
|
@for($i=0; $i<=10; $i++) <td style="border: 1px solid #e2e8f0; text-align: center;"></td> @endfor
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
|
|
<div style="margin-bottom: 30px;">
|
|
<label style="font-size: 10px; font-weight: bold;">Commentaires Compétences :</label>
|
|
<div class="notes-box"></div>
|
|
</div>
|
|
|
|
<h3>2. Savoir être & Adaptabilité</h3>
|
|
<table>
|
|
<thead>
|
|
<tr>
|
|
<th style="width: 40%">Personnalité</th>
|
|
@for($i=0; $i<=10; $i++) <th style="width: 4%; font-size: 8px; text-align: center;">{{ $i }}</th> @endfor
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
@php
|
|
$softSkills = [
|
|
'Communication & Pédagogie',
|
|
'Esprit d\'équipe & Collaboration',
|
|
'Résolution de problèmes & Logique',
|
|
'Adaptabilité & Résilience',
|
|
'Autonomie & Proactivité'
|
|
];
|
|
@endphp
|
|
@foreach($softSkills as $skill)
|
|
<tr>
|
|
<td><strong>{{ $skill }}</strong></td>
|
|
@for($i=0; $i<=10; $i++) <td style="border: 1px solid #e2e8f0; text-align: center;"></td> @endfor
|
|
</tr>
|
|
@endforeach
|
|
</tbody>
|
|
</table>
|
|
|
|
<div style="margin-bottom: 30px;">
|
|
<label style="font-size: 10px; font-weight: bold;">Commentaires Savoir être :</label>
|
|
<div class="notes-box"></div>
|
|
</div>
|
|
|
|
<div class="page-break"></div>
|
|
|
|
<h3>3. Questions d'Entretien (Guide)</h3>
|
|
@if($candidate->ai_analysis && !empty($candidate->ai_analysis['questions_entretien_suggerees']))
|
|
@foreach($candidate->ai_analysis['questions_entretien_suggerees'] as $idx => $question)
|
|
<div style="margin-bottom: 20px;">
|
|
<div style="font-size: 12px; font-weight: bold; color: #004f82;">Q{{ $idx + 1 }}. {{ $question }}</div>
|
|
<div style="height: 60px; border-bottom: 1px dashed #cbd5e0; margin-top: 10px;"></div>
|
|
</div>
|
|
@endforeach
|
|
@else
|
|
<p style="font-style: italic; color: #a0aec0;">Aucune question suggérée. Utilisez vos questions standards.</p>
|
|
@for($i=1; $i<=5; $i++)
|
|
<div style="margin-bottom: 25px;">
|
|
<div style="height: 1px; background-color: #e2e8f0; margin-bottom: 5px;"></div>
|
|
<div style="height: 40px; border: 1px solid #f7fafc;"></div>
|
|
</div>
|
|
@endfor
|
|
@endif
|
|
|
|
<div style="margin-top: 40px; border: 2px solid #004f82; padding: 20px; border-radius: 15px;">
|
|
<div style="font-weight: bold; text-transform: uppercase; color: #004f82; margin-bottom: 10px; text-align: center;">Verdict Final & Avis Client</div>
|
|
<div style="display: table; width: 100%;">
|
|
<div style="display: table-cell; width: 33%; text-align: center; border-right: 1px solid #e2e8f0;">
|
|
<span style="display: inline-block; width: 15px; height: 15px; border: 2px solid #057a55;"></span>
|
|
<span style="font-size: 14px; font-weight: bold; color: #057a55; margin-left: 10px;">FAVORABLE</span>
|
|
</div>
|
|
<div style="display: table-cell; width: 33%; text-align: center; border-right: 1px solid #e2e8f0;">
|
|
<span style="display: inline-block; width: 15px; height: 15px; border: 2px solid #e0b04c;"></span>
|
|
<span style="font-size: 14px; font-weight: bold; color: #92400e; margin-left: 10px;">A REVOIR</span>
|
|
</div>
|
|
<div style="display: table-cell; width: 33%; text-align: center;">
|
|
<span style="display: inline-block; width: 15px; height: 15px; border: 2px solid #9b1c1c;"></span>
|
|
<span style="font-size: 14px; font-weight: bold; color: #9b1c1c; margin-left: 10px;">DEFAVORABLE</span>
|
|
</div>
|
|
</div>
|
|
<div style="margin-top: 20px;">
|
|
<label style="font-size: 10px; font-weight: bold;">Motivations du choix / Points à éclaircir :</label>
|
|
<div style="height: 150px;"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="footer">
|
|
Généré le {{ date('d/m/Y H:i') }} par CABM - Dossier Confidentiel
|
|
</div>
|
|
</body>
|
|
</html>
|