Previous version made GPDR-friendly

This commit is contained in:
2025-08-18 16:06:37 +02:00
commit fa64b62d5a
357 changed files with 10137 additions and 0 deletions

View File

@@ -0,0 +1,140 @@
{% from "macros/form.njk" import label, field, select, option, textarea, checkboxes, button, hidden_field %}
<section class="[ form-container ]">
{% if not removeWave %}
<svg aria-hidden="true" viewBox="0 0 1440 131" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="#fff" d="M0 0h1440v131H0z"/><path d="M0 4.643l40-2.326c40-2.5 120-6.888 200 11.67 80 18.735 160 60.854 240 74.894 80 14.04 160 0 240-16.365 80-16.54 160-34.968 240-28.08 80 7.152 160 39.619 240 39.75 80-.131 160-32.598 200-49.139l40-16.365V131H0V4.643z" fill="#D6F253"/></svg>
{% endif %}
<div class="[ inner-wrapper ]">
{% if not contactMember %}
<h2 id="contact-form" class="[ contact-heading ]">Nous contacter</h2>
{% elif contactTitle %}
<h2 id="contact-form" class="[ contact-heading ]">{{ contactTitle }}</h2>
{% endif %}
<div class="form-messages" aria-live="polite"></div>
<form name="contact" method="POST" action="/form/contact-form-handler.php" class="contact-form">
<ol class="[ field-list ]">
<li class="[ field-list__field-group ]">
{{ label("Nom", "namezzz") }}
{{ field( "text", "namezzz", { required: true, placeholder: "", autocomplete: "name", autocorrect: "off", autocapitalize: "off" } ) }}
</li>
<li class="[ field-list__field-group ]">
{{ label("Email", "emailzzz") }}
{{ field( "email", "emailzzz", { required: true, placeholder: "", autocomplete: "email" } ) }}
</li>
<li class="[ field-list__field-group ] [ full-width ]">
{{ label("Je vous contacte pour :", "select") }}
{% if contactMember %}
{{ select( "select", [
{label: "Obtenir un rendez-vous (décrivez votre projet en quelques lignes)", value: "option 1"},
{label: "Proposer une mission à un coopérateur", value: "option 3"}
], { required: true, options_before: [""], options_after: ["Autre demande"] } ) }}
{% else %}
{{ select( "select", [
{label: "Obtenir un rendez-vous (décrivez votre projet en quelques lignes)", value: "option 1"},
{label: "Obtenir des précisions sur le statut d'entrepreneur salarié", value: "option 2"},
{label: "Proposer une mission à un coopérateur", value: "option 3"},
{label: "Proposer un partenariat", value: "option 4"}
], { required: true, options_before: [""], options_after: ["Autre demande"] } ) }}
{% endif %}
</li>
<li class="[ field-list__field-group ] [ full-width ]">
{{ label("Votre message", "message") }}
{{ textarea( "message", { required: true, autocapitalize: "sentences", spellcheck: "true" } ) }}
</li>
{% if contactMember %}
{{ hidden_field('subscribe', '') }}
{% else %}
<li class="[ field-list__field-group ] [ full-width ]">
{{ checkboxes("", "subscribe", [ "Je souhaite être tenu au courant de l'actualité Astrolabe"], { description: "" } ) }}
</li>
{% endif %}
<!-- H o n e y p o t -->
<li aria-hidden="true">
<label class="ohnohoney" for="name"></label>
<input tabindex="-1" class="ohnohoney" autocomplete="off" type="text" id="name" name="name" placeholder="Your name here">
</li>
<li aria-hidden="true">
<label class="ohnohoney" for="email"></label>
<input tabindex="-1" class="ohnohoney" autocomplete="off" type="email" id="email" name="email" placeholder="Your e-mail here">
</li>
<div class="h-captcha" data-sitekey="b07c49fe-50ee-4432-af0a-96d675c6326a"></div>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
</ol>
{% if contactMember %}
{{ hidden_field('contactTo', contactMember) }}
{% endif %}
{{ button("Envoyer") }}
</form>
</div>
</section>
<style>
.form-messages {
margin-bottom: 1rem;
}
.form-messages .error {
color: #dc3545;
margin-bottom: 0.5rem;
}
.form-messages .success {
color: #28a745;
}
.field-error {
color: #dc3545;
font-size: 0.875rem;
margin-top: 0.25rem;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function() {
const form = document.querySelector('.contact-form');
const messagesContainer = document.querySelector('.form-messages');
form.addEventListener('submit', async function(e) {
e.preventDefault();
// Clean previous messages
messagesContainer.innerHTML = '';
// Get form data
const formData = new FormData(form);
try {
const response = await fetch(form.action, {
method: 'POST',
body: formData
});
const data = await response.json();
if (data.success) {
// Display success message
messagesContainer.innerHTML = `<div class="success">${data.message}</div>`;
form.reset();
// Redirect to thank you page
window.location.href = '/thank-you/index.html';
} else {
// Display errors
const errorHtml = data.errors.map(error =>
`<div class="error">${error}</div>`
).join('');
messagesContainer.innerHTML = errorHtml;
// Scroll to error messages
messagesContainer.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
}
} catch (error) {
messagesContainer.innerHTML = `
<div class="error">Une erreur est survenue lors de l'envoi du formulaire. Veuillez réessayer.</div>
`;
}
});
});
</script>

