This commit is contained in:
Putrid1ana 2025-05-24 21:02:25 +07:00
parent 4adc6df40b
commit af29398f05
18 changed files with 509 additions and 304 deletions

View File

@ -17,12 +17,12 @@ public function index(Request $request)
{ {
$query = Booking::query(); $query = Booking::query();
// Filter pencarian berdasarkan status_booking // Filter pencarian berdasarkan bulan dari tanggal_booking
if ($request->has('search') && !empty($request->search)) { if ($request->has('search') && !empty($request->search)) {
$query->where('status_booking', 'like', '%' . $request->search . '%'); $query->whereMonth('tanggal_checkout', $request->search);
} }
$bookings = $query->orderBy('tanggal_booking', 'desc')->paginate(10); $bookings = $query->orderBy('tanggal_checkout', 'desc')->paginate(10);
return view('admin.booking', compact('bookings')); return view('admin.booking', compact('bookings'));
} }
@ -220,4 +220,25 @@ public function approvePerpanjangan($id)
return redirect()->route('admin.booking')->with('success', 'Perpanjangan berhasil dikonfirmasi.'); return redirect()->route('admin.booking')->with('success', 'Perpanjangan berhasil dikonfirmasi.');
} }
public function markAsCompleted($id_booking)
{
$booking = Booking::findOrFail($id_booking);
// Pastikan hanya booking yang dikonfirmasi bisa selesai
if ($booking->status_booking === 'Dikonfirmasi') {
$booking->update(['status_booking' => 'Selesai']);
// Update status kamar menjadi tersedia
$room = $booking->room;
if ($room) {
$room->update(['status' => 'tersedia']);
}
return redirect()->route('admin.booking')->with('success', 'Booking telah diselesaikan.');
}
return redirect()->route('admin.booking')->with('error', 'Booking belum dikonfirmasi.');
}
} }

View File

@ -6,19 +6,43 @@
use App\Models\User; use App\Models\User;
use App\Models\Room; use App\Models\Room;
use App\Models\Booking; use App\Models\Booking;
use Carbon\Carbon;
class DashboardAdminController extends Controller class DashboardAdminController extends Controller
{ {
public function index() public function index()
{ {
// Mengambil data dari database
$totalUsers = User::count(); $totalUsers = User::count();
$totalRooms = Room::count(); $totalRooms = Room::count();
$totalBookings = Booking::count(); $totalBookings = Booking::count();
// Ambil semua booking yang sudah dikonfirmasi
$confirmedBookings = Booking::with('user', 'room')
->where('status_booking', 'Dikonfirmasi')
->get();
// Buat array untuk simpan sisa hari per booking
$daysLeftPerBooking = [];
foreach ($confirmedBookings as $booking) {
if ($booking->tanggal_checkout) {
$daysLeftPerBooking[$booking->id_booking] = now()->diffInDays(Carbon::parse($booking->tanggal_checkout), false);
} else {
$daysLeftPerBooking[$booking->id_booking] = null;
}
}
// Ambil booking pending untuk ditampilkan di tabel
$pendingBookings = Booking::where('status_booking', 'pending')->with('user', 'room')->get(); $pendingBookings = Booking::where('status_booking', 'pending')->with('user', 'room')->get();
// Mengirim data ke view return view('admin.dashboard', compact(
return view('admin.dashboard', compact('totalUsers', 'totalRooms', 'totalBookings', 'pendingBookings')); 'totalUsers',
'totalRooms',
'totalBookings',
'pendingBookings',
'confirmedBookings',
'daysLeftPerBooking'
));
} }
} }

View File

