352 lines
19 KiB
HTML
352 lines
19 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}Disponibilités — GMAO Collège{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="container-fluid">
|
||
<div class="row mb-4">
|
||
<div class="col">
|
||
<h1><i class="bi bi-clock"></i> Disponibilités</h1>
|
||
<p class="text-muted">Gérez vos horaires de travail, les vacances scolaires et vos congés personnels.</p>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Horaires de travail -->
|
||
<div class="row mb-4">
|
||
<div class="col-md-6">
|
||
<div class="card">
|
||
<div class="card-header d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0"><i class="bi bi-calendar-week"></i> Horaires de travail</h5>
|
||
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#scheduleModal">
|
||
<i class="bi bi-plus"></i> Ajouter
|
||
</button>
|
||
</div>
|
||
<div class="card-body">
|
||
{% if schedules %}
|
||
<table class="table table-sm">
|
||
<thead>
|
||
<tr>
|
||
<th>Jour</th>
|
||
<th>Début</th>
|
||
<th>Fin</th>
|
||
<th>Pause déjeuner</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for schedule in schedules %}
|
||
<tr>
|
||
<td>{{ days.get(schedule.day_of_week, schedule.day_of_week) }}</td>
|
||
<td>{{ schedule.start_time.strftime('%H:%M') if schedule.start_time else '-' }}</td>
|
||
<td>{{ schedule.end_time.strftime('%H:%M') if schedule.end_time else '-' }}</td>
|
||
<td>
|
||
{% if schedule.lunch_start and schedule.lunch_end %}
|
||
{{ schedule.lunch_start.strftime('%H:%M') }} - {{ schedule.lunch_end.strftime('%H:%M') }}
|
||
{% else %}
|
||
-
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
<form method="POST" action="{{ url_for('planning.delete_schedule', id=schedule.id) }}" style="display:inline">
|
||
<button type="submit" class="btn btn-outline-danger btn-sm" onclick="return confirm('Supprimer cet horaire?')">
|
||
<i class="bi bi-trash"></i>
|
||
</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% else %}
|
||
<p class="text-muted">Aucun horaire défini. Ajoutez vos horaires habituels.</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="col-md-6">
|
||
<div class="card">
|
||
<div class="card-header d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0"><i class="bi bi-calendar-x"></i> Congés personnels</h5>
|
||
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#leaveModal">
|
||
<i class="bi bi-plus"></i> Ajouter
|
||
</button>
|
||
</div>
|
||
<div class="card-body">
|
||
{% if leaves %}
|
||
<table class="table table-sm">
|
||
<thead>
|
||
<tr>
|
||
<th>Type</th>
|
||
<th>Du</th>
|
||
<th>Au</th>
|
||
<th>Statut</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for leave in leaves %}
|
||
<tr>
|
||
<td>
|
||
{% if leave.leave_type == 'conge' %}Congé
|
||
{% elif leave.leave_type == 'maladie' %}Maladie
|
||
{% elif leave.leave_type == 'formation' %}Formation
|
||
{% else %}Autre{% endif %}
|
||
</td>
|
||
<td>{{ leave.start_date.strftime('%d/%m/%Y') }}</td>
|
||
<td>{{ leave.end_date.strftime('%d/%m/%Y') }}</td>
|
||
<td>
|
||
{% if leave.is_approved %}
|
||
<span class="badge bg-success">Approuvé</span>
|
||
{% else %}
|
||
<span class="badge bg-warning">En attente</span>
|
||
{% endif %}
|
||
</td>
|
||
<td>
|
||
<form method="POST" action="{{ url_for('planning.delete_leave', id=leave.id) }}" style="display:inline">
|
||
<button type="submit" class="btn btn-outline-danger btn-sm" onclick="return confirm('Supprimer ce congé?')">
|
||
<i class="bi bi-trash"></i>
|
||
</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% else %}
|
||
<p class="text-muted">Aucun congé déclaré.</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Vacances scolaires -->
|
||
<div class="row">
|
||
<div class="col-12">
|
||
<div class="card">
|
||
<div class="card-header d-flex justify-content-between align-items-center">
|
||
<h5 class="mb-0"><i class="bi bi-calendar2-event"></i> Vacances scolaires</h5>
|
||
<button type="button" class="btn btn-primary btn-sm" data-bs-toggle="modal" data-bs-target="#closureModal">
|
||
<i class="bi bi-plus"></i> Ajouter
|
||
</button>
|
||
</div>
|
||
<div class="card-body">
|
||
<p class="text-muted mb-3">
|
||
<i class="bi bi-info-circle"></i>
|
||
Définissez les périodes de vacances. Vous pouvez spécifier si vous travaillez pendant ces périodes avec des horaires différents.
|
||
</p>
|
||
{% if closures %}
|
||
<table class="table">
|
||
<thead>
|
||
<tr>
|
||
<th>Nom</th>
|
||
<th>Du</th>
|
||
<th>Au</th>
|
||
<th>Travail</th>
|
||
<th>Notes</th>
|
||
<th></th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for closure in closures %}
|
||
<tr>
|
||
<td>{{ closure.name }}</td>
|
||
<td>{{ closure.start_date.strftime('%d/%m/%Y') }}</td>
|
||
<td>{{ closure.end_date.strftime('%d/%m/%Y') }}</td>
|
||
<td>
|
||
{% if closure.work_hours_type == 'none' %}
|
||
<span class="badge bg-secondary">Non travaillé</span>
|
||
{% elif closure.work_hours_type == 'reduced' %}
|
||
<span class="badge bg-info">Horaires réduits</span>
|
||
{% elif closure.work_hours_type == 'custom' %}
|
||
<span class="badge bg-success">Horaires spécifiques</span>
|
||
{% else %}
|
||
<span class="badge bg-secondary">-</span>
|
||
{% endif %}
|
||
{% if closure.work_days %}
|
||
<div class="small mt-1">
|
||
<span class="badge bg-success">{{ closure.work_days|length }} présence(s)</span>
|
||
{% for day in closure.work_days %}
|
||
<div>{{ day.work_date.strftime('%d/%m') }} : {{ day.start_time.strftime('%H:%M') }}–{{ day.end_time.strftime('%H:%M') }}</div>
|
||
{% endfor %}
|
||
</div>
|
||
{% endif %}
|
||
</td>
|
||
<td>{{ closure.notes or '-' }}</td>
|
||
<td>
|
||
<a href="{{ url_for('planning.edit_closure', id=closure.id) }}" class="btn btn-outline-primary btn-sm">
|
||
<i class="bi bi-pencil"></i>
|
||
</a>
|
||
<form method="POST" action="{{ url_for('planning.delete_closure', id=closure.id) }}" style="display:inline">
|
||
<button type="submit" class="btn btn-outline-danger btn-sm" onclick="return confirm('Supprimer cette période?')">
|
||
<i class="bi bi-trash"></i>
|
||
</button>
|
||
</form>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% else %}
|
||
<p class="text-muted">Aucune période de vacances définie.</p>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal Horaire -->
|
||
<div class="modal fade" id="scheduleModal" tabindex="-1">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<form method="POST" action="{{ url_for('planning.new_schedule') }}">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">Nouveaux horaires</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="mb-3">
|
||
<label class="form-label">Jours de travail</label>
|
||
<div class="row">
|
||
{% for day_num, day_name in days.items() %}
|
||
{% if day_num > 0 and day_num < 6 %}{# Lundi à Vendredi par défaut cochés #}
|
||
<div class="col-md-4 mb-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" name="days" value="{{ day_num }}" id="sched_day_{{ day_num }}" checked>
|
||
<label class="form-check-label" for="sched_day_{{ day_num }}">{{ day_name }}</label>
|
||
</div>
|
||
</div>
|
||
{% else %}
|
||
<div class="col-md-4 mb-2">
|
||
<div class="form-check">
|
||
<input class="form-check-input" type="checkbox" name="days" value="{{ day_num }}" id="sched_day_{{ day_num }}">
|
||
<label class="form-check-label" for="sched_day_{{ day_num }}">{{ day_name }}</label>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
{% endfor %}
|
||
</div>
|
||
<small class="text-muted">Cochez les jours avec ces horaires</small>
|
||
</div>
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="start_time" class="form-label">Heure de début</label>
|
||
<input type="time" class="form-control" id="start_time" name="start_time" value="08:00" required>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="end_time" class="form-label">Heure de fin</label>
|
||
<input type="time" class="form-control" id="end_time" name="end_time" value="17:00" required>
|
||
</div>
|
||
</div>
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="lunch_start" class="form-label">Début pause déjeuner</label>
|
||
<input type="time" class="form-control" id="lunch_start" name="lunch_start" value="12:00">
|
||
<small class="text-muted">Optionnel</small>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="lunch_end" class="form-label">Fin pause déjeuner</label>
|
||
<input type="time" class="form-control" id="lunch_end" name="lunch_end" value="13:00">
|
||
<small class="text-muted">Optionnel</small>
|
||
</div>
|
||
</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 pour les jours sélectionnés</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal Vacances -->
|
||
<div class="modal fade" id="closureModal" tabindex="-1">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<form method="POST" action="{{ url_for('planning.new_closure') }}">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">Nouvelle période</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="mb-3">
|
||
<label for="name" class="form-label">Nom</label>
|
||
<input type="text" class="form-control" id="name" name="name" placeholder="ex: Vacances de Noël" required>
|
||
</div>
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="start_date" class="form-label">Du</label>
|
||
<input type="date" class="form-control" id="start_date" name="start_date" required>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="end_date" class="form-label">Au</label>
|
||
<input type="date" class="form-control" id="end_date" name="end_date" required>
|
||
</div>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label for="work_hours_type" class="form-label">Travail pendant cette période</label>
|
||
<select class="form-select" id="work_hours_type" name="work_hours_type">
|
||
<option value="none">Non travaillé (congé)</option>
|
||
<option value="reduced">Horaires réduits</option>
|
||
<option value="custom">Horaires spécifiques</option>
|
||
</select>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label for="notes" class="form-label">Notes</label>
|
||
<textarea class="form-control" id="notes" name="notes" rows="2" placeholder="Horaires précis si travail..."></textarea>
|
||
</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>
|
||
|
||
<!-- Modal Congé -->
|
||
<div class="modal fade" id="leaveModal" tabindex="-1">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<form method="POST" action="{{ url_for('planning.new_leave') }}">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title">Nouveau congé</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="mb-3">
|
||
<label for="leave_type" class="form-label">Type de congé</label>
|
||
<select class="form-select" id="leave_type" name="leave_type">
|
||
<option value="conge">Congé</option>
|
||
<option value="maladie">Maladie</option>
|
||
<option value="formation">Formation</option>
|
||
<option value="autre">Autre</option>
|
||
</select>
|
||
</div>
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="leave_start" class="form-label">Du</label>
|
||
<input type="date" class="form-control" id="leave_start" name="start_date" required>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="leave_end" class="form-label">Au</label>
|
||
<input type="date" class="form-control" id="leave_end" name="end_date" required>
|
||
</div>
|
||
</div>
|
||
<div class="mb-3">
|
||
<label for="leave_notes" class="form-label">Notes</label>
|
||
<textarea class="form-control" id="leave_notes" name="notes" rows="2"></textarea>
|
||
</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>
|
||
{% endblock %}
|