Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 70 additions & 52 deletions app/Http/Controllers/Admin/AdminBookingController.php
Original file line number Diff line number Diff line change
@@ -1,100 +1,118 @@
<?php

namespace App\Http\Controllers\Admin;

use App\Models\Booking;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;
use Illuminate\Support\Facades\Storage;
use Carbon\Carbon;

class AdminBookingController extends Controller
{
/**
* Display a listing of the resource.
* Tampilkan daftar pesanan.
*/
public function index()
{
// Ambil semua pesanan dan urutkan dari yang terbaru
$bookings = Booking::latest()->paginate(15);

return view('admin.bookings.index', compact('bookings'));
}

/**
* Show the form for creating a new resource.
* Tampilkan detail pesanan.
*/
public function create()
public function show(string $id)
{
//
$booking = Booking::findOrFail($id);
return view('admin.bookings.show', compact('booking'));
}

/**
* Store a newly created resource in storage.
* Konfirmasi pembayaran DP dan arahkan ke WhatsApp.
*/
public function store(Request $request)
public function confirmDp(Request $request, $id)
{
//
}
$booking = Booking::findOrFail($id);

/**
* Display the specified resource.
*/
public function show(string $id)
{
$booking = Booking::findOrFail($id); // Cari booking secara manual
$request->validate([
'dp_amount' => 'required|numeric|min:0',
'dp_proof' => 'required|image|max:2048',
]);

return view('admin.bookings.show', compact('booking'));
}
$path = $request->file('dp_proof')->store('bukti_dp', 'public');

/**
* Show the form for editing the specified resource.
*/
public function edit(string $id)
{
//
$booking->update([
'dp_amount' => $request->dp_amount,
'dp_proof' => $path,
'status' => 'booked',
]);

// Pesan sukses
session()->flash('success', 'DP berhasil dikonfirmasi. Silakan kirim pesan ke pelanggan.');

// Pesan WhatsApp
$message = "Halo kak {$booking->contact_name},\n\n"
. "Terima kasih, DP kamu untuk sesi {$booking->session_name} pada tanggal "
. Carbon::parse($booking->booking_date)->format('d F Y') . " pukul {$booking->booking_time} telah kami terima.\n"
. "Pesananmu sudah dikonfirmasi. Sampai jumpa di hari H!";

$whatsappNumber = preg_replace('/[^0-9]/', '', $booking->whatsapp_number);
$url = 'https://wa.me/' . $whatsappNumber . '?text=' . urlencode($message);

return redirect()->away($url);
}

/**
* Update the specified resource in storage.
* Selesaikan pesanan (pelunasan) dan arahkan ke WhatsApp.
*/
public function update(Request $request, $id)
public function completeBooking(Request $request, $id)
{
$booking = Booking::findOrFail($id);

$validatedData = $request->validate([
'status' => ['required', Rule::in(['pending', 'confirmed', 'completed', 'cancelled'])],
$request->validate([
'final_payment_amount' => 'required|numeric|min:0',
'final_payment_proof' => 'required|image|max:2048',
]);

$booking->status = $validatedData['status'];
$booking->save();

// Cek apakah status yang baru adalah 'confirmed'
if ($booking->status === 'confirmed') {
// Jika iya, siapkan pesan WhatsApp
$message = "Halo kak " . $booking->contact_name . ",\n\n"
. "Pesanan kamu untuk sesi " . $booking->session_name . " pada tanggal "
. Carbon::parse($booking->booking_date)->format('d F Y')
. " jam " . $booking->booking_time . " sudah berhasil dikonfirmasi.\n\n"
. "Terima kasih sudah memesan di tempat kami!";

$whatsappUrl = 'https://wa.me/' . $booking->whatsapp_number . '?text=' . urlencode($message);

// Redirect ke URL WhatsApp
return redirect()->away($whatsappUrl);
}
$path = $request->file('final_payment_proof')->store('bukti_pelunasan', 'public');

// Jika status bukan 'confirmed', redirect kembali ke halaman sebelumnya
return redirect()->back()->with('success', 'Status pesanan berhasil diperbarui.');
}
$booking->update([
'final_payment_amount' => $request->final_payment_amount,
'final_payment_proof' => $path,
'status' => 'completed',
]);

// Pesan sukses
session()->flash('success', 'Pelunasan berhasil dikonfirmasi. Silakan kirim konfirmasi ke pelanggan.');

// Pesan WhatsApp
$message = "Halo kak {$booking->contact_name},\n\n"
. "Kami telah menerima pelunasan untuk sesi {$booking->session_name} pada tanggal "
. Carbon::parse($booking->booking_date)->format('d F Y') . ".\n"
. "Terima kasih telah mempercayakan layanan kami. See you next time!";

$whatsappNumber = preg_replace('/[^0-9]/', '', $booking->whatsapp_number);
$url = 'https://wa.me/' . $whatsappNumber . '?text=' . urlencode($message);

return redirect()->away($url);
}

/**
* Remove the specified resource from storage.
* Hapus pesanan dan hapus file bukti pembayaran.
*/
public function destroy(Booking $booking)
public function destroy(Booking $booking)
{
// Hapus file bukti jika ada
if ($booking->dp_proof) {
Storage::disk('public')->delete($booking->dp_proof);
}
if ($booking->final_payment_proof) {
Storage::disk('public')->delete($booking->final_payment_proof);
}

$booking->delete();

return redirect()->route('bookings.index')->with('success', 'Pesanan berhasil dihapus.');
}
}
}
5 changes: 5 additions & 0 deletions app/Models/Booking.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,13 @@ class Booking extends Model
'total_price',
'notes',
'status',
'dp_amount',
'dp_proof',
'final_payment_amount',
'final_payment_proof',
];


