feat: customize error UI

This commit is contained in:
myuqinurrohman 2025-04-10 14:01:14 +07:00
parent 8cd1eb9c00
commit a40fcca9b1
24 changed files with 452 additions and 1 deletions

View File

@ -186,4 +186,8 @@ public function contact(){
return view('homepage.contacts.index', $data); return view('homepage.contacts.index', $data);
} }
public function customError($code){
abort($code);
}
} }

View File

@ -21,7 +21,7 @@ public function handle(Request $request, Closure $next, ...$roles): Response
} }
if (!in_array(Auth::user()->role_id, $roles)) { if (!in_array(Auth::user()->role_id, $roles)) {
return abort(403, 'Anda tidak memiliki akses ke halaman ini.'); abort(403);
} }
return $next($request); return $next($request);

View File

@ -0,0 +1,107 @@
* {
-webkit-box-sizing: border-box;
box-sizing: border-box;
}
body {
padding: 0;
margin: 0;
}
#notfound {
position: relative;
height: 100vh;
}
#notfound .notfound {
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
}
.notfound {
max-width: 520px;
width: 100%;
line-height: 1.4;
}
.notfound>div:first-child {
padding-left: 200px;
padding-top: 12px;
height: 170px;
margin-bottom: 20px;
}
.notfound .notfound-404 {
position: absolute;
left: 0;
top: 0;
width: 170px;
height: 170px;
background: #e01818;
border-radius: 7px;
-webkit-box-shadow: 0px 0px 0px 10px #e01818 inset, 0px 0px 0px 20px #fff inset;
box-shadow: 0px 0px 0px 10px #e01818 inset, 0px 0px 0px 20px #fff inset;
}
.notfound .notfound-404 h1 {
font-family: 'Chango', cursive;
color: #fff;
font-size: 118px;
margin: 0px;
position: absolute;
left: 50%;
top: 50%;
-webkit-transform: translate(-50%, -50%);
-ms-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
display: inline-block;
height: 60px;
line-height: 60px;
}
.notfound h2 {
font-family: 'Chango', cursive;
font-size: 68px;
color: #222;
font-weight: 400;
text-transform: uppercase;
margin: 0px;
line-height: 1.1;
}
.notfound p {
font-family: 'Montserrat', sans-serif;
font-size: 16px;
font-weight: 400;
color: #222;
margin-top: 5px;
}
.notfound a {
font-family: 'Montserrat', sans-serif;
color: #e01818;
font-weight: 400;
text-decoration: none;
}
@media only screen and (max-width: 480px) {
.notfound {
padding-left: 15px;
padding-right: 15px;
}
.notfound>div:first-child {
padding: 0px;
height: auto;
}
.notfound .notfound-404 {
position: relative;
margin-bottom: 15px;
}
.notfound h2 {
font-size: 42px;
}
}

View File

