Files
sirh/SIRH/static/templates/SIRH/rapport.html

206 lines
9.4 KiB
HTML

{% load static %}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Tableau de Bord RH</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static 'bootstrap.min.css' %}">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css">
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels"></script>
<style>
h1 { font-weight: 700; }
.card { border-radius: 15px; }
.chart-container { position: relative; height: 350px; }
table { min-width: 100%; }
/* Couleurs oranges */
.bg-orange-dark { background: linear-gradient(90deg, #b35400, #cc6600); color: white; }
.bg-orange { background: #ff9f1c; color: white; }
.bg-orange-light { background: #ffc107; color: #212529; }
/* Badges */
.badge-warning { background-color: #ffc107; color: #212529; }
.badge-success { background-color: #28a745; color: #fff; }
.badge-primary { background-color: #007bff; color: #fff; }
@media print {
body * { visibility: hidden; }
.printable-table, .printable-table * { visibility: visible; }
.printable-table { position: absolute; top: 0; left: 0; width: 100%; }
}
</style>
</head>
<body>
<div class="container-fluid py-4">
<div class="row flex-nowrap">
{% include 'menu_principal.html' %}
<main class="col px-2 py-4" style="margin-left: 280px;">
<h1 class="mb-5 text-center"><i class="bi bi-bar-chart-line-fill me-2"></i>Tableau de Bord RH</h1>
<!-- Filtres -->
<form method="GET" class="row g-3 mb-5">
<div class="col-md-4">
<select name="mois" class="form-select">
<option value="">Tous les mois</option>
{% for num, nom in mois_liste %}
<option value="{{ num }}" {% if mois_selectionne == num %}selected{% endif %}>{{ nom }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<select name="departement" class="form-select">
<option value="">Tous les départements</option>
{% for d in departements %}
<option value="{{ d.id }}" {% if departement_selectionne == d.id %}selected{% endif %}>{{ d.nom }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<button type="submit" class="btn btn-outline-primary w-100"><i class="bi bi-search"></i> Filtrer</button>
</div>
</form>
<!-- Cartes statistiques -->
<div class="row g-4 mb-5">
<div class="col-md-3"><div class="card text-center"><div class="card-body"><h6 class="fw-bold"><i class="bi bi-people me-2"></i>Total Employés</h6><h3 class="fw-bold">{{ total_employes }}</h3></div></div></div>
<div class="col-md-3"><div class="card text-center"><div class="card-body"><h6 class="fw-bold"><i class="bi bi-gender-male me-2"></i>Hommes</h6><h3 class="fw-bold">{{ hommes }}</h3></div></div></div>
<div class="col-md-3"><div class="card text-center"><div class="card-body"><h6 class="fw-bold"><i class="bi bi-gender-female me-2"></i>Femmes</h6><h3 class="fw-bold">{{ femmes }}</h3></div></div></div>
<div class="col-md-3"><div class="card text-center"><div class="card-body"><h6 class="fw-bold"><i class="bi bi-clock-history me-2"></i>Contrats expirants(2mois)</h6><h3 class="fw-bold">{{ expirants }}</h3></div></div></div>
</div>
<div class="row g-4 mb-5">
<div class="col-md-3"><div class="card text-center"><div class="card-header fw-bold"><i class="bi bi-airplane me-2"></i>Congés en attente</div><div class="card-body"><h5 class="display-6 fw-bold">{{ conges_attente }}</h5></div></div></div>
<div class="col-md-3"><div class="card text-center"><div class="card-body"><h6 class="fw-bold"><i class="bi bi-kanban me-2"></i>Projets</h6><h6>(actifs / total)</h6><h3 class="fw-bold">{{ nb_projets_actifs }} / {{ nb_projets }}</h3></div></div></div>
<div class="col-md-3"><div class="card text-center"><div class="card-header fw-bold"><i class="bi bi-clock-history me-2"></i>Âge moyen</div><div class="card-body"><h5 class="display-6 fw-bold">{{ age_moyen }} ans</h5></div></div></div>
</div>
<!-- Graphiques -->
<div class="row g-4 mb-5">
<div class="col-lg-6">
<div class="card shadow"><div class="card-header bg-orange-dark text-white"><i class="bi bi-pie-chart-fill me-2"></i> Répartition par Département</div>
<div class="card-body chart-container"><canvas id="chartDepartement"></canvas></div></div>
</div>
<div class="col-lg-6">
<div class="card shadow"><div class="card-header bg-orange-dark text-white"><i class="bi bi-pie-chart-fill me-2"></i> Répartition par genre</div>
<div class="card-body chart-container"><canvas id="chartSexe"></canvas></div></div>
</div>
</div>
<div class="row g-4 mb-6">
<div class="col-lg-6">
<div class="card shadow"><div class="card-header bg-orange-dark text-white"><i class="bi bi-bar-chart-fill me-2"></i> Projets (En cours / Terminés)</div>
<div class="card-body chart-container"><canvas id="chartProjets"></canvas></div></div>
</div>
<div class="col-lg-6">
<div class="card shadow"><div class="card-header bg-orange-dark text-white"><i class="bi bi-bar-chart-fill me-2"></i> Projets par domaine de recherche</div>
<div class="card-body chart-container"><canvas id="chartDomaine"></canvas></div></div>
</div>
</div>
</main>
</div>
</div>
<script>
const couleursOrange = ['#b35400', '#ff9f1c', '#ffc107', '#ffb84d', '#ffcc80'];
const departementLabels = {{ departement_labels|safe }};
const departementCounts = {{ departement_counts|safe }};
const sexeLabels = {{ sexe_labels|safe }};
const sexeCounts = {{ sexe_counts|safe }};
const projetLabels = {{ projet_labels|safe }};
const projetCounts = {{ projet_counts|safe }};
const ticketsLabels = ["Traités", "Non traités"];
const ticketsCounts = [{{ tickets_traite }}, {{ tickets_non_traite }}];
const domaineLabels = {{ domaine_labels|safe }};
const domaineCounts = {{ domaine_counts|safe }};
new Chart(document.getElementById("chartDepartement"), {
type: 'pie',
plugins: [ChartDataLabels],
data: {
labels: departementLabels,
datasets: [{ data: departementCounts, backgroundColor: couleursOrange }]
},
options: {
plugins: {
legend: { position: 'bottom' },
datalabels: { color: '#fff', font: { weight: 'bold', size: 14 }, formatter: v => v }
}
}
});
new Chart(document.getElementById("chartSexe"), {
type: 'doughnut',
plugins: [ChartDataLabels],
data: {
labels: sexeLabels,
datasets: [{ data: sexeCounts, backgroundColor: couleursOrange }]
},
options: {
plugins: {
legend: { position: 'bottom' },
datalabels: { color: '#fff', font: { weight: 'bold', size: 14 }, formatter: v => v }
}
}
});
new Chart(document.getElementById("chartProjets"), {
type: 'bar',
plugins: [ChartDataLabels],
data: {
labels: projetLabels,
datasets: [{ label:'Nombre de projets', data: projetCounts, backgroundColor: couleursOrange }]
},
options: {
responsive: true,
plugins: {
legend: { display: false },
datalabels: { anchor:'end', align:'top', color:'#000', font:{ weight:'bold', size:16 }, formatter:v => v }
},
scales: {
y: { beginAtZero:true, ticks:{ stepSize:1, precision:0 }, title:{ display:true, text:'Nombre de projets' } },
x: { title:{ display:true, text:'' } }
}
}
});
new Chart(document.getElementById("chartDomaine"), {
type: 'bar',
plugins: [ChartDataLabels],
data: {
labels: domaineLabels,
datasets: [{ label:'Nombre de projets', data: domaineCounts, backgroundColor: couleursOrange }]
},
options: {
responsive: true,
plugins: {
legend: { display: false },
datalabels: { anchor:'end', align:'top', color:'#000', font:{ weight:'bold', size:14 }, formatter:v => v }
},
scales: {
y: { beginAtZero:true, title:{ display:true, text:'Nombre de projets' }, ticks:{ precision:0, stepSize:1 } },
x: {
ticks:{ autoSkip:false, maxRotation:100, minRotation:30, callback: function(value){ return this.getLabelForValue(value); } }
}
}
}
});
document.getElementById('btnVoirRapport').addEventListener('click', function() {
const projetId = document.getElementById('projetId').value;
if(!projetId) return alert("Veuillez sélectionner un projet.");
fetch(`/rapports/projet/${projetId}/`)
.then(resp => { if(!resp.ok) throw new Error("Projet non trouvé"); return resp.text(); })
.then(html => { document.getElementById('contenuRapportProjet').innerHTML = html; })
.catch(err => { document.getElementById('contenuRapportProjet').innerHTML = "<p class='text-danger'>Erreur lors du chargement.</p>"; console.error(err); });
});
</script>
</body>
</html>