@ -57,7 +57,14 @@ public function index(Request $request)
return $p - $q; return $p - $q;
}, $pemasukan, $pengeluaran); }, $pemasukan, $pengeluaran);
// Kirim data ke view // Ambil data status kamar (tersedia, terisi, maintenance)
$data_kamar = [
'Terisi' => Room::where('status', 'terisi')->count(),
'Kosong' => Room::where('status', 'tersedia')->count(),
'Rusak' => Room::where('status', 'maintenance')->count(),
];
// Kirim semua data ke view
return view('pemilik.dashboard', compact( return view('pemilik.dashboard', compact(
'totalUsers', 'totalUsers',
'totalRooms', 'totalRooms',
@ -70,7 +77,8 @@ public function index(Request $request)
'pengeluaran', 'pengeluaran',
'keuntungan', 'keuntungan',
'tahunList', 'tahunList',
'tahunTerpilih' 'tahunTerpilih',
'data_kamar'
)); ));
} }
} }

View File

@ -44,13 +44,19 @@ public function store(Request $request)
{ {
$request->validate([ $request->validate([
'keterangan' => 'required|string|max:255', 'keterangan' => 'required|string|max:255',
'jumlah_pengeluaran' => 'required|numeric|min:0', 'jumlah_pengeluaran' => 'required',
'tanggal_pengeluaran'=> 'required|date', 'tanggal_pengeluaran'=> 'required|date',
]); ]);
Expense::create($request->only(['keterangan', 'jumlah_pengeluaran', 'tanggal_pengeluaran'])); // Hilangkan titik/koma agar jumlah valid
$jumlah = str_replace(['.', ','], '', $request->jumlah_pengeluaran);
Expense::create([
'keterangan' => $request->keterangan,
'jumlah_pengeluaran' => $jumlah,
'tanggal_pengeluaran' => $request->tanggal_pengeluaran,
]);
// Update data keuangan
$this->updateFinance(); $this->updateFinance();
return redirect()->route('admin.expense')->with('success', 'Pengeluaran berhasil ditambahkan.'); return redirect()->route('admin.expense')->with('success', 'Pengeluaran berhasil ditambahkan.');
@ -72,14 +78,21 @@ public function update(Request $request, $id_pengeluaran)
{ {
$request->validate([ $request->validate([
'keterangan' => 'required|string|max:255', 'keterangan' => 'required|string|max:255',
'jumlah_pengeluaran' => 'required|numeric|min:0', 'jumlah_pengeluaran' => 'required',
'tanggal_pengeluaran'=> 'required|date', 'tanggal_pengeluaran'=> 'required|date',
]); ]);
$pengeluaran = Expense::findOrFail($id_pengeluaran); $pengeluaran = Expense::findOrFail($id_pengeluaran);
$pengeluaran->update($request->only(['keterangan', 'jumlah_pengeluaran', 'tanggal_pengeluaran']));
// Update data keuangan // Hilangkan titik/koma dari input user
$jumlah = str_replace(['.', ','], '', $request->jumlah_pengeluaran);
$pengeluaran->update([
'keterangan' => $request->keterangan,
'jumlah_pengeluaran' => $jumlah,
'tanggal_pengeluaran' => $request->tanggal_pengeluaran,
]);
$this->updateFinance(); $this->updateFinance();
return redirect()->route('admin.expense')->with('success', 'Pengeluaran berhasil diperbarui.'); return redirect()->route('admin.expense')->with('success', 'Pengeluaran berhasil diperbarui.');
@ -104,12 +117,27 @@ public function destroy($id_pengeluaran)
*/ */
private function updateFinance() private function updateFinance()
{ {
$tanggalHariIni = now()->format('Y-m-d');
$totalPemasukan = Transaksi::sum('jumlah_pembayaran'); $totalPemasukan = Transaksi::sum('jumlah_pembayaran');
$totalPengeluaran = Expense::sum('jumlah_pengeluaran'); $totalPengeluaran = Expense::sum('jumlah_pengeluaran');
$totalKeuntungan = $totalPemasukan - $totalPengeluaran; $totalKeuntungan = $totalPemasukan - $totalPengeluaran;
// Cek apakah sudah ada data finance untuk hari ini
$finance = Finance::where('tanggal', $tanggalHariIni)->first();
if ($finance) {
// Update data yang sudah ada
$finance->update([
'pemasukan' => $totalPemasukan,
'pengeluaran' => $totalPengeluaran,
'keuntungan' => $totalKeuntungan,
'keterangan' => 'Update otomatis dari data pengeluaran'
]);
} else {
// Buat data baru
Finance::create([ Finance::create([
'tanggal' => now()->format('Y-m-d'), 'tanggal' => $tanggalHariIni,
'pemasukan' => $totalPemasukan, 'pemasukan' => $totalPemasukan,
'pengeluaran' => $totalPengeluaran, 'pengeluaran' => $totalPengeluaran,
'keuntungan' => $totalKeuntungan, 'keuntungan' => $totalKeuntungan,
@ -117,3 +145,4 @@ private function updateFinance()
]); ]);
} }
} }
}

View File

@ -5,14 +5,26 @@
use Illuminate\Http\Request; use Illuminate\Http\Request;
use App\Models\Room; use App\Models\Room;
use App\Models\Booking; use App\Models\Booking;
use Carbon\Carbon;
class KamarController extends Controller class KamarController extends Controller
{ {
public function index() public function index()
{ {
$booking = Booking::where('id_user', auth()->id())->orderBy('tanggal_booking', 'desc')->first(); $booking = Booking::where('id_user', auth()->id())
->orderBy('tanggal_booking', 'desc')
->first();
$rooms = Room::all(); $rooms = Room::all();
return view('users.peta', compact('booking', 'rooms'));
$daysLeft = null;
if ($booking && $booking->status_booking === 'Dikonfirmasi' && $booking->tanggal_checkout) {
$today = Carbon::now();
$checkoutDate = Carbon::parse($booking->tanggal_checkout);
$daysLeft = $today->diffInDays($checkoutDate, false);
} }
return view('users.peta', compact('booking', 'rooms', 'daysLeft'));
}
} }

View File

@ -36,7 +36,15 @@ public function index(Request $request)
$row->bulan = $months[$row->bulan] ?? $row->bulan; $row->bulan = $months[$row->bulan] ?? $row->bulan;
} }
return view('admin.keuangan', compact('filteredLaporan', 'years', 'months')); // Hitung total pemasukan, pengeluaran, dan keuntungan bersih
} $totalPemasukan = $filteredLaporan->sum('total_pemasukan');
} $totalPengeluaran = $filteredLaporan->sum('total_pengeluaran');
$totalKeuntungan = $filteredLaporan->sum('keuntungan_bersih');
// Kirim ke view
return view('admin.keuangan', compact(
'filteredLaporan', 'years', 'months',
'totalPemasukan', 'totalPengeluaran', 'totalKeuntungan'
));
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 146 KiB

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 74 KiB