@ -0,0 +1,76 @@
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f9fbfd;
color: #333;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
text-align: center;
padding: 20px;
}
.error-container {
max-width: 600px;
padding: 20px;
}
.error-container img {
max-width: 300px;
margin-bottom: 30px;
}
h1 {
font-size: 36px;
margin-bottom: 7px;
color: #2c3e50;
}
p {
font-size: 16px;
line-height: 1.6;
margin-bottom: 30px;
color: #555;
}
.back{
display: inline-block;
text-decoration: none;
background-color: #3498db;
color: #fff;
padding: 12px 24px;
border-radius: 30px;
transition: background 0.3s ease;
font-weight: 500;
/* margin-bottom: 2rem; */
}
.back:hover {
background-color: #2980b9;
}
footer{
margin-top: 2rem;
}
.social-links{
/* margin-top: 2rem; */
display: flex;
flex-wrap: wrap;
/* background-color: red; */
}
.social-links a{
margin: 0 0.5rem;
}
.social-links a img{
width: 1.5rem;
}

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 23 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 40 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 18 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 91 KiB

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>400 Bad Request - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/400-error.svg') }}" alt="Error Illustration" />
<h1>Oops! Bad Request</h1>
<p>Permintaanmu nggak bisa diproses karena formatnya kurang pas. Yuk dicek lagi dan coba ulangi!</p>
<a href="{{Auth::check() ? route('dashboard.overview') : route('homepage.landing')}}" class="back">Kembali</a>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>401 Unauthorized - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/401-error.svg') }}" alt="Error Illustration" />
<h1>Eh, Belum Login!</h1>
<p>Akses ke halaman ini butuh login dulu. Silakan masuk untuk lanjut.</p>
<a href="{{route('login')}}" class="back">Login</a>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>403 Forbidden - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/403-error.svg') }}" alt="Error Illustration" />
<h1>Akses Ditolak!</h1>
<p>Kamu tidak punya izin untuk membuka halaman ini. Kalau merasa ini salah, hubungi admin ya.</p>
<a href="{{Auth::check() ? route('dashboard.overview') : route('homepage.landing')}}" class="back">Kembali</a>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>404 Not Found - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/404-error.svg') }}" alt="Error Illustration" />
<h1>Oops! Halaman Tidak Ditemukan</h1>
<p>Halaman tidak ditemukan. Mungkin sudah dipindahkan atau tautannya salah.</p>
<a href="{{Auth::check() ? route('dashboard.overview') : route('homepage.landing')}}" class="back">Kembali</a>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>405 Method Not Allowed - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/405-error.svg') }}" alt="Error Illustration" />
<h1>Cara Ini Nggak Bisa</h1>
<p>Metode permintaan ini tidak didukung untuk halaman ini. Silakan coba cara lain.</p>
<a href="{{Auth::check() ? route('dashboard.overview') : route('homepage.landing')}}" class="back">Kembali</a>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>408 Request Time Out - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/408-error.svg') }}" alt="Error Illustration" />
<h1>Waktu Habis Nih</h1>
<p>Server nunggu terlalu lama dan akhirnya berhenti. Coba ulangi permintaanmu, ya!</p>
<a href="{{Auth::check() ? route('dashboard.overview') : route('homepage.landing')}}" class="back">Kembali</a>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>419 Page Expired - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/419-error.svg') }}" alt="Error Illustration" />
<h1>Oops! Sesi Kedaluwarsa</h1>
<p>Sesi kamu sudah habis, biasanya karena terlalu lama diam atau ada masalah token. Silakan muat ulang halaman dan coba lagi, ya!</p>
<a href="{{Auth::check() ? route('dashboard.overview') : route('homepage.landing')}}" class="back">Kembali</a>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,26 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>500 Internal Server Error - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/500-error.svg') }}" alt="Error Illustration" />
<h1>Oops! Ada Kesalahan di Server</h1>
<p>Terjadi gangguan tak terduga. Tim kami sedang memperbaikinya, coba lagi sebentar ya!</p>
<a href="{{Auth::check() ? route('dashboard.overview') : route('homepage.landing')}}" class="back">Kembali</a>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html lang="id">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>503 Service Unavailable - {{$app->app_title}}</title>
@include('partials.app.head')
<!-- Custom stlylesheet -->
<link type="text/css" rel="stylesheet" href="{{asset('assets/errors/css/style2.css')}}" />
</head>
<body>
<div class="error-container">
<img src="{{ asset('assets/errors/images/503-error.svg') }}" alt="Error Illustration" />
<h1>Layanan Sedang Sibuk</h1>
<p>Server sedang penuh atau dalam perbaikan. Mohon bersabar dan coba beberapa saat lagi.</p>
</div>
{{-- <footer>
@include('errors.partials.media-socials')
</footer> --}}
</body>
</html>

View File

@ -0,0 +1,20 @@
<div class="social-links">
<a href="{{filled($app->contact_facebook) ? $app->contact_facebook : 'javascript:void(0);'}}" {{filled($app->contact_facebook) ? 'target="_blank"' : ''}}>
<img src="{{ asset('assets/defaults/facebook.png') }}" alt="Facebook">
</a>
<a href="{{filled($app->contact_twitter) ? $app->contact_twitter : 'javascript:void(0);'}}" {{filled($app->contact_twitter) ? 'target="_blank"' : ''}}>
<img src="{{ asset('assets/defaults/twitter.png') }}" alt="Twitter">
</a>
<a href="{{filled($app->contact_instagram) ? $app->contact_instagram : 'javascript:void(0);'}}" {{filled($app->contact_instagram) ? 'target="_blank"' : ''}}>
<img src="{{ asset('assets/defaults/instagram.png') }}" alt="Instagram">
</a>
<a href="{{filled($app->contact_youtube) ? $app->contact_youtube : 'javascript:void(0);'}}" {{filled($app->contact_youtube) ? 'target="_blank"' : ''}}>
<img src="{{ asset('assets/defaults/youtube.png') }}" alt="YouTube">
</a>
<a href="{{filled($app->contact_whatsapp) ? $app->contact_whatsapp : 'javascript:void(0);'}}" {{filled($app->contact_whatsapp) ? 'target="_blank"' : ''}}>
<img src="{{ asset('assets/defaults/whatsapp.png') }}" alt="WhatsApp">
</a>
<a href="{{filled($app->contact_telegram) ? $app->contact_telegram : 'javascript:void(0);'}}" {{filled($app->contact_telegram) ? 'target="_blank"' : ''}}>
<img src="{{ asset('assets/defaults/telegram.png') }}" alt="Telegram">
</a>
</div>

View File

@ -50,6 +50,8 @@
Route::prefix('contacts')->name('contacts.')->group(function(){ Route::prefix('contacts')->name('contacts.')->group(function(){
Route::get('/', 'contact')->name('index'); Route::get('/', 'contact')->name('index');
}); });
Route::get('/errors/{code}', 'customError')->name('error.custom');
}); });
Route::prefix('auth')->group(function(){ Route::prefix('auth')->group(function(){