")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = FuelStopScript(vehicles).Render(ctx, templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
templ_7745c5c3_Err = components.BaseLayout("Edit Fuel Stop", user, username).Render(templ.WithChildren(ctx, templ_7745c5c3_Var18), templ_7745c5c3_Buffer)
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}
func FuelStopScript(vehicles []models.Vehicle) templ.ComponentScript {
return templ.ComponentScript{
Name: `__templ_FuelStopScript_4386`,
Function: `function __templ_FuelStopScript_4386(vehicles){// Update currency display when currency dropdown changes
document.addEventListener('DOMContentLoaded', function() {
const currencySelect = document.querySelector('select[name="currency"]');
const priceCurrency = document.getElementById('price-currency');
const totalCurrency = document.getElementById('total-currency');
if (currencySelect) {
currencySelect.addEventListener('change', function() {
const selectedCurrency = this.value;
if (priceCurrency) priceCurrency.textContent = selectedCurrency;
if (totalCurrency) totalCurrency.textContent = selectedCurrency;
});
}
// Update fuel type when vehicle is selected
const vehicleSelect = document.querySelector('select[name="vehicle_id"]');
const fuelTypeSelect = document.querySelector('select[name="fuel_type"]');
if (vehicleSelect && fuelTypeSelect) {
vehicleSelect.addEventListener('change', async function() {
const selectedVehicleId = this.value;
if (selectedVehicleId) {
try {
// Fetch vehicle information from API
const response = await fetch(` + "`" + `/api/vehicles/${selectedVehicleId}` + "`" + `);
if (response.ok) {
const vehicle = await response.json();
if (vehicle.fuel_type) {
fuelTypeSelect.value = vehicle.fuel_type;
}
} else {
console.warn('Failed to fetch vehicle information');
}
} catch (error) {
console.error('Error fetching vehicle information:', error);
}
} else {
// Reset fuel type when no vehicle is selected
fuelTypeSelect.value = '';
}
});
}
// Auto-calculate total cost when amount or price per liter changes
const amountInput = document.querySelector('input[name="amount"]');
const priceInput = document.querySelector('input[name="price_per_liter"]');
const totalInput = document.querySelector('input[name="total_cost"]');
function calculateTotal() {
if (amountInput && priceInput && totalInput) {
const amount = parseFloat(amountInput.value) || 0;
const price = parseFloat(priceInput.value) || 0;
const total = amount * price;
totalInput.value = total.toFixed(2);
}
}
if (amountInput) {
amountInput.addEventListener('input', calculateTotal);
}
if (priceInput) {
priceInput.addEventListener('input', calculateTotal);
}
// Also calculate total when total is changed (reverse calculation)
if (totalInput && amountInput) {
totalInput.addEventListener('input', function() {
const total = parseFloat(this.value) || 0;
const amount = parseFloat(amountInput.value) || 0;
if (amount > 0) {
const pricePerLiter = total / amount;
if (priceInput) {
priceInput.value = pricePerLiter.toFixed(3);
}
}
});
}
});
// Check if page is served over HTTPS
function isSecureContext() {
return location.protocol === 'https:' || location.hostname === 'localhost' || location.hostname === '127.0.0.1';
}
// Debug function for location issues
function debugLocationInfo() {
console.log('=== Location Debug Info ===');
console.log('Protocol:', location.protocol);
console.log('Hostname:', location.hostname);
console.log('Is secure context:', isSecureContext());
console.log('Geolocation supported:', !!navigator.geolocation);
console.log('Permissions API supported:', !!navigator.permissions);
if (navigator.permissions) {
navigator.permissions.query({name: 'geolocation'}).then(function(result) {
console.log('Geolocation permission:', result.state);
}).catch(function(error) {
console.log('Permission query error:', error);
});
}
}
// Fuel Station Search Functions
window.findNearbyStations = function() {
// Debug location setup
debugLocationInfo();
// Check if we're in a secure context
if (!isSecureContext()) {
showStationSearchError('Geolocation requires HTTPS. Please access this page via HTTPS or use manual entry.');
return;
}
const modal = new bootstrap.Modal(document.getElementById('stationSearchModal'));
modal.show();
// Reset modal content
document.getElementById('stationSearchResults').innerHTML = ` + "`" + `
Searching...
Finding nearby fuel stations...
` + "`" + `;
// Get user's location with improved error handling
if (navigator.geolocation) {
console.log('Starting geolocation request...');
// Update status to show we're requesting location
document.getElementById('stationSearchResults').innerHTML = ` + "`" + `
Getting location...
Requesting your location...
Please allow location access when prompted
` + "`" + `;
navigator.geolocation.getCurrentPosition(
function(position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
console.log('Location obtained:', lat, lon);
console.log('Accuracy:', position.coords.accuracy + 'm');
console.log('Timestamp:', new Date(position.timestamp));
searchNearbyStations(lat, lon);
},
function(error) {
console.error('Geolocation error:', error);
console.error('Error code:', error.code);
console.error('Error message:', error.message);
let errorMessage = 'Unable to get your location. ';
let showRetryOption = false;
switch(error.code) {
case error.PERMISSION_DENIED:
errorMessage += 'Location access was denied. Please enable location services, refresh the page, and try again.';
if (!isSecureContext()) {
errorMessage += ' Note: This page requires HTTPS for location access.';
}
break;
case error.POSITION_UNAVAILABLE:
errorMessage += 'Location information is unavailable. Please check your GPS settings or try again.';
showRetryOption = true;
break;
case error.TIMEOUT:
errorMessage += 'Location request timed out. Trying with lower accuracy...';
// Try again with lower accuracy
tryLowAccuracyLocation();
return;
default:
errorMessage += 'An unknown error occurred while retrieving location.';
showRetryOption = true;
break;
}
showStationSearchError(errorMessage, showRetryOption);
},
{
enableHighAccuracy: true,
timeout: 15000, // Increased timeout to 15 seconds
maximumAge: 300000 // 5 minutes
}
);
} else {
showStationSearchError('Geolocation is not supported by this browser. Please enter station details manually.');
}
};
// Fallback function for low accuracy location
function tryLowAccuracyLocation() {
document.getElementById('stationSearchResults').innerHTML = ` + "`" + `
Trying low accuracy...
Trying with lower accuracy...
` + "`" + `;
navigator.geolocation.getCurrentPosition(
function(position) {
const lat = position.coords.latitude;
const lon = position.coords.longitude;
console.log('Low accuracy location obtained:', lat, lon);
searchNearbyStations(lat, lon);
},
function(error) {
console.error('Low accuracy geolocation error:', error);
showStationSearchError('Unable to get your location even with low accuracy. Please enter station details manually or try again later.');
},
{
enableHighAccuracy: false, // Use less accurate but faster location
timeout: 30000, // Longer timeout for low accuracy
maximumAge: 600000 // 10 minutes cache for low accuracy
}
);
};
function searchNearbyStations(lat, lon) {
console.log('Searching for stations near:', lat, lon);
// Update status to show we're searching
document.getElementById('stationSearchResults').innerHTML = ` + "`" + `
Searching...
Searching for nearby fuel stations...
This may take a few seconds
` + "`" + `;
const overpassUrl = 'https://overpass-api.de/api/interpreter';
const query = ` + "`" + `
[out:json][timeout:30];
(
node["amenity"="fuel"](around:5000,${lat},${lon});
way["amenity"="fuel"](around:5000,${lat},${lon});
relation["amenity"="fuel"](around:5000,${lat},${lon});
);
out center meta;
` + "`" + `;
console.log('Overpass query:', query);
// Add timeout to the fetch request
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout
fetch(overpassUrl, {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
},
body: 'data=' + encodeURIComponent(query),
signal: controller.signal
})
.then(response => {
clearTimeout(timeoutId);
console.log('API response status:', response.status);
if (!response.ok) {
throw new Error(` + "`" + `HTTP error! status: ${response.status}` + "`" + `);
}
return response.json();
})
.then(data => {
console.log('API response data:', data);
if (data.remark && data.remark.includes('timeout')) {
throw new Error('API request timed out');
}
if (data.elements && data.elements.length > 0) {
console.log(` + "`" + `Found ${data.elements.length} stations` + "`" + `);
displayStationResults(data.elements, lat, lon);
} else {
console.log('No stations found in API response');
showStationSearchError('No fuel stations found within 5km of your location. Try searching manually or check a different area.');
}
})
.catch(error => {
clearTimeout(timeoutId);
console.error('Error searching for stations:', error);
let errorMessage = 'Error searching for fuel stations. ';
if (error.name === 'AbortError') {
errorMessage += 'The search timed out. Please try again or enter station details manually.';
} else if (error.message.includes('HTTP error')) {
errorMessage += 'The map service is temporarily unavailable. Please try again later.';
} else if (error.message.includes('Failed to fetch')) {
errorMessage += 'Network error. Please check your internet connection and try again.';
} else {
errorMessage += 'Please try again or enter station details manually.';
}
showStationSearchError(errorMessage);
});
}
function displayStationResults(stations, userLat, userLon) {
// Calculate distances and sort by distance
const stationsWithDistance = stations.map(station => {
const stationLat = station.lat || (station.center && station.center.lat);
const stationLon = station.lon || (station.center && station.center.lon);
if (stationLat && stationLon) {
const distance = calculateDistance(userLat, userLon, stationLat, stationLon);
return {
...station,
distance: distance,
displayLat: stationLat,
displayLon: stationLon
};
}
return null;
}).filter(station => station !== null);
stationsWithDistance.sort((a, b) => a.distance - b.distance);
const resultsHTML = stationsWithDistance.map(station => {
const name = station.tags.name || station.tags.brand || 'Unknown Station';
const address = [
station.tags['addr:street'],
station.tags['addr:housenumber'],
station.tags['addr:city'],
station.tags['addr:postcode']
].filter(Boolean).join(' ');
const brand = station.tags.brand || '';
const operator = station.tags.operator || '';
const displayName = brand || operator || name;
return ` + "`" + `