View File

@ -50,21 +50,11 @@
<i class="bi bi-trash-fill"></i> <i class="bi bi-trash-fill"></i>
</a> </a>
{{-- <!-- Tombol Konfirmasi Pemesanan hanya muncul jika status booking 'Pending' --> @if ($booking->status_booking === 'Dikonfirmasi')
@if($booking->status_booking == 'Pending') <a href="{{ route('admin.bookingselesai', $booking->id_booking) }}" class="btn btn-success btn-sm mt-1">
<form action="{{ route('admin.bookingconfirm', $booking->id_booking) }}" method="POST" style="display:inline-block; margin-top: 5px;"> Tandai Selesai
@csrf </a>
<button type="submit" class="btn btn-primary btn-sm">Konfirmasi Pemesanan</button>
</form>
@endif @endif
<!-- Tombol Batalkan Booking hanya muncul jika status booking 'Dikonfirmasi' -->
@if($booking->status_booking == 'Dikonfirmasi')
<form action="{{ route('admin.bookingcancel', $booking->id_booking) }}" method="POST" style="display:inline-block; margin-top: 5px;">
@csrf
<button type="submit" class="btn btn-danger btn-sm">Batalkan Booking</button>
</form>
@endif --}}
</td> </td>
</tr> </tr>
@endforeach @endforeach

View File