View File

@@ -0,0 +1,16 @@
<section class="[ partner ]">
<div class="[ wrapper ]">
<p class="[ partner__heading ]">{{ customersHeading }}</p>
{% if customersListItems.length %}
<ol class="[ partner__list ]">
{% for item in customersListItems %}
<li class="partner__list-item">
<a href="{{ item.data.url }}" title="{{ item.data.name }}" target="_blank" rel="noreferrer noopener">
<img src="{{ item.data.thumbnail }}" alt="logo de {{ item.data.name }}">
</a>
</li>
{% endfor %}
</ol>
{% endif %}
</div>
</section>

View File

@@ -0,0 +1,24 @@
<section class="[ faq ]">
{% if faq.items %}
<div class="[ inner-wrapper ]">
<h1 class="faq__heading">{{ faqHeading }}</h1>
{{ content | safe }}
<div class="accordion accordion-flush" id="accordionFlushExample">
{% for item in faq.items %}
<div class="accordion-item">
<h3 class="accordion-header" id="flush-heading{{ loop.index }}">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#flush-collapse{{ loop.index }}" aria-expanded="false" aria-controls="flush-collapse{{ loop.index }}">
{{ item.q }}
</button>
</h3>
<div id="flush-collapse{{ loop.index }}" class="accordion-collapse collapse" aria-labelledby="flush-heading{{ loop.index }}" data-bs-parent="#accordionFlushExample">
<div class="accordion-body">
{{ item.a | urlize | safe }}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endif %}
</section>

View File

