Initial commit: Proyecto Portal ePromos completo con documentación unificada y seguridad base
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
(function () {
|
||||
const ruleta = document.getElementById("ruleta");
|
||||
const puntero = document.getElementById("puntero");
|
||||
|
||||
// Modal confirmación
|
||||
const confirmModal = document.getElementById("confirm-modal");
|
||||
const confirmYes = document.getElementById("confirm-yes");
|
||||
const confirmNo = document.getElementById("confirm-no");
|
||||
|
||||
// Modal agradecimiento
|
||||
const thankModal = document.getElementById("thank-you-modal");
|
||||
const thankTitle = document.getElementById("thank-you-message");
|
||||
const thankDetails = document.getElementById("thank-you-details");
|
||||
const thankCloseBtn = document.getElementById("redirect-button");
|
||||
|
||||
// Fullscreen
|
||||
const fullscreenBtn = document.getElementById("fullscreen-btn");
|
||||
|
||||
let gira = 0;
|
||||
let articuloGanador = "";
|
||||
let estaGirando = false;
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const ruletaId = parseInt(params.get("ruleta_id") || "1", 10) || 1;
|
||||
|
||||
// Fallback local (solo si backend no manda ángulos)
|
||||
const rangosFallback = [
|
||||
{ articulo: "Freidora de aire", inicio: 330, final: 16 },
|
||||
{ articulo: "Articulo plastico", inicio: 15, final: 16 },
|
||||
{ articulo: "Sandwichera", inicio: 150, final: 196 },
|
||||
{ articulo: "Bandana", inicio: 170, final: 16 },
|
||||
{ articulo: "Cubeta", inicio: 20, final: 52 },
|
||||
{ articulo: "Bandana1", inicio: 42, final: 88 },
|
||||
{ articulo: "Beggin'", inicio: 130, final: 160 },
|
||||
{ articulo: "Sobre Pro Plan", inicio: 220, final: 232 },
|
||||
{ articulo: "Plancha", inicio: 150, final: 232 },
|
||||
{ articulo: "Caldero", inicio: 30, final: 194 },
|
||||
{ articulo: "Abanico de piso", inicio: 296, final: 328 },
|
||||
];
|
||||
|
||||
function normaliza(a){ return ((a % 360) + 360) % 360; }
|
||||
function centro(inicio, fin){
|
||||
const i = normaliza(inicio), f = normaliza(fin);
|
||||
if (i === f) return i;
|
||||
if (i < f) return i + (f - i)/2;
|
||||
const span = 360 - i + f;
|
||||
return normaliza(i + span/2);
|
||||
}
|
||||
function buscarRangoLocal(nombre){
|
||||
return rangosFallback.find(r => r.articulo.toLowerCase() === String(nombre).toLowerCase());
|
||||
}
|
||||
|
||||
function mostrarConfirmacion(){ confirmModal.style.display = "block"; }
|
||||
function cerrarConfirmacion(){ confirmModal.style.display = "none"; }
|
||||
|
||||
function mostrarAgradecimiento(nombre){
|
||||
thankTitle.textContent = "🎊🎉¡Felicidades!🎉🎊";
|
||||
thankDetails.textContent = `🎁 Has ganado "${nombre}" 🎁`;
|
||||
thankModal.style.display = "flex";
|
||||
}
|
||||
function ocultarAgradecimiento(){ thankModal.style.display = "none"; }
|
||||
|
||||
function girarA(angulo){
|
||||
gira = 1440 + normaliza(angulo); // 4 vueltas + objetivo
|
||||
estaGirando = true;
|
||||
puntero.style.pointerEvents = "none";
|
||||
ruleta.style.transition = "all 5s ease-out";
|
||||
ruleta.style.transform = `rotate(${gira}deg)`;
|
||||
}
|
||||
|
||||
ruleta.addEventListener("transitionend", function () {
|
||||
ruleta.style.transition = "none";
|
||||
ruleta.style.transform = `rotate(${normaliza(gira)}deg)`;
|
||||
estaGirando = false;
|
||||
puntero.style.pointerEvents = "auto";
|
||||
lanzarConfeti();
|
||||
mostrarAgradecimiento(articuloGanador);
|
||||
});
|
||||
|
||||
async function obtenerIP() {
|
||||
try {
|
||||
const r = await fetch("https://api.ipify.org?format=json");
|
||||
const d = await r.json();
|
||||
return d.ip || "0.0.0.0";
|
||||
} catch { return "0.0.0.0"; }
|
||||
}
|
||||
|
||||
async function obtenerArticuloGanadorYSpin() {
|
||||
const userAgent = navigator.userAgent || "unknown";
|
||||
const ip = await obtenerIP();
|
||||
|
||||
try {
|
||||
const resp = await fetch("api/seleccionar_premio.php", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({
|
||||
user_agent: userAgent,
|
||||
ip_address: ip,
|
||||
ruleta_id: ruletaId,
|
||||
}),
|
||||
});
|
||||
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
|
||||
const data = await resp.json();
|
||||
|
||||
// data esperado:
|
||||
// { ok:true, nombre:"X", inicio:120, fin:160 } (inicio/fin opcionales)
|
||||
articuloGanador = data.nombre || "Premio";
|
||||
|
||||
let angulo = null;
|
||||
if (typeof data.inicio === "number" && typeof data.fin === "number") {
|
||||
angulo = centro(data.inicio, data.fin);
|
||||
} else {
|
||||
const rango = buscarRangoLocal(articuloGanador);
|
||||
angulo = rango ? centro(rango.inicio, rango.final) : Math.floor(Math.random() * 360);
|
||||
}
|
||||
|
||||
girarA(angulo);
|
||||
} catch (err) {
|
||||
console.error("Error al obtener el artículo ganador:", err);
|
||||
estaGirando = false;
|
||||
puntero.style.pointerEvents = "auto";
|
||||
alert("Hubo un problema al obtener el premio. Intenta de nuevo.");
|
||||
}
|
||||
}
|
||||
|
||||
// Interacciones
|
||||
puntero.addEventListener("mousedown", function () {
|
||||
if (estaGirando) return;
|
||||
mostrarConfirmacion();
|
||||
});
|
||||
confirmYes.addEventListener("click", function () {
|
||||
cerrarConfirmacion();
|
||||
if (estaGirando) return;
|
||||
obtenerArticuloGanadorYSpin();
|
||||
});
|
||||
confirmNo.addEventListener("click", function () {
|
||||
cerrarConfirmacion();
|
||||
});
|
||||
thankCloseBtn.addEventListener("click", ocultarAgradecimiento);
|
||||
|
||||
// Fullscreen
|
||||
fullscreenBtn.addEventListener("click", () => {
|
||||
if (!document.fullscreenElement) {
|
||||
document.documentElement.requestFullscreen().catch(console.error);
|
||||
} else {
|
||||
document.exitFullscreen().catch(console.error);
|
||||
}
|
||||
});
|
||||
|
||||
// Confeti
|
||||
function lanzarConfeti() {
|
||||
const duration = 4000;
|
||||
const end = Date.now() + duration;
|
||||
(function frame() {
|
||||
confetti({ particleCount: 7, angle: 60, spread: 55, origin: { x: 0 }, scalar: 1.2 });
|
||||
confetti({ particleCount: 7, angle: 120, spread: 55, origin: { x: 1 }, scalar: 1.2 });
|
||||
if (Date.now() < end) requestAnimationFrame(frame);
|
||||
})();
|
||||
}
|
||||
})();
|
||||
Reference in New Issue
Block a user