first commit
This commit is contained in:
39
resources/views/submissions/_comments.blade.php
Normal file
39
resources/views/submissions/_comments.blade.php
Normal file
@@ -0,0 +1,39 @@
|
||||
@php($isJpp = auth()->user()->can('serahan.lihat_semua'))
|
||||
<div class="card mb-3" id="komen">
|
||||
<div class="card-header bg-white fw-semibold"><i class="bi bi-chat-dots me-1"></i> Perbualan / Komen</div>
|
||||
<div class="card-body">
|
||||
<div class="mb-3" style="max-height:420px; overflow-y:auto">
|
||||
@forelse ($submission->comments as $comment)
|
||||
{{-- Komen dalaman hanya kelihatan kepada kakitangan JPP --}}
|
||||
@if ($comment->is_internal && ! $isJpp) @continue @endif
|
||||
<div class="chat-message {{ $comment->is_internal ? 'internal' : '' }}">
|
||||
<div class="d-flex justify-content-between">
|
||||
<strong class="small">{{ $comment->user?->name ?? 'Pengguna' }}
|
||||
@if($comment->is_internal)<span class="badge bg-warning text-dark">Dalaman</span>@endif
|
||||
</strong>
|
||||
<span class="text-muted" style="font-size:.72rem">{{ $comment->created_at->format('d/m/Y H:i') }}</span>
|
||||
</div>
|
||||
<div class="small">{!! nl2br(e($comment->body)) !!}</div>
|
||||
@can('komen.padam')
|
||||
<form method="POST" action="{{ route('comments.destroy', $comment) }}" data-confirm="Padam mesej ini (soft delete, rekod audit disimpan)?">@csrf @method('DELETE')<button class="btn btn-link btn-sm text-danger p-0" style="font-size:.72rem">Padam</button></form>
|
||||
@endcan
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-muted small">Tiada mesej lagi.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
|
||||
@can('comment', $submission)
|
||||
<form method="POST" action="{{ route('comments.store', $submission) }}">
|
||||
@csrf
|
||||
<textarea name="body" rows="2" class="form-control mb-2" placeholder="Tulis mesej..." required></textarea>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
@if($isJpp)
|
||||
<div class="form-check"><input type="checkbox" name="is_internal" value="1" class="form-check-input" id="internalChk"><label for="internalChk" class="form-check-label small">Mesej dalaman (JPP sahaja)</label></div>
|
||||
@else<span></span>@endif
|
||||
<button class="btn btn-sm btn-success"><i class="bi bi-send me-1"></i> Hantar</button>
|
||||
</div>
|
||||
</form>
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
55
resources/views/submissions/_corrections_panel.blade.php
Normal file
55
resources/views/submissions/_corrections_panel.blade.php
Normal file
@@ -0,0 +1,55 @@
|
||||
@php($canReview = auth()->user()->can('review', $submission))
|
||||
@php($canRespond = auth()->user()->can('respondCorrection', $submission))
|
||||
<div class="card mb-3" id="pembetulan">
|
||||
<div class="card-header bg-white fw-semibold"><i class="bi bi-pencil-square me-1"></i> Permohonan Pembetulan</div>
|
||||
<div class="card-body">
|
||||
@forelse ($submission->correctionRequests as $cr)
|
||||
<div class="border rounded p-2 mb-2">
|
||||
<div class="d-flex justify-content-between">
|
||||
<strong class="small">m/s {{ $cr->page_reference }} — {{ $cr->location }}</strong>
|
||||
<span class="badge bg-{{ $cr->status==='terbuka'?'warning text-dark':($cr->status==='dijawab'?'info':'success') }}">{{ App\Models\SubmissionCorrectionRequest::STATUSES[$cr->status] ?? $cr->status }}</span>
|
||||
</div>
|
||||
<div class="small">{{ $cr->description }}</div>
|
||||
<div class="text-muted" style="font-size:.75rem">Oleh {{ $cr->createdBy?->name }} • {{ $cr->created_at->format('d/m/Y') }}</div>
|
||||
|
||||
@if($cr->consultant_response)
|
||||
<div class="bg-light rounded p-2 mt-1 small"><strong>Maklum balas perunding:</strong> {{ $cr->consultant_response }}</div>
|
||||
@endif
|
||||
|
||||
@if($canRespond && $cr->status !== 'selesai')
|
||||
<form method="POST" action="{{ route('corrections.respond', $cr) }}" class="mt-2">
|
||||
@csrf
|
||||
<textarea name="consultant_response" rows="2" class="form-control form-control-sm mb-1" placeholder="Maklum balas / tindakan pembetulan" required>{{ $cr->consultant_response }}</textarea>
|
||||
<button class="btn btn-sm btn-outline-primary">Hantar Maklum Balas</button>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
@if($canReview && $cr->status !== 'selesai')
|
||||
<form method="POST" action="{{ route('corrections.resolve', $cr) }}" class="mt-1">@csrf<button class="btn btn-sm btn-link text-success p-0">Tandakan selesai</button></form>
|
||||
@endif
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-muted small mb-2">Tiada permohonan pembetulan.</p>
|
||||
@endforelse
|
||||
|
||||
@if($canReview)
|
||||
<hr>
|
||||
<form method="POST" action="{{ route('corrections.store', $submission) }}">
|
||||
@csrf
|
||||
<label class="form-label small fw-semibold">Tambah Permohonan Pembetulan</label>
|
||||
<div class="row g-2 mb-1">
|
||||
<div class="col-4"><input name="page_reference" class="form-control form-control-sm" placeholder="No. m/s" required></div>
|
||||
<div class="col-8"><input name="location" class="form-control form-control-sm" placeholder="Lokasi/seksyen/item" required></div>
|
||||
</div>
|
||||
<select name="checklist_item_id" class="form-select form-select-sm mb-1">
|
||||
<option value="">— Kaitkan item (pilihan) —</option>
|
||||
@foreach (($template?->sections ?? []) as $s)
|
||||
@foreach ($s->items as $it)<option value="{{ $it->id }}">{{ $s->code }} • {{ $it->code }} — {{ \Illuminate\Support\Str::limit($it->label, 40) }}</option>@endforeach
|
||||
@endforeach
|
||||
</select>
|
||||
<textarea name="description" rows="2" class="form-control form-control-sm mb-1" placeholder="Apa yang perlu dibetulkan?" required></textarea>
|
||||
<button class="btn btn-sm btn-warning w-100">Tambah Pembetulan</button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
32
resources/views/submissions/_documents_panel.blade.php
Normal file
32
resources/views/submissions/_documents_panel.blade.php
Normal file
@@ -0,0 +1,32 @@
|
||||
<div class="card mb-3">
|
||||
<div class="card-header bg-white fw-semibold"><i class="bi bi-file-earmark-pdf me-1"></i> Laporan PDF</div>
|
||||
<div class="card-body">
|
||||
@if ($submission->isEditableByConsultant() && auth()->user()->can('update', $submission))
|
||||
<form method="POST" action="{{ route('documents.store', $submission) }}" enctype="multipart/form-data" class="mb-3">
|
||||
@csrf
|
||||
<input type="file" name="report" accept="application/pdf" class="form-control form-control-sm mb-2" required>
|
||||
<button class="btn btn-sm btn-outline-primary w-100"><i class="bi bi-upload me-1"></i> Muat Naik (versi baharu)</button>
|
||||
<div class="form-text">PDF sahaja. Versi lama dikekalkan.</div>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
@forelse ($submission->documents as $doc)
|
||||
<div class="d-flex justify-content-between align-items-center border rounded p-2 mb-1 {{ $doc->is_active ? 'border-success' : '' }}">
|
||||
<div class="small">
|
||||
<i class="bi bi-file-earmark-pdf text-danger"></i> v{{ $doc->version }}
|
||||
@if($doc->is_active)<span class="badge bg-success">Aktif</span>@endif
|
||||
<div class="text-muted text-truncate" style="max-width:160px">{{ $doc->original_filename }}</div>
|
||||
<div class="text-muted">{{ $doc->humanSize() }} • {{ $doc->created_at->format('d/m/Y H:i') }}</div>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<a href="{{ route('documents.download', $doc) }}" class="btn btn-sm btn-link p-0"><i class="bi bi-download"></i></a>
|
||||
@if (!$doc->is_active && auth()->user()->can('update', $submission) && $submission->isEditableByConsultant())
|
||||
<form method="POST" action="{{ route('documents.active', $doc) }}">@csrf<button class="btn btn-sm btn-link p-0" title="Jadikan aktif"><i class="bi bi-check2-circle"></i></button></form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-muted small mb-0">Tiada laporan dimuat naik.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
46
resources/views/submissions/_item_field.blade.php
Normal file
46
resources/views/submissions/_item_field.blade.php
Normal file
@@ -0,0 +1,46 @@
|
||||
@php
|
||||
$val = old("answers.{$item->id}.value", $answer->value ?? '');
|
||||
$page = old("answers.{$item->id}.page_reference", $answer->page_reference ?? '');
|
||||
$note = old("answers.{$item->id}.consultant_note", $answer->consultant_note ?? '');
|
||||
$disabled = (!$editable || $item->is_calculated) ? 'disabled' : '';
|
||||
@endphp
|
||||
<div class="mb-3 pb-2 border-bottom">
|
||||
<label class="form-label mb-1">
|
||||
<span class="text-muted small">{{ $item->code }}</span> {{ $item->label }}
|
||||
@if($item->is_required)<span class="text-danger">*</span>@endif
|
||||
@if($item->unit)<span class="badge bg-light text-dark">{{ $item->unit }}</span>@endif
|
||||
@if($item->is_calculated)<span class="badge bg-info">dikira automatik</span>@endif
|
||||
</label>
|
||||
@if($item->description)<div class="form-text mb-1">{{ $item->description }}</div>@endif
|
||||
|
||||
<div class="row g-2">
|
||||
<div class="col-md-5">
|
||||
@switch($item->input_type)
|
||||
@case('textarea')
|
||||
<textarea name="answers[{{ $item->id }}][value]" rows="2" class="form-control form-control-sm" {{ $disabled }}>{{ $val }}</textarea>
|
||||
@break
|
||||
@case('select')
|
||||
<select name="answers[{{ $item->id }}][value]" class="form-select form-select-sm" {{ $disabled }}>
|
||||
<option value="">— Pilih —</option>
|
||||
@foreach (($item->options ?? []) as $opt)<option value="{{ $opt }}" @selected($val===$opt)>{{ $opt }}</option>@endforeach
|
||||
</select>
|
||||
@break
|
||||
@case('checkbox')
|
||||
<div class="form-check"><input type="hidden" name="answers[{{ $item->id }}][value]" value="0"><input type="checkbox" name="answers[{{ $item->id }}][value]" value="1" class="form-check-input" @checked($val=='1') {{ $disabled }}></div>
|
||||
@break
|
||||
@case('number')
|
||||
@case('calculated')
|
||||
<input type="number" step="any" name="answers[{{ $item->id }}][value]" value="{{ $val }}" class="form-control form-control-sm" {{ $disabled }}>
|
||||
@break
|
||||
@default
|
||||
<input type="text" name="answers[{{ $item->id }}][value]" value="{{ $val }}" class="form-control form-control-sm" {{ $disabled }}>
|
||||
@endswitch
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<input type="text" name="answers[{{ $item->id }}][page_reference]" value="{{ $page }}" class="form-control form-control-sm" placeholder="No. m/s laporan" {{ $editable ? '' : 'disabled' }}>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<input type="text" name="answers[{{ $item->id }}][consultant_note]" value="{{ $note }}" class="form-control form-control-sm" placeholder="Catatan perunding" {{ $editable ? '' : 'disabled' }}>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
17
resources/views/submissions/_results_panel.blade.php
Normal file
17
resources/views/submissions/_results_panel.blade.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<div class="card mb-3">
|
||||
<div class="card-header bg-white fw-semibold"><i class="bi bi-calculator me-1"></i> Hasil Formula (dikira automatik)</div>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-sm mb-0">
|
||||
<tbody>
|
||||
@forelse ($submission->results as $r)
|
||||
<tr>
|
||||
<td class="ps-3"><code>{{ $r->result_token }}</code> <span class="small text-muted">{{ $r->label }}</span></td>
|
||||
<td class="text-end pe-3 fw-semibold">{{ $r->value !== null ? number_format($r->value, 2) : '—' }} {{ $r->unit }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td class="text-center text-muted py-3">Simpan draf untuk mengira formula.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
87
resources/views/submissions/_review_panel.blade.php
Normal file
87
resources/views/submissions/_review_panel.blade.php
Normal file
@@ -0,0 +1,87 @@
|
||||
@php($canReview = auth()->user()->can('review', $submission))
|
||||
<div class="card mb-3 border-primary">
|
||||
<div class="card-header bg-white fw-semibold text-primary"><i class="bi bi-clipboard-check me-1"></i> Tindakan JPP</div>
|
||||
<div class="card-body">
|
||||
@if($canReview)
|
||||
{{-- Tukar status --}}
|
||||
<form method="POST" action="{{ route('submissions.status', $submission) }}" class="mb-3">
|
||||
@csrf
|
||||
<label class="form-label small fw-semibold">Tukar Status</label>
|
||||
<select name="status" class="form-select form-select-sm mb-2" id="statusSelect">
|
||||
@foreach (App\Models\Submission::STATUSES as $k => $v)<option value="{{ $k }}" @selected($submission->status===$k)>{{ $v }}</option>@endforeach
|
||||
</select>
|
||||
<div class="mb-2" id="hardcopySentWrap" style="display:none">
|
||||
<label class="form-label small">Tarikh hardcopy dihantar ke Bahagian Kawalan Perancangan</label>
|
||||
<input type="date" name="hardcopy_sent_date" class="form-control form-control-sm" value="{{ $submission->hardcopy_sent_date?->toDateString() }}">
|
||||
</div>
|
||||
<textarea name="notes" rows="2" class="form-control form-control-sm mb-2" placeholder="Nota status (pilihan)"></textarea>
|
||||
<button class="btn btn-sm btn-primary w-100">Kemaskini Status</button>
|
||||
<div class="form-text">Status "Pembetulan Perunding" perlu ada permohonan pembetulan terbuka.</div>
|
||||
</form>
|
||||
|
||||
{{-- Pegawai bertanggungjawab --}}
|
||||
<form method="POST" action="{{ route('submissions.assign-officer', $submission) }}" class="mb-3">
|
||||
@csrf
|
||||
<label class="form-label small fw-semibold">Pegawai Bertanggungjawab</label>
|
||||
<div class="input-group input-group-sm">
|
||||
<select name="assigned_officer_id" class="form-select">
|
||||
<option value="">— Tiada —</option>
|
||||
@foreach ($officers as $o)<option value="{{ $o->id }}" @selected($submission->assigned_officer_id==$o->id)>{{ $o->name }}</option>@endforeach
|
||||
</select>
|
||||
<button class="btn btn-outline-primary">Set</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{{-- Nota semakan keseluruhan --}}
|
||||
<form method="POST" action="{{ route('submissions.review-note', $submission) }}" class="mb-3">
|
||||
@csrf
|
||||
<label class="form-label small fw-semibold">Nota Semakan</label>
|
||||
<textarea name="review_notes" rows="2" class="form-control form-control-sm mb-2">{{ $submission->review_notes }}</textarea>
|
||||
<button class="btn btn-sm btn-outline-secondary w-100">Simpan Nota</button>
|
||||
</form>
|
||||
@endif
|
||||
|
||||
{{-- Salinan keras --}}
|
||||
@can('markHardcopy', $submission)
|
||||
<form method="POST" action="{{ route('submissions.hardcopy', $submission) }}" class="mb-3">
|
||||
@csrf
|
||||
<label class="form-label small fw-semibold">Dokumen Salinan Keras (Hardcopy)</label>
|
||||
<div class="form-check"><input type="hidden" name="hardcopy_received" value="0"><input type="checkbox" name="hardcopy_received" value="1" class="form-check-input" id="hcReceived" @checked($submission->hardcopy_received)><label for="hcReceived" class="form-check-label">Telah diterima</label></div>
|
||||
<input type="date" name="hardcopy_received_date" class="form-control form-control-sm my-2" value="{{ $submission->hardcopy_received_date?->toDateString() }}">
|
||||
<button class="btn btn-sm btn-outline-secondary w-100">Simpan</button>
|
||||
</form>
|
||||
@endcan
|
||||
|
||||
{{-- Kunci / buka kunci --}}
|
||||
@can('lock', $submission)
|
||||
<hr>
|
||||
@if(!$submission->is_locked)
|
||||
<form method="POST" action="{{ route('submissions.lock', $submission) }}">
|
||||
@csrf
|
||||
<input type="text" name="lock_reason" class="form-control form-control-sm mb-2" placeholder="Sebab kunci (pilihan)">
|
||||
<button class="btn btn-sm btn-danger w-100" data-confirm="Kunci serahan ini? Perunding tidak boleh mengubah."><i class="bi bi-lock me-1"></i> Kunci Serahan</button>
|
||||
</form>
|
||||
@else
|
||||
<form method="POST" action="{{ route('submissions.unlock', $submission) }}">
|
||||
@csrf
|
||||
@if($submission->lock_reason)<div class="small text-muted mb-1">Sebab kunci: {{ $submission->lock_reason }}</div>@endif
|
||||
<input type="text" name="lock_reason" class="form-control form-control-sm mb-2" placeholder="Sebab buka kunci (wajib)" required>
|
||||
<button class="btn btn-sm btn-warning w-100"><i class="bi bi-unlock me-1"></i> Buka Kunci</button>
|
||||
</form>
|
||||
@endif
|
||||
@endcan
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@push('scripts')
|
||||
<script>
|
||||
(function () {
|
||||
const sel = document.getElementById('statusSelect');
|
||||
const wrap = document.getElementById('hardcopySentWrap');
|
||||
if (sel && wrap) {
|
||||
const toggle = () => wrap.style.display = sel.value === 'selesai' ? 'block' : 'none';
|
||||
sel.addEventListener('change', toggle); toggle();
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
@endpush
|
||||
35
resources/views/submissions/create.blade.php
Normal file
35
resources/views/submissions/create.blade.php
Normal file
@@ -0,0 +1,35 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Mula Serahan')
|
||||
@section('heading', 'Serahan')
|
||||
@section('page-title', 'Mula Serahan Baharu')
|
||||
|
||||
@section('content')
|
||||
<div class="card"><div class="card-body">
|
||||
@if ($dataCentres->isEmpty())
|
||||
<div class="alert alert-warning mb-0">Anda tiada pusat data aktif yang ditugaskan. Sila hubungi JPP.</div>
|
||||
@elseif ($cycles->isEmpty())
|
||||
<div class="alert alert-warning mb-0">Tiada kitaran pelaporan aktif buat masa ini.</div>
|
||||
@else
|
||||
<form method="POST" action="{{ route('submissions.store') }}">
|
||||
@csrf
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Pusat Data <span class="text-danger">*</span></label>
|
||||
<select name="data_centre_id" class="form-select" required>
|
||||
<option value="">— Pilih pusat data —</option>
|
||||
@foreach ($dataCentres as $dc)<option value="{{ $dc->id }}">{{ $dc->nama_pusat_data }}</option>@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Kitaran Pelaporan <span class="text-danger">*</span></label>
|
||||
<select name="reporting_cycle_id" class="form-select" required>
|
||||
<option value="">— Pilih kitaran —</option>
|
||||
@foreach ($cycles as $c)<option value="{{ $c->id }}">Pembaharuan {{ $c->renewal_year }} / Pelaporan {{ $c->reporting_year }} (tutup {{ $c->cut_off_date?->format('d/m/Y') }})</option>@endforeach
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4"><button class="btn btn-success"><i class="bi bi-arrow-right me-1"></i> Teruskan ke Borang Senarai Semak</button></div>
|
||||
</form>
|
||||
@endif
|
||||
</div></div>
|
||||
@endsection
|
||||
78
resources/views/submissions/fill.blade.php
Normal file
78
resources/views/submissions/fill.blade.php
Normal file
@@ -0,0 +1,78 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Borang Senarai Semak')
|
||||
@section('heading', 'Serahan')
|
||||
@section('page-title', 'Borang Senarai Semak')
|
||||
@section('subtitle', $submission->dataCentre->nama_pusat_data.' • Pelaporan '.$submission->reportingCycle->reporting_year)
|
||||
|
||||
@section('actions')
|
||||
<a href="{{ route('submissions.show', $submission) }}" class="btn btn-link">Lihat Ringkasan</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@if (!$submission->isEditableByConsultant())
|
||||
<div class="alert alert-warning"><i class="bi bi-lock me-1"></i> Serahan ini telah dikunci / selesai dan tidak boleh diubah.</div>
|
||||
@endif
|
||||
|
||||
@if ($submission->correctionRequests->where('status','!=','selesai')->count())
|
||||
<div class="alert alert-warning">
|
||||
<strong><i class="bi bi-pencil-square me-1"></i> Permohonan pembetulan daripada JPP:</strong>
|
||||
<ul class="mb-0 mt-1">
|
||||
@foreach ($submission->correctionRequests->where('status','!=','selesai') as $cr)
|
||||
<li>[m/s {{ $cr->page_reference }}] <strong>{{ $cr->location }}</strong> — {{ $cr->description }}
|
||||
<a href="{{ route('submissions.show', $submission) }}#pembetulan" class="small">jawab di sini</a></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-8">
|
||||
<form method="POST" action="{{ route('submissions.update', $submission) }}" id="checklistForm">
|
||||
@csrf @method('PUT')
|
||||
|
||||
@forelse ($template->sections as $section)
|
||||
<div class="card mb-3">
|
||||
<div class="card-header checklist-section-header"><span class="badge bg-success me-1">{{ $section->code }}</span> <strong>{{ $section->title }}</strong></div>
|
||||
<div class="card-body">
|
||||
@if($section->description)<p class="small text-muted">{{ $section->description }}</p>@endif
|
||||
|
||||
@php($renderItem = function($item) use ($answers) {
|
||||
return [$item, $answers[$item->id] ?? null];
|
||||
})
|
||||
|
||||
{{-- Item terus di bawah seksyen (tanpa skop) --}}
|
||||
@foreach ($section->items->whereNull('checklist_scope_id') as $item)
|
||||
@include('submissions._item_field', ['item' => $item, 'answer' => $answers[$item->id] ?? null, 'editable' => $submission->isEditableByConsultant()])
|
||||
@endforeach
|
||||
|
||||
{{-- Item dikumpul mengikut skop --}}
|
||||
@foreach ($section->scopes as $scope)
|
||||
<div class="border-start border-3 ps-3 mb-3">
|
||||
<h6 class="mt-2"><span class="badge bg-secondary">{{ $scope->code }}</span> {{ $scope->title }}</h6>
|
||||
@if($scope->description)<p class="small text-muted">{{ $scope->description }}</p>@endif
|
||||
@foreach ($scope->items as $item)
|
||||
@include('submissions._item_field', ['item' => $item, 'answer' => $answers[$item->id] ?? null, 'editable' => $submission->isEditableByConsultant()])
|
||||
@endforeach
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="alert alert-info">Templat senarai semak tidak mempunyai seksyen.</div>
|
||||
@endforelse
|
||||
|
||||
@if ($submission->isEditableByConsultant())
|
||||
<div class="d-flex gap-2 mb-4">
|
||||
<button type="submit" class="btn btn-outline-primary"><i class="bi bi-save me-1"></i> Simpan Draf</button>
|
||||
<button type="submit" formaction="{{ route('submissions.submit', $submission) }}" class="btn btn-success" data-confirm="Hantar serahan secara muktamad kepada JPP?"><i class="bi bi-send me-1"></i> Hantar Serahan</button>
|
||||
</div>
|
||||
@endif
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-4">
|
||||
@include('submissions._documents_panel', ['submission' => $submission])
|
||||
@include('submissions._results_panel', ['submission' => $submission])
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
57
resources/views/submissions/index.blade.php
Normal file
57
resources/views/submissions/index.blade.php
Normal file
@@ -0,0 +1,57 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Senarai Serahan')
|
||||
@section('heading', 'Serahan')
|
||||
@section('page-title', 'Senarai Serahan')
|
||||
|
||||
@section('actions')
|
||||
@can('create', App\Models\Submission::class)
|
||||
<a href="{{ route('submissions.create') }}" class="btn btn-success"><i class="bi bi-plus-lg me-1"></i> Mula Serahan</a>
|
||||
@endcan
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="card"><div class="card-body">
|
||||
<form class="row g-2 mb-3">
|
||||
<div class="col-md-3">
|
||||
<select name="cycle" class="form-select">
|
||||
<option value="">Semua kitaran</option>
|
||||
@foreach ($cycles as $c)<option value="{{ $c->id }}" @selected(request('cycle')==$c->id)>Pembaharuan {{ $c->renewal_year }} / Pelaporan {{ $c->reporting_year }}</option>@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<select name="status" class="form-select">
|
||||
<option value="">Semua status</option>
|
||||
@foreach (App\Models\Submission::STATUSES as $k => $v)<option value="{{ $k }}" @selected(request('status')===$k)>{{ $v }}</option>@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2 d-grid"><button class="btn btn-outline-primary"><i class="bi bi-funnel me-1"></i> Tapis</button></div>
|
||||
</form>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-hover align-middle">
|
||||
<thead><tr><th>Pusat Data</th><th>Kitaran</th><th>Perunding</th><th>Status</th><th>Pegawai</th><th>Dihantar</th><th></th></tr></thead>
|
||||
<tbody>
|
||||
@forelse ($submissions as $s)
|
||||
<tr>
|
||||
<td class="fw-semibold">{{ $s->dataCentre->nama_pusat_data }}</td>
|
||||
<td class="small">Pemb. {{ $s->reportingCycle->renewal_year }} / Pel. {{ $s->reportingCycle->reporting_year }}</td>
|
||||
<td class="small">{{ $s->consultant->nama_perunding }}</td>
|
||||
<td><span class="badge bg-{{ $s->statusBadgeClass() }}">{{ $s->statusLabel() }}</span> @if($s->is_locked)<i class="bi bi-lock-fill text-danger" title="Dikunci"></i>@endif</td>
|
||||
<td class="small">{{ $s->assignedOfficer?->name ?? '—' }}</td>
|
||||
<td class="small">{{ $s->submitted_at?->format('d/m/Y') ?? '—' }}</td>
|
||||
<td class="text-end">
|
||||
@if ($s->isEditableByConsultant() && auth()->user()->can('update', $s))
|
||||
<a href="{{ route('submissions.edit', $s) }}" class="btn btn-sm btn-outline-primary">Isi</a>
|
||||
@endif
|
||||
<a href="{{ route('submissions.show', $s) }}" class="btn btn-sm btn-outline-secondary">Lihat</a>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-muted py-3">Tiada serahan.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $submissions->links() }}
|
||||
</div></div>
|
||||
@endsection
|
||||
111
resources/views/submissions/show.blade.php
Normal file
111
resources/views/submissions/show.blade.php
Normal file
@@ -0,0 +1,111 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Butiran Serahan')
|
||||
@section('heading', 'Serahan')
|
||||
@section('page-title', $submission->dataCentre->nama_pusat_data)
|
||||
@section('subtitle', 'Pelaporan '.$submission->reportingCycle->reporting_year.' • Pembaharuan '.$submission->reportingCycle->renewal_year)
|
||||
|
||||
@section('actions')
|
||||
@if ($submission->isEditableByConsultant() && auth()->user()->can('update', $submission))
|
||||
<a href="{{ route('submissions.edit', $submission) }}" class="btn btn-outline-primary"><i class="bi bi-pencil me-1"></i> Isi / Kemaskini</a>
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@php($canReview = auth()->user()->can('review', $submission))
|
||||
<div class="d-flex flex-wrap gap-2 mb-3 align-items-center">
|
||||
<span class="badge bg-{{ $submission->statusBadgeClass() }} fs-6">{{ $submission->statusLabel() }}</span>
|
||||
@if($submission->is_locked)<span class="badge bg-danger"><i class="bi bi-lock-fill"></i> Dikunci</span>@endif
|
||||
<span class="text-muted small">Perunding: {{ $submission->consultant->nama_perunding }}</span>
|
||||
@if($submission->submitted_at)<span class="text-muted small">• Dihantar: {{ $submission->submitted_at->format('d/m/Y H:i') }}</span>@endif
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-lg-8">
|
||||
{{-- ===== Jawapan senarai semak ===== --}}
|
||||
@foreach ($template?->sections ?? [] as $section)
|
||||
<div class="card mb-3">
|
||||
<div class="card-header checklist-section-header"><span class="badge bg-success me-1">{{ $section->code }}</span> <strong>{{ $section->title }}</strong></div>
|
||||
<div class="card-body p-0">
|
||||
<table class="table table-sm mb-0 align-middle">
|
||||
<thead><tr><th class="ps-3">Item</th><th>Nilai</th><th>m/s</th><th>Catatan Perunding</th>@if($canReview)<th>Semakan</th>@endif</tr></thead>
|
||||
<tbody>
|
||||
@foreach ($section->items as $item)
|
||||
@php($a = $answers[$item->id] ?? null)
|
||||
<tr>
|
||||
<td class="ps-3"><span class="text-muted small">{{ $item->code }}</span> {{ $item->label }}</td>
|
||||
<td>{{ $a?->value !== null && $a?->value !== '' ? $a->value : '—' }} <span class="text-muted small">{{ $item->unit }}</span></td>
|
||||
<td>{{ $a?->page_reference ?: '—' }}</td>
|
||||
<td class="small">{{ $a?->consultant_note ?: '—' }}</td>
|
||||
@if($canReview)
|
||||
<td>
|
||||
@if($a)
|
||||
<button class="btn btn-sm btn-link p-0" data-bs-toggle="modal" data-bs-target="#reviewAns{{ $a->id }}">
|
||||
@php($vs = $a->validation_status)
|
||||
<span class="badge bg-{{ $vs==='sah'?'success':($vs==='tidak_sah'?'danger':'secondary') }}">{{ ['belum_semak'=>'Belum Semak','sah'=>'Sah','tidak_sah'=>'Tidak Sah'][$vs] ?? $vs }}</span>
|
||||
</button>
|
||||
@else — @endif
|
||||
</td>
|
||||
@endif
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
|
||||
@include('submissions._comments', ['submission' => $submission])
|
||||
</div>
|
||||
|
||||
{{-- ===== Panel sisi ===== --}}
|
||||
<div class="col-lg-4">
|
||||
@include('submissions._results_panel', ['submission' => $submission])
|
||||
@include('submissions._documents_panel', ['submission' => $submission])
|
||||
|
||||
@if($canReview || auth()->user()->can('markHardcopy', $submission))
|
||||
@include('submissions._review_panel', ['submission' => $submission, 'officers' => $officers])
|
||||
@endif
|
||||
|
||||
@include('submissions._corrections_panel', ['submission' => $submission])
|
||||
|
||||
{{-- Sejarah status --}}
|
||||
<div class="card mb-3"><div class="card-header bg-white fw-semibold"><i class="bi bi-clock-history me-1"></i> Sejarah Status</div>
|
||||
<div class="card-body p-0"><ul class="list-group list-group-flush small">
|
||||
@forelse ($submission->statusHistories as $h)
|
||||
<li class="list-group-item">
|
||||
<span class="badge bg-secondary">{{ App\Models\Submission::STATUSES[$h->from_status] ?? $h->from_status ?? '—' }}</span> →
|
||||
<span class="badge bg-primary">{{ App\Models\Submission::STATUSES[$h->to_status] ?? $h->to_status }}</span>
|
||||
<div class="text-muted">{{ $h->changedBy?->name }} • {{ $h->created_at->format('d/m/Y H:i') }}</div>
|
||||
@if($h->notes)<div>{{ $h->notes }}</div>@endif
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item text-muted">Tiada sejarah.</li>
|
||||
@endforelse
|
||||
</ul></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Modal semakan item (pegawai) --}}
|
||||
@if($canReview)
|
||||
@foreach ($submission->answers as $a)
|
||||
<div class="modal fade" id="reviewAns{{ $a->id }}" tabindex="-1"><div class="modal-dialog"><div class="modal-content">
|
||||
<form method="POST" action="{{ route('answers.review', $a) }}">
|
||||
@csrf
|
||||
<div class="modal-header"><h6 class="modal-title">Semakan Item {{ $a->item->code ?? '' }}</h6><button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
|
||||
<div class="modal-body">
|
||||
<div class="mb-2"><label class="form-label">Status Pengesahan</label>
|
||||
<select name="validation_status" class="form-select">
|
||||
<option value="belum_semak" @selected($a->validation_status==='belum_semak')>Belum Semak</option>
|
||||
<option value="sah" @selected($a->validation_status==='sah')>Sah</option>
|
||||
<option value="tidak_sah" @selected($a->validation_status==='tidak_sah')>Tidak Sah</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mb-2"><label class="form-label">Nota Pegawai</label><textarea name="officer_note" class="form-control">{{ $a->officer_note }}</textarea></div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-success btn-sm">Simpan</button></div>
|
||||
</form>
|
||||
</div></div></div>
|
||||
@endforeach
|
||||
@endif
|
||||
@endsection
|
||||
Reference in New Issue
Block a user