<!DOCTYPE html>
<html lang="ms">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sistem Rekod Dokumen - Gaji IPD SKN</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Rajdhani:wght@400;500;600;700&display=swap" rel="stylesheet">
<style>
:root {
--bg-color-dark: #0a0e17;
--neon-cyan: #00f3ff;
--neon-purple: #bc13fe;
}
body {
background-color: var(--bg-color-dark);
color: #e2e8f0;
font-family: 'Rajdhani', sans-serif;
overflow-x: hidden;
transition: background-color 0.8s ease;
}
body.light-mode { background-color: #f3f4f6; }
body.light-mode .cyber-grid,
body.light-mode .dark-overlay {
opacity: 0 !important;
visibility: hidden;
transition: opacity 0.8s ease, visibility 0.8s ease;
}
h1, h2, .font-cyber { font-family: 'Orbitron', sans-serif; }
.cyber-grid {
position: fixed;
top: 0; left: 0; width: 100vw; height: 100vh;
background-image:
linear-gradient(rgba(0, 243, 255, 0.05) 1px, transparent 1px),
linear-gradient(90deg, rgba(0, 243, 255, 0.05) 1px, transparent 1px);
background-size: 40px 40px;
background-position: center center;
z-index: -2;
transform: perspective(500px) rotateX(60deg) scale(2.5) translateY(-100px);
animation: gridMove 20s linear infinite;
transition: opacity 0.8s ease, visibility 0.8s ease;
}
.dark-overlay { transition: opacity 0.8s ease, visibility 0.8s ease; }
@keyframes gridMove {
0% { transform: perspective(500px) rotateX(60deg) scale(2.5) translateY(0); }
100% { transform: perspective(500px) rotateX(60deg) scale(2.5) translateY(40px); }
}
.neon-text-cyan {
color: var(--neon-cyan);
text-shadow: 0 0 8px rgba(0, 243, 255, 0.6), 0 0 20px rgba(0, 243, 255, 0.4);
}
.neon-text-white {
color: #ffffff;
text-shadow: 0 0 10px rgba(255, 255, 255, 0.8), 0 0 20px var(--neon-cyan);
}
.cyber-button {
position: relative;
background: rgba(0, 243, 255, 0.05);
color: var(--neon-cyan);
border: 1px solid var(--neon-cyan);
text-transform: uppercase;
letter-spacing: 2px;
overflow: hidden;
transition: 0.3s;
box-shadow: 0 0 10px rgba(0, 243, 255, 0.2);
backdrop-filter: blur(5px);
}
.cyber-button::before {
content: '';
position: absolute;
top: 0; left: -100%;
width: 100%; height: 100%;
background: linear-gradient(90deg, transparent, rgba(0, 243, 255, 0.4), transparent);
transition: 0.5s;
}
.cyber-button:hover {
background: rgba(0, 243, 255, 0.15);
box-shadow: 0 0 25px rgba(0, 243, 255, 0.6);
color: #fff;
}
.cyber-button:hover::before { left: 100%; }
.fade-slide-hidden {
opacity: 0;
transform: translateY(30px);
pointer-events: none;
position: absolute;
}
.fade-slide-active {
opacity: 1;
transform: translateY(0);
transition: opacity 0.6s ease-out, transform 0.6s ease-out;
position: relative;
}
.form-card {
background: #ffffff;
border: 1px solid #e5e7eb;
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05), 0 8px 10px -6px rgba(0, 0, 0, 0.01);
border-radius: 0.75rem;
color: #1f2937;
}
.form-input-clean {
background-color: #ffffff;
border: 1px solid #d1d5db;
color: #111827;
transition: all 0.2s ease;
}
.form-input-clean:focus {
outline: none;
border-color: #3b82f6;
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.2);
}
@media print {
body { background: white !important; color: black !important; font-family: Arial, sans-serif !important; }
.cyber-grid, header, .no-print, #hero-section, .dark-overlay, #toast-container { display: none !important; }
.print-only { display: block !important; }
#app-container { padding: 0 !important; margin: 0 !important; background: white !important; max-width: 100% !important; }
.form-card { background: white !important; border: none !important; box-shadow: none !important; width: 100% !important; padding: 0 !important; margin: 0 !important; }
.form-input-clean, select, textarea { color: black !important; border-color: #ccc !important; background: white !important; -webkit-appearance: none; }
.print-header { text-align: center; margin-bottom: 2rem; border-bottom: 2px solid black; padding-bottom: 1rem; }
.signature-area { margin-top: 5rem; display: flex; justify-content: space-between; page-break-inside: avoid; }
.signature-box { width: 40%; text-align: center; border-top: 1px dashed black; padding-top: 10px; }
}
.print-only { display: none; }
</style>
</head>
<body class="antialiased min-h-screen flex flex-col items-center">
<div class="cyber-grid"></div>
<div class="dark-overlay fixed inset-0 bg-gradient-to-b from-transparent via-[#0a0e17]/80 to-[#0a0e17] z-[-1] pointer-events-none"></div>
<div id="toast-container" class="fixed top-5 right-5 z-[9999] flex flex-col gap-2"></div>
<header class="w-full fixed top-0 z-50 bg-[#0a0e17]/90 backdrop-blur-md border-b border-cyan-900/50 shadow-[0_4px_30px_rgba(0,243,255,0.1)] no-print">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 h-16 flex items-center justify-between">
<div class="flex items-center gap-3 cursor-pointer group" onclick="kembaliKeHome()">
<svg class="w-8 h-8 text-[#00f3ff] drop-shadow-[0_0_8px_rgba(0,243,255,0.8)] group-hover:rotate-90 transition-transform duration-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4M7.835 4.697a3.42 3.42 0 001.946-.806 3.42 3.42 0 014.438 0 3.42 3.42 0 001.946.806 3.42 3.42 0 013.138 3.138 3.42 3.42 0 00.806 1.946 3.42 3.42 0 010 4.438 3.42 3.42 0 00-.806 1.946 3.42 3.42 0 01-3.138 3.138 3.42 3.42 0 00-1.946.806 3.42 3.42 0 01-4.438 0 3.42 3.42 0 00-1.946-.806 3.42 3.42 0 01-3.138-3.138 3.42 3.42 0 00-.806-1.946 3.42 3.42 0 010-4.438 3.42 3.42 0 00.806-1.946 3.42 3.42 0 013.138-3.138z"></path>
</svg>
<div>
<h1 class="font-cyber text-lg md:text-xl font-bold tracking-wider neon-text-white leading-none">UNIT GAJI</h1>
<p class="text-xs text-cyan-400 font-medium tracking-[0.2em] group-hover:text-cyan-200 transition-colors">IPD SKN</p>
</div>
</div>
<button onclick="bukaSistemApp()" class="text-cyan-400 hover:text-cyan-100 transition-colors focus:outline-none flex items-center gap-2 group">
<span class="hidden sm:inline-block font-cyber text-sm tracking-widest border border-cyan-800 px-3 py-1 rounded-sm bg-cyan-900/20 group-hover:bg-cyan-800/40 transition-all">MENU</span>
<svg class="w-7 h-7 drop-shadow-[0_0_5px_rgba(0,243,255,0.5)] group-hover:scale-110 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path></svg>
</button>
</div>
</header>
<div id="hero-section" class="flex flex-col items-center justify-center min-h-screen w-full px-4 pt-16 transition-all duration-700 no-print">
<div class="relative w-64 h-64 md:w-72 md:h-72 mb-8 z-10 group mt-4">
<div class="absolute -inset-2 bg-gradient-to-r from-[#00f3ff] to-[#bc13fe] rounded-full blur-md opacity-75 group-hover:opacity-100 transition duration-1000 group-hover:duration-200 animate-pulse"></div>
<div class="absolute -inset-4 bg-gradient-to-tr from-[#00f3ff] via-transparent to-[#bc13fe] rounded-full blur-xl opacity-40"></div>
<img src="https://images.unsplash.com/photo-1614729939124-032f0b56c9ce?ixlib=rb-4.0.3&auto=format&fit=crop&w=800&q=80"
alt="Cyberpunk Avatar"
class="relative w-full h-full object-cover rounded-full border-4 border-[#0a0e17] shadow-[0_0_20px_rgba(0,243,255,0.8)] z-10 transition-transform duration-500 group-hover:scale-[1.02]">
</div>
<h1 class="font-cyber text-4xl md:text-5xl lg:text-6xl font-black text-center mb-2 neon-text-white uppercase tracking-tighter z-10">
SISTEM REKOD <br/><span class="neon-text-cyan">DOKUMEN</span>
</h1>
<p class="text-cyan-300 font-medium tracking-[0.3em] text-sm md:text-lg mb-10 text-center max-w-xl z-10 drop-shadow-md">
UNIT GAJI IPD SKN
</p>
<button onclick="bukaSistemApp()" class="cyber-button font-cyber font-bold py-4 px-10 rounded-sm text-lg flex items-center gap-3 group z-10">
<svg class="w-6 h-6 group-hover:translate-x-2 transition-transform" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"></path></svg>
AKSES SISTEM
</button>
</div>
<div id="app-container" class="fade-slide-hidden w-full max-w-4xl px-4 py-24 min-h-screen flex flex-col items-center justify-start z-30">
<div class="form-card w-full p-6 md:p-10 mb-8 relative overflow-hidden">
<div class="print-only print-header">
<h1 class="text-2xl font-bold uppercase">Rekod Pengesahan Penerimaan Dokumen Gaji</h1>
<p class="text-sm text-gray-600">JABATAN SUMBER MANUSIA / UNIT GAJI IPD SKN</p>
</div>
<div id="paparanAdmin" class="space-y-6 no-print">
<div class="border-b border-gray-200 pb-4 mb-6 flex justify-between items-end">
<h3 class="text-xl sm:text-2xl font-bold text-gray-800 flex items-center tracking-wide">
<svg class="w-6 h-6 mr-3 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"></path></svg>
Borang Penghantaran Dokumen
</h3>
<span class="text-xs text-gray-500 font-mono tracking-widest bg-gray-100 border border-gray-200 px-2 py-1 rounded">ADMIN_MODE</span>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-1.5">
<label for="noRujukan" class="block text-sm font-semibold text-gray-700">No. Rujukan [ID]</label>
<input type="text" id="noRujukan" placeholder="Contoh: REF/2026/08/001" class="form-input-clean w-full rounded-md px-4 py-3 text-sm">
</div>
<div class="space-y-1.5">
<label for="tarikhSurat" class="block text-sm font-semibold text-gray-700">Tarikh Transmisi</label>
<input type="date" id="tarikhSurat" class="form-input-clean w-full rounded-md px-4 py-3 text-sm">
</div>
</div>
<div class="space-y-1.5 mt-2">
<label for="perkaraUtama" class="block text-sm font-semibold text-gray-700">Perkara</label>
<select id="perkaraUtama" class="form-input-clean w-full rounded-md px-4 py-3 text-sm font-medium">
<option value="PENYATA PERUBAHAN PENDAPATAN SESEORANG PEGAWAI">PENYATA PERUBAHAN PENDAPATAN SESEORANG PEGAWAI</option>
</select>
</div>
<div class="space-y-1.5 mt-6">
<label for="bahagian" class="block text-sm font-semibold text-gray-700">Pilih Bahagian Penerima</label>
<select id="bahagian" class="form-input-clean w-full rounded-md px-4 py-3 text-sm">
<option value="">-- Sila Pilih Bahagian --</option>
<option value="Cawangan Khas">Cawangan Khas</option>
<option value="Bahagian Ketenteraman Awam">Bahagian Ketenteraman Awam</option>
<option value="Bahagian Siasatan Jenayah Narkotik">Bahagian Siasatan Jenayah Narkotik</option>
<option value="Bahagian Integriti Pematuhan Standart">Bahagian Integriti Pematuhan Standart</option>
<option value="KPB Bandar Sandakan">KPB Bandar Sandakan</option>
<option value="KPB KM52">KPB KM52</option>
<option value="Cawangan Lat/Sukan">Cawangan Lat/Sukan</option>
<option value="Cawangan Kebajikan">Cawangan Kebajikan</option>
<option value="Cawangan HEA">Cawangan HEA</option>
<option value="Cawangan Kawalan Keselamatan Lapangan Terbang">Cawangan Kawalan Keselamatan Lapangan Terbang</option>
</select>
</div>
<div class="space-y-3 mt-6 border-t border-gray-200 pt-6">
<label class="block text-sm font-bold text-gray-700 uppercase tracking-wide border-l-4 border-blue-500 pl-3">Pilihan Mod Kemasukan Kakitangan</label>
<div class="flex flex-col sm:flex-row gap-4 sm:gap-6 bg-gray-50 p-4 rounded-md border border-gray-200">
<label class="flex items-center gap-2 cursor-pointer group">
<input type="radio" name="modKemasukan" value="individu" checked onchange="tukarModKemasukan()" class="w-5 h-5 text-blue-600 border-gray-300 focus:ring-blue-500 cursor-pointer">
<span class="text-sm font-bold text-gray-700 group-hover:text-blue-600 transition-colors">Isi Individu</span>
</label>
<label class="flex items-center gap-2 cursor-pointer group">
<input type="radio" name="modKemasukan" value="kelompok" onchange="tukarModKemasukan()" class="w-5 h-5 text-blue-600 border-gray-300 focus:ring-blue-500 cursor-pointer">
<span class="text-sm font-bold text-gray-700 group-hover:text-blue-600 transition-colors">Tampal Kelompok (Pukal)</span>
</label>
<label class="flex items-center gap-2 cursor-pointer group">
<input type="radio" name="modKemasukan" value="semua" onchange="tukarModKemasukan()" class="w-5 h-5 text-blue-600 border-gray-300 focus:ring-blue-500 cursor-pointer">
<span class="text-sm font-bold text-gray-700 group-hover:text-blue-600 transition-colors">Semua Kakitangan</span>
</label>
</div>
<!-- Mod 1: Individu -->
<div id="modIndividu" class="space-y-3 pt-2">
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-3 mb-2">
<label class="block text-sm font-semibold text-gray-600">Senarai Nama & Butiran</label>
<button type="button" onclick="tambahBarisKakitangan()" class="text-sm bg-blue-50 text-blue-600 hover:bg-blue-100 hover:text-blue-700 font-semibold py-2 px-4 rounded-md transition-colors flex items-center border border-blue-200">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg>
Tambah Kakitangan
</button>
</div>
<div id="bekasSenaraiKakitangan" class="space-y-3"></div>
</div>
<!-- Mod 2: Kelompok -->
<div id="modKelompok" class="space-y-4 pt-2 hidden">
<div class="bg-blue-50 border border-blue-100 p-4 rounded-md space-y-4">
<div class="space-y-1.5">
<label for="butiranKelompok" class="block text-sm font-semibold text-gray-700">Tetapkan Butiran (Untuk semua nama ditampal)</label>
<select id="butiranKelompok" class="form-input-clean w-full rounded-md px-4 py-3 text-sm font-medium bg-white"></select>
</div>
<div class="space-y-1.5">
<label for="senaraiNamaKelompok" class="block text-sm font-semibold text-gray-700 flex items-center justify-between">
Tampal Senarai Nama Di Sini
<span class="text-xs font-normal text-blue-600 bg-white px-2 py-1 rounded border border-blue-200">Satu nama per baris</span>
</label>
<textarea id="senaraiNamaKelompok" rows="6" placeholder="Contoh: Abu Bin Bakar Ali Bin Ahmad" class="form-input-clean w-full rounded-md px-4 py-3 text-sm"></textarea>
</div>
</div>
</div>
<!-- Mod 3: Semua Kakitangan -->
<div id="modSemua" class="space-y-4 pt-2 hidden">
<div class="bg-green-50 border border-green-200 p-5 rounded-md space-y-3">
<div class="flex items-start">
<svg class="w-6 h-6 text-green-600 mr-3 mt-0.5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"></path></svg>
<p class="text-sm text-green-800">Mod pukal <strong>"SEMUA KAKITANGAN"</strong> untuk bahagian penerima yang dipilih.</p>
</div>
<div class="space-y-1.5 mt-4">
<label for="butiranSemua" class="block text-sm font-semibold text-gray-700">Tetapkan Butiran Gaji</label>
<select id="butiranSemua" class="form-input-clean w-full rounded-md px-4 py-3 text-sm font-medium bg-white border-green-300"></select>
</div>
</div>
</div>
</div>
<div class="pt-8 flex flex-col sm:flex-row items-center justify-between gap-4">
<button onclick="simpanDanJanaLink()" id="btnSimpan" class="w-full sm:w-auto bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-8 rounded-md flex items-center justify-center transition-colors shadow-sm">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13.828 10.172a4 4 0 00-5.656 0l-4 4a4 4 0 105.656 5.656l1.102-1.101m-.758-4.899a4 4 0 005.656 0l4-4a4 4 0 00-5.656-5.656l-1.1 1.1"></path></svg>
Simpan & Jana Link
</button>
<button onclick="kosongkanBorangAdmin()" class="text-sm text-gray-500 hover:text-red-500 font-medium transition-colors">
Kosongkan Borang
</button>
</div>
<div id="ruanganLink" class="hidden mt-8 bg-green-50 border border-green-200 rounded-lg p-5 shadow-sm relative overflow-hidden">
<div class="absolute left-0 top-0 bottom-0 w-1 bg-green-500"></div>
<p class="text-green-800 font-bold mb-2 flex items-center">
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path></svg>
Pautan Berjaya Dijana
</p>
<div class="bg-white border border-green-200 rounded p-4 break-all flex justify-between items-center group cursor-pointer shadow-sm" onclick="bukaPaparanPenerimaDgnID(event)">
<a href="#" id="pautanSimulasi" class="text-blue-600 font-mono text-sm underline group-hover:text-blue-700 pointer-events-none"></a>
<span class="text-xs text-green-600 font-bold">BUKA →</span>
</div>
</div>
</div>
<div id="paparanPenerima" class="hidden">
<div class="border-b border-gray-200 pb-4 mb-6 flex justify-between items-center no-print">
<h3 class="text-xl sm:text-2xl font-bold text-gray-800 flex items-center tracking-wide">
<svg class="w-6 h-6 mr-3 text-blue-600" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"></path></svg>
Modul Pengesahan
</h3>
</div>
<div class="bg-gray-50 rounded-lg p-6 border border-gray-200 mb-8 relative shadow-sm">
<div class="absolute top-0 right-0 -mt-3 -mr-3 px-4 py-1 rounded text-xs font-bold tracking-wider shadow-sm border bg-yellow-100 text-yellow-800 border-yellow-300 z-10 no-print" id="statusLencana">
STATUS: PENDING
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-y-5 gap-x-6 text-sm">
<div>
<span class="block text-gray-500 text-xs font-bold uppercase tracking-wider mb-1">NO. RUJUKAN</span>
<span id="paparNoRujukan" class="font-mono text-gray-900 text-base font-medium"></span>
</div>
<div>
<span class="block text-gray-500 text-xs font-bold uppercase tracking-wider mb-1">TARIKH TRANSMISI</span>
<span id="paparTarikhSurat" class="text-gray-900 text-base font-medium"></span>
</div>
<div class="sm:col-span-2">
<span class="block text-gray-500 text-xs font-bold uppercase tracking-wider mb-1">PERKARA</span>
<span id="paparPerkaraUtama" class="text-gray-900 text-base font-medium"></span>
</div>
<div class="sm:col-span-2">
<span class="block text-gray-500 text-xs font-bold uppercase tracking-wider mb-1">BAHAGIAN PENERIMA</span>
<span id="paparBahagian" class="text-gray-900 text-base font-medium"></span>
</div>
<div class="sm:col-span-2 mt-4">
<span class="block text-gray-500 text-xs font-bold uppercase tracking-wider mb-2">SENARAI KAKITANGAN & BUTIRAN</span>
<div class="bg-white rounded-md border border-gray-300 overflow-hidden shadow-sm">
<table class="min-w-full divide-y divide-gray-200 text-sm">
<thead class="bg-gray-50">
<tr>
<th scope="col" class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase tracking-wider w-1/2">Nama Kakitangan</th>
<th scope="col" class="px-4 py-3 text-left text-xs font-bold text-gray-600 uppercase tracking-wider w-1/2 border-l border-gray-200">Butiran</th>
</tr>
</thead>
<tbody id="paparSenaraiKakitangan" class="bg-white divide-y divide-gray-200"></tbody>
</table>
</div>
</div>
</div>
</div>
<div id="borangInputPenerima" class="space-y-6 bg-white p-6 rounded-lg border border-gray-200 shadow-sm no-print">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="space-y-1.5">
<label for="namaPenerima" class="block text-sm font-semibold text-gray-700">Nama Penerima</label>
<input type="text" id="namaPenerima" class="form-input-clean w-full rounded-md px-4 py-3 text-sm">
</div>
<div class="space-y-1.5">
<label for="tarikhTerima" class="block text-sm font-semibold text-gray-700">Tarikh Terima</label>
<input type="date" id="tarikhTerima" class="form-input-clean w-full rounded-md px-4 py-3 text-sm">
</div>
</div>
<div class="pt-4 flex gap-4">
<button onclick="sahkanPenerimaan()" id="btnSahkan" class="flex-1 bg-green-600 hover:bg-green-700 text-white font-bold py-3 px-4 rounded-md shadow-sm transition-colors">
Sahkan Penerimaan
</button>
<button onclick="kembaliKeAdmin()" class="bg-white border border-gray-300 text-gray-700 hover:bg-gray-50 py-3 px-6 rounded-md transition-colors">
Batal
</button>
</div>
</div>
<div id="butiranPengesahanSelesai" class="hidden mt-6 bg-green-50 border border-green-200 p-6 rounded-lg shadow-sm relative overflow-hidden">
<div class="absolute left-0 top-0 bottom-0 w-1 bg-green-500 no-print"></div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-6 text-sm bg-white p-4 rounded border border-green-100 shadow-sm">
<div>
<span class="block text-gray-500 text-xs font-bold uppercase mb-1">DISAHKAN OLEH</span>
<span id="paparNamaDisahkan" class="text-gray-900 text-base font-semibold"></span>
</div>
<div>
<span class="block text-gray-500 text-xs font-bold uppercase mb-1">TARIKH PENGESAHAN</span>
<span id="paparTarikhDisahkan" class="text-gray-900 text-base font-semibold"></span>
</div>
</div>
</div>
<div class="print-only signature-area text-sm">
<div class="signature-box"><p>Tandatangan Penerima</p><br><br><br><p>Nama:</p><p>Tarikh:</p></div>
<div class="signature-box"><p>Cop Jabatan / Bahagian</p><br><br><br></div>
</div>
<div id="aksiSelepasSah" class="hidden mt-10 flex flex-col sm:flex-row gap-4 no-print border-t border-gray-200 pt-8">
<button onclick="cetakKePDF()" class="flex-1 bg-blue-600 hover:bg-blue-700 text-white font-bold py-3 px-4 rounded-md shadow-sm transition-colors">
Cetak Rekod (PDF)
</button>
<button onclick="kembaliKeAdmin()" class="bg-white border border-gray-300 text-gray-700 font-bold py-3 px-6 rounded-md transition-colors">
Kembali ke Borang Utama
</button>
</div>
</div>
</div>
</div>
<script>
// =========================================================================
// MAKLUMAT SUPABASE ANDA TELAH DIMASUKKAN DI SINI
// =========================================================================
const SUPABASE_URL = "https://iqzzrbfchpfbtqfjpopd.supabase.co";
const SUPABASE_ANON_KEY = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImlxenpyYmZjaHBmYnRxZmpwb3BkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODY0MTA0ODgsImV4cCI6MjEwMTk4NjQ4OH0.ewQvwAkCBAIO7jzGpm0tmGmwVR57Yhd26r8rV6JUiPA";
// =========================================================================
let idSemasa = "";
const pilihanButiranHTML =
'<option value="">-- Sila Pilih Butiran --</option>' +
'<option value="KEW.8 Pergerakkan Gaji Januari">KEW.8 Pergerakkan Gaji Januari</option>' +
'<option value="KEW.8 Pergerakkan Gaji April">KEW.8 Pergerakkan Gaji April</option>' +
'<option value="KEW.8 Pergerakkan Gaji Julai">KEW.8 Pergerakkan Gaji Julai</option>' +
'<option value="KEW.8 Pergerakkan Gaji Oktober">KEW.8 Pergerakkan Gaji Oktober</option>' +
'<option value="ITP">ITP</option>' +
'<option value="BIW">BIW</option>' +
'<option value="BIMLTK">BIMLTK</option>' +
'<option value="EL.Detektif">EL.Detektif</option>' +
'<option value="BITA">BITA</option>' +
'<option value="Kemajuan Pangkat L/Kpl">Kemajuan Pangkat L/Kpl</option>' +
'<option value="Kenaikan Pangkat KPL">Kenaikan Pangkat KPL</option>' +
'<option value="Kenaikan Pangkat SJN">Kenaikan Pangkat SJN</option>' +
'<option value="Kenaikan Pangkat SM">Kenaikan Pangkat SM</option>' +
'<option value="Kenaikan Pangkat Sub Insp">Kenaikan Pangkat Sub Insp</option>';
function tunjukMesej(mesej, jenis = 'ralat') {
const bekas = document.getElementById('toast-container');
const toast = document.createElement('div');
const bgColor = jenis === 'ralat' ? 'bg-red-600' : 'bg-green-600';
toast.className = 'flex items-center ' + bgColor + ' text-white px-5 py-3 rounded-md shadow-lg transform transition-all duration-300 translate-x-full opacity-0 font-medium text-sm';
toast.innerHTML = '<span>' + mesej + '</span>';
bekas.appendChild(toast);
setTimeout(() => { toast.classList.remove('translate-x-full', 'opacity-0'); toast.classList.add('translate-x-0', 'opacity-100'); }, 10);
setTimeout(() => { toast.classList.remove('translate-x-0', 'opacity-100'); toast.classList.add('translate-x-full', 'opacity-0'); setTimeout(() => toast.remove(), 300); }, 4000);
}
document.addEventListener("DOMContentLoaded", () => {
const today = new Date().toISOString().split('T')[0];
document.getElementById('tarikhSurat').value = today;
document.getElementById('tarikhTerima').value = today;
document.getElementById('butiranKelompok').innerHTML = pilihanButiranHTML;
document.getElementById('butiranSemua').innerHTML = pilihanButiranHTML;
tambahBarisKakitangan();
const urlParams = new URLSearchParams(window.location.search);
const idDariURL = urlParams.get('id');
if (idDariURL) bukaPaparanPenerima(idDariURL);
});
function tukarModKemasukan() {
const mod = document.querySelector('input[name="modKemasukan"]:checked').value;
document.getElementById('modIndividu').classList.add('hidden');
document.getElementById('modKelompok').classList.add('hidden');
document.getElementById('modSemua').classList.add('hidden');
if(mod === 'individu') document.getElementById('modIndividu').classList.remove('hidden');
else if(mod === 'kelompok') document.getElementById('modKelompok').classList.remove('hidden');
else if(mod === 'semua') document.getElementById('modSemua').classList.remove('hidden');
}
function tambahBarisKakitangan() {
const container = document.getElementById('bekasSenaraiKakitangan');
const row = document.createElement('div');
row.className = 'kakitangan-row flex flex-col sm:flex-row gap-3 items-start sm:items-center bg-gray-50 p-3 rounded-md border border-gray-200';
row.innerHTML =
'<div class="w-full sm:w-1/2">' +
'<input type="text" class="input-nama form-input-clean w-full rounded-md px-3 py-2 text-sm" placeholder="Nama Kakitangan...">' +
'</div>' +
'<div class="w-full sm:w-1/2 flex gap-2">' +
'<select class="input-butiran form-input-clean w-full rounded-md px-3 py-2 text-sm text-gray-700">' + pilihanButiranHTML + '</select>' +
'<button type="button" onclick="padamBarisKakitangan(this)" class="p-2 text-gray-400 hover:text-red-600 border rounded-md">X</button>' +
'</div>';
container.appendChild(row);
}
function padamBarisKakitangan(btn) {
const row = btn.closest('.kakitangan-row');
if (document.querySelectorAll('.kakitangan-row').length > 1) row.remove();
else { row.querySelector('.input-nama').value = ''; row.querySelector('.input-butiran').value = ''; }
}
function bukaSistemApp() {
document.body.classList.add('light-mode');
document.getElementById('hero-section').classList.add('hidden');
const app = document.getElementById('app-container');
app.classList.remove('hidden', 'fade-slide-hidden');
app.classList.add('fade-slide-active');
}
async function simpanDanJanaLink() {
const payloadData = {
noRujukan: document.getElementById('noRujukan').value.trim(),
tarikhSurat: document.getElementById('tarikhSurat').value,
perkaraUtama: document.getElementById('perkaraUtama').value,
bahagian: document.getElementById('bahagian').value,
senaraiKakitangan: [],
status: "PENDING",
namaPenerima: "",
tarikhTerima: "",
timestamp: Date.now()
};
const mod = document.querySelector('input[name="modKemasukan"]:checked').value;
if(!payloadData.noRujukan || !payloadData.perkaraUtama || !payloadData.bahagian) return tunjukMesej("Lengkapkan borang utama", "ralat");
if (mod === 'individu') {
document.querySelectorAll('.kakitangan-row').forEach(row => {
const nama = row.querySelector('.input-nama').value.trim();
const butiran = row.querySelector('.input-butiran').value;
if(nama && butiran) payloadData.senaraiKakitangan.push({ nama, butiran });
});
if(payloadData.senaraiKakitangan.length === 0) return tunjukMesej("Masukkan sekurang-kurangnya 1 nama & butiran", "ralat");
} else if (mod === 'kelompok') {
const butiran = document.getElementById('butiranKelompok').value;
const teksNama = document.getElementById('senaraiNamaKelompok').value;
if(!butiran || !teksNama.trim()) return tunjukMesej("Lengkapkan maklumat kelompok", "ralat");
teksNama.split('\n').forEach(n => { if(n.trim()) payloadData.senaraiKakitangan.push({ nama: n.trim(), butiran }); });
} else if (mod === 'semua') {
const butiran = document.getElementById('butiranSemua').value;
if(!butiran) return tunjukMesej("Pilih butiran", "ralat");
payloadData.senaraiKakitangan.push({ nama: "SEMUA KAKITANGAN", butiran });
}
const btn = document.getElementById('btnSimpan');
const textAsal = btn.innerHTML;
btn.innerHTML = 'Menyimpan...';
btn.disabled = true;
const newId = 'gaji-' + Math.random().toString(36).substring(2, 8);
try {
const res = await fetch(`${SUPABASE_URL}/rest/v1/rekod_gaji`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'apikey': SUPABASE_ANON_KEY,
'Authorization': `Bearer ${SUPABASE_ANON_KEY}`,
'Prefer': 'return=minimal'
},
body: JSON.stringify({ id: newId, data: payloadData })
});
if (!res.ok) throw new Error("Gagal hantar ke Supabase");
tunjukMesej("Berjaya Disimpan!", "sukses");
idSemasa = newId;
const realURL = window.location.origin + window.location.pathname + "?id=" + idSemasa;
const pautanSimulasi = document.getElementById('pautanSimulasi');
pautanSimulasi.innerText = realURL;
pautanSimulasi.href = realURL;
pautanSimulasi.setAttribute('data-id', idSemasa);
document.getElementById('ruanganLink').classList.remove('hidden');
} catch (e) {
tunjukMesej("Gagal berhubung dengan pangkalan data.", "ralat");
console.error(e);
} finally { btn.innerHTML = textAsal; btn.disabled = false; }
}
async function bukaPaparanPenerima(id) {
idSemasa = id;
document.body.classList.add('light-mode');
document.getElementById('hero-section').classList.add('hidden');
document.getElementById('app-container').classList.remove('hidden', 'fade-slide-hidden');
document.getElementById('app-container').classList.add('fade-slide-active');
document.getElementById('paparanAdmin').classList.add('hidden');
document.getElementById('paparanPenerima').classList.remove('hidden');
try {
const res = await fetch(`${SUPABASE_URL}/rest/v1/rekod_gaji?id=eq.${id}&select=data`, {
headers: {
'apikey': SUPABASE_ANON_KEY,
'Authorization': `Bearer ${SUPABASE_ANON_KEY}`
}
});
const result = await res.json();
if (result && result.length > 0) {
renderPaparanPenerima(result[0].data);
} else {
throw new Error("Gagal mencari data");
}
} catch (e) {
tunjukMesej("Ralat: Rekod tidak dijumpai dalam sistem", "ralat");
kembaliKeAdmin();
}
}
function renderPaparanPenerima(data) {
document.getElementById('paparNoRujukan').innerText = data.noRujukan;
document.getElementById('paparTarikhSurat').innerText = data.tarikhSurat;
document.getElementById('paparPerkaraUtama').innerText = data.perkaraUtama;
document.getElementById('paparBahagian').innerText = data.bahagian;
const jadual = document.getElementById('paparSenaraiKakitangan');
jadual.innerHTML = '';
data.senaraiKakitangan.forEach(staf => {
const namaText = staf.nama === "SEMUA KAKITANGAN" ? '<b>' + staf.nama + '</b>' : staf.nama;
jadual.innerHTML += '<tr><td class="px-4 py-2 border-r border-b border-gray-200">' + namaText + '</td><td class="px-4 py-2 border-b border-gray-200">' + staf.butiran + '</td></tr>';
});
const status = document.getElementById('statusLencana');
if(data.status === "VERIFIED") {
status.innerText = "STATUS: SAH";
status.className = "absolute top-0 right-0 -mt-3 -mr-3 px-4 py-1 rounded text-xs font-bold bg-green-100 text-green-800 border border-green-300 no-print";
document.getElementById('borangInputPenerima').classList.add('hidden');
document.getElementById('butiranPengesahanSelesai').classList.remove('hidden');
document.getElementById('aksiSelepasSah').classList.remove('hidden');
document.getElementById('paparNamaDisahkan').innerText = data.namaPenerima;
document.getElementById('paparTarikhDisahkan').innerText = data.tarikhTerima;
} else {
status.innerText = "STATUS: PENDING";
status.className = "absolute top-0 right-0 -mt-3 -mr-3 px-4 py-1 rounded text-xs font-bold bg-yellow-100 text-yellow-800 border border-yellow-300 no-print animate-pulse";
document.getElementById('borangInputPenerima').classList.remove('hidden');
document.getElementById('butiranPengesahanSelesai').classList.add('hidden');
document.getElementById('aksiSelepasSah').classList.add('hidden');
}
}
async function sahkanPenerimaan() {
const namaPenerima = document.getElementById('namaPenerima').value.trim();
const tarikhTerima = document.getElementById('tarikhTerima').value;
if(!namaPenerima || !tarikhTerima) return tunjukMesej("Sila isi Nama & Tarikh", "ralat");
const btn = document.getElementById('btnSahkan');
btn.innerHTML = 'Mengesahkan...';
btn.disabled = true;
try {
// Ambil data asal dari Supabase
const getRes = await fetch(`${SUPABASE_URL}/rest/v1/rekod_gaji?id=eq.${idSemasa}&select=data`, {
headers: { 'apikey': SUPABASE_ANON_KEY, 'Authorization': `Bearer ${SUPABASE_ANON_KEY}` }
});
const getResult = await getRes.json();
if (!getResult || getResult.length === 0) throw new Error("Data tidak dijumpai");
let dataDokumen = getResult[0].data;
dataDokumen.status = "VERIFIED";
dataDokumen.namaPenerima = namaPenerima;
dataDokumen.tarikhTerima = tarikhTerima;
dataDokumen.tarikhDisahkan = new Date().toISOString();
// Patch/Kemaskini data baharu ke Supabase
const patchRes = await fetch(`${SUPABASE_URL}/rest/v1/rekod_gaji?id=eq.${idSemasa}`, {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
'apikey': SUPABASE_ANON_KEY,
'Authorization': `Bearer ${SUPABASE_ANON_KEY}`,
'Prefer': 'return=minimal'
},
body: JSON.stringify({ data: dataDokumen })
});
if(!patchRes.ok) throw new Error("Gagal sahkan");
tunjukMesej("Berjaya Disahkan!", "sukses");
bukaPaparanPenerima(idSemasa);
} catch (e) {
tunjukMesej("Gagal mengemaskini status", "ralat");
console.error(e);
} finally { btn.innerHTML = 'Sahkan Penerimaan'; btn.disabled = false; }
}
function bukaPaparanPenerimaDgnID(e) { e.preventDefault(); bukaPaparanPenerima(e.currentTarget.querySelector('a').getAttribute('data-id')); }
function kembaliKeAdmin() { window.location.href = window.location.pathname; }
function kembaliKeHome() { window.location.href = window.location.pathname; }
function kosongkanBorangAdmin() { window.location.reload(); }
function cetakKePDF() { window.print(); }
</script>
</body>
</html>