@ -19,7 +19,7 @@
<div class="mb-3"> <div class="mb-3">
<label for="jumlah_pengeluaran" class="form-label">Jumlah (Rp)</label> <label for="jumlah_pengeluaran" class="form-label">Jumlah (Rp)</label>
<input type="number" name="jumlah_pengeluaran" id="jumlah_pengeluaran" class="form-control" step="0.01" required> <input type="text" name="jumlah_pengeluaran" id="jumlah_pengeluaran" class="form-control" required placeholder="Contoh: 1.200.000">
</div> </div>
<div class="d-flex justify-content-between"> <div class="d-flex justify-content-between">

View File

@ -2,7 +2,28 @@
@section('content') @section('content')
<div class="container-fluid p-4" style="background-color: #F5F5F5; border-radius: 10px;"> <div class="container-fluid p-4" style="background-color: #F5F5F5; border-radius: 10px;">
<h3 class="fw-bold" style="color: #063986;">Selamat Datang Di Kos Calista</h3> <h3 class="fw-bold" style="color: #063986;">Selamat Datang Di Kos Calista</h3>
{{-- Notifikasi sisa masa booking customer (kalau ada booking terakhir) --}}
@isset($booking)
@if (!is_null($daysLeft))
@if ($daysLeft > 0)
<div class="alert alert-warning mt-3 fw-semibold text-dark">
Sisa booking customer: <strong>{{ $daysLeft }} hari</strong>
</div>
@elseif ($daysLeft === 0)
<div class="alert alert-danger mt-3 fw-semibold">
Hari ini adalah <strong>hari terakhir</strong> masa booking customer!
</div>
@else
<div class="alert alert-secondary mt-3 fw-semibold">
Masa booking customer sudah <strong>berakhir</strong>.
</div>
@endif
@endif
@endisset
<div class="row mt-4"> <div class="row mt-4">
{{-- Statistik --}}
<div class="col-md-4"> <div class="col-md-4">
<div class="card border shadow-sm"> <div class="card border shadow-sm">
<div class="card-body text-center p-4"> <div class="card-body text-center p-4">
@ -45,6 +66,8 @@
</div> </div>
</div> </div>
</div> </div>
{{-- Tabel Pending Booking --}}
<div class="row mt-5"> <div class="row mt-5">
<div class="col-12"> <div class="col-12">
<div class="card border shadow-sm"> <div class="card border shadow-sm">
@ -64,6 +87,7 @@
<th>Kamar</th> <th>Kamar</th>
<th>Tanggal Pemesanan</th> <th>Tanggal Pemesanan</th>
<th>Status</th> <th>Status</th>
<th>Aksi</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -102,7 +126,6 @@
</tr> </tr>
@endforeach @endforeach
</tbody> </tbody>
</table> </table>
</div> </div>
@endif @endif
@ -110,5 +133,38 @@
</div> </div>
</div> </div>
</div> </div>
{{-- Tampilkan Booking yang sudah dikonfirmasi beserta sisa hari --}}
<div class="row mt-5">
<div class="col-12">
<h5 class="fw-bold text-primary mb-3">Sisa Hari Booking</h5>
@foreach ($confirmedBookings as $booking)
<div class="mb-3 p-3 border rounded bg-light">
<p><strong>Customer:</strong> {{ $booking->user->name }}</p>
<p><strong>Booking Kamar:</strong> {{ $booking->room->room_type }}</p>
@php
$daysLeft = $daysLeftPerBooking[$booking->id_booking] ?? null;
@endphp
@if(!is_null($daysLeft))
@if($daysLeft > 0)
<div class="alert alert-warning mb-0">
Sisa booking: <strong>{{ $daysLeft }} hari</strong>
</div>
@elseif($daysLeft === 0)
<div class="alert alert-danger mb-0">
Hari ini <strong>terakhir</strong> masa booking!
</div>
@else
<div class="alert alert-secondary mb-0">
Masa booking sudah <strong>berakhir</strong>
</div>
@endif
@endif
</div>
@endforeach
</div>
</div>
</div>
</div> </div>
@endsection @endsection

View File

