258 lines
13 KiB
PHP
258 lines
13 KiB
PHP
@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>
|