forked from izu/student-web-if-development-kit
fix: perbaiki filter prestasi #3
@@ -570,7 +570,7 @@ const translations = {
|
||||
kontrib_guideline_4: "Hindari plagiarisme. Karya harus orisinal.",
|
||||
kontrib_guideline_5: "Tim redaksi berhak menyunting konten untuk keperluan editorial.",
|
||||
|
||||
// Jellyfish.Corp - Prefix: grp_jellyfish_
|
||||
// Jellyfish.Corp
|
||||
grp_jellyfish_hero_title: "Sekilas Informatika",
|
||||
grp_jellyfish_hero_subtitle: "Universitas Tanjungpura",
|
||||
grp_jellyfish_hero_desc: "Mencetak talenta digital unggulan dari Kalimantan Barat untuk Indonesia dan dunia. Bergabunglah bersama kami dalam perjalanan membangun masa depan teknologi.",
|
||||
@@ -633,7 +633,6 @@ const translations = {
|
||||
grp_jellyfish_btn_registration: "Daftar Mahasiswa Baru",
|
||||
grp_jellyfish_btn_whatsapp: "💬 Chat WhatsApp",
|
||||
|
||||
// Timeline Keys
|
||||
grp_jellyfish_timeline_2004_title: "Pendirian Program Studi",
|
||||
grp_jellyfish_timeline_2004_desc: "Penerimaan mahasiswa angkatan pertama diselenggarakan pada tanggal 18 Mei melalui mekanisme seleksi internal dan perpindahan studi dari Program Studi Teknik Elektro.",
|
||||
grp_jellyfish_timeline_2005_title: "SNMPTN Pertama",
|
||||
@@ -655,27 +654,17 @@ const translations = {
|
||||
grp_jellyfish_timeline_2025_title: "Kaprodi Ke-5",
|
||||
grp_jellyfish_timeline_2025_desc: "Pelantikan Ibu Eva Faja Ripanti, S.Kom., M.M.S.I., Ph.D. sebagai Ketua Program Studi Informatika yang kelima.",
|
||||
|
||||
// Achievement Cards - Badges & Labels
|
||||
badge_competition: "Kompetisi",
|
||||
badge_international: "Kompetisi",
|
||||
badge_publication: "Publikasi",
|
||||
badge_community: "Pengabdian Masyarakat",
|
||||
badge_innovation: "Inovasi Aplikasi",
|
||||
label_year_2025: "📅 2025",
|
||||
label_year_2024: "📅 2024",
|
||||
label_year_2023: "📅 2023",
|
||||
label_year_2008: "📅 2008",
|
||||
label_year_2021: "📅 2021",
|
||||
label_finalist: "Finalis",
|
||||
label_team_best: "Tim Regional Terbaik",
|
||||
label_honor: "Honor",
|
||||
label_participant: "PESERTA",
|
||||
label_icpc_region: "🌏 Asia Jakarta Regional Contest 2025",
|
||||
label_gemastik17: "GEMASTIK XVII",
|
||||
label_still_active: "💡 Masih aktif",
|
||||
label_faculty_scale: "🚀 Skala Fakultas",
|
||||
|
||||
// Achievement Titles & Descriptions
|
||||
grp_jellyfish_prest_compfest_title: "Finalis 10 Besar Competitive Programming Contest (COMPFEST) 17",
|
||||
grp_jellyfish_prest_compfest_desc: "Berhasil meraih posisi 10 besar nasional pada COMPFEST 17, kompetisi pemrograman yang diselenggarakan oleh Universitas Indonesia (UI).",
|
||||
grp_jellyfish_prest_gemastik18_title: "Tim Regional Terbaik GEMASTIK XVIII bidang Competitive Programming",
|
||||
@@ -751,7 +740,6 @@ const translations = {
|
||||
grp_jellyfish_infra_eresources_stat: "IEEE · Scopus · ACM",
|
||||
grp_jellyfish_license_label: "Lisensi Perangkat Lunak Tersedia:",
|
||||
|
||||
// Infrastructure - Labs & Facilities
|
||||
grp_jellyfish_labs: "Lab Pemrograman, Jaringan, Multimedia, IoT, AI, Basis Data, Mobile Dev, dan Keamanan Siber — ber-AC, High-Speed PC.",
|
||||
grp_jellyfish_labs2: "8 Lab Aktif & Berteknologi",
|
||||
grp_jellyfish_data_center: "Server on-premise dengan infrastruktur cloud lokal berkapasitas tinggi untuk penelitian dan deployment aplikasi.",
|
||||
@@ -759,13 +747,11 @@ const translations = {
|
||||
grp_jellyfish_free: "Gratis · GPU Access",
|
||||
grp_jellyfish_resources: "Akses jurnal internasional Scopus, IEEE Xplore, ACM Digital Library, Springer, dan database ilmiah lainnya.",
|
||||
grp_jellyfish_license: "Lisensi Perangkat Lunak Tersedia:",
|
||||
|
||||
// Partnership Categories
|
||||
|
||||
grp_jellyfish_industri: "Industri & Swasta",
|
||||
grp_jellyfish_pemerintah: "Instansi Pemerintah",
|
||||
grp_jellyfish_perguruan_tinggi: "Perguruan Tinggi & Lembaga Riset",
|
||||
|
||||
// Contact Information
|
||||
|
||||
grp_jellyfish_info_kontak: "Informasi Kontak",
|
||||
grp_jellyfish_alamat: "Alamat",
|
||||
grp_jellyfish_tanggal: "Senin – Jumat, 08.00 – 16.00 WIB",
|
||||
@@ -1337,7 +1323,7 @@ const translations = {
|
||||
kontrib_guideline_4: "Avoid plagiarism. Work must be original.",
|
||||
kontrib_guideline_5: "The editorial team reserves the right to edit content for editorial purposes.",
|
||||
|
||||
// Jellyfish.Corp - English (grp_jellyfish_)
|
||||
// Jellyfish.Corp
|
||||
grp_jellyfish_hero_title: "Informatika Overview",
|
||||
grp_jellyfish_hero_subtitle: "Tanjungpura University",
|
||||
grp_jellyfish_hero_desc: "Producing outstanding digital talents from West Kalimantan for Indonesia and the world. Join us on the journey to build the future of technology.",
|
||||
@@ -1400,7 +1386,6 @@ const translations = {
|
||||
grp_jellyfish_btn_registration: "Register as New Student",
|
||||
grp_jellyfish_btn_whatsapp: "💬 Chat on WhatsApp",
|
||||
|
||||
// Timeline Keys (English)
|
||||
grp_jellyfish_timeline_2004_title: "Program Establishment",
|
||||
grp_jellyfish_timeline_2004_desc: "The first batch of students was admitted on May 18 through internal selection and transfer from the Electrical Engineering Study Program.",
|
||||
grp_jellyfish_timeline_2005_title: "First SNMPTN",
|
||||
@@ -1421,28 +1406,18 @@ const translations = {
|
||||
grp_jellyfish_timeline_2023_desc: "Inauguration of the first Professor of Informatika Study Program UNTAN, namely Prof. Dr. Herry Sujaini, S.T., M.T.",
|
||||
grp_jellyfish_timeline_2025_title: "5th Head of Study Program",
|
||||
grp_jellyfish_timeline_2025_desc: "Inauguration of Eva Faja Ripanti, S.Kom., M.M.S.I., Ph.D. as the fifth Head of Informatika Study Program.",
|
||||
|
||||
// Achievement Badges & Labels (English)
|
||||
|
||||
badge_competition: "Competition",
|
||||
badge_international: "Competition",
|
||||
badge_publication: "Publication",
|
||||
badge_community: "Community Service",
|
||||
badge_innovation: "Application Innovation",
|
||||
label_year_2025: "📅 2025",
|
||||
label_year_2024: "📅 2024",
|
||||
label_year_2023: "📅 2023",
|
||||
label_year_2008: "📅 2008",
|
||||
label_year_2021: "📅 2021",
|
||||
label_finalist: "Finalist",
|
||||
label_team_best: "Best Regional Team",
|
||||
label_honor: "Honor",
|
||||
label_participant: "PARTICIPANT",
|
||||
label_icpc_region: "🌏 Asia Jakarta Regional Contest 2025",
|
||||
label_gemastik17: "GEMASTIK XVII",
|
||||
label_still_active: "💡 Still Active",
|
||||
label_faculty_scale: "🚀 Faculty-wide Scale",
|
||||
|
||||
// Achievement Titles & Descriptions (English)
|
||||
grp_jellyfish_prest_compfest_title: "Top 10 Finalist Competitive Programming Contest (COMPFEST) 17",
|
||||
grp_jellyfish_prest_compfest_desc: "Successfully achieved top 10 national position at COMPFEST 17, a programming competition organized by Universitas Indonesia (UI).",
|
||||
grp_jellyfish_prest_gemastik18_title: "Best Regional Team GEMASTIK XVIII Competitive Programming Category",
|
||||
@@ -1518,7 +1493,6 @@ const translations = {
|
||||
grp_jellyfish_infra_eresources_stat: "IEEE · Scopus · ACM",
|
||||
grp_jellyfish_license_label: "Available Software Licenses:",
|
||||
|
||||
// Infrastructure - Labs & Facilities
|
||||
grp_jellyfish_labs: "Programming, Networking, Multimedia, IoT, AI, Database, Mobile Dev, and Cybersecurity labs — air-conditioned, high-speed PCs.",
|
||||
grp_jellyfish_labs2: "8 Active & High-Tech Labs",
|
||||
grp_jellyfish_data_center: "On-premise servers with high-capacity local cloud infrastructure for research and application deployment.",
|
||||
@@ -1526,13 +1500,11 @@ const translations = {
|
||||
grp_jellyfish_free: "Free · GPU Access",
|
||||
grp_jellyfish_resources: "Access to international journals like Scopus, IEEE Xplore, ACM Digital Library, Springer, and other research databases.",
|
||||
grp_jellyfish_license: "Available Software Licenses:",
|
||||
|
||||
// Partnership Categories
|
||||
|
||||
grp_jellyfish_industri: "Industry & Private Sector",
|
||||
grp_jellyfish_pemerintah: "Government Agencies",
|
||||
grp_jellyfish_perguruan_tinggi: "Higher Education & Research Institutes",
|
||||
|
||||
// Contact Information
|
||||
|
||||
grp_jellyfish_info_kontak: "Contact Information",
|
||||
grp_jellyfish_alamat: "Address",
|
||||
grp_jellyfish_tanggal: "Monday – Friday, 08.00 – 16.00 WIB",
|
||||
|
||||
@@ -1417,61 +1417,61 @@
|
||||
<span class="jf-prest-badge jf-prest-nasional" data-i18n="badge_competition">Kompetisi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_gemastik18_title">Tim Regional Terbaik GEMASTIK XVIII bidang Competitive Programming</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_gemastik18_desc">Berhasil menjadi Tim Regional Terbaik pada GEMASTIK XVIII pada bidang Competitive Programming</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2025">📅 2025</span><span data-i18n="label_team_best">Tim Regional Terbaik</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2025</span><span data-i18n="label_team_best">Tim Regional Terbaik</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="kompetisi">
|
||||
<span class="jf-prest-badge jf-prest-internasional" data-i18n="badge_international">Kompetisi</span>
|
||||
<span class="jf-prest-badge jf-prest-nasional" data-i18n="badge_competition">Kompetisi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_icpc_title">International Collegiate Programming Contest predikat Honor</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_icpc_desc">Tim competitive programming Informatika UNTAN berhasil lolos ke babak regional ICPC Asia Jakarta 2025.</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_icpc_region">🌏 Asia Jakarta Regional Contest 2025</span><span data-i18n="label_honor">Honor</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2025</span><span data-i18n="label_honor">Honor</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="kompetisi">
|
||||
<span class="jf-prest-badge jf-prest-nasional" data-i18n="label_gemastik17">GEMASTIK XVII</span>
|
||||
<span class="jf-prest-badge jf-prest-nasional" data-i18n="badge_competition">Kompetisi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_gemastik17_title">Tim Regional Terbaik GEMASTIK XVII bidang Competitive Programming</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_gemastik17_desc">Berhasil menjadi Tim Regional Terbaik pada GEMASTIK XVII pada bidang Competitive Programming</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2024">📅 2024</span><span data-i18n="label_team_best">Tim Regional Terbaik</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2024</span><span data-i18n="label_team_best">Tim Regional Terbaik</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="kompetisi">
|
||||
<span class="jf-prest-badge jf-prest-nasional" data-i18n="badge_competition">Kompetisi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_mtq_title">LOMBA MTQ TINGKAT PROVINSI KALIMANTAN BARAT PESERTA CABANG TAHFIDZ HADITS GOLONGAN 100 HADIST DENGAN SANAD PUTRI</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_mtq_desc">Berpastisipasi pada MTQ tingkat provinsi Kalimantan Barat cabang Tahfidz Hadits 100 Hadits Bersanad Putri</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2024">📅 2024</span><span data-i18n="label_participant">PESERTA</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2024</span><span data-i18n="label_participant">PESERTA</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="publikasi">
|
||||
<span class="jf-prest-badge jf-prest-publikasi" data-i18n="badge_publication">Publikasi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_crm_title">Customer Relationship Management (CRM) System pada Peningkatan Layanan Pengguna E-Learning</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_crm_desc">Penulis: EF Ripanti, EE Pratama, F Asrin. Penelitian ini mengkaji penerapan sistem CRM untuk meningkatkan kualitas layanan dan kepuasan pengguna pada platform e-learning.</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2025">📅 2025</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2025</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="publikasi">
|
||||
<span class="jf-prest-badge jf-prest-publikasi" data-i18n="badge_publication">Publikasi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_dbscan_title">REKOMENDASI AREA PEMASARAN BAGI PEDAGANG SAYUR KELILING MENGGUNAKAN METODE DBSCAN DAN VISUALISASI HEATMAP</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_dbscan_desc">Penulis: DA Nugraha, IY Sholva, EE Pratama. Penelitian ini memanfaatkan metode DBSCAN dan visualisasi heatmap untuk merekomendasikan area pemasaran yang potensial bagi pedagang sayur keliling.</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2024">📅 2024</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2024</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="publikasi">
|
||||
<span class="jf-prest-badge jf-prest-publikasi" data-i18n="badge_publication">Publikasi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_kmeans_title">Data mining untuk pengelompokan saham pada sektor energi dengan metode k-means</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_kmeans_desc">Penulis: AS Sukamto, W Setiawan, EE Pratama. Penelitian ini menerapkan algoritma K-Means untuk mengelompokkan saham sektor energi berdasarkan karakteristik data yang serupa guna mendukung analisis investasi.</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2023">📅 2023</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2023</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="publikasi">
|
||||
<span class="jf-prest-badge jf-prest-penghargaan" data-i18n="badge_community">Pengabdian Masyarakat</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_kodingmu_title">KODINGMU PLATFORM BELAJAR COMPUTATIONAL THINKING BAGI SISWA SMAN 1 MEMPAWAH HILIR</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_kodingmu_desc">Kegiatan pengabdian yang bertujuan meningkatkan kemampuan berpikir komputasional dan pemecahan masalah siswa melalui pelatihan serta pemanfaatan platform pembelajaran Kodingmu berbasis aktivitas pemrograman yang interaktif dan menyenangkan.</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2025">📅 2025</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2025</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="aplikasi">
|
||||
<span class="jf-prest-badge" style="background:#e0f2fe;color:#0369a1;" data-i18n="badge_innovation">Inovasi Aplikasi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_spota_title">SPOTA (2008)</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_spota_desc">Sistem Pendukung Outline Tugas Akhir — lahir dari ide dosen, dibangun mahasiswa, masih digunakan hingga kini. Inovasi yang melampaui zamannya.</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2008">📅 2008</span><span data-i18n="label_still_active">💡 Masih aktif</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2008</span><span data-i18n="label_still_active">💡 Masih aktif</span></div>
|
||||
</div>
|
||||
<div class="jf-prestasi-card" data-cat="aplikasi">
|
||||
<span class="jf-prest-badge" style="background:#e0f2fe;color:#0369a1;" data-i18n="badge_innovation">Inovasi Aplikasi</span>
|
||||
<h4 data-i18n="grp_jellyfish_prest_edoxid_title">EdoXid (2021)</h4>
|
||||
<p data-i18n="grp_jellyfish_prest_edoxid_desc">Sistem pengajuan sidang digital — hadir menjawab pandemi, kini naik kelas ke skala Fakultas MIPA Universitas Tanjungpura.</p>
|
||||
<div class="jf-prest-meta"><span data-i18n="label_year_2021">📅 2021</span><span data-i18n="label_faculty_scale">🚀 Skala Fakultas</span></div>
|
||||
<div class="jf-prest-meta"><span>📅 2021</span><span data-i18n="label_faculty_scale">🚀 Skala Fakultas</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2045,7 +2045,7 @@
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script src="script.js"></script>
|
||||
<script src="../../assets/global/localization.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
+60
-332
@@ -1,290 +1,40 @@
|
||||
// ===== LANGUAGE TOGGLE =====
|
||||
let currentLang = 'id';
|
||||
// ===== SCROLL REVEAL — jf-* cards di dalam #assignment-body =====
|
||||
function initScrollReveal() {
|
||||
const body = document.getElementById('assignment-body');
|
||||
if (!body) return;
|
||||
|
||||
function setLangLabel(lang) {
|
||||
const nextLang = lang === 'id' ? 'EN' : 'ID';
|
||||
const labelDesktop = document.getElementById('lang-label');
|
||||
const labelMobile = document.getElementById('lang-label-mobile');
|
||||
if (labelDesktop) labelDesktop.textContent = nextLang;
|
||||
if (labelMobile) labelMobile.textContent = nextLang;
|
||||
}
|
||||
const targets = body.querySelectorAll(
|
||||
'.jf-stat-card, .jf-stat-row-card, .jf-prestasi-card, ' +
|
||||
'.jf-sc-card, .jf-karir-card, .jf-alumni-card, ' +
|
||||
'.jf-infra-card, .jf-mitra-card, .jf-tl-item, .jf-kontak-item'
|
||||
);
|
||||
targets.forEach(el => {
|
||||
el.style.opacity = '0';
|
||||
el.style.transform = 'translateY(24px)';
|
||||
el.style.transition = 'opacity 0.55s ease, transform 0.55s ease';
|
||||
});
|
||||
|
||||
function applyLang(lang) {
|
||||
const pageBody = document.getElementById('page-body');
|
||||
pageBody.classList.toggle('lang-id', lang === 'id');
|
||||
pageBody.classList.toggle('lang-en', lang === 'en');
|
||||
document.documentElement.lang = lang;
|
||||
}
|
||||
const obs = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry, i) => {
|
||||
if (!entry.isIntersecting) return;
|
||||
setTimeout(() => {
|
||||
entry.target.style.opacity = '1';
|
||||
entry.target.style.transform = 'translateY(0)';
|
||||
}, i * 70);
|
||||
obs.unobserve(entry.target);
|
||||
});
|
||||
}, { threshold: 0.08 });
|
||||
|
||||
function toggleLang() {
|
||||
currentLang = currentLang === 'id' ? 'en' : 'id';
|
||||
applyLang(currentLang);
|
||||
setLangLabel(currentLang);
|
||||
}
|
||||
targets.forEach(el => obs.observe(el));
|
||||
}
|
||||
|
||||
document.getElementById('lang-toggle')?.addEventListener('click', toggleLang);
|
||||
document.getElementById('lang-toggle-mobile')?.addEventListener('click', toggleLang);
|
||||
// ===== PRESTASI FILTER — tab filter di dalam #assignment-body =====
|
||||
function initPrestasiFilter() {
|
||||
const body = document.getElementById('assignment-body');
|
||||
if (!body) return;
|
||||
|
||||
// ===== SCROLL REVEAL =====
|
||||
function initScrollReveal() {
|
||||
const revealEls = document.querySelectorAll('.reveal');
|
||||
const observer = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (entry.isIntersecting) {
|
||||
entry.target.classList.add('visible');
|
||||
observer.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.1 });
|
||||
revealEls.forEach(el => observer.observe(el));
|
||||
}
|
||||
initScrollReveal();
|
||||
|
||||
// ===== BACK TO TOP =====
|
||||
function initBackToTop() {
|
||||
const btn = document.getElementById('back-to-top');
|
||||
if (!btn) return;
|
||||
|
||||
btn.addEventListener('click', () => window.scrollTo({ top: 0, behavior: 'smooth' }));
|
||||
|
||||
window.addEventListener('scroll', () => {
|
||||
const isPastThreshold = window.scrollY > 400;
|
||||
btn.classList.toggle('hidden', !isPastThreshold);
|
||||
btn.classList.toggle('flex', isPastThreshold);
|
||||
});
|
||||
}
|
||||
initBackToTop();
|
||||
|
||||
// ===== PRESTASI FILTER =====
|
||||
function setActiveTabStyle(btn, isActive) {
|
||||
btn.classList.toggle('bg-untan-navy', isActive);
|
||||
btn.classList.toggle('text-white', isActive);
|
||||
btn.classList.toggle('bg-white', !isActive);
|
||||
btn.classList.toggle('text-slate-700', !isActive);
|
||||
btn.classList.toggle('border', !isActive);
|
||||
btn.classList.toggle('border-slate-200',!isActive);
|
||||
}
|
||||
|
||||
function filterPrestasi(category) {
|
||||
document.querySelectorAll('.prestasi-tab-btn').forEach(btn => {
|
||||
setActiveTabStyle(btn, btn.dataset.tab === category);
|
||||
});
|
||||
document.querySelectorAll('#prestasi-grid .prestasi-card').forEach(card => {
|
||||
card.style.display = (category === 'all' || card.dataset.category === category) ? '' : 'none';
|
||||
});
|
||||
}
|
||||
|
||||
function initPrestasiFilter() {
|
||||
document.querySelectorAll('.prestasi-tab-btn').forEach(btn => {
|
||||
btn.addEventListener('click', () => filterPrestasi(btn.dataset.tab));
|
||||
});
|
||||
}
|
||||
initPrestasiFilter();
|
||||
|
||||
// ===== MEGA MENU =====
|
||||
(function initMegaMenu() {
|
||||
const menuItems = document.querySelectorAll('[data-menu]');
|
||||
if (!menuItems.length) return;
|
||||
|
||||
let activeMenuId = null;
|
||||
|
||||
function closeAllMenus() {
|
||||
document.querySelectorAll('.mega-panel').forEach(p => p.classList.remove('active'));
|
||||
updateButtonStates(null);
|
||||
activeMenuId = null;
|
||||
}
|
||||
|
||||
function updateButtonStates(openMenuId) {
|
||||
menuItems.forEach(item => {
|
||||
const isActive = item.getAttribute('data-menu') === openMenuId;
|
||||
const btn = item.querySelector('.nav-menu-btn');
|
||||
const chevron = item.querySelector('.fa-chevron-down');
|
||||
if (btn) {
|
||||
btn.classList.toggle('active', isActive);
|
||||
btn.setAttribute('aria-expanded', isActive ? 'true' : 'false');
|
||||
}
|
||||
if (chevron) chevron.style.transform = isActive ? 'rotate(180deg)' : '';
|
||||
});
|
||||
}
|
||||
|
||||
menuItems.forEach(item => {
|
||||
const menuId = item.getAttribute('data-menu');
|
||||
const btn = item.querySelector('.nav-menu-btn');
|
||||
if (!btn) return;
|
||||
|
||||
btn.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (activeMenuId === menuId) {
|
||||
closeAllMenus();
|
||||
} else {
|
||||
closeAllMenus();
|
||||
updateButtonStates(menuId);
|
||||
activeMenuId = menuId;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener('keydown', e => { if (e.key === 'Escape') closeAllMenus(); });
|
||||
document.addEventListener('click', e => { if (!e.target.closest('#main-nav') && activeMenuId) closeAllMenus(); });
|
||||
})();
|
||||
|
||||
// ===== MOBILE MENU =====
|
||||
function initMobileMenu() {
|
||||
const menuBtn = document.getElementById('mobile-menu-btn');
|
||||
const menu = document.getElementById('mobile-menu');
|
||||
const closeBtn = document.getElementById('close-mobile-menu');
|
||||
|
||||
if (menuBtn && menu) {
|
||||
menuBtn.addEventListener('click', () => {
|
||||
const isOpen = menu.classList.toggle('-translate-x-full') === false;
|
||||
menuBtn.setAttribute('aria-expanded', String(isOpen));
|
||||
});
|
||||
}
|
||||
if (closeBtn && menu) {
|
||||
closeBtn.addEventListener('click', () => menu.classList.add('-translate-x-full'));
|
||||
}
|
||||
}
|
||||
initMobileMenu();
|
||||
|
||||
// ===== LUCO CHATBOT BUBBLE =====
|
||||
function initLucoBubble() {
|
||||
const bubble = document.getElementById('luco-bubble');
|
||||
const closeBtn = document.getElementById('luco-bubble-close');
|
||||
|
||||
if (!bubble) return;
|
||||
|
||||
setTimeout(() => bubble.classList.remove('hidden'), 3000);
|
||||
|
||||
closeBtn?.addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
bubble.classList.add('hidden');
|
||||
});
|
||||
}
|
||||
initLucoBubble();
|
||||
|
||||
// ===== #ASSIGNMENT-BODY ENHANCEMENTS =====
|
||||
(function initAssignmentBody() {
|
||||
const body = document.getElementById('assignment-body');
|
||||
if (!body) return;
|
||||
|
||||
// --- 1. Scroll-reveal untuk setiap child langsung ---
|
||||
const revealTargets = body.querySelectorAll('h3, h4, p, ul, table, figure');
|
||||
const revealObserver = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry, i) => {
|
||||
if (entry.isIntersecting) {
|
||||
setTimeout(() => entry.target.classList.add('visible'), i * 60);
|
||||
revealObserver.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.08 });
|
||||
|
||||
revealTargets.forEach(el => {
|
||||
el.classList.add('ab-reveal');
|
||||
revealObserver.observe(el);
|
||||
});
|
||||
|
||||
// --- 2. Collapsible: Alumni & Mitra (sections yang panjang) ---
|
||||
// Wrap konten setelah h3 "Kisah Sukses Alumni" dalam collapsible
|
||||
const allH3 = [...body.querySelectorAll('h3')];
|
||||
const collapsibleTitles = ['Kisah Sukses Alumni', 'Mitra Strategis', 'Fasilitas Akademik'];
|
||||
|
||||
allH3.forEach(h3 => {
|
||||
if (!collapsibleTitles.includes(h3.textContent.trim())) return;
|
||||
|
||||
// Kumpulkan sibling sampai h3 berikutnya
|
||||
const siblings = [];
|
||||
let next = h3.nextElementSibling;
|
||||
while (next && next.tagName !== 'H3') {
|
||||
siblings.push(next);
|
||||
next = next.nextElementSibling;
|
||||
}
|
||||
if (!siblings.length) return;
|
||||
|
||||
// Buat wrapper collapsible
|
||||
const wrapper = document.createElement('div');
|
||||
wrapper.className = 'ab-collapsible';
|
||||
h3.parentNode.insertBefore(wrapper, siblings[0]);
|
||||
siblings.forEach(s => wrapper.appendChild(s));
|
||||
|
||||
// Buat tombol toggle
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'ab-readmore-btn';
|
||||
btn.innerHTML = 'Lihat Detail <span class="arrow">▼</span>';
|
||||
btn.setAttribute('aria-expanded', 'false');
|
||||
h3.insertAdjacentElement('afterend', btn);
|
||||
|
||||
btn.addEventListener('click', () => {
|
||||
const isOpen = wrapper.classList.toggle('open');
|
||||
btn.classList.toggle('open', isOpen);
|
||||
btn.innerHTML = isOpen
|
||||
? 'Sembunyikan <span class="arrow">▼</span>'
|
||||
: 'Lihat Detail <span class="arrow">▼</span>';
|
||||
btn.setAttribute('aria-expanded', String(isOpen));
|
||||
});
|
||||
});
|
||||
|
||||
// --- 3. Table row highlight on click ---
|
||||
body.querySelectorAll('tbody tr').forEach(row => {
|
||||
row.style.cursor = 'pointer';
|
||||
row.addEventListener('click', () => {
|
||||
body.querySelectorAll('tbody tr.selected').forEach(r => r.classList.remove('selected'));
|
||||
row.classList.add('selected');
|
||||
row.style.background = '#dbeafe';
|
||||
row.style.fontWeight = '600';
|
||||
setTimeout(() => {
|
||||
row.style.background = '';
|
||||
row.style.fontWeight = '';
|
||||
row.classList.remove('selected');
|
||||
}, 1800);
|
||||
});
|
||||
});
|
||||
|
||||
// --- 4. Callout block: inject setelah paragraf karir ---
|
||||
const pEls = [...body.querySelectorAll('p')];
|
||||
const kariPara = pEls.find(p => p.textContent.includes('Rp 5–12 Juta'));
|
||||
if (kariPara) {
|
||||
const callout = document.createElement('div');
|
||||
callout.className = 'ab-callout ab-reveal';
|
||||
callout.textContent = '87% lulusan bekerja di bidang IT sesuai kompetensi, dengan rata-rata waktu tunggu kerja kurang dari 3 bulan.';
|
||||
kariPara.insertAdjacentElement('afterend', callout);
|
||||
revealObserver.observe(callout);
|
||||
}
|
||||
|
||||
// --- 5. Tambahkan section label di atas setiap h3 ---
|
||||
const sectionMap = {
|
||||
'Mengenal Program Studi': 'Tentang Prodi',
|
||||
'Visi': 'Identitas',
|
||||
'Misi': 'Identitas',
|
||||
'Tonggak Sejarah': 'Sejarah',
|
||||
'dalam Angka': 'Data & Statistik',
|
||||
'Pencapaian': 'Prestasi',
|
||||
'Study Club': 'Komunitas',
|
||||
'Prospek Karir': 'Karir',
|
||||
'Kisah Sukses': 'Alumni',
|
||||
'Fasilitas': 'Infrastruktur',
|
||||
'Mitra Strategis': 'Kerjasama',
|
||||
'Informasi Kontak': 'Kontak',
|
||||
};
|
||||
allH3.forEach(h3 => {
|
||||
const key = Object.keys(sectionMap).find(k => h3.textContent.includes(k));
|
||||
if (!key) return;
|
||||
const label = document.createElement('div');
|
||||
label.className = 'ab-section-label';
|
||||
label.textContent = sectionMap[key];
|
||||
h3.insertAdjacentElement('beforebegin', label);
|
||||
});
|
||||
|
||||
})();
|
||||
|
||||
// =====================================================
|
||||
// JELLYFISH.CORP — MOCKUP SCRIPTS
|
||||
// =====================================================
|
||||
|
||||
// ===== PRESTASI FILTER (new jf-* classes) =====
|
||||
(function initPrestasiFilterJF() {
|
||||
const tabs = document.querySelectorAll('.jf-tab-btn');
|
||||
const cards = document.querySelectorAll('#prestasi-grid .jf-prestasi-card');
|
||||
const tabs = body.querySelectorAll('.jf-tab-btn');
|
||||
const cards = body.querySelectorAll('#prestasi-grid .jf-prestasi-card');
|
||||
if (!tabs.length) return;
|
||||
|
||||
tabs.forEach(tab => {
|
||||
@@ -295,70 +45,48 @@
|
||||
cards.forEach(card => {
|
||||
const show = filter === 'all' || card.dataset.cat === filter;
|
||||
card.style.display = show ? '' : 'none';
|
||||
if (show) {
|
||||
card.style.animation = 'jfFadeIn 0.35s ease forwards';
|
||||
}
|
||||
if (show) card.style.animation = 'jfFadeIn 0.35s ease forwards';
|
||||
});
|
||||
});
|
||||
});
|
||||
})();
|
||||
}
|
||||
|
||||
// ===== SCROLL REVEAL for jf-* cards =====
|
||||
(function initJFScrollReveal() {
|
||||
const targets = document.querySelectorAll(
|
||||
'.jf-stat-card, .jf-stat-row-card, .jf-prestasi-card, ' +
|
||||
'.jf-sc-card, .jf-karir-card, .jf-alumni-card, ' +
|
||||
'.jf-infra-card, .jf-mitra-card, .jf-life-card, ' +
|
||||
'.jf-tl-item, .jf-visi-card, .jf-kontak-item'
|
||||
);
|
||||
targets.forEach(el => {
|
||||
el.style.opacity = '0';
|
||||
el.style.transform = 'translateY(24px)';
|
||||
el.style.transition = 'opacity 0.55s ease, transform 0.55s ease';
|
||||
});
|
||||
// ===== ANIMATED COUNTER — .jf-stat-num di dalam #assignment-body =====
|
||||
function initCounters() {
|
||||
const body = document.getElementById('assignment-body');
|
||||
if (!body) return;
|
||||
|
||||
const obs = new IntersectionObserver((entries) => {
|
||||
entries.forEach((entry, i) => {
|
||||
if (entry.isIntersecting) {
|
||||
setTimeout(() => {
|
||||
entry.target.style.opacity = '1';
|
||||
entry.target.style.transform = 'translateY(0)';
|
||||
}, i * 70);
|
||||
obs.unobserve(entry.target);
|
||||
}
|
||||
});
|
||||
}, { threshold: 0.08 });
|
||||
|
||||
targets.forEach(el => obs.observe(el));
|
||||
})();
|
||||
|
||||
// ===== ANIMATED COUNTER for jf-stat-num =====
|
||||
(function initJFCounters() {
|
||||
const nums = document.querySelectorAll('.jf-stat-num');
|
||||
const obs = new IntersectionObserver((entries) => {
|
||||
entries.forEach(entry => {
|
||||
if (!entry.isIntersecting) return;
|
||||
const el = entry.target;
|
||||
const raw = el.textContent.trim();
|
||||
const num = parseFloat(raw.replace(/[^0-9.]/g, ''));
|
||||
const el = entry.target;
|
||||
const raw = el.textContent.trim();
|
||||
const num = parseFloat(raw.replace(/[^0-9.]/g, ''));
|
||||
if (isNaN(num) || num === 0) return;
|
||||
const suffix = raw.replace(/[0-9.,]/g, '');
|
||||
const prefix = raw.startsWith('<') ? '<' : '';
|
||||
const cleanSuffix = prefix ? suffix : suffix;
|
||||
|
||||
const prefix = raw.match(/^[^0-9]*/)[0];
|
||||
const suffix = raw.match(/[^0-9.]*$/)[0];
|
||||
|
||||
let start = 0;
|
||||
const duration = 1400;
|
||||
const step = 16;
|
||||
const increment = num / (duration / step);
|
||||
const increment = num / (1400 / step);
|
||||
const timer = setInterval(() => {
|
||||
start += increment;
|
||||
if (start >= num) { start = num; clearInterval(timer); }
|
||||
const display = num % 1 === 0
|
||||
start = Math.min(start + increment, num);
|
||||
const display = Number.isInteger(num)
|
||||
? Math.floor(start).toLocaleString('id-ID')
|
||||
: start.toFixed(0);
|
||||
el.textContent = prefix + display + cleanSuffix;
|
||||
: start.toFixed(1);
|
||||
el.textContent = prefix + display + suffix;
|
||||
if (start >= num) clearInterval(timer);
|
||||
}, step);
|
||||
|
||||
obs.unobserve(el);
|
||||
});
|
||||
}, { threshold: 0.5 });
|
||||
nums.forEach(el => obs.observe(el));
|
||||
})();
|
||||
|
||||
body.querySelectorAll('.jf-stat-num').forEach(el => obs.observe(el));
|
||||
}
|
||||
|
||||
// ===== INIT =====
|
||||
initScrollReveal();
|
||||
initPrestasiFilter();
|
||||
initCounters();
|
||||
Generated
-1
@@ -917,7 +917,6 @@
|
||||
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user