No description
  • PHP 42%
  • JavaScript 37.6%
  • CSS 13.6%
  • Shell 6.8%
Find a file
2026-10-27 10:18:52 +07:00
data Aplikasi undian parallax: PHP native + SQLite 2026-10-06 15:08:33 +07:00
public Pagination server-side admin, detail per id, undian pakai sampel nama 2026-10-27 10:18:52 +07:00
src Pagination server-side admin, detail per id, undian pakai sampel nama 2026-10-27 10:18:52 +07:00
tests Pagination server-side admin, detail per id, undian pakai sampel nama 2026-10-27 10:18:52 +07:00
.gitignore Aplikasi undian parallax: PHP native + SQLite 2026-10-06 15:08:33 +07:00
PRD.md Pagination server-side admin, detail per id, undian pakai sampel nama 2026-10-27 10:18:52 +07:00
README.md Pagination server-side admin, detail per id, undian pakai sampel nama 2026-10-27 10:18:52 +07:00
seed.php Aplikasi undian parallax: PHP native + SQLite 2026-10-06 15:08:33 +07:00

Undian Parallax

Aplikasi undian (giveaway/raffle) PHP native + SQLite dengan latar parallax. Ringan dan portabel: cukup copy folder, tanpa instalasi database server.

Fitur

  • Halaman Undian (default) dengan efek parallax dan animasi rol + ledakan saat menarik pemenang. Hanya menampilkan nomor undian dan nama lengkap pemenang.
  • Pendaftaran peserta manual (nomor undian, nama, alias/sebutan, data identitas & domisili).
  • Dasbor Admin dengan sub-tab: Total Peserta / Belum Menang / Sudah Menang, plus pencarian dan pagination.
  • Alias / sebutan: diisi manual atau dibuat otomatis bila kosong. Hanya nomor undian yang wajib unik; alias, nomor identitas, dan data lain boleh sama.
  • Banner undian: unggah gambar berukuran tepat 1200 × 400 px (JPG/PNG/WEBP/GIF, maks 5 MB) untuk ditampilkan di panggung undian.
  • Judul aplikasi: ubah judul/brand dari Dasbor Admin.
  • Teks footer: ubah teks footer halaman undian dari Dasbor Admin (kosongkan untuk menyembunyikan).
  • Durasi undian: atur lama pengacakan 10–30 detik dari Dasbor Admin (default 20 detik), lengkap dengan hitungan mundur di panggung undian.
  • Eliminasi pemenang: status yang membatalkan kemenangan dan mengeluarkan peserta dari undian; data peserta tetap tersimpan.
  • Hapus peserta: menghapus data peserta yang salah input (riwayat kemenangannya ikut terhapus).
  • Detail peserta: tombol untuk melihat seluruh data peserta (termasuk hadiah bila sudah menang).
  • Zona Bahaya: reset (truncate) seluruh data peserta beserta riwayat pemenang event ini.
  • Import CSV (Excel: Save As CSV).
  • Undian diproses server-side secara acak dan transaksional.
  • Efek suara: drums.mp3 diputar selama pengacakan sesuai durasi undian (10–30 detik; melompat ke detik 35 satu detik sebelum selesai), lalu tepuktangan.mp3 3 detik setelah nama pemenang muncul.
  • Kembang api: animasi fireworks.js setelah undian selesai, berlangsung selama audio tepuk tangan diputar, bersamaan dengan tepuk tangan (dimatikan bila pengguna memilih reduce motion).

Tech Stack

  • Frontend: HTML5, CSS3, JavaScript vanilla + parallax.js dan fireworks.js, keduanya disimpan lokal di public/assets/ (tanpa CDN, bisa jalan offline).
  • Backend: PHP native (diuji pada PHP 7.4), ekstensi pdo_sqlite.
  • Database: SQLite (data/database.sqlite, dibuat otomatis).

Struktur

undian/
├── public/                 <- Document root
│   ├── index.php           <- Halaman Undian (Basic Auth)
│   ├── admin.php           <- Halaman Admin (Basic Auth)
│   ├── assets/{style.css,app.js,parallax.min.js,fireworks.js,particles.gif,drums.mp3,tepuktangan.mp3}
│   ├── api/                <- Endpoint REST
│   │   ├── event.php       GET  info event + banner
│   │   ├── participants.php GET  daftar peserta (paginated) + detail + statistik
│   │   ├── register.php    POST daftar peserta
│   │   ├── draw.php        POST tarik pemenang
│   │   ├── eliminate.php   POST eliminasi (batalkan menang) / aktifkan
│   │   ├── delete.php      POST hapus peserta
│   │   ├── reset.php       POST reset data peserta
│   │   ├── banner.php      POST unggah banner
│   │   └── import.php      POST import CSV
│   └── uploads/            <- Gambar banner (.htaccess menolak skrip)
├── src/config.php          PDO SQLite, auto-migrasi, helper, CORS
├── data/                   database.sqlite + .htaccess (di luar web root)
├── seed.php                isi data dummy
├── tests/smoke.sh          smoke test end-to-end
└── PRD.md

Menjalankan

Document root harus diarahkan ke folder public/.

