taklimat ulangan+profil

This commit is contained in:
Saufi
2026-07-04 14:45:16 +08:00
parent e803f55b80
commit 0c134b9038
24 changed files with 2375 additions and 34 deletions

View File

@@ -22,5 +22,7 @@
<button type="submit" class="btn btn-penuh">Log Masuk</button>
</form>
<p class="teks-kecil mt-1"><a href="{{ route('password.request') }}">Lupa kata laluan?</a></p>
</div>
@endsection

View File

@@ -0,0 +1,25 @@
@extends('layouts.app')
@section('tajuk', 'Lupa Kata Laluan')
@section('saiz-container', 'container-kecil')
@section('kandungan')
<div class="kad">
<h1>Lupa Kata Laluan</h1>
<p class="teks-kecil">Masukkan e-mel akaun anda. Pautan set semula kata laluan akan dihantar ke e-mel tersebut.</p>
@if ($errors->any())
<div class="makluman makluman-ralat">{{ $errors->first() }}</div>
@endif
<form method="POST" action="{{ route('password.email') }}">
@csrf
<label for="email">E-mel</label>
<input type="email" id="email" name="email" value="{{ old('email') }}" required autofocus>
<button type="submit" class="btn btn-penuh">Hantar Pautan Set Semula</button>
</form>
<p class="teks-kecil mt-1"><a href="{{ route('login') }}">Kembali ke Log Masuk</a></p>
</div>
@endsection

View File

@@ -0,0 +1,30 @@
@extends('layouts.app')
@section('tajuk', 'Set Semula Kata Laluan')
@section('saiz-container', 'container-kecil')
@section('kandungan')
<div class="kad">
<h1>Set Semula Kata Laluan</h1>
@if ($errors->any())
<div class="makluman makluman-ralat">{{ $errors->first() }}</div>
@endif
<form method="POST" action="{{ route('password.update') }}">
@csrf
<input type="hidden" name="token" value="{{ $token }}">
<label for="email">E-mel</label>
<input type="email" id="email" name="email" value="{{ old('email', $email) }}" required autofocus>
<label for="password">Kata Laluan Baharu</label>
<input type="password" id="password" name="password" required minlength="8">
<label for="password_confirmation">Sahkan Kata Laluan Baharu</label>
<input type="password" id="password_confirmation" name="password_confirmation" required minlength="8">
<button type="submit" class="btn btn-penuh">Set Semula Kata Laluan</button>
</form>
</div>
@endsection

View File

@@ -0,0 +1,30 @@
@extends('layouts.app')
@section('tajuk', 'Pernah Hadir')
@section('saiz-container', 'container-kecil')
@section('kandungan')
<div class="kad teks-tengah">
<div class="makluman makluman-info">
Anda telah pun hadir taklimat sebelum ini. Tiada keperluan untuk daftar semula.
</div>
<p class="teks-kecil mb-0">Status</p>
<div class="slip-nombor">Pernah Hadir</div>
</div>
<div class="kad">
<table class="slip-butiran">
<tr><th>Nama</th><td><strong>{{ $petugas->nama_ic }}</strong></td></tr>
<tr><th>No. KP</th><td>{{ $petugas->no_kp }}</td></tr>
</table>
<h2 class="tajuk-jadual" style="margin-top:1.5rem;">Sesi Taklimat Sebelum Ini</h2>
<table class="slip-butiran">
<tr><th>DUN</th><td>{{ $sesiSebelumIni->dun->code ?? '' }} {{ $sesiSebelumIni->dun->nama ?? '-' }}</td></tr>
<tr><th>Sesi</th><td>{{ $sesiSebelumIni->nama }} ({{ $sesiSebelumIni->tarikh->format('d/m/Y') }})</td></tr>
<tr><th>Lokasi</th><td>{{ $sesiSebelumIni->lokasi }}</td></tr>
<tr><th>Nombor Siri</th><td>{{ $kehadiranSebelumIni->nombor_siri_papar }}</td></tr>
<tr><th>Masa Daftar</th><td>{{ $kehadiranSebelumIni->hadir_at->format('d/m/Y h:i A') }}</td></tr>
</table>
</div>
@endsection