@@ -0,0 +1,13 @@
<header class="[ intro ]">
<div class="[ wrapper ]">
<h1 class="[ intro__heading ]">{{ brandHeading }}</h1>
<svg viewBox="0 0 127 237" width="100%" height="100%" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M116.77 20.74c-.472-1.843-2.433-5.326-6.48-5.326h-4.283C105.395 6.814 98.249 0 89.533 0c-9.116 0-16.534 7.448-16.534 16.605v20.597L10.073 61.124a2.422 2.422 0 00-1.403 3.124c6.302 16.578 22.13 26.795 38.897 26.795 2.778 0 5.582-.315 8.375-.895 2.026.425 4.09.704 6.169.824v21.449a2.422 2.422 0 104.842 0V90.962a41.398 41.398 0 006.046-.8v22.259a2.422 2.422 0 104.843 0v-23.59c16.39-5.573 28.22-21.102 28.22-39.352V20.256h4.228c1.262 0 1.737 1.513 1.793 1.708a2.425 2.425 0 002.94 1.723 2.424 2.424 0 001.747-2.948zM32.478 82.973c-8.206-3.684-14.61-10.117-18.31-18.225l62.113-23.615c.013-.004.023-.013.034-.017.09-.036.173-.083.257-.128.058-.032.119-.058.174-.093.066-.044.124-.096.186-.146.06-.05.127-.095.184-.151.05-.05.092-.109.138-.162.054-.063.112-.124.159-.192.043-.065.077-.136.116-.203.037-.067.079-.131.11-.202.03-.07.05-.146.074-.22.024-.076.053-.15.07-.229.015-.065.019-.132.028-.199.013-.093.028-.187.03-.282l.003-.039V16.605c0-6.485 5.245-11.762 11.69-11.762 6.416 0 11.637 5.226 11.687 11.667v30.547H86.663a2.421 2.421 0 00-2.422 2.422c0 .023.007.043.007.068-.033 15.12-9.538 28.88-23.678 34.255-9.166 3.483-19.144 3.192-28.092-.828zm34.639 3.12c12.614-6.78 21.023-19.79 21.88-34.194h12.133c-1.194 18.255-15.785 32.903-34.013 34.195z" fill="#1E1E1E"/><path d="M89.53 20.256h4.464a2.421 2.421 0 100-4.842h-4.463a2.421 2.421 0 100 4.842zM123.897 194.561h-4.496V114.15a2.241 2.241 0 00-2.248-2.233H6.994c-1.24 0-2.248 1-2.248 2.233v80.411H2.498a2.242 2.242 0 00-2.248 2.234v37.971A2.242 2.242 0 002.498 237h121.399a2.243 2.243 0 002.249-2.234v-37.971a2.243 2.243 0 00-2.249-2.234zM9.243 116.384h105.662v78.177H9.243v-78.177zm112.406 116.149H4.746v-33.505H121.65v33.505z" fill="#1E1E1E"/><path d="M103.663 125.318h-83.18a2.242 2.242 0 00-2.249 2.234v55.841a2.241 2.241 0 002.248 2.233h83.181c1.241 0 2.248-1 2.248-2.233v-55.841a2.242 2.242 0 00-2.248-2.234zm-2.248 55.841H22.73v-51.373h78.685v51.373zM114.904 206.846h-13.488a2.242 2.242 0 00-2.248 2.234v13.401a2.242 2.242 0 002.248 2.234h13.488a2.243 2.243 0 002.249-2.234V209.08a2.243 2.243 0 00-2.249-2.234zm-2.248 13.402h-8.992v-8.935h8.992v8.935zM92.423 206.846h-13.49a2.242 2.242 0 00-2.247 2.234v13.401a2.242 2.242 0 002.248 2.234h13.489a2.242 2.242 0 002.248-2.234V209.08a2.242 2.242 0 00-2.248-2.234zm-2.248 13.402h-8.993v-8.935h8.993v8.935z" fill="#1E1E1E"/><path d="M78.934 134.253H27.227v4.467h51.707v-4.467zM63.197 143.187h-35.97v4.468h35.97v-4.468zM45.212 152.122H27.227v4.467h17.985v-4.467zM58.7 152.122h-8.993v4.467h8.992v-4.467z" fill="#111"/></svg>
<div class="btn-grp">
<a role="button" href="/comprendre-la-cae/" class="btn btn-secondary">Une CAE c'est quoi ?</a>
<a role="button" href="/nous-rejoindre/" class="btn btn-primary">Nous rejoindre
<svg width="18" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.602 5.823L12.05.376a1.357 1.357 0 00-1.875 0 1.295 1.295 0 000 1.84l3.278 3.235H1.326C.587 5.451 0 6.027 0 6.752s.587 1.302 1.326 1.302h12.127l-3.278 3.215a1.295 1.295 0 000 1.84 1.349 1.349 0 001.894 0l5.533-5.427c.246-.242.398-.576.398-.93 0-.353-.133-.687-.398-.93z" fill="#111"/></svg>
</a>
<a role="button" href="/posts/flyer-2023/" class="btn btn-secondary">Notre flyer 📄</a>
</div>
</div>
</header>