@ -42,7 +42,7 @@
<td>{{ ($rooms->currentPage() - 1) * $rooms->perPage() + $loop->iteration }}</td> <td>{{ ($rooms->currentPage() - 1) * $rooms->perPage() + $loop->iteration }}</td>
<td>{{ $room->room_number }}</td> <td>{{ $room->room_number }}</td>
<td>{{ $room->room_type }}</td> <td>{{ $room->room_type }}</td>
<td>Rp {{ number_format($room->harga, 0, ',', '.') }}</td> <td>Rp {{ number_format((int) $room->harga, 0, ',', '.') }}</td>
<td>{{ ucfirst($room->status) }}</td> <td>{{ ucfirst($room->status) }}</td>
<td>{{ $room->lantai }}</td> <td>{{ $room->lantai }}</td>
<td>{{ $room->fasilitas }}</td> <td>{{ $room->fasilitas }}</td>

View File

@ -36,7 +36,7 @@
<tr> <tr>
<td>{{ $index + 1 }}</td> <td>{{ $index + 1 }}</td>
<td>{{ $item->booking->user->name }} - Kamar {{ $item->booking->room->room_number }}</td> <td>{{ $item->booking->user->name }} - Kamar {{ $item->booking->room->room_number }}</td>
<td>Rp {{ number_format($item->jumlah_pembayaran, 2, ',', '.') }}</td> <td>Rp {{ number_format((int) $item->jumlah_pembayaran, 0, ',', '.') }}</td>
<td>{{ $item->metode_pembayaran ?? 'Belum dipilih' }}</td> <td>{{ $item->metode_pembayaran ?? 'Belum dipilih' }}</td>
<td>{{ ucfirst($item->status_transaksi) }}</td> <td>{{ ucfirst($item->status_transaksi) }}</td>
<td> <td>

View File