View File

@@ -13,8 +13,20 @@
Kehadiran Taklimat SPR 2026
</a>
@auth
@php
$labelPeranan = match (auth()->user()->role) {
'admin' => 'Admin',
'pengurus' => 'Pengurus DUN',
'kaunter' => 'Kaunter',
default => auth()->user()->role,
};
@endphp
<div class="pengguna">
<span>{{ auth()->user()->name }} ({{ auth()->user()->role === 'admin' ? 'Admin' : 'Pengurus DUN' }})</span>
@if (auth()->user()->isAdmin() || auth()->user()->isPengurus())
<a href="{{ route('pengguna.index') }}">Pengguna</a>
@endif
<a href="{{ route('profil.edit') }}">Profil</a>
<span>{{ auth()->user()->name }} ({{ $labelPeranan }})</span>
<form method="POST" action="{{ route('logout') }}" style="margin:0">
@csrf
<button type="submit" class="btn btn-kecil btn-merah">Log Keluar</button>

View File

@@ -0,0 +1,82 @@
@extends('layouts.app')
@section('tajuk', 'Daftar Pengguna Baharu')
@section('saiz-container', 'container-kecil')
@section('kandungan')
<div class="kad">
<h1>Daftar Pengguna Baharu</h1>
@unless (auth()->user()->isAdmin())
<p class="teks-kecil">Pengguna yang didaftarkan akan ditetapkan untuk DUN anda sendiri.</p>
@endunless
@if ($errors->any())
<div class="makluman makluman-ralat">{{ $errors->first() }}</div>
@endif
<form method="POST" action="{{ route('pengguna.store') }}">
@csrf
<label for="name">Nama</label>
<input type="text" id="name" name="name" value="{{ old('name') }}" required autofocus>
<label for="email">E-mel</label>
<input type="email" id="email" name="email" value="{{ old('email') }}" required>
<label for="role">Peranan</label>
<select id="role" name="role" required>
<option value=""> Pilih Peranan </option>
@foreach ($peranan as $kod)
<option value="{{ $kod }}" @selected(old('role') === $kod)>
{{ match ($kod) {
'admin' => 'Admin',
'pengurus' => 'Pengurus DUN',
'kaunter' => 'Kaunter',
default => $kod,
} }}
</option>
@endforeach
</select>
@if (auth()->user()->isAdmin())
<div id="baris-dun">
<label for="dun_id">DUN</label>
<select id="dun_id" name="dun_id">
<option value=""> Pilih DUN </option>
@foreach ($senaraiDun as $dun)
<option value="{{ $dun->id }}" @selected(old('dun_id') == $dun->id)>
{{ $dun->code }} {{ $dun->nama }}
</option>
@endforeach
</select>
</div>
@endif
<label for="password">Kata Laluan</label>
<input type="password" id="password" name="password" required minlength="8">
<label for="password_confirmation">Sahkan Kata Laluan</label>
<input type="password" id="password_confirmation" name="password_confirmation" required minlength="8">
<button type="submit" class="btn btn-penuh">Daftar Pengguna</button>
</form>
</div>
@if (auth()->user()->isAdmin())
<script>
(function () {
var role = document.getElementById('role');
var barisDun = document.getElementById('baris-dun');
var dunSelect = document.getElementById('dun_id');
function kemaskini() {
var perluDun = role.value !== '' && role.value !== 'admin';
barisDun.style.display = perluDun ? '' : 'none';
dunSelect.required = perluDun;
}
role.addEventListener('change', kemaskini);
kemaskini();
})();
</script>
@endif
@endsection

View File