View File

@@ -0,0 +1,50 @@
<div class="[ wrapper ]">
<h2 class="mt-5 mb-2">Où sommes-nous ?</h2>
</div>
<div id = "map" style = "width: 100%; height: 500px; margin-bottom: 8rem;"></div>
<script type="text/javascript" src="/vendor/js/leaflet.js"></script>
<script>
// Creating map options
var mapOptions = {
center: [48.10494125597395, -1.6795760019626425],
zoom: 15
}
// Creating a map object
var map = new L.map('map', mapOptions);
var iconMarker = L.icon({
iconUrl: '/images/marker-stroke.svg',
iconSize: [28, 40],
iconAnchor: [14, 40],
popupAnchor: [0, -40]
});
var iconMarkerAlt = L.icon({
iconUrl: '/images/astrolabe/marker-logo-alt.svg',
iconSize: [40, 40],
iconAnchor: [20, 40],
popupAnchor: [0, -40]
});
var members = {{ collections.membersLocations | dump | safe }};
var markerGroup = members.map( member => {
return new L.marker(member.location, {icon: iconMarker}).bindPopup('<a href="'+member.url+'/">'+member.name+'</a>');
});
var markerSiege = L.marker([48.10494125597395, -1.6795760019626425], {icon: iconMarkerAlt}).bindPopup('Siège Astrolabe CAE')
.openPopup();
markerGroup.push(markerSiege)
var featureGroup = L.featureGroup(markerGroup).addTo(map);
map.fitBounds(featureGroup.getBounds());
// Creating a Layer object
var layer = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
// Adding layer to the map
map.addLayer(layer);
</script>

View File

@@ -0,0 +1,6 @@
<section id="Meeting" class="[ meeting ]">
<a class="[ meeting__link btn btn-secondary ]" href="https://nuage.astrolabe.coop/apps/forms/embed/jiKKjDLEJZ7DEck3tacdRMX3" target="_blank">
Réunions d'information&nbsp;
<svg width="18" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.602 5.823L12.05.376a1.357 1.357 0 00-1.875 0 1.295 1.295 0 000 1.84l3.278 3.235H1.326C.587 5.451 0 6.027 0 6.752s.587 1.302 1.326 1.302h12.127l-3.278 3.215a1.295 1.295 0 000 1.84 1.349 1.349 0 001.894 0l5.533-5.427c.246-.242.398-.576.398-.93 0-.353-.133-.687-.398-.93z" fill="#FFF"></path></svg>
</a>
</section>

View File

@@ -0,0 +1,20 @@
<section class="[ member-list ]">
<div class="[ wrapper ]">
{% if teamListItems.length %}
<ol class="[ member-list__items ]" reversed>
{% for item in teamListItems %}
<li class="member-list__item">
<a href="{{ item.data.url }}/" class="">
<img src=" {{ item.data.profile }}" alt="photo de {{ item.data.name }}">
<span class="member-name btn btn-primary">{{ item.data.name }}</span>
</a>
<p>{{ item.data.position }}</p>
{% if item.data.positionInternal %}
<p>{{ item.data.positionInternal }}</p>
{% endif %}
</li>
{% endfor %}
</ol>
{% endif %}
</div>
</section>

View File