@ -49,63 +49,66 @@
</div> </div>
</div> </div>
<!-- Grafik Keuangan -->
<div class="row mt-4"> <div class="row mt-4">
<div class="col-12 text-center mb-3"> <div class="col-12 text-center mb-3">
<div class="d-flex justify-content-center gap-3 flex-wrap"> <div class="d-flex justify-content-center gap-3 flex-wrap">
<div> <div>
<label for="bulanSelect" class="form-label fw-semibold mb-1">Pilih Bulan</label> <label for="bulanSelect" class="form-label fw-semibold mb-1">Pilih Bulan</label>
<select id="bulanSelect" class="form-select"> <select id="bulanSelect" class="form-select">
<option value="all">Semua Bulan</option> <option value="0">Semua Bulan</option>
@foreach($labels as $index => $bulan) @foreach($labels as $index => $bulan)
<option value="{{ $index }}">{{ $bulan }}</option> <option value="{{ $index + 1 }}">{{ $bulan }}</option>
@endforeach @endforeach
</select> </select>
</div> </div>
<div> <div>
<label for="tahunSelect" class="form-label fw-semibold mb-1">Pilih Tahun</label> <label for="tahunSelect" class="form-label fw-semibold mb-1">Pilih Tahun</label>
<select id="tahunSelect" class="form-select"> <select id="tahunSelect" class="form-select" onchange="location.href='?tahun=' + this.value">
@foreach($tahunList as $tahun) @foreach($tahunList as $tahun)
<option value="{{ $tahun }}" {{ $tahun == $tahunTerpilih ? 'selected' : '' }}>{{ $tahun }}</option> <option value="{{ $tahun }}" {{ $tahun == $tahunTerpilih ? 'selected' : '' }}>{{ $tahun }}
</option>
@endforeach @endforeach
</select> </select>
</div> </div>
</div> </div>
</div> </div>
<!-- Grafik Keuangan -->
<div class="col-md-6"> <div class="col-md-6">
<div class="card border shadow-sm"> <div class="card border shadow-sm">
<div class="card-body p-4"> <div class="card-body p-4">
<h5 class="text-center fw-bold">Bar Chart Keuangan</h5> <h5 class="text-center fw-bold">Keuangan</h5>
<canvas id="keuanganBarChart"></canvas> <canvas id="keuanganBarChart" style="max-height: 300px;"></canvas>
</div> </div>
</div> </div>
</div> </div>
<!-- Grafik Kamar -->
<div class="col-md-6"> <div class="col-md-6">
<div class="card border shadow-sm"> <div class="card border shadow-sm">
<div class="card-body p-4"> <div class="card-body p-4">
<h5 class="text-center fw-bold">Pie Chart Keuangan</h5> <h5 class="text-center fw-bold">Data Kamar</h5>
<canvas id="keuanganPieChart"></canvas> <canvas id="dataKamarPieChart" style="max-height: 300px;"></canvas>
</div>
</div> </div>
</div> </div>
</div> </div>
@endsection @endsection
@push('scripts') @push('scripts')
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script> <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script src="https://cdn.jsdelivr.net/npm/chartjs-plugin-datalabels@2"></script>
<script> <script>
document.addEventListener("DOMContentLoaded", function () { document.addEventListener("DOMContentLoaded", function () {
const labels = {!! json_encode($labels) !!}; const labels = {!! json_encode($labels) !!};
const pemasukan = {!! json_encode($pemasukan) !!}; const pemasukan = {!! json_encode($pemasukan) !!};
const pengeluaran = {!! json_encode($pengeluaran) !!}; const pengeluaran = {!! json_encode($pengeluaran) !!};
const keuntungan = {!! json_encode($keuntungan) !!}; const keuntungan = {!! json_encode($keuntungan) !!};
const dataKamar = {!! json_encode($data_kamar ?? []) !!}; // ✅ benar
// === BAR CHART === // BAR CHART KEUANGAN
const ctxBar = document.getElementById('keuanganBarChart').getContext('2d'); new Chart(document.getElementById('keuanganBarChart').getContext('2d'), {
new Chart(ctxBar, {
type: 'bar', type: 'bar',
data: { data: {
labels: labels, labels: labels,
@ -147,43 +150,40 @@
y: { y: {
beginAtZero: true, beginAtZero: true,
ticks: { ticks: {
callback: function(value) { callback: value => 'Rp ' + value.toLocaleString('id-ID')
return 'Rp ' + value.toLocaleString('id-ID');
}
} }
} }
}, },
plugins: { plugins: {
tooltip: { tooltip: {
callbacks: { callbacks: {
label: function(context) { label: context => `${context.dataset.label}: Rp ${context.parsed.y.toLocaleString('id-ID')}`
return context.dataset.label + ': Rp ' + context.parsed.y.toLocaleString('id-ID');
}
} }
} }
} }
} }
}); });
// === PIE CHART === // PIE CHART DATA KAMAR (Tampilkan jumlah kamar sebagai label)
const bulanSelect = document.getElementById('bulanSelect'); const ctxKamar = document.getElementById('dataKamarPieChart').getContext('2d');
const ctxPie = document.getElementById('keuanganPieChart').getContext('2d'); const kamarLabels = Object.keys(dataKamar);
const kamarData = Object.values(dataKamar);
let pieChart = new Chart(ctxPie, { new Chart(ctxKamar, {
type: 'pie', type: 'pie',
data: { data: {
labels: ['Pemasukan', 'Pengeluaran', 'Keuntungan'], labels: kamarLabels,
datasets: [{ datasets: [{
data: [pemasukan[0], pengeluaran[0], keuntungan[0]], data: kamarData,
backgroundColor: [ backgroundColor: [
'rgba(54, 162, 235, 0.7)', 'rgba(75, 192, 192, 0.7)', // Terisi
'rgba(255, 99, 132, 0.7)', 'rgba(255, 206, 86, 0.7)', // Kosong
'rgba(75, 192, 192, 0.7)' 'rgba(255, 99, 132, 0.7)' // Rusak
], ],
borderColor: [ borderColor: [
'rgba(54, 162, 235, 1)', 'rgba(75, 192, 192, 1)',
'rgba(255, 99, 132, 1)', 'rgba(255, 206, 86, 1)',
'rgba(75, 192, 192, 1)' 'rgba(255, 99, 132, 1)'
], ],
borderWidth: 1 borderWidth: 1
}] }]
@ -193,20 +193,26 @@
plugins: { plugins: {
tooltip: { tooltip: {
callbacks: { callbacks: {
label: function(context) { label: (context) => {
return context.label + ': Rp ' + context.parsed.toLocaleString('id-ID'); const value = context.parsed;
return `${context.label}: ${value} kamar`;
}
}
},
legend: {
position: 'bottom'
},
datalabels: {
color: '#000',
formatter: (value) => `${value} kamar`,
font: {
weight: 'bold',
size: 14
} }
} }
} }
} },
} plugins: [ChartDataLabels] // ← tambahkan kembali plugin ini
});
// Event listener untuk ubah bulan
bulanSelect.addEventListener('change', function () {
const i = parseInt(this.value);
pieChart.data.datasets[0].data = [pemasukan[i], pengeluaran[i], keuntungan[i]];
pieChart.update();
}); });
}); });
</script> </script>

