diff --git a/assets/global/localization.js b/assets/global/localization.js
index bccabfa..456448a 100644
--- a/assets/global/localization.js
+++ b/assets/global/localization.js
@@ -578,6 +578,7 @@ const translations = {
grp_m4n1fest_hero_btn_stats: "Lihat Statistik Alumni",
grp_m4n1fest_hero_btn_join: "Gabung Grup IKA",
grp_m4n1fest_hero_stat_alumni: "TOTAL ALUMNI",
+ grp_m4n1fest_hero_stat_alumni_desc: "data diperoleh dari alumni terdata di tracer study",
grp_m4n1fest_hero_stat_batch: "ANGKATAN",
grp_m4n1fest_hero_stat_company: "PERUSAHAAN",
grp_m4n1fest_eyebrow_achievers: "High Achievers",
@@ -1285,6 +1286,7 @@ const translations = {
grp_m4n1fest_hero_btn_stats: "View Alumni Statistics",
grp_m4n1fest_hero_btn_join: "Join Alumni Group",
grp_m4n1fest_hero_stat_alumni: "TOTAL ALUMNI",
+ grp_m4n1fest_hero_stat_alumni_desc: "data obtained from alumni recorded in tracer study",
grp_m4n1fest_hero_stat_batch: "CLASSES",
grp_m4n1fest_hero_stat_company: "COMPANIES",
grp_m4n1fest_eyebrow_achievers: "High Achievers",
diff --git a/groups/M4N1FEST/index.html b/groups/M4N1FEST/index.html
index 0d4b863..2bdd916 100644
--- a/groups/M4N1FEST/index.html
+++ b/groups/M4N1FEST/index.html
@@ -1,4 +1,4 @@
-
+
@@ -50,6 +50,11 @@
z-index: 40;
}
+ @keyframes spin {
+ from { transform: rotate(0deg); }
+ to { transform: rotate(360deg); }
+ }
+
@media (prefers-reduced-motion: reduce) {
*,
@@ -1183,15 +1188,16 @@
-
850+
+
212+
TOTAL ALUMNI
+
data diperoleh dari alumni terdata di tracer study
@@ -1466,50 +1472,66 @@
-
-
+
+
+
+
Web Development
-
-
78%
+
+
—
+
Python / Data Science
-
-
65%
+
+
—
+
Mobile Development
-
-
54%
+
+
—
+
UI/UX Design
-
-
48%
+
+
—
+
Networking / DevOps
-
-
38%
+
+
—
+
Cybersecurity
-
-
25%
+
+
—
+
+
+
Machine Learning / AI
+
+
—
+
+
+
+
+
+
+
+ Memuat data skill alumni...
+
@@ -1547,12 +1569,24 @@
-
-
+
+
+
+
+
-
+
| Periode |
Jumlah |
@@ -1584,18 +1618,6 @@
Sumber : BAK UNTAN
-
-
-
@@ -2705,6 +2727,98 @@
}
}
+ /* ── SKILL DISTRIBUTION — Live fetch from Google Sheets (approved rows only) ── */
+ (function fetchSkillData() {
+ const SHEET_ID = '1mtVB1vLev-OWz6aTuuddGKPS8tCv8MJcGpzws8irpxk';
+ // Col I=Skill1, J=Skill2, K=Skill3, L=Approved (admin status)
+ const query = encodeURIComponent("select I,J,K where lower(L)='approved'");
+ const url = `https://docs.google.com/spreadsheets/d/${SHEET_ID}/gviz/tq?tqx=out:json&tq=${query}`;
+
+ // Map: skill label → bar id prefix (must match id="bar-XXX" and id="pct-XXX" in HTML)
+ const SKILL_MAP = {
+ 'Web Development' : 'web-development',
+ 'Mobile Development' : 'mobile-development',
+ 'Python / Data Science': 'python-data-science',
+ 'UI/UX Design' : 'uiux-design',
+ 'Networking / DevOps' : 'networking-devops',
+ 'Cybersecurity' : 'cybersecurity',
+ 'Machine Learning / AI': 'machine-learning-ai',
+ 'Database' : 'database',
+ };
+
+ const spinner = document.getElementById('skill-note-spinner');
+ const noteText = document.getElementById('skill-note-text');
+
+ function setNote(text, spin, isCta) {
+ if (spinner) spinner.style.animation = spin ? 'spin 1s linear infinite' : 'none';
+ if (!noteText) return;
+ if (isCta) {
+ noteText.innerHTML = text + ' Isi form kontribusi';
+ } else {
+ noteText.textContent = text;
+ }
+ }
+
+ function normalizeSkill(val) {
+ if (!val) return null;
+ const s = val.toLowerCase().trim();
+ if (s.includes('web')) return 'Web Development';
+ if (s.includes('mobile')) return 'Mobile Development';
+ if (s.includes('python') || s.includes('data science') || s.includes('data science')) return 'Python / Data Science';
+ if (s.includes('ui') || s.includes('ux')) return 'UI/UX Design';
+ if (s.includes('network') || s.includes('devops')) return 'Networking / DevOps';
+ if (s.includes('cyber')) return 'Cybersecurity';
+ if (s.includes('machine') || s.includes('ai') || s.includes('artificial')) return 'Machine Learning / AI';
+ if (s.includes('database') || s.includes('db')) return 'Database';
+ return null;
+ }
+
+ fetch(url)
+ .then(res => res.text())
+ .then(raw => {
+ const json = JSON.parse(raw.replace(/^[^{]+/, '').replace(/[);]+$/, ''));
+ const rows = (json.table && json.table.rows) ? json.table.rows : [];
+
+ if (rows.length === 0) {
+ setNote('Data skill masih kosong, bantu kami lengkapi data ini!', false, false);
+ return;
+ }
+
+ // Count normalized skill mentions
+ const counts = {};
+ rows.forEach(row => {
+ [0, 1, 2].forEach(colIdx => {
+ const cell = row.c && row.c[colIdx];
+ const val = cell && cell.v ? String(cell.v).trim() : '';
+ const normalized = normalizeSkill(val);
+ if (normalized) {
+ counts[normalized] = (counts[normalized] || 0) + 1;
+ }
+ });
+ });
+
+ const totalMentions = Object.values(counts).reduce((s, c) => s + c, 0);
+ const maxCount = Math.max(...Object.values(counts), 0);
+
+ // Update bars for predefined skills
+ Object.entries(SKILL_MAP).forEach(([label, idKey]) => {
+ const count = counts[label] || 0;
+ const pct = totalMentions > 0 ? Math.round((count / totalMentions) * 100) : 0;
+ const barPct = maxCount > 0 ? Math.round((count / maxCount) * 100) : 0;
+
+ const barEl = document.getElementById('bar-' + idKey);
+ const pctEl = document.getElementById('pct-' + idKey);
+ if (barEl) barEl.style.width = barPct + '%';
+ if (pctEl) pctEl.textContent = count > 0 ? pct + '%' : '—';
+ });
+
+ setNote(`Data dari ${rows.length} alumni yang diverifikasi.`, false, false);
+ })
+ .catch(() => {
+ setNote('Data skill masih kosong, bantu kami lengkapi data ini!', false, false);
+ });
+ })();
+
/* ── REVEAL ON SCROLL ── */
const ro = new IntersectionObserver(
(entries) => {
diff --git a/groups/M4N1FEST/style.css b/groups/M4N1FEST/style.css
index 127a74b..8fc82f7 100644
--- a/groups/M4N1FEST/style.css
+++ b/groups/M4N1FEST/style.css
@@ -666,11 +666,15 @@ ul.achiever-achievements li::before {
gap: 52px;
align-items: start;
}
+.stat-cols {
+ grid-template-columns: 1.3fr 0.7fr;
+}
.two-col > * {
min-width: 0;
}
@media (max-width: 760px) {
- .two-col {
+ .two-col,
+ .stat-cols {
grid-template-columns: 1fr;
gap: 32px;
}