opening and off days

This commit is contained in:
Tykayn 2025-06-07 00:06:34 +02:00 committed by tykayn
parent 56ec8ba4f0
commit 16bc549ece
4 changed files with 167 additions and 73 deletions

View file

@ -94,30 +94,44 @@ const openingHoursFormManager = {
const horairesContainer = checkbox.closest('.jour-container').querySelector('.horaires-container'); const horairesContainer = checkbox.closest('.jour-container').querySelector('.horaires-container');
horairesContainer.classList.remove('d-none'); horairesContainer.classList.remove('d-none');
// Décocher la deuxième plage si elle n'est pas présente dans l'input // Gérer le cas "fermé"
if (hours && !hours.includes(',')) { if (hours === 'off') {
const plage2Checkbox = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage2-active"]`); const fermeCheckbox = horairesContainer.querySelector(`input[name="${daysMap[day]}-ferme"]`);
if (plage2Checkbox) { if (fermeCheckbox) {
plage2Checkbox.checked = false; fermeCheckbox.checked = true;
// Décocher les plages horaires
const plageInputs = horairesContainer.querySelectorAll('.time-range input[type="checkbox"]');
plageInputs.forEach(plageInput => {
plageInput.checked = false;
plageInput.dispatchEvent(new Event('change'));
});
}
} else {
// Décocher la deuxième plage si elle n'est pas présente dans l'input
if (hours && !hours.includes(',')) {
const plage2Checkbox = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage2-active"]`);
if (plage2Checkbox) {
plage2Checkbox.checked = false;
}
} }
}
// Remplir la première plage horaire si spécifiée // Remplir la première plage horaire si spécifiée
if (hours) { if (hours) {
const [startTime, endTime] = hours.split('-'); const [startTime, endTime] = hours.split('-');
if (startTime && endTime) { if (startTime && endTime) {
const [startHour, startMinute] = startTime.split(':'); const [startHour, startMinute] = startTime.split(':');
const [endHour, endMinute] = endTime.split(':'); const [endHour, endMinute] = endTime.split(':');
const startHourInput = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage1-start-hour"]`); const startHourInput = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage1-start-hour"]`);
const startMinuteInput = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage1-start-minute"]`); const startMinuteInput = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage1-start-minute"]`);
const endHourInput = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage1-end-hour"]`); const endHourInput = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage1-end-hour"]`);
const endMinuteInput = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage1-end-minute"]`); const endMinuteInput = horairesContainer.querySelector(`input[name="${daysMap[day]}-plage1-end-minute"]`);
if (startHourInput) startHourInput.value = startHour; if (startHourInput) startHourInput.value = startHour;
if (startMinuteInput) startMinuteInput.value = startMinute; if (startMinuteInput) startMinuteInput.value = startMinute;
if (endHourInput) endHourInput.value = endHour; if (endHourInput) endHourInput.value = endHour;
if (endMinuteInput) endMinuteInput.value = endMinute; if (endMinuteInput) endMinuteInput.value = endMinute;
}
} }
} }
} }
@ -135,30 +149,44 @@ const openingHoursFormManager = {
const horairesContainer = checkbox.closest('.jour-container').querySelector('.horaires-container'); const horairesContainer = checkbox.closest('.jour-container').querySelector('.horaires-container');
horairesContainer.classList.remove('d-none'); horairesContainer.classList.remove('d-none');
// Décocher la deuxième plage si elle n'est pas présente dans l'input // Gérer le cas "fermé"
if (hours && !hours.includes(',')) { if (hours === 'off') {
const plage2Checkbox = horairesContainer.querySelector(`input[name="${day}-plage2-active"]`); const fermeCheckbox = horairesContainer.querySelector(`input[name="${day}-ferme"]`);
if (plage2Checkbox) { if (fermeCheckbox) {
plage2Checkbox.checked = false; fermeCheckbox.checked = true;
// Décocher les plages horaires
const plageInputs = horairesContainer.querySelectorAll('.time-range input[type="checkbox"]');
plageInputs.forEach(plageInput => {
plageInput.checked = false;
plageInput.dispatchEvent(new Event('change'));
});
}
} else {
// Décocher la deuxième plage si elle n'est pas présente dans l'input
if (hours && !hours.includes(',')) {
const plage2Checkbox = horairesContainer.querySelector(`input[name="${day}-plage2-active"]`);
if (plage2Checkbox) {
plage2Checkbox.checked = false;
}
} }
}
// Remplir la première plage horaire si spécifiée // Remplir la première plage horaire si spécifiée
if (hours) { if (hours) {
const [startTime, endTime] = hours.split('-'); const [startTime, endTime] = hours.split('-');
if (startTime && endTime) { if (startTime && endTime) {
const [startHour, startMinute] = startTime.split(':'); const [startHour, startMinute] = startTime.split(':');
const [endHour, endMinute] = endTime.split(':'); const [endHour, endMinute] = endTime.split(':');
const startHourInput = horairesContainer.querySelector(`input[name="${day}-plage1-start-hour"]`); const startHourInput = horairesContainer.querySelector(`input[name="${day}-plage1-start-hour"]`);
const startMinuteInput = horairesContainer.querySelector(`input[name="${day}-plage1-start-minute"]`); const startMinuteInput = horairesContainer.querySelector(`input[name="${day}-plage1-start-minute"]`);
const endHourInput = horairesContainer.querySelector(`input[name="${day}-plage1-end-hour"]`); const endHourInput = horairesContainer.querySelector(`input[name="${day}-plage1-end-hour"]`);
const endMinuteInput = horairesContainer.querySelector(`input[name="${day}-plage1-end-minute"]`); const endMinuteInput = horairesContainer.querySelector(`input[name="${day}-plage1-end-minute"]`);
if (startHourInput) startHourInput.value = startHour; if (startHourInput) startHourInput.value = startHour;
if (startMinuteInput) startMinuteInput.value = startMinute; if (startMinuteInput) startMinuteInput.value = startMinute;
if (endHourInput) endHourInput.value = endHour; if (endHourInput) endHourInput.value = endHour;
if (endMinuteInput) endMinuteInput.value = endMinute; if (endMinuteInput) endMinuteInput.value = endMinute;
}
} }
} }
} }
@ -217,7 +245,26 @@ const openingHoursFormManager = {
// Conteneur pour les plages horaires // Conteneur pour les plages horaires
const horairesContainer = document.createElement('div'); const horairesContainer = document.createElement('div');
horairesContainer.classList.add('horaires-container', 'ms-4', 'd-none', 'row', 'g-3'); horairesContainer.classList.add('horaires-container', 'ml-2', 'd-none', 'row');
// Option "fermé"
const fermeContainer = document.createElement('div');
fermeContainer.classList.add('col-12', 'mb-2');
const fermeCheck = document.createElement('div');
fermeCheck.classList.add('form-check');
const fermeInput = document.createElement('input');
fermeInput.type = 'checkbox';
fermeInput.id = `${jour.toLowerCase()}-ferme`;
fermeInput.name = `${jour.toLowerCase()}-ferme`;
fermeInput.classList.add('form-check-input');
const fermeLabel = document.createElement('label');
fermeLabel.htmlFor = `${jour.toLowerCase()}-ferme`;
fermeLabel.classList.add('form-check-label');
fermeLabel.textContent = 'Fermé';
fermeCheck.appendChild(fermeInput);
fermeCheck.appendChild(fermeLabel);
fermeContainer.appendChild(fermeCheck);
horairesContainer.appendChild(fermeContainer);
// Première plage horaire // Première plage horaire
const plage1 = this.createTimeRangeInputs(`${jour.toLowerCase()}-plage1`); const plage1 = this.createTimeRangeInputs(`${jour.toLowerCase()}-plage1`);
@ -235,6 +282,16 @@ const openingHoursFormManager = {
horairesContainer.classList.toggle('d-none', !e.target.checked); horairesContainer.classList.toggle('d-none', !e.target.checked);
this.convertToOSMOpeningHours(inputSelector); this.convertToOSMOpeningHours(inputSelector);
}); });
// Ajouter l'événement pour gérer l'option "fermé"
fermeInput.addEventListener('change', (e) => {
const plageInputs = horairesContainer.querySelectorAll('.time-range input[type="checkbox"]');
plageInputs.forEach(plageInput => {
plageInput.checked = !e.target.checked;
plageInput.dispatchEvent(new Event('change'));
});
this.convertToOSMOpeningHours(inputSelector);
});
}); });
form.appendChild(joursDiv); form.appendChild(joursDiv);
@ -307,7 +364,7 @@ const openingHoursFormManager = {
// Heure de début // Heure de début
const startContainer = document.createElement('div'); const startContainer = document.createElement('div');
startContainer.classList.add('col-6', 'd-flex', 'align-items-center', 'gap-2'); startContainer.classList.add('col-6', 'd-flex', 'align-items-center', 'gap-2', 'start-hour');
const startHour = document.createElement('input'); const startHour = document.createElement('input');
startHour.type = 'number'; startHour.type = 'number';
@ -332,7 +389,7 @@ const openingHoursFormManager = {
// Heure de fin // Heure de fin
const endContainer = document.createElement('div'); const endContainer = document.createElement('div');
endContainer.classList.add('col-6', 'd-flex', 'align-items-center', 'gap-2'); endContainer.classList.add('col-6', 'd-flex', 'align-items-center', 'gap-2', 'end-hour');
const endHour = document.createElement('input'); const endHour = document.createElement('input');
endHour.type = 'number'; endHour.type = 'number';
@ -425,17 +482,23 @@ const openingHoursFormManager = {
if (checkbox && checkbox.checked) { if (checkbox && checkbox.checked) {
joursSelectionnes.push(jours[jour]); joursSelectionnes.push(jours[jour]);
// Récupérer les horaires pour ce jour // Vérifier si le jour est marqué comme fermé
const prefix = jour.toLowerCase(); const fermeCheckbox = document.getElementById(`${jour.toLowerCase()}-ferme`);
const plage1 = this.getTimeRange(`${prefix}-plage1`); if (fermeCheckbox && fermeCheckbox.checked) {
const plage2 = this.getTimeRange(`${prefix}-plage2`); horairesParJour[jours[jour]] = 'off';
} else {
// Récupérer les horaires pour ce jour
const prefix = jour.toLowerCase();
const plage1 = this.getTimeRange(`${prefix}-plage1`);
const plage2 = this.getTimeRange(`${prefix}-plage2`);
let horaires = []; let horaires = [];
if (plage1) horaires.push(plage1); if (plage1) horaires.push(plage1);
if (plage2) horaires.push(plage2); if (plage2) horaires.push(plage2);
if (horaires.length > 0) { if (horaires.length > 0) {
horairesParJour[jours[jour]] = horaires.join(','); horairesParJour[jours[jour]] = horaires.join(',');
}
} }
} }
}); });
@ -527,6 +590,9 @@ const openingHoursFormManager = {
transform: translateY(-50%); transform: translateY(-50%);
z-index: 1; z-index: 1;
} }
.opening-hours-closed {
background-color: #f8d7da;
}
`; `;
document.head.appendChild(style); document.head.appendChild(style);
@ -554,29 +620,43 @@ const openingHoursFormManager = {
// Trouver les horaires pour ce jour // Trouver les horaires pour ce jour
const rule = rules.find(r => r.days.includes(osmDay)); const rule = rules.find(r => r.days.includes(osmDay));
if (rule && rule.hours) { if (rule) {
const timeRanges = rule.hours.split(','); if (rule.hours === 'off') {
timeRanges.forEach((timeRange, index) => { // Jour fermé
const [start, end] = timeRange.split('-'); dayDiv.classList.add('opening-hours-closed');
const [startHour, startMinute] = start.split(':'); } else if (rule.hours) {
const [endHour, endMinute] = end.split(':'); // Plages horaires spécifiques
const timeRanges = rule.hours.split(',');
timeRanges.forEach((timeRange, index) => {
const [start, end] = timeRange.split('-');
const [startHour, startMinute] = start.split(':');
const [endHour, endMinute] = end.split(':');
// Calculer la position et la largeur // Calculer la position et la largeur
const startMinutes = parseInt(startHour) * 60 + parseInt(startMinute); const startMinutes = parseInt(startHour) * 60 + parseInt(startMinute);
const endMinutes = parseInt(endHour) * 60 + parseInt(endMinute); const endMinutes = parseInt(endHour) * 60 + parseInt(endMinute);
const totalMinutes = 24 * 60; const totalMinutes = 24 * 60;
const left = (startMinutes / totalMinutes) * 100; const left = (startMinutes / totalMinutes) * 100;
const width = ((endMinutes - startMinutes) / totalMinutes) * 100; const width = ((endMinutes - startMinutes) / totalMinutes) * 100;
const timeDiv = document.createElement('div');
timeDiv.classList.add('opening-hours-time');
timeDiv.style.left = `${left}%`;
timeDiv.style.width = `${width}%`;
timeDiv.title = `${start}-${end}`;
dayDiv.appendChild(timeDiv);
});
} else {
// Toute la journée
const timeDiv = document.createElement('div'); const timeDiv = document.createElement('div');
timeDiv.classList.add('opening-hours-time'); timeDiv.classList.add('opening-hours-time');
timeDiv.style.left = `${left}%`; timeDiv.style.left = '0%';
timeDiv.style.width = `${width}%`; timeDiv.style.width = '100%';
timeDiv.title = `${start}-${end}`; timeDiv.title = 'Toute la journée';
dayDiv.appendChild(timeDiv); dayDiv.appendChild(timeDiv);
}); }
} }
container.appendChild(dayDiv); container.appendChild(dayDiv);

View file

@ -100,3 +100,12 @@ table.js-sort-table th:active {
border-left: solid 3px #ccc; border-left: solid 3px #ccc;
padding-left: 2rem; padding-left: 2rem;
} }
.start-hour {
margin-left: -1rem;
}
.end-hour {
margin-left: -1rem;
}

