feat(app): add initial Berlayar Sinema event landing page

This commit introduces the complete initial version of the "Berlayar Sinema" event landing page application. It includes the core HTML structure, CSS for styling, and JavaScript for interactivity.

Key features implemented:
- Responsive layout with Hero, Sponsors, and Film Screening sections.
- A registration form that submits data to a backend webhook.
- An interactive chat assistant powered by a separate webhook.
- Modals for successful registration and a promotional flyer popup.
- All necessary static assets, including images, logos, and posters.
This commit is contained in:
Emmanuel Rizky
2025-07-25 11:25:35 +07:00
commit bd83b83f25
16 changed files with 961 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1,321 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Berlayar Sinema: Registration</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">
<link rel="stylesheet" href="style.css">
</head>
<body>
<!-- Hero Section -->
<section class="hero-section text-white py-20 md:py-32">
<div class="container mx-auto px-4 text-center">
<h1 class="title-font text-4xl md:text-6xl font-bold mb-6">BERLAYAR SINEMA</h1>
<h2 class="text-2xl md:text-3xl font-semibold mb-8">SILATURASA DAN MENENUN KOMUNITAS FILM INDONESIA</h2>
<p class="text-lg md:text-xl max-w-3xl mx-auto mb-10"></p>
<a href="#registration-form" class="bg-yellow-500 hover:bg-yellow-600 text-purple-900 font-bold py-3 px-8 rounded-full text-lg transition-colors inline-block">
Daftar Sekarang! <i class="fas fa-arrow-right ml-2"></i>
</a>
</div>
</section>
<!-- Sponsors Section -->
<section class="py-16 bg-white">
<div class="container mx-auto px-4">
<h2 class="title-font text-3xl font-bold text-center mb-12 text-purple-900">Didukung Oleh</h2>
<div class="sponsor-container">
<div class="sponsor-track">
<!-- Original set -->
<div class="sponsor-slide">
<img src="assets/sponsor1.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor2.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor3.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor4.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor5.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor1.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor2.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor6.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor7.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor1.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor2.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor3.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<!-- Duplicate set for seamless looping -->
<div class="sponsor-slide">
<img src="assets/sponsor4.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor5.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor6.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor7.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor1.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor2.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor3.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor4.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor5.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor6.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor7.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
<div class="sponsor-slide">
<img src="assets/sponsor1.png" alt="Sponsor" class="sponsor-logo max-h-16">
</div>
</div>
</div>
</div>
</section>
<!-- Featured Films Section -->
<section class="py-16 bg-gray-100">
<div class="container mx-auto px-4">
<h2 class="title-font text-3xl font-bold text-center mb-12 text-purple-900">Special Screening</h2>
<div id="film-carousel-container" class="relative max-w-5xl mx-auto">
<div id="film-carousel" class="flex overflow-x-auto snap-x snap-mandatory scroll-smooth md:grid md:grid-cols-3 md:gap-8 md:overflow-x-visible">
<!-- Film 1 -->
<div class="film-card bg-white rounded-lg overflow-hidden shadow-lg w-4/5 flex-shrink-0 snap-center md:w-auto">
<div class="aspect-[2/3] w-full overflow-hidden">
<img src="assets/poster1.jpeg" alt="The Echoes of Tomorrow" class="w-full h-full object-cover">
</div>
<div class="p-6">
<h3 class="title-font text-xl font-bold mb-3 text-purple-900">Mbok dan Bung</h3>
<p class="text-gray-700 mb-2 font-semibold">Sutradara: Ninndi Raras</p>
<p class="text-gray-700 mb-4">
Sebuah film pendek yang mengisahkan tentang sosok Sarinah, pengasuh Soekarno semasa kecil.
</p>
<div class="flex flex-wrap gap-2">
<span class="bg-purple-100 text-purple-800 text-xs px-3 py-1 rounded-full">Drama</span>
<span class="bg-purple-100 text-purple-800 text-xs px-3 py-1 rounded-full">Biografi</span>
</div>
</div>
</div>
<!-- Film 2 -->
<div class="film-card bg-white rounded-lg overflow-hidden shadow-lg w-4/5 flex-shrink-0 snap-center md:w-auto">
<div class="aspect-[2/3] w-full overflow-hidden">
<img src="assets/poster3.jpeg" alt="Whispers of the Old City" class="w-full h-full object-cover">
</div>
<div class="p-6">
<h3 class="title-font text-xl font-bold mb-3 text-purple-900">Kitorang Basudara</h3>
<p class="text-gray-700 mb-2 font-semibold">Sutradara: Ninndi Raras</p>
<p class="text-gray-700 mb-4">
Rony dan Berto, dua bersaudara Papua, merantau ke Yogyakarta, menghadapi diskriminasi rasial saat mencari kos, sementara Berto beradaptasi dengan pekerjaan kakaknya sebagai penagih utang.
</p>
<div class="flex flex-wrap gap-2">
<span class="bg-purple-100 text-purple-800 text-xs px-3 py-1 rounded-full">Drama</span>
</div>
</div>
</div>
<div class="film-card bg-white rounded-lg overflow-hidden shadow-lg w-4/5 flex-shrink-0 snap-center md:w-auto">
<div class="aspect-[2/3] w-full overflow-hidden">
<img src="assets/poster2.jpg" alt="Whispers of the Old City" class="w-full h-full object-cover">
</div>
<div class="p-6">
<h3 class="title-font text-xl font-bold mb-3 text-purple-900">Laila</h3>
<p class="text-gray-700 mb-2 font-semibold">Sutradara: Bayu Pradityo</p>
<p class="text-gray-700 mb-4">
Laila, disabilitas yang rentan, depresi setelah yatim piatu dan masuk panti. Ia bangkit mandiri, lalu menemukan kekuatan untuk menerima kepergian orangtuanya.
</p>
<div class="flex flex-wrap gap-2">
<span class="bg-purple-100 text-purple-800 text-xs px-3 py-1 rounded-full">Dokumenter</span>
</div>
</div>
</div>
</div>
<button id="prev-film" class="absolute top-1/2 left-0 transform -translate-y-1/2 bg-white bg-opacity-50 rounded-full p-2 hidden"><</button>
<button id="next-film" class="absolute top-1/2 right-0 transform -translate-y-1/2 bg-white bg-opacity-50 rounded-full p-2 hidden">></button>
</div>
</div>
</section>
<!-- Registration Form Section -->
<section id="registration-form" class="py-16 bg-purple-900 text-white">
<div class="container mx-auto px-4 max-w-4xl">
<h2 class="title-font text-3xl font-bold text-center mb-12">Daftar Sekarang!</h2>
<form id="eventRegistration" class="glass-card bg-white bg-opacity-20 backdrop-blur-md border border-white border-opacity-30 rounded-xl p-6 md:p-8 text-white shadow-xl">
<div class="mb-6">
<label for="fullName" class="block text-white font-semibold mb-2 text-sm uppercase tracking-wider">Nama Lengkap <span class="text-yellow-300">*</span></label>
<input type="text" id="fullName" name="fullName" required
class="form-input w-full px-4 py-3 bg-white border border-white rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-300 text-purple-900 placeholder-gray-500 font-medium transition-all duration-200" placeholder="Contoh: Budi Santoso">
</div>
<div class="mb-6">
<label for="email" class="block text-white font-medium mb-2 text-sm uppercase tracking-wider">Email <span class="text-red-300">*</span></label>
<input type="email" id="email" name="email" required
class="form-input w-full px-4 py-3 bg-white border border-purple-400 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-300 text-purple-900 placeholder-gray-500 font-medium transition-all duration-200" placeholder="Contoh: budi@gmail.com">
</div>
<div class="mb-6">
<label for="phone" class="block text-white font-medium mb-2 text-sm uppercase tracking-wider">Nomor Telepon/WhatsApp <span class="text-red-300">*</span></label>
<div class="flex">
<span class="inline-flex items-center px-3 rounded-l-lg border border-r-0 border-purple-300 bg-gray-200 text-gray-600">
+62
</span>
<input type="tel" id="phone" name="phone" required
class="form-input w-full px-4 py-3 bg-white border border-purple-300 rounded-r-lg focus:outline-none focus:ring-2 focus:ring-purple-300 text-purple-900 placeholder-gray-500 font-medium transition-all duration-200" placeholder="81234567890">
</div>
</div>
<div class="mb-6">
<label for="socialMedia" class="block text-white font-medium mb-2 text-sm uppercase tracking-wider">Akun Media Sosial<span class="text-red-300">*</span></label>
<input type="text" id="socialMedia" name="socialMedia" required
class="form-input w-full px-4 py-3 bg-white border border-purple-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-300 text-purple-900 placeholder-gray-500 font-medium transition-all duration-200" placeholder="Contoh: @budi_santoso">
</div>
<div class="mb-6">
<label for="origin" class="block text-white font-medium mb-2">Asal Komunitas/Institusi/Pekerjaan <span class="text-yellow-300">*</span></label>
<input type="text" id="origin" name="origin" required
class="form-input w-full px-4 py-3 bg-white bg-opacity-90 border border-purple-400 rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-300 text-white placeholder-purple-100 font-medium transition-all duration-200 hover:bg-opacity-100" placeholder="Contoh: Komunitas Film Kediri">
</div>
<div class="mb-6">
<label for="category" class="block text-white font-medium mb-2">Pilihan Kategori Peserta <span class="text-red-500">*</span></label>
<select id="category" name="category" required
class="form-input w-full px-4 py-3 bg-white text-purple-900 border border-white rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-300">
<option value="" disabled selected>Pilih kategori</option>
<option value="Komunitas Film">Komunitas Film Kediri</option>
<option value="Sineas Muda/Pelajar Broadcasting/Perfilman">Sineas Muda/Pelajar Broadcasting/Perfilman</option>
<option value="Pegiat Seni Visual">Pegiat Seni Visual</option>
<option value="Perwakilan Komunitas Lokal">Perwakilan Komunitas Lokal</option>
<option value="Masyarakat Umum/Peminat Film & Industri Kreatif">Masyarakat Umum/Peminat Film & Industri Kreatif</option>
</select>
</div>
<div class="mb-6">
<label for="discovery" class="block text-white font-medium mb-2">Bagaimana Anda mengetahui acara ini? <span class="text-red-500">*</span></label>
<input type="text" id="discovery" name="discovery" required
class="form-input w-full px-4 py-2 bg-white border rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 text-purple-900 placeholder-gray-500" placeholder="Contoh: Instagram, teman, dll">
</div>
<div class="mb-6">
<label for="expectation" class="block text-white font-medium mb-2">Harapan apa yang Anda miliki dari kegiatan ini? <span class="text-red-500">*</span></label>
<textarea id="expectation" name="expectation" rows="3" required
class="form-input w-full px-4 py-2 bg-white border border-white rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-300 text-purple-900 placeholder-gray-500 font-medium" placeholder="Contoh: Saya ingin belajar lebih banyak tentang produksi film"></textarea>
</div>
<div class="mb-8">
<label for="discussionTopic" class="block text-white font-medium mb-2">Pertanyaan/topik khusus yang ingin didiskusikan terkait perfilman lokal? (opsional)</label>
<textarea id="discussionTopic" name="discussionTopic" rows="3"
class="form-input w-full px-4 py-2 bg-white border rounded-lg focus:outline-none focus:ring-2 focus:ring-purple-500 text-purple-900 placeholder-gray-500" placeholder="Contoh: Bagaimana cara memulai produksi film indie?"></textarea>
</div>
<button type="submit" class="w-full bg-gradient-to-r from-yellow-400 to-yellow-500 hover:from-yellow-500 hover:to-yellow-600 text-purple-900 font-bold py-4 px-6 rounded-lg transition-all duration-300 shadow-lg hover:shadow-xl transform hover:-translate-y-1 uppercase tracking-wider">
DAFTAR SEKARANG <i class="fas fa-paper-plane ml-2"></i>
</button>
</form>
</div>
</section>
<!-- Footer -->
<footer class="bg-gray-900 text-white py-8">
<div class="container mx-auto px-4 text-center">
<p class="text-gray-400 text-sm">
© 2025 Kediri Technopark. Hak Cipta Dilindungi.
</p>
</div>
</footer>
<!-- Success Modal -->
<div id="successModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center hidden z-50">
<div class="glass-card rounded-2xl p-8 max-w-md w-full mx-4 text-center text-white glass-card">
<div class="text-green-500 text-6xl mb-4">
<i class="fas fa-check-circle"></i>
</div>
<h3 class="text-2xl font-bold text-white-800 mb-4">Pendaftaran Berhasil!</h3>
<p class="text-white-600 mb-6">
Terima kasih telah mendaftar untuk Berlayar Sinema. Kami telah mengirimkan konfirmasi ke WhatsApp Anda.
</p>
<button id="closeModal" class="bg-gradient-to-r from-yellow-400 to-yellow-500 hover:from-yellow-500 hover:to-yellow-600 text-purple-900 font-bold py-2 px-6 rounded-lg transition-colors">
Tutup
</button>
</div>
</div>
<!-- Image Popup Modal -->
<div id="imagePopup" class="fixed inset-0 bg-black bg-opacity-70 flex items-center justify-center hidden z-50">
<div class="relative bg-white p-4 rounded-lg shadow-lg max-w-lg mx-4 sm:mx-auto">
<button id="closeImagePopup" class="absolute top-2 right-2 text-gray-700 hover:text-gray-900 text-2xl font-bold">&times;</button>
<img src="assets/flyer1.jpeg" alt="Popup Image" class="w-full h-auto rounded-lg">
</div>
</div>
<!-- Floating Chat Button -->
<div class="fixed bottom-8 right-8 z-40">
<button id="chatButton" class="bg-gradient-to-r from-yellow-400 to-yellow-500 hover:from-yellow-500 hover:to-yellow-600 text-purple-900 w-16 h-16 rounded-full shadow-lg flex items-center justify-center transition-all duration-300 hover:scale-110">
<i class="fas fa-comment-dots text-2xl"></i>
</button>
<div id="chatWindow" class="hidden absolute bottom-20 right-0 w-80 bg-white rounded-lg shadow-xl overflow-hidden glass-card">
<div class="bg-purple-900 text-white p-4 flex flex-col items-start">
<h3 class="font-bold text-lg">Maya</h3>
<p class="text-sm text-purple-200">Virtual Agent - Kediri Technopark</p>
<button id="closeChat" class="absolute top-4 right-4 text-white hover:text-purple-200">
<i class="fas fa-times"></i>
</button>
</div>
<div class="p-4 h-64 overflow-y-auto bg-white">
<div class="mb-4 text-left">
<p class="chat-message-received">
Hai! Aku Maya, asisten virtual Berlayar Sinema. Ada yang bisa kubantu? Aku bisa kasih info detail acara, sinopsis film, sampai info narasumber lho. Tanya aja ya!
</p>
</div>
</div>
<div class="p-4 border-t border-purple-800 bg-purple-900">
<div class="flex">
<input type="text" placeholder="Ketik pesan..." class="flex-1 border border-purple-700 bg-white text-purple-900 rounded-l-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-yellow-500 placeholder-gray-500">
<button class="bg-yellow-500 hover:bg-yellow-600 text-purple-900 px-4 py-2 rounded-r-lg">
<i class="fas fa-paper-plane"></i>
</button>
</div>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,358 @@
document.addEventListener('DOMContentLoaded', () => {
const registrationForm = document.getElementById('eventRegistration');
const successModal = document.getElementById('successModal');
const closeModal = document.getElementById('closeModal');
const chatButton = document.getElementById('chatButton');
const chatWindow = document.getElementById('chatWindow');
const closeChat = document.getElementById('closeChat');
const imagePopup = document.getElementById('imagePopup');
const closeImagePopup = document.getElementById('closeImagePopup');
// Form submission handling
if (registrationForm) {
registrationForm.addEventListener('submit', function(event) {
event.preventDefault();
let isValid = true;
// Simple validation example
const fullName = document.getElementById('fullName');
const email = document.getElementById('email');
const phone = document.getElementById('phone');
const socialMedia = document.getElementById('socialMedia');
const origin = document.getElementById('origin');
const category = document.getElementById('category');
const discovery = document.getElementById('discovery');
const expectation = document.getElementById('expectation');
if (fullName.value.trim() === '') {
isValid = false;
alert('Please enter your full name.');
} else if (email.value.trim() === '' || !email.value.includes('@')) {
isValid = false;
alert('Please enter a valid email address.');
} else if (phone.value.trim() === '') {
isValid = false;
alert('Please enter your phone number.');
} else if (socialMedia.value.trim() === '') {
isValid = false;
alert('Please enter your social media account.');
} else if (origin.value.trim() === '') {
isValid = false;
alert('Please enter your origin.');
} else if (category.value === '') {
isValid = false;
alert('Please select a category.');
} else if (discovery.value.trim() === '') {
isValid = false;
alert('Please let us know how you discovered this event.');
} else if (expectation.value.trim() === '') {
isValid = false;
alert('Please enter your expectation.');
}
if (isValid) {
let phoneNumber = phone.value.trim();
if (phoneNumber.startsWith('0')) {
phoneNumber = '62' + phoneNumber.substring(1);
} else if (!phoneNumber.startsWith('62')) {
phoneNumber = '62' + phoneNumber;
}
const formData = {
Nama: fullName.value,
Email: email.value,
WhatsApp: phoneNumber,
Akun_Sosial_Media: socialMedia.value,
Asal_Komunitas: origin.value,
Kategori_Peserta: category.value,
Informasi_Event: discovery.value,
Harapan: expectation.value,
Pertanyaan_Diskusi: document.getElementById('discussionTopic').value
};
fetch('https://bot.kediritechnopark.com/webhook/form-berlayar-sinema', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Form submission successful:', data);
// Show success modal
if (successModal) {
successModal.classList.remove('hidden');
successModal.classList.add('flex');
}
// Reset form
registrationForm.reset();
})
.catch(error => {
console.error('Form submission failed:', error);
alert('Pendaftaran gagal. Silakan coba lagi nanti.');
});
// Show success modal
if (successModal) {
successModal.classList.remove('hidden');
successModal.classList.add('flex');
}
// Reset form
registrationForm.reset();
}
});
}
// Close success modal
if (closeModal) {
closeModal.addEventListener('click', () => {
if (successModal) {
successModal.classList.add('hidden');
successModal.classList.remove('flex');
}
});
}
// Image popup on page load
if (imagePopup) {
// Show the popup after a short delay
setTimeout(() => {
imagePopup.classList.remove('hidden');
imagePopup.classList.add('flex');
}, 1000); // Show after 1 second
// Close image popup
if (closeImagePopup) {
closeImagePopup.addEventListener('click', () => {
imagePopup.classList.add('hidden');
imagePopup.classList.remove('flex');
});
}
}
// Chat window functionality
if (chatButton && chatWindow && closeChat) {
// Film carousel functionality
const filmCarousel = document.getElementById('film-carousel');
const prevFilmButton = document.getElementById('prev-film');
const nextFilmButton = document.getElementById('next-film');
if (filmCarousel && prevFilmButton && nextFilmButton) {
let filmInterval;
const startFilmCarousel = () => {
if (window.innerWidth < 768) {
filmInterval = setInterval(() => {
if (filmCarousel.scrollLeft + filmCarousel.clientWidth >= filmCarousel.scrollWidth) {
filmCarousel.scrollTo({ left: 0, behavior: 'smooth' });
} else {
filmCarousel.scrollBy({ left: filmCarousel.clientWidth, behavior: 'smooth' });
}
}, 3000);
}
};
const stopFilmCarousel = () => {
clearInterval(filmInterval);
};
const setupFilmCarousel = () => {
stopFilmCarousel();
startFilmCarousel();
updateCarouselButtons();
};
const updateCarouselButtons = () => {
if (window.innerWidth < 768) {
prevFilmButton.classList.toggle('film-carousel-btn-hidden', filmCarousel.scrollLeft === 0);
nextFilmButton.classList.toggle('film-carousel-btn-hidden', filmCarousel.scrollLeft + filmCarousel.clientWidth >= filmCarousel.scrollWidth - 1);
} else {
prevFilmButton.classList.add('film-carousel-btn-hidden');
nextFilmButton.classList.add('film-carousel-btn-hidden');
}
};
filmCarousel.addEventListener('scroll', () => {
updateCarouselButtons();
});
nextFilmButton.addEventListener('click', () => {
stopFilmCarousel();
filmCarousel.scrollBy({ left: filmCarousel.clientWidth, behavior: 'smooth' });
startFilmCarousel();
});
prevFilmButton.addEventListener('click', () => {
stopFilmCarousel();
filmCarousel.scrollBy({ left: -filmCarousel.clientWidth, behavior: 'smooth' });
startFilmCarousel();
});
window.addEventListener('resize', setupFilmCarousel);
const equalizeCardHeights = () => {
if (window.innerWidth < 768) {
const filmCards = filmCarousel.querySelectorAll('.film-card');
let maxHeight = 0;
filmCards.forEach(card => {
card.style.height = 'auto';
if (card.offsetHeight > maxHeight) {
maxHeight = card.offsetHeight;
}
});
filmCards.forEach(card => {
card.style.height = `${maxHeight}px`;
});
} else {
const filmCards = filmCarousel.querySelectorAll('.film-card');
filmCards.forEach(card => {
card.style.height = '100%';
});
}
};
window.addEventListener('resize', () => {
setupFilmCarousel();
equalizeCardHeights();
});
setupFilmCarousel();
equalizeCardHeights();
}
const chatInput = chatWindow.querySelector('input[type="text"]');
const sendButton = chatWindow.querySelector('button.bg-yellow-500');
const chatMessagesContainer = chatWindow.querySelector('.p-4.h-64.overflow-y-auto');
let sessionId = null;
function generateUUID() { // Public Domain/MIT
var d = new Date().getTime();//Timestamp
var d2 = ((typeof performance !== 'undefined') && performance.now && (performance.now()*1000)) || 0;//Time in microseconds since page-load or 0 if unsupported
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16;//random number between 0 and 16
if(d > 0){//Use timestamp until depleted
r = (d + r)%16 | 0;
d = Math.floor(d/16);
} else {//Use microseconds since page-load if supported
r = (d2 + r)%16 | 0;
d2 = Math.floor(d2/16);
}
return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
});
}
chatButton.addEventListener('click', () => {
chatWindow.classList.toggle('hidden');
if (!sessionId) {
sessionId = generateUUID();
console.log('Chat session started with ID:', sessionId);
}
});
closeChat.addEventListener('click', () => {
chatWindow.classList.add('hidden');
});
sendButton.addEventListener('click', () => {
sendMessage();
});
chatInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
sendMessage();
}
});
function sendMessage() {
const messageText = chatInput.value.trim();
if (messageText === '') return;
// Display sent message
const sentMessageDiv = document.createElement('div');
sentMessageDiv.className = 'mb-4 text-right';
sentMessageDiv.innerHTML = `<p class="chat-message-sent">${messageText}</p>`;
chatMessagesContainer.appendChild(sentMessageDiv);
chatInput.value = ''; // Clear input
// Show typing indicator
const typingIndicator = document.createElement('div');
typingIndicator.className = 'mb-4 text-left typing-indicator';
typingIndicator.innerHTML = '<span></span><span></span><span></span>';
chatMessagesContainer.appendChild(typingIndicator);
// Scroll to bottom
chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight;
// Send message to webhook
fetch('https://bot.kediritechnopark.com/webhook/chat-berlayar-sinema', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ message: messageText, sessionId: sessionId }),
})
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Chat message sent successfully:', data);
// Remove typing indicator
chatMessagesContainer.removeChild(typingIndicator);
// Display response from the webhook
if (data && data.output) {
const receivedMessageDiv = document.createElement('div');
receivedMessageDiv.className = 'mb-4 text-left';
receivedMessageDiv.innerHTML = `<p class="chat-message-received">${data.output}</p>`;
chatMessagesContainer.appendChild(receivedMessageDiv);
chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight;
}
})
.catch(error => {
console.error('Chat message failed to send:', error);
// Remove typing indicator
chatMessagesContainer.removeChild(typingIndicator);
// Optionally, display an error message in the chat
const errorMessageDiv = document.createElement('div');
errorMessageDiv.className = 'mb-4 text-left';
errorMessageDiv.innerHTML = `<p class="chat-message-received text-red-500">Error: Could not send message.</p>`;
chatMessagesContainer.appendChild(errorMessageDiv);
chatMessagesContainer.scrollTop = chatMessagesContainer.scrollHeight;
});
}
}
// Observer to disable chat button when image popup is active
if (imagePopup && chatButton) {
const observer = new MutationObserver((mutationsList) => {
for (const mutation of mutationsList) {
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
if (!imagePopup.classList.contains('hidden')) {
chatButton.classList.add('opacity-50', 'cursor-not-allowed');
chatButton.disabled = true;
} else {
chatButton.classList.remove('opacity-50', 'cursor-not-allowed');
chatButton.disabled = false;
}
}
}
});
observer.observe(imagePopup, { attributes: true });
// Initial check
if (!imagePopup.classList.contains('hidden')) {
chatButton.classList.add('opacity-50', 'cursor-not-allowed');
chatButton.disabled = true;
}
}
});

View File

@@ -0,0 +1,282 @@
@import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&family=Roboto:wght@300;400;500;700&display=swap');
body {
font-family: 'Roboto', sans-serif;
background-color: #f8f9fa;
}
.hero-section {
background: linear-gradient(rgba(0, 0, 0, 0.3), rgba(0, 0, 0, 0.3)),
url('assets/hero-cover.png');
background-size: cover;
background-position: center;
backdrop-filter: blur(10px);
}
.glass-card {
background: rgba(255, 255, 255, 0.2);
backdrop-filter: blur(10px);
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.2);
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.2);
}
.film-card {
transition: transform 0.3s ease, box-shadow 0.3s ease;
display: flex;
flex-direction: column;
height: 100%;
}
.film-card .p-6 {
flex-grow: 1;
display: flex;
flex-direction: column;
}
.film-card .p-6 .flex-wrap {
margin-top: auto;
}
.film-card:hover {
transform: translateY(-10px);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.sponsor-logo {
filter: grayscale(100%);
opacity: 0.7;
transition: all 0.3s ease;
}
.sponsor-logo:hover {
filter: grayscale(0%);
opacity: 1;
}
.form-input {
transition: all 0.3s ease;
}
.form-input:focus {
border-color: #6b46c1;
box-shadow: 0 0 0 3px rgba(107, 70, 193, 0.2);
}
.title-font {
font-family: 'Poppins', sans-serif;
font-weight: 700;
}
/* Form styling */
#registration-form {
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
#registration-form input,
#registration-form textarea,
#registration-form select {
transition: all 0.3s ease;
}
#registration-form input:focus,
#registration-form textarea:focus,
#registration-form select:focus {
box-shadow: 0 0 0 3px rgba(192, 132, 252, 0.5);
}
#registration-form input::placeholder,
#registration-form textarea::placeholder {
color: #A9A9A9; /* Solid light gray */
}
#registration-form input:not(:placeholder-shown),
#registration-form textarea:not(:placeholder-shown),
#registration-form select:not([value=""]) {
color: #4B0082; /* Solid dark purple for active input */
}
@keyframes scroll {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
.animate-scroll {
display: inline-block;
animation: scroll 20s linear infinite;
}
.sponsor-carousel:hover .animate-scroll {
animation-play-state: paused;
}
.sponsor-container {
position: relative;
overflow: hidden;
}
.sponsor-container::before, .sponsor-container::after {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 100px;
pointer-events: none;
z-index: 2;
}
@media (max-width: 640px) {
.sponsor-container::before, .sponsor-container::after {
width: 50px;
}
}
.sponsor-container::before {
left: 0;
background: linear-gradient(90deg, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 100%);
}
.sponsor-container::after {
right: 0;
background: linear-gradient(270deg, rgba(255,255,255,0.8) 0%, rgba(255,255,255,0) 100%);
}
@media (max-width: 640px) {
.sponsor-container::before {
background: linear-gradient(90deg, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0) 100%);
}
.sponsor-container::after {
background: linear-gradient(270deg, rgba(255,255,255,0.9) 0%, rgba(255,255,255,0) 100%);
}
}
.sponsor-track {
display: flex;
width: max-content;
animation: scroll 20s linear infinite;
}
.sponsor-track:hover {
animation-play-state: paused;
}
.sponsor-slide {
display: flex;
align-items: center;
justify-content: center;
padding: 0 2rem;
}
/* Improved dropdown styles */
#registration-form select {
border: 1px solid rgba(255, 255, 255, 0.3);
}
#registration-form select option {
background-color: #ffffff;
color: #6b46c1;
}
/* Chat window styles */
#chatWindow {
background: rgba(255, 255, 255, 0.15); /* Slightly more opaque than glass-card for better readability */
backdrop-filter: blur(15px); /* Stronger blur for frosted effect */
border-radius: 20px;
border: 1px solid rgba(255, 255, 255, 0.3); /* Slightly more visible border */
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37); /* Stronger shadow */
transition: all 0.3s ease;
transform-origin: bottom right;
}
#chatWindow:not(.hidden) {
animation: chatFadeIn 0.3s ease;
}
@keyframes chatFadeIn {
from {
opacity: 0;
transform: scale(0.8) translateY(10px);
}
to {
opacity: 1;
transform: scale(1) translateY(0);
}
}
/* Chat bubble styles */
.chat-message-received {
background-color: #e9d5ff; /* Purple pastel for received messages */
color: #4b0082; /* Dark purple text */
border-radius: 1.25rem; /* Rounded corners */
padding: 0.75rem 1rem;
display: inline-block;
max-width: 75%; /* Limit width */
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
margin-bottom: 0.5rem;
}
.chat-message-sent {
background-color: #6b46c1; /* Purple for sent messages */
color: #ffffff; /* White text */
border-radius: 1.25rem;
padding: 0.75rem 1rem;
display: inline-block;
max-width: 75%;
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
margin-bottom: 0.5rem;
}
/* Typing indicator styles */
.typing-indicator {
display: flex;
align-items: center;
padding: 0.75rem 1rem;
}
.typing-indicator span {
height: 8px;
width: 8px;
background-color: #4b0082;
border-radius: 50%;
display: inline-block;
margin: 0 2px;
animation: bounce 1.4s infinite both;
}
.typing-indicator span:nth-child(1) {
animation-delay: -0.32s;
}
.typing-indicator span:nth-child(2) {
animation-delay: -0.16s;
}
@keyframes bounce {
0%, 80%, 100% {
transform: scale(0);
}
40% {
transform: scale(1.0);
}
}
.film-carousel-btn-hidden {
opacity: 0 !important;
pointer-events: none !important;
}
/* Hide scrollbar for film carousel */
#film-carousel::-webkit-scrollbar {
display: none;
}
#film-carousel {
-ms-overflow-style: none; /* IE and Edge */
scrollbar-width: none; /* Firefox */
gap: 1rem;
align-items: stretch;
padding-bottom: 1rem;
}