{% extends "Parent/LayoutParent.html.twig" %} {% block LinksCss %}
{{ parent() }}
<script src="https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.js"></script>
<link rel="stylesheet" href="{{ '/css/Parent/css/premiercnx.css' }}" />
<link href="{{ asset('css/Parent/css/detailsejour.css') }}" type="text/css" rel="stylesheet" />
<link rel="stylesheet" href="{{ '/css/Accompagnateur/imgzoom.css' }}" />
<link rel="stylesheet" href="{{ asset('Plugins/css/dropzone.css') }}" />
<link rel="stylesheet" href="{{ asset('css/splide.min.css') }}" />
<link rel="stylesheet" href="{{ asset('css/favorites-sidebar.css') }}" />
{% set destination = "detailsejour" %}
<style>
.btn-cmdFav {
background-color: #F56040;
color: white;
padding: 10px 20px;
border-radius: 6px;
font-size: 1rem;
box-shadow: 0 4px 8px rgba(0,0,0,0.15);
transition: all 0.3s ease;
}
.btn-cmdFav:hover {
background-color: #e64a30;
transform: scale(1.05);
box-shadow: 0 6px 12px rgba(0,0,0,0.2);
}
.filter-badge {
background-color: #ccc;
color: white;
font-size: 12px;
padding: 2px 10px;
border-radius: 20px;
display: flex;
align-items: center;
cursor: pointer;
transition: all 0.3s ease;
}
.filter-badge:hover {
background-color: #aaa;
}
/* Quand le filtre est actif */
.filter-badge.active {
background-color: #3BA39B; /* Vert plus vif */
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
font-weight: bold;
color: white;
}
.close-btn-purchase {
position: absolute;
padding: 2px;
top: 10px;
right: 10px;
background: none;
border: none;
font-size: 35px;
cursor: pointer;
}
.close-btn-purchase :hover {
color: red;
}
.rowimag.no-margin {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
/* auto-fill + minmax ensures they fill the row and wrap automatically */
gap: 8px; /* spacing between items, optional */
margin: 0; /* override default margin if you want */
padding: 0;
}
/* Each cell is 200px tall (or pick your own dimension). */
.photo-item {
width: 100%;
height: 250px; /* fixed height: 200px */
position: relative;
overflow: hidden; /* hide any overflow if the image is bigger */
border-radius: 4px; /* optional rounding corners */
background: #f0f0f0; /* fallback background color while image loads */
margin-bottom: 20px;
}
/* For images, we want them to fill the box and maintain a cover aspect. */
.photo-item img,
.photo-item video {
width: 100%;
height: 100%;
object-fit: cover; /* ensures image or video is cropped rather than distorted */
display: block;
}
.fav-button {
pointer-events: none; /* Makes the entire button unclickable */
}
/* Enable hover effects only */
.fav-button * {
pointer-events: auto; /* Re-enable events for children */
pointer-events: hover; /* Only allow hover events, not clicks */
}
/* Add this class to the purchase alert to ensure it remains interactive */
#purchase-alert {
pointer-events: auto;
}
/* Réduit l'espace autour du header */
.header {
padding: 15px 15px 5px 15px;
background: #f9f9f9;
}
/* Réduit l'espace sous le titre et le sous-titre */
.titreDetailSej {
margin-bottom: 8px;
}
.media-counts {
margin-bottom: 8px;
}
/* Centre la navigation des dates */
.date-navigation {
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
margin-top: 0;
}
/* Centre le conteneur des cartes */
.date-container {
display: flex;
justify-content: center;
width: 100%;
}
.media-list-horizontal {
gap: 4px;
font-size: 11px;
margin-top: 2px;
display: flex;
justify-content: center;
list-style: none;
margin-bottom: 0;
padding-left: 0;
}
.sejour-title h1 {
font-size: 1.5rem;
font-weight: bold;
color: #3BA39B;
display: flex;
align-items: center;
gap: 10px;
}
.sejour-dates {
font-size: 14px;
color: #777;
margin-top: 5px;
}
.sejour-medias {
display: flex;
gap: 20px;
align-items: center;
font-size: 14px;
color: #555;
}
.media-info {
display: flex;
align-items: center;
gap: 5px;
}
/* Responsive Mobile */
@media (max-width: 768px) {
.sejour-header {
flex-direction: column;
align-items: center;
text-align: center;
}
.sejour-medias {
margin-top: 10px;
gap: 10px;
}
}
</style>
{% endblock %} {% set pageMenu = app.session.get('pageMenu') %} {% block Content
%}
<!-- Alerte pour inciter à acheter -->
<div id="purchase-alert" class="purchase-alert hidden" style="display: none;">
<button class="close-btn" onclick="closePurchaseAlert()">×</button>
<div id="purchase-alert-content">
<!-- Le contenu de l'alerte sera mis à jour dynamiquement en fonction du nombre de favoris -->
</div>
</div>
<div
id="verifImg"
class="modal fade"
role="dialog"
style="background-color: rgba(112, 112, 112, 0.56); z-index: 1000000"
>
<div class="modal-dialog dialogUploadImg">
<div class="row modal-content no-margin contentdialogNoImg">
<div class="headerdialogUploadImg">
<h1 class="titledialogUploadImg"></h1>
<img
src="{{ '/images/Accompagnateur/CroixFermeture.svg' }}"
class="closeNOUploadImg"
data-dismiss="modal"
/>
</div>
<div class="ContenudetailsSejour">
<div class="row no-margin detailsSejour">
<div class="ContentUpload">
<h1 class="titleTelechargement">
Oulala, patience, avant tout sélectionnez vos photos préférées à
l'aide de ce bouton
<i
class="bi bi-heart"
style="font-size: 1.3rem"
title="Ajouter à ma sélection"
></i>
sous les photos <br /><br /><a style="color: #f09e7a"
>Pensez à commander des tirages... pour leurs offrir un beau
souvenir !
</a>
</h1>
</div>
</div>
</div>
<div class="BottomNoUploadImg">
<button class="BtnUploadImg btnAnnulerUpload" data-dismiss="modal">
OK
</button>
</div>
</div>
</div>
</div>
<div class="main-content">
<div class="row no-margin">
<!-- Chat button -->
<div
class="fav-button"
onmouseover="showSelection()"
onmouseout="hideSelection()"
>
<i id="favoris-icon-Accueilpayment" class="bi bi-heart-fill CoeurEclat"></i
><label
id="likeCount"
class="labelFavCount"
style="background-color: #f56040"
>
{{ likes | length }}</label
>
</div>
<div class="selection-popover" id="selectionPopover">
<h4>Votre sélection</h4>
<p>Tirages : {{ likes | length }} / 12</p>
<p>Numériques : {{ likes | length }} / 15</p>
<p>Album : {{ likes | length }} / 20</p>
<button class="finalize-button">Finaliser ma commande</button>
</div>
</div>
<div class="divSliderModern">
<input type="hidden" id="nbFavCurrent" value="{{ nblikes }}" />
<div
class="splide no-padding no-margin"
id="imageSlider"
style="max-height: 200px"
>
<div class="splide__track">
<ul class="splide__list">
<!-- Slide 1 -->
<li class="splide__slide">
<div class="slider-content" style="background: white">
<div class="namePRD" style="display: block">
<h4
class="titleProdbienvenu titleProdbienvenu1"
style="color: #41a2aa"
>
Ajoutez vos favoris dès maintenant
</h4>
<h4
class="titleProdbienvenu titleProdbienvenu2"
style="color: #f09e7a"
>
et profitez de nos produits souvenirs personnalisés !
</h4>
</div>
<img
src="{{ asset('/images/imgSliderEmpty2.png') }}"
class="imgslider"
alt="Image 1"
/>
</div>
</li>
<!-- Slide 2 -->
<li class="splide__slide">
<div class="slider-content" style="background: white">
<div class="namePRD" style="display: block">
<h4
class="titleProdbienvenu titleProdbienvenu1"
style="color: #f09e7a"
>
Pensez à commander le livre du séjour
</h4>
<h4
class="titleProdbienvenu titleProdbienvenu2"
style="color: #41a2aa"
>
et offrez lui le plus beau des cadeaux !
</h4>
</div>
<img
src="{{ asset('/images/imgSliderEmpty1.png') }}"
class="imgslider"
alt="Image 2"
/>
</div>
</li>
</ul>
</div>
</div>
</div>
<!-- Section de contenu à atteindre après le scroll -->
<div
class="no-margin"
id="scrollTarget"
style="width: 100%; background: #f9f9f9; padding-top: 30px"
>
<div class="no-margin" id="scrollTarget" style="width: 100%">
<!-- Conteneur principal en ligne -->
<div
class="header d-flex align-items-center justify-content-between"
style="padding: 15px;"
>
<!-- Bloc titre -->
<div class="box divInfosSejour" style="width: 95%;">
<img
class="imageTitreSej"
src="/Accueil/imagesAccueil/sejour.png"
alt="Icône séjour"
style="width: 40px; height: auto"
/>
<h1 class="titreDetailSej">
Séjour {{sejour.codeSejour}} {{ sejour.themSejour }}
<span class="spnTitleSej">
du
{{ sejour.dateDebutSejour|date("d M Y")|replace({"Jan": "janv.", "Feb": "fév.", "Mar": "mars", "Apr": "avr.", "May": "mai", "Jun": "juin", "Jul": "juil.", "Aug": "août", "Sep": "sept.", "Oct.": "oct.", "Nov.": "nov.", "Dec.": "déc."}) }}
au
{{ sejour.dateFinSejour|date("d M Y")|replace({"Jan": "janv.", "Feb": "fév.", "Mar": "mars", "Apr": "avr.", "May": "mai", "Jun": "juin", "Jul": "juil.", "Aug": "août", "Sep": "sept.", "Oct.": "oct.", "Nov.": "nov.", "Dec.": "déc."}) }}
</span>
</h1>
<span class="spnTitleSej" style="color:black">
(📷 {{ attachementsCount }} Photos/Vidéos | 🎵 {{ nbmessages }} Audios ❤️ <label
id="mesFavCount" style="color:black;margin-right:5px"
>
{{ nblikes }} </label> Favoris )
</span>
<div class="date-navigation">
<div class="date-container">
{% for x, groupAttach in listeattach %}
{% set xDate = date(x) %}
{% set finDate = date(sejour.dateFinSejour) %}
{% if xDate <= finDate %}
<div
class="date-card modern-card {% if loop.last and xDate <= finDate %} active {% endif %}"
data-aos="fade-up"
data-bs-toggle="collapse"
data-bs-target="#demP{{ loop.index }}"
id="iconedemoP{{ loop.index }}"
>
<div class="card-content text-center">
<span class="day">
{% if groupAttach.isFirstDay == "yes" %} Premier jour
{% elseif groupAttach.isLastDay == "yes" %} Dernier jour
{% else %}
{{ xDate|date("D")|replace({
"Mon": "lun.",
"Tue": "mar.",
"Wed": "mer.",
"Thu": "jeu.",
"Fri": "ven.",
"Sat": "sam.",
"Sun": "dim."
}) }}
{% endif %}
</span>
<span class="full-date">
{{ xDate|date("d M Y")|replace({
"Jan": "janv.",
"Feb": "fév.",
"Mar": "mars",
"Apr": "avr.",
"May": "mai",
"Jun": "juin",
"Jul": "juil.",
"Aug": "août",
"Sep": "sept.",
"Oct.": "oct.",
"Nov.": "nov.",
"Dec.": "déc."
}) }}
</span>
<ul class="media-list-horizontal">
{% if groupAttach.countPhotos > 0 %}
<li>
<i class="bi bi-images" style="color: #f56040; font-size: 0.7rem; margin-right: 3px"></i>
{{ groupAttach.countPhotos }}
</li>
{% endif %}
{% if groupAttach.countAudio > 0 %}
<li>
<i class="bi bi-mic-fill" style="color: #ffa500; font-size: 0.7rem; margin-right: 5px"></i>
{{ groupAttach.countAudio }}
</li>
{% endif %}
{% if groupAttach.countVideos > 0 %}
<li>
<i class="bi bi-camera-video-fill" style="color: #41a2aa; font-size: 0.7rem; margin-right: 5px"></i>
{{ groupAttach.countVideos }}
</li>
{% endif %}
</ul>
</div>
</div>
{% endif %}
{% endfor %} <div id="dynamic-card" class="dynamic-card">
<div id="dynamic-card-content" class="dynamic-card-content">
<!-- Le contenu dynamique (album, pochette, montage vidéo) sera injecté ici -->
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Descriptions and Attachments -->
<div class="container--gallery modern">
{% set lastValidIndex = 0 %}
{% set hasAttachments = false %}
{% for x, groupAttach in listeattach %}
{% set xDate = date(x) %}
{% set finDate = date(sejour.dateFinSejour) %}
{% if xDate <= finDate %}
{% set lastValidIndex = loop.index %}
{% set hasAttachments = true %}
<div
id="demP{{ loop.index }}"
class="collapse {% if loop.last and xDate <= finDate %}show{% endif %}"
style="padding: 2%; padding-top: 0%"
>
<div class="journal-entry">
<div class="entry-header" style="
display: flex;
align-items: center;
justify-content: space-between;
background: #ffffff;
padding: 8px 15px;
border-radius: 10px;
margin-bottom: 20px;
box-shadow: 0 2px 8px rgba(0,0,0,0.05);
border-bottom: 1px solid #eee;
flex-wrap: wrap;
">
<!-- Bouton Jour Précédent -->
{% if not loop.first %}
<button class="btn-prev-day" data-target="{{ loop.index0 - 1 }}" style="
background-color: #3BA39B;
border: none;
padding: 5px 10px;
border-radius: 8px;
font-weight: bold;
font-size: 14px;
height: 36px;
display: flex;
align-items: center;
color: white;
cursor: pointer;
transition: all 0.3s ease;
">
<i class="bi bi-chevron-left" style="font-size: 18px;"></i>
</button>
{% else %}
<div style="width: 36px;"></div>
{% endif %}
<!-- Centre : Date + Médias -->
<div style="
flex-grow: 1;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
gap: 12px;
">
<!-- Date -->
<div style="font-weight: bold; font-size: 16px; color: #333;">
{{ x|date("l d F Y")|replace({
"Monday": "Lundi", "Tuesday": "Mardi", "Wednesday": "Mercredi",
"Thursday": "Jeudi", "Friday": "Vendredi", "Saturday": "Samedi",
"Sunday": "Dimanche",
"January": "Janvier", "February": "Février", "March": "Mars",
"April": "Avril", "May": "Mai", "June": "Juin",
"July": "Juillet", "August": "Août", "September": "Septembre",
"October": "Octobre", "November": "Novembre", "December": "Décembre"
}) }}
</div>
<!-- Filtres Médias -->
<div class="filter-icons" style="display: flex; gap: 8px; flex-wrap: wrap;">
<span class="filter-badge active" data-filter="all" title="Afficher tout">
<i class="bi bi-grid-3x3-gap-fill" style="margin-right: 5px; font-size: 14px;"></i> Tout
</span>
{% if groupAttach.countPhotos > 0 %}
<span class="filter-badge" data-filter="photo" title="Filtrer les photos">
<i class="bi bi-image" style="margin-right: 5px; font-size: 14px;"></i> {{ groupAttach.countPhotos }}
</span>
{% endif %}
{% if groupAttach.countVideos > 0 %}
<span class="filter-badge" data-filter="video" title="Filtrer les vidéos">
<i class="bi bi-camera-video-fill" style="margin-right: 5px; font-size: 14px;"></i> {{ groupAttach.countVideos }}
</span>
{% endif %}
{% if groupAttach.countAudio > 0 %}
<span class="filter-badge" data-filter="audio" title="Filtrer les messages audio">
<i class="bi bi-mic-fill" style="margin-right: 5px; font-size: 14px;"></i> {{ groupAttach.countAudio }}
</span>
{% endif %}
</div>
</div>
<!-- Bouton Jour Suivant -->
{% if not loop.last %}
<button class="btn-next-day" data-target="{{ loop.index0 + 1 }}" style="
background-color: #3BA39B;
border: none;
padding: 5px 10px;
border-radius: 8px;
font-weight: bold;
font-size: 14px;
height: 36px;
display: flex;
align-items: center;
color: white;
cursor: pointer;
transition: all 0.3s ease;
">
<i class="bi bi-chevron-right" style="font-size: 18px;"></i>
</button>
{% else %}
<div style="width: 36px;"></div>
{% endif %}
</div>
<!-- Contenu -->
<div class="entry-content" id="TourContent">
<p class="description" style="margin-left:2%;width:95%;margin-top:1%;margin-bottom:1%;text-align:left">
{% for description in sejour.jourdescripdate %} {% if
description.datejourphoto|date("m/d/Y") == x|date("m/d/Y") %}
{{ description.description | nl2br }}
{% endif %} {% endfor %}
</p>
<!-- Conteneur des photos et vidéos -->
<div
class="rowimag no-margin"
style="
width: 100%;
display: flex;
flex-wrap: wrap;
margin: 0;
box-sizing: border-box;
"
>
<!-- Afficher les Photos et Vidéos -->
{% for attach in groupAttach.attachments %}
{% if attach.libiller == 'photo' %}
<div class="column" data-type="{{ attach.libiller }}">
<div class="photo-zoom photo-item">
<a href="{{ attach.path }}">
<img src="{{ attach.path }}" alt="{{ attach.descreption }}" />
</a>
<!-- Icône du cœur avec logique existante -->
<div
class="heart-icon"
id="coeur{{ attach.id_attchment }}"
data-id="{{ attach.id_attchment }}"
data-sejour-id="{{ sejour.id }}"
data-path="{{ attach.path }}"
data-description="{{ attach.descreption }}"
>
{% if app.user %} {% if attach.is_favorite %}
<i
class="bi bi-heart-fill"
title="Sélectionnée"
style="color: #f56040"
></i>
{% else %}
<i class="bi bi-heart" title="Ajouter à ma sélection"></i>
{% endif %} {% endif %}
</div>
<div class="photo-actions" style="display: none">
<button class="menu-btn">⋮</button>
<div class="menu-options">
<button onclick="addToPack('tirage')">
🖨️ Ajouter au tirage
</button>
<button onclick="addToPack('numerique')">
💾 Ajouter au numérique
</button>
</div>
</div>
</div>
{% if attach.descreption != "" %}
<h4 class="description">{{ attach.descreption }}</h4>
{% endif %}
</div>
{% endif %}
{% if attach.libiller == 'video' %}
<div class="column" data-type="{{ attach.libiller }}">
<div class="video-container" style="position: relative; display: inline-block; width: 100%; border-radius: 8px; overflow: hidden;">
<video class="photo-zoom" controls controlslist="nodownload noplaybackrate" style="width: 100%;">
<source src="{{ attach.path }}" type="video/mp4" />
Votre navigateur ne supporte pas la lecture vidéo.
</video>
</div>
{% if attach.descreption != "" %}
<h4 class="description">{{ attach.descreption }}</h4>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
<!-- Section séparée pour les messages audio -->
{% if groupAttach.countAudio > 0 %}
<div class="audio-messages-section" style="margin-top:15px; border-top: 1px solid #eee; padding: 30px;">
<h4 style="margin-bottom: 15px; color: #555">
<i class="bi bi-mic-fill" style="margin-right: 8px; color: #ffa500"></i>
Messages vocaux ({{ groupAttach.countAudio }})
</h4>
{% if sejour.codeSejour|slice(0, 2) == 'PF' %}
{# Les séjours commençant par PF ont toujours accès #}
<div class="audio-messages-container" style="display: flex; flex-wrap: wrap; gap: 15px">
{% for attach in groupAttach.attachments %}
{% if attach.libiller == 'message' %}
<div class="audio-message-item" style="background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;">
<div class="audio-player-container" style="display: flex; align-items: center; margin-bottom: 10px;">
<i class="bi bi-mic-fill" style="font-size: 20px; margin-right: 10px; color: #ffa500"></i>
<audio controls controlslist="nodownload noplaybackrate" style="flex: 1">
<source src="{{ attach.path }}" type="audio/mp3" />
Votre navigateur ne supporte pas la lecture audio.
</audio>
</div>
{% if attach.descreption != "" %}
<div class="audio-description" style="padding-left: 30px">
<p style="margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;">
{{ attach.descreption }}
</p>
</div>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
{% elseif sejour.codeSejour|slice(0, 2) == 'PP' and parentsejour.payment == 1 or sejour.codeSejour|slice(0, 2) == 'EF' and parentsejour.payment == 1 %}
{# PP ou EF avec paiement effectué #}
<div class="audio-messages-container" style="display: flex; flex-wrap: wrap; gap: 15px">
{% for attach in groupAttach.attachments %}
{% if attach.libiller == 'message' %}
<div class="audio-message-item" style="background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;">
<div class="audio-player-container" style="display: flex; align-items: center; margin-bottom: 10px;">
<i class="bi bi-mic-fill" style="font-size: 20px; margin-right: 10px; color: #ffa500"></i>
<audio controls controlslist="nodownload noplaybackrate" style="flex: 1">
<source src="{{ attach.path }}" type="audio/mp3" />
Votre navigateur ne supporte pas la lecture audio.
</audio>
</div>
{% if attach.descreption != "" %}
<div class="audio-description" style="padding-left: 30px">
<p style="margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;">
{{ attach.descreption }}
</p>
</div>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
{% elseif sejour.codeSejour|slice(0, 2) == 'PP' and parentsejour.payment == 0 or sejour.codeSejour|slice(0, 2) == 'EF' and parentsejour.payment == 0 %}
{# PP ou EF sans paiement - message d'accès limité et audio désactivés #}
<div class="audio-messages-container" style="display: flex; flex-wrap: wrap; gap: 15px; opacity: 0.5; pointer-events: none; filter: grayscale(100%);">
<div class="audio-messages-restricted" style="padding: 20px; background: #f0f0f0; border-radius: 8px; text-align: center; margin-bottom: 15px; width: 100%;">
<i class="bi bi-lock-fill" style="font-size: 24px; color: #808080; margin-bottom: 10px;"></i>
<p style="margin: 0; color: #555;">Pour accéder aux messages vocaux, veuillez effectuer le paiement de votre séjour.</p>
</div>
{% for attach in groupAttach.attachments %}
{% if attach.libiller == 'message' %}
<div class="audio-message-item" style="background: #f9f9f9; border-radius: 8px; padding: 12px; display: flex; flex-direction: column; width: calc(33.33% - 10px); min-width: 250px; flex-grow: 1;">
<div class="audio-player-container" style="display: flex; align-items: center; margin-bottom: 10px;">
<i class="bi bi-mic-fill" style="font-size: 20px; margin-right: 10px; color: #ffa500"></i>
<audio controls controlslist="nodownload noplaybackrate" style="flex: 1" disabled>
<source src="{{ attach.path }}" type="audio/mp3" />
Votre navigateur ne supporte pas la lecture audio.
</audio>
</div>
{% if attach.descreption != "" %}
<div class="audio-description" style="padding-left: 30px">
<p style="margin: 0; font-size: 14px; color: #555; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;">
{{ attach.descreption }}
</p>
</div>
{% endif %}
</div>
{% endif %}
{% endfor %}
</div>
{% endif %}
</div>
{% endif %}
</div>
</div>
</div>
{% endif %}
{% endfor %}
{% if not hasAttachments %}
<div class="welcome-message" style="padding: 50px 20px; text-align: center; background: #f9f9f9; border-radius: 15px; margin: 30px auto; max-width: 800px; box-shadow: 0 5px 15px rgba(0,0,0,0.05);">
<img src="/images/welcome-icon.svg" alt="Bienvenue" style="width: 80px; margin-bottom: 20px;" onerror="this.src='/images/Accompagnateur/Picto5sur5.svg'; this.style.width='120px';">
<h2 style="color: #41a2aa; margin-bottom: 20px; font-size: 24px;">Bienvenue sur votre espace séjour !</h2>
<p style="font-size: 18px; color: #555; margin-bottom: 15px;">
Aucun contenu n'a encore été partagé pour ce séjour.
</p>
<p style="font-size: 16px; color: #666; margin-bottom: 25px;">
L'accompagnateur partagera bientôt des photos, vidéos et messages vocaux.
<br>Revenez consulter cette page régulièrement pour suivre les aventures du séjour !
</p>
<div style="display: flex; justify-content: center; gap: 15px; flex-wrap: wrap;">
<div style="display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);">
<i class="bi bi-images" style="font-size: 24px; color: #f56040; margin-right: 10px;"></i>
<span>Photos du séjour</span>
</div>
<div style="display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);">
<i class="bi bi-camera-video-fill" style="font-size: 24px; color: #41a2aa; margin-right: 10px;"></i>
<span>Vidéos des activités</span>
</div>
<div style="display: flex; align-items: center; background: #fff; padding: 15px; border-radius: 10px; box-shadow: 0 2px 8px rgba(0,0,0,0.05);">
<i class="bi bi-mic-fill" style="font-size: 24px; color: #ffa500; margin-right: 10px;"></i>
<span>Messages vocaux</span>
</div>
</div>
</div>
<!-- Espace supplémentaire pour déplacer le footer vers le bas -->
<div style="height: 300px;"></div>
{% endif %}
<!-- Make sure we're showing the right content by default if no valid content is marked 'show' -->
{% if lastValidIndex > 0 %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Check if no content is showing
if (document.querySelectorAll('.container--gallery .collapse.show').length === 0) {
// Show the content for the last valid date
var lastValidContent = document.getElementById('demP{{ lastValidIndex }}');
if (lastValidContent) {
lastValidContent.classList.add('show');
// Also mark the corresponding date card as active
var dateCards = document.querySelectorAll('.date-card');
if (dateCards.length >= {{ lastValidIndex }}) {
dateCards.forEach(card => card.classList.remove('active'));
dateCards[{{ lastValidIndex - 1 }}].classList.add('active');
}
}
}
});
</script>
{% endif %}
</div>
</div>
{% endblock %} {% block Javascript %}
{{ parent() }}
<script>// Gestion de la sidebar des favoris
document.addEventListener('DOMContentLoaded', function() {
const sidebar = document.getElementById('favorites-sidebar');
const openBtn = document.getElementById('openFavoritesSidebar');
const closeBtn = document.querySelector('.favorites-close');
const favButton = document.querySelector('.fav-button');
function openSidebar() {
sidebar.classList.add('active');
updateFavoritesSidebar();
}
function closeSidebar() {
sidebar.classList.remove('active');
}
function updateFavoritesSidebar() {
const grid = document.getElementById('favorites-grid');
const counter = document.getElementById('favorites-counter');
const emptyState = document.getElementById('favorites-empty-state');
const progress = document.getElementById('favorites-progress');
const count = parseInt(document.getElementById('likeCount').textContent);
counter.textContent = count +1;
if (count === 0) {
emptyState.style.display = 'flex';
grid.style.display = 'none';
} else {
emptyState.style.display = 'none';
grid.style.display = 'grid';
const percentage = (count / 20) * 100;
progress.style.width = `${percentage}%`;
}
}
if (openBtn) {
openBtn.addEventListener('click', openSidebar);
}
if (favButton) {
favButton.addEventListener('click', openSidebar);
}
if (closeBtn) {
closeBtn.addEventListener('click', closeSidebar);
}
document.addEventListener('click', (e) => {
if (sidebar.classList.contains('active') &&
!sidebar.contains(e.target) &&
!favButton.contains(e.target) &&
!openBtn.contains(e.target)) {
closeSidebar();
}
});
});
// Modification des fonctions existantes
const originalAddFavoris = window.AddFavoris;
window.AddFavoris = function($id, $idSejour, $urlimg, $description) {
if (originalAddFavoris) {
originalAddFavoris($id, $idSejour, $urlimg, $description);
}
// Vérifier si la sidebar est ouverte - noter que nous vérifions la valeur CSS right: 0
if ($("#favorites-sidebar").css("right") === "0px") {
// Recharger les favoris
loadFavorites();
}
};
const originalSupprimerFavoris = window.supprimerFavoris;
window.supprimerFavoris = function($id, $idSejour) {
if (originalSupprimerFavoris) {
originalSupprimerFavoris($id, $idSejour);
}
// Vérifier si la sidebar est ouverte
if ($("#favorites-sidebar").css("right") === "0px") {
// Recharger les favoris
loadFavorites();
}
};
// Variables globales
let selectedFavorites = [];
let allFavorites = [];
// Fonction pour mettre à jour la sidebar
function loadFavorites() {
$("#favorites-grid").html("<div style='text-align:center;padding:20px;'>Chargement...</div>");
$.ajax({
url: "/Parent/mes-favoris",
type: "GET",
dataType: "json",
success: function(data) {
$("#favorites-grid").empty();
allFavorites = data.data || [];
if (allFavorites.length > 0) {
$("#favorites-empty-state").hide();
$.each(allFavorites, function(i, fav) {
var isSelected = selectedFavorites.includes(fav.id);
var item = $("<div class='favorite-item' style='position:relative;border-radius:8px;overflow:hidden;aspect-ratio:1;cursor:pointer;'></div>");
var img = $("<img style='width:100%;height:100%;object-fit:cover;transition:transform 0.3s ease;'>").attr("src", fav.path).attr("alt", fav.descreption || "Photo favorite");
// Overlay de sélection
var selectionOverlay = $("<div class='selection-overlay' style='position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.3);display:flex;align-items:center;justify-content:center;'></div>");
// Icône de sélection
var checkIcon = $("<div style='width:25px;height:25px;border-radius:50%;border:2px solid white;display:flex;align-items:center;justify-content:center;background:" + (isSelected ? "#F56040" : "transparent") + ";transition:background 0.2s;'></div>");
if (isSelected) {
checkIcon.append("<i class='bi bi-check' style='color:white;font-size:16px;'></i>");
}
selectionOverlay.append(checkIcon);
// Overlay d'action (bouton supprimer)
var actionOverlay = $("<div class='action-overlay' style='position:absolute;top:5px;right:5px;opacity:0;transition:opacity 0.2s;'></div>");
actionOverlay.append(deleteBtn);
// Ajouter les événements
item.hover(
function() { $(this).find(".action-overlay").css("opacity", "1"); },
function() { $(this).find(".action-overlay").css("opacity", "0"); }
);
item.click(function() {
toggleSelection(fav.id, $(this).find(".selection-overlay > div"));
});
item.append(img).append(selectionOverlay).append(actionOverlay);
$("#favorites-grid").append(item);
});
$("#favorites-counter").text(allFavorites.length);
// Mettre à jour le compteur sur le bouton également
$("#openFavoritesSidebar span").text(allFavorites.length);
// Mettre à jour l'interface produits
updateProductsView();
} else {
$("#favorites-empty-state").show();
$("#favorites-counter").text("0");
$("#openFavoritesSidebar span").text("0");
$("#selection-count").text("0");
updateProductsView();
}
},
error: function() {
$("#favorites-grid").html("<div style='color:red;text-align:center;padding:20px;'>Erreur de chargement</div>");
}
});
}
// Fonction pour supprimer un favori
function removeFavorite(id) {
$.ajax({
url: "/Parent/remove-favorite/" + id,
type: "POST",
success: function() {
// Retirer de la sélection si présent
selectedFavorites = selectedFavorites.filter(favId => favId != id);
// Mettre à jour le compteur de sélection
$("#selection-count").text(selectedFavorites.length);
// Recharger les favoris
loadFavorites();
// Mettre à jour les compteurs globaux
var count = parseInt($("#likeCount").text());
if (!isNaN(count)) {
$("#likeCount").text(count - 1);
}
var countFav = parseInt($("#mesFavCount").text());
if (!isNaN(countFav)) {
$("#mesFavCount").text(countFav - 1);
}
// Mettre à jour l'interface produits
updateProductsView();
},
error: function() {
alert("Erreur lors de la suppression du favori");
}
});
}
// Fonction pour basculer la sélection d'une photo
function toggleSelection(id, checkElement) {
const index = selectedFavorites.indexOf(id);
if (index === -1) {
// Ajouter à la sélection
selectedFavorites.push(id);
checkElement.css("background", "#F56040");
checkElement.html("<i class='bi bi-check' style='color:white;font-size:16px;'></i>");
} else {
// Retirer de la sélection
selectedFavorites.splice(index, 1);
checkElement.css("background", "transparent");
checkElement.html("");
}
// Mettre à jour le compteur
$("#selection-count").text(selectedFavorites.length);
// Mettre à jour l'interface produits
updateProductsView();
}
// Fonction pour mettre à jour la vue des produits
function updateProductsView() {
const current = selectedFavorites.length;
$("#product-photo-count").text(current);
let remainingForAlbum = Math.max(0, 20 - current);
let remainingForPochette = Math.max(0, 12 - current);
let remainingForPack = Math.max(0, 12 - current);
const progressBar = (count, total, color) => `
<div style="margin: 5px 0;">
<div style="background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;">
<div style="width: ${(count / total) * 100}%; background-color: ${color}; height: 100%;"></div>
</div>
<small style="font-size: 12px;">${count}/${total} photos</small>
</div>
`;
// Liste des produits
const products = [
{
name: "Pack numérique (20 photos)",
required: 20,
remaining: Math.max(0, 20 - current),
image: "/images/produit/photoNumerique.jpg",
color: "#4caf50",
link: "{{ path('PackPhotosNumerique_Favoris', {'nbr':20}) }}",
},
+
{
name: "Pochette photo (12 photos)",
required: 12,
remaining: Math.max(0, 12 - current),
image: "/images/produit/PochettePhoto5sur5-2.jpg",
color: "#2196f3",
link: "{{ path('AjoutPochettePhotos_Favoris', {'nbr': 12}) }}",
},
].sort((a, b) => a.remaining - b.remaining);
const productList = products
.map((product) => {
const count = current;
const total = product.required;
const remaining = product.remaining;
return `
<li style="margin-bottom: 20px;">
<div style="display: flex; align-items: center; gap: 10px;">
<img src="${product.image}" alt="${product.name}" style="width: 70px; height: 70px; border-radius: 5px; object-fit: cover;" />
<div style="flex: 1;">
<strong style="font-size: 14px;">${product.name}</strong>
${progressBar(count, total, product.color)}
${
`<small style="color: ${product.color}; font-size: 12px;">
Encore ${remaining} photos pour compléter ${product.name.toLowerCase()}
</small>
<button
style="
margin-top: 5px;
padding: 6px 12px;
background-color: ${product.color};
color: white;
border: none;
border-radius: 5px;
font-size: 13px;
cursor: pointer;
"
onclick="window.location.href='${product.link}'"
>
Commander
</button>`
}
</div>
</div>
</li>
`;
})
.join("");
const boutiqueButton = `
<li style="margin-top: 25px; text-align: center;">
<button
style="
padding: 8px 15px;
background-color: #F56040;
color: white;
border: none;
border-radius: 5px;
font-size: 14px;
width: 170px;
height: 40px;
cursor: pointer;
"
onclick="window.location.href='{{ path('boutique5sur5') }}'"
>
Voir toute la boutique
</button>
</li>
`;
$("#product-list").html(productList + boutiqueButton);
}
// Modifications au script existant
$(document).ready(function() {
// Fonctions pour ouvrir/fermer la sidebar
$("#openFavoritesSidebar").click(function() {
$("#favorites-sidebar").css("right", "0");
loadFavorites();
});
$("#close-favorites-btn").click(function() {
closeFavoritesSidebar();
});
// Fonction pour fermer la sidebar
window.closeFavoritesSidebar = function() {
$("#favorites-sidebar").css("right", "-500px");
};
// Tout sélectionner / Tout désélectionner
$("#select-all-btn").click(function() {
if (selectedFavorites.length === allFavorites.length) {
// Tout désélectionner
selectedFavorites = [];
$(".selection-overlay > div").css("background", "transparent").html("");
$(this).text("Tout sélectionner");
} else {
// Tout sélectionner
selectedFavorites = allFavorites.map(fav => fav.id);
$(".selection-overlay > div").css("background", "#F56040").html("<i class='bi bi-check' style='color:white;font-size:16px;'></i>");
$(this).text("Tout désélectionner");
}
// Mettre à jour le compteur
$("#selection-count").text(selectedFavorites.length);
// Mettre à jour l'interface produits
updateProductsView();
});
// Gestion des onglets
$(".sidebar-tab").click(function() {
$(".sidebar-tab").removeClass("active").css({
"color": "#666",
"border-bottom": "none"
});
$(this).addClass("active").css({
"color": "#F56040",
"border-bottom": "2px solid #F56040"
});
const tabId = $(this).attr("id");
$(".tab-content").hide();
if (tabId === "tab-photos") {
$("#photos-content").show();
} else if (tabId === "tab-products") {
$("#products-content").show();
}
});
// Modifier les fonctions existantes pour intercepter l'ajout/suppression de favoris
const originalAddFavoris = window.AddFavoris;
window.AddFavoris = function($id, $idSejour, $urlimg, $description) {
if (originalAddFavoris) {
originalAddFavoris($id, $idSejour, $urlimg, $description);
}
// Recharger les favoris si la sidebar est ouverte
if ($("#favorites-sidebar").css("right") === "0px") {
loadFavorites();
}
};
const originalSupprimerFavoris = window.supprimerFavoris;
window.supprimerFavoris = function($id, $idSejour) {
if (originalSupprimerFavoris) {
originalSupprimerFavoris($id, $idSejour);
}
// Recharger les favoris si la sidebar est ouverte
if ($("#favorites-sidebar").css("right") === "0px") {
// Retirer de la sélection si présent
selectedFavorites = selectedFavorites.filter(favId => favId != $id);
loadFavorites();
}
};
// Fermer en cliquant en dehors
$(document).click(function(event) {
if (!$(event.target).closest("#favorites-sidebar").length &&
!$(event.target).closest("#openFavoritesSidebar").length &&
$("#favorites-sidebar").css("right") === "0px") {
closeFavoritesSidebar();
}
});
});
// Initialisation de la sidebar
$(document).ready(function() {
// Fonctions pour ouvrir/fermer la sidebar
$("#openFavoritesSidebar").click(function() {
$("#favorites-sidebar").css("right", "0");
loadFavorites();
});
$("#close-favorites-btn").click(function() {
$("#favorites-sidebar").css("right", "-500px");
});
// Fermer en cliquant en dehors
$(document).click(function(event) {
if (!$(event.target).closest("#favorites-sidebar").length &&
!$(event.target).closest("#openFavoritesSidebar").length &&
$("#favorites-sidebar").css("right") === "0px") {
$("#favorites-sidebar").css("right", "-500px");
}
});
});
</script>
<script src="{{ asset('js/splide.min.js') }}"></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const openBtn = document.getElementById('openFavoritesSidebar');
const sidebar = document.getElementById('favorites-sidebar');
const closeBtn = document.getElementById('favorites-close');
if (openBtn && sidebar) {
openBtn.addEventListener('click', () => sidebar.classList.add('active'));
}
if (closeBtn && sidebar) {
closeBtn.addEventListener('click', () => sidebar.classList.remove('active'));
}
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const filterBadges = document.querySelectorAll('.filter-badge');
filterBadges.forEach(badge => {
badge.addEventListener('click', function() {
// Désactiver tous les badges
filterBadges.forEach(b => b.classList.remove('active'));
// Activer le badge cliqué
this.classList.add('active');
});
});
});
</script>
<script
type="text/javascript"
src="{{ asset('Accueil/js/jquery.magnific-popup.min.js') }}"
></script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const prevButtons = document.querySelectorAll('.btn-prev-day');
const nextButtons = document.querySelectorAll('.btn-next-day');
const dateCards = document.querySelectorAll('.date-card.modern-card');
const collapseSections = document.querySelectorAll('.collapse');
function navigateToDay(index) {
if (index >= 0 && index < collapseSections.length) {
// Fermer tous les jours
collapseSections.forEach(s => s.classList.remove('show'));
dateCards.forEach(c => c.classList.remove('active'));
// Ouvrir le bon jour
const targetCollapse = collapseSections[index];
const targetCard = dateCards[index];
if (targetCollapse && targetCard) {
targetCollapse.classList.add('show');
targetCard.classList.add('active');
}
}
}
prevButtons.forEach(button => {
button.addEventListener('click', function () {
const targetIndex = parseInt(this.dataset.target, 10);
navigateToDay(targetIndex);
});
});
nextButtons.forEach(button => {
button.addEventListener('click', function () {
const targetIndex = parseInt(this.dataset.target, 10);
navigateToDay(targetIndex);
});
});
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function() {
const style = document.createElement('style');
style.textContent = `
.hidden {
display: none !important;
}
`;
document.head.appendChild(style);
});
document.addEventListener('DOMContentLoaded', function() {
// Get the favorite button
const favoriteButton = document.querySelector('.fav-button');
if (favoriteButton) {
// Make it unclickable with JS too (belt and suspenders approach)
favoriteButton.style.pointerEvents = 'none';
// Override any existing click handlers
favoriteButton.onclick = function(e) {
e.preventDefault();
e.stopPropagation();
return false;
};
// Make sure hover still works
favoriteButton.addEventListener('mouseover', function() {
document.getElementById('purchase-alert').style.display = 'block';
});
// Keep any existing hover functionality
if (typeof showSelection === 'function') {
favoriteButton.onmouseover = showSelection;
}
}
// Make sure the purchase alert remains interactive
const purchaseAlert = document.getElementById('purchase-alert');
if (purchaseAlert) {
purchaseAlert.style.pointerEvents = 'auto';
}
});
// Sélection des éléments
const purchaseAlert = document.getElementById("purchase-alert");
const alertContent = document.getElementById("purchase-alert-content");
const likeCountLabel = document.getElementById("likeCount");
const favoriteCount = parseInt(likeCountLabel.textContent.trim(), 10); // Convertir en nombre
// Fonction pour mettre à jour le contenu de l'alerte
function updatePurchaseAlert(current) {
let remainingForAlbum = Math.max(0, 20 - current);
let remainingForPochette = Math.max(0, 12 - current);
let remainingForPack = Math.max(0, 12 - current);
const progressBar = (count, total, color) => `
<div style="margin: 5px 0;">
<div style="background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;">
<div style="width: ${
(count / total) * 100
}%; background-color: ${color}; height: 100%;"></div>
</div>
<small style="font-size: 12px;">${count}/${total} photos</small>
</div>
`;
// Use Twig paths here:
const products = [
{
name: "Pochette photo (12 photos)",
required: 12,
remaining: remainingForPochette,
image: "/images/produit/PochettePhoto5sur5-2.jpg",
color: "#2196f3",
link: "{{ path('AjoutPochettePhotos_Favoris', {'nbr': 12}) }}",
},
{
name: "Pack numérique (20 photos)",
required: 20,
remaining: remainingForAlbum,
image: "/images/produit/photoNumerique.jpg",
color: "#4caf50",
link: "{{ path('PackPhotosNumerique_Favoris', {'nbr': 20}) }}",
}
].sort((a, b) => a.remaining - b.remaining);
const productList = products
.map((product) => {
const count = current;
const total = product.required;
const remaining = product.remaining;
return `
<li style="margin-bottom: 15px;">
<div style="display: flex; align-items: center; gap: 10px;">
<img
src="${product.image}"
alt="${product.name}"
style="width: 65px; height: 65px; border-radius: 5px; margin-top:-19px"
/>
<div style="flex: 1;">
<strong style="font-size: 14px;">${product.name}</strong>
${progressBar(count, total, product.color)}
${
remaining > 0
? `<small style="color: ${product.color}; font-size: 12px;">
Encore ${remaining} photos ❤️ pour compléter ${product.name.toLowerCase()}
</small>`
: `<button
style="
margin-top: 5px;
padding: 5px 8px;
background-color: ${product.color};
color: white;
border: none;
border-radius: 5px;
font-size: 12px;
cursor: pointer;
"
onclick="window.location.href='${product.link}'"
>
Commander
</button>`
}
</div>
</div>
</li>
`;
})
.join("");
const plusButton = `
<li style="margin-bottom: 15px; text-align: center;">
<button
style="
padding: 5px 8px;
background-color: #F56040;
color: white;
border: none;
border-radius: 5px;
font-size: 14px;
line-height: 1;
width: 150px;
height: 40px;
cursor: pointer;
"
onclick="window.location.href='{{ path('boutique5sur5') }}'"
>
Aller à la boutique
</button>
</li>
`;
if (current === 0) {
alertContent.innerHTML = `
<p style="font-size: 16px; font-weight: bold; color: #333;">
Vous n'avez pas encore de photos favorites !
</p>
<p style="margin-bottom: 20px; color: #555;">
Commencez à ajouter vos moments préférés pour profiter de nos offres.
</p>
<ul style="list-style-type: none; padding: 0;">${productList}${plusButton}</ul>
`;
} else {
alertContent.innerHTML = `
<p style="font-size: 16px; font-weight: bold; color: #333;">
Vous avez atteint ${current} photos favorites !
</p>
<p style="margin-bottom: 20px; color: #555;">
Profitez de nos offres spéciales :
</p>
<ul style="list-style-type: none; padding: 0;">${productList}${plusButton}</ul>
`;
}
purchaseAlert.classList.remove("hidden");
clearTimeout(purchaseAlertTimeout);
purchaseAlertTimeout = setTimeout(() => {
if (!purchaseAlert.matches(":hover")) {
closePurchaseAlert();
}
}, 5000);
}
// Fonction pour fermer l'alerte
function closePurchaseAlert() {
purchaseAlert.classList.add("hidden");
}
// Événement pour mettre à jour le contenu et afficher la popover dynamiquement au hover
document.querySelector(".fav-button").addEventListener("mouseover", () => {
updatePurchaseAlert(favoriteCount);
purchaseAlert.classList.remove("cachee"); // Réaffiche la popover
});
function showSelection() {
document.getElementById("purchase-alert").style.display = "block";
}
function hideSelection() {
document.getElementById("selectionPopover").style.display = "none";
}
document.addEventListener("DOMContentLoaded", function () {
const container = document.querySelector(".date-container");
// Vérifie si le conteneur existe pour éviter les erreurs
if (container) {
container.scrollTo({
left: container.scrollWidth, // Scroll directement à la position maximale
behavior: "smooth", // Défilement fluide
});
}
});
document.addEventListener("DOMContentLoaded", function () {
const container = document.querySelector(".date-container");
const leftArrow = document.querySelector(".scroll-btn.left");
const rightArrow = document.querySelector(".scroll-btn.right");
// Fonction pour vérifier le débordement et activer/désactiver les flèches
function updateArrowsVisibility() {
const isOverflowing = container.scrollWidth > container.clientWidth; // Vérifie si débordement
leftArrow.style.display = isOverflowing ? "flex" : "none";
rightArrow.style.display = isOverflowing ? "flex" : "none";
}
// Fonction pour défiler
function scrollContainer(direction) {
container.scrollBy({
left: direction === "left" ? -200 : 200, // Défiler à gauche ou à droite
behavior: "smooth",
});
}
// Ajout des événements de clic pour les flèches
leftArrow.addEventListener("click", () => scrollContainer("left"));
rightArrow.addEventListener("click", () => scrollContainer("right"));
// Vérification initiale et sur redimensionnement de la fenêtre
updateArrowsVisibility();
window.addEventListener("resize", updateArrowsVisibility);
});
document.addEventListener("DOMContentLoaded", function () {
const container = document.querySelector(".date-container");
const leftBtn = document.querySelector(".scroll-btn.left");
const rightBtn = document.querySelector(".scroll-btn.right");
leftBtn.addEventListener("click", () => {
container.scrollBy({
left: -200, // Défile vers la gauche
behavior: "smooth",
});
});
rightBtn.addEventListener("click", () => {
container.scrollBy({
left: 200, // Défile vers la droite
behavior: "smooth",
});
});
});
document.addEventListener("DOMContentLoaded", function () {
// Sélectionnez tous les badges de filtre
const filterBadges = document.querySelectorAll(".filter-badge");
// Sélectionnez tous les éléments de la galerie
const galleryItems = document.querySelectorAll(".column");
// Sélectionnez tous les jours
const days = document.querySelectorAll(".collapse");
// Fonction pour réinitialiser les filtres
function resetFilters() {
// Réinitialisez tous les éléments de la galerie
galleryItems.forEach((item) => {
item.style.display = "block";
});
// Réinitialisez les états des badges
filterBadges.forEach((badge) => badge.classList.remove("active"));
}
// Ajoutez un gestionnaire d'événements pour chaque badge
filterBadges.forEach((badge) => {
badge.addEventListener("click", function () {
const filter = this.getAttribute("data-filter");
// Réinitialisez l'état actif pour tous les badges
filterBadges.forEach((btn) => btn.classList.remove("active"));
// Ajoutez l'état actif au badge cliqué
this.classList.add("active");
// Affichez ou masquez les éléments de la galerie
galleryItems.forEach((item) => {
if (filter === "all") {
item.style.display = "block";
} else if (filter === "photo" && item.querySelector("img")) {
item.style.display = "block";
} else if (filter === "video" && item.querySelector("video")) {
item.style.display = "block";
} else if (filter === "audio" && item.classList.contains("audio-message-item")) {
item.style.display = "block";
} else {
item.style.display = "none";
}
});
});
});
// Réinitialiser les filtres lors du changement de jour
days.forEach((day) => {
day.addEventListener("show.bs.collapse", function () {
resetFilters();
});
});
});
$(document).ready(function () {
let zoomCounter = 0; // Initialize zoom counter
let currentImageSrc = ""; // Track current image source
let lastClickPosition = { x: 50, y: 50 }; // Default to center of image
$(".container--gallery").magnificPopup({
delegate: "a",
type: "image",
mainClass: "mfp-with-zoom mfp-img-mobile",
image: {
verticalFit: true,
},
gallery: {
enabled: true,
tPrev: "Previous (Left arrow key)", // Alt text on left arrow
tNext: "Next (Right arrow key)", // Alt text on right arrow
tCounter: "%curr% of %total%", // Markup for "1 of 7" counter
},
zoom: {
enabled: true,
duration: 300,
opener: function (element) {
return element.find("img");
},
},
callbacks: {
open: function () {
// Get current image data from the link that was clicked
const currentLink = this.currItem.el;
const imageId =
currentLink
.closest(".photo-zoom")
.find(".heart-icon")
.data("id") || "";
const sejourId =
currentLink
.closest(".photo-zoom")
.find(".heart-icon")
.data("sejour-id") || "";
const imagePath =
currentLink
.closest(".photo-zoom")
.find(".heart-icon")
.data("path") || "";
const imageDesc =
currentLink
.closest(".photo-zoom")
.find(".heart-icon")
.data("description") || "";
const isFavorite = currentLink
.closest(".photo-zoom")
.find(".heart-icon i")
.hasClass("bi-heart-fill");
const favoriteIconClass = isFavorite ? "bi-heart-fill" : "bi-heart";
const favoriteIconColor = isFavorite ? "#f56040" : "white";
const favoriteTooltip = isFavorite
? "Retirer des favoris"
: "Ajouter aux favoris";
const zoomControls = `
<div class="mfp-zoom-controls">
<button class="zoom-btn zoom-out" title="Zoom Out"><i class="fa fa-search-minus"></i></button>
<button class="zoom-btn zoom-in" title="Zoom In"><i class="fa fa-search-plus"></i></button>
</div>
<div class="mfp-favorite">
<button class="favorite-btn"
data-id="${imageId}"
data-sejour-id="${sejourId}"
data-path="${imagePath}"
data-description="${imageDesc}"
title="${favoriteTooltip}">
<i class="bi ${favoriteIconClass}" style="color: ${favoriteIconColor}; text-shadow: 0px 0px 3px rgba(0,0,0,0.5);"></i>
</button>
</div>
<div class="mfp-counter"></div>
`;
$(".mfp-content").append(zoomControls);
initializeZoomControls();
initializeFavoriteButton();
const intervalId = setInterval(() => {
const newImageSrc = $(".mfp-img").attr("src");
if (newImageSrc !== currentImageSrc) {
currentImageSrc = newImageSrc;
zoomCounter = 0;
lastClickPosition = { x: 50, y: 50 }; // Reset to center
attachZoomHandler(); // Reattach zoom handler to new image
$(".mfp-img").css({
"transform-origin": `${lastClickPosition.x}% ${lastClickPosition.y}%`,
transform: `scale(1)`,
});
// Update favorite button for the new image
updateFavoriteButton();
initializeZoomControls();
updateCounter();
}
}, 100);
this.content.on("mfpClose", function () {
clearInterval(intervalId);
});
attachZoomHandler();
},
close: function () {
$(".mfp-zoom-controls").remove();
$(".mfp-favorite").remove();
$(".mfp-counter").remove();
zoomCounter = 0;
},
},
});
function attachZoomHandler() {
$(".mfp-img")
.off("click")
.on("click", function (event) {
event.stopPropagation(); // Prevent default navigation behavior
// Calculate click coordinates relative to the image
const imgOffset = $(this).offset();
const clickX = event.pageX - imgOffset.left;
const clickY = event.pageY - imgOffset.top;
const imgWidth = $(this).width();
const imgHeight = $(this).height();
// Calculate transform-origin based on click position
lastClickPosition = {
x: (clickX / imgWidth) * 100,
y: (clickY / imgHeight) * 100,
};
// Cycle through zoom levels: 1x, 1.5x, 2x
zoomCounter = (zoomCounter + 1) % 3;
const zoomLevels = [1, 1.5, 2];
const zoomLevel = zoomLevels[zoomCounter];
$(this).css({
"transform-origin": `${lastClickPosition.x}% ${lastClickPosition.y}%`,
transform: `scale(${zoomLevel})`,
});
updateZoomButtonState();
});
}
function initializeZoomControls() {
$(".mfp-zoom-controls .zoom-in")
.off("click")
.on("click", function (event) {
event.stopPropagation();
zoomCounter = (zoomCounter + 1) % 3;
const zoomLevels = [1, 1.5, 2];
const zoomLevel = zoomLevels[zoomCounter];
$(".mfp-img").css({
"transform-origin": `${lastClickPosition.x}% ${lastClickPosition.y}%`,
transform: `scale(${zoomLevel})`,
});
updateZoomButtonState();
});
$(".mfp-zoom-controls .zoom-out")
.off("click")
.on("click", function (event) {
event.stopPropagation();
if (zoomCounter > 0) {
zoomCounter -= 1;
const zoomLevels = [1, 1.5, 2];
const zoomLevel = zoomLevels[zoomCounter];
$(".mfp-img").css({
"transform-origin": `${lastClickPosition.x}% ${lastClickPosition.y}%`,
transform: `scale(${zoomLevel})`,
});
updateZoomButtonState();
} else {
$.magnificPopup.close();
}
});
}
function initializeFavoriteButton() {
$(".mfp-favorite .favorite-btn")
.off("click")
.on("click", function (event) {
event.stopPropagation();
const $this = $(this);
const imageId = $this.data("id");
const sejourId = $this.data("sejour-id");
// Toggle favorite status
const isFavorite = $this.find("i").hasClass("bi-heart-fill");
// Update the button appearance
if (isFavorite) {
$this
.find("i")
.removeClass("bi-heart-fill")
.addClass("bi-heart")
.css("color", "white");
$this.attr("title", "Ajouter aux favoris");
} else {
$this
.find("i")
.removeClass("bi-heart")
.addClass("bi-heart-fill")
.css("color", "#f56040");
$this.attr("title", "Retirer des favoris");
}
// Update the original heart icon in the gallery
const originalHeartIcon = $(
`.heart-icon[data-id="${imageId}"]`
).find("i");
if (isFavorite) {
originalHeartIcon
.removeClass("bi-heart-fill")
.addClass("bi-heart")
.css("color", "");
} else {
originalHeartIcon
.removeClass("bi-heart")
.addClass("bi-heart-fill")
.css("color", "#f56040");
}
// Make AJAX call to update favorite status in the backend using Parent routes
$.ajax({
url: isFavorite ? "/Parent/aSupprimerFav" : "/Parent/ajouterFav",
type: "POST",
data: {
id: imageId,
idSejour: sejourId,
},
success: function (response) {
// Optional: Show a success message or handle response
console.log("Favorite status updated", response);
},
error: function (error) {
console.error("Error updating favorite status", error);
// Revert the icon change on error
if (isFavorite) {
$this
.find("i")
.removeClass("bi-heart")
.addClass("bi-heart-fill")
.css("color", "#f56040");
originalHeartIcon
.removeClass("bi-heart")
.addClass("bi-heart-fill")
.css("color", "#f56040");
} else {
$this
.find("i")
.removeClass("bi-heart-fill")
.addClass("bi-heart")
.css("color", "white");
originalHeartIcon
.removeClass("bi-heart-fill")
.addClass("bi-heart")
.css("color", "");
}
},
});
});
}
function updateFavoriteButton() {
// Get current image data from the current slide
const currentSlide = $.magnificPopup.instance.currItem.el;
const photoZoom = currentSlide.closest(".photo-zoom");
if (photoZoom.length) {
const heartIcon = photoZoom.find(".heart-icon");
const imageId = heartIcon.data("id") || "";
const sejourId = heartIcon.data("sejour-id") || "";
const imagePath = heartIcon.data("path") || "";
const imageDesc = heartIcon.data("description") || "";
const isFavorite = heartIcon.find("i").hasClass("bi-heart-fill");
const favoriteIconClass = isFavorite ? "bi-heart-fill" : "bi-heart";
const favoriteIconColor = isFavorite ? "#f56040" : "white";
const favoriteTooltip = isFavorite
? "Retirer des favoris"
: "Ajouter aux favoris";
// Update the favorite button
const $favoriteBtn = $(".mfp-favorite .favorite-btn");
$favoriteBtn.data("id", imageId);
$favoriteBtn.data("sejour-id", sejourId);
$favoriteBtn.data("path", imagePath);
$favoriteBtn.data("description", imageDesc);
$favoriteBtn.attr("title", favoriteTooltip);
$favoriteBtn
.find("i")
.removeClass("bi-heart bi-heart-fill")
.addClass(favoriteIconClass)
.css("color", favoriteIconColor);
}
}
function updateZoomButtonState() {
const zoomLevels = [1, 1.5, 2];
const currentZoom = zoomLevels[zoomCounter];
$(".zoom-in").prop("disabled", currentZoom === 2);
$(".zoom-out").prop("disabled", currentZoom === 1);
}
function updateCounter() {
const counterText = $(".mfp-counter")
.closest(".mfp-content")
.find(".mfp-counter")
.text();
const matches = counterText.match(/(\d+) of (\d+)/);
if (matches) {
const currentIndex = matches[1];
const totalImages = matches[2];
$(".mfp-counter").text(`${currentIndex} of ${totalImages}`);
}
}
// Add CSS for the favorite button and rounded image corners
$("<style>")
.prop("type", "text/css")
.html(
`
.mfp-favorite {
position: absolute;
top: 15px;
left: 15px;
z-index: 1046;
}
.favorite-btn {
background: transparent;
border: none;
font-size: 24px;
padding: 5px;
cursor: pointer;
outline: none;
}
.favorite-btn i {
transition: all 0.3s ease;
}
.favorite-btn:hover i {
transform: scale(1.2);
}
/* Rounded corners for zoomed images */
.mfp-img {
border-radius: 8px;
}
/* Make sure the container doesn't clip the rounded corners */
.mfp-figure:after {
border-radius: 8px;
}
`
)
.appendTo("head");
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function () {
const openBtn = document.getElementById('openFavoritesBtn');
const closeBtn = document.getElementById('closeSidebarBtn');
const sidebar = document.getElementById('favoritesSidebar');
const tbody = document.querySelector('#favoritesTable tbody');
openBtn.addEventListener('click', async () => {
try {
const response = await fetch('/Parent/mes-favoris', {
headers: {
'Accept': 'application/json'
}
});
const result = await response.json();
if (!result.success || !Array.isArray(result.data)) {
alert('Erreur lors du chargement des favoris.');
return;
}
tbody.innerHTML = '';
result.data.forEach((fav, index) => {
const row = document.createElement('tr');
row.innerHTML = `
<td>${index + 1}</td>
<td><img src="${fav.path}" alt="favori"></td>
<td>${fav.descreption || '—'}</td>
<td>${fav.created_at}</td>
`;
tbody.appendChild(row);
});
sidebar.classList.add('active');
} catch (e) {
console.error('Erreur réseau:', e);
alert('Impossible de charger les favoris.');
}
});
closeBtn.addEventListener('click', () => {
sidebar.classList.remove('active');
});
});
</script>
<script>
// Fonction pour vérifier et afficher l'alerte
function checkFavorites() {
if (favoriteCount >= 10) {
purchaseAlert.style.display = 'block'; // Affiche l'alerte
} else {
purchaseAlert.style.display = 'none'; // Cache l'alerte si le nombre est réduit
}
}
// Ajout d'un favori
function addFavorite() {
favoriteCount++;
likeCountLabel.textContent = favoriteCount;
checkFavorites();
}
// Suppression d'un favori
function removeFavorite() {
if (favoriteCount > 0) {
favoriteCount--;
likeCountLabel.textContent = favoriteCount;
checkFavorites();
}
}document.addEventListener('DOMContentLoaded', () => {
const favoriteCount = {{ nblikes }};
updateCardContent(favoriteCount);
});
function updateCardContent(favoriteCount) {
const card = document.getElementById('dynamic-card');
const cardContent = document.getElementById('dynamic-card-content');
let produits = [];
if (favoriteCount >= 20) {
produits.push({
titre: "Album débloqué !",
bouton: "Commander",
image: "/images/produit/Album5sur5-3.jpg",
lien: "{{ path('EditionAlbum') }}"
});
}
if (favoriteCount >= 12) {
produits.push({
titre: "Pochette débloquée !",
bouton: "Commander",
image: "/images/produit/PochettePhoto5sur5-2.jpg",
lien: "{{ path('AjoutPochettePhotos_Favoris', {'nbr': 12}) }}"
});
}
if (favoriteCount >= 5) {
produits.push({
titre: "Pack numérique débloqué !",
bouton: "Commander",
image: "/images/produit/photoNumerique.jpg",
lien: "{{ path('PackPhotosNumerique_Favoris', {'nbr': 15}) }}"
});
}
if (produits.length === 0) {
cardContent.innerHTML = `
<div style="text-align: center; padding: 10px;">
Ajoutez des favoris pour débloquer des surprises ✨
</div>
`;
return;
}
cardContent.innerHTML = `
<div class="splide" id="dynamicSplide">
<div class="splide__track">
<ul class="splide__list">
${produits.map(produit => `
<li class="splide__slide" style="position: relative;">
<img src="${produit.image}" alt="${produit.titre}" style="width: 100%; height: 150px; object-fit: cover; border-radius: 8px;">
<div style="position: absolute; bottom: 0; left: 0; right: 0; background: rgba(0,0,0,0.1); color: white; padding: 10px; text-align: center; border-bottom-left-radius: 8px; border-bottom-right-radius: 8px;">
<div style="font-weight: bold; font-size: 14px;">${produit.titre}</div>
<button style="margin-top: 5px; padding: 5px 8px; background-color: #F56040; color: white; border: none; border-radius: 4px; font-size: 12px; cursor: pointer;" onclick="window.location.href='${produit.lien}'">
${produit.bouton}
</button>
</div>
</li>
`).join('')}
</ul>
</div>
</div>
`;
// Monte le carrousel
new Splide('#dynamicSplide', {
type: 'loop',
arrows: true,
pagination: false,
autoplay: true,
interval: 4000,
speed: 800,
}).mount();
}
function supprimerFavoris($id, $idSejour) {
// Vider l'élément coeur pour ce favori
const coeurElement = $('#coeur' + $id);
coeurElement.empty();
// Ajout d'une animation sur le bouton favori
const favoriteButton = document.querySelector('.fav-button');
if (favoriteButton) {
favoriteButton.classList.add('active');
// Retirer l'animation après qu'elle soit jouée
setTimeout(() => {
favoriteButton.classList.remove('active');
}, 600); // La durée doit correspondre à celle de l'animation
}
// Mise à jour de l'icône coeur
const clas = $('.IconImag6').hasClass('active') ? "IconDelete IconDeletesix" : "IconDelete";
coeurElement.html(
`<i class="bi bi-heart ${clas}" onclick="AddFavoris(${$id}, ${$idSejour})"></i>`
);
// Mettre à jour le compteur des favoris
const likeCountLabel = document.getElementById('likeCount');
const likeMesFavLabel = document.getElementById('mesFavCount');
if (likeMesFavLabel) {
let currentCount = parseInt(likeMesFavLabel.textContent.trim(), 10) || 0;
currentCount = Math.max(0, currentCount - 1); // Empêche le compteur d'aller en dessous de 0
likeMesFavLabel.textContent = currentCount;
}
if (likeCountLabel) {
let currentCount = parseInt(likeCountLabel.textContent.trim(), 10) || 0;
currentCount = Math.max(0, currentCount - 1); // Empêche le compteur d'aller en dessous de 0
likeCountLabel.textContent = currentCount;
// Mettre à jour la valeur dans l'input hidden
const nbFavCurrentInput = $('#nbFavCurrent');
if (nbFavCurrentInput.length) {
nbFavCurrentInput.val(currentCount);
}
}
// Préparation des données pour l'Ajax
const $_data = { 'id': $id, 'idSejour': $idSejour };
// Appel Ajax pour supprimer le favori
$.ajax({
type: "POST",
url: "{{ path('Supprimer_fav') }}",
data: $_data,
success: function () {
// Réactiver les icônes après succès
$('.IconDelete').each(function () {
$(this).css('pointer-events', '');
});
},
error: function (xhr, status, error) {
console.error('Erreur lors de la suppression du favori :', error);
}
});
}
function AddFavoris($id, $idSejour, $urlimg, $description) {
// console.log('Adding favorite:', { attachmentId, sejourId, path, description });
$("#close-favorites-btn").click()
favoriteButton.classList.add('active');
const likeMesFavLabel = document.getElementById('mesFavCount');
const likeCountLabel = document.getElementById('likeCount');
if (likeCountLabel) {
let currentCount = parseInt(likeCountLabel.textContent.trim(), 10) || 0;
likeCountLabel.textContent = currentCount + 1;
likeMesFavLabel.textContent = currentCount + 1;
}
// Retirer l'animation après qu'elle soit jouée
setTimeout(() => {
favoriteButton.classList.remove('active');
}, 600); // La durée doit correspondre à celle de l'animation
$('#coeur' + $id).empty();
var clas = $('.IconImag6').hasClass('active') ? "IconDelete IconDeletesix" : "IconDelete";
$('#coeur' + $id).html("<i class=\"bi bi-heart-fill favSelect " + clas + "\" onclick=\"supprimerFavoris(" + $id + "," + $idSejour + ")\"></i>");
var $total = parseInt($("#totalLike").html()) + 1;
$("#totalLike").html($total);
$("#totalLikeTitle").html($total);
$("#totalLikeMobile").html($total);
var $data = { 'id': $id, 'idSejour': $idSejour };
$.ajax({
type: "POST",
url: "{{ path('Ajouter_fav') }}",
data: $data,
success: function () {
$('.IconDelete').each(function () {
$(this).css('pointer-events', '');
});
if ($description === undefined) {
$description = ''; // Set it to an empty string
}
$('.rowMaselection').append(
'<div class="column" id="column-' + $id + '">'+
'<a style="position: relative;" title="Enlever de ma sélection" onclick="supprimerFavoris(' + $id + ',' + $idSejour + ')" class="iconeSuppImg"><i class="bi bi-x" style="font-size:17px;cursor:pointer;color:#d30909;float:right;margin-top:-3%;margin-right:2%"></i></a>'+
'<a class="photo-zoom">'+
'<img data-idAtach="'+$id+'" id="'+$idSejour+'" src="'+$urlimg+'"></a>'+
($description ? '<h4 id="commint" class="titleHeadPhoto">'+$description+'</h4>' : '')+ // Only add the <h4> if $description is not empty
'</div>'
);
// Directly update nbLikes count in the header
var currentNbLikes = parseInt($('#favoris-link-Accueilpayment .nbrpanier').text());
var newNbLikes = currentNbLikes + 1;
$('#favoris-link-Accueilpayment .nbrpanier').text(newNbLikes);
},
error: function (xhr, status, error) {
console.error('Error:', error);
}
});
}
$(document).on('click', '.bi-heart, .bi-heart-fill', function () {
const heartIcon = $(this);
const heartContainer = heartIcon.closest('.heart-icon');
// Extract data attributes
const attachmentId = heartContainer.data('id');
const sejourId = heartContainer.data('sejour-id');
const path = heartContainer.data('path');
const description = heartContainer.data('description');
const isFavorite = heartIcon.hasClass('bi-heart-fill');
// Get the input that contains the favorite count
const likeFavInput = document.getElementById('nbFavCurrent');
let favoriteNb = parseInt(likeFavInput.value, 10);
if (isFavorite) {
// Remove from favorites
supprimerFavoris(attachmentId, sejourId);
favoriteNb = Math.max(0, favoriteNb - 1);
likeFavInput.value = favoriteNb;
updateCardContent(favoriteNb);
updateFavoritesSidebar();
$("#close-favorites-btn").click()
} else {
// Add to favorites
AddFavoris(attachmentId, sejourId, path, description);
favoriteNb = favoriteNb + 1;
likeFavInput.value = favoriteNb;
updateCardContent(favoriteNb);
updateFavoritesSidebar();
$("#close-favorites-btn").click()
}
// **** SIMPLE STEP: Update the purchase alert ****
// This will refresh the progress bars, count, etc.
updatePurchaseAlert(favoriteNb);
});
// Gestion dynamique du clic sur les icônes cœur
$(document).on('click', '.bi-hsddddeart, .bi-hdddeart-fill', function () {
const heartIcon = $(this);
// const heartIcon = $(this);
//const attachmentId = heartIcon.data('id'); // Récupère l'ID directement
const attachmentId = heartIcon.closest('.heart-icon').attr('id').replace('coeur', '');
const sejourId = heartIcon.data('sejour-id'); // Store the sejour ID in a data attribute
const isFavorite = heartIcon.hasClass('bi-heart-fill');
// Récupérer l'input contenant le nombre de favoris
const likeFavInput = document.getElementById('nbFavCurrent');
let favoriteNb = parseInt(likeFavInput.value, 10); // Utiliser .value pour les inputs
// Validation pour éviter les NaN
if (isNaN(favoriteNb)) {
favoriteNb = 0;
}
if (isFavorite) {
// Si c'est un favori, le supprimer
supprimerFavoris(attachmentId, sejourId);
// Décrémenter le compteur
favoriteNb = Math.max(0, favoriteNb - 1);
likeFavInput.value = favoriteNb; // Mettre à jour la valeur de l'input
// Mettre à jour dynamiquement le contenu des cartes ou popovers
updateCardContent(favoriteNb);
} else {
// Si ce n'est pas un favori, l'ajouter
const path = heartIcon.data('path'); // Path de l'attachement
const description = heartIcon.data('description'); // Description de l'attachement
AddFavoris(attachmentId, sejourId, path, description);
// Décrémenter le compteur
favoriteNb = Math.max(0, favoriteNb + 1);
likeFavInput.value = favoriteNb; // Mettre à jour la valeur de l'input
// Incrémenter le compteur
// Mettre à jour dynamiquement le contenu des cartes ou popovers
updateCardContent(favoriteNb);
}
// Mettre à jour dynamiquement la popover ou d'autres éléments liés
});
// Ajoutez les événements sur les icônes de cœur
document.querySelectorAll('.IconDelete').forEach((icon) => {
icon.addEventListener('click', (event) => {
const isFavorite = icon.classList.contains('bi-heart-fill');
if (isFavorite) {
removeFavorite();
icon.classList.remove('bi-heart-fill');
icon.classList.add('bi-heart');
} else {
addFavorite();
icon.classList.remove('bi-heart');
icon.classList.add('bi-heart-fill');
}
});
});
// Vérifie l'état initial
checkFavorites();
</script>
<!-- Initialisation -->
<script>
AOS.init({
duration: 800, // Duration of animations in milliseconds
easing: "ease-in-out", // Animation timing function
});
document.addEventListener("DOMContentLoaded", function () {
const dateCards = document.querySelectorAll(".date-card");
const sections = document.querySelectorAll(".collapse");
dateCards.forEach((card) => {
card.addEventListener("click", function () {
// Supprimer les classes actives des autres cartes et sections
dateCards.forEach((c) => c.classList.remove("active"));
sections.forEach((s) => s.classList.remove("show"));
// Ajouter la classe active à la carte cliquée
this.classList.add("active");
// Récupérer la cible et afficher la bonne section
const targetId = this.getAttribute("data-bs-target");
const targetSection = document.querySelector(targetId);
if (targetSection) {
targetSection.classList.add("show");
}
});
});
});
document.addEventListener("DOMContentLoaded", function () {
// Initialisation du carrousel Splide
var splide = new Splide("#imageSlider", {
type: "loop",
perPage: 1,
autoplay: true,
interval: 6000,
pauseOnHover: false,
pauseOnFocus: false,
pagination: false, // Désactive la pagination
arrows: false,
});
splide.mount();
// Fonction pour faire défiler automatiquement vers la section suivante avec un ajustement personnalisé de la hauteur
function scrollToNextSection() {
const targetSection = document.getElementById("scrollTarget");
if (targetSection) {
const targetPosition =
targetSection.getBoundingClientRect().top + window.scrollY; // Position de la section
const adjustedPosition = targetPosition - 50; // Réduit la hauteur du scroll de 150px (ajustez selon vos besoins)
// Scroll vers la position ajustée
window.scrollTo({
top: adjustedPosition,
behavior: "smooth",
});
}
}
// Démarrer le timer pour le scroll automatique après 10 secondes
setTimeout(scrollToNextSection, 5000); // 10 secondes
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function () {
var myModal = new bootstrap.Modal(document.getElementById('PubProd'));
myModal.show();
});
// Function to close the modal
function closeModal() {
var myModal = bootstrap.Modal.getInstance(document.getElementById('PubProd'));
if (myModal) {
myModal.hide();
}
}
const favoriteButton = document.querySelector('.fav-button');
favoriteButton.addEventListener('click', () => {
// Ajouter la classe 'active' pour déclencher l'éclat
favoriteButton.classList.add('active');
// Retirer l'animation après qu'elle soit jouée
setTimeout(() => {
favoriteButton.classList.remove('active');
}, 600); // La durée doit correspondre à celle de l'animation
});
//const HeartAddButton = document.querySelector('.IconDelete');
$(".IconDelete").on('click', () => {
// Ajouter la classe 'active' pour déclencher l'éclat
favoriteButton.classList.add('active');
// Retirer l'animation après qu'elle soit jouée
setTimeout(() => {
favoriteButton.classList.remove('active');
}, 600); // La durée doit correspondre à celle de l'animation
});
$(document).ready(function() {
// Attach click event to collapse triggers
const lastCard = $('.date-card.modern-card.active');
const lastTargetId = lastCard.attr('data-bs-target');
if (lastTargetId) {
$(lastTargetId).collapse('show'); // Expand the last collapse section
LoadImagesCloud($(lastTargetId)); // Load images for the last day
}
$('[data-bs-toggle="collapse"]').on('click', function() {
var targetId = $(this).attr('data-bs-target'); // Get the target ID
$('.date-card.modern-card').removeClass('active'); // Remove 'active' class from all cards
$(this).addClass('active'); // Add 'active' class to the clicked card
LoadImagesCloud($(targetId)); // Ensure this function works as expected
// Hide all other collapses except the one clicked
$('[data-bs-target]').each(function() {
var currentTargetId = $(this).attr('data-bs-target');
// If the current collapse is not the one clicked, hide it
if (currentTargetId !== targetId) {
$(currentTargetId).collapse('hide');
//$('[data-bs-toggle="collapse"]').removeClass('active'); // Remove active class from all cards
//Modifier leurs style en non active aussi
}
});
});
});
function rotateIcone(iconId) {
// Use the icon ID to target the specific element
var icon = $('#' + iconId);
// Toggle the rotate-right class to apply rotation
if (icon.hasClass('rotate-right')) {
icon.removeClass('rotate-right'); // Remove rotation class
} else {
icon.addClass('rotate-right'); // Add rotation class
}
}
$(document).ready(function () {
$total1 = parseInt($("#esphoto").find('strong').html().replace('(', '').replace(')', ''));
$('[data-bs-toggle="tooltip"]').tooltip();
{% if app.session.get("paymentmoniteco") %}
{% if app.session.get("paymentmoniteco") == "succses" %}
Swal.fire({
icon: 'success',
title: ' succès ',
text: 'votre commande est validée'
});
{% endif %}
{% endif %}
if ($total1 > 0) {
$('.iconeFleche').first().click();
// $([document.documentElement, document.body]).animate({
// scrollTop: $('.iconeFleche').last().offset().top
// }, );
}
else {
$(window).scrollTop(0);
}
var slider = $('.responsive').slick({
infinite: true,
slidesToShow: 1,
slidesToScroll: 1,
autoplay: true,
autoplaySpeed: 4000,
pauseOnFocus: false,
pauseOnHover: false,
draggable: false,
fade: true
});
$('.responsive').css('display', 'block');
$('.namePRD').css('display', 'block');
var currSlide = 0;
var nextSlide = 0;
slider.on('afterChange', function (event, slick, currentSlide) {
console.log(typeof ($('.slick-active .slick-current').find('.imgproduit2')) != "undefined");
if (typeof ($('.slick-active .slick-current').find('.imgproduit2')) != "undefined") {
setTimeout(function () {
$('.slick-active .imgproduit1').removeClass('animated fadeIn');
$('.slick-active .imgproduit1').addClass('animated fadeOut');
$('.slick-active .imgproduit1').css('display', 'none');
$('.slick-active .imgproduit2').css('display', 'block');
$('.slick-active .imgproduit2').removeClass('animated fadeOut');
$('.slick-active .imgproduit2').addClass('animated fadeIn');
}, 2000);
}
});
slider.on('beforeChange', function (event, slick, currentSlide, nextSlide) {
currSlide = currentSlide;
$('.imgproduit2').each(function () {
$(this).removeClass('animated fadeIn');
$(this).addClass('animated fadeOut');
$(this).css('display', 'none');
});
$('.imgproduit1').each(function () {
$(this).css('display', 'block');
$(this).removeClass('animated fadeOut');
$(this).addClass('animated fadeIn');
});
});
$('.columnPub').each(function () {
$(this).slick({
infinite: true,
speed: 50,
fade: true,
slidesToShow: 1,
slidesToScroll: 1,
autoplay: true,
pauseOnFocus: false,
pauseOnHover: false,
draggable: false
});
$(this).css('display', 'block');
});
$("#offrePack").click();
{%if app.user.showpubprod != 'false' %}
$('#btnPubProd').click();
$('.modal-backdrop').css('background-color', 'rgba(0, 0, 0, 0.2)');
{% endif %}
});
$("#closeImage").click(function () {
$('#myModalImage').css('display', "none");
});
$.ajax({
type: "POST",
url: "{{ path("delateSession_parent") }}",
success: function () { }
});
function afficheDiv(elem) {
$('.nav-link').each(function () {
$(this).removeClass('active');
});
elem.addClass('active');
if (elem.attr('id') === "esphoto" || elem.attr('id') === "esphotoMobile") {
$("#espacphoto").show();
$("#espacemessage").hide();
$("#espaceMa_selection").hide();
pageMenu = 'MonSejour'
$(this).addClass('active');
$('#imageActifphoto').css('display', 'block');
$('#imagenoActifphoto').css('display', 'none');
$('#VocalActivee').css('display', 'none');
$('#noActifVocal').css('display', 'block');
}
if (elem.attr('id') === "esmessage" || elem.attr('id') === "esmessageMobile") {
$("#espacphoto").hide();
$("#espaceMa_selection").hide();
$("#espacemessage").show();
pageMenu = 'BoiteVocale'
$("#espaceMa_selection").hide();
$(this).addClass('active');
$('#imageActifphoto').css('display', 'none');
$('#imagenoActifphoto').css('display', 'block');
$('#VocalActivee').css('display', 'block');
$('#noActifVocal').css('display', 'none');
}
if (elem.attr('id') === "esselection" || elem.attr('id') === "esselectionMobile") {
$("#espacphoto").hide();
$("#espacemessage").hide();
$("#espaceMa_selection").show();
$(homeNavmob).removeClass('bi bi-house-door-fill');
$(homeNavmob).addClass('bi bi-house-door');
$(micromob).removeClass('bi bi-mic-fill');
$(micromob).addClass('bi bi-mic');
$(selecNavmob).removeClass('bi bi-heart');
$(selecNavmob).addClass('bi bi-heart-fill');
}
}
function LoadImagesCloud($element) {
$element.find('.photo-zoom img').each(function ($this) {
if ($(this).attr('data-src') != $(this).attr('src')) {
$(this).attr('src', $(this).attr('data-src'));
}
});
}
function afficheDivFooterMobile(elem) {
if(elem =='esphotoMobile') {
$("#espacphoto").show();
$("#espacemessage").hide();
$("#espaceMa_selection").hide();
$("#storevide").hide();
$("#storefull").show();
$("#fullphoto").show();
$("#videphoto").hide()
$("#vocalfull").hide();
$("#vocalvide").show();
}
if (elem === "esmessageMobile" ) {
$("#espacphoto").hide();
$("#espacemessage").show();
$("#espaceMa_selection").hide();
$("#storefull").hide();
$("#storevide").show();
$("#fullphoto").hide();
$("#videphoto").show()
$("#vocalfull").show();
$("#vocalvide").hide();
}
}
function permutation(elem) {
$(".IconImag").each(function () {
$(this).removeClass('active');
});
elem.addClass("active");
}
function per(elem) {
$(".list-group-item ").each(function () {
$(this).removeClass('show');
});
elem.addClass("active");
$("#iconeFleche").addClass('active');
}
function setidattach(id) {
$("#idattachipmut").val(id)
}
var ParentAjouterALL_fav = "{{ path('ParentAjouterALL_fav') }}";
function AllFavoris($idSejour) {
$('#SelectALL').html('Désélectionner tout');
$('#SelectALL').css('pointer-events', 'none');
$('#SelectALL').css('opacity', '0.5');
$('#SelectALL').css('cursor', 'no-drop');
$('#SelectALL1').html('Désélectionner tout');
$('#SelectALL1').css('pointer-events', 'none');
$('#SelectALL1').css('opacity', '0.5');
$('#SelectALL1').css('cursor', 'no-drop');
$data = { 'idSejour': $idSejour }
$.ajax({
type: "POST",
url: "{{ path('ParentAjouterALL_fav') }}",
data: $data,
success: function () {
location.reload();
}
});
}
function RemoveAllFavoris($idSejour) {
$('#SelectALL').html('Sélectionner tout');
$('#SelectALL').css('pointer-events', 'none');
$('#SelectALL').css('opacity', '0.5');
$('#SelectALL').css('cursor', 'no-drop');
$('#SelectALL1').html('Sélectionner tout');
$('#SelectALL1').css('pointer-events', 'none');
$('#SelectALL1').css('opacity', '0.5');
$('#SelectALL1').css('cursor', 'no-drop');
$data = { 'idSejour': $idSejour }
$.ajax({
type: "POST",
url: "{{ path('ParentSupprimer_ALLfav') }}",
data: $data,
success: function () {
location.reload();
}
});
}
// Get the elements with class="column"
var elements = document.getElementsByClassName("column");
// Declare a "loop" variable
var i;
// Full-width images
function Four() {
for (i = 0; i < elements.length; i++) {
elements[i].style.flex = "0 0 25%";
}
$('.IconDelete').attr('class', 'IconDelete ');
$('.photo-zoom ').attr('class', 'photo-zoom');
$('.localistaion').css('visibility', 'visible');
$('.localistaion').attr('class', 'localistaion');
$('.legend').css('visibility', 'visible');
$('.columnPub').each(function () {
$(this).css('max-width', '25%');
$(this).find('.slick-list').removeClass('miniature');
$(this).find('.single_service').removeClass('miniature');
$(this).find('.bottomdivpub').removeClass('miniature');
});
}
// Two images side by side
function six() {
for (i = 0; i < elements.length; i++) {
elements[i].style.flex = "0 0 15%";
}
$('.column').css('padding', '0px 10px 0px 0px');
$('.localistaion').attr('class', 'localistaion localistaionsix');
$('.IconDelete').attr('class', 'IconDelete IconDeletesix');
$('.legend').css('visibility', 'visible');
$('.photo-zoom ').attr('class', 'photo-zoom heightimg');
$('.columnPub').each(function () {
$(this).css('max-width', '15%');
$(this).find('.slick-list').addClass('miniature');
$(this).find('.single_service').addClass('miniature');
$(this).find('.bottomdivpub').addClass('miniature');
});
}
// Four images side by side
function two() {
for (i = 0; i < elements.length; i++) {
elements[i].style.flex = "0 0 40%";
}
$('.column').css('padding', '14px 10px');
$('.column').css('max-width', '40%');
$('.localistaion').css('visibility', 'visible');
$('.legend').css('visibility', 'visible');
$('.photo-zoom ').attr('class', 'photo-zoom');
$('.localistaion').attr('class', 'localistaion localistaiontwo');
$('.IconDelete').attr('class', 'IconDelete IconDeletetwo');
$('.legend').attr('class', 'legend legendtwo');
$('.columnPub').each(function () {
$(this).css('max-width', '40%');
$(this).find('.slick-list').removeClass('miniature');
$(this).find('.single_service').removeClass('miniature');
$(this).find('.bottomdivpub').removeClass('miniature');
});
}
function hidePopPub() {
$('.modal-backdrop').css('background-color', 'rgb(0, 0, 0)');
}
function changeHref(elem, newhref) {
$(elem).parent().attr('href', newhref);
}
function VerifNbLikes(nblikes) {
$('#allerAlaBoutique').click();
}
function handleMenuClick(menuId, pageMenu) {
// Reset all icons
document.getElementById('imagenoActifphoto').style.display = 'block';
document.getElementById('imageActifphoto').style.display = 'none';
document.getElementById('nofavorisVocal').style.display = 'block';
document.getElementById('favorisActive').style.display = 'none';
document.getElementById('noActifVocal').style.display = 'block';
document.getElementById('VocalActivee').style.display = 'none';
// Set selected icon
if (menuId === 'photo') {
document.getElementById('imagenoActifphoto').style.display = 'none';
document.getElementById('imageActifphoto').style.display = 'block';
} else if (menuId === 'selection') {
document.getElementById('nofavorisVocal').style.display = 'none';
document.getElementById('favorisActive').style.display = 'block';
} else if (menuId === 'message') {
document.getElementById('noActifVocal').style.display = 'none';
document.getElementById('VocalActivee').style.display = 'block';
}
// Handle any other necessary logic
$('#list-tab-photo').removeClass('show');
$('#list-tab-message').removeClass('show');
afficheDiv($(`#${menuId}`));
}
</script>
<script>
$(document).ready(function () {
$("#PubProd").on("hidden.bs.modal", function () {
$(document).trigger("modalClosed");
});
});
</script>
<script>
$(document).ready(function () {
$("#noShow").on("change", function () {
if ($(this).is(":checked")) {
$.ajax({
url: "/Parent/showpub",
type: "POST",
dataType: "json",
success: function (response) {
if (response.status === "success") {
console.log("User showpubprod updated successfully.");
} else {
console.log("Error:", response.message);
}
},
error: function (xhr, status, error) {
console.log("AJAX Error:", error);
},
});
}
});
});
</script>
</div>
<!-- Script pour la sidebar des favoris -->
<script>
$(document).ready(function() {
// Ouvrir la sidebar
$("#openFavoritesSidebar").click(function() {
$(".favorites-sidebar").addClass("open");
loadFavorites();
});
// Fermer la sidebar
$(".favorites-close").click(function() {
$(".favorites-sidebar").removeClass("open");
});
// Charger les favoris
function loadFavorites() {
$.ajax({
url: "/Parent/mes-favoris",
type: "GET",
dataType: "json",
beforeSend: function() {
$("#favorites-grid").html("<div style='text-align:center'>Chargement...</div>");
},
success: function(data) {
$("#favorites-grid").empty();
if (data.data && data.data.length > 0) {
$("#favorites-empty-state").hide();
$.each(data.data, function(i, fav) {
var item = $("<div class='favorite-item'></div>");
var img = $("<img>").attr("src", fav.path).attr("alt", fav.descreption || "Photo favorite");
var overlay = $("<div class='favorite-overlay'></div>");
btn.click(function(e) {
e.preventDefault();
e.stopPropagation();
removeFavorite(fav.id);
});
overlay.append(btn);
item.append(img).append(overlay);
$("#favorites-grid").append(item);
});
$("#favorites-counter").text(data.data.length);
var percentage = (data.data.length / 10) * 100;
$("#favorites-progress").css("width", percentage + "%");
} else {
$("#favorites-empty-state").show();
$("#favorites-counter").text("0");
$("#favorites-progress").css("width", "0%");
}
},
error: function() {
$("#favorites-grid").html("<div style='color:red;text-align:center'>Erreur de chargement</div>");
}
});
}
// Supprimer un favori
function removeFavorite(id) {
$.ajax({
url: "/Parent/remove-favorite/" + id,
type: "POST",
success: function() {
loadFavorites();
// Mettre à jour le compteur global
var count = parseInt($("#likeCount").text());
if (!isNaN(count)) {
$("#likeCount").text(count - 1);
}
var countFav = parseInt($("#mesFavCount").text());
if (!isNaN(countFav)) {
$("#mesFavCount").text(countFav - 1);
}
},
error: function() {
alert("Erreur lors de la suppression du favori");
}
});
}
});
</script>
<!-- Script pour la sidebar des favoris -->
<script>
$(document).ready(function() {
// Fonctions pour ouvrir/fermer la sidebar
$("#openFavoritesSidebar").click(function() {
$("#favorites-sidebar").css("right", "0");
loadFavorites();
});
$("#close-favorites-btn").click(function() {
$("#favorites-sidebar").css("right", "-400px");
});
// Fermer en cliquant en dehors
$(document).click(function(event) {
if (!$(event.target).closest("#favorites-sidebar").length &&
!$(event.target).closest("#openFavoritesSidebar").length &&
$("#favorites-sidebar").css("right") === "0px") {
$("#favorites-sidebar").css("right", "-400px");
}
});
// Variables globales
let selectedFavorites = [];
let allFavorites = [];
let coverPhotoId = null; // ID de la photo de couverture
// Fonction pour mettre à jour la sidebar
function loadFavorites() {
$("#favorites-grid").html("<div style='text-align:center;padding:20px;'>Chargement...</div>");
$.ajax({
url: "/Parent/mes-favoris",
type: "GET",
dataType: "json",
success: function(data) {
$("#favorites-grid").empty();
allFavorites = data.data || [];
if (allFavorites.length > 0) {
$("#favorites-empty-state").hide();
// Ajouter l'option de photo de couverture au-dessus de la grille
if (!$("#cover-photo-section").length) {
const coverSection = $(`
<div id="cover-photo-section" style="margin-bottom:15px;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;">
<h4 style="margin:0;font-size:15px;color:#333;">Photo de couverture</h4>
<span style="font-size:12px;color:#777;">Pour la personnalisation des produits</span>
</div>
<div id="cover-photo-container" style="height:120px;background:#f5f5f5;border-radius:8px;display:flex;align-items:center;justify-content:center;overflow:hidden;position:relative;border:1px dashed #ccc;">
<div id="cover-photo-placeholder" style="text-align:center;padding:15px;color:#777;">
<i class="bi bi-image" style="font-size:24px;display:block;margin-bottom:8px;"></i>
<p style="margin:0;font-size:13px;">Sélectionnez une photo comme couverture</p>
</div>
<div id="cover-photo-preview" style="display:none;width:100%;height:100%;position:relative;">
<img src="" style="width:100%;height:100%;object-fit:cover;" />
<button id="remove-cover-photo" style="position:absolute;top:5px;right:5px;background:#F56040;color:white;border:none;width:24px;height:24px;border-radius:50%;cursor:pointer;display:flex;align-items:center;justify-content:center;">
<i class="bi bi-x"></i>
</button>
</div>
</div>
</div>
`);
$("#photos-content").prepend(coverSection);
// Événement pour retirer la photo de couverture
$("#remove-cover-photo").click(function(e) {
e.stopPropagation();
setCoverPhoto(null);
});
}
// Mettre à jour l'affichage de la photo de couverture
updateCoverPhotoDisplay();
// Générer la grille de photos
$.each(allFavorites, function(i, fav) {
var isSelected = selectedFavorites.includes(fav.id);
var isCoverPhoto = (coverPhotoId === fav.id);
// Conteneur principal avec styles conditionnels
var item = $("<div class='favorite-item' data-id='" + fav.id + "' style='position:relative;border-radius:8px;overflow:hidden;aspect-ratio:1;cursor:pointer;transition:all 0.2s;border:3px solid " + (isSelected ? "#F56040" : (isCoverPhoto ? "#4CAF50" : "transparent")) + ";'></div>");
var img = $("<img style='width:100%;height:100%;object-fit:cover;'>").attr("src", fav.path).attr("alt", fav.descreption || "Photo favorite");
// Badge de sélection
var selectionBadge = $("<div class='selection-badge' style='position:absolute;top:5px;right:5px;width:22px;height:22px;border-radius:50%;background:#F56040;display:" + (isSelected ? "flex" : "none") + ";align-items:center;justify-content:center;color:white;font-size:12px;z-index:10;'><i class='bi bi-check'></i></div>");
// Badge de photo de couverture
var coverBadge = $("<div class='cover-badge' style='position:absolute;top:5px;left:5px;padding:2px 6px;background:#4CAF50;color:white;font-size:10px;border-radius:3px;display:" + (isCoverPhoto ? "block" : "none") + ";z-index:10;'><i class='bi bi-star-fill' style='margin-right:3px;font-size:8px;'></i>Couverture</div>");
// Overlay simple pour effet au survol
var hoverOverlay = $("<div class='hover-overlay' style='position:absolute;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,0.2);opacity:0;transition:opacity 0.2s;z-index:5;'></div>");
// Actions sur hover
var actionsOverlay = $("<div class='actions-overlay' style='position:absolute;bottom:5px;left:5px;right:5px;display:flex;justify-content:center;gap:8px;opacity:0;transition:opacity 0.2s;z-index:15;'></div>");
// Bouton pour définir comme photo de couverture
var setCoverBtn = $("<button style='background:" + (isCoverPhoto ? "#4CAF50" : "rgba(255,255,255,0.8)") + ";color:" + (isCoverPhoto ? "white" : "#333") + ";border:none;border-radius:3px;font-size:11px;padding:5px 8px;cursor:pointer;'><i class='bi bi-star" + (isCoverPhoto ? "-fill" : "") + "' style='margin-right:3px;'></i>Couverture</button>");
setCoverBtn.click(function(e) {
e.stopPropagation();
if (isCoverPhoto) {
setCoverPhoto(null);
} else {
setCoverPhoto(fav.id);
}
});
actionsOverlay.append(setCoverBtn);
// Ajouter effet de survol
item.hover(
function() {
$(this).find(".hover-overlay").css("opacity", "1");
$(this).find(".actions-overlay").css("opacity", "1");
},
function() {
$(this).find(".hover-overlay").css("opacity", "0");
$(this).find(".actions-overlay").css("opacity", "0");
}
);
// Gérer le clic pour la sélection
item.click(function(e) {
e.stopPropagation();
toggleSelection($(this).data('id'));
});
item.append(img).append(hoverOverlay).append(selectionBadge).append(coverBadge).append(actionsOverlay);
// Ajouter explicitement une classe pour le style
item.addClass("no-trash-button");
$("#favorites-grid").append(item);
});
// Supprimer tout bouton de suppression qui pourrait être ajouté dynamiquement
setTimeout(function() {
$(".favorite-item .remove-favorite, .favorite-item button:has(.bi-trash), .favorite-overlay button").remove();
}, 100);
$("#favorites-counter").text(allFavorites.length);
$("#openFavoritesSidebar span").text(allFavorites.length);
updateProductsView();
} else {
$("#favorites-empty-state").show();
$("#favorites-counter").text("0");
$("#openFavoritesSidebar span").text("0");
$("#selection-count").text("0");
updateProductsView();
}
},
error: function() {
$("#favorites-grid").html("<div style='color:red;text-align:center;padding:20px;'>Erreur de chargement</div>");
}
});
}
// Fonction pour définir la photo de couverture
function setCoverPhoto(id) {
coverPhotoId = id;
// Mettre à jour l'affichage
updateCoverPhotoDisplay();
// Mettre à jour le style des photos dans la grille
$(".favorite-item").each(function() {
const itemId = $(this).data('id');
const isSelected = selectedFavorites.includes(itemId);
const isCover = (itemId === coverPhotoId);
// Mettre à jour la bordure
$(this).css("border", "3px solid " + (isSelected ? "#F56040" : (isCover ? "#4CAF50" : "transparent")));
// Mettre à jour le badge de couverture
$(this).find(".cover-badge").css("display", isCover ? "block" : "none");
// Mettre à jour le bouton de couverture
const coverBtn = $(this).find(".actions-overlay button:first");
coverBtn.css({
"background": isCover ? "#4CAF50" : "rgba(255,255,255,0.8)",
"color": isCover ? "white" : "#333"
});
coverBtn.find("i").attr("class", "bi bi-star" + (isCover ? "-fill" : ""));
});
// Enregistrer l'ID de la photo de couverture (si nécessaire pour le backend)
if (id) {
console.log("Photo de couverture définie avec l'ID:", id);
// Ici vous pouvez ajouter une requête AJAX pour enregistrer ce choix sur le serveur
// Ajouter automatiquement la photo de couverture à la sélection si elle n'y est pas déjà
if (!selectedFavorites.includes(id)) {
toggleSelection(id);
}
} else {
console.log("Photo de couverture supprimée");
}
}
// Mettre à jour l'affichage de la photo de couverture
function updateCoverPhotoDisplay() {
if (coverPhotoId) {
// Trouver la photo correspondante
const coverPhoto = allFavorites.find(fav => fav.id === coverPhotoId);
if (coverPhoto) {
$("#cover-photo-placeholder").hide();
$("#cover-photo-preview").show();
$("#cover-photo-preview img").attr("src", coverPhoto.path);
} else {
// Si l'ID ne correspond à aucune photo (cas rare)
coverPhotoId = null;
$("#cover-photo-placeholder").show();
$("#cover-photo-preview").hide();
}
} else {
$("#cover-photo-placeholder").show();
$("#cover-photo-preview").hide();
}
}
// Modifier la fonction updateProductsView pour tenir compte de la photo de couverture
function updateProductsView() {
const current = selectedFavorites.length;
const hasCoverPhoto = coverPhotoId !== null;
$("#product-photo-count").text(current);
let remainingForAlbum = Math.max(0, 20 - current);
let remainingForPochette = Math.max(0, 12 - current);
let remainingForPack = Math.max(0, 12 - current);
const progressBar = (count, total, color) => `
<div style="margin: 5px 0;">
<div style="background-color: #e9ecef; border-radius: 5px; overflow: hidden; height: 8px;">
<div style="width: ${(count / total) * 100}%; background-color: ${color}; height: 100%;"></div>
</div>
<small style="font-size: 12px;">${count}/${total} photos</small>
</div>
`;
// Liste des produits
const products = [
{
name: "Pochette photo (12 photos)",
required: 12,
remaining: Math.max(0, 12 - current),
image: "/images/produit/PochettePhoto5sur5-2.jpg",
color: "#2196f3",
link: "{{ path('AjoutPochettePhotos_Favoris', {'nbr': 12}) }}",
needsCover: true
},
{
name: "Pack numérique (20 photos)",
required: 20,
remaining: Math.max(0, 20 - current),
image: "/images/produit/photoNumerique.jpg",
color: "#4caf50",
link: "{{ path('PackPhotosNumerique_Favoris', {'nbr': 20}) }}",
needsCover: false
},
].sort((a, b) => a.remaining - b.remaining);
const productList = products
.map((product) => {
const count = current;
const total = product.required;
const remaining = product.remaining;
const coverRequired = product.needsCover && !hasCoverPhoto;
return `
<li style="margin-bottom: 20px; position: relative;">
${coverRequired ? `<div style="position: absolute; top: 0; right: 0; background: #FFC107; color: #333; font-size: 10px; padding: 2px 6px; border-radius: 3px; z-index: 5;">
<i class="bi bi-exclamation-triangle"></i> Photo de couverture requise
</div>` : ''}
<div style="display: flex; align-items: center; gap: 10px;">
<img src="${product.image}" alt="${product.name}" style="width: 70px; height: 70px; border-radius: 5px; object-fit: cover;" />
<div style="flex: 1;">
<strong style="font-size: 14px;">${product.name}</strong>
${progressBar(count, total, product.color)}
${
remaining > 0
? `<small style="color: ${product.color}; font-size: 12px;">
Encore ${remaining} photos pour compléter ${product.name.toLowerCase()}
</small>`
: coverRequired
? `<button
style="
margin-top: 5px;
padding: 6px 12px;
background-color: #FFC107;
color: #333;
border: none;
border-radius: 5px;
font-size: 13px;
cursor: pointer;
"
onclick="$('#tab-photos').click(); /* Rediriger vers l'onglet photos */"
>
Choisir une couverture
</button>`
: `<button
style="
margin-top: 5px;
padding: 6px 12px;
background-color: ${product.color};
color: white;
border: none;
border-radius: 5px;
font-size: 13px;
cursor: pointer;
"
onclick="window.location.href='${product.link}'"
>
Commander
</button>`
}
</div>
</div>
</li>
`;
})
.join("");
const boutiqueButton = `
<li style="margin-top: 25px; text-align: center;">
<button
style="
padding: 8px 15px;
background-color: #F56040;
color: white;
border: none;
border-radius: 5px;
font-size: 14px;
width: 170px;
height: 40px;
cursor: pointer;
"
onclick="window.location.href='{{ path('boutique5sur5') }}'"
>
Voir toute la boutique
</button>
</li>
`;
$("#product-list").html(productList + boutiqueButton);
}
});
</script>
{% endblock %}