Development cepat:

php -d upload_max_filesize=200M -d post_max_size=201M -d max_input_time=600 -S localhost:8000 -t public

Buka http://localhost:8000. Database dan tabel dibuat otomatis saat request pertama.

Import CSV besar butuh batas upload PHP yang lebih tinggi. public/.user.ini sudah menyetelnya untuk PHP-FPM/CGI. Dev server php -S tidak membaca .user.ini, jadi pakai perintah -d di atas (atau php.ini). Apache mod_php: set php_value upload_max_filesize 200M dan php_value post_max_size 201M di vhost/.htaccess. Nginx: client_max_body_size 201m;.

  • index.php — halaman undian (default). Dilindungi Basic Auth yang sama dengan admin, jadi browser cukup login sekali.
  • admin.php — halaman admin (pendaftaran, banner, import, dasbor). Dilindungi Basic Auth; default user admin, password admin123 (ubah ADMIN_USER/ADMIN_PASS di src/config.php).

Produksi (Apache/Nginx): set document root ke public/. Pastikan folder data/ tidak dapat diakses publik.

Data dummy

php seed.php 1000     # membuat 1000 peserta dummy (default 25)

Uji

bash tests/smoke.sh   # register -> list -> draw -> habis

REST API

Method Endpoint Fungsi
GET /api/event.php?event_id=1 Info event + banner
POST /api/event.php Ubah judul aplikasi / durasi undian / footer (JSON: app_title, draw_duration 10–30, footer_text)
GET /api/participants.php?event_id=1&page=1&filter=all&q= Daftar peserta per halaman (10 baris). filter: all/wait/win; q: cari nomor undian, alias, nama, HP, kota, hadiah. Hanya kolom tabel yang dikirim.
GET /api/participants.php?id=123&event_id=1 Detail lengkap satu peserta + hadiah bila menang (dipakai modal Detail)
GET /api/participants.php?roll=1&event_id=1 Sampel maksimal 30 peserta yang belum menang (id, no_unik, nama) untuk animasi rol halaman undian
POST /api/register.php Daftar peserta (JSON)
POST /api/draw.php Tarik pemenang (JSON: hadiah; respons berisi id, no_unik, nama)
POST /api/eliminate.php Eliminasi pemenang / aktifkan peserta (JSON: participant_id, eliminated 0/1)
POST /api/delete.php Hapus peserta (JSON: participant_id)
POST /api/reset.php Reset seluruh peserta + pemenang event
POST /api/banner.php Unggah banner (multipart: image)
POST /api/import.php Import peserta (multipart: file CSV)

Format Import CSV

Baris pertama berisi nama kolom (boleh tidak berurutan; delimiter , atau ;).

Kolom Wajib Keterangan
no_unik Ya Nomor undian, unik per event. Kosong = dibuat otomatis.
nama Ya Nama lengkap peserta.
alias Tidak Sebutan; dibuat otomatis bila kosong. Boleh sama.
no_hp Tidak Nomor kontak.
identitas_jenis Tidak KTP / SIM / Paspor / Lainnya.
identitas_no Tidak Nomor identitas. Boleh sama.
alamat_domisili Tidak Alamat lengkap.
negara Tidak Negara asal.
provinsi Tidak Provinsi.
kota Tidak Kota / Kabupaten.

Contoh:

no_unik,nama,alias,no_hp,identitas_jenis,identitas_no,alamat_domisili,negara,provinsi,kota
001,Budi Santoso,Elang Cepat,08123456789,KTP,3201012345670001,Jl. Merdeka No. 1,Indonesia,Jawa Barat,Bandung
002,Siti Aminah,,08129876543,Paspor,A1234567,,Indonesia,DKI Jakarta,Jakarta

no_unik wajib unik per event; baris dengan nomor undian duplikat dilewati dan dilaporkan, baris lain tetap diproses. Kolom lain (alias, nomor identitas, dll.) boleh duplikat.

Berkas maksimal 200 MB dan seluruh baris diimpor (tanpa batas jumlah baris). File dibaca per baris, jadi tidak perlu menaikkan memory_limit. Untuk file besar, naikkan juga batas waktu request di web server (mis. fastcgi_read_timeout) bila impor memakan lebih dari satu menit.

Keamanan

  • Semua query memakai PDO prepared statements.
  • File data/database.sqlite diletakkan di luar document root dan diproteksi .htaccess.
  • Unggahan banner divalidasi berdasarkan isi file (JPG/PNG/WEBP/GIF, maks 5 MB) dan folder uploads/ menolak eksekusi skrip.
  • CORS dapat dibatasi lewat ALLOWED_ORIGINS di src/config.php (default: same-origin).

Catatan

  • Halaman admin.php dilindungi Basic Auth (ADMIN_USER/ADMIN_PASS di src/config.php). Endpoint API masih terbuka, jadi proteksi API juga diperlukan sebelum dipakai publik.
  • Import hanya mendukung CSV. Untuk Excel, simpan sebagai CSV. Dukungan .xlsx langsung memerlukan library tambahan.
  • Nomor undian unik per event dijamin oleh constraint UNIQUE(event_id, no_unik).