@@ -0,0 +1,24 @@
<section class="[ member-list ]">
<div class="[ wrapper ]">
{% if teamListItems.length %}
<ol class="[ member-list__items ]" reversed>
{% for item in teamListItems %}
<li class="member-list__item">
<a href="{{ item.data.url }}/" class="">
<img src=" {{ item.data.profile }}" alt="photo de {{ item.data.name }}">
<span class="member-name btn btn-primary">{{ item.data.name }}</span>
</a>
<p>{{ item.data.position }}</p>
{% if item.data.positionInternal %}
<p>{{ item.data.positionInternal }}</p>
{% endif %}
</li>
{% endfor %}
<li class="member-list__item info">
<p>Vous êtes porteur dun projet entrepreneurial en numérique et nouvelles technologies ?</p>
<a role="button" href="/nous-rejoindre/" class="btn btn-secondary">Rejoignez-nous</a>
</li>
</ol>
{% endif %}
</div>
</section>

View File

@@ -0,0 +1,26 @@
{% if navigation.items %}
<nav id="menu" class="nav" aria-label="{{ariaLabel}}">
<ul class="[ nav__list ]">
{% for item in navigation.items %}
{% set relAttribute = '' %}
{% set currentAttribute = '' %}
{% if item.rel %}
{% set relAttribute = ' rel="' + item.rel + '"' %}
{% endif %}
{% if page.url == item.url %}
{% set currentAttribute = ' aria-current="page"' %}
{% endif %}
{% if page.url == item.url %}
<li class="nav__item active">
{% else %}
<li class="nav__item">
{% endif %}
<a href="{{ item.url | url }}" {{ relAttribute | safe }}{{ currentAttribute | safe }}>{{ item.text }}</a>
</li>
{% endfor %}
</ul>
</nav>
{% endif %}

View File

@@ -0,0 +1,16 @@
<section class="[ partner ]">
<div class="[ wrapper ]">
<p class="[ partner__heading ]">{{ partnersHeading }}</p>
{% if partnersListItems.length %}
<ol class="[ partner__list ]">
{% for item in partnersListItems %}
<li class="partner__list-item">
<a href="{{ item.data.url }}" title="{{ item.data.name }}" target="_blank" rel="noreferrer noopener">
<img src="{{ item.data.thumbnail }}" alt="logo de {{ item.data.name }}">
</a>
</li>
{% endfor %}
</ol>
{% endif %}
</div>
</section>

View File

@@ -0,0 +1,10 @@
<section class="[ news-list ]">
<svg aria-hidden="true" viewBox="0 0 1440 349" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill="#282156" d="M1440 154H0v195h1440z"/><path d="M1440 54.078l-48 12.41c-48 12.41-144 37.23-240 45.53-96 7.989-192 .232-288-29.01C768 54.079 672 4.438 576 .327c-96-4.421-192 37.463-288 45.452-96 8.3-192-16.52-240-28.931L0 4.437V203h1440V54.078z" fill="#282156"/></svg>
<div class="[ wrapper ]">
<div class="news-list__inner">
<h2 class="[ news-list__heading ]">{{ newsListHeading }}</h2>
{% include "partials/components/posts-list.njk" %}
<a href="/posts/" class="return-link">Voir tout</a>
</div>
</div>
</section>

View File

@@ -0,0 +1,28 @@
{% if newsListItems.length %}
<ol class="[ news-list__items ]" reversed>
{% for item in newsListItems %}
{% if item.date.getTime() <= global.now %}
<li class="news-list__item {{ item.data.type }}">
<a href="{{ item.url | url }}" class="news-list__link" style="background-image: url({{ item.data.illustration }});">
{% if item.data.type == 'event' %}
<p class="news-list__item-type">Évènement</p>
{% else %}
<p class="news-list__item-type">Actualité</p>
{% endif %}
<h3 class="news-list__item-heading">{{ item.data.title }}</h3>
<p class="news-list__item-date">
{% if item.data.eventDate %}
<time datetime="{{ item.data.eventDate | w3DateFilter }}">{{ item.data.eventDate | dateFilter }}</time>
{% else %}
<time datetime="{{ item.date | w3DateFilter }}">{{ item.date | dateFilter }}</time>
{% endif %}
{% if item.data.eventTime %}
<time datetime="{{ item.data.eventTime }}">{{ item.data.eventTime }}</time>
{% endif %}
</p>
</a>
</li>
{% endif %}
{% endfor %}
</ol>
{% endif %}

