Scripts

<script>
    window.addEventListener('alpine:init', () => {
        console.log('Alpine.js has been initialized');
        Alpine.store('screen', {
            isSmall: window.matchMedia('(max-width: 639px)').matches,
            isMobile: window.matchMedia('(max-width: 767px)').matches,
            isTablet: window.matchMedia('(max-width: 1023px)').matches,
            init() {
                const smallMedia = window.matchMedia('(max-width: 639px)');
                const mobileMedia = window.matchMedia('(max-width: 767px)');
                const tabletMedia = window.matchMedia('(max-width: 1023px)');
                this.isSmall = smallMedia.matches;
                this.isMobile = mobileMedia.matches;
                this.isTablet = tabletMedia.matches;
                const updateScreen = (event, type) => {
                    if (type === 'small') this.isSmall = event.matches;
                    if (type === 'mobile') this.isMobile = event.matches;
                    if (type === 'tablet') this.isTablet = event.matches;
                };
                [{
                        media: smallMedia,
                        type: 'small'
                    },
                    {
                        media: mobileMedia,
                        type: 'mobile'
                    },
                    {
                        media: tabletMedia,
                        type: 'tablet'
                    }
                ].forEach(({
                    media,
                    type
                }) => {
                    if (typeof media.onchange !== 'object') {
                        media.addListener((e) => updateScreen(e, type));
                    } else {
                        media.addEventListener('change', (e) => updateScreen(e, type));
                    }
                });
            }
        });
        Alpine.store('asideBlocs', {
            asides: [],
            // Add new aside block
            addAside(name, customProperties = {}) {
                if (!this.asides.find(aside => aside.name === name)) {
                    this.asides.push({
                        name,
                        open: false,
                        ...customProperties,
                    });
                }
            },
            removeAside(name) {
                this.asides = this.asides.filter(aside => aside.name !== name);
            },
            toggleAside(name) {
                const aside = this.asides.find(aside => aside.name === name);
                if (aside) {
                    aside.open = !aside.open;
                    document.body.classList.toggle('overflow-hidden', aside.open);
                }
            },
            closeAside(name) {
                const aside = this.asides.find(aside => aside.name === name);
                if (aside) {
                    aside.open = false;
                    document.body.classList.remove('overflow-hidden');
                }
            },
            openAside(name) {
                const aside = this.asides.find(aside => aside.name === name);
                if (aside) {
                    aside.open = true;
                    document.body.classList.add('overflow-hidden');
                }
            }
        });
        Alpine.store('locator', {
            days: [{
                    key: 'monday',
                    label: 'Lundi'
                },
                {
                    key: 'tuesday',
                    label: 'Mardi'
                },
                {
                    key: 'wednesday',
                    label: 'Mercredi'
                },
                {
                    key: 'thursday',
                    label: 'Jeudi'
                },
                {
                    key: 'friday',
                    label: 'Vendredi'
                },
                {
                    key: 'saturday',
                    label: 'Samedi'
                },
                {
                    key: 'sunday',
                    label: 'Dimanche'
                },
            ],
            allStores: [],
            countStore: "",
            filteredDistanceStores: null,
            selectedStore: null,
            loading: true,
            mapCenter: null,
            mapInstance: null,
            async init() {
                try {
                    await this.loadLibraries();
                    await this.loadStores();
                } finally {
                    this.loading = false;
                }
            },
            async loadLibraries() {
                const [geometry] = await Promise.all([
                    google.maps.importLibrary("geometry"),
                ]);
            },
            async loadStores() {
                try {
                    const response = await fetch(`${window.location.origin}/js/json/getList.json`);
                    const data = await response.json();
                    if (data) {
                        this.countStore = data.length;
                        this.allStores = data;
                    }
                } catch (error) {
                    console.error('Erreur lors du chargement des magasins:', error);
                    this.allStores = [];
                }
            },
            selectStore(store) {
                this.selectedStore = store;
                if (typeof this.onSelectStore === 'function') {
                    this.onSelectStore(store);
                }
            },
            updateDistances(minZoom = 12) {
                if (!this.mapInstance) return;
                const zoom = this.mapInstance.getZoom();
                if (zoom < minZoom) {
                    return this.filteredDistanceStores = []
                }
                const center = this.mapInstance.getCenter();
                if (!center) return;
                this.filteredDistanceStores = this.allStores
                    .filter(store => this.validateCoordinates(store.lat, store.lng).isValid)
                    .map(store => {
                        const position = new google.maps.LatLng(parseFloat(store.lat), parseFloat(store.lng));
                        const distanceInMeters = google.maps.geometry.spherical.computeDistanceBetween(center, position);
                        const distanceInKm = distanceInMeters / 1000;
                        return {
                            ...store,
                            distanceInKm,
                            distance: `${distanceInKm.toFixed(1)} km`
                        };
                    })
                    .sort((a, b) => a.distanceInKm - b.distanceInKm);
            },
            validateCoordinates(lat, lng) {
                const isEmpty = (v) => v === '' || v === null || v === undefined;
                if (isEmpty(lat) || isEmpty(lng)) {
                    return {
                        isValid: false,
                        error: 'Les coordonnées ne peuvent pas être null, undefined ou vides'
                    };
                }
                const latitude = parseFloat(lat);
                const longitude = parseFloat(lng);
                if (isNaN(latitude) || isNaN(longitude)) {
                    return {
                        isValid: false,
                        error: 'Les coordonnées doivent être des nombres valides'
                    };
                }
                if (latitude < -90 || latitude > 90) {
                    return {
                        isValid: false,
                        error: 'La latitude doit être comprise entre -90 et 90'
                    };
                }
                if (longitude < -180 || longitude > 180) {
                    return {
                        isValid: false,
                        error: 'La longitude doit être comprise entre -180 et 180'
                    };
                }
                return {
                    isValid: true,
                    coordinates: {
                        lat: latitude,
                        lng: longitude
                    }
                };
            },
            setMapCenter(lat, lng, zoom) {
                const parsedLat = parseFloat(lat);
                const parsedLng = parseFloat(lng);
                if (!isNaN(parsedLat) && !isNaN(parsedLng)) {
                    this.mapInstance.panTo({
                        lat: parsedLat,
                        lng: parsedLng
                    })
                }
                if (zoom) {
                    this.mapInstance.setZoom(zoom)
                }
            },
            goToStore(store) {
                if (!this.mapInstance || !store) return;
                const lat = parseFloat(store.lat);
                const lng = parseFloat(store.lng);
                if (isNaN(lat) || isNaN(lng)) return;
                this.setMapCenter(lat, lng, 15)
                this.selectStore(store);
            },
            getOpeningStatus(store) {
                const now = new Date();
                const days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
                const currentDayKey = days[now.getDay()];
                const schedule = store[currentDayKey];
                if (!schedule || schedule.toLowerCase().includes('fermé')) {
                    return {
                        status: 'Fermé',
                        end: null
                    };
                }
                const [start, end] = schedule.split(' - ');
                if (!start || !end) {
                    return {
                        status: 'Fermé',
                        end: null
                    };
                }
                const [startHour, startMin] = start.split(':').map(Number);
                const [endHour, endMin] = end.split(':').map(Number);
                const startTime = new Date();
                startTime.setHours(startHour, startMin, 0);
                const endTime = new Date();
                endTime.setHours(endHour, endMin, 0);
                if (now >= startTime && now <= endTime) {
                    return {
                        status: 'Ouvert',
                        end
                    };
                }
                return {
                    status: 'Fermé',
                    end: null
                };
            }
        });
    });
