Files
sirh/SIRH/static/templates/SIRH/tiket.html
2026-04-21 16:35:31 +00:00

621 lines
21 KiB
HTML

{% load static %}
{% load roles %}
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Mes demandes</title>
<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">
<link rel="stylesheet" href="{% static 'styles.css' %}">
<style>
@keyframes pulse {
0% { transform: scale(1); }
50% { transform: scale(1.2); }
100% { transform: scale(1); }
}
.bg-orange-dark {
background: linear-gradient(90deg, #b35400, #cc6600);
color: white;
}
</style>
</head>
<body>
<div class="container-fluid">
<div class="row flex-nowrap">
<nav class="col-12 col-md-3 col-lg-2 sidebar p-3">
{% include 'menu_principal.html' %}
</nav>
<main class="col px-4 py-4">
<!-- Boutons Notifications -->
{% if notifications %}
<div class="d-flex justify-content-end mb-3">
<button type="button" class="btn position-relative" data-bs-toggle="modal" data-bs-target="#modalNotifications">
<i class="bi bi-bell-fill"></i> Notifications
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
{{ notifications|length }}
</span>
</button>
</div>
{% endif %}
<!-- Bouton Notifications -->
{% if notifications_employe %}
<div class="d-flex justify-content-end mb-3">
<button type="button" class="btn position-relative" data-bs-toggle="modal" data-bs-target="#modalNotifications">
<i class="bi bi-bell-fill"></i> Notifications
<span id="badgeNotifications" class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">
{{ notifications_employe|length }}
</span>
</button>
</div>
{% endif %}
<!-- Modal Notifications -->
<div class="modal fade" id="modalNotifications" tabindex="-1" aria-labelledby="modalNotificationsLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="modalNotificationsLabel">Mes Notifications</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
{% if notifications_employe %}
<ul class="list-group">
{% for notif in notifications_employe %}
<li class="list-group-item d-flex justify-content-between align-items-center">
{{ notif.message|default:"Nouvelle notification" }}
<small class="text-muted">{{ notif.date_created|date:"d/m/Y H:i" }}</small>
</li>
{% endfor %}
</ul>
{% else %}
<p class="text-muted">Aucune notification pour le moment.</p>
{% endif %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>
<script>document.addEventListener('DOMContentLoaded', function () {
var modal = document.getElementById('modalNotifications');
modal.addEventListener('show.bs.modal', function () {
fetch("{% url 'notifications-lues' %}", {
method: 'POST',
headers: {
'X-CSRFToken': '{{ csrf_token }}',
'Content-Type': 'application/json'
},
body: JSON.stringify({})
})
.then(res => res.json())
.then(data => {
if(data.status === "ok"){
document.getElementById('badgeNotifications').style.display = 'none';
}
});
});
});
</script>
<h1 class="mb-4">La liste des demandes de congés</h1>
<!-- Cartes Statistiques -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card text-white ">
<div class="card-body">
<h6 class="card-title"><i class="bi bi-list-check me-2"></i> Total Demandes</h6>
<p class="card-text fs-4">{{ total }}</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white ">
<div class="card-body">
<h6 class="card-title"><i class="bi bi-check-circle me-2"></i> Validés</h6>
<p class="card-text fs-4">{{ valides }}</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-white ">
<div class="card-body">
<h6 class="card-title"><i class="bi bi-x-circle me-2"></i> Refusés</h6>
<p class="card-text fs-4">{{ refuses }}</p>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-dark ">
<div class="card-body">
<h6 class="card-title"><i class="bi bi-hourglass-split me-2"></i> En attente</h6>
<p class="card-text fs-4">{{ attentes }}</p>
</div>
</div>
</div>
</div>
{% if messages %}
<!-- Modal message -->
<div class="modal fade" id="messageModal" tabindex="-1" aria-labelledby="messageModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header bg-orange-dark
{% if messages.0.tags == 'error' %}bg-danger text-white
{% elif messages.0.tags == 'success' %}bg-success text-white
{% else %}bg-info text-white{% endif %}">
<h5 class="modal-title" id="messageModalLabel">
{% if messages.0.tags == 'error' %}Erreur
{% elif messages.0.tags == 'success' %}Succès
{% else %}Information{% endif %}
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{% for message in messages %}
<p>{{ message }}</p>
{% endfor %}
</div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function() {
var messageModal = new bootstrap.Modal(document.getElementById('messageModal'));
messageModal.show();
});
</script>
{% endif %}
<!-- Bouton Nouvelle Demande -->
<div class="d-flex justify-content-between align-items-center mb-3">
<h2><i class="bi bi-people"></i> Liste</h2>
<button type="button" class="btn btn-primary mb-3" data-bs-toggle="modal" data-bs-target="#modalDemandeConge">
<i class="bi bi-calendar-plus"></i> Nouvelle demande de congé
</button>
</div>
<!-- Modal Nouvelle Demande -->
<div class="modal fade" id="modalDemandeConge" tabindex="-1" aria-labelledby="modalDemandeCongeLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content">
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-header bg-orange-dark">
<h5 class="modal-title" id="modalDemandeCongeLabel">
<i class="bi bi-calendar-plus me-2"></i> Nouvelle demande de congé
</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fermer"></button>
</div>
<div class="modal-body">
<fieldset class="border p-3 rounded">
<legend class="fw-bold">Informations du congé
Il vous reste {{ employe.solde_conge }} jours de congé Annuel
</legend>
<div class="row">
<div class="col-md-6 mb-3">
{{ form.type.label_tag }} {{ form.type }}
</div>
<div class="col-md-6 mb-3">
{{ form.date_debut.label_tag }} {{ form.date_debut }}
</div>
<div class="col-md-6 mb-3">
{{ form.date_fin.label_tag }} {{ form.date_fin }}
</div>
<div class="col-md-6 mb-3">
{{ form.nombre_jours.label_tag }} {{ form.nombre_jours }}
</div>
</div>
</fieldset>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-success">
<i class="bi bi-send"></i> Envoyer
</button>
<button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">
<i class="bi bi-x-circle"></i> Annuler
</button>
</div>
</form>
</div>
</div>
</div>
<!-- Tableau des demandes -->
<table class="table table-striped mt-2">
<thead>
<tr>
<th>Employe</th>
<th>Date demande</th>
<th>Type</th>
<th>Date début</th>
<th>Date fin</th>
<th>Nombre jours</th>
<th>Jours restant</th>
<th>Statut</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for conge in conges %}
<tr>
<td>{{ conge.employe.first_name }} {{ conge.employe.last_name }}</td>
<td>{{ conge.date_demande|date:"d/m/Y" }}</td>
<td>{{ conge.type }}</td>
<td>{{ conge.date_debut|date:"d/m/Y"}}</td>
<td>{{ conge.date_fin|date:"d/m/Y" }}</td>
<td>{{ conge.nombre_jours }}</td>
<td>{{ conge.employe.solde_conge }} </td>
<td>
{% if conge.statut == "Refusé" %}
<span class="badge bg-danger">Refusé</span>
{% elif conge.statut == "Validé directeur" %}
<span class="badge bg-success">Valide </span>
{% elif conge.statut == "Validé chef" %}
<span class="badge bg-warning">Approuvé </span>
{% elif conge.statut == "Refusé par chef" %}
<span class="badge bg-danger">Refusé </span>
{% elif conge.statut == "En attente" %}
<span class="badge bg-warning">En attente </span>
{% endif %}
</td>
<td>
<button class="btn btn-sm btn-info"
data-bs-toggle="modal"
data-bs-target="#detailsCongeModal{{ conge.id }}">
<i class="bi bi-eye"></i> Voir
</button>
{% if conge.statut == "En attente" and conge.employe == request.user %}
<!-- Bouton modifier -->
<button class="btn btn-sm btn-primary"
data-bs-toggle="modal"
data-bs-target="#modifierCongeModal{{ conge.id }}">
Modifier
</button>
<!-- Bouton supprimer -->
<button class="btn btn-sm btn-danger"
data-bs-toggle="modal"
data-bs-target="#supprimerCongeModal{{ conge.id }}">
Supprimer
</button>
{% endif %}
</td>
{% for conge in conges %}
<div class="modal fade" id="modifierCongeModal{{ conge.id }}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form method="post">
{% csrf_token %}
<input type="hidden" name="conge_id" value="{{ conge.id }}">
<div class="modal-header bg-orange-dark">
<h5 class="modal-title">Modifier la demande de congé</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<div class="mb-2">
<label>Type de congé</label>
<select name="type" class="form-select">
<option value="Conge Annuel" {% if conge.type == "Conge Annuel" %}selected{% endif %}>Conge Annuel</option>
<option value="Maladie" {% if conge.type == "Maladie" %}selected{% endif %}>Maladie</option>
<option value="Vacances" {% if conge.type == "Vacances" %}selected{% endif %}>Vacances</option>
<option value="Maternité" {% if conge.type == "Maternité" %}selected{% endif %}>Maternité</option>
</select>
</div>
<div class="mb-2">
<label>Nombre de jours</label>
<input type="number" name="nombre_jours" class="form-control" value="{{ conge.nombre_jours }}">
</div>
<div class="mb-2">
<label>Date début</label>
<input type="date" name="date_debut" class="form-control" value="{{ conge.date_debut|date:'Y-m-d' }}">
</div>
<div class="mb-2">
<label>Date fin</label>
<input type="date" name="date_fin" class="form-control" value="{{ conge.date_fin|date:'Y-m-d' }}">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
<button type="submit" class="btn btn-primary">Enregistrer</button>
</div>
</form>
</div>
</div>
</div>
{% endfor %}
{% for conge in conges %}
<div class="modal fade" id="detailsCongeModal{{ conge.id }}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header bg-orange-dark">
<h5 class="modal-title">Détails de la demande</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<ul class="list-group list-group-flush">
<li class="list-group-item"><strong>Employé :</strong> {{ conge.employe.first_name }} {{ conge.employe.last_name }}</li>
<li class="list-group-item"><strong>Type de congé :</strong> {{ conge.type }}</li>
<li class="list-group-item"><strong>Date début :</strong> {{ conge.date_debut|date:"d/m/Y" }}</li>
<li class="list-group-item"><strong>Date fin :</strong> {{ conge.date_fin|date:"d/m/Y" }}</li>
<li class="list-group-item"><strong>Nombre de jours :</strong> {{ conge.nombre_jours }}</li>
<li class="list-group-item"><strong>Solde restant :</strong> {{ conge.employe.solde_conge }}</li>
<li class="list-group-item">
<strong>Statut :</strong>
{% if conge.statut == "En attente" %}
<span class="badge bg-warning text-dark">{{ conge.statut }}</span>
{% elif conge.statut == "Validé directeur" %}
<span class="badge bg-success">Validé</span>
{% elif conge.statut == "Refusé" %}
<span class="badge bg-danger">Refusé</span>
{% else %}
<span class="badge bg-secondary">{{ conge.statut }}</span>
{% endif %}
</li>
<li class="list-group-item"><strong>Motif :</strong> {{ conge.motif_refus|default:"—" }}</li>
<li class="list-group-item"><strong>Date de la demande :</strong> {{ conge.date_demande|date:"d/m/Y H:i" }}</li>
</ul>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>
{% endfor %}
{% for conge in conges %}
<!-- Modal supprimer -->
<div class="modal fade" id="supprimerCongeModal{{ conge.id }}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<form method="post">
{% csrf_token %}
<input type="hidden" name="delete_id" value="{{ conge.id }}">
<div class="modal-header bg-orange-dark">
<h5 class="modal-title">Supprimer la demande</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>Voulez-vous vraiment supprimer la demande de congé du
<strong>{{ conge.date_debut|date:"d/m/Y" }}</strong> au
<strong>{{ conge.date_fin|date:"d/m/Y" }}</strong> ?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
<button type="submit" class="btn btn-danger">Supprimer</button>
</div>
</form>
</div>
</div>
</div>
{% endfor %}
</tr>
{% empty %}
<tr>
<td colspan="10" class="text-center text-muted">Aucune demande trouvée.</td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- Pagination -->
<nav>
<ul class="pagination">
{% for page_num in conges.paginator.page_range %}
<li class="page-item {% if conges.number == page_num %}active{% endif %}">
<a class="page-link" href="?page={{ page_num }}&search={{ search }}">{{ page_num }}</a>
</li>
{% endfor %}
</ul>
</nav>
<!-- Modal Notifications Chef -->
<div class="modal fade" id="modalNotifications" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header bg-orange-dark">
<h5 class="modal-title"><i class="bi bi-bell-fill me-2"></i> Demandes de congé en attente</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
{% if notifications %}
<table class="table table-bordered table-hover">
<thead class="table-light">
<tr>
<th>Employé</th>
<th>Période</th>
<th>Jours</th>
<th>Type</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for conge in notifications %}
<tr>
<td>{{ conge.employe.first_name }} {{ conge.employe.last_name }}</td>
<td>{{ conge.date_debut|date:"d/m/Y" }} - {{ conge.date_fin|date:"d/m/Y" }}</td>
<td>{{ conge.nombre_jours }}</td>
<td>{{ conge.type }}</td>
<td class="d-flex gap-1">
<!-- Valider -->
<form method="POST" action="{% url 'valider-par-chef' conge.id %}">
{% csrf_token %}
<button type="submit" class="btn btn-success btn-sm" title="Valider">
<i class="bi bi-check-circle"></i>
</button>
</form>
<!-- Refuser -->
<button class="btn btn-danger btn-sm btn-refuser"
data-id="{{ conge.id }}"
data-nom="{{ conge.employe.first_name }} {{ conge.employe.last_name }}"
data-bs-toggle="modal"
data-bs-target="#modalRefuserGlobal">
<i class="bi bi-x-circle"></i>
</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else %}
<div class="alert alert-info">Aucune demande en attente.</div>
{% endif %}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Fermer</button>
</div>
</div>
</div>
</div>
<!-- Modal Refuser -->
<div class="modal fade" id="modalRefuserGlobal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<form method="POST" id="formRefuser">
{% csrf_token %}
<div class="modal-header bg-orange-dark">
<h5 class="modal-title">Refuser la demande</h5>
<button type="button" class="btn-close btn-close-white" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p id="texteConge"></p>
<div class="mb-3">
<label class="form-label">Motif du refus</label>
{{ form.motif_refus }}
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-danger">Refuser</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Annuler</button>
</div>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const modal = new bootstrap.Modal(document.getElementById('modalRefuserGlobal'));
const texteConge = document.getElementById('texteConge');
const formRefuser = document.getElementById('formRefuser');
document.querySelectorAll('.btn-refuser').forEach(button => {
button.addEventListener('click', function() {
const congeId = this.getAttribute('data-id');
const nomEmploye = this.getAttribute('data-nom');
texteConge.innerHTML = `Refuser le congé de <strong>${nomEmploye}</strong> ?`;
formRefuser.action = `/refuser-par-chef/${congeId}/`; // URL dynamique vers Django
formRefuser.reset();
modal.show();
});
});
});
</script>
</main>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>