feat(app): Implement major features and complete UI overhaul
This commit introduces a suite of major features and a comprehensive UI refactor, creating distinct, polished experiences for each user role.
This commit is contained in:
parent
6f90936e3c
commit
58f0c8baab
|
|
@ -13,26 +13,37 @@
|
|||
class ProfileController extends Controller
|
||||
{
|
||||
/**
|
||||
* Menampilkan halaman utama profil pengguna.
|
||||
* Menampilkan halaman utama profil pengguna secara dinamis berdasarkan role.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$user = Auth::user();
|
||||
|
||||
if (!$user) {
|
||||
return redirect()->route('login');
|
||||
}
|
||||
|
||||
$bukuOffline = DummyDataService::getBukuPinjamOffline($user);
|
||||
$bukuOnline = DummyDataService::getBacaBukuOnline($user);
|
||||
$statistik = DummyDataService::getDashboardStats();
|
||||
$viewData = ['user' => $user];
|
||||
|
||||
return view('profile.index', [
|
||||
'user' => $user,
|
||||
'bukuOffline' => $bukuOffline,
|
||||
'bukuOnline' => $bukuOnline,
|
||||
'statistik' => $statistik,
|
||||
]);
|
||||
// Menyiapkan data berdasarkan role pengguna
|
||||
if ($user->role === 'penjaga perpus') {
|
||||
// Data untuk Penjaga Perpus: Statistik global & aktivitas terkini
|
||||
$viewData['statistik'] = DummyDataService::getAdminDashboardStats();
|
||||
$viewData['aktivitasTerakhir'] = DummyDataService::getAktivitasTerakhir();
|
||||
|
||||
} elseif ($user->role === 'guru') {
|
||||
// Data untuk Guru: Data personal + ringkasan laporan minat baca
|
||||
$viewData['bukuOffline'] = DummyDataService::getBukuPinjamOffline($user);
|
||||
$viewData['bukuOnline'] = DummyDataService::getBacaBukuOnline($user);
|
||||
$viewData['laporan'] = DummyDataService::getLaporanMinatBaca();
|
||||
|
||||
} else {
|
||||
// Data default untuk Siswa
|
||||
$viewData['bukuOffline'] = DummyDataService::getBukuPinjamOffline($user);
|
||||
$viewData['bukuOnline'] = DummyDataService::getBacaBukuOnline($user);
|
||||
$viewData['statistik'] = DummyDataService::getDashboardStats();
|
||||
}
|
||||
|
||||
return view('profile.index', $viewData);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -27,8 +27,15 @@ public function boot(): void
|
|||
}
|
||||
|
||||
View::composer('*', function ($view) {
|
||||
$notifikasi = collect(DummyDataService::getNotifikasi());
|
||||
$unreadNotificationsCount = $notifikasi->where('read', false)->count();
|
||||
$notifikasi = collect([]);
|
||||
$unreadNotificationsCount = 0;
|
||||
|
||||
// Hanya ambil notifikasi jika ada pengguna yang login
|
||||
if (auth()->check()) {
|
||||
$user = auth()->user();
|
||||
$notifikasi = collect(DummyDataService::getNotifikasiForUser($user));
|
||||
$unreadNotificationsCount = $notifikasi->where('read', false)->count();
|
||||
}
|
||||
|
||||
$view->with(compact('notifikasi', 'unreadNotificationsCount'));
|
||||
});
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ public static function getAllSiswa(): array
|
|||
'kelas' => 'XII RPL A',
|
||||
'golongan' => 'A',
|
||||
],
|
||||
|
||||
[
|
||||
'id' => 4,
|
||||
'nisn' => '5566778899',
|
||||
|
|
@ -205,6 +206,7 @@ public static function getAdminDashboardStats(): array
|
|||
['label' => 'Denda Menunggu', 'value' => 0, 'icon' => 'bi-cash-coin', 'color' => 'danger'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Data untuk bar chart di dashboard admin (total peminjaman per bulan).
|
||||
*/
|
||||
|
|
@ -240,17 +242,19 @@ public static function getAktivitasTerakhir(): array
|
|||
['nama' => 'Rina Marlina', 'judul_buku' => 'Modul Ajar IPAS', 'tipe' => 'Peminjaman', 'waktu' => 'Kemarin', 'status' => 'Dipinjam'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Data untuk 4 kartu statistik
|
||||
* Data untuk halaman Dashboard Siswa dan Guru dengan warna spesifik.
|
||||
*/
|
||||
public static function getDashboardStats(): array
|
||||
{
|
||||
return [
|
||||
['label' => 'Buku yang dipinjam', 'value' => 3, 'icon' => 'bi-book-half', 'color' => 'primary'],
|
||||
['label' => 'Tenggat Waktu', 'value' => '2', 'icon' => 'bi-clock-history', 'color' => 'warning'],
|
||||
['label' => 'Buku dikembalikan', 'value' => 12, 'icon' => 'bi-check-circle', 'color' => 'success'],
|
||||
['label' => 'History Baca', 'value' => 15, 'icon' => 'bi-hourglass-split', 'color' => 'info'],
|
||||
['label' => 'Buku yang dipinjam', 'value' => 3, 'icon' => 'bi-book-half', 'color' => '#5A81FA'],
|
||||
|
||||
['label' => 'Tenggat Waktu', 'value' => '2', 'icon' => 'bi-clock-history', 'color' => '#5A5FBA'],
|
||||
|
||||
['label' => 'Buku dikembalikan', 'value' => 12, 'icon' => 'bi-check-circle', 'color' => '#696E82'],
|
||||
|
||||
['label' => 'History Baca', 'value' => 15, 'icon' => 'bi-hourglass-split', 'color' => '#A8B1CE'],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
@ -642,19 +646,86 @@ public static function getRiwayatOnline(): array
|
|||
}
|
||||
|
||||
/**
|
||||
* Data untuk fitur notifikasi.
|
||||
* Data untuk notifikasi pengguna.
|
||||
* @param \App\Models\User $user Pengguna yang sedang login.
|
||||
* @return array Daftar notifikasi.
|
||||
*/
|
||||
public static function getNotifikasi(): array
|
||||
public static function getNotifikasiForUser($user): array
|
||||
{
|
||||
return [
|
||||
['icon' => 'bi-check2-circle', 'color' => 'success', 'title' => 'Buku "Perahu Kertas" berhasil dipinjam.', 'time' => '5 menit yang lalu', 'read' => false],
|
||||
['icon' => 'bi-exclamation-triangle', 'color' => 'danger', 'title' => 'Buku "Sosiologi" akan jatuh tempo besok!', 'time' => '1 jam yang lalu', 'read' => false],
|
||||
['icon' => 'bi-book-half', 'color' => 'info', 'title' => '5 buku baru ditambahkan ke kategori Fiksi.', 'time' => '3 jam yang lalu', 'read' => false],
|
||||
['icon' => 'bi-arrow-repeat', 'color' => 'primary', 'title' => 'Peminjaman buku "Modul IPAS" telah diperpanjang.', 'time' => 'Kemarin', 'read' => true],
|
||||
['icon' => 'bi-check-circle', 'color' => 'success', 'title' => 'Anda telah mengembalikan buku "The Last Spell Breather".', 'time' => 'Kemarin', 'read' => true],
|
||||
['icon' => 'bi-info-circle', 'color' => 'info', 'title' => 'Perpustakaan akan mengadakan acara baca buku bersama.', 'time' => '2 hari yang lalu', 'read' => true],
|
||||
['icon' => 'bi-person-check', 'color' => 'primary', 'title' => 'Profil Anda berhasil diperbarui.', 'time' => '2 hari yang lalu', 'read' => true],
|
||||
['icon' => 'bi-exclamation-triangle', 'color' => 'warning', 'title' => 'Sistem akan maintenance pada pukul 23:00.', 'time' => '3 hari yang lalu', 'read' => true],
|
||||
$notifikasi = [];
|
||||
|
||||
$bukuPinjaman = self::getBukuPinjamOffline($user);
|
||||
|
||||
if (!empty($bukuPinjaman)) {
|
||||
$bukuTerbaru = $bukuPinjaman[0];
|
||||
$notifikasi[] = [
|
||||
'icon' => 'bi-check2-circle',
|
||||
'color' => 'success',
|
||||
'title' => 'Buku "' . $bukuTerbaru['judul'] . '" berhasil dipinjam.',
|
||||
'time' => '5 menit yang lalu',
|
||||
'read' => false,
|
||||
'type' => 'riwayat_peminjaman',
|
||||
'link_id' => null,
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
foreach ($bukuPinjaman as $buku) {
|
||||
if ($buku['sisa_hari'] <= 3) {
|
||||
$notifikasi[] = [
|
||||
'icon' => 'bi-exclamation-triangle',
|
||||
'color' => 'danger',
|
||||
'title' => 'Buku "' . $buku['judul'] . '" akan jatuh tempo!',
|
||||
'time' => '1 jam yang lalu',
|
||||
'read' => false,
|
||||
'type' => 'riwayat_peminjaman',
|
||||
'link_id' => null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->role === 'guru') {
|
||||
$notifikasi[] = [
|
||||
'icon' => 'bi-lightbulb-fill',
|
||||
'color' => 'success',
|
||||
'title' => 'Rekomendasi pembelajaran baru telah ditambahkan.',
|
||||
'time' => 'Kemarin',
|
||||
'read' => true,
|
||||
'type' => 'rekomendasi',
|
||||
'link_id' => 1,
|
||||
];
|
||||
}
|
||||
|
||||
$notifikasiUmum = [
|
||||
[
|
||||
'icon' => 'bi-book-half',
|
||||
'color' => 'info',
|
||||
'title' => 'Buku baru ditambahkan ke kategori Fiksi.',
|
||||
'time' => '3 jam yang lalu',
|
||||
'read' => false,
|
||||
'type' => 'katalog_kategori',
|
||||
'link_id' => 'Fiksi',
|
||||
],
|
||||
[
|
||||
'icon' => 'bi-megaphone-fill',
|
||||
'color' => 'warning',
|
||||
'title' => 'Perpustakaan akan tutup lebih awal pada hari Jumat.',
|
||||
'time' => '1 hari yang lalu',
|
||||
'read' => true,
|
||||
'type' => 'halaman_profil',
|
||||
'link_id' => null,
|
||||
],
|
||||
[
|
||||
'icon' => 'bi-calendar-event',
|
||||
'color' => 'primary',
|
||||
'title' => 'Acara "Bedah Buku" akan diadakan minggu depan.',
|
||||
'time' => '2 hari yang lalu',
|
||||
'read' => true,
|
||||
'type' => 'halaman_profil',
|
||||
'link_id' => null,
|
||||
],
|
||||
];
|
||||
|
||||
return array_merge($notifikasi, $notifikasiUmum);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
<svg width="611" height="521" viewBox="0 0 611 521" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M417.706 482.151C400.468 384.075 372.095 381.337 372.095 381.337L278.435 377.276C240.03 425.344 233.393 521 233.393 521H321.991H423.828L417.706 482.151Z" fill="#BFAA98"/>
|
||||
<path d="M385.357 81.3175C385.357 81.3175 383.33 113.066 392.797 129.925C402.268 146.774 409.464 153.721 411.989 172.027C411.989 172.027 332.577 195.717 253.049 169.353L284.295 81.3175H385.357Z" fill="#3B161B"/>
|
||||
<path d="M284.445 44.9603C284.445 44.9603 358.851 24.8054 379.892 62.1114C395.156 89.1843 377.118 138.199 342.256 152.011C309.046 165.167 318.469 56.9517 318.469 56.9517L284.445 44.9603Z" fill="#3B161B"/>
|
||||
<path d="M291.535 112.257C292.282 121.187 285.651 129.044 276.717 129.796C267.782 130.553 259.93 123.917 259.177 114.983C258.425 106.048 265.056 98.1956 273.991 97.4387C282.925 96.6865 290.782 103.322 291.535 112.257Z" fill="#EF9676"/>
|
||||
<path d="M298.826 157.621L301.586 192.895C302.529 205.284 310.669 211.33 322.857 210.3C333.262 209.424 342.581 203.229 343.002 192.804L335.988 137.499L298.826 157.621Z" fill="#F9AA89"/>
|
||||
<path d="M300.766 183.103L341.483 146.027L298.466 154.013L300.766 183.103Z" fill="#EF9676"/>
|
||||
<path d="M309.653 163.169C288.794 163.538 271.327 147.359 270.455 130.342L268.639 90.1568C267.547 68.8233 283.577 50.4649 304.867 48.6684C326.66 46.8335 349.642 62.6911 351.477 84.4844L352.583 116.813C353.441 141.821 334.584 161.07 309.653 163.169Z" fill="#F9AA89"/>
|
||||
<path d="M328.462 65.9584C320.916 84.1539 343.84 112.046 343.84 112.046L371.44 78.8696C371.44 78.8696 333.799 53.0807 328.462 65.9584Z" fill="#3B161B"/>
|
||||
<path d="M371.991 111.931C372.743 120.866 366.113 128.718 357.173 129.47C348.243 130.222 340.386 123.587 339.634 114.657C338.882 105.722 345.512 97.8652 354.452 97.1131C363.382 96.3609 371.239 102.996 371.991 111.931Z" fill="#F9AA89"/>
|
||||
<path d="M350.567 118.581C350.567 118.581 349.575 106.848 360.948 107.753" stroke="#14191C" stroke-width="0.718219" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M291.812 119.577L291.079 126.811L296.517 127.031" stroke="#14191C" stroke-width="0.718219" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M316.662 92.5234C316.662 92.5234 307.65 91.7377 307.55 95.5272C307.55 95.5272 307.554 98.0903 315.416 98.6221C323.278 99.149 325.324 98.5598 326.047 96.15C326.775 93.7403 320.892 92.5569 316.662 92.5234Z" fill="#14191C"/>
|
||||
<path d="M278.983 93.5199C278.983 93.5199 286.423 92.7438 287.022 96.3033C287.022 96.3033 287.372 98.7131 280.856 99.24C274.341 99.7718 272.223 98.9095 271.615 96.9644C270.92 94.7606 275.442 93.5678 278.983 93.5199Z" fill="#14191C"/>
|
||||
<path d="M284.295 111.615C284.358 113.775 282.714 115.577 280.626 115.639C278.537 115.706 276.793 114.01 276.726 111.854C276.664 109.698 278.307 107.897 280.396 107.83C282.484 107.768 284.228 109.459 284.295 111.615Z" fill="#14191C"/>
|
||||
<path d="M317.444 110.561C317.506 112.717 315.863 114.518 313.774 114.585C311.685 114.647 309.946 112.951 309.879 110.8C309.817 108.635 311.455 106.833 313.549 106.771C315.633 106.704 317.382 108.405 317.444 110.561Z" fill="#14191C"/>
|
||||
<path d="M287.027 134.529H314.459C314.459 134.529 310.123 143.09 298.827 143.047C288.531 143.009 287.027 134.529 287.027 134.529Z" fill="white"/>
|
||||
<path d="M333.062 65.9584C333.062 65.9584 316.658 93.9894 264.036 84.1539C264.036 84.1539 251.244 55.4426 284.445 44.9603C317.64 34.4828 355.813 52.1897 355.813 52.1897V75.794L333.062 65.9584Z" fill="#3B161B"/>
|
||||
<path d="M288.757 198.165C288.757 198.165 241.706 209.323 233.404 271.541L263.586 297.373L288.757 198.165Z" fill="#707EC7"/>
|
||||
<path d="M214.25 374.39C215.098 372.996 214.552 384.47 215.069 382.918C215.069 382.918 229.083 359.098 249.808 309.211C255.106 296.449 247.963 257.403 234.189 256.316C224.071 255.521 212.066 274.377 209.656 284.232L184.538 347.404L214.25 374.39Z" fill="#F9AA89"/>
|
||||
<path d="M206.517 352.932L108.607 300.137L99.5906 310.097L178.696 388.557C190.185 400.083 209.707 396.193 215.897 381.14C220.185 370.711 216.194 358.715 206.517 352.932Z" fill="#F9AA89"/>
|
||||
<path d="M71.9428 296.061C65.365 304.761 68.7665 318.424 79.5506 326.588C90.3347 334.746 104.41 334.311 110.993 325.61C117.57 316.92 114.169 303.252 103.385 295.093C92.6007 286.929 78.5254 287.37 71.9428 296.061Z" fill="#F9AA89"/>
|
||||
<path d="M385.502 388.576C381.526 388.653 265.536 387.234 265.536 387.234L274.169 215.915L359.929 230.518L385.502 388.576Z" fill="white"/>
|
||||
<path d="M359.928 196.393L325.515 190.361L300.105 194.946L280.453 234.858C280.453 234.858 274.575 253.13 305.892 256.029C337.214 258.927 358.965 236.89 364.182 223.26C369.404 209.63 359.928 196.393 359.928 196.393Z" fill="#F9AA89"/>
|
||||
<path d="M300.106 194.946C300.106 194.946 274.351 249.192 280.732 305.221C287.113 361.24 255.293 420.435 255.293 420.435V265.859C255.293 265.859 255.633 201.347 300.106 194.946Z" fill="#707EC7"/>
|
||||
<path d="M258.517 241.704C258.517 241.704 248.011 267.493 255.293 310.836" stroke="#5168BB" stroke-width="1.01863" stroke-miterlimit="10"/>
|
||||
<path d="M359.928 196.393C359.928 196.393 281.479 293.306 403.227 427.937L390.369 204.446L359.928 196.393Z" fill="#707EC7"/>
|
||||
<path d="M390.168 204.374C390.168 204.374 448.041 216.605 450.887 333.295L381.626 326.755L372.14 231.864L390.168 204.374Z" fill="#707EC7"/>
|
||||
<path d="M383.495 355.227C383.495 355.227 368.399 340.442 381.626 326.755C381.626 326.755 430.962 319.08 459.707 337.137C459.707 337.137 471.741 357.665 456.363 368.794C456.363 368.794 435.638 355.227 383.495 355.227Z" fill="#8F9ED8"/>
|
||||
<path d="M381.627 326.755L370.167 256.048" stroke="#5168BB" stroke-width="1.01863" stroke-miterlimit="10"/>
|
||||
<path d="M383.494 355.227L275.835 368.795L281.819 389.965L427.34 393.558C441.913 393.918 454.427 383.249 456.362 368.795C456.362 368.795 424.13 345.626 383.494 355.227Z" fill="#F9AA89"/>
|
||||
<path d="M233.423 379.775C233.983 393.213 247.944 403.542 264.601 402.848C281.264 402.158 294.314 390.698 293.753 377.265C293.193 363.822 279.232 353.493 262.575 354.187C245.912 354.882 232.862 366.337 233.423 379.775Z" fill="#F9AA89"/>
|
||||
<path d="M380.591 367.252H265.659V354.283H380.591C384.169 354.283 387.072 357.186 387.072 360.765C387.072 364.344 384.169 367.252 380.591 367.252Z" fill="#111719"/>
|
||||
<path d="M280.788 367.252H115.783C107.011 367.252 99.3126 361.402 96.9603 352.951L67.2621 246.265C64.6368 236.832 71.732 227.494 81.5244 227.494H234.111C239.966 227.494 245.082 231.442 246.572 237.105L280.788 367.252Z" fill="#1F2A30"/>
|
||||
<path d="M181.706 303.343C181.706 311.3 175.257 317.753 167.3 317.753C159.342 317.753 152.894 311.3 152.894 303.343C152.894 295.39 159.342 288.937 167.3 288.937C175.257 288.937 181.706 295.39 181.706 303.343Z" fill="white"/>
|
||||
<path d="M91.4662 145.184H17.8076C7.9721 145.184 0.000239619 137.212 0.000239619 127.376C0.000239619 117.546 7.9721 109.579 17.8076 109.579H91.4662C101.302 109.579 109.274 117.546 109.274 127.376C109.274 137.212 101.302 145.184 91.4662 145.184Z" fill="white"/>
|
||||
<path d="M39.006 127.429C39.0156 130.055 36.8933 132.186 34.2679 132.191C31.6425 132.201 29.5106 130.083 29.501 127.458C29.4914 124.833 31.6138 122.701 34.2391 122.691C36.8645 122.681 38.9964 124.804 39.006 127.429Z" fill="#8D8D8D"/>
|
||||
<path d="M59.3878 127.367C59.3974 129.987 57.2751 132.124 54.6497 132.134C52.0292 132.143 49.8925 130.016 49.8877 127.391C49.8781 124.77 52.0004 122.634 54.621 122.629C57.2464 122.619 59.3831 124.742 59.3878 127.367Z" fill="#8D8D8D"/>
|
||||
<path d="M79.7707 127.3C79.7802 129.925 77.6579 132.057 75.0325 132.067C72.4072 132.076 70.2753 129.959 70.2657 127.333C70.2561 124.708 72.3785 122.576 75.0038 122.567C77.6244 122.557 79.7611 124.675 79.7707 127.3Z" fill="#8D8D8D"/>
|
||||
<path d="M598.74 82.6414H450.133C443.542 82.6414 438.2 77.2368 438.2 70.5712V12.0738C438.2 5.40828 443.542 3.7767e-05 450.133 3.7767e-05H598.74C605.331 3.7767e-05 610.669 5.40828 610.669 12.0738V70.5712C610.669 77.2368 605.331 82.6414 598.74 82.6414Z" fill="#7383CA"/>
|
||||
<path d="M459.759 71.8621V93.4804C459.759 96.6205 463.83 98.1955 466.214 95.9747L492.097 71.8621H459.759Z" fill="#7383CA"/>
|
||||
<path d="M466.945 21.5587H581.924" stroke="white" stroke-width="1.36499" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M466.945 39.5242H506.469" stroke="white" stroke-width="1.36499" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<path d="M466.945 61.0828H549.586" stroke="white" stroke-width="1.36499" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 8.3 KiB |
|
|
@ -11,7 +11,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||
labels: statistikData.labels,
|
||||
datasets: [{
|
||||
label: 'Buku Dibaca',
|
||||
backgroundColor: '#435ebe',
|
||||
backgroundColor: '#5A81FA',
|
||||
data: statistikData.data,
|
||||
borderRadius: 8
|
||||
}]
|
||||
|
|
@ -63,7 +63,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||
labels: ['Telah Dibaca', 'Belum Dibaca'],
|
||||
datasets: [{
|
||||
data: [progressData.selesai, progressData.sisa],
|
||||
backgroundColor: ['#435ebe', '#e9ecef'],
|
||||
backgroundColor: ['#5A81FA', '#e9ecef'],
|
||||
borderColor: ['#ffffff'],
|
||||
borderWidth: 3,
|
||||
}]
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
@use "sass:color";
|
||||
|
||||
// ===================================
|
||||
// VARIABLES & MAPS
|
||||
// VARIABLES & MAPS
|
||||
// ===================================
|
||||
|
||||
// Theme Colors Map
|
||||
$theme-colors: (
|
||||
"primary": #435ebe,
|
||||
"secondary": color.mix(#6c757d, #ffffff, 80%),
|
||||
"primary": #5A81FA,
|
||||
"secondary": #5A5FBA,
|
||||
"success": color.mix(#198754, #ffffff, 85%),
|
||||
"info": color.mix(#0dcaf0, #ffffff, 80%),
|
||||
"warning": color.mix(#ffc107, #ffffff, 80%),
|
||||
|
|
@ -16,10 +16,9 @@ $theme-colors: (
|
|||
|
||||
// Gray Colors Map
|
||||
$grays: (
|
||||
"light": #f4f7f8,
|
||||
"dark": #4c5053,
|
||||
"light": #f9f9f9,
|
||||
"dark": #696E82,
|
||||
);
|
||||
|
||||
// Spacing & Sizing
|
||||
$border-radius: 0.5rem;
|
||||
$border-radius-sm: 0.25rem;
|
||||
|
|
@ -117,9 +116,9 @@ $transition: all 0.3s ease;
|
|||
}
|
||||
|
||||
.icon-circle {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 50%;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 15%;
|
||||
}
|
||||
|
||||
.icon-box {
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ body {
|
|||
}
|
||||
|
||||
.main-wrapper {
|
||||
margin-left: 250px;
|
||||
margin-left: 240px;
|
||||
}
|
||||
|
||||
.sidebar.minimized {
|
||||
|
|
|
|||
|
|
@ -6,34 +6,37 @@
|
|||
Pinjam Buku Baru
|
||||
</button> --}}
|
||||
|
||||
<div class="mb-4">
|
||||
<h3>{{ $greeting }}, {{ $user->nama_lengkap }} !</h3>
|
||||
<p class="text-muted">Apa yang ingin kamu baca hari ini?</p>
|
||||
<div class="card border-0 shadow-sm rounded-4 my-4 p-4 position-relative" style="background-color: #CEDEFF;">
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-8 p-4 p-md-5" style="z-index: 2;">
|
||||
<h2 class="fw-bold text-dark mb-2">{{ $greeting }}, {{ $user->nama_lengkap }}!</h2>
|
||||
<p class="fs-5 mb-0" style="color: #696E82;">Siap memulai harimu dengan bacaan baru?</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="position-absolute d-none d-md-block" style="top: -35px; right: 40px; width: 30%; max-width: 300px; z-index: 1;">
|
||||
<img src="{{ asset('images/assets/vector-dashboard.svg') }}" alt="Ilustrasi Dashboard" class="img-fluid">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 mb-4">
|
||||
@foreach ($stats as $stat)
|
||||
<div class="col-xl-3 col-lg-6 col-md-6">
|
||||
<div class="card rounded-2 bg-{{ $stat['color'] }}-light border-0 h-100">
|
||||
<div class="card-body p-4 ">
|
||||
<div class="d-flex justify-content-between align-items-start">
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="text-muted fw-normal mb-2 text-uppercase small">{{ $stat['label'] }}</h6>
|
||||
<h3 class="fw-bold mb-0 text-dark">{{ $stat['value'] }}</h3>
|
||||
</div>
|
||||
<div class="icon-wrapper">
|
||||
<div class="icon-circle bg-{{ $stat['color'] }}-light">
|
||||
<i class="bi {{ $stat['icon'] }} text-{{ $stat['color'] }} fs-4"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xl-3 col-lg-6 col-md-6">
|
||||
<div class="card rounded-4 border-0 h-100 text-white" style="background-color: {{ $stat['color'] }};">
|
||||
<div class="card-body p-4">
|
||||
<div class="icon-circle bg-white bg-opacity-25 mb-3">
|
||||
<i class="bi {{ $stat['icon'] }} fs-3"></i>
|
||||
</div>
|
||||
<div>
|
||||
<h3 class="fw-bold mb-1">{{ $stat['value'] }}</h3>
|
||||
<p class="text-white-75 mb-0 text-uppercase small">{{ $stat['label'] }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<!-- Charts Section -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-lg-7">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
|
|
@ -46,7 +49,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="card-body p-4">
|
||||
<canvas id="barChart" style="max-height: 300px;" data-stats='@json($statistikBulanan ?? ['labels' => [], 'data' => []])'>
|
||||
<canvas id="barChart" style="max-height: 300px;" data-stats='@json($statistikBulanan ?? [' labels'=> [], 'data' => []])'>
|
||||
</canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -63,7 +66,7 @@
|
|||
</div>
|
||||
<div class="card-body text-center d-flex justify-content-center align-items-center p-4">
|
||||
<div class="chart-container" style="position: relative; height: 200px; width: 200px;">
|
||||
<canvas id="donutChart" data-progress='@json($progressMembaca ?? ['selesai' => 0, 'sisa' => 0])'>
|
||||
<canvas id="donutChart" data-progress='@json($progressMembaca ?? [' selesai'=> 0, 'sisa' => 0])'>
|
||||
</canvas>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -81,7 +84,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Announcements and Notifications Section -->
|
||||
<div class="row g-4 mb-4">
|
||||
<div class="col-lg-6">
|
||||
<div class="card border-0 shadow-sm h-100">
|
||||
|
|
@ -99,21 +101,21 @@
|
|||
</div>
|
||||
<div class="card-body p-4">
|
||||
@forelse(collect($pengumuman)->take(2) as $item)
|
||||
<div class="alert alert-{{ $item['type'] }} border-0 d-flex align-items-start mb-3 shadow-sm"
|
||||
role="alert">
|
||||
<div class="alert-icon me-3 mt-1">
|
||||
<i class="{{ $item['icon'] }} fs-5"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-bold mb-1">{{ $item['title'] }}!</div>
|
||||
<div class="small">{{ $item['content'] }}</div>
|
||||
</div>
|
||||
<div class="alert alert-{{ $item['type'] }} border-0 d-flex align-items-start mb-3 shadow-sm"
|
||||
role="alert">
|
||||
<div class="alert-icon me-3 mt-1">
|
||||
<i class="{{ $item['icon'] }} fs-5"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-bold mb-1">{{ $item['title'] }}!</div>
|
||||
<div class="small">{{ $item['content'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-inbox text-muted mb-3" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mb-0">Tidak ada pengumuman baru.</p>
|
||||
</div>
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-inbox text-muted mb-3" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mb-0">Tidak ada pengumuman baru.</p>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -134,156 +136,148 @@
|
|||
</div>
|
||||
<div class="card-body p-0">
|
||||
@forelse(collect($pemberitahuan)->take(3) as $item)
|
||||
<div
|
||||
class="list-group-item border-0 d-flex justify-content-between align-items-center px-4 py-3">
|
||||
<div class="d-flex align-items-start flex-grow-1">
|
||||
<div class="notification-icon me-3 mt-1">
|
||||
<i class="bi {{ $item['icon'] }} text-{{ $item['type'] }}"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-semibold text-dark mb-1">{{ $item['title'] }}:</div>
|
||||
<div class="text-muted small">{{ $item['content'] }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="list-group-item border-0 d-flex justify-content-between align-items-center px-4 py-3">
|
||||
<div class="d-flex align-items-start flex-grow-1">
|
||||
<div class="notification-icon me-3 mt-1">
|
||||
<i class="bi {{ $item['icon'] }} text-{{ $item['type'] }}"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-semibold text-dark mb-1">{{ $item['title'] }}:</div>
|
||||
<div class="text-muted small">{{ $item['content'] }}</div>
|
||||
</div>
|
||||
<span
|
||||
class="badge bg-{{ $item['type'] }}-soft text-{{ $item['type'] }} rounded-pill px-3 py-2 ms-3">
|
||||
{{ $item['badge'] }}
|
||||
</span>
|
||||
</div>
|
||||
@if (!$loop->last)
|
||||
<hr class="my-0 mx-4">
|
||||
@endif
|
||||
<span
|
||||
class="badge bg-{{ $item['type'] }}-soft text-{{ $item['type'] }} rounded-pill px-3 py-2 ms-3">
|
||||
{{ $item['badge'] }}
|
||||
</span>
|
||||
</div>
|
||||
@if (!$loop->last)
|
||||
<hr class="my-0 mx-4">
|
||||
@endif
|
||||
@empty
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-bell-slash text-muted mb-3" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mb-0 px-4">Tidak ada pemberitahuan baru.</p>
|
||||
</div>
|
||||
<div class="text-center py-4">
|
||||
<i class="bi bi-bell-slash text-muted mb-3" style="font-size: 3rem;"></i>
|
||||
<p class="text-muted mb-0 px-4">Tidak ada pemberitahuan baru.</p>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Buku Pinjam Offline Section -->
|
||||
<div class="card border-0 shadow-sm mb-4">
|
||||
<div class="card border-0 shadow-sm mb-4" x-data="{ expanded: {{ count($bukuPinjamOffline) <= 2 ? 'true' : 'false' }} }">
|
||||
<div class="card-header bg-white border-0 py-3 d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0 fw-bold text-dark">
|
||||
<i class="bi bi-book-half text-danger me-2"></i>Buku Pinjam Offline
|
||||
</h6>
|
||||
@if (count($bukuPinjamOffline) > 2)
|
||||
<div x-data="{ expanded: false }">
|
||||
<button type="button"
|
||||
:class="expanded ? 'btn btn-sm btn-primary rounded-pill px-3' :
|
||||
'btn btn-sm btn-outline-primary rounded-pill px-3'"
|
||||
@click="expanded = !expanded">
|
||||
<span x-text="expanded ? 'Sembunyikan' : 'Lihat Semua'"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button"
|
||||
:class="expanded ? 'btn btn-sm btn-primary rounded-pill px-3' : 'btn btn-sm btn-outline-primary rounded-pill px-3'"
|
||||
@click="expanded = !expanded">
|
||||
<span x-text="expanded ? 'Sembunyikan' : 'Lihat Semua'"></span>
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-4" x-data="{ expanded: {{ count($bukuPinjamOffline) <= 2 ? 'true' : 'false' }} }">
|
||||
<div class="row g-4">
|
||||
@forelse($bukuPinjamOffline as $buku)
|
||||
<div class="col-xl-4 col-md-6" x-show="expanded || {{ $loop->index }} < 2" x-transition>
|
||||
<x-book-card :buku="$buku">
|
||||
<div class="alert alert-danger border-0 py-2 px-3 mb-0 d-flex align-items-center">
|
||||
<i class="bi bi-clock-fill me-2"></i>
|
||||
<span class="fw-bold small">Sisa: {{ $buku['sisa_hari'] }} hari</span>
|
||||
</div>
|
||||
</x-book-card>
|
||||
</div>
|
||||
@empty
|
||||
{{-- Jika tidak ada buku, akan menampilkan pesan ini di dalam card-body --}}
|
||||
<div class="col-12">
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-book text-muted mb-3" style="font-size: 4rem;"></i>
|
||||
<p class="text-muted mb-0">Tidak ada buku yang sedang dipinjam secara offline.</p>
|
||||
<div class="col-xl-4 col-md-6" x-show="expanded || {{ $loop->index }} < 2" x-transition>
|
||||
<x-book-card :buku="$buku">
|
||||
<div class="alert alert-danger border-0 py-2 px-3 mb-0 d-flex align-items-center">
|
||||
<i class="bi bi-clock-fill me-2"></i>
|
||||
<span class="fw-bold small">Sisa: {{ $buku['sisa_hari'] }} hari</span>
|
||||
</div>
|
||||
</x-book-card>
|
||||
</div>
|
||||
@empty
|
||||
<div class="col-12">
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-book text-muted mb-3" style="font-size: 4rem;"></i>
|
||||
<p class="text-muted mb-0">Tidak ada buku yang sedang dipinjam secara offline.</p>
|
||||
</div>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Baca Buku Online Section -->
|
||||
<div class="card border-0 shadow-sm">
|
||||
<div class="card border-0 shadow-sm" x-data="{ expanded: {{ count($bacaBukuOnline) <= 3 ? 'true' : 'false' }} }">
|
||||
<div class="card-header bg-white border-0 py-3 d-flex justify-content-between align-items-center">
|
||||
<h6 class="mb-0 fw-bold text-dark">
|
||||
<i class="bi bi-globe text-success me-2"></i>Baca Buku Online
|
||||
</h6>
|
||||
@if (count($bacaBukuOnline) > 3)
|
||||
<div x-data="{ expanded: false }">
|
||||
<button type="button"
|
||||
:class="expanded ? 'btn btn-sm btn-primary rounded-pill px-3' :
|
||||
'btn btn-sm btn-outline-primary rounded-pill px-3'"
|
||||
@click="expanded = !expanded">
|
||||
<span x-text="expanded ? 'Sembunyikan' : 'Lihat Semua'"></span>
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button type="button"
|
||||
:class="expanded ? 'btn btn-sm btn-primary rounded-pill px-3' : 'btn btn-sm btn-outline-primary rounded-pill px-3'"
|
||||
@click="expanded = !expanded">
|
||||
<span x-text="expanded ? 'Sembunyikan' : 'Lihat Semua'"></span>
|
||||
</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row g-4" x-data="{ expanded: {{ count($bacaBukuOnline) <= 3 ? 'true' : 'false' }} }">
|
||||
<div class="row g-4">
|
||||
@forelse($bacaBukuOnline as $buku)
|
||||
<div class="col-xl-4 col-md-6" x-show="expanded || {{ $loop->index }} < 3" x-transition>
|
||||
<x-book-card :buku="$buku">
|
||||
<div class="progress-wrapper">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||
<span class="small text-muted">Progress</span>
|
||||
<span class="small fw-bold text-primary">{{ $buku['progress'] }}%</span>
|
||||
</div>
|
||||
<div class="progress" style="height: 8px;">
|
||||
<div class="progress-bar bg-primary rounded-pill"
|
||||
style="width: {{ $buku['progress'] }}%" role="progressbar"></div>
|
||||
</div>
|
||||
<div class="col-xl-4 col-md-6" x-show="expanded || {{ $loop->index }} < 3" x-transition>
|
||||
<x-book-card :buku="$buku">
|
||||
<div class="progress-wrapper">
|
||||
<div class="d-flex justify-content-between align-items-center mb-1">
|
||||
<span class="small text-muted">Progress</span>
|
||||
<span class="small fw-bold text-primary">{{ $buku['progress'] }}%</span>
|
||||
</div>
|
||||
<div class="progress" style="height: 8px;">
|
||||
<div class="progress-bar bg-primary rounded-pill"
|
||||
style="width: {{ $buku['progress'] }}%" role="progressbar"></div>
|
||||
</div>
|
||||
</x-book-card>
|
||||
</div>
|
||||
@empty
|
||||
{{-- Jika tidak ada buku, akan menampilkan pesan ini di dalam card-body --}}
|
||||
<div class="col-12">
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-book text-muted mb-3" style="font-size: 4rem;"></i>
|
||||
<p class="text-muted mb-0">Tidak ada buku yang sedang dibaca secara online.</p>
|
||||
</div>
|
||||
</x-book-card>
|
||||
</div>
|
||||
@empty
|
||||
<div class="col-12">
|
||||
<div class="text-center py-5">
|
||||
<i class="bi bi-book text-muted mb-3" style="font-size: 4rem;"></i>
|
||||
<p class="text-muted mb-0">Tidak ada buku yang sedang dibaca secara online.</p>
|
||||
</div>
|
||||
</div>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rekomendasi Pembelajaran Section (Section ini hanya tampil saat Role yang login adalah Guru) -->
|
||||
@if (Auth::user()->role == 'guru')
|
||||
<div class="card border-0 shadow-sm mt-4">
|
||||
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center py-3">
|
||||
<h6 class="m-0 fw-bold text-dark">
|
||||
<i class="bi bi-lightbulb-fill text-success me-2"></i>Rekomendasi Pembelajaran
|
||||
</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary rounded-pill px-3"
|
||||
data-bs-toggle="modal" data-bs-target="#rekomendasiModal">
|
||||
Lihat Semua
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@forelse($rekomendasiPembelajaran->take(3) as $item)
|
||||
<a href="{{ route('rekomendasi.show', $item['id']) }}"
|
||||
class="d-flex gap-3 text-decoration-none text-dark mb-3">
|
||||
<img src="{{ $item['thumbnail'] }}" class="rounded"
|
||||
style="width: 120px; height: 70px; object-fit: cover;" alt="Thumbnail">
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="fw-bold mb-1 text-black">{{ $item['judul'] }}</h6>
|
||||
<span
|
||||
class="badge fw-normal text-primary border me-1">{{ $item['kategori'] }}</span>
|
||||
</div>
|
||||
</a>
|
||||
@if (!$loop->last)
|
||||
<hr class="my-3">
|
||||
@endif
|
||||
@empty
|
||||
<p class="text-muted text-center">Belum ada rekomendasi.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
<div class="card border-0 shadow-sm mt-4">
|
||||
<div class="card-header bg-white border-0 d-flex justify-content-between align-items-center py-3">
|
||||
<h6 class="m-0 fw-bold text-dark">
|
||||
<i class="bi bi-lightbulb-fill text-success me-2"></i>Rekomendasi Pembelajaran
|
||||
</h6>
|
||||
<button type="button" class="btn btn-sm btn-outline-primary rounded-pill px-3"
|
||||
data-bs-toggle="modal" data-bs-target="#rekomendasiModal">
|
||||
Lihat Semua
|
||||
</button>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
@forelse(collect($rekomendasiPembelajaran)->take(3) as $item)
|
||||
<a href="{{ route('rekomendasi.show', $item['id']) }}"
|
||||
class="d-flex gap-3 text-decoration-none text-dark mb-3">
|
||||
<img src="{{ $item['thumbnail'] }}" class="rounded"
|
||||
style="width: 120px; height: 70px; object-fit: cover;" alt="Thumbnail">
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="fw-bold mb-1 text-black">{{ $item['judul'] }}</h6>
|
||||
<span class="badge fw-normal text-primary border me-1">{{ $item['kategori'] }}</span>
|
||||
</div>
|
||||
</a>
|
||||
@if (!$loop->last)
|
||||
<hr class="my-3">
|
||||
@endif
|
||||
@empty
|
||||
<p class="text-muted text-center">Belum ada rekomendasi.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
|
|
@ -300,16 +294,16 @@ class="badge fw-normal text-primary border me-1">{{ $item['kategori'] }}</span>
|
|||
</div>
|
||||
<div class="modal-body px-4">
|
||||
@foreach ($pengumuman as $item)
|
||||
<div class="alert alert-{{ $item['type'] }} border-0 d-flex align-items-start mb-3 shadow-sm"
|
||||
role="alert">
|
||||
<div class="alert-icon me-3 mt-1">
|
||||
<i class="{{ $item['icon'] }} fs-5"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-bold mb-1">{{ $item['title'] }}!</div>
|
||||
<div class="small">{{ $item['content'] }}</div>
|
||||
</div>
|
||||
<div class="alert alert-{{ $item['type'] }} border-0 d-flex align-items-start mb-3 shadow-sm"
|
||||
role="alert">
|
||||
<div class="alert-icon me-3 mt-1">
|
||||
<i class="{{ $item['icon'] }} fs-5"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-bold mb-1">{{ $item['title'] }}!</div>
|
||||
<div class="small">{{ $item['content'] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
<div class="modal-footer border-0">
|
||||
|
|
@ -334,22 +328,22 @@ class="badge fw-normal text-primary border me-1">{{ $item['kategori'] }}</span>
|
|||
<div class="modal-body p-0">
|
||||
<div class="list-group list-group-flush">
|
||||
@foreach ($pemberitahuan as $item)
|
||||
<div
|
||||
class="list-group-item border-0 d-flex justify-content-between align-items-center px-4 py-3">
|
||||
<div class="d-flex align-items-start flex-grow-1">
|
||||
<div class="notification-icon me-3 mt-1">
|
||||
<i class="bi {{ $item['icon'] }} text-{{ $item['type'] }}"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-semibold text-dark mb-1">{{ $item['title'] }}:</div>
|
||||
<div class="text-muted small">{{ $item['content'] }}</div>
|
||||
</div>
|
||||
<div
|
||||
class="list-group-item border-0 d-flex justify-content-between align-items-center px-4 py-3">
|
||||
<div class="d-flex align-items-start flex-grow-1">
|
||||
<div class="notification-icon me-3 mt-1">
|
||||
<i class="bi {{ $item['icon'] }} text-{{ $item['type'] }}"></i>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<div class="fw-semibold text-dark mb-1">{{ $item['title'] }}:</div>
|
||||
<div class="text-muted small">{{ $item['content'] }}</div>
|
||||
</div>
|
||||
<span
|
||||
class="badge bg-{{ $item['type'] }}-soft text-{{ $item['type'] }} rounded-pill px-3 py-2 ms-3">
|
||||
{{ $item['badge'] }}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
class="badge bg-{{ $item['type'] }}-soft text-{{ $item['type'] }} rounded-pill px-3 py-2 ms-3">
|
||||
{{ $item['badge'] }}
|
||||
</span>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -375,16 +369,16 @@ class="badge bg-{{ $item['type'] }}-soft text-{{ $item['type'] }} rounded-pill p
|
|||
<div class="modal-body px-4">
|
||||
<div class="list-group list-group-flush">
|
||||
@foreach ($rekomendasiPembelajaran as $item)
|
||||
<a href="{{ route('rekomendasi.show', $item['id']) }}"
|
||||
class="list-group-item list-group-item-action d-flex gap-3 px-0 py-3">
|
||||
<img src="{{ $item['thumbnail'] }}" class="rounded"
|
||||
style="width: 120px; height: 70px; object-fit: cover;" alt="Thumbnail">
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="fw-bold mb-1 text-black">{{ $item['judul'] }}</h6>
|
||||
<span
|
||||
class="badge fw-normal text-primary border me-1">{{ $item['kategori'] }}</span>
|
||||
</div>
|
||||
</a>
|
||||
<a href="{{ route('rekomendasi.show', $item['id']) }}"
|
||||
class="list-group-item list-group-item-action d-flex gap-3 px-0 py-3">
|
||||
<img src="{{ $item['thumbnail'] }}" class="rounded"
|
||||
style="width: 120px; height: 70px; object-fit: cover;" alt="Thumbnail">
|
||||
<div class="flex-grow-1">
|
||||
<h6 class="fw-bold mb-1 text-black">{{ $item['judul'] }}</h6>
|
||||
<span
|
||||
class="badge fw-normal text-primary border me-1">{{ $item['kategori'] }}</span>
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -398,11 +392,10 @@ class="badge fw-normal text-primary border me-1">{{ $item['kategori'] }}</span>
|
|||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const statistikData = @json($statistikBulanan ?? ['labels' => [], 'data' => []]);
|
||||
const progressData = @json($progressMembaca ?? ['selesai' => 0, 'sisa' => 0]);
|
||||
const statistikData = JSON.parse(document.getElementById('barChart').getAttribute('data-stats'));
|
||||
const progressData = JSON.parse(document.getElementById('donutChart').getAttribute('data-progress'));
|
||||
});
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
|
||||
|
||||
<script src="{{ asset('js/dashboard-charts.js') }}"></script>
|
||||
</x-app-layout>
|
||||
</x-app-layout>
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
|
||||
<div class="main-wrapper flex-grow-1">
|
||||
@include('layouts.navigation')
|
||||
<main class="container-fluid py-4">
|
||||
<main class="container-fluid py-4 px-4">
|
||||
{{ $slot }}
|
||||
</main>
|
||||
<footer class="footer text-center py-3">
|
||||
|
|
@ -46,7 +46,21 @@
|
|||
<div class="modal-body pt-0">
|
||||
<div class="notification-list px-2">
|
||||
@forelse ($notifikasi as $item)
|
||||
<a href="#"
|
||||
@php
|
||||
$url = '#';
|
||||
|
||||
if (isset($item['type'])) {
|
||||
if ($item['type'] === 'riwayat_peminjaman') {
|
||||
$url = route('riwayat.offline');
|
||||
} elseif ($item['type'] === 'rekomendasi' && isset($item['link_id'])) {
|
||||
$url = route('rekomendasi.show', $item['link_id']);
|
||||
} elseif ($item['type'] === 'katalog_kategori' && isset($item['link_id'])) {
|
||||
$url = route('katalog.index', ['kategori' => $item['link_id']]);
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
|
||||
<a href="{{ $url }}"
|
||||
class="notification-item d-flex my-1 rounded-3 text-body text-decoration-none @if (!$item['read']) unread @endif">
|
||||
<div class="notification-icon bg-{{ $item['color'] }}-subtle">
|
||||
<i class="bi {{ $item['icon'] }} text-{{ $item['color'] }}-emphasis"></i>
|
||||
|
|
|
|||
|
|
@ -38,7 +38,21 @@ class="badge bg-primary-subtle text-primary-emphasis rounded-pill">{{ $unreadNot
|
|||
<hr class="my-1">
|
||||
<div class="notification-wrapper overflow-auto px-2">
|
||||
@forelse($notifikasi->take(5) as $item)
|
||||
<a href="#"
|
||||
@php
|
||||
$url = '#';
|
||||
|
||||
if (isset($item['type'])) {
|
||||
if ($item['type'] === 'riwayat_peminjaman') {
|
||||
$url = route('riwayat.offline');
|
||||
} elseif ($item['type'] === 'rekomendasi' && isset($item['link_id'])) {
|
||||
$url = route('rekomendasi.show', $item['link_id']);
|
||||
} elseif ($item['type'] === 'katalog_kategori' && isset($item['link_id'])) {
|
||||
$url = route('katalog.index', ['kategori' => $item['link_id']]);
|
||||
}
|
||||
}
|
||||
@endphp
|
||||
|
||||
<a href="{{ $url }}"
|
||||
class="notification-item my-1 rounded-pill dropdown-item @if (!$item['read']) unread @endif">
|
||||
<div class="notification-icon bg-{{ $item['color'] }}-subtle">
|
||||
<i class="bi {{ $item['icon'] }} text-{{ $item['color'] }}-emphasis"></i>
|
||||
|
|
|
|||
|
|
@ -1,139 +1,173 @@
|
|||
@section('page-title', 'Profile')
|
||||
<x-app-layout>
|
||||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||||
<h1 class="h2 mb-0">Profil Saya</h1>
|
||||
</div>
|
||||
@section('page-title', 'Profil')
|
||||
|
||||
<div class="row">
|
||||
{{-- Section Left --}}
|
||||
<div class="col-lg-8">
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=435ebe&color=fff&size=80&rounded=true"
|
||||
alt="Foto Profil" class="rounded-circle flex-shrink-0">
|
||||
{{-- =================================================================== --}}
|
||||
{{-- TAMPILAN PROFIL UNTUK PENJAGA PERPUSTAKAAN --}}
|
||||
{{-- =================================================================== --}}
|
||||
@if (Auth::user()->role == 'penjaga perpus')
|
||||
|
||||
<h1 class="h2 mb-4">Profil Petugas</h1>
|
||||
<div class="row g-4">
|
||||
{{-- Kolom Kiri: Info & Statistik Global --}}
|
||||
<div class="col-lg-8">
|
||||
{{-- Info Petugas --}}
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4 d-flex align-items-center">
|
||||
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=435ebe&color=fff&size=80&rounded=true" alt="Foto Profil" class="rounded-circle">
|
||||
<div class="ms-4">
|
||||
<h4 class="fw-bold mb-1">{{ $user->name }}</h4>
|
||||
<span class="badge rounded-pill bg-primary-soft">{{ $user->role }}</span>
|
||||
<span class="badge rounded-pill bg-success-subtle text-success-emphasis">{{ Str::title($user->role) }}</span>
|
||||
</div>
|
||||
<a href="{{ route('profile.edit') }}" class="btn btn-outline-primary rounded-pill ms-auto">
|
||||
<i class="bi bi-pencil-square me-2"></i>Edit Profil
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr class="my-4">
|
||||
|
||||
{{-- Informasi Personal --}}
|
||||
<h5 class="fw-bold mb-3">Informasi Personal</h5>
|
||||
<div class="row g-4">
|
||||
<div class="col-md-6 d-flex">
|
||||
<i class="bi bi-person-badge text-primary fs-4 me-3"></i>
|
||||
<div>
|
||||
<small class="text-muted">NISN</small>
|
||||
<p class="fw-semibold mb-0">{{ $user->nisn }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 d-flex">
|
||||
<i class="bi bi-envelope text-primary fs-4 me-3"></i>
|
||||
<div>
|
||||
<small class="text-muted">Email</small>
|
||||
<p class="fw-semibold mb-0">{{ $user->email }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 d-flex">
|
||||
<i class="bi bi-telephone text-primary fs-4 me-3"></i>
|
||||
<div>
|
||||
<small class="text-muted">Nomor HP</small>
|
||||
<p class="fw-semibold mb-0">{{ $user->nomor_hp }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6 d-flex">
|
||||
<i class="bi bi-building text-primary fs-4 me-3"></i>
|
||||
<div>
|
||||
<small class="text-muted">Kelas</small>
|
||||
<p class="fw-semibold mb-0">{{ $user->kelas }} / {{ $user->golongan }}</p>
|
||||
</div>
|
||||
{{-- Statistik Perpustakaan --}}
|
||||
<div class="card border-0">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="fw-bold mb-3">Statistik Perpustakaan</h5>
|
||||
<div class="d-flex justify-content-around text-center">
|
||||
@foreach ($statistik as $stat)
|
||||
<div class="flex-fill">
|
||||
<i class="bi {{ $stat['icon'] }} fs-4 text-{{ $stat['color'] }}"></i>
|
||||
<h5 class="fw-bolder mb-0 mt-2">{{ $stat['value'] }}</h5>
|
||||
<small class="text-muted">{{ $stat['label'] }}</small>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Statistic Card --}}
|
||||
<div class="card border-0">
|
||||
<div class="card-body p-4">
|
||||
<div class="section-header mb-3">
|
||||
<h5 class="mb-0">Statistik Saya</h5>
|
||||
{{-- Kolom Kanan: Pintasan & Aktivitas --}}
|
||||
<div class="col-lg-4">
|
||||
{{-- Pintasan Manajemen --}}
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="fw-bold mb-3">Pintasan Manajemen</h5>
|
||||
<div class="d-grid gap-2">
|
||||
<a href="{{ route('admin.buku.index') }}" class="btn btn-light text-start"><i class="bi bi-book-fill me-2"></i> Kelola Buku</a>
|
||||
<a href="{{ route('admin.pengguna.index') }}" class="btn btn-light text-start"><i class="bi bi-people-fill me-2"></i> Kelola Pengguna</a>
|
||||
<a href="{{ route('admin.pengumuman.index') }}" class="btn btn-light text-start"><i class="bi bi-megaphone-fill me-2"></i> Kelola Pengumuman</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex justify-content-around text-center">
|
||||
@foreach ($statistik as $stat)
|
||||
<div class="flex-fill">
|
||||
<i class="bi {{ $stat['icon'] }} fs-4 text-{{ $stat['color'] }}"></i>
|
||||
<h5 class="fw-bolder mb-0 mt-2">{{ $stat['value'] }}</h5>
|
||||
<small class="text-muted">{{ $stat['label'] }}</small>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
{{-- Keamanan Akun --}}
|
||||
<div class="card border-0">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="fw-bold mb-3">Keamanan Akun</h5>
|
||||
<p class="small text-muted">Ubah password Anda secara berkala.</p>
|
||||
<a href="{{ route('profile.edit') }}" class="btn btn-outline-secondary rounded-pill">Ubah Password</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Right Section --}}
|
||||
<div class="col-lg-4">
|
||||
{{-- Card Buku yang Dipinjam --}}
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<div class="section-header">
|
||||
<h5 class="mb-0">Buku yang Dipinjam</h5>
|
||||
{{-- =================================================================== --}}
|
||||
{{-- TAMPILAN PROFIL UNTUK GURU --}}
|
||||
{{-- =================================================================== --}}
|
||||
@elseif (Auth::user()->role == 'guru')
|
||||
|
||||
<h1 class="h2 mb-4">Profil Guru</h1>
|
||||
<div class="row g-4">
|
||||
{{-- Kolom Kiri: Info & Ringkasan Laporan --}}
|
||||
<div class="col-lg-8">
|
||||
{{-- Info Guru --}}
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4 d-flex align-items-center">
|
||||
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=198754&color=fff&size=80&rounded=true" alt="Foto Profil" class="rounded-circle">
|
||||
<div class="ms-4">
|
||||
<h4 class="fw-bold mb-1">{{ $user->name }}</h4>
|
||||
<span class="badge rounded-pill bg-success-subtle text-success-emphasis">{{ Str::title($user->role) }}</span>
|
||||
</div>
|
||||
<a href="{{ route('profile.edit') }}" class="btn btn-outline-primary rounded-pill ms-auto"><i class="bi bi-pencil-square me-2"></i>Edit Profil</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Ringkasan Laporan Minat Baca --}}
|
||||
<div class="card border-0">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex justify-content-between align-items-center mb-3">
|
||||
<h5 class="fw-bold mb-0">Ringkasan Laporan Minat Baca</h5>
|
||||
<a href="{{ route('guru.laporan.index') }}" class="btn btn-sm btn-outline-primary rounded-pill">Lihat Laporan Lengkap</a>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<h6 class="small text-muted">Buku Terpopuler</h6>
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach($laporan['buku_terpopuler'] as $buku)
|
||||
<li class="list-group-item px-0 d-flex justify-content-between"><span>{{ $buku['judul'] }}</span> <span class="fw-bold">{{ $buku['total_pembaca'] }}</span></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h6 class="small text-muted">Kategori Terpopuler</h6>
|
||||
<ul class="list-group list-group-flush">
|
||||
@foreach($laporan['kategori_populer'] as $kategori)
|
||||
<li class="list-group-item px-0 d-flex justify-content-between"><span>{{ $kategori['nama'] }}</span> <span class="fw-bold">{{ $kategori['total_pembaca'] }}</span></li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush mt-3">
|
||||
@forelse ($bukuOffline as $buku)
|
||||
<li class="list-group-item px-0">
|
||||
<h6 class="fw-semibold mb-1">{{ $buku['judul'] }}</h6>
|
||||
<small class="text-muted">{{ $buku['penulis'] }}</small>
|
||||
<span class="badge bg-danger-light text-danger float-end">Sisa
|
||||
{{ $buku['sisa_hari'] }} hari</span>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item px-0 text-center text-muted small py-3">Tidak ada buku yang
|
||||
sedang dipinjam.</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Riwayat Online --}}
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<div class="section-header">
|
||||
<h5 class="mb-0">Riwayat Baca Online</h5>
|
||||
</div>
|
||||
<ul class="list-group list-group-flush mt-3">
|
||||
@forelse ($bukuOnline as $buku)
|
||||
<li class="list-group-item px-0">
|
||||
<h6 class="fw-semibold mb-1">{{ $buku['judul'] }}</h6>
|
||||
<small class="text-muted">{{ $buku['penulis'] }}</small>
|
||||
<span class="badge bg-primary-light text-primary float-end">Progress
|
||||
{{ $buku['progress'] }}%</span>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item px-0 text-center text-muted small py-3">Tidak ada riwayat buku
|
||||
yang dibaca.</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Keamanan Akun --}}
|
||||
<div class="card border-0">
|
||||
<div class="card-body p-4">
|
||||
<div class="section-header mb-3">
|
||||
<h5 class="mb-0">Keamanan Akun</h5>
|
||||
</div>
|
||||
<p class="small text-muted">Ubah password Anda secara berkala untuk menjaga keamanan akun.</p>
|
||||
<a href="{{ route('profile.edit') }}#security" class="btn btn-outline-secondary rounded-pill">Ubah
|
||||
Password</a>
|
||||
</div>
|
||||
{{-- Kolom Kanan: Aktivitas Personal Guru --}}
|
||||
<div class="col-lg-4">
|
||||
@include('profile.partials.personal-activities', ['bukuOffline' => $bukuOffline, 'bukuOnline' => $bukuOnline])
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
|
||||
{{-- =================================================================== --}}
|
||||
{{-- TAMPILAN PROFIL UNTUK SISWA (DEFAULT) --}}
|
||||
{{-- =================================================================== --}}
|
||||
@else
|
||||
<h1 class="h2 mb-4">Profil Saya</h1>
|
||||
<div class="row g-4">
|
||||
{{-- Kolom Kiri: Info & Statistik Siswa --}}
|
||||
<div class="col-lg-8">
|
||||
{{-- Info Siswa --}}
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<div class="d-flex align-items-center">
|
||||
<img src="https://ui-avatars.com/api/?name={{ urlencode($user->name) }}&background=435ebe&color=fff&size=80&rounded=true" alt="Foto Profil" class="rounded-circle">
|
||||
<div class="ms-4">
|
||||
<h4 class="fw-bold mb-1">{{ $user->name }}</h4>
|
||||
<span class="badge rounded-pill bg-primary-subtle text-primary-emphasis">{{ Str::title($user->role) }}</span>
|
||||
</div>
|
||||
<a href="{{ route('profile.edit') }}" class="btn btn-outline-primary rounded-pill ms-auto"><i class="bi bi-pencil-square me-2"></i>Edit Profil</a>
|
||||
</div>
|
||||
<hr class="my-4">
|
||||
<h5 class="fw-bold mb-3">Informasi Personal</h5>
|
||||
<div class="row g-3">
|
||||
<div class="col-md-6"><small class="text-muted">NISN</small><p class="fw-semibold mb-0">{{ $user->nisn ?? 'N/A' }}</p></div>
|
||||
<div class="col-md-6"><small class="text-muted">Email</small><p class="fw-semibold mb-0">{{ $user->email }}</p></div>
|
||||
<div class="col-md-6"><small class="text-muted">Nomor HP</small><p class="fw-semibold mb-0">{{ $user->nomor_hp ?? 'N/A' }}</p></div>
|
||||
<div class="col-md-6"><small class="text-muted">Kelas</small><p class="fw-semibold mb-0">{{ $user->kelas ?? 'N/A' }}</p></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Statistik Personal Siswa --}}
|
||||
<div class="card border-0">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="fw-bold mb-3">Statistik Saya</h5>
|
||||
<div class="d-flex justify-content-around text-center">
|
||||
@foreach ($statistik as $stat)
|
||||
<div class="flex-fill">
|
||||
<i class="bi {{ $stat['icon'] }} fs-4 text-{{ $stat['color'] }}"></i>
|
||||
<h5 class="fw-bolder mb-0 mt-2">{{ $stat['value'] }}</h5>
|
||||
<small class="text-muted">{{ $stat['label'] }}</small>
|
||||
</div>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{-- Kolom Kanan: Aktivitas Personal Siswa --}}
|
||||
<div class="col-lg-4">
|
||||
@include('profile.partials.personal-activities', ['bukuOffline' => $bukuOffline, 'bukuOnline' => $bukuOnline])
|
||||
</div>
|
||||
</div>
|
||||
@endif
|
||||
</x-app-layout>
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
{{-- Card Buku yang Dipinjam --}}
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="fw-bold mb-0">Buku yang Dipinjam</h5>
|
||||
<ul class="list-group list-group-flush mt-3">
|
||||
@forelse ($bukuOffline as $buku)
|
||||
<li class="list-group-item px-0">
|
||||
<h6 class="fw-semibold mb-1">{{ $buku['judul'] }}</h6>
|
||||
<small class="text-muted">{{ $buku['penulis'] }}</small>
|
||||
<span class="badge bg-danger-subtle text-danger-emphasis float-end">Sisa {{ $buku['sisa_hari'] }} hari</span>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item px-0 text-center text-muted small py-3">Tidak ada buku yang sedang dipinjam.</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Riwayat Online --}}
|
||||
<div class="card border-0 mb-4">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="fw-bold mb-0">Baca Buku Online</h5>
|
||||
<ul class="list-group list-group-flush mt-3">
|
||||
@forelse ($bukuOnline as $buku)
|
||||
<li class="list-group-item px-0">
|
||||
<h6 class="fw-semibold mb-1">{{ $buku['judul'] }}</h6>
|
||||
<small class="text-muted">{{ $buku['penulis'] }}</small>
|
||||
<span class="badge bg-primary-subtle text-primary-emphasis float-end">{{ $buku['progress'] }}%</span>
|
||||
</li>
|
||||
@empty
|
||||
<li class="list-group-item px-0 text-center text-muted small py-3">Tidak ada riwayat buku yang dibaca.</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Card Keamanan Akun --}}
|
||||
<div class="card border-0">
|
||||
<div class="card-body p-4">
|
||||
<h5 class="fw-bold mb-3">Keamanan Akun</h5>
|
||||
<p class="small text-muted">Ubah password Anda secara berkala.</p>
|
||||
<a href="{{ route('profile.edit') }}" class="btn btn-outline-secondary rounded-pill">Ubah Password</a>
|
||||
</div>
|
||||
</div>
|
||||
Loading…
Reference in New Issue