|
Server : Apache/2.4.18 (Ubuntu) System : Linux canvaswebdesign 3.13.0-71-generic #114-Ubuntu SMP Tue Dec 1 02:34:22 UTC 2015 x86_64 User : oppastar ( 1041) PHP Version : 7.0.33-0ubuntu0.16.04.15 Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority, Directory : /var/www/laciasmara.com/public_html/shop/application/views/account/ |
Upload File : |
<?php defined('BASEPATH') or exit('No direct script access allowed'); ?>
<div class="account-shipping-container">
<h1><?= ucfirst(lang('shipping_title')) ?></h1>
<div class="account-shipping-header">
<div class="shipping-search-and-button">
<div class="shipping-search-box">
<i class="fas fa-search shipping-search-icon"></i>
<input type="text" placeholder="Tulis Nama Alamat / Kota tujuan pengiriman kamu" />
</div>
<button class="add-address-btn" onclick="openModal()">+ Tambah Alamat Baru</button>
</div>
</div>
<div class="shipping-address-list">
<?php if (empty($addresses)): ?>
<div class="shipping-empty-state">
<div class="shipping-empty-icon">
<i class="fas fa-map-marker-alt"></i>
</div>
<h3>Belum ada alamat tersimpan</h3>
<p>Tambahkan alamat pengiriman untuk mempermudah proses checkout</p>
<button class="shipping-btn-card shipping-btn-primary" onclick="openModal()">
Masukin Alamat Pertama
</button>
</div>
<?php else: ?>
<?php foreach ($addresses as $address): ?>
<div class="shipping-address-card <?= $address->is_default ? 'default' : '' ?>" data-id="<?= $address->id ?>">
<div class=" shipping-address-header">
<div class="shipping-address-label">
<span class="shipping-label-text"><?= htmlspecialchars($address->label) ?></span>
<?php if ($address->is_default): ?>
<span class="shipping-default-badge">Utama</span>
<?php endif; ?>
</div>
</div>
<div class="shipping-address-body">
<div class="shipping-recipient-info">
<div class="shipping-recipient-name">
<i class="fas fa-user"></i>
<span><?= htmlspecialchars($address->recipient_name) ?></span>
</div>
<div class="shipping-recipient-phone">
<i class="fas fa-phone"></i>
<span><?= htmlspecialchars($address->phone) ?></span>
</div>
</div>
<div class="shipping-full-address">
<i class="fas fa-map-marker-alt"></i>
<div class="shipping-address-text">
<div class="shipping-address-main"><?= htmlspecialchars($address->address) ?>
<?php if (!empty($address->notes)): ?>
(<?= htmlspecialchars($address->notes) ?>)
<?php endif; ?>
</div>
</div>
</div>
</div>
<div class="shipping-address-footer">
<!-- <button class="shipping-btn-card shipping-btn-edit" onclick="editAddress(<?= $address->id ?>)">
Ubah Alamat
</button> -->
<?php if (!$address->is_default): ?>
<button class="shipping-btn-card shipping-btn-outline" onclick="setDefaultAddress(<?= $address->id ?>)">
Jadikan Alamat Utama
</button>
<?php endif; ?>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
<div class="shipping-modal-overlay" id="addressModal">
<div class="shipping-modal-container">
<!-- Modal Header -->
<div class="shipping-modal-header">
<h2>Tambah Alamat</h2>
<button class="shipping-close-btn" onclick="closeModal()">
<i class="fas fa-times"></i>
</button>
</div>
<!-- Progress Bar -->
<div class="shipping-progress-container">
<div class="shipping-progress-bar">
<div class="shipping-progress-line">
<div class="shipping-progress-line-fill" id="progressFill"></div>
</div>
<div class="step-wrapper">
<div class="shipping-step active" id="step1">1</div>
<div class="shipping-step-label active" id="label1">Cari lokasi pengirimanmu</div>
</div>
<div class="step-wrapper">
<div class="shipping-step" id="step2">2</div>
<div class="shipping-step-label" id="label2">Tentukan pinpoint lokasi</div>
</div>
<div class="step-wrapper">
<div class="shipping-step" id="step3">3</div>
<div class="shipping-step-label" id="label3">Lengkapi detail alamat</div>
</div>
</div>
</div>
<!-- Modal Content -->
<div class="shipping-modal-content">
<!-- Step 1: Search Location -->
<div class="shipping-step-content active" id="content1">
<div class="shipping-search-location">
<h3>Cari Lokasi Pengiriman</h3>
<div class="shipping-search-input-group">
<input type="text" id="addressSearch" placeholder="Masukkan nama jalan, gedung, atau area">
</div>
<button class="shipping-current-location-btn" onclick="getCurrentLocation()">
<i class="fas fa-location-crosshairs"></i>
Gunakan Lokasi Saat Ini
</button>
</div>
</div>
<!-- Step 2: Map -->
<div class="shipping-step-content" id="content2">
<div class="shipping-map-container">
<h3>Tentukan Pinpoint Lokasi</h3>
<div id="map"></div>
<p style="color: #666; font-size: 14px;">
<i class="fas fa-info-circle"></i>
Drag pin untuk menyesuaikan lokasi yang tepat
</p>
</div>
</div>
<!-- Step 3: Address Details -->
<div class="shipping-step-content" id="content3">
<div class="shipping-address-details">
<h3>Lengkapi detail alamat</h3>
<form id="addressForm">
<div class="shipping-form-group">
<label for="addressLabel">Label Alamat *</label>
<input type="text" id="addressLabel" placeholder="Contoh: Rumah, Kantor, Apartemen">
</div>
<div class="shipping-form-group">
<label for="fullAddress">Alamat Lengkap *</label>
<textarea id="fullAddress" placeholder="Alamat lengkap akan diisi otomatis"></textarea>
</div>
<div class="shipping-form-group">
<label for="addressNotes">Catatan Alamat</label>
<textarea id="addressNotes" placeholder="Contoh: Rumah cat hijau, sebelah warung Pak Budi"></textarea>
</div>
<div class="shipping-form-row">
<div class="shipping-form-group">
<label for="receiverName">Nama Penerima *</label>
<input type="text" id="receiverName" placeholder="Nama lengkap penerima">
</div>
<div class="shipping-form-group">
<label for="receiverPhone">Nomor HP *</label>
<input type="tel" id="receiverPhone" placeholder="08xxxxxxxxxx">
</div>
</div>
<div class="shipping-checkbox-group">
<input type="checkbox" id="isMainAddress">
<label for="isMainAddress">Jadikan sebagai alamat utama</label>
</div>
<!-- Hidden fields for coordinates -->
<input type="hidden" id="latitude">
<input type="hidden" id="longitude">
<input type="hidden" id="province">
<input type="hidden" id="city">
<input type="hidden" id="district">
<input type="hidden" id="subdistrict">
<input type="hidden" id="postal-code">
</form>
</div>
</div>
</div>
<!-- Modal Footer -->
<div class="shipping-modal-footer">
<button class="shipping-btn shipping-btn-secondary" id="backBtn" onclick="prevStep()" style="display: none;">
<i class="fas fa-arrow-left"></i> Kembali
</button>
<div style="flex: 1;"></div>
<button class="shipping-btn shipping-btn-primary" id="nextBtn" onclick="nextStep()">
Lanjutkan <i class="fas fa-arrow-right"></i>
</button>
</div>
</div>
</div>
</div>
<script async src="https://maps.googleapis.com/maps/api/js?key=<?php echo $this->config->item('google_maps_api_key'); ?>&loading=async&libraries=places,marker&callback=initMap&language=id®ion=ID&v=beta" defer></script>
<script>
let currentStep = 1;
let map;
let marker;
let autocomplete;
let geocoder;
let selectedPlace = null;
const searchAddressInput = document.querySelector('.shipping-search-box input');
const addressCards = document.querySelectorAll('.shipping-address-card');
const notyf = new Notyf({
duration: 3500,
position: {
x: 'right',
y: 'top'
},
types: [{
type: 'success',
background: '#7A4397',
icon: {
className: 'fas fa-check',
tagName: 'i',
color: 'white'
}
},
{
type: 'error',
background: '#dc3545',
icon: {
className: 'fas fa-circle-xmark',
tagName: 'i',
color: 'white'
}
}
]
});
// Modal functions
function openModal() {
document.getElementById('addressModal').classList.add('active');
document.body.style.overflow = 'hidden';
// Initialize map when modal opens
setTimeout(() => {
if (typeof google !== 'undefined' && google.maps) {
initMap();
} else {
console.log('Google Maps not loaded yet');
}
}, 300);
}
function closeModal() {
document.getElementById('addressModal').classList.remove('active');
document.body.style.overflow = 'auto';
resetModal();
}
function resetModal() {
currentStep = 1;
updateStepDisplay();
document.getElementById('addressForm').reset();
document.getElementById('addressSearch').value = '';
selectedPlace = null;
}
// Step navigation
function nextStep() {
if (currentStep < 3) {
if (validateCurrentStep()) {
currentStep++;
updateStepDisplay();
// Initialize map when entering step 2
if (currentStep === 2) {
setTimeout(() => {
if (map && selectedPlace) {
map.setCenter(selectedPlace.geometry.location);
map.setZoom(17);
if (marker.position !== undefined) {
marker.position = selectedPlace.geometry.location;
} else {
marker.setPosition(selectedPlace.geometry.location);
}
}
}, 100);
}
}
} else {
// Save address (step 3)
saveAddress();
}
}
function prevStep() {
if (currentStep > 1) {
currentStep--;
updateStepDisplay();
}
}
function updateStepDisplay() {
// Update progress bar
const progressFill = document.getElementById('progressFill');
const progressPercentage = ((currentStep - 1) / 2) * 100;
progressFill.style.width = progressPercentage + '%';
// Update steps
for (let i = 1; i <= 3; i++) {
const step = document.getElementById(`step${i}`);
const label = document.getElementById(`label${i}`);
const content = document.getElementById(`content${i}`);
// Reset all classes first
step.classList.remove('active', 'completed');
label.classList.remove('active');
content.classList.remove('active');
if (i < currentStep) {
step.classList.add('completed');
} else if (i === currentStep) {
step.classList.add('active');
label.classList.add('active');
content.classList.add('active');
}
}
// Update footer buttons
const backBtn = document.getElementById('backBtn');
const nextBtn = document.getElementById('nextBtn');
if (currentStep === 1) {
backBtn.style.display = 'none';
nextBtn.innerHTML = 'Lanjutkan <i class="fas fa-arrow-right"></i>';
} else if (currentStep === 2) {
backBtn.style.display = 'block';
nextBtn.innerHTML = 'Lanjutkan <i class="fas fa-arrow-right"></i>';
} else {
backBtn.style.display = 'block';
nextBtn.innerHTML = 'Simpan Alamat <i class="fas fa-save"></i>';
}
}
function validateCurrentStep() {
if (currentStep === 1) {
if (!selectedPlace) {
notyf.error('Silakan pilih lokasi terlebih dahulu');
return false;
}
} else if (currentStep === 2) {
// Map validation (always valid as long as marker exists)
return true;
} else if (currentStep === 3) {
// Form validation
const label = document.getElementById('addressLabel').value;
const fullAddress = document.getElementById('fullAddress').value;
const receiverName = document.getElementById('receiverName').value;
const receiverPhone = document.getElementById('receiverPhone').value;
if (!label || !fullAddress || !receiverName || !receiverPhone) {
notyf.error('Silakan lengkapi semua field yang wajib diisi');
return false;
}
}
return true;
}
function setDefaultAddress(addressId) {
const csrfName = '<?php echo $this->security->get_csrf_token_name(); ?>';
const csrfHash = '<?php echo $this->security->get_csrf_hash(); ?>';
const formData = new FormData();
formData.append(csrfName, csrfHash);
fetch(`<?= base_url('account/set_default_address/') ?>${addressId}`, {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
notyf.success(data.message);
setTimeout(() => location.reload(), 1000);
} else {
notyf.error(data.message);
}
})
.catch(error => {
console.error('Error:', error);
notyf.error('Terjadi kesalahan saat mengubah alamat utama');
});
}
function saveAddress() {
if (!validateCurrentStep()) return;
// Collect address data
const addressData = {
label: document.getElementById('addressLabel').value,
fullAddress: document.getElementById('fullAddress').value,
notes: document.getElementById('addressNotes').value,
receiverName: document.getElementById('receiverName').value,
receiverPhone: document.getElementById('receiverPhone').value,
isMainAddress: document.getElementById('isMainAddress').checked,
latitude: document.getElementById('latitude').value,
longitude: document.getElementById('longitude').value,
province: document.getElementById('province') ? document.getElementById('province').value : '',
city: document.getElementById('city') ? document.getElementById('city').value : '',
district: document.getElementById('district') ? document.getElementById('district').value : '',
subdistrict: document.getElementById('subdistrict') ? document.getElementById('subdistrict').value : '',
postalCode: document.getElementById('postal-code') ? document.getElementById('postal-code').value : ''
};
// Show loading state
const saveButton = document.getElementById('nextBtn');
if (saveButton) {
saveButton.disabled = true;
saveButton.innerHTML = 'Menyimpan...';
}
// Create form data for POST request
const formData = new FormData();
Object.keys(addressData).forEach(key => {
formData.append(key, addressData[key]);
});
const csrfName = '<?php echo $this->security->get_csrf_token_name(); ?>';
const csrfHash = '<?php echo $this->security->get_csrf_hash(); ?>';
if (csrfName && csrfHash) {
formData.append(csrfName, csrfHash);
}
// Send POST request
fetch('<?php echo base_url('account/save_address'); ?>', {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest'
}
})
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => {
if (data.success) {
notyf.success(data.message || 'Alamat berhasil disimpan!');
closeModal();
setTimeout(() => {
location.reload();
}, 1000);
} else {
notyf.error(data.message || 'Gagal menyimpan alamat. Silakan coba lagi.');
}
})
.catch(error => {
console.error('Error:', error);
notyf.error('Terjadi kesalahan. Silakan coba lagi.');
})
.finally(() => {
if (saveButton) {
saveButton.disabled = false;
saveButton.innerHTML = 'Simpan Alamat <i class="fas fa-save"></i>';
}
});
}
// async function editAddress(address_id) {
// try {
// const response = await fetch(`<?= base_url('account/get_address_by_id/') ?>${address_id}`);
// const data = await response.json();
// if (data.success) {
// openEditModal(data.address);
// } else {
// notyf.error(data.message || 'Gagal mengambil data alamat');
// }
// } catch (error) {
// console.error('Error fetching address data:', error);
// notyf.error('Terjadi kesalahan saat mengambil data alamat');
// }
// }
// Google Maps functions
async function initMap() {
try {
const {
Map
} = await google.maps.importLibrary("maps");
const {
AdvancedMarkerElement
} = await google.maps.importLibrary("marker");
const defaultLocation = {
lat: -6.194985,
lng: 106.823070
};
map = new Map(document.getElementById('map'), {
center: defaultLocation,
zoom: 13,
mapId: '1873c42fd77c25f9fad736e6',
mapTypeControl: false,
streetViewControl: false,
fullscreenControl: false
});
marker = new AdvancedMarkerElement({
map: map,
position: defaultLocation,
gmpDraggable: true,
title: 'Drag untuk memilih lokasi'
});
geocoder = new google.maps.Geocoder();
setupAutocomplete();
setupEventListeners();
} catch (error) {
console.error('Error initializing map:', error);
initMapFallback();
}
}
function initMapFallback() {
const defaultLocation = {
lat: -6.2088,
lng: 106.8456
};
map = new google.maps.Map(document.getElementById('map'), {
center: defaultLocation,
zoom: 13,
mapTypeControl: false,
streetViewControl: false,
fullscreenControl: false
});
marker = new google.maps.Marker({
position: defaultLocation,
map: map,
draggable: true,
title: 'Drag untuk memilih lokasi'
});
geocoder = new google.maps.Geocoder();
setupAutocomplete();
setupEventListeners();
}
function setupAutocomplete() {
const searchInput = document.getElementById('addressSearch');
if (!searchInput) return;
autocomplete = new google.maps.places.Autocomplete(searchInput, {
componentRestrictions: {
country: 'ID'
},
fields: ['formatted_address', 'geometry', 'address_components', 'name'],
});
autocomplete.addListener('place_changed', function() {
const place = autocomplete.getPlace();
if (!place.geometry) {
notyf.error('Alamat tidak ditemukan');
return;
}
selectedPlace = place;
reverseGeocode(place.geometry.location);
});
}
function setupEventListeners() {
if (marker.addListener) {
marker.addListener('dragend', function() {
let position;
if (marker.position && marker.position.lat) {
position = marker.position;
} else {
position = marker.getPosition();
}
reverseGeocode(position);
});
}
if (map.addListener) {
map.addListener('click', function(event) {
if (marker.position !== undefined) {
marker.position = event.latLng;
} else {
marker.setPosition(event.latLng);
}
reverseGeocode(event.latLng);
});
}
if (searchAddressInput) {
searchAddressInput.addEventListener('input', function() {
const query = this.value.toLowerCase().trim();
addressCards.forEach(card => {
const label = card.querySelector('.shipping-label-text')?.textContent.toLowerCase() || '';
const name = card.querySelector('.shipping-recipient-name span')?.textContent.toLowerCase() || '';
const phone = card.querySelector('.shipping-recipient-phone span')?.textContent.toLowerCase() || '';
const addressText = card.querySelector('.shipping-address-main')?.textContent.toLowerCase() || '';
const matches = label.includes(query) || name.includes(query) || phone.includes(query) || addressText.includes(query);
card.style.display = matches ? '' : 'none';
});
});
}
}
function getCurrentLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(
function(position) {
const userLocation = {
lat: position.coords.latitude,
lng: position.coords.longitude
};
// Create a place object similar to autocomplete result
geocoder.geocode({
location: userLocation
}, function(results, status) {
if (status === 'OK' && results[0]) {
selectedPlace = {
formatted_address: results[0].formatted_address,
geometry: {
location: userLocation
},
address_components: results[0].address_components
};
document.getElementById('addressSearch').value = results[0].formatted_address;
reverseGeocode(selectedPlace.geometry.location);
}
});
},
function(error) {
alert('Tidak dapat mengakses lokasi saat ini');
}
);
} else {
alert('Geolocation tidak didukung oleh browser ini');
}
}
function reverseGeocode(location) {
geocoder.geocode({
location: location
}, function(results, status) {
if (status === 'OK' && results[0]) {
// Update address details
const components = results[0].address_components;
let addressData = {
province: '',
city: '',
district: '',
subdistrict: '',
postal_code: ''
};
if (components) {
components.forEach(function(component) {
const types = component.types;
if (types.includes('administrative_area_level_1')) {
addressData.province = component.long_name;
} else if (types.includes('administrative_area_level_2')) {
addressData.city = component.long_name;
} else if (types.includes('administrative_area_level_3')) {
addressData.district = component.long_name;
} else if (types.includes('administrative_area_level_4')) {
addressData.subdistrict = component.long_name;
} else if (types.includes('postal_code')) {
addressData.postal_code = component.long_name;
}
});
}
// Fill form fields
document.getElementById('fullAddress').value = results[0].formatted_address;
// PERBAIKAN KOORDINAT - Handle berbagai format location
let lat, lng;
// Cek apakah ini LatLng object dengan method lat() dan lng()
if (typeof location.lat === 'function' && typeof location.lng === 'function') {
lat = location.lat();
lng = location.lng();
}
// Cek apakah ada property position (seperti di marker)
else if (location.position && typeof location.position.lat === 'function') {
lat = location.position.lat();
lng = location.position.lng();
}
// Cek apakah ini object literal dengan property lat/lng
else if (typeof location.lat === 'number' && typeof location.lng === 'number') {
lat = location.lat;
lng = location.lng;
}
// Cek apakah menggunakan latitude/longitude
else if (typeof location.latitude === 'number' && typeof location.longitude === 'number') {
lat = location.latitude;
lng = location.longitude;
}
// Fallback - coba getPosition() jika ada
else if (typeof location.getPosition === 'function') {
const pos = location.getPosition();
lat = pos.lat();
lng = pos.lng();
} else {
console.error('Unknown location format:', location);
console.error('Available properties:', Object.keys(location));
return;
}
// Set nilai ke input field
document.getElementById('latitude').value = lat;
document.getElementById('longitude').value = lng;
console.log('Coordinates successfully set:', {
lat,
lng,
addressData
});
// Fill other fields
if (document.getElementById('province')) {
document.getElementById('province').value = addressData.province;
}
if (document.getElementById('city')) {
document.getElementById('city').value = addressData.city;
}
if (document.getElementById('district')) {
document.getElementById('district').value = addressData.district;
}
if (document.getElementById('subdistrict')) {
document.getElementById('subdistrict').value = addressData.subdistrict;
}
if (document.getElementById('postal-code')) {
document.getElementById('postal-code').value = addressData.postal_code;
}
} else {
console.error('Geocoding failed:', status);
}
});
}
// Close modal when clicking outside
document.getElementById('addressModal').addEventListener('click', function(e) {
if (e.target === this) {
closeModal();
}
});
// Close modal with Escape key
document.addEventListener('keydown', function(e) {
if (e.key === 'Escape' && document.getElementById('addressModal').classList.contains('active')) {
closeModal();
}
});
</script>