View File

@@ -0,0 +1,62 @@
{% set profilePics = collections.profiles %}
<section class="[ presentation ]">
<div class="[ wrapper ]">
<article>
<div class="content">
<h2>Qui sommes-nous ?</h2>
<p>
Astrolabe CAE est une scop spécialisée dans le développement de <strong>projets</strong> ou de prestation de <strong>services</strong> autour des métiers du <strong>numérique</strong>.
Notre objectif est de favoriser l<strong>autonomie</strong> et l<strong>émancipation</strong> de nos membres sur un modèle déconomie sociale et <strong>solidaire</strong> (ESS).
</p>
</div>
<div class="side-info">
{# <figure> #}
<img src="/images/crew-join.svg" alt="équipage astrolabe" loading="lazy" style="width: 22rem;">
{# </figure> #}
<a role="button" href="/nous-rejoindre/" class="btn btn-primary">Nous rejoindre
<svg width="18" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M17.602 5.823L12.05.376a1.357 1.357 0 00-1.875 0 1.295 1.295 0 000 1.84l3.278 3.235H1.326C.587 5.451 0 6.027 0 6.752s.587 1.302 1.326 1.302h12.127l-3.278 3.215a1.295 1.295 0 000 1.84 1.349 1.349 0 001.894 0l5.533-5.427c.246-.242.398-.576.398-.93 0-.353-.133-.687-.398-.93z" fill="#111"></path></svg>
</a>
</div>
</article>
<article>
<div class="content">
<h2>Communs numérique</h2>
<p>
Chez Astrolabe nous aimons et faisons la promotion du <a href="https://fr.wikipedia.org/wiki/Logiciel_libre" target="_blank" rel="noreferrer noopener">logiciel libre</a>. Nos sommes membres d<a href="http://www.alliance-libre.org/" target="_blank" rel="noreferrer noopener">Alliance Libre</a>
et nous mettons nos documents et projets internes à disposition sur <a href="https://git.astrolabe.coop/explore/repos" target="_blank" rel="noreferrer noopener">notre instance Gitea</a>.
</p>
</div>
<div class="side-info">
<figure>
<img src="/images/gitea.svg" alt="logo Gitea" loading="lazy" width="100" height="100">
</figure>
<a role="button" href="https://git.astrolabe.coop/explore/repos" class="btn btn-primary btn-icon" target="_blank" rel="noreferrer noopener">Gitea</a>
</div>
</article>
<article>
<div class="content">
<h2>Des profils variés</h2>
<p>
Nos coopérateurs possèdent des compétences propres allant de développement linux embarqué au web design et créent ainsi la <b>pluralité</b> de nos prestations.
<br><br>
Nous sommes également <b>fournisseur de service SAAS</b> de la solution logicielle libre de gestion de CAE <a href="https://www.baloop-erp.fr/" target="_blank" rel="noreferrer noopener">Baloop</a>.
<br><br>
Nous sommes détenteur de l'<a href="https://www.astrolabe.coop/posts/agrement-cir-2024/" target="_blank" rel="noreferrer noopener">Agrément CIR</a> utile pour nos membres qui travaillent dans le domaine de la R&D.
</p>
</div>
<div class="side-info">
<ul class="profile-preview">
{% for profile in profilePics %}
<li>
<a href="{{ profile.data.url }}/" title="{{ profile.data.name }}">
<img src="{{ profile.data.profile }}" alt="photo de {{ profile.data.name }}">
</a>
</li>
{% endfor %}
</ul>
<a role="button" href="/equipe/" class="btn btn-primary">Voir l'équipe</a>
</div>
</article>
</div>
</section>