diff --git a/lib/controller/gasstations_controller.dart b/lib/controller/gasstations_controller.dart index 34e4889..30e766a 100644 --- a/lib/controller/gasstations_controller.dart +++ b/lib/controller/gasstations_controller.dart @@ -22,21 +22,51 @@ class GasstationsController extends GetxController { Future _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 dieselStations = (fuelData['DIE'] as List) .map((json) => EControlModel.fromJson(json)) .toList(); + + List supStations = (fuelData['SUP'] as List) + .map((json) => EControlModel.fromJson(json)) + .toList(); + + // Map zur Zusammenführung nach Tankstellen-ID + Map 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(); } -} +} \ No newline at end of file diff --git a/lib/pages/gasstations_view.dart b/lib/pages/gasstations_view.dart index 1588dad..ffee80c 100644 --- a/lib/pages/gasstations_view.dart +++ b/lib/pages/gasstations_view.dart @@ -51,7 +51,7 @@ class GasstationsPage extends GetView { strokeWidth: 3, ), const SizedBox(height: 20), - Text( + const Text( 'Lade Tankstellen...', style: TextStyle( color: Colors.white, @@ -172,4 +172,4 @@ class GasstationsPage extends GetView { ), ); } -} +} \ No newline at end of file diff --git a/lib/services/econtrol_service.dart b/lib/services/econtrol_service.dart index e6fb06b..cbaea8a 100644 --- a/lib/services/econtrol_service.dart +++ b/lib/services/econtrol_service.dart @@ -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>> 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]}; } } diff --git a/lib/widgets/gasstation_card_widget.dart b/lib/widgets/gasstation_card_widget.dart index e857941..15ec8de 100644 --- a/lib/widgets/gasstation_card_widget.dart +++ b/lib/widgets/gasstation_card_widget.dart @@ -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 { ), ); } -} +} \ No newline at end of file