View file

@ -106,7 +106,7 @@
<div class="row"> <div class="row">
<div class="col-12 mt-4"> <div class="col-12 mt-4">
<div class="actions-modification"> <div class="actions-modification mb-4 mx-2">
<a class="btn btn-info" href="{{ path('app_public_index') }}"> <a class="btn btn-info" href="{{ path('app_public_index') }}">
<i class="bi bi-people"></i> <i class="bi bi-people"></i>
@ -141,7 +141,7 @@
<div class="lien-OpenStreetMap"> <div class="lien-OpenStreetMap">
<a href="https://www.openstreetmap.org/{{commerce.osmKind}}/{{ commerce_overpass['@attributes'].id }}" class="btn btn-outline-secondary"> <a href="https://www.openstreetmap.org/{{commerce.osmKind}}/{{ commerce_overpass['@attributes'].id }}" class="btn btn-outline-secondary">
{{ 'display.view_on_osm'|trans }} <i class="bi bi-globe"></i> {{ 'display.view_on_osm'|trans }}
</a> </a>
<button onclick="openInJOSM('{{commerce.osmKind}}', '{{ commerce_overpass['@attributes'].id }}')" class="btn btn-outline-secondary ms-2"> <button onclick="openInJOSM('{{commerce.osmKind}}', '{{ commerce_overpass['@attributes'].id }}')" class="btn btn-outline-secondary ms-2">
<i class="bi bi-pencil"></i> Éditer dans JOSM <i class="bi bi-pencil"></i> Éditer dans JOSM
@ -150,9 +150,14 @@
<i class="bi bi-camera"></i> Voir dans Panoramax <i class="bi bi-camera"></i> Voir dans Panoramax
</button> </button>
</div> </div>
<a href="{{ path('app_admin_stats', {'zip_code': zone ?? '-1'}) }}" class="btn btn-outline-secondary"> {# <a href="{{ path('app_admin_stats', {'zip_code': zone ?? '-1'}) }}" class="btn btn-outline-secondary">
<i class="bi bi-bar-chart"></i> <i class="bi bi-bar-chart"></i>
{{ 'display.view_stats'|trans }} {{ 'display.view_stats'|trans }}
</a> #}
<a href="{{ path('app_admin_stats', {'zip_code': zone ?? '-1'}) }}" class="btn btn-outline-secondary">
<i class="bi bi-bar-chart"></i>
Dashboard
</a> </a>
</div> </div>
<div class="disclaimer mt-3 p-3 bg-light rounded"> <div class="disclaimer mt-3 p-3 bg-light rounded">

View file

@ -1,4 +1,4 @@
<div id="clim" class="mb-6"> <div id="clim" class="mb-4">
<h2 class="mb-3 title"> <h2 class="mb-3 title">
<label for="commerce_tag_value__clim"> <label for="commerce_tag_value__clim">
<i class="bi bi-thermometer-half"></i> <i class="bi bi-thermometer-half"></i>