# LAPORAN ANALISIS STRUKTUR SISTEM FLS3N 2025
## Eksplorasi Struktur Database, Kelola Peserta, dan Form Pendaftaran

---

## 1. STRUKTUR TABEL DATABASE

### Database Connection
- **Database Name**: `c2fls3n_2`
- **Server**: localhost
- **Port**: 3306 (default MySQL)
- **Config File**: [admin/config.php](admin/config.php)

### Tabel-Tabel Utama

#### A. Tabel Master/Validasi Peserta
**Tabel: `peserta_terdaftar`**
- **Tujuan**: Menyimpan data master peserta yang terdaftar, digunakan untuk validasi saat proses pendaftaran
- **Kolom**:
  - `id` (INT, PRIMARY KEY, AUTO INCREMENT)
  - `Nama_Peserta` (VARCHAR) - Nama lengkap peserta (UPPERCASE)
  - `NPSN` (VARCHAR) - Nomor Pokok Sekolah Nasional (UPPERCASE)
  - `domisili` (VARCHAR) - Nilai: "kabupaten semarang", "kabupaten demak", atau "kota salatiga"
  - `created_at` (TIMESTAMP) - Waktu pembuatan record

- **Cara Penggunaan**:
  - Admin menggunakan menu "Kelola Peserta" untuk menambah/import data peserta
  - Data diduplikasi berdasarkan NPSN untuk menghindari duplikasi
  - Saat pendaftaran online, sistem melakukan validasi nama peserta & NPSN terhadap tabel ini

#### B. Tabel Peserta Terregistrasi Berdasarkan Domisili

**Tabel: `domisilikota`** (Peserta Kota Salatiga)
- Menyimpan peserta yang telah mendaftar dari kota Salatiga
- Kolom:
  - `NISN` - Nomor Induk Siswa Nasional (10 digit)
  - `Nama_Peserta` - Nama lengkap (UPPERCASE)
  - `Nama_Sekolah` - Nama sekolah (UPPERCASE)
  - `NPSN` - Nomor Pokok Sekolah (UPPERCASE)
  - `TTL` - Tempat, Tanggal Lahir
  - `Email` - Email & No WhatsApp (format: email - nomor)
  - `Jenis_Kelamin` - "Laki-laki" atau "Perempuan"
  - `Foto_Peserta` - URL link foto (Google Drive, YouTube, dll)
  - `Karya` - URL link karya (Google Drive, YouTube, dll)
  - `ID_Cabang_Lomba` - ID cabang lomba yang diikuti
  - `created_at` - Timestamp

**Tabel: `domisilikabupaten`** (Peserta Kabupaten Semarang)
- Struktur sama dengan `domisilikota`

**Tabel: `domisilikabupaten2`** (Peserta Kabupaten Demak)
- Struktur sama dengan `domisilikota`

#### C. Tabel Pendukung

**Tabel: `status_lomba`**
- Menyimpan status registrasi untuk setiap domisili
- Kolom: `name` (kota_salatiga, kabupaten_semarang, kabupaten_demak), `status`, `updated_at`, `updated_by`
- Digunakan untuk mengontrol buka/tutup pendaftaran

**Tabel: `cabang_lomba`**
- Menyimpan bidang/kategori lomba
- Kolom: `ID`, `Bidang_Lomba`, dll

**Tabel: `users`**
- Menyimpan admin dan juri
- Kolom: `id`, `nama_lengkap`, `role` (admin/juri), `domisili`, dll

---

## 2. SISTEM VALIDASI SAAT INI

### Flow Validasi Pendaftaran

```
User mengakses form pendaftaran
    ↓
User memilih cabang lomba & domisili
    ↓
User mengisi form lengkap (Nama, NISN, Email, Link Karya, dll)
    ↓
User klik "Daftar Sekarang" → Modal Konfirmasi muncul
    ↓
User klik "Ya, Saya Yakin" → Form di-submit
    ↓
[PHP Server-side Validation]
    ├─ Validasi URL Foto & Karya (FILTER_VALIDATE_URL)
    ├─ Cek di tabel peserta_terdaftar:
    │  └─ SELECT id FROM peserta_terdaftar 
    │     WHERE Nama_Peserta = X AND NPSN = Y AND domisili = Z
    ├─ Jika tidak terdaftar: Error "Data peserta tidak sesuai"
    ├─ Tentukan tabel tujuan:
    │  └─ IF domisili mengandung "kabupaten" THEN domisilikabupaten/domisilikabupaten2
    │     ELSE domisilikota
    ├─ Cek NISN duplikat di tabel tujuan
    └─ INSERT ke tabel tujuan
```

