privateuserh's picture
Update index.html
7792754 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Performance Venue Booking</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>
/* Custom animations */
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.fade-in {
animation: fadeIn 0.5s ease-out forwards;
}
/* Custom checkbox */
.custom-checkbox {
display: none;
}
.custom-checkbox + label:before {
content: '';
display: inline-block;
width: 20px;
height: 20px;
margin-right: 10px;
border: 2px solid #4f46e5;
border-radius: 4px;
background-color: white;
vertical-align: middle;
}
.custom-checkbox:checked + label:before {
background-color: #4f46e5;
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='white'%3E%3Cpath d='M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z'/%3E%3C/svg%3E");
background-position: center;
background-repeat: no-repeat;
background-size: 60%;
}
/* Custom scrollbar */
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 10px;
}
::-webkit-scrollbar-thumb {
background: #888;
border-radius: 10px;
}
::-webkit-scrollbar-thumb:hover {
background: #555;
}
</style>
</head>
<body class="bg-gray-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<!-- Header with navigation -->
<header class="mb-10">
<div class="flex justify-between items-center">
<div class="flex items-center space-x-2">
<i class="fas fa-theater-masks text-indigo-600 text-3xl"></i>
<h1 class="text-2xl font-bold text-gray-800">StageMasters</h1>
</div>
<nav class="hidden md:block">
<ul class="flex space-x-8">
<li><a href="#" class="text-gray-700 hover:text-indigo-600 transition">Venues</a></li>
<li><a href="#" class="text-gray-700 hover:text-indigo-600 transition">Artists</a></li>
<li><a href="#" class="text-gray-700 hover:text-indigo-600 transition">Pricing</a></li>
<li><a href="#" class="text-gray-700 hover:text-indigo-600 transition">Support</a></li>
</ul>
</nav>
<button class="md:hidden text-gray-700">
<i class="fas fa-bars text-2xl"></i>
</button>
</div>
</header>
<!-- Main booking section -->
<div class="max-w-5xl mx-auto fade-in">
<div class="overflow-hidden shadow-lg rounded-xl">
<div class="grid lg:grid-cols-12 bg-white">
<!-- Calendar section -->
<div class="lg:col-span-7 p-8 bg-gray-50 border-r border-gray-200">
<div class="flex justify-between items-center mb-6">
<h2 class="text-2xl font-bold text-gray-800">Select Date & Time</h2>
<div class="flex items-center space-x-3">
<button id="prev-month" class="p-2 rounded-full hover:bg-gray-200 transition">
<i class="fas fa-chevron-left text-gray-600"></i>
</button>
<button id="next-month" class="p-2 rounded-full hover:bg-gray-200 transition">
<i class="fas fa-chevron-right text-gray-600"></i>
</button>
</div>
</div>
<div id="month-year" class="text-xl font-semibold text-center mb-6 text-indigo-700"></div>
<div class="grid grid-cols-7 gap-2 mb-6">
<div class="text-center font-medium text-gray-500">Sun</div>
<div class="text-center font-medium text-gray-500">Mon</div>
<div class="text-center font-medium text-gray-500">Tue</div>
<div class="text-center font-medium text-gray-500">Wed</div>
<div class="text-center font-medium text-gray-500">Thu</div>
<div class="text-center font-medium text-gray-500">Fri</div>
<div class="text-center font-medium text-gray-500">Sat</div>
</div>
<div id="calendar-grid" class="grid grid-cols-7 gap-2 mb-8"></div>
<div class="mb-6">
<h3 class="font-semibold text-gray-700 mb-3">Available Time Slots</h3>
<div id="time-slots" class="grid grid-cols-2 sm:grid-cols-3 gap-3">
<!-- Time slots will be populated by JavaScript -->
</div>
</div>
<div>
<h3 class="font-semibold text-gray-700 mb-3">Performance Duration</h3>
<div class="flex flex-wrap gap-2">
<button class="duration-btn px-4 py-2 rounded-full bg-indigo-100 text-indigo-700 font-medium hover:bg-indigo-200 transition" data-duration="1">1 hour</button>
<button class="duration-btn px-4 py-2 rounded-full bg-gray-100 text-gray-700 font-medium hover:bg-gray-200 transition" data-duration="2">2 hours</button>
<button class="duration-btn px-4 py-2 rounded-full bg-gray-100 text-gray-700 font-medium hover:bg-gray-200 transition" data-duration="3">3 hours</button>
<button class="duration-btn px-4 py-2 rounded-full bg-gray-100 text-gray-700 font-medium hover:bg-gray-200 transition" data-duration="all">Full day</button>
</div>
</div>
</div>
<!-- Booking summary section -->
<div class="lg:col-span-5 p-8">
<h2 class="text-2xl font-bold text-gray-800 mb-6">Chandelier Booking Summary</h2>
<div class="bg-gray-50 rounded-lg p-4 mb-6">
<div class="flex items-center space-x-3 mb-4">
<div class="w-16 h-16 rounded-md overflow-hidden">
<img src="https://images.unsplash.com/photo-1551818255-e6e10975bc17?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=400&q=80" alt="Venue Image" class="w-full h-full object-cover">
</div>
<div>
<h3 class="font-semibold">4th Street</h3>
<p class="text-sm text-gray-600"><i class="fas fa-map-marker-alt text-indigo-500 mr-1"></i>Pop Up Location, Santa Monica</p>
</div>
</div>
<div class="space-y-3">
<div class="flex justify-between">
<span class="text-gray-600">Capacity:</span>
<span class="font-medium">50 seated / 100 standing</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Stage size:</span>
<span class="font-medium">10m x 8m</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Equipment:</span>
<span class="font-medium">Sound system, lights</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Dressing rooms:</span>
<span class="font-medium">1 available</span>
</div>
</div>
</div>
<div class="space-y-4">
<div class="flex justify-between items-center border-b border-gray-200 pb-2">
<div>
<h4 class="font-medium text-gray-700">Selected Date</h4>
<p id="selected-date" class="text-sm text-gray-500">Not selected</p>
</div>
<button id="edit-date" class="text-indigo-600 hover:text-indigo-800 transition">
<i class="fas fa-edit"></i>
</button>
</div>
<div class="flex justify-between items-center border-b border-gray-200 pb-2">
<div>
<h4 class="font-medium text-gray-700">Time Slot</h4>
<p id="selected-time" class="text-sm text-gray-500">Not selected</p>
</div>
<button id="edit-time" class="text-indigo-600 hover:text-indigo-800 transition">
<i class="fas fa-edit"></i>
</button>
</div>
<div class="flex justify-between items-center border-b border-gray-200 pb-2">
<div>
<h4 class="font-medium text-gray-700">Performance Duration</h4>
<p id="selected-duration" class="text-sm text-gray-500">Not selected</p>
</div>
<button id="edit-duration" class="text-indigo-600 hover:text-indigo-800 transition">
<i class="fas fa-edit"></i>
</button>
</div>
<div class="pt-2">
<div class="flex justify-between mb-1">
<span class="text-gray-600">Base rate:</span>
<span id="base-rate" class="font-medium">$0.00</span>
</div>
<div class="flex justify-between mb-1">
<span class="text-gray-600">Equipment fee:</span>
<span id="equipment-fee" class="font-medium">$50.00</span>
</div>
<div class="flex justify-between font-bold text-lg">
<span>Total:</span>
<span id="total-cost" class="text-indigo-600">$0.00</span>
</div>
</div>
</div>
<div class="mt-8">
<input type="checkbox" id="terms-check" class="custom-checkbox">
<label for="terms-check" class="text-sm text-gray-600 cursor-pointer">I agree to the <a href="#" class="text-indigo-600 hover:underline">terms and conditions</a> and <a href="#" class="text-indigo-600 hover:underline">venue policies</a></label>
<button id="book-now-btn" class="w-full mt-4 bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-3 px-4 rounded-lg transition disabled:opacity-50 disabled:cursor-not-allowed" disabled>
Book Now
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Modal for booking confirmation -->
<div id="success-modal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4 z-50 hidden">
<div class="bg-white rounded-xl p-8 max-w-md w-full text-center fade-in">
<div class="w-20 h-20 bg-green-100 rounded-full flex items-center justify-center mx-auto mb-4">
<i class="fas fa-check text-green-500 text-3xl"></i>
</div>
<h2 class="text-2xl font-bold text-gray-800 mb-2">Booking Confirmed!</h2>
<p class="text-gray-600 mb-6">Your performance slot has been successfully booked.</p>
<div class="bg-gray-50 rounded-lg p-4 mb-6">
<div id="confirmation-details" class="space-y-2 text-left">
<!-- Details will be populated by JavaScript -->
</div>
</div>
<button id="close-modal" class="w-full bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-2 px-4 rounded-lg transition">
Back to Dashboard
</button>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Date handling
let currentDate = new Date();
let selectedDate = null;
let selectedTime = null;
let selectedDuration = null;
const monthYearEl = document.getElementById('month-year');
const calendarGridEl = document.getElementById('calendar-grid');
const timeSlotsEl = document.getElementById('time-slots');
const selectedDateEl = document.getElementById('selected-date');
const selectedTimeEl = document.getElementById('selected-time');
const selectedDurationEl = document.getElementById('selected-duration');
const baseRateEl = document.getElementById('base-rate');
const equipmentFeeEl = document.getElementById('equipment-fee');
const totalCostEl = document.getElementById('total-cost');
const bookNowBtn = document.getElementById('book-now-btn');
const successModal = document.getElementById('success-modal');
const confirmationDetails = document.getElementById('confirmation-details');
// Initialize calendar
renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
// Navigation buttons
document.getElementById('prev-month').addEventListener('click', function() {
currentDate.setMonth(currentDate.getMonth() - 1);
renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
});
document.getElementById('next-month').addEventListener('click', function() {
currentDate.setMonth(currentDate.getMonth() + 1);
renderCalendar(currentDate.getFullYear(), currentDate.getMonth());
});
// Duration buttons
document.querySelectorAll('.duration-btn').forEach(btn => {
btn.addEventListener('click', function() {
// Remove active class from all buttons
document.querySelectorAll('.duration-btn').forEach(b => {
b.classList.remove('bg-indigo-100', 'text-indigo-700');
b.classList.add('bg-gray-100', 'text-gray-700');
});
// Add active class to clicked button
this.classList.remove('bg-gray-100', 'text-gray-700');
this.classList.add('bg-indigo-100', 'text-indigo-700');
selectedDuration = this.dataset.duration;
selectedDurationEl.textContent = selectedDuration === 'all' ? 'Full day (8 hours)' : `${selectedDuration} hour(s)`;
updateTotalCost();
checkBookingReady();
});
});
// Edit buttons
document.getElementById('edit-date').addEventListener('click', function() {
selectedDate = null;
selectedDateEl.textContent = 'Not selected';
checkBookingReady();
});
document.getElementById('edit-time').addEventListener('click', function() {
selectedTime = null;
selectedTimeEl.textContent = 'Not selected';
checkBookingReady();
});
document.getElementById('edit-duration').addEventListener('click', function() {
selectedDuration = null;
document.querySelectorAll('.duration-btn').forEach(b => {
b.classList.remove('bg-indigo-100', 'text-indigo-700');
b.classList.add('bg-gray-100', 'text-gray-700');
});
selectedDurationEl.textContent = 'Not selected';
checkBookingReady();
});
// Terms checkbox
document.getElementById('terms-check').addEventListener('change', checkBookingReady);
// Book now button
bookNowBtn.addEventListener('click', function() {
if (!selectedDate || !selectedTime || !selectedDuration) return;
// Show confirmation modal
confirmationDetails.innerHTML = `
<p><strong>Venue:</strong> Grand Performance Hall</p>
<p><strong>Date:</strong> ${selectedDate.toDateString()}</p>
<p><strong>Time:</strong> ${selectedTime}</p>
<p><strong>Duration:</strong> ${selectedDuration === 'all' ? 'Full day (8 hours)' : selectedDuration + ' hour(s)'}</p>
<p><strong>Total:</strong> ${totalCostEl.textContent}</p>
`;
successModal.classList.remove('hidden');
});
// Close modal button
document.getElementById('close-modal').addEventListener('click', function() {
successModal.classList.add('hidden');
});
// Functions
function renderCalendar(year, month) {
monthYearEl.textContent = new Date(year, month).toLocaleString('default', { month: 'long', year: 'numeric' });
calendarGridEl.innerHTML = '';
// Get first day of month and total days
const firstDay = new Date(year, month, 1).getDay();
const daysInMonth = new Date(year, month + 1, 0).getDate();
// Add empty cells for days before first day of month
for (let i = 0; i < firstDay; i++) {
const cell = document.createElement('div');
cell.className = 'h-12';
calendarGridEl.appendChild(cell);
}
// Add cells for each day of the month
for (let day = 1; day <= daysInMonth; day++) {
const date = new Date(year, month, day);
const cell = document.createElement('button');
cell.className = 'h-12 rounded-full flex items-center justify-center font-medium hover:bg-gray-100 transition';
cell.textContent = day;
// Highlight today
if (day === new Date().getDate() && month === new Date().getMonth() && year === new Date().getFullYear()) {
cell.classList.add('bg-indigo-100', 'text-indigo-700');
}
// Disable past dates
if (date < new Date(new Date().setHours(0, 0, 0, 0))) {
cell.classList.add('text-gray-400', 'cursor-not-allowed');
cell.disabled = true;
} else {
cell.addEventListener('click', function() {
// Remove selected class from all cells
document.querySelectorAll('#calendar-grid button').forEach(c => {
c.classList.remove('bg-indigo-600', 'text-white');
});
// Add selected class to clicked cell
cell.classList.add('bg-indigo-600', 'text-white');
selectedDate = date;
selectedDateEl.textContent = date.toDateString();
generateTimeSlots();
checkBookingReady();
});
}
calendarGridEl.appendChild(cell);
}
}
function generateTimeSlots() {
if (!selectedDate) return;
timeSlotsEl.innerHTML = '';
// Generate available time slots (mock data)
const startHour = 9; // 9 AM
const endHour = 22; // 10 PM
const hourDiff = endHour - startHour;
for (let i = 0; i < hourDiff; i++) {
const hour = startHour + i;
const ampm = hour >= 12 ? 'PM' : 'AM';
const displayHour = hour > 12 ? hour - 12 : hour;
// Skip some unavailable times (mock)
if (Math.random() > 0.7) continue;
const timeSlot = document.createElement('button');
timeSlot.className = 'bg-gray-100 hover:bg-gray-200 text-gray-700 rounded-lg py-2 px-3 text-sm font-medium transition';
timeSlot.textContent = `${displayHour}:00 ${ampm}`;
// Highlight if already selected
if (selectedTime === timeSlot.textContent) {
timeSlot.classList.remove('bg-gray-100', 'text-gray-700');
timeSlot.classList.add('bg-indigo-600', 'text-white');
}
timeSlot.addEventListener('click', function() {
// Remove selected class from all time slots
document.querySelectorAll('#time-slots button').forEach(t => {
t.classList.remove('bg-indigo-600', 'text-white');
t.classList.add('bg-gray-100', 'text-gray-700');
});
// Add selected class to clicked time slot
timeSlot.classList.remove('bg-gray-100', 'text-gray-700');
timeSlot.classList.add('bg-indigo-600', 'text-white');
selectedTime = timeSlot.textContent;
selectedTimeEl.textContent = selectedTime;
updateTotalCost();
checkBookingReady();
});
timeSlotsEl.appendChild(timeSlot);
}
// Add a "custom time" option
if (timeSlotsEl.children.length === 0) {
timeSlotsEl.innerHTML = '<p class="text-gray-500 col-span-3 text-center">No standard slots available.<br><button class="text-indigo-600 font-medium mt-2">Request custom time</button></p>';
}
}
function updateTotalCost() {
if (!selectedDate || !selectedTime || !selectedDuration) return;
// Calculate base rate based on duration and day of week (weekend more expensive)
let baseRate = 0;
const day = selectedDate.getDay(); // Sunday is 0
if (selectedDuration === '1') baseRate = day === 0 || day === 6 ? 300 : 250;
else if (selectedDuration === '2') baseRate = day === 0 || day === 6 ? 500 : 400;
else if (selectedDuration === '3') baseRate = day === 0 || day === 6 ? 700 : 550;
else if (selectedDuration === 'all') baseRate = day === 0 || day === 6 ? 1200 : 1000;
baseRateEl.textContent = `$${baseRate.toFixed(2)}`;
// Equipment fee might vary (mock logic)
const equipmentFee = selectedDuration === 'all' ? 250 : 150;
equipmentFeeEl.textContent = `$${equipmentFee.toFixed(2)}`;
// Calculate total
const total = baseRate + equipmentFee;
totalCostEl.textContent = `$${total.toFixed(2)}`;
}
function checkBookingReady() {
const termsChecked = document.getElementById('terms-check').checked;
const isReady = selectedDate && selectedTime && selectedDuration && termsChecked;
bookNowBtn.disabled = !isReady;
}
});
</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-performance-module" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>