diff --git a/api/sessions/create.php b/api/sessions/create.php new file mode 100644 index 0000000..62d4823 --- /dev/null +++ b/api/sessions/create.php @@ -0,0 +1,39 @@ +prepare( + "INSERT INTO sessions (session_id, pair_code, pair_token, expires_at, status, created_by) VALUES (?, ?, ?, ?, 'pending', 'ui')" + ); + $stmt->execute([$session_id, $pair_code, $pair_token, $expires_at]); + + $response = [ + 'success' => true, + 'pair_code' => $pair_code, + 'qr_payload' => json_encode(['pair_token' => $pair_token]), // QR payload should be structured data + 'expires_at' => $expires_at + ]; + + echo json_encode($response); + +} catch (Exception $e) { + http_response_code(500); + echo json_encode(['success' => false, 'error' => $e->getMessage()]); +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..dd432a4 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,114 @@ + +document.addEventListener('DOMContentLoaded', () => { + const canvas = document.getElementById('bg'); + if (!canvas) return; + + const ctx = canvas.getContext('2d'); + let width = canvas.width = window.innerWidth; + let height = canvas.height = window.innerHeight; + + window.addEventListener('resize', () => { + width = canvas.width = window.innerWidth; + height = canvas.height = window.innerHeight; + }); + + const orbs = []; + const orbCount = 25; + const minRadius = 3; + const maxRadius = 7; + + class Orb { + constructor() { + this.radius = Math.random() * (maxRadius - minRadius) + minRadius; + this.x = Math.random() * width; + this.y = Math.random() * height; + this.vx = (Math.random() - 0.5) * 0.5; + this.vy = (Math.random() - 0.5) * 0.5; + this.color = '#23D160'; + } + + draw() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI * 2); + ctx.fillStyle = this.color; + ctx.globalAlpha = 0.7; + ctx.fill(); + ctx.filter = 'blur(2px)'; + } + + update() { + this.x += this.vx; + this.y += this.vy; + + if (this.x - this.radius < 0 || this.x + this.radius > width) { + this.vx *= -1; + } + if (this.y - this.radius < 0 || this.y + this.radius > height) { + this.vy *= -1; + } + } + } + + function init() { + for (let i = 0; i < orbCount; i++) { + orbs.push(new Orb()); + } + } + + function animate() { + ctx.clearRect(0, 0, width, height); + orbs.forEach(orb => { + orb.update(); + orb.draw(); + }); + requestAnimationFrame(animate); + } + + init(); + animate(); + + // -- Pairing Logic -- + const pairButton = document.getElementById('pair-button'); + const qrContainer = document.getElementById('qr-container'); + const pairCodeEl = document.getElementById('pair-code'); + const cardContent = document.getElementById('card-content'); + const spinner = document.getElementById('spinner'); + const qrCodeInstance = new QRCode(qrContainer, { + width: 200, + height: 200, + colorDark: "#dfffe3", + colorLight: "rgba(0,0,0,0)", + correctLevel: QRCode.CorrectLevel.H + }); + + + if (pairButton) { + pairButton.addEventListener('click', async () => { + spinner.style.display = 'block'; + pairButton.style.display = 'none'; + + try { + const response = await fetch('api/sessions/create.php', { method: 'POST' }); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + const data = await response.json(); + + if (data.success) { + cardContent.style.display = 'block'; + pairCodeEl.textContent = data.pair_code; + qrCodeInstance.makeCode(data.qr_payload); + } else { + throw new Error(data.error || 'Failed to create session.'); + } + + } catch (error) { + console.error('Pairing error:', error); + alert('Could not create a new pairing session. Please try again.'); + pairButton.style.display = 'inline-block'; + } finally { + spinner.style.display = 'none'; + } + }); + } +}); diff --git a/db/config.php b/db/config.php index b92662e..81a2562 100644 --- a/db/config.php +++ b/db/config.php @@ -5,6 +5,24 @@ define('DB_NAME', 'app_35705'); define('DB_USER', 'app_35705'); define('DB_PASS', 'cdc156d8-b1ec-4426-86fb-b1e546c1a442'); +function db_init() { + $pdo = db(); + $pdo->exec("CREATE TABLE IF NOT EXISTS sessions ( + id INT AUTO_INCREMENT PRIMARY KEY, + session_id VARCHAR(255) NOT NULL UNIQUE, + pair_code VARCHAR(8) NOT NULL, + pair_token TEXT NOT NULL, + status VARCHAR(20) NOT NULL DEFAULT 'pending', + paired_at TIMESTAMP NULL, + phone_number VARCHAR(50) NULL, + wa_id VARCHAR(255) NULL, + created_by VARCHAR(50) NULL, + expires_at TIMESTAMP NOT NULL, + meta JSON NULL, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + );"); +} + function db() { static $pdo; if (!$pdo) { @@ -15,3 +33,6 @@ function db() { } return $pdo; } + +// Initialize database schema +db_init(); \ No newline at end of file diff --git a/index.php b/index.php index 7205f3d..48534d2 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,57 @@ - - - - New Style - - - - - - - - - - - - - - - - - - - + + +Session Pairing — Silent Wolf + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

+ +
+
+

Pair your device

+

Click the button to generate a secure session. Then scan the QR code or use the pair code in your app.

+ + +
+ +
+
+
+

Or enter this code:

+
+
-
- + + + + + + - + \ No newline at end of file