<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Générateur d'annonces immobilières</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: system-ui, sans-serif; background: #f5f5f3; color: #1a1a1a; min-height: 100vh; padding: 2rem 1rem; }
.card { background: #fff; border: 1px solid #e0e0d8; border-radius: 12px; padding: 1.5rem; max-width: 680px; margin: 0 auto; }
h1 { font-size: 20px; font-weight: 500; margin-bottom: 0.25rem; }
.sub { font-size: 13px; color: #888; margin-bottom: 1.5rem; }
input, textarea { width: 100%; padding: 9px 12px; font-size: 14px; border: 1px solid #ddd; border-radius: 8px; font-family: inherit; background: #fff; color: #1a1a1a; }
input:focus, textarea:focus { outline: 2px solid #333; outline-offset: 1px; }
textarea { min-height: 80px; resize: vertical; }
.row { display: flex; gap: 10px; align-items: center; }
button { padding: 9px 18px; font-size: 14px; border: 1px solid #ccc; border-radius: 8px; background: #fff; cursor: pointer; font-family: inherit; }
button:hover { background: #f5f5f3; }
button:disabled { opacity: 0.4; cursor: not-allowed; }
button.primary { background: #1a1a1a; color: #fff; border-color: #1a1a1a; }
button.primary:hover { background: #333; }
.hint { font-size: 12px; color: #aaa; margin-top: 6px; }
.error { color: #c0392b; font-size: 13px; margin-top: 8px; }
.badge { background: #f5f5f3; border-radius: 6px; padding: 8px 12px; font-size: 13px; color: #555; margin-bottom: 16px; }
.section-title { font-size: 14px; font-weight: 500; margin-bottom: 4px; }
.section-sub { font-size: 13px; color: #888; margin-bottom: 1rem; }
.field { margin-bottom: 12px; }
label { font-size: 13px; color: #666; display: block; margin-bottom: 4px; }
.result-box { border: 1px solid #e0e0d8; border-radius: 10px; padding: 1.25rem; }
.result-title { font-weight: 500; font-size: 15px; margin-bottom: 1rem; }
.result-body { font-size: 13px; line-height: 1.8; white-space: pre-wrap; margin-bottom: 1rem; }
.result-mentions { font-size: 12px; color: #666; line-height: 1.7; white-space: pre-wrap; border-top: 1px solid #eee; padding-top: 0.75rem; }
.actions { display: flex; gap: 8px; margin-bottom: 12px; }
</style>
</head>
<body>
<div class="card">
<h1>Générateur d'annonces immobilières</h1>
<p class="sub">Saisissez la référence Apimo du bien pour générer une annonce optimale.</p>
<div id="step-input">
<div class="row">
<input id="ref-input" type="text" placeholder="Ex : SC2-1234, AP1-567, BP1-890, SR1-123…" />
<button class="primary" id="btn-search" onclick="startSearch()">Rechercher →</button>
</div>
<p class="hint">SC2 → Arcachon · AP1/CF1 → Andernos · BP1/BC1 → Bordeaux · SR1 → Hossegor</p>
<p class="error" id="err-input"></p>
</div>
<div id="step-questions" style="display:none">
<div class="badge" id="badge-ref"></div>
<p class="section-title">Informations complémentaires</p>
<p class="section-sub">Ces éléments ne figurent pas dans Apimo. Répondez à ceux que vous pouvez (optionnel).</p>
<div id="questions-list"></div>
<div class="row" style="margin-top:16px">
<button class="primary" onclick="generateFinal()">Générer l'annonce →</button>
<button onclick="reset()">Annuler</button>
</div>
<p class="error" id="err-questions"></p>
</div>
<div id="step-loading" style="display:none;text-align:center;padding:2rem 0;color:#888;font-size:14px">
Génération en cours…
</div>
<div id="step-result" style="display:none">
<div class="actions">
<button onclick="copyAll()">Copier</button>
<button onclick="reset()">Nouveau bien</button>
</div>
<div class="result-box">
<div class="result-title" id="res-titre"></div>
<div class="result-body" id="res-annonce"></div>
<div class="result-mentions" id="res-mentions"></div>
</div>
</div>
</div>
<script>
const WORKER = "https://apimo-proxy.stephanie-collaudin.workers.dev";
const AGENCIES = {
SC2: "10374", AP1: "21117", CF1: "21117",
BP1: "10373", BC1: "10373", SR1: "19342"
};
let currentRef = "";
let currentAgency = "";
let missingQuestions = [];
function getAgency(ref) {
const up = ref.trim().toUpperCase().replace(/[^A-Z0-9]/g, "");
for (const key of Object.keys(AGENCIES)) {
if (up.startsWith(key)) return { id: AGENCIES[key], key };
}
return null;
}
function show(stepId) {
["step-input","step-questions","step-loading","step-result"].forEach(id => {
document.getElementById(id).style.display = id === stepId ? "block" : "none";
});
}
async function callWorker(ref, agencyId, answers) {
const params = new URLSearchParams({ agency: agencyId, ref: ref.trim().toUpperCase() });
if (answers) params.set("answers", answers);
const res = await fetch(`${WORKER}?${params.toString()}`);
const data = await res.json();
if (data.error) throw new Error(data.error);
return data;
}
async function startSearch() {
const ref = document.getElementById("ref-input").value.trim();
const errEl = document.getElementById("err-input");
errEl.textContent = "";
const agency = getAgency(ref);
if (!agency) { errEl.textContent = "Préfixe non reconnu."; return; }
currentRef = ref;
currentAgency = agency.id;
document.getElementById("btn-search").disabled = true;
show("step-loading");
try {
const data = await callWorker(ref, agency.id, "");
handleResult(data);
} catch(e) {
show("step-input");
errEl.textContent = "Erreur : " + e.message;
}
document.getElementById("btn-search").disabled = false;
}
function handleResult(data) {
if (data.missing && data.missing.length > 0) {
missingQuestions = data.missing;
document.getElementById("badge-ref").textContent = "Bien trouvé · " + currentRef.toUpperCase();
const list = document.getElementById("questions-list");
list.innerHTML = "";
data.missing.forEach((q, i) => {
list.innerHTML += `<div class="field"><label>${q}</label><input type="text" id="q${i}" placeholder="Votre réponse (optionnel)" /></div>`;
});
show("step-questions");
} else {
showResult(data);
}
}
async function generateFinal() {
document.getElementById("err-questions").textContent = "";
const answersStr = missingQuestions.map((q, i) => {
const v = document.getElementById("q"+i)?.value.trim();
return v ? `${q} → ${v}` : "";
}).filter(Boolean).join("\n");
show("step-loading");
try {
const data = await callWorker(currentRef, currentAgency, answersStr);
showResult(data);
} catch(e) {
show("step-questions");
document.getElementById("err-questions").textContent = "Erreur : " + e.message;
}
}
function showResult(data) {
document.getElementById("res-titre").textContent = data.titre || "";
document.getElementById("res-annonce").textContent = data.annonce || "";
document.getElementById("res-mentions").textContent = data.mentions || "";
show("step-result");
}
function copyAll() {
const t = document.getElementById("res-titre").textContent;
const a = document.getElementById("res-annonce").textContent;
const m = document.getElementById("res-mentions").textContent;
navigator.clipboard.writeText(`${t}\n\n${a}\n\n${m}`);
}
function reset() {
document.getElementById("ref-input").value = "";
document.getElementById("err-input").textContent = "";
currentRef = ""; currentAgency = ""; missingQuestions = [];
show("step-input");
}
document.getElementById("ref-input").addEventListener("keydown", e => {
if (e.key === "Enter") startSearch();
});
</script>
</body>
</html>