import { Achievement, Project } from '../data'; // Determine API Base URL dynamically from Vite env, fallback to hardcoded if not set const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'https://api.ifuntanhub.dev'; const BIDANG_MAP: Record = { 1: 'Kecerdasan Buatan', 2: 'Cyber Security', 3: 'Data', 4: 'Software Engineering', 5: 'Competitive Programming', 6: 'IoT', 7: 'Smart City', 8: 'Web3', 9: 'Karya Tulis Ilmiah', 10: 'Robotik', }; /** * Helper to parse Rank/Juara from Achievement title */ function extractRank(title: string): string { const match = title.match(/(Juara\s+\d+|Juara\s+Harapan\s*\d*|Top\s+\d+|Finalis|Peringkat\s+\d+|Medali\s+\w+)/i); return match ? match[0] : 'Pemenang'; } /** * Helper to parse Level (Nasional, Internasional, Regional) from title/category */ function extractLevel(title: string, category: string): 'Nasional' | 'Internasional' | 'Regional' { const text = `${title} ${category}`.toLowerCase(); if ( text.includes('internasional') || text.includes('international') || text.includes('global') || text.includes('world') || text.includes('asean') || text.includes('unesco') ) { return 'Internasional'; } if ( text.includes('regional') || text.includes('kalbar') || text.includes('kalimantan') || text.includes('provinsi') || text.includes('kota') || text.includes('kabupaten') || text.includes('lokal') ) { return 'Regional'; } return 'Nasional'; // Default fallback } /** * Helper to extract competition name from full achievement title */ function extractCompetition(title: string): string { return title .replace(/^(Juara\s+\d+|Juara\s+Harapan\s*\d*|Top\s+\d+|Finalis|Peringkat\s+\d+|Medali\s+\w+)\s+(di\s+|pada\s+|dalam\s+)?/i, '') .trim(); } /** * Fetch achievements from API */ export async function fetchAchievementsFromAPI(): Promise { const response = await fetch(`${API_BASE_URL}/items/prestasi?fields=*.*`); if (!response.ok) { throw new Error(`Failed to fetch achievements: ${response.statusText}`); } const result = await response.json(); const data = result.data || []; return data .filter((item: any) => item.status === 'published') .map((item: any) => { const id = String(item.id); const title = item.nama_prestasi || 'Untitled Achievement'; let category = 'Umum'; if (item.bidang_id) { if (typeof item.bidang_id === 'object' && item.bidang_id.nama_bidang) { category = item.bidang_id.nama_bidang; } else { category = BIDANG_MAP[item.bidang_id as number] || 'Umum'; } } const rank = extractRank(title); const level = extractLevel(title, category); const competition = extractCompetition(title); const year = parseInt(item.tahun) || new Date().getFullYear(); const anggota = Array.isArray(item.anggota) ? item.anggota : []; const team = item.nama_tim || (anggota.length > 0 ? anggota[0].nama : 'Mahasiswa'); // Handle image url mapping for directus assets let image = `https://picsum.photos/seed/prestasi-${id}/800/600`; if (item.galeri && Array.isArray(item.galeri) && item.galeri.length > 0) { const firstImg = item.galeri[0]; const imgId = typeof firstImg === 'string' ? firstImg : (firstImg.directus_files_id || firstImg.id); if (imgId) image = `${API_BASE_URL}/assets/${imgId}`; } else if (item.foto) { image = `${API_BASE_URL}/assets/${item.foto}`; } const avatar = (item.nama_tim || item.nama_prestasi || 'IF') .substring(0, 2) .toUpperCase(); const description = item.deskripsi || `${team} berhasil meraih prestasi luar biasa sebagai ${rank} dalam ajang ${competition} tahun ${year} pada bidang ${category.toLowerCase()}.`; return { id, title, category, competition, rank, year, level, description, team, nim: item.nim || undefined, generation: item.angkatan ? `Angkatan ${item.angkatan}` : 'Informatika', image, avatar, members: anggota.map((m: any) => ({ nama: m.nama, angkatan: m.angkatan ? parseInt(m.angkatan) : undefined })), }; }); } /** * Fetch projects/portfolio from API */ export async function fetchProjectsFromAPI(): Promise { const response = await fetch(`${API_BASE_URL}/items/portfolio?fields=*,bidang.bidang_id.nama_bidang,galeri.*`); if (!response.ok) { throw new Error(`Failed to fetch portfolio: ${response.statusText}`); } const result = await response.json(); const data = result.data || []; return data .filter((item: any) => item.status === 'published') .map((item: any) => { const id = String(item.id); const title = item.nama_proyek || 'Untitled Project'; const anggota = Array.isArray(item.anggota) ? item.anggota : []; const studentName = item.nama_mahasiswa || (anggota.length > 0 ? anggota[0].nama : 'Mahasiswa'); const year = parseInt(item.tahun) || new Date().getFullYear(); const description = item.deskripsi || 'Tidak ada deskripsi.'; let categories: string[] = []; if (item.bidang && Array.isArray(item.bidang)) { categories = item.bidang.map((b: any) => { if (b.bidang_id && typeof b.bidang_id === 'object' && b.bidang_id.nama_bidang) { return b.bidang_id.nama_bidang; } if (typeof b.bidang_id === 'number') { return BIDANG_MAP[b.bidang_id] || 'Umum'; } return 'Umum'; }).filter(Boolean); } if (categories.length === 0) { categories = ['Umum']; } let link = item.url || undefined; if (link && !/^https?:\/\//i.test(link)) { link = `https://${link}`; } let image = `https://picsum.photos/seed/project-${id}/800/600`; if (item.galeri && Array.isArray(item.galeri) && item.galeri.length > 0) { const firstImg = item.galeri[0]; const imgId = typeof firstImg === 'string' ? firstImg : (firstImg.directus_files_id || firstImg.id); if (imgId) image = `${API_BASE_URL}/assets/${imgId}`; } else if (item.foto) { image = `${API_BASE_URL}/assets/${item.foto}`; } return { id, title, studentName, nim: item.nim || undefined, year, category: categories, description, image, link, catatan: item.catatan || undefined, members: anggota.map((m: any) => ({ nama: m.nama, nim: m.nim || undefined })), }; }); }