Docker-AdvancedFeaturesSecu.../resources/views/choose-seat.blade.php

263 lines
13 KiB
PHP

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Choose Seats</title>
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@700;500;400&display=swap" rel="stylesheet">
<style>
body { font-family: 'Montserrat', Arial, sans-serif; background: linear-gradient(120deg, #e0eaff 0%, #fff 100%); margin: 0; padding: 0; }
.header-bar { max-width: 1200px; margin: 0 auto; padding-top: 32px; }
.back-btn { display: inline-flex; align-items: center; background: #fff; color: #2d2350; font-weight: 700; border-radius: 999px; padding: 10px 24px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); border: 1px solid #e0e0e0; text-decoration: none; margin-bottom: 24px; }
.back-btn svg { margin-right: 8px; }
.choose-seats-title { font-size: 2.8rem; font-weight: 900; margin-bottom: 32px; letter-spacing: -2px; color: #2d2350; text-align: left; }
.main-container { max-width: 1200px; margin: 0 auto; display: flex; gap: 40px; align-items: flex-start; }
.flight-card { background: #fff; border-radius: 24px; box-shadow: 0 4px 24px rgba(0,0,0,0.08); padding: 36px 36px 28px 36px; min-width: 390px; max-width: 440px; }
.flight-card h2 { font-size: 1.4rem; margin-bottom: 22px; font-weight: 800; letter-spacing: 1px; }
.flight-info-row { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
.flight-info-label { color: #888; font-size: 1.05rem; font-weight: 500; min-width: 90px; }
.flight-info-value { font-weight: 700; color: #2d2350; text-align: right; max-width: 220px; }
.flight-card .airline-logo { height: 36px; margin-bottom: 10px; }
.flight-card .price { color: #1e9c5a; font-weight: 700; font-size: 1.2rem; }
.flight-card .flight-detail { background: #f7f7fa; border-radius: 16px; padding: 18px 16px; margin: 22px 0; }
.flight-card .flight-detail .airline-logo { height: 32px; }
.flight-card .flight-detail .detail-row { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.flight-card .flight-detail .detail-label { color: #888; font-size: 0.98rem; }
.flight-card .flight-detail .detail-value { font-weight: 700; }
.flight-card .class-card { background: #fff; border-radius: 16px; box-shadow: 0 2px 8px rgba(0,0,0,0.04); padding: 14px 18px; margin-top: 16px; display: flex; align-items: center; }
.flight-card .class-card img { border-radius: 10px; width: 52px; height: 52px; object-fit: cover; margin-right: 16px; }
.flight-card .class-card .class-info { flex: 1; }
.flight-card .class-card .class-title { font-weight: 700; font-size: 1.1rem; }
.flight-card .class-card .class-price { color: #1e9c5a; font-weight: 700; font-size: 1.08rem; }
.plane-bg { background: url('https://i.ibb.co/6b7Qw8k/plane-bg.png') no-repeat center top/contain; border-radius: 32px; min-height: 600px; padding: 40px 32px 32px 32px; flex: 1; position: relative; }
.seat-section { background: rgba(255,255,255,0.97); border-radius: 32px; padding: 36px 28px 28px 28px; box-shadow: 0 4px 24px rgba(0,0,0,0.04); margin-top: 60px; }
.seat-section h3 { text-align: center; font-size: 1.35rem; font-weight: 800; margin-bottom: 22px; letter-spacing: 1px; }
.legend { text-align: center; margin-bottom: 22px; font-size: 1.05rem; }
.legend span { display: inline-block; width: 18px; height: 18px; border-radius: 4px; margin-right: 6px; vertical-align: middle; }
.legend .available { border: 2px solid orange; background: #fff; }
.legend .booked { border: 2px solid #ccc; background: #eee; }
.legend .selected { border: 2px solid #007bff; background: #e0f0ff; }
.seat-map {
display: grid;
grid-template-columns: repeat(3, 48px) 48px repeat(3, 48px);
column-gap: 0;
row-gap: 22px;
justify-content: center;
margin-bottom: 24px;
}
.seat {
border: 2px solid orange;
border-radius: 12px;
padding: 10px 0;
background: #fff;
font-weight: bold;
text-align: center;
cursor: pointer;
font-size: 1.13rem;
transition: 0.2s;
position: relative;
box-sizing: border-box;
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
outline: none;
}
.seat:focus { outline: none; }
.seat.empty { background: transparent; border: none; box-shadow: none; cursor: default; }
.seat.seat-gap { margin-left: 36px; }
.seat.booked { background: #eee; color: #aaa; border: 2px solid #ccc; cursor: not-allowed; }
.seat.selected {
border: 2.5px solid #007bff !important;
background: #e0f0ff !important;
}
@media (max-width: 900px) {
.main-container { flex-direction: column; align-items: stretch; }
.plane-bg { min-height: 400px; }
}
.transaction-card {
background: #fff;
border-radius: 18px;
box-shadow: 0 4px 24px rgba(0,0,0,0.08);
padding: 28px 28px 18px 28px;
margin-bottom: 32px;
min-width: 340px;
max-width: 400px;
}
.transaction-title {
font-size: 1.2rem;
font-weight: 800;
margin-bottom: 18px;
}
.transaction-row {
display: flex;
justify-content: space-between;
margin-bottom: 8px;
font-size: 1.05rem;
}
.transaction-label { color: #888; }
.transaction-value { font-weight: 700; }
.transaction-grand { color: #1976f9; font-weight: 900; font-size: 1.25rem; }
.continue-btn {
width: 100%;
margin-top: 24px;
background: #1976f9;
color: #fff;
border: none;
border-radius: 12px;
padding: 16px 0;
font-size: 1.1rem;
font-weight: 700;
cursor: pointer;
transition: background 0.2s;
}
.continue-btn:disabled {
background: #b3c6f7;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="header-bar">
<a href="{{ url()->previous() }}" class="back-btn">
<svg width="20" height="20" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path d="M15 19l-7-7 7-7"/></svg>
Back to Choose Flight
</a>
<div class="choose-seats-title">Choose Seats</div>
</div>
<div class="main-container">
<!-- Left: Transaction Details -->
<div>
<div class="transaction-card" id="transaction-details">
<div class="transaction-title">Transaction Details</div>
<div class="transaction-row">
<span class="transaction-label">Quantity</span>
<span class="transaction-value" id="quantity-value">1 People</span>
</div>
<div class="transaction-row">
<span class="transaction-label">Tiers</span>
<span class="transaction-value">{{ ucfirst($class->class_type ?? '-') }}</span>
</div>
<div class="transaction-row">
<span class="transaction-label">Seats</span>
<span class="transaction-value" id="seats-value">-</span>
</div>
<div class="transaction-row">
<span class="transaction-label">Price</span>
<span class="transaction-value" id="price-value">Rp {{ number_format($class->price ?? 0, 0, ',', '.') }}</span>
</div>
<div class="transaction-row">
<span class="transaction-label">Govt. Tax</span>
<span class="transaction-value">11%</span>
</div>
<div class="transaction-row">
<span class="transaction-label">Sub Total</span>
<span class="transaction-value" id="subtotal-value">Rp 0</span>
</div>
<div class="transaction-row">
<span class="transaction-label">Total Tax</span>
<span class="transaction-value" id="totaltax-value">Rp 0</span>
</div>
<div class="transaction-row">
<span class="transaction-label">Grand Total</span>
<span class="transaction-grand" id="grandtotal-value">Rp 0</span>
</div>
</div>
</div>
<!-- Right: Seat Map -->
<div class="plane-bg">
<div class="seat-section">
<h3>{{ ucfirst($class->class_type ?? 'Economy') }} Class</h3>
<div class="legend">
<span class="available"></span> Available
<span class="booked"></span> Booked
<span class="selected"></span> Selected
</div>
<form id="seat-booking-form" method="POST" action="{{ route('bookings.store') }}">
@csrf
<input type="hidden" name="seats" id="selected-seats-input">
<input type="hidden" name="class_id" value="{{ $class->id ?? '' }}">
<input type="hidden" name="total_price" id="total-price-input">
<input type="hidden" name="flight_id" value="{{ $flight->id }}">
<div class="seat-map">
@php
$rows = ['A','B','C','D','E'];
$seatMap = collect($seats)->keyBy('name');
@endphp
@foreach($rows as $row)
@for($col = 1; $col <= 7; $col++)
@if($col == 4)
<button class="seat empty" tabindex="-1" disabled></button>
@else
@php
$realCol = $col < 4 ? $col : $col - 1;
$seatName = $row . $realCol;
$seat = $seatMap->get($seatName);
$isAvailable = $seat ? $seat->is_available : true;
$isBooked = $seat && !$seat->is_available;
@endphp
<button type="button" class="seat {{ $isBooked ? 'booked' : '' }}" {{ $isBooked ? 'disabled' : '' }}>{{ $seatName }}</button>
@endif
@endfor
@endforeach
</div>
<button class="continue-btn" id="continue-btn" type="submit" disabled>Continue Booking</button>
</form>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Ambil semua button seat yang tidak empty dan tidak booked
const seatButtons = document.querySelectorAll('.seat:not(.empty):not(.booked)');
const continueBtn = document.getElementById('continue-btn');
const selectedSeatsInput = document.getElementById('selected-seats-input');
const totalPriceInput = document.getElementById('total-price-input');
let selectedSeats = [];
seatButtons.forEach(function(seat) {
seat.addEventListener('click', function() {
this.classList.toggle('selected');
updateTransaction();
});
});
function updateTransaction() {
const seatsValue = document.getElementById('seats-value');
const quantityValue = document.getElementById('quantity-value');
const subtotalValue = document.getElementById('subtotal-value');
const totaltaxValue = document.getElementById('totaltax-value');
const grandtotalValue = document.getElementById('grandtotal-value');
const price = {{ $class->price ?? 0 }};
const tax = 0.11;
const selected = document.querySelectorAll('.seat.selected');
selectedSeats = Array.from(selected).map(s => s.textContent);
seatsValue.textContent = selectedSeats.length ? selectedSeats.join(', ') : '-';
quantityValue.textContent = selectedSeats.length + ' People';
const subtotal = price * selectedSeats.length;
const totaltax = subtotal * tax;
const grandtotal = subtotal + totaltax;
subtotalValue.textContent = 'Rp ' + subtotal.toLocaleString('id-ID');
totaltaxValue.textContent = 'Rp ' + totaltax.toLocaleString('id-ID');
grandtotalValue.textContent = 'Rp ' + grandtotal.toLocaleString('id-ID');
continueBtn.disabled = selectedSeats.length === 0;
selectedSeatsInput.value = JSON.stringify(selectedSeats);
totalPriceInput.value = grandtotal;
}
document.getElementById('seat-booking-form').addEventListener('submit', function(e) {
if (selectedSeats.length === 0) {
e.preventDefault();
return false;
}
selectedSeatsInput.value = JSON.stringify(selectedSeats);
totalPriceInput.value = document.getElementById('grandtotal-value').textContent.replace('Rp ', '').replace(/\./g, '');
});
updateTransaction();
});
</script>
</body>
</html>