|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Booking Confirmation | Event Management</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
|
<style> |
|
.confetti { |
|
position: fixed; |
|
width: 10px; |
|
height: 10px; |
|
background-color: #f00; |
|
opacity: 0.7; |
|
animation: fall linear forwards; |
|
} |
|
|
|
@keyframes fall { |
|
to { |
|
transform: translateY(100vh); |
|
} |
|
} |
|
|
|
.checked-in { |
|
box-shadow: 0 0 10px 3px rgba(34, 197, 94, 0.5); |
|
border: 2px solid #22c55e; |
|
} |
|
|
|
.qr-code { |
|
transition: all 0.3s ease; |
|
} |
|
|
|
.qr-code:hover { |
|
transform: scale(1.05); |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-50 min-h-screen"> |
|
<div class="container mx-auto px-4 py-12"> |
|
|
|
<div class="max-w-4xl mx-auto bg-white rounded-xl shadow-md overflow-hidden transition-all duration-300 hover:shadow-xl"> |
|
<div class="p-1 bg-gradient-to-r from-purple-600 via-pink-500 to-red-500"></div> |
|
|
|
<div class="p-8"> |
|
|
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-8"> |
|
<div> |
|
<div class="flex items-center space-x-2"> |
|
<i class="fas fa-calendar-check text-3xl text-purple-600"></i> |
|
<h1 class="text-3xl font-bold text-gray-800">Booking Confirmed!</h1> |
|
</div> |
|
<p class="text-gray-600 mt-2">Thank you for your booking. Here are your details.</p> |
|
</div> |
|
<div class="mt-4 md:mt-0 bg-purple-100 text-purple-800 px-4 py-2 rounded-lg font-medium"> |
|
<i class="fas fa-bolt mr-1"></i> Status: Confirmed |
|
</div> |
|
</div> |
|
|
|
<div class="border-b border-gray-200 my-6"></div> |
|
|
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-8"> |
|
<div> |
|
<h2 class="text-xl font-semibold text-gray-800 mb-4">Booking Information</h2> |
|
|
|
<div class="space-y-4"> |
|
<div> |
|
<p class="text-sm text-gray-500">Booking ID</p> |
|
<div id="bookingId" class="flex items-center mt-1"> |
|
<span class="font-mono bg-gray-100 px-3 py-1 rounded text-gray-800 text-lg font-bold">#</span> |
|
<button onclick="copyBookingId()" class="ml-2 text-purple-600 hover:text-purple-800 transition"> |
|
<i class="far fa-copy"></i> Copy |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<p class="text-sm text-gray-500">Event Name</p> |
|
<p class="font-medium text-gray-800">LIVE Music Night with The Midnight Stars</p> |
|
</div> |
|
|
|
<div> |
|
<p class="text-sm text-gray-500">Date & Time</p> |
|
<p class="font-medium text-gray-800">June 15, 2023 • 7:00 PM - 10:00 PM</p> |
|
</div> |
|
|
|
<div> |
|
<p class="text-sm text-gray-500">Location</p> |
|
<p class="font-medium text-gray-800">Grand Ballroom, The Plaza Hotel</p> |
|
</div> |
|
|
|
<div> |
|
<p class="text-sm text-gray-500">Number of Guests</p> |
|
<p class="font-medium text-gray-800">4 people</p> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<h2 class="text-xl font-semibold text-gray-800 mb-4">Your Tickets</h2> |
|
|
|
<div id="ticketList" class="space-y-3"> |
|
|
|
</div> |
|
|
|
<div class="mt-6"> |
|
<button onclick="generateAttendeeCodes()" class="flex items-center bg-purple-600 hover:bg-purple-700 text-white px50 py-2 rounded-lg transition"> |
|
<i class="fas fa-qrcode mr-2"></i> Generate Attendee ID Codes |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="attendanceSection" class="mt-12 hidden"> |
|
<div class="border-b border-gray-200 my-6"></div> |
|
|
|
<div class="flex flex-col md:flex-row justify-between items-start md:items-center mb-6"> |
|
<h2 class="text-xl font-semibold text-gray-800">Attendance Confirmation</h2> |
|
<div class="mt-2 md:mt-0 text-sm text-gray-600"> |
|
<i class="fas fa-info-circle mr-1"></i> Share these codes with your attendees |
|
</div> |
|
</div> |
|
|
|
<div id="qrCodesContainer" class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4"> |
|
|
|
</div> |
|
|
|
<div class="mt-8 bg-blue-50 border border-blue-200 rounded-lg p-4"> |
|
<h3 class="font-medium text-blue-800 mb-2"><i class="fas fa-user-check mr-1"></i> Attendance Tracker</h3> |
|
<p class="text-blue-700 text-sm">Enter an attendee code below to confirm attendance:</p> |
|
|
|
<div class="flex mt-3"> |
|
<input type="text" id="attendeeCodeInput" placeholder="Enter attendee code" class="flex-grow border border-gray-300 rounded-l-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"> |
|
<button onclick="confirmAttendance()" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-r-lg transition"> |
|
<i class="fas fa-check mr-1"></i> Confirm |
|
</button> |
|
</div> |
|
|
|
<div id="attendanceResult" class="mt-2 text-sm hidden"></div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="mt-10 flex flex-col sm:flex-row space-y-3 sm:space-y-0 sm:space-x-4"> |
|
<button class="flex-1 bg-white border border-purple-600 text-purple-600 hover:bg-purple-50 px-4 py-3 rounded-lg font-medium transition flex items-center justify-center"> |
|
<i class="fas fa-calendar-plus mr-2"></i> Add to Calendar |
|
</button> |
|
<button class="flex-1 bg-white border border-purple-600 text-purple-600 hover:bg-purple-50 px-4 py-3 rounded-lg font-medium transition flex items-center justify-center"> |
|
<i class="fas fa-envelope mr-2"></i> Email Details |
|
</button> |
|
<button class="flex-1 bg-purple-600 hover:bg-purple-700 text-white px-4 py-3 rounded-lg font-medium transition flex items-center justify-center"> |
|
<i class="fas fa-print mr-2"></i> Print Tickets |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
|
|
const bookingId = generateUniqueId(8); |
|
document.getElementById('bookingId').querySelector('span').textContent = `#${bookingId}`; |
|
|
|
|
|
if(!localStorage.getItem('bookingId')) { |
|
localStorage.setItem('bookingId', bookingId); |
|
} |
|
|
|
|
|
createConfetti(); |
|
|
|
|
|
generateTickets(); |
|
}); |
|
|
|
|
|
function generateUniqueId(length) { |
|
const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'; |
|
let result = ''; |
|
for (let i = 0; i < length; i++) { |
|
result += chars.charAt(Math.floor(Math.random() * chars.length)); |
|
} |
|
return result; |
|
} |
|
|
|
|
|
function copyBookingId() { |
|
const bookingId = document.getElementById('bookingId').querySelector('span').textContent; |
|
navigator.clipboard.writeText(bookingId.substring(1)); |
|
|
|
|
|
const button = document.getElementById('bookingId').querySelector('button'); |
|
const originalIcon = button.innerHTML; |
|
button.innerHTML = '<i class="fas fa-check"></i> Copied!'; |
|
|
|
setTimeout(() => { |
|
button.innerHTML = originalIcon; |
|
}, 2000); |
|
} |
|
|
|
|
|
function generateTickets() { |
|
const ticketTypes = ['General Admission', 'VIP Pass', 'Student Ticket']; |
|
const ticketList = document.getElementById('ticketList'); |
|
|
|
|
|
ticketList.innerHTML = ''; |
|
|
|
for (let i = 1; i <= 4; i++) { |
|
const randomType = ticketTypes[Math.floor(Math.random() * ticketTypes.length)]; |
|
const ticketHtml = ` |
|
<div class="flex items-center justify-between bg-gray-50 p-3 rounded-lg"> |
|
<div> |
|
<p class="font-medium text-gray-800">Ticket #${i}</p> |
|
<p class="text-sm text-gray-600">${randomType}</p> |
|
</div> |
|
<span class="bg-gray-200 text-gray-700 text-xs font-medium px-2.5 py-0.5 rounded">Pending ID</span> |
|
</div> |
|
`; |
|
ticketList.insertAdjacentHTML('beforeend', ticketHtml); |
|
} |
|
} |
|
|
|
|
|
function generateAttendeeCodes() { |
|
const bookingId = localStorage.getItem('bookingId'); |
|
const qrCodesContainer = document.getElementById('qrCodesContainer'); |
|
|
|
|
|
qrCodesContainer.innerHTML = ''; |
|
|
|
|
|
for (let i = 1; i <= 4; i++) { |
|
const attendeeCode = `${bookingId}-${generateUniqueId(3)}-${i}`; |
|
const qrCodeHtml = ` |
|
<div class="bg-white p-4 rounded-lg shadow-md text-center"> |
|
<div class="qr-code bg-white p-2 inline-block mb-2"> |
|
<!-- This would be replaced with a real QR code generator in production --> |
|
<div class="grid grid-cols-5 gap-1 w-32 h-32 flex items-center justify-center border-2 border-gray-300"> |
|
${Array(25).fill().map((_, idx) => |
|
`<div class="w-full h-full ${Math.random() > 0.6 ? 'bg-gray-800' : 'bg-white'}"></div>` |
|
).join('')} |
|
</div> |
|
</div> |
|
<p class="font-mono text-sm mt-2 px-2 py-1 bg-gray-100 rounded">${attendeeCode}</p> |
|
<p class="text-xs text-gray-500 mt-1">Ticket #${i}</p> |
|
<button onclick="copyCode('${attendeeCode}')" class="mt-2 text-xs text-purple-600 hover:text-purple-800 transition"> |
|
<i class="far fa-copy mr-1"></i> Copy Code |
|
</button> |
|
</div> |
|
`; |
|
qrCodesContainer.insertAdjacentHTML('beforeend', qrCodeHtml); |
|
|
|
|
|
const ticketSpans = document.querySelectorAll('#ticketList span'); |
|
ticketSpans[i-1].textContent = attendeeCode; |
|
ticketSpans[i-1].className = 'bg-green-100 text-green-800 text-xs font-medium px-2.5 py-0.5 rounded'; |
|
|
|
|
|
if(!localStorage.getItem('attendeeCodes')) { |
|
localStorage.setItem('attendeeCodes', JSON.stringify([])); |
|
} |
|
|
|
const currentCodes = JSON.parse(localStorage.getItem('attendeeCodes')); |
|
if(!currentCodes.includes(attendeeCode)) { |
|
currentCodes.push(attendeeCode); |
|
localStorage.setItem('attendeeCodes', JSON.stringify(currentCodes)); |
|
} |
|
} |
|
|
|
|
|
document.getElementById('attendanceSection').classList.remove('hidden'); |
|
} |
|
|
|
|
|
function copyCode(code) { |
|
navigator.clipboard.writeText(code); |
|
|
|
|
|
const buttons = document.querySelectorAll('button[onclick^="copyCode"]'); |
|
buttons.forEach(button => { |
|
if (button.getAttribute('onclick').includes(code)) { |
|
const originalHtml = button.innerHTML; |
|
button.innerHTML = '<i class="fas fa-check"></i> Copied!'; |
|
|
|
setTimeout(() => { |
|
button.innerHTML = originalHtml; |
|
}, 2000); |
|
} |
|
}); |
|
} |
|
|
|
|
|
function confirmAttendance() { |
|
const input = document.getElementById('attendeeCodeInput'); |
|
const code = input.value.trim(); |
|
const resultDiv = document.getElementById('attendanceResult'); |
|
|
|
|
|
const attendeeCodes = JSON.parse(localStorage.getItem('attendeeCodes') || '[]'); |
|
|
|
if (!code) { |
|
resultDiv.textContent = 'Please enter an attendee code'; |
|
resultDiv.className = 'mt-2 text-sm text-red-600'; |
|
resultDiv.classList.remove('hidden'); |
|
return; |
|
} |
|
|
|
if (attendeeCodes.includes(code)) { |
|
resultDiv.textContent = `Attendance confirmed for code: ${code}`; |
|
resultDiv.className = 'mt-2 text-sm text-green-600 font-medium'; |
|
resultDiv.classList.remove('hidden'); |
|
|
|
|
|
const qrContainers = document.querySelectorAll('#qrCodesContainer > div'); |
|
qrContainers.forEach(container => { |
|
const codeText = container.querySelector('p.font-mono').textContent; |
|
if (codeText === code) { |
|
container.classList.add('checked-in'); |
|
} |
|
}); |
|
|
|
|
|
input.value = ''; |
|
} else { |
|
resultDiv.textContent = 'Invalid attendee code. Please try again.'; |
|
resultDiv.className = 'mt-2 text-sm text-red-600'; |
|
resultDiv.classList.remove('hidden'); |
|
} |
|
} |
|
|
|
|
|
function createConfetti() { |
|
const colors = ['#f44336', '#e91e63', '#9c27b0', '#673ab7', '#3f51b5', '#2196f3', '#03a9f4', '#00bcd4', '#009688', '#4CAF50', '#8BC34A', '#CDDC39', '#FFEB3B', '#FFC107', '#FF9800', '#FF5722']; |
|
|
|
for (let i = 0; i < 100; i++) { |
|
const confetti = document.createElement('div'); |
|
confetti.className = 'confetti'; |
|
confetti.style.left = Math.random() * 100 + 'vw'; |
|
confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)]; |
|
confetti.style.width = Math.random() * 8 + 5 + 'px'; |
|
confetti.style.height = Math.random() * 8 + 5 + 'px'; |
|
confetti.style.animationDuration = Math.random() * 3 + 2 + 's'; |
|
confetti.style.animationDelay = Math.random() * 5 + 's'; |
|
document.body.appendChild(confetti); |
|
|
|
|
|
setTimeout(() => { |
|
confetti.remove(); |
|
}, 5000); |
|
} |
|
} |
|
</script> |
|
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=privateuserh/chandelier-events-booking" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |