|
<!DOCTYPE html> |
|
<html lang="es"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>New Tunk - Club & Concert Venue</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> |
|
|
|
.event-card:hover { |
|
transform: translateY(-5px); |
|
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2); |
|
} |
|
|
|
.table-selected { |
|
box-shadow: 0 0 0 3px #f59e0b; |
|
} |
|
|
|
.admin-panel { |
|
transition: all 0.3s ease; |
|
} |
|
|
|
.admin-panel.hidden { |
|
transform: translateX(100%); |
|
opacity: 0; |
|
} |
|
|
|
.logo-text { |
|
font-family: 'Impact', sans-serif; |
|
text-shadow: 3px 3px 0 #000, -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000; |
|
} |
|
|
|
@keyframes pulse { |
|
0%, 100% { |
|
opacity: 1; |
|
} |
|
50% { |
|
opacity: 0.5; |
|
} |
|
} |
|
|
|
.animate-pulse { |
|
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; |
|
} |
|
</style> |
|
</head> |
|
<body class="bg-gray-900 text-white min-h-screen"> |
|
|
|
<button id="adminToggle" class="fixed top-4 right-4 bg-purple-800 hover:bg-purple-700 text-white px-4 py-2 rounded-full z-50 shadow-lg"> |
|
<i class="fas fa-lock mr-2"></i>Admin |
|
</button> |
|
|
|
|
|
<div id="adminPanel" class="admin-panel hidden fixed top-0 right-0 h-full w-full md:w-1/3 bg-gray-800 z-40 p-6 overflow-y-auto shadow-2xl"> |
|
<div class="flex justify-between items-center mb-8"> |
|
<h2 class="text-2xl font-bold">Admin Panel</h2> |
|
<button id="closeAdmin" class="text-gray-400 hover:text-white"> |
|
<i class="fas fa-times text-2xl"></i> |
|
</button> |
|
</div> |
|
|
|
<div class="mb-8"> |
|
<h3 class="text-xl font-semibold mb-4 border-b border-gray-700 pb-2">Manage Events</h3> |
|
<div class="space-y-4"> |
|
<div class="bg-gray-700 p-4 rounded-lg"> |
|
<h4 class="font-medium mb-2">Add New Event</h4> |
|
<div class="space-y-3"> |
|
<input type="text" id="eventTitle" placeholder="Event Title" class="w-full bg-gray-600 rounded px-3 py-2"> |
|
<input type="date" id="eventDate" class="w-full bg-gray-600 rounded px-3 py-2"> |
|
<input type="time" id="eventTime" class="w-full bg-gray-600 rounded px-3 py-2"> |
|
<textarea id="eventDescription" placeholder="Description" class="w-full bg-gray-600 rounded px-3 py-2"></textarea> |
|
<input type="number" id="eventPrice" placeholder="Ticket Price" class="w-full bg-gray-600 rounded px-3 py-2"> |
|
<input type="text" id="eventImage" placeholder="Image URL" class="w-full bg-gray-600 rounded px-3 py-2"> |
|
<button id="addEvent" class="w-full bg-green-600 hover:bg-green-700 py-2 rounded font-medium"> |
|
<i class="fas fa-plus mr-2"></i>Add Event |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div class="bg-gray-700 p-4 rounded-lg"> |
|
<h4 class="font-medium mb-2">Current Events</h4> |
|
<div id="adminEventsList" class="space-y-3"> |
|
|
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<h3 class="text-xl font-semibold mb-4 border-b border-gray-700 pb-2">Table Configuration</h3> |
|
<div class="grid grid-cols-2 gap-4 mb-4"> |
|
<div> |
|
<label class="block mb-1">Table Rows</label> |
|
<input type="number" id="tableRows" min="1" max="10" value="4" class="w-full bg-gray-600 rounded px-3 py-2"> |
|
</div> |
|
<div> |
|
<label class="block mb-1">Tables per Row</label> |
|
<input type="number" id="tablesPerRow" min="1" max="10" value="6" class="w-full bg-gray-600 rounded px-3 py-2"> |
|
</div> |
|
</div> |
|
<button id="updateTableLayout" class="w-full bg-blue-600 hover:bg-blue-700 py-2 rounded font-medium mb-6"> |
|
<i class="fas fa-sync-alt mr-2"></i>Update Layout |
|
</button> |
|
|
|
<div class="bg-gray-700 p-4 rounded-lg"> |
|
<h4 class="font-medium mb-2">Current Reservations</h4> |
|
<div id="reservationsList" class="space-y-3"> |
|
|
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div class="container mx-auto px-4"> |
|
|
|
<header class="py-8 text-center"> |
|
<div class="logo-container inline-block relative"> |
|
<div class="absolute -inset-4 bg-purple-600 rounded-full blur-md opacity-30 animate-pulse"></div> |
|
<h1 class="logo-text text-6xl md:text-8xl font-bold text-purple-400 relative z-10">NEW TUNK</h1> |
|
</div> |
|
<p class="mt-4 text-xl text-purple-200">Club & Concert Venue</p> |
|
</header> |
|
|
|
|
|
<nav class="flex justify-center mb-12"> |
|
<div class="flex space-x-1 bg-gray-800 rounded-full p-1"> |
|
<button class="nav-link px-6 py-2 rounded-full font-medium active" data-section="events"> |
|
<i class="fas fa-calendar-alt mr-2"></i>Events |
|
</button> |
|
<button class="nav-link px-6 py-2 rounded-full font-medium" data-section="tickets"> |
|
<i class="fas fa-ticket-alt mr-2"></i>Tickets |
|
</button> |
|
<button class="nav-link px-6 py-2 rounded-full font-medium" data-section="reservations"> |
|
<i class="fas fa-utensils mr-2"></i>Reservations |
|
</button> |
|
<button class="nav-link px-6 py-2 rounded-full font-medium" data-section="about"> |
|
<i class="fas fa-info-circle mr-2"></i>About |
|
</button> |
|
</div> |
|
</nav> |
|
|
|
|
|
<main> |
|
|
|
<section id="events-section" class="section-content py-8"> |
|
<h2 class="text-3xl font-bold mb-8 text-center">Upcoming Events</h2> |
|
<div id="eventsContainer" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8"> |
|
|
|
<div class="text-center py-12"> |
|
<div class="animate-spin inline-block text-purple-500 text-4xl mb-4"> |
|
<i class="fas fa-compact-disc"></i> |
|
</div> |
|
<p>Loading events...</p> |
|
</div> |
|
</div> |
|
</section> |
|
|
|
|
|
<section id="tickets-section" class="section-content py-8 hidden"> |
|
<h2 class="text-3xl font-bold mb-8 text-center">Buy Tickets</h2> |
|
<div id="ticketsContainer" class="max-w-2xl mx-auto"> |
|
<div class="bg-gray-800 rounded-lg p-6 mb-6"> |
|
<p class="text-center text-gray-400">Select an event to purchase tickets</p> |
|
</div> |
|
</div> |
|
</section> |
|
|
|
|
|
<section id="reservations-section" class="section-content py-8 hidden"> |
|
<h2 class="text-3xl font-bold mb-8 text-center">Table Reservations</h2> |
|
<div class="max-w-4xl mx-auto"> |
|
<div class="bg-gray-800 rounded-lg p-6 mb-6"> |
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
<div> |
|
<h3 class="text-xl font-semibold mb-4">Available Tables</h3> |
|
<div id="tableLayout" class="grid grid-cols-6 gap-2 mb-4"> |
|
|
|
</div> |
|
<div class="text-sm text-gray-400"> |
|
<p>Click on a table to select it for reservation</p> |
|
</div> |
|
</div> |
|
<div> |
|
<h3 class="text-xl font-semibold mb-4">Reservation Details</h3> |
|
<div class="space-y-4"> |
|
<div> |
|
<label class="block mb-1">Selected Table</label> |
|
<input type="text" id="selectedTable" readonly class="w-full bg-gray-700 rounded px-3 py-2"> |
|
</div> |
|
<div> |
|
<label class="block mb-1">Event</label> |
|
<select id="reservationEvent" class="w-full bg-gray-700 rounded px-3 py-2"> |
|
<option value="">Select an event</option> |
|
</select> |
|
</div> |
|
<div> |
|
<label class="block mb-1">Name</label> |
|
<input type="text" id="reservationName" class="w-full bg-gray-700 rounded px-3 py-2"> |
|
</div> |
|
<div> |
|
<label class="block mb-1">Email</label> |
|
<input type="email" id="reservationEmail" class="w-full bg-gray-700 rounded px-3 py-2"> |
|
</div> |
|
<div> |
|
<label class="block mb-1">Phone</label> |
|
<input type="tel" id="reservationPhone" class="w-full bg-gray-700 rounded px-3 py-2"> |
|
</div> |
|
<div> |
|
<label class="block mb-1">Number of Guests</label> |
|
<input type="number" id="reservationGuests" min="1" max="10" value="2" class="w-full bg-gray-700 rounded px-3 py-2"> |
|
</div> |
|
<button id="submitReservation" class="w-full bg-purple-600 hover:bg-purple-700 py-2 rounded font-medium"> |
|
<i class="fas fa-check mr-2"></i>Confirm Reservation |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
</section> |
|
|
|
|
|
<section id="about-section" class="section-content py-8 hidden"> |
|
<h2 class="text-3xl font-bold mb-8 text-center">About New Tunk</h2> |
|
<div class="max-w-3xl mx-auto"> |
|
<div class="bg-gray-800 rounded-lg p-6 mb-6"> |
|
<div class="flex flex-col md:flex-row gap-6"> |
|
<div class="md:w-1/3"> |
|
<div class="bg-purple-900 aspect-square rounded-lg mb-4 flex items-center justify-center"> |
|
<i class="fas fa-music text-6xl text-purple-400"></i> |
|
</div> |
|
</div> |
|
<div class="md:w-2/3"> |
|
<h3 class="text-xl font-semibold mb-4">The Ultimate Nightlife Experience</h3> |
|
<p class="mb-4">New Tunk is the premier destination for music lovers and party-goers alike. With state-of-the-art sound systems, stunning light shows, and an electric atmosphere, we bring you unforgettable nights.</p> |
|
<p class="mb-4">Our venue hosts world-class DJs, live bands, and special events throughout the year. Whether you're looking to dance the night away or enjoy cocktails with friends, New Tunk has something for everyone.</p> |
|
<div class="flex space-x-4 mt-6"> |
|
<a href="#" class="text-purple-400 hover:text-purple-300"> |
|
<i class="fab fa-facebook-f text-2xl"></i> |
|
</a> |
|
<a href="#" class="text-purple-400 hover:text-purple-300"> |
|
<i class="fab fa-instagram text-2xl"></i> |
|
</a> |
|
<a href="#" class="text-purple-400 hover:text-purple-300"> |
|
<i class="fab fa-twitter text-2xl"></i> |
|
</a> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-6"> |
|
<div class="bg-gray-800 rounded-lg p-6"> |
|
<h3 class="text-xl font-semibold mb-4 flex items-center"> |
|
<i class="fas fa-clock mr-3 text-purple-400"></i>Opening Hours |
|
</h3> |
|
<ul class="space-y-2"> |
|
<li class="flex justify-between border-b border-gray-700 pb-2"> |
|
<span>Monday - Thursday</span> |
|
<span>6PM - 2AM</span> |
|
</li> |
|
<li class="flex justify-between border-b border-gray-700 pb-2"> |
|
<span>Friday - Saturday</span> |
|
<span>8PM - 4AM</span> |
|
</li> |
|
<li class="flex justify-between"> |
|
<span>Sunday</span> |
|
<span>Closed</span> |
|
</li> |
|
</ul> |
|
</div> |
|
|
|
<div class="bg-gray-800 rounded-lg p-6"> |
|
<h3 class="text-xl font-semibold mb-4 flex items-center"> |
|
<i class="fas fa-map-marker-alt mr-3 text-purple-400"></i>Location |
|
</h3> |
|
<p class="mb-4">123 Music Avenue<br>Nightlife District<br>City, ST 12345</p> |
|
<button class="bg-purple-600 hover:bg-purple-700 px-4 py-2 rounded font-medium"> |
|
<i class="fas fa-directions mr-2"></i>Get Directions |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</section> |
|
</main> |
|
|
|
|
|
<footer class="py-12 mt-12 border-t border-gray-800"> |
|
<div class="text-center"> |
|
<div class="logo-container inline-block mb-6"> |
|
<h2 class="logo-text text-4xl font-bold text-purple-400">NEW TUNK</h2> |
|
</div> |
|
<p class="text-gray-400 mb-6">© 2023 New Tunk. All rights reserved.</p> |
|
<div class="flex justify-center space-x-6"> |
|
<a href="#" class="text-gray-400 hover:text-white"> |
|
<i class="fab fa-facebook-f"></i> |
|
</a> |
|
<a href="#" class="text-gray-400 hover:text-white"> |
|
<i class="fab fa-instagram"></i> |
|
</a> |
|
<a href="#" class="text-gray-400 hover:text-white"> |
|
<i class="fab fa-twitter"></i> |
|
</a> |
|
<a href="#" class="text-gray-400 hover:text-white"> |
|
<i class="fab fa-soundcloud"></i> |
|
</a> |
|
</div> |
|
</div> |
|
</footer> |
|
</div> |
|
|
|
|
|
<div id="eventModal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 hidden"> |
|
<div class="bg-gray-800 rounded-lg max-w-2xl w-full mx-4 max-h-[90vh] overflow-y-auto"> |
|
<div class="p-6"> |
|
<div class="flex justify-between items-start mb-4"> |
|
<div> |
|
<h2 id="modalEventTitle" class="text-2xl font-bold"></h2> |
|
<p id="modalEventDate" class="text-purple-400"></p> |
|
</div> |
|
<button id="closeModal" class="text-gray-400 hover:text-white"> |
|
<i class="fas fa-times text-2xl"></i> |
|
</button> |
|
</div> |
|
|
|
<div class="mb-6"> |
|
<div id="modalEventImage" class="w-full h-48 md:h-64 bg-gray-700 rounded-lg mb-4 flex items-center justify-center"> |
|
<i class="fas fa-music text-5xl text-gray-500"></i> |
|
</div> |
|
<p id="modalEventDescription" class="mb-4"></p> |
|
<div class="flex items-center"> |
|
<span class="bg-purple-600 text-white px-3 py-1 rounded-full text-sm font-medium"> |
|
<i class="fas fa-ticket-alt mr-1"></i> <span id="modalEventPrice"></span> |
|
</span> |
|
</div> |
|
</div> |
|
|
|
<div class="grid grid-cols-1 md:grid-cols-2 gap-4"> |
|
<button id="buyTicketsBtn" class="bg-green-600 hover:bg-green-700 py-3 rounded font-medium"> |
|
<i class="fas fa-ticket-alt mr-2"></i>Buy Tickets |
|
</button> |
|
<button id="reserveTableBtn" class="bg-purple-600 hover:bg-purple-700 py-3 rounded font-medium"> |
|
<i class="fas fa-utensils mr-2"></i>Reserve Table |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="ticketModal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 hidden"> |
|
<div class="bg-gray-800 rounded-lg max-w-md w-full mx-4"> |
|
<div class="p-6"> |
|
<div class="flex justify-between items-start mb-4"> |
|
<div> |
|
<h2 class="text-2xl font-bold">Ticket Purchase</h2> |
|
<p id="ticketEventTitle" class="text-purple-400"></p> |
|
</div> |
|
<button id="closeTicketModal" class="text-gray-400 hover:text-white"> |
|
<i class="fas fa-times text-2xl"></i> |
|
</button> |
|
</div> |
|
|
|
<div class="space-y-4 mb-6"> |
|
<div> |
|
<label class="block mb-1">Quantity</label> |
|
<div class="flex items-center"> |
|
<button id="decrementTicket" class="bg-gray-700 px-3 py-2 rounded-l"> |
|
<i class="fas fa-minus"></i> |
|
</button> |
|
<input type="number" id="ticketQuantity" min="1" value="1" class="bg-gray-700 w-16 text-center py-2"> |
|
<button id="incrementTicket" class="bg-gray-700 px-3 py-2 rounded-r"> |
|
<i class="fas fa-plus"></i> |
|
</button> |
|
</div> |
|
</div> |
|
|
|
<div> |
|
<label class="block mb-1">Name</label> |
|
<input type="text" id="ticketName" class="w-full bg-gray-700 rounded px-3 py-2"> |
|
</div> |
|
|
|
<div> |
|
<label class="block mb-1">Email</label> |
|
<input type="email" id="ticketEmail" class="w-full bg-gray-700 rounded px-3 py-2"> |
|
</div> |
|
|
|
<div class="pt-4 border-t border-gray-700"> |
|
<div class="flex justify-between mb-2"> |
|
<span>Tickets (<span id="ticketQtyDisplay">1</span>x)</span> |
|
<span id="ticketUnitPrice"></span> |
|
</div> |
|
<div class="flex justify-between font-bold text-lg"> |
|
<span>Total</span> |
|
<span id="ticketTotalPrice"></span> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<button id="confirmPurchase" class="w-full bg-green-600 hover:bg-green-700 py-3 rounded font-medium"> |
|
<i class="fas fa-credit-card mr-2"></i>Confirm Purchase |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
|
|
<div id="confirmationModal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 hidden"> |
|
<div class="bg-gray-800 rounded-lg max-w-md w-full mx-4"> |
|
<div class="p-6 text-center"> |
|
<div class="w-16 h-16 bg-green-500 rounded-full flex items-center justify-center mx-auto mb-4"> |
|
<i class="fas fa-check text-2xl text-white"></i> |
|
</div> |
|
<h2 id="confirmationTitle" class="text-2xl font-bold mb-2"></h2> |
|
<p id="confirmationMessage" class="mb-6"></p> |
|
<button id="closeConfirmation" class="bg-purple-600 hover:bg-purple-700 px-6 py-2 rounded font-medium"> |
|
Close |
|
</button> |
|
</div> |
|
</div> |
|
</div> |
|
|
|
<script> |
|
|
|
let events = [ |
|
{ |
|
id: 1, |
|
title: "Electronic Night", |
|
date: "2023-12-15", |
|
time: "22:00", |
|
description: "Experience the best electronic music with our resident DJs and special guests. A night of non-stop beats and incredible light show.", |
|
price: 25, |
|
image: "https://images.unsplash.com/photo-1493225457124-a3eb161ffa5f?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", |
|
active: true |
|
}, |
|
{ |
|
id: 2, |
|
title: "Live Rock Band", |
|
date: "2023-12-22", |
|
time: "21:00", |
|
description: "The legendary rock band 'Midnight Riders' performs live with all their greatest hits. Don't miss this exclusive show!", |
|
price: 40, |
|
image: "https://images.unsplash.com/photo-1470229722913-7c0e2dbbafd3?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", |
|
active: true |
|
}, |
|
{ |
|
id: 3, |
|
title: "Hip Hop Festival", |
|
date: "2024-01-05", |
|
time: "20:00", |
|
description: "A full night of hip hop with performances from top artists, DJ battles, and breakdance competitions.", |
|
price: 30, |
|
image: "https://images.unsplash.com/photo-1514525253161-7a46d19cd819?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80", |
|
active: true |
|
} |
|
]; |
|
|
|
let reservations = []; |
|
let selectedEvent = null; |
|
let selectedTable = null; |
|
let tableRows = 4; |
|
let tablesPerRow = 6; |
|
|
|
|
|
const adminPanel = document.getElementById('adminPanel'); |
|
const adminToggle = document.getElementById('adminToggle'); |
|
const closeAdmin = document.getElementById('closeAdmin'); |
|
const navLinks = document.querySelectorAll('.nav-link'); |
|
const sectionContents = document.querySelectorAll('.section-content'); |
|
const eventsContainer = document.getElementById('eventsContainer'); |
|
const ticketsContainer = document.getElementById('ticketsContainer'); |
|
const tableLayout = document.getElementById('tableLayout'); |
|
const reservationEvent = document.getElementById('reservationEvent'); |
|
const selectedTableInput = document.getElementById('selectedTable'); |
|
const submitReservation = document.getElementById('submitReservation'); |
|
const eventModal = document.getElementById('eventModal'); |
|
const closeModal = document.getElementById('closeModal'); |
|
const modalEventTitle = document.getElementById('modalEventTitle'); |
|
const modalEventDate = document.getElementById('modalEventDate'); |
|
const modalEventDescription = document.getElementById('modalEventDescription'); |
|
const modalEventPrice = document.getElementById('modalEventPrice'); |
|
const modalEventImage = document.getElementById('modalEventImage'); |
|
const buyTicketsBtn = document.getElementById('buyTicketsBtn'); |
|
const reserveTableBtn = document.getElementById('reserveTableBtn'); |
|
const ticketModal = document.getElementById('ticketModal'); |
|
const closeTicketModal = document.getElementById('closeTicketModal'); |
|
const ticketEventTitle = document.getElementById('ticketEventTitle'); |
|
const ticketQuantity = document.getElementById('ticketQuantity'); |
|
const decrementTicket = document.getElementById('decrementTicket'); |
|
const incrementTicket = document.getElementById('incrementTicket'); |
|
const ticketQtyDisplay = document.getElementById('ticketQtyDisplay'); |
|
const ticketUnitPrice = document.getElementById('ticketUnitPrice'); |
|
const ticketTotalPrice = document.getElementById('ticketTotalPrice'); |
|
const confirmPurchase = document.getElementById('confirmPurchase'); |
|
const confirmationModal = document.getElementById('confirmationModal'); |
|
const confirmationTitle = document.getElementById('confirmationTitle'); |
|
const confirmationMessage = document.getElementById('confirmationMessage'); |
|
const closeConfirmation = document.getElementById('closeConfirmation'); |
|
const adminEventsList = document.getElementById('adminEventsList'); |
|
const reservationsList = document.getElementById('reservationsList'); |
|
const addEvent = document.getElementById('addEvent'); |
|
const eventTitle = document.getElementById('eventTitle'); |
|
const eventDate = document.getElementById('eventDate'); |
|
const eventTime = document.getElementById('eventTime'); |
|
const eventDescription = document.getElementById('eventDescription'); |
|
const eventPrice = document.getElementById('eventPrice'); |
|
const eventImage = document.getElementById('eventImage'); |
|
const tableRowsInput = document.getElementById('tableRows'); |
|
const tablesPerRowInput = document.getElementById('tablesPerRow'); |
|
const updateTableLayout = document.getElementById('updateTableLayout'); |
|
|
|
|
|
document.addEventListener('DOMContentLoaded', function() { |
|
renderEvents(); |
|
generateTableLayout(); |
|
setupAdminPanel(); |
|
|
|
|
|
const today = new Date().toISOString().split('T')[0]; |
|
eventDate.min = today; |
|
}); |
|
|
|
|
|
navLinks.forEach(link => { |
|
link.addEventListener('click', function() { |
|
|
|
navLinks.forEach(l => l.classList.remove('active')); |
|
|
|
this.classList.add('active'); |
|
|
|
|
|
sectionContents.forEach(section => section.classList.add('hidden')); |
|
|
|
|
|
const sectionId = this.getAttribute('data-section'); |
|
document.getElementById(`${sectionId}-section`).classList.remove('hidden'); |
|
}); |
|
}); |
|
|
|
|
|
adminToggle.addEventListener('click', function() { |
|
adminPanel.classList.toggle('hidden'); |
|
}); |
|
|
|
closeAdmin.addEventListener('click', function() { |
|
adminPanel.classList.add('hidden'); |
|
}); |
|
|
|
|
|
function renderEvents() { |
|
eventsContainer.innerHTML = ''; |
|
|
|
const activeEvents = events.filter(event => event.active); |
|
|
|
if (activeEvents.length === 0) { |
|
eventsContainer.innerHTML = ` |
|
<div class="col-span-full text-center py-12"> |
|
<i class="fas fa-calendar-times text-4xl text-gray-500 mb-4"></i> |
|
<p>No upcoming events scheduled. Check back soon!</p> |
|
</div> |
|
`; |
|
return; |
|
} |
|
|
|
activeEvents.forEach(event => { |
|
const eventDate = new Date(`${event.date}T${event.time}`); |
|
const options = { weekday: 'long', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' }; |
|
const formattedDate = eventDate.toLocaleDateString('en-US', options); |
|
|
|
const eventCard = document.createElement('div'); |
|
eventCard.className = 'event-card bg-gray-800 rounded-lg overflow-hidden transition-all duration-300 cursor-pointer'; |
|
eventCard.innerHTML = ` |
|
<div class="h-48 overflow-hidden"> |
|
<img src="${event.image}" alt="${event.title}" class="w-full h-full object-cover"> |
|
</div> |
|
<div class="p-6"> |
|
<h3 class="text-xl font-bold mb-2">${event.title}</h3> |
|
<p class="text-purple-400 mb-3">${formattedDate}</p> |
|
<p class="text-gray-400 mb-4 line-clamp-2">${event.description}</p> |
|
<div class="flex justify-between items-center"> |
|
<span class="bg-purple-600 text-white px-3 py-1 rounded-full text-sm font-medium"> |
|
$${event.price} |
|
</span> |
|
<button class="text-white hover:text-purple-300 font-medium"> |
|
More info <i class="fas fa-arrow-right ml-1"></i> |
|
</button> |
|
</div> |
|
</div> |
|
`; |
|
|
|
eventCard.addEventListener('click', () => openEventModal(event)); |
|
eventsContainer.appendChild(eventCard); |
|
}); |
|
|
|
|
|
updateReservationEventDropdown(); |
|
} |
|
|
|
|
|
function openEventModal(event) { |
|
selectedEvent = event; |
|
const eventDate = new Date(`${event.date}T${event.time}`); |
|
const options = { weekday: 'long', month: 'long', day: 'numeric', hour: '2-digit', minute: '2-digit' }; |
|
const formattedDate = eventDate.toLocaleDateString('en-US', options); |
|
|
|
modalEventTitle.textContent = event.title; |
|
modalEventDate.textContent = formattedDate; |
|
modalEventDescription.textContent = event.description; |
|
modalEventPrice.textContent = `$${event.price}`; |
|
|
|
|
|
modalEventImage.innerHTML = ''; |
|
const img = document.createElement('img'); |
|
img.src = event.image; |
|
img.alt = event.title; |
|
img.className = 'w-full h-full object-cover rounded-lg'; |
|
modalEventImage.appendChild(img); |
|
|
|
eventModal.classList.remove('hidden'); |
|
document.body.style.overflow = 'hidden'; |
|
} |
|
|
|
|
|
closeModal.addEventListener('click', function() { |
|
eventModal.classList.add('hidden'); |
|
document.body.style.overflow = ''; |
|
}); |
|
|
|
|
|
buyTicketsBtn.addEventListener('click', function() { |
|
eventModal.classList.add('hidden'); |
|
openTicketModal(); |
|
}); |
|
|
|
|
|
reserveTableBtn.addEventListener('click', function() { |
|
eventModal.classList.add('hidden'); |
|
|
|
navLinks.forEach(l => l.classList.remove('active')); |
|
document.querySelector('.nav-link[data-section="reservations"]').classList.add('active'); |
|
sectionContents.forEach(section => section.classList.add('hidden')); |
|
document.getElementById('reservations-section').classList.remove('hidden'); |
|
|
|
|
|
reservationEvent.value = selectedEvent.id; |
|
|
|
|
|
window.scrollTo(0, 0); |
|
}); |
|
|
|
|
|
function openTicketModal() { |
|
ticketEventTitle.textContent = selectedEvent.title; |
|
ticketUnitPrice.textContent = `$${selectedEvent.price}`; |
|
updateTicketTotal(); |
|
|
|
ticketModal.classList.remove('hidden'); |
|
document.body.style.overflow = 'hidden'; |
|
} |
|
|
|
|
|
closeTicketModal.addEventListener('click', function() { |
|
ticketModal.classList.add('hidden'); |
|
document.body.style.overflow = ''; |
|
}); |
|
|
|
|
|
decrementTicket.addEventListener('click', function() { |
|
if (ticketQuantity.value > 1) { |
|
ticketQuantity.value--; |
|
updateTicketDisplay(); |
|
} |
|
}); |
|
|
|
incrementTicket.addEventListener('click', function() { |
|
ticketQuantity.value++; |
|
updateTicketDisplay(); |
|
}); |
|
|
|
ticketQuantity.addEventListener('change', function() { |
|
if (this.value < 1) this.value = 1; |
|
updateTicketDisplay(); |
|
}); |
|
|
|
function updateTicketDisplay() { |
|
ticketQtyDisplay.textContent = ticketQuantity.value; |
|
updateTicketTotal(); |
|
} |
|
|
|
function updateTicketTotal() { |
|
const total = selectedEvent.price * ticketQuantity.value; |
|
ticketTotalPrice.textContent = `$${total.toFixed(2)}`; |
|
} |
|
|
|
|
|
confirmPurchase.addEventListener('click', function() { |
|
const name = document.getElementById('ticketName').value; |
|
const email = document.getElementById('ticketEmail').value; |
|
|
|
if (!name || !email) { |
|
showConfirmation('Error', 'Please fill in all required fields.', false); |
|
return; |
|
} |
|
|
|
|
|
ticketModal.classList.add('hidden'); |
|
showConfirmation('Purchase Complete!', `Your tickets for ${selectedEvent.title} have been reserved. A confirmation has been sent to ${email}.`, true); |
|
|
|
|
|
ticketQuantity.value = 1; |
|
document.getElementById('ticketName').value = ''; |
|
document.getElementById('ticketEmail').value = ''; |
|
updateTicketDisplay(); |
|
}); |
|
|
|
|
|
function generateTableLayout() { |
|
tableLayout.innerHTML = ''; |
|
const totalTables = tableRows * tablesPerRow; |
|
|
|
for (let i = 1; i <= totalTables; i++) { |
|
const table = document.createElement('div'); |
|
table.className = 'bg-gray-700 rounded-lg aspect-square flex items-center justify-center cursor-pointer hover:bg-gray-600 transition-colors'; |
|
table.innerHTML = ` |
|
<div class="text-center"> |
|
<i class="fas fa-utensils text-xl mb-1"></i> |
|
<div>Table ${i}</div> |
|
</div> |
|
`; |
|
|
|
table.addEventListener('click', () => selectTable(i)); |
|
|
|
|
|
const isReserved = reservations.some(r => r.table === i && |
|
events.some(e => e.id === r.eventId && e.active)); |
|
|
|
if (isReserved) { |
|
table.classList.add('bg-red-900', 'hover:bg-red-800'); |
|
table.classList.remove('bg-gray-700', 'hover:bg-gray-600'); |
|
} |
|
|
|
tableLayout.appendChild(table); |
|
} |
|
} |
|
|
|
|
|
function selectTable(tableNumber) { |
|
|
|
const isReserved = reservations.some(r => r.table === tableNumber && |
|
events.some(e => e.id === r.eventId && e.active)); |
|
|
|
if (isReserved) { |
|
showConfirmation('Table Reserved', `Table ${tableNumber} is already reserved for an event. Please choose another table.`, false); |
|
return; |
|
} |
|
|
|
|
|
document.querySelectorAll('#tableLayout > div').forEach(t => { |
|
t.classList.remove('table-selected'); |
|
}); |
|
|
|
|
|
const selectedTableElement = document.querySelector(`#tableLayout > div:nth-child(${tableNumber})`); |
|
selectedTableElement.classList.add('table-selected'); |
|
|
|
selectedTable = tableNumber; |
|
selectedTableInput.value = `Table ${tableNumber}`; |
|
} |
|
|
|
|
|
submitReservation.addEventListener('click', function() { |
|
const eventId = parseInt(reservationEvent.value); |
|
const name = document.getElementById('reservationName').value; |
|
const email = document.getElementById('reservationEmail').value; |
|
const phone = document.getElementById('reservationPhone').value; |
|
const guests = document.getElementById('reservationGuests').value; |
|
|
|
if (!eventId || !name || !email || !selectedTable) { |
|
showConfirmation('Error', 'Please fill in all required fields and select a table.', false); |
|
return; |
|
} |
|
|
|
|
|
const reservation = { |
|
id: Date.now(), |
|
eventId: eventId, |
|
table: selectedTable, |
|
name: name, |
|
email: email, |
|
phone: phone, |
|
guests: guests, |
|
date: new Date().toISOString() |
|
}; |
|
|
|
reservations.push(reservation); |
|
|
|
|
|
const event = events.find(e => e.id === eventId); |
|
showConfirmation('Reservation Confirmed!', `Your table at ${event.title} has been reserved. A confirmation has been sent to ${email}.`, true); |
|
|
|
|
|
selectedTable = null; |
|
selectedTableInput.value = ''; |
|
document.getElementById('reservationName').value = ''; |
|
document.getElementById('reservationEmail').value = ''; |
|
document.getElementById('reservationPhone').value = ''; |
|
document.getElementById('reservationGuests').value = '2'; |
|
|
|
|
|
generateTableLayout(); |
|
|
|
|
|
updateAdminReservationsList(); |
|
}); |
|
|
|
|
|
function showConfirmation(title, message, isSuccess) { |
|
confirmationTitle.textContent = title; |
|
confirmationMessage.textContent = message; |
|
|
|
const icon = document.querySelector('#confirmationModal .w-16'); |
|
icon.className = `w-16 h-16 rounded-full flex items-center justify-center mx-auto mb-4 ${isSuccess ? 'bg-green-500' : 'bg-red-500'}`; |
|
icon.innerHTML = isSuccess ? '<i class="fas fa-check text-2xl text-white"></i>' : '<i class="fas fa-times text-2xl text-white"></i>'; |
|
|
|
confirmationModal.classList.remove('hidden'); |
|
document.body.style.overflow = 'hidden'; |
|
} |
|
|
|
|
|
closeConfirmation.addEventListener('click', function() { |
|
confirmationModal.classList.add('hidden'); |
|
document.body.style.overflow = ''; |
|
}); |
|
|
|
|
|
function updateReservationEventDropdown() { |
|
reservationEvent.innerHTML = '<option value="">Select an event</option>'; |
|
|
|
const activeEvents = events.filter(event => event.active); |
|
activeEvents.forEach(event => { |
|
const option = document.createElement('option'); |
|
option.value = event.id; |
|
option.textContent = event.title; |
|
reservationEvent.appendChild(option); |
|
}); |
|
|
|
|
|
const ticketsEventDropdown = document.createElement('select'); |
|
ticketsEventDropdown.className = 'w-full bg-gray-700 rounded px-3 py-2 mb-4'; |
|
ticketsEventDropdown.innerHTML = '<option value="">Select an event to purchase tickets</option>'; |
|
|
|
activeEvents.forEach(event => { |
|
const option = document.createElement('option'); |
|
option.value = event.id; |
|
option.textContent = `${event.title} - $${event.price}`; |
|
ticketsEventDropdown.appendChild(option); |
|
}); |
|
|
|
ticketsEventDropdown.addEventListener('change', function() { |
|
const selectedId = parseInt(this.value); |
|
if (selectedId) { |
|
const event = events.find(e => e.id === selectedId); |
|
selectedEvent = event; |
|
openTicketModal(); |
|
} |
|
}); |
|
|
|
ticketsContainer.innerHTML = ''; |
|
ticketsContainer.appendChild(ticketsEventDropdown); |
|
} |
|
|
|
|
|
function setupAdminPanel() { |
|
|
|
tableRowsInput.value = tableRows; |
|
tablesPerRowInput.value = tablesPerRow; |
|
|
|
|
|
updateTableLayout.addEventListener('click', function() { |
|
tableRows = parseInt(tableRowsInput.value); |
|
tablesPerRow = parseInt(tablesPerRowInput.value); |
|
generateTableLayout(); |
|
}); |
|
|
|
|
|
addEvent.addEventListener('click', function() { |
|
const title = eventTitle.value.trim(); |
|
const date = eventDate.value; |
|
const time = eventTime.value; |
|
const description = eventDescription.value.trim(); |
|
const price = parseFloat(eventPrice.value); |
|
const image = eventImage.value.trim(); |
|
|
|
if (!title || !date || !time || !description || isNaN(price) || !image) { |
|
alert('Please fill in all fields with valid data'); |
|
return; |
|
} |
|
|
|
const newEvent = { |
|
id: Date.now(), |
|
title: title, |
|
date: date, |
|
time: time, |
|
description: description, |
|
price: price, |
|
image: image, |
|
active: true |
|
}; |
|
|
|
events.push(newEvent); |
|
renderEvents(); |
|
updateAdminEventsList(); |
|
|
|
|
|
eventTitle.value = ''; |
|
eventDate.value = ''; |
|
eventTime.value = ''; |
|
eventDescription.value = ''; |
|
eventPrice.value = ''; |
|
eventImage.value = ''; |
|
}); |
|
|
|
|
|
updateAdminEventsList(); |
|
updateAdminReservationsList(); |
|
} |
|
|
|
|
|
function updateAdminEventsList() { |
|
adminEventsList.innerHTML = ''; |
|
|
|
events.forEach(event => { |
|
const eventElement = document.createElement('div'); |
|
eventElement.className = 'bg-gray-700 p-3 rounded flex justify-between items-center'; |
|
eventElement.innerHTML = ` |
|
<div> |
|
<h4 class="font-medium">${event.title}</h4> |
|
<p class="text-sm text-gray-400">${event.date} at ${event.time}</p> |
|
</div> |
|
<div class="flex space-x-2"> |
|
<button class="toggle-event px-3 py-1 rounded text-sm ${event.active ? 'bg-green-600 hover:bg-green-700' : 'bg-gray-600 hover:bg-gray-500'}" data-id="${event.id}"> |
|
${event.active ? 'Active' : 'Inactive'} |
|
</button> |
|
<button class="delete-event px-3 py-1 rounded text-sm bg-red-600 hover:bg-red-700" data-id="${event.id}"> |
|
<i class="fas fa-trash"></i> |
|
</button> |
|
</div> |
|
`; |
|
|
|
adminEventsList.appendChild(eventElement); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.toggle-event').forEach(button => { |
|
button.addEventListener('click', function() { |
|
const eventId = parseInt(this.getAttribute('data-id')); |
|
const event = events.find(e => e.id === eventId); |
|
if (event) { |
|
event.active = !event.active; |
|
updateAdminEventsList(); |
|
renderEvents(); |
|
} |
|
}); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.delete-event').forEach(button => { |
|
button.addEventListener('click', function() { |
|
if (confirm('Are you sure you want to delete this event?')) { |
|
const eventId = parseInt(this.getAttribute('data-id')); |
|
events = events.filter(e => e.id !== eventId); |
|
updateAdminEventsList(); |
|
renderEvents(); |
|
} |
|
}); |
|
}); |
|
} |
|
|
|
|
|
function updateAdminReservationsList() { |
|
reservationsList.innerHTML = ''; |
|
|
|
if (reservations.length === 0) { |
|
reservationsList.innerHTML = '<p class="text-gray-400 text-center py-4">No reservations yet</p>'; |
|
return; |
|
} |
|
|
|
|
|
const sortedReservations = [...reservations].sort((a, b) => new Date(b.date) - new Date(a.date)); |
|
|
|
sortedReservations.forEach(reservation => { |
|
const event = events.find(e => e.id === reservation.eventId); |
|
if (!event) return; |
|
|
|
const reservationElement = document.createElement('div'); |
|
reservationElement.className = 'bg-gray-700 p-3 rounded'; |
|
reservationElement.innerHTML = ` |
|
<div class="flex justify-between items-start mb-2"> |
|
<h4 class="font-medium">${event.title}</h4> |
|
<button class="delete-reservation text-red-400 hover:text-red-300 text-sm" data-id="${reservation.id}"> |
|
<i class="fas fa-trash"></i> |
|
</button> |
|
</div> |
|
<div class="grid grid-cols-2 gap-2 text-sm"> |
|
<div> |
|
<span class="text-gray-400">Table:</span> |
|
<span>${reservation.table}</span> |
|
</div> |
|
<div> |
|
<span class="text-gray-400">Guests:</span> |
|
<span>${reservation.guests}</span> |
|
</div> |
|
<div> |
|
<span class="text-gray-400">Name:</span> |
|
<span>${reservation.name}</span> |
|
</div> |
|
<div> |
|
<span class="text-gray-400">Contact:</span> |
|
<span>${reservation.email}</span> |
|
</div> |
|
<div class="col-span-2 text-xs text-gray-500"> |
|
Reserved on: ${new Date(reservation.date).toLocaleString()} |
|
</div> |
|
</div> |
|
`; |
|
|
|
reservationsList.appendChild(reservationElement); |
|
}); |
|
|
|
|
|
document.querySelectorAll('.delete-reservation').forEach(button => { |
|
button.addEventListener('click', function() { |
|
if (confirm('Are you sure you want to delete this reservation?')) { |
|
const reservationId = parseInt(this.getAttribute('data-id')); |
|
reservations = reservations.filter(r => r.id !== reservationId); |
|
updateAdminReservationsList(); |
|
generateTableLayout(); |
|
} |
|
}); |
|
}); |
|
} |
|
</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=Dataio/tunk" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
|
</html> |