protected $casts = [
'booking_date' => 'date',
'selected_backgrounds' => 'array',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ public function up(): void
$table->json('selected_extra_items'); // Simpan sebagai JSON
$table->integer('total_price');
$table->text('notes')->nullable();
$table->enum('status', ['pending', 'confirmed', 'completed', 'cancelled'])->default('pending');
$table->enum('status', ['waiting', 'booked', 'completed', 'cancelled'])->default('waiting');
$table->timestamps();
});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
public function up(): void
{
Schema::table('bookings', function (Blueprint $table) {
$table->integer('dp_amount')->nullable()->after('notes');
$table->string('dp_proof')->nullable()->after('dp_amount');
$table->integer('final_payment_amount')->nullable()->after('dp_proof');
$table->string('final_payment_proof')->nullable()->after('final_payment_amount');
});
}

public function down(): void
{
Schema::table('bookings', function (Blueprint $table) {
$table->dropColumn([
'dp_amount',
'dp_proof',
'final_payment_amount',
'final_payment_proof',
]);
});
}
};
81 changes: 48 additions & 33 deletions resources/views/admin/bookings/index.blade.php
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
<x-layouts.app :title="__('Bookings')">
<x-layouts.app :title="__('Manajemen Pesanan')">
<div class="container mx-auto px-4 py-8">
<!-- Header -->
<div class="flex justify-between items-center mb-6">
<h1 class="text-2xl font-bold text-gray-800">Manajemen Pesanan</h1>
</div>

<!-- Alert Success -->
@if (session('success'))
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded-lg mb-4" role="alert">
{{ session('success') }}
</div>
<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded-lg mb-4" role="alert">
{{ session('success') }}
</div>
@endif

<!-- Table Container -->
<div class="bg-white shadow-lg rounded-lg overflow-hidden">
<div class="overflow-x-auto">
<table class="min-w-full leading-normal">
Expand All @@ -25,42 +28,54 @@
</thead>
<tbody class="text-gray-600 text-sm font-light">
@forelse ($bookings as $booking)
<tr class="border-b border-gray-200 hover:bg-gray-50">
<td class="py-3 px-6 whitespace-nowrap">{{ $booking->id }}</td>
<td class="py-3 px-6">{{ $booking->contact_name }}</td>
<td class="py-3 px-6">{{ $booking->package_name }}</td>
<td class="py-3 px-6">
{{ \Carbon\Carbon::parse($booking->booking_date)->format('d M Y') }}
<br>
<span class="text-xs text-gray-500">{{ $booking->booking_time }}</span>
</td>
<td class="py-3 px-6">
@php
$badgeColor = [
'pending' => 'bg-yellow-100 text-yellow-800',
'confirmed' => 'bg-green-100 text-green-800',
'completed' => 'bg-blue-100 text-blue-800',
'cancelled' => 'bg-red-100 text-red-800'
][$booking->status] ?? 'bg-gray-100 text-gray-800';
@endphp
<span class="px-2 py-1 text-xs font-semibold rounded-full {{ $badgeColor }}">
{{ ucfirst($booking->status) }}
</span>
</td>
<td class="py-3 px-6 text-center">
<a href="{{ route('bookings.show', $booking->id) }}" class="bg-blue-500 hover:bg-blue-600 text-white font-bold py-1 px-3 rounded text-xs">Lihat Detail</a>
</td>
</tr>
<tr class="border-b border-gray-200 hover:bg-gray-50 transition duration-150">
<td class="py-3 px-6 whitespace-nowrap font-medium text-gray-800">
#{{ $booking->id }}
</td>
<td class="py-3 px-6">
{{ $booking->contact_name }}
</td>
<td class="py-3 px-6">
{{ $booking->package_name }}
</td>
<td class="py-3 px-6">
{{ \Carbon\Carbon::parse($booking->booking_date)->translatedFormat('d F Y') }}
<br>
<span class="text-xs text-gray-500">{{ $booking->booking_time }}</span>
</td>
<td class="py-3 px-6">
@php
$badgeColor = match ($booking->status) {
'waiting' => 'bg-yellow-100 text-yellow-800 border-yellow-200',
'booked' => 'bg-green-100 text-green-800 border-green-200',
'completed' => 'bg-blue-100 text-blue-800 border-blue-200',
default => 'bg-gray-100 text-gray-800 border-gray-200'
};
@endphp
<span class="inline-flex px-2.5 py-1 text-xs font-semibold rounded-full border {{ $badgeColor }}">
{{ ucfirst($booking->status === 'waiting' ? 'Menunggu DP' : ($booking->status === 'booked' ? 'Sudah Dibooking' : 'Selesai')) }}
</span>
</td>
<td class="py-3 px-6 text-center">
<a href="{{ route('bookings.show', $booking->id) }}"
class="inline-block bg-blue-600 hover:bg-blue-700 text-white font-semibold text-sm py-1.5 px-3 rounded-lg transition duration-200 shadow-sm">
Lihat Detail
</a>
</td>
</tr>
@empty
<tr>
<td colspan="6" class="py-3 px-6 text-center text-gray-500">Tidak ada pesanan saat ini.</td>
</tr>
<tr>
<td colspan="6" class="py-6 px-6 text-center text-gray-500 italic">
Tidak ada pesanan saat ini.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>

<!-- Pagination -->
<div class="mt-6">
{{ $bookings->links('pagination::tailwind') }}
</div>
Expand Down
Loading