add benzin to gasview

This commit is contained in:
2026-09-25 21:17:36 +02:00
parent 9a4c5cd82a
commit 44fa19b89f
4 changed files with 143 additions and 78 deletions
+40 -10
View File
@@ -22,21 +22,51 @@ class GasstationsController extends GetxController {
Future<void> _loadStationInfosList() async {
isLoading.value = true;
var gelocationService = GeolocationService();
var geolocationService = GeolocationService();
var eControlService = EControlService();
// check if location is available
await gelocationService.getCurrentLocation();
if (gelocationService.hasLocation) {
var listResult = await eControlService.getEControlData(
gelocationService.latitude,
gelocationService.longitude,
'DIE',
await geolocationService.getCurrentLocation();
if (geolocationService.hasLocation) {
// Parallel Diesel und Benzin laden
final fuelData = await eControlService.getBothFuelData(
geolocationService.latitude,
geolocationService.longitude,
);
eControlData.value = listResult
List<EControlModel> dieselStations = (fuelData['DIE'] as List)
.map((json) => EControlModel.fromJson(json))
.toList();
List<EControlModel> supStations = (fuelData['SUP'] as List)
.map((json) => EControlModel.fromJson(json))
.toList();
// Map zur Zusammenführung nach Tankstellen-ID
Map<int, EControlModel> combinedMap = {};
for (var station in dieselStations) {
if (station.id != null) {
combinedMap[station.id!] = station;
}
}
// Benzin-Preise in dieselben Tankstellen-Objekte mergen
for (var supStation in supStations) {
if (supStation.id != null) {
if (combinedMap.containsKey(supStation.id)) {
// Falls Tankstelle schon existiert, füge Benzin-Preis hinzu
final existingPrices = combinedMap[supStation.id!]!.prices ?? [];
final supPrices = supStation.prices ?? [];
combinedMap[supStation.id!]!.prices = [...existingPrices, ...supPrices];
} else {
combinedMap[supStation.id!] = supStation;
}
}
}
eControlData.value = combinedMap.values.toList();
}
isLoading.value = false;
update();
}
}
}
+2 -2
View File
@@ -51,7 +51,7 @@ class GasstationsPage extends GetView<GasstationsController> {
strokeWidth: 3,
),
const SizedBox(height: 20),
Text(
const Text(
'Lade Tankstellen...',
style: TextStyle(
color: Colors.white,
@@ -172,4 +172,4 @@ class GasstationsPage extends GetView<GasstationsController> {
),
);
}
}
}
+17 -3
View File
@@ -7,11 +7,25 @@ class EControlService {
double longitude,
String fuelType,
) async {
// REST Service... URL
String apiUrl =
'https://api.e-control.at/sprit/1.0/search/gas-stations/by-address?latitude=$latitude&longitude=$longitude&fuelType=$fuelType&includeClosed=false';
var response = await http.get(Uri.parse(apiUrl));
print('${response.statusCode}');
return jsonDecode(response.body);
if (response.statusCode == 200) {
return jsonDecode(response.body);
}
return [];
}
/// Holt parallel Diesel ('DIE') und Super ('SUP') Daten
Future<Map<String, List<dynamic>>> getBothFuelData(
double latitude,
double longitude,
) async {
final results = await Future.wait([
getEControlData(latitude, longitude, 'DIE'),
getEControlData(latitude, longitude, 'SUP'),
]);
return {'DIE': results[0], 'SUP': results[1]};
}
}
+84 -63
View File
@@ -23,14 +23,68 @@ class GasStationCard extends StatelessWidget {
}
}
// Hilfsmethode zur Erstellung eines einzelnen Preis-Badges
Widget _buildPriceBadge(Prices? priceInfo) {
if (priceInfo == null || priceInfo.amount == null) {
return const SizedBox.shrink();
}
final double price = priceInfo.amount!;
final String label = priceInfo.label ?? priceInfo.fuelType ?? '';
final Color badgeColor = _getPriceColor(price);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: badgeColor.withAlpha(35),
borderRadius: BorderRadius.circular(12),
border: Border.all(color: badgeColor, width: 1.5),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.local_gas_station, color: badgeColor, size: 22),
const SizedBox(width: 6),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(
'€ ${price.toStringAsFixed(3)}',
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: badgeColor,
),
),
if (label.isNotEmpty)
Text(
label,
style: TextStyle(
fontSize: 10,
color: Colors.grey[700],
fontWeight: FontWeight.w500,
),
),
],
),
],
),
);
}
@override
Widget build(BuildContext context) {
final price = station.prices?.isNotEmpty == true
? station.prices!.first.amount
: null;
final priceLabel = station.prices?.isNotEmpty == true
? station.prices!.first.label
: '';
// Suchen nach Diesel und Super/Benzin im Prices-Array
final dieselPrice = station.prices?.firstWhere(
(p) => p.fuelType == 'DIE' || (p.label?.toLowerCase().contains('diesel') ?? false),
orElse: () => station.prices?.isNotEmpty == true ? station.prices!.first : Prices(),
);
final supPrice = station.prices?.firstWhere(
(p) => p.fuelType == 'SUP' || (p.label?.toLowerCase().contains('benzin') ?? false) || (p.label?.toLowerCase().contains('super') ?? false),
orElse: () => Prices(),
);
return Card(
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
@@ -50,7 +104,7 @@ class GasStationCard extends StatelessWidget {
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Header Row with Position and Status
// Header Row
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
@@ -113,7 +167,7 @@ class GasStationCard extends StatelessWidget {
Text(
station.name ?? 'Unbekannte Tankstelle',
style: const TextStyle(
fontSize: 20,
fontSize: 18,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
@@ -134,7 +188,7 @@ class GasStationCard extends StatelessWidget {
'${station.location?.address ?? ''}, '
'${station.location?.postalCode ?? ''} '
'${station.location?.city ?? ''}',
style: TextStyle(fontSize: 14, color: Colors.grey[700]),
style: TextStyle(fontSize: 13, color: Colors.grey[700]),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
@@ -143,80 +197,47 @@ class GasStationCard extends StatelessWidget {
),
const SizedBox(height: 12),
// Price and Distance Row
// Prices & Distance Row
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Price
if (price != null)
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 10,
),
decoration: BoxDecoration(
color: _getPriceColor(price).withAlpha(50),
borderRadius: BorderRadius.circular(12),
border: Border.all(
color: _getPriceColor(price),
width: 2,
),
),
child: Row(
children: [
Icon(
Icons.local_gas_station,
color: _getPriceColor(price),
size: 24,
),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'€ ${price.toStringAsFixed(3)}',
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: _getPriceColor(price),
),
),
if (priceLabel?.isNotEmpty == true)
Text(
priceLabel!,
style: TextStyle(
fontSize: 10,
color: Colors.grey[600],
),
),
],
),
],
),
// Diesel & Benzin Preise nebeneinander
Expanded(
child: Wrap(
spacing: 8,
runSpacing: 8,
children: [
if (dieselPrice?.amount != null)
_buildPriceBadge(dieselPrice),
if (supPrice?.amount != null)
_buildPriceBadge(supPrice),
],
),
),
// Distance
// Distance Badge
Container(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 10,
horizontal: 12,
vertical: 8,
),
decoration: BoxDecoration(
color: Colors.blue[50],
borderRadius: BorderRadius.circular(12),
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
Icons.navigation,
color: Colors.blue[700],
size: 20,
size: 18,
),
const SizedBox(width: 8),
const SizedBox(width: 6),
Text(
_formatDistance(station.distance),
style: TextStyle(
fontSize: 16,
fontSize: 14,
fontWeight: FontWeight.bold,
color: Colors.blue[700],
),
@@ -232,4 +253,4 @@ class GasStationCard extends StatelessWidget {
),
);
}
}
}