first
This commit is contained in:
52
resources/views/admin/attendance/index.blade.php
Normal file
52
resources/views/admin/attendance/index.blade.php
Normal file
@@ -0,0 +1,52 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Dashboard Kehadiran')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<h1 class="h3 mb-1">Dashboard Kehadiran</h1>
|
||||
<p class="text-secondary mb-0">Ringkasan kehadiran mengikut Pusat Mengundi.</p>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-0 overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<x-sort-th column="name" label="Pusat Mengundi" />
|
||||
<th>Staf</th>
|
||||
<th>Hadir</th>
|
||||
<th>Tidak Hadir</th>
|
||||
<th>Belum Rekod</th>
|
||||
<th>Status Modul</th>
|
||||
<th class="text-end no-sort">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($pusats as $pusat)
|
||||
@php($summary = $summaryService->totalsForPusat($pusat))
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $pusat->code }} - {{ $pusat->name }}</div>
|
||||
<div class="small text-secondary">{{ $pusat->election?->name }}</div>
|
||||
</td>
|
||||
<td>{{ $summary['total_staff'] }}</td>
|
||||
<td><span class="badge text-bg-success">{{ $summary['present'] }}</span></td>
|
||||
<td><span class="badge text-bg-danger">{{ $summary['absent'] }}</span></td>
|
||||
<td><span class="badge text-bg-warning">{{ $summary['not_recorded'] }}</span></td>
|
||||
<td><span class="badge {{ $pusat->election?->settings?->is_attendance_active ? 'text-bg-success' : 'text-bg-secondary' }}">{{ $pusat->election?->settings?->is_attendance_active ? 'Aktif' : 'Belum aktif' }}</span></td>
|
||||
<td class="text-end">
|
||||
<a class="btn btn-sm btn-outline-primary" href="{{ route('admin.attendance.show', $pusat) }}">Detail</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-secondary py-4">Tiada Pusat Mengundi.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">{{ $pusats->links() }}</div>
|
||||
@endsection
|
||||
86
resources/views/admin/attendance/show.blade.php
Normal file
86
resources/views/admin/attendance/show.blade.php
Normal file
@@ -0,0 +1,86 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Detail Kehadiran')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Detail Kehadiran</h1>
|
||||
<p class="text-secondary mb-0">{{ $pusat->code }} - {{ $pusat->name }}</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<a class="btn btn-outline-secondary" href="{{ route('admin.attendance.index') }}">Kembali</a>
|
||||
<a class="btn btn-primary" href="{{ route('admin.attendance.export', $pusat) }}"><i class="bi bi-download me-1"></i>Export</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-4">
|
||||
@foreach ([
|
||||
['label' => 'Staf', 'value' => $summary['total_staff'], 'tone' => 'primary'],
|
||||
['label' => 'Hadir', 'value' => $summary['present'], 'tone' => 'success'],
|
||||
['label' => 'Tidak hadir', 'value' => $summary['absent'], 'tone' => 'danger'],
|
||||
['label' => 'Belum rekod', 'value' => $summary['not_recorded'], 'tone' => 'warning'],
|
||||
] as $card)
|
||||
<div class="col-6 col-xl-3">
|
||||
<div class="stat-card h-100">
|
||||
<div class="text-secondary small">{{ $card['label'] }}</div>
|
||||
<div class="fs-3 fw-bold mt-2 text-{{ $card['tone'] }}">{{ $card['value'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-3 p-md-4 mb-4">
|
||||
<h2 class="h5 mb-3">Ringkasan Mengikut Jawatan</h2>
|
||||
<div class="row g-2">
|
||||
@foreach ($roleSummaries as $roleSummary)
|
||||
<div class="col-12 col-md-6 col-xl-3">
|
||||
<div class="border rounded p-3 h-100">
|
||||
<div class="fw-semibold">{{ $roleSummary['role'] }}</div>
|
||||
<div class="small text-secondary">Staf {{ $roleSummary['total_staff'] }} · Hadir {{ $roleSummary['present'] }} · Tidak hadir {{ $roleSummary['absent'] }} · Belum {{ $roleSummary['not_recorded'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-0 overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Staf</th>
|
||||
<th>Jawatan</th>
|
||||
<th>Saluran</th>
|
||||
<th>Status</th>
|
||||
<th>Masa Check-in</th>
|
||||
<th>Catatan</th>
|
||||
<th>Direkod Oleh</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($assignments as $assignment)
|
||||
@php($attendance = $assignment->attendance)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $assignment->application?->name ?: $assignment->user?->name ?: 'Tanpa nama' }}</div>
|
||||
<div class="small text-secondary">{{ $assignment->application?->ic_number ?: $assignment->user?->email ?: '-' }}</div>
|
||||
</td>
|
||||
<td>{{ $assignment->position?->code }}</td>
|
||||
<td>{{ $assignment->saluranMengundi?->number ?: '-' }}</td>
|
||||
<td><span class="badge text-bg-secondary">{{ str_replace('_', ' ', $attendance?->status ?? 'not_recorded') }}</span></td>
|
||||
<td>{{ $attendance?->check_in_time?->format('d/m/Y H:i') ?: '-' }}</td>
|
||||
<td>{{ $attendance?->note ?: '-' }}</td>
|
||||
<td>{{ $attendance?->recordedBy?->name ?: '-' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-secondary py-4">Tiada staf aktif.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
22
resources/views/admin/management/_nav.blade.php
Normal file
22
resources/views/admin/management/_nav.blade.php
Normal file
@@ -0,0 +1,22 @@
|
||||
<div class="content-panel mb-4 p-2">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.management.index') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.management.index') }}">
|
||||
<i class="bi bi-grid me-1"></i>Ringkasan
|
||||
</a>
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.management.applications.*') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.management.applications.index') }}">
|
||||
<i class="bi bi-file-earmark-person me-1"></i>Permohonan
|
||||
</a>
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.management.assignments.*') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.management.assignments.index') }}">
|
||||
<i class="bi bi-person-lines-fill me-1"></i>Tugasan
|
||||
</a>
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.management.penempatan.*') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.dashboard') }}">
|
||||
<i class="bi bi-people-fill me-1"></i>Penempatan
|
||||
</a>
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.management.representatives.*') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.management.representatives.index') }}">
|
||||
<i class="bi bi-building-check me-1"></i>Wakil Agensi
|
||||
</a>
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.management.wheelchairs.*') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.management.wheelchairs.index') }}">
|
||||
<i class="bi bi-universal-access me-1"></i>Kerusi Roda
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,48 @@
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="assign_position_id">Jawatan</label>
|
||||
<select class="form-select" id="assign_position_id" name="position_id" required>
|
||||
@foreach ($positions as $position)
|
||||
<option value="{{ $position->id }}" @selected(old('position_id', $application->approved_position_id ?: $application->requested_position_id) == $position->id)>{{ $position->code }} - {{ $position->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="assign_pusat_mengundi_id">Pusat Mengundi</label>
|
||||
<select class="form-select" id="assign_pusat_mengundi_id" name="pusat_mengundi_id" required>
|
||||
@foreach ($pusats as $pusat)
|
||||
<option value="{{ $pusat->id }}" @selected(old('pusat_mengundi_id', $application->pusat_mengundi_id) == $pusat->id)>{{ $pusat->code }} - {{ $pusat->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="assign_saluran_mengundi_id">Saluran</label>
|
||||
<select class="form-select" id="assign_saluran_mengundi_id" name="saluran_mengundi_id">
|
||||
<option value="">Pusat level / ikut KTM</option>
|
||||
@foreach ($salurans as $saluran)
|
||||
<option value="{{ $saluran->id }}" @selected(old('saluran_mengundi_id', $application->staffAssignments->first()?->saluran_mengundi_id) == $saluran->id)>{{ $saluran->pusatMengundi?->code }} - Saluran {{ $saluran->number }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="reports_to_assignment_id">KTM Ketua</label>
|
||||
<select class="form-select" id="reports_to_assignment_id" name="reports_to_assignment_id">
|
||||
<option value="">Tiada</option>
|
||||
@foreach ($ktmAssignments as $ktm)
|
||||
<option value="{{ $ktm->id }}" @selected(old('reports_to_assignment_id', $application->selected_ktm_assignment_id) == $ktm->id)>{{ $ktm->user?->name ?? 'KTM' }} - {{ $ktm->pusatMengundi?->code }} / Saluran {{ $ktm->saluranMengundi?->number }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="assign_status">Status Tugasan</label>
|
||||
<select class="form-select" id="assign_status" name="status">
|
||||
@foreach (['active', 'inactive', 'replaced', 'cancelled'] as $status)
|
||||
<option value="{{ $status }}">{{ $status }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="assign_note">Catatan</label>
|
||||
<textarea class="form-control" id="assign_note" name="note" rows="2" placeholder="Wajib selepas tempoh pendaftaran ditutup">{{ old('note') }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,86 @@
|
||||
@php($isEdit = $application->exists)
|
||||
|
||||
<div class="row g-3">
|
||||
@unless($isEdit)
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="election_id">Pilihanraya</label>
|
||||
<select class="form-select" id="election_id" name="election_id" required>
|
||||
@foreach ($elections as $election)
|
||||
<option value="{{ $election->id }}" @selected(old('election_id', $application->election_id) == $election->id)>{{ $election->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
@endunless
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="pusat_mengundi_id">Pusat Mengundi</label>
|
||||
<select class="form-select" id="pusat_mengundi_id" name="pusat_mengundi_id" required>
|
||||
@foreach ($pusats as $pusat)
|
||||
<option value="{{ $pusat->id }}" @selected(old('pusat_mengundi_id', $application->pusat_mengundi_id) == $pusat->id)>{{ $pusat->code }} - {{ $pusat->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="requested_position_id">Jawatan Dipohon</label>
|
||||
<select class="form-select" id="requested_position_id" name="requested_position_id" required>
|
||||
@foreach ($positions as $position)
|
||||
<option value="{{ $position->id }}" @selected(old('requested_position_id', $application->requested_position_id) == $position->id)>{{ $position->code }} - {{ $position->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@if($isEdit)
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="approved_position_id">Jawatan Diluluskan</label>
|
||||
<select class="form-select" id="approved_position_id" name="approved_position_id">
|
||||
<option value="">Belum diluluskan</option>
|
||||
@foreach ($positions as $position)
|
||||
<option value="{{ $position->id }}" @selected(old('approved_position_id', $application->approved_position_id) == $position->id)>{{ $position->code }} - {{ $position->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="status">Status</label>
|
||||
<select class="form-select" id="status" name="status" required>
|
||||
@foreach (['draft', 'submitted', 'under_ppm_review', 'approved', 'rejected', 'assigned', 'cancelled'] as $status)
|
||||
<option value="{{ $status }}" @selected(old('status', $application->status) === $status)>{{ str_replace('_', ' ', $status) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="name">Nama</label>
|
||||
<input class="form-control" id="name" name="name" value="{{ old('name', $application->name) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="ic_number">No. IC</label>
|
||||
<input class="form-control" id="ic_number" name="ic_number" value="{{ old('ic_number', $application->ic_number) }}" maxlength="12" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="phone_number">Telefon</label>
|
||||
<input class="form-control" id="phone_number" name="phone_number" value="{{ old('phone_number', $application->phone_number) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="email">Email</label>
|
||||
<input class="form-control" id="email" name="email" type="email" value="{{ old('email', $application->email) }}">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="address">Alamat</label>
|
||||
<textarea class="form-control" id="address" name="address" rows="2">{{ old('address', $application->address) }}</textarea>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="bank_name">Bank</label>
|
||||
<input class="form-control" id="bank_name" name="bank_name" value="{{ old('bank_name', $application->bank_name) }}">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="bank_account_number">No. Akaun Bank</label>
|
||||
<input class="form-control" id="bank_account_number" name="bank_account_number" value="{{ old('bank_account_number', $application->bank_account_number) }}">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="note">Catatan</label>
|
||||
<textarea class="form-control" id="note" name="note" rows="2" placeholder="Wajib selepas tempoh pendaftaran ditutup">{{ old('note') }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,24 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Manual Entry')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<h1 class="h3 mb-1">Manual Entry Permohonan</h1>
|
||||
<p class="text-secondary mb-0">Rekod yang dimasukkan Admin tidak menghantar email permintaan butiran bank.</p>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.management.applications.store') }}">
|
||||
@csrf
|
||||
@include('admin.management.applications._form')
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a class="btn btn-outline-secondary" href="{{ route('admin.management.applications.index') }}">Batal</a>
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-save me-1"></i>Simpan</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
77
resources/views/admin/management/applications/edit.blade.php
Normal file
77
resources/views/admin/management/applications/edit.blade.php
Normal file
@@ -0,0 +1,77 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Permohonan')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Edit Permohonan</h1>
|
||||
<p class="text-secondary mb-0">{{ $application->name }} · {{ $application->public_uuid }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<h2 class="h5 mb-3">Maklumat Pemohon</h2>
|
||||
<form method="POST" action="{{ route('admin.management.applications.update', $application->public_uuid) }}">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
@include('admin.management.applications._form')
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a class="btn btn-outline-secondary" href="{{ route('admin.management.applications.index') }}">Kembali</a>
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-save me-1"></i>Kemas Kini</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-5">
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<h2 class="h5 mb-3">Direct Assignment</h2>
|
||||
<form method="POST" action="{{ route('admin.management.applications.assign', $application->public_uuid) }}">
|
||||
@csrf
|
||||
@include('admin.management.applications._assignment_form')
|
||||
<div class="d-flex justify-content-end mt-4">
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-person-check me-1"></i>Assign</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-3 p-md-4 mt-3">
|
||||
<h2 class="h6 mb-3">Sejarah Status</h2>
|
||||
<div class="list-group list-group-flush">
|
||||
@forelse ($application->statusHistories->sortByDesc('created_at') as $history)
|
||||
<div class="list-group-item px-0">
|
||||
<div class="fw-semibold">{{ $history->from_status ?: '-' }} → {{ $history->to_status }}</div>
|
||||
<div class="text-secondary small">{{ $history->created_at?->format('d/m/Y H:i') }} · {{ $history->note ?: '-' }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-secondary">Tiada sejarah.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-3 p-md-4 mt-3">
|
||||
<h2 class="h6 mb-3">Dokumen</h2>
|
||||
@forelse ($application->documents as $document)
|
||||
<div class="d-flex justify-content-between align-items-center border-bottom py-2">
|
||||
<div>
|
||||
<div class="fw-semibold">{{ str_replace('_', ' ', $document->document_type) }}</div>
|
||||
<div class="small text-secondary">{{ $document->original_name }}</div>
|
||||
</div>
|
||||
<a class="btn btn-sm btn-outline-primary" href="{{ route('admin.documents.download', $document) }}">
|
||||
<i class="bi bi-download me-1"></i>Muat turun
|
||||
</a>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-secondary">Tiada dokumen dimuat naik.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,87 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Senarai Permohonan')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Senarai Permohonan</h1>
|
||||
<p class="text-secondary mb-0">Paparan global untuk semakan, edit, dan direct assignment.</p>
|
||||
</div>
|
||||
<div><a class="btn btn-primary" href="{{ route('admin.management.applications.create') }}"><i class="bi bi-plus-circle me-1"></i>Manual Entry</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="content-panel p-3 mb-3">
|
||||
<form class="row g-2" method="GET">
|
||||
<div class="col-12 col-md-3"><input class="form-control" name="q" value="{{ $filters['q'] ?? '' }}" placeholder="Cari nama / IC / email"></div>
|
||||
<div class="col-6 col-md-3">
|
||||
<select class="form-select" name="status">
|
||||
<option value="">Semua status</option>
|
||||
@foreach (['submitted', 'under_ppm_review', 'approved', 'assigned', 'rejected', 'cancelled'] as $status)
|
||||
<option value="{{ $status }}" @selected(($filters['status'] ?? '') === $status)>{{ str_replace('_', ' ', $status) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<select class="form-select" name="pusat_mengundi_id">
|
||||
<option value="">Semua pusat</option>
|
||||
@foreach ($pusats as $pusat)
|
||||
<option value="{{ $pusat->id }}" @selected(($filters['pusat_mengundi_id'] ?? '') == $pusat->id)>{{ $pusat->code }} - {{ $pusat->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 col-md-2">
|
||||
<select class="form-select" name="position_id">
|
||||
<option value="">Semua jawatan</option>
|
||||
@foreach ($positions as $position)
|
||||
<option value="{{ $position->id }}" @selected(($filters['position_id'] ?? '') == $position->id)>{{ $position->code }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 col-md-1"><button class="btn btn-outline-primary w-100" type="submit"><i class="bi bi-search"></i></button></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-0 overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<x-sort-th column="name" label="Nama" />
|
||||
<th>Pusat</th>
|
||||
<th>Jawatan</th>
|
||||
<x-sort-th column="status" label="Status" />
|
||||
<th>Sumber</th>
|
||||
<x-sort-th column="created_at" label="Tarikh" />
|
||||
<th class="text-end no-sort">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($applications as $application)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $application->name }}</div>
|
||||
<div class="text-secondary small">{{ $application->ic_number }} · {{ $application->email ?: '-' }}</div>
|
||||
</td>
|
||||
<td>{{ $application->pusatMengundi?->code }}<div class="small text-secondary">{{ $application->pusatMengundi?->name }}</div></td>
|
||||
<td>{{ $application->approvedPosition?->code ?: $application->requestedPosition?->code }}</td>
|
||||
<td><span class="badge text-bg-secondary">{{ str_replace('_', ' ', $application->status) }}</span></td>
|
||||
<td>{{ $application->source }}</td>
|
||||
<td class="small text-secondary">{{ $application->created_at?->format('d/m/Y') }}</td>
|
||||
<td class="text-end"><a class="btn btn-sm btn-outline-primary" href="{{ route('admin.management.applications.edit', $application->public_uuid) }}">Edit</a></td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-secondary py-4">Tiada permohonan dijumpai.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">{{ $applications->links() }}</div>
|
||||
@endsection
|
||||
89
resources/views/admin/management/assignments/edit.blade.php
Normal file
89
resources/views/admin/management/assignments/edit.blade.php
Normal file
@@ -0,0 +1,89 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Tugasan')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<h1 class="h3 mb-1">Edit Tugasan</h1>
|
||||
<p class="text-secondary mb-0">{{ $assignment->application?->name ?: $assignment->user?->name ?: 'Tugasan staf' }}</p>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.management.assignments.update', $assignment) }}">
|
||||
@csrf
|
||||
@method('PATCH')
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="position_id">Jawatan</label>
|
||||
<select class="form-select" id="position_id" name="position_id" required>
|
||||
@foreach ($positions as $position)
|
||||
<option value="{{ $position->id }}" @selected(old('position_id', $assignment->position_id) == $position->id)>{{ $position->code }} - {{ $position->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="pusat_mengundi_id">Pusat Mengundi</label>
|
||||
<select class="form-select" id="pusat_mengundi_id" name="pusat_mengundi_id" required>
|
||||
@foreach ($pusats as $pusat)
|
||||
<option value="{{ $pusat->id }}" @selected(old('pusat_mengundi_id', $assignment->pusat_mengundi_id) == $pusat->id)>{{ $pusat->code }} - {{ $pusat->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="saluran_mengundi_id">Saluran</label>
|
||||
<select class="form-select" id="saluran_mengundi_id" name="saluran_mengundi_id">
|
||||
<option value="">Pusat level / ikut KTM</option>
|
||||
@foreach ($salurans as $saluran)
|
||||
<option value="{{ $saluran->id }}" @selected(old('saluran_mengundi_id', $assignment->saluran_mengundi_id) == $saluran->id)>{{ $saluran->pusatMengundi?->code }} - Saluran {{ $saluran->number }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="reports_to_assignment_id">KTM Ketua</label>
|
||||
<select class="form-select" id="reports_to_assignment_id" name="reports_to_assignment_id">
|
||||
<option value="">Tiada</option>
|
||||
@foreach ($ktmAssignments as $ktm)
|
||||
<option value="{{ $ktm->id }}" @selected(old('reports_to_assignment_id', $assignment->reports_to_assignment_id) == $ktm->id)>{{ $ktm->user?->name ?? 'KTM' }} - {{ $ktm->pusatMengundi?->code }} / Saluran {{ $ktm->saluranMengundi?->number }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="status">Status</label>
|
||||
<select class="form-select" id="status" name="status" required>
|
||||
@foreach (['active', 'inactive', 'replaced', 'cancelled'] as $status)
|
||||
<option value="{{ $status }}" @selected(old('status', $assignment->status) === $status)>{{ $status }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="note">Catatan</label>
|
||||
<textarea class="form-control" id="note" name="note" rows="2" placeholder="Wajib selepas tempoh pendaftaran ditutup">{{ old('note') }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a class="btn btn-outline-secondary" href="{{ route('admin.management.assignments.index') }}">Kembali</a>
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-save me-1"></i>Kemas Kini</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12 col-xl-5">
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<h2 class="h6 mb-3">Sejarah Tugasan</h2>
|
||||
@forelse ($assignment->histories->sortByDesc('created_at') as $history)
|
||||
<div class="border-bottom py-2">
|
||||
<div class="small text-secondary">{{ $history->created_at?->format('d/m/Y H:i') }}</div>
|
||||
<div>{{ $history->note ?: '-' }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-secondary">Tiada sejarah.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
79
resources/views/admin/management/assignments/index.blade.php
Normal file
79
resources/views/admin/management/assignments/index.blade.php
Normal file
@@ -0,0 +1,79 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Senarai Tugasan')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<h1 class="h3 mb-1">Senarai Tugasan Staf</h1>
|
||||
<p class="text-secondary mb-0">Semak dan ubah penempatan staf secara langsung.</p>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="content-panel p-3 mb-3">
|
||||
<form class="row g-2" method="GET">
|
||||
<div class="col-12 col-md-4">
|
||||
<select class="form-select" name="pusat_mengundi_id">
|
||||
<option value="">Semua pusat</option>
|
||||
@foreach ($pusats as $pusat)
|
||||
<option value="{{ $pusat->id }}" @selected(($filters['pusat_mengundi_id'] ?? '') == $pusat->id)>{{ $pusat->code }} - {{ $pusat->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<select class="form-select" name="position_id">
|
||||
<option value="">Semua jawatan</option>
|
||||
@foreach ($positions as $position)
|
||||
<option value="{{ $position->id }}" @selected(($filters['position_id'] ?? '') == $position->id)>{{ $position->code }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<select class="form-select" name="status">
|
||||
<option value="">Semua status</option>
|
||||
@foreach (['active', 'inactive', 'replaced', 'cancelled'] as $status)
|
||||
<option value="{{ $status }}" @selected(($filters['status'] ?? '') === $status)>{{ $status }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-md-2"><button class="btn btn-outline-primary w-100" type="submit"><i class="bi bi-funnel me-1"></i>Tapis</button></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-0 overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Staf</th>
|
||||
<th>Jawatan</th>
|
||||
<th>Pusat / Saluran</th>
|
||||
<th>KTM Ketua</th>
|
||||
<x-sort-th column="status" label="Status" />
|
||||
<th class="text-end no-sort">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($assignments as $assignment)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $assignment->application?->name ?: $assignment->user?->name ?: 'Tanpa nama' }}</div>
|
||||
<div class="small text-secondary">{{ $assignment->application?->ic_number ?: $assignment->user?->email ?: '-' }}</div>
|
||||
</td>
|
||||
<td>{{ $assignment->position?->code }}</td>
|
||||
<td>{{ $assignment->pusatMengundi?->code }}<div class="small text-secondary">{{ $assignment->saluranMengundi ? 'Saluran '.$assignment->saluranMengundi->number : 'Pusat level' }}</div></td>
|
||||
<td>{{ $assignment->reportsTo?->user?->name ?: '-' }}</td>
|
||||
<td><span class="badge text-bg-secondary">{{ $assignment->status }}</span></td>
|
||||
<td class="text-end"><a class="btn btn-sm btn-outline-primary" href="{{ route('admin.management.assignments.edit', $assignment) }}">Edit</a></td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="6" class="text-center text-secondary py-4">Tiada tugasan dijumpai.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">{{ $assignments->links() }}</div>
|
||||
@endsection
|
||||
53
resources/views/admin/management/index.blade.php
Normal file
53
resources/views/admin/management/index.blade.php
Normal file
@@ -0,0 +1,53 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pengurusan Admin')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Pengurusan Admin</h1>
|
||||
<p class="text-secondary mb-0">Senarai global, manual entry, direct assignment, wakil agensi, dan catatan perubahan selepas pendaftaran tutup.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="row g-3">
|
||||
@foreach ([
|
||||
['label' => 'Permohonan', 'value' => $counts['applications'], 'icon' => 'bi-file-earmark-person', 'tone' => 'primary'],
|
||||
['label' => 'Assigned', 'value' => $counts['assigned'], 'icon' => 'bi-person-check', 'tone' => 'success'],
|
||||
['label' => 'Tugasan aktif', 'value' => $counts['staffAssignments'], 'icon' => 'bi-person-lines-fill', 'tone' => 'info'],
|
||||
['label' => 'Wakil agensi', 'value' => $counts['representatives'], 'icon' => 'bi-building-check', 'tone' => 'secondary'],
|
||||
['label' => 'Dokumen tidak lengkap', 'value' => $counts['missingDocuments'], 'icon' => 'bi-file-earmark-x', 'tone' => 'danger'],
|
||||
['label' => 'Bank tidak lengkap', 'value' => $counts['incompleteBank'], 'icon' => 'bi-bank', 'tone' => 'warning'],
|
||||
['label' => 'Kerusi roda', 'value' => $counts['wheelchairAllocated'], 'icon' => 'bi-universal-access', 'tone' => 'primary'],
|
||||
['label' => 'Belum dipulang', 'value' => $counts['wheelchairOutstanding'], 'icon' => 'bi-arrow-return-left', 'tone' => 'warning'],
|
||||
] as $card)
|
||||
<div class="col-12 col-sm-6 col-xl-3">
|
||||
<div class="stat-card h-100">
|
||||
<div class="d-flex justify-content-between gap-3">
|
||||
<div>
|
||||
<div class="text-secondary small">{{ $card['label'] }}</div>
|
||||
<div class="fs-3 fw-bold mt-2">{{ $card['value'] }}</div>
|
||||
</div>
|
||||
<span class="stat-icon text-bg-{{ $card['tone'] }}"><i class="bi {{ $card['icon'] }}"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="content-panel mt-4 p-3 p-md-4">
|
||||
<h2 class="h5 mb-3">Tindakan</h2>
|
||||
<div class="row g-2">
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-primary w-100 text-start" href="{{ route('admin.management.applications.create') }}"><i class="bi bi-plus-circle me-2"></i>Manual Entry</a></div>
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-primary w-100 text-start" href="{{ route('admin.management.applications.index') }}"><i class="bi bi-search me-2"></i>Senarai Permohonan</a></div>
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-primary w-100 text-start" href="{{ route('admin.management.assignments.index') }}"><i class="bi bi-person-lines-fill me-2"></i>Senarai Tugasan</a></div>
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-primary w-100 text-start" href="{{ route('admin.management.representatives.index') }}"><i class="bi bi-building-check me-2"></i>Wakil Agensi</a></div>
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-primary w-100 text-start" href="{{ route('admin.management.wheelchairs.index') }}"><i class="bi bi-universal-access me-2"></i>Kerusi Roda</a></div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
78
resources/views/admin/management/penempatan/pindah.blade.php
Normal file
78
resources/views/admin/management/penempatan/pindah.blade.php
Normal file
@@ -0,0 +1,78 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pindah Petugas')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin · <a href="{{ route('admin.management.penempatan.show', $pusat) }}">{{ $pusat->name }}</a></div>
|
||||
<h1 class="h3 mb-0">Pindah Petugas</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-xl-5">
|
||||
{{-- Maklumat petugas semasa --}}
|
||||
<div class="content-panel p-3 p-md-4 mb-3">
|
||||
<h2 class="h6 fw-semibold text-secondary mb-3">Maklumat Petugas Semasa</h2>
|
||||
<dl class="row mb-0">
|
||||
<dt class="col-5 text-secondary small">Nama</dt>
|
||||
<dd class="col-7">{{ $assignment->application?->name ?? $assignment->user?->name ?? '-' }}</dd>
|
||||
<dt class="col-5 text-secondary small">No. KP</dt>
|
||||
<dd class="col-7 small">{{ $assignment->application?->ic_number ?? '-' }}</dd>
|
||||
<dt class="col-5 text-secondary small">Jawatan</dt>
|
||||
<dd class="col-7"><span class="badge text-bg-primary">{{ $assignment->position?->code }}</span></dd>
|
||||
<dt class="col-5 text-secondary small">Pusat Semasa</dt>
|
||||
<dd class="col-7">{{ $pusat->code }} — {{ $pusat->name }}</dd>
|
||||
<dt class="col-5 text-secondary small">Saluran Semasa</dt>
|
||||
<dd class="col-7">{{ $assignment->saluranMengundi ? 'Saluran '.$assignment->saluranMengundi->number : 'Peringkat Pusat' }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
{{-- Form pindah --}}
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<h2 class="h6 fw-semibold mb-3">Pindah ke Lokasi Baru</h2>
|
||||
<form method="POST" action="{{ route('admin.management.penempatan.pindah', [$pusat, $assignment]) }}">
|
||||
@csrf
|
||||
<div class="mb-3">
|
||||
<label class="form-label fw-semibold" for="pusat_mengundi_id">Pusat Mengundi Baru</label>
|
||||
<select id="pusat_mengundi_id" name="pusat_mengundi_id"
|
||||
class="form-select @error('pusat_mengundi_id') is-invalid @enderror"
|
||||
required data-tom-select>
|
||||
@foreach ($pusats as $p)
|
||||
<option value="{{ $p->id }}" @selected($p->id === $pusat->id)>
|
||||
{{ $p->code }} — {{ $p->name }}
|
||||
@if ($p->election) ({{ $p->election->name }}) @endif
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('pusat_mengundi_id') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label class="form-label fw-semibold" for="saluran_mengundi_id">Saluran (pilihan)</label>
|
||||
<select id="saluran_mengundi_id" name="saluran_mengundi_id"
|
||||
class="form-select @error('saluran_mengundi_id') is-invalid @enderror">
|
||||
<option value="">Peringkat Pusat (Saluran 0)</option>
|
||||
@foreach ($salurans as $saluran)
|
||||
<option value="{{ $saluran->id }}" @selected($saluran->id === $assignment->saluran_mengundi_id)>
|
||||
Saluran {{ $saluran->number }}
|
||||
@if ($saluran->name) — {{ $saluran->name }} @endif
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<div class="form-text">Senarai saluran akan dikemaskini apabila pusat baru dipilih.</div>
|
||||
@error('saluran_mengundi_id') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2">
|
||||
<a href="{{ route('admin.management.penempatan.show', $pusat) }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button type="submit" class="btn btn-primary">
|
||||
<i class="bi bi-arrow-left-right me-1"></i>Sahkan Pindah
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
146
resources/views/admin/management/penempatan/show.blade.php
Normal file
146
resources/views/admin/management/penempatan/show.blade.php
Normal file
@@ -0,0 +1,146 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Penempatan — ' . $pusat->name)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin · <a href="{{ route('admin.dashboard') }}">Dashboard</a></div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Penempatan Petugas</h1>
|
||||
<p class="text-secondary mb-0">
|
||||
{{ $pusat->code }} — {{ $pusat->name }}
|
||||
@if ($pusat->dun) · DUN {{ $pusat->dun->code }} @endif
|
||||
@if ($ppm) · PPM: {{ $ppm->application?->name }} @endif
|
||||
</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2 align-items-start">
|
||||
<a href="{{ route('admin.dashboard') }}" class="btn btn-outline-secondary">Kembali</a>
|
||||
<a href="{{ route('admin.management.applications.index', ['pusat_mengundi_id' => $pusat->id]) }}"
|
||||
class="btn btn-outline-primary">
|
||||
<i class="bi bi-file-earmark-person me-1"></i>Permohonan Pusat Ini
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
@forelse ($sections as $section)
|
||||
<div class="content-panel p-0 overflow-hidden mb-4">
|
||||
{{-- Section header --}}
|
||||
<div class="p-3 border-bottom d-flex justify-content-between align-items-center">
|
||||
<h2 class="h6 mb-0 fw-semibold">
|
||||
@if ($section['saluran'])
|
||||
<i class="bi bi-signpost me-2 text-primary"></i>{{ $section['label'] }}
|
||||
<span class="text-secondary fw-normal small ms-2">{{ $section['saluran']->voter_count ?? 0 }} pengundi</span>
|
||||
@else
|
||||
<i class="bi bi-building me-2 text-secondary"></i>{{ $section['label'] }}
|
||||
@endif
|
||||
</h2>
|
||||
@php
|
||||
$sectionFilled = $section['entries']->sum(fn($e) => $e['assignments']->count());
|
||||
$sectionQuota = $section['entries']->sum(fn($e) => $e['quota']->quota);
|
||||
$sectionVacant = $section['entries']->sum(fn($e) => $e['vacant']);
|
||||
@endphp
|
||||
<span class="badge {{ $sectionVacant > 0 ? 'text-bg-warning' : 'text-bg-success' }}">
|
||||
{{ $sectionFilled }} / {{ $sectionQuota }} diisi
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Jawatan</th>
|
||||
<th>Nama Petugas</th>
|
||||
<th>No. KP</th>
|
||||
<th>Telefon</th>
|
||||
<th>Bank</th>
|
||||
<th>No. Akaun</th>
|
||||
<th class="text-end">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($section['entries'] as $entry)
|
||||
{{-- Filled slots --}}
|
||||
@foreach ($entry['assignments'] as $assignment)
|
||||
<tr>
|
||||
@if ($loop->first)
|
||||
<td rowspan="{{ $entry['assignments']->count() + $entry['vacant'] }}"
|
||||
class="fw-semibold align-top pt-3">
|
||||
{{ $entry['position']?->code }}
|
||||
<div class="small text-secondary fw-normal">{{ $entry['position']?->name }}</div>
|
||||
<div class="small text-secondary">Kuota: {{ $entry['quota']->quota }}</div>
|
||||
</td>
|
||||
@endif
|
||||
@php $app = $assignment->application; @endphp
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $app?->name ?? $assignment->user?->name ?? 'Tanpa nama' }}</div>
|
||||
<span class="badge text-bg-success small">Aktif</span>
|
||||
</td>
|
||||
<td class="small text-secondary">{{ $app?->ic_number ?? '-' }}</td>
|
||||
<td class="small text-secondary">{{ $app?->phone_number ?? '-' }}</td>
|
||||
<td class="small">{{ $app?->bank_name ?? '-' }}</td>
|
||||
<td class="small text-secondary">
|
||||
{{ $app?->bank_account_number ? \App\Support\SensitiveData::maskAccount($app->bank_account_number) : '-' }}
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.management.penempatan.pindah.form', [$pusat, $assignment]) }}"
|
||||
class="btn btn-sm btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left-right"></i> Pindah
|
||||
</a>
|
||||
<form method="POST"
|
||||
action="{{ route('admin.management.penempatan.lepas', [$pusat, $assignment]) }}"
|
||||
class="d-inline"
|
||||
onsubmit="return confirm('Lepaskan {{ addslashes($app?->name ?? 'petugas') }} dari tugasan ini?')">
|
||||
@csrf
|
||||
<button class="btn btn-sm btn-outline-danger">
|
||||
<i class="bi bi-person-dash"></i> Lepas
|
||||
</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
|
||||
{{-- Vacant slots --}}
|
||||
@for ($i = 0; $i < $entry['vacant']; $i++)
|
||||
<tr class="table-warning">
|
||||
@if ($entry['assignments']->isEmpty() && $i === 0)
|
||||
<td rowspan="{{ $entry['vacant'] }}"
|
||||
class="fw-semibold align-top pt-3">
|
||||
{{ $entry['position']?->code }}
|
||||
<div class="small text-secondary fw-normal">{{ $entry['position']?->name }}</div>
|
||||
<div class="small text-secondary">Kuota: {{ $entry['quota']->quota }}</div>
|
||||
</td>
|
||||
@endif
|
||||
<td colspan="5" class="text-secondary fst-italic small">— Slot kosong —</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.management.applications.index', [
|
||||
'pusat_mengundi_id' => $pusat->id,
|
||||
'position_id' => $entry['position']?->id,
|
||||
'status' => 'approved',
|
||||
]) }}"
|
||||
class="btn btn-sm btn-success">
|
||||
<i class="bi bi-person-plus me-1"></i>Assign
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
@endfor
|
||||
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="7" class="text-center text-secondary py-3">Tiada kuota ditetapkan untuk bahagian ini.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="content-panel p-4 text-center text-secondary">
|
||||
<i class="bi bi-info-circle fs-3 d-block mb-2"></i>
|
||||
Tiada kuota ditetapkan untuk pusat ini. <a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">Tetapkan kuota</a>.
|
||||
</div>
|
||||
@endforelse
|
||||
@endsection
|
||||
@@ -0,0 +1,96 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Wakil Agensi')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<h1 class="h3 mb-1">Wakil Polis, KKM dan JKM</h1>
|
||||
<p class="text-secondary mb-0">Kemasukan manual wakil agensi untuk Pusat Mengundi dan Saluran.</p>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4 mb-4">
|
||||
<h2 class="h5 mb-3">Tambah Wakil</h2>
|
||||
<form method="POST" action="{{ route('admin.management.representatives.store') }}">
|
||||
@csrf
|
||||
<div class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="type">Jenis</label>
|
||||
<select class="form-select" id="type" name="type" required>
|
||||
<option value="police">Polis Pengiring</option>
|
||||
<option value="kkm">Wakil KKM</option>
|
||||
<option value="jkm">Wakil JKM</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="election_id">Pilihanraya</label>
|
||||
<select class="form-select" id="election_id" name="election_id" required>
|
||||
@foreach ($elections as $election)
|
||||
<option value="{{ $election->id }}">{{ $election->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="pusat_mengundi_id">Pusat</label>
|
||||
<select class="form-select" id="pusat_mengundi_id" name="pusat_mengundi_id" required>
|
||||
@foreach ($pusats as $pusat)
|
||||
<option value="{{ $pusat->id }}">{{ $pusat->code }} - {{ $pusat->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="saluran_mengundi_id">Saluran Polis</label>
|
||||
<select class="form-select" id="saluran_mengundi_id" name="saluran_mengundi_id">
|
||||
<option value="">Tiada / Pusat level</option>
|
||||
@foreach ($salurans as $saluran)
|
||||
<option value="{{ $saluran->id }}">{{ $saluran->pusatMengundi?->code }} - Saluran {{ $saluran->number }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4"><label class="form-label" for="name">Nama</label><input class="form-control" id="name" name="name" required></div>
|
||||
<div class="col-md-4"><label class="form-label" for="ic_number">No. IC</label><input class="form-control" id="ic_number" name="ic_number" maxlength="12"></div>
|
||||
<div class="col-md-4"><label class="form-label" for="phone_number">Telefon</label><input class="form-control" id="phone_number" name="phone_number"></div>
|
||||
<div class="col-md-4"><label class="form-label" for="rank">Pangkat Polis</label><input class="form-control" id="rank" name="rank"></div>
|
||||
<div class="col-md-4"><label class="form-label" for="station">Balai Polis</label><input class="form-control" id="station" name="station"></div>
|
||||
<div class="col-md-4"><label class="form-label" for="agency">Agensi</label><input class="form-control" id="agency" name="agency"></div>
|
||||
<div class="col-md-6"><label class="form-label" for="notes">Nota Operasi</label><textarea class="form-control" id="notes" name="notes" rows="2"></textarea></div>
|
||||
<div class="col-md-6"><label class="form-label" for="note">Catatan Admin</label><textarea class="form-control" id="note" name="note" rows="2" placeholder="Wajib selepas tempoh pendaftaran ditutup"></textarea></div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end mt-3"><button class="btn btn-primary" type="submit"><i class="bi bi-save me-1"></i>Simpan</button></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@foreach ([['title' => 'Polis Pengiring', 'items' => $policeEscorts, 'type' => 'police'], ['title' => 'Wakil KKM', 'items' => $kkmRepresentatives, 'type' => 'kkm'], ['title' => 'Wakil JKM', 'items' => $jkmRepresentatives, 'type' => 'jkm']] as $section)
|
||||
<div class="content-panel p-0 overflow-hidden mb-4">
|
||||
<div class="p-3 border-bottom fw-semibold">{{ $section['title'] }}</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead><tr><th>Nama</th><th>Pusat</th><th>Telefon</th><th>Nota</th><th class="text-end no-sort">Tindakan</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($section['items'] as $item)
|
||||
<tr>
|
||||
<td>{{ $item->name }}<div class="small text-secondary">{{ $item->ic_number ?: '-' }}</div></td>
|
||||
<td>{{ $item->pusatMengundi?->code }} @if($section['type'] === 'police' && $item->saluranMengundi) · Saluran {{ $item->saluranMengundi->number }} @endif</td>
|
||||
<td>{{ $item->phone_number ?: '-' }}</td>
|
||||
<td>{{ $item->notes ?: '-' }}</td>
|
||||
<td class="text-end">
|
||||
<form method="POST" action="{{ route('admin.management.representatives.destroy', [$section['type'], $item->id]) }}" onsubmit="return confirm('Padam rekod ini?')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<input type="hidden" name="note" value="Dipadam oleh Admin.">
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit"><i class="bi bi-trash"></i></button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="text-center text-secondary py-4">Tiada rekod.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="p-3">{{ $section['items']->links() }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
@endsection
|
||||
91
resources/views/admin/management/wheelchairs/index.blade.php
Normal file
91
resources/views/admin/management/wheelchairs/index.blade.php
Normal file
@@ -0,0 +1,91 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Kerusi Roda')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Pengurusan Kerusi Roda</h1>
|
||||
<p class="text-secondary mb-0">Peruntukan, rekod ambil, rekod pulang, keadaan, dan catatan kerusi roda.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4 mb-4">
|
||||
<h2 class="h5 mb-3">Tetapkan Peruntukan</h2>
|
||||
<form method="POST" action="{{ route('admin.management.wheelchairs.store') }}">
|
||||
@csrf
|
||||
<div class="row g-3">
|
||||
<div class="col-md-3">
|
||||
<label class="form-label" for="election_id">Pilihanraya</label>
|
||||
<select class="form-select" id="election_id" name="election_id" required>
|
||||
@foreach ($elections as $election)
|
||||
<option value="{{ $election->id }}">{{ $election->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-5">
|
||||
<label class="form-label" for="pusat_mengundi_id">Pusat Mengundi</label>
|
||||
<select class="form-select" id="pusat_mengundi_id" name="pusat_mengundi_id" required>
|
||||
@foreach ($pusats as $pusat)
|
||||
<option value="{{ $pusat->id }}">{{ $pusat->code }} - {{ $pusat->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label" for="allocated_quantity">Jumlah</label>
|
||||
<input class="form-control" id="allocated_quantity" name="allocated_quantity" type="number" min="0" value="0" required>
|
||||
</div>
|
||||
<div class="col-md-2 d-flex align-items-end">
|
||||
<button class="btn btn-primary w-100" type="submit"><i class="bi bi-save me-1"></i>Simpan</button>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="notes">Nota</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="2"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-0 overflow-hidden">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Pusat Mengundi</th>
|
||||
<th>Peruntukan</th>
|
||||
<th>Diambil</th>
|
||||
<th>Dipulang</th>
|
||||
<th>Belum Dipulang</th>
|
||||
<th>Baki Boleh Diambil</th>
|
||||
<th class="text-end no-sort">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($allocations as $allocation)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $allocation->pusatMengundi?->code }} - {{ $allocation->pusatMengundi?->name }}</div>
|
||||
<div class="small text-secondary">{{ $allocation->election?->name }}</div>
|
||||
</td>
|
||||
<td>{{ $allocation->allocated_quantity }}</td>
|
||||
<td>{{ $service->takenQuantity($allocation) }}</td>
|
||||
<td>{{ $service->returnedQuantity($allocation) }}</td>
|
||||
<td><span class="badge text-bg-warning">{{ $service->outstandingQuantity($allocation) }}</span></td>
|
||||
<td><span class="badge text-bg-success">{{ $service->availableQuantity($allocation) }}</span></td>
|
||||
<td class="text-end"><a class="btn btn-sm btn-outline-primary" href="{{ route('admin.management.wheelchairs.show', $allocation) }}">Urus</a></td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-secondary py-4">Tiada peruntukan kerusi roda.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">{{ $allocations->links() }}</div>
|
||||
@endsection
|
||||
232
resources/views/admin/management/wheelchairs/show.blade.php
Normal file
232
resources/views/admin/management/wheelchairs/show.blade.php
Normal file
@@ -0,0 +1,232 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Rekod Kerusi Roda')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Rekod Kerusi Roda</h1>
|
||||
<p class="text-secondary mb-0">{{ $allocation->pusatMengundi?->code }} — {{ $allocation->pusatMengundi?->name }}</p>
|
||||
</div>
|
||||
<div><a class="btn btn-outline-secondary" href="{{ route('admin.management.wheelchairs.index') }}">Kembali</a></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.management._nav')
|
||||
|
||||
@php
|
||||
$taken = $service->takenQuantity($allocation);
|
||||
$returned = $service->returnedQuantity($allocation);
|
||||
$outstanding = $service->outstandingQuantity($allocation);
|
||||
$available = $service->availableQuantity($allocation);
|
||||
@endphp
|
||||
|
||||
<div class="row g-3 mb-4">
|
||||
@foreach ([
|
||||
['label' => 'Peruntukan', 'value' => $allocation->allocated_quantity, 'tone' => 'primary'],
|
||||
['label' => 'Diambil', 'value' => $taken, 'tone' => 'info'],
|
||||
['label' => 'Dipulang', 'value' => $returned, 'tone' => 'success'],
|
||||
['label' => 'Belum dipulang', 'value' => $outstanding, 'tone' => 'warning'],
|
||||
['label' => 'Baki boleh diambil','value' => $available, 'tone' => 'secondary'],
|
||||
] as $card)
|
||||
<div class="col-12 col-sm-6 col-xl">
|
||||
<div class="stat-card h-100">
|
||||
<div class="text-secondary small">{{ $card['label'] }}</div>
|
||||
<div class="fs-3 fw-bold mt-2 text-{{ $card['tone'] }}">{{ $card['value'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
{{-- Kiri: 3 panel borang --}}
|
||||
<div class="col-12 col-xl-5">
|
||||
|
||||
{{-- Kemaskini Peruntukan --}}
|
||||
<div class="content-panel p-3 p-md-4 mb-3">
|
||||
<h2 class="h5 mb-3">Kemaskini Peruntukan</h2>
|
||||
<form method="POST" action="{{ route('admin.management.wheelchairs.update', $allocation) }}">
|
||||
@csrf @method('PATCH')
|
||||
<input type="hidden" name="election_id" value="{{ $allocation->election_id }}">
|
||||
<input type="hidden" name="pusat_mengundi_id" value="{{ $allocation->pusat_mengundi_id }}">
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="allocated_quantity">Jumlah Peruntukan</label>
|
||||
<input class="form-control @error('allocated_quantity') is-invalid @enderror"
|
||||
id="allocated_quantity" name="allocated_quantity" type="number" min="{{ $outstanding }}"
|
||||
value="{{ old('allocated_quantity', $allocation->allocated_quantity) }}" required>
|
||||
<div class="form-text">Minimum {{ $outstanding }} (kerusi belum dipulang).</div>
|
||||
@error('allocated_quantity') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label class="form-label" for="notes">Nota</label>
|
||||
<textarea class="form-control" id="notes" name="notes" rows="2">{{ old('notes', $allocation->notes) }}</textarea>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-save me-1"></i>Simpan</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
{{-- Rekod Ambil --}}
|
||||
<div class="content-panel p-3 p-md-4 mb-3 border-start border-4 border-info">
|
||||
<h2 class="h5 mb-1">Rekod Ambil</h2>
|
||||
<p class="text-secondary small mb-3">Baki boleh diambil: <strong class="text-info">{{ $available }}</strong></p>
|
||||
|
||||
@if ($available === 0)
|
||||
<div class="alert alert-secondary py-2 mb-0">Tiada baki kerusi roda untuk diambil.</div>
|
||||
@else
|
||||
<form method="POST" action="{{ route('admin.management.wheelchairs.ambil', $allocation) }}">
|
||||
@csrf
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="taken_quantity">Jumlah Ambil</label>
|
||||
<input class="form-control @error('quantity') is-invalid @enderror"
|
||||
id="taken_quantity" name="quantity" type="number" min="1" max="{{ $available }}"
|
||||
value="{{ old('quantity') }}" required>
|
||||
<div class="form-text">Maks: {{ $available }}</div>
|
||||
@error('quantity') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="taken_at">Masa Ambil</label>
|
||||
<input class="form-control @error('taken_at') is-invalid @enderror"
|
||||
id="taken_at" name="taken_at" type="datetime-local"
|
||||
value="{{ old('taken_at', now()->format('Y-m-d\TH:i')) }}">
|
||||
@error('taken_at') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="taken_by_name">Diambil Oleh <span class="text-danger">*</span></label>
|
||||
<input class="form-control @error('taken_by_name') is-invalid @enderror"
|
||||
id="taken_by_name" name="taken_by_name"
|
||||
value="{{ old('taken_by_name') }}" required>
|
||||
@error('taken_by_name') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="taken_notes">Nota</label>
|
||||
<textarea class="form-control" id="taken_notes" name="notes" rows="2">{{ old('notes') }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<button class="btn btn-info text-white" type="submit"><i class="bi bi-box-arrow-up-right me-1"></i>Rekod Ambil</button>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
{{-- Rekod Pulang --}}
|
||||
<div class="content-panel p-3 p-md-4 border-start border-4 border-success">
|
||||
<h2 class="h5 mb-1">Rekod Pulang</h2>
|
||||
<p class="text-secondary small mb-3">Belum dipulang: <strong class="text-warning">{{ $outstanding }}</strong></p>
|
||||
|
||||
@if ($outstanding === 0)
|
||||
<div class="alert alert-secondary py-2 mb-0">Tiada kerusi roda yang perlu dipulangkan.</div>
|
||||
@else
|
||||
<form method="POST" action="{{ route('admin.management.wheelchairs.pulang', $allocation) }}">
|
||||
@csrf
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="return_quantity">Jumlah Pulang</label>
|
||||
<input class="form-control @error('quantity') is-invalid @enderror"
|
||||
id="return_quantity" name="quantity" type="number" min="1" max="{{ $outstanding }}"
|
||||
value="{{ old('quantity') }}" required>
|
||||
<div class="form-text">Maks: {{ $outstanding }}</div>
|
||||
@error('quantity') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label" for="returned_at">Masa Pulang</label>
|
||||
<input class="form-control @error('returned_at') is-invalid @enderror"
|
||||
id="returned_at" name="returned_at" type="datetime-local"
|
||||
value="{{ old('returned_at', now()->format('Y-m-d\TH:i')) }}">
|
||||
@error('returned_at') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="returned_by_name">Dipulang Oleh <span class="text-danger">*</span></label>
|
||||
<input class="form-control @error('returned_by_name') is-invalid @enderror"
|
||||
id="returned_by_name" name="returned_by_name"
|
||||
value="{{ old('returned_by_name') }}" required>
|
||||
@error('returned_by_name') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
<div class="col-md-12">
|
||||
<label class="form-label" for="return_condition">Keadaan <span class="text-danger">*</span></label>
|
||||
<select class="form-select @error('return_condition') is-invalid @enderror"
|
||||
id="return_condition" name="return_condition" required>
|
||||
<option value="">Pilih keadaan</option>
|
||||
<option value="baik" @selected(old('return_condition') === 'baik')>Baik</option>
|
||||
<option value="rosak" @selected(old('return_condition') === 'rosak')>Rosak</option>
|
||||
</select>
|
||||
@error('return_condition') <div class="invalid-feedback">{{ $message }}</div> @enderror
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label" for="return_notes">Nota</label>
|
||||
<textarea class="form-control" id="return_notes" name="notes" rows="2">{{ old('notes') }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end mt-3">
|
||||
<button class="btn btn-success" type="submit"><i class="bi bi-box-arrow-in-down-left me-1"></i>Rekod Pulang</button>
|
||||
</div>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Kanan: Sejarah transaksi --}}
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="content-panel p-0 overflow-hidden">
|
||||
<div class="p-3 border-bottom fw-semibold">Sejarah Transaksi</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle mb-0">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Jenis</th>
|
||||
<th>Jml</th>
|
||||
<th>Masa</th>
|
||||
<th>Nama</th>
|
||||
<th>Keadaan</th>
|
||||
<th>Direkod Oleh</th>
|
||||
<th>Nota</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($allocation->transactions->sortByDesc('created_at') as $tx)
|
||||
<tr>
|
||||
<td>
|
||||
@if ($tx->transaction_type === 'taken')
|
||||
<span class="badge text-bg-info">Ambil</span>
|
||||
@else
|
||||
<span class="badge text-bg-success">Pulang</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="fw-semibold">{{ $tx->quantity }}</td>
|
||||
<td class="small">
|
||||
{{ ($tx->taken_at ?? $tx->returned_at)?->format('d/m/Y H:i') ?? '-' }}
|
||||
</td>
|
||||
<td class="small">
|
||||
@if ($tx->transaction_type === 'taken')
|
||||
{{ $tx->taken_by_name ?: '-' }}
|
||||
@else
|
||||
{{ $tx->returned_by_name ?: '-' }}
|
||||
@endif
|
||||
</td>
|
||||
<td>
|
||||
@if ($tx->transaction_type === 'returned' && $tx->return_condition)
|
||||
<span class="badge {{ $tx->return_condition === 'baik' ? 'text-bg-success' : 'text-bg-danger' }}">
|
||||
{{ ucfirst($tx->return_condition) }}
|
||||
</span>
|
||||
@else
|
||||
<span class="text-secondary">—</span>
|
||||
@endif
|
||||
</td>
|
||||
<td class="small text-secondary">{{ $tx->recordedBy?->name ?: '-' }}</td>
|
||||
<td class="small text-secondary">{{ $tx->notes ?: '-' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-secondary py-4">Tiada transaksi direkodkan.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
18
resources/views/admin/setup/_nav.blade.php
Normal file
18
resources/views/admin/setup/_nav.blade.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<div class="content-panel p-2 mb-4">
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.setup.index') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.setup.index') }}">
|
||||
<i class="bi bi-grid me-1"></i>Overview
|
||||
</a>
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.setup.positions.*') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.setup.positions.index') }}">Jawatan</a>
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.setup.pusat.*') ? 'btn-primary' : 'btn-outline-primary' }}" href="{{ route('admin.setup.pusat.index') }}">Pusat</a>
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.setup.import.*') ? 'btn-success' : 'btn-outline-success' }}" href="{{ route('admin.setup.import.create') }}">
|
||||
<i class="bi bi-upload me-1"></i>Import
|
||||
</a>
|
||||
@php $activeElection = \App\Models\Election::query()->where('status', 'active')->first(); @endphp
|
||||
@if ($activeElection)
|
||||
<a class="btn btn-sm {{ request()->routeIs('admin.setup.settings.*') ? 'btn-warning' : 'btn-outline-warning' }}" href="{{ route('admin.setup.settings.edit', $activeElection) }}">
|
||||
<i class="bi bi-sliders me-1"></i>Tetapan
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
25
resources/views/admin/setup/bahagian/_form.blade.php
Normal file
25
resources/views/admin/setup/bahagian/_form.blade.php
Normal file
@@ -0,0 +1,25 @@
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-4">
|
||||
<label class="form-label" for="election_id">Election</label>
|
||||
<select id="election_id" name="election_id" class="form-select" required>
|
||||
@foreach ($elections as $election)
|
||||
<option value="{{ $election->id }}" @selected(old('election_id', $bahagian->election_id) == $election->id)>{{ $election->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-lg-3">
|
||||
<label class="form-label" for="code">Kod</label>
|
||||
<input id="code" name="code" class="form-control" value="{{ old('code', $bahagian->code) }}" required>
|
||||
</div>
|
||||
<div class="col-12 col-lg-5">
|
||||
<label class="form-label" for="name">Nama Bahagian</label>
|
||||
<input id="name" name="name" class="form-control" value="{{ old('name', $bahagian->name) }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a href="{{ route('admin.setup.bahagian.index') }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-save me-1"></i>Simpan</button>
|
||||
</div>
|
||||
13
resources/views/admin/setup/bahagian/create.blade.php
Normal file
13
resources/views/admin/setup/bahagian/create.blade.php
Normal file
@@ -0,0 +1,13 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Tambah Bahagian')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading"><div class="eyebrow">Setup</div><h1 class="h3 mb-0">Tambah Bahagian Pilihanraya</h1></div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.bahagian.store') }}">
|
||||
@include('admin.setup.bahagian._form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
14
resources/views/admin/setup/bahagian/edit.blade.php
Normal file
14
resources/views/admin/setup/bahagian/edit.blade.php
Normal file
@@ -0,0 +1,14 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Bahagian')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading"><div class="eyebrow">Setup</div><h1 class="h3 mb-0">Edit Bahagian Pilihanraya</h1></div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.bahagian.update', $bahagian) }}">
|
||||
@method('PUT')
|
||||
@include('admin.setup.bahagian._form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
45
resources/views/admin/setup/bahagian/index.blade.php
Normal file
45
resources/views/admin/setup/bahagian/index.blade.php
Normal file
@@ -0,0 +1,45 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Bahagian Pilihanraya')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Bahagian Pilihanraya</h1>
|
||||
<p class="text-secondary mb-0">Senarai bahagian pilihanraya untuk election aktif.</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.setup.bahagian.create') }}" class="btn btn-primary"><i class="bi bi-plus-circle me-1"></i>Tambah</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead><tr><x-sort-th column="code" label="Kod" /><x-sort-th column="name" label="Nama" /><th>Election</th><th class="text-end no-sort">Tindakan</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($bahagians as $bahagian)
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ $bahagian->code }}</td>
|
||||
<td>{{ $bahagian->name }}</td>
|
||||
<td>{{ $bahagian->election?->name }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.setup.bahagian.edit', $bahagian) }}" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
<form method="POST" action="{{ route('admin.setup.bahagian.destroy', $bahagian) }}" class="d-inline" data-confirm>
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit">Padam</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4" class="text-center text-secondary py-4">Tiada rekod.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $bahagians->links() }}
|
||||
</div>
|
||||
@endsection
|
||||
33
resources/views/admin/setup/daerah/_form.blade.php
Normal file
33
resources/views/admin/setup/daerah/_form.blade.php
Normal file
@@ -0,0 +1,33 @@
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-4">
|
||||
<label class="form-label" for="election_id">Election</label>
|
||||
<select id="election_id" name="election_id" class="form-select" required>
|
||||
@foreach ($elections as $election)
|
||||
<option value="{{ $election->id }}" @selected(old('election_id', $daerah->election_id) == $election->id)>{{ $election->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-lg-4">
|
||||
<label class="form-label" for="bahagian_pilihanraya_id">Bahagian</label>
|
||||
<select id="bahagian_pilihanraya_id" name="bahagian_pilihanraya_id" class="form-select" required data-tom-select>
|
||||
@foreach ($bahagians as $bahagian)
|
||||
<option value="{{ $bahagian->id }}" @selected(old('bahagian_pilihanraya_id', $daerah->bahagian_pilihanraya_id) == $bahagian->id)>{{ $bahagian->code }} - {{ $bahagian->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-lg-2">
|
||||
<label class="form-label" for="code">Kod</label>
|
||||
<input id="code" name="code" class="form-control" value="{{ old('code', $daerah->code) }}" required>
|
||||
</div>
|
||||
<div class="col-12 col-lg-2">
|
||||
<label class="form-label" for="name">Nama</label>
|
||||
<input id="name" name="name" class="form-control" value="{{ old('name', $daerah->name) }}" required>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a href="{{ route('admin.setup.daerah.index') }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-save me-1"></i>Simpan</button>
|
||||
</div>
|
||||
7
resources/views/admin/setup/daerah/create.blade.php
Normal file
7
resources/views/admin/setup/daerah/create.blade.php
Normal file
@@ -0,0 +1,7 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Tambah Daerah')
|
||||
@section('content')
|
||||
<div class="page-heading"><div class="eyebrow">Setup</div><h1 class="h3 mb-0">Tambah Daerah Mengundi</h1></div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4"><form method="POST" action="{{ route('admin.setup.daerah.store') }}">@include('admin.setup.daerah._form')</form></div>
|
||||
@endsection
|
||||
7
resources/views/admin/setup/daerah/edit.blade.php
Normal file
7
resources/views/admin/setup/daerah/edit.blade.php
Normal file
@@ -0,0 +1,7 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Edit Daerah')
|
||||
@section('content')
|
||||
<div class="page-heading"><div class="eyebrow">Setup</div><h1 class="h3 mb-0">Edit Daerah Mengundi</h1></div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4"><form method="POST" action="{{ route('admin.setup.daerah.update', $daerah) }}">@method('PUT') @include('admin.setup.daerah._form')</form></div>
|
||||
@endsection
|
||||
41
resources/views/admin/setup/daerah/index.blade.php
Normal file
41
resources/views/admin/setup/daerah/index.blade.php
Normal file
@@ -0,0 +1,41 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Daerah Mengundi')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div><h1 class="h3 mb-1">Daerah Mengundi</h1><p class="text-secondary mb-0">Daerah mengundi di bawah bahagian pilihanraya.</p></div>
|
||||
<a href="{{ route('admin.setup.daerah.create') }}" class="btn btn-primary"><i class="bi bi-plus-circle me-1"></i>Tambah</a>
|
||||
</div>
|
||||
</div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead><tr><x-sort-th column="code" label="Kod" /><x-sort-th column="name" label="Nama" /><th>Bahagian</th><th>Election</th><th class="text-end no-sort">Tindakan</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($daerahs as $daerah)
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ $daerah->code }}</td>
|
||||
<td>{{ $daerah->name }}</td>
|
||||
<td>{{ $daerah->bahagianPilihanraya?->name }}</td>
|
||||
<td>{{ $daerah->election?->name }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.setup.daerah.edit', $daerah) }}" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
<form method="POST" action="{{ route('admin.setup.daerah.destroy', $daerah) }}" class="d-inline" data-confirm>
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit">Padam</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="text-center text-secondary py-4">Tiada rekod.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $daerahs->links() }}
|
||||
</div>
|
||||
@endsection
|
||||
128
resources/views/admin/setup/import/create.blade.php
Normal file
128
resources/views/admin/setup/import/create.blade.php
Normal file
@@ -0,0 +1,128 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Import Pusat Mengundi')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin · Setup</div>
|
||||
<h1 class="h3 mb-1">Import Pusat Mengundi</h1>
|
||||
<p class="text-secondary mb-0">Upload fail XLSX untuk mencipta DUN, Pusat Mengundi, Saluran, dan Kuota secara automatik.</p>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
@if (session('import_errors'))
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<div class="fw-semibold mb-1">Beberapa baris tidak dapat diimport:</div>
|
||||
<ul class="mb-0 small">
|
||||
@foreach (session('import_errors') as $err)
|
||||
<li>{{ $err }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<h2 class="h5 mb-3">Borang Import</h2>
|
||||
|
||||
<form method="POST" action="{{ route('admin.setup.import.store') }}" enctype="multipart/form-data">
|
||||
@csrf
|
||||
|
||||
<div class="mb-3">
|
||||
<label for="election_id" class="form-label fw-semibold">Pilihan Raya</label>
|
||||
<select id="election_id" name="election_id" class="form-select @error('election_id') is-invalid @enderror" required>
|
||||
<option value="">Pilih pilihan raya</option>
|
||||
@foreach ($elections as $election)
|
||||
<option value="{{ $election->id }}" @selected(old('election_id') == $election->id)>
|
||||
{{ $election->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('election_id')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-md-4">
|
||||
<label for="dun_code" class="form-label fw-semibold">Kod DUN</label>
|
||||
<input id="dun_code" type="text" name="dun_code" value="{{ old('dun_code', 'N49') }}"
|
||||
class="form-control @error('dun_code') is-invalid @enderror" maxlength="20"
|
||||
placeholder="cth: N49" required>
|
||||
@error('dun_code')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
<label for="dun_name" class="form-label fw-semibold">Nama DUN</label>
|
||||
<input id="dun_name" type="text" name="dun_name" value="{{ old('dun_name', 'Kota Iskandar') }}"
|
||||
class="form-control @error('dun_name') is-invalid @enderror" maxlength="255"
|
||||
placeholder="cth: Kota Iskandar" required>
|
||||
@error('dun_name')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-4">
|
||||
<label for="file" class="form-label fw-semibold">Fail XLSX Senarai Pusat Mengundi</label>
|
||||
<input id="file" type="file" name="file" accept=".xlsx"
|
||||
class="form-control @error('file') is-invalid @enderror" required>
|
||||
<div class="form-text">Format: .xlsx sahaja, saiz maksimum 10MB.</div>
|
||||
@error('file')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="alert alert-warning py-2 small" role="alert">
|
||||
<i class="bi bi-exclamation-triangle me-1"></i>
|
||||
<strong>Amaran:</strong> Import akan <strong>menggantikan</strong> semua data Pusat Mengundi, Saluran, dan Kuota sedia ada untuk DUN yang sama. Pastikan fail betul sebelum teruskan.
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-3">
|
||||
<a href="{{ route('admin.setup.index') }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button type="submit" class="btn btn-success">
|
||||
<i class="bi bi-upload me-1"></i>Import Data
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-xl-5">
|
||||
<div class="content-panel p-3 p-md-4 h-100">
|
||||
<h2 class="h5 mb-3">Format Fail XLSX</h2>
|
||||
<p class="text-secondary small mb-2">Fail mesti mempunyai lajur mengikut susunan berikut (baris pertama = tajuk):</p>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm table-bordered small">
|
||||
<thead class="table-light">
|
||||
<tr>
|
||||
<th>Lajur</th>
|
||||
<th>Nama</th>
|
||||
<th>Keterangan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>A</td><td>SEKOLAH</td><td>Nama Pusat Mengundi</td></tr>
|
||||
<tr><td>B</td><td>NAMA PPM</td><td>Nama PPM (simpan sebagai metadata)</td></tr>
|
||||
<tr><td>C</td><td>SALURAN</td><td>Bilangan saluran (nombor)</td></tr>
|
||||
<tr><td>D–F</td><td>KTM, POLIS, KP</td><td>Dikira automatik dari bilangan saluran</td></tr>
|
||||
<tr><td>G</td><td>PPM</td><td>Kuota PPM per pusat (0 atau 1)</td></tr>
|
||||
<tr><td>H</td><td>KPDP</td><td>Dikira automatik</td></tr>
|
||||
<tr><td>I</td><td>PAPM</td><td>Kuota PAPM per pusat (nombor)</td></tr>
|
||||
<tr><td>J</td><td>JKM</td><td>Kuota JKM per pusat</td></tr>
|
||||
<tr><td>K</td><td>KKM</td><td>Kuota KKM per pusat</td></tr>
|
||||
<tr><td>L</td><td>TAMBAHAN</td><td>Dikira automatik</td></tr>
|
||||
<tr><td>M</td><td>NO TELEFON</td><td>Telefon PPM (simpan sebagai metadata)</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="text-secondary small mt-2 mb-0">
|
||||
Lajur dengan formula Excel (KTM, POLIS, KP, KPDP, TAMBAHAN) dikira semula secara automatik berdasarkan bilangan saluran — nilai asal dalam fail diabaikan.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
55
resources/views/admin/setup/index.blade.php
Normal file
55
resources/views/admin/setup/index.blade.php
Normal file
@@ -0,0 +1,55 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Setup Pilihanraya')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Setup Pilihanraya</h1>
|
||||
<p class="text-secondary mb-0">Konfigurasi hierarchy, jawatan, kuota, PPM, dan QR Pusat Mengundi.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="row g-3">
|
||||
@foreach ([
|
||||
['label' => 'Election', 'value' => $counts['elections'], 'icon' => 'bi-calendar-event', 'tone' => 'primary'],
|
||||
['label' => 'DUN', 'value' => $counts['duns'], 'icon' => 'bi-map', 'tone' => 'info'],
|
||||
['label' => 'Pusat', 'value' => $counts['pusat'], 'icon' => 'bi-building', 'tone' => 'success'],
|
||||
['label' => 'Saluran', 'value' => $counts['saluran'], 'icon' => 'bi-diagram-3', 'tone' => 'success'],
|
||||
['label' => 'Jawatan', 'value' => $counts['positions'], 'icon' => 'bi-person-vcard', 'tone' => 'secondary'],
|
||||
['label' => 'Kuota', 'value' => $counts['quotas'], 'icon' => 'bi-list-ol', 'tone' => 'warning'],
|
||||
['label' => 'PPM aktif', 'value' => $counts['ppmAssignments'], 'icon' => 'bi-person-check', 'tone' => 'primary'],
|
||||
] as $card)
|
||||
<div class="col-12 col-sm-6 col-xl-3">
|
||||
<div class="stat-card h-100">
|
||||
<div class="d-flex justify-content-between gap-3">
|
||||
<div>
|
||||
<div class="text-secondary small">{{ $card['label'] }}</div>
|
||||
<div class="fs-3 fw-bold mt-2">{{ $card['value'] }}</div>
|
||||
</div>
|
||||
<span class="stat-icon text-bg-{{ $card['tone'] }}"><i class="bi {{ $card['icon'] }}"></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="content-panel mt-4 p-3 p-md-4">
|
||||
<h2 class="h5 mb-3">Tindakan Setup</h2>
|
||||
<div class="row g-2">
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-success w-100 text-start" href="{{ route('admin.setup.import.create') }}"><i class="bi bi-upload me-2"></i>Import Data Pusat</a></div>
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-primary w-100 text-start" href="{{ route('admin.setup.pusat.index') }}"><i class="bi bi-building me-2"></i>Senarai Pusat</a></div>
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-primary w-100 text-start" href="{{ route('admin.setup.positions.index') }}"><i class="bi bi-person-vcard me-2"></i>Setup Jawatan</a></div>
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-primary w-100 text-start" href="{{ route('admin.setup.pusat.index') }}"><i class="bi bi-list-ol me-2"></i>Urus Kuota</a></div>
|
||||
@php $activeElection = \App\Models\Election::query()->where('status', 'active')->first(); @endphp
|
||||
@if ($activeElection)
|
||||
<div class="col-12 col-md-6 col-xl-3"><a class="btn btn-outline-warning w-100 text-start" href="{{ route('admin.setup.settings.edit', $activeElection) }}"><i class="bi bi-sliders me-2"></i>Tetapan Pilihanraya</a></div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
45
resources/views/admin/setup/positions/_form.blade.php
Normal file
45
resources/views/admin/setup/positions/_form.blade.php
Normal file
@@ -0,0 +1,45 @@
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-3">
|
||||
<label class="form-label" for="code">Kod</label>
|
||||
<input id="code" name="code" class="form-control" value="{{ old('code', $position->code) }}" required>
|
||||
</div>
|
||||
<div class="col-12 col-lg-5">
|
||||
<label class="form-label" for="name">Nama Jawatan</label>
|
||||
<input id="name" name="name" class="form-control" value="{{ old('name', $position->name) }}" required>
|
||||
</div>
|
||||
<div class="col-12 col-lg-2">
|
||||
<label class="form-label" for="scope">Skop</label>
|
||||
<select id="scope" name="scope" class="form-select" required>
|
||||
@foreach (['pusat' => 'Pusat', 'saluran' => 'Saluran', 'external' => 'External'] as $value => $label)
|
||||
<option value="{{ $value }}" @selected(old('scope', $position->scope ?: 'pusat') === $value)>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-12 col-lg-2">
|
||||
<label class="form-label" for="sort_order">Susunan</label>
|
||||
<input id="sort_order" name="sort_order" type="number" min="0" class="form-control" value="{{ old('sort_order', $position->sort_order ?? 0) }}">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="d-flex flex-wrap gap-4">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="1" id="is_public_applyable" name="is_public_applyable" @checked(old('is_public_applyable', $position->is_public_applyable))>
|
||||
<label class="form-check-label" for="is_public_applyable">Boleh dipohon awam</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="1" id="is_assignable" name="is_assignable" @checked(old('is_assignable', $position->exists ? $position->is_assignable : true))>
|
||||
<label class="form-check-label" for="is_assignable">Boleh assign</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="1" id="allows_dual_role" name="allows_dual_role" @checked(old('allows_dual_role', $position->allows_dual_role))>
|
||||
<label class="form-check-label" for="allows_dual_role">Benarkan dual-role</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a href="{{ route('admin.setup.positions.index') }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-save me-1"></i>Simpan</button>
|
||||
</div>
|
||||
7
resources/views/admin/setup/positions/create.blade.php
Normal file
7
resources/views/admin/setup/positions/create.blade.php
Normal file
@@ -0,0 +1,7 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Tambah Jawatan')
|
||||
@section('content')
|
||||
<div class="page-heading"><div class="eyebrow">Setup</div><h1 class="h3 mb-0">Tambah Jawatan</h1></div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4"><form method="POST" action="{{ route('admin.setup.positions.store') }}">@include('admin.setup.positions._form')</form></div>
|
||||
@endsection
|
||||
7
resources/views/admin/setup/positions/edit.blade.php
Normal file
7
resources/views/admin/setup/positions/edit.blade.php
Normal file
@@ -0,0 +1,7 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Edit Jawatan')
|
||||
@section('content')
|
||||
<div class="page-heading"><div class="eyebrow">Setup</div><h1 class="h3 mb-0">Edit Jawatan</h1></div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4"><form method="POST" action="{{ route('admin.setup.positions.update', $position) }}">@method('PUT') @include('admin.setup.positions._form')</form></div>
|
||||
@endsection
|
||||
42
resources/views/admin/setup/positions/index.blade.php
Normal file
42
resources/views/admin/setup/positions/index.blade.php
Normal file
@@ -0,0 +1,42 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Jawatan')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div><h1 class="h3 mb-1">Jawatan</h1><p class="text-secondary mb-0">Tetapan jawatan dan ciri assignment.</p></div>
|
||||
<a href="{{ route('admin.setup.positions.create') }}" class="btn btn-primary"><i class="bi bi-plus-circle me-1"></i>Tambah</a>
|
||||
</div>
|
||||
</div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead><tr><x-sort-th column="code" label="Kod" /><x-sort-th column="name" label="Nama" /><x-sort-th column="scope" label="Skop" /><th>Awam</th><th>Dual-role</th><th class="text-end no-sort">Tindakan</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($positions as $position)
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ $position->code }}</td>
|
||||
<td>{{ $position->name }}</td>
|
||||
<td><span class="badge text-bg-light border">{{ $position->scope }}</span></td>
|
||||
<td>{{ $position->is_public_applyable ? 'Ya' : 'Tidak' }}</td>
|
||||
<td>{{ $position->allows_dual_role ? 'Ya' : 'Tidak' }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.setup.positions.edit', $position) }}" class="btn btn-sm btn-outline-primary">Edit</a>
|
||||
<form method="POST" action="{{ route('admin.setup.positions.destroy', $position) }}" class="d-inline" data-confirm>
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit">Padam</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="6" class="text-center text-secondary py-4">Tiada rekod.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $positions->links() }}
|
||||
</div>
|
||||
@endsection
|
||||
105
resources/views/admin/setup/pusat/_form.blade.php
Normal file
105
resources/views/admin/setup/pusat/_form.blade.php
Normal file
@@ -0,0 +1,105 @@
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label for="election_id" class="form-label">Pilihan Raya</label>
|
||||
<select id="election_id" name="election_id" class="form-select @error('election_id') is-invalid @enderror" required>
|
||||
<option value="">Pilih pilihan raya</option>
|
||||
@foreach ($elections as $election)
|
||||
<option value="{{ $election->id }}" @selected((string) old('election_id', $pusat->election_id) === (string) $election->id)>
|
||||
{{ $election->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('election_id')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label for="dun_id" class="form-label">Dewan Undangan Negeri (DUN)</label>
|
||||
<select id="dun_id" name="dun_id" class="form-select @error('dun_id') is-invalid @enderror">
|
||||
<option value="">Pilih DUN (pilihan)</option>
|
||||
@foreach ($duns as $dun)
|
||||
<option value="{{ $dun->id }}" @selected((string) old('dun_id', $pusat->dun_id) === (string) $dun->id)>
|
||||
{{ $dun->code }} - {{ $dun->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('dun_id')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<label for="code" class="form-label">Kod Pusat</label>
|
||||
<input id="code" type="text" name="code" value="{{ old('code', $pusat->code) }}" class="form-control @error('code') is-invalid @enderror" maxlength="50" required>
|
||||
@error('code')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="col-md-8">
|
||||
<label for="name" class="form-label">Nama Pusat Mengundi</label>
|
||||
<input id="name" type="text" name="name" value="{{ old('name', $pusat->name) }}" class="form-control @error('name') is-invalid @enderror" maxlength="255" required>
|
||||
@error('name')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="col-12">
|
||||
<label for="address" class="form-label">Alamat</label>
|
||||
<textarea id="address" name="address" rows="3" class="form-control @error('address') is-invalid @enderror">{{ old('address', $pusat->address) }}</textarea>
|
||||
@error('address')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
@unless ($pusat->exists)
|
||||
@php
|
||||
$operationalFields = [
|
||||
'saluran_count' => ['label' => 'Bilangan Saluran', 'default' => 1, 'min' => 1],
|
||||
'ktm_count' => ['label' => 'KTM setiap Saluran', 'default' => 1],
|
||||
'polis_iring_count' => ['label' => 'Polis Iring setiap Saluran', 'default' => 1],
|
||||
'kp_count' => ['label' => 'KP setiap Saluran', 'default' => 4],
|
||||
'ppm_count' => ['label' => 'PPM setiap Pusat', 'default' => 1],
|
||||
'kpdp_count' => ['label' => 'KPDP setiap Saluran', 'default' => 1],
|
||||
'papm_count' => ['label' => 'PAPM setiap Pusat', 'default' => 0],
|
||||
'jkm_count' => ['label' => 'JKM setiap Pusat', 'default' => 1],
|
||||
'kkm_count' => ['label' => 'KKM setiap Pusat', 'default' => 1],
|
||||
'calon_tambahan_count' => ['label' => 'Calon Tambahan setiap Saluran', 'default' => 1],
|
||||
];
|
||||
@endphp
|
||||
|
||||
<div class="col-12 mt-4">
|
||||
<h2 class="h6 mb-1">Bilangan Operasi</h2>
|
||||
<p class="text-body-secondary small mb-0">Saluran akan dijana mengikut nombor secara automatik.</p>
|
||||
</div>
|
||||
|
||||
@foreach ($operationalFields as $field => $configuration)
|
||||
<div class="col-6 col-md-4 col-xl-3">
|
||||
<label for="{{ $field }}" class="form-label">{{ $configuration['label'] }}</label>
|
||||
<input
|
||||
id="{{ $field }}"
|
||||
type="number"
|
||||
name="{{ $field }}"
|
||||
value="{{ old($field, $configuration['default']) }}"
|
||||
min="{{ $configuration['min'] ?? 0 }}"
|
||||
max="100"
|
||||
class="form-control @error($field) is-invalid @enderror"
|
||||
required
|
||||
>
|
||||
@error($field)
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
@endforeach
|
||||
@endunless
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a href="{{ $pusat->exists ? route('admin.setup.pusat.show', $pusat) : route('admin.setup.pusat.index') }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button class="btn btn-primary" type="submit">
|
||||
<i class="bi bi-save me-1"></i>{{ $pusat->exists ? 'Kemas Kini Pusat' : 'Simpan Pusat' }}
|
||||
</button>
|
||||
</div>
|
||||
18
resources/views/admin/setup/pusat/create.blade.php
Normal file
18
resources/views/admin/setup/pusat/create.blade.php
Normal file
@@ -0,0 +1,18 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Tambah Pusat')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup</div>
|
||||
<h1 class="h3 mb-0">Tambah Pusat Mengundi</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.store') }}">
|
||||
@include('admin.setup.pusat._form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
19
resources/views/admin/setup/pusat/edit.blade.php
Normal file
19
resources/views/admin/setup/pusat/edit.blade.php
Normal file
@@ -0,0 +1,19 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Pusat')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup</div>
|
||||
<h1 class="h3 mb-0">Edit Pusat Mengundi</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.update', $pusat) }}">
|
||||
@method('PUT')
|
||||
@include('admin.setup.pusat._form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
47
resources/views/admin/setup/pusat/index.blade.php
Normal file
47
resources/views/admin/setup/pusat/index.blade.php
Normal file
@@ -0,0 +1,47 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pusat Mengundi')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div><h1 class="h3 mb-1">Pusat Mengundi</h1><p class="text-secondary mb-0">Pusat Mengundi, QR pendaftaran, dan assignment PPM.</p></div>
|
||||
<a href="{{ route('admin.setup.pusat.create') }}" class="btn btn-primary"><i class="bi bi-plus-circle me-1"></i>Tambah</a>
|
||||
</div>
|
||||
</div>
|
||||
@include('admin.setup._nav')
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead><tr><x-sort-th column="code" label="Kod" /><x-sort-th column="name" label="Nama" /><th>DUN</th><th>PPM</th><th>Saluran</th><th>QR</th><th class="text-end no-sort">Tindakan</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($pusats as $pusat)
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ $pusat->code }}</td>
|
||||
<td>{{ $pusat->name }}</td>
|
||||
<td>{{ $pusat->dun?->code }}</td>
|
||||
<td class="small text-secondary">{{ $pusat->ppm_name ?: '-' }}</td>
|
||||
<td>{{ $pusat->saluran_mengundis_count ?? $pusat->saluranMengundis->count() }}</td>
|
||||
<td><span class="badge {{ $pusat->qr_code_path ? 'text-bg-success' : 'text-bg-secondary' }}">{{ $pusat->qr_code_path ? 'Ada' : 'Belum' }}</span></td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.setup.pusat.show', $pusat) }}" class="btn btn-sm btn-outline-primary">Buka</a>
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}" class="btn btn-sm btn-outline-info">Saluran</a>
|
||||
<a href="{{ route('admin.setup.pusat.edit', $pusat) }}" class="btn btn-sm btn-outline-secondary">Edit</a>
|
||||
<form action="{{ route('admin.setup.pusat.destroy', $pusat) }}" method="POST" class="d-inline"
|
||||
onsubmit="return confirm('Padam {{ addslashes($pusat->name) }}? Tindakan ini tidak boleh diundur.')">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-sm btn-outline-danger">Padam</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-secondary py-4">Tiada rekod. <a href="{{ route('admin.setup.import.create') }}">Import data pusat</a>.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $pusats->links() }}
|
||||
</div>
|
||||
@endsection
|
||||
87
resources/views/admin/setup/pusat/show.blade.php
Normal file
87
resources/views/admin/setup/pusat/show.blade.php
Normal file
@@ -0,0 +1,87 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', $pusat->name)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Pusat Mengundi</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">{{ $pusat->name }}</h1>
|
||||
<p class="text-secondary mb-0">{{ $pusat->code }} - {{ $pusat->daerahMengundi?->name }}</p>
|
||||
</div>
|
||||
<div class="d-flex gap-2">
|
||||
<a href="{{ route('admin.setup.pusat.edit', $pusat) }}" class="btn btn-outline-primary"><i class="bi bi-pencil me-1"></i>Edit</a>
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.generate-qr', $pusat) }}">
|
||||
@csrf
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-qr-code me-1"></i>Jana QR</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-12 col-xl-7">
|
||||
<div class="content-panel p-3 p-md-4 mb-4">
|
||||
<h2 class="h5 mb-3">Maklumat Pusat</h2>
|
||||
<dl class="row mb-0">
|
||||
<dt class="col-sm-4">Election</dt><dd class="col-sm-8">{{ $pusat->election?->name }}</dd>
|
||||
<dt class="col-sm-4">Alamat</dt><dd class="col-sm-8">{{ $pusat->address ?: '-' }}</dd>
|
||||
<dt class="col-sm-4">Public UUID</dt><dd class="col-sm-8"><code>{{ $pusat->public_uuid }}</code></dd>
|
||||
<dt class="col-sm-4">Link QR</dt>
|
||||
<dd class="col-sm-8">
|
||||
@if ($pusat->registration_url)
|
||||
<a href="{{ $pusat->registration_url }}" target="_blank">{{ $pusat->registration_url }}</a>
|
||||
@else
|
||||
<span class="text-secondary">Belum dijana.</span>
|
||||
@endif
|
||||
</dd>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<h2 class="h5 mb-3">Saluran</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm align-middle">
|
||||
<thead><tr><th>No.</th><th>Nama</th><th>Pengundi</th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($pusat->saluranMengundis as $saluran)
|
||||
<tr><td>{{ $saluran->number }}</td><td>{{ $saluran->name }}</td><td>{{ $saluran->voter_count ?? '-' }}</td></tr>
|
||||
@empty
|
||||
<tr><td colspan="3" class="text-secondary text-center py-3">Tiada saluran.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-xl-5">
|
||||
<div class="content-panel p-3 p-md-4 mb-4">
|
||||
<h2 class="h5 mb-3">QR Pendaftaran</h2>
|
||||
@if ($pusat->qr_code_path)
|
||||
<img class="img-fluid border rounded bg-white p-2 mb-3" style="max-width: 220px" src="{{ route('admin.setup.pusat.qr-svg', $pusat) }}" alt="QR Pusat Mengundi">
|
||||
@else
|
||||
<p class="text-secondary">QR belum dijana.</p>
|
||||
@endif
|
||||
<div class="small text-secondary">QR menunjuk ke pautan awam Pusat Mengundi ini.</div>
|
||||
</div>
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<h2 class="h5 mb-3">Tetapan PPM</h2>
|
||||
<p class="mb-3">PPM semasa: <span class="fw-semibold">{{ $ppmAssignment?->user?->name ?? 'Belum ditetapkan' }}</span></p>
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.assign-ppm', $pusat) }}">
|
||||
@csrf
|
||||
<label for="user_id" class="form-label">Pilih pengguna</label>
|
||||
<select id="user_id" name="user_id" class="form-select mb-3" required data-tom-select>
|
||||
@foreach ($users as $user)
|
||||
<option value="{{ $user->id }}" @selected($ppmAssignment?->user_id === $user->id)>{{ $user->name }} - {{ $user->email }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<button class="btn btn-primary" type="submit"><i class="bi bi-person-check me-1"></i>Simpan PPM</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
35
resources/views/admin/setup/quotas/_form.blade.php
Normal file
35
resources/views/admin/setup/quotas/_form.blade.php
Normal file
@@ -0,0 +1,35 @@
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-8">
|
||||
<label class="form-label fw-semibold" for="position_id">Jawatan</label>
|
||||
<select id="position_id" name="position_id" class="form-select @error('position_id') is-invalid @enderror" required data-tom-select>
|
||||
<option value="">Pilih jawatan</option>
|
||||
@foreach ($positions as $position)
|
||||
<option value="{{ $position->id }}" @selected((int) old('position_id', $quota->position_id) === $position->id)>
|
||||
{{ $position->code }} — {{ $position->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('position_id')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-4">
|
||||
<label class="form-label fw-semibold" for="quota">Bilangan Kekosongan</label>
|
||||
<input id="quota" name="quota" type="number" min="0" max="9999"
|
||||
class="form-control @error('quota') is-invalid @enderror"
|
||||
value="{{ old('quota', $quota->quota ?? 0) }}" required>
|
||||
@error('quota')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a href="{{ route('admin.setup.pusat.saluran.kuota.index', [$pusat, $saluran]) }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button class="btn btn-primary" type="submit">
|
||||
<i class="bi bi-save me-1"></i>{{ $quota->exists ? 'Kemas Kini' : 'Simpan' }}
|
||||
</button>
|
||||
</div>
|
||||
41
resources/views/admin/setup/quotas/_pusat-form.blade.php
Normal file
41
resources/views/admin/setup/quotas/_pusat-form.blade.php
Normal file
@@ -0,0 +1,41 @@
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-12 col-lg-8">
|
||||
<label class="form-label fw-semibold" for="position_id">Jawatan</label>
|
||||
@if ($quota->exists)
|
||||
{{-- Edit: papar nama sahaja, tidak boleh tukar jawatan (guna updateOrCreate) --}}
|
||||
<input type="hidden" name="position_id" value="{{ $quota->position_id }}">
|
||||
<input type="text" class="form-control" value="{{ $quota->position?->code }} — {{ $quota->position?->name }}" disabled>
|
||||
@else
|
||||
<select id="position_id" name="position_id" class="form-select @error('position_id') is-invalid @enderror" required data-tom-select>
|
||||
<option value="">Pilih jawatan</option>
|
||||
@foreach ($positions as $position)
|
||||
<option value="{{ $position->id }}" @selected((int) old('position_id', $quota->position_id) === $position->id)>
|
||||
{{ $position->code }} — {{ $position->name }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('position_id')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="col-12 col-lg-4">
|
||||
<label class="form-label fw-semibold" for="quota">Bilangan Kekosongan</label>
|
||||
<input id="quota" name="quota" type="number" min="0" max="9999"
|
||||
class="form-control @error('quota') is-invalid @enderror"
|
||||
value="{{ old('quota', $quota->quota ?? 0) }}" required>
|
||||
@error('quota')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a href="{{ route('admin.setup.pusat.kuota.index', $pusat) }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button class="btn btn-primary" type="submit">
|
||||
<i class="bi bi-save me-1"></i>{{ $quota->exists ? 'Kemas Kini' : 'Simpan' }}
|
||||
</button>
|
||||
</div>
|
||||
23
resources/views/admin/setup/quotas/create.blade.php
Normal file
23
resources/views/admin/setup/quotas/create.blade.php
Normal file
@@ -0,0 +1,23 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Tambah Kuota — Saluran ' . $saluran->number)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">
|
||||
Setup ·
|
||||
<a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">{{ $pusat->name }}</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.saluran.kuota.index', [$pusat, $saluran]) }}">Saluran {{ $saluran->number }}</a>
|
||||
</div>
|
||||
<h1 class="h3 mb-0">Tambah Kuota Jawatan</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.saluran.kuota.store', [$pusat, $saluran]) }}">
|
||||
@include('admin.setup.quotas._form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
24
resources/views/admin/setup/quotas/edit.blade.php
Normal file
24
resources/views/admin/setup/quotas/edit.blade.php
Normal file
@@ -0,0 +1,24 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Kuota — ' . $quota->position?->code)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">
|
||||
Setup ·
|
||||
<a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">{{ $pusat->name }}</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.saluran.kuota.index', [$pusat, $saluran]) }}">Saluran {{ $saluran->number }}</a>
|
||||
</div>
|
||||
<h1 class="h3 mb-0">Edit Kuota Jawatan</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.saluran.kuota.update', [$pusat, $saluran, $quota]) }}">
|
||||
@method('PUT')
|
||||
@include('admin.setup.quotas._form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
70
resources/views/admin/setup/quotas/index.blade.php
Normal file
70
resources/views/admin/setup/quotas/index.blade.php
Normal file
@@ -0,0 +1,70 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Kuota — Saluran ' . $saluran->number)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">
|
||||
Setup ·
|
||||
<a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">{{ $pusat->name }}</a>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Kuota Jawatan</h1>
|
||||
<p class="text-secondary mb-0">{{ $pusat->code }} — {{ $pusat->name }} · Saluran {{ $saluran->number }}</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.setup.pusat.saluran.kuota.create', [$pusat, $saluran]) }}" class="btn btn-primary">
|
||||
<i class="bi bi-plus-circle me-1"></i>Tambah Kuota
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Jawatan</th>
|
||||
<x-sort-th column="quota" label="Kuota" class="text-end" />
|
||||
<th class="text-end no-sort">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($quotas as $quota)
|
||||
<tr>
|
||||
<td>
|
||||
<span class="fw-semibold">{{ $quota->position?->code }}</span>
|
||||
<div class="small text-secondary">{{ $quota->position?->name }}</div>
|
||||
</td>
|
||||
<td class="text-end fw-semibold">{{ $quota->quota }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.setup.pusat.saluran.kuota.edit', [$pusat, $saluran, $quota]) }}" class="btn btn-sm btn-outline-secondary">Edit</a>
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.saluran.kuota.destroy', [$pusat, $saluran, $quota]) }}" class="d-inline"
|
||||
onsubmit="return confirm('Padam kuota {{ addslashes($quota->position?->code) }}?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit">Padam</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="3" class="text-center text-secondary py-4">
|
||||
Tiada kuota. <a href="{{ route('admin.setup.pusat.saluran.kuota.create', [$pusat, $saluran]) }}">Tambah kuota</a>.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $quotas->links() }}
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left me-1"></i>Kembali ke Saluran
|
||||
</a>
|
||||
</div>
|
||||
@endsection
|
||||
23
resources/views/admin/setup/quotas/pusat-create.blade.php
Normal file
23
resources/views/admin/setup/quotas/pusat-create.blade.php
Normal file
@@ -0,0 +1,23 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Tambah Kuota Pusat — ' . $pusat->name)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">
|
||||
Setup ·
|
||||
<a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">{{ $pusat->name }}</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.kuota.index', $pusat) }}">Saluran 0 (Pusat)</a>
|
||||
</div>
|
||||
<h1 class="h3 mb-0">Tambah Kuota Peringkat Pusat</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.kuota.store', $pusat) }}">
|
||||
@include('admin.setup.quotas._pusat-form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
24
resources/views/admin/setup/quotas/pusat-edit.blade.php
Normal file
24
resources/views/admin/setup/quotas/pusat-edit.blade.php
Normal file
@@ -0,0 +1,24 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Kuota Pusat — ' . $quota->position?->code)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">
|
||||
Setup ·
|
||||
<a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">{{ $pusat->name }}</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.kuota.index', $pusat) }}">Saluran 0 (Pusat)</a>
|
||||
</div>
|
||||
<h1 class="h3 mb-0">Edit Kuota Peringkat Pusat</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.kuota.update', [$pusat, $quota]) }}">
|
||||
@method('PUT')
|
||||
@include('admin.setup.quotas._pusat-form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
70
resources/views/admin/setup/quotas/pusat-index.blade.php
Normal file
70
resources/views/admin/setup/quotas/pusat-index.blade.php
Normal file
@@ -0,0 +1,70 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Kuota Pusat — ' . $pusat->name)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">
|
||||
Setup ·
|
||||
<a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a> ·
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">{{ $pusat->name }}</a>
|
||||
</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Kuota Jawatan — Peringkat Pusat</h1>
|
||||
<p class="text-secondary mb-0">{{ $pusat->code }} — {{ $pusat->name }} · Saluran 0 (Pusat)</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.setup.pusat.kuota.create', $pusat) }}" class="btn btn-primary">
|
||||
<i class="bi bi-plus-circle me-1"></i>Tambah Kuota
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Jawatan</th>
|
||||
<x-sort-th column="quota" label="Kuota" class="text-end" />
|
||||
<th class="text-end no-sort">Tindakan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($quotas as $quota)
|
||||
<tr>
|
||||
<td>
|
||||
<span class="fw-semibold">{{ $quota->position?->code }}</span>
|
||||
<div class="small text-secondary">{{ $quota->position?->name }}</div>
|
||||
</td>
|
||||
<td class="text-end fw-semibold">{{ $quota->quota }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.setup.pusat.kuota.edit', [$pusat, $quota]) }}" class="btn btn-sm btn-outline-secondary">Edit</a>
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.kuota.destroy', [$pusat, $quota]) }}" class="d-inline"
|
||||
onsubmit="return confirm('Padam kuota {{ addslashes($quota->position?->code) }}?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit">Padam</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="3" class="text-center text-secondary py-4">
|
||||
Tiada kuota peringkat pusat. <a href="{{ route('admin.setup.pusat.kuota.create', $pusat) }}">Tambah kuota</a>.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $quotas->links() }}
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left me-1"></i>Kembali ke Saluran
|
||||
</a>
|
||||
</div>
|
||||
@endsection
|
||||
28
resources/views/admin/setup/saluran/_form.blade.php
Normal file
28
resources/views/admin/setup/saluran/_form.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
@csrf
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label for="number" class="form-label">Nombor Saluran</label>
|
||||
<input id="number" type="text" name="number" value="{{ old('number', $saluran->number) }}"
|
||||
class="form-control @error('number') is-invalid @enderror" maxlength="20" required>
|
||||
@error('number')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="col-md-6">
|
||||
<label for="voter_count" class="form-label">Bilangan Pengundi</label>
|
||||
<input id="voter_count" type="number" name="voter_count" value="{{ old('voter_count', $saluran->voter_count) }}"
|
||||
class="form-control @error('voter_count') is-invalid @enderror" min="0">
|
||||
@error('voter_count')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-4">
|
||||
<a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}" class="btn btn-outline-secondary">Batal</a>
|
||||
<button class="btn btn-primary" type="submit">
|
||||
<i class="bi bi-save me-1"></i>{{ $saluran->exists ? 'Kemas Kini Saluran' : 'Simpan Saluran' }}
|
||||
</button>
|
||||
</div>
|
||||
18
resources/views/admin/setup/saluran/create.blade.php
Normal file
18
resources/views/admin/setup/saluran/create.blade.php
Normal file
@@ -0,0 +1,18 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Tambah Saluran — ' . $pusat->name)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup · <a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a> · <a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">{{ $pusat->name }}</a></div>
|
||||
<h1 class="h3 mb-0">Tambah Saluran Mengundi</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.saluran.store', $pusat) }}">
|
||||
@include('admin.setup.saluran._form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
19
resources/views/admin/setup/saluran/edit.blade.php
Normal file
19
resources/views/admin/setup/saluran/edit.blade.php
Normal file
@@ -0,0 +1,19 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Edit Saluran — ' . $pusat->name)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup · <a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a> · <a href="{{ route('admin.setup.pusat.saluran.index', $pusat) }}">{{ $pusat->name }}</a></div>
|
||||
<h1 class="h3 mb-0">Edit Saluran Mengundi</h1>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.saluran.update', [$pusat, $saluran]) }}">
|
||||
@method('PUT')
|
||||
@include('admin.setup.saluran._form')
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
69
resources/views/admin/setup/saluran/index.blade.php
Normal file
69
resources/views/admin/setup/saluran/index.blade.php
Normal file
@@ -0,0 +1,69 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Saluran — ' . $pusat->name)
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Setup · <a href="{{ route('admin.setup.pusat.index') }}">Pusat Mengundi</a></div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Saluran Mengundi</h1>
|
||||
<p class="text-secondary mb-0">{{ $pusat->code }} — {{ $pusat->name }}</p>
|
||||
</div>
|
||||
<a href="{{ route('admin.setup.pusat.saluran.create', $pusat) }}" class="btn btn-primary">
|
||||
<i class="bi bi-plus-circle me-1"></i>Tambah Saluran
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead>
|
||||
<tr><x-sort-th column="number" label="No." /><th>Nama</th><x-sort-th column="voter_count" label="Bilangan Pengundi" /><th class="text-end no-sort">Tindakan</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{-- Row tetap: Saluran 0 = Kuota peringkat Pusat --}}
|
||||
<tr class="table-light">
|
||||
<td class="fw-semibold text-secondary">0</td>
|
||||
<td>
|
||||
<span class="fw-semibold">Pusat</span>
|
||||
<div class="small text-secondary">Kuota jawatan peringkat pusat (PPM, PAPM, JKM, KKM, dll.)</div>
|
||||
</td>
|
||||
<td class="text-secondary">—</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.setup.pusat.kuota.index', $pusat) }}" class="btn btn-sm btn-outline-info">Kuota</a>
|
||||
</td>
|
||||
</tr>
|
||||
@forelse ($salurans as $saluran)
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ $saluran->number }}</td>
|
||||
<td>{{ $saluran->name ?? '-' }}</td>
|
||||
<td>{{ $saluran->voter_count ?? '-' }}</td>
|
||||
<td class="text-end">
|
||||
<a href="{{ route('admin.setup.pusat.saluran.kuota.index', [$pusat, $saluran]) }}" class="btn btn-sm btn-outline-info">Kuota</a>
|
||||
<a href="{{ route('admin.setup.pusat.saluran.edit', [$pusat, $saluran]) }}" class="btn btn-sm btn-outline-secondary">Edit</a>
|
||||
<form method="POST" action="{{ route('admin.setup.pusat.saluran.destroy', [$pusat, $saluran]) }}" class="d-inline"
|
||||
onsubmit="return confirm('Padam saluran {{ $saluran->number }}?')">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-outline-danger" type="submit">Padam</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4" class="text-center text-secondary py-4">Tiada saluran. <a href="{{ route('admin.setup.pusat.saluran.create', $pusat) }}">Tambah saluran</a>.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $salurans->links() }}
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
<a href="{{ route('admin.setup.pusat.show', $pusat) }}" class="btn btn-outline-secondary">
|
||||
<i class="bi bi-arrow-left me-1"></i>Kembali ke {{ $pusat->name }}
|
||||
</a>
|
||||
</div>
|
||||
@endsection
|
||||
213
resources/views/admin/setup/settings/edit.blade.php
Normal file
213
resources/views/admin/setup/settings/edit.blade.php
Normal file
@@ -0,0 +1,213 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Tetapan Pilihanraya')
|
||||
|
||||
@section('content')
|
||||
<div class="page-heading">
|
||||
<div class="eyebrow">Admin · Setup</div>
|
||||
<div class="d-flex justify-content-between flex-column flex-lg-row gap-3">
|
||||
<div>
|
||||
<h1 class="h3 mb-1">Tetapan Pilihanraya</h1>
|
||||
<p class="text-secondary mb-0">{{ $election->name }} · Kawalan tarikh, mod kehadiran, dan pendaftaran.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@include('admin.setup._nav')
|
||||
|
||||
<div class="row g-3">
|
||||
{{-- Status semasa --}}
|
||||
<div class="col-12 col-xl-4">
|
||||
<div class="content-panel p-3 p-md-4 h-100">
|
||||
<h2 class="h5 mb-3">Status Semasa</h2>
|
||||
|
||||
@if ($election->settings)
|
||||
<dl class="mb-0">
|
||||
<dt class="text-secondary small">Pilihanraya</dt>
|
||||
<dd class="mb-3">{{ $election->name }}</dd>
|
||||
|
||||
<dt class="text-secondary small">Tarikh Daftar Buka</dt>
|
||||
<dd class="mb-3">{{ $election->settings->registration_start_date?->format('d/m/Y') ?? '-' }}</dd>
|
||||
|
||||
<dt class="text-secondary small">Tarikh Daftar Tutup</dt>
|
||||
<dd class="mb-3">{{ $election->settings->registration_end_date?->format('d/m/Y') ?? '-' }}</dd>
|
||||
|
||||
<dt class="text-secondary small">Tarikh Mengundi</dt>
|
||||
<dd class="mb-3">{{ $election->settings->polling_date?->format('d/m/Y') ?? '-' }}</dd>
|
||||
|
||||
<dt class="text-secondary small">Status Pendaftaran</dt>
|
||||
<dd class="mb-3">
|
||||
@if ($isRegistrationOpen)
|
||||
<span class="badge text-bg-success"><i class="bi bi-door-open me-1"></i>Dibuka</span>
|
||||
@else
|
||||
<span class="badge text-bg-secondary"><i class="bi bi-door-closed me-1"></i>Ditutup</span>
|
||||
@endif
|
||||
@if ($election->settings->is_registration_open_override !== null)
|
||||
<span class="badge text-bg-warning ms-1"><i class="bi bi-exclamation-triangle me-1"></i>Override aktif</span>
|
||||
@endif
|
||||
</dd>
|
||||
|
||||
<dt class="text-secondary small">Mod Kehadiran</dt>
|
||||
<dd class="mb-0">
|
||||
@if ($election->settings->is_attendance_active)
|
||||
<span class="badge text-bg-success"><i class="bi bi-check-circle me-1"></i>Aktif</span>
|
||||
@else
|
||||
<span class="badge text-bg-secondary"><i class="bi bi-dash-circle me-1"></i>Tidak aktif</span>
|
||||
@endif
|
||||
</dd>
|
||||
</dl>
|
||||
@else
|
||||
<p class="text-secondary small mb-0">Tiada tetapan lagi. Isikan borang untuk mencipta tetapan baru.</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Borang tetapan --}}
|
||||
<div class="col-12 col-xl-8">
|
||||
<div class="content-panel p-3 p-md-4">
|
||||
<h2 class="h5 mb-3">{{ $election->settings ? 'Kemaskini Tetapan' : 'Tetapan Baru' }}</h2>
|
||||
|
||||
@php
|
||||
$isNew = $election->settings === null;
|
||||
$formAction = $isNew
|
||||
? route('admin.setup.settings.store', $election)
|
||||
: route('admin.setup.settings.update', $election);
|
||||
@endphp
|
||||
|
||||
<form method="POST" action="{{ $formAction }}">
|
||||
@csrf
|
||||
@unless ($isNew) @method('PATCH') @endunless
|
||||
|
||||
{{-- Tarikh --}}
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-12 col-md-4">
|
||||
<label for="registration_start_date" class="form-label fw-semibold">Tarikh Daftar Buka</label>
|
||||
<input type="date" class="form-control @error('registration_start_date') is-invalid @enderror"
|
||||
id="registration_start_date" name="registration_start_date"
|
||||
value="{{ old('registration_start_date', $election->settings?->registration_start_date?->format('Y-m-d')) }}">
|
||||
@error('registration_start_date')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-12 col-md-4">
|
||||
<label for="registration_end_date" class="form-label fw-semibold">Tarikh Daftar Tutup</label>
|
||||
<input type="date" class="form-control @error('registration_end_date') is-invalid @enderror"
|
||||
id="registration_end_date" name="registration_end_date"
|
||||
value="{{ old('registration_end_date', $election->settings?->registration_end_date?->format('Y-m-d')) }}">
|
||||
@error('registration_end_date')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-12 col-md-4">
|
||||
<label for="polling_date" class="form-label fw-semibold">Tarikh Mengundi</label>
|
||||
<input type="date" class="form-control @error('polling_date') is-invalid @enderror"
|
||||
id="polling_date" name="polling_date"
|
||||
value="{{ old('polling_date', $election->settings?->polling_date?->format('Y-m-d')) }}">
|
||||
@error('polling_date')
|
||||
<div class="invalid-feedback">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{{-- Mod Kehadiran --}}
|
||||
<div class="mb-4">
|
||||
<label class="form-label fw-semibold">Mod Kehadiran</label>
|
||||
<p class="text-secondary small mb-2">
|
||||
Apabila diaktifkan, PPM boleh merekod kehadiran staf pada skrin kehadiran.
|
||||
Aktifkan hanya pada hari mengundi.
|
||||
</p>
|
||||
<div class="d-flex gap-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="is_attendance_active"
|
||||
id="attendance_off" value="0"
|
||||
{{ old('is_attendance_active', $election->settings?->is_attendance_active ? '1' : '0') === '0' ? 'checked' : '' }}>
|
||||
<label class="form-check-label" for="attendance_off">
|
||||
<span class="badge text-bg-secondary"><i class="bi bi-dash-circle me-1"></i>Tidak aktif</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="is_attendance_active"
|
||||
id="attendance_on" value="1"
|
||||
{{ old('is_attendance_active', $election->settings?->is_attendance_active ? '1' : '0') === '1' ? 'checked' : '' }}>
|
||||
<label class="form-check-label" for="attendance_on">
|
||||
<span class="badge text-bg-success"><i class="bi bi-check-circle me-1"></i>Aktif</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@error('is_attendance_active')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
{{-- Override Pendaftaran --}}
|
||||
<div class="mb-4">
|
||||
<label class="form-label fw-semibold">Override Tempoh Pendaftaran</label>
|
||||
<p class="text-secondary small mb-2">
|
||||
Secara lalai, sistem mengikut tarikh buka dan tutup pendaftaran yang ditetapkan.
|
||||
Gunakan override hanya apabila perlu buka atau tutup pendaftaran di luar tarikh tersebut.
|
||||
</p>
|
||||
|
||||
@php
|
||||
$currentOverride = old('is_registration_open_override',
|
||||
$election->settings?->is_registration_open_override === null
|
||||
? ''
|
||||
: ($election->settings->is_registration_open_override ? '1' : '0')
|
||||
);
|
||||
@endphp
|
||||
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="is_registration_open_override"
|
||||
id="override_auto" value=""
|
||||
{{ $currentOverride === '' ? 'checked' : '' }}>
|
||||
<label class="form-check-label" for="override_auto">
|
||||
<span class="fw-semibold">Auto</span>
|
||||
<div class="text-secondary small">Ikut tarikh buka/tutup pendaftaran</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="is_registration_open_override"
|
||||
id="override_open" value="1"
|
||||
{{ $currentOverride === '1' ? 'checked' : '' }}>
|
||||
<label class="form-check-label" for="override_open">
|
||||
<span class="fw-semibold text-success">Buka Paksa</span>
|
||||
<div class="text-secondary small">Buka walaupun di luar tempoh tarikh</div>
|
||||
</label>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="radio" name="is_registration_open_override"
|
||||
id="override_closed" value="0"
|
||||
{{ $currentOverride === '0' ? 'checked' : '' }}>
|
||||
<label class="form-check-label" for="override_closed">
|
||||
<span class="fw-semibold text-danger">Tutup Paksa</span>
|
||||
<div class="text-secondary small">Tutup walaupun dalam tempoh tarikh</div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@error('is_registration_open_override')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
@if ($election->settings?->is_registration_open_override !== null)
|
||||
<div class="alert alert-warning py-2" role="alert">
|
||||
<i class="bi bi-exclamation-triangle me-2"></i>
|
||||
Override sedang aktif. Tetapkan semula ke <strong>Auto</strong> untuk kembali kepada kawalan tarikh biasa.
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="d-flex justify-content-end gap-2 mt-3">
|
||||
<a class="btn btn-outline-secondary" href="{{ route('admin.setup.index') }}">Kembali</a>
|
||||
<button class="btn btn-primary" type="submit">
|
||||
<i class="bi bi-save me-1"></i>{{ $isNew ? 'Cipta Tetapan' : 'Simpan Tetapan' }}
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
Reference in New Issue
Block a user