# 🎰 Ruleta con PIN

Aplicación web de **ruleta de premios** protegida por PIN, con registro de resultados vía backend PHP y base de datos MySQL/MariaDB.

Desarrollada para campañas promocionales de **Gomez Lee Marketing (GLM)**.

---

## 📋 Tabla de Contenidos

- [Características](#-características)
- [Requisitos](#-requisitos)
- [Instalación](#-instalación)
- [Configuración de Base de Datos](#-configuración-de-base-de-datos)
- [Configuración de PINs](#-configuración-de-pins)
- [Estructura del Proyecto](#-estructura-del-proyecto)
- [Flujo del Sistema](#-flujo-del-sistema)
- [Operación Diaria](#-operación-diaria)
- [Solución de Problemas](#-solución-de-problemas)

---

## ✨ Características

- **Autenticación por PIN** antes de girar la ruleta
- **Selección aleatoria ponderada** de premios según probabilidades configurables
- **Control de stock** por premio y cupo global de giros
- **Registro de auditoría** con IP, user agent y timestamp
- **Animación fluida** de ruleta con CSS transitions
- **Efecto confeti** al ganar (canvas-confetti)
- **Diseño responsive** con soporte de pantalla completa
- **Redirección a formulario JotForm** para reclamar el premio

---

## 📦 Requisitos

| Componente | Versión mínima |
|---|---|
| PHP | 8.0+ con extensión `mysqli` |
| MySQL / MariaDB | 5.7+ / 10.3+ |
| Servidor Web | Apache (XAMPP) o Nginx |
| Navegador | Cualquier navegador moderno con JS habilitado |

> La aplicación requiere acceso HTTP saliente a `https://api.ipify.org` para obtener la IP pública del usuario.

---

## 🚀 Instalación

### 1. Clonar el repositorio

```bash
git clone https://git.digitalcompass.agency/Isaac_Aracena/ruleta-con-pin.git
```

### 2. Colocar en el servidor web

- **Windows (XAMPP):** Copiar a `C:\xampp\htdocs\ruleta\`
- **Linux (Apache/Nginx):** Copiar a `/var/www/ruleta/`

### 3. Configurar credenciales de BD

```bash
cp config.example.php config.php
```

Editar `config.php` con los datos reales:

```php
$servername = "localhost";
$username   = "tu_usuario";
$password   = "tu_contraseña";
$dbname     = "ruleta_db";
```

> ⚠️ **`config.php` está en `.gitignore`** y nunca se versiona. Las credenciales quedan solo en tu servidor.

### 4. Crear la base de datos

Ejecutar el script SQL incluido:

```bash
mysql -u root -p < database/schema.sql
```

### 5. Cargar premios y PINs

Ver sección [Configuración de PINs](#-configuración-de-pins).

### 6. Probar

Abrir `http://localhost/ruleta/index.html` e ingresar un PIN válido.

---

## 🗄️ Configuración de Base de Datos

### Tablas

| Tabla | Descripción |
|---|---|
| `girospermitidos` | Control global de cupo de giros (1 registro, id=1) |
| `premiosnew` | Premios con stock, probabilidad y PIN asignado |
| `premiosentregados` | Auditoría de premios entregados |

### Ajustar cupo de giros

```sql
UPDATE girospermitidos SET cantidad = 50000 WHERE id = 1;
```

### Cargar un premio

```sql
INSERT INTO premiosnew (nombre, probabilidad, cantidad, inicio, final, nombre_usuario)
VALUES ('Gorra', 1.0, 10, 0, 45, '1989');
```

- `inicio` / `final` = ángulos en la imagen de la ruleta (0–360°)
- `nombre_usuario` = el PIN que podrá ganar este premio
- `cantidad` = stock disponible

---

## 🔑 Configuración de PINs

Los PINs deben estar sincronizados en **dos lugares**:

1. **Base de datos:** columna `premiosnew.nombre_usuario`
2. **Frontend:** array `validPins` en `script.js` (línea 35)

```javascript
const validPins = ["1989", "4708", "6823", "7591", ...];
```

> Si un PIN está en la BD pero no en `validPins`, el modal del frontend no dejará pasar.
> Si un PIN está en `validPins` pero no en la BD, el backend responderá "No hay premios disponibles".

---

## 📁 Estructura del Proyecto

```
ruleta-con-pin/
├── index.html            # Página principal (modal PIN + ruleta)
├── script.js             # Lógica del juego, validación, animación
├── style.css             # Estilos, responsive, modales
├── seleccionar_premio.php # Backend: selección aleatoria + registro BD
├── config.example.php    # Plantilla de configuración de BD
├── config.php            # ⛔ Credenciales reales (no versionado)
├── database/
│   └── schema.sql        # Script de creación de BD y tablas
└── img/
    ├── background.png    # Fondo de la página
    ├── ruleta.png        # Imagen de la ruleta
    ├── puntero.png       # Flecha/puntero de la ruleta
    ├── fullscreen-icon.png
    ├── BANNER-1.png      # Logo GLM
    ├── BANNER-2.png      # Banner lateral
    └── BANNER-4.png      # Banner inferior
```

---

## 🔄 Flujo del Sistema

```
Usuario → Ingresa PIN → Validación frontend (validPins)
  → Muestra ruleta → Click en puntero → Obtiene IP (ipify)
  → POST a seleccionar_premio.php
    → Verifica cupo global (girospermitidos)
    → Selecciona premio aleatorio ponderado (premiosnew)
    → Descuenta stock + registra en premiosentregados
    → Retorna JSON {id, nombre, inicio, final}
  → Anima ruleta al ángulo del premio
  → Confeti 🎊 + Modal "¡Ganaste!"
  → Botón "Ir al formulario" → JotForm
```

---

## 📊 Operación Diaria

### Agregar PINs/premios

1. Insertar en `premiosnew` con el PIN deseado
2. Agregar el PIN al array `validPins` en `script.js`

### Consultar premios entregados

```sql
SELECT * FROM premiosentregados ORDER BY created_at DESC;
```

### Consultar stock restante

```sql
SELECT nombre, nombre_usuario, cantidad FROM premiosnew;
```

### Aumentar cupo de giros

```sql
UPDATE girospermitidos SET cantidad = cantidad + 1000 WHERE id = 1;
```

---

## 🔧 Solución de Problemas

| Problema | Causa |
|---|---|
| "Conexión fallida…" | Credenciales en `config.php` incorrectas o BD inaccesible |
| "No hay premios disponibles" | No hay fila en `premiosnew` con ese PIN y `cantidad > 0` |
| No pasa del modal de PIN | El PIN no está en `validPins` en `script.js` |
| No registra IP | Navegador no puede acceder a `https://api.ipify.org` |
| "Se ha alcanzado el límite de giros" | `girospermitidos.cantidad` llegó a 0 |

---

## 🛡️ Notas de Seguridad

- Las credenciales de BD se cargan desde `config.php` (no versionado)
- Los `INSERT` usan **prepared statements** para prevenir SQL injection
- La validación de PINs en el frontend es solo UX; la validación real ocurre en el backend vía `nombre_usuario` en la consulta SQL

---