View File

@ -51,9 +51,40 @@ class="{{ $room->status == 'tersedia' ? 'text-green-600' : ($room->status == 'te
@endif @endif
@if (!empty($room->deskripsi)) @if (!empty($room->deskripsi))
@php
// Pisahkan berdasarkan dua bagian utama: 'Fasilitas umum :' dan 'Aturan di Kos Calista'
$fasilitas = '';
$aturan = '';
if (preg_match('/Fasilitas umum\s*:\s*(.+?)\s*Aturan di Kos Calista\s*/s', $room->deskripsi, $match)) {
$fasilitas = trim($match[1]);
}
if (preg_match('/Aturan di Kos Calista\s*(.+)/s', $room->deskripsi, $match)) {
$aturan = trim($match[1]);
}
// Ambil item berdasarkan pola angka di depan (1. xxx 2. xxx ...)
preg_match_all('/\d+\.\s*([^0-9]+)/', $fasilitas, $fasilitasList);
preg_match_all('/\d+\.\s*([^0-9]+)/', $aturan, $aturanList);
@endphp
<div class="mb-4"> <div class="mb-4">
<h3 class="text-md font-semibold text-gray-800 mb-1">Deskripsi:</h3> <h3 class="text-md font-semibold text-gray-800 mb-1">Fasilitas Umum:</h3>
<p class="text-gray-700 leading-relaxed text-sm">{!! nl2br(e($room->deskripsi)) !!}</p> <ul class="list-disc pl-5 text-gray-700 text-sm leading-relaxed">
@foreach ($fasilitasList[1] as $item)
<li>{{ trim($item) }}</li>
@endforeach
</ul>
</div>
<div class="mb-4">
<h3 class="text-md font-semibold text-gray-800 mb-1">Aturan di Kos Calista:</h3>
<ul class="list-decimal pl-5 text-gray-700 text-sm leading-relaxed">
@foreach ($aturanList[1] as $item)
<li>{{ trim($item) }}</li>
@endforeach
</ul>
</div> </div>
@endif @endif

View File