### Validasi Client-Side (JavaScript)

```javascript
// 1. NISN Validation
   - Hanya angka (10 digit)
   - Regex: /[0-9]{10}/
   - OnInput: remove non-numeric characters, limit to 10 digits
   - Visual feedback: is-valid / is-invalid class

// 2. Nama Peserta, Nama Sekolah, NPSN
   - UPPERCASE only
   - OnInput: toUpperCase()
   - OnPaste: prevent lowercase paste

// 3. URL Validation
   - filter_var($url, FILTER_VALIDATE_URL)
   - Supported: Google Drive, YouTube, dll (public URLs)

// 4. Email Format
   - HTML5 email input validation
   - Pattern: email - nomor_wa (dipisahkan dengan " – ")
```

### Validasi Database

| Field | Validasi | Notes |
|-------|----------|-------|
| NISN | Tidak duplikat di tabel domisili | UNIQUE per domisili |
| Nama_Peserta | Master check di peserta_terdaftar | Harus terdaftar terlebih dahulu |
| NPSN | Master check di peserta_terdaftar | Harus match dengan Nama_Peserta |
| Domisili | Harus salah satu dari: kabupaten semarang, kabupaten demak, kota salatiga | - |
| Email | Format valid URL | Filter FILTER_VALIDATE_URL |
| Karya | URL valid + bukan duplikat NISN | - |

---

## 3. STRUKTUR DAN FITUR KELOLA PESERTA

### Lokasi: [admin/admin_dashboard/admin_kelola_peserta/index.php](admin/admin_dashboard/admin_kelola_peserta/index.php)

### Fitur Utama

#### A. Tambah Peserta Manual
- Button: "Tambah Peserta" → Modal Form
- Form Input:
  - Nama Peserta (UPPERCASE)
  - NPSN Sekolah (UPPERCASE)
  - Domisili (dropdown: Kabupaten Semarang, Kabupaten Demak, Kota Salatiga)
- Action: INSERT ke `peserta_terdaftar`

#### B. Import Data dari CSV
- Button: "Import Data" → Modal Upload
- Format CSV yang diterima:
  ```csv
  Nama_Peserta;NPSN;Domisili
  SISWA SATU;12345678;kabupaten semarang
  SISWA DUA;87654321;kota salatiga
  ```
- Fitur:
  - Validasi format setiap baris
  - Cek duplikasi
  - Log error per baris
  - Download template CSV
- Output: Detail import (berhasil, gagal, duplikat)

#### C. Tabel Data Peserta
**Struktur Tabel:**
| Kolom | Fungsi |
|-------|--------|
| Nama Peserta | Nama peserta terdaftar |
| NPSN | Nomor sekolah |
| Domisili | Lokasi pendaftaran |
| Tgl Dibuat | Waktu data dibuat |
| Aksi | Button hapus |

**Fitur Tabel:**
- Pagination (default 10 records per halaman)
- Filter berdasarkan domisili
- Pencarian nama peserta & NPSN
- Button Hapus → Modal konfirmasi

#### D. Aksi Tambahan
- **Hapus Semua Data**: Button danger dengan modal konfirmasi warning
- **Status Lampu Kuning**: Auto-hide alert setelah 5 detik

