Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9900cfefcc | ||
|
|
952c5512bd | ||
|
|
671cfc4325 | ||
|
|
e34b0d39c6 | ||
|
|
a856209cc3 | ||
|
|
89a0c490a8 | ||
|
|
4547a80315 | ||
|
|
2aa48ae7ba | ||
|
|
2837630e53 | ||
|
|
c3231632ac |
@@ -5,6 +5,9 @@ menu:
|
|||||||
main:
|
main:
|
||||||
weight: 2
|
weight: 2
|
||||||
etapesTitle: "Une démarche simple et pratique"
|
etapesTitle: "Une démarche simple et pratique"
|
||||||
|
depliantLink: "depliant_covoiturage.pdf"
|
||||||
|
ctaText: "Vous aussi, devenez conducteur solidaire !"
|
||||||
|
ctaLink: "https://docs.google.com/forms/d/e/1FAIpQLSfZ1QFpt2iuYsx4d9zhOKZ-DIiuW_NJxZ14R808eOfJDch9-g/viewform"
|
||||||
---
|
---
|
||||||
|
|
||||||
Aidez une personne de votre territoire sans solution de transport pour un trajet ponctuel.
|
Aidez une personne de votre territoire sans solution de transport pour un trajet ponctuel.
|
||||||
|
|||||||
@@ -4,4 +4,6 @@ layout: "engagez-votre-entreprise"
|
|||||||
menu:
|
menu:
|
||||||
main:
|
main:
|
||||||
weight: 3
|
weight: 3
|
||||||
|
depliantLink: "depliant_entreprises.pdf"
|
||||||
|
video: "videos/capsule_entreprises.mp4"
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ title: Garage solidaire
|
|||||||
image: images/visuels/Garage-solidaire-Eric-Soudan.png
|
image: images/visuels/Garage-solidaire-Eric-Soudan.png
|
||||||
weight: 6
|
weight: 6
|
||||||
---
|
---
|
||||||
Solidarauto43 est un garage réservé aux quotients familiaux inférieur à 950 €. Locations, vente et réparations de véhicules, conseils pour l'achat en direct à un particulier. En savoir plus sur [Solidarauto43](https://solidarauto.org/garage-solidaire-le-puy-en-velay/)
|
Solidarauto43 est un garage réservé aux quotients familiaux inférieur à 950 €. Locations, vente et réparations de véhicules, conseils pour l'achat en direct à un particulier. [En savoir plus sur Solidarauto43](https://solidarauto.org/garage-solidaire-le-puy-en-velay/)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ savoirPlusLinks:
|
|||||||
url: "https://lebimsa.fr/l-actu-des-territoires/mobilite-en-haute-loire-la-solution-du-covoiturage/"
|
url: "https://lebimsa.fr/l-actu-des-territoires/mobilite-en-haute-loire-la-solution-du-covoiturage/"
|
||||||
- text: "Découvrez l'interview de Willy Guieau, Directeur opérationnel de la Maison de la Mobilité Solidaire de Haute-Loire"
|
- text: "Découvrez l'interview de Willy Guieau, Directeur opérationnel de la Maison de la Mobilité Solidaire de Haute-Loire"
|
||||||
url: "https://www.linkedin.com/pulse/maison-de-la-mobilit%C3%A9-solidaire-haute-loire-humains-%C3%A0-coeur-bw18e/"
|
url: "https://www.linkedin.com/pulse/maison-de-la-mobilit%C3%A9-solidaire-haute-loire-humains-%C3%A0-coeur-bw18e/"
|
||||||
|
- text: "La Maison de la mobilité solidaire Haute-Loire bien implantée dans le territoire"
|
||||||
|
url: "https://www.auvergnerhonealpes-ee.fr/annuaires/actualites/detail/maison-de-la-mobilite-solidaire-haute-loire-bien-implantee-dans-le-territoire"
|
||||||
---
|
---
|
||||||
|
|
||||||
La Maison de la Mobilité Solidaire Haute-Loire est un projet porté par les associations FIT, Solidarauto43 et FACE43, avec pour missions :
|
La Maison de la Mobilité Solidaire Haute-Loire est un projet porté par les associations FIT, Solidarauto43 et FACE43, avec pour missions :
|
||||||
|
|||||||
@@ -20,10 +20,12 @@ line2after = "EN HAUTE-LOIRE"
|
|||||||
|
|
||||||
[params.search]
|
[params.search]
|
||||||
title = "Rechercher un trajet"
|
title = "Rechercher un trajet"
|
||||||
labelDepart = "Départ"
|
labelDepart = "Départ : Indiquez une adresse précise"
|
||||||
labelDestination = "Destination"
|
labelDestination = "Destination : Indiquez une adresse précise"
|
||||||
labelDate = "Date"
|
labelDate = "Date"
|
||||||
labelHeure = "Heure"
|
labelHeure = "Heure départ"
|
||||||
|
placeholderDepart = "Ex : 1 place du Breuil, Le Puy-en-Velay"
|
||||||
|
placeholderDestination = "Ex : 24 boulevard du Montferrand, Le Puy-en-Velay"
|
||||||
buttonText = "Rechercher"
|
buttonText = "Rechercher"
|
||||||
|
|
||||||
[params.video]
|
[params.video]
|
||||||
|
|||||||
@@ -156,6 +156,8 @@ collections:
|
|||||||
- { name: title, label: "Titre", widget: string }
|
- { name: title, label: "Titre", widget: string }
|
||||||
- { name: headline, label: "Accroche", widget: string }
|
- { name: headline, label: "Accroche", widget: string }
|
||||||
- { name: etapesTitle, label: "Titre section étapes", widget: string, required: false }
|
- { name: etapesTitle, label: "Titre section étapes", widget: string, required: false }
|
||||||
|
- { name: video, label: "Vidéo", widget: string, required: false, hint: "Chemin vers la vidéo (ex: videos/capsule_covoiturage.mp4)" }
|
||||||
|
- { name: depliantLink, label: "Lien dépliant", widget: string, required: false, hint: "Chemin vers le PDF du dépliant (ex: depliant_covoiturage.pdf)" }
|
||||||
- { name: body, label: "Contenu", widget: markdown }
|
- { name: body, label: "Contenu", widget: markdown }
|
||||||
- name: prise-de-contact
|
- name: prise-de-contact
|
||||||
label: "Étape : Prise de contact"
|
label: "Étape : Prise de contact"
|
||||||
@@ -205,6 +207,8 @@ collections:
|
|||||||
- { name: title, label: "Titre", widget: string }
|
- { name: title, label: "Titre", widget: string }
|
||||||
- { name: headline, label: "Accroche", widget: string }
|
- { name: headline, label: "Accroche", widget: string }
|
||||||
- { name: subtitle, label: "Sous-titre engagements", widget: string, required: false }
|
- { name: subtitle, label: "Sous-titre engagements", widget: string, required: false }
|
||||||
|
- { name: video, label: "Vidéo", widget: string, required: false, hint: "Chemin vers la vidéo (ex: videos/capsule_entreprises.mp4)" }
|
||||||
|
- { name: depliantLink, label: "Lien dépliant", widget: string, required: false, hint: "Chemin vers le PDF du dépliant (ex: depliant_entreprises.pdf)" }
|
||||||
- name: avantage-financier
|
- name: avantage-financier
|
||||||
label: "Avantage : Financier"
|
label: "Avantage : Financier"
|
||||||
file: content/pages/engagez-votre-entreprise/avantage-financier.md
|
file: content/pages/engagez-votre-entreprise/avantage-financier.md
|
||||||
|
|||||||
|
After Width: | Height: | Size: 11 KiB |
|
After Width: | Height: | Size: 511 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -874,6 +874,38 @@ main {
|
|||||||
left: -80px;
|
left: -80px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Sidebar Conducteur */
|
||||||
|
.conducteur-sidebar {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 2rem;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CTA Conducteur */
|
||||||
|
.cta-conducteur {
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-conducteur-button {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: var(--color-highlight);
|
||||||
|
color: var(--color-white);
|
||||||
|
padding: 1rem 2rem;
|
||||||
|
border-radius: 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 700;
|
||||||
|
transition: opacity 0.2s, transform 0.2s;
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cta-conducteur-button:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
/* Plus d'infos */
|
/* Plus d'infos */
|
||||||
.plus-infos {
|
.plus-infos {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@@ -2236,6 +2268,23 @@ a {
|
|||||||
margin-right: 0.75rem;
|
margin-right: 0.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Secondary count on the Covoiturage accordion: how many carpooling areas
|
||||||
|
were found. The accordion sits on --color-secondary, so this is a white
|
||||||
|
pill with the header's own green inside — legible on that background, and
|
||||||
|
clearly a different kind of count from the orange trip badge next to it. */
|
||||||
|
.accordion-badge-areas {
|
||||||
|
background-color: var(--color-white);
|
||||||
|
color: var(--color-secondary);
|
||||||
|
gap: 0.25rem;
|
||||||
|
padding: 0 0.5rem;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordion-badge-areas svg {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.accordion-arrow {
|
.accordion-arrow {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
@@ -2397,31 +2446,54 @@ a {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Map Markers */
|
/* Map Markers */
|
||||||
|
/* MapLibre writes `transform: translate(-50%,-50%) translate(Xpx,Ypx)` on
|
||||||
|
.map-marker to position it, and rewrites it on every map frame. Any
|
||||||
|
transform or transition declared here would fight that — a hover scale
|
||||||
|
would also scale the pixel offset, and a transition would make the marker
|
||||||
|
lag behind the map. So .map-marker only reserves space; everything visual
|
||||||
|
lives on .map-marker-inner, which MapLibre never touches. */
|
||||||
.map-marker {
|
.map-marker {
|
||||||
width: 36px;
|
width: 36px;
|
||||||
height: 36px;
|
height: 36px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-marker-inner {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
border: 2px solid var(--color-white);
|
border: 2px solid var(--color-white);
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.25);
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
|
||||||
transition: transform 0.2s ease;
|
transition: transform 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-marker:hover {
|
.map-marker-inner:hover {
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-marker-departure {
|
.map-marker-departure .map-marker-inner {
|
||||||
background-color: var(--color-secondary);
|
background-color: var(--color-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.map-marker-arrival {
|
.map-marker-arrival .map-marker-inner {
|
||||||
background-color: var(--color-highlight);
|
background-color: var(--color-highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Carpooling areas: smaller than trip endpoints, they are context not
|
||||||
|
destinations. */
|
||||||
|
.map-marker-area {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-marker-area .map-marker-inner {
|
||||||
|
background-color: var(--color-highlight);
|
||||||
|
border-width: 1px;
|
||||||
|
}
|
||||||
|
|
||||||
/* MapLibre Popup Styling */
|
/* MapLibre Popup Styling */
|
||||||
.maplibregl-popup-content {
|
.maplibregl-popup-content {
|
||||||
padding: 12px 16px;
|
padding: 12px 16px;
|
||||||
@@ -2449,6 +2521,41 @@ a {
|
|||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.transit-whole-day-toggle {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.65rem 1rem;
|
||||||
|
background-color: #dcfce7;
|
||||||
|
color: #166534;
|
||||||
|
border: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transit-whole-day-toggle:hover {
|
||||||
|
background-color: #bbf7d0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transit-whole-day-toggle.is-active {
|
||||||
|
background-color: #f3f4f6;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transit-whole-day-toggle.is-active:hover {
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transit-whole-day-toggle img {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
.transit-journey {
|
.transit-journey {
|
||||||
background-color: #f9fafb;
|
background-color: #f9fafb;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
@@ -2922,3 +3029,76 @@ a {
|
|||||||
height: 400px;
|
height: 400px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Aires de covoiturage (BNLC), sous les trajets de l'onglet Covoiturage */
|
||||||
|
.carpool-areas {
|
||||||
|
margin-top: 1rem;
|
||||||
|
padding-top: 1rem;
|
||||||
|
border-top: 1px solid #e5e7eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-areas-title {
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: var(--color-text);
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-areas-group {
|
||||||
|
margin-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-areas-group:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-areas-subtitle {
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #6b7280;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-area-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 0.25rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-area-item:hover {
|
||||||
|
background-color: #f3f4f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-area-name {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--color-text);
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-area-address {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #6b7280;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-area-tags {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-area-tag {
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 0.125rem 0.5rem;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: #f3f4f6;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.carpool-area-tag:first-child {
|
||||||
|
background-color: #fdf1e3;
|
||||||
|
color: var(--color-highlight);
|
||||||
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 155 KiB |
|
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 188 KiB |
|
Before Width: | Height: | Size: 3.2 MiB After Width: | Height: | Size: 348 KiB |
@@ -1,5 +1,9 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width">
|
<meta name="viewport" content="width=device-width">
|
||||||
<title>{{ if .IsHome }}{{ site.Title }}{{ else }}{{ printf "%s | %s" .Title site.Title }}{{ end }}</title>
|
<title>{{ if .IsHome }}{{ site.Title }}{{ else }}{{ printf "%s | %s" .Title site.Title }}{{ end }}</title>
|
||||||
|
<link rel="icon" type="image/x-icon" href="/favicon.ico">
|
||||||
|
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||||
|
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
|
||||||
{{ partialCached "head/css.html" . }}
|
{{ partialCached "head/css.html" . }}
|
||||||
{{ partialCached "head/js.html" . }}
|
{{ partialCached "head/js.html" . }}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
@focus="departure.showResults = departure.results.length > 0"
|
@focus="departure.showResults = departure.results.length > 0"
|
||||||
@click.outside="departure.showResults = false"
|
@click.outside="departure.showResults = false"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder=""
|
placeholder="{{ site.Params.search.placeholderDepart }}"
|
||||||
:class="{ 'input-error': errors.departure }"
|
:class="{ 'input-error': errors.departure }"
|
||||||
required />
|
required />
|
||||||
<ul class="autocomplete-results" x-show="departure.showResults && departure.results.length > 0" x-cloak>
|
<ul class="autocomplete-results" x-show="departure.showResults && departure.results.length > 0" x-cloak>
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
@focus="destination.showResults = destination.results.length > 0"
|
@focus="destination.showResults = destination.results.length > 0"
|
||||||
@click.outside="destination.showResults = false"
|
@click.outside="destination.showResults = false"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
placeholder=""
|
placeholder="{{ site.Params.search.placeholderDestination }}"
|
||||||
:class="{ 'input-error': errors.destination }"
|
:class="{ 'input-error': errors.destination }"
|
||||||
required />
|
required />
|
||||||
<ul class="autocomplete-results" x-show="destination.showResults && destination.results.length > 0" x-cloak>
|
<ul class="autocomplete-results" x-show="destination.showResults && destination.results.length > 0" x-cloak>
|
||||||
@@ -179,7 +179,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetch(`https://api-adresse.data.gouv.fr/search/?q=${encodeURIComponent(fieldData.input)}&limit=5`);
|
const response = await fetch(`/api/geo/autocomplete?text=${encodeURIComponent(fieldData.input)}`);
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
fieldData.results = json.features || [];
|
fieldData.results = json.features || [];
|
||||||
fieldData.showResults = fieldData.results.length > 0;
|
fieldData.showResults = fieldData.results.length > 0;
|
||||||
|
|||||||
@@ -26,6 +26,16 @@
|
|||||||
<div class="accordion-inner">
|
<div class="accordion-inner">
|
||||||
<template x-if="results.public_transit?.number > 0">
|
<template x-if="results.public_transit?.number > 0">
|
||||||
<div class="transit-journeys">
|
<div class="transit-journeys">
|
||||||
|
<!-- Toggle Pareto best-options vs full-day listing. Reloads
|
||||||
|
the page with transit_whole_day flipped; the backend
|
||||||
|
switches transit-routing from PlanPareto to PlanProfile
|
||||||
|
across the requested day. -->
|
||||||
|
<button type="button" class="transit-whole-day-toggle"
|
||||||
|
:class="transitWholeDay ? 'is-active' : ''"
|
||||||
|
@click="toggleTransitWholeDay()">
|
||||||
|
{{ if $iconBus }}<img src="{{ $iconBus.RelPermalink }}" alt="" />{{ end }}
|
||||||
|
<span x-text="transitWholeDay ? 'Voir les meilleures options' : 'Voir tous les trajets de la journée'"></span>
|
||||||
|
</button>
|
||||||
<template x-for="(journey, index) in results.public_transit.results" :key="index">
|
<template x-for="(journey, index) in results.public_transit.results" :key="index">
|
||||||
<div class="transit-journey" @click="selectItem('transit', index, journey)" :class="{ 'active': isSelected('transit', index) }">
|
<div class="transit-journey" @click="selectItem('transit', index, journey)" :class="{ 'active': isSelected('transit', index) }">
|
||||||
<!-- En-tête du trajet -->
|
<!-- En-tête du trajet -->
|
||||||
@@ -60,7 +70,7 @@
|
|||||||
<div class="leg-details">
|
<div class="leg-details">
|
||||||
<template x-if="leg.mode === 'WALK'">
|
<template x-if="leg.mode === 'WALK'">
|
||||||
<div>
|
<div>
|
||||||
<p class="leg-line">Marche à pieds</p>
|
<p class="leg-line">Marche à pied</p>
|
||||||
<p class="leg-text">
|
<p class="leg-text">
|
||||||
<span x-text="formatDistance(leg.distance)"></span>
|
<span x-text="formatDistance(leg.distance)"></span>
|
||||||
<span class="leg-duration" x-text="'(' + formatDuration(leg.duration) + ')'"></span>
|
<span class="leg-duration" x-text="'(' + formatDuration(leg.duration) + ')'"></span>
|
||||||
@@ -111,10 +121,20 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Covoiturage -->
|
<!-- Covoiturage -->
|
||||||
<div class="result-accordion" x-data="{ open: false }">
|
<div class="result-accordion"
|
||||||
|
x-data="{ open: false, get areaCount() { return (results.carpool_areas?.departure?.number || 0) + (results.carpool_areas?.arrival?.number || 0); } }"
|
||||||
|
x-init="$watch('open', value => value ? showCarpoolAreaMarkers() : hideCarpoolAreaMarkers())">
|
||||||
<button type="button" class="accordion-header" @click="open = !open" :class="{ 'active': open }">
|
<button type="button" class="accordion-header" @click="open = !open" :class="{ 'active': open }">
|
||||||
<span class="accordion-title">Covoiturage</span>
|
<span class="accordion-title">Covoiturage</span>
|
||||||
<span class="accordion-badge" x-text="results.carpools?.number || 0"></span>
|
<span class="accordion-badge" x-text="results.carpools?.number || 0"></span>
|
||||||
|
<span class="accordion-badge accordion-badge-areas" x-show="areaCount" x-cloak
|
||||||
|
:title="areaCount + ' aire' + (areaCount > 1 ? 's' : '') + ' de covoiturage à proximité'">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||||||
|
<path d="M15 10.5a3 3 0 1 1 -6 0a3 3 0 0 1 6 0z"/>
|
||||||
|
<path d="M19.5 10.5c0 7.142 -7.5 11.25 -7.5 11.25s-7.5 -4.108 -7.5 -11.25a7.5 7.5 0 1 1 15 0z"/>
|
||||||
|
</svg>
|
||||||
|
<span x-text="areaCount"></span>
|
||||||
|
</span>
|
||||||
{{ if $iconArrow }}
|
{{ if $iconArrow }}
|
||||||
<img src="{{ $iconArrow.RelPermalink }}" alt="" class="accordion-arrow" :class="{ 'open': open }" />
|
<img src="{{ $iconArrow.RelPermalink }}" alt="" class="accordion-arrow" :class="{ 'open': open }" />
|
||||||
{{ end }}
|
{{ end }}
|
||||||
@@ -146,6 +166,32 @@
|
|||||||
<template x-if="!results.carpools?.number">
|
<template x-if="!results.carpools?.number">
|
||||||
<p class="no-result-text">Aucun covoiturage disponible pour ce trajet.</p>
|
<p class="no-result-text">Aucun covoiturage disponible pour ce trajet.</p>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<!-- Aires de covoiturage (BNLC) autour du départ et de l'arrivée -->
|
||||||
|
<div class="carpool-areas" x-data="carpoolAreasBlock()" x-show="groups.length" x-cloak>
|
||||||
|
<div class="carpool-areas-title">Aires de covoiturage</div>
|
||||||
|
<template x-for="group in groups" :key="group.end">
|
||||||
|
<div class="carpool-areas-group">
|
||||||
|
<div class="carpool-areas-subtitle" x-text="group.label"></div>
|
||||||
|
<template x-for="(area, index) in group.areas" :key="group.end + '-' + index">
|
||||||
|
<div class="carpool-area-item" @click="focusArea(area)">
|
||||||
|
<span class="carpool-area-name" x-text="area.name"></span>
|
||||||
|
<span class="carpool-area-address" x-show="area.address || area.city">
|
||||||
|
<span x-text="area.address" x-show="area.address"></span>
|
||||||
|
<span x-show="area.address && area.city">·</span>
|
||||||
|
<span x-text="area.city" x-show="area.city"></span>
|
||||||
|
</span>
|
||||||
|
<span class="carpool-area-tags">
|
||||||
|
<span class="carpool-area-tag" x-show="area.type" x-text="area.type"></span>
|
||||||
|
<span class="carpool-area-tag" x-show="area.places" x-text="area.places + ' place(s)'"></span>
|
||||||
|
<span class="carpool-area-tag" x-show="area.placesPmr" x-text="area.placesPmr + ' PMR'"></span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{ with .Params.contactCTA.carpool }}
|
{{ with .Params.contactCTA.carpool }}
|
||||||
<div class="accordion-cta">
|
<div class="accordion-cta">
|
||||||
<p>{{ . }}</p>
|
<p>{{ . }}</p>
|
||||||
@@ -422,14 +468,14 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Déterminer la couleur et le style selon le type de leg
|
// Déterminer la couleur et le style selon le type de leg.
|
||||||
|
// routeColor is already canonical "#RRGGBB" (transit-routing
|
||||||
|
// emits it that way; the parcoursmob adapter normalises Transitous
|
||||||
|
// to match). No extra '#' prefix.
|
||||||
const isWalk = leg.mode === 'WALK';
|
const isWalk = leg.mode === 'WALK';
|
||||||
let lineColor = '#888888'; // Gris par défaut pour la marche
|
const lineColor = isWalk
|
||||||
|
? '#888888'
|
||||||
if (!isWalk) {
|
: (leg.routeColor || '#283959');
|
||||||
// Utiliser la couleur de la route si disponible
|
|
||||||
lineColor = leg.routeColor ? '#' + leg.routeColor : '#283959';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ajouter le layer
|
// Ajouter le layer
|
||||||
map.addLayer({
|
map.addLayer({
|
||||||
@@ -658,6 +704,127 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Aires de covoiturage (BNLC), servies par le service geography via
|
||||||
|
// parcoursmob. Les propriétés BNLC sont éparses : tout est gardé.
|
||||||
|
function carpoolAreasFromData() {
|
||||||
|
const areas = ((window.__PARCOURSMOB_DATA__ || {}).results || {}).carpool_areas || {};
|
||||||
|
const toArea = (feature, end) => {
|
||||||
|
const props = (feature && feature.properties) || {};
|
||||||
|
return {
|
||||||
|
end: end,
|
||||||
|
name: props.nom || 'Aire de covoiturage',
|
||||||
|
address: props.adresse || null,
|
||||||
|
city: props.commune || null,
|
||||||
|
type: props.type || null,
|
||||||
|
places: typeof props.places === 'number' ? props.places : null,
|
||||||
|
placesPmr: typeof props.places_pmr === 'number' ? props.places_pmr : null,
|
||||||
|
coordinates: (feature && feature.geometry) ? feature.geometry.coordinates : null
|
||||||
|
};
|
||||||
|
};
|
||||||
|
return []
|
||||||
|
.concat(((areas.departure || {}).results || []).map(f => toArea(f, 'departure')))
|
||||||
|
.concat(((areas.arrival || {}).results || []).map(f => toArea(f, 'arrival')))
|
||||||
|
.filter(area => area.coordinates);
|
||||||
|
}
|
||||||
|
|
||||||
|
function carpoolAreasBlock() {
|
||||||
|
const areas = carpoolAreasFromData();
|
||||||
|
return {
|
||||||
|
groups: [
|
||||||
|
{end: 'departure', label: 'Près du départ', areas: areas.filter(a => a.end === 'departure')},
|
||||||
|
{end: 'arrival', label: "Près de l'arrivée", areas: areas.filter(a => a.end === 'arrival')}
|
||||||
|
].filter(group => group.areas.length),
|
||||||
|
|
||||||
|
focusArea(area) {
|
||||||
|
if (window.parcoursmobMap && area.coordinates) {
|
||||||
|
window.parcoursmobMap.flyTo({center: area.coordinates, zoom: 14});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marker glyph per BNLC type — same set as the back-office compact view.
|
||||||
|
function carpoolAreaIcon(type) {
|
||||||
|
const glyph = (body, width) => `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="13" height="13" fill="none" stroke="white" stroke-width="${width || 2}" stroke-linecap="round" stroke-linejoin="round">${body}</svg>`;
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 'Aire de covoiturage':
|
||||||
|
return glyph('<circle cx="7" cy="17" r="2"/><circle cx="17" cy="17" r="2"/><path d="M5 17h-2v-6l2 -5h9l4 5h1a2 2 0 0 1 2 2v4h-2m-4 0h-6"/>');
|
||||||
|
case 'Parking':
|
||||||
|
return `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="13" height="13"><text x="12" y="18.5" text-anchor="middle" font-family="ui-sans-serif, system-ui, sans-serif" font-size="20" font-weight="700" fill="white">P</text></svg>`;
|
||||||
|
case 'Parking relais':
|
||||||
|
return glyph('<circle cx="6" cy="17" r="2"/><circle cx="18" cy="17" r="2"/><path d="M4 17h-2v-11a1 1 0 0 1 1 -1h14a5 7 0 0 1 5 7v5h-2m-4 0h-8"/><path d="M2 10h15"/>');
|
||||||
|
case "Sortie d'autoroute":
|
||||||
|
return glyph('<path d="M4 21v-8a4 4 0 0 1 4 -4h9"/><path d="M14 6l3 3l-3 3"/>');
|
||||||
|
case 'Supermarché':
|
||||||
|
return glyph('<circle cx="9" cy="19" r="1.5"/><circle cx="17" cy="19" r="1.5"/><path d="M3 4h2l2.4 10.5a2 2 0 0 0 2 1.5h7.6a2 2 0 0 0 2 -1.6l1 -5.4h-13"/>');
|
||||||
|
case 'Auto-stop':
|
||||||
|
return glyph('<circle cx="13" cy="4" r="1"/><path d="M7 21l3 -4"/><path d="M16 21l-2 -4l-3 -3l1 -6"/><path d="M6 12l2 -3l4 -1l3 3l3 1"/>');
|
||||||
|
case 'Délaissé routier':
|
||||||
|
return glyph('<path d="M12 3v4"/><path d="M12 10v4"/><path d="M12 17v4"/><path d="M5 3v18"/><path d="M19 3v18"/>');
|
||||||
|
default:
|
||||||
|
return glyph('<path d="M15 10.5a3 3 0 1 1 -6 0a3 3 0 0 1 6 0z"/><path d="M19.5 10.5c0 7.142 -7.5 11.25 -7.5 11.25s-7.5 -4.108 -7.5 -11.25a7.5 7.5 0 1 1 15 0z"/>', 1.8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// The areas only show while the Covoiturage accordion is open. The flag
|
||||||
|
// outlives the map so the markers come back when the map is recreated on
|
||||||
|
// a desktop/mobile switch.
|
||||||
|
let carpoolAreasVisible = false;
|
||||||
|
let carpoolAreaMarkers = [];
|
||||||
|
|
||||||
|
function clearCarpoolAreaMarkers() {
|
||||||
|
carpoolAreaMarkers.forEach(marker => marker.remove());
|
||||||
|
carpoolAreaMarkers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderCarpoolAreaMarkers() {
|
||||||
|
const map = window.parcoursmobMap;
|
||||||
|
clearCarpoolAreaMarkers();
|
||||||
|
if (!map || !carpoolAreasVisible) return;
|
||||||
|
|
||||||
|
const areas = carpoolAreasFromData();
|
||||||
|
if (!areas.length) return;
|
||||||
|
|
||||||
|
const data = window.__PARCOURSMOB_DATA__ || {};
|
||||||
|
const bounds = new maplibregl.LngLatBounds();
|
||||||
|
|
||||||
|
areas.forEach((area) => {
|
||||||
|
const el = document.createElement('div');
|
||||||
|
el.className = 'map-marker map-marker-area';
|
||||||
|
el.innerHTML = `<div class="map-marker-inner">${carpoolAreaIcon(area.type)}</div>`;
|
||||||
|
|
||||||
|
const lines = [`<strong>${area.name}</strong>`];
|
||||||
|
if (area.city) lines.push(area.city);
|
||||||
|
if (area.address) lines.push(area.address);
|
||||||
|
if (area.type) lines.push(area.type);
|
||||||
|
|
||||||
|
const marker = new maplibregl.Marker({ element: el })
|
||||||
|
.setLngLat(area.coordinates)
|
||||||
|
.setPopup(new maplibregl.Popup({ offset: 20 }).setHTML(lines.join('<br>')))
|
||||||
|
.addTo(map);
|
||||||
|
|
||||||
|
carpoolAreaMarkers.push(marker);
|
||||||
|
bounds.extend(area.coordinates);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Keep the trip framed while bringing the areas into view, rather than
|
||||||
|
// recentring on the areas alone.
|
||||||
|
if (data.departure) bounds.extend(data.departure.geometry.coordinates);
|
||||||
|
if (data.destination) bounds.extend(data.destination.geometry.coordinates);
|
||||||
|
map.fitBounds(bounds, { padding: 60, maxZoom: 14 });
|
||||||
|
}
|
||||||
|
|
||||||
|
function showCarpoolAreaMarkers() {
|
||||||
|
carpoolAreasVisible = true;
|
||||||
|
renderCarpoolAreaMarkers();
|
||||||
|
}
|
||||||
|
|
||||||
|
function hideCarpoolAreaMarkers() {
|
||||||
|
carpoolAreasVisible = false;
|
||||||
|
clearCarpoolAreaMarkers();
|
||||||
|
}
|
||||||
|
|
||||||
function initMap() {
|
function initMap() {
|
||||||
const data = window.__PARCOURSMOB_DATA__ || {};
|
const data = window.__PARCOURSMOB_DATA__ || {};
|
||||||
const departure = data.departure;
|
const departure = data.departure;
|
||||||
@@ -696,9 +863,11 @@
|
|||||||
const departureEl = document.createElement('div');
|
const departureEl = document.createElement('div');
|
||||||
departureEl.className = 'map-marker map-marker-departure';
|
departureEl.className = 'map-marker map-marker-departure';
|
||||||
departureEl.innerHTML = `
|
departureEl.innerHTML = `
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18" height="18">
|
<div class="map-marker-inner">
|
||||||
<path fill-rule="evenodd" d="M11.54 22.351l.07.04.028.016a.76.76 0 00.723 0l.028-.015.071-.041a16.975 16.975 0 001.144-.742 19.58 19.58 0 002.683-2.282c1.944-1.99 3.963-4.98 3.963-8.827a8.25 8.25 0 00-16.5 0c0 3.846 2.02 6.837 3.963 8.827a19.58 19.58 0 002.682 2.282 16.975 16.975 0 001.145.742zM12 13.5a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd" />
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18" height="18">
|
||||||
</svg>
|
<path fill-rule="evenodd" d="M11.54 22.351l.07.04.028.016a.76.76 0 00.723 0l.028-.015.071-.041a16.975 16.975 0 001.144-.742 19.58 19.58 0 002.683-2.282c1.944-1.99 3.963-4.98 3.963-8.827a8.25 8.25 0 00-16.5 0c0 3.846 2.02 6.837 3.963 8.827a19.58 19.58 0 002.682 2.282 16.975 16.975 0 001.145.742zM12 13.5a3 3 0 100-6 3 3 0 000 6z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
new maplibregl.Marker({ element: departureEl })
|
new maplibregl.Marker({ element: departureEl })
|
||||||
.setLngLat(depCoords)
|
.setLngLat(depCoords)
|
||||||
@@ -709,15 +878,21 @@
|
|||||||
const arrivalEl = document.createElement('div');
|
const arrivalEl = document.createElement('div');
|
||||||
arrivalEl.className = 'map-marker map-marker-arrival';
|
arrivalEl.className = 'map-marker map-marker-arrival';
|
||||||
arrivalEl.innerHTML = `
|
arrivalEl.innerHTML = `
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18" height="18">
|
<div class="map-marker-inner">
|
||||||
<path fill-rule="evenodd" d="M3 2.25a.75.75 0 01.75.75v.54l1.838-.46a9.75 9.75 0 016.725.738l.108.054a8.25 8.25 0 005.58.652l3.109-.732a.75.75 0 01.917.81 47.784 47.784 0 00.005 10.337.75.75 0 01-.574.812l-3.114.733a9.75 9.75 0 01-6.594-.77l-.108-.054a8.25 8.25 0 00-5.69-.625l-2.202.55V21a.75.75 0 01-1.5 0V3A.75.75 0 013 2.25z" clip-rule="evenodd" />
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="white" width="18" height="18">
|
||||||
</svg>
|
<path fill-rule="evenodd" d="M3 2.25a.75.75 0 01.75.75v.54l1.838-.46a9.75 9.75 0 016.725.738l.108.054a8.25 8.25 0 005.58.652l3.109-.732a.75.75 0 01.917.81 47.784 47.784 0 00.005 10.337.75.75 0 01-.574.812l-3.114.733a9.75 9.75 0 01-6.594-.77l-.108-.054a8.25 8.25 0 00-5.69-.625l-2.202.55V21a.75.75 0 01-1.5 0V3A.75.75 0 013 2.25z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
`;
|
`;
|
||||||
new maplibregl.Marker({ element: arrivalEl })
|
new maplibregl.Marker({ element: arrivalEl })
|
||||||
.setLngLat(destCoords)
|
.setLngLat(destCoords)
|
||||||
.setPopup(new maplibregl.Popup().setHTML(`<strong>Arrivée</strong><br>${destination.properties.label}`))
|
.setPopup(new maplibregl.Popup().setHTML(`<strong>Arrivée</strong><br>${destination.properties.label}`))
|
||||||
.addTo(map);
|
.addTo(map);
|
||||||
|
|
||||||
|
// window.parcoursmobMap is assigned by the caller, which has already
|
||||||
|
// returned by the time `load` fires.
|
||||||
|
map.on('load', () => renderCarpoolAreaMarkers());
|
||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,17 +62,28 @@
|
|||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<div class="plus-infos">
|
<div class="conducteur-sidebar">
|
||||||
{{ $downloadIcon := resources.Get "images/picto/Telechargez.svg" }}
|
{{ with .Params.ctaLink }}
|
||||||
<h3 class="plus-infos-title">{{ .Params.plusInfosTitle | default "Plus d'infos ?" }}</h3>
|
<div class="cta-conducteur">
|
||||||
<p class="plus-infos-text">{{ .Params.plusInfosText | default "Vous avez des questions ? Vous souhaitez recevoir de la documentation imprimée ?" }}</p>
|
<a href="{{ . }}" class="cta-conducteur-button" target="_blank">{{ $.Params.ctaText | default "Vous aussi, devenez conducteur solidaire !" }}</a>
|
||||||
<a href="{{ .Params.plusInfosContactLink | default "/pages/contact/" }}" class="plus-infos-button">Contactez-nous</a>
|
</div>
|
||||||
<a href="{{ $downloadIcon := resources.Get "images/picto/download_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg" }}" class="plus-infos-download">
|
{{ end }}
|
||||||
{{ if $downloadIcon }}
|
|
||||||
<img src="{{ $downloadIcon.RelPermalink }}" alt="" />
|
<div class="plus-infos">
|
||||||
|
{{ $downloadIcon := resources.Get "images/picto/Telechargez.svg" }}
|
||||||
|
<h3 class="plus-infos-title">{{ .Params.plusInfosTitle | default "Plus d'infos ?" }}</h3>
|
||||||
|
<p class="plus-infos-text">{{ .Params.plusInfosText | default "Vous avez des questions ? Vous souhaitez recevoir de la documentation imprimée ?" }}</p>
|
||||||
|
<a href="{{ .Params.plusInfosContactLink | default "/pages/contact/" }}" class="plus-infos-button">Contactez-nous</a>
|
||||||
|
{{ with .Params.depliantLink }}
|
||||||
|
<a href="{{ . }}" class="plus-infos-download" target="_blank">
|
||||||
|
{{ $downloadIcon := resources.Get "images/picto/download_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg" }}
|
||||||
|
{{ if $downloadIcon }}
|
||||||
|
<img src="{{ $downloadIcon.RelPermalink }}" alt="" />
|
||||||
|
{{ end }}
|
||||||
|
<span>Ou téléchargez le dépliant d'information</span>
|
||||||
|
</a>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<span>Ou téléchargez le dépliant d'information</span>
|
</div>
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -88,14 +99,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ $pageFooter := where $allResources "Params.type" "page-footer" }}
|
|
||||||
{{ range $pageFooter }}
|
|
||||||
<div class="page-footer-section">
|
|
||||||
<h2 class="page-footer-title">{{ .Title }}</h2>
|
|
||||||
<div class="page-footer-content">
|
|
||||||
{{ .Content }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
</section>
|
</section>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|||||||
@@ -76,13 +76,15 @@
|
|||||||
{{ $downloadIcon := resources.Get "images/picto/download_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg" }}
|
{{ $downloadIcon := resources.Get "images/picto/download_24dp_1F1F1F_FILL0_wght400_GRAD0_opsz24.svg" }}
|
||||||
<h3 class="plus-infos-title">{{ .Params.plusInfosTitle | default "Plus d'infos ?" }}</h3>
|
<h3 class="plus-infos-title">{{ .Params.plusInfosTitle | default "Plus d'infos ?" }}</h3>
|
||||||
<p class="plus-infos-text">{{ .Params.plusInfosText | default "Vous avez des questions ? Vous souhaitez recevoir de la documentation imprimée à mettre à disposition de vos publics ?" }}</p>
|
<p class="plus-infos-text">{{ .Params.plusInfosText | default "Vous avez des questions ? Vous souhaitez recevoir de la documentation imprimée à mettre à disposition de vos publics ?" }}</p>
|
||||||
<a href="{{ .Params.plusInfosContactLink | default "/pages/contact/" }}" class="plus-infos-button">Contactez-nous</a>
|
<a href="{{ $.Params.plusInfosContactLink | default "/pages/contact/" }}" class="plus-infos-button">Contactez-nous</a>
|
||||||
<a href="{{ .Params.plusInfosDocLink | default "#" }}" class="plus-infos-download">
|
{{ with $.Params.depliantLink }}
|
||||||
|
<a href="{{ . }}" class="plus-infos-download" target="_blank">
|
||||||
{{ if $downloadIcon }}
|
{{ if $downloadIcon }}
|
||||||
<img src="{{ $downloadIcon.RelPermalink }}" alt="" />
|
<img src="{{ $downloadIcon.RelPermalink }}" alt="" />
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<span>{{ .Params.plusInfosDownloadText | default "Ou téléchargez le dépliant d'informations Mobi'Conseil" }}</span>
|
<span>Ou téléchargez le dépliant d'information</span>
|
||||||
</a>
|
</a>
|
||||||
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
{{ if $iconClose }}<img src="{{ $iconClose.RelPermalink }}" alt="" />{{ end }}
|
{{ if $iconClose }}<img src="{{ $iconClose.RelPermalink }}" alt="" />{{ end }}
|
||||||
</div>
|
</div>
|
||||||
<div class="solution-content">
|
<div class="solution-content">
|
||||||
<p class="solution-text">{{ .Content | plainify }}</p>
|
<div class="solution-text">{{ .Content }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -51,6 +51,17 @@
|
|||||||
destination: data.destination || null,
|
destination: data.destination || null,
|
||||||
departureDate: data.departure_date || '',
|
departureDate: data.departure_date || '',
|
||||||
departureTime: data.departure_time || '',
|
departureTime: data.departure_time || '',
|
||||||
|
transitWholeDay: data.transit_whole_day || false,
|
||||||
|
|
||||||
|
toggleTransitWholeDay() {
|
||||||
|
const u = new URL(window.location.href);
|
||||||
|
if (u.searchParams.get('transit_whole_day') === '1') {
|
||||||
|
u.searchParams.delete('transit_whole_day');
|
||||||
|
} else {
|
||||||
|
u.searchParams.set('transit_whole_day', '1');
|
||||||
|
}
|
||||||
|
window.location.href = u.toString();
|
||||||
|
},
|
||||||
|
|
||||||
get departureLabel() {
|
get departureLabel() {
|
||||||
return this.departure?.properties?.label || this.departure?.properties?.name || 'Départ';
|
return this.departure?.properties?.label || this.departure?.properties?.name || 'Départ';
|
||||||
@@ -77,83 +88,11 @@
|
|||||||
(r.local_solutions?.number || 0);
|
(r.local_solutions?.number || 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// showJourneyOnMap is intentionally a no-op: the real route
|
||||||
|
// rendering lives in window.showJourneyRoute (search-results.html),
|
||||||
|
// invoked by selectionManager.selectItem.
|
||||||
showJourneyOnMap(journey, index) {
|
showJourneyOnMap(journey, index) {
|
||||||
console.log('showJourneyOnMap called', index, journey);
|
|
||||||
this.selectedJourney = index;
|
this.selectedJourney = index;
|
||||||
|
|
||||||
if (!window.parcoursmobMap) {
|
|
||||||
console.log('Map not found');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const map = window.parcoursmobMap;
|
|
||||||
|
|
||||||
// Supprimer l'ancien tracé s'il existe
|
|
||||||
if (map.getSource('journey-route')) {
|
|
||||||
map.removeLayer('journey-route-line');
|
|
||||||
map.removeSource('journey-route');
|
|
||||||
}
|
|
||||||
|
|
||||||
// Collecter toutes les coordonnées des legs
|
|
||||||
const coordinates = [];
|
|
||||||
|
|
||||||
journey.legs.forEach(leg => {
|
|
||||||
if (leg.legGeometry && leg.legGeometry.points) {
|
|
||||||
try {
|
|
||||||
const decoded = polyline.decode(leg.legGeometry.points);
|
|
||||||
decoded.forEach(point => {
|
|
||||||
const lng = point[1];
|
|
||||||
const lat = point[0];
|
|
||||||
if (lat >= -90 && lat <= 90 && lng >= -180 && lng <= 180) {
|
|
||||||
coordinates.push([lng, lat]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (e) {
|
|
||||||
console.error('Erreur décodage polyline:', e);
|
|
||||||
}
|
|
||||||
} else if (leg.from && leg.to) {
|
|
||||||
const fromLng = leg.from.lon || leg.from.lng;
|
|
||||||
const fromLat = leg.from.lat;
|
|
||||||
const toLng = leg.to.lon || leg.to.lng;
|
|
||||||
const toLat = leg.to.lat;
|
|
||||||
|
|
||||||
if (fromLat && fromLng) coordinates.push([fromLng, fromLat]);
|
|
||||||
if (toLat && toLng) coordinates.push([toLng, toLat]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (coordinates.length < 2) return;
|
|
||||||
|
|
||||||
// Ajouter le tracé sur la carte
|
|
||||||
map.addSource('journey-route', {
|
|
||||||
type: 'geojson',
|
|
||||||
data: {
|
|
||||||
type: 'Feature',
|
|
||||||
properties: {},
|
|
||||||
geometry: {
|
|
||||||
type: 'LineString',
|
|
||||||
coordinates: coordinates
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
map.addLayer({
|
|
||||||
id: 'journey-route-line',
|
|
||||||
type: 'line',
|
|
||||||
source: 'journey-route',
|
|
||||||
layout: {
|
|
||||||
'line-join': 'round',
|
|
||||||
'line-cap': 'round'
|
|
||||||
},
|
|
||||||
paint: {
|
|
||||||
'line-color': '#283959',
|
|
||||||
'line-width': 4
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Ajuster la vue pour montrer tout le tracé
|
|
||||||
const bounds = new maplibregl.LngLatBounds();
|
|
||||||
coordinates.forEach(coord => bounds.extend(coord));
|
|
||||||
map.fitBounds(bounds, { padding: 50 });
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||