diff --git a/assets/global/localization.js b/assets/global/localization.js index 4bf8143..4c54c2b 100644 --- a/assets/global/localization.js +++ b/assets/global/localization.js @@ -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", diff --git a/groups/Jellyfish.Corp/index.html b/groups/Jellyfish.Corp/index.html index eef8324..25f3cda 100644 --- a/groups/Jellyfish.Corp/index.html +++ b/groups/Jellyfish.Corp/index.html @@ -1417,61 +1417,61 @@ Kompetisi

Tim Regional Terbaik GEMASTIK XVIII bidang Competitive Programming

Berhasil menjadi Tim Regional Terbaik pada GEMASTIK XVIII pada bidang Competitive Programming

-
๐Ÿ“… 2025Tim Regional Terbaik
+
๐Ÿ“… 2025Tim Regional Terbaik
- Kompetisi + Kompetisi

International Collegiate Programming Contest predikat Honor

Tim competitive programming Informatika UNTAN berhasil lolos ke babak regional ICPC Asia Jakarta 2025.

-
๐ŸŒ Asia Jakarta Regional Contest 2025Honor
+
๐Ÿ“… 2025Honor
- GEMASTIK XVII + Kompetisi

Tim Regional Terbaik GEMASTIK XVII bidang Competitive Programming

Berhasil menjadi Tim Regional Terbaik pada GEMASTIK XVII pada bidang Competitive Programming

-
๐Ÿ“… 2024Tim Regional Terbaik
+
๐Ÿ“… 2024Tim Regional Terbaik
Kompetisi

LOMBA MTQ TINGKAT PROVINSI KALIMANTAN BARAT PESERTA CABANG TAHFIDZ HADITS GOLONGAN 100 HADIST DENGAN SANAD PUTRI

Berpastisipasi pada MTQ tingkat provinsi Kalimantan Barat cabang Tahfidz Hadits 100 Hadits Bersanad Putri

-
๐Ÿ“… 2024PESERTA
+
๐Ÿ“… 2024PESERTA
Publikasi

Customer Relationship Management (CRM) System pada Peningkatan Layanan Pengguna E-Learning

Penulis: EF Ripanti, EE Pratama, F Asrin. Penelitian ini mengkaji penerapan sistem CRM untuk meningkatkan kualitas layanan dan kepuasan pengguna pada platform e-learning.

-
๐Ÿ“… 2025
+
๐Ÿ“… 2025
Publikasi

REKOMENDASI AREA PEMASARAN BAGI PEDAGANG SAYUR KELILING MENGGUNAKAN METODE DBSCAN DAN VISUALISASI HEATMAP

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.

-
๐Ÿ“… 2024
+
๐Ÿ“… 2024
Publikasi

Data mining untuk pengelompokan saham pada sektor energi dengan metode k-means

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.

-
๐Ÿ“… 2023
+
๐Ÿ“… 2023
Pengabdian Masyarakat

KODINGMU PLATFORM BELAJAR COMPUTATIONAL THINKING BAGI SISWA SMAN 1 MEMPAWAH HILIR

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.

-
๐Ÿ“… 2025
+
๐Ÿ“… 2025
Inovasi Aplikasi

SPOTA (2008)

Sistem Pendukung Outline Tugas Akhir โ€” lahir dari ide dosen, dibangun mahasiswa, masih digunakan hingga kini. Inovasi yang melampaui zamannya.

-
๐Ÿ“… 2008๐Ÿ’ก Masih aktif
+
๐Ÿ“… 2008๐Ÿ’ก Masih aktif
Inovasi Aplikasi

EdoXid (2021)

Sistem pengajuan sidang digital โ€” hadir menjawab pandemi, kini naik kelas ke skala Fakultas MIPA Universitas Tanjungpura.

-
๐Ÿ“… 2021๐Ÿš€ Skala Fakultas
+
๐Ÿ“… 2021๐Ÿš€ Skala Fakultas
@@ -2045,7 +2045,7 @@ } })(); - + \ No newline at end of file diff --git a/groups/Jellyfish.Corp/script.js b/groups/Jellyfish.Corp/script.js index 9503479..25ee30f 100644 --- a/groups/Jellyfish.Corp/script.js +++ b/groups/Jellyfish.Corp/script.js @@ -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 โ–ผ'; - 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 โ–ผ' - : 'Lihat Detail โ–ผ'; - 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)); -})(); \ No newline at end of file + + body.querySelectorAll('.jf-stat-num').forEach(el => obs.observe(el)); +} + +// ===== INIT ===== +initScrollReveal(); +initPrestasiFilter(); +initCounters(); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a16578c..43e70d0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -917,7 +917,6 @@ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" },