Compare commits
2 Commits
dfd22ff2af
...
57c20353c7
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
57c20353c7 | ||
|
|
cd5cfb49a9 |
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\KehadiranKtm;
|
||||||
use App\Models\Sppm\Dun;
|
use App\Models\Sppm\Dun;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
@@ -65,4 +66,21 @@ class PenggunaController extends Controller
|
|||||||
|
|
||||||
return redirect()->route('pengguna.index')->with('status', 'Pengguna baharu berjaya didaftarkan.');
|
return redirect()->route('pengguna.index')->with('status', 'Pengguna baharu berjaya didaftarkan.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function destroy(Request $request, User $pengguna)
|
||||||
|
{
|
||||||
|
if ($pengguna->id === $request->user()->id) {
|
||||||
|
return back()->withErrors(['pengguna' => 'Anda tidak boleh memadam akaun anda sendiri.']);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (KehadiranKtm::where('dicatat_oleh_user_id', $pengguna->id)->exists()) {
|
||||||
|
return back()->withErrors([
|
||||||
|
'pengguna' => "Pengguna {$pengguna->name} tidak boleh dipadam kerana telah mencatat rekod kehadiran.",
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$pengguna->delete();
|
||||||
|
|
||||||
|
return redirect()->route('pengguna.index')->with('status', "Pengguna {$pengguna->name} telah dipadam.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
@section('tajuk', 'Dashboard Kehadiran KTM')
|
@section('tajuk', 'Dashboard Kehadiran KTM')
|
||||||
|
|
||||||
@section('kandungan')
|
@section('kandungan')
|
||||||
<div class="stat-grid">
|
<div class="stat-grid" id="stat-grid">
|
||||||
<div class="stat">
|
<div class="stat">
|
||||||
<div class="nilai">{{ $jumlahSemua }}</div>
|
<div class="nilai">{{ $jumlahSemua }}</div>
|
||||||
<div class="label">Jumlah KTM</div>
|
<div class="label">Jumlah KTM</div>
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="kad">
|
<div class="kad">
|
||||||
<form method="GET" action="{{ route('dashboard') }}">
|
<form method="GET" action="{{ route('dashboard') }}" id="borang-tapis">
|
||||||
<div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:0 0.75rem;">
|
<div style="display:grid; grid-template-columns:repeat(auto-fit, minmax(180px, 1fr)); gap:0 0.75rem;">
|
||||||
@if (auth()->user()->isSuperadmin())
|
@if (auth()->user()->isSuperadmin())
|
||||||
<div>
|
<div>
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="kad" style="padding:0;">
|
<div class="kad" style="padding:0;" id="senarai-ktm">
|
||||||
<div class="jadual-kepala">
|
<div class="jadual-kepala">
|
||||||
<h2 class="tajuk-jadual mb-0">Senarai KTM (Ketua Tempat Mengundi)</h2>
|
<h2 class="tajuk-jadual mb-0">Senarai KTM (Ketua Tempat Mengundi)</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -145,4 +145,66 @@
|
|||||||
<span class="teks-kecil">{{ $assignments->count() }} rekod dipaparkan</span>
|
<span class="teks-kecil">{{ $assignments->count() }} rekod dipaparkan</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
var borang = document.getElementById('borang-tapis');
|
||||||
|
var inputCari = document.getElementById('q');
|
||||||
|
var pilihPusat = document.getElementById('pusat_id');
|
||||||
|
var pilihStatus = document.getElementById('status');
|
||||||
|
var timer = null;
|
||||||
|
var fetchSemasa = null;
|
||||||
|
|
||||||
|
// Cari terus semasa menaip (AJAX) — butang Cari kekal sebagai fallback tanpa JS.
|
||||||
|
function cariSekarang() {
|
||||||
|
var params = new URLSearchParams(new FormData(borang));
|
||||||
|
var url = borang.action + (params.toString() ? '?' + params.toString() : '');
|
||||||
|
|
||||||
|
if (fetchSemasa) {
|
||||||
|
fetchSemasa.abort();
|
||||||
|
}
|
||||||
|
fetchSemasa = new AbortController();
|
||||||
|
|
||||||
|
document.getElementById('senarai-ktm').style.opacity = '0.5';
|
||||||
|
|
||||||
|
fetch(url, {
|
||||||
|
headers: { 'X-Requested-With': 'XMLHttpRequest' },
|
||||||
|
signal: fetchSemasa.signal,
|
||||||
|
})
|
||||||
|
.then(function (r) { return r.text(); })
|
||||||
|
.then(function (html) {
|
||||||
|
var doc = new DOMParser().parseFromString(html, 'text/html');
|
||||||
|
['stat-grid', 'senarai-ktm'].forEach(function (id) {
|
||||||
|
var baru = doc.getElementById(id);
|
||||||
|
if (baru) {
|
||||||
|
document.getElementById(id).replaceWith(baru);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Kekalkan URL supaya refresh/eksport/set-semula konsisten
|
||||||
|
window.history.replaceState(null, '', url);
|
||||||
|
})
|
||||||
|
.catch(function (e) {
|
||||||
|
if (e.name !== 'AbortError') {
|
||||||
|
borang.submit(); // fallback: muat semula penuh
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function cariLewat() {
|
||||||
|
clearTimeout(timer);
|
||||||
|
timer = setTimeout(cariSekarang, 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
inputCari.addEventListener('input', cariLewat);
|
||||||
|
pilihPusat.addEventListener('change', cariSekarang);
|
||||||
|
pilihStatus.addEventListener('change', cariSekarang);
|
||||||
|
|
||||||
|
// Elak penghantaran borang penuh bila tekan Enter dalam kotak carian
|
||||||
|
borang.addEventListener('submit', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
clearTimeout(timer);
|
||||||
|
cariSekarang();
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@if ($errors->any())
|
||||||
|
<div class="makluman makluman-ralat">{{ $errors->first() }}</div>
|
||||||
|
@endif
|
||||||
|
|
||||||
@if ($pengguna->isEmpty())
|
@if ($pengguna->isEmpty())
|
||||||
<div class="kad teks-tengah">
|
<div class="kad teks-tengah">
|
||||||
<p>Tiada pengguna lagi.</p>
|
<p>Tiada pengguna lagi.</p>
|
||||||
@@ -23,6 +27,7 @@
|
|||||||
<th>E-mel</th>
|
<th>E-mel</th>
|
||||||
<th>Peranan</th>
|
<th>Peranan</th>
|
||||||
<th>DUN</th>
|
<th>DUN</th>
|
||||||
|
<th>Tindakan</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -38,6 +43,18 @@
|
|||||||
} }}
|
} }}
|
||||||
</td>
|
</td>
|
||||||
<td>{{ $p->dun ? $p->dun->code . ' — ' . $p->dun->nama : '-' }}</td>
|
<td>{{ $p->dun ? $p->dun->code . ' — ' . $p->dun->nama : '-' }}</td>
|
||||||
|
<td>
|
||||||
|
@if ($p->id === auth()->id())
|
||||||
|
<span class="teks-kecil">(akaun anda)</span>
|
||||||
|
@else
|
||||||
|
<form method="POST" action="{{ route('pengguna.destroy', $p) }}" style="margin:0"
|
||||||
|
onsubmit="return confirm('Padam pengguna {{ $p->name }}? Tindakan ini tidak boleh dikembalikan.');">
|
||||||
|
@csrf
|
||||||
|
@method('DELETE')
|
||||||
|
<button type="submit" class="btn btn-kecil btn-merah">Padam</button>
|
||||||
|
</form>
|
||||||
|
@endif
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -44,5 +44,6 @@ Route::middleware(['auth'])->group(function () {
|
|||||||
Route::get('/pengguna', [PenggunaController::class, 'index'])->name('pengguna.index');
|
Route::get('/pengguna', [PenggunaController::class, 'index'])->name('pengguna.index');
|
||||||
Route::get('/pengguna/cipta', [PenggunaController::class, 'create'])->name('pengguna.create');
|
Route::get('/pengguna/cipta', [PenggunaController::class, 'create'])->name('pengguna.create');
|
||||||
Route::post('/pengguna', [PenggunaController::class, 'store'])->name('pengguna.store');
|
Route::post('/pengguna', [PenggunaController::class, 'store'])->name('pengguna.store');
|
||||||
|
Route::delete('/pengguna/{pengguna}', [PenggunaController::class, 'destroy'])->name('pengguna.destroy');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user