This commit is contained in:
Stephen Gesityan 2025-05-10 18:15:10 +07:00
parent 6000103c21
commit b4d73f7d4d
4 changed files with 313 additions and 268 deletions

View File

@ -1,174 +1,173 @@
@extends('layouts.app')
@extends('layouts.main')
@section('content')
<div class="py-12 animated-bg">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card shadow-lg border-0 rounded-3 overflow-hidden">
<div class="card-header bg-gradient-to-r from-indigo-600 to-blue-500 text-white p-3">
<h2 class="mb-0 d-flex align-items-center">
<i class="fas fa-user-cog me-2"></i>{{ __('Account Settings') }}
<div class="min-h-screen bg-gray-50 py-12">
<div class="container mx-auto px-4 lg:px-44">
<div class="flex justify-center">
<div class="w-full max-w-2xl">
<div class="bg-white rounded-xl shadow-lg overflow-hidden">
<div class="bg-gradient-to-r from-blue-600 to-indigo-600 px-6 py-4">
<h2 class="text-xl font-semibold text-white flex items-center">
<i class="fas fa-user-cog mr-2"></i>{{ __('Pengaturan Akun') }}
</h2>
</div>
<div class="card-body p-4">
<div class="p-6">
@if (session('message'))
<div class="alert alert-success d-flex align-items-center border-0 shadow-sm mb-4" role="alert">
<div class="me-2">
@if (session('message') || session('success'))
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-4 rounded-md flex items-center"
role="alert">
<div class="mr-2">
<i class="fas fa-check-circle"></i>
</div>
<div>
{{ session('message') }}
{{ session('message') ?? session('success') }}
</div>
</div>
@endif
@if (session('success'))
<div class="alert alert-success d-flex align-items-center border-0 shadow-sm mb-4" role="alert">
<div class="me-2">
<i class="fas fa-check-circle"></i>
</div>
<div>
{{ session('success') }}
</div>
</div>
@endif
<form method="POST" action="{{ route('account.update') }}">
<form method="POST" action="{{ route('account.update') }}" class="space-y-6">
@csrf
@method('PUT')
<!-- Name -->
<div class="mb-4">
<label for="name" class="form-label fw-medium">
<i class="fas fa-user text-primary me-1"></i>{{ __('Name') }}
<div>
<label for="name" class="block text-sm font-medium text-gray-700 mb-1">
<i class="fas fa-user text-blue-600 mr-1"></i>{{ __('Nama') }}
</label>
<div class="input-group">
<span class="input-group-text bg-light">
<div class="flex rounded-md shadow-sm">
<span
class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500">
<i class="fas fa-user-edit"></i>
</span>
<input id="name" type="text" name="name" value="{{ old('name', $user->name) }}"
required autofocus class="form-control border-start-0"
placeholder="Enter your name">
required autofocus
class="focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded-none rounded-r-md border-gray-300 p-1"
placeholder="Masukkan nama">
</div>
@error('name')
<div class="text-danger mt-1 small"><i
class="fas fa-exclamation-circle me-1"></i>{{ $message }}</div>
<div class="text-red-500 mt-1 text-sm"><i
class="fas fa-exclamation-circle mr-1"></i>{{ $message }}</div>
@enderror
</div>
<!-- Email -->
<div class="mb-4">
<label for="email" class="form-label fw-medium">
<i class="fas fa-envelope text-primary me-1"></i>{{ __('Email') }}
<div>
<label for="email" class="block text-sm font-medium text-gray-700 mb-1">
<i class="fas fa-envelope text-blue-600 mr-1"></i>{{ __('Email') }}
</label>
<div class="input-group">
<span class="input-group-text bg-light">
<div class="flex rounded-md shadow-sm">
<span
class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500">
<i class="fas fa-at"></i>
</span>
<input id="email" type="email" name="email" value="{{ old('email', $user->email) }}"
required class="form-control border-start-0" placeholder="Enter your email">
required
class="focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded-none rounded-r-md border-gray-300 p-1"
placeholder="Masukkan email">
</div>
@error('email')
<div class="text-danger mt-1 small"><i
class="fas fa-exclamation-circle me-1"></i>{{ $message }}</div>
<div class="text-red-500 mt-1 text-sm"><i
class="fas fa-exclamation-circle mr-1"></i>{{ $message }}</div>
@enderror
@if ($user->email)
<div class="mt-2 small d-flex align-items-center">
<div class="mt-2 text-sm flex items-center">
@if ($user->hasVerifiedEmail())
<span class="text-success d-flex align-items-center">
<i class="fas fa-check-circle me-1"></i> {{ __('Email verified') }}
<span class="text-green-600 flex items-center">
<i class="fas fa-check-circle mr-1"></i> {{ __('Email terverifikasi') }}
</span>
@else
<span class="text-warning d-flex align-items-center">
<i class="fas fa-exclamation-circle me-1"></i> {{ __('Not Verified') }}
<span class="text-yellow-600 flex items-center">
<i class="fas fa-exclamation-circle mr-1"></i> {{ __('Belum Terverifikasi') }}
</span>
<a href="{{ route('verification.resend') }}"
class="ms-2 text-primary text-decoration-none">
{{ __('Resend verification email') }}
class="ml-2 text-blue-600 hover:underline">
{{ __('Kirim ulang email verifikasi') }}
</a>
@endif
</div>
@endif
</div>
<div class="card mt-4 mb-4 shadow-sm border-0">
<div class="card-header bg-light">
<h3 class="mb-0 fs-5 fw-semibold text-primary">
<i class="fas fa-lock me-2"></i>{{ __('Change Password') }}
<div class="bg-gray-50 rounded-lg p-4 mt-6 mb-6">
<h3 class="text-lg font-semibold text-blue-600 mb-4 flex items-center">
<i class="fas fa-lock mr-2"></i>{{ __('Ubah Password') }}
</h3>
</div>
<div class="card-body">
<!-- Current Password -->
<div class="mb-3">
<label for="current_password" class="form-label fw-medium">
<i class="fas fa-key text-primary me-1"></i>{{ __('Current Password') }}
<div class="mb-4">
<label for="current_password" class="block text-sm font-medium text-gray-700 mb-1">
<i class="fas fa-key text-blue-600 mr-1"></i>{{ __('Password Saat Ini') }}
</label>
<div class="input-group">
<span class="input-group-text bg-light">
<div class="flex rounded-md shadow-sm">
<span
class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500">
<i class="fas fa-lock"></i>
</span>
<input id="current_password" type="password" name="current_password"
class="form-control border-start-0"
placeholder="Enter current password">
<button class="btn btn-outline-secondary" type="button"
id="toggleCurrentPassword">
class="focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded-none border-gray-300 p-1"
placeholder="Masukkan password saat ini">
<button type="button" id="toggleCurrentPassword"
class="inline-flex items-center px-3 rounded-r-md border border-l-0 border-gray-300 bg-gray-50 text-gray-500 hover:bg-gray-100">
<i class="fas fa-eye"></i>
</button>
</div>
@error('current_password')
<div class="text-danger mt-1 small"><i
class="fas fa-exclamation-circle me-1"></i>{{ $message }}</div>
<div class="text-red-500 mt-1 text-sm"><i
class="fas fa-exclamation-circle mr-1"></i>{{ $message }}</div>
@enderror
</div>
<!-- New Password -->
<div class="mb-3">
<label for="password" class="form-label fw-medium">
<i class="fas fa-lock-open text-primary me-1"></i>{{ __('New Password') }}
<div class="mb-4">
<label for="password" class="block text-sm font-medium text-gray-700 mb-1">
<i class="fas fa-lock-open text-blue-600 mr-1"></i>{{ __('Password Baru') }}
</label>
<div class="input-group">
<span class="input-group-text bg-light">
<div class="flex rounded-md shadow-sm">
<span
class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500">
<i class="fas fa-key"></i>
</span>
<input id="password" type="password" name="password"
class="form-control border-start-0" placeholder="Enter new password">
<button class="btn btn-outline-secondary" type="button"
id="toggleNewPassword">
class="focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded-none border-gray-300 p-1"
placeholder="Masukkan password baru">
<button type="button" id="toggleNewPassword"
class="inline-flex items-center px-3 rounded-r-md border border-l-0 border-gray-300 bg-gray-50 text-gray-500 hover:bg-gray-100">
<i class="fas fa-eye"></i>
</button>
</div>
@error('password')
<div class="text-danger mt-1 small"><i
class="fas fa-exclamation-circle me-1"></i>{{ $message }}</div>
<div class="text-red-500 mt-1 text-sm"><i
class="fas fa-exclamation-circle mr-1"></i>{{ $message }}</div>
@enderror
</div>
<!-- Confirm New Password -->
<div class="mb-3">
<label for="password_confirmation" class="form-label fw-medium">
<i class="fas fa-check-double text-primary me-1"></i>{{ __('Confirm New Password') }}
<div>
<label for="password_confirmation"
class="block text-sm font-medium text-gray-700 mb-1">
<i
class="fas fa-check-double text-blue-600 mr-1"></i>{{ __('Konfirmasi Password Baru') }}
</label>
<div class="input-group">
<span class="input-group-text bg-light">
<div class="flex rounded-md shadow-sm">
<span
class="inline-flex items-center px-3 rounded-l-md border border-r-0 border-gray-300 bg-gray-50 text-gray-500">
<i class="fas fa-key"></i>
</span>
<input id="password_confirmation" type="password" name="password_confirmation"
class="form-control border-start-0" placeholder="Confirm new password">
<button class="btn btn-outline-secondary" type="button"
id="toggleConfirmPassword">
class="focus:ring-blue-500 focus:border-blue-500 flex-1 block w-full rounded-none border-gray-300 p-1"
placeholder="Konfirmasi password baru">
<button type="button" id="toggleConfirmPassword"
class="inline-flex items-center px-3 rounded-r-md border border-l-0 border-gray-300 bg-gray-50 text-gray-500 hover:bg-gray-100">
<i class="fas fa-eye"></i>
</button>
</div>
</div>
</div>
</div>
<div class="d-flex justify-content-end mt-4">
<div class="flex justify-end mt-6">
<button type="submit"
class="btn btn-primary-custom d-flex align-items-center">
<i class="fas fa-save me-2"></i>{{ __('Update Account') }}
class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded flex items-center transition">
<i class="fas fa-save mr-2"></i>{{ __('Simpan Perubahan') }}
</button>
</div>
</form>
@ -177,29 +176,11 @@ class="btn btn-primary-custom d-flex align-items-center">
</div>
</div>
</div>
</div>
</div>
<style>
@keyframes fade-in-down {
0% {
opacity: 0;
transform: translateY(-10px);
}
100% {
opacity: 1;
transform: translateY(0);
}
}
.animate-fade-in-down {
animation: fade-in-down 0.5s ease-out;
}
</style>
<script>
<script>
// Toggle password visibility
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('DOMContentLoaded', function () {
const toggleCurrentPassword = document.getElementById('toggleCurrentPassword');
const toggleNewPassword = document.getElementById('toggleNewPassword');
const toggleConfirmPassword = document.getElementById('toggleConfirmPassword');
@ -208,20 +189,20 @@ class="btn btn-primary-custom d-flex align-items-center">
const newPassword = document.getElementById('password');
const confirmPassword = document.getElementById('password_confirmation');
if(toggleCurrentPassword) {
toggleCurrentPassword.addEventListener('click', function() {
if (toggleCurrentPassword) {
toggleCurrentPassword.addEventListener('click', function () {
togglePasswordVisibility(currentPassword, this);
});
}
if(toggleNewPassword) {
toggleNewPassword.addEventListener('click', function() {
if (toggleNewPassword) {
toggleNewPassword.addEventListener('click', function () {
togglePasswordVisibility(newPassword, this);
});
}
if(toggleConfirmPassword) {
toggleConfirmPassword.addEventListener('click', function() {
if (toggleConfirmPassword) {
toggleConfirmPassword.addEventListener('click', function () {
togglePasswordVisibility(confirmPassword, this);
});
}
@ -241,5 +222,5 @@ function togglePasswordVisibility(input, button) {
}
}
});
</script>
</script>
@endsection

View File

@ -12,15 +12,18 @@
body {
font-family: 'Inter', sans-serif;
}
.nav-item {
transition: all 0.3s ease;
}
.nav-item.active {
position: relative;
background-color: rgb(239, 246, 255);
color: rgb(37, 99, 235);
font-weight: 500;
}
.nav-item.active::before {
content: '';
position: absolute;
@ -31,10 +34,12 @@
background-color: rgb(37, 99, 235);
border-radius: 0 4px 4px 0;
}
.nav-item:hover:not(.active) {
background-color: rgb(249, 250, 251);
color: rgb(55, 65, 81);
}
.dropdown-transition {
transition: all 0.2s ease-out;
}
@ -44,7 +49,8 @@
<body x-data="{ sidebarOpen: true, userDropdownOpen: false }" class="bg-gray-50">
<div class="flex h-screen overflow-hidden">
<!-- Sidebar Overlay -->
<div x-show="sidebarOpen" @click="sidebarOpen = false" class="fixed inset-0 z-20 bg-black bg-opacity-50 lg:hidden"></div>
<div x-show="sidebarOpen" @click="sidebarOpen = false"
class="fixed inset-0 z-20 bg-black bg-opacity-50 lg:hidden"></div>
<!-- Sidebar -->
<div :class="sidebarOpen ? 'translate-x-0' : '-translate-x-full lg:translate-x-0 lg:w-20'"
@ -54,79 +60,89 @@ class="fixed inset-y-0 left-0 z-30 w-64 bg-white shadow-lg transition-all durati
<div class="flex items-center justify-between h-16 px-4 border-b">
<div class="flex items-center space-x-2">
<div class="p-2 bg-blue-600 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-white" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-white" fill="none"
viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M13 10V3L4 14h7v7l9-11h-7z" />
</svg>
</div>
<span class="font-bold text-lg text-gray-800" x-show="sidebarOpen">VenueApp</span>
</div>
<button @click="sidebarOpen = !sidebarOpen" class="p-1 rounded-md hover:bg-gray-100 focus:outline-none">
<svg x-show="sidebarOpen" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 19l-7-7 7-7m8 14l-7-7 7-7" />
<svg x-show="sidebarOpen" xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 text-gray-500"
fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M11 19l-7-7 7-7m8 14l-7-7 7-7" />
</svg>
<svg x-show="!sidebarOpen" class="w-6 h-6 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16m-7 6h7"></path>
<svg x-show="!sidebarOpen" class="w-6 h-6 text-gray-500" fill="none" stroke="currentColor"
viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 6h16M4 12h16m-7 6h7"></path>
</svg>
</button>
</div>
<!-- Navigation -->
<div class="px-2 py-4">
<div x-show="sidebarOpen" class="text-xs font-semibold text-gray-400 uppercase tracking-wider px-3 mb-2">
<div x-show="sidebarOpen"
class="text-xs font-semibold text-gray-400 uppercase tracking-wider px-3 mb-2">
Menu Utama
</div>
<nav class="space-y-1">
<a href="{{ route('admin.dashboard') }}"
class="nav-item flex items-center px-3 py-2.5 rounded-lg {{ request()->routeIs('admin.dashboard') ? 'active' : '' }}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" />
</svg>
<span x-show="sidebarOpen">Dashboard</span>
</a>
<a href="{{ route('admin.tables.index') }}"
class="nav-item flex items-center px-3 py-2.5 rounded-lg {{ request()->routeIs('admin.tables.*') ? 'active' : '' }}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" />
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4" />
</svg>
<span x-show="sidebarOpen">Kelola Meja</span>
</a>
<a href="{{ route('admin.bookings.index') }}"
class="nav-item flex items-center px-3 py-2.5 rounded-lg {{ request()->routeIs('admin.bookings.*') ? 'active' : '' }}">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
<span x-show="sidebarOpen">Daftar Booking</span>
</a>
<a href="#"
class="nav-item flex items-center px-3 py-2.5 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197M13 7a4 4 0 11-8 0 4 4 0 018 0z" />
</svg>
<span x-show="sidebarOpen">Data User</span>
</a>
</nav>
<div x-show="sidebarOpen" class="text-xs font-semibold text-gray-400 uppercase tracking-wider px-3 mb-2 mt-6">
<div x-show="sidebarOpen"
class="text-xs font-semibold text-gray-400 uppercase tracking-wider px-3 mb-2 mt-6">
Sistem
</div>
<nav class="space-y-1">
<a href="#"
class="nav-item flex items-center px-3 py-2.5 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
<a href="#" class="nav-item flex items-center px-3 py-2.5 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
<span x-show="sidebarOpen">Notifikasi</span>
<span class="ml-auto bg-red-500 text-white px-2 py-0.5 rounded-full text-xs" x-show="sidebarOpen">3</span>
<span class="ml-auto bg-red-500 text-white px-2 py-0.5 rounded-full text-xs"
x-show="sidebarOpen">3</span>
</a>
<a href="#"
class="nav-item flex items-center px-3 py-2.5 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
<a href="#" class="nav-item flex items-center px-3 py-2.5 rounded-lg">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span x-show="sidebarOpen">Pengaturan</span>
</a>
@ -138,7 +154,8 @@ class="nav-item flex items-center px-3 py-2.5 rounded-lg">
<div x-data="{ open: false }" class="relative p-4">
<button @click="open = !open" class="flex items-center w-full text-left focus:outline-none">
<div class="flex-shrink-0">
<div class="w-8 h-8 bg-blue-600 rounded-full flex items-center justify-center text-white font-semibold">
<div
class="w-8 h-8 bg-blue-600 rounded-full flex items-center justify-center text-white font-semibold">
{{ substr(auth()->user()->name, 0, 1) }}
</div>
</div>
@ -146,19 +163,22 @@ class="nav-item flex items-center px-3 py-2.5 rounded-lg">
<p class="text-sm font-medium text-gray-800 truncate">{{ auth()->user()->name }}</p>
<p class="text-xs text-gray-500 truncate">{{ auth()->user()->email }}</p>
</div>
<svg x-show="sidebarOpen" xmlns="http://www.w3.org/2000/svg" class="ml-auto h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<svg x-show="sidebarOpen" xmlns="http://www.w3.org/2000/svg"
class="ml-auto h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
<!-- Dropdown -->
<div x-show="open" @click.outside="open = false" class="absolute bottom-full left-0 mb-1 w-full bg-white rounded-lg shadow-lg border border-gray-200 py-1 dropdown-transition">
<div x-show="open" @click.outside="open = false"
class="absolute bottom-full left-0 mb-1 w-full bg-white rounded-lg shadow-lg border border-gray-200 py-1 dropdown-transition">
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Profile</a>
<a href="#" class="block px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">Settings</a>
<div class="border-t border-gray-200 my-1"></div>
<form method="POST" action="{{ route('logout') }}">
@csrf
<button type="submit" class="block w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-gray-100">
<button type="submit"
class="block w-full text-left px-4 py-2 text-sm text-red-600 hover:bg-gray-100">
Logout
</button>
</form>
@ -172,9 +192,12 @@ class="nav-item flex items-center px-3 py-2.5 rounded-lg">
<!-- Top Header -->
<header class="bg-white shadow-sm lg:hidden">
<div class="px-4 sm:px-6 lg:px-8 py-4 flex items-center justify-between">
<button @click="sidebarOpen = !sidebarOpen" class="p-1 rounded-md text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 lg:hidden">
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
<button @click="sidebarOpen = !sidebarOpen"
class="p-1 rounded-md text-gray-500 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 lg:hidden">
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M4 6h16M4 12h16M4 18h16"></path>
</svg>
</button>
<div class="lg:hidden">

View File

@ -28,8 +28,6 @@
</a>
<div class="flex items-center space-x-4">
<a href="#"><i class="fa fa-shopping-cart text-xl text-gray-700"></i></a>
<!-- Mobile hamburger -->
<button @click="isMobileMenuOpen = !isMobileMenuOpen"
class="block lg:hidden border-l pl-4 border-gray-300 focus:outline-none">
@ -159,10 +157,6 @@ class="w-full border px-4 py-2 rounded" required>
<div class="flex items-center justify-between">
<div class="flex items-center">
<input class="mr-2" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
<label class="text-sm text-gray-600" for="remember">
Ingat saya
</label>
</div>
<a href="{{ route('password.request') }}" class="text-sm text-primary hover:underline">
Lupa Password?

View File

@ -142,6 +142,9 @@ class="border rounded-lg shadow-md p-4 mb-4">
<script src="https://app.sandbox.midtrans.com/snap/snap.js"
data-client-key="{{ config('midtrans.client_key') }}"></script>
<script>
// Custom event for refreshing pending bookings across components
const refreshPendingBookingsEvent = new Event('refresh-pending-bookings');
function updateClock() {
const now = new Date();
const options = { timeZone: 'Asia/Jakarta', hour12: false };
@ -153,28 +156,36 @@ function updateClock() {
// Format functions for pending bookings
function formatDateTime(dateTimeStr) {
const date = new Date(dateTimeStr);
// Explicitly use Jakarta timezone for display
return new Intl.DateTimeFormat('id-ID', {
// Parse the ISO date string without timezone conversion
const parts = dateTimeStr.split(/[^0-9]/);
const year = parseInt(parts[0]);
const month = parseInt(parts[1]) - 1; // JS months are 0-based
const day = parseInt(parts[2]);
const hour = parseInt(parts[3]);
const minute = parseInt(parts[4]);
const dateFormatter = new Intl.DateTimeFormat('id-ID', {
day: '2-digit',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: 'Asia/Jakarta'
}).format(date);
});
// Format the date and time separately to avoid timezone issues
const dateObj = new Date(year, month, day);
return dateFormatter.format(dateObj) + ' ' +
(hour.toString().padStart(2, '0') + ':' +
minute.toString().padStart(2, '0'));
}
function formatTime(timeStr) {
const date = new Date(timeStr);
// Explicitly use Jakarta timezone for display
return new Intl.DateTimeFormat('id-ID', {
hour: '2-digit',
minute: '2-digit',
hour12: false,
timeZone: 'Asia/Jakarta'
}).format(date);
// Parse the ISO date string without timezone conversion
const parts = timeStr.split(/[^0-9]/);
const hour = parseInt(parts[3]);
const minute = parseInt(parts[4]);
// Format time manually to avoid timezone issues
return hour.toString().padStart(2, '0') + ':' +
minute.toString().padStart(2, '0');
}
function formatPrice(price) {
@ -190,6 +201,13 @@ function formatPrice(price) {
init() {
this.fetchPendingBookings();
// Listen for the custom event to refresh pending bookings
document.addEventListener('refresh-pending-bookings', () => {
console.log('Refreshing pending bookings from event');
this.fetchPendingBookings();
this.showPendingBookings = true; // Auto-expand the section
});
},
fetchPendingBookings() {
@ -208,6 +226,13 @@ function formatPrice(price) {
// Log jumlah pending bookings yang ditemukan
console.log("Found", this.pendingBookings.length, "pending bookings");
// If we have pending bookings and this was triggered by payment cancellation,
// make sure to show them
if (this.pendingBookings.length > 0 && window.justClosedPayment) {
this.showPendingBookings = true;
window.justClosedPayment = false;
}
})
.catch(error => console.error('Error fetching pending bookings:', error));
},
@ -392,6 +417,9 @@ function formatPrice(price) {
const start_time = `${today} ${selectedTime}`;
const end_time = `${today} ${endTimeFormatted}`;
// Track that we're creating a new booking
window.creatingNewBooking = true;
// Kirim ke backend untuk membuat payment intent (tanpa membuat booking dulu)
fetch('/booking/payment-intent', {
method: 'POST',
@ -430,10 +458,24 @@ function formatPrice(price) {
onError: (result) => {
alert('Pembayaran gagal');
this.isLoading = false;
// Reset the state
window.creatingNewBooking = false;
},
onClose: () => {
alert('Anda menutup popup tanpa menyelesaikan pembayaran');
this.isLoading = false;
// Set flag to indicate payment popup was just closed
window.justClosedPayment = true;
// Only trigger the refresh if we were creating a new booking
if (window.creatingNewBooking) {
// Reset the flag
window.creatingNewBooking = false;
// Dispatch the custom event to refresh pending bookings
document.dispatchEvent(refreshPendingBookingsEvent);
}
}
});
})
@ -441,6 +483,7 @@ function formatPrice(price) {
console.error('Payment intent error:', err);
alert('Gagal membuat payment: ' + err.message);
this.isLoading = false;
window.creatingNewBooking = false;
});
},
@ -470,6 +513,9 @@ function formatPrice(price) {
.then(data => {
alert('Pembayaran dan booking berhasil!');
// Reset the flag
window.creatingNewBooking = false;
// Refresh component data
document.dispatchEvent(new CustomEvent('booking-completed'));
@ -480,6 +526,7 @@ function formatPrice(price) {
console.error('Booking error:', err);
alert('Pembayaran berhasil tetapi gagal menyimpan booking: ' + err.message);
this.isLoading = false;
window.creatingNewBooking = false;
});
},