ECOMMERCE/resources/views/checkout/v1-delivery-1.blade.php

551 lines
30 KiB
PHP

@extends('layouts.landing', ['title' => 'Checkout'])
@section('content')
<x-layout.header-grocery />
<!-- Page content -->
<main class="content-wrapper">
<div class="container py-5">
<div class="row pt-1 pt-sm-3 pt-lg-4 pb-2 pb-md-3 pb-lg-4 pb-xl-5">
{{-- show error message --}}
@if (session('error'))
<div class="alert alert-danger">
{{ session('error') }}
</div>
@endif
<!-- Delivery info (Step 1) -->
<div class="col-lg-8 col-xl-7 mb-5 mb-lg-0">
<div class="d-flex flex-column gap-5 pe-lg-4 pe-xl-0">
<div class="d-flex align-items-start">
<div class="d-flex align-items-center justify-content-center bg-primary text-white rounded-circle fs-sm fw-semibold lh-1 flex-shrink-0"
style="width: 2rem; height: 2rem; margin-top: -.125rem">1</div>
<div class="w-100 ps-3 ps-md-4">
<h1 class="h5 mb-md-4">{{ __('checkout.delivery_method') }}</h1>
<div class="ms-n5 ms-sm-0">
<p class="fs-sm mb-md-4">{{ __('checkout.choose_delivery_method') }}</p>
<!-- Delivery Method Selection -->
<div class="delivery-method-selection mb-4">
<div class="row">
<div class="col-md-6">
<div class="form-check">
<input class="form-check-input" type="radio" name="deliveryMethod"
id="deliveryOption" value="delivery" checked>
<label class="form-check-label d-flex align-items-center"
for="deliveryOption">
<div>
<div class="fw-medium">
{{ __('checkout.delivery') }}</div>
<div class="text-muted small">
{{ __('checkout.delivery_description') }}</div>
</div>
</label>
</div>
</div>
<div class="col-md-6">
<div class="form-check">
<input class="form-check-input" type="radio" name="deliveryMethod"
id="pickupOption" value="pickup" disabled>
<label class="form-check-label d-flex align-items-center"
for="pickupOption">
<div>
<div class="fw-medium">{{ __('checkout.store_pickup') }}</div>
<div class="text-muted small">
{{ __('checkout.pickup_not_available') }}</div>
</div>
</label>
</div>
</div>
</div>
</div>
<!-- Delivery Options -->
<div id="deliveryOptions" class="delivery-options">
{{-- dropdown address --}}
@if ($address_list->count() > 0)
<div class="mb-4">
<label for="addressSelect"
class="form-label">{{ __('checkout.select_saved_address') }}</label>
<select class="form-select form-select-lg" id="addressSelect">
@foreach ($address_list as $key => $address)
<option value="{{ $address->id }}"
data-first-name="{{ $address->name }}" data-last-name=""
data-address="{{ $address->address }}"
data-city="{{ $address->city->name }}"
data-district="{{ $address->district->name }}"
data-subdistrict="{{ $address->subdistrict->name }}"
data-state="{{ $address->province->name }}"
data-postcode="{{ $address->postal_code }}"
data-phone="{{ $address->phone }}"
data-latitude="{{ $address->latitude }}"
data-longitude="{{ $address->longitude }}"
{{ $address->is_primary || $key === 0 ? 'selected' : '' }}>
{{ $address->label }} - {{ $address->name }},
{{ $address->address }}
@if ($address->is_primary)
<span
class="badge bg-primary ms-2">({{ __('checkout.primary') }})</span>
@endif
</option>
@endforeach
</select>
</div>
@endif
<!-- Shipping Address (shown automatically) -->
<div id="shippingAddress" class="shipping-address mt-4" style="display: block;">
<div class="d-flex justify-content-between">
<h6 class="mb-3">{{ __('checkout.shipping_address') }}</h6>
<a type="button" href="{{ route('addresses') }}"
class="btn btn-outline-primary btn-sm">Edit</a>
</div>
<div class="row g-1">
<div>
<span id="firstName"></span>
(<span id="phone"></span>)
</div>
<div id="address"></div>
<div>
<span id="city"></span>,
<span id="state"></span>, <span id="zip"></span>
</div>
<div>
<span id="latitude"></span>,
<span id="longitude"></span>
</div>
</div>
</div>
</div>
<!-- Pickup Options -->
<div id="pickupOptions" class="pickup-options" style="display: none;">
<div class="store-list">
<div class="form-check mb-3">
<input type="hidden" name="store" value="{{ $store->id }}">
<label class="form-check-label" style="margin-left: 0px;" for="store1">
<div class="fw-medium">{{ $store->display_name }}</div>
<div class="text-muted small">
{{ __('checkout.store_address') }}: {{ $store->address }}<br>
{{ __('checkout.phone') }}: {{ $store->phone }}<br>
{{ __('checkout.hours') }}: {{ $store->hours }}
</div>
</label>
</div>
</div>
</div>
<!-- Continue Button -->
<div class="mt-4">
<form action="{{ route('checkout.delivery.process') }}" method="post">
@csrf
<input type="hidden" name="delivery_method" id="deliveryMethodInput"
value="shipping">
<input type="hidden" name="address_id" id="addressIdInput"
value="{{ $address_list->first()->id }}">
<button type="submit" class="btn btn-lg btn-primary w-100"
id="continueButton">
<span
id="continueButtonText">{{ __('checkout.continue_to_shipping') }}</span>
<i class="ci-chevron-right fs-lg ms-1 me-n1"></i>
</button>
</form>
</div>
</div>
</div>
</div>
<div class="d-flex align-items-start" id="shippingAddressStep">
<div class="d-flex align-items-center justify-content-center bg-body-secondary text-body-secondary rounded-circle fs-sm fw-semibold lh-1 flex-shrink-0"
style="width: 2rem; height: 2rem; margin-top: -.125rem">2</div>
<h2 class="h5 text-body-secondary ps-3 ps-md-4 mb-0">{{ __('checkout.choose_shipping') }}
</h2>
</div>
<div class="d-flex align-items-start">
<div class="d-flex align-items-center justify-content-center bg-body-secondary text-body-secondary rounded-circle fs-sm fw-semibold lh-1 flex-shrink-0"
style="width: 2rem; height: 2rem; margin-top: -.125rem">3</div>
<h2 class="h5 text-body-secondary ps-3 ps-md-4 mb-0">{{ __('checkout.payment') }}</h2>
</div>
</div>
</div>
<!-- Order summary (sticky sidebar) -->
<aside class="col-lg-4 offset-xl-1" style="margin-top: -100px">
<div class="position-sticky top-0" style="padding-top: 100px">
<x-checkout.order-summary :subtotal="$subtotal" :total="$total"
:showEdit="true" :editUrl="route('cart.index')" />
</div>
</aside>
</div>
</div>
</main>
@include('layouts.partials/footer2')
@endsection
@section('scripts')
<script>
document.addEventListener('DOMContentLoaded', function() {
// Delivery method selection
const deliveryOption = document.getElementById('deliveryOption');
const pickupOption = document.getElementById('pickupOption');
const deliveryOptions = document.getElementById('deliveryOptions');
const pickupOptions = document.getElementById('pickupOptions');
const shippingAddress = document.getElementById('shippingAddress');
const continueButton = document.getElementById('continueButton');
// Handle delivery method change
deliveryOption.addEventListener('change', function() {
if (this.checked) {
deliveryOptions.style.display = 'block';
pickupOptions.style.display = 'none';
resetPickupSelection();
// Update button text for delivery
document.getElementById('continueButtonText').textContent =
'{{ __('checkout.continue_to_shipping') }}';
// Update hidden input values
document.getElementById('deliveryMethodInput').value = 'delivery';
// Update address ID from selected address
const addressSelect = document.getElementById('addressSelect');
if (addressSelect && addressSelect.value) {
document.getElementById('addressIdInput').value = addressSelect.value;
}
// Show shipping address step and shipping row
const shippingAddressStep = document.getElementById('shippingAddressStep');
const shippingRow = document.getElementById('shipping-row');
if (shippingAddressStep) {
console.log("Showing shipping address step");
shippingAddressStep.style.visibility = 'visible';
shippingAddressStep.style.height = 'auto';
shippingAddressStep.style.overflow = 'visible';
shippingAddressStep.style.margin = '';
shippingAddressStep.style.padding = '';
}
if (shippingRow) {
console.log("Showing shipping row");
shippingRow.style.visibility = 'visible';
shippingRow.style.height = 'auto';
shippingRow.style.overflow = 'visible';
shippingRow.style.margin = '';
shippingRow.style.padding = '';
} else {
console.log("Shipping row not found");
}
}
});
pickupOption.addEventListener('change', function() {
if (this.checked) {
deliveryOptions.style.display = 'none';
pickupOptions.style.display = 'block';
resetDeliverySelection();
// Update button text for pickup
document.getElementById('continueButtonText').textContent =
'{{ __('checkout.continue_to_payment') }}';
// Update hidden input values
document.getElementById('deliveryMethodInput').value = 'pickup';
document.getElementById('addressIdInput').value = '';
// Hide shipping address step and shipping row
const shippingAddressStep = document.getElementById('shippingAddressStep');
const shippingRow = document.getElementById('shipping-row');
console.log("Elements found:", shippingAddressStep, shippingRow);
if (shippingAddressStep) {
console.log("Hiding shipping address step");
shippingAddressStep.style.visibility = 'hidden';
shippingAddressStep.style.height = '0';
shippingAddressStep.style.overflow = 'hidden';
shippingAddressStep.style.margin = '0';
shippingAddressStep.style.padding = '0';
}
if (shippingRow) {
console.log("Hiding shipping row");
shippingRow.style.visibility = 'hidden';
shippingRow.style.height = '0';
shippingRow.style.overflow = 'hidden';
shippingRow.style.margin = '0';
shippingRow.style.padding = '0';
} else {
console.log("Shipping row not found");
}
}
});
// Address selection handler
const addressSelect = document.getElementById('addressSelect');
if (addressSelect) {
// Auto-populate form with first selected address on page load
function populateAddressForm() {
const selectedOption = addressSelect.options[addressSelect.selectedIndex];
if (selectedOption && selectedOption.value) {
// Populate all shipping address form fields
document.getElementById('firstName').textContent = selectedOption.dataset.firstName || '';
// document.getElementById('lastName').value = selectedOption.dataset.lastName || '';
document.getElementById('address').textContent = selectedOption.dataset.address || '';
document.getElementById('city').textContent = selectedOption.dataset.city || '';
document.getElementById('state').textContent = selectedOption.dataset.state || '';
document.getElementById('zip').textContent = selectedOption.dataset.postcode || '';
document.getElementById('phone').textContent = selectedOption.dataset.phone || '';
document.getElementById('latitude').textContent = selectedOption.dataset.latitude || '';
document.getElementById('longitude').textContent = selectedOption.dataset.longitude || '';
document.getElementById('zip').textContent = selectedOption.dataset.postcode || '';
// Update order summary with postcode
if (selectedOption.dataset.postcode) {
updateOrderSummaryWithShipping();
}
}
}
// Populate on page load
populateAddressForm();
// Set initial address ID
if (addressSelect.value) {
document.getElementById('addressIdInput').value = addressSelect.value;
}
addressSelect.addEventListener('change', function() {
const selectedOption = this.options[this.selectedIndex];
if (this.value === 'new' || this.value === '') {
// Clear form fields for new address
document.getElementById('firstName').textContent = '';
// document.getElementById('lastName').value = '';
document.getElementById('address').textContent = '';
document.getElementById('city').textContent = '';
document.getElementById('state').textContent = '';
document.getElementById('zip').textContent = '';
document.getElementById('phone').textContent = '';
document.getElementById('latitude').textContent = '';
document.getElementById('longitude').textContent = '';
document.getElementById('zip').textContent = '';
// Clear address ID input
document.getElementById('addressIdInput').value = '';
} else {
// Populate form fields with selected address
document.getElementById('firstName').textContent = selectedOption.dataset
.firstName || '';
// document.getElementById('lastName').value = selectedOption.dataset.lastName || '';
document.getElementById('address').textContent = selectedOption.dataset.address ||
'';
document.getElementById('city').textContent = selectedOption.dataset.city || '';
document.getElementById('state').textContent = selectedOption.dataset.state || '';
document.getElementById('zip').textContent = selectedOption.dataset.postcode || '';
document.getElementById('phone').textContent = selectedOption.dataset.phone || '';
document.getElementById('latitude').textContent = selectedOption.dataset.latitude ||
'';
document.getElementById('longitude').textContent = selectedOption.dataset
.longitude || '';
document.getElementById('zip').textContent = selectedOption.dataset.postcode || '';
// Update address ID input
document.getElementById('addressIdInput').value = this.value;
// Update order summary with postcode
if (selectedOption.dataset.postcode) {
updateOrderSummaryWithShipping();
}
}
});
}
// Auto-update order summary when postcode changes
document.getElementById('zip').addEventListener('input', function() {
if (this.value) {
updateOrderSummaryWithShipping();
}
});
// Store selection for pickup
const storeRadios = document.querySelectorAll('input[name="store"]');
storeRadios.forEach(radio => {
radio.addEventListener('change', function() {
if (this.checked) {
updateOrderSummaryForPickup();
}
});
});
// Form validation before continue
continueButton.addEventListener('click', function(e) {
const selectedMethod = document.querySelector('input[name="deliveryMethod"]:checked').value;
if (selectedMethod === 'delivery') {
if (!validateDeliveryForm()) {
e.preventDefault();
return;
}
} else if (selectedMethod === 'pickup') {
if (!validatePickupForm()) {
e.preventDefault();
return;
}
}
});
function resetDeliverySelection() {
resetShippingCalculation();
}
function resetPickupSelection() {
document.querySelectorAll('input[name="store"]').forEach(radio => {
radio.checked = false;
});
resetShippingCalculation();
}
function resetShippingCalculation() {
// Reset order summary to original state
const shippingElement = document.querySelector('[data-shipping-cost]');
if (shippingElement) {
shippingElement.style.display = 'none';
}
const totalElement = document.getElementById('cart-estimated-total');
if (totalElement && window.originalTotal) {
totalElement.textContent = `Rp ${window.originalTotal}`;
}
}
function updateOrderSummaryWithShipping() {
// Simulate shipping cost calculation based on postcode
const shippingCost = calculateShippingCost(document.getElementById('zip').value);
const saving = {{ session('use_point') ?? 0 }};
// Update order summary
const subtotalElement = document.getElementById('cart-subtotal');
const currentSubtotal = parseFloat(subtotalElement.textContent.replace(/[^\d]/g, ''));
const newTotal = currentSubtotal + 0 - saving;
// Store original total
if (!window.originalTotal) {
window.originalTotal = subtotalElement.textContent;
}
// Update total
const totalElement = document.getElementById('cart-estimated-total');
totalElement.textContent = `Rp ${number_format(newTotal, 0, ',', '.')}`;
// Show shipping cost in summary
showShippingCost(shippingCost);
}
function updateOrderSummaryForPickup() {
// Pickup is usually free
const subtotalElement = document.getElementById('cart-subtotal');
const currentSubtotal = parseFloat(subtotalElement.textContent.replace(/[^\d]/g, ''));
// Store original total
if (!window.originalTotal) {
window.originalTotal = subtotalElement.textContent;
}
// Update total (same as subtotal for pickup)
const totalElement = document.getElementById('cart-estimated-total');
totalElement.textContent = subtotalElement.textContent;
// Show free shipping
showShippingCost(0, true);
}
function calculateShippingCost(postcode) {
// Simple shipping cost calculation based on postcode
// In real implementation, this would call an API
const jakartaPostcodes = ['10000', '10110', '10220', '10310', '10410'];
const bandungPostcodes = ['40111', '40112', '40113', '40114', '40115'];
if (jakartaPostcodes.includes(postcode)) {
return 15000; // Jakarta: Rp 15,000
} else if (bandungPostcodes.includes(postcode)) {
return 25000; // Bandung: Rp 25,000
} else {
return 35000; // Other areas: Rp 35,000
}
}
function showShippingCost(cost, isFree = false) {
}
function validateDeliveryForm() {
const postcode = document.getElementById('zip').textContent;
const firstName = document.getElementById('firstName').textContent;
const address = document.getElementById('address').textContent;
const city = document.getElementById('city').textContent;
const phone = document.getElementById('phone').textContent;
if (!postcode) {
alert('{{ __('checkout.enter_postcode') }}');
return false;
}
if (!firstName || !address || !city || !phone) {
alert('{{ __('checkout.fill_required_fields') }}');
return false;
}
return true;
}
function validatePickupForm() {
const selectedStore = document.querySelector('input[name="store"]:checked');
if (!selectedStore) {
alert('{{ __('checkout.select_store') }}');
return false;
}
return true;
}
// Number formatting helper
function number_format(number, decimals, dec_point, thousands_sep) {
number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
var n = !isFinite(+number) ? 0 : +number;
var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals);
var sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep;
var dec = (typeof dec_point === 'undefined') ? '.' : dec_point;
var s = '';
var toFixedFix = function(n, prec) {
var k = Math.pow(10, prec);
return '' + Math.round(n * k) / k;
};
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
if (thousands_sep) {
var re = /(-?\d+)(\d{3})/;
while (re.test(s[0])) {
s[0] = s[0].replace(re, '$1' + sep + '$2');
}
}
if ((s[1] || '').length < prec) {
s[1] = s[1] || '';
s[1] += new Array(prec - s[1].length + 1).join('0');
}
return s.join(dec);
}
});
</script>
@endsection