</script>
<script>
	window.addEventListener('alpine:init', () => {
		console.log('Alpine.js has been initialized');
		Alpine.store('screen', {
            isSmall: window.matchMedia('(max-width: 639px)').matches,
            isMobile: window.matchMedia('(max-width: 767px)').matches,
            isTablet: window.matchMedia('(max-width: 1023px)').matches,

			init() {
				const smallMedia = window.matchMedia('(max-width: 639px)');
				const mobileMedia = window.matchMedia('(max-width: 767px)');
				const tabletMedia = window.matchMedia('(max-width: 1023px)');

				this.isSmall = smallMedia.matches;
				this.isMobile = mobileMedia.matches;
				this.isTablet = tabletMedia.matches;

				const updateScreen = (event, type) => {
					if (type === 'small') this.isSmall = event.matches;
					if (type === 'mobile') this.isMobile = event.matches;
					if (type === 'tablet') this.isTablet = event.matches;
				};

				[
					{media: smallMedia, type: 'small'},
					{media: mobileMedia, type: 'mobile'},
					{media: tabletMedia, type: 'tablet'}
				].forEach(({media, type}) => {
					if (typeof media.onchange !== 'object') {
						media.addListener((e) => updateScreen(e, type));
					} else {
						media.addEventListener('change', (e) => updateScreen(e, type));
					}
				});
			}
		});
		Alpine.store('asideBlocs', {
			asides: [],

			// Add new aside block
			addAside(name, customProperties = {}) {
				if (!this.asides.find(aside => aside.name === name)) {
					this.asides.push({
						name,
						open: false,
						...customProperties,
					});
				}
			},


			removeAside(name) {
				this.asides = this.asides.filter(aside => aside.name !== name);
			},

			toggleAside(name) {
				const aside = this.asides.find(aside => aside.name === name);
				if (aside) {
					aside.open = !aside.open;
					document.body.classList.toggle('overflow-hidden', aside.open);
				}
			},

			closeAside(name) {
				const aside = this.asides.find(aside => aside.name === name);
				if (aside) {
					aside.open = false;
					document.body.classList.remove('overflow-hidden');
				}
			},

			openAside(name) {
				const aside = this.asides.find(aside => aside.name === name);
				if (aside) {
					aside.open = true;
					document.body.classList.add('overflow-hidden');
				}
			}
		});

        Alpine.store('locator', {
	        days: [
		        { key: 'monday', label: 'Lundi' },
		        { key: 'tuesday', label: 'Mardi' },
		        { key: 'wednesday', label: 'Mercredi' },
		        { key: 'thursday', label: 'Jeudi' },
		        { key: 'friday', label: 'Vendredi' },
		        { key: 'saturday', label: 'Samedi' },
		        { key: 'sunday', label: 'Dimanche' },
	        ],
            allStores: [],
            countStore: "",
            filteredDistanceStores: null,
            selectedStore: null,
            loading: true,
            mapCenter: null,
            mapInstance: null,

            async init() {
                try {
                    await this.loadLibraries();
                    await this.loadStores();
                } finally {
                    this.loading = false;
                }
            },

            async loadLibraries() {
                const [geometry] = await Promise.all([
                    google.maps.importLibrary("geometry"),
                ]);
            },

            async loadStores() {
                try {
                    const response = await fetch(`${window.location.origin}/js/json/getList.json`);
                    const data = await response.json();
                    if (data) {
                        this.countStore = data.length;
                        this.allStores = data;
                    }
                } catch (error) {
                    console.error('Erreur lors du chargement des magasins:', error);
                    this.allStores = [];
                }
            },

            selectStore(store) {
                this.selectedStore = store;
	            if (typeof this.onSelectStore === 'function') {
		            this.onSelectStore(store);
	            }
            },

	        updateDistances(minZoom = 12) {
		        if (!this.mapInstance) return;

		        const zoom = this.mapInstance.getZoom();
		        if (zoom < minZoom) {
                    return this.filteredDistanceStores = []
                }

		        const center = this.mapInstance.getCenter();
		        if (!center) return;

		        this.filteredDistanceStores = this.allStores
			        .filter(store => this.validateCoordinates(store.lat, store.lng).isValid)
			        .map(store => {
				        const position = new google.maps.LatLng(parseFloat(store.lat), parseFloat(store.lng));
				        const distanceInMeters = google.maps.geometry.spherical.computeDistanceBetween(center, position);
				        const distanceInKm = distanceInMeters / 1000;

				        return {
					        ...store,
					        distanceInKm,
					        distance: `${distanceInKm.toFixed(1)} km`
				        };
			        })
			        .sort((a, b) => a.distanceInKm - b.distanceInKm);
	        },

	        validateCoordinates(lat, lng) {
		        const isEmpty = (v) => v === '' || v === null || v === undefined;

		        if (isEmpty(lat) || isEmpty(lng)) {
			        return {
				        isValid: false,
				        error: 'Les coordonnées ne peuvent pas être null, undefined ou vides'
			        };
		        }

		        const latitude = parseFloat(lat);
		        const longitude = parseFloat(lng);

		        if (isNaN(latitude) || isNaN(longitude)) {
			        return {
				        isValid: false,
				        error: 'Les coordonnées doivent être des nombres valides'
			        };
		        }

		        if (latitude < -90 || latitude > 90) {
			        return {
				        isValid: false,
				        error: 'La latitude doit être comprise entre -90 et 90'
			        };
		        }

		        if (longitude < -180 || longitude > 180) {
			        return {
				        isValid: false,
				        error: 'La longitude doit être comprise entre -180 et 180'
			        };
		        }

		        return {
			        isValid: true,
			        coordinates: {lat: latitude, lng: longitude}
		        };
	        },

            setMapCenter(lat, lng, zoom) {
	            const parsedLat = parseFloat(lat);
	            const parsedLng = parseFloat(lng);

	            if (!isNaN(parsedLat) && !isNaN(parsedLng)) {
                    this.mapInstance.panTo({lat: parsedLat, lng: parsedLng})
                }
                if (zoom) {
                    this.mapInstance.setZoom(zoom)
                }
            },
            goToStore(store) {
                if (!this.mapInstance || !store) return;

                const lat = parseFloat(store.lat);
                const lng = parseFloat(store.lng);

                if (isNaN(lat) || isNaN(lng)) return;

                this.setMapCenter(lat, lng, 15)

                this.selectStore(store);
            },

	        getOpeningStatus(store) {
		        const now = new Date();
		        const days = ['sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday'];
		        const currentDayKey = days[now.getDay()];
		        const schedule = store[currentDayKey];

		        if (!schedule || schedule.toLowerCase().includes('fermé')) {
			        return { status: 'Fermé', end: null };
		        }

		        const [start, end] = schedule.split(' - ');
		        if (!start || !end) {
			        return { status: 'Fermé', end: null };
		        }

		        const [startHour, startMin] = start.split(':').map(Number);
		        const [endHour, endMin] = end.split(':').map(Number);

		        const startTime = new Date();
		        startTime.setHours(startHour, startMin, 0);
		        const endTime = new Date();
		        endTime.setHours(endHour, endMin, 0);

		        if (now >= startTime && now <= endTime) {
			        return { status: 'Ouvert', end };
		        }
		        return { status: 'Fermé', end: null };
	        }
        });
    });
</script>
/* No context defined. */

No notes defined.