@@ -0,0 +1,48 @@
@extends('layouts.app')
@section('tajuk', 'Senarai Pengguna')
@section('kandungan')
<div class="kad">
<div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:0.5rem;">
<h1 class="mb-0">Pengguna</h1>
<a href="{{ route('pengguna.create') }}" class="btn">+ Daftar Pengguna</a>
</div>
</div>
@if ($pengguna->isEmpty())
<div class="kad teks-tengah">
<p>Tiada pengguna lagi.</p>
</div>
@else
<div class="kad" style="overflow-x:auto; padding:0;">
<table class="jadual">
<thead>
<tr>
<th>Nama</th>
<th>E-mel</th>
<th>Peranan</th>
<th>DUN</th>
</tr>
</thead>
<tbody>
@foreach ($pengguna as $p)
<tr>
<td>{{ $p->name }}</td>
<td>{{ $p->email }}</td>
<td>
{{ match ($p->role) {
'admin' => 'Admin',
'pengurus' => 'Pengurus DUN',
'kaunter' => 'Kaunter',
default => $p->role,
} }}
</td>
<td>{{ $p->dun ? $p->dun->code . ' — ' . $p->dun->nama : '-' }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
@endif
@endsection

View File

@@ -13,13 +13,17 @@
<div class="stat-grid">
<div class="stat">
<div class="nilai">{{ $hadir->count() + $tidakHadir->count() }}</div>
<div class="nilai">{{ $hadir->count() + $hadirSesiLain->count() + $tidakHadir->count() }}</div>
<div class="label">Jumlah Petugas</div>
</div>
<div class="stat">
<div class="nilai" style="color:var(--hijau)">{{ $hadir->count() }}</div>
<div class="label">Hadir</div>
</div>
<div class="stat">
<div class="nilai" style="color:var(--kuning)">{{ $hadirSesiLain->count() }}</div>
<div class="label">Pernah Hadir (Sesi Lain)</div>
</div>
<div class="stat">
<div class="nilai" style="color:var(--merah)">{{ $tidakHadir->count() }}</div>
<div class="label">Tidak / Belum Hadir</div>
@@ -81,6 +85,55 @@
</div>
</div>
{{-- ============= PERNAH HADIR (SESI LAIN) ============= --}}
<div class="kad jadual-kad" data-alat data-per-page="10" style="padding:0;">
<div class="jadual-kepala">
<h2 class="tajuk-jadual kuning">PERNAH HADIR - SESI LAIN ({{ $hadirSesiLain->count() }})</h2>
<input type="text" class="cari-input tiada-cetak" data-cari
placeholder="Cari nama, telefon, pusat mengundi…" aria-label="Cari senarai pernah hadir sesi lain">
</div>
<div class="jadual-bekas">
<table class="jadual jadual-responsif">
<thead>
<tr>
<th>Nama</th>
<th>No. Telefon</th>
<th>Emel</th>
<th>Pusat Mengundi</th>
<th>Saluran</th>
<th>Jawatan</th>
<th>Sesi Dihadiri</th>
<th>Tarikh Hadir</th>
</tr>
</thead>
<tbody>
@forelse ($hadirSesiLain as $p)
@php
$penempatan = $p->butiranPenempatan();
$rekod = $kehadiranSesiLain->get($p->id);
@endphp
<tr class="baris-data">
<td data-label="Nama">{{ $p->nama_ic }}</td>
<td data-label="No. Telefon">{{ $p->no_telefon ?? '-' }}</td>
<td data-label="Emel">{{ $p->emel ?? '-' }}</td>
<td data-label="Pusat Mengundi">{{ $penempatan['pusat_mengundi'] }}</td>
<td data-label="Saluran">{{ $penempatan['saluran'] }}</td>
<td data-label="Jawatan">{{ $penempatan['jawatan'] }}</td>
<td data-label="Sesi Dihadiri">{{ $rekod?->sesi?->nama }}</td>
<td data-label="Tarikh Hadir">{{ $rekod?->hadir_at?->format('d/m/Y') }}</td>
</tr>
@empty
<tr class="baris-tiada"><td colspan="8" class="teks-tengah">Tiada petugas dalam kumpulan ini.</td></tr>
@endforelse
</tbody>
</table>
</div>
<div class="jadual-kaki tiada-cetak">
<span class="teks-kecil" data-info></span>
<div class="paging" data-pager></div>
</div>
</div>
{{-- ================ TIDAK / BELUM HADIR ================ --}}
<div class="kad jadual-kad" data-alat data-per-page="10" style="padding:0;">
<div class="jadual-kepala">

View File

@@ -0,0 +1,52 @@
@extends('layouts.app')
@section('tajuk', 'Profil Saya')
@section('saiz-container', 'container-kecil')
@section('kandungan')
<div class="kad">
<h1>Profil Saya</h1>
<table class="slip-butiran">
<tr><th>Nama</th><td>{{ $pengguna->name }}</td></tr>
<tr><th>E-mel</th><td>{{ $pengguna->email }}</td></tr>
<tr>
<th>Peranan</th>
<td>
{{ match ($pengguna->role) {
'admin' => 'Admin',
'pengurus' => 'Pengurus DUN',
'kaunter' => 'Kaunter',
default => $pengguna->role,
} }}
@if ($pengguna->dun)
{{ $pengguna->dun->code }} {{ $pengguna->dun->nama }}
@endif
</td>
</tr>
</table>
</div>
<div class="kad">
<h2 class="mb-0">Tukar Kata Laluan</h2>
@if ($errors->any())
<div class="makluman makluman-ralat">{{ $errors->first() }}</div>
@endif
<form method="POST" action="{{ route('profil.kata-laluan') }}">
@csrf
@method('PUT')
<label for="kata_laluan_semasa">Kata Laluan Semasa</label>
<input type="password" id="kata_laluan_semasa" name="kata_laluan_semasa" required>
<label for="kata_laluan_baharu">Kata Laluan Baharu</label>
<input type="password" id="kata_laluan_baharu" name="kata_laluan_baharu" required minlength="8">
<label for="kata_laluan_baharu_confirmation">Sahkan Kata Laluan Baharu</label>
<input type="password" id="kata_laluan_baharu_confirmation" name="kata_laluan_baharu_confirmation" required minlength="8">
<button type="submit" class="btn btn-penuh">Kemaskini Kata Laluan</button>
</form>
</div>
@endsection

View File

@@ -6,10 +6,12 @@
<div class="kad">
<div style="display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:0.5rem;">
<h1 class="mb-0">Sesi Taklimat</h1>
<div class="baris-tindakan">
<a href="{{ route('sesi.eksport') }}" class="btn btn-luar"> Export Kehadiran</a>
<a href="{{ route('sesi.create') }}" class="btn">+ Cipta Sesi</a>
</div>
@unless (auth()->user()->isKaunter())
<div class="baris-tindakan">
<a href="{{ route('sesi.eksport') }}" class="btn btn-luar"> Export Kehadiran</a>
<a href="{{ route('sesi.create') }}" class="btn">+ Cipta Sesi</a>
</div>
@endunless
</div>
</div>

View File

@@ -32,12 +32,14 @@
<a href="{{ route('sesi.qr', $sesi) }}" class="btn">Papar / Cetak QR Code</a>
<a href="{{ route('kaunter.index', $sesi) }}" class="btn btn-hijau">Kaunter Borang</a>
<a href="{{ route('pengurus.senarai', $sesi) }}" class="btn btn-luar">Senarai Kehadiran</a>
<form method="POST" action="{{ route('sesi.toggle', $sesi) }}" style="margin:0">
@csrf
<button type="submit" class="btn {{ $sesi->is_active ? 'btn-merah' : 'btn-hijau' }}">
{{ $sesi->is_active ? 'Tutup Pendaftaran' : 'Buka Pendaftaran' }}
</button>
</form>
@unless (auth()->user()->isKaunter())
<form method="POST" action="{{ route('sesi.toggle', $sesi) }}" style="margin:0">
@csrf
<button type="submit" class="btn {{ $sesi->is_active ? 'btn-merah' : 'btn-hijau' }}">
{{ $sesi->is_active ? 'Tutup Pendaftaran' : 'Buka Pendaftaran' }}
</button>
</form>
@endunless
</div>
</div>