diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 46faa13..f6ffa13 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -11,6 +11,7 @@ import 'package:intl/intl.dart'; import 'package:intl/date_symbol_data_local.dart'; import 'package:camera/camera.dart'; import 'package:mapbox_gl/mapbox_gl.dart'; // Add this import +import 'dart:math'; import '../variable/globals.dart' as globals; void main() { @@ -41,7 +42,7 @@ class _MyHomePageState extends State { List filteredPosts = []; String geographicalZone = ''; String query = ''; - List suggestions = []; // Store suggestions + List> suggestions = []; TextEditingController inputGeo = TextEditingController(); // Fetching events from API @@ -66,15 +67,18 @@ class _MyHomePageState extends State { final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? ''; final url = - 'https://api.mapbox.com/geocoding/v5/mapbox.places/${input}.json?access_token=${mapboxAccessToken}&proximity=ip'; // Replace with your Mapbox token + 'https://api.mapbox.com/geocoding/v5/mapbox.places/${input}.json?access_token=${mapboxAccessToken}&proximity=ip'; final response = await http.get(Uri.parse(url)); if (response.statusCode == 200) { final data = json.decode(response.body); setState(() { suggestions = (data['features'] as List) - .map((feature) => - feature['place_name'] as String) // Cast to String explicitly + .map((feature) => { + 'place_name': feature['place_name'], + 'geometry': feature[ + 'geometry'], // Include geometry for latitude/longitude + }) .toList(); }); } else { @@ -82,6 +86,43 @@ class _MyHomePageState extends State { } } + Future fetchPostsByLocation(double latitude, double longitude) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + + if (accessToken.isNotEmpty) { + // Calculate the boundaries + double radiusInKm = 50; + double latDistance = radiusInKm / 111.0; + double lonDistance = radiusInKm / (111.0 * cos(latitude * pi / 180)); + + double minLat = latitude - latDistance; + double maxLat = latitude + latDistance; + double minLon = longitude - lonDistance; + double maxLon = longitude + lonDistance; + + var url = Uri.parse("${globals.api}/events/search" + "?min_lat=$minLat&max_lat=$maxLat" + "&min_lon=$minLon&max_lon=$maxLon"); + + final response = await http.get(url, headers: { + "Content-Type": "application/json", + HttpHeaders.cookieHeader: "access_token=$accessToken" + }); + + if (response.statusCode == 200) { + final List body = json.decode(utf8.decode(response.bodyBytes)); + setState(() { + filteredPosts = body + .map((e) => Events.fromJson(e as Map)) + .toList(); + }); + } else { + throw Exception('Failed to load posts'); + } + } + } + Padding _buildGeographicalZoneSearchField() { return Padding( padding: const EdgeInsets.all(8.0), @@ -92,6 +133,16 @@ class _MyHomePageState extends State { decoration: InputDecoration( labelText: 'Search by geographical zone', border: OutlineInputBorder(), + suffixIcon: IconButton( + icon: Icon(Icons.clear), + onPressed: () { + setState(() { + inputGeo.clear(); // Clear the text field + geographicalZone = ''; // Reset the geographical zone state + suggestions.clear(); // Optionally clear suggestions + }); + }, + ), ), onChanged: (value) { setState(() { @@ -109,19 +160,24 @@ class _MyHomePageState extends State { BorderRadius.circular(8), // Optional: rounded corners ), child: ListView.builder( - shrinkWrap: - true, // Ensure the list takes only the required space - + shrinkWrap: true, itemCount: suggestions.length, itemBuilder: (context, index) { return ListTile( - title: Text(suggestions[index]), - onTap: () { + title: Text(suggestions[index]['place_name']), + onTap: () async { + final latitude = + suggestions[index]['geometry']['coordinates'][1]; + final longitude = + suggestions[index]['geometry']['coordinates'][0]; + setState(() { - geographicalZone = suggestions[index]; - inputGeo.text = suggestions[index]; + geographicalZone = suggestions[index]['place_name']; + inputGeo.text = geographicalZone; suggestions.clear(); }); + + await fetchPostsByLocation(latitude, longitude); }, ); },