@ -14,8 +14,28 @@
<!-- Header --> <!-- Header -->
<header class="bg-black text-white px-6 py-4 rounded-lg flex justify-between items-center shadow-md"> <header class="bg-black text-white px-6 py-4 rounded-lg flex justify-between items-center shadow-md">
<h1 class="text-2xl font-bold">Kos Calista</h1> <h1 class="text-2xl font-bold">Kos Calista</h1>
<div class="flex items-center gap-4">
<div class="flex items-center gap-6">
{{-- Notifikasi sisa masa booking --}}
@isset($daysLeft)
@if ($daysLeft > 0)
<div class="bg-yellow-400 text-black px-4 py-1 rounded text-sm font-medium">
Sisa booking: <strong>{{ $daysLeft }} hari</strong>
</div>
@elseif ($daysLeft === 0)
<div class="bg-red-500 text-white px-4 py-1 rounded text-sm font-medium">
Hari ini <strong>terakhir</strong> masa booking!
</div>
@else
<div class="bg-gray-600 text-white px-4 py-1 rounded text-sm font-medium">
Masa booking sudah <strong>berakhir</strong>
</div>
@endif
@endisset
<i class="fa fa-female text-2xl"></i> <i class="fa fa-female text-2xl"></i>
<!-- Dropdown --> <!-- Dropdown -->
<div class="relative group"> <div class="relative group">
<button class="bg-white text-blue-800 font-semibold px-4 py-2 rounded shadow hover:bg-gray-100 transition"> <button class="bg-white text-blue-800 font-semibold px-4 py-2 rounded shadow hover:bg-gray-100 transition">
@ -27,7 +47,6 @@
class="block px-4 py-2 text-black hover:bg-gray-100"> class="block px-4 py-2 text-black hover:bg-gray-100">
Detail Pesanan Detail Pesanan
</a> </a>
<!-- Menambahkan opsi perpanjangan sewa -->
<a href="{{ route('users.perpanjangan-sewa', ['id_booking' => $booking->id_booking]) }}" <a href="{{ route('users.perpanjangan-sewa', ['id_booking' => $booking->id_booking]) }}"
class="block px-4 py-2 text-black hover:bg-gray-100"> class="block px-4 py-2 text-black hover:bg-gray-100">
Perpanjang Sewa Perpanjang Sewa
@ -37,7 +56,7 @@ class="block px-4 py-2 text-black hover:bg-gray-100">
Detail Pesanan Detail Pesanan
</span> </span>
@endisset @endisset
<!-- Menambahkan opsi Profile -->
<a href="{{ route('users.profile') }}" class="block px-4 py-2 text-black hover:bg-gray-100"> <a href="{{ route('users.profile') }}" class="block px-4 py-2 text-black hover:bg-gray-100">
Profile Profile
</a> </a>

View File

@ -98,9 +98,9 @@
Route::get('/', [CustomerController::class, 'index'])->name('admin.customer'); Route::get('/', [CustomerController::class, 'index'])->name('admin.customer');
Route::get('/create', [CustomerController::class, 'create'])->name('admin.createcustomer'); Route::get('/create', [CustomerController::class, 'create'])->name('admin.createcustomer');
Route::post('/store', [CustomerController::class, 'store'])->name('admin.storecustomer'); Route::post('/store', [CustomerController::class, 'store'])->name('admin.storecustomer');
Route::get('/edit/{id}', [CustomerController::class, 'edit'])->name('admin.editcustomer'); Route::get('/edit/{id_user}', [CustomerController::class, 'edit'])->name('admin.editcustomer');
Route::put('/update/{id}', [CustomerController::class, 'update'])->name('admin.updatecustomer'); Route::put('/update/{id_user}', [CustomerController::class, 'update'])->name('admin.updatecustomer');
Route::get('/delete/{id}', [CustomerController::class, 'destroy'])->name('admin.deletecustomer'); Route::get('/delete/{id_user}', [CustomerController::class, 'destroy'])->name('admin.deletecustomer');
}); });
// Rooms // Rooms
@ -134,6 +134,7 @@
Route::put('/confirm/{id_booking}', [BookingController::class, 'confirm'])->name('admin.bookingconfirm'); Route::put('/confirm/{id_booking}', [BookingController::class, 'confirm'])->name('admin.bookingconfirm');
Route::put('/cancel/{id_booking}', [BookingController::class, 'cancel'])->name('admin.bookingcancel'); Route::put('/cancel/{id_booking}', [BookingController::class, 'cancel'])->name('admin.bookingcancel');
Route::put('/admin/booking/perpanjangan/{id}/approve', [BookingController::class, 'approvePerpanjangan'])->name('admin.approvePerpanjangan'); Route::put('/admin/booking/perpanjangan/{id}/approve', [BookingController::class, 'approvePerpanjangan'])->name('admin.approvePerpanjangan');
Route::get('/admin/booking/selesai/{id_booking}', [BookingController::class, 'markAsCompleted'])->name('admin.bookingselesai');
}); });
// Expense // Expense