| Current Path : /home/h/a/p/happyrenas/fun/public/assets/ |
Linux webd005.cluster105.gra.hosting.ovh.net 5.15.206-ovh-vps-grsec-zfs-classid #1 SMP Fri May 15 02:41:25 UTC 2026 x86_64 |
| Current File : /home/h/a/p/happyrenas/fun/public/assets/apps.js |
const $ = (id) => document.getElementById(id);
const state = {
activity: null,
products: [],
product: null,
tarifsUrl: null,
debounce: null
};
function setVisible(el, visible) {
el.hidden = !visible;
}
function setMsg(text, ok = true) {
const box = $("formMsg");
box.textContent = text;
box.style.borderColor = ok ? "rgba(0,0,0,.10)" : "rgba(176,0,32,.35)";
box.style.background = ok ? "rgba(206,195,186,.18)" : "rgba(176,0,32,.08)";
setVisible(box, true);
}
async function apiFetch(url, opts = {}) {
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 12000);
try {
const res = await fetch(url, { ...opts, signal: ctrl.signal });
const data = await res.json().catch(() => ({}));
if (!res.ok) {
throw new Error(data?.error || `HTTP ${res.status}`);
}
return data;
} finally {
clearTimeout(t);
}
}
function openDropdown(items) {
const dd = $("activityResults");
dd.innerHTML = "";
if (!items.length) {
dd.classList.remove("open");
return;
}
for (const it of items) {
const div = document.createElement("div");
div.className = "dd-item";
div.textContent = it.name;
div.dataset.id = it.id;
div.dataset.name = it.name;
div.addEventListener("click", () => selectActivity(it.id, it.name));
dd.appendChild(div);
}
dd.classList.add("open");
}
function closeDropdown() {
$("activityResults").classList.remove("open");
}
function quickchartQrUrl(textOrUrl) {
const s = (textOrUrl || "").trim();
if (!s) return "";
if (s.includes("quickchart.io/qr") && s.includes("format=png")) return s;
const encoded = encodeURIComponent(s);
// URL QuickChart :
return `https://quickchart.io/qr?text=${encoded}&size=360&format=png`;
}
function formatPrice(p) {
const s = String(p ?? "").trim();
if (!s) return "";
return s.includes("€") ? s : `${s}€`;
}
function resetAfterActivity() {
state.products = [];
state.product = null;
$("productSelect").innerHTML = `<option value="">Sélectionner un tarif</option>`;
setVisible($("productBlock"), false);
setVisible($("finalBlock"), false);
setVisible($("qrBlock"), false);
setVisible($("tarifsBlock"), false);
setVisible($("stripeBtn"), false);
setVisible($("formMsg"), false);
}
async function selectActivity(id, name) {
closeDropdown();
$("activitySearch").value = name;
resetAfterActivity();
$("activityLoading").hidden = false;
try {
const activity = await apiFetch(`./api/activity.php?id=${encodeURIComponent(id)}`);
state.activity = activity;
// Bloc 2 infos
$("hebergList").textContent = (activity.liste_heberg || "").trim() || "—";
$("activityAddress").textContent = (activity.full_address || "").trim();
setVisible($("activityInfo"), true);
// Bloc 3 QR
const qr = quickchartQrUrl(activity.qr_mrx);
if (qr) {
$("qrImg").src = qr;
setVisible($("qrBlock"), true);
}
// Bloc 4 Tarifs (non bloquant)
setVisible($("tarifsBlock"), true);
loadTarifsNonBlocking();
// Bloc 5 Produits
setVisible($("productBlock"), true);
await loadProductsForActivity(activity.id);
} catch (e) {
setMsg(`Erreur: ${e.message}`, false);
} finally {
$("activityLoading").hidden = true;
}
}
async function loadTarifsNonBlocking() {
try {
const { url } = await apiFetch("./api/tarifs.php");
state.tarifsUrl = url || "";
const img = $("tarifsImg");
const link = $("tarifsLink");
link.hidden = true;
img.hidden = false;
img.onerror = () => {
img.hidden = true;
if (state.tarifsUrl) {
link.href = state.tarifsUrl;
link.hidden = false;
}
};
if (state.tarifsUrl) img.src = state.tarifsUrl;
} catch (_) {
// pas bloquant, on ne casse pas l’UI
}
}
async function loadProductsForActivity(activityId) {
$("productLoading").hidden = false;
try {
const data = await apiFetch(`./api/products.php?activityId=${encodeURIComponent(activityId)}`);
const items = data.items || [];
state.products = items;
const sel = $("productSelect");
sel.innerHTML = `<option value="">Sélectionner un tarif</option>`;
for (const p of items) {
const opt = document.createElement("option");
opt.value = p.id_produit;
opt.textContent = `${p["désignation"] || p.designation || "Offre"} — ${formatPrice(p.prix)}`;
sel.appendChild(opt);
}
} finally {
$("productLoading").hidden = true;
}
}
function onProductChange() {
const idp = $("productSelect").value;
state.product = state.products.find(p => String(p.id_produit) === String(idp)) || null;
setVisible($("stripeBtn"), false);
setVisible($("formMsg"), false);
setVisible($("finalBlock"), !!state.product);
}
async function onSubmit() {
if (!state.activity || !state.product) return;
const pays = $("paysInput").value.trim();
const urlBooking = $("bookingInput").value.trim();
const hp = $("website").value.trim();
if (!pays) {
setMsg("Veuillez renseigner PAYS.", false);
return;
}
const btn = $("submitBtn");
btn.disabled = true;
try {
const payload = {
activityId: state.activity.id,
productId: state.product.id_produit,
pays,
urlBooking,
website: hp // honeypot
};
const res = await apiFetch("./api/avant-paiement.php", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(payload)
});
setMsg("Enregistré ✅", true);
if (res?.stripeUrl) {
const a = $("stripeBtn");
a.href = res.stripeUrl;
setVisible(a, true);
}
} catch (e) {
setMsg(`Erreur: ${e.message}`, false);
} finally {
btn.disabled = false;
}
}
function initActivitySearch() {
const input = $("activitySearch");
document.addEventListener("click", (ev) => {
if (!ev.target.closest(".field")) closeDropdown();
});
input.addEventListener("input", () => {
const q = input.value.trim();
if (state.debounce) clearTimeout(state.debounce);
state.debounce = setTimeout(async () => {
if (q.length < 1) {
closeDropdown();
return;
}
$("activityLoading").hidden = false;
try {
const data = await apiFetch(`./api/activities.php?query=${encodeURIComponent(q)}&limit=20`);
openDropdown(data.items || []);
} catch (_) {
closeDropdown();
} finally {
$("activityLoading").hidden = true;
}
}, 250);
});
input.addEventListener("focus", () => {
if (input.value.trim().length >= 1) {
input.dispatchEvent(new Event("input"));
}
});
}
document.addEventListener("DOMContentLoaded", () => {
initActivitySearch();
$("productSelect").addEventListener("change", onProductChange);
$("submitBtn").addEventListener("click", onSubmit);
});