- ChatbotV2.vue : Vue island, thread chat (input + messages bot/user), persistance sessionStorage, bandeau beta '120 fiches AEP, RAG-PE bientot', gestion erreurs 429/502/504 ; pas de streaming ni markdown V1 - /api/chatbot.ts : endpoint Astro server proxy POST vers CHATBOT_UPSTREAM (default https://aep.trans-former.fr/api/chatbot), timeout 25s, body { question, history } -> upstream classique chatbot AEP Mistral Small - astro.config.mjs : output 'server' + adapter @astrojs/node standalone (Astro 6 a supprime mode hybrid ; on opt-in prerender sur les pages) - Toutes les pages publiques (index, manifeste, manifeste/commander, a-propos, mentions-legales) ont 'export const prerender = true' - ColCentre.astro : remplace ChatbotPlaceholder par ChatbotV2 dans le tab - .env.example : ajoute CHATBOT_UPSTREAM (V1.5 = switch LightRAG-PE 1 ligne) Decision V1 : endpoint AEP /api/chatbot (classique, repond bien) au lieu de /api/chatbot-v2 qui retourne v2_ready=false ('base vectorielle en cours'). Bandeau beta reste valide ; switch v2 quand ready cote AEP via env var. Note PC8 deploy : Coolify doit booter avec 'node ./dist/server/entry.mjs' (SSR Node standalone) au lieu de servir dist/client/ static. Test end-to-end OK : SSR boot port 4399 + curl POST /api/chatbot -> reponse_texte 800+ chars de l'AEP backend.
115 lines
3.6 KiB
Plaintext
115 lines
3.6 KiB
Plaintext
---
|
|
export const prerender = true;
|
|
|
|
import BaseLayout from '../../layouts/BaseLayout.astro';
|
|
import HamburgerMenu from '../../components/astro/HamburgerMenu.astro';
|
|
---
|
|
<BaseLayout
|
|
title="Commander la version imprimee - Manifeste AEP"
|
|
description="Pre-inscription pour la version imprimee du manifeste Architecture d'Ecologie Politique."
|
|
>
|
|
<HamburgerMenu />
|
|
|
|
<main class="min-h-screen bg-white">
|
|
<article class="max-w-xl mx-auto px-6 py-16 md:py-24">
|
|
|
|
<header class="mb-10">
|
|
<p class="text-sm uppercase tracking-widest text-neutral-500 mb-3">
|
|
Manifeste imprime
|
|
</p>
|
|
<h1 class="text-3xl md:text-4xl font-semibold text-neutral-900 leading-tight">
|
|
Commander la version imprimee
|
|
</h1>
|
|
</header>
|
|
|
|
<div class="text-neutral-700 text-base md:text-lg leading-relaxed space-y-5">
|
|
<p>
|
|
La version imprimee du manifeste sera disponible prochainement ; tirage limite, papier recycle, format A5.
|
|
</p>
|
|
<p>
|
|
Inscrivez-vous pour etre averti-e de la mise en vente. Vous serez prevenu-e en priorite, sans engagement.
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Form pre-inscription (V1 stub, V1.1 cable Listmonk) -->
|
|
<form
|
|
id="manifeste-preinscription"
|
|
class="mt-10 flex flex-col gap-3"
|
|
novalidate
|
|
>
|
|
<label for="email" class="text-sm font-medium text-neutral-700">
|
|
Votre email
|
|
</label>
|
|
<input
|
|
id="email"
|
|
name="email"
|
|
type="email"
|
|
required
|
|
autocomplete="email"
|
|
placeholder="prenom@exemple.fr"
|
|
class="px-4 py-3 border border-neutral-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-neutral-900 focus:border-neutral-900"
|
|
/>
|
|
<button
|
|
type="submit"
|
|
class="mt-2 px-5 py-3 bg-neutral-900 text-white rounded-lg font-medium hover:bg-neutral-700 transition-colors"
|
|
>
|
|
Etre averti-e
|
|
</button>
|
|
<p
|
|
id="form-feedback"
|
|
class="text-sm text-neutral-600 hidden"
|
|
aria-live="polite"
|
|
></p>
|
|
</form>
|
|
|
|
<p class="mt-8 text-sm text-neutral-500">
|
|
<a
|
|
href="/manifeste"
|
|
class="underline underline-offset-2 hover:text-neutral-900 transition-colors"
|
|
>
|
|
← Retour au manifeste
|
|
</a>
|
|
</p>
|
|
|
|
</article>
|
|
</main>
|
|
</BaseLayout>
|
|
|
|
<script>
|
|
// V1 stub : capture email en localStorage, V1.1 = POST Listmonk
|
|
const form = document.getElementById('manifeste-preinscription') as HTMLFormElement | null;
|
|
const feedback = document.getElementById('form-feedback');
|
|
|
|
form?.addEventListener('submit', (e) => {
|
|
e.preventDefault();
|
|
const data = new FormData(form);
|
|
const email = String(data.get('email') || '').trim();
|
|
if (!email || !email.includes('@')) {
|
|
if (feedback) {
|
|
feedback.textContent = 'Merci de saisir un email valide.';
|
|
feedback.classList.remove('hidden');
|
|
feedback.classList.add('text-red-600');
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Stockage local en attendant le cable Listmonk (V1.1)
|
|
try {
|
|
const existing = JSON.parse(
|
|
localStorage.getItem('tf-manifeste-preinscriptions') || '[]'
|
|
);
|
|
existing.push({ email, ts: Date.now() });
|
|
localStorage.setItem('tf-manifeste-preinscriptions', JSON.stringify(existing));
|
|
} catch {
|
|
// mode prive : on ignore
|
|
}
|
|
|
|
if (feedback) {
|
|
feedback.textContent = 'Merci ; vous serez prevenu-e des sa disponibilite.';
|
|
feedback.classList.remove('hidden', 'text-red-600');
|
|
feedback.classList.add('text-green-700');
|
|
}
|
|
form.reset();
|
|
});
|
|
</script>
|