### Teknologi UI
- **Framework CSS**: Bootstrap 5.3.0
- **Icons**: Font Awesome 6.0.0
- **Sidebar**: Dark theme (#212529)
- **Responsive**: Mobile-first design

---

## 4. STRUKTUR DAN STYLING FORM PENDAFTARAN

### Lokasi: [cabang_lomba_kab/form-daftar/index.php](cabang_lomba_kab/form-daftar/index.php)
**Catatan**: Form serupa juga ada di `cabang_lomba_kab_2` dan `cabang_lomba_kota`

### Struktur Form

#### A. Header dengan Logo
```html
Header Tetap (Fixed Top):
├─ Logo: TI Unisbank, Unisbank, FLS3N
├─ Judul: "FLS3N 2025"
└─ Styling: Gradient background, blur effect
```

#### B. Sektor 1: Informasi Pribadi
```
┌─ NISN
│  └─ Input: 10 digit angka only
├─ Nama Peserta
│  └─ Input: UPPERCASE only
├─ Tempat Tanggal Lahir (TTL)
│  └─ Format: Kota, Tanggal Bulan Tahun (dipisahkan dengan ",")
└─ Email & No WA
   └─ Format: email – nomor_wa (dipisahkan dengan " – ")
```

#### C. Sektor 2: Informasi Sekolah
```
├─ Nama Sekolah
│  └─ UPPERCASE, constraint: [A-Z0-9\s/]+
│  └─ Note: "Jangan disingkat! Contoh: SMA NEGERI 1 SEMARANG"
├─ NPSN Sekolah
│  └─ UPPERCASE
│  └─ Special: Jika PKBM/Non Formal, input "PKBM"
└─ Jenis Kelamin
   └─ Dropdown: Laki-laki / Perempuan
```

#### D. Sektor 3: Informasi Lomba
```
├─ Domisili (Readonly)
│  └─ Ditentukan dari session saat pilih cabang
└─ Cabang Lomba (Readonly)
   └─ Ditampilkan dari database berdasarkan ID
```

#### E. Sektor 4: Upload Dokumen
```
├─ Link Bukti Peserta (Foto)
│  └─ Input: URL
│  └─ Sumber: Google Drive, YouTube, dll (MUST PUBLIC)
│  └─ Validasi: filter_var($url, FILTER_VALIDATE_URL)
└─ Link Karya
   └─ Input: URL
   └─ Sumber: Google Drive, YouTube, dll (MUST PUBLIC)
   └─ Validasi: filter_var($url, FILTER_VALIDATE_URL)
```

### CSS Styling

#### Color Scheme (CSS Variables)
```css
--primary-color: #9d174d (Maroon)
--secondary-color: #f43f5e (Rose)
--accent-color: #fbcfe8 (Light Pink)
--dark-color: #4b5563 (Dark Gray)
--light-color: #f9fafb (Off White)
```

#### Komponen Styling

| Komponen | Style |
|----------|-------|
| Form Card | White, border-radius 16px, shadow 0 10px 30px |
| Card Header | Gradient bg, positioning decoration |
| Input Fields | Padding 12x15, border-radius 8px, focus with rose color |
| Labels | Font-weight 600, font-size 0.9rem |
| Buttons | Gradient bg, shadow, hover translateY effect |
| Section Title | Color primary, flex display, icon margin |
| Icons (input) | Positioned absolute left with light-gray color |

#### Animasi
```css
Fade In: opacity 0 → 1, translateY(20px) → 0 (0.6s)
Hover Effect: translateY(-2px atau -5px)
Transition: 0.3s ease
```

#### Responsive Design
```css
Mobile (≤768px):
├─ Main header: height 70px (from 80px)
├─ Logo: 45px (from 65px)
├─ Font sizes: smaller
├─ Padding: reduced
└─ Form section: margin-bottom 20px (from 30px)
```

### JavaScript Features

#### 1. Input Validation & Formatting
```javascript
NISN:
  - Remove non-numeric on input
  - Limit to 10 digits
  - Add visual feedback (is-valid/is-invalid)

Nama, Sekolah, NPSN:
  - Force UPPERCASE on input
  - Prevent lowercase paste
  - Pattern matching: [A-Z\s/]+
```

#### 2. Form Submission
```javascript
Flow:
1. User click "Daftar Sekarang"
2. Validate all fields (client-side)
3. Show confirmation modal
4. Display all data in modal for review
5. User click "Ya, Saya Yakin"
6. Submit form via POST
```

#### 3. Confirmation Modal
```javascript
Menampilkan:
├─ Warning: "Submit Karya hanya dapat dilakukan Sekali!"
├─ Data confirmation list
│  ├─ NISN
│  ├─ Nama Peserta
│  ├─ Nama Sekolah
│  ├─ NPSN Sekolah
│  ├─ TTL
│  ├─ Email & No WA
│  ├─ Jenis Kelamin
│  ├─ Domisili
│  ├─ Cabang Lomba
│  ├─ Link Bukti Peserta
│  └─ Link Karya
└─ Button: Cancel / Submit
```

#### 4. Tooltip di Form
```javascript
- NISN tooltip: "NISN harus terdiri dari 10 digit angka"
- Nama tooltip: "Nama harus menggunakan huruf kapital"
- TTL tooltip: "Format: Kota/Kab, Tanggal Bulan Tahun"
```

---

## 5. TIDAK ADA TABEL SEKOLAH TERPISAH

### Findings:
- ✗ Tidak ada tabel `sekolah` atau `master_sekolah` di database
- ✓ Informasi sekolah disimpan langsung di tabel peserta:
  - `Nama_Sekolah` - VARCHAR
  - `NPSN` - VARCHAR

### Implikasi:
- Sekolah bisa duplikat (tidak ada constraint UNIQUE di level sekolah)
- NPSN dijadikan identifier sekolah, bukan ID internal
- Fleksibel: siswa dari sekolah berbeda bisa mendaftar

---

## REKOMENDASI UNTUK FITUR PENDAFTARAN SEKOLAH

### File Reference untuk Implementasi:
1. **Form Structure**: Copy dari [cabang_lomba_kab/form-daftar/index.php](cabang_lomba_kab/form-daftar/index.php)
2. **Admin Panel**: Copy dari [admin/admin_dashboard/admin_kelola_peserta/index.php](admin/admin_dashboard/admin_kelola_peserta/index.php)
3. **CSS Styling**: Extend dari color variables dan form-card structure
4. **JavaScript Validation**: Adapt dari NISN validation pattern

### Tahapan Implementasi:

#### Phase 1: Database (jika diperlukan)
```sql
-- Opsi A: Tabel sekolah terpisah (lebih terstruktur)
CREATE TABLE master_sekolah (
    ID INT PRIMARY KEY AUTO_INCREMENT,
    Nama_Sekolah VARCHAR(255) UNIQUE NOT NULL,
    NPSN VARCHAR(50) UNIQUE NOT NULL,
    Lokasi_Kabupaten VARCHAR(100),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Opsi B: Tetap simple (seperti saat ini)
-- Sekolah info tetap di tabel peserta tanpa perubahan struktur
```

#### Phase 2: Admin Interface
- Buat menu baru: "Kelola Sekolah"
- CRUD operations: Create, Read, Update, Delete
- Import dari CSV (nama sekolah + NPSN)
- Tampilkan daftar sekolah dalam pagination table
- Delete dengan confirmation modal

#### Phase 3: Form Pendaftaran
- Ganti input text nama_sekolah → dropdown select dari master_sekolah
- Auto-populate NPSN saat pilih sekolah
- Atau tetap input manual (lebih fleksibel untuk PKBM)

#### Phase 4: Validasi
- Validasi NPSN terhadap master_sekolah
- Prevent duplicate NPSN entry
- Log perubahan sekolah (audit trail)

---

## SUMMARY STRUKTUR

| Aspek | Status | Notes |
|-------|--------|-------|
| Database | ✓ Terstruktur | 3 tabel domisili + 1 master peserta + supporting tables |
| Validasi | ✓ Double-layer | Client-side JavaScript + Server-side PHP |
| Form | ✓ Professional | Bootstrap responsive + gradient styling |
| Kelola Peserta | ✓ Complete | CRUD + Import CSV + Filter + Search |
| Tabel Sekolah | ✗ Tidak ada | Data sebagai column, bisa dibuat terstruktur |
| UI/UX | ✓ Modern | Consistent styling, smooth animations, mobile-ready |

---

*Laporan ini dibuat berdasarkan analisis kode pada 2026-04-09*
