feat: tambah isi konten keseluruhan

This commit is contained in:
miaaurl
2026-06-04 20:09:31 +07:00
parent 0ebc25809b
commit 0768a9c04a
6 changed files with 3880 additions and 42 deletions
+364
View File
@@ -0,0 +1,364 @@
// ===== LANGUAGE TOGGLE =====
let currentLang = 'id';
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;
}
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;
}
function toggleLang() {
currentLang = currentLang === 'id' ? 'en' : 'id';
applyLang(currentLang);
setLangLabel(currentLang);
}
document.getElementById('lang-toggle')?.addEventListener('click', toggleLang);
document.getElementById('lang-toggle-mobile')?.addEventListener('click', toggleLang);
// ===== 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 512 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');
if (!tabs.length) return;
tabs.forEach(tab => {
tab.addEventListener('click', () => {
tabs.forEach(t => t.classList.remove('jf-tab-active'));
tab.classList.add('jf-tab-active');
const filter = tab.dataset.filter;
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';
}
});
});
});
})();
// ===== 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';
});
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, ''));
if (isNaN(num) || num === 0) return;
const suffix = raw.replace(/[0-9.,]/g, '');
const prefix = raw.startsWith('<') ? '<' : '';
const cleanSuffix = prefix ? suffix : suffix;
let start = 0;
const duration = 1400;
const step = 16;
const increment = num / (duration / step);
const timer = setInterval(() => {
start += increment;
if (start >= num) { start = num; clearInterval(timer); }
const display = num % 1 === 0
? Math.floor(start).toLocaleString('id-ID')
: start.toFixed(0);
el.textContent = prefix + display + cleanSuffix;
}, step);
obs.unobserve(el);
});
}, { threshold: 0.5 });
nums.forEach(el => obs.observe(el));
})();