430 lines
20 KiB
Plaintext
430 lines
20 KiB
Plaintext
@{
|
|
ViewData["Title"] = "BPS-RW Jakarta - Panduan";
|
|
ViewData["FooterBgColor"] = "bg-black";
|
|
ViewData["FooterHoverColor"] = "bg-black-800/20";
|
|
ViewData["FooterShowLeaf"] = "false";
|
|
}
|
|
|
|
<!-- Panduan Section -->
|
|
<section class="w-full px-4 lg:px-28 xl:px-48 py-12 lg:py-18 bg-white">
|
|
<div class="w-full mx-auto gap-10">
|
|
<div class="inline-flex px-4 py-2 bg-primary-50 rounded-full mb-4">
|
|
<div class="flex items-center gap-2">
|
|
<div class="w-2 h-2 bg-primary-500 rounded-full"></div>
|
|
<span class="text-primary-500 text-base font-semibold font-jakarta">BPS RW</span>
|
|
</div>
|
|
</div>
|
|
<h1 class="text-gray-900 text-3xl lg:text-5xl font-bold font-jakarta mb-4">Panduan</h1>
|
|
<p class="text-gray-500 text-lg font-normal font-jakarta leading-relaxed max-w-3xl">
|
|
Di sini anda bisa melihat segala macam panduan yang berguna bagi Anda untuk mengerti cara menggunakan
|
|
aplikasi ini dan mengelola BPS-RW.
|
|
</p>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- Video Panduan Section -->
|
|
<section class="w-full px-4 lg:px-28 xl:px-48 py-16 lg:py-24 bg-gray-100">
|
|
<div class="w-full mx-auto">
|
|
<div class="flex justify-between items-center mb-8">
|
|
<h2 class="text-gray-900 text-2xl lg:text-3xl font-semibold font-jakarta">Video Panduan</h2>
|
|
<div class="flex gap-3">
|
|
<button id="videoPrevBtn"
|
|
class="w-10 h-10 bg-white hover:bg-gray-100 rounded-full flex items-center justify-center transition-colors shadow-sm border border-gray-200">
|
|
<svg class="w-5 h-5 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7">
|
|
</path>
|
|
</svg>
|
|
</button>
|
|
<button id="videoNextBtn"
|
|
class="w-10 h-10 bg-white hover:bg-gray-100 rounded-full flex items-center justify-center transition-colors shadow-sm border border-gray-200">
|
|
<svg class="w-5 h-5 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="relative overflow-hidden">
|
|
<div id="videoCarousel" class="flex flex-nowrap transition-transform duration-500 ease-in-out gap-5">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- E-Book Section -->
|
|
<section class="w-full px-4 lg:px-28 xl:px-48 pb-16 lg:pb-24 bg-gray-100">
|
|
<div class="w-full mx-auto">
|
|
<div class="flex justify-between items-center mb-8">
|
|
<h2 class="text-gray-900 text-2xl lg:text-3xl font-semibold font-jakarta">E-Book</h2>
|
|
<div class="flex gap-3">
|
|
<button id="ebookPrevBtn"
|
|
class="w-10 h-10 bg-white hover:bg-gray-100 rounded-full flex items-center justify-center transition-colors shadow-sm border border-gray-200">
|
|
<svg class="w-5 h-5 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 19l-7-7 7-7">
|
|
</path>
|
|
</svg>
|
|
</button>
|
|
<button id="ebookNextBtn"
|
|
class="w-10 h-10 bg-white hover:bg-gray-100 rounded-full flex items-center justify-center transition-colors shadow-sm border border-gray-200">
|
|
<svg class="w-5 h-5 text-gray-700" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path>
|
|
</svg>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="relative overflow-hidden">
|
|
<div id="ebookCarousel" class="flex flex-nowrap transition-transform duration-500 ease-in-out gap-5">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<!-- FAQ Section -->
|
|
<section class="w-full px-4 lg:px-28 xl:px-48 py-16 lg:py-24 bg-white">
|
|
<div class="w-full mx-auto">
|
|
<div class="mb-8">
|
|
<div class="inline-flex px-4 py-2 bg-primary-50 rounded-full mb-6">
|
|
<div class="flex items-center gap-2">
|
|
<div class="w-2 h-2 bg-primary-500 rounded-full"></div>
|
|
<span class="text-primary-500 text-base font-semibold font-jakarta">BPS RW</span>
|
|
</div>
|
|
</div>
|
|
<h2 class="text-gray-900 text-3xl lg:text-5xl font-bold font-jakarta mb-4">Frequently Asked Question</h2>
|
|
<p class="text-slate-500 text-lg font-normal font-jakarta leading-relaxed max-w-3xl">
|
|
Temukan jawaban atas pertanyaan yang sering diajukan seputar program BPS-RW Jakarta.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="faqAccordion" class="space-y-0 border-t border-gray-200">
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
@{
|
|
ViewData["ContactBgColor"] = "bg-black";
|
|
ViewData["ContactBgCardColor"] = "bg-black";
|
|
ViewData["ContactBorderCardColor"] = "bg-black";
|
|
ViewData["ContactTitleTextColor"] = "text-white";
|
|
ViewData["ContactTitleCardColor"] = "text-white";
|
|
ViewData["ContactIconBgColor"] = "bg-primary-700";
|
|
ViewData["ContactLinkColor"] = "text-primary-500";
|
|
}
|
|
@await Html.PartialAsync("_ContactSection")
|
|
|
|
<script>
|
|
// Data Dummy
|
|
const videos = [
|
|
{
|
|
youtubeId: '_vx9Lzx794o',
|
|
title: 'Video Sosialisasi BPS RW',
|
|
description: 'Tonton video ini untuk memahami cara kerja dan manfaat program BPS-RW.',
|
|
thumbnailUrl: 'https://img.youtube.com/vi/_vx9Lzx794o/sddefault.jpg'
|
|
},
|
|
{
|
|
youtubeId: '_vx9Lzx794o',
|
|
title: 'Webinar Edukasi BPS-RW',
|
|
description: 'Ikuti webinar ini untuk mendapatkan informasi mendalam tentang pelaksanaan program BPS-RW.',
|
|
thumbnailUrl: 'https://img.youtube.com/vi/_vx9Lzx794o/sddefault.jpg'
|
|
},
|
|
{
|
|
youtubeId: '_vx9Lzx794o',
|
|
title: 'Sesi Tanya Jawab BPS-RW',
|
|
description: 'Bergabunglah dalam sesi tanya jawab untuk menjawab segala pertanyaan mengenai BPS-RW.',
|
|
thumbnailUrl: 'https://img.youtube.com/vi/_vx9Lzx794o/sddefault.jpg'
|
|
},
|
|
{
|
|
youtubeId: '_vx9Lzx794o',
|
|
title: 'Sesi Tanya Jawab BPS-RW',
|
|
description: 'Bergabunglah dalam sesi tanya jawab untuk menjawab segala pertanyaan mengenai BPS-RW.',
|
|
thumbnailUrl: 'https://img.youtube.com/vi/_vx9Lzx794o/sddefault.jpg'
|
|
},
|
|
{
|
|
youtubeId: '_vx9Lzx794o',
|
|
title: 'Sosialisasi Program BPS-RW',
|
|
description: 'Tips mensosialisasikan program BPS-RW kepada warga',
|
|
thumbnailUrl: 'https://img.youtube.com/vi/_vx9Lzx794o/sddefault.jpg'
|
|
}
|
|
];
|
|
|
|
const ebooks = [
|
|
{
|
|
title: 'Panduan Praktis BPS-RW',
|
|
description: 'Simak lankah-langkah mudah dan contoh sukses penerapan BPS-RW',
|
|
documentUrl: 'https://drive.google.com/file/d/1Cd5eQFqhqGpgctI6JkE4oiEvE1drFlNc/view?pli=1'
|
|
},
|
|
{
|
|
title: 'Pelatihan Intensif BPS-RW',
|
|
description: 'Pelajari strategi implementasi BPS-RW yang efektif dan berkelanjutan',
|
|
documentUrl: 'https://drive.google.com/file/d/1Cd5eQFqhqGpgctI6JkE4oiEvE1drFlNc/view?pli=1'
|
|
|
|
},
|
|
{
|
|
title: 'Kupas Tuntas BPS-RW',
|
|
description: 'Dapatkan jawaban dari pakar terkait pengelolaan sampah di lingkungan RW',
|
|
documentUrl: 'https://drive.google.com/file/d/1Cd5eQFqhqGpgctI6JkE4oiEvE1drFlNc/view?pli=1'
|
|
|
|
},
|
|
{
|
|
title: 'Forum Diskusi BPS-RW',
|
|
description: 'Diskusi dan bertukar pikiran tentang pengelolaan sampah bersama BPS-RW',
|
|
documentUrl: 'https://drive.google.com/file/d/1Cd5eQFqhqGpgctI6JkE4oiEvE1drFlNc/view?pli=1'
|
|
|
|
},
|
|
{
|
|
title: 'Laporan Tahunan 2024',
|
|
description: 'Laporan pencapaian program BPS-RW Jakarta tahun 2024',
|
|
documentUrl: 'https://drive.google.com/file/d/1Cd5eQFqhqGpgctI6JkE4oiEvE1drFlNc/view?pli=1'
|
|
|
|
}
|
|
];
|
|
|
|
const faqs = [
|
|
{
|
|
question: 'Apa itu BPS-RW dan bagaimana cara kerjanya?',
|
|
answer: 'BPS-RW adalah program pengelolaan sampah berbasis komunitas yang bertujuan untuk meningkatkan kesadaran dan partisipasi masyarakat dalam pengelolaan sampah yang berkelanjutan. Program ini bekerja melalui pengumpulan, pemilahan, dan pengolahan sampah di tingkat RW.'
|
|
},
|
|
|
|
{
|
|
question: 'Bagaimana cara mendaftar sebagai anggota BPS-RW?',
|
|
answer: 'Untuk mendaftar sebagai anggota BPS-RW, Anda dapat menghubungi ketua RW setempat atau mengunjungi kantor kelurahan. Anda akan diminta untuk mengisi formulir pendaftaran dan mengikuti pelatihan singkat tentang pengelolaan sampah.'
|
|
},
|
|
{
|
|
question: 'Apa saja manfaat menjadi anggota BPS-RW?',
|
|
answer: 'Menjadi anggota BPS-RW memberikan banyak manfaat, termasuk kesempatan untuk belajar tentang pengelolaan sampah yang benar, berkontribusi pada lingkungan yang lebih bersih dan sehat, serta mendapatkan insentif berupa pelatihan dan peralatan pengelolaan sampah.'
|
|
},
|
|
{
|
|
question: 'Apakah ada biaya yang terkait dengan keanggotaan BPS-RW?',
|
|
answer: "Tidak, keanggotaan BPS-RW tidak dikenakan biaya. Program ini bertujuan untuk melibatkan sebanyak mungkin masyarakat dalam pengelolaan sampah, sehingga keanggotaan bersifat sukarela dan gratis."
|
|
},
|
|
{
|
|
question: 'Bagaimana cara memperbarui informasi pribadi di BPS-RW?',
|
|
answer: 'Untuk memperbarui informasi pribadi di BPS-RW, Anda dapat menghubungi ketua RW setempat atau mengunjungi kantor kelurahan. Anda akan diminta untuk mengisi formulir perubahan data dan melampirkan dokumen pendukung jika diperlukan.'
|
|
}
|
|
];
|
|
|
|
function toggleFaq(id) {
|
|
const content = document.getElementById(id);
|
|
const icon = document.getElementById(id + '-icon');
|
|
|
|
if (content.classList.contains('hidden')) {
|
|
content.classList.remove('hidden');
|
|
icon.classList.add('rotate-180');
|
|
} else {
|
|
content.classList.add('hidden');
|
|
icon.classList.remove('rotate-180');
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
// Render Videos
|
|
const videoCarousel = document.getElementById('videoCarousel');
|
|
videos.forEach(video => {
|
|
const videoCard = `
|
|
<div class="shrink-0 w-full md:w-[calc(50%-10px)] lg:w-[calc(25%-15px)]">
|
|
<div class="bg-white rounded-2xl overflow-hidden shadow-sm hover:shadow-md transition-shadow">
|
|
<div class="relative w-full aspect-video overflow-hidden bg-gray-300" data-video-id="${video.youtubeId}">
|
|
<img src="${video.thumbnailUrl}"
|
|
alt="${video.title}"
|
|
class="absolute inset-0 w-full h-full object-cover video-thumbnail cursor-pointer"
|
|
loading="lazy">
|
|
<div class="absolute inset-0 flex items-center justify-center video-play-btn cursor-pointer">
|
|
<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
<path d="M20 0C8.96 0 0 8.96 0 20C0 31.04 8.96 40 20 40C31.04 40 40 31.04 40 20C40 8.96 31.04 0 20 0ZM16 29V11L28 20L16 29Z" fill="white"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="pt-5">
|
|
<h3 class="text-gray-900 text-xl font-bold font-jakarta mb-2">${video.title}</h3>
|
|
<p class="text-gary-500 text-sm font-normal font-jakarta line-clamp-2">${video.description}</p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
videoCarousel.innerHTML += videoCard;
|
|
});
|
|
|
|
// E-books
|
|
const ebookCarousel = document.getElementById('ebookCarousel');
|
|
ebooks.forEach(ebook => {
|
|
const ebookCard = `
|
|
<div class="shrink-0 w-full md:w-[calc(50%-10px)] lg:w-[calc(25%-15px)]">
|
|
<div class="group">
|
|
<div class="bg-primary-100 min-h-56 rounded-2xl p-12 mb-4 flex items-center justify-center hover:opacity-80 transition-opacity">
|
|
<i class="ph-fill ph-file-text text-8xl text-primary-500"></i>
|
|
</div>
|
|
<h3 class="text-gray-900 text-xl font-bold font-jakarta mb-2">${ebook.title}</h3>
|
|
<p class="text-gray-500 text-sm font-normal font-jakarta mb-4 line-clamp-2">${ebook.description}</p>
|
|
<a href="${ebook.documentUrl}" target="_blank"
|
|
class="block w-full px-6 py-2.5 bg-white rounded-full text-primary-700 text-base font-semibold transition-colors border border-primary-500 text-center">
|
|
Baca Dokumen
|
|
</a>
|
|
</div>
|
|
</div>
|
|
`;
|
|
ebookCarousel.innerHTML += ebookCard;
|
|
});
|
|
|
|
// FAQs
|
|
const faqAccordion = document.getElementById('faqAccordion');
|
|
faqs.forEach((faq, index) => {
|
|
const faqId = `faq${index + 1}`;
|
|
const faqItem = `
|
|
<div class="border-b border-gray-200">
|
|
<button onclick="toggleFaq('${faqId}')"
|
|
class="w-full py-6 flex justify-between items-center text-left transition-colors">
|
|
<h3 class="text-gray-900 text-lg lg:text-2xl font-medium font-jakarta pr-4">${faq.question}</h3>
|
|
<svg id="${faqId}-icon" class="w-5 h-5 text-gray-900 transform transition-transform shrink-0"
|
|
fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path>
|
|
</svg>
|
|
</button>
|
|
<div id="${faqId}" class="hidden pb-6">
|
|
<p class="text-gray-500 text-base lg:text-lg font-normal font-jakarta leading-relaxed">
|
|
${faq.answer}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
`;
|
|
faqAccordion.innerHTML += faqItem;
|
|
});
|
|
|
|
// Lazy load YouTube videos - dipindahkan setelah video cards di-render
|
|
setTimeout(() => {
|
|
const videoContainers = document.querySelectorAll('[data-video-id]');
|
|
|
|
videoContainers.forEach(container => {
|
|
const videoId = container.dataset.videoId;
|
|
|
|
const loadVideo = () => {
|
|
const iframe = document.createElement('iframe');
|
|
iframe.className = 'absolute inset-0 w-full h-full border-0';
|
|
iframe.src = `https://www.youtube.com/embed/${videoId}?autoplay=1`;
|
|
iframe.title = 'YouTube video player';
|
|
iframe.frameBorder = '0';
|
|
iframe.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share';
|
|
iframe.allowFullscreen = true;
|
|
|
|
// Hide thumbnail and play button
|
|
const thumbnail = container.querySelector('.video-thumbnail');
|
|
const playBtn = container.querySelector('.video-play-btn');
|
|
if (thumbnail) thumbnail.classList.add('hidden');
|
|
if (playBtn) playBtn.classList.add('hidden');
|
|
|
|
container.appendChild(iframe);
|
|
};
|
|
|
|
const thumbnail = container.querySelector('.video-thumbnail');
|
|
const playBtn = container.querySelector('.video-play-btn');
|
|
|
|
if (thumbnail) thumbnail.addEventListener('click', loadVideo);
|
|
if (playBtn) playBtn.addEventListener('click', loadVideo);
|
|
});
|
|
}, 50);
|
|
|
|
// Video Carousel
|
|
const carousel = document.getElementById('videoCarousel');
|
|
const prevBtn = document.getElementById('videoPrevBtn');
|
|
const nextBtn = document.getElementById('videoNextBtn');
|
|
|
|
let currentIndex = 0;
|
|
const totalVideos = videos.length;
|
|
|
|
function getVisibleItems() {
|
|
if (window.innerWidth >= 1024) return 4;
|
|
if (window.innerWidth >= 768) return 2;
|
|
return 1;
|
|
}
|
|
|
|
function updateCarousel() {
|
|
const visibleItems = getVisibleItems();
|
|
const maxIndex = totalVideos - visibleItems;
|
|
|
|
if (currentIndex < 0) currentIndex = 0;
|
|
if (currentIndex > maxIndex) currentIndex = maxIndex;
|
|
|
|
const itemWidth = carousel.children[0]?.offsetWidth || 0;
|
|
const gap = 20;
|
|
const offset = -(currentIndex * (itemWidth + gap));
|
|
|
|
carousel.style.transform = `translateX(${offset}px)`;
|
|
|
|
prevBtn.disabled = currentIndex === 0;
|
|
nextBtn.disabled = currentIndex >= maxIndex;
|
|
|
|
prevBtn.style.opacity = currentIndex === 0 ? '0.5' : '1';
|
|
nextBtn.style.opacity = currentIndex >= maxIndex ? '0.5' : '1';
|
|
}
|
|
|
|
prevBtn.addEventListener('click', function () {
|
|
currentIndex--;
|
|
updateCarousel();
|
|
});
|
|
|
|
nextBtn.addEventListener('click', function () {
|
|
currentIndex++;
|
|
updateCarousel();
|
|
});
|
|
|
|
let resizeTimeout;
|
|
window.addEventListener('resize', function () {
|
|
clearTimeout(resizeTimeout);
|
|
resizeTimeout = setTimeout(function () {
|
|
currentIndex = 0;
|
|
updateCarousel();
|
|
}, 250);
|
|
});
|
|
|
|
setTimeout(updateCarousel, 100);
|
|
|
|
// E-Book Carousel
|
|
const ebookCarouselEl = document.getElementById('ebookCarousel');
|
|
const ebookPrevBtn = document.getElementById('ebookPrevBtn');
|
|
const ebookNextBtn = document.getElementById('ebookNextBtn');
|
|
|
|
let ebookCurrentIndex = 0;
|
|
const totalEbooks = ebooks.length;
|
|
|
|
function updateEbookCarousel() {
|
|
const visibleItems = getVisibleItems();
|
|
const maxIndex = totalEbooks - visibleItems;
|
|
|
|
if (ebookCurrentIndex < 0) ebookCurrentIndex = 0;
|
|
if (ebookCurrentIndex > maxIndex) ebookCurrentIndex = maxIndex;
|
|
|
|
const itemWidth = ebookCarouselEl.children[0]?.offsetWidth || 0;
|
|
const gap = 20;
|
|
const offset = -(ebookCurrentIndex * (itemWidth + gap));
|
|
|
|
ebookCarouselEl.style.transform = `translateX(${offset}px)`;
|
|
|
|
ebookPrevBtn.disabled = ebookCurrentIndex === 0;
|
|
ebookNextBtn.disabled = ebookCurrentIndex >= maxIndex;
|
|
|
|
ebookPrevBtn.style.opacity = ebookCurrentIndex === 0 ? '0.5' : '1';
|
|
ebookNextBtn.style.opacity = ebookCurrentIndex >= maxIndex ? '0.5' : '1';
|
|
}
|
|
|
|
ebookPrevBtn.addEventListener('click', function () {
|
|
ebookCurrentIndex--;
|
|
updateEbookCarousel();
|
|
});
|
|
|
|
ebookNextBtn.addEventListener('click', function () {
|
|
ebookCurrentIndex++;
|
|
updateEbookCarousel();
|
|
});
|
|
|
|
window.addEventListener('resize', function () {
|
|
clearTimeout(resizeTimeout);
|
|
resizeTimeout = setTimeout(function () {
|
|
currentIndex = 0;
|
|
ebookCurrentIndex = 0;
|
|
updateCarousel();
|
|
updateEbookCarousel();
|
|
}, 250);
|
|
});
|
|
|
|
setTimeout(updateEbookCarousel, 100);
|
|
});
|
|
</script> |