first
This commit is contained in:
11
src/resources/css/app.css
Normal file
11
src/resources/css/app.css
Normal file
@@ -0,0 +1,11 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
|
||||
@source '../../storage/framework/views/*.php';
|
||||
@source '../**/*.blade.php';
|
||||
@source '../**/*.js';
|
||||
|
||||
@theme {
|
||||
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
}
|
||||
1
src/resources/js/app.js
Normal file
1
src/resources/js/app.js
Normal file
@@ -0,0 +1 @@
|
||||
//
|
||||
87
src/resources/views/admin/application-show.blade.php
Normal file
87
src/resources/views/admin/application-show.blade.php
Normal file
@@ -0,0 +1,87 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Butiran Permohonan Admin')
|
||||
@section('page-title', 'Butiran Permohonan')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('page-actions')
|
||||
<a href="{{ route('admin.applications.print', $application) }}" target="_blank" class="btn btn-outline-secondary">Print Borang</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-8">
|
||||
<div class="card surface-card p-4">
|
||||
<div class="d-flex justify-content-between align-items-start mb-3">
|
||||
<div>
|
||||
<div class="mini-label">No Permohonan</div>
|
||||
<h2 class="h4 fw-bold mb-1">{{ $application->application_no }}</h2>
|
||||
</div>
|
||||
@include('components.status-badge', ['status' => $application->status])
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6"><strong>Pemohon</strong><br>{{ $application->user->displayName() }}</div>
|
||||
<div class="col-md-6"><strong>Contact Number</strong><br>{{ $application->country_code }} {{ $application->mobile_no }}</div>
|
||||
<div class="col-md-6"><strong>Emel</strong><br>{{ $application->email }}</div>
|
||||
<div class="col-md-6"><strong>Alamat Surat Menyurat</strong><br>{{ $application->alamat_surat_menyurat }}</div>
|
||||
<div class="col-md-6"><strong>Alamat Harta</strong><br>{{ $application->alamat_harta }}</div>
|
||||
<div class="col-md-6"><strong>Pekerjaan</strong><br>{{ $application->pekerjaan ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>No Lot</strong><br>{{ $application->no_lot ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>No DHM</strong><br>{{ $application->no_dhm ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>No Syarikat</strong><br>{{ $application->no_syarikat ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>Pendapatan Sebulan</strong><br>{{ $application->pendapatan_sebulan ? 'RM '.number_format((float) $application->pendapatan_sebulan, 2) : '-' }}</div>
|
||||
<div class="col-md-6"><strong>Ulasan Staff</strong><br>{{ $application->staff_remarks ?: 'Tiada ulasan direkodkan.' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card surface-card p-4 mt-4">
|
||||
<h3 class="h5 fw-bold mb-3">Jadual Ansuran Manual</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ansuran Ke-</th>
|
||||
<th>Tarikh</th>
|
||||
<th>Amaun</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($application->schedules as $schedule)
|
||||
<tr>
|
||||
<td>{{ $schedule->installment_no }}</td>
|
||||
<td>{{ optional($schedule->due_date)->format('d/m/Y') }}</td>
|
||||
<td>RM {{ number_format((float) $schedule->amount, 2) }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $schedule->payment_status])</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4" class="text-center text-muted py-4">Tiada jadual direkodkan.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Maklumat Akaun</h3>
|
||||
<dl class="row mb-0">
|
||||
<dt class="col-sm-5">Pemilik</dt><dd class="col-sm-7">{{ $application->propertyAccount?->pemilik }}</dd>
|
||||
<dt class="col-sm-5">Bandar</dt><dd class="col-sm-7">{{ $application->propertyAccount?->bandar }}</dd>
|
||||
<dt class="col-sm-5">Taman</dt><dd class="col-sm-7">{{ $application->propertyAccount?->taman }}</dd>
|
||||
<dt class="col-sm-5">Rupacara</dt><dd class="col-sm-7">{{ $application->propertyAccount?->rupacara }}</dd>
|
||||
<dt class="col-sm-5">Kadar</dt><dd class="col-sm-7">{{ $application->propertyAccount?->kadar }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="card surface-card p-4 mt-4">
|
||||
<h3 class="h5 fw-bold mb-3">Sejarah Tindakan</h3>
|
||||
@foreach ($application->histories as $history)
|
||||
<div class="border-bottom pb-3 mb-3">
|
||||
<div class="fw-semibold">{{ str($history->action)->replace('_', ' ')->headline() }}</div>
|
||||
<div class="text-muted small">{{ $history->created_at->format('d/m/Y h:i A') }}</div>
|
||||
<div class="small">{{ $history->remarks ?: '-' }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
71
src/resources/views/admin/applications-index.blade.php
Normal file
71
src/resources/views/admin/applications-index.blade.php
Normal file
@@ -0,0 +1,71 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pengurusan Permohonan')
|
||||
@section('page-title', 'Pengurusan Permohonan')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('page-actions')
|
||||
<a href="{{ route('admin.applications.export') }}" class="btn btn-outline-primary">Eksport Excel</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4 mb-4">
|
||||
<form class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Carian</label>
|
||||
<input type="text" name="search" class="form-control" value="{{ request('search') }}" placeholder="No akaun / status / no permohonan">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Status</label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="">Semua</option>
|
||||
@foreach (['diproses', 'aktif', 'gagal', 'batal', 'selesai'] as $status)
|
||||
<option value="{{ $status }}" @selected(request('status') === $status)>{{ ucfirst($status) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Dari Tarikh</label>
|
||||
<input type="date" name="date_from" class="form-control" value="{{ request('date_from') }}">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Hingga Tarikh</label>
|
||||
<input type="date" name="date_to" class="form-control" value="{{ request('date_to') }}">
|
||||
</div>
|
||||
<div class="col-md-1 d-flex align-items-end">
|
||||
<button class="btn btn-primary w-100">Tapis</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Permohonan</th>
|
||||
<th>Pemohon</th>
|
||||
<th>No Akaun Tunggakan</th>
|
||||
<th>Kategori</th>
|
||||
<th>Status</th>
|
||||
<th>Pegawai</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($applications as $application)
|
||||
<tr>
|
||||
<td>{{ $application->application_no }}</td>
|
||||
<td>{{ $application->user->displayName() }}</td>
|
||||
<td>{{ $application->no_akaun_tunggakan }}</td>
|
||||
<td>{{ $application->category }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $application->status])</td>
|
||||
<td>{{ $application->reviewer?->displayName() ?: '-' }}</td>
|
||||
<td class="text-end"><a href="{{ route('admin.applications.show', $application) }}" class="btn btn-sm btn-outline-secondary">Lihat</a></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $applications->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
37
src/resources/views/admin/audit-trail.blade.php
Normal file
37
src/resources/views/admin/audit-trail.blade.php
Normal file
@@ -0,0 +1,37 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Audit Trail')
|
||||
@section('page-title', 'Audit Trail')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tarikh</th>
|
||||
<th>Pengguna</th>
|
||||
<th>Modul</th>
|
||||
<th>Tindakan</th>
|
||||
<th>Keterangan</th>
|
||||
<th>IP</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($audits as $audit)
|
||||
<tr>
|
||||
<td>{{ $audit->created_at->format('d/m/Y h:i A') }}</td>
|
||||
<td>{{ $audit->user?->displayName() ?: 'Sistem' }}</td>
|
||||
<td>{{ $audit->module }}</td>
|
||||
<td>{{ $audit->action }}</td>
|
||||
<td>{{ $audit->description }}</td>
|
||||
<td>{{ $audit->ip_address ?: '-' }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $audits->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
34
src/resources/views/admin/communications-index.blade.php
Normal file
34
src/resources/views/admin/communications-index.blade.php
Normal file
@@ -0,0 +1,34 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Notifikasi & Emel')
|
||||
@section('page-title', 'Notifikasi & Emel')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-6">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Notifikasi Sistem</h3>
|
||||
@foreach ($notifications as $notification)
|
||||
<div class="border-bottom pb-3 mb-3">
|
||||
<div class="fw-semibold">{{ $notification->title }}</div>
|
||||
<div class="small text-muted">{{ $notification->user?->displayName() }} | {{ $notification->created_at->format('d/m/Y h:i A') }}</div>
|
||||
<div class="small mt-1">{{ $notification->message }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Dummy Email Log</h3>
|
||||
@foreach ($emailLogs as $emailLog)
|
||||
<div class="border-bottom pb-3 mb-3">
|
||||
<div class="fw-semibold">{{ $emailLog->subject }}</div>
|
||||
<div class="small text-muted">{{ $emailLog->recipient_email }} | {{ optional($emailLog->sent_at)->format('d/m/Y h:i A') }}</div>
|
||||
<div class="small mt-1">{{ $emailLog->body }}</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
77
src/resources/views/admin/dashboard.blade.php
Normal file
77
src/resources/views/admin/dashboard.blade.php
Normal file
@@ -0,0 +1,77 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Dashboard Admin')
|
||||
@section('page-title', 'Dashboard Admin')
|
||||
@section('page-label', 'Pemantauan Keseluruhan')
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4 mb-4">
|
||||
@foreach ([
|
||||
['label' => 'Permohonan Baharu', 'value' => $summary['new_applications'], 'icon' => 'bi-journal-plus'],
|
||||
['label' => 'Permohonan Lulus', 'value' => $summary['approved_applications'], 'icon' => 'bi-check2-circle'],
|
||||
['label' => 'Permohonan Gagal', 'value' => $summary['failed_applications'], 'icon' => 'bi-x-circle'],
|
||||
['label' => 'Permohonan Batal', 'value' => $summary['cancelled_applications'], 'icon' => 'bi-ban'],
|
||||
['label' => 'Akaun Ansuran Aktif', 'value' => $summary['active_accounts'], 'icon' => 'bi-calendar-range'],
|
||||
['label' => 'Bayaran Diterima', 'value' => 'RM '.number_format((float) $summary['payments_received'], 2), 'icon' => 'bi-cash-coin'],
|
||||
['label' => 'Tunggakan Semasa', 'value' => 'RM '.number_format((float) $summary['outstanding_arrears'], 2), 'icon' => 'bi-exclamation-diamond'],
|
||||
['label' => 'Akaun Ansuran Selesai', 'value' => $summary['completed_accounts'], 'icon' => 'bi-patch-check'],
|
||||
['label' => 'Pengguna Awam Berdaftar', 'value' => $summary['public_users'], 'icon' => 'bi-people'],
|
||||
] as $card)
|
||||
<div class="col-md-6 col-xl-4">
|
||||
<div class="card stat-card p-4 h-100">
|
||||
<div class="d-flex justify-content-between align-items-center gap-3">
|
||||
<div>
|
||||
<div class="mini-label">{{ $card['label'] }}</div>
|
||||
<div class="h3 fw-bold mb-0">{{ $card['value'] }}</div>
|
||||
</div>
|
||||
<div class="stat-icon"><i class="bi {{ $card['icon'] }} fs-4"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-8">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Permohonan Terkini</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Permohonan</th>
|
||||
<th>Pemohon</th>
|
||||
<th>No Akaun</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($latestApplications as $application)
|
||||
<tr>
|
||||
<td>{{ $application->application_no }}</td>
|
||||
<td>{{ $application->user->displayName() }}</td>
|
||||
<td>{{ $application->no_akaun_tunggakan }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $application->status])</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Notifikasi Terkini</h3>
|
||||
@forelse ($latestNotifications as $notification)
|
||||
<div class="border-bottom pb-3 mb-3">
|
||||
<div class="fw-semibold">{{ $notification->title }}</div>
|
||||
<div class="small text-muted">{{ $notification->user?->displayName() }} | {{ $notification->created_at->format('d/m/Y h:i A') }}</div>
|
||||
<div class="small mt-1">{{ $notification->message }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-muted small">Tiada notifikasi untuk dipaparkan.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,36 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Akaun Ansuran')
|
||||
@section('page-title', 'Akaun Ansuran Aktif')
|
||||
@section('page-label', 'Pemantauan Akaun')
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Permohonan</th>
|
||||
<th>Pemohon</th>
|
||||
<th>No Akaun</th>
|
||||
<th>Jumlah Jadual</th>
|
||||
<th>Baki Tertunggak</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($applications as $application)
|
||||
@php($paid = $application->payments->where('status', 'success')->sum('amount'))
|
||||
<tr>
|
||||
<td>{{ $application->application_no }}</td>
|
||||
<td>{{ $application->user->displayName() }}</td>
|
||||
<td>{{ $application->no_akaun_tunggakan }}</td>
|
||||
<td>RM {{ number_format((float) $application->schedule_total, 2) }}</td>
|
||||
<td>RM {{ number_format((float) $application->schedule_total - (float) $paid, 2) }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $applications->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
37
src/resources/views/admin/payments-index.blade.php
Normal file
37
src/resources/views/admin/payments-index.blade.php
Normal file
@@ -0,0 +1,37 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pengurusan Bayaran')
|
||||
@section('page-title', 'Senarai Bayaran')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Resit</th>
|
||||
<th>Pembayar</th>
|
||||
<th>No Akaun</th>
|
||||
<th>Amaun</th>
|
||||
<th>Status</th>
|
||||
<th>Tarikh</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($payments as $payment)
|
||||
<tr>
|
||||
<td>{{ $payment->receipt_no }}</td>
|
||||
<td>{{ $payment->user?->displayName() }}</td>
|
||||
<td>{{ $payment->application?->no_akaun }}</td>
|
||||
<td>RM {{ number_format((float) $payment->amount, 2) }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $payment->status])</td>
|
||||
<td>{{ optional($payment->paid_at)->format('d/m/Y h:i A') }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $payments->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
28
src/resources/views/admin/property-account-form.blade.php
Normal file
28
src/resources/views/admin/property-account-form.blade.php
Normal file
@@ -0,0 +1,28 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', $account->exists ? 'Edit Data Harta' : 'Tambah Data Harta')
|
||||
@section('page-title', $account->exists ? 'Edit Data Harta' : 'Tambah Data Harta')
|
||||
@section('page-label', 'Data Harta')
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4 p-lg-5">
|
||||
<form method="POST" action="{{ $account->exists ? route('admin.property-accounts.update', $account) : route('admin.property-accounts.store') }}" class="row g-3">
|
||||
@csrf
|
||||
@if ($account->exists) @method('PUT') @endif
|
||||
<div class="col-md-6"><label class="form-label">No Akaun</label><input type="text" name="no_akaun" class="form-control" value="{{ old('no_akaun', $account->no_akaun) }}" required></div>
|
||||
<div class="col-md-6"><label class="form-label">No Akaun Tunggakan</label><input type="text" name="no_akaun_tunggakan" class="form-control" value="{{ old('no_akaun_tunggakan', $account->no_akaun_tunggakan) }}" required></div>
|
||||
<div class="col-md-6"><label class="form-label">No Bgnn</label><input type="text" name="no_bgnn" class="form-control" value="{{ old('no_bgnn', $account->no_bgnn) }}"></div>
|
||||
<div class="col-md-6"><label class="form-label">Nama Jalan</label><input type="text" name="nama_jalan" class="form-control" value="{{ old('nama_jalan', $account->nama_jalan) }}"></div>
|
||||
<div class="col-md-6"><label class="form-label">Pemilik</label><input type="text" name="pemilik" class="form-control" value="{{ old('pemilik', $account->pemilik) }}" required></div>
|
||||
<div class="col-md-6"><label class="form-label">Kategori</label><input type="text" name="category" class="form-control" value="{{ old('category', $account->category) }}"></div>
|
||||
<div class="col-md-4"><label class="form-label">Bandar</label><input type="text" name="bandar" class="form-control" value="{{ old('bandar', $account->bandar) }}"></div>
|
||||
<div class="col-md-4"><label class="form-label">Taman</label><input type="text" name="taman" class="form-control" value="{{ old('taman', $account->taman) }}"></div>
|
||||
<div class="col-md-4"><label class="form-label">Rupacara</label><input type="text" name="rupacara" class="form-control" value="{{ old('rupacara', $account->rupacara) }}"></div>
|
||||
<div class="col-md-6"><label class="form-label">Kadar</label><input type="text" name="kadar" class="form-control" value="{{ old('kadar', $account->kadar) }}"></div>
|
||||
<div class="col-md-3"><label class="form-label">Cukai Harta</label><input type="number" step="0.01" name="cukai_harta" class="form-control" value="{{ old('cukai_harta', $account->cukai_harta) }}"></div>
|
||||
<div class="col-md-3"><label class="form-label">Tunggakan</label><input type="number" step="0.01" name="tunggakan" class="form-control" value="{{ old('tunggakan', $account->tunggakan) }}" required></div>
|
||||
<div class="col-12"><label class="form-label">Alamat Harta</label><textarea name="alamat_harta" class="form-control" rows="3">{{ old('alamat_harta', $account->alamat_harta) }}</textarea></div>
|
||||
<div class="col-12"><button class="btn btn-primary">{{ $account->exists ? 'Kemaskini Data Harta' : 'Simpan Data Harta' }}</button></div>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
66
src/resources/views/admin/property-accounts-index.blade.php
Normal file
66
src/resources/views/admin/property-accounts-index.blade.php
Normal file
@@ -0,0 +1,66 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Data Harta')
|
||||
@section('page-title', 'Data Harta')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('page-actions')
|
||||
<a href="{{ route('admin.property-accounts.create') }}" class="btn btn-primary">Tambah Data Harta</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4 mb-4">
|
||||
<form class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Carian</label>
|
||||
<input type="text" name="search" class="form-control" value="{{ request('search') }}" placeholder="No akaun / pemilik / jalan / bandar">
|
||||
</div>
|
||||
<div class="col-md-2 d-flex align-items-end">
|
||||
<button class="btn btn-primary w-100">Cari</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Akaun</th>
|
||||
<th>No Akaun Tunggakan</th>
|
||||
<th>No Bgnn</th>
|
||||
<th>Pemilik</th>
|
||||
<th>Jalan / Bandar</th>
|
||||
<th>Cukai Harta</th>
|
||||
<th>Tunggakan</th>
|
||||
<th>Status Data</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($accounts as $account)
|
||||
<tr>
|
||||
<td>{{ $account->no_akaun }}</td>
|
||||
<td>{{ $account->no_akaun_tunggakan }}</td>
|
||||
<td>{{ $account->no_bgnn ?: '-' }}</td>
|
||||
<td>{{ $account->pemilik }}</td>
|
||||
<td>{{ $account->nama_jalan ?: '-' }} / {{ $account->bandar ?: '-' }}</td>
|
||||
<td>RM {{ number_format((float) $account->cukai_harta, 2) }}</td>
|
||||
<td>RM {{ number_format((float) $account->tunggakan, 2) }}</td>
|
||||
<td>{{ $account->status_data }}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group">
|
||||
<a href="{{ route('admin.property-accounts.edit', $account) }}" class="btn btn-sm btn-outline-secondary">Edit</a>
|
||||
<form method="POST" action="{{ route('admin.property-accounts.destroy', $account) }}">
|
||||
@csrf @method('DELETE')
|
||||
<button class="btn btn-sm btn-outline-danger">Padam</button>
|
||||
</form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $accounts->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
98
src/resources/views/admin/reports.blade.php
Normal file
98
src/resources/views/admin/reports.blade.php
Normal file
@@ -0,0 +1,98 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Laporan')
|
||||
@section('page-title', 'Laporan')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('page-actions')
|
||||
<div class="d-flex gap-2">
|
||||
<a href="{{ route('admin.reports.export-applications') }}" class="btn btn-outline-primary">Eksport Permohonan</a>
|
||||
<a href="{{ route('admin.reports.export-payments') }}" class="btn btn-outline-primary">Eksport Bayaran</a>
|
||||
<a href="{{ route('admin.reports.print') }}" target="_blank" class="btn btn-outline-secondary">Print HTML</a>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4 mb-4">
|
||||
@foreach ([
|
||||
['label' => 'Jumlah Bayaran Diterima', 'value' => 'RM '.number_format((float) $summary['payments_received'], 2)],
|
||||
['label' => 'Jumlah Tunggakan', 'value' => 'RM '.number_format((float) $summary['outstanding_arrears'], 2)],
|
||||
['label' => 'Permohonan Batal', 'value' => $summary['cancelled_applications']],
|
||||
['label' => 'Akaun Ansuran Aktif', 'value' => $summary['active_accounts']],
|
||||
] as $card)
|
||||
<div class="col-md-6 col-xl-3">
|
||||
<div class="card stat-card p-4">
|
||||
<div class="mini-label">{{ $card['label'] }}</div>
|
||||
<div class="h3 fw-bold mb-0">{{ $card['value'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-6">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Jumlah Permohonan Bulanan</h3>
|
||||
<table class="table">
|
||||
<thead><tr><th>Bulan</th><th>Jumlah</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($monthlyApplications as $item)
|
||||
<tr><td>{{ $item->month }}</td><td>{{ $item->total }}</td></tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Bayaran Diterima</h3>
|
||||
<table class="table">
|
||||
<thead><tr><th>Bulan</th><th>Jumlah</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($monthlyPayments as $item)
|
||||
<tr><td>{{ $item->month }}</td><td>RM {{ number_format((float) $item->total, 2) }}</td></tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Laporan Ikut Kategori Harta</h3>
|
||||
<table class="table">
|
||||
<thead><tr><th>Kategori</th><th>Jumlah</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($categoryBreakdown as $item)
|
||||
<tr><td>{{ $item->category }}</td><td>{{ $item->total }}</td></tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-6">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Laporan Ikut Kawasan</h3>
|
||||
<table class="table">
|
||||
<thead><tr><th>Bandar</th><th>Jumlah</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($areaBreakdown as $item)
|
||||
<tr><td>{{ $item->bandar ?: 'Tidak Ditetapkan' }}</td><td>{{ $item->total }}</td></tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Prestasi Staff / Pegawai</h3>
|
||||
<table class="table">
|
||||
<thead><tr><th>Nama</th><th>Jumlah Disemak</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($staffPerformance as $staff)
|
||||
<tr><td>{{ $staff->name }}</td><td>{{ $staff->total_reviewed }}</td></tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
26
src/resources/views/admin/roles-index.blade.php
Normal file
26
src/resources/views/admin/roles-index.blade.php
Normal file
@@ -0,0 +1,26 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pengurusan Peranan')
|
||||
@section('page-title', 'Pengurusan Peranan')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4">
|
||||
@foreach ($roles as $role)
|
||||
<div class="col-lg-4">
|
||||
<div class="card surface-card p-4 h-100">
|
||||
<h3 class="h5 fw-bold">{{ $role->name }}</h3>
|
||||
<p class="text-muted">{{ $role->description }}</p>
|
||||
<div class="small text-muted mb-2">Akses modul</div>
|
||||
<ul class="mb-0 ps-3">
|
||||
@forelse ($role->permissions as $permission)
|
||||
<li>{{ $permission->module }}: {{ implode(', ', $permission->permissions) }}</li>
|
||||
@empty
|
||||
<li>Belum ditetapkan</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
@endsection
|
||||
33
src/resources/views/admin/settings.blade.php
Normal file
33
src/resources/views/admin/settings.blade.php
Normal file
@@ -0,0 +1,33 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Tetapan Sistem')
|
||||
@section('page-title', 'Tetapan Sistem')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4 p-lg-5">
|
||||
<form method="POST" action="{{ route('admin.settings.update') }}" class="d-grid gap-4">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
@foreach ($settings as $group => $items)
|
||||
<div>
|
||||
<h3 class="h5 fw-bold text-capitalize">{{ $group }}</h3>
|
||||
<div class="row g-3">
|
||||
@foreach ($items as $setting)
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">{{ $setting->label }}</label>
|
||||
<input type="text" name="settings[{{ $setting->key }}]" class="form-control" value="{{ old('settings.'.$setting->key, $setting->value) }}">
|
||||
@if ($setting->description)
|
||||
<div class="form-text">{{ $setting->description }}</div>
|
||||
@endif
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
<div>
|
||||
<button class="btn btn-primary">Simpan Tetapan</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
35
src/resources/views/admin/tasks-index.blade.php
Normal file
35
src/resources/views/admin/tasks-index.blade.php
Normal file
@@ -0,0 +1,35 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pengurusan Tugasan')
|
||||
@section('page-title', 'Pengurusan Tugasan')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tajuk</th>
|
||||
<th>Pegawai</th>
|
||||
<th>Prioriti</th>
|
||||
<th>Status</th>
|
||||
<th>Due Date</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($tasks as $task)
|
||||
<tr>
|
||||
<td>{{ $task->title }}</td>
|
||||
<td>{{ $task->assignee?->displayName() ?: '-' }}</td>
|
||||
<td>{{ ucfirst($task->priority) }}</td>
|
||||
<td>{{ ucfirst(str_replace('_', ' ', $task->status)) }}</td>
|
||||
<td>{{ optional($task->due_at)->format('d/m/Y h:i A') ?: '-' }}</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $tasks->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
54
src/resources/views/admin/user-form.blade.php
Normal file
54
src/resources/views/admin/user-form.blade.php
Normal file
@@ -0,0 +1,54 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', $user->exists ? 'Edit Pengguna' : 'Tambah Pengguna')
|
||||
@section('page-title', $user->exists ? 'Edit Pengguna' : 'Tambah Pengguna')
|
||||
@section('page-label', 'Pengurusan Pengguna')
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4 p-lg-5">
|
||||
<form method="POST" action="{{ $user->exists ? route('admin.users.update', $user) : route('admin.users.store') }}" class="row g-3">
|
||||
@csrf
|
||||
@if ($user->exists)
|
||||
@method('PUT')
|
||||
@endif
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Nama</label>
|
||||
<input type="text" name="name" class="form-control" value="{{ old('name', $user->name) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Emel</label>
|
||||
<input type="email" name="email" class="form-control" value="{{ old('email', $user->email) }}" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Peranan</label>
|
||||
<select name="role_id" class="form-select" required>
|
||||
@foreach ($roles as $role)
|
||||
<option value="{{ $role->id }}" @selected(old('role_id', $user->role_id) == $role->id)>{{ $role->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Bahagian / Unit</label>
|
||||
<select name="department_id" class="form-select">
|
||||
<option value="">Tiada</option>
|
||||
@foreach ($departments as $department)
|
||||
<option value="{{ $department->id }}" @selected(old('department_id', $user->department_id) == $department->id)>{{ $department->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Kata Laluan {{ $user->exists ? '(Kosongkan jika tidak diubah)' : '' }}</label>
|
||||
<input type="password" name="password" class="form-control" {{ $user->exists ? '' : 'required' }}>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" name="is_active" value="1" id="is_active" @checked(old('is_active', $user->is_active ?? true))>
|
||||
<label class="form-check-label" for="is_active">Akaun Aktif</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary">{{ $user->exists ? 'Kemaskini Pengguna' : 'Simpan Pengguna' }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
47
src/resources/views/admin/users-index.blade.php
Normal file
47
src/resources/views/admin/users-index.blade.php
Normal file
@@ -0,0 +1,47 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pengurusan Pengguna')
|
||||
@section('page-title', 'Pengurusan Pengguna')
|
||||
@section('page-label', 'Admin')
|
||||
|
||||
@section('page-actions')
|
||||
<a href="{{ route('admin.users.create') }}" class="btn btn-primary">Tambah Pengguna</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Nama</th>
|
||||
<th>Emel</th>
|
||||
<th>Peranan</th>
|
||||
<th>Bahagian/Unit</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($users as $user)
|
||||
<tr>
|
||||
<td>{{ $user->displayName() }}</td>
|
||||
<td>{{ $user->email }}</td>
|
||||
<td>{{ $user->role?->name }}</td>
|
||||
<td>{{ $user->department?->name ?: '-' }}</td>
|
||||
<td>{!! $user->is_active ? '<span class="badge text-bg-success">Aktif</span>' : '<span class="badge text-bg-secondary">Nyahaktif</span>' !!}</td>
|
||||
<td class="text-end">
|
||||
<div class="btn-group">
|
||||
<a href="{{ route('admin.users.edit', $user) }}" class="btn btn-sm btn-outline-secondary">Edit</a>
|
||||
<form method="POST" action="{{ route('admin.users.toggle', $user) }}">@csrf<button class="btn btn-sm btn-outline-warning">Toggle</button></form>
|
||||
<form method="POST" action="{{ route('admin.users.reset-password', $user) }}">@csrf<button class="btn btn-sm btn-outline-primary">Reset Kata Laluan</button></form>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $users->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
42
src/resources/views/auth/login.blade.php
Normal file
42
src/resources/views/auth/login.blade.php
Normal file
@@ -0,0 +1,42 @@
|
||||
@extends('layouts.guest')
|
||||
|
||||
@section('title', 'Log Masuk | MyAnsuran')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-5">
|
||||
<div class="text-center mb-4">
|
||||
<h1 class="fw-bold section-title">Log Masuk MyAnsuran</h1>
|
||||
<p class="text-muted">Portal permohonan bayaran cukai harta secara ansuran.</p>
|
||||
</div>
|
||||
<div class="card auth-card p-4 p-lg-5">
|
||||
@include('components.flash')
|
||||
<form method="POST" action="{{ route('login.store') }}" class="d-grid gap-3">
|
||||
@csrf
|
||||
<div>
|
||||
<label class="form-label">Emel</label>
|
||||
<input type="email" name="email" class="form-control form-control-lg" value="{{ old('email') }}" required>
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label">Kata Laluan</label>
|
||||
<input type="password" name="password" class="form-control form-control-lg" required>
|
||||
</div>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="remember" value="1" id="remember">
|
||||
<label class="form-check-label" for="remember">Kekalkan sesi log masuk</label>
|
||||
</div>
|
||||
<button class="btn btn-brand btn-lg">Log Masuk</button>
|
||||
</form>
|
||||
<div class="mt-4 text-center text-muted small">
|
||||
Akaun demo: <strong>admin@myansuran.test</strong>, <strong>staff@myansuran.test</strong>, <strong>user@myansuran.test</strong><br>
|
||||
Kata laluan demo: <strong>password</strong>
|
||||
</div>
|
||||
<div class="text-center mt-3">
|
||||
<a href="{{ route('register') }}">Belum ada akaun? Daftar di sini.</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
38
src/resources/views/auth/register.blade.php
Normal file
38
src/resources/views/auth/register.blade.php
Normal file
@@ -0,0 +1,38 @@
|
||||
@extends('layouts.guest')
|
||||
|
||||
@section('title', 'Daftar | MyAnsuran')
|
||||
|
||||
@section('content')
|
||||
<div class="container py-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-5">
|
||||
<div class="text-center mb-4">
|
||||
<h1 class="fw-bold section-title">Pendaftaran Pengguna Awam</h1>
|
||||
<p class="text-muted">Daftar akaun untuk memohon bayaran ansuran cukai harta secara atas talian.</p>
|
||||
</div>
|
||||
<div class="card auth-card p-4 p-lg-5">
|
||||
@include('components.flash')
|
||||
<form method="POST" action="{{ route('register.store') }}" class="d-grid gap-3">
|
||||
@csrf
|
||||
<div>
|
||||
<label class="form-label">Emel</label>
|
||||
<input type="email" name="email" class="form-control form-control-lg" value="{{ old('email') }}" required>
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label">Kata Laluan</label>
|
||||
<input type="password" name="password" class="form-control form-control-lg" required>
|
||||
</div>
|
||||
<div>
|
||||
<label class="form-label">Sahkan Kata Laluan</label>
|
||||
<input type="password" name="password_confirmation" class="form-control form-control-lg" required>
|
||||
</div>
|
||||
<button class="btn btn-brand btn-lg">Daftar Akaun</button>
|
||||
</form>
|
||||
<div class="text-center mt-3">
|
||||
<a href="{{ route('login') }}">Sudah ada akaun? Log masuk.</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
19
src/resources/views/components/flash.blade.php
Normal file
19
src/resources/views/components/flash.blade.php
Normal file
@@ -0,0 +1,19 @@
|
||||
@foreach (['success' => 'success', 'warning' => 'warning', 'error' => 'danger'] as $key => $variant)
|
||||
@if (session($key))
|
||||
<div class="alert alert-{{ $variant }} alert-dismissible fade show" role="alert">
|
||||
{{ session($key) }}
|
||||
<button type="button" class="btn-close" data-bs-dismiss="alert"></button>
|
||||
</div>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
<div class="fw-semibold mb-1">Terdapat ralat pada borang.</div>
|
||||
<ul class="mb-0 ps-3">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
29
src/resources/views/components/status-badge.blade.php
Normal file
29
src/resources/views/components/status-badge.blade.php
Normal file
@@ -0,0 +1,29 @@
|
||||
@php
|
||||
$statusMap = [
|
||||
'diproses' => 'warning',
|
||||
'aktif' => 'success',
|
||||
'gagal' => 'danger',
|
||||
'batal' => 'danger',
|
||||
'selesai' => 'dark',
|
||||
'pending' => 'warning',
|
||||
'success' => 'success',
|
||||
'failed' => 'danger',
|
||||
'belum_bayar' => 'secondary',
|
||||
'dibayar' => 'success',
|
||||
'lewat' => 'danger',
|
||||
];
|
||||
$labelMap = [
|
||||
'diproses' => 'Diproses',
|
||||
'aktif' => 'Aktif',
|
||||
'gagal' => 'Gagal',
|
||||
'batal' => 'Batal',
|
||||
'selesai' => 'Selesai',
|
||||
'pending' => 'Pending',
|
||||
'success' => 'Berjaya',
|
||||
'failed' => 'Gagal',
|
||||
'belum_bayar' => 'Belum Bayar',
|
||||
'dibayar' => 'Dibayar',
|
||||
'lewat' => 'Lewat',
|
||||
];
|
||||
@endphp
|
||||
<span class="badge text-bg-{{ $statusMap[$status] ?? 'secondary' }}">{{ $labelMap[$status] ?? ucfirst($status) }}</span>
|
||||
40
src/resources/views/exports/report-print.blade.php
Normal file
40
src/resources/views/exports/report-print.blade.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ms">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Laporan MyAnsuran</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; margin: 28px; color: #17354d; }
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 12px; margin-bottom: 20px; }
|
||||
th, td { border: 1px solid #d1dbe4; padding: 8px; text-align: left; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Laporan Ringkas MyAnsuran</h1>
|
||||
<table>
|
||||
<tr><th>Jumlah Permohonan Baharu</th><td>{{ $summary['new_applications'] }}</td></tr>
|
||||
<tr><th>Jumlah Bayaran Diterima</th><td>RM {{ number_format((float) $summary['payments_received'], 2) }}</td></tr>
|
||||
<tr><th>Jumlah Tunggakan</th><td>RM {{ number_format((float) $summary['outstanding_arrears'], 2) }}</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>Permohonan Bulanan</h2>
|
||||
<table>
|
||||
<thead><tr><th>Bulan</th><th>Jumlah</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($monthlyApplications as $item)
|
||||
<tr><td>{{ $item->month }}</td><td>{{ $item->total }}</td></tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h2>Bayaran Bulanan</h2>
|
||||
<table>
|
||||
<thead><tr><th>Bulan</th><th>Jumlah</th></tr></thead>
|
||||
<tbody>
|
||||
@foreach ($monthlyPayments as $item)
|
||||
<tr><td>{{ $item->month }}</td><td>RM {{ number_format((float) $item->total, 2) }}</td></tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
257
src/resources/views/layouts/app.blade.php
Normal file
257
src/resources/views/layouts/app.blade.php
Normal file
@@ -0,0 +1,257 @@
|
||||
@php
|
||||
$user = auth()->user();
|
||||
$isPublicPortal = $user?->isPublicUser();
|
||||
$notifications = $user?->notifications()->latest()->take(5)->get() ?? collect();
|
||||
$menus = match($user?->role?->slug) {
|
||||
'admin' => [
|
||||
['route' => 'admin.dashboard', 'label' => 'Dashboard', 'icon' => 'bi-grid-1x2-fill'],
|
||||
['route' => 'admin.users.index', 'label' => 'Pengurusan Pengguna', 'icon' => 'bi-people-fill'],
|
||||
['route' => 'admin.roles.index', 'label' => 'Pengurusan Peranan', 'icon' => 'bi-shield-lock-fill'],
|
||||
['route' => 'admin.applications.index', 'label' => 'Permohonan', 'icon' => 'bi-journal-text'],
|
||||
['route' => 'admin.installment-accounts.index', 'label' => 'Akaun Ansuran', 'icon' => 'bi-calendar-range-fill'],
|
||||
['route' => 'admin.payments.index', 'label' => 'Bayaran', 'icon' => 'bi-credit-card-2-front-fill'],
|
||||
['route' => 'admin.tasks.index', 'label' => 'Tugasan', 'icon' => 'bi-list-task'],
|
||||
['route' => 'admin.communications.index', 'label' => 'Notifikasi & Emel', 'icon' => 'bi-envelope-paper-fill'],
|
||||
['route' => 'admin.property-accounts.index', 'label' => 'Data Harta', 'icon' => 'bi-house-check-fill'],
|
||||
['route' => 'admin.import.index', 'label' => 'Import Excel', 'icon' => 'bi-file-earmark-arrow-up-fill'],
|
||||
['route' => 'admin.settings.index', 'label' => 'Tetapan Sistem', 'icon' => 'bi-gear-fill'],
|
||||
['route' => 'admin.reports.index', 'label' => 'Laporan', 'icon' => 'bi-bar-chart-fill'],
|
||||
['route' => 'admin.audit-trail.index', 'label' => 'Audit Trail', 'icon' => 'bi-clock-history'],
|
||||
],
|
||||
'staff' => [
|
||||
['route' => 'staff.dashboard', 'label' => 'Dashboard Staff', 'icon' => 'bi-speedometer2'],
|
||||
['route' => 'staff.applications.index', 'label' => 'Permohonan', 'icon' => 'bi-folder2-open'],
|
||||
['route' => 'staff.bulk-payments.index', 'label' => 'Kemaskini Bayaran Pukal', 'icon' => 'bi-file-earmark-spreadsheet-fill'],
|
||||
['route' => 'staff.import.index', 'label' => 'Import Excel', 'icon' => 'bi-file-earmark-arrow-up-fill'],
|
||||
],
|
||||
default => [
|
||||
['route' => 'portal.dashboard', 'label' => 'Dashboard', 'icon' => 'bi-house-door-fill'],
|
||||
['route' => 'portal.applications.index', 'label' => 'Permohonan Saya', 'icon' => 'bi-journal-check'],
|
||||
['route' => 'portal.applications.create', 'label' => 'Permohonan Baharu', 'icon' => 'bi-plus-circle-fill'],
|
||||
['route' => 'portal.profile.edit', 'label' => 'Profil Pengguna', 'icon' => 'bi-person-vcard-fill'],
|
||||
],
|
||||
};
|
||||
@endphp
|
||||
<!DOCTYPE html>
|
||||
<html lang="ms">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>@yield('title', 'MyAnsuran')</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
--ma-navy: #10375c;
|
||||
--ma-blue: #1d5d9b;
|
||||
--ma-green: #5c8374;
|
||||
--ma-gold: #f0b86e;
|
||||
--ma-soft: #f4f8fc;
|
||||
--ma-border: #dbe6f0;
|
||||
}
|
||||
body {
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(180deg, #eef5fb 0%, #f7f9fc 100%);
|
||||
color: #17354d;
|
||||
}
|
||||
.shell-sidebar {
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(240, 184, 110, 0.2), transparent 35%),
|
||||
linear-gradient(180deg, #11385e 0%, #0e2c47 100%);
|
||||
min-height: 100vh;
|
||||
color: #fff;
|
||||
}
|
||||
.shell-content {
|
||||
min-height: 100vh;
|
||||
}
|
||||
.sidebar-link {
|
||||
color: rgba(255, 255, 255, 0.88);
|
||||
border-radius: 1rem;
|
||||
padding: .78rem 1rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .85rem;
|
||||
text-decoration: none;
|
||||
transition: .2s ease;
|
||||
}
|
||||
.sidebar-link:hover,
|
||||
.sidebar-link.active {
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
color: #fff;
|
||||
}
|
||||
.portal-topbar,
|
||||
.surface-card,
|
||||
.stat-card {
|
||||
border: none;
|
||||
border-radius: 1.2rem;
|
||||
box-shadow: 0 18px 42px rgba(22, 48, 78, 0.08);
|
||||
}
|
||||
.portal-topbar {
|
||||
background: rgba(255, 255, 255, 0.92);
|
||||
backdrop-filter: blur(12px);
|
||||
}
|
||||
.stat-card {
|
||||
background: linear-gradient(135deg, #ffffff 0%, #f8fbff 100%);
|
||||
}
|
||||
.stat-icon {
|
||||
width: 3rem;
|
||||
height: 3rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 1rem;
|
||||
background: rgba(29, 93, 155, 0.12);
|
||||
color: var(--ma-blue);
|
||||
}
|
||||
.banner-card {
|
||||
background:
|
||||
radial-gradient(circle at top right, rgba(240, 184, 110, 0.24), transparent 22%),
|
||||
linear-gradient(135deg, rgba(16, 55, 92, 0.98), rgba(29, 93, 155, 0.88));
|
||||
color: #fff;
|
||||
border-radius: 1.4rem;
|
||||
border: none;
|
||||
}
|
||||
.table thead th {
|
||||
color: #4f667a;
|
||||
font-size: .85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
border-bottom-width: 1px;
|
||||
}
|
||||
.top-nav-link {
|
||||
color: #31526a;
|
||||
text-decoration: none;
|
||||
font-weight: 600;
|
||||
}
|
||||
.mini-label {
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .08em;
|
||||
font-size: .75rem;
|
||||
color: #6a8094;
|
||||
}
|
||||
.public-layout {
|
||||
max-width: 1240px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
</style>
|
||||
@stack('styles')
|
||||
</head>
|
||||
<body>
|
||||
@if ($isPublicPortal)
|
||||
<div class="container-fluid px-lg-4 py-3 public-layout">
|
||||
<nav class="portal-topbar navbar navbar-expand-lg mb-4 px-3">
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand fw-bold text-primary" href="{{ route('portal.dashboard') }}">MyAnsuran</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#publicNav">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="collapse navbar-collapse" id="publicNav">
|
||||
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
|
||||
@foreach ($menus as $menu)
|
||||
<li class="nav-item">
|
||||
<a class="nav-link top-nav-link {{ request()->routeIs(str_replace('.index', '.*', $menu['route'])) || request()->routeIs($menu['route']) ? 'text-primary' : '' }}"
|
||||
href="{{ route($menu['route']) }}">{{ $menu['label'] }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-light position-relative" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-bell"></i>
|
||||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">{{ $notifications->count() }}</span>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end p-3" style="width: 320px;">
|
||||
<div class="fw-semibold mb-2">Notifikasi</div>
|
||||
@forelse ($notifications as $notification)
|
||||
<div class="border-bottom pb-2 mb-2">
|
||||
<div class="fw-semibold small">{{ $notification->title }}</div>
|
||||
<div class="text-muted small">{{ $notification->message }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-muted small">Tiada notifikasi baharu.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-end">
|
||||
<div class="fw-semibold">{{ $user->displayName() }}</div>
|
||||
<div class="text-muted small">{{ $user->email }}</div>
|
||||
</div>
|
||||
<form method="POST" action="{{ route('logout') }}">
|
||||
@csrf
|
||||
<button class="btn btn-outline-secondary">Logout</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@include('components.flash')
|
||||
@yield('content')
|
||||
</div>
|
||||
@else
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<aside class="col-lg-3 col-xl-2 shell-sidebar px-3 py-4">
|
||||
<div class="d-flex align-items-center gap-3 mb-4">
|
||||
<div class="rounded-4 bg-white bg-opacity-10 p-3">
|
||||
<i class="bi bi-bank2 fs-4"></i>
|
||||
</div>
|
||||
<div>
|
||||
<div class="fw-bold fs-5">MyAnsuran</div>
|
||||
<div class="small text-white-50">Portal Demo KIK</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mb-4 pb-2 border-bottom border-light border-opacity-25">
|
||||
<div class="fw-semibold">{{ $user->displayName() }}</div>
|
||||
<div class="small text-white-50">{{ $user->role->name }}</div>
|
||||
</div>
|
||||
<nav class="d-grid gap-2">
|
||||
@foreach ($menus as $menu)
|
||||
<a href="{{ route($menu['route']) }}"
|
||||
class="sidebar-link {{ request()->routeIs(str_replace('.index', '.*', $menu['route'])) || request()->routeIs($menu['route']) ? 'active' : '' }}">
|
||||
<i class="bi {{ $menu['icon'] }}"></i>
|
||||
<span>{{ $menu['label'] }}</span>
|
||||
</a>
|
||||
@endforeach
|
||||
</nav>
|
||||
</aside>
|
||||
<main class="col-lg-9 col-xl-10 shell-content p-3 p-lg-4">
|
||||
<div class="portal-topbar px-4 py-3 mb-4 d-flex flex-wrap align-items-center justify-content-between gap-3">
|
||||
<div>
|
||||
<div class="mini-label">@yield('page-label', 'Modul Sistem')</div>
|
||||
<h1 class="h4 mb-0 fw-bold">@yield('page-title', 'MyAnsuran')</h1>
|
||||
</div>
|
||||
<div class="d-flex align-items-center gap-3">
|
||||
<div class="dropdown">
|
||||
<button class="btn btn-light position-relative" data-bs-toggle="dropdown">
|
||||
<i class="bi bi-bell"></i>
|
||||
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger">{{ $notifications->count() }}</span>
|
||||
</button>
|
||||
<div class="dropdown-menu dropdown-menu-end p-3" style="width: 320px;">
|
||||
<div class="fw-semibold mb-2">Notifikasi Terkini</div>
|
||||
@forelse ($notifications as $notification)
|
||||
<div class="border-bottom pb-2 mb-2">
|
||||
<div class="fw-semibold small">{{ $notification->title }}</div>
|
||||
<div class="text-muted small">{{ $notification->message }}</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-muted small">Tiada notifikasi untuk dipaparkan.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
@yield('page-actions')
|
||||
<form method="POST" action="{{ route('logout') }}">
|
||||
@csrf
|
||||
<button class="btn btn-outline-secondary">Logout</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@include('components.flash')
|
||||
@yield('content')
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</body>
|
||||
</html>
|
||||
66
src/resources/views/layouts/guest.blade.php
Normal file
66
src/resources/views/layouts/guest.blade.php
Normal file
@@ -0,0 +1,66 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ms">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>@yield('title', 'MyAnsuran')</title>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.css" rel="stylesheet">
|
||||
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js"></script>
|
||||
<style>
|
||||
:root {
|
||||
--ma-navy: #10375c;
|
||||
--ma-blue: #1d5d9b;
|
||||
--ma-green: #5c8374;
|
||||
--ma-soft: #f5f8fb;
|
||||
--ma-gold: #f0b86e;
|
||||
}
|
||||
body {
|
||||
font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
|
||||
background: linear-gradient(180deg, #f5f8fb 0%, #eef4f9 100%);
|
||||
color: #14324a;
|
||||
}
|
||||
.hero-surface {
|
||||
background:
|
||||
radial-gradient(circle at top right, rgba(240, 184, 110, 0.18), transparent 28%),
|
||||
linear-gradient(135deg, rgba(16, 55, 92, 0.98), rgba(29, 93, 155, 0.88));
|
||||
color: #fff;
|
||||
}
|
||||
.brand-pill {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: .75rem;
|
||||
padding: .75rem 1rem;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
border-radius: 999px;
|
||||
backdrop-filter: blur(6px);
|
||||
}
|
||||
.feature-card,
|
||||
.auth-card {
|
||||
border: none;
|
||||
border-radius: 1.25rem;
|
||||
box-shadow: 0 18px 42px rgba(22, 48, 78, 0.08);
|
||||
}
|
||||
.section-title {
|
||||
color: var(--ma-navy);
|
||||
font-weight: 700;
|
||||
}
|
||||
.btn-brand {
|
||||
background: var(--ma-green);
|
||||
border-color: var(--ma-green);
|
||||
color: #fff;
|
||||
}
|
||||
.btn-brand:hover {
|
||||
background: #4e7266;
|
||||
border-color: #4e7266;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
||||
@stack('styles')
|
||||
</head>
|
||||
<body>
|
||||
@yield('content')
|
||||
</body>
|
||||
</html>
|
||||
428
src/resources/views/portal/application-form.blade.php
Normal file
428
src/resources/views/portal/application-form.blade.php
Normal file
@@ -0,0 +1,428 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Permohonan Baharu')
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$profile = auth()->user()->profile;
|
||||
$declarationFields = [
|
||||
'declaration_name',
|
||||
'declaration_identification_type',
|
||||
'declaration_identification_number',
|
||||
'declaration_date',
|
||||
'declaration_accepted',
|
||||
'ic_attachment',
|
||||
];
|
||||
$hasDeclarationErrors = collect($declarationFields)->contains(fn ($field) => $errors->has($field));
|
||||
$isOldAccountBlocked = (bool) ($oldAccountStatus['is_blocked'] ?? false);
|
||||
$initialStep = $hasDeclarationErrors && ! $isOldAccountBlocked ? 3 : (old('property_account_id') && ! $isOldAccountBlocked ? 2 : 1);
|
||||
@endphp
|
||||
|
||||
<div class="card surface-card p-4 p-lg-5">
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-start gap-3 mb-4">
|
||||
<div>
|
||||
<div class="mini-label">Permohonan Baharu</div>
|
||||
<h1 class="h4 fw-bold mb-1">Permohonan Bayaran Cukai Harta Secara Ansuran</h1>
|
||||
<p class="text-muted mb-0">Lengkapkan permohonan mengikut turutan semakan, borang dan perakuan.</p>
|
||||
</div>
|
||||
<a href="{{ route('portal.applications.index') }}" class="btn btn-outline-secondary">Kembali</a>
|
||||
</div>
|
||||
|
||||
<div class="application-stepper mb-4">
|
||||
<div class="application-stepper-item" data-step-indicator="1">
|
||||
<span>1</span>
|
||||
<strong>Semakan No_Akaun_Tunggakan</strong>
|
||||
</div>
|
||||
<div class="application-stepper-item" data-step-indicator="2">
|
||||
<span>2</span>
|
||||
<strong>Borang Permohonan</strong>
|
||||
</div>
|
||||
<div class="application-stepper-item" data-step-indicator="3">
|
||||
<span>3</span>
|
||||
<strong>Teks Perakuan Pemohon</strong>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="alert alert-danger">
|
||||
Sila semak semula maklumat permohonan sebelum dihantar.
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<section class="wizard-step" data-step="1">
|
||||
<div class="row g-4 align-items-start">
|
||||
<div class="col-lg-7">
|
||||
<h2 class="h5 fw-bold mb-3">Semakan No_Akaun_Tunggakan</h2>
|
||||
<p class="text-muted">Masukkan nombor akaun tunggakan untuk mendapatkan maklumat akaun cukai harta.</p>
|
||||
<div class="mb-3">
|
||||
<label class="form-label">No_Akaun_Tunggakan</label>
|
||||
<input type="text" id="lookup_no_akaun_tunggakan" class="form-control" value="{{ old('no_akaun_tunggakan') }}" placeholder="Masukkan nombor akaun tunggakan">
|
||||
<div class="form-text">Pengguna hanya dibenarkan memasukkan nombor akaun tunggakan. No_Akaun akan dipaparkan secara automatik selepas semakan berjaya.</div>
|
||||
</div>
|
||||
<div class="d-flex flex-wrap gap-2">
|
||||
<button type="button" id="lookup-button" class="btn btn-primary">Semak Akaun</button>
|
||||
<button type="button" id="lookup-next-button" class="btn btn-outline-primary" data-next-step="2" disabled>Seterusnya</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div id="lookup-feedback" class="border rounded-4 p-4 bg-light h-100">
|
||||
@if ($oldAccount)
|
||||
<div class="alert alert-{{ $isOldAccountBlocked ? 'warning' : 'success' }} mb-0">
|
||||
Akaun dijumpai: <strong>{{ $oldAccount->no_akaun }}</strong><br>
|
||||
Status Akaun:
|
||||
<span class="badge text-bg-{{ $oldAccountStatus['badge_class'] }}">{{ $oldAccountStatus['label'] }}</span>
|
||||
@if ($oldAccountStatus['application_no'])
|
||||
<span class="text-muted small">({{ $oldAccountStatus['application_no'] }})</span>
|
||||
@endif
|
||||
<br>
|
||||
Pemilik: {{ $oldAccount->pemilik }}<br>
|
||||
Tunggakan: RM {{ number_format((float) $oldAccount->tunggakan, 2) }}
|
||||
@if ($isOldAccountBlocked)
|
||||
<hr>
|
||||
<strong>Permohonan tidak boleh diteruskan.</strong><br>
|
||||
{{ $oldAccountStatus['block_message'] }}
|
||||
@endif
|
||||
</div>
|
||||
@else
|
||||
<div class="text-muted small">Maklumat akaun dan status terkini akan dipaparkan selepas semakan berjaya.</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<form method="POST" action="{{ route('portal.applications.store') }}" enctype="multipart/form-data" id="application-form">
|
||||
@csrf
|
||||
<input type="hidden" name="property_account_id" id="property_account_id" value="{{ old('property_account_id') }}">
|
||||
<input type="hidden" name="no_akaun_tunggakan" id="form_no_akaun_tunggakan" value="{{ old('no_akaun_tunggakan', $oldAccount?->no_akaun_tunggakan) }}">
|
||||
|
||||
<section class="wizard-step" data-step="2">
|
||||
<div class="d-flex justify-content-between align-items-start gap-3 mb-4">
|
||||
<div>
|
||||
<h2 class="h5 fw-bold mb-1">Borang Permohonan Bayaran Cukai Harta Secara Ansuran</h2>
|
||||
<p class="text-muted mb-0">Lengkapkan semua maklumat permohonan selepas semakan akaun berjaya.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">No_Akaun</label>
|
||||
<input type="text" id="no_akaun" class="form-control" value="{{ $oldAccount?->no_akaun }}" readonly>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Status Akaun Terkini</label>
|
||||
<input type="text" id="account_status" class="form-control" value="{{ $oldAccount ? $oldAccountStatus['label'] : '' }}" readonly>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Pemilik</label>
|
||||
<input type="text" id="pemilik" class="form-control" value="{{ $oldAccount?->pemilik }}" readonly>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Rupacara</label>
|
||||
<input type="text" id="rupacara" class="form-control" value="{{ $oldAccount?->rupacara }}" readonly>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">No_Lot</label>
|
||||
<input type="text" name="no_lot" id="no_lot" class="form-control" value="{{ old('no_lot', $oldAccount?->no_lot) }}" readonly>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">No_DHM</label>
|
||||
<input type="text" name="no_dhm" id="no_dhm" class="form-control" value="{{ old('no_dhm', $oldAccount?->no_dhm) }}" placeholder="Masukkan No_DHM jika perlu dikemaskini">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">No_Syarikat</label>
|
||||
<input type="text" name="no_syarikat" id="no_syarikat" class="form-control" value="{{ old('no_syarikat', $oldAccount?->no_syarikat) }}">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-text">Rupacara, No_Lot dan Alamat_Harta akan diisi automatik daripada data import Excel. No_DHM dan No_Syarikat boleh dikemas kini oleh pemohon jika perlu.</div>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Kategori Harta</label>
|
||||
<select name="category" class="form-select" required>
|
||||
<option value="">Pilih kategori</option>
|
||||
@foreach ($categories as $category)
|
||||
<option value="{{ $category->value }}" @selected(old('category') === $category->value)>{{ $category->value }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Tempoh Ansuran</label>
|
||||
<select name="installment_months" class="form-select" required>
|
||||
<option value="">Pilih tempoh</option>
|
||||
@foreach ($months as $month)
|
||||
<option value="{{ $month }}" @selected(old('installment_months') == $month)>{{ $month }} bulan</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Identification Type</label>
|
||||
<select name="identification_type" class="form-select" required>
|
||||
@foreach (['Army/Police ID', 'MyKad', 'National ID'] as $type)
|
||||
<option value="{{ $type }}" @selected(old('identification_type', $profile?->identification_type) === $type)>{{ $type }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Identification Number</label>
|
||||
<input type="text" name="identification_number" class="form-control" value="{{ old('identification_number', $profile?->identification_number) }}" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Alamat_Harta</label>
|
||||
<textarea id="alamat_harta" name="alamat_harta" class="form-control" rows="2" required readonly>{{ old('alamat_harta', $oldPropertyAddress) }}</textarea>
|
||||
<div class="form-text">Susunan alamat harta: No_Bgnn, Nama_Jalan.</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Alamat_Surat_Menyurat</label>
|
||||
<textarea name="alamat_surat_menyurat" class="form-control" rows="2" required>{{ old('alamat_surat_menyurat', $profile?->correspondence_address) }}</textarea>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Kod Negara</label>
|
||||
<select name="country_code" class="form-select">
|
||||
@foreach (['+60', '+65', '+62'] as $code)
|
||||
<option value="{{ $code }}" @selected(old('country_code', $profile?->country_code ?? '+60') === $code)>{{ $code }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Mobile_No</label>
|
||||
<input type="text" name="mobile_no" class="form-control" value="{{ old('mobile_no', $profile?->mobile_no) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Emel</label>
|
||||
<input type="email" name="email" class="form-control" value="{{ old('email', auth()->user()->email) }}" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Alamat_Tempat_Bekerja</label>
|
||||
<textarea name="alamat_tempat_bekerja" class="form-control" rows="2">{{ old('alamat_tempat_bekerja', $profile?->workplace_address) }}</textarea>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Pekerjaan</label>
|
||||
<input type="text" name="pekerjaan" class="form-control" value="{{ old('pekerjaan', $profile?->occupation) }}">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Pendapatan Sebulan</label>
|
||||
<input type="number" step="0.01" name="pendapatan_sebulan" class="form-control" value="{{ old('pendapatan_sebulan', $profile?->monthly_income) }}">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between mt-4">
|
||||
<button type="button" class="btn btn-outline-secondary" data-prev-step="1">Kembali</button>
|
||||
<button type="button" class="btn btn-primary" data-next-step="3">Seterusnya</button>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="wizard-step" data-step="3">
|
||||
<h2 class="h5 fw-bold mb-3">Teks Perakuan Pemohon</h2>
|
||||
<div class="alert alert-warning">
|
||||
“Saya yang bertandatangan dibawah bersetuju dan berjanji akan menjelaskan bayaran cukai harta mengikut jadual ansuran yang telah diluluskan sebagaimana di bawah. Sekiranya saya gagal maka pihak Majlis Bandaraya Iskandar Puteri berhak membatalkan permohonan ini dan mengambil TINDAKAN SITAAN / UNDANG-UNDANG ke atas SAYA / PREMIS tanpa apa-apa notis lagi.”
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Nama Perakuan</label>
|
||||
<input type="text" name="declaration_name" class="form-control" value="{{ old('declaration_name', $profile?->public_name ?? auth()->user()->name) }}" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Jenis ID Perakuan</label>
|
||||
<select name="declaration_identification_type" class="form-select" required>
|
||||
@foreach (['Army/Police ID', 'MyKad', 'National ID'] as $type)
|
||||
<option value="{{ $type }}" @selected(old('declaration_identification_type', $profile?->identification_type) === $type)>{{ $type }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">No ID Perakuan</label>
|
||||
<input type="text" name="declaration_identification_number" class="form-control" value="{{ old('declaration_identification_number', $profile?->identification_number) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Tarikh Perakuan</label>
|
||||
<input type="date" name="declaration_date" class="form-control" value="{{ old('declaration_date', now()->format('Y-m-d')) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Upload / Capture Salinan IC</label>
|
||||
<input type="file" name="ic_attachment" class="form-control">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="declaration_accepted" value="1" id="declaration_accepted" @checked(old('declaration_accepted')) required>
|
||||
<label class="form-check-label" for="declaration_accepted">Saya bersetuju dengan perakuan pemohon di atas.</label>
|
||||
</div>
|
||||
@error('declaration_accepted')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-between mt-4">
|
||||
<button type="button" class="btn btn-outline-secondary" data-prev-step="2">Kembali</button>
|
||||
<button class="btn btn-primary btn-lg">Hantar Permohonan</button>
|
||||
</div>
|
||||
</section>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('styles')
|
||||
<style>
|
||||
.application-stepper {
|
||||
display: grid;
|
||||
gap: .75rem;
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
.application-stepper-item {
|
||||
border: 1px solid var(--ma-border);
|
||||
border-radius: .8rem;
|
||||
padding: .9rem;
|
||||
color: #60768a;
|
||||
background: #fff;
|
||||
}
|
||||
.application-stepper-item span {
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border-radius: 50%;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: .5rem;
|
||||
background: #edf3f8;
|
||||
color: #31526a;
|
||||
font-weight: 700;
|
||||
}
|
||||
.application-stepper-item.active {
|
||||
border-color: var(--ma-blue);
|
||||
color: var(--ma-navy);
|
||||
box-shadow: 0 12px 28px rgba(29, 93, 155, .12);
|
||||
}
|
||||
.application-stepper-item.active span {
|
||||
background: var(--ma-blue);
|
||||
color: #fff;
|
||||
}
|
||||
.wizard-step {
|
||||
display: none;
|
||||
}
|
||||
.wizard-step.active {
|
||||
display: block;
|
||||
}
|
||||
@media (max-width: 768px) {
|
||||
.application-stepper {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
$(function () {
|
||||
const initialStep = Number('{{ $initialStep }}');
|
||||
const hasOldAccount = Boolean('{{ old('property_account_id') ? '1' : '' }}');
|
||||
const hasBlockedOldAccount = Boolean('{{ $isOldAccountBlocked ? '1' : '' }}');
|
||||
let currentStep = initialStep;
|
||||
|
||||
function showStep(step) {
|
||||
currentStep = step;
|
||||
$('.wizard-step').removeClass('active');
|
||||
$('.wizard-step[data-step="' + step + '"]').addClass('active');
|
||||
$('[data-step-indicator]').removeClass('active');
|
||||
$('[data-step-indicator="' + step + '"]').addClass('active');
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
|
||||
function validateStep(step) {
|
||||
if (step === 1 && !$('#property_account_id').val()) {
|
||||
$('#lookup-feedback').html('<div class="alert alert-warning mb-0">Sila buat semakan No_Akaun_Tunggakan dahulu.</div>');
|
||||
return false;
|
||||
}
|
||||
|
||||
if (step === 1 && $('#lookup-next-button').prop('disabled')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const controls = $('.wizard-step[data-step="' + step + '"]').find('input, select, textarea');
|
||||
|
||||
for (const control of controls) {
|
||||
if (!control.checkValidity()) {
|
||||
control.reportValidity();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function fillAccount(response) {
|
||||
$('#property_account_id').val(response.id);
|
||||
$('#form_no_akaun_tunggakan').val(response.no_akaun_tunggakan);
|
||||
$('#no_akaun').val(response.no_akaun);
|
||||
$('#account_status').val(response.account_status?.label ?? 'Belum Ada Permohonan Ansuran');
|
||||
$('#pemilik').val(response.pemilik);
|
||||
$('#rupacara').val(response.rupacara ?? '');
|
||||
$('#no_lot').val(response.no_lot ?? '');
|
||||
$('#no_dhm').val(response.no_dhm ?? '');
|
||||
$('#no_syarikat').val(response.no_syarikat ?? '');
|
||||
$('#alamat_harta').val(response.alamat_harta ?? '');
|
||||
$('#lookup-next-button').prop('disabled', !response.can_continue);
|
||||
}
|
||||
|
||||
function escapeHtml(value) {
|
||||
return $('<div>').text(value ?? '').html();
|
||||
}
|
||||
|
||||
$('#lookup-button').on('click', function () {
|
||||
const noAkaunTunggakan = $('#lookup_no_akaun_tunggakan').val();
|
||||
$('#lookup-feedback').html('<div class="text-muted small">Sedang menyemak akaun...</div>');
|
||||
|
||||
$.get('{{ route('portal.applications.lookup') }}', { no_akaun_tunggakan: noAkaunTunggakan })
|
||||
.done(function (response) {
|
||||
fillAccount(response);
|
||||
const accountStatus = response.account_status ?? {};
|
||||
const statusBadge = `
|
||||
<span class="badge text-bg-${escapeHtml(accountStatus.badge_class ?? 'secondary')}">
|
||||
${escapeHtml(accountStatus.label ?? 'Belum Ada Permohonan Ansuran')}
|
||||
</span>
|
||||
`;
|
||||
const applicationNo = accountStatus.application_no
|
||||
? `<span class="text-muted small">(${escapeHtml(accountStatus.application_no)})</span>`
|
||||
: '';
|
||||
const isBlocked = !response.can_continue;
|
||||
const blockMessage = isBlocked
|
||||
? `
|
||||
<hr>
|
||||
<strong>Permohonan tidak boleh diteruskan.</strong><br>
|
||||
${escapeHtml(response.block_message ?? 'Akaun ini tidak boleh meneruskan permohonan baharu.')}
|
||||
`
|
||||
: '';
|
||||
|
||||
$('#lookup-feedback').html(`
|
||||
<div class="alert alert-${isBlocked ? 'warning' : 'success'} mb-0">
|
||||
Akaun dijumpai: <strong>${escapeHtml(response.no_akaun)}</strong><br>
|
||||
Status Akaun: ${statusBadge} ${applicationNo}<br>
|
||||
Pemilik: ${escapeHtml(response.pemilik)}<br>
|
||||
Tunggakan: RM ${escapeHtml(response.tunggakan)}
|
||||
${blockMessage}
|
||||
</div>
|
||||
`);
|
||||
})
|
||||
.fail(function (xhr) {
|
||||
$('#property_account_id, #form_no_akaun_tunggakan').val('');
|
||||
$('#no_akaun, #account_status, #pemilik, #rupacara, #no_lot, #no_dhm, #no_syarikat, #alamat_harta').val('');
|
||||
$('#lookup-next-button').prop('disabled', true);
|
||||
$('#lookup-feedback').html(`<div class="alert alert-danger mb-0">${xhr.responseJSON?.message ?? 'Ralat semasa menyemak akaun.'}</div>`);
|
||||
});
|
||||
});
|
||||
|
||||
$('[data-next-step]').on('click', function () {
|
||||
if (validateStep(currentStep)) {
|
||||
showStep(Number($(this).data('next-step')));
|
||||
}
|
||||
});
|
||||
|
||||
$('[data-prev-step]').on('click', function () {
|
||||
showStep(Number($(this).data('prev-step')));
|
||||
});
|
||||
|
||||
if (hasOldAccount && !hasBlockedOldAccount) {
|
||||
$('#lookup-next-button').prop('disabled', false);
|
||||
}
|
||||
|
||||
showStep(currentStep);
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
95
src/resources/views/portal/application-show.blade.php
Normal file
95
src/resources/views/portal/application-show.blade.php
Normal file
@@ -0,0 +1,95 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Butiran Permohonan')
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-8">
|
||||
<div class="card surface-card p-4">
|
||||
<div class="d-flex justify-content-between align-items-start mb-3">
|
||||
<div>
|
||||
<div class="mini-label">No Permohonan</div>
|
||||
<h2 class="h4 fw-bold mb-1">{{ $application->application_no }}</h2>
|
||||
<p class="text-muted mb-0">Tarikh permohonan: {{ $application->created_at->format('d/m/Y h:i A') }}</p>
|
||||
</div>
|
||||
@include('components.status-badge', ['status' => $application->status])
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6"><strong>No Akaun:</strong><br>{{ $application->no_akaun }}</div>
|
||||
<div class="col-md-6"><strong>No Akaun Tunggakan:</strong><br>{{ $application->no_akaun_tunggakan }}</div>
|
||||
<div class="col-md-6"><strong>Kategori:</strong><br>{{ $application->category }}</div>
|
||||
<div class="col-md-6"><strong>Tempoh Ansuran:</strong><br>{{ $application->installment_months }} bulan</div>
|
||||
<div class="col-md-6"><strong>No Lot:</strong><br>{{ $application->no_lot ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>No DHM:</strong><br>{{ $application->no_dhm ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>No Syarikat:</strong><br>{{ $application->no_syarikat ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>Jumlah Tunggakan:</strong><br>RM {{ number_format((float) $application->total_arrears, 2) }}</div>
|
||||
<div class="col-md-6"><strong>Ulasan Staff:</strong><br>{{ $application->staff_remarks ?: 'Belum direkodkan.' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4 mt-4">
|
||||
<h3 class="h5 fw-bold mb-3">Jadual Ansuran Manual</h3>
|
||||
@if ($application->status === 'aktif' && $application->schedules->count())
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ansuran Ke-</th>
|
||||
<th>Tarikh Bayaran</th>
|
||||
<th>Amaun</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($application->schedules as $schedule)
|
||||
<tr>
|
||||
<td>{{ $schedule->installment_no }}</td>
|
||||
<td>{{ optional($schedule->due_date)->format('d/m/Y') }}</td>
|
||||
<td>RM {{ number_format((float) $schedule->amount, 2) }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $schedule->payment_status])</td>
|
||||
<td class="text-end">
|
||||
@if ($schedule->payment_status === 'belum_bayar')
|
||||
<a href="{{ route('portal.payments.create', ['application' => $application, 'schedule' => $schedule->id]) }}" class="btn btn-sm btn-primary">Bayar Dummy JomPAY</a>
|
||||
@endif
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@else
|
||||
<div class="alert alert-warning mb-0">Jadual ansuran akan dipaparkan selepas disahkan oleh staff.</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Maklumat Akaun</h3>
|
||||
<dl class="row mb-0">
|
||||
<dt class="col-sm-5">Pemilik</dt><dd class="col-sm-7">{{ $application->propertyAccount?->pemilik }}</dd>
|
||||
<dt class="col-sm-5">Taman</dt><dd class="col-sm-7">{{ $application->propertyAccount?->taman }}</dd>
|
||||
<dt class="col-sm-5">Rupacara</dt><dd class="col-sm-7">{{ $application->propertyAccount?->rupacara }}</dd>
|
||||
<dt class="col-sm-5">Kadar</dt><dd class="col-sm-7">{{ $application->propertyAccount?->kadar }}</dd>
|
||||
<dt class="col-sm-5">Alamat Harta</dt><dd class="col-sm-7">{{ $application->alamat_harta }}</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="card surface-card p-4 mt-4">
|
||||
<h3 class="h5 fw-bold mb-3">Sejarah Tindakan</h3>
|
||||
<div class="timeline">
|
||||
@forelse ($application->histories as $history)
|
||||
<div class="border-start ps-3 pb-3 mb-3">
|
||||
<div class="fw-semibold">{{ str($history->action)->replace('_', ' ')->headline() }}</div>
|
||||
<div class="text-muted small">{{ $history->created_at->format('d/m/Y h:i A') }} oleh {{ $history->user?->displayName() ?? 'Sistem' }}</div>
|
||||
@if ($history->remarks)
|
||||
<div class="small mt-1">{{ $history->remarks }}</div>
|
||||
@endif
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-muted small">Tiada sejarah tindakan direkodkan.</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
47
src/resources/views/portal/applications-index.blade.php
Normal file
47
src/resources/views/portal/applications-index.blade.php
Normal file
@@ -0,0 +1,47 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Permohonan Saya')
|
||||
|
||||
@section('content')
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h4 fw-bold mb-1">Senarai Permohonan Ansuran</h2>
|
||||
<p class="text-muted mb-0">Pantau status permohonan dan jadual ansuran manual yang disahkan.</p>
|
||||
</div>
|
||||
<a href="{{ route('portal.applications.create') }}" class="btn btn-primary">Tambah Permohonan</a>
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Permohonan</th>
|
||||
<th>No Akaun</th>
|
||||
<th>Kategori</th>
|
||||
<th>Tempoh</th>
|
||||
<th>Jumlah Tunggakan</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($applications as $application)
|
||||
<tr>
|
||||
<td>{{ $application->application_no }}</td>
|
||||
<td>{{ $application->no_akaun_tunggakan }}</td>
|
||||
<td>{{ $application->category }}</td>
|
||||
<td>{{ $application->installment_months }} bulan</td>
|
||||
<td>RM {{ number_format((float) $application->total_arrears, 2) }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $application->status])</td>
|
||||
<td class="text-end"><a href="{{ route('portal.applications.show', $application) }}" class="btn btn-outline-secondary btn-sm">Butiran</a></td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-muted py-4">Tiada permohonan untuk dipaparkan.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $applications->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
85
src/resources/views/portal/dashboard.blade.php
Normal file
85
src/resources/views/portal/dashboard.blade.php
Normal file
@@ -0,0 +1,85 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Dashboard Pengguna Awam')
|
||||
|
||||
@section('content')
|
||||
<div class="card banner-card p-4 p-lg-5 mb-4">
|
||||
<div class="row align-items-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="mini-label text-white-50">Portal Pengguna Awam</div>
|
||||
<h2 class="fw-bold mb-2">Salam Maju Johor, {{ auth()->user()->displayName() }}</h2>
|
||||
<p class="mb-0 text-white-50">Maklumat log masuk terakhir: {{ optional(auth()->user()->last_login_at)->format('d/m/Y h:i A') ?? 'Ini adalah log masuk pertama anda.' }}</p>
|
||||
</div>
|
||||
<div class="col-lg-4 text-lg-end mt-3 mt-lg-0">
|
||||
<a href="{{ route('portal.applications.create') }}" class="btn btn-light btn-lg">Tambah Permohonan Baharu</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
@foreach ([
|
||||
['label' => 'Jumlah Permohonan', 'value' => $stats['total'], 'icon' => 'bi-journal-text'],
|
||||
['label' => 'Permohonan Diproses', 'value' => $stats['processing'], 'icon' => 'bi-hourglass-split'],
|
||||
['label' => 'Akaun Aktif', 'value' => $stats['active'], 'icon' => 'bi-check-circle-fill'],
|
||||
['label' => 'Bayaran Selesai', 'value' => $stats['completed'], 'icon' => 'bi-patch-check-fill'],
|
||||
] as $card)
|
||||
<div class="col-md-6 col-xl-3">
|
||||
<div class="card stat-card p-4 h-100">
|
||||
<div class="d-flex align-items-center justify-content-between">
|
||||
<div>
|
||||
<div class="mini-label">{{ $card['label'] }}</div>
|
||||
<div class="display-6 fw-bold">{{ $card['value'] }}</div>
|
||||
</div>
|
||||
<div class="stat-icon"><i class="bi {{ $card['icon'] }} fs-4"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h3 class="h5 fw-bold mb-0">Permohonan Terkini</h3>
|
||||
<a href="{{ route('portal.applications.index') }}" class="btn btn-outline-primary btn-sm">Lihat Semua</a>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Permohonan</th>
|
||||
<th>No Akaun Tunggakan</th>
|
||||
<th>Kategori</th>
|
||||
<th>Tempoh</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($applications as $application)
|
||||
<tr>
|
||||
<td>{{ $application->application_no }}</td>
|
||||
<td>{{ $application->no_akaun_tunggakan }}</td>
|
||||
<td>{{ $application->category }}</td>
|
||||
<td>{{ $application->installment_months }} bulan</td>
|
||||
<td>@include('components.status-badge', ['status' => $application->status])</td>
|
||||
<td class="text-end"><a href="{{ route('portal.applications.show', $application) }}" class="btn btn-sm btn-outline-secondary">Butiran</a></td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="6" class="text-center text-muted py-4">Belum ada permohonan dihantar.</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="pt-4 text-muted small text-center">
|
||||
<div>Terma & Syarat | Polisi Privasi | Maklumat Hubungan</div>
|
||||
<div class="mt-2">
|
||||
<i class="bi bi-facebook"></i>
|
||||
<i class="bi bi-instagram ms-2"></i>
|
||||
<i class="bi bi-youtube ms-2"></i>
|
||||
</div>
|
||||
</footer>
|
||||
@endsection
|
||||
97
src/resources/views/portal/landing.blade.php
Normal file
97
src/resources/views/portal/landing.blade.php
Normal file
@@ -0,0 +1,97 @@
|
||||
@extends('layouts.guest')
|
||||
|
||||
@section('title', 'MyAnsuran')
|
||||
|
||||
@section('content')
|
||||
<section class="hero-surface py-5">
|
||||
<div class="container py-lg-4">
|
||||
<div class="row align-items-center g-5">
|
||||
<div class="col-lg-7">
|
||||
<div class="brand-pill mb-4">
|
||||
<i class="bi bi-bank2 fs-4"></i>
|
||||
<span>Demo KIK MBIP | Portal Bayaran Ansuran Cukai Harta</span>
|
||||
</div>
|
||||
<h1 class="display-5 fw-bold mb-3">MyAnsuran memudahkan permohonan bayaran cukai harta secara ansuran.</h1>
|
||||
<p class="lead text-white-50 mb-4">Pengguna awam boleh semak akaun tunggakan, memohon tempoh ansuran 2 hingga 6 bulan, dan membuat bayaran dummy JomPAY selepas jadual ansuran manual disahkan oleh staff.</p>
|
||||
<div class="d-flex flex-wrap gap-3">
|
||||
<a href="{{ route('register') }}" class="btn btn-light btn-lg px-4">Daftar Pengguna Awam</a>
|
||||
<a href="{{ route('login') }}" class="btn btn-outline-light btn-lg px-4">Log Masuk</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="card feature-card p-4">
|
||||
<div class="row g-3">
|
||||
<div class="col-12">
|
||||
<div class="stat-card p-3">
|
||||
<div class="mini-label">Jumlah Permohonan Demo</div>
|
||||
<div class="display-6 fw-bold">{{ $stats['applications'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="stat-card p-3">
|
||||
<div class="mini-label">Data Harta</div>
|
||||
<div class="h2 fw-bold mb-0">{{ $stats['property_accounts'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div class="stat-card p-3">
|
||||
<div class="mini-label">Akaun Aktif</div>
|
||||
<div class="h2 fw-bold mb-0">{{ $stats['active_cases'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="alert alert-primary mb-0">
|
||||
<strong>Biller Code JomPAY:</strong> 37317
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="container py-5">
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-4">
|
||||
<div class="card feature-card h-100 p-4">
|
||||
<div class="stat-icon mb-3"><i class="bi bi-signpost-split-fill"></i></div>
|
||||
<h3 class="h5 fw-bold">Langkah Proses Ringkas</h3>
|
||||
<ol class="mb-0 ps-3">
|
||||
<li>Daftar dan lengkapkan profil.</li>
|
||||
<li>Masukkan No_Akaun_Tunggakan.</li>
|
||||
<li>Pilih tempoh ansuran 2 hingga 6 bulan.</li>
|
||||
<li>Staff semak dan masukkan amaun ansuran manual.</li>
|
||||
<li>Buat bayaran dummy JomPAY.</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card feature-card h-100 p-4">
|
||||
<div class="stat-icon mb-3"><i class="bi bi-cash-stack"></i></div>
|
||||
<h3 class="h5 fw-bold">Panduan Bayaran Pertama</h3>
|
||||
<table class="table mb-0">
|
||||
<tbody>
|
||||
<tr><th>Kediaman</th><td>Minimum 30%</td></tr>
|
||||
<tr><th>Industri</th><td>Minimum 50%</td></tr>
|
||||
<tr><th>Perdagangan</th><td>Minimum 50%</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-muted small mt-3 mb-0">Panduan ini hanya untuk rujukan. Amaun ansuran sebenar dimasukkan secara manual oleh staff.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-4">
|
||||
<div class="card feature-card h-100 p-4">
|
||||
<div class="stat-icon mb-3"><i class="bi bi-shield-check"></i></div>
|
||||
<h3 class="h5 fw-bold">Kelebihan Sistem</h3>
|
||||
<ul class="mb-0 ps-3">
|
||||
<li>Dashboard berasingan untuk Admin, Staff dan Pengguna Awam.</li>
|
||||
<li>Modul import Excel data akaun tunggakan.</li>
|
||||
<li>Rekod notifikasi, email dummy, laporan dan audit trail.</li>
|
||||
<li>Print borang rasmi termasuk ulasan staff.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
75
src/resources/views/portal/payment.blade.php
Normal file
75
src/resources/views/portal/payment.blade.php
Normal file
@@ -0,0 +1,75 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Pembayaran Dummy JomPAY')
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-7">
|
||||
<div class="card surface-card p-4 p-lg-5">
|
||||
<h2 class="h4 fw-bold mb-1">Pembayaran Dummy JomPAY</h2>
|
||||
<p class="text-muted mb-4">Masukkan maklumat bil dan amaun pembayaran sebelum simulasi pembayaran berjaya.</p>
|
||||
<form method="POST" action="{{ route('portal.payments.store', $application) }}" id="payment-form" class="row g-3">
|
||||
@csrf
|
||||
<input type="hidden" name="schedule_id" value="{{ $schedule?->id }}">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Biller Code</label>
|
||||
<input type="text" name="biller_code" class="form-control" value="37317" readonly>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">REF 1</label>
|
||||
<input type="text" name="ref_1" class="form-control" value="{{ $application->no_akaun }}" required>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">REF 2</label>
|
||||
<input type="text" name="ref_2" class="form-control" value="{{ auth()->user()->email }}" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Amaun Bayaran</label>
|
||||
<input type="text" id="amount-display" name="amount" class="form-control form-control-lg text-end fw-bold" value="{{ number_format((float) $defaultAmount, 2, '.', '') }}" required>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="row g-2" id="numpad">
|
||||
@foreach ([1,2,3,4,5,6,7,8,9,'.',0,'C'] as $key)
|
||||
<div class="col-4">
|
||||
<button type="button" class="btn btn-outline-primary w-100 py-3 numpad-key" data-key="{{ $key }}">{{ $key }}</button>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary btn-lg">Bayar</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-5">
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Maklumat Pembayar</h3>
|
||||
<div class="mb-2"><strong>Nama Pembayar:</strong> {{ auth()->user()->displayName() }}</div>
|
||||
<div class="mb-2"><strong>Emel:</strong> {{ auth()->user()->email }}</div>
|
||||
<div class="mb-2"><strong>No. Telefon:</strong> {{ auth()->user()->profile?->country_code }} {{ auth()->user()->profile?->mobile_no }}</div>
|
||||
<div class="mb-2"><strong>Jumlah Amaun:</strong> RM {{ number_format((float) $defaultAmount, 2) }}</div>
|
||||
<hr>
|
||||
<div class="text-muted small">Klik nombor pada pad untuk mengemaskini amaun bayaran. Untuk demo, status bayaran akan direkodkan sebagai <strong>success</strong>.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('styles')
|
||||
<script>
|
||||
$(function () {
|
||||
$('.numpad-key').on('click', function () {
|
||||
const key = $(this).data('key').toString();
|
||||
const $input = $('#amount-display');
|
||||
|
||||
if (key === 'C') {
|
||||
$input.val('');
|
||||
return;
|
||||
}
|
||||
|
||||
$input.val(($input.val() ?? '') + key);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
73
src/resources/views/portal/profile.blade.php
Normal file
73
src/resources/views/portal/profile.blade.php
Normal file
@@ -0,0 +1,73 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Profil Pengguna')
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4 p-lg-5">
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<div>
|
||||
<h2 class="h4 fw-bold mb-1">Pendaftaran Maklumat Pengguna Awam</h2>
|
||||
<p class="text-muted mb-0">Lengkapkan maklumat pemohon sebelum membuat permohonan ansuran.</p>
|
||||
</div>
|
||||
</div>
|
||||
<form method="POST" action="{{ route('portal.profile.update') }}" class="row g-3">
|
||||
@csrf
|
||||
@method('PUT')
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Nama Pengguna Awam</label>
|
||||
<input type="text" name="name" class="form-control" value="{{ old('name', $user->name) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Emel</label>
|
||||
<input type="email" name="email" class="form-control" value="{{ old('email', $user->email) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Nama Paparan</label>
|
||||
<input type="text" name="public_name" class="form-control" value="{{ old('public_name', $user->profile?->public_name) }}" required>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Identification Type</label>
|
||||
<select name="identification_type" class="form-select" required>
|
||||
@foreach (['Army/Police ID', 'MyKad', 'National ID'] as $type)
|
||||
<option value="{{ $type }}" @selected(old('identification_type', $user->profile?->identification_type) === $type)>{{ $type }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Identification Number</label>
|
||||
<input type="text" name="identification_number" class="form-control" value="{{ old('identification_number', $user->profile?->identification_number) }}" required>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Kod Negara</label>
|
||||
<select name="country_code" class="form-select">
|
||||
@foreach (['+60', '+65', '+62'] as $code)
|
||||
<option value="{{ $code }}" @selected(old('country_code', $user->profile?->country_code ?? '+60') === $code)>{{ $code }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Mobile No</label>
|
||||
<input type="text" name="mobile_no" class="form-control" value="{{ old('mobile_no', $user->profile?->mobile_no) }}" required>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Pekerjaan</label>
|
||||
<input type="text" name="occupation" class="form-control" value="{{ old('occupation', $user->profile?->occupation) }}">
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Pendapatan Sebulan</label>
|
||||
<input type="number" step="0.01" name="monthly_income" class="form-control" value="{{ old('monthly_income', $user->profile?->monthly_income) }}">
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Alamat Surat Menyurat</label>
|
||||
<textarea name="correspondence_address" class="form-control" rows="3" required>{{ old('correspondence_address', $user->profile?->correspondence_address) }}</textarea>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<label class="form-label">Alamat Tempat Bekerja</label>
|
||||
<textarea name="workplace_address" class="form-control" rows="3">{{ old('workplace_address', $user->profile?->workplace_address) }}</textarea>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button class="btn btn-primary">Simpan Profil</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endsection
|
||||
30
src/resources/views/portal/receipt.blade.php
Normal file
30
src/resources/views/portal/receipt.blade.php
Normal file
@@ -0,0 +1,30 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Resit Pembayaran')
|
||||
|
||||
@section('content')
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-lg-8">
|
||||
<div class="card surface-card p-4 p-lg-5">
|
||||
<div class="text-center mb-4">
|
||||
<div class="stat-icon mx-auto mb-3"><i class="bi bi-receipt-cutoff fs-3"></i></div>
|
||||
<h2 class="fw-bold">Resit Pembayaran Dummy JomPAY</h2>
|
||||
<p class="text-muted mb-0">Sila simpan salinan ini untuk tujuan demo dan semakan dalaman.</p>
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6"><strong>No. Resit</strong><br>{{ $payment->receipt_no }}</div>
|
||||
<div class="col-md-6"><strong>No. Transaksi</strong><br>{{ $payment->transaction_no }}</div>
|
||||
<div class="col-md-6"><strong>Pembayar</strong><br>{{ $payment->user->displayName() }}</div>
|
||||
<div class="col-md-6"><strong>Status</strong><br>@include('components.status-badge', ['status' => $payment->status])</div>
|
||||
<div class="col-md-6"><strong>Akaun</strong><br>{{ $payment->application->no_akaun }}</div>
|
||||
<div class="col-md-6"><strong>REF 2</strong><br>{{ $payment->ref_2 }}</div>
|
||||
<div class="col-12"><strong>Jumlah Bayaran</strong><br><span class="display-6 fw-bold text-success">RM {{ number_format((float) $payment->amount, 2) }}</span></div>
|
||||
</div>
|
||||
<div class="mt-4 d-flex flex-wrap gap-2">
|
||||
<a href="{{ route('portal.applications.show', $payment->application) }}" class="btn btn-primary">Kembali ke Permohonan</a>
|
||||
<button class="btn btn-outline-secondary" onclick="window.print()">Cetak Resit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
141
src/resources/views/print/application.blade.php
Normal file
141
src/resources/views/print/application.blade.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="ms">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Borang Permohonan Ansuran</title>
|
||||
<style>
|
||||
body { font-family: Arial, sans-serif; color: #1c2f3f; margin: 28px; }
|
||||
h1, h2, h3 { margin-bottom: 8px; }
|
||||
.muted { color: #5b7083; }
|
||||
.section { margin-top: 26px; }
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 12px; }
|
||||
th, td { border: 1px solid #b8c7d3; padding: 8px; text-align: left; vertical-align: top; }
|
||||
.two-col { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px 24px; }
|
||||
.signature { margin-top: 36px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
|
||||
.signature div { border-top: 1px solid #333; padding-top: 8px; }
|
||||
@media print { .no-print { display: none; } body { margin: 0.5cm; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="no-print" style="text-align:right; margin-bottom:16px;">
|
||||
<button onclick="window.print()">Cetak</button>
|
||||
</div>
|
||||
<h1>BORANG PERMOHONAN BAYARAN CUKAI HARTA SECARA ANSURAN</h1>
|
||||
<div class="muted">No Permohonan: {{ $application->application_no }} | Tarikh: {{ $application->created_at->format('d/m/Y h:i A') }}</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Maklumat Akaun</h3>
|
||||
<table>
|
||||
<tr><th>No Akaun</th><td>{{ $application->no_akaun }}</td><th>No Akaun Tunggakan</th><td>{{ $application->no_akaun_tunggakan }}</td></tr>
|
||||
<tr><th>Pemilik</th><td>{{ $application->propertyAccount?->pemilik }}</td><th>Taman</th><td>{{ $application->propertyAccount?->taman }}</td></tr>
|
||||
<tr><th>Rupacara</th><td>{{ $application->propertyAccount?->rupacara }}</td><th>Kadar</th><td>{{ $application->propertyAccount?->kadar }}</td></tr>
|
||||
<tr><th>No Lot</th><td>{{ $application->no_lot ?: '-' }}</td><th>No DHM</th><td>{{ $application->no_dhm ?: '-' }}</td></tr>
|
||||
<tr><th>No Syarikat</th><td>{{ $application->no_syarikat ?: '-' }}</td><th>Alamat Harta</th><td>{{ $application->alamat_harta ?: '-' }}</td></tr>
|
||||
<tr><th>Tunggakan</th><td>RM {{ number_format((float) $application->total_arrears, 2) }}</td><th>Kategori Harta</th><td>{{ $application->category }}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>MAKLUMAT PEMOHON</h3>
|
||||
<div class="two-col">
|
||||
<div><strong>Nama:</strong> {{ $application->user->displayName() }}</div>
|
||||
<div><strong>No. Kad Pengenalan / ID:</strong> {{ $application->identification_type }} - {{ $application->identification_number }}</div>
|
||||
<div><strong>No. Telefon:</strong> {{ $application->country_code }} {{ $application->mobile_no }}</div>
|
||||
<div><strong>Emel:</strong> {{ $application->email }}</div>
|
||||
<div><strong>Alamat Surat Menyurat:</strong> {{ $application->alamat_surat_menyurat }}</div>
|
||||
<div><strong>Alamat Harta:</strong> {{ $application->alamat_harta }}</div>
|
||||
<div><strong>Alamat Tempat Bekerja:</strong> {{ $application->alamat_tempat_bekerja ?: '-' }}</div>
|
||||
<div><strong>Pekerjaan:</strong> {{ $application->pekerjaan ?: '-' }}</div>
|
||||
<div><strong>Pendapatan Sebulan:</strong> {{ $application->pendapatan_sebulan ? 'RM '.number_format((float) $application->pendapatan_sebulan, 2) : '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Maklumat Permohonan</h3>
|
||||
<table>
|
||||
<tr><th>Tarikh Permohonan</th><td>{{ $application->created_at->format('d/m/Y') }}</td><th>Tempoh Ansuran</th><td>{{ $application->installment_months }} bulan</td></tr>
|
||||
<tr><th>Status Permohonan</th><td>{{ ucfirst($application->status) }}</td><th>Pegawai Penyemak</th><td>{{ $application->reviewer?->displayName() ?: 'Belum disahkan' }}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Jadual Ansuran Manual</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Ansuran Ke-</th>
|
||||
<th>Tarikh Bayaran</th>
|
||||
<th>Amaun</th>
|
||||
<th>Status Bayaran</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($application->schedules as $schedule)
|
||||
<tr>
|
||||
<td>{{ $schedule->installment_no }}</td>
|
||||
<td>{{ optional($schedule->due_date)->format('d/m/Y') }}</td>
|
||||
<td>RM {{ number_format((float) $schedule->amount, 2) }}</td>
|
||||
<td>{{ ucfirst(str_replace('_', ' ', $schedule->payment_status)) }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="4">Tiada jadual ansuran direkodkan.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Rekod Pembayaran</h3>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tarikh Bayaran</th>
|
||||
<th>No Resit</th>
|
||||
<th>No Transaksi</th>
|
||||
<th>Ansuran Ke-</th>
|
||||
<th>REF 1</th>
|
||||
<th>REF 2</th>
|
||||
<th>Amaun</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($application->payments->sortByDesc(fn ($payment) => $payment->paid_at ?? $payment->created_at) as $payment)
|
||||
<tr>
|
||||
<td>{{ optional($payment->paid_at)->format('d/m/Y h:i A') ?: $payment->created_at->format('d/m/Y h:i A') }}</td>
|
||||
<td>{{ $payment->receipt_no ?: '-' }}</td>
|
||||
<td>{{ $payment->transaction_no ?: '-' }}</td>
|
||||
<td>{{ $payment->schedule?->installment_no ? 'Ansuran '.$payment->schedule->installment_no : '-' }}</td>
|
||||
<td>{{ $payment->ref_1 ?: '-' }}</td>
|
||||
<td>{{ $payment->ref_2 ?: '-' }}</td>
|
||||
<td>RM {{ number_format((float) $payment->amount, 2) }}</td>
|
||||
<td>{{ $payment->status === 'success' ? 'Berjaya' : ucfirst($payment->status) }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="8">Tiada rekod pembayaran direkodkan setakat ini.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>Perakuan Pemohon</h3>
|
||||
<p>“Saya yang bertandatangan dibawah bersetuju dan berjanji akan menjelaskan bayaran cukai harta mengikut jadual ansuran yang telah diluluskan sebagaimana di bawah. Sekiranya saya gagal maka pihak Majlis Bandaraya Iskandar Puteri berhak membatalkan permohonan ini dan mengambil TINDAKAN SITAAN / UNDANG-UNDANG ke atas SAYA / PREMIS tanpa apa-apa notis lagi.”</p>
|
||||
<table>
|
||||
<tr><th>Nama</th><td>{{ $application->declaration_name }}</td><th>Tarikh</th><td>{{ $application->declaration_date->format('d/m/Y') }}</td></tr>
|
||||
<tr><th>No ID</th><td>{{ $application->declaration_identification_type }} - {{ $application->declaration_identification_number }}</td><th>Status Tick</th><td>{{ $application->declaration_accepted ? 'Ditanda' : 'Tidak Ditanda' }}</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
<h3>ULASAN STAFF / PEGAWAI PENYEMAK</h3>
|
||||
<p>{{ $application->staff_remarks ?: 'Tiada ulasan direkodkan.' }}</p>
|
||||
</div>
|
||||
|
||||
<div class="signature">
|
||||
<div>Tandatangan Pemohon</div>
|
||||
<div>Tandatangan Staff / Pegawai Penyemak</div>
|
||||
<div>Tarikh</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
77
src/resources/views/shared/import-excel.blade.php
Normal file
77
src/resources/views/shared/import-excel.blade.php
Normal file
@@ -0,0 +1,77 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', $pageTitle)
|
||||
@section('page-title', $pageTitle)
|
||||
@section('page-label', 'Import Excel')
|
||||
|
||||
@section('page-actions')
|
||||
<a href="{{ route('import.template', ['type' => $importType]) }}" class="btn btn-outline-primary">Download Template Excel</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-5">
|
||||
<div class="card surface-card p-4">
|
||||
<h2 class="h5 fw-bold mb-3">Muat Naik dan Proses Fail</h2>
|
||||
<p class="text-muted">{{ $description }}</p>
|
||||
<div class="alert alert-info">
|
||||
@if ($importType === 'tax')
|
||||
Import ini hanya untuk <strong>Admin</strong> dan digunakan sebagai data cukai harta. Kolum penting: <strong>No_Bgnn</strong>, <strong>Nama_Jalan</strong>, <strong>Kadar</strong>, <strong>Cukai_Harta</strong>.
|
||||
@else
|
||||
Import ini digunakan oleh <strong>Staff</strong> untuk data tunggakan. Format tunggakan sedia ada dikekalkan.
|
||||
@endif
|
||||
</div>
|
||||
<p class="text-muted">Format dibenarkan: <strong>xlsx</strong>, <strong>xls</strong> atau <strong>csv</strong>.</p>
|
||||
<form method="POST" action="{{ route($prefix.'.import.store') }}" enctype="multipart/form-data" class="d-grid gap-3">
|
||||
@csrf
|
||||
<div>
|
||||
<label class="form-label">Pilih Fail Excel</label>
|
||||
<input type="file" name="file" class="form-control" required>
|
||||
</div>
|
||||
<button class="btn btn-primary">Muat Naik dan Proses</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-lg-7">
|
||||
<div class="card surface-card p-4">
|
||||
<h2 class="h5 fw-bold mb-3">Sejarah Import</h2>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Batch</th>
|
||||
<th>Jenis</th>
|
||||
<th>Fail</th>
|
||||
<th>Diproses</th>
|
||||
<th>Baharu</th>
|
||||
<th>Dikemaskini</th>
|
||||
<th>Tiada Dalam Import</th>
|
||||
<th>Gagal</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($batches as $batch)
|
||||
<tr>
|
||||
<td>#{{ $batch->id }}</td>
|
||||
<td>{{ $batch->import_type === 'tax' ? 'Cukai Harta' : 'Tunggakan' }}</td>
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $batch->filename }}</div>
|
||||
<div class="text-muted small">{{ $batch->created_at->format('d/m/Y h:i A') }}</div>
|
||||
</td>
|
||||
<td>{{ $batch->total_processed }}</td>
|
||||
<td>{{ $batch->total_new }}</td>
|
||||
<td>{{ $batch->total_updated }}</td>
|
||||
<td>{{ $batch->total_missing }}</td>
|
||||
<td>{{ $batch->total_failed }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="8" class="text-center text-muted py-4">Belum ada sejarah import.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $batches->links() }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
12
src/resources/views/shared/page-header.blade.php
Normal file
12
src/resources/views/shared/page-header.blade.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<div class="d-flex flex-wrap align-items-center justify-content-between gap-3 mb-4">
|
||||
<div>
|
||||
<div class="mini-label">{{ $label ?? 'Maklumat Modul' }}</div>
|
||||
<h2 class="h3 fw-bold mb-1">{{ $title }}</h2>
|
||||
@if (! empty($subtitle))
|
||||
<p class="text-muted mb-0">{{ $subtitle }}</p>
|
||||
@endif
|
||||
</div>
|
||||
@if (! empty($actions ?? null))
|
||||
<div>{!! $actions !!}</div>
|
||||
@endif
|
||||
</div>
|
||||
396
src/resources/views/staff/application-show.blade.php
Normal file
396
src/resources/views/staff/application-show.blade.php
Normal file
@@ -0,0 +1,396 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Semakan Permohonan Staff')
|
||||
@section('page-title', 'Semakan Permohonan')
|
||||
@section('page-label', 'Butiran Permohonan')
|
||||
|
||||
@section('page-actions')
|
||||
<a href="{{ route('staff.applications.print', $application) }}" class="btn btn-outline-secondary" target="_blank">Print Borang</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
@php
|
||||
$propertyTax = (float) ($application->propertyAccount?->cukai_harta ?? 0);
|
||||
$propertyTaxHalf = $application->property_tax_half_amount !== null ? (float) $application->property_tax_half_amount : $propertyTax / 2;
|
||||
$installmentTarget = (float) $application->total_arrears + $propertyTaxHalf;
|
||||
@endphp
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-7">
|
||||
<div class="card surface-card p-4 mb-4">
|
||||
<div class="d-flex justify-content-between align-items-start mb-3">
|
||||
<div>
|
||||
<div class="mini-label">No Permohonan</div>
|
||||
<h2 class="h4 fw-bold mb-1">{{ $application->application_no }}</h2>
|
||||
<p class="text-muted mb-0">Dihantar pada {{ $application->created_at->format('d/m/Y h:i A') }}</p>
|
||||
</div>
|
||||
@include('components.status-badge', ['status' => $application->status])
|
||||
</div>
|
||||
<div class="alert alert-info">
|
||||
Panduan bayaran pertama minimum bagi kategori <strong>{{ $application->category }}</strong>:
|
||||
<strong>{{ $guidance?->guidanceRate() ?? 0 }}%</strong>.
|
||||
Staff masih perlu memasukkan amaun ansuran secara manual.
|
||||
</div>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6"><strong>No Akaun:</strong><br>{{ $application->no_akaun }}</div>
|
||||
<div class="col-md-6"><strong>No Akaun Tunggakan:</strong><br>{{ $application->no_akaun_tunggakan }}</div>
|
||||
<div class="col-md-6"><strong>Kategori Harta:</strong><br>{{ $application->category }}</div>
|
||||
<div class="col-md-6"><strong>Tempoh Ansuran Dipilih:</strong><br>{{ $application->installment_months }} bulan</div>
|
||||
<div class="col-md-6"><strong>No Lot:</strong><br>{{ $application->no_lot ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>No DHM:</strong><br>{{ $application->no_dhm ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>No Syarikat:</strong><br>{{ $application->no_syarikat ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>Jumlah Tunggakan:</strong><br>RM <span id="arrears-total">{{ number_format((float) $application->total_arrears, 2, '.', '') }}</span></div>
|
||||
<div class="col-md-6"><strong>Cukai Harta:</strong><br>RM {{ number_format($propertyTax, 2) }}</div>
|
||||
<div class="col-md-6"><strong>Cukai Harta / 2:</strong><br>RM <span id="property-tax-half-display">{{ number_format($propertyTaxHalf, 2) }}</span></div>
|
||||
<div class="col-md-6"><strong>Jumlah Ansuran:</strong><br><span id="installment-target-display">RM {{ number_format($installmentTarget, 2) }}</span></div>
|
||||
<div class="col-md-6"><strong>Jumlah Jadual Semasa:</strong><br><span id="schedule-total">RM {{ number_format((float) $application->schedule_total, 2) }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4 mb-4">
|
||||
<h3 class="h5 fw-bold mb-3">Maklumat Pemohon</h3>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6"><strong>Nama Pemohon</strong><br>{{ $application->user->displayName() }}</div>
|
||||
<div class="col-md-6"><strong>Identification Type</strong><br>{{ $application->identification_type }}</div>
|
||||
<div class="col-md-6"><strong>Identification Number</strong><br>{{ $application->identification_number }}</div>
|
||||
<div class="col-md-6"><strong>No. Telefon / Contact Number</strong><br>{{ $application->country_code }} {{ $application->mobile_no }}</div>
|
||||
<div class="col-md-6"><strong>Emel</strong><br>{{ $application->email }}</div>
|
||||
<div class="col-md-6"><strong>Alamat Surat Menyurat</strong><br>{{ $application->alamat_surat_menyurat }}</div>
|
||||
<div class="col-md-6"><strong>Alamat Harta</strong><br>{{ $application->alamat_harta }}</div>
|
||||
<div class="col-md-6"><strong>Alamat Tempat Bekerja</strong><br>{{ $application->alamat_tempat_bekerja ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>Pekerjaan</strong><br>{{ $application->pekerjaan ?: '-' }}</div>
|
||||
<div class="col-md-6"><strong>Pendapatan Sebulan</strong><br>{{ $application->pendapatan_sebulan ? 'RM '.number_format((float) $application->pendapatan_sebulan, 2) : '-' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4 mb-4">
|
||||
<h3 class="h5 fw-bold mb-3">Rekod Pembayaran</h3>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tarikh Bayaran</th>
|
||||
<th>No Resit</th>
|
||||
<th>No Transaksi</th>
|
||||
<th>Ansuran Ke-</th>
|
||||
<th>REF 1</th>
|
||||
<th>REF 2</th>
|
||||
<th>Amaun</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($application->payments->sortByDesc(fn ($payment) => $payment->paid_at ?? $payment->created_at) as $payment)
|
||||
<tr>
|
||||
<td>{{ optional($payment->paid_at)->format('d/m/Y h:i A') ?: $payment->created_at->format('d/m/Y h:i A') }}</td>
|
||||
<td>{{ $payment->receipt_no ?: '-' }}</td>
|
||||
<td>{{ $payment->transaction_no ?: '-' }}</td>
|
||||
<td>{{ $payment->schedule?->installment_no ? 'Ansuran '.$payment->schedule->installment_no : '-' }}</td>
|
||||
<td>{{ $payment->ref_1 ?: '-' }}</td>
|
||||
<td>{{ $payment->ref_2 ?: '-' }}</td>
|
||||
<td>RM {{ number_format((float) $payment->amount, 2) }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $payment->status])</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="8" class="text-center text-muted py-4">Tiada rekod pembayaran direkodkan setakat ini.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Maklumat Akaun & Sejarah</h3>
|
||||
<div class="row g-3 mb-4">
|
||||
<div class="col-md-6"><strong>Pemilik</strong><br>{{ $application->propertyAccount?->pemilik }}</div>
|
||||
<div class="col-md-6"><strong>Bandar / Taman</strong><br>{{ $application->propertyAccount?->bandar }} / {{ $application->propertyAccount?->taman }}</div>
|
||||
<div class="col-md-6"><strong>Rupacara</strong><br>{{ $application->propertyAccount?->rupacara }}</div>
|
||||
<div class="col-md-6"><strong>Kadar</strong><br>{{ $application->propertyAccount?->kadar }}</div>
|
||||
<div class="col-md-6"><strong>Cukai Harta</strong><br>RM {{ number_format($propertyTax, 2) }}</div>
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Tindakan</th>
|
||||
<th>Status Lama</th>
|
||||
<th>Status Baharu</th>
|
||||
<th>Ulasan</th>
|
||||
<th>Tarikh</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($application->histories as $history)
|
||||
<tr>
|
||||
<td>{{ str($history->action)->replace('_', ' ')->headline() }}</td>
|
||||
<td>{{ $history->old_status ?: '-' }}</td>
|
||||
<td>{{ $history->new_status ?: '-' }}</td>
|
||||
<td>{{ $history->remarks ?: '-' }}</td>
|
||||
<td>{{ $history->created_at->format('d/m/Y h:i A') }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="5" class="text-center text-muted">Belum ada sejarah tindakan.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-5">
|
||||
@php($recordableSchedules = $application->schedules->whereIn('payment_status', ['belum_bayar', 'lewat'])->sortBy('installment_no')->values())
|
||||
<div class="card surface-card p-4">
|
||||
<h3 class="h5 fw-bold mb-3">Input Manual Ansuran Oleh Staff</h3>
|
||||
<form method="POST" action="{{ route('staff.applications.review', $application) }}" class="d-grid gap-3">
|
||||
@csrf
|
||||
@if ($errors->has('schedules') || $errors->has('staff_remarks'))
|
||||
<div class="alert alert-danger mb-0">
|
||||
Sila semak semula input ansuran manual dan ulasan staff sebelum simpan.
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Jumlah Tunggakan</label>
|
||||
<input type="number" step="0.01" min="0" name="total_arrears" id="staff-total-arrears" class="form-control" value="{{ old('total_arrears', number_format((float) $application->total_arrears, 2, '.', '')) }}">
|
||||
@error('total_arrears')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Cukai Harta / 2</label>
|
||||
<input type="number" step="0.01" min="0" name="property_tax_half_amount" id="property-tax-half" class="form-control" value="{{ old('property_tax_half_amount', number_format($propertyTaxHalf, 2, '.', '')) }}">
|
||||
@error('property_tax_half_amount')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
<div class="form-text">Autofill daripada Cukai Harta / 2, tetapi staff boleh ubah jika perlu.</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="alert alert-info mb-0">
|
||||
Jumlah Ansuran = Jumlah Tunggakan + (Cukai Harta / 2)
|
||||
<br>
|
||||
Jumlah Ansuran semasa: <strong id="formula-target">RM {{ number_format($installmentTarget, 2) }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th style="width: 20%;">Ansuran</th>
|
||||
<th style="width: 22%;">Tarikh Bayaran</th>
|
||||
<th style="width: 22%;">Amaun Ansuran</th>
|
||||
<th>Catatan</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($scheduleRows as $index => $row)
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $index === 0 ? 'Bayaran Pertama' : 'Bayaran Bulan Ke-'.($index + 1) }}</div>
|
||||
<div class="small text-muted">Ansuran {{ $row['installment_no'] }}</div>
|
||||
</td>
|
||||
<td>
|
||||
<input type="date" name="schedules[{{ $index }}][due_date]" class="form-control" value="{{ old("schedules.$index.due_date", $row['due_date']) }}">
|
||||
</td>
|
||||
<td>
|
||||
<input type="number" step="0.01" name="schedules[{{ $index }}][amount]" class="form-control schedule-amount" value="{{ old("schedules.$index.amount", $row['amount']) }}" placeholder="0.00">
|
||||
</td>
|
||||
<td>
|
||||
<input type="text" name="schedules[{{ $index }}][notes]" class="form-control" value="{{ old("schedules.$index.notes", $row['notes']) }}" placeholder="Catatan ansuran">
|
||||
</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-secondary mb-0" id="schedule-warning">
|
||||
Jumlah ansuran semasa: <strong id="running-total">RM 0.00</strong>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="form-label">Ulasan Staff / Pegawai Penyemak</label>
|
||||
<textarea name="staff_remarks" class="form-control" rows="4">{{ old('staff_remarks', $application->staff_remarks) }}</textarea>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="form-label">Tindakan Staff</label>
|
||||
@php($selectedAction = old('action', $application->status === 'diproses' ? 'processing' : ($application->status === 'aktif' ? 'active' : 'none')))
|
||||
<select name="action" class="form-select">
|
||||
<option value="processing" @selected($selectedAction === 'processing')>Akaun Diproses</option>
|
||||
<option value="active" @selected($selectedAction === 'active')>Akaun Aktif (permohonan diterima)</option>
|
||||
<option value="cancel" @selected($selectedAction === 'cancel')>Akaun Batal</option>
|
||||
<option value="failed" @selected($selectedAction === 'failed')>Akaun Gagal</option>
|
||||
<option value="complete" @selected($selectedAction === 'complete')>Akaun Selesai</option>
|
||||
<option value="none" @selected($selectedAction === 'none')>Tiada Tindakan</option>
|
||||
</select>
|
||||
@error('action')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-lg">Simpan Semakan Staff</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4 mt-4">
|
||||
<h3 class="h5 fw-bold mb-3">Rekod Bayaran Manual</h3>
|
||||
<p class="text-muted small mb-3">Digunakan apabila bayaran diterima secara manual tanpa integrasi API. Staff perlu key-in nombor resit untuk tujuan rekod database.</p>
|
||||
|
||||
@error('manual_payment')
|
||||
<div class="alert alert-danger">{{ $message }}</div>
|
||||
@enderror
|
||||
|
||||
@if ($application->status !== 'aktif')
|
||||
<div class="alert alert-warning mb-0">
|
||||
Rekod bayaran manual hanya dibenarkan selepas staff mengesahkan akaun sebagai <strong>aktif</strong>.
|
||||
</div>
|
||||
@elseif ($recordableSchedules->isEmpty())
|
||||
<div class="alert alert-success mb-0">
|
||||
Semua ansuran untuk akaun ini telah direkodkan sebagai dibayar.
|
||||
</div>
|
||||
@else
|
||||
<form method="POST" action="{{ route('staff.applications.payments.store', $application) }}" class="d-grid gap-3">
|
||||
@csrf
|
||||
<div>
|
||||
<label class="form-label">Ansuran Untuk Direkodkan</label>
|
||||
<select name="installment_schedule_id" class="form-select" required>
|
||||
<option value="">Pilih ansuran</option>
|
||||
@foreach ($recordableSchedules as $schedule)
|
||||
<option value="{{ $schedule->id }}" data-amount="{{ number_format((float) $schedule->amount, 2, '.', '') }}" @selected(old('installment_schedule_id') == $schedule->id)>
|
||||
Ansuran {{ $schedule->installment_no }} | {{ optional($schedule->due_date)->format('d/m/Y') ?: 'Tiada tarikh' }} | RM {{ number_format((float) $schedule->amount, 2) }}
|
||||
</option>
|
||||
@endforeach
|
||||
</select>
|
||||
@error('installment_schedule_id')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">No. Resit</label>
|
||||
<input type="text" name="receipt_no" class="form-control" value="{{ old('receipt_no') }}" placeholder="Contoh: MBIP-2026-0001" required>
|
||||
@error('receipt_no')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">No. Transaksi</label>
|
||||
<input type="text" name="transaction_no" class="form-control" value="{{ old('transaction_no') }}" placeholder="Pilihan, sistem akan jana jika kosong">
|
||||
@error('transaction_no')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Amaun Bayaran</label>
|
||||
<input type="number" step="0.01" name="amount" id="manual-payment-amount" class="form-control" value="{{ old('amount') }}" placeholder="0.00" required>
|
||||
@error('amount')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<label class="form-label">Tarikh Bayaran</label>
|
||||
<input type="datetime-local" name="paid_at" class="form-control" value="{{ old('paid_at', now()->format('Y-m-d\TH:i')) }}" required>
|
||||
@error('paid_at')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="form-label">Catatan Bayaran Manual</label>
|
||||
<textarea name="remarks" class="form-control" rows="3" placeholder="Contoh: Bayaran kaunter / EFT / pindahan dalaman">{{ old('remarks') }}</textarea>
|
||||
@error('remarks')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<div class="small text-muted">
|
||||
REF 1 akan menggunakan <strong>{{ $application->no_akaun }}</strong> dan REF 2 akan menggunakan emel atau nombor telefon pemohon secara automatik.
|
||||
</div>
|
||||
|
||||
<button class="btn btn-outline-primary">Simpan Bayaran Manual</button>
|
||||
</form>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('styles')
|
||||
<script>
|
||||
$(function () {
|
||||
const propertyTaxHalfInput = $('#property-tax-half');
|
||||
const arrearsInput = $('#staff-total-arrears');
|
||||
const manualScheduleSelect = $('select[name="installment_schedule_id"]');
|
||||
const manualAmountInput = $('#manual-payment-amount');
|
||||
|
||||
function parseAmount(value) {
|
||||
return parseFloat(String(value || '0').replace(/[^0-9.-]/g, '')) || 0;
|
||||
}
|
||||
|
||||
function targetTotal() {
|
||||
const arrears = parseAmount(arrearsInput.val() || $('#arrears-total').text());
|
||||
const propertyTaxHalf = parseAmount(propertyTaxHalfInput.val());
|
||||
const target = arrears + propertyTaxHalf;
|
||||
|
||||
$('#arrears-total').text(arrears.toFixed(2));
|
||||
$('#property-tax-half-display').text(propertyTaxHalf.toFixed(2));
|
||||
$('#formula-target, #installment-target-display').text('RM ' + target.toFixed(2));
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
function adjustArrearsForPropertyTaxChange() {
|
||||
const currentTarget = parseAmount($('#formula-target').text()) || targetTotal();
|
||||
const propertyTaxHalf = parseAmount(propertyTaxHalfInput.val());
|
||||
const adjustedArrears = Math.max(currentTarget - propertyTaxHalf, 0);
|
||||
|
||||
arrearsInput.val(adjustedArrears.toFixed(2));
|
||||
recalcTotal();
|
||||
}
|
||||
|
||||
function recalcTotal() {
|
||||
let total = 0;
|
||||
$('.schedule-amount').each(function () {
|
||||
total += parseAmount($(this).val());
|
||||
});
|
||||
|
||||
const target = targetTotal();
|
||||
|
||||
$('#running-total').text('RM ' + total.toFixed(2));
|
||||
$('#schedule-total').text('RM ' + total.toFixed(2));
|
||||
|
||||
if (Math.abs(total - target) > 0.009) {
|
||||
$('#schedule-warning').removeClass('alert-success').addClass('alert-warning')
|
||||
.html('Jumlah ansuran tidak sama dengan Jumlah Tunggakan + (Cukai Harta / 2). Sila semak semula amaun ansuran.');
|
||||
} else {
|
||||
$('#schedule-warning').removeClass('alert-warning').addClass('alert-success')
|
||||
.html('Jumlah ansuran sepadan dengan formula: <strong>RM ' + total.toFixed(2) + '</strong>');
|
||||
}
|
||||
}
|
||||
|
||||
function syncManualPaymentAmount() {
|
||||
if (!manualScheduleSelect.length || !manualAmountInput.length || manualAmountInput.val()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const amount = manualScheduleSelect.find(':selected').data('amount');
|
||||
|
||||
if (amount !== undefined) {
|
||||
manualAmountInput.val(amount);
|
||||
}
|
||||
}
|
||||
|
||||
$('.schedule-amount').on('input', recalcTotal);
|
||||
arrearsInput.on('input', recalcTotal);
|
||||
propertyTaxHalfInput.on('input', adjustArrearsForPropertyTaxChange);
|
||||
manualScheduleSelect.on('change', syncManualPaymentAmount);
|
||||
recalcTotal();
|
||||
syncManualPaymentAmount();
|
||||
});
|
||||
</script>
|
||||
@endpush
|
||||
76
src/resources/views/staff/applications-index.blade.php
Normal file
76
src/resources/views/staff/applications-index.blade.php
Normal file
@@ -0,0 +1,76 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Permohonan Staff')
|
||||
@section('page-title', 'Permohonan Ansuran')
|
||||
@section('page-label', 'Modul Staff')
|
||||
|
||||
@section('page-actions')
|
||||
<a href="{{ route('staff.applications.export') }}" class="btn btn-outline-primary">Eksport Excel</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="card surface-card p-4 mb-4">
|
||||
<div class="alert alert-secondary mb-4">
|
||||
Hanya akaun berstatus <strong>diproses</strong> dan <strong>aktif</strong> dipaparkan untuk semakan staff. Akaun <strong>batal</strong>, <strong>gagal</strong>, dan <strong>selesai</strong> kekal dalam sejarah, database, dan kemas kini Excel.
|
||||
</div>
|
||||
<form class="row g-3">
|
||||
<div class="col-md-4">
|
||||
<label class="form-label">Carian</label>
|
||||
<input type="text" name="search" class="form-control" value="{{ request('search') }}" placeholder="No permohonan / pemohon / akaun">
|
||||
</div>
|
||||
<div class="col-md-3">
|
||||
<label class="form-label">Status</label>
|
||||
<select name="status" class="form-select">
|
||||
<option value="">Diproses + Aktif</option>
|
||||
@foreach ($allowedStatuses as $status)
|
||||
<option value="{{ $status }}" @selected(request('status') === $status)>{{ ucfirst($status) }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Dari Tarikh</label>
|
||||
<input type="date" name="date_from" class="form-control" value="{{ request('date_from') }}">
|
||||
</div>
|
||||
<div class="col-md-2">
|
||||
<label class="form-label">Hingga Tarikh</label>
|
||||
<input type="date" name="date_to" class="form-control" value="{{ request('date_to') }}">
|
||||
</div>
|
||||
<div class="col-md-1 d-flex align-items-end">
|
||||
<button class="btn btn-primary w-100">Tapis</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="card surface-card p-4">
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Permohonan</th>
|
||||
<th>Pemohon</th>
|
||||
<th>No Akaun Tunggakan</th>
|
||||
<th>Kategori</th>
|
||||
<th>Tempoh</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($applications as $application)
|
||||
<tr>
|
||||
<td>{{ $application->application_no }}</td>
|
||||
<td>{{ $application->user->displayName() }}</td>
|
||||
<td>{{ $application->no_akaun_tunggakan }}</td>
|
||||
<td>{{ $application->category }}</td>
|
||||
<td>{{ $application->installment_months }} bulan</td>
|
||||
<td>@include('components.status-badge', ['status' => $application->status])</td>
|
||||
<td class="text-end"><a href="{{ route('staff.applications.show', $application) }}" class="btn btn-outline-secondary btn-sm">Semak Detail</a></td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="7" class="text-center text-muted py-4">Tiada rekod ditemui.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="mt-3">{{ $applications->links() }}</div>
|
||||
</div>
|
||||
@endsection
|
||||
183
src/resources/views/staff/bulk-payments-index.blade.php
Normal file
183
src/resources/views/staff/bulk-payments-index.blade.php
Normal file
@@ -0,0 +1,183 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Kemaskini Bayaran Pukal')
|
||||
@section('page-title', 'Kemaskini Bayaran Pukal')
|
||||
@section('page-label', 'Modul Staff')
|
||||
|
||||
@section('page-actions')
|
||||
<a href="{{ route('staff.bulk-payments.template') }}" class="btn btn-outline-primary">
|
||||
<i class="bi bi-download me-1"></i> Download Template Excel
|
||||
</a>
|
||||
@endsection
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-md-4">
|
||||
<div class="card stat-card p-4 h-100">
|
||||
<div class="stat-icon mb-3"><i class="bi bi-person-check-fill"></i></div>
|
||||
<div class="mini-label">Akaun Aktif</div>
|
||||
<div class="h3 fw-bold mb-0">{{ $activeAccountCount }}</div>
|
||||
<div class="text-muted small">Akaun ansuran yang sedang aktif.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card stat-card p-4 h-100">
|
||||
<div class="stat-icon mb-3"><i class="bi bi-list-check"></i></div>
|
||||
<div class="mini-label">Ansuran Dalam Excel</div>
|
||||
<div class="h3 fw-bold mb-0">{{ $activeSchedules->count() }}</div>
|
||||
<div class="text-muted small">{{ $unpaidScheduleCount }} belum bayar, {{ $paidScheduleCount }} sudah dibayar.</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="card stat-card p-4 h-100">
|
||||
<div class="stat-icon mb-3"><i class="bi bi-cash-coin"></i></div>
|
||||
<div class="mini-label">Jumlah Belum Direkod</div>
|
||||
<div class="h3 fw-bold mb-0">RM {{ number_format($totalUnpaidAmount, 2) }}</div>
|
||||
<div class="text-muted small">Jumlah ansuran aktif yang belum dibayar.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4">
|
||||
<div class="col-lg-5">
|
||||
<div class="card surface-card p-4 h-100">
|
||||
<h2 class="h5 fw-bold mb-3">Upload Excel/CSV Bayaran</h2>
|
||||
<p class="text-muted">
|
||||
Gunakan template daripada sistem supaya setiap baris mempunyai <strong>Installment_Schedule_ID</strong>,
|
||||
<strong>No_Akaun</strong> dan <strong>Ansuran_Ke</strong>. Staff hanya perlu isi No_Resit, Tarikh_Bayaran,
|
||||
Amaun_Bayaran dan catatan jika perlu. Baris yang sudah dibayar akan membawa transaksi sedia ada untuk semakan atau kemaskini.
|
||||
</p>
|
||||
|
||||
<div class="alert alert-info small">
|
||||
Hanya akaun berstatus <strong>aktif</strong> akan diproses. Ansuran <strong>belum bayar/lewat</strong>
|
||||
akan direkodkan sebagai bayaran baharu, manakala ansuran <strong>dibayar</strong> akan mengemaskini
|
||||
transaksi bayaran sedia ada dalam database.
|
||||
</div>
|
||||
|
||||
<form method="POST" action="{{ route('staff.bulk-payments.store') }}" enctype="multipart/form-data" class="d-grid gap-3">
|
||||
@csrf
|
||||
<div>
|
||||
<label class="form-label">Fail Bayaran Pukal</label>
|
||||
<input type="file" name="file" class="form-control" accept=".xlsx,.xls,.csv" required>
|
||||
@error('file')
|
||||
<div class="text-danger small mt-1">{{ $message }}</div>
|
||||
@enderror
|
||||
</div>
|
||||
|
||||
<button class="btn btn-primary btn-lg">
|
||||
<i class="bi bi-upload me-1"></i> Muat Naik & Kemaskini Bayaran
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-lg-7">
|
||||
<div class="card surface-card p-4 h-100">
|
||||
<h2 class="h5 fw-bold mb-3">Ringkasan Proses Terakhir</h2>
|
||||
|
||||
@if ($importResult)
|
||||
<div class="row g-3 mb-3">
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="border rounded-4 p-3">
|
||||
<div class="mini-label">Diproses</div>
|
||||
<div class="h4 fw-bold mb-0">{{ $importResult['processed'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="border rounded-4 p-3">
|
||||
<div class="mini-label">Berjaya</div>
|
||||
<div class="h4 fw-bold text-success mb-0">{{ $importResult['success'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="border rounded-4 p-3">
|
||||
<div class="mini-label">Gagal</div>
|
||||
<div class="h4 fw-bold text-danger mb-0">{{ $importResult['failed'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 col-md-3">
|
||||
<div class="border rounded-4 p-3">
|
||||
<div class="mini-label">Diabaikan</div>
|
||||
<div class="h4 fw-bold text-muted mb-0">{{ $importResult['skipped'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (! empty($importResult['errors']))
|
||||
<div class="alert alert-warning mb-0">
|
||||
<div class="fw-semibold mb-2">Ralat yang perlu disemak</div>
|
||||
<ul class="mb-0 ps-3">
|
||||
@foreach ($importResult['errors'] as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@else
|
||||
<div class="alert alert-success mb-0">
|
||||
Semua baris bayaran yang lengkap berjaya dikemaskini.
|
||||
</div>
|
||||
@endif
|
||||
@else
|
||||
<div class="text-muted">
|
||||
Belum ada proses upload bayaran pukal dalam sesi ini.
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4 mt-4">
|
||||
<div class="d-flex flex-wrap justify-content-between align-items-center gap-3 mb-3">
|
||||
<div>
|
||||
<h2 class="h5 fw-bold mb-1">Senarai Ansuran Aktif Untuk Template</h2>
|
||||
<div class="text-muted small">Paparan ini menunjukkan ansuran akaun aktif termasuk transaksi yang sudah dibayar.</div>
|
||||
</div>
|
||||
<a href="{{ route('staff.bulk-payments.template') }}" class="btn btn-outline-primary">
|
||||
Download Template
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Akaun</th>
|
||||
<th>No Permohonan</th>
|
||||
<th>Pemohon</th>
|
||||
<th>Ansuran</th>
|
||||
<th>Tarikh Jadual</th>
|
||||
<th>Amaun</th>
|
||||
<th>Status</th>
|
||||
<th>No Resit</th>
|
||||
<th>No Transaksi</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@forelse ($activeSchedules as $schedule)
|
||||
@php($payment = $schedule->payments->sortByDesc(fn ($item) => $item->paid_at?->timestamp ?? $item->id)->first())
|
||||
<tr>
|
||||
<td>
|
||||
<div class="fw-semibold">{{ $schedule->application?->no_akaun }}</div>
|
||||
<div class="text-muted small">{{ $schedule->application?->no_akaun_tunggakan }}</div>
|
||||
</td>
|
||||
<td>{{ $schedule->application?->application_no }}</td>
|
||||
<td>{{ $schedule->application?->user?->displayName() }}</td>
|
||||
<td>Ansuran {{ $schedule->installment_no }}</td>
|
||||
<td>{{ optional($schedule->due_date)->format('d/m/Y') ?: '-' }}</td>
|
||||
<td>RM {{ number_format((float) $schedule->amount, 2) }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $schedule->payment_status])</td>
|
||||
<td>{{ $payment?->receipt_no ?: '-' }}</td>
|
||||
<td>{{ $payment?->transaction_no ?: '-' }}</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td colspan="9" class="text-center text-muted py-4">
|
||||
Tiada ansuran akaun aktif setakat ini.
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
62
src/resources/views/staff/dashboard.blade.php
Normal file
62
src/resources/views/staff/dashboard.blade.php
Normal file
@@ -0,0 +1,62 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Dashboard Staff')
|
||||
@section('page-title', 'Dashboard Staff')
|
||||
@section('page-label', 'Pengurusan Permohonan')
|
||||
|
||||
@section('content')
|
||||
<div class="row g-4 mb-4">
|
||||
@foreach ([
|
||||
['label' => 'Akaun Boleh Disemak', 'value' => $stats['reviewable'], 'icon' => 'bi-clipboard2-check'],
|
||||
['label' => 'Akaun Diproses', 'value' => $stats['processing'], 'icon' => 'bi-hourglass-top'],
|
||||
['label' => 'Akaun Aktif', 'value' => $stats['active'], 'icon' => 'bi-check2-circle'],
|
||||
['label' => 'Tugasan Belum Selesai', 'value' => $stats['pending_tasks'], 'icon' => 'bi-list-task'],
|
||||
] as $card)
|
||||
<div class="col-md-6 col-xl">
|
||||
<div class="card stat-card p-4 h-100">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div>
|
||||
<div class="mini-label">{{ $card['label'] }}</div>
|
||||
<div class="display-6 fw-bold">{{ $card['value'] }}</div>
|
||||
</div>
|
||||
<div class="stat-icon"><i class="bi {{ $card['icon'] }} fs-4"></i></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="card surface-card p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h3 class="h5 fw-bold mb-0">Senarai Akaun Boleh Disemak</h3>
|
||||
<a href="{{ route('staff.applications.index') }}" class="btn btn-outline-primary btn-sm">Lihat Semua</a>
|
||||
</div>
|
||||
<div class="alert alert-secondary">
|
||||
Akaun berstatus <strong>diproses</strong> dan <strong>aktif</strong> sahaja dipaparkan di dashboard staff. Akaun <strong>batal</strong>, <strong>gagal</strong>, dan <strong>selesai</strong> kekal dalam sejarah, database, dan kemas kini Excel tetapi tidak dipaparkan untuk semakan staff.
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>No Permohonan</th>
|
||||
<th>Pemohon</th>
|
||||
<th>No Akaun Tunggakan</th>
|
||||
<th>Status</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach ($applications as $application)
|
||||
<tr>
|
||||
<td>{{ $application->application_no }}</td>
|
||||
<td>{{ $application->user->displayName() }}</td>
|
||||
<td>{{ $application->no_akaun_tunggakan }}</td>
|
||||
<td>@include('components.status-badge', ['status' => $application->status])</td>
|
||||
<td class="text-end"><a href="{{ route('staff.applications.show', $application) }}" class="btn btn-sm btn-outline-secondary">Semak</a></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
223
src/resources/views/welcome.blade.php
Normal file
223
src/resources/views/welcome.blade.php
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user