591 lines
23 KiB
HTML
591 lines
23 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Instinct App</title>
|
|
<link href="https://fonts.googleapis.com/css2?family=Syne:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
|
<link rel="canonical" href="https://kingomarnajjar.github.io/instinct/" />
|
|
<link rel="manifest" href="/instinct/manifest.json">
|
|
<style>
|
|
:root {
|
|
--primary-neon: rgba(0, 255, 0, 0.9);
|
|
--light-neon: rgba(0, 255, 0, 0.7);
|
|
--pulse-neon: rgba(0, 255, 0, 0.5);
|
|
--bright-neon: rgba(0, 255, 0, 1);
|
|
--off-neon: #333;
|
|
--neon-shadow: 0 0 7px 4px var(--light-neon), 0 0 7px 4px var(--light-neon) inset;
|
|
--neon-shadow-pulse: 0 0 8px 5px var(--pulse-neon), 0 0 8px 5px var(--pulse-neon) inset;
|
|
--neon-shadow-bright: 0 0 8px 4px var(--bright-neon), 0 0 8px 4px var(--bright-neon) inset;
|
|
--neon-shadow-text: 0 0 7px var(--primary-neon);
|
|
}
|
|
body {
|
|
font-family: 'Syne', sans-serif;
|
|
background-color: #000;
|
|
color: #fff;
|
|
overflow: hidden;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
min-height: 100vh;
|
|
margin: 0;
|
|
flex-direction: column;
|
|
}
|
|
.page {
|
|
display: none;
|
|
text-align: center;
|
|
width: 100%;
|
|
max-width: 600px;
|
|
padding: 20px;
|
|
border-radius: 10px;
|
|
background: rgba(20, 20, 20, 0.8);
|
|
border: 1px solid #fff; /* Added white thin border */
|
|
box-shadow: 0 0 20px rgba(255, 255, 255, 0.15);
|
|
margin-top: 20px;
|
|
}
|
|
.page.active {
|
|
display: block;
|
|
}
|
|
.btn-place, .btn-confirm {
|
|
cursor: pointer;
|
|
padding: 10px 20px;
|
|
border-radius: 5px;
|
|
color: white;
|
|
border: 1px solid #fff;
|
|
background: transparent;
|
|
font-size: 16px;
|
|
font-weight: bold;
|
|
margin-top: 10px;
|
|
transition: background-color 0.2s ease, color 0.2s ease;
|
|
position: relative;
|
|
text-transform: uppercase;
|
|
box-shadow: var(--neon-shadow);
|
|
animation: flicker 10s linear infinite;
|
|
}
|
|
.btn-place:hover, .btn-confirm:hover {
|
|
color: var(--primary-neon);
|
|
border-color: var(--primary-neon);
|
|
text-shadow: var(--neon-shadow-text);
|
|
}
|
|
.floating-bet {
|
|
position: absolute;
|
|
color: white;
|
|
animation: floatBet 1s ease-out forwards;
|
|
pointer-events: none;
|
|
}
|
|
@keyframes floatBet {
|
|
0% {
|
|
opacity: 1;
|
|
transform: translateY(0);
|
|
}
|
|
100% {
|
|
opacity: 0;
|
|
transform: translateY(-50px);
|
|
}
|
|
}
|
|
input[type="email"], input[type="text"], input[type="tel"], input[type="number"], textarea {
|
|
width: calc(100% - 40px);
|
|
padding: 10px;
|
|
border-radius: 5px;
|
|
border: 1px solid #fff;
|
|
background-color: #222;
|
|
color: #fff;
|
|
margin-top: 10px;
|
|
font-weight: 300; /* Lighter font */
|
|
line-height: 1.5; /* Taller text */
|
|
}
|
|
.avatars img {
|
|
width: 60px;
|
|
height: 60px;
|
|
margin: 10px;
|
|
cursor: pointer;
|
|
border-radius: 50%;
|
|
border: 2px solid transparent;
|
|
transition: transform 0.2s, border-color 0.2s;
|
|
}
|
|
.avatars img:hover {
|
|
transform: scale(1.1);
|
|
border-color: #fff;
|
|
}
|
|
.video-frame {
|
|
position: relative;
|
|
width: 100%;
|
|
max-width: 600px;
|
|
height: 300px;
|
|
border-radius: 10px;
|
|
margin: 0 auto; /* Centers the video frame */
|
|
overflow: hidden; /* Ensures no overflow from the video */
|
|
}
|
|
.live-indicator {
|
|
position: absolute;
|
|
top: 10px;
|
|
right: 10px;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
color: #fff;
|
|
background-color: #ff0000;
|
|
padding: 5px 10px;
|
|
border-radius: 5px;
|
|
animation: flash 1s infinite;
|
|
z-index: 20; /* Ensures it is above the video */
|
|
}
|
|
.countdown {
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate(-50%, -50%);
|
|
font-size: 48px;
|
|
font-weight: 700;
|
|
z-index: 10;
|
|
color: #FFF; /* Ensures visibility on top of any background */
|
|
}
|
|
.bet-buttons {
|
|
display: flex;
|
|
justify-content: space-around;
|
|
margin: 20px 0;
|
|
}
|
|
@keyframes flash {
|
|
0%, 50%, 100% {
|
|
opacity: 1;
|
|
}
|
|
25%, 75% {
|
|
opacity: 0;
|
|
}
|
|
}
|
|
@keyframes flicker {
|
|
0% {
|
|
box-shadow: var(--neon-shadow);
|
|
}
|
|
45% {
|
|
box-shadow: var(--neon-shadow-pulse);
|
|
}
|
|
90% {
|
|
box-shadow: var(--neon-shadow);
|
|
border-color: var(--primary-neon);
|
|
color: var(--primary-neon);
|
|
text-shadow: var(--neon-shadow-text);
|
|
}
|
|
90.01% {
|
|
box-shadow: none;
|
|
border-color: var(--off-neon);
|
|
color: var(--off-neon);
|
|
text-shadow: none;
|
|
}
|
|
94% {
|
|
box-shadow: none;
|
|
border-color: var(--off-neon);
|
|
}
|
|
94.01% {
|
|
box-shadow: var(--neon-shadow);
|
|
border-color: var(--primary-neon);
|
|
}
|
|
95% {
|
|
box-shadow: var(--neon-shadow);
|
|
border-color: var (--primary-neon);
|
|
}
|
|
95.01% {
|
|
box-shadow: none;
|
|
border-color: var(--off-neon);
|
|
}
|
|
95.5% {
|
|
box-shadow: none;
|
|
border-color: var(--off-neon);
|
|
}
|
|
95.51% {
|
|
box-shadow: var(--neon-shadow-bright);
|
|
border-color: var(--primary-neon);
|
|
}
|
|
100% {
|
|
box-shadow: var(--neon-shadow);
|
|
border-color: var(--primary-neon);
|
|
}
|
|
}
|
|
.live-chat-btn {
|
|
position: fixed;
|
|
bottom: 20px;
|
|
right: 20px;
|
|
font-size: 18px;
|
|
font-weight: bold;
|
|
color: #fff;
|
|
background-color: #000;
|
|
padding: 10px 15px;
|
|
border-radius: 50px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
z-index: 30; /* Ensures it is above other elements */
|
|
border: 1px solid #fff;
|
|
}
|
|
.live-chat-btn:hover {
|
|
background-color: #333;
|
|
}
|
|
.live-chat-popup {
|
|
position: fixed;
|
|
bottom: 80px;
|
|
right: 20px;
|
|
width: calc(100% - 40px);
|
|
max-width: 400px;
|
|
height: 50%;
|
|
max-height: 400px;
|
|
background: rgba(0, 0, 0, 0.8);
|
|
border: 1px solid #fff; /* Added white thin border */
|
|
border-radius: 10px;
|
|
padding: 10px;
|
|
display: none;
|
|
flex-direction: column;
|
|
z-index: 40; /* Ensures it is above the chat button */
|
|
overflow-y: scroll; /* Enable scrolling */
|
|
}
|
|
.live-chat-popup.active {
|
|
display: flex;
|
|
}
|
|
.live-chat-popup .chat-messages {
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
margin-bottom: 10px;
|
|
}
|
|
.live-chat-popup .chat-input {
|
|
display: flex;
|
|
align-items: center;
|
|
}
|
|
.live-chat-popup .chat-input textarea {
|
|
flex: 1;
|
|
margin-right: 10px;
|
|
padding: 5px;
|
|
border-radius: 5px;
|
|
border: 1px solid #fff;
|
|
background-color: #222;
|
|
color: #fff;
|
|
resize: none;
|
|
}
|
|
.live-chat-popup .chat-input button {
|
|
padding: 10px 20px;
|
|
border-radius: 5px;
|
|
color: white;
|
|
border: 1px solid #fff;
|
|
background: #007bff;
|
|
cursor: pointer;
|
|
}
|
|
.live-chat-popup .chat-input button:hover {
|
|
background: #0056b3;
|
|
}
|
|
.live-chat-popup .message {
|
|
color: #fff;
|
|
background: rgba(255, 255, 255, 0.1);
|
|
padding: 5px;
|
|
margin-bottom: 5px;
|
|
border-radius: 5px;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<!-- Page 1: Email Input -->
|
|
<div id="page1" class="page active">
|
|
<h1 class="text-2xl font-bold text-center mb-4">Instinct</h1>
|
|
<input type="email" id="email" placeholder="Enter your email" required>
|
|
<button class="btn-place" onclick="navigateTo('page2')">Enter</button>
|
|
<!-- Toggle for validation bypass -->
|
|
<label>
|
|
<input type="checkbox" id="bypassValidation" /> Bypass validation for testing
|
|
</label>
|
|
</div>
|
|
<!-- Page 2: User Info -->
|
|
<div id="page2" class="page">
|
|
<h1 class="text-2xl font-bold text-center mb-4">Welcome, <span id="userEmail"></span></h1>
|
|
<h2 class="text-xl text-center mb-4">Setup your account</h2>
|
|
<input type="text" id="name" placeholder="Name" required>
|
|
<input type="tel" id="phone" placeholder="Phone" required>
|
|
<button class="btn-place" onclick="saveUserData()">Next</button>
|
|
</div>
|
|
<!-- Page 3: Avatar Selection -->
|
|
<div id="page3" class="page">
|
|
<h2 class="text-xl text-center mb-4">Choose your avatar</h2>
|
|
<div class="avatars flex justify-center gap-4">
|
|
<!-- Avatars will be dynamically generated here -->
|
|
</div>
|
|
<button class="btn-place" onclick="navigateTo('page4')">Next</button>
|
|
</div>
|
|
<!-- Page 4: Set Default Bet Size -->
|
|
<div id="page4" class="page">
|
|
<h2 class="text-xl text-center mb-4">Set Default Bet Size</h2>
|
|
<input type="number" id="defaultBetSize" placeholder="Enter default bet size" required>
|
|
<button class="btn-place" onclick="navigateTo('page5')">Next</button>
|
|
</div>
|
|
<!-- Page 5: Video, Bet Buttons, and Balance -->
|
|
<div id="page5" class="page">
|
|
<h2 class="text-xl text-center mb-4">Your Balance: $<span id="userBalance">0</span></h2>
|
|
<div class="video-frame mb-4">
|
|
<div class="countdown" id="countdown">5</div>
|
|
<div class="live-indicator">LIVE</div>
|
|
<!-- iframe is now dynamically added by the script to control timing -->
|
|
</div>
|
|
<div class="bet-buttons">
|
|
<button class="btn-place" onclick="placeBet('Lion')">Bet Lion</button>
|
|
<button class="btn-confirm" onclick="placeBet('Giraffe')">Bet Giraffe</button>
|
|
</div>
|
|
<div>
|
|
<p>Total Bets on Lion: <span id="totalBetsLion">0</span></p>
|
|
<p>Total Bets on Buffalo: <span id="totalBetsBuffalo">0</span></p>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="live-chat-btn" onclick="toggleChatPopup()">💬 Live Chat</div>
|
|
|
|
<div class="live-chat-popup" id="liveChatPopup">
|
|
<div class="chat-messages" id="liveMessages"></div>
|
|
<div class="chat-input">
|
|
<textarea id="chatBox" placeholder="Type your message..." onkeydown="if(event.keyCode==13){sendChatMessage(event)}"></textarea>
|
|
<button onclick="sendChatMessage(event)">Send</button>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const WORKER_URL = 'https://instinct-api.yazdani.dev'; // Updated API URL
|
|
let userEmail = '';
|
|
let defaultBetSize = 0;
|
|
let eventID = 98; // Set the event ID to a fixed value
|
|
|
|
async function navigateTo(pageId) {
|
|
document.querySelectorAll('.page').forEach(page => {
|
|
page.classList.remove('active');
|
|
});
|
|
document.getElementById(pageId).classList.add('active');
|
|
if (pageId === 'page2') {
|
|
if (!document.getElementById('bypassValidation').checked) {
|
|
await fetchUserData();
|
|
}
|
|
} else if (pageId === 'page3') {
|
|
generateRandomAvatars();
|
|
} else if (pageId === 'page5') {
|
|
userEmail = document.getElementById('email').value;
|
|
defaultBetSize = document.getElementById('defaultBetSize').value;
|
|
startCountdown(5);
|
|
await fetchUserBalance();
|
|
await fetchTotalBets();
|
|
}
|
|
}
|
|
|
|
function startCountdown(duration) {
|
|
var timer = duration, seconds;
|
|
var countdownElement = document.getElementById('countdown');
|
|
var videoFrame = document.querySelector('.video-frame');
|
|
countdownElement.style.display = 'block';
|
|
countdownElement.textContent = duration;
|
|
|
|
var countdownTimer = setInterval(function () {
|
|
seconds = parseInt(timer % 60, 10);
|
|
countdownElement.textContent = seconds;
|
|
|
|
if (--timer < 0) {
|
|
countdownElement.style.display = 'none';
|
|
clearInterval(countdownTimer);
|
|
// Only create and display the video after the countdown finishes
|
|
var iframe = document.createElement('iframe');
|
|
iframe.src = "https://customer-0sb72e7akfw9m0dg.cloudflarestream.com/7d7cb4e7e6ead747b72073c3824a9d3f/iframe?preload=true&autoplay=true&poster=https%3A%2F%2Fcustomer-0sb72e7akfw9m0dg.cloudflarestream.com%2F7d7cb4e7e6ead747b72073c3824a9d3f%2Fthumbnails%2Fthumbnail.jpg%3Ftime%3D%26height%3D600&controls=false";
|
|
iframe.style.cssText = 'border: none; position: absolute; top: 0; left: 0; height: 100%; width: 100%;';
|
|
iframe.allow = "accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;";
|
|
iframe.allowfullscreen = true;
|
|
videoFrame.appendChild(iframe);
|
|
|
|
// Listen for the end of the first video
|
|
iframe.onload = function () {
|
|
var firstVideo = iframe.contentWindow.document.querySelector('video');
|
|
if (firstVideo) {
|
|
firstVideo.onended = function () {
|
|
playEndingVideo(videoFrame);
|
|
};
|
|
}
|
|
};
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
function playEndingVideo(videoFrame) {
|
|
// Remove the first video
|
|
videoFrame.innerHTML = '';
|
|
// Add the ending video
|
|
var iframe = document.createElement('iframe');
|
|
iframe.src = "https://customer-0sb72e7akfw9m0dg.cloudflarestream.com/ea82c3f795b5a68a78ef3d44c85a689f/watch/iframe?preload=true&autoplay=true";
|
|
iframe.style.cssText = 'border: none; position: absolute; top: 0; left: 0; height: 100%; width: 100%;';
|
|
iframe.allow = "accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;";
|
|
iframe.allowfullscreen = true;
|
|
videoFrame.appendChild(iframe);
|
|
}
|
|
|
|
function toggleChatPopup() {
|
|
var chatPopup = document.getElementById('liveChatPopup');
|
|
chatPopup.classList.toggle('active');
|
|
}
|
|
|
|
function sendChatMessage(event) {
|
|
event.preventDefault();
|
|
var message = document.getElementById('chatBox').value.trim();
|
|
if (message) {
|
|
var messageElement = document.createElement('div');
|
|
messageElement.classList.add('message');
|
|
messageElement.textContent = message;
|
|
document.getElementById('liveMessages').appendChild(messageElement);
|
|
document.getElementById('chatBox').value = ''; // Clear the input after sending
|
|
}
|
|
}
|
|
|
|
async function fetchUserData() {
|
|
const email = document.getElementById('email').value;
|
|
const response = await fetch(`${WORKER_URL}/user?email=${encodeURIComponent(email)}`, { method: 'GET' });
|
|
if (response.ok) {
|
|
const userData = await response.json();
|
|
document.getElementById('name').value = userData.name || '';
|
|
document.getElementById('phone').value = userData.phone || '';
|
|
document.getElementById('userEmail').textContent = userData.email || '';
|
|
} else {
|
|
console.error('Failed to fetch user data');
|
|
}
|
|
}
|
|
|
|
async function saveUserData() {
|
|
if (document.getElementById('bypassValidation').checked) {
|
|
navigateTo('page3'); // Skip validation and navigate to next page
|
|
return;
|
|
}
|
|
|
|
const userData = {
|
|
email: document.getElementById('email').value,
|
|
name: document.getElementById('name').value,
|
|
phone: document.getElementById('phone').value
|
|
};
|
|
const response = await fetch(`${WORKER_URL}/signup`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(userData)
|
|
});
|
|
if (response.ok) {
|
|
navigateTo('page3'); // Navigate to the next page after saving data
|
|
} else {
|
|
console.error('Failed to save user data');
|
|
}
|
|
}
|
|
|
|
function selectAvatar(avatarId) {
|
|
console.log('Selected avatar:', avatarId);
|
|
}
|
|
|
|
async function placeBet(team) {
|
|
const response = await fetch(`${WORKER_URL}/bet`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
email: userEmail,
|
|
event: eventID, // Use the eventID variable here
|
|
team: team === 'Lion' ? 0 : 1,
|
|
amount: defaultBetSize
|
|
})
|
|
});
|
|
if (response.ok) {
|
|
console.log('Bet placed successfully');
|
|
await fetchUserBalance();
|
|
await fetchTotalBets();
|
|
animateBet(team);
|
|
} else {
|
|
console.error('Failed to place bet');
|
|
}
|
|
}
|
|
|
|
function animateBet(team) {
|
|
const betButton = document.querySelector(team === 'Lion' ? '.btn-place' : '.btn-confirm');
|
|
const betAmount = document.createElement('div');
|
|
betAmount.classList.add('floating-bet');
|
|
betAmount.textContent = `$${defaultBetSize}`;
|
|
document.body.appendChild(betAmount);
|
|
const rect = betButton.getBoundingClientRect();
|
|
betAmount.style.left = `${rect.left + window.scrollX}px`;
|
|
betAmount.style.top = `${rect.top + window.scrollY}px`;
|
|
setTimeout(() => {
|
|
betAmount.remove();
|
|
}, 1000);
|
|
}
|
|
|
|
async function fetchUserBalance() {
|
|
const response = await fetch(`${WORKER_URL}/user?email=${encodeURIComponent(userEmail)}`, { method: 'GET' });
|
|
if (response.ok) {
|
|
const userData = await response.json();
|
|
document.getElementById('userBalance').textContent = userData.balance || '0';
|
|
// Disable bet buttons if balance is insufficient
|
|
const betButtons = document.querySelectorAll('.bet-buttons button');
|
|
if (userData.balance < defaultBetSize) {
|
|
betButtons.forEach(button => button.disabled = true);
|
|
} else {
|
|
betButtons.forEach(button => button.disabled = false);
|
|
}
|
|
} else {
|
|
console.error('Failed to fetch user balance');
|
|
}
|
|
}
|
|
|
|
async function fetchTotalBets() {
|
|
const response = await fetch(`${WORKER_URL}/totals?event=${eventID}`, { method: 'GET' });
|
|
if (response.ok) {
|
|
const totals = await response.json();
|
|
const totalBetsLion = totals.bets.find(bet => bet.team === 0)?.total || 0;
|
|
const totalBetsBuffalo = totals.bets.find(bet => bet.team === 1)?.total || 0;
|
|
document.getElementById('totalBetsLion').textContent = totalBetsLion;
|
|
document.getElementById('totalBetsBuffalo').textContent = totalBetsBuffalo;
|
|
} else {
|
|
console.error('Failed to fetch total bets');
|
|
}
|
|
}
|
|
|
|
function generateRandomAvatars() {
|
|
const avatarsContainer = document.querySelector('.avatars');
|
|
avatarsContainer.innerHTML = ''; // Clear existing avatars
|
|
|
|
for (let i = 0; i < 4; i++) {
|
|
const avatarId = Math.floor(Math.random() * 1000000);
|
|
const img = document.createElement('img');
|
|
img.src = `https://api.multiavatar.com/${avatarId}.png`;
|
|
img.alt = `Avatar ${i + 1}`;
|
|
img.onclick = () => selectAvatar(avatarId);
|
|
avatarsContainer.appendChild(img);
|
|
}
|
|
}
|
|
|
|
// Add to Home Screen Prompt
|
|
let deferredPrompt;
|
|
window.addEventListener('beforeinstallprompt', (e) => {
|
|
e.preventDefault();
|
|
deferredPrompt = e;
|
|
showInstallPromotion();
|
|
});
|
|
|
|
function showInstallPromotion() {
|
|
const installBtn = document.createElement('button');
|
|
installBtn.textContent = 'Add to Home Screen';
|
|
installBtn.className = 'install-btn';
|
|
document.body.appendChild(installBtn);
|
|
|
|
installBtn.addEventListener('click', () => {
|
|
installBtn.style.display = 'none';
|
|
deferredPrompt.prompt();
|
|
deferredPrompt.userChoice.then((choiceResult) => {
|
|
if (choiceResult.outcome === 'accepted') {
|
|
console.log('User accepted the A2HS prompt');
|
|
} else {
|
|
console.log('User dismissed the A2HS prompt');
|
|
}
|
|
deferredPrompt = null;
|
|
});
|
|
});
|
|
}
|
|
|
|
// Service Worker Registration
|
|
if ('serviceWorker' in navigator) {
|
|
window.addEventListener('load', () => {
|
|
navigator.serviceWorker.register('/instinct/service-worker.js').then((registration) => {
|
|
console.log('Service Worker registered with scope:', registration.scope);
|
|
}, (err) => {
|
|
console.log('Service Worker registration failed:', err);
|
|
});
|
|
});
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|