forked from izu/student-web-if-development-kit
83 lines
2.9 KiB
JavaScript
83 lines
2.9 KiB
JavaScript
// =====================================================
|
|
// API.js — Mekanisme Fetch Data Beasiswa (terpusat)
|
|
// -----------------------------------------------------
|
|
// Alur: coba API remote (Directus publik) → jika gagal,
|
|
// fallback ke berkas lokal `data/beasiswa.json`.
|
|
//
|
|
// Data remote dinormalisasi ke skema UI yang sama dengan
|
|
// data lokal agar filter.js dan popup.js tidak perlu berubah.
|
|
// =====================================================
|
|
|
|
(function (global) {
|
|
'use strict';
|
|
|
|
const CONFIG = {
|
|
baseUrl: 'https://api.ifuntanhub.dev',
|
|
collection: '/items/beasiswa',
|
|
localSource: 'data/beasiswa.json',
|
|
};
|
|
|
|
// Normalise status remote → nilai yang dipakai UI
|
|
function normalizeStatus(s) {
|
|
if (!s) return 'Ditutup';
|
|
const lower = s.toLowerCase();
|
|
if (lower === 'dibuka' || lower === 'buka') return 'Buka';
|
|
if (lower === 'ditutup') return 'Ditutup';
|
|
return s; // "Segera Dibuka" atau nilai lain: tampilkan apa adanya
|
|
}
|
|
|
|
// Petakan satu item (API remote maupun lokal) ke skema yang diharapkan filter.js / popup.js
|
|
function normalizeItem(item) {
|
|
const parts = [item.jenjang, item.negara, item.tipe_pendanaan].filter(Boolean);
|
|
return {
|
|
id: String(item.id),
|
|
nama: item.nama || '',
|
|
status: normalizeStatus(item.status),
|
|
kategori: item.tipe_pendanaan || '',
|
|
thumbnail: item.thumbnail || '',
|
|
deskripsi_singkat: item.deskripsi_singkat || parts.join(' · ') || 'Info beasiswa tersedia di sumber resmi.',
|
|
deskripsi_singkat_en: item.deskripsi_singkat_en || '',
|
|
tanggal_buka: item.tanggal_buka || '',
|
|
tanggal_tutup: item.tenggat_waktu || '',
|
|
url_sumber: item.url || '',
|
|
syarat_umum: item.syarat_umum || [],
|
|
syarat_umum_en: item.syarat_umum_en || [],
|
|
kontak: item.kontak || '',
|
|
tags: item.tags || parts,
|
|
};
|
|
}
|
|
|
|
async function fetchRemote() {
|
|
const res = await fetch(CONFIG.baseUrl + CONFIG.collection);
|
|
if (!res.ok) throw new Error(`API merespons HTTP ${res.status}`);
|
|
const json = await res.json();
|
|
return (json.data || []).map(normalizeItem);
|
|
}
|
|
|
|
async function fetchLocal() {
|
|
const res = await fetch(CONFIG.localSource);
|
|
if (!res.ok) throw new Error(`Gagal memuat data lokal (HTTP ${res.status})`);
|
|
const json = await res.json();
|
|
const raw = Array.isArray(json) ? json : json.data || [];
|
|
return raw.map(normalizeItem);
|
|
}
|
|
|
|
async function getBeasiswa() {
|
|
try {
|
|
const data = await fetchRemote();
|
|
return { data, source: 'remote' };
|
|
} catch (err) {
|
|
console.warn('[BeasiswaAPI] API remote gagal, fallback ke data lokal:', err.message);
|
|
try {
|
|
const data = await fetchLocal();
|
|
return { data, source: 'local' };
|
|
} catch (localErr) {
|
|
console.error('[BeasiswaAPI] Semua sumber gagal:', localErr.message);
|
|
throw localErr;
|
|
}
|
|
}
|
|
}
|
|
|
|
global.BeasiswaAPI = { config: CONFIG, getBeasiswa, fetchRemote, fetchLocal };
|
|
})(window);
|