forked from izu/student-web-if-development-kit
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:
@@ -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: 48–64px bold | H2: 32–40px semibold | H3: 24–28px semibold
|
||||
- Body: 16–18px regular | Caption: 12–14px
|
||||
|
||||
---
|
||||
|
||||
## 📄 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
|
||||
@@ -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 | 48–64px | 700 (Bold) |
|
||||
| Heading H2 | Poppins / Inter | 32–40px | 600 (SemiBold) |
|
||||
| Heading H3 | Poppins / Inter | 24–28px | 600 (SemiBold) |
|
||||
| Body Text | Inter / Poppins | 16–18px | 400 (Regular) |
|
||||
| Caption/Label | Inter / Poppins | 12–14px | 400–500 |
|
||||
| Navbar | Inter | 14–16px | 500 (Medium) |
|
||||
| Button | Inter | 14–16px | 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, 3–4 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 (768–1279px) | 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 | 3–4 kolom |
|
||||
| Teks Body | 16px | 16–17px | 17–18px |
|
||||
| Padding Section | 24px 16px | 40px 32px | 80px 64px |
|
||||
| Footer | Stack vertikal | 2 kolom | 3–4 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.
|
||||
@@ -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 |
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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 =>
|
||||
({ '<': '<', '>': '>', '&': '&', '"': '"', "'": ''' }[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();
|
||||
});
|
||||
@@ -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! — Beasiswa Pertamina Foundation open hingga Agustus 2026 — Daftarkan diri Anda sekarang! — Info lengkap tersedia di halaman direktori beasiswa — Beasiswa LPDP S2 masih tersedia hingga September 2026 — ',
|
||||
},
|
||||
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! — Pertamina Foundation Scholarship open until August 2026 — Register now! — Full info available in the scholarship directory — LPDP S2 Scholarship available until September 2026 — ',
|
||||
}
|
||||
};
|
||||
|
||||
// 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);
|
||||
});
|
||||
@@ -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
|
||||
@@ -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;
|
||||
@@ -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"]
|
||||
}
|
||||
]
|
||||
@@ -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!"
|
||||
}
|
||||
]
|
||||
+569
-1306
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user