forked from ScoDoc/ScoDoc
376 lines
9.0 KiB
Django/Jinja
376 lines
9.0 KiB
Django/Jinja
{% extends "sco_page.j2" %}
|
|
|
|
{% block styles %}
|
|
{{ super() }}
|
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/assiduites.css">
|
|
<link rel="stylesheet" href="{{scu.STATIC_DIR}}/css/minitimeline.css">
|
|
|
|
<style>
|
|
.rbtn::before {
|
|
width: 30px;
|
|
height: 30px;
|
|
}
|
|
|
|
.ui-timepicker-container,
|
|
#ui-datepicker-div {
|
|
z-index: 5 !important;
|
|
}
|
|
|
|
#new_periode,
|
|
#actions {
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: fit-content;
|
|
gap: 0.5em;
|
|
}
|
|
|
|
#actions {
|
|
flex-direction: row;
|
|
align-items: center;
|
|
margin: 5px 0;
|
|
}
|
|
|
|
#actions label {
|
|
margin: 0;
|
|
}
|
|
|
|
#fix {
|
|
display: flex;
|
|
flex-direction: row;
|
|
gap: 1em;
|
|
justify-content: space-between;
|
|
width: fit-content;
|
|
}
|
|
|
|
#fix>.box {
|
|
border: 1px solid #444;
|
|
border-radius: 0.5em;
|
|
padding: 1em;
|
|
}
|
|
|
|
.timepicker {
|
|
width: 5em;
|
|
text-align: center;
|
|
}
|
|
|
|
#moduleimpl_select {
|
|
text-align: center;
|
|
}
|
|
|
|
table {
|
|
border-collapse: collapse;
|
|
width: 100%;
|
|
max-width: 1600px;
|
|
position: relative;
|
|
}
|
|
|
|
th,
|
|
td {
|
|
border: 1px solid #ddd;
|
|
padding: 8px;
|
|
text-align: center;
|
|
background-color: white;
|
|
}
|
|
|
|
th {
|
|
z-index: 1;
|
|
}
|
|
|
|
.premier th {
|
|
position: sticky;
|
|
top: 0;
|
|
background-color: white;
|
|
}
|
|
|
|
.second th {
|
|
position: sticky;
|
|
top: 38px;
|
|
background-color: white;
|
|
}
|
|
|
|
|
|
.sticky-col {
|
|
position: sticky;
|
|
left: 0;
|
|
z-index: 1;
|
|
}
|
|
|
|
.rbtn:not(:checked)::before {
|
|
opacity: 0.5;
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
<style>
|
|
.timePicker-modal {
|
|
display: none;
|
|
position: fixed;
|
|
z-index: 1;
|
|
left: 0;
|
|
top: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow: auto;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
}
|
|
|
|
.timePicker-modal.show {
|
|
display: block;
|
|
}
|
|
|
|
.timePicker-modal-content {
|
|
background-color: white;
|
|
margin: 15% auto;
|
|
padding: 20px;
|
|
border: 1px solid #888;
|
|
width: 300px;
|
|
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
|
|
text-align: center;
|
|
}
|
|
|
|
.timePicker-close {
|
|
color: #aaa;
|
|
float: right;
|
|
font-size: 28px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.timePicker-close:hover,
|
|
.timePicker-close:focus {
|
|
color: black;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.time-picker-container {
|
|
margin: 15px 0;
|
|
}
|
|
|
|
#confirmButton {
|
|
padding: 10px 20px;
|
|
font-size: 16px;
|
|
background-color: var(--color-primary);
|
|
color: white;
|
|
border: none;
|
|
cursor: pointer;
|
|
}
|
|
|
|
#confirmButton:hover {
|
|
background-color: var(--color-secondary);
|
|
}
|
|
</style>
|
|
{% endblock styles %}
|
|
|
|
{% block scripts %}
|
|
{{ super() }}
|
|
<script src="{{scu.STATIC_DIR}}/js/etud_info.js"></script>
|
|
<script src="{{scu.STATIC_DIR}}/js/assiduites.js"></script>
|
|
<script src="{{scu.STATIC_DIR}}/js/date_utils.js"></script>
|
|
{% include "sco_timepicker.j2" %}
|
|
|
|
|
|
<script>
|
|
|
|
function updateTemps(temps){
|
|
let matin = document.getElementById("text-matin");
|
|
let apresmidi = document.getElementById("text-apresmidi");
|
|
matin.textContent = `${temps.matin.debut} à ${temps.matin.fin}`;
|
|
apresmidi.textContent = `${temps.apresmidi.debut} à ${temps.apresmidi.fin}`;
|
|
}
|
|
|
|
const temps = {
|
|
matin: {
|
|
debut: "09:00",
|
|
fin: "12:00"
|
|
},
|
|
apresmidi: {
|
|
debut: "13:00",
|
|
fin: "17:00"
|
|
}
|
|
}
|
|
|
|
document.querySelectorAll(".rbtn").forEach((el)=>{
|
|
el.addEventListener("click", (e)=>{
|
|
let target = e.target;
|
|
let parent = target.parentElement;
|
|
let inputs = parent.querySelectorAll(".rbtn");
|
|
|
|
inputs.forEach((input)=>{
|
|
if (input != target){
|
|
input.checked = false;
|
|
}
|
|
});
|
|
});
|
|
});
|
|
|
|
document.getElementById("text-matin").addEventListener("click", (e)=>{
|
|
e.preventDefault();
|
|
openModal(true);
|
|
});
|
|
|
|
document.getElementById("text-apresmidi").addEventListener("click", (e)=>{
|
|
e.preventDefault();
|
|
openModal(false);
|
|
});
|
|
|
|
updateTemps(temps);
|
|
|
|
</script>
|
|
|
|
<script>
|
|
|
|
function openModal(morning = true){
|
|
|
|
let text = morning ? "du matin" : "de l'après-midi";
|
|
const modal = document.getElementById("timePickerModal");
|
|
modal.querySelector("#timePicker-modal-text").textContent = text;
|
|
|
|
let time1 = $("#time1");
|
|
let time2 = $("#time2");
|
|
|
|
// Réinitialiser les champs
|
|
time1.val("");
|
|
time2.val("");
|
|
|
|
// Définir l'action du bouton de confirmation
|
|
|
|
document.getElementById("confirmButton").onclick = function(){
|
|
let debut = time1.val();
|
|
let fin = time2.val();
|
|
|
|
if (debut == "" || fin == ""){
|
|
alert("Veuillez remplir les deux champs");
|
|
return;
|
|
}
|
|
|
|
if (debut >= fin){
|
|
alert("L'heure de début doit être inférieure à l'heure de fin");
|
|
return;
|
|
}
|
|
|
|
if (morning){
|
|
if (fin > temps.apresmidi.debut){
|
|
alert("L'heure de fin du matin doit être inférieure à l'heure de début de l'après-midi");
|
|
return;
|
|
}
|
|
temps.matin.debut = debut;
|
|
temps.matin.fin = fin;
|
|
} else {
|
|
if (debut < temps.matin.fin){
|
|
alert("L'heure de début de l'après-midi doit être supérieure à l'heure de fin du matin");
|
|
return;
|
|
}
|
|
temps.apresmidi.debut = debut;
|
|
temps.apresmidi.fin = fin;
|
|
}
|
|
|
|
updateTemps(temps);
|
|
modal.classList.remove("show");
|
|
}
|
|
|
|
modal.classList.add("show");
|
|
}
|
|
|
|
document.addEventListener("DOMContentLoaded", ()=>{
|
|
const modal = document.getElementById("timePickerModal");
|
|
modal.querySelector(".timePicker-close").onclick = function() {
|
|
modal.classList.remove("show");
|
|
}
|
|
|
|
document.addEventListener('keyup', function(e) {
|
|
if (e.key === "Escape" && modal.classList.contains("show")) {
|
|
modal.classList.remove("show");
|
|
}
|
|
});
|
|
})
|
|
|
|
</script>
|
|
|
|
{% endblock scripts %}
|
|
|
|
{% block title %}
|
|
{{ title }}
|
|
{% endblock title %}
|
|
|
|
{% block app_content %}
|
|
|
|
<h2>Signalement hebdomadaire de l'assiduité {{ gr | safe }}</h2>
|
|
<br>
|
|
<div id="actions" class="flex">
|
|
<button>Semaine précédente</button>
|
|
<label for="moduleimpl_select">
|
|
Module:
|
|
{{moduleimpl_select | safe}}
|
|
</label>
|
|
<button>Semaine suivante</button>
|
|
</div>
|
|
|
|
<h3 id="tableau-dates">
|
|
Le matin <a href="#" id="text-matin" title="Cliquer pour modifier les horaires">9h à 12h</a> et l'après-midi de <a href="#" id="text-apresmidi" title="Cliquer pour modifier les horaires">13h à 17h</a>
|
|
</h3>
|
|
|
|
<table>
|
|
<thead>
|
|
<tr class="premier">
|
|
<th rowspan="2">Étudiants</th>
|
|
<th colspan="2">Lundi</th>
|
|
<th colspan="2">Mardi</th>
|
|
<th colspan="2">Mercredi</th>
|
|
<th colspan="2">Jeudi</th>
|
|
<th colspan="2">Vendredi</th>
|
|
</tr>
|
|
<tr class="second">
|
|
<th>Matin</th>
|
|
<th>Après-midi</th>
|
|
<th>Matin</th>
|
|
<th>Après-midi</th>
|
|
<th>Matin</th>
|
|
<th>Après-midi</th>
|
|
<th>Matin</th>
|
|
<th>Après-midi</th>
|
|
<th>Matin</th>
|
|
<th>Après-midi</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for etud in etudiants %}
|
|
<tr>
|
|
<td class="etudinfo" id="etud-{{etud.etudid}}">{{ etud.nomprenom }}</td>
|
|
{# à changer par jour travaillés (sco pref) #}
|
|
{% for day in ['lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi'] %}
|
|
<td>
|
|
<input type="checkbox" name="" id="" class="rbtn present">
|
|
<input type="checkbox" name="" id="" class="rbtn retard">
|
|
<input type="checkbox" name="" id="" class="rbtn absent">
|
|
</td>
|
|
<td>
|
|
<input type="checkbox" name="" id="" class="rbtn present">
|
|
<input type="checkbox" name="" id="" class="rbtn retard">
|
|
<input type="checkbox" name="" id="" class="rbtn absent">
|
|
</td>
|
|
{% endfor %}
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
|
|
<div id="timePickerModal" class="timePicker-modal">
|
|
<div class="timePicker-modal-content">
|
|
<span class="timePicker-close">×</span>
|
|
<h2>Choisissez les horaires <span id="timePicker-modal-text"></span></h2>
|
|
<div class="time-picker-container">
|
|
<label for="time1">Début</label>
|
|
<input type="text" id="time1" name="time1" class="timepicker" placeholder="hh:mm">
|
|
</div>
|
|
<div class="time-picker-container">
|
|
<label for="time2">Fin</label>
|
|
<input type="text" id="time2" name="time2" class="timepicker" placeholder="hh:mm">
|
|
</div>
|
|
<span>
|
|
<button id="confirmButton">Confirmer</button>
|
|
</div>
|
|
</div>
|
|
|
|
{% include "assiduites/widgets/alert.j2" %}
|
|
{% endblock app_content %} |