update tampilan

This commit is contained in:
alfinfadli16 2025-06-01 03:20:55 +07:00
parent 92c811bca3
commit 3c9f5774a5
13 changed files with 1388 additions and 871 deletions

View File

@ -398,4 +398,35 @@ public function activateAll($id)
return redirect()->route('paket')->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
}
}
/**
* Menampilkan detail paket untuk modal
*/
public function detail($id)
{
try {
$paket = Paket::with(['barangs'])->findOrFail($id);
return response()->json([
'id' => $paket->id,
'nama_paket' => $paket->nama_paket,
'jenis_paket' => $paket->jenis_paket,
'harga' => $paket->harga,
'stok' => $paket->stok,
'minimum_order' => $paket->minimum_order,
'keterangan' => $paket->keterangan,
'image' => $paket->image,
'barangs' => $paket->barangs->map(function($barang) {
return [
'nama_barang' => $barang->nama_barang,
'pivot' => [
'jumlah' => $barang->pivot->jumlah
]
];
})
]);
} catch (\Exception $e) {
return response()->json(['error' => 'Paket tidak ditemukan'], 404);
}
}
}

View File

@ -5,6 +5,7 @@
use App\Models\Sewa;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Storage;
class RiwayatController extends Controller
{
@ -28,7 +29,8 @@ public function index()
*/
public function show($id)
{
$sewa = Sewa::with('paket')->findOrFail($id);
$sewa = Sewa::with(['paket', 'kota', 'user'])
->findOrFail($id);
// Pastikan yang melihat adalah pemilik pesanan
if ($sewa->user_id != Auth::id() && !Auth::user()->tipe_pengguna == 'admin') {
@ -36,6 +38,23 @@ public function show($id)
->with('error', 'Anda tidak memiliki akses untuk melihat pesanan ini.');
}
// Jika request adalah AJAX, kembalikan response JSON
if (request()->ajax()) {
return response()->json([
'id' => $sewa->id,
'tanggal_pembayaran' => $sewa->tanggal_pembayaran ? $sewa->tanggal_pembayaran->format('d/m/Y H:i') : null,
'status_pembayaran' => $sewa->nominal_pembayaran
? ($sewa->nominal_pembayaran >= $sewa->total_harga ? 'Lunas' : 'DP ' . number_format(($sewa->nominal_pembayaran / $sewa->total_harga) * 100, 0) . '%')
: 'Belum Bayar',
'lokasi' => $sewa->lokasi,
'kota' => $sewa->kota,
'ongkir' => $sewa->ongkir,
'bukti_pembayaran' => $sewa->bukti_pembayaran,
'jenis_jaminan' => $sewa->jenis_jaminan,
'foto_jaminan' => $sewa->foto_jaminan
]);
}
return view('detail-riwayat', compact('sewa'));
}
@ -114,4 +133,37 @@ public function updateStatus(Request $request, $id)
return redirect()->route('admin.riwayat')
->with('success', 'Status pesanan berhasil diperbarui.');
}
/**
* Menghapus riwayat pemesanan
*/
public function hapus($id)
{
$sewa = Sewa::findOrFail($id);
// Pastikan yang menghapus adalah pemilik pesanan
if ($sewa->user_id != Auth::id()) {
return redirect()->route('riwayat')
->with('error', 'Anda tidak memiliki akses untuk menghapus pesanan ini.');
}
// Hanya bisa menghapus pesanan yang sudah selesai atau dibatalkan
if (!in_array($sewa->status, ['completed', 'dibatalkan'])) {
return redirect()->route('riwayat')
->with('error', 'Hanya pesanan yang sudah selesai atau dibatalkan yang dapat dihapus.');
}
// Hapus file bukti pembayaran dan jaminan jika ada
if ($sewa->bukti_pembayaran) {
Storage::disk('public')->delete($sewa->bukti_pembayaran);
}
if ($sewa->foto_jaminan) {
Storage::disk('public')->delete($sewa->foto_jaminan);
}
$sewa->delete();
return redirect()->route('riwayat')
->with('success', 'Riwayat pesanan berhasil dihapus.');
}
}

View File

@ -34,24 +34,16 @@ public function riwayat(Request $request)
{
$query = Sewa::with(['user', 'paket']);
// Jika view=all dan user adalah admin, tampilkan semua data sewa
if ($request->view == 'all' && auth()->user()->tipe_pengguna === 'admin') {
$sewas = $query->orderBy('created_at', 'desc')->get();
return view('sewa.index', [
'sewas' => $sewas,
'showDetailPenyewa' => true
]);
}
// Jika user biasa, hanya tampilkan sewa miliknya
if (auth()->user()->tipe_pengguna !== 'admin') {
$query->where('user_id', auth()->id());
}
$sewas = $query->orderBy('created_at', 'desc')->get();
return view('sewa.index', [
return view('sewa.riwayat', [
'sewas' => $sewas,
'showDetailPenyewa' => false
'showDetailPenyewa' => auth()->user()->tipe_pengguna === 'admin'
]);
}
@ -60,8 +52,24 @@ public function riwayat(Request $request)
*/
public function create($id)
{
$paket = Paket::with('ongkirKota')->findOrFail($id);
return view('sewa.create', compact('paket'));
try {
$paket = Paket::with('ongkirKota')->findOrFail($id);
// Cek apakah paket tersedia
$activeSewa = $paket->sewas()
->whereIn('status', ['confirmed', 'ongoing'])
->count();
if ($activeSewa >= $paket->stok) {
return redirect()->route('sewa.index')
->with('error', 'Maaf, paket ini sedang tidak tersedia.');
}
return view('sewa.create', compact('paket'));
} catch (\Exception $e) {
return redirect()->route('sewa.index')
->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
}
}
/**
@ -71,45 +79,63 @@ public function store(Request $request)
{
$request->validate([
'paket_id' => 'required|exists:pakets,id',
'tanggal_mulai' => 'required|date',
'tanggal_mulai' => 'required|date|after_or_equal:today',
'tanggal_selesai' => 'required|date|after_or_equal:tanggal_mulai',
'lokasi' => 'required|string',
'lokasi' => 'required|string|max:255',
'kota_id' => 'required|exists:paket_ongkir_kota,id',
'catatan' => 'nullable|string',
'catatan' => 'nullable|string|max:1000',
]);
try {
$paket = Paket::findOrFail($request->paket_id);
$kota = PaketOngkirKota::where('id', $request->kota_id)
->where('paket_id', $request->paket_id)
->firstOrFail();
// Hitung durasi sewa dalam hari
$paket = Paket::findOrFail($request->paket_id);
// Cek ketersediaan paket
$activeSewa = $paket->sewas()
->whereIn('status', ['confirmed', 'ongoing'])
->where(function($query) use ($request) {
$query->whereBetween('tanggal_mulai', [$request->tanggal_mulai, $request->tanggal_selesai])
->orWhereBetween('tanggal_selesai', [$request->tanggal_mulai, $request->tanggal_selesai]);
})
->count();
if ($activeSewa >= $paket->stok) {
return back()->with('error', 'Maaf, paket tidak tersedia untuk tanggal yang dipilih.');
}
// Cek minimum order
$tanggal_mulai = Carbon::parse($request->tanggal_mulai);
$tanggal_selesai = Carbon::parse($request->tanggal_selesai);
$durasi = $tanggal_mulai->diffInDays($tanggal_selesai) + 1;
// Ambil ongkir dari kota yang dipilih
$ongkir = $kota->biaya_ongkir;
// Hitung total harga
$total_harga = ($paket->harga * $durasi) + $ongkir;
$durasi = $tanggal_mulai->diffInDays($tanggal_selesai) + 1;
$sewa = Sewa::create([
if ($paket->minimum_order && $durasi < $paket->minimum_order) {
return back()->with('error', "Minimum pemesanan untuk paket ini adalah {$paket->minimum_order} hari.");
}
// Validasi kota tujuan
$kota = PaketOngkirKota::where('id', $request->kota_id)
->where('paket_id', $request->paket_id)
->firstOrFail();
// Hitung total harga
$total_harga = ($paket->harga * $durasi) + $kota->biaya_ongkir;
// Buat pesanan baru
$sewa = Sewa::create([
'user_id' => auth()->id(),
'paket_id' => $request->paket_id,
'paket_id' => $request->paket_id,
'kota_id' => $kota->id,
'ongkir' => $ongkir,
'tanggal_mulai' => $request->tanggal_mulai,
'tanggal_selesai' => $request->tanggal_selesai,
'lokasi' => $request->lokasi,
'catatan' => $request->catatan,
'total_harga' => $total_harga,
'ongkir' => $kota->biaya_ongkir,
'tanggal_mulai' => $request->tanggal_mulai,
'tanggal_selesai' => $request->tanggal_selesai,
'lokasi' => $request->lokasi,
'catatan' => $request->catatan,
'total_harga' => $total_harga,
'status' => 'pending'
]);
]);
return redirect()->route('sewa.show', $sewa->id)
->with('success', 'Pesanan berhasil dibuat. Silakan upload bukti pembayaran dan jaminan untuk melanjutkan proses penyewaan.');
return redirect()->route('sewa.show', $sewa->id)
->with('success', 'Silakan upload bukti pembayaran dan jaminan untuk melanjutkan proses penyewaan.');
} catch (\Exception $e) {
return back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
}
@ -124,60 +150,61 @@ public function show($id)
public function uploadBukti(Request $request, $id)
{
$request->validate([
'nominal_pembayaran' => 'required|numeric|min:0',
'bukti_pembayaran' => 'required|image|max:2048', // max 2MB
'nominal_pembayaran' => 'required|numeric|min:1',
'bukti_pembayaran' => 'required|image|max:2048',
'jenis_jaminan' => 'required|in:ktp,sim',
'foto_jaminan' => 'required|image|max:2048', // max 2MB
'foto_jaminan' => 'required|image|max:2048',
]);
try {
$sewa = Sewa::findOrFail($id);
// Validasi pemilik sewa
if ($sewa->user_id !== auth()->id()) {
return back()->with('error', 'Anda tidak memiliki akses untuk mengupload bukti pembayaran ini.');
}
// Validasi status sewa
if ($sewa->status !== 'pending') {
return back()->with('error', 'Status sewa tidak valid untuk upload bukti pembayaran.');
}
// Validasi nominal pembayaran
if ($request->nominal_pembayaran > $sewa->total_harga) {
return back()->with('error', 'Nominal pembayaran tidak boleh melebihi total harga sewa.');
}
// Pastikan yang mengupload adalah pemilik sewa
if ($sewa->user_id !== auth()->id()) {
return back()->with('error', 'Anda tidak memiliki akses untuk mengupload bukti pembayaran ini.');
}
// Pastikan status masih pending
if ($sewa->status !== 'pending') {
return back()->with('error', 'Status sewa tidak valid untuk upload bukti pembayaran.');
}
if ($request->hasFile('bukti_pembayaran') && $request->hasFile('foto_jaminan')) {
// Hapus file lama jika ada
// Upload bukti pembayaran
if ($request->hasFile('bukti_pembayaran')) {
if ($sewa->bukti_pembayaran) {
Storage::disk('public')->delete($sewa->bukti_pembayaran);
}
$pathBukti = $request->file('bukti_pembayaran')
->store('bukti-pembayaran/' . date('Y/m'), 'public');
}
// Upload foto jaminan
if ($request->hasFile('foto_jaminan')) {
if ($sewa->foto_jaminan) {
Storage::disk('public')->delete($sewa->foto_jaminan);
}
// Simpan bukti pembayaran dengan nama unik
$pathBukti = $request->file('bukti_pembayaran')->store('bukti-pembayaran/' . date('Y/m'), 'public');
// Simpan foto jaminan dengan nama unik
$pathJaminan = $request->file('foto_jaminan')->store('jaminan/' . date('Y/m'), 'public');
// Update data sewa - status tetap pending menunggu verifikasi admin
$sewa->update([
'bukti_pembayaran' => $pathBukti,
'jenis_jaminan' => $request->jenis_jaminan,
'foto_jaminan' => $pathJaminan,
'nominal_pembayaran' => $request->nominal_pembayaran,
'tanggal_pembayaran' => now(),
'status' => 'pending' // Status tetap pending sampai admin verifikasi
]);
return redirect()->route('riwayat')
->with('success', 'Bukti pembayaran dan jaminan berhasil diupload. Mohon tunggu verifikasi dari admin.');
$pathJaminan = $request->file('foto_jaminan')
->store('jaminan/' . date('Y/m'), 'public');
}
return back()->with('error', 'Terjadi kesalahan saat upload bukti pembayaran dan jaminan.');
// Update data sewa
$sewa->update([
'bukti_pembayaran' => $pathBukti ?? $sewa->bukti_pembayaran,
'jenis_jaminan' => $request->jenis_jaminan,
'foto_jaminan' => $pathJaminan ?? $sewa->foto_jaminan,
'nominal_pembayaran' => $request->nominal_pembayaran,
'tanggal_pembayaran' => now(),
'status' => 'pending'
]);
return redirect()->route('riwayat')
->with('success', 'Bukti pembayaran dan jaminan berhasil diupload. Mohon tunggu verifikasi dari admin.');
} catch (\Exception $e) {
return back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
}
@ -218,30 +245,35 @@ public function uploadJaminan(Request $request, $id)
*/
public function batal($id)
{
$sewa = Sewa::findOrFail($id);
// Pastikan yang membatalkan adalah pemilik sewa
if ($sewa->user_id !== auth()->id()) {
return back()->with('error', 'Anda tidak memiliki akses untuk membatalkan penyewaan ini.');
}
// Cek status sewa
if (!in_array($sewa->status, ['pending', 'confirmed'])) {
return back()->with('error', 'Penyewaan tidak dapat dibatalkan karena status sudah ' . $sewa->status);
}
try {
$sewa = Sewa::findOrFail($id);
// Validasi pemilik sewa
if ($sewa->user_id !== auth()->id()) {
return back()->with('error', 'Anda tidak memiliki akses untuk membatalkan penyewaan ini.');
}
// Validasi status sewa
if (!in_array($sewa->status, ['pending', 'confirmed'])) {
return back()->with('error', 'Penyewaan tidak dapat dibatalkan karena status sudah ' . $sewa->status_label);
}
// Jika status sudah confirmed, tambahkan catatan pembatalan
if ($sewa->status === 'confirmed') {
$sewa->catatan = $sewa->catatan . "\n[DIBATALKAN OLEH PENYEWA SETELAH DISETUJUI] - " . now();
// Jika status sudah confirmed, tambahkan catatan pembatalan
if ($sewa->status === 'confirmed') {
$sewa->catatan = trim($sewa->catatan . "\n[DIBATALKAN OLEH PENYEWA SETELAH DISETUJUI] - " . now());
}
// Update status menjadi dibatalkan
$sewa->status = 'dibatalkan';
$sewa->save();
return redirect()->route('riwayat')
->with('success', 'Penyewaan berhasil dibatalkan.' .
($sewa->status === 'confirmed' ? ' Mohon hubungi admin untuk informasi biaya pembatalan.' : ''));
} catch (\Exception $e) {
return back()->with('error', 'Terjadi kesalahan: ' . $e->getMessage());
}
// Update status menjadi dibatalkan
$sewa->status = 'dibatalkan';
$sewa->save();
return redirect()->route('sewa.riwayat')
->with('success', 'Penyewaan berhasil dibatalkan.' .
($sewa->status === 'confirmed' ? ' Mohon hubungi admin untuk informasi biaya pembatalan.' : ''));
}
/**

View File

@ -9,147 +9,196 @@
@endpush
@section('content')
<!-- Dashboard Stats -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<!-- Pengguna Stats -->
<div class="bg-gradient-to-br from-blue-50 to-blue-100 rounded-xl shadow-lg p-6">
<a href="{{ route('pengguna') }}" class="block">
<div class="flex items-center">
<div class="p-3 rounded-full bg-blue-500 text-white mr-4 shadow-md">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>
</div>
<div>
<p class="text-blue-600 text-sm font-medium">Total Pengguna</p>
<p class="text-3xl font-bold text-blue-800">{{ $stats['total_pengguna'] ?? 0 }}</p>
<div class="flex flex-col mt-2 space-y-2">
<div class="flex items-center text-sm text-blue-600">
<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="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
<span>User: {{ $stats['pengguna'] }}</span>
</div>
<div class="flex items-center text-sm text-indigo-600">
<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="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
<span>Admin: {{ $stats['admin'] }}</span>
</div>
</div>
<div class="container mx-auto px-4 py-8">
<!-- Welcome Message -->
<div class="mb-8 bg-[#1e3a8a] rounded-lg shadow-lg p-6 relative overflow-hidden">
<div class="relative z-10">
<div class="flex items-center space-x-3 mb-2">
<h2 class="text-2xl font-bold text-white">Selamat Datang, {{ auth()->user()->nama }}!</h2>
</div>
<p class="text-gray-900 font-bold bg-white/90 inline-block px-3 py-1 rounded-full">
{{ \Carbon\Carbon::now()->locale('id')->isoFormat('dddd, D MMMM Y') }}
</p>
</div>
</div>
<!-- Barang Stats -->
<div class="bg-gradient-to-br from-purple-50 to-purple-100 rounded-xl shadow-lg p-6 transform hover:scale-105 transition-all duration-300">
<a href="{{ route('paket') }}" class="block">
<!-- Dashboard Stats -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<!-- Pengguna Stats -->
<div class="bg-gradient-to-br from-blue-50 to-blue-100 rounded-xl shadow-lg p-6 transform hover:scale-105 transition-all duration-300">
<a href="{{ route('pengguna') }}" class="block">
<div class="flex items-center">
<div class="p-3 rounded-full bg-blue-500 text-white mr-4 shadow-md">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" />
</svg>
</div>
<div>
<p class="text-blue-600 text-sm font-medium">Total Pengguna</p>
<p class="text-3xl font-bold text-blue-800">{{ $stats['total_pengguna'] ?? 0 }}</p>
<div class="flex flex-col mt-2 space-y-1">
<div class="flex items-center text-sm text-blue-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
<span>User: {{ $stats['pengguna'] }}</span>
</div>
<div class="flex items-center text-sm text-indigo-600">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
<span>Admin: {{ $stats['admin'] }}</span>
</div>
</div>
</div>
</div>
</a>
</div>
<!-- Barang Stats -->
<div class="bg-gradient-to-br from-purple-50 to-purple-100 rounded-xl shadow-lg p-6 transform hover:scale-105 transition-all duration-300">
<a href="{{ route('paket') }}" class="block">
<div class="flex items-center">
<div class="p-3 rounded-full bg-purple-500 text-white mr-4 shadow-md">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
</svg>
</div>
<div>
<p class="text-purple-600 text-sm font-medium">Total Paket</p>
<p class="text-3xl font-bold text-purple-800">{{ $stats['barang'] ?? 0 }}</p>
<p class="text-sm text-purple-600 mt-1">Paket Sound System</p>
</div>
</div>
</a>
</div>
<!-- Sewa Stats -->
<div class="bg-gradient-to-br from-yellow-50 to-yellow-100 rounded-xl shadow-lg p-6 transform hover:scale-105 transition-all duration-300">
<a href="{{ route('sewa.riwayat') }}" class="block hover:no-underline">
<div class="flex items-center">
<div class="p-3 rounded-full bg-yellow-500 text-white mr-4 shadow-md">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
</div>
<div>
<p class="text-yellow-600 text-sm font-medium">Total Sewa</p>
<p class="text-3xl font-bold text-yellow-800">{{ $stats['sewa'] ?? 0 }}</p>
<p class="text-sm text-yellow-600 mt-1">Klik untuk lihat riwayat</p>
</div>
</div>
</a>
</div>
<!-- Pendapatan Stats -->
<div class="bg-gradient-to-br from-green-50 to-green-100 rounded-xl shadow-lg p-6 transform hover:scale-105 transition-all duration-300">
<div class="flex items-center">
<div class="p-3 rounded-full bg-purple-500 text-white mr-4 shadow-md">
<div class="p-3 rounded-full bg-green-500 text-white mr-4 shadow-md">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" />
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
</div>
<div>
<p class="text-purple-600 text-sm font-medium">Total paket tersedia</p>
<p class="text-3xl font-bold text-purple-800">{{ $stats['barang'] ?? 0 }}</p>
<p class="text-green-600 text-sm font-medium">Pendapatan</p>
<p class="text-3xl font-bold text-green-800">
{{ isset($chartData['datasets'][0]['data']) ? 'Rp ' . number_format(end($chartData['datasets'][0]['data']), 0, ',', '.') : 'Rp 0' }}
</p>
<p class="text-sm text-green-600 mt-1">Tahun {{ date('Y') }}</p>
</div>
</div>
</a>
</div>
</div>
<!-- Sewa Stats -->
<div class="bg-gradient-to-br from-yellow-50 to-yellow-100 rounded-xl shadow-lg p-6 transform hover:scale-105 transition-all duration-300">
<a href="{{ route('sewa.riwayat', ['view' => 'all']) }}" class="block hover:no-underline">
<div class="flex items-center">
<div class="p-3 rounded-full bg-yellow-500 text-white mr-4 shadow-md">
<svg xmlns="http://www.w3.org/2000/svg" class="h-8 w-8" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
</svg>
</div>
<div>
<p class="text-yellow-600 text-sm font-medium">Total Sewa</p>
<p class="text-3xl font-bold text-yellow-800">{{ $stats['sewa'] ?? 0 }}</p>
<p class="text-sm text-yellow-600 mt-1">Klik untuk lihat riwayat sewa</p>
</div>
</div>
</a>
</div>
</div>
<!-- Grafik Statistik -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
<!-- Grafik Pemasukan & Pengeluaran -->
<!-- Grafik Statistik -->
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
<!-- Grafik Pemasukan & Pengeluaran -->
<div class="bg-white rounded-xl shadow-lg p-6 hover:shadow-xl transition-shadow duration-300">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-bold text-gray-800">Statistik Keuangan & Sewa</h3>
<div class="flex space-x-2">
<span class="px-3 py-1 bg-green-100 text-green-600 rounded-full text-sm font-medium">Pemasukan</span>
<span class="px-3 py-1 bg-red-100 text-red-600 rounded-full text-sm font-medium">Pengeluaran</span>
<span class="px-3 py-1 bg-blue-100 text-blue-600 rounded-full text-sm font-medium">Total Sewa</span>
</div>
</div>
<div class="relative h-80">
<canvas id="financeChart"></canvas>
</div>
</div>
<!-- Grafik Pertumbuhan Pengguna -->
<div class="bg-white rounded-xl shadow-lg p-6 hover:shadow-xl transition-shadow duration-300">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-bold text-gray-800">Pertumbuhan Pengguna</h3>
<span class="px-3 py-1 bg-purple-100 text-purple-600 rounded-full text-sm font-medium">Total Pengguna</span>
</div>
<div class="relative h-80">
<canvas id="userGrowthChart"></canvas>
</div>
</div>
</div>
<!-- Ringkasan Statistik -->
<div class="bg-white rounded-xl shadow-lg p-6 hover:shadow-xl transition-shadow duration-300">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-bold text-gray-800">Statistik Keuangan & Sewa</h3>
<div class="flex space-x-2">
<span class="px-3 py-1 bg-green-100 text-green-600 rounded-full text-sm font-medium">Pemasukan</span>
<span class="px-3 py-1 bg-red-100 text-red-600 rounded-full text-sm font-medium">Pengeluaran</span>
<span class="px-3 py-1 bg-blue-100 text-blue-600 rounded-full text-sm font-medium">Total Sewa</span>
<h3 class="text-xl font-bold text-gray-800">Ringkasan Statistik Tahun {{ date('Y') }}</h3>
<span class="px-3 py-1 bg-gray-100 text-gray-600 rounded-full text-sm font-medium">Data Terkini</span>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- Pemasukan -->
<div class="p-6 bg-gradient-to-br from-green-50 to-green-100 rounded-xl border border-green-200">
<div class="flex items-center justify-between mb-4">
<div class="p-2 bg-green-500 rounded-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
</div>
<span class="text-sm font-medium text-green-600">
+{{ isset($chartData['datasets'][0]['data']) ? number_format(end($chartData['datasets'][0]['data']) / 1000000, 1) : '0' }}M
</span>
</div>
<p class="text-sm text-green-600 font-medium">Total Pemasukan</p>
<p class="text-2xl font-bold text-green-700 mt-2">
Rp {{ isset($chartData['datasets'][0]['data']) ? number_format(end($chartData['datasets'][0]['data']), 0, ',', '.') : '0' }}
</p>
</div>
</div>
<div class="relative h-80">
<canvas id="financeChart"></canvas>
</div>
</div>
<!-- Grafik Pertumbuhan Pengguna -->
<div class="bg-white rounded-xl shadow-lg p-6 hover:shadow-xl transition-shadow duration-300">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-bold text-gray-800">Pertumbuhan Pengguna</h3>
<span class="px-3 py-1 bg-purple-100 text-purple-600 rounded-full text-sm font-medium">Total Pengguna</span>
</div>
<div class="relative h-80">
<canvas id="userGrowthChart"></canvas>
</div>
</div>
</div>
<!-- Pengeluaran -->
<div class="p-6 bg-gradient-to-br from-red-50 to-red-100 rounded-xl border border-red-200">
<div class="flex items-center justify-between mb-4">
<div class="p-2 bg-red-500 rounded-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 17h8m0 0V9m0 8l-8-8-4 4-6-6"></path>
</svg>
</div>
<span class="text-sm font-medium text-red-600">
-{{ isset($chartData['datasets'][1]['data']) ? number_format(end($chartData['datasets'][1]['data']) / 1000000, 1) : '0' }}M
</span>
</div>
<p class="text-sm text-red-600 font-medium">Total Pengeluaran</p>
<p class="text-2xl font-bold text-red-700 mt-2">
Rp {{ isset($chartData['datasets'][1]['data']) ? number_format(end($chartData['datasets'][1]['data']), 0, ',', '.') : '0' }}
</p>
</div>
<!-- Ringkasan Statistik -->
<div class="bg-white rounded-xl shadow-lg p-6 hover:shadow-xl transition-shadow duration-300">
<div class="flex items-center justify-between mb-6">
<h3 class="text-xl font-bold text-gray-800">Ringkasan Statistik Tahun {{ date('Y') }}</h3>
<span class="px-3 py-1 bg-gray-100 text-gray-600 rounded-full text-sm font-medium">Data Terkini</span>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="p-6 bg-gradient-to-br from-green-50 to-green-100 rounded-xl border border-green-200">
<div class="flex items-center justify-between mb-4">
<div class="p-2 bg-green-500 rounded-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8c-1.657 0-3 .895-3 2s1.343 2 3 2 3 .895 3 2-1.343 2-3 2m0-8c1.11 0 2.08.402 2.599 1M12 8V7m0 1v8m0 0v1m0-1c-1.11 0-2.08-.402-2.599-1M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<!-- Total Sewa -->
<div class="p-6 bg-gradient-to-br from-blue-50 to-blue-100 rounded-xl border border-blue-200">
<div class="flex items-center justify-between mb-4">
<div class="p-2 bg-blue-500 rounded-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path>
</svg>
</div>
<span class="text-sm font-medium text-blue-600">
{{ isset($chartData['datasets'][2]['data']) ? (end($chartData['datasets'][2]['data']) > 0 ? '+' : '') . end($chartData['datasets'][2]['data']) : '0' }}
</span>
</div>
<span class="text-sm font-medium text-green-600">+{{ number_format(($chartData['datasets'][0]['data'][count($chartData['datasets'][0]['data'])-1] ?? 0) / 1000000, 1) }}M</span>
<p class="text-sm text-blue-600 font-medium">Total Sewa</p>
<p class="text-2xl font-bold text-blue-700 mt-2">
{{ isset($chartData['datasets'][2]['data']) ? number_format(end($chartData['datasets'][2]['data']), 0, ',', '.') : '0' }} Sewa
</p>
</div>
<p class="text-sm text-green-600 font-medium">Total Pemasukan</p>
<p class="text-2xl font-bold text-green-700 mt-2">Rp {{ number_format($chartData['datasets'][0]['data'][count($chartData['datasets'][0]['data'])-1] ?? 0, 0, ',', '.') }}</p>
</div>
<div class="p-6 bg-gradient-to-br from-red-50 to-red-100 rounded-xl border border-red-200">
<div class="flex items-center justify-between mb-4">
<div class="p-2 bg-red-500 rounded-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 17h8m0 0V9m0 8l-8-8-4 4-6-6"></path>
</svg>
</div>
<span class="text-sm font-medium text-red-600">-{{ number_format(($chartData['datasets'][1]['data'][count($chartData['datasets'][1]['data'])-1] ?? 0) / 1000000, 1) }}M</span>
</div>
<p class="text-sm text-red-600 font-medium">Total Pengeluaran</p>
<p class="text-2xl font-bold text-red-700 mt-2">Rp {{ number_format($chartData['datasets'][1]['data'][count($chartData['datasets'][1]['data'])-1] ?? 0, 0, ',', '.') }}</p>
</div>
<div class="p-6 bg-gradient-to-br from-blue-50 to-blue-100 rounded-xl border border-blue-200">
<div class="flex items-center justify-between mb-4">
<div class="p-2 bg-blue-500 rounded-lg">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2"></path>
</svg>
</div>
<span class="text-sm font-medium text-blue-600">{{ ($chartData['datasets'][2]['data'][count($chartData['datasets'][2]['data'])-1] ?? 0) > 0 ? '+' : '' }}{{ $chartData['datasets'][2]['data'][count($chartData['datasets'][2]['data'])-1] ?? 0 }}</span>
</div>
<p class="text-sm text-blue-600 font-medium">Total Sewa</p>
<p class="text-2xl font-bold text-blue-700 mt-2">{{ number_format($chartData['datasets'][2]['data'][count($chartData['datasets'][2]['data'])-1] ?? 0, 0, ',', '.') }} Sewa</p>
</div>
</div>
</div>

View File

@ -11,99 +11,150 @@
<div class="flex justify-between items-center">
<h2 class="text-lg font-bold">Kode Pemesanan: #{{ $sewa->id }}</h2>
<span class="px-3 py-1 rounded-full text-sm font-semibold
{{ $sewa->status == 'pending' ? 'bg-yellow-200 text-yellow-800' :
($sewa->status == 'confirmed' ? 'bg-blue-200 text-blue-800' :
($sewa->status == 'ongoing' ? 'bg-purple-200 text-purple-800' :
($sewa->status == 'completed' ? 'bg-green-200 text-green-800' :
'bg-red-200 text-red-800'))) }}">
{{ $sewa->status == 'pending' ? 'bg-yellow-200 text-yellow-800' :
($sewa->status == 'confirmed' ? 'bg-blue-200 text-blue-800' :
($sewa->status == 'ongoing' ? 'bg-purple-200 text-purple-800' :
($sewa->status == 'completed' ? 'bg-green-200 text-green-800' :
'bg-red-200 text-red-800'))) }}">
{{ ucfirst($sewa->status) }}
</span>
</div>
<p class="text-sm opacity-80 mt-1">Tanggal Pemesanan: {{ $sewa->created_at->format('d F Y, H:i') }}</p>
</div>
<!-- Informasi Paket -->
<div class="p-6 border-b border-gray-200">
<h3 class="text-lg font-semibold mb-3">Informasi Paket</h3>
<div class="flex flex-col md:flex-row">
<div class="md:w-1/4">
<img src="{{ asset('storage/' . $sewa->paket->gambar) }}"
alt="{{ $sewa->paket->nama }}"
class="w-full h-48 object-cover rounded-lg"
onerror="this.src='https://via.placeholder.com/300x150?text=Paket+Sound+System'">
</div>
<div class="md:w-3/4 md:pl-6 mt-4 md:mt-0">
<h4 class="text-xl font-bold">{{ $sewa->paket->nama }}</h4>
<p class="text-gray-600 mt-2">{{ $sewa->paket->deskripsi }}</p>
<div class="mt-4 grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<p class="text-sm text-gray-500">Tanggal Mulai</p>
<p class="font-medium">{{ date('d F Y', strtotime($sewa->tanggal_mulai)) }}</p>
<!-- Detail Informasi -->
<div class="p-6 grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Informasi Paket -->
<div class="space-y-4">
<h3 class="text-lg font-semibold">Informasi Paket</h3>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="space-y-2">
<div class="flex justify-between">
<span class="text-gray-600">Nama Paket:</span>
<span class="font-medium">{{ $sewa->paket->nama_paket }}</span>
</div>
<div>
<p class="text-sm text-gray-500">Tanggal Selesai</p>
<p class="font-medium">{{ date('d F Y', strtotime($sewa->tanggal_selesai)) }}</p>
<div class="flex justify-between">
<span class="text-gray-600">Harga per Hari:</span>
<span class="font-medium">Rp {{ number_format($sewa->paket->harga, 0, ',', '.') }}</span>
</div>
<div>
<p class="text-sm text-gray-500">Lokasi Acara</p>
<p class="font-medium">{{ $sewa->lokasi }}</p>
<div class="flex justify-between">
<span class="text-gray-600">Durasi Sewa:</span>
<span class="font-medium">{{ $sewa->durasi_sewa }} hari</span>
</div>
<div>
<p class="text-sm text-gray-500">Durasi</p>
<p class="font-medium">
<?php
$tglMulai = new DateTime($sewa->tanggal_mulai);
$tglSelesai = new DateTime($sewa->tanggal_selesai);
$selisih = $tglMulai->diff($tglSelesai);
echo ($selisih->days + 1) . ' hari';
?>
</p>
<div class="flex justify-between">
<span class="text-gray-600">Total Harga:</span>
<span class="font-medium text-blue-600">Rp {{ number_format($sewa->total_harga, 0, ',', '.') }}</span>
</div>
</div>
</div>
</div>
</div>
<!-- Detail Biaya -->
<div class="p-6 border-b border-gray-200">
<h3 class="text-lg font-semibold mb-3">Detail Biaya</h3>
<div class="space-y-2">
<div class="flex justify-between">
<span>Harga Paket (per hari)</span>
<span>Rp {{ number_format($sewa->paket->harga, 0, ',', '.') }}</span>
<!-- Informasi Pembayaran -->
<div class="space-y-4">
<h3 class="text-lg font-semibold">Informasi Pembayaran</h3>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="space-y-2">
<div class="flex justify-between">
<span class="text-gray-600">Nominal Pembayaran:</span>
<span class="font-medium">
@if($sewa->nominal_pembayaran)
Rp {{ number_format($sewa->nominal_pembayaran, 0, ',', '.') }}
@else
<span class="text-gray-500">-</span>
@endif
</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Status Pembayaran:</span>
<span>
@if($sewa->nominal_pembayaran)
@if($sewa->nominal_pembayaran >= $sewa->total_harga)
<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs font-semibold">
Lunas
</span>
@else
<span class="px-2 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs font-semibold">
DP {{ number_format(($sewa->nominal_pembayaran / $sewa->total_harga) * 100, 0) }}%
</span>
@endif
@else
<span class="px-2 py-1 bg-red-100 text-red-800 rounded-full text-xs font-semibold">
Belum Bayar
</span>
@endif
</span>
</div>
@if($sewa->tanggal_pembayaran)
<div class="flex justify-between">
<span class="text-gray-600">Tanggal Pembayaran:</span>
<span class="font-medium">{{ $sewa->tanggal_pembayaran->format('d/m/Y H:i') }}</span>
</div>
@endif
@if($sewa->bukti_pembayaran)
<div class="flex justify-between items-center">
<span class="text-gray-600">Bukti Pembayaran:</span>
<a href="{{ Storage::url($sewa->bukti_pembayaran) }}" target="_blank"
class="text-blue-600 hover:text-blue-800 font-medium">
Lihat Bukti
</a>
</div>
@endif
</div>
</div>
<div class="flex justify-between">
<span>Durasi</span>
<span>
<?php
$tglMulai = new DateTime($sewa->tanggal_mulai);
$tglSelesai = new DateTime($sewa->tanggal_selesai);
$selisih = $tglMulai->diff($tglSelesai);
echo ($selisih->days + 1) . ' hari';
?>
</span>
</div>
<!-- Informasi Pengiriman -->
<div class="space-y-4">
<h3 class="text-lg font-semibold">Informasi Pengiriman</h3>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="space-y-2">
<div class="flex justify-between">
<span class="text-gray-600">Kota Tujuan:</span>
<span class="font-medium">{{ $sewa->kota->nama_kota }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Biaya Ongkir:</span>
<span class="font-medium">Rp {{ number_format($sewa->ongkir, 0, ',', '.') }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Alamat:</span>
<span class="font-medium">{{ $sewa->lokasi }}</span>
</div>
</div>
</div>
<div class="flex justify-between font-bold text-lg pt-2 border-t border-gray-200 mt-2">
<span>Total</span>
<span>Rp {{ number_format($sewa->total_harga, 0, ',', '.') }}</span>
</div>
<!-- Informasi Jaminan -->
<div class="space-y-4">
<h3 class="text-lg font-semibold">Informasi Jaminan</h3>
<div class="bg-gray-50 p-4 rounded-lg">
<div class="space-y-2">
@if($sewa->foto_jaminan)
<div class="flex justify-between">
<span class="text-gray-600">Jenis Jaminan:</span>
<span class="font-medium">{{ strtoupper($sewa->jenis_jaminan) }}</span>
</div>
<div class="flex justify-between items-center">
<span class="text-gray-600">Foto Jaminan:</span>
<a href="{{ Storage::url($sewa->foto_jaminan) }}" target="_blank"
class="text-blue-600 hover:text-blue-800 font-medium">
Lihat Jaminan
</a>
</div>
@else
<p class="text-gray-500 text-center">Belum ada jaminan yang diupload</p>
@endif
</div>
</div>
</div>
</div>
<!-- Tombol Aksi -->
<div class="p-6 flex justify-between">
<a href="{{ route('riwayat') }}" class="bg-gray-300 text-gray-800 py-2 px-4 rounded hover:bg-gray-400 transition-colors">
Kembali
<!-- Tombol Kembali -->
<div class="p-6 border-t border-gray-200">
<a href="{{ route('riwayat') }}"
class="inline-block bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition-colors">
Kembali ke Riwayat
</a>
@if($sewa->status == 'pending')
<form action="{{ route('riwayat.cancel', $sewa->id) }}" method="POST" onsubmit="return confirm('Apakah Anda yakin ingin membatalkan pesanan ini?')">
@csrf
@method('PUT')
<button type="submit" class="bg-red-600 text-white py-2 px-4 rounded hover:bg-red-700 transition-colors">
Batalkan Pesanan
</button>
</form>
@endif
</div>
</div>
@endsection

View File

@ -25,7 +25,7 @@
<a href="{{ route('paket') }}" class="block py-3 px-4 text-gray-800 font-semibold mb-1 hover:bg-gray-100 {{ request()->routeIs('paket*') ? 'bg-blue-800 text-white' : '' }}">
Paket
</a>
<a href="{{ route('sewa') }}" class="block py-3 px-4 text-gray-800 font-semibold mb-1 hover:bg-gray-100 {{ request()->routeIs('sewa.*') ? 'bg-blue-800 text-white' : '' }}">
<a href="{{ route('sewa.index') }}" class="block py-3 px-4 text-gray-800 font-semibold mb-1 hover:bg-gray-100 {{ request()->routeIs('sewa.*') ? 'bg-blue-800 text-white' : '' }}">
Sewa
</a>
<a href="{{ route('riwayat') }}" class="block py-3 px-4 text-gray-800 font-semibold mb-1 hover:bg-gray-100 {{ request()->routeIs('riwayat') ? 'bg-blue-800 text-white' : '' }}">

View File

@ -5,28 +5,19 @@
@section('header', 'Riwayat Sewa')
@section('content')
<div class="bg-white p-6 rounded-lg shadow-lg">
<h2 class="text-xl font-bold mb-4">Riwayat Pemesanan</h2>
@if(isset($sewas) && count($sewas) > 0)
<div class="bg-white rounded-lg shadow-lg p-6">
@if(count($sewas) > 0)
<div class="overflow-x-auto">
<table class="min-w-full bg-white">
<thead>
<tr class="bg-gray-100">
<th class="py-3 px-4 text-left">No</th>
<th class="py-3 px-4 text-left">Tanggal</th>
<th class="py-3 px-4 text-left">Paket</th>
<th class="py-3 px-4 text-left">Tanggal Mulai</th>
<th class="py-3 px-4 text-left">Tanggal Selesai</th>
<th class="py-3 px-4 text-left">Lokasi</th>
<th class="py-3 px-4 text-left">Kota Tujuan</th>
<th class="py-3 px-4 text-left">Ongkir</th>
<th class="py-3 px-4 text-left">Total Harga</th>
<th class="py-3 px-4 text-left">Nominal Pembayaran</th>
<th class="py-3 px-4 text-left">Status Pembayaran</th>
<th class="py-3 px-4 text-left">Sisa Pembayaran</th>
<th class="py-3 px-4 text-left">Status</th>
<th class="py-3 px-4 text-left">Bukti pembayaran</th>
<th class="py-3 px-4 text-left">Jaminan sewa</th>
<th class="py-3 px-4 text-left">Tanggal Pembayaran</th>
<th class="py-3 px-4 text-left">Aksi</th>
</tr>
</thead>
@ -34,24 +25,8 @@
@foreach($sewas as $index => $sewa)
<tr class="border-b hover:bg-gray-50">
<td class="py-3 px-4">{{ $index + 1 }}</td>
<td class="py-3 px-4">{{ $sewa->created_at->format('d/m/Y') }}</td>
<td class="py-3 px-4">{{ $sewa->paket->nama_paket }}</td>
<td class="py-3 px-4">{{ date('d/m/Y', strtotime($sewa->tanggal_mulai)) }}</td>
<td class="py-3 px-4">{{ date('d/m/Y', strtotime($sewa->tanggal_selesai)) }}</td>
<td class="py-3 px-4">{{ $sewa->lokasi }}</td>
<td class="py-3 px-4">
@if($sewa->kota)
{{ $sewa->kota->nama_kota }}
@else
<span class="text-gray-500">-</span>
@endif
</td>
<td class="py-3 px-4">
@if($sewa->ongkir)
Rp {{ number_format($sewa->ongkir, 0, ',', '.') }}
@else
<span class="text-gray-500">-</span>
@endif
</td>
<td class="py-3 px-4">Rp {{ number_format($sewa->total_harga, 0, ',', '.') }}</td>
<td class="py-3 px-4">
@if($sewa->nominal_pembayaran)
@ -61,99 +36,193 @@
@endif
</td>
<td class="py-3 px-4">
@if($sewa->nominal_pembayaran)
@if($sewa->nominal_pembayaran >= $sewa->total_harga)
<span class="px-2 py-1 bg-green-100 text-green-800 rounded-full text-xs font-semibold">
Lunas
</span>
@else
<span class="px-2 py-1 bg-yellow-100 text-yellow-800 rounded-full text-xs font-semibold">
DP {{ number_format(($sewa->nominal_pembayaran / $sewa->total_harga) * 100, 0) }}%
</span>
@endif
@else
<span class="px-2 py-1 bg-red-100 text-red-800 rounded-full text-xs font-semibold">
Belum Bayar
@php
$sisaPembayaran = $sewa->total_harga - ($sewa->nominal_pembayaran ?? 0);
@endphp
@if($sisaPembayaran > 0)
<span class="text-red-600 font-medium">
Rp {{ number_format($sisaPembayaran, 0, ',', '.') }}
</span>
@else
<span class="text-green-600 font-medium">Lunas</span>
@endif
</td>
<td class="py-3 px-4">
<span class="
@if($sewa->status == 'pending') bg-yellow-100 text-yellow-800
@elseif($sewa->status == 'confirmed') bg-blue-100 text-blue-800
@elseif($sewa->status == 'ongoing') bg-purple-100 text-purple-800
<span class="px-2 py-1 rounded-full text-xs font-semibold
@if($sewa->status == 'pending') bg-yellow-100 text-yellow-800
@elseif($sewa->status == 'confirmed') bg-blue-100 text-blue-800
@elseif($sewa->status == 'completed') bg-green-100 text-green-800
@elseif($sewa->status == 'dibatalkan') bg-red-100 text-red-800
@else bg-red-100 text-red-800
@endif
px-2 py-1 rounded-full text-xs font-semibold
">
@if($sewa->status == 'pending')
Menunggu Verifikasi Admin
@elseif($sewa->status == 'confirmed')
Disetujui
@elseif($sewa->status == 'ongoing')
Sedang Berjalan
@elseif($sewa->status == 'completed')
Selesai
@elseif($sewa->status == 'dibatalkan')
Dibatalkan
@else
{{ ucfirst($sewa->status) }}
@endif
@endif">
{{ ucfirst($sewa->status) }}
</span>
</td>
<td class="py-3 px-4">
@if($sewa->bukti_pembayaran)
<a href="{{ Storage::url($sewa->bukti_pembayaran) }}" target="_blank" class="text-blue-600 hover:text-blue-800">
<i class="fas fa-receipt mr-1"></i>bukti pembayaran
</a>
@else
<span class="text-gray-500">-</span>
@endif
</td>
<td class="py-3 px-4">
@if($sewa->foto_jaminan)
<a href="{{ Storage::url($sewa->foto_jaminan) }}" target="_blank" class="text-blue-600 hover:text-blue-800">
<i class="fas fa-id-card mr-1"></i>{{ ucfirst($sewa->jenis_jaminan) }}
</a>
@else
<span class="text-gray-500">-</span>
@endif
</td>
<td class="py-3 px-4">
@if($sewa->tanggal_pembayaran)
{{ date('d/m/Y H:i', strtotime($sewa->tanggal_pembayaran)) }}
@else
<span class="text-gray-500">-</span>
@endif
</td>
<td class="py-3 px-4">
@if(!in_array($sewa->status, ['completed', 'dibatalkan', 'ongoing']))
<form action="{{ route('riwayat.batal', $sewa->id) }}" method="POST">
@csrf
@method('PUT')
<button type="submit"
onclick="return confirm('Apakah Anda yakin ingin membatalkan pesanan ini?' +
(('{{ $sewa->status }}' === 'confirmed') ? ' Pembatalan setelah disetujui mungkin dikenakan biaya pembatalan.' : ''))"
class="bg-red-500 text-white px-3 py-1 rounded hover:bg-red-600 mb-2">
Batalkan Pesanan
</button>
</form>
@endif
<div class="space-y-2">
<!-- Tombol Detail dengan Modal -->
<button type="button"
onclick="showDetail('{{ $sewa->id }}')"
class="w-full bg-blue-600 text-white px-3 py-1 rounded hover:bg-blue-700">
Detail
</button>
@if(!in_array($sewa->status, ['completed', 'dibatalkan', 'ongoing']))
<form action="{{ route('riwayat.batal', $sewa->id) }}" method="POST">
@csrf
@method('PUT')
<button type="submit"
onclick="return confirm('Apakah Anda yakin ingin membatalkan pesanan ini?' +
(('{{ $sewa->status }}' === 'confirmed') ? ' Pembatalan setelah disetujui mungkin dikenakan biaya pembatalan.' : ''))"
class="w-full bg-red-500 text-white px-3 py-1 rounded hover:bg-red-600">
Batalkan Pesanan
</button>
</form>
@endif
@if(in_array($sewa->status, ['dibatalkan', 'completed']))
<form action="{{ route('riwayat.hapus', $sewa->id) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit"
onclick="return confirm('Apakah Anda yakin ingin menghapus riwayat pesanan ini?')"
class="w-full bg-gray-500 text-white px-3 py-1 rounded hover:bg-gray-600">
Hapus Riwayat
</button>
</form>
@endif
</div>
</td>
</tr>
@endforeach
</tbody>
</table>
</div>
<!-- Modal Detail -->
<div id="detailModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white rounded-lg shadow-xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-y-auto">
<div class="p-6">
<div class="flex justify-between items-start mb-4">
<h3 class="text-xl font-bold text-gray-800">Detail Pesanan</h3>
<button onclick="closeDetail()" class="text-gray-400 hover:text-gray-600">
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div id="modalContent" class="space-y-4">
<!-- Konten modal akan diisi melalui JavaScript -->
</div>
</div>
</div>
</div>
@else
<div class="text-center py-8">
<p class="text-gray-500">Belum ada riwayat pemesanan</p>
<a href="{{ route('sewa.index') }}" class="mt-4 inline-block bg-blue-800 text-white py-2 px-4 rounded hover:bg-blue-900 transition duration-200">
Pesan Sekarang
</a>
@auth
@if(auth()->user()->tipe_pengguna === 'customer')
<a href="{{ route('customer.sewa') }}" class="mt-4 inline-block bg-blue-800 text-white py-2 px-4 rounded hover:bg-blue-900 transition duration-200">
Pesan Sekarang
</a>
@else
<a href="{{ route('paket') }}" class="mt-4 inline-block bg-blue-800 text-white py-2 px-4 rounded hover:bg-blue-900 transition duration-200">
Lihat Paket
</a>
@endif
@else
<a href="{{ route('login') }}" class="mt-4 inline-block bg-blue-800 text-white py-2 px-4 rounded hover:bg-blue-900 transition duration-200">
Login untuk Memesan
</a>
@endauth
</div>
@endif
</div>
@push('scripts')
<script>
async function showDetail(sewaId) {
try {
const response = await fetch(`/riwayat/${sewaId}`, {
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
const modalContent = document.getElementById('modalContent');
modalContent.innerHTML = `
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Status Pembayaran -->
<div class="space-y-2">
<h4 class="font-semibold">Status Pembayaran</h4>
<div class="bg-gray-50 p-4 rounded-lg">
<p class="text-sm">Tanggal Pembayaran: ${data.tanggal_pembayaran || '-'}</p>
<p class="text-sm">Status: ${data.status_pembayaran}</p>
</div>
</div>
<!-- Informasi Pengiriman -->
<div class="space-y-2">
<h4 class="font-semibold">Informasi Pengiriman</h4>
<div class="bg-gray-50 p-4 rounded-lg">
<p class="text-sm">Lokasi: ${data.lokasi || '-'}</p>
<p class="text-sm">Kota: ${data.kota?.nama_kota || '-'}</p>
<p class="text-sm">Ongkir: ${data.ongkir ? `Rp ${parseInt(data.ongkir).toLocaleString('id-ID')}` : '-'}</p>
</div>
</div>
<!-- Bukti Pembayaran -->
${data.bukti_pembayaran ? `
<div class="space-y-2">
<h4 class="font-semibold">Bukti Pembayaran</h4>
<div class="bg-gray-50 p-4 rounded-lg">
<a href="/storage/${data.bukti_pembayaran}" target="_blank"
class="text-blue-600 hover:text-blue-800">Lihat Bukti Pembayaran</a>
</div>
</div>
` : ''}
<!-- Jaminan -->
${data.foto_jaminan ? `
<div class="space-y-2">
<h4 class="font-semibold">Jaminan</h4>
<div class="bg-gray-50 p-4 rounded-lg">
<p class="text-sm">Jenis: ${data.jenis_jaminan || '-'}</p>
<a href="/storage/${data.foto_jaminan}" target="_blank"
class="text-blue-600 hover:text-blue-800">Lihat Jaminan</a>
</div>
</div>
` : ''}
</div>
`;
document.getElementById('detailModal').classList.remove('hidden');
document.getElementById('detailModal').classList.add('flex');
document.body.style.overflow = 'hidden';
} catch (error) {
console.error('Error:', error);
alert('Terjadi kesalahan saat memuat detail. Silakan coba lagi.');
}
}
function closeDetail() {
document.getElementById('detailModal').classList.add('hidden');
document.getElementById('detailModal').classList.remove('flex');
document.body.style.overflow = 'auto';
}
// Menutup modal saat mengklik area di luar modal
document.getElementById('detailModal').addEventListener('click', function(e) {
if (e.target === this) {
closeDetail();
}
});
</script>
@endpush
@endsection

View File

@ -4,116 +4,304 @@
@section('header', 'Sewa Paket Sound System')
@section('content')
<div class="container mx-auto px-4 py-6">
<!-- Card Grid -->
<div class="bg-white rounded-lg shadow-lg p-6">
@if(count($pakets) > 0)
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
@foreach($pakets as $paket)
<div class="bg-white rounded-lg shadow-md hover:shadow-xl transition-shadow duration-300 overflow-hidden">
<div class="p-3 border-b bg-gray-50">
<h3 class="text-center font-bold text-gray-800">{{ $paket->nama_paket }}</h3>
</div>
<div class="h-48 p-2 flex items-center justify-center overflow-hidden bg-gray-100 relative">
@if($paket->image)
<img src="{{ asset('storage/' . $paket->image) }}"
alt="{{ $paket->nama_paket }}"
class="w-full h-full object-contain">
@else
<div class="w-full h-full flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-20 w-20 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
</div>
@endif
<div class="container mx-auto px-4 py-8">
@if(session('error'))
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4 rounded">
{{ session('error') }}
</div>
@endif
@php
$activeSewa = $paket->sewas()->whereIn('status', ['confirmed', 'ongoing'])->count();
@endphp
@if($activeSewa > 0)
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center">
<div class="text-white text-center p-4">
<i class="fas fa-clock text-3xl mb-2"></i>
<p class="font-bold">Sedang Disewa</p>
<p class="text-sm">Stok tersedia: {{ $paket->stok - $activeSewa }}</p>
</div>
</div>
@endif
<!-- Paket Grid -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
@foreach($pakets as $paket)
<div class="bg-white rounded-lg shadow-md overflow-hidden">
<!-- Image Section with Overlay -->
<div class="h-48 bg-gray-200 relative">
@if($paket->image)
<img src="{{ Storage::url($paket->image) }}"
alt="{{ $paket->nama_paket }}"
class="w-full h-full object-cover">
@else
<div class="w-full h-full flex items-center justify-center">
<i class="fas fa-image text-4xl text-gray-400"></i>
</div>
<div class="p-4">
<div class="space-y-2">
<div class="flex justify-between items-center">
<span class="text-sm font-semibold text-gray-600">Harga Sewa:</span>
<span class="px-3 py-1 bg-green-100 text-green-800 rounded-full text-sm font-medium">
Rp {{ number_format($paket->harga, 0, ',', '.') }}/hari
</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm font-semibold text-gray-600">Jenis Paket:</span>
<span class="px-3 py-1 bg-purple-100 text-purple-800 rounded-full text-sm">
{{ ucfirst($paket->jenis_paket) }}
</span>
</div>
@if($paket->minimum_order)
<div class="flex justify-between items-center">
<span class="text-sm font-semibold text-gray-600">Minimum Order:</span>
<span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full text-sm">
{{ $paket->minimum_order }} hari
</span>
</div>
@endif
<!-- Stok Information -->
<div class="flex justify-between items-center">
<span class="text-sm font-semibold text-gray-600">Stok:</span>
<span class="px-3 py-1 {{ $activeSewa > 0 ? 'bg-orange-100 text-orange-800' : 'bg-green-100 text-green-800' }} rounded-full text-sm">
{{ $paket->stok - $activeSewa }} tersedia
</span>
</div>
</div>
@if($paket->keterangan)
<div class="mt-4">
<p class="text-sm text-gray-600 line-clamp-2">{{ $paket->keterangan }}</p>
</div>
@endif
<div class="mt-4">
@if($activeSewa >= $paket->stok)
<button disabled
class="block w-full bg-gray-400 text-white px-4 py-2 rounded text-sm cursor-not-allowed">
Paket Tidak Tersedia
</button>
@else
<a href="{{ route('sewa.create', $paket->id) }}"
class="block w-full bg-blue-700 text-white px-4 py-2 rounded text-sm hover:bg-blue-800 text-center">
Sewa Sekarang
</a>
@endif
</div>
</div>
</div>
@endforeach
</div>
@else
<div class="text-center py-12">
<svg xmlns="http://www.w3.org/2000/svg" class="h-20 w-20 text-gray-400 mx-auto mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Tidak Ada Paket Tersedia</h3>
<p class="text-gray-600 mb-6">Saat ini tidak ada paket yang tersedia untuk disewa.</p>
@endif
@if(auth()->check() && auth()->user()->role === 'admin')
<a href="{{ route('paket.create') }}" class="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700">
<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 6v6m0 0v6m0-6h6m-6 0H6" />
</svg>
Tambah Paket Baru
</a>
@php
$activeSewa = $paket->sewas()
->whereIn('status', ['confirmed', 'ongoing'])
->count();
$tersedia = $paket->stok - $activeSewa;
@endphp
@if($tersedia <= 0)
<div class="absolute inset-0 bg-black bg-opacity-50 flex items-center justify-center">
<div class="text-white text-center p-4">
<i class="fas fa-clock text-3xl mb-2"></i>
<p class="font-bold">Sedang Disewa</p>
<p class="text-sm">{{ $activeSewa }} dari {{ $paket->stok }} unit disewa</p>
</div>
</div>
@endif
</div>
@endif
<!-- Content Section -->
<div class="p-4">
<h3 class="text-xl font-bold mb-2">{{ $paket->nama_paket }}</h3>
<div class="space-y-2 mb-4">
<div class="flex justify-between">
<span class="text-gray-600">Harga:</span>
<span class="font-semibold text-green-600">
Rp {{ number_format($paket->harga, 0, ',', '.') }}/hari
</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Jenis:</span>
<span class="font-semibold">{{ ucfirst($paket->jenis_paket) }}</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Stok:</span>
<span class="font-semibold">
{{ $paket->stok }}
@if($activeSewa > 0)
<span class="text-orange-500 text-sm ml-1">({{ $tersedia }} tersedia)</span>
@endif
</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">Status:</span>
<span class="font-semibold
@if($tersedia > 0)
text-green-600
@else
text-red-600
@endif">
@if($tersedia > 0)
Tersedia ({{ $tersedia }} unit)
@else
Sedang Disewa Semua
@endif
</span>
</div>
<!-- Ongkir per Kota -->
@if($paket->ongkirKota->count() > 0)
<div class="mt-2">
<span class="text-gray-600 font-medium">Ongkir per Kota:</span>
<div class="mt-1 space-y-1">
@foreach($paket->ongkirKota as $ongkir)
<div class="flex justify-between text-sm">
<span class="text-gray-600">{{ $ongkir->nama_kota }}</span>
<span class="font-medium">Rp {{ number_format($ongkir->biaya_ongkir, 0, ',', '.') }}</span>
</div>
@endforeach
</div>
</div>
@endif
</div>
@if($paket->keterangan)
<p class="text-gray-600 text-sm mb-4">{{ $paket->keterangan }}</p>
@endif
<!-- Action Buttons -->
<div class="flex flex-col space-y-2 mt-4">
<button type="button"
onclick="showPaketDetail('{{ $paket->id }}')"
class="w-full bg-gray-100 hover:bg-gray-200 text-gray-800 font-semibold py-2 px-4 rounded transition-colors">
<i class="fas fa-info-circle mr-2"></i>Lihat Detail
</button>
@auth
@if($tersedia <= 0)
<button disabled
class="w-full bg-gray-400 text-white py-2 px-4 rounded cursor-not-allowed">
<i class="fas fa-ban mr-2"></i>Tidak Tersedia
</button>
@else
<a href="{{ route('sewa.create', $paket->id) }}"
class="w-full bg-blue-600 hover:bg-blue-700 text-white text-center py-2 px-4 rounded transition-colors">
<i class="fas fa-shopping-cart mr-2"></i>Sewa Sekarang
</a>
@endif
@else
<a href="{{ route('login') }}"
class="w-full bg-blue-600 hover:bg-blue-700 text-white text-center py-2 px-4 rounded transition-colors">
<i class="fas fa-sign-in-alt mr-2"></i>Login untuk Menyewa
</a>
@endauth
</div>
</div>
</div>
@endforeach
</div>
@if(count($pakets) === 0)
<div class="text-center py-12">
<svg xmlns="http://www.w3.org/2000/svg" class="h-20 w-20 text-gray-400 mx-auto mb-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" />
</svg>
<h3 class="text-xl font-semibold text-gray-800 mb-2">Tidak Ada Paket Tersedia</h3>
<p class="text-gray-600 mb-6">Saat ini tidak ada paket yang tersedia untuk disewa.</p>
</div>
@endif
</div>
<!-- Modal Detail Paket -->
<div id="paketDetailModal" class="fixed inset-0 bg-black bg-opacity-50 hidden items-center justify-center z-50">
<div class="bg-white rounded-lg shadow-xl max-w-4xl w-full mx-4 max-h-[90vh] overflow-y-auto">
<div class="p-6">
<div class="flex justify-between items-start mb-4">
<h3 class="text-2xl font-bold text-gray-800" id="modalTitle"></h3>
<button onclick="closePaketDetail()" class="text-gray-400 hover:text-gray-600">
<svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Gambar Paket -->
<div class="h-64 bg-gray-200 rounded-lg overflow-hidden">
<div id="modalImage" class="w-full h-full"></div>
</div>
<!-- Informasi Paket -->
<div class="space-y-4">
<div id="modalInfo"></div>
<div id="modalBarang" class="border-t pt-4">
<h4 class="font-semibold text-gray-700 mb-2">Daftar Barang:</h4>
<ul class="list-disc list-inside text-gray-600 space-y-1"></ul>
</div>
<div class="pt-4">
<div id="modalAction"></div>
</div>
</div>
</div>
</div>
</div>
</div>
@push('scripts')
<script>
async function showPaketDetail(paketId) {
try {
const response = await fetch(`/paket/${paketId}/detail`);
if (!response.ok) {
throw new Error('Network response was not ok');
}
const paket = await response.json();
// Update modal content
document.getElementById('modalTitle').textContent = paket.nama_paket;
// Update image
const modalImage = document.getElementById('modalImage');
if (paket.image) {
modalImage.innerHTML = `
<img src="/storage/${paket.image}"
alt="${paket.nama_paket}"
class="w-full h-full object-cover">
`;
} else {
modalImage.innerHTML = `
<div class="w-full h-full flex items-center justify-center">
<i class="fas fa-image text-4xl text-gray-400"></i>
</div>
`;
}
// Update info
const modalInfo = document.getElementById('modalInfo');
modalInfo.innerHTML = `
<div class="space-y-3">
<p class="text-gray-600">${paket.keterangan || 'Tidak ada keterangan'}</p>
<div class="flex justify-between items-center">
<span class="font-semibold">Harga Sewa:</span>
<span class="text-green-600 font-bold">Rp ${parseInt(paket.harga).toLocaleString('id-ID')}/hari</span>
</div>
<div class="flex justify-between items-center">
<span class="font-semibold">Jenis Paket:</span>
<span class="px-3 py-1 bg-purple-100 text-purple-800 rounded-full">
${paket.jenis_paket}
</span>
</div>
${paket.minimum_order ? `
<div class="flex justify-between items-center">
<span class="font-semibold">Minimum Order:</span>
<span class="px-3 py-1 bg-blue-100 text-blue-800 rounded-full">
${paket.minimum_order} hari
</span>
</div>
` : ''}
<div class="flex justify-between items-center">
<span class="font-semibold">Stok:</span>
<span class="px-3 py-1 ${paket.stok > 0 ? 'bg-green-100 text-green-800' : 'bg-red-100 text-red-800'} rounded-full">
${paket.stok} unit
</span>
</div>
</div>
`;
// Update barang list
const barangList = document.querySelector('#modalBarang ul');
barangList.innerHTML = '';
if (paket.barangs && paket.barangs.length > 0) {
paket.barangs.forEach(barang => {
const li = document.createElement('li');
li.textContent = `${barang.nama_barang} (${barang.pivot.jumlah} unit)`;
barangList.appendChild(li);
});
} else {
barangList.innerHTML = '<li>Tidak ada daftar barang</li>';
}
// Update action button
const modalAction = document.getElementById('modalAction');
if (paket.stok > 0) {
modalAction.innerHTML = `
<a href="/sewa/create/${paket.id}"
class="block w-full bg-blue-600 text-white text-center px-4 py-2 rounded hover:bg-blue-700 transition-colors">
<i class="fas fa-shopping-cart mr-2"></i>Sewa Sekarang
</a>
`;
} else {
modalAction.innerHTML = `
<button disabled class="block w-full bg-gray-400 text-white px-4 py-2 rounded cursor-not-allowed">
<i class="fas fa-ban mr-2"></i>Stok Tidak Tersedia
</button>
`;
}
// Show modal
document.getElementById('paketDetailModal').classList.remove('hidden');
document.getElementById('paketDetailModal').classList.add('flex');
document.body.style.overflow = 'hidden';
} catch (error) {
console.error('Error fetching paket details:', error);
alert('Terjadi kesalahan saat memuat detail paket');
}
}
function closePaketDetail() {
document.getElementById('paketDetailModal').classList.add('hidden');
document.getElementById('paketDetailModal').classList.remove('flex');
document.body.style.overflow = 'auto';
}
// Close modal when clicking outside
document.getElementById('paketDetailModal').addEventListener('click', function(e) {
if (e.target === this) {
closePaketDetail();
}
});
</script>
@endpush
@endsection

View File

@ -1,173 +1,158 @@
@extends('layouts.app')
@section('title', 'Form Sewa - INUFA')
@section('header', 'Form Penyewaan Paket')
@section('title', 'Form Pemesanan - INUFA')
@section('header', 'Form Pemesanan')
@section('content')
<div class="container mx-auto px-4 py-6">
<div class="bg-white rounded-lg shadow-lg p-6">
<div class="mb-6">
<h2 class="text-2xl font-bold mb-4">Detail Paket</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="flex items-center justify-center">
@if($paket->image)
<img src="{{ Storage::url($paket->image) }}"
alt="{{ $paket->nama_paket }}"
class="max-w-full h-auto rounded-lg shadow-md">
@else
<div class="w-full h-48 bg-gray-200 rounded-lg flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-20 w-20 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
</div>
@endif
</div>
<div>
<h3 class="text-xl font-semibold mb-2">{{ $paket->nama_paket }}</h3>
<p class="text-gray-600 mb-4">{{ $paket->keterangan }}</p>
<div class="space-y-2">
<p class="font-medium">Jenis Paket: <span class="text-gray-600">{{ $paket->jenis_paket }}</span></p>
<p class="font-medium">Harga Sewa: <span class="text-blue-600">Rp {{ number_format($paket->harga, 0, ',', '.') }}/hari</span></p>
@if($paket->minimum_order)
<p class="font-medium">Minimum Order: <span class="text-green-600">{{ $paket->minimum_order }} hari</span></p>
@endif
<div class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<!-- Informasi Paket -->
<div class="bg-white rounded-lg shadow-lg overflow-hidden">
<!-- Image Section -->
<div class="h-64 bg-gray-200 relative">
@if($paket->image)
<img src="{{ Storage::url($paket->image) }}"
alt="{{ $paket->nama_paket }}"
class="w-full h-full object-cover">
@else
<div class="w-full h-full flex items-center justify-center">
<i class="fas fa-image text-4xl text-gray-400"></i>
</div>
@endif
</div>
<!-- Info Section -->
<div class="p-6">
<h2 class="text-2xl font-bold mb-4">Informasi Paket</h2>
<div class="space-y-4">
<div>
<h3 class="text-xl font-bold text-gray-800">{{ $paket->nama_paket }}</h3>
<p class="text-gray-600">{{ $paket->keterangan }}</p>
</div>
@if($paket->detail_barang)
<div class="mt-4">
<p class="font-medium mb-2">Daftar Barang dalam Paket:</p>
<ul class="list-disc list-inside text-gray-600 space-y-1">
@foreach($paket->detail_barang as $barang)
<li>{{ $barang['nama_barang'] }} ({{ $barang['jumlah'] }} unit)</li>
@endforeach
</ul>
<div class="flex justify-between items-center">
<span class="font-semibold">Harga per Hari:</span>
<span class="text-blue-600 font-bold text-lg">Rp {{ number_format($paket->harga, 0, ',', '.') }}</span>
</div>
<div class="flex justify-between items-center">
<span class="font-semibold">Minimum Order:</span>
<span class="bg-blue-100 text-blue-800 px-3 py-1 rounded-full text-sm font-medium">
{{ $paket->minimum_order ?? 1 }} hari
</span>
</div>
<div class="flex justify-between items-center">
<span class="font-semibold">Stok Tersedia:</span>
<span class="bg-green-100 text-green-800 px-3 py-1 rounded-full text-sm font-medium">
{{ $paket->stok }} unit
</span>
</div>
@endif
</div>
</div>
</div>
<form action="{{ route('sewa.store') }}" method="POST" class="space-y-6">
@csrf
<input type="hidden" name="paket_id" value="{{ $paket->id }}">
<!-- Form Pemesanan -->
<div class="bg-white rounded-lg shadow-lg p-6">
<h2 class="text-2xl font-bold mb-6">Form Pemesanan</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<form action="{{ route('sewa.store') }}" method="POST" class="space-y-6">
@csrf
<input type="hidden" name="paket_id" value="{{ $paket->id }}">
<!-- Tanggal Mulai -->
<div>
<label for="tanggal_mulai" class="block text-sm font-medium text-gray-700 mb-2">Tanggal Mulai</label>
<input type="date" name="tanggal_mulai" id="tanggal_mulai"
<input type="date" id="tanggal_mulai" name="tanggal_mulai"
class="w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200"
min="{{ date('Y-m-d') }}" required>
@error('tanggal_mulai')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
required min="{{ date('Y-m-d') }}">
</div>
<!-- Tanggal Selesai -->
<div>
<label for="tanggal_selesai" class="block text-sm font-medium text-gray-700 mb-2">Tanggal Selesai</label>
<input type="date" name="tanggal_selesai" id="tanggal_selesai"
<input type="date" id="tanggal_selesai" name="tanggal_selesai"
class="w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200"
required>
@error('tanggal_selesai')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
required min="{{ date('Y-m-d') }}">
</div>
</div>
<!-- Lokasi -->
<div class="mb-4">
<label for="lokasi" class="block text-gray-700 font-medium mb-2">Lokasi Acara <span class="text-red-500">*</span></label>
<input type="text" id="lokasi" name="lokasi" value="{{ old('lokasi') }}" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" required>
@error('lokasi')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<!-- Kota Tujuan -->
<div>
<label for="kota_id" class="block text-sm font-medium text-gray-700 mb-2">Kota Tujuan</label>
<select id="kota_id" name="kota_id"
class="w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200"
required>
<option value="">Pilih Kota</option>
@foreach($paket->ongkirKota as $kota)
<option value="{{ $kota->id }}" data-ongkir="{{ $kota->biaya_ongkir }}">
{{ $kota->nama_kota }} - Rp {{ number_format($kota->biaya_ongkir, 0, ',', '.') }}
</option>
@endforeach
</select>
</div>
<!-- Kota Tujuan -->
<div class="mb-4">
<label for="kota_id" class="block text-sm font-medium text-gray-700">Kota Tujuan</label>
<select id="kota_id" name="kota_id" class="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500 sm:text-sm" required>
<option value="">Pilih Kota Tujuan</option>
@foreach($paket->ongkirKota as $ongkir)
<option value="{{ $ongkir->id }}" data-ongkir="{{ $ongkir->biaya_ongkir }}">
{{ $ongkir->nama_kota }} - Rp {{ number_format($ongkir->biaya_ongkir, 0, ',', '.') }}
</option>
@endforeach
</select>
@error('kota_id')
<p class="mt-2 text-sm text-red-600">{{ $message }}</p>
@enderror
</div>
<!-- Alamat Lengkap -->
<div>
<label for="lokasi" class="block text-sm font-medium text-gray-700 mb-2">Alamat Lengkap</label>
<textarea id="lokasi" name="lokasi" rows="3"
class="w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200"
placeholder="Masukkan alamat lengkap lokasi acara" required></textarea>
</div>
<!-- Biaya Ongkir (readonly) -->
<div class="mb-4">
<label for="ongkir_display" class="block text-sm font-medium text-gray-700">Biaya Ongkir</label>
<div class="mt-1 relative rounded-md shadow-sm">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<span class="text-gray-500 sm:text-sm">Rp</span>
<!-- Catatan -->
<div>
<label for="catatan" class="block text-sm font-medium text-gray-700 mb-2">Catatan (Opsional)</label>
<textarea id="catatan" name="catatan" rows="3"
class="w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200"
placeholder="Tambahkan catatan jika ada"></textarea>
</div>
<!-- Informasi Biaya -->
<div class="border-t pt-4">
<div class="flex justify-between items-center mb-2">
<span class="font-semibold">Harga Sewa per Hari:</span>
<span class="text-lg font-bold" id="hargaPerHari">Rp {{ number_format($paket->harga, 0, ',', '.') }}</span>
</div>
<div class="flex justify-between items-center mb-2">
<span class="font-semibold">Durasi Sewa:</span>
<span class="font-bold" id="durasiSewa">0 hari</span>
</div>
<input type="text" id="ongkir_display" class="mt-1 block w-full pl-10 pr-3 py-2 text-gray-700 border border-gray-300 rounded-md bg-gray-50" readonly>
<input type="hidden" id="ongkir_value" name="ongkir" value="0">
</div>
</div>
<div>
<label for="catatan" class="block text-sm font-medium text-gray-700 mb-2">Catatan (Opsional)</label>
<textarea name="catatan" id="catatan" rows="3"
class="w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring focus:ring-blue-200"
placeholder="Tambahkan catatan khusus jika ada"></textarea>
@error('catatan')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<div class="flex justify-end space-x-4">
<a href="{{ route('sewa.index') }}"
class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50">
Batal
</a>
<button type="submit"
class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
Ajukan Sewa
</button>
</div>
</form>
<!-- Submit Button -->
<div class="flex justify-end">
<button type="submit" class="bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-6 rounded-lg">
Lanjutkan Pemesanan
</button>
</div>
</form>
</div>
</div>
</div>
@push('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
const kotaSelect = document.getElementById('kota_id');
const ongkirDisplay = document.getElementById('ongkir_display');
const ongkirValue = document.getElementById('ongkir_value');
const tanggalMulaiInput = document.getElementById('tanggal_mulai');
const tanggalSelesaiInput = document.getElementById('tanggal_selesai');
const hargaPerHari = parseFloat("{{ $paket->harga }}");
const tanggalMulai = document.getElementById('tanggal_mulai');
const tanggalSelesai = document.getElementById('tanggal_selesai');
const durasiSewa = document.getElementById('durasiSewa');
function formatRupiah(angka) {
return new Intl.NumberFormat('id-ID').format(angka);
}
function hitungOngkir() {
// Set ongkir saat kota dipilih
let ongkir = 0;
if (kotaSelect.value) {
ongkir = parseFloat(kotaSelect.selectedOptions[0].dataset.ongkir) || 0;
ongkirDisplay.value = `Rp ${formatRupiah(ongkir)}`;
ongkirValue.value = ongkir;
function hitungDurasi() {
if (tanggalMulai.value && tanggalSelesai.value) {
const start = new Date(tanggalMulai.value);
const end = new Date(tanggalSelesai.value);
const diffTime = Math.abs(end - start);
const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1;
durasiSewa.textContent = diffDays + ' hari';
}
}
// Event listeners
kotaSelect.addEventListener('change', hitungOngkir);
tanggalMulaiInput.addEventListener('change', function() {
tanggalSelesaiInput.min = this.value;
tanggalMulai.addEventListener('change', function() {
tanggalSelesai.min = this.value;
hitungDurasi();
});
// Inisialisasi form
if (kotaSelect.value) {
hitungOngkir();
}
tanggalSelesai.addEventListener('change', hitungDurasi);
});
</script>
@endpush

View File

@ -0,0 +1,95 @@
@extends('layouts.app')
@section('title', 'Riwayat Sewa - INUFA')
@section('header', 'Riwayat Sewa')
@section('content')
<div class="container mx-auto px-4 py-8">
@if(session('success'))
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-4 rounded">
{{ session('success') }}
</div>
@endif
@if(session('error'))
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4 rounded">
{{ session('error') }}
</div>
@endif
<!-- Riwayat Sewa Table -->
<div class="bg-white rounded-lg shadow-lg overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">No</th>
@if($showDetailPenyewa)
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Penyewa</th>
@endif
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Paket</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Tanggal Sewa</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Status</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Total Harga</th>
<th class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">Aksi</th>
</tr>
</thead>
<tbody class="bg-white divide-y divide-gray-200">
@forelse($sewas as $index => $sewa)
<tr>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
{{ $index + 1 }}
</td>
@if($showDetailPenyewa)
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm font-medium text-gray-900">{{ $sewa->user->nama }}</div>
<div class="text-sm text-gray-500">{{ $sewa->user->email }}</div>
</td>
@endif
<td class="px-6 py-4">
<div class="text-sm font-medium text-gray-900">{{ $sewa->paket->nama_paket }}</div>
<div class="text-sm text-gray-500">{{ ucfirst($sewa->paket->jenis_paket) }}</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<div class="text-sm text-gray-900">{{ \Carbon\Carbon::parse($sewa->tanggal_sewa)->format('d M Y') }}</div>
<div class="text-sm text-gray-500">{{ $sewa->durasi_sewa }} hari</div>
</td>
<td class="px-6 py-4 whitespace-nowrap">
<span class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full
@if($sewa->status === 'pending')
bg-yellow-100 text-yellow-800
@elseif($sewa->status === 'confirmed')
bg-green-100 text-green-800
@elseif($sewa->status === 'ongoing')
bg-blue-100 text-blue-800
@elseif($sewa->status === 'completed')
bg-purple-100 text-purple-800
@else
bg-red-100 text-red-800
@endif">
{{ ucfirst($sewa->status) }}
</span>
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-500">
Rp {{ number_format($sewa->total_harga, 0, ',', '.') }}
</td>
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium">
<a href="{{ route('sewa.show', $sewa->id) }}"
class="text-blue-600 hover:text-blue-900">
<i class="fas fa-eye mr-1"></i>Detail
</a>
</td>
</tr>
@empty
<tr>
<td colspan="{{ $showDetailPenyewa ? 7 : 6 }}" class="px-6 py-4 text-center text-gray-500">
Tidak ada riwayat sewa
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
</div>
@endsection

View File

@ -10,244 +10,206 @@
@section('content')
<div class="container mx-auto px-4 py-6">
<div class="bg-white rounded-lg shadow-lg p-6">
@if(session('success'))
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-6">
{{ session('success') }}
</div>
@endif
@if(session('success'))
<div class="bg-green-100 border-l-4 border-green-500 text-green-700 p-4 mb-4 rounded">
{{ session('success') }}
</div>
@endif
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<!-- Detail Paket -->
<div>
<h2 class="text-xl font-bold mb-4">Detail Paket</h2>
<div class="bg-gray-50 rounded-lg p-4">
<div class="mb-4">
@if($sewa->paket->image)
<img src="{{ Storage::url($sewa->paket->image) }}"
alt="{{ $sewa->paket->nama_paket }}"
class="w-full h-48 object-contain rounded-lg">
@else
<div class="w-full h-48 bg-gray-200 rounded-lg flex items-center justify-center">
<svg xmlns="http://www.w3.org/2000/svg" class="h-20 w-20 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
</svg>
</div>
@endif
</div>
<h3 class="font-semibold text-lg mb-2">{{ $sewa->paket->nama_paket }}</h3>
<p class="text-gray-600 mb-4">{{ $sewa->paket->keterangan }}</p>
<div class="space-y-2">
<p><span class="font-medium">Jenis Paket:</span> {{ $sewa->paket->jenis_paket }}</p>
<p><span class="font-medium">Harga Sewa:</span> Rp {{ number_format($sewa->paket->harga, 0, ',', '.') }}/hari</p>
</div>
@if(session('error'))
<div class="bg-red-100 border-l-4 border-red-500 text-red-700 p-4 mb-4 rounded">
{{ session('error') }}
</div>
@endif
@if($sewa->paket->detail_barang)
<div class="mt-4">
<p class="font-medium mb-2">Daftar Barang dalam Paket:</p>
<ul class="list-disc list-inside text-gray-600 space-y-1">
@foreach($sewa->paket->detail_barang as $barang)
<li>{{ $barang['nama_barang'] }} ({{ $barang['jumlah'] }} unit)</li>
@endforeach
</ul>
</div>
@endif
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6">
<!-- Detail Sewa -->
<div class="lg:col-span-2">
<div class="bg-white rounded-lg shadow-lg p-6">
<div class="border-b pb-4 mb-4">
<h3 class="text-xl font-bold text-gray-800">Detail Penyewaan</h3>
<p class="text-sm text-gray-600">ID Pesanan: {{ $sewa->id }}</p>
</div>
</div>
<!-- Detail Penyewaan -->
<div>
<h2 class="text-xl font-bold mb-4">Detail Penyewaan</h2>
<div class="bg-gray-50 rounded-lg p-4 space-y-4">
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<!-- Informasi Paket -->
<div>
<p class="font-medium">Status</p>
<span class="inline-block px-3 py-1 rounded-full text-sm font-medium
@if($sewa->status == 'draft') bg-gray-100 text-gray-800
@elseif($sewa->status == 'pending') bg-yellow-100 text-yellow-800
@elseif($sewa->status == 'disetujui') bg-green-100 text-green-800
@elseif($sewa->status == 'ditolak') bg-red-100 text-red-800
@elseif($sewa->status == 'selesai') bg-blue-100 text-blue-800
@else bg-gray-100 text-gray-800
@endif">
@if($sewa->status == 'draft')
Draft (Belum Disimpan)
@elseif($sewa->status == 'pending')
Menunggu Verifikasi Admin
@elseif($sewa->status == 'disetujui')
Disetujui
@elseif($sewa->status == 'ditolak')
Ditolak
@elseif($sewa->status == 'selesai')
Selesai
@else
{{ $sewa->status_label }}
<h4 class="font-semibold text-gray-700 mb-3">Informasi Paket</h4>
<div class="space-y-2">
<p class="text-sm">
<span class="font-medium">Nama Paket:</span>
<span class="text-gray-600">{{ $sewa->paket->nama_paket }}</span>
</p>
<p class="text-sm">
<span class="font-medium">Harga per Hari:</span>
<span class="text-gray-600">Rp {{ number_format($sewa->paket->harga, 0, ',', '.') }}</span>
</p>
<p class="text-sm">
<span class="font-medium">Durasi Sewa:</span>
<span class="text-gray-600">{{ $sewa->durasi_sewa }} hari</span>
</p>
<p class="text-sm">
<span class="font-medium">Total Harga:</span>
<span class="text-blue-600 font-semibold">Rp {{ number_format($sewa->total_harga, 0, ',', '.') }}</span>
</p>
</div>
</div>
<!-- Informasi Pengiriman -->
<div>
<h4 class="font-semibold text-gray-700 mb-3">Informasi Pengiriman</h4>
<div class="space-y-2">
<p class="text-sm">
<span class="font-medium">Kota Tujuan:</span>
<span class="text-gray-600">{{ $sewa->kota->nama_kota }}</span>
</p>
<p class="text-sm">
<span class="font-medium">Biaya Ongkir:</span>
<span class="text-gray-600">Rp {{ number_format($sewa->ongkir, 0, ',', '.') }}</span>
</p>
<p class="text-sm">
<span class="font-medium">Alamat:</span>
<span class="text-gray-600">{{ $sewa->lokasi }}</span>
</p>
@if($sewa->catatan)
<p class="text-sm">
<span class="font-medium">Catatan:</span>
<span class="text-gray-600">{{ $sewa->catatan }}</span>
</p>
@endif
</span>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<p class="font-medium">Tanggal Mulai</p>
<p>{{ $sewa->tanggal_mulai ? $sewa->tanggal_mulai->format('d M Y') : '-' }}</p>
</div>
<div>
<p class="font-medium">Tanggal Selesai</p>
<p>{{ $sewa->tanggal_selesai ? $sewa->tanggal_selesai->format('d M Y') : '-' }}</p>
</div>
</div>
<!-- Informasi Waktu -->
<div>
<p class="font-medium">Durasi Sewa</p>
<p>{{ $sewa->durasi_sewa }} hari</p>
</div>
<div>
<p class="font-medium">Total Harga</p>
<p class="text-lg text-blue-600 font-semibold">
Rp {{ number_format($sewa->total_harga, 0, ',', '.') }}
</p>
</div>
<div>
<p class="font-medium">Lokasi Penggunaan</p>
<p>{{ $sewa->lokasi }}</p>
</div>
<div>
<p class="font-medium">Kota Tujuan</p>
<p>{{ $sewa->kota ? $sewa->kota->nama_kota : '-' }}</p>
</div>
<div>
<p class="font-medium">Biaya Ongkir</p>
<p>Rp {{ number_format($sewa->ongkir, 0, ',', '.') }}</p>
</div>
@if($sewa->catatan)
<div>
<p class="font-medium">Catatan</p>
<p class="text-gray-600">{{ $sewa->catatan }}</p>
</div>
@endif
@if($sewa->status == 'pending')
<div class="pt-4">
<div class="bg-blue-50 border-l-4 border-blue-400 p-4 mb-4">
<div class="flex">
<div class="flex-shrink-0">
<svg class="h-5 w-5 text-blue-400" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd"/>
</svg>
</div>
<div class="ml-3">
<p class="text-sm text-blue-700">
Silakan isi kolom nominal dana yang diupload pada upload bukti pembayaran dan upload juga jaminan untuk melanjutkan proses penyewaan.
<br>Total yang harus dibayar DP 50% atau melunasi pembayaran sewa
</p>
</div>
</div>
</div>
<div class="bg-white rounded-lg border p-6">
<h3 class="text-lg font-semibold mb-4">Upload Bukti Pembayaran dan Jaminan</h3>
<form action="{{ route('sewa.upload-bukti', $sewa->id) }}" method="POST" enctype="multipart/form-data" class="space-y-6">
@csrf
<div>
<label for="nominal_pembayaran" class="block text-sm font-medium text-gray-700 mb-2">
Nominal Pembayaran <span class="text-red-500">*</span>
</label>
<div class="mt-1 relative rounded-md shadow-sm">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<span class="text-gray-500 sm:text-sm">Rp</span>
</div>
<input type="number" name="nominal_pembayaran" id="nominal_pembayaran"
required
class="focus:ring-blue-500 focus:border-blue-500 block w-full pl-12 pr-12 sm:text-sm border-gray-300 rounded-md"
placeholder="0"
min="1"
max="{{ $sewa->total_harga }}">
</div>
<div class="mt-1">
<p class="text-sm text-gray-500">Rekomendasi pembayaran minimal DP 50% (Rp {{ number_format($sewa->total_harga * 0.5, 0, ',', '.') }})</p>
<p class="text-sm text-gray-500">Total yang harus dibayar: Rp {{ number_format($sewa->total_harga, 0, ',', '.') }}</p>
</div>
@error('nominal_pembayaran')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<div>
<label for="bukti_pembayaran" class="block text-sm font-medium text-gray-700 mb-2">
Bukti Pembayaran <span class="text-red-500">*</span>
</label>
<input type="file" name="bukti_pembayaran" id="bukti_pembayaran"
accept="image/*"
class="w-full border border-gray-300 rounded-md shadow-sm px-3 py-2 focus:ring-blue-500 focus:border-blue-500" required>
<p class="mt-1 text-sm text-gray-500">Format: JPG, PNG, JPEG (Maks. 2MB)</p>
@error('bukti_pembayaran')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<div>
<label for="jenis_jaminan" class="block text-sm font-medium text-gray-700 mb-2">
Jenis Jaminan <span class="text-red-500">*</span>
</label>
<select name="jenis_jaminan" id="jenis_jaminan"
class="w-full border border-gray-300 rounded-md shadow-sm px-3 py-2 focus:ring-blue-500 focus:border-blue-500" required>
<option value="">Pilih Jenis Jaminan</option>
<option value="ktp">KTP</option>
<option value="sim">SIM</option>
</select>
@error('jenis_jaminan')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<div>
<label for="foto_jaminan" class="block text-sm font-medium text-gray-700 mb-2">
Foto Jaminan (KTP/SIM) <span class="text-red-500">*</span>
</label>
<input type="file" name="foto_jaminan" id="foto_jaminan"
accept="image/*"
class="w-full border border-gray-300 rounded-md shadow-sm px-3 py-2 focus:ring-blue-500 focus:border-blue-500" required>
<p class="mt-1 text-sm text-gray-500">Format: JPG, PNG, JPEG (Maks. 2MB)</p>
@error('foto_jaminan')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<div class="pt-4">
<button type="submit"
class="w-full bg-blue-600 text-white rounded-md py-2 px-4 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">
Upload dan Lanjutkan Penyewaan
</button>
</div>
</form>
<h4 class="font-semibold text-gray-700 mb-3">Informasi Waktu</h4>
<div class="space-y-2">
<p class="text-sm">
<span class="font-medium">Tanggal Mulai:</span>
<span class="text-gray-600">{{ $sewa->tanggal_mulai->format('d M Y') }}</span>
</p>
<p class="text-sm">
<span class="font-medium">Tanggal Selesai:</span>
<span class="text-gray-600">{{ $sewa->tanggal_selesai->format('d M Y') }}</span>
</p>
<p class="text-sm">
<span class="font-medium">Status:</span>
<span class="px-2 py-1 text-xs font-semibold rounded-full
{{ $sewa->status === 'pending' ? 'bg-yellow-100 text-yellow-800' : '' }}
{{ $sewa->status === 'disetujui' ? 'bg-green-100 text-green-800' : '' }}
{{ $sewa->status === 'ditolak' ? 'bg-red-100 text-red-800' : '' }}
{{ $sewa->status === 'selesai' ? 'bg-blue-100 text-blue-800' : '' }}
{{ $sewa->status === 'dibatalkan' ? 'bg-gray-100 text-gray-800' : '' }}">
{{ $sewa->status_label }}
</span>
</p>
</div>
</div>
@endif
</div>
</div>
</div>
<div class="mt-8 flex space-x-4">
<a href="{{ route('sewa.index') }}"
class="inline-flex items-center px-4 py-2 border border-gray-300 rounded-md text-gray-700 bg-white hover:bg-gray-50">
<svg class="h-5 w-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
Kembali
</a>
@if(auth()->check() && $sewa->status != 'draft')
<a href="{{ auth()->user()->tipe_pengguna === 'admin' ? route('chat.show', $sewa->user_id) : route('chat.show', $adminId) }}"
class="inline-flex items-center px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">
<svg class="h-5 w-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />
</svg>
{{ auth()->user()->tipe_pengguna === 'admin' ? 'Chat dengan Penyewa' : 'Chat dengan Admin' }}
</a>
<!-- Form Upload -->
<div class="lg:col-span-1">
@if($sewa->status === 'pending' && !$sewa->bukti_pembayaran)
<div class="bg-white rounded-lg shadow-lg p-6">
<h3 class="text-lg font-bold text-gray-800 mb-4">Upload Bukti Pembayaran</h3>
<div class="bg-blue-50 border-l-4 border-blue-500 text-blue-700 p-4 mb-4">
<p class="font-medium">Informasi Pembayaran:</p>
<p>Silakan masukkan nominal pembayaran sesuai keinginan Anda.</p>
</div>
<form action="{{ route('sewa.upload-bukti', $sewa->id) }}" method="POST" enctype="multipart/form-data" class="space-y-4">
@csrf
<!-- Nominal Pembayaran -->
<div>
<label for="nominal_pembayaran" class="block text-sm font-medium text-gray-700 mb-1">
Nominal Pembayaran (DP 50% = Rp {{ number_format($sewa->total_harga * 0.5, 0, ',', '.') }})
</label>
<div class="relative rounded-md shadow-sm">
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
<span class="text-gray-500 sm:text-sm">Rp</span>
</div>
<input type="number" name="nominal_pembayaran" id="nominal_pembayaran"
class="block w-full pl-10 pr-3 py-2 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
placeholder="Masukkan nominal pembayaran sesuai keinginan"
min="1"
max="{{ $sewa->total_harga }}"
required>
</div>
@error('nominal_pembayaran')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<!-- Bukti Pembayaran -->
<div>
<label for="bukti_pembayaran" class="block text-sm font-medium text-gray-700 mb-1">
Bukti Pembayaran
</label>
<input type="file" name="bukti_pembayaran" id="bukti_pembayaran"
class="block w-full text-sm text-gray-500
file:mr-4 file:py-2 file:px-4
file:rounded-full file:border-0
file:text-sm file:font-semibold
file:bg-blue-50 file:text-blue-700
hover:file:bg-blue-100"
accept="image/*"
required>
@error('bukti_pembayaran')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<!-- Jenis Jaminan -->
<div>
<label for="jenis_jaminan" class="block text-sm font-medium text-gray-700 mb-1">
Jenis Jaminan
</label>
<select name="jenis_jaminan" id="jenis_jaminan"
class="block w-full py-2 px-3 border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
required>
<option value="">Pilih Jenis Jaminan</option>
<option value="ktp">KTP</option>
<option value="sim">SIM</option>
</select>
@error('jenis_jaminan')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<!-- Foto Jaminan -->
<div>
<label for="foto_jaminan" class="block text-sm font-medium text-gray-700 mb-1">
Foto Jaminan
</label>
<input type="file" name="foto_jaminan" id="foto_jaminan"
class="block w-full text-sm text-gray-500
file:mr-4 file:py-2 file:px-4
file:rounded-full file:border-0
file:text-sm file:font-semibold
file:bg-blue-50 file:text-blue-700
hover:file:bg-blue-100"
accept="image/*"
required>
@error('foto_jaminan')
<p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror
</div>
<div class="pt-4">
<button type="submit"
class="w-full bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition-colors mb-4">
Upload Bukti Pembayaran
</button>
<a href="{{ route('sewa.index') }}"
class="block w-full text-center bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 transition-colors">
Kembali ke Daftar Sewa
</a>
</div>
</form>
</div>
@endif
</div>
</div>

View File

@ -119,7 +119,7 @@
<p class="text-gray-600 mb-4">{{ $paket->keterangan ?? 'Paket lengkap untuk acara Anda' }}</p>
<p class="text-xl font-bold text-[#1e3a8a] mb-4">Rp {{ number_format($paket->harga, 0, ',', '.') }}</p>
@auth
<a href="{{ route('sewa.paket', $paket->id) }}" class="block text-center py-2 px-4 bg-[#1e3a8a] text-white rounded-lg hover:bg-blue-700 transition duration-300">Sewa Sekarang</a>
<a href="{{ route('sewa.create', $paket->id) }}" class="block text-center py-2 px-4 bg-[#1e3a8a] text-white rounded-lg hover:bg-blue-700 transition duration-300">Sewa Sekarang</a>
@else
<a href="{{ route('register', ['paket_id' => $paket->id]) }}" class="block text-center py-2 px-4 bg-[#1e3a8a] text-white rounded-lg hover:bg-blue-700 transition duration-300">Sewa Sekarang</a>
@endauth

View File

@ -34,8 +34,8 @@
return view('welcome', compact('pakets'));
});
// Route untuk proses sewa dari landing page
Route::get('/sewa-paket/{id}', [SewaController::class, 'create'])->name('sewa.paket');
// Route untuk sewa yang bisa diakses tanpa login
Route::get('/sewa', [SewaController::class, 'index'])->name('sewa.index');
// Route untuk Authentication (untuk guest)
Route::middleware('guest')->group(function () {
@ -108,21 +108,22 @@
Route::put('/paket-barang/{id}', [PaketBarangController::class, 'update'])->name('paket-barang.update');
Route::delete('/paket-barang/{id}', [PaketBarangController::class, 'destroy'])->name('paket-barang.destroy');
// Sewa
Route::get('/sewa', [SewaController::class, 'index'])->name('sewa');
Route::get('/sewa/riwayat', [SewaController::class, 'riwayat'])->name('sewa.riwayat');
Route::get('/sewa/{id}/detail', [SewaController::class, 'detail'])->name('sewa.detail');
Route::get('/sewa/create/{id}', [SewaController::class, 'create'])->name('sewa.create');
Route::post('/sewa', [SewaController::class, 'store'])->name('sewa.store');
Route::get('/sewa/{id}', [SewaController::class, 'show'])->name('sewa.show');
Route::post('/sewa/{id}/upload-bukti', [SewaController::class, 'uploadBukti'])->name('sewa.upload-bukti');
Route::post('/sewa/{id}/upload-jaminan', [SewaController::class, 'uploadJaminan'])->name('sewa.upload-jaminan');
Route::post('/sewa/{id}/batal', [SewaController::class, 'batal'])->name('sewa.batal');
// Sewa Routes
Route::prefix('sewa')->name('sewa.')->group(function () {
Route::get('/create/{id}', [SewaController::class, 'create'])->name('create');
Route::post('/', [SewaController::class, 'store'])->name('store');
Route::get('/{id}', [SewaController::class, 'show'])->name('show');
Route::post('/{id}/upload-bukti', [SewaController::class, 'uploadBukti'])->name('upload-bukti');
Route::post('/{id}/upload-jaminan', [SewaController::class, 'uploadJaminan'])->name('upload-jaminan');
Route::post('/{id}/batal', [SewaController::class, 'batal'])->name('batal');
Route::get('/riwayat', [SewaController::class, 'riwayat'])->name('riwayat');
});
// Riwayat
Route::get('/riwayat', [RiwayatController::class, 'index'])->name('riwayat');
Route::get('/riwayat/{id}', [RiwayatController::class, 'show'])->name('riwayat.show');
Route::put('/riwayat/{id}/batal', [RiwayatController::class, 'cancel'])->name('riwayat.batal');
Route::delete('/riwayat/{id}/hapus', [RiwayatController::class, 'hapus'])->name('riwayat.hapus');
// Admin Riwayat
Route::prefix('admin')->name('admin.')->group(function () {
@ -186,3 +187,5 @@
Route::get('/admin/contact', [ContactInfoController::class, 'index'])->name('contact.index');
Route::post('/admin/contact', [ContactInfoController::class, 'store'])->name('contact.store');
});
Route::get('/paket/{id}/detail', [PaketController::class, 'detail'])->name('paket.detail');