1import { Controller } from "@hotwired/stimulus" 2 3// Connects to data-controller="calendar" 4export default class extends Controller { 5 static targets = ["popup", "popupText"] 6 7 connect() { 8 const calendarEl = document.getElementById('calendar'); 9 if (!calendarEl) return; 10 11 const calendar = new FullCalendar.Calendar(calendarEl, { 12 locale: 'fr', 13 initialView: window.innerWidth < 768 ? 'listWeek' : 'dayGridMonth', 14 buttonText: { 15 today: 'Aujourdâhui', 16 month: 'Mois', 17 week: 'Semaine', 18 day: 'Jour', 19 list: 'Liste' 20 }, 21 22 // â Optional: Make title look like "Juin 2025" 23 titleFormat: { year: 'numeric', month: 'long' }, 24 25 // â Capitalize weekday headers like "Lundi" 26 dayHeaderFormat: { weekday: 'long' }, 27 28 events: this.classSchedule(), 29 eventTimeFormat: { 30 hour: '2-digit', 31 minute: '2-digit', 32 hour12: false 33 }, 34 35 eventClick: function(info) { 36 const overlay = document.getElementById('calendar-popup-overlay'); 37 const popupText = document.getElementById('popup-text'); 38 39 const date = info.event.start.toLocaleDateString('fr-FR'); 40 const time = info.event.start.toTimeString().substring(0, 5); 41 const teacher = info.event.extendedProps.teacher || 'Professeur'; 42 const image = info.event.extendedProps.image || 'default.jpg'; 43 const level = info.event.extendedProps.level; 44 const title = 'Cours collectif'; 45 const link = `https://www.eversports.fr/org/widget/overview?companyId=659faeaa-0fe1-4fdc-bc8e-caa5a74a57e5`; 46 47 popupText.innerHTML = ` 48 <div class="text-center" style="margin: auto; padding: 20px; background: rgb(241, 241, 241); border-radius: 12px;"> 49 <strong>${title}</strong><br><br> 50 <img src="/assets/${image}" alt="${teacher}" class="teacher-img"><br> 51 ${teacher}<br> 52 ${date}<br> 53 ${time}<br><br> 54 <a href="${link}" class="btn-reserve">Réserver</a> 55 </div> 56 `; 57 58 overlay.classList.remove('hidden'); 59 } 60 }); 61 62 calendar.render(); 63 64 // Close popup on outside click 65 this.handleOutsideClick = this._handleOutsideClick.bind(this); 66 document.addEventListener('click', this.handleOutsideClick); 67 } 68 69 classSchedule() { 70 const weekly = [ 71 // Monday (Lundi) 72 { daysOfWeek: [1], time: '09:00', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Intermédiaire' }, 73 // { daysOfWeek: [1], time: '10:00', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 74 { daysOfWeek: [1], time: '12:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 75 { daysOfWeek: [1], time: '18:30', teacher: 'Oksana Boiko', image: 'oksana-5c2d3e3d3e3ae70863c45898958cf5586815fa525a330d9023c9eb42e9687168.png', level: 'Normal' }, 76 { daysOfWeek: [1], time: '19:30', teacher: 'Oksana Boiko', image: 'oksana-5c2d3e3d3e3ae70863c45898958cf5586815fa525a330d9023c9eb42e9687168.png', level: 'Normal' }, 77 78 // Tuesday (Mardi) 79 { daysOfWeek: [2], time: '09:00', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 80 { daysOfWeek: [2], time: '14:00', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 81 { daysOfWeek: [2], time: '17:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 82 { daysOfWeek: [2], time: '18:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 83 { daysOfWeek: [2], time: '19:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Intermédiaire' }, 84 85 // Wednesday (Mercredi) 86 { daysOfWeek: [3], time: '17:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 87 { daysOfWeek: [3], time: '18:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 88 { daysOfWeek: [3], time: '19:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Intermédiaire' }, 89 90 // Thursday (Jeudi) 91 { daysOfWeek: [4], time: '09:00', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 92 // { daysOfWeek: [4], time: '10:00', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 93 { daysOfWeek: [4], time: '12:30', teacher: 'Oksana Boiko', image: 'oksana-5c2d3e3d3e3ae70863c45898958cf5586815fa525a330d9023c9eb42e9687168.png', level: 'Intermédiaire' }, 94 { daysOfWeek: [4], time: '18:30', teacher: 'Astrid Colomb-Bouvard', image: 'astrid-cb7d91b0a4e4eea2801a453d9caf5b3f900f4626bc07490dc76f76b3be0aa969.png', level: 'Normal' }, 95 { daysOfWeek: [4], time: '19:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 96 97 // Friday (Vendredi) 98 { daysOfWeek: [5], time: '09:00', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Intermédiaire' }, 99 { daysOfWeek: [5], time: '12:30', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 100 101 // Saturday (Samedi) 102 { daysOfWeek: [6], time: '10:00', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Normal' }, 103 { daysOfWeek: [6], time: '11:15', teacher: 'Chiara Paperini', image: 'chiara_profile-c37f375bedd3fbd7ca2d40b163dc7c993a3096b5bfa5652f7ab9c50c258a4c2b.jpeg', level: 'Intermédiaire' }, 104 ]; 105 106 return weekly.map((item, index) => ({ 107 id: index, 108 title: `${item.level}`, 109 daysOfWeek: item.daysOfWeek, 110 startTime: item.time,
111 endTime: this.addMinutes(item.time, 55), 112 startRecur: new Date().toISOString().split('T')[0], 113 extendedProps: { 114 teacher: item.teacher, 115 image: item.image 116 } 117 })); 118 } 119 120 addMinutes(timeStr, mins) { 121 const [h, m] = timeStr.split(':').map(Number); 122 const date = new Date(); 123 date.setHours(h); 124 date.setMinutes(m + mins); 125 return date.toTimeString().substring(0, 5); 126 } 127 128 closePopup() { 129 const overlay = document.getElementById('calendar-popup-overlay'); 130 if (overlay) overlay.classList.add('hidden'); 131 } 132 133 disconnect() { 134 document.removeEventListener('click', this.handleOutsideClick); 135 } 136 137 _handleOutsideClick(event) { 138 const overlay = document.getElementById('calendar-popup-overlay'); 139 const popup = document.getElementById('calendar-popup'); 140 141 if (!overlay || overlay.classList.contains('hidden')) return; 142 143 const isClickInsidePopup = popup.contains(event.target); 144 const isCalendarClick = event.target.closest('.fc') !== null; 145 146 if (!isClickInsidePopup && !isCalendarClick) { 147 overlay.classList.add('hidden'); 148 } 149 } 150};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.