feat(ApeNameTeamE): tambah proyek web-beasiswa-untan

Memindahkan seluruh file web-beasiswa-untan (assets, data, index.html,
SRS/SDD, PROJECT_CONTEXT) ke dalam folder grup ApeNameTeamE.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Araya's Project
2026-05-22 13:33:40 +07:00
parent 0ebc25809b
commit 8e9137f725
17 changed files with 4256 additions and 1306 deletions
+273
View File
@@ -0,0 +1,273 @@
# PROJECT CONTEXT
## Website Statis Halaman Beasiswa — Informatika UNTAN
> File ini adalah konteks utama proyek untuk AI assistant (Antigravity).
> Baca file ini setiap kali kamu membantu pengerjaan proyek ini.
---
## 🎯 Apa yang Dibangun?
**Single static landing page** berbasis HTML/CSS/JS murni (native web) untuk menampilkan informasi beasiswa bagi mahasiswa aktif, alumni, dan masyarakat umum Program Studi Informatika, Universitas Tanjungpura (UNTAN), Pontianak.
Website ini bukan aplikasi web dinamis. Tidak ada backend, tidak ada database, tidak ada login. Update konten dilakukan dengan mengedit file JSON dan push ke GitHub → auto-deploy via Puify ke server prodi.
---
## 🏗️ Tech Stack
| Layer | Teknologi |
|---|---|
| Markup | HTML5 |
| Styling | CSS3 + Tailwind CSS |
| Interaktivitas | Vanilla JavaScript (ES6+) |
| Font | Google Fonts (Inter / Poppins) |
| Ikon | Font Awesome |
| Animasi | AOS.js (Animate on Scroll) |
| Carousel | Swiper.js |
| Hosting | Dedicated Server Prodi UNTAN via Puify |
| Version Control | Git + GitHub |
**Tidak boleh menggunakan:** Framework berat (React, Vue, Angular), backend (Node.js, PHP, Python), database (MySQL, MongoDB).
---
## 📐 Desain
- **Figma Project:** https://www.figma.com/design/rG6JYG19CWziaPMhbJ2NPL/PPL-FIGMA?node-id=0-1
- **Prototype:** https://www.figma.com/proto/rG6JYG19CWziaPMhbJ2NPL/PPL-FIGMA?node-id=120-1247
### Warna Utama
| Variabel | Hex | Penggunaan |
|---|---|---|
| Primary (Biru) | `#2B4590` | Navbar, heading, tombol, border aktif |
| Secondary (Kuning) | `#F5A623` | CTA, aksen, badge |
| Background | `#FFFFFF` | Latar halaman |
| Text | `#1A1A1A` | Body text |
| Accent | `#6B7280` | Caption, label, border |
| Success | `#10B981` | Badge "Buka" |
| Danger | `#EF4444` | Badge "Ditutup" |
| Overlay | `#00000080` | Background popup |
### Tipografi
- **Font:** Inter (utama) / Poppins (heading)
- H1: 4864px bold | H2: 3240px semibold | H3: 2428px semibold
- Body: 1618px regular | Caption: 1214px
---
## 📄 Struktur Halaman (Top → Bottom)
```
[NAVBAR - Sticky]
Logo UNTAN | Menu: Beranda, Beasiswa, Testimoni, Kontak | Toggle ID/EN
[#hero - Hero Section]
Judul: "Beasiswa Studi & Penelitian"
Sub: Teknik Informatika Universitas Tanjungpura
Deskripsi singkat tentang beasiswa
CTA Button (kuning): "Lihat Daftar Beasiswa →"
Foto ilustrasi mahasiswa (kanan)
[#statistics - Statistik Counter]
3 angka dengan animasi scroll:
- Total Mahasiswa Penerima Beasiswa Semester Ini
- Total Penerima Beasiswa Pembiayaan Pemerintah
- Total Penerima Beasiswa Pembiayaan Swasta
[#directory - Direktori Beasiswa]
- Tab filter: Semua | Sedang Buka | Ditutup | Pemerintah | Swasta
- Search bar (real-time)
- Grid kartu beasiswa:
* Desktop: 3 kolom
* Tablet: 2 kolom
* Mobile: 1 kolom
- Tiap kartu: thumbnail, badge status, nama, deskripsi singkat, tanggal, tombol "Selengkapnya →"
- Klik "Selengkapnya →" → buka POPUP MODAL
[POPUP MODAL - Detail Beasiswa]
- Nama + thumbnail/logo beasiswa
- Badge status (Buka / Ditutup)
- Syarat umum (ringkasan/bullet)
- Kontak yang bisa dihubungi
- Tombol "Info Lebih Lanjut" → buka URL sumber resmi (tab baru)
- Tutup: tombol ×, klik luar area, tekan Escape
[#testimonial - Testimoni Penerima Beasiswa]
- Carousel / grid kartu
- Tiap kartu: foto, nama, nama beasiswa yang diterima, kutipan singkat
- Navigasi carousel jika > 3 testimoni
[#cta - Call to Action]
- Judul: "Ingin Mengetahui Info Lebih Lanjut?"
- Dua tombol:
* "Daftar Beasiswa" (scroll ke #directory)
* "Hubungi Kami" (WhatsApp admin)
[#footer - Footer]
- Logo Informatika UNTAN
- Alamat prodi, email, telepon, WhatsApp
- Ikon media sosial
- Ilustrasi khas Pontianak (dekorasi bawah)
```
---
## 📁 Struktur File Proyek
```
project-root/
├── index.html
├── assets/
│ ├── css/
│ │ └── style.css
│ ├── js/
│ │ ├── main.js # Init AOS, smooth scroll, sticky navbar
│ │ ├── filter.js # Filter tab + real-time search
│ │ ├── popup.js # Modal detail beasiswa
│ │ ├── counter.js # Animasi counter statistik
│ │ ├── carousel.js # Carousel testimoni (Swiper.js)
│ │ └── i18n.js # Toggle bahasa ID/EN
│ └── images/
│ ├── hero/
│ ├── beasiswa/ # Logo/thumbnail beasiswa
│ └── testimoni/ # Foto penerima
├── data/
│ ├── beasiswa.json
│ └── testimoni.json
└── README.md
```
---
## 🗃️ Format Data
### `data/beasiswa.json`
```json
[
{
"id": "bsw-001",
"nama": "Beasiswa Adaro Foundation 2026",
"kategori": "Swasta",
"status": "Ditutup",
"thumbnail": "assets/images/beasiswa/adaro.jpg",
"deskripsi_singkat": "Beasiswa untuk mahasiswa S1 & D4 dengan IPK minimal 3.00...",
"syarat_umum": [
"Mahasiswa aktif S1/D4",
"IPK minimal 3.00",
"Berasal dari keluarga kurang mampu"
],
"kontak": "Admin Prodi / Kemahasiswaan UNTAN",
"tanggal_buka": "2026-01-01",
"tanggal_tutup": "2026-04-09",
"url_sumber": "https://...",
"tags": ["S1", "Swasta"]
}
]
```
### `data/testimoni.json`
```json
[
{
"id": "tsm-001",
"nama": "Aulia Rahman",
"foto": "assets/images/testimoni/aulia.jpg",
"nama_beasiswa": "Beasiswa Prestasi",
"kutipan": "Beasiswa ini benar-benar membuka jalan bagi saya untuk fokus sepenuhnya pada pendidikan..."
}
]
```
---
## ⚙️ Fitur Interaktif yang Harus Diimplementasikan
| Fitur | Status | File |
|---|---|---|
| Sticky Navbar (transparent → solid saat scroll) | ⏳ | `main.js` |
| Hamburger Menu | ⏳ | `main.js` |
| Smooth Scroll ke seksi | ⏳ | `main.js` |
| Active State Navbar (IntersectionObserver) | ⏳ | `main.js` |
| Animasi AOS (elemen muncul saat scroll) | ⏳ | `main.js` |
| Counter Animasi Statistik | ⏳ | `counter.js` |
| Render kartu beasiswa dari JSON | ⏳ | `filter.js` |
| Filter tab (Semua/Buka/Ditutup/Pemerintah/Swasta) | ⏳ | `filter.js` |
| Real-time search | ⏳ | `filter.js` |
| Popup Modal detail beasiswa | ⏳ | `popup.js` |
| Tutup popup (×, klik luar, Escape) | ⏳ | `popup.js` |
| Carousel testimoni (Swiper.js) | ⏳ | `carousel.js` |
| Toggle bahasa ID/EN | ⏳ | `i18n.js` |
---
## 📱 Responsive Breakpoints
```css
/* Mobile first */
/* Default: mobile < 768px */
/* Tablet: */ @media (min-width: 768px) { ... }
/* Laptop: */ @media (min-width: 1024px) { ... }
/* Desktop: */ @media (min-width: 1280px) { ... }
```
---
## 🔒 Aturan Keamanan Kode
- Semua link eksternal: `target="_blank" rel="noopener noreferrer"`
- Tidak ada hardcoded data sensitif di source code
- Input search di-sanitasi sebelum digunakan untuk filter DOM
- Tidak menggunakan `innerHTML` dengan input pengguna langsung (cegah XSS)
---
## 👥 Tim & Peran
| Nama | Peran |
|---|---|
| Djapianus Thebrianto | Project Manager |
| Derangga Aray Abimanyu | Backend Developer (data, scraping, JSON) |
| Destra Aulia Faza Ananda Putra | Frontend Developer (HTML, CSS, JS) |
| Dian Satrio Prayogo | UI/UX Designer (Figma) |
| Jonathan Geral Nababan | Quality Assurance (testing) |
---
## 📋 Hal Penting untuk AI Assistant
1. **Ini bukan React/Vue/Angular.** Semua harus ditulis dalam HTML/CSS/Tailwind/Vanilla JS.
2. **Data beasiswa dibaca dari `data/beasiswa.json`** — bukan hardcoded di HTML.
3. **Warna wajib sesuai palet resmi** — jangan gunakan warna lain sembarangan.
4. **Mobile-first** — tulis CSS dari ukuran kecil dulu, baru ke besar.
5. **Popup harus bisa ditutup 3 cara:** tombol ×, klik overlay, tekan Escape.
6. **Filter dan search bisa aktif bersamaan** (kumulatif, bukan saling menggantikan).
7. **Navbar berubah warna saat scroll** — transparent di atas hero, solid biru setelah scroll turun.
8. **Semua animasi pakai AOS.js** — inisialisasi di `main.js` dengan `AOS.init()`.
9. **Carousel testimoni pakai Swiper.js** — touch-friendly untuk mobile.
10. **Tidak ada `alert()`, `console.log()` di production code.**
---
## 🚀 Cara Kerja Deployment
```
Developer push ke GitHub
Puify detects push
Auto-deploy ke server
Website live (Dev)
Approved → Production
```
---
## 📎 Dokumen Terkait
- `SRS.md` — Spesifikasi kebutuhan lengkap (use case, NFR, batasan)
- `SDD.md` — Desain teknis lengkap (arsitektur, komponen, schema data)
- Figma: https://www.figma.com/design/rG6JYG19CWziaPMhbJ2NPL/PPL-FIGMA?node-id=0-1
+329
View File
@@ -0,0 +1,329 @@
# Software Design Document (SDD)
## Website Statis Halaman Beasiswa — One-Page HTML
### Program Studi Informatika — Universitas Tanjungpura
| Field | Detail |
|---|---|
| Nama Proyek | Pengembangan Website Statis Halaman Beasiswa |
| Kelompok | Ape Nama Team E |
| Versi | 1.0 |
| Fase SDLC | Design (aktif) |
| Dosen | Izuardo Zulkarnain, S.Pd., M.T |
| Semester | Genap 2025/2026 |
---
## 1. Pendahuluan
### 1.1 Tujuan Dokumen
SDD ini mendeskripsikan perancangan teknis website beasiswa Informatika UNTAN sebagai one-page HTML native. Dokumen ini menjadi panduan tim dalam mengimplementasikan:
- Fitur popup detail beasiswa
- Integrasi data hasil scraping & survei admin
- Otomatisasi deployment via Puify (push-to-deploy)
### 1.2 Stack Teknologi
| Layer | Teknologi | Keterangan |
|---|---|---|
| Markup | HTML5 | Struktur konten |
| Styling | CSS3 / Tailwind CSS | Layout responsif |
| Interaktivitas | JavaScript (Vanilla / Alpine.js) | Animasi, scroll, toggle |
| Font & Ikon | Google Fonts / Font Awesome | Tipografi & ikon |
| Hosting | Puify (SaaS) | Auto-deploy dari repo ke server |
| Server | Dedicated Server Prodi | Dev & Production |
| Version Control | Git + GitHub | Kolaborasi & push-to-deploy |
### 1.3 Posisi dalam SDLC
| Fase | Status |
|---|---|
| Requirement | ✅ Selesai |
| Design | 🔄 Aktif |
| Implementation | ⏳ Belum |
| Testing | ⏳ Belum |
| Deployment | ⏳ Belum |
---
## 2. Arsitektur Halaman (Site Architecture)
### 2.1 Konsep One-Page Website
Single-page statis — semua konten dalam satu file HTML utama. Navigasi menggunakan **smooth scroll**. Detail beasiswa (syarat umum) ditampilkan via **popup modal** agar halaman tetap bersih.
### 2.2 Struktur Seksi (Vertikal, Atas → Bawah)
| No | ID | Nama Seksi | Konten Utama |
|---|---|---|---|
| 1 | `#hero` | Hero / Landing | Judul "Beasiswa Studi & Penelitian", deskripsi, CTA "Lihat Daftar Beasiswa", foto ilustrasi mahasiswa |
| 2 | `#statistics` | Statistik Counter | 3 angka animasi: Total Penerima Semester Ini, Total Pemerintah, Total Swasta |
| 3 | `#directory` | Direktori Beasiswa | Grid kartu (3 kolom desktop, 2 tablet, 1 mobile), tab filter, real-time search, popup detail |
| 4 | `#testimonial` | Testimoni | Carousel/grid testimoni: foto, nama, beasiswa, kutipan singkat |
| 5 | `#cta` | Call-to-Action | Banner ajakan + tombol WhatsApp admin + Instagram kemahasiswaan |
| 6 | `#footer` | Footer | Logo prodi, alamat, email, telepon, WA, ikon sosmed, dekorasi ilustrasi Pontianak |
### 2.3 Navigasi
**Sticky navbar** yang selalu terlihat saat scroll.
| Perangkat | Perilaku Navbar |
|---|---|
| Desktop/Laptop | Horizontal, semua item terlihat |
| Tablet | Horizontal, item muat; sisanya dropdown |
| Mobile | Hamburger menu (≡) — tap untuk expand vertikal |
---
## 3. Desain Visual & Identitas
### 3.1 Color Palette
| Peran | Nama | Hex | Digunakan Untuk |
|---|---|---|---|
| Primary | Biru Informatika | `#2B4590` | Navbar, heading, tombol primary, border aktif |
| Secondary | Kuning/Oranye | `#F5A623` | CTA button, aksen, badge |
| Background | White | `#FFFFFF` | Latar halaman utama |
| Text | Dark Gray | `#1A1A1A` | Body text, paragraf |
| Accent | Abu-abu | `#6B7280` | Caption, label, border |
| Success | Hijau | `#10B981` | Badge status "Buka" |
| Danger | Merah | `#EF4444` | Badge status "Ditutup" |
| Overlay | Hitam + Transparansi | `#00000080` | Background popup modal |
### 3.2 Tipografi
| Elemen | Font Family | Ukuran | Weight |
|---|---|---|---|
| Heading H1 | Poppins / Inter | 4864px | 700 (Bold) |
| Heading H2 | Poppins / Inter | 3240px | 600 (SemiBold) |
| Heading H3 | Poppins / Inter | 2428px | 600 (SemiBold) |
| Body Text | Inter / Poppins | 1618px | 400 (Regular) |
| Caption/Label | Inter / Poppins | 1214px | 400500 |
| Navbar | Inter | 1416px | 500 (Medium) |
| Button | Inter | 1416px | 600 (SemiBold) |
### 3.3 Komponen UI
| Komponen | Spesifikasi |
|---|---|
| Navbar | Sticky; transparent di atas hero → solid biru `#2B4590` saat scroll; toggle ID/EN di kanan |
| Hero Section | Full-height, overlay gradient gelap, judul besar, deskripsi, CTA kuning kontras |
| Card Beasiswa | Border subtle, shadow ringan; hover: scale sedikit + shadow lebih dalam; thumbnail 100% lebar |
| Button Primary | Solid biru, teks putih |
| Button Secondary | Outline biru |
| Button Ghost | Tanpa border |
| Badge Status | Rounded pill; Hijau "Buka", Merah "Ditutup" |
| Tab Filter | Underline active state, smooth transition, teks hitam, garis bawah aktif biru |
| Popup Modal | Center screen, dark overlay, border-radius 12px, close button (×) kanan atas |
| Footer | Background `#1A1A1A`, teks putih, 34 kolom desktop |
---
## 4. Desain Mockup (UI/UX)
### 4.1 Alat Desain
**Figma** — kolaborasi realtime, wireframe + hi-fidelity prototype.
- **Figma Project:** https://www.figma.com/design/rG6JYG19CWziaPMhbJ2NPL/PPL-FIGMA?node-id=0-1
- **Prototype Interaktif:** https://www.figma.com/proto/rG6JYG19CWziaPMhbJ2NPL/PPL-FIGMA?node-id=120-1247
### 4.2 Tahapan Desain
1. **Wireframe (Lo-Fi)** — sketsa hitam-putih, fokus layout & posisi elemen
2. **Mockup (Hi-Fi)** — desain lengkap dengan warna, font, dan aset visual
3. **Prototype** — mockup yang bisa diklik untuk simulasi navigasi antar seksi
4. **User Testing** — validasi desain bersama calon pengguna
### 4.3 Breakpoint & Resolusi
| Perangkat | Resolusi Mockup |
|---|---|
| Desktop Monitor | 1920 × 1080 |
| Laptop | 1366 × 768 |
| Tablet Portrait | 768 × 1024 |
| Tablet Landscape | 1024 × 768 |
| Mobile / HP | 390 × 844 |
---
## 5. Desain Responsif
### 5.1 Strategi: Mobile-First
Desain dimulai dari layar terkecil → diperluas ke layar lebih besar via CSS media query. Memastikan performa optimal di koneksi lambat.
### 5.2 Breakpoint
| Perangkat | Breakpoint | Resolusi Umum |
|---|---|---|
| Desktop Monitor | `>= 1280px` | 1920×1080, 2560×1440 |
| Laptop | `>= 1024px` | 1366×768, 1440×900 |
| Tablet | `>= 768px` | 768×1024, 820×1180 |
| Mobile | `< 768px` | 360×800, 390×844, 414×896 |
### 5.3 Perubahan Layout per Breakpoint
| Elemen | Mobile (<768px) | Tablet (7681279px) | Desktop (≥1280px) |
|---|---|---|---|
| Navbar | Hamburger menu | Hamburger / partial menu | Horizontal full menu |
| Hero Section | Teks atas, gambar bawah | Teks kiri, gambar kanan 50/50 | Teks kiri, gambar kanan lebar |
| Card Grid | 1 kolom | 2 kolom | 34 kolom |
| Teks Body | 16px | 1617px | 1718px |
| Padding Section | 24px 16px | 40px 32px | 80px 64px |
| Footer | Stack vertikal | 2 kolom | 34 kolom |
### 5.4 Hasil Uji Responsivitas
| No | Perangkat/Browser | Ukuran | Status | Catatan |
|---|---|---|---|---|
| 1 | Chrome Desktop | 1920×1080 | ✅ Lulus | Layout proporsional, spacing rapi |
| 2 | Chrome Mobile Sim. | 390×844 | ✅ Lulus | Card grid 1 kolom, teks 16px nyaman |
| 3 | Firefox Desktop | 1440×900 | ✅ Lulus | Konsisten dengan Chrome Desktop |
| 4 | iPhone (Safari) | 390×844 | ✅ Lulus | Hero stack sempurna, padding aman |
| 5 | Android Chrome | 360×800 | ✅ Lulus | Touch target ideal, gambar proporsional |
| 6 | iPad (Safari) | 768×1024 | ✅ Lulus | Hero 50/50, spasi sentuh lega |
---
## 6. Use Case Diagram
### 6.1 Aktor Sistem
| Aktor | Deskripsi |
|---|---|
| Pengunjung Umum | Mahasiswa aktif, alumni, calon mahasiswa, dosen, masyarakat — tanpa autentikasi |
| Admin Prodi | Pengelola konten: memperbarui data beasiswa, testimoni, statistik via push-to-repo |
### 6.2 Daftar Use Case & Skenario
Lihat detail lengkap di SRS.md. Ringkasan:
| Kode | Nama | Aktor |
|---|---|---|
| UC-01 | Melihat Daftar Beasiswa | Pengunjung Umum |
| UC-02 | Memfilter Beasiswa Berdasarkan Kategori | Pengunjung Umum |
| UC-03 | Mencari Beasiswa | Pengunjung Umum |
| UC-04 | Melihat Detail Beasiswa (Popup) | Pengunjung Umum |
| UC-05 | Mengakses Sumber Resmi Beasiswa | Pengunjung Umum |
| UC-06 | Menghubungi Admin via CTA | Pengunjung Umum |
| UC-07 | Melihat Testimoni Penerima Beasiswa | Pengunjung Umum |
| UC-08 | Mengganti Bahasa Tampilan (ID/EN) | Pengunjung Umum |
| UC-09 | Memperbarui Data Beasiswa | Admin Prodi |
**Relasi antar UC:** UC-04 `<<include>>` UC-05 (popup detail menyertakan akses sumber resmi)
---
## 7. Fitur Interaktif (Client-Side)
Tidak ada backend API. Semua interaktivitas dijalankan di sisi klien.
| No | Fitur | Teknologi | Keterangan |
|---|---|---|---|
| 1 | Smooth Scroll Navigasi | CSS `scroll-behavior` / JS | Scroll halus ke seksi saat klik menu |
| 2 | Sticky Navbar | CSS `position:sticky` / JS scroll | Navbar tetap di atas saat scroll |
| 3 | Hamburger Menu | JavaScript + CSS toggle | Menu responsif layar kecil |
| 4 | Active State Navbar | JS `IntersectionObserver` | Highlight menu sesuai seksi terlihat |
| 5 | Animasi Masuk (AOS) | AOS.js / CSS animation | Elemen muncul saat pertama kali di viewport |
| 6 | Counter Animasi | JavaScript | Angka statistik berjalan saat di-scroll |
| 7 | Filter Real-Time | Vanilla JavaScript | Filter kartu saat klik tab, tanpa reload |
| 8 | Pencarian Real-Time | Vanilla JavaScript | Cari beasiswa saat ketik di search bar |
| 9 | Popup Modal Detail | Vanilla JavaScript | Detail beasiswa dalam modal; tutup via ×, klik luar, atau Escape |
| 10 | Toggle Bahasa ID/EN | Vanilla JS + localStorage | Ubah teks tanpa reload, simpan preference di session |
| 11 | Carousel Testimoni | Vanilla JS / Swiper.js | Navigasi testimoni left/right; touch swipe di mobile |
| 12 | Form Kontak (Opsional) | Formspree / EmailJS / mailto | Kirim pesan tanpa backend |
| 13 | Lightbox Galeri (Opsional) | Fancybox / vanilla JS | Gambar fullscreen saat diklik |
---
## 8. Layanan Pihak Ketiga
| Layanan | Kegunaan | Gratis? |
|---|---|---|
| Google Fonts | Tipografi (Inter/Poppins) | ✅ Ya |
| Font Awesome | Ikon UI | ✅ Ya (tier dasar) |
| Google Maps Embed | Peta lokasi di seksi kontak | ✅ Ya (basic embed) |
| Formspree | Form kontak tanpa backend | ✅ Ya (tier dasar) |
| AOS.js | Animasi scroll (Animate on Scroll) | ✅ Ya (open source) |
| Swiper.js | Carousel testimoni | ✅ Ya (open source) |
---
## 9. Desain Keamanan
### 9.1 Keamanan Form Kontak
- Validasi client-side: semua field wajib diisi, format email dicek sebelum submit
- Rate limiting: Formspree/EmailJS membatasi pengiriman untuk mencegah spam
- reCAPTCHA (Opsional): Google reCAPTCHA v3 untuk mencegah bot
### 9.2 Keamanan Konten
- **Tidak ada data sensitif** — website tidak menyimpan data pengguna (no login, no database)
- **HTTPS wajib** — sertifikat SSL/TLS pada server hosting prodi
- **Content Security Policy** — meta CSP header untuk mencegah XSS
- **External link** — semua link eksternal menggunakan `rel="noopener noreferrer"`
---
## 10. Struktur File yang Direkomendasikan
```
project-root/
├── index.html # File HTML utama (one-page)
├── assets/
│ ├── css/
│ │ └── style.css # Custom CSS (jika tidak full Tailwind)
│ ├── js/
│ │ ├── main.js # Logika utama: scroll, navbar, AOS init
│ │ ├── filter.js # Filter & pencarian beasiswa
│ │ ├── popup.js # Modal popup detail beasiswa
│ │ ├── counter.js # Animasi counter statistik
│ │ ├── carousel.js # Carousel testimoni
│ │ └── i18n.js # Toggle bahasa ID/EN
│ └── images/
│ ├── hero/ # Foto hero section
│ ├── beasiswa/ # Thumbnail logo beasiswa
│ └── testimoni/ # Foto penerima beasiswa
├── data/
│ ├── beasiswa.json # Data beasiswa (diupdate oleh admin)
│ └── testimoni.json # Data testimoni
└── README.md # Panduan setup & deployment
```
---
## 11. Data Schema
### 11.1 Schema Beasiswa (`beasiswa.json`)
```json
{
"id": "string",
"nama": "string",
"kategori": "Pemerintah | Swasta",
"status": "Buka | Ditutup",
"thumbnail": "path/to/image.jpg",
"deskripsi_singkat": "string (max 150 char)",
"syarat_umum": ["string", "string"],
"kontak": "string",
"tanggal_buka": "YYYY-MM-DD",
"tanggal_tutup": "YYYY-MM-DD",
"url_sumber": "https://...",
"tags": ["S1", "S2", "Magang", "Luar Negeri"]
}
```
### 11.2 Schema Testimoni (`testimoni.json`)
```json
{
"id": "string",
"nama": "string",
"foto": "path/to/foto.jpg",
"nama_beasiswa": "string",
"kutipan": "string (max 200 char)"
}
```
---
## 12. Referensi
1. IEEE Standard 1016-2009 — Software Design Descriptions
2. W3C — HTML5 & CSS3 Specification (https://www.w3.org)
3. Google — Web Fundamentals: Responsive Web Design
4. MDN Web Docs — CSS Media Queries
5. Figma — Design Tool Documentation
6. Nurhikmat et al. (2024) — Optimasi Responsivitas Web dengan Mobile-First Design. JINTEKS.
+337
View File
@@ -0,0 +1,337 @@
# Software Requirements Specification (SRS)
## Pengembangan Website Statis Halaman Beasiswa
### Program Studi Informatika — Universitas Tanjungpura
| Field | Detail |
|---|---|
| Nama Proyek | Pengembangan Website Statis Halaman Beasiswa |
| Kelompok | Ape Nama Team E |
| Versi | 1.1 |
| Tanggal | 01/05/2026 |
| Dosen | Izuardo Zulkarnain, S.Pd., M.T |
| Mata Kuliah | Proyek Perangkat Lunak — Semester Genap 2025/2026 |
**Anggota Tim:**
- Djapianus Thebrianto — Project Manager
- Derangga Aray Abimanyu — Backend Developer
- Destra Aulia Faza Ananda Putra — Frontend Developer
- Dian Satrio Prayogo — UI/UX Designer
- Jonathan Geral Nababan — Quality Assurance
---
## 1. Pendahuluan
### 1.1 Tujuan Dokumen
SRS ini memberikan spesifikasi teknis dan fungsional untuk pengembangan Website Statis Beasiswa Informatika Universitas Tanjungpura. Dokumen ini memastikan:
- Pengembang membangun sistem dengan kode sederhana yang mudah di-maintain melalui mekanisme push-to-repo ke dedicated server prodi.
- Penyajian data beasiswa (nama & syarat umum) dilakukan melalui fitur **Pop-up** dengan akses langsung ke admin via WhatsApp dan Instagram kemahasiswaan UNTAN.
- Proyek mengalihkan alur data dari portal universitas/survei admin ke static page dengan **availability 24 jam**.
**Ditujukan kepada:** Tim Ape Nama Team E, Product Owner (dosen), dan Administrator Prodi.
### 1.2 Ruang Lingkup
Website statis single-page yang menjadi pusat informasi beasiswa, riset, dan pengembangan karir — terintegrasi dengan infrastruktur server Prodi Informatika UNTAN.
**Fitur yang dicakup:**
- Direktori beasiswa (mahasiswa aktif, alumni, S2 luar negeri, magang)
- Detail beasiswa via popup (nama + syarat umum)
- Data beasiswa dari web scraping sumber resmi
- Seksi testimoni penerima beasiswa (foto, profil, kutipan)
- Toggle bahasa Indonesia / Inggris (bilingual)
- CTA ke WhatsApp admin & Instagram kemahasiswaan UNTAN
**Yang TIDAK dicakup:**
- Formulir pendaftaran (diarahkan ke URL asli penyedia)
- Halaman admin berbasis web (update via push-to-repo)
- Database — data bersifat statis (JSON/JS di repositori)
### 1.3 Definisi & Akronim
| Istilah | Definisi |
|---|---|
| Native Website | Web dengan HTML, CSS, JS murni tanpa framework kompleks |
| Scraping | Pengambilan data otomatis dari website eksternal |
| Dedicated Server | Server milik Prodi Informatika UNTAN (Dev & Production) |
| Pop-up / Modal | Jendela overlay di atas halaman tanpa reload |
| CTA | Call-to-Action — tombol ajakan ke WhatsApp/Instagram |
| Availability | Kemampuan sistem beroperasi 24 jam |
| Puify | Platform SaaS otomatisasi deployment dari repo ke server |
### 1.4 Referensi
- IEEE Std 830-1998 — Software Requirements Specifications
- UU No. 27 Tahun 2022 tentang Perlindungan Data Pribadi (UU PDP)
---
## 2. Deskripsi Umum Sistem
### 2.1 Perspektif Produk
Produk baru berdiri sendiri sebagai **single static landing page** — bukan pengganti sistem lama. Website ini hadir sebagai transformasi digital dari penyebaran info beasiswa yang sebelumnya manual (portal, surat kabar mahasiswa, grup medsos) ke satu platform terpusat.
**Integrasi eksternal (satu arah):**
- Website resmi penyedia beasiswa (data via scraping)
- API Website Informatika UNTAN (konten artikel/berita)
- WhatsApp & Instagram Kemahasiswaan UNTAN (CTA)
Tidak ada antarmuka admin berbasis web. Semua update konten via **push ke GitHub → auto-deploy ke server** melalui Puify.
### 2.2 Fungsi Utama Sistem
| Kode | Fungsi | Deskripsi |
|---|---|---|
| F01 | Direktori Beasiswa | Grid kartu beasiswa aktif, S2, magang, penelitian dari berbagai sumber resmi |
| F02 | Filter & Pencarian | Saring berdasarkan kategori (Semua/Buka/Ditutup/Pemerintah/Swasta) + real-time search |
| F03 | Detail via Pop-up | Modal berisi nama, syarat umum, kontak, tautan sumber resmi |
| F04 | Testimoni | Foto, nama, nama beasiswa, kutipan dari penerima beasiswa |
| F05 | CTA Hubungi Admin | Tombol cepat ke WhatsApp admin & Instagram kemahasiswaan |
| F06 | Bilingual ID/EN | Toggle bahasa Indonesia ↔ Inggris tanpa reload |
| F07 | Update via Repository | Admin edit file data + push → halaman publik auto-update |
### 2.3 Kelas Pengguna
| Kelas | Karakteristik | Hak Akses |
|---|---|---|
| Pengunjung Umum | Mahasiswa aktif, alumni, masyarakat — tanpa login | Lihat konten, filter, search, buka popup, akses link eksternal |
| Admin Prodi | Staf/mahasiswa dengan kemampuan Git dasar | Edit file data di GitHub → push → deploy otomatis |
### 2.4 Lingkungan Operasional
| Komponen | Spesifikasi |
|---|---|
| Platform | Browser modern: Chrome ≥v100, Firefox ≥v100, Edge ≥v100, Safari ≥v15 |
| Server/Hosting | Dedicated server Prodi Informatika UNTAN (Dev & Production) via Puify |
| Database | Tidak ada — data di file statis JSON/JS di repositori |
| Bahasa Pemrograman | HTML5, CSS3 + Tailwind CSS, JavaScript ES6+ |
| Version Control | Git / GitHub |
| Koneksi | Min 1 Mbps (dasar), 10 Mbps (optimal) |
### 2.5 Asumsi & Ketergantungan
**Asumsi:**
- Pengunjung menggunakan browser modern dengan JS ES6+ dan CSS3 aktif
- Data beasiswa sudah diverifikasi admin sebelum dipublikasikan
- Perangkat pengunjung mendukung akses WhatsApp (app atau web)
**Ketergantungan:**
- Dedicated server Prodi UNTAN harus aktif untuk availability 24 jam
- Update data bergantung pada keaktifan admin melakukan push secara berkala
- Fitur berita bergantung pada stabilitas API Website Informatika UNTAN
- CTA bergantung pada keaktifan nomor WhatsApp & akun Instagram kemahasiswaan
---
## 3. Kebutuhan Fungsional
### 3.1 Daftar Use Case
| UC ID | Nama Use Case | Aktor | Prioritas (MoSCoW) |
|---|---|---|---|
| UC-01 | Melihat Daftar Beasiswa | Pengunjung Umum | Must Have |
| UC-02 | Memfilter Beasiswa Berdasarkan Kategori | Pengunjung Umum | Must Have |
| UC-03 | Mencari Beasiswa | Pengunjung Umum | Must Have |
| UC-04 | Melihat Detail Beasiswa (Popup) | Pengunjung Umum | Must Have |
| UC-05 | Mengakses Sumber Informasi Beasiswa | Pengunjung Umum | Must Have |
| UC-06 | Menghubungi Admin via CTA | Pengunjung Umum | Must Have |
| UC-07 | Melihat Testimoni Penerima Beasiswa | Pengunjung Umum | Should Have |
| UC-08 | Mengganti Bahasa Tampilan (ID/EN) | Pengunjung Umum | Should Have |
| UC-09 | Memperbarui Data Beasiswa | Admin Prodi | Must Have |
### 3.2 Detail Use Case
#### UC-01: Melihat Daftar Beasiswa
| Field | Detail |
|---|---|
| Aktor | Pengunjung Umum |
| Precondition | Halaman berhasil dimuat di browser |
| Trigger | Pengunjung membuka URL atau scroll ke seksi Daftar Beasiswa |
| Main Flow | 1. Pengunjung buka URL halaman<br>2. Sistem tampilkan hero, statistik, daftar beasiswa<br>3. Kartu ditampilkan grid: 3 kolom desktop / 2 tablet / 1 mobile<br>4. Tiap kartu: thumbnail, badge status, nama, deskripsi singkat, tanggal, tombol "Selengkapnya"<br>5. Paginasi tampil di bawah grid jika beasiswa > 1 halaman |
| Alt Flow | 3a. Koneksi lambat → skeleton loading<br>3b. Tidak ada data → tampil "Belum ada beasiswa tersedia saat ini." |
| Postcondition | Pengunjung dapat melihat seluruh daftar beasiswa |
#### UC-02: Memfilter Beasiswa Berdasarkan Kategori
| Field | Detail |
|---|---|
| Aktor | Pengunjung Umum |
| Precondition | Halaman dimuat, daftar beasiswa tampil |
| Trigger | Pengunjung klik salah satu tab filter |
| Main Flow | 1. Tampil tab: Semua \| Sedang Buka \| Ditutup \| Pemerintah \| Swasta<br>2. Pengunjung klik tab<br>3. Sistem real-time filter beasiswa sesuai kategori<br>4. Tab aktif ditandai bold/underline/warna<br>5. Jumlah hasil diperbarui |
| Alt Flow | 3a. Tidak ada hasil → "Tidak ada beasiswa pada kategori ini."<br>3b. Klik "Semua" → tampil semua beasiswa |
| Postcondition | Daftar beasiswa sesuai filter yang dipilih |
#### UC-03: Mencari Beasiswa
| Field | Detail |
|---|---|
| Aktor | Pengunjung Umum |
| Precondition | Halaman dimuat, kolom pencarian tersedia |
| Trigger | Pengunjung mengetik di kolom pencarian |
| Main Flow | 1. Pengunjung klik kolom pencarian<br>2. Ketik kata kunci (misal: "Pertamina", "KIP", "luar negeri")<br>3. Sistem real-time filter kartu yang nama/deskripsinya cocok<br>4. Hapus kata kunci → kembali ke tampilan penuh<br>5. Filter dan pencarian dapat aktif bersamaan (kumulatif) |
| Alt Flow | 3a. Tidak ada hasil → "Tidak ditemukan beasiswa yang sesuai pencarian Anda." |
| Postcondition | Daftar beasiswa sesuai kata kunci |
#### UC-04: Melihat Detail Beasiswa (Popup)
| Field | Detail |
|---|---|
| Aktor | Pengunjung Umum |
| Precondition | Kartu beasiswa tampil, pengunjung menemukan beasiswa yang diinginkan |
| Trigger | Klik tombol "Selengkapnya →" pada kartu |
| Main Flow | 1. Klik "Selengkapnya →"<br>2. Sistem tampilkan modal popup berisi: nama + thumbnail, badge status, syarat umum ringkasan, kontak, tombol "Info Lebih Lanjut" (→ URL sumber resmi di tab baru)<br>3. Background di-overlay gelap<br>4. Tutup via: tombol ×, klik di luar area, atau tekan Escape |
| Alt Flow | 4a. Klik "Info Lebih Lanjut" → jalankan UC-05 |
| Postcondition | Pengunjung mendapat info ringkas dan dapat lanjut ke sumber resmi |
#### UC-05: Mengakses Sumber Informasi Beasiswa
| Field | Detail |
|---|---|
| Aktor | Pengunjung Umum |
| Precondition | Popup detail terbuka, tombol "Info Lebih Lanjut" tersedia |
| Trigger | Klik tombol "Info Lebih Lanjut" di popup |
| Main Flow | 1. Klik tombol<br>2. Sistem buka URL sumber resmi di tab baru<br>3. Popup di tab asal tetap terbuka |
| Alt Flow | 3a. URL tidak tersedia → "Tautan tidak tersedia. Silakan hubungi admin prodi." |
| Postcondition | Pengunjung diarahkan ke sumber resmi beasiswa |
#### UC-06: Menghubungi Admin via CTA
| Field | Detail |
|---|---|
| Aktor | Pengunjung Umum |
| Precondition | Pengunjung ingin info lebih lanjut |
| Trigger | Scroll ke seksi CTA, klik salah satu tombol |
| Main Flow | 1. Scroll ke CTA ("Ingin Tahu Lebih Banyak tentang Beasiswa?")<br>2. Tampil dua tombol: "Hubungi Admin" (WhatsApp) + "Instagram Beasiswa" (IG kemahasiswaan)<br>3. Klik tombol → buka platform di tab baru |
| Alt Flow | 4a. Tanpa WhatsApp terinstall → buka WhatsApp Web |
| Postcondition | Pengunjung terhubung dengan admin atau follow Instagram |
#### UC-07: Melihat Testimoni Penerima Beasiswa
| Field | Detail |
|---|---|
| Aktor | Pengunjung Umum |
| Precondition | Halaman dimuat, data testimoni tersedia di source code |
| Trigger | Scroll ke seksi Testimoni |
| Main Flow | 1. Scroll ke seksi Testimoni<br>2. Tampil kartu testimoni: foto, nama, nama beasiswa, kutipan singkat<br>3. Jika > 3 testimoni → navigasi carousel/tombol selanjutnya |
| Alt Flow | 2a. Belum ada data → seksi tidak ditampilkan atau tampil placeholder |
| Postcondition | Pengunjung mendapat gambaran pengalaman penerima beasiswa |
#### UC-08: Mengganti Bahasa Tampilan (ID/EN)
| Field | Detail |
|---|---|
| Aktor | Pengunjung Umum |
| Precondition | Toggle ID\|EN tersedia di header navigasi |
| Trigger | Klik toggle bahasa di pojok kanan header |
| Main Flow | 1. Pengunjung lihat toggle ID \| EN di kanan atas<br>2. Klik bahasa yang diinginkan<br>3. Seluruh teks berubah tanpa reload<br>4. Pilihan tersimpan di session (tidak reset saat scroll/filter) |
| Alt Flow | 3a. Konten hanya tersedia 1 bahasa → tetap tampil bahasa aslinya |
| Postcondition | Halaman tampil dalam bahasa yang dipilih |
#### UC-09: Memperbarui Data Beasiswa
| Field | Detail |
|---|---|
| Aktor | Admin Prodi |
| Precondition | Admin punya akses repo, ada info beasiswa baru/perubahan status |
| Trigger | Admin mendapat informasi update dari survei/portal/sumber lain |
| Main Flow | 1. Admin dapat info baru/perubahan status<br>2. Edit file data beasiswa (nama, kategori, status, syarat, kontak, URL)<br>3. Simpan dan push ke GitHub<br>4. Halaman publik auto-update dalam waktu singkat via Puify |
| Alt Flow | 3a. Error saat deploy → halaman publik tidak berubah, admin perbaiki dan push ulang |
| Postcondition | Info beasiswa terbaru tersedia di halaman publik 24/7 |
---
## 4. Kebutuhan Antarmuka Eksternal
### 4.1 Antarmuka Pengguna (UI)
- Responsive design: breakpoint 320px (mobile), 768px (tablet), 1280px (desktop)
- Warna utama: Biru Informatika `#2B4590` dan Kuning `#F5A623` (branding UNTAN)
- Font: Inter atau Poppins, minimal 14px untuk body text
- Waktu respons antarmuka ≤ 3 detik pada koneksi 10 Mbps
- Aksesibilitas WCAG 2.1 level AA (kontras warna, ARIA label, navigasi keyboard)
- Semua elemen interaktif memiliki feedback visual saat hover/klik
**Halaman / Seksi:**
| Seksi | ID | Konten Utama |
|---|---|---|
| Header & Navigasi | — | Navbar sticky, logo UNTAN, toggle ID/EN, info ticker |
| Hero | `#hero` | Judul "Beasiswa Studi & Penelitian", deskripsi, CTA kuning, foto mahasiswa |
| Statistik Counter | `#statistics` | 3 angka animasi: Total Penerima, Pemerintah, Swasta |
| Direktori Beasiswa | `#directory` | Grid kartu, tab filter, real-time search, popup detail |
| Testimoni | `#testimonial` | Carousel foto+nama+kutipan penerima beasiswa |
| CTA | `#cta` | Banner ajakan + tombol WhatsApp & Instagram |
| Footer | `#footer` | Logo, alamat, kontak, sosial media, ilustrasi Pontianak |
### 4.2 Antarmuka Hardware
- Browser modern: Chrome/Firefox/Edge ≥v100, Safari ≥v15
- Koneksi minimal 1 Mbps; optimal 10 Mbps
- Resolusi minimal 320px lebar
- Tidak butuh hardware khusus (kamera, printer, sensor, dll.)
### 4.3 Antarmuka Software
| Layanan | Tujuan | Protokol |
|---|---|---|
| Dedicated Server + Puify | Hosting dev & production, auto-deploy dari GitHub | HTTPS |
| GitHub | Version control, kolaborasi, deliverable akhir | HTTPS/SSH |
| Sumber Resmi Beasiswa | Link eksternal di popup (dibuka tab baru) | HTTPS |
| WhatsApp / Instagram UNTAN | Tombol CTA | HTTPS / wa.me |
| Figma | Desain mockup & wireframe acuan implementasi | HTTPS |
| Web Scraper | Ambil data beasiswa dari sumber resmi | HTTPS |
### 4.4 Antarmuka Komunikasi
- Semua file dikirim via HTTPS dengan sertifikat SSL/TLS valid
- Fitur interaktif (filter, search, toggle bahasa, popup, counter) berjalan client-side (JS) — tanpa request ke server
- Semua link eksternal: `target="_blank"` + `rel="noopener noreferrer"`
- Tidak menggunakan cookie, session storage, atau autentikasi pengguna (v1.0)
---
## 5. Kebutuhan Non-Fungsional
### NFR-01: Performa
- **P-01** Loading halaman ≤ 3 detik pada koneksi 10 Mbps
- **P-02** Filter beasiswa merespons < 0,5 detik setelah klik
- **P-03** Tetap responsif dan optimal di desktop, tablet, dan smartphone
### NFR-02: Keamanan
- **S-01** Semua komunikasi via HTTPS dengan SSL/TLS
- **S-02** Source code bersih dari script berbahaya, bebas celah XSS
- **S-03** Semua link CTA dan pendaftaran mengarah ke sumber resmi tervalidasi
### NFR-03: Skalabilitas
- **SC-01** Mampu menampilkan minimal 100 data beasiswa tanpa penurunan performa
- **SC-02** Struktur kode memungkinkan penambahan kategori baru tanpa perubahan besar
- **SC-03** Sistem bilingual mendukung penambahan bahasa baru di masa depan
### NFR-04: Ketersediaan & Reliabilitas
- **R-01** Uptime minimal 99% selama masa operasional
- **R-02** Dapat diakses 24 jam selama server aktif
- **R-03** Backup source code via Git/GitHub untuk pemulihan data
### NFR-05: Usability
- **U-01** Antarmuka bilingual ID/EN
- **U-02** Pengguna menemukan info beasiswa dalam < 2 menit via navigasi & filter
- **U-03** Tombol CTA di Hero kontras dan posisinya jelas
### NFR-06: Maintainability
- **M-01** Tech stack: HTML5, CSS3 + Tailwind CSS, JavaScript ES6+ — kode rapi dan mudah dipelihara
- **M-02** Semua perubahan dikelola via Git/GitHub (version control)
- **M-03** Dokumentasi teknis & panduan deployment disertakan saat penyerahan akhir
---
## 6. Batasan & Kendala
### 6.1 Batasan Implementasi
- Tech stack terkunci: HTML5, CSS3, Tailwind CSS, JavaScript ES6+, Figma, Git/GitHub
- Single static landing page — tidak ada backend, database, atau login
- Harus berjalan optimal di Chrome, Firefox, Edge versi terbaru
- Wajib responsif: desktop, tablet, smartphone
### 6.2 Batasan Proyek
- Durasi: 10 hari kerja (1 Mei 11 Mei 2026)
- Tim: 5 orang dengan peran tetap (PM, Backend, Frontend, UI/UX, QA)
- Revisi antarmuka/konten sesuai batas yang disepakati
- Penambahan fitur baru saat development = di luar ruang lingkup utama
### 6.3 Regulasi & Standar
- UU PDP No. 27/2022 untuk pengelolaan data testimoni mahasiswa
- Visual harus selaras branding resmi Informatika UNTAN
- Memenuhi prinsip aksesibilitas dasar (navigasi jelas, tampilan informatif)
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 848 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 755 KiB

+109
View File
@@ -0,0 +1,109 @@
// =====================================================
// carousel.js — Swiper.js Carousel Testimoni
// Touch-friendly, auto-play, responsive breakpoints
// =====================================================
let testimoniSwiper = null;
/** Render slide testimoni ke dalam swiper-wrapper */
function renderTestimoniSlides(data) {
const wrapper = document.getElementById('testimonial-wrapper');
if (!wrapper) return;
wrapper.innerHTML = data.map(t => `
<div class="swiper-slide" style="height:auto;">
<div class="testimonial-card">
<img
src="${t.foto}"
alt="Foto ${t.nama}"
class="testimonial-avatar"
loading="lazy"
onerror="
this.style.display='none';
this.nextElementSibling.style.display='flex';
"
>
<div
class="testimonial-avatar"
style="
display:none;
background:linear-gradient(135deg,#003150,#4a6bc5);
align-items:center;
justify-content:center;
color:white;
font-size:22px;
font-weight:700;
"
>
${t.nama.charAt(0).toUpperCase()}
</div>
<div class="testimonial-name">${t.nama}</div>
<div class="testimonial-beasiswa">${t.nama_beasiswa}</div>
<p class="testimonial-quote">"${t.kutipan}"</p>
</div>
</div>
`).join('');
}
/** Inisialisasi Swiper setelah slide di-render */
function initSwiper(count) {
if (testimoniSwiper) {
testimoniSwiper.destroy(true, true);
testimoniSwiper = null;
}
testimoniSwiper = new Swiper('.testimonial-swiper', {
slidesPerView: 1,
spaceBetween: 24,
loop: count > 3,
centerInsufficientSlides: true,
autoplay: {
delay: 4500,
disableOnInteraction: false,
pauseOnMouseEnter: true,
},
pagination: {
el: '.testimonial-pagination',
clickable: true,
},
grabCursor: true,
breakpoints: {
640: { slidesPerView: 2 },
1024: { slidesPerView: 3 },
},
a11y: {
prevSlideMessage: 'Slide sebelumnya',
nextSlideMessage: 'Slide berikutnya',
},
});
}
/** Fetch data testimoni dan render */
async function initCarousel() {
const section = document.getElementById('testimonial');
try {
const res = await fetch('data/testimoni.json');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
if (!data || data.length === 0) {
// Sembunyikan seksi testimoni jika data kosong (sesuai UC-07 Alt Flow)
section?.classList.add('hidden');
return;
}
renderTestimoniSlides(data);
// Init Swiper setelah DOM di-render
requestAnimationFrame(() => initSwiper(data.length));
} catch {
// Jika gagal fetch, sembunyikan seksi (graceful degradation)
section?.classList.add('hidden');
}
}
document.addEventListener('DOMContentLoaded', initCarousel);
+53
View File
@@ -0,0 +1,53 @@
// =====================================================
// counter.js — Animasi Counter Statistik
// Menggunakan IntersectionObserver + requestAnimationFrame
// =====================================================
/**
* Animasi angka dari 0 ke nilai target
* @param {HTMLElement} el - Elemen yang menampilkan angka
* @param {number} target - Angka target
* @param {number} duration - Durasi animasi dalam ms
*/
function animateCounter(el, target, duration = 1800) {
const startTime = performance.now();
function update(currentTime) {
const elapsed = currentTime - startTime;
const progress = Math.min(elapsed / duration, 1);
// Ease out cubic — percepat di awal, lambat di akhir
const eased = 1 - Math.pow(1 - progress, 3);
const current = Math.round(eased * target);
el.textContent = current;
if (progress < 1) {
requestAnimationFrame(update);
}
}
requestAnimationFrame(update);
}
function initCounters() {
const counters = document.querySelectorAll('[data-counter]');
if (!counters.length) return;
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting && !entry.target.dataset.animated) {
entry.target.dataset.animated = 'true';
const target = parseInt(entry.target.dataset.counter, 10) || 0;
animateCounter(entry.target, target);
}
});
},
{ threshold: 0.6 }
);
counters.forEach(el => observer.observe(el));
}
document.addEventListener('DOMContentLoaded', initCounters);
+242
View File
@@ -0,0 +1,242 @@
// =====================================================
// filter.js — Fetch JSON, Render Kartu, Filter Tab, Pencarian, Paginasi
// Filter dan search berjalan KUMULATIF (sesuai PROJECT_CONTEXT rule #6)
// =====================================================
const ITEMS_PER_PAGE = 6; // 2 baris × 3 kolom desktop
let allData = []; // Semua data beasiswa dari JSON
let activeFilter = 'semua';
let searchKeyword = '';
let currentPage = 1;
// Format tanggal
function formatDate(str) {
if (!str) return '—';
const d = new Date(str);
if (isNaN(d.getTime())) return str;
return d.toLocaleDateString('id-ID', {
day: 'numeric', month: 'long', year: 'numeric'
});
}
// Sanitasi string untuk mencegah XSS pada search
function sanitize(str) {
return str.replace(/[<>&"']/g, c =>
({ '<': '&lt;', '>': '&gt;', '&': '&amp;', '"': '&quot;', "'": '&#39;' }[c])
);
}
/**
* Buat elemen kartu beasiswa
* Gunakan textContent/setAttribute — hindari langsung innerHTML dari user input
*/
function createCard(bsw) {
const isBuka = bsw.status === 'Buka';
const article = document.createElement('article');
article.className = 'scholarship-card fade-in-up';
article.setAttribute('role', 'listitem');
article.setAttribute('data-id', bsw.id);
article.innerHTML = `
<div class="card-img-wrap">
<img
src="${bsw.thumbnail}"
alt="${bsw.nama}"
class="card-img"
loading="lazy"
onerror="this.style.display='none';this.parentElement.style.background='#eef2ff';this.parentElement.innerHTML+='<i class=\\'fas fa-graduation-cap\\' style=\\'font-size:40px;color:#c7d2fe;\\'></i>'"
>
</div>
<div class="card-body">
<span class="badge-status ${isBuka ? 'badge-buka' : 'badge-ditutup'}">
${bsw.status}
</span>
<h3 class="card-title">${bsw.nama}</h3>
<p class="card-desc">${bsw.deskripsi_singkat}</p>
<div class="card-date">
<i class="fas fa-calendar-alt"></i>
<span>${formatDate(bsw.tanggal_tutup)}</span>
</div>
</div>
<div class="card-footer">
<button
class="btn-selengkapnya"
onclick="openPopup('${bsw.id}')"
aria-label="Lihat detail beasiswa ${bsw.nama}"
>
Selengkapnya <i class="fas fa-arrow-right" style="font-size:10px;"></i>
</button>
</div>
`;
return article;
}
/**
* Filter data KUMULATIF: filter tab DAN search harus terpenuhi keduanya
*/
function getFiltered() {
const kw = searchKeyword.toLowerCase();
return allData.filter(bsw => {
// Cocok dengan filter tab
const matchFilter =
activeFilter === 'semua' ||
bsw.status === activeFilter ||
bsw.kategori === activeFilter;
// Cocok dengan pencarian (nama atau deskripsi atau tags)
const matchSearch =
!kw ||
bsw.nama.toLowerCase().includes(kw) ||
bsw.deskripsi_singkat.toLowerCase().includes(kw) ||
(bsw.tags || []).some(t => t.toLowerCase().includes(kw));
return matchFilter && matchSearch;
});
}
/** Render kartu + paginasi ke DOM */
function renderCards() {
const grid = document.getElementById('beasiswa-grid');
const pagCont = document.getElementById('pagination');
const filtered = getFiltered();
// Bersihkan grid
grid.innerHTML = '';
if (filtered.length === 0) {
grid.innerHTML = `
<div class="empty-state" style="grid-column:1/-1">
<i class="fas fa-search-minus"></i>
<p style="font-size:15px;font-weight:700;color:#94a3b8;margin-bottom:6px;">
Tidak ada beasiswa ditemukan
</p>
<p style="font-size:13px;color:#cbd5e1;">
Coba ubah filter atau kata kunci pencarian Anda
</p>
</div>`;
pagCont.innerHTML = '';
return;
}
// Hitung paginasi
const totalPages = Math.ceil(filtered.length / ITEMS_PER_PAGE);
if (currentPage > totalPages) currentPage = totalPages;
const start = (currentPage - 1) * ITEMS_PER_PAGE;
const items = filtered.slice(start, start + ITEMS_PER_PAGE);
// Render kartu dengan delay animasi berurutan
items.forEach((bsw, i) => {
const card = createCard(bsw);
card.style.animationDelay = `${i * 55}ms`;
grid.appendChild(card);
});
renderPagination(totalPages, pagCont);
}
/** Render tombol-tombol paginasi */
function renderPagination(total, container) {
container.innerHTML = '';
if (total <= 1) return;
const make = (content, page, disabled = false, isActive = false) => {
const btn = document.createElement('button');
btn.className = `page-btn${isActive ? ' active' : ''}`;
btn.innerHTML = content;
btn.disabled = disabled;
btn.setAttribute('aria-label', typeof page === 'number' ? `Halaman ${page}` : content);
if (!disabled) {
btn.addEventListener('click', () => {
currentPage = page;
renderCards();
// Scroll halus ke atas direktori
const dir = document.getElementById('directory');
if (dir) {
const top = dir.getBoundingClientRect().top + window.scrollY - 120;
window.scrollTo({ top, behavior: 'smooth' });
}
});
}
return btn;
};
// Prev
container.appendChild(make('<i class="fas fa-chevron-left" style="font-size:11px;"></i>', currentPage - 1, currentPage === 1));
// Halaman
for (let i = 1; i <= total; i++) {
container.appendChild(make(i, i, false, i === currentPage));
}
// Next
container.appendChild(make('<i class="fas fa-chevron-right" style="font-size:11px;"></i>', currentPage + 1, currentPage === total));
}
/** Inisialisasi tab filter */
function initFilterTabs() {
document.querySelectorAll('.filter-tab').forEach(btn => {
btn.addEventListener('click', () => {
document.querySelectorAll('.filter-tab').forEach(b => {
b.classList.remove('active');
b.setAttribute('aria-selected', 'false');
});
btn.classList.add('active');
btn.setAttribute('aria-selected', 'true');
activeFilter = btn.dataset.filter;
currentPage = 1;
renderCards();
});
});
}
/** Inisialisasi real-time search */
function initSearch() {
const input = document.getElementById('search-input');
if (!input) return;
input.addEventListener('input', () => {
// Sanitasi input sebelum digunakan (cegah XSS)
searchKeyword = sanitize(input.value).trim();
currentPage = 1;
renderCards();
});
}
/** Fetch data JSON dan render */
async function initDirectory() {
const grid = document.getElementById('beasiswa-grid');
try {
const res = await fetch('data/beasiswa.json');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
allData = await res.json();
// Simpan ke window agar popup.js bisa akses
window.beasiswaData = allData;
renderCards();
} catch (err) {
grid.innerHTML = `
<div class="empty-state" style="grid-column:1/-1">
<i class="fas fa-exclamation-triangle" style="color:#fca5a5;"></i>
<p style="font-size:15px;font-weight:700;color:#94a3b8;margin-bottom:6px;">
Gagal memuat data beasiswa
</p>
<p style="font-size:13px;color:#cbd5e1;">
Pastikan menggunakan live server. Silakan refresh atau hubungi admin.
</p>
</div>`;
}
}
document.addEventListener('DOMContentLoaded', () => {
initFilterTabs();
initSearch();
initDirectory();
});
+128
View File
@@ -0,0 +1,128 @@
// =====================================================
// i18n.js — Toggle Bahasa Indonesia / English
// Sesuai PROJECT_CONTEXT: tersimpan di sessionStorage
// =====================================================
const i18nData = {
id: {
'nav.tentang': 'TENTANG KAMI',
'nav.program': 'PROGRAM',
'nav.sdm': 'SDM',
'nav.fasilitas': 'FASILITAS',
'nav.agenda': 'KARYA & AGENDA',
'nav.kontak': 'KONTAK',
'breadcrumb.home': 'Beranda',
'breadcrumb.profile': 'Profil',
'breadcrumb.scholarship': 'Beasiswa',
'hero.badge': 'Program Beasiswa',
'hero.title': 'Beasiswa Studi &<br>Penelitian',
'hero.subtitle': 'Teknik Informatika Universitas Tanjungpura',
'hero.desc': 'Temukan berbagai peluang beasiswa untuk mendukung perjalanan akademik dan penelitian Anda. Program Studi Informatika UNTAN berkomitmen membantu mahasiswa meraih prestasi terbaik.',
'hero.cta': 'Lihat Daftar Beasiswa',
'stats.total': 'Total Mahasiswa Penerima<br>Beasiswa Semester Ini',
'stats.gov': 'Total Penerima Beasiswa<br>Pembiayaan Pemerintah',
'stats.private': 'Total Penerima Beasiswa<br>Pembiayaan Swasta',
'dir.label': 'Daftar Beasiswa',
'dir.title': 'Daftar Beasiswa',
'dir.desc': 'Temukan beragam beasiswa dari berbagai sumber resmi yang tersedia untuk mahasiswa aktif, alumni, dan calon mahasiswa Program Studi Informatika UNTAN.',
'dir.receive': 'Terima Bantuan Beasiswa?',
'filter.all': 'SEMUA',
'filter.open': 'Sedang Buka',
'filter.closed': 'Ditutup',
'filter.gov': 'Pemerintah',
'filter.private': 'Swasta',
'search.placeholder': 'Cari Nama Beasiswa...',
'testimonial.title': 'Apa Kata Mereka?',
'testimonial.desc': 'Cerita inspiratif dari para penerima beasiswa Program Studi Informatika UNTAN',
'cta.title': 'Ingin Mengetahui Info Lebih Lanjut?',
'cta.desc': 'Hubungi admin prodi atau ikuti Instagram kemahasiswaan UNTAN untuk informasi terbaru tentang beasiswa dan program akademik.',
'cta.btn1': 'DAFTAR BEASISWA',
'cta.btn2': 'Hubungi Kami',
'ticker': 'Pendaftaran Beasiswa KIP Kuliah 2026 telah dibuka! &nbsp;—&nbsp; Beasiswa Pertamina Foundation open hingga Agustus 2026 &nbsp;—&nbsp; Daftarkan diri Anda sekarang! &nbsp;—&nbsp; Info lengkap tersedia di halaman direktori beasiswa &nbsp;—&nbsp; Beasiswa LPDP S2 masih tersedia hingga September 2026 &nbsp;—&nbsp;',
},
en: {
'nav.tentang': 'ABOUT US',
'nav.program': 'PROGRAMS',
'nav.sdm': 'HUMAN RESOURCES',
'nav.fasilitas': 'FACILITIES',
'nav.agenda': 'WORKS & EVENTS',
'nav.kontak': 'CONTACT',
'breadcrumb.home': 'Home',
'breadcrumb.profile': 'Profile',
'breadcrumb.scholarship': 'Scholarship',
'hero.badge': 'Scholarship Program',
'hero.title': 'Study & Research<br>Scholarships',
'hero.subtitle': 'Informatics Engineering, Tanjungpura University',
'hero.desc': 'Discover various scholarship opportunities to support your academic and research journey. The Informatics Study Program at UNTAN is committed to helping students achieve excellence.',
'hero.cta': 'View Scholarships',
'stats.total': 'Total Scholarship<br>Recipients This Semester',
'stats.gov': 'Total Government<br>Scholarship Recipients',
'stats.private': 'Total Private<br>Scholarship Recipients',
'dir.label': 'Scholarship Directory',
'dir.title': 'Scholarship Directory',
'dir.desc': 'Find various scholarships from official sources available for active students, alumni, and prospective students of the UNTAN Informatics Study Program.',
'dir.receive': 'Need Scholarship Aid?',
'filter.all': 'ALL',
'filter.open': 'Open',
'filter.closed': 'Closed',
'filter.gov': 'Government',
'filter.private': 'Private',
'search.placeholder': 'Search Scholarship Name...',
'testimonial.title': 'What They Say?',
'testimonial.desc': 'Inspiring stories from scholarship recipients at UNTAN Informatics Study Program',
'cta.title': 'Want to Know More?',
'cta.desc': 'Contact the program admin or follow UNTAN student affairs Instagram for the latest scholarship and academic program information.',
'cta.btn1': 'SCHOLARSHIP LIST',
'cta.btn2': 'Contact Us',
'ticker': 'KIP Kuliah Scholarship 2026 registration is now open! &nbsp;—&nbsp; Pertamina Foundation Scholarship open until August 2026 &nbsp;—&nbsp; Register now! &nbsp;—&nbsp; Full info available in the scholarship directory &nbsp;—&nbsp; LPDP S2 Scholarship available until September 2026 &nbsp;—&nbsp;',
}
};
// Load saved language from session storage
let currentLang = sessionStorage.getItem('lang') || 'id';
function applyTranslations(lang) {
const t = i18nData[lang];
if (!t) return;
// Apply data-i18n attributes
document.querySelectorAll('[data-i18n]').forEach(el => {
const key = el.getAttribute('data-i18n');
if (t[key] !== undefined) {
el.innerHTML = t[key];
}
});
// Apply data-i18n-placeholder attributes
document.querySelectorAll('[data-i18n-placeholder]').forEach(el => {
const key = el.getAttribute('data-i18n-placeholder');
if (t[key] !== undefined) {
el.placeholder = t[key];
}
});
// Update HTML lang attribute
document.documentElement.lang = lang === 'id' ? 'id' : 'en';
}
function setLanguage(lang) {
if (lang !== 'id' && lang !== 'en') return;
currentLang = lang;
sessionStorage.setItem('lang', lang);
// Update button visual states
document.querySelectorAll('.lang-btn').forEach(btn => {
const isActive = btn.dataset.lang === lang;
btn.classList.toggle('active', isActive);
});
applyTranslations(lang);
}
// Expose globally so onclick in HTML works
window.setLanguage = setLanguage;
// Initialize on DOM ready
document.addEventListener('DOMContentLoaded', () => {
setLanguage(currentLang);
});
+177
View File
@@ -0,0 +1,177 @@
// =====================================================
// main.js — Inisialisasi Utama
// Sticky Navbar, Hamburger Menu, Smooth Scroll, AOS, Active Nav
// =====================================================
document.addEventListener('DOMContentLoaded', () => {
// ─── AOS (Animate on Scroll) ────────────────────────
AOS.init({
duration: 700,
easing: 'ease-out-cubic',
once: true,
offset: 50,
});
// ─── Sticky Navbar ──────────────────────────────────
// Navbar sudah fixed di CSS; tidak perlu mengubah warna karena
// warna primary sudah menjadi identitas halaman ini.
// Namun kita tambahkan shadow saat scroll untuk depth effect.
const navbar = document.getElementById('navbar');
const handleScroll = () => {
if (window.scrollY > 10) {
navbar.style.boxShadow = '0 4px 20px rgba(0,0,0,0.25)';
} else {
navbar.style.boxShadow = 'none';
}
};
window.addEventListener('scroll', handleScroll, { passive: true });
handleScroll(); // initial call
// ─── Ticker Visibility (Muncul setelah Hero & Stats) ─
const ticker = document.querySelector('.ticker-wrapper');
const statsSection = document.getElementById('statistics');
const handleTickerVisibility = () => {
if (!ticker || !statsSection) return;
// Ticker muncul setelah melewati batas bawah elemen statistik
const statsBottom = statsSection.offsetTop + statsSection.offsetHeight;
if (window.scrollY > statsBottom) {
ticker.classList.add('show-ticker');
} else {
ticker.classList.remove('show-ticker');
}
};
window.addEventListener('scroll', handleTickerVisibility, { passive: true });
// Call once on load with a slight delay to ensure layout is ready
setTimeout(handleTickerVisibility, 100);
// ─── Hamburger Menu (Mobile) ─────────────────────────
const hamburger = document.getElementById('hamburger');
const mobileMenu = document.getElementById('mobile-menu');
hamburger?.addEventListener('click', () => {
const isOpen = !mobileMenu.classList.contains('hidden');
mobileMenu.classList.toggle('hidden');
// Toggle icon
const icon = hamburger.querySelector('i');
if (isOpen) {
icon.className = 'fas fa-bars text-lg';
} else {
icon.className = 'fas fa-times text-lg';
}
// Aksesibilitas
hamburger.setAttribute('aria-expanded', String(!isOpen));
});
// ─── Smooth Scroll untuk anchor links ──────────────
// Sesuai SDD: CSS scroll-behavior + JS fallback dengan offset
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
anchor.addEventListener('click', e => {
const href = anchor.getAttribute('href');
const target = document.querySelector(href);
if (!target) return;
e.preventDefault();
const navHeight = navbar.offsetHeight || 110;
const top = target.getBoundingClientRect().top + window.scrollY - navHeight - 4;
window.scrollTo({ top, behavior: 'smooth' });
// Tutup mobile menu jika sedang terbuka
mobileMenu?.classList.add('hidden');
const icon = hamburger?.querySelector('i');
if (icon) icon.className = 'fas fa-bars text-lg';
});
});
// ─── Active Nav Link via IntersectionObserver ──────
// Sesuai SDD fitur #4: highlight menu sesuai seksi yang terlihat
const sections = document.querySelectorAll('section[id]');
const navLinks = document.querySelectorAll('a.nav-link');
const sectionObserver = new IntersectionObserver(
entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${entry.target.id}`) {
link.classList.add('active');
}
});
}
});
},
{ rootMargin: '-30% 0px -65% 0px' }
);
sections.forEach(s => sectionObserver.observe(s));
// ─── Back to Top visibility ────────────────────────
const backToTop = document.getElementById('back-to-top');
if (backToTop) {
window.addEventListener('scroll', () => {
if (window.scrollY > 400) {
backToTop.classList.remove('opacity-0', 'pointer-events-none');
backToTop.classList.add('opacity-100');
} else {
backToTop.classList.add('opacity-0', 'pointer-events-none');
backToTop.classList.remove('opacity-100');
}
}, { passive: true });
backToTop.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
}
// ─── Contact Us Modal (Hubungi Kami) ────────────────
const btnOpenContact = document.getElementById('btn-open-contact');
const contactOverlay = document.getElementById('contact-overlay');
const contactModal = document.getElementById('contact-modal');
const contactClose = document.getElementById('contact-close');
const contactBackdrop = document.getElementById('contact-backdrop');
const openContactModal = () => {
if (!contactOverlay) return;
contactOverlay.classList.remove('hidden');
contactOverlay.classList.add('flex');
// Animasi muncul
setTimeout(() => {
contactOverlay.classList.remove('opacity-0');
contactModal.classList.remove('scale-95');
contactModal.classList.add('scale-100');
}, 10);
};
const closeContactModal = () => {
if (!contactOverlay) return;
contactOverlay.classList.add('opacity-0');
contactModal.classList.remove('scale-100');
contactModal.classList.add('scale-95');
// Tunggu animasi selesai baru di-hide
setTimeout(() => {
contactOverlay.classList.remove('flex');
contactOverlay.classList.add('hidden');
}, 300);
};
if (btnOpenContact) btnOpenContact.addEventListener('click', openContactModal);
if (contactClose) contactClose.addEventListener('click', closeContactModal);
if (contactBackdrop) contactBackdrop.addEventListener('click', closeContactModal);
}); // end DOMContentLoaded
+158
View File
@@ -0,0 +1,158 @@
// =====================================================
// popup.js — Modal Detail Beasiswa
// Tutup via: tombol ×, klik overlay, tekan Escape
// =====================================================
const overlay = document.getElementById('popup-overlay');
const modal = document.getElementById('popup-modal');
const closeBtn = document.getElementById('popup-close');
const popupBody = document.getElementById('popup-content');
// Format tanggal ke format Indonesia
function fmtDate(str) {
if (!str) return '—';
const d = new Date(str);
if (isNaN(d.getTime())) return str;
return d.toLocaleDateString('id-ID', {
day: 'numeric',
month: 'long',
year: 'numeric'
});
}
/**
* Buka popup modal untuk beasiswa dengan ID tertentu
* Data diambil dari window.beasiswaData yang diset oleh filter.js
*/
function openPopup(id) {
const data = window.beasiswaData || [];
const bsw = data.find(b => b.id === id);
if (!bsw) return;
const isBuka = bsw.status === 'Buka';
const badgeClass = isBuka ? 'badge-buka' : 'badge-ditutup';
// Bangun list syarat umum
const syaratItems = (bsw.syarat_umum || [])
.map(s => `
<li>
<i class="fas fa-check-circle"></i>
<span>${s}</span>
</li>`)
.join('');
const syaratHTML = syaratItems
? `<ul class="syarat-list">${syaratItems}</ul>`
: `<p style="font-size:13px;color:#94a3b8;font-style:italic;">
Syarat belum tersedia. Kunjungi sumber resmi.
</p>`;
const hasUrl = bsw.url_sumber && bsw.url_sumber !== '#';
// Render konten popup
popupBody.innerHTML = `
<!-- Thumbnail / Hero gambar -->
<img
src="${bsw.thumbnail || ''}"
alt="${bsw.nama}"
class="popup-hero"
onerror="this.style.display='none'"
>
<div class="popup-body">
<!-- Badge status + kategori -->
<div class="popup-kategori-row">
<span class="badge-status ${badgeClass}">${bsw.status}</span>
<span class="popup-kategori">${bsw.kategori}</span>
</div>
<!-- Judul -->
<h2 id="popup-title" class="popup-title">${bsw.nama}</h2>
<!-- Deskripsi singkat -->
<p class="popup-desc">${bsw.deskripsi_singkat}</p>
<!-- Syarat Umum -->
<div class="popup-section-title">
<i class="fas fa-list-check"></i>
Syarat Umum
</div>
${syaratHTML}
<!-- Periode Pendaftaran -->
<div class="popup-periode">
<div class="popup-periode-item">
<label>Tanggal Buka</label>
<span>${fmtDate(bsw.tanggal_buka)}</span>
</div>
<div class="popup-periode-item">
<label>Tanggal Tutup</label>
<span style="${!isBuka ? 'color:#EF4444;' : ''}">${fmtDate(bsw.tanggal_tutup)}</span>
</div>
</div>
<!-- Kontak -->
${bsw.kontak ? `
<div class="popup-kontak">
<i class="fas fa-phone-alt"></i>
<div>
<div style="font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:.5px;margin-bottom:2px;">Kontak</div>
${bsw.kontak}
</div>
</div>` : ''}
<!-- Tombol Info Lebih Lanjut (UC-05) -->
${hasUrl
? `<a
href="${bsw.url_sumber}"
target="_blank"
rel="noopener noreferrer"
class="popup-cta"
aria-label="Info lebih lanjut tentang ${bsw.nama}"
>
Info Lebih Lanjut
<i class="fas fa-external-link-alt" style="font-size:12px;"></i>
</a>`
: `<button class="popup-cta disabled" disabled aria-disabled="true">
Info Lebih Lanjut
<i class="fas fa-external-link-alt" style="font-size:12px;"></i>
</button>
<p style="text-align:center;font-size:11px;color:#94a3b8;margin-top:8px;">
Tautan tidak tersedia. Silakan hubungi admin prodi.
</p>`
}
</div>
`;
// Tampilkan overlay
overlay.classList.add('show');
document.body.style.overflow = 'hidden';
// Set focus ke modal untuk aksesibilitas
setTimeout(() => modal.focus(), 50);
}
/** Tutup popup modal */
function closePopup() {
overlay.classList.remove('show');
document.body.style.overflow = '';
}
// === Event Listeners untuk menutup popup ===
// 1. Tombol × close
closeBtn?.addEventListener('click', closePopup);
// 2. Klik di luar area modal (backdrop)
document.getElementById('popup-backdrop')?.addEventListener('click', closePopup);
// 3. Tekan Escape
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && overlay.classList.contains('show')) {
closePopup();
}
});
// Expose ke global (dipanggil dari onclick di kartu)
window.openPopup = openPopup;
window.closePopup = closePopup;
+198
View File
@@ -0,0 +1,198 @@
[
{
"id": "bsw-001",
"nama": "Boustany Foundation Scholarship, MBA - Harvard University",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1541339907198-e08756dedf3f?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa bergengsi dari Boustany Foundation untuk program MBA di Harvard University, Amerika Serikat, bagi calon pemimpin bisnis dunia.",
"syarat_umum": [
"Diterima atau mendaftar di program MBA Harvard Business School",
"Memiliki rekam jejak prestasi akademik dan profesional yang luar biasa",
"Menunjukkan potensi kepemimpinan dan kontribusi internasional",
"Melengkapi aplikasi beasiswa secara online melalui situs resmi Boustany Foundation"
],
"kontak": "Boustany Foundation — boustany-foundation.com",
"tanggal_buka": "2026-05-21",
"tanggal_tutup": "2027-05-31",
"url_sumber": "https://www.schoters.com/id/beasiswa/boustany-foundation-scholarship-mba-harvard-university-1",
"tags": ["S2", "Swasta", "Amerika Serikat", "Partially Funded", "MBA"]
},
{
"id": "bsw-002",
"nama": "La Trobe University - La Trobe High Achiever Scholarship (S1)",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1523240795612-9a054b0db644?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa dari La Trobe University Australia untuk mahasiswa internasional jenjang S1 berprestasi tinggi yang ingin melanjutkan studi di Melbourne.",
"syarat_umum": [
"Mendaftar sebagai mahasiswa internasional jenjang S1 (Undergraduate) di La Trobe University",
"Memiliki nilai akademik yang sangat baik (High Achiever)",
"Tidak sedang menerima beasiswa penuh lainnya dari La Trobe University",
"Memenuhi persyaratan masuk dan kemampuan bahasa Inggris La Trobe University"
],
"kontak": "La Trobe University Admissions — latrobe.edu.au",
"tanggal_buka": "2023-09-29",
"tanggal_tutup": "2026-12-31",
"url_sumber": "https://www.schoters.com/id/beasiswa/la-trobe-university-la-trobe-high-achiever-scholarship-2",
"tags": ["S1", "Swasta", "Australia", "Partially Funded"]
},
{
"id": "bsw-003",
"nama": "Charles Sturt University - International Student Support Scholarship",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1560472354-b33ff0c44a43?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa dukungan dari Charles Sturt University bagi mahasiswa internasional jenjang S1 yang mendaftar di kampus yang berlokasi di New South Wales, Australia.",
"syarat_umum": [
"Mendaftar sebagai mahasiswa internasional penuh waktu (full-time) jenjang S1",
"Memenuhi persyaratan penerimaan akademik Charles Sturt University",
"Memiliki kemampuan Bahasa Inggris yang memadai (IELTS/TOEFL)",
"Mendaftar melalui jalur penerimaan internasional resmi"
],
"kontak": "Charles Sturt University International — csu.edu.au",
"tanggal_buka": "2026-05-21",
"tanggal_tutup": "2026-12-31",
"url_sumber": "https://www.schoters.com/id/beasiswa/charles-sturt-university-international-student-support-scholarship-3",
"tags": ["S1", "Swasta", "Australia", "Partially Funded"]
},
{
"id": "bsw-004",
"nama": "La Trobe University - La Trobe High Achiever Scholarship (S2)",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1529156069898-49953e39b3ac?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa dari La Trobe University Australia untuk mahasiswa internasional jenjang S2 (Postgraduate) dengan pencapaian akademik tinggi.",
"syarat_umum": [
"Mendaftar sebagai mahasiswa internasional jenjang S2 di La Trobe University",
"Memiliki nilai akademik yang sangat baik di jenjang sarjana sebelumnya",
"Memenuhi persyaratan bahasa Inggris yang ditetapkan",
"Tidak sedang menerima beasiswa lain dari universitas yang sama"
],
"kontak": "La Trobe University Admissions — latrobe.edu.au",
"tanggal_buka": "2023-09-29",
"tanggal_tutup": "2026-12-31",
"url_sumber": "https://www.schoters.com/id/beasiswa/la-trobe-university-la-trobe-high-achiever-scholarship-4",
"tags": ["S2", "Swasta", "Australia", "Partially Funded"]
},
{
"id": "bsw-005",
"nama": "ETH Zurich - Excellence Scholarship & Opportunity Programme (ESOP)",
"kategori": "Pemerintah",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1497366754035-f200968a6e72?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa bergengsi dari ETH Zurich (salah satu universitas teknik terbaik dunia) untuk mahasiswa S2 internasional yang unggul secara akademik.",
"syarat_umum": [
"Mendaftar program Master (S2) di ETH Zurich",
"Lulus ujian penerimaan ETH Zurich atau memiliki setara gelar sarjana yang diakui",
"Menunjukkan prestasi akademik luar biasa (biasanya masuk 10% terbaik angkatan)",
"Melengkapi formulir aplikasi beasiswa ESOP yang terpisah dari aplikasi studi",
"Mendapatkan surat rekomendasi dari akademisi berwenang"
],
"kontak": "ETH Zurich Scholarship Office — ethz.ch",
"tanggal_buka": "2026-11-01",
"tanggal_tutup": "2026-11-30",
"url_sumber": "https://www.schoters.com/id/beasiswa/eth-zurich-excellence-scholarship-opportunity-programme-esop-5",
"tags": ["S2", "Pemerintah", "Swiss", "Fully Funded", "Prestasi"]
},
{
"id": "bsw-006",
"nama": "STUST - Scholarship for International Students (S3, Fully Funded)",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1580582932707-520aed937b7b?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa penuh (fully funded) dari Southern Taiwan University of Science and Technology untuk mahasiswa internasional jenjang S3 (Doktoral).",
"syarat_umum": [
"Mendaftar program Doktoral (S3) di STUST, Taiwan",
"Memiliki gelar magister (S2) yang diakui",
"Memenuhi persyaratan kemampuan bahasa Inggris atau Mandarin",
"Menyerahkan proposal penelitian yang relevan dengan bidang studi yang dipilih",
"Mendapatkan persetujuan dari calon pembimbing (supervisor) di STUST"
],
"kontak": "STUST International Affairs Office — stust.edu.tw",
"tanggal_buka": "2026-09-15",
"tanggal_tutup": "2026-11-30",
"url_sumber": "https://www.schoters.com/id/beasiswa/southern-taiwan-university-of-science-and-technology-the-stust-scholarship-for-international-students-6",
"tags": ["S3", "Swasta", "Taiwan", "Fully Funded"]
},
{
"id": "bsw-007",
"nama": "STUST - Scholarship for International Students (S2, Partially Funded)",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1606761568499-6d2451b23c66?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa parsial (partially funded) dari Southern Taiwan University of Science and Technology untuk mahasiswa internasional jenjang S2 (Magister).",
"syarat_umum": [
"Mendaftar program Magister (S2) di STUST, Taiwan",
"Memiliki gelar sarjana (S1) yang diakui",
"Memenuhi persyaratan kemampuan bahasa Inggris atau Mandarin",
"Melengkapi berkas aplikasi secara online melalui portal resmi STUST",
"Menyertakan transkrip nilai dan surat motivasi"
],
"kontak": "STUST International Affairs Office — stust.edu.tw",
"tanggal_buka": "2026-09-15",
"tanggal_tutup": "2026-11-30",
"url_sumber": "https://www.schoters.com/id/beasiswa/southern-taiwan-university-of-science-and-technology-the-stust-scholarship-for-international-students-7",
"tags": ["S2", "Swasta", "Taiwan", "Partially Funded"]
},
{
"id": "bsw-008",
"nama": "University of Melbourne - Melbourne International Undergraduate Scholarship",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1504711434969-e33886168f5c?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa untuk mahasiswa internasional berprestasi yang mendaftar program S1 di University of Melbourne, salah satu universitas terbaik di Australia.",
"syarat_umum": [
"Merupakan mahasiswa internasional (bukan warga negara Australia atau New Zealand)",
"Mendaftar program sarjana (S1 / Undergraduate) di University of Melbourne",
"Memiliki hasil akademik yang sangat luar biasa di tingkat sekolah menengah atas",
"Memenuhi persyaratan kemampuan bahasa Inggris (IELTS minimal 6.5)",
"Beasiswa diberikan otomatis berdasarkan nilai akademik, tidak perlu aplikasi terpisah"
],
"kontak": "University of Melbourne Future Students — unimelb.edu.au",
"tanggal_buka": "2026-05-21",
"tanggal_tutup": "2026-10-31",
"url_sumber": "https://www.schoters.com/id/beasiswa/university-of-melbourne-melbourne-international-undergraduate-scholarship-8",
"tags": ["S1", "Swasta", "Australia", "Partially Funded", "Prestasi"]
},
{
"id": "bsw-009",
"nama": "Charles Darwin University - CDU Global Merit Scholarship",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1434030216411-0b793f4b4173?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa merit global dari Charles Darwin University (CDU) di Darwin, Australia, untuk mahasiswa internasional S1 yang memiliki rekam jejak akademik yang kuat.",
"syarat_umum": [
"Mendaftar sebagai mahasiswa internasional baru (new international student) di CDU",
"Mendaftar untuk program sarjana (Undergraduate/S1) penuh waktu",
"Memiliki nilai ujian akhir sekolah yang baik (dikonversi ke skala CDU)",
"Memenuhi persyaratan bahasa Inggris (IELTS 6.0 atau setara)",
"Tidak sedang menerima potongan biaya kuliah lainnya dari CDU"
],
"kontak": "CDU International — cdu.edu.au",
"tanggal_buka": "2026-05-21",
"tanggal_tutup": "2026-10-09",
"url_sumber": "https://www.schoters.com/id/beasiswa/charles-darwin-university-cdu-global-merit-scholarship-9",
"tags": ["S1", "Swasta", "Australia", "Partially Funded"]
},
{
"id": "bsw-010",
"nama": "Deakin University - Vice-Chancellor's International Scholarship",
"kategori": "Swasta",
"status": "Buka",
"thumbnail": "https://images.unsplash.com/photo-1541339907198-e08756dedf3f?w=400&q=80&auto=format&fit=crop",
"deskripsi_singkat": "Beasiswa bergengsi dari Wakil Rektor (Vice-Chancellor) Deakin University untuk mahasiswa internasional terbaik yang akan menempuh studi S1 atau S2 di Australia.",
"syarat_umum": [
"Merupakan mahasiswa internasional (bukan warga negara Australia/New Zealand)",
"Mendaftar untuk program S1 (Undergraduate) atau S2 (Postgraduate Coursework) di Deakin",
"Memiliki rekam jejak akademik yang sangat baik dan konsisten",
"Memenuhi persyaratan masuk dan kemampuan bahasa Inggris Deakin University",
"Mengajukan aplikasi beasiswa sebelum tanggal penutupan yang ditetapkan"
],
"kontak": "Deakin University International — deakin.edu.au",
"tanggal_buka": "2026-05-21",
"tanggal_tutup": "2026-09-25",
"url_sumber": "https://www.schoters.com/id/beasiswa/deakin-university-vice-chancellor-s-international-scholarship-10",
"tags": ["S1", "S2", "Swasta", "Australia", "Partially Funded", "Prestasi"]
}
]
+9
View File
@@ -0,0 +1,9 @@
[
{
"id": "tsm-001",
"nama": "Violaine Gunawan",
"foto": "https://ui-avatars.com/api/?name=Violaine+Gunawan&background=111a2f&color=fff&size=200&rounded=true",
"nama_beasiswa": "Beasiswa Bakti BCA 2026",
"kutipan": "Beasiswa ini sangat berdampak besar. Tantangannya menyeimbangkan kuliah, asisten praktikum, organisasi, dan projek besar beasiswa. Namun, relasi di kampus dan masyarakat jadi bertambah luas. Tips: Jangan takut mencoba, pahami fokus beasiswa, sesuaikan visi misi, dan aktiflah berorganisasi!"
}
]
File diff suppressed because it is too large Load Diff
+200
View File
@@ -0,0 +1,200 @@
{
"source": "https://www.schoters.com/id/beasiswa",
"title": "Kalender Beasiswa - Schoters",
"description": "Kalender dan informasi beasiswa terlengkap dari semua jenjang S1, S2, & S3 di setiap negara dan kampus impian beserta persyaratan dan proses pendaftarannya",
"filters": {
"jenjang": [
{ "level": "D2", "count": 2 },
{ "level": "D3", "count": 6 },
{ "level": "Non-Degree", "count": 20 },
{ "level": "S1", "count": 648 },
{ "level": "S2", "count": 683 },
{ "level": "S3", "count": 362 }
],
"tipe_pendanaan": [
{ "type": "Fully Funded", "count": 809 },
{ "type": "Partially Funded", "count": 590 }
],
"tipe_beasiswa": [
{ "type": "Company/Institution Scholarship", "count": 237 },
{ "type": "Government Scholarship", "count": 459 },
{ "type": "University Scholarship", "count": 830 }
],
"negara": [
{ "country": "Australia", "count": 161 },
{ "country": "Austria", "count": 19 },
{ "country": "Azerbaijan", "count": 6 },
{ "country": "Belgium", "count": 38 },
{ "country": "Brazil", "count": 2 },
{ "country": "Brunei", "count": 5 },
{ "country": "Canada", "count": 46 },
{ "country": "China", "count": 114 },
{ "country": "Czech Republic", "count": 2 },
{ "country": "Denmark", "count": 13 },
{ "country": "Egypt", "count": 3 },
{ "country": "Estonia", "count": 2 },
{ "country": "Finland", "count": 11 },
{ "country": "France", "count": 20 },
{ "country": "Germany", "count": 46 },
{ "country": "Hong Kong", "count": 24 },
{ "country": "Hungary", "count": 5 },
{ "country": "India", "count": 2 },
{ "country": "Indonesia", "count": 35 },
{ "country": "Ireland", "count": 8 },
{ "country": "Italy", "count": 19 },
{ "country": "Japan", "count": 254 },
{ "country": "Kazakhstan", "count": 3 },
{ "country": "Latvia", "count": 3 },
{ "country": "Libya", "count": 2 },
{ "country": "Luxembourg", "count": 1 },
{ "country": "Macau", "count": 6 },
{ "country": "Malaysia", "count": 12 },
{ "country": "Morocco", "count": 2 },
{ "country": "Netherlands", "count": 21 },
{ "country": "New Zealand", "count": 22 },
{ "country": "Pakistan", "count": 1 },
{ "country": "Philippines", "count": 2 },
{ "country": "Poland", "count": 9 },
{ "country": "Portugal", "count": 4 },
{ "country": "Qatar", "count": 6 },
{ "country": "Romania", "count": 9 },
{ "country": "Russia", "count": 6 },
{ "country": "Saudi Arabia", "count": 12 },
{ "country": "Scotland", "count": 2 },
{ "country": "Serbia", "count": 3 },
{ "country": "Singapore", "count": 49 },
{ "country": "Slovakia", "count": 1 },
{ "country": "South Korea", "count": 109 },
{ "country": "Spain", "count": 12 },
{ "country": "Sweden", "count": 11 },
{ "country": "Switzerland", "count": 19 },
{ "country": "Taiwan", "count": 112 },
{ "country": "Thailand", "count": 38 },
{ "country": "Turkey", "count": 11 },
{ "country": "United Arab Emirates", "count": 67 },
{ "country": "United Kingdom", "count": 76 },
{ "country": "United States", "count": 55 },
{ "country": "Universal", "count": 2 },
{ "country": "Vietnam", "count": 2 }
]
},
"scholarships_page_1": [
{
"name": "Boustany Foundation Scholarship, MBA - Harvard University",
"funding_type": "Partially Funded",
"level": ["S2"],
"country": "United States",
"open_date": "2026-05-21",
"deadline": "2027-05-31",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/boustany-foundation-scholarship-mba-harvard-university-1"
},
{
"name": "La Trobe University - La Trobe High Achiever Scholarship",
"funding_type": "Partially Funded",
"level": ["S1"],
"country": "Australia",
"open_date": "2023-09-29",
"deadline": "2026-12-31",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/la-trobe-university-la-trobe-high-achiever-scholarship-2"
},
{
"name": "Charles Sturt University - International Student Support Scholarship",
"funding_type": "Partially Funded",
"level": ["S1"],
"country": "Australia",
"open_date": "2026-05-21",
"deadline": "2026-12-31",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/charles-sturt-university-international-student-support-scholarship-3"
},
{
"name": "La Trobe University - La Trobe High Achiever Scholarship",
"funding_type": "Partially Funded",
"level": ["S2"],
"country": "Australia",
"open_date": "2023-09-29",
"deadline": "2026-12-31",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/la-trobe-university-la-trobe-high-achiever-scholarship-4"
},
{
"name": "ETH Zurich - Excellence Scholarship & Opportunity Programme (ESOP)",
"funding_type": "Fully Funded",
"level": ["S2"],
"country": "Switzerland",
"open_date": "2026-11-01",
"deadline": "2026-11-30",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/eth-zurich-excellence-scholarship-opportunity-programme-esop-5"
},
{
"name": "Southern Taiwan University of Science and Technology - The STUST Scholarship for International Students",
"funding_type": "Fully Funded",
"level": ["S3"],
"country": "Taiwan",
"open_date": "2026-09-15",
"deadline": "2026-11-30",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/southern-taiwan-university-of-science-and-technology-the-stust-scholarship-for-international-students-6"
},
{
"name": "Southern Taiwan University of Science and Technology - The STUST Scholarship for International Students",
"funding_type": "Partially Funded",
"level": ["S2"],
"country": "Taiwan",
"open_date": "2026-09-15",
"deadline": "2026-11-30",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/southern-taiwan-university-of-science-and-technology-the-stust-scholarship-for-international-students-7"
},
{
"name": "University of Melbourne - Melbourne International Undergraduate Scholarship",
"funding_type": "Partially Funded",
"level": ["S1"],
"country": "Australia",
"open_date": "2026-05-21",
"deadline": "2026-10-31",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/university-of-melbourne-melbourne-international-undergraduate-scholarship-8"
},
{
"name": "Charles Darwin University - CDU Global Merit Scholarship",
"funding_type": "Partially Funded",
"level": ["S1"],
"country": "Australia",
"open_date": "2026-05-21",
"deadline": "2026-10-09",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/charles-darwin-university-cdu-global-merit-scholarship-9"
},
{
"name": "Deakin University - Vice-Chancellor's International Scholarship",
"funding_type": "Partially Funded",
"level": ["S1", "S2"],
"country": "Australia",
"open_date": "2026-05-21",
"deadline": "2026-09-25",
"status": "Pendaftaran dibuka",
"url": "https://www.schoters.com/id/beasiswa/deakin-university-vice-chancellor-s-international-scholarship-10"
}
],
"pagination": {
"current_page": 1,
"total_pages": 153
},
"contact": {
"email": "ask@schoters.com",
"phone": "0811 9424 966",
"address": "Gedung Sinarmas MSIG Tower Lt. 33, Jl. Jenderal Sudirman Kav. 21, Karet Kuningan, Setiabudi, Jakarta Selatan, Jakarta 12920"
},
"social_media": {
"instagram": "https://www.instagram.com/schoters/",
"facebook": "https://www.facebook.com/schoters",
"youtube": "https://www.youtube.com/@Schoters",
"tiktok": "https://www.tiktok.com/@schoters.id",
"twitter_x": "https://x.com/schoters_com",
"linkedin": "https://id.linkedin.com/company/schoters"
}
}