diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 4c18ef3..46faa13 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -1,17 +1,18 @@ +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv import 'dart:convert'; import 'dart:io'; import 'ItemMenu.dart'; import 'Camera.dart'; -import 'package:http/http.dart' as http; -import 'package:flutter/material.dart'; import '../classes/events.dart'; import 'package:shared_preferences/shared_preferences.dart'; 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 '../variable/globals.dart' as globals; -// app starting point void main() { initializeDateFormatting("fr_FR", null).then((_) => runApp(const MyApp())); } @@ -28,7 +29,6 @@ class MyApp extends StatelessWidget { } } -// homepage class class ListItemMenu extends StatefulWidget { const ListItemMenu({super.key}); @@ -36,14 +36,15 @@ class ListItemMenu extends StatefulWidget { State createState() => _MyHomePageState(); } -// homepage state class _MyHomePageState extends State { Future> postsFuture = getPosts(); List filteredPosts = []; String geographicalZone = ''; String query = ''; + List suggestions = []; // Store suggestions + TextEditingController inputGeo = TextEditingController(); - // function to fetch data from api and return future list of posts + // Fetching events from API static Future> getPosts() async { SharedPreferences prefs = await SharedPreferences.getInstance(); var accessToken = prefs.getString("access_token") ?? ""; @@ -60,45 +61,77 @@ class _MyHomePageState extends State { return body; } - Future> searchPosts(String query) async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - var accessToken = prefs.getString("access_token") ?? ""; - final List body = []; - if (accessToken.isNotEmpty) { - var url = Uri.parse("${globals.api}/events/search?item=$query"); - final response = await http.get(url, headers: { - "Content-Type": "application/json", - HttpHeaders.cookieHeader: "access_token=${accessToken}" - }); - final List body = json.decode(utf8.decode(response.bodyBytes)); - return body.map((e) => Events.fromJson(e)).toList(); - } - return body; - } + Future searchSuggestions(String input) async { + await dotenv.load(fileName: ".env"); // Load .env file - Future popCamera() async { - await availableCameras().then((value) => Navigator.push(context, - MaterialPageRoute(builder: (_) => Camera(camera: value.first)))); + 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 + 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 + .toList(); + }); + } else { + throw Exception('Failed to load suggestions'); + } } Padding _buildGeographicalZoneSearchField() { return Padding( padding: const EdgeInsets.all(8.0), - child: TextField( - decoration: InputDecoration( - labelText: 'Search by geographical zone', - border: OutlineInputBorder(), - ), - onChanged: (value) { - setState(() { - geographicalZone = value; // Update geographical zone - }); - }, + child: Column( + children: [ + TextField( + controller: inputGeo, + decoration: InputDecoration( + labelText: 'Search by geographical zone', + border: OutlineInputBorder(), + ), + onChanged: (value) { + setState(() { + geographicalZone = value; + searchSuggestions(value); + }); + }, + ), + if (suggestions.isNotEmpty) + Container( + height: 200, + decoration: BoxDecoration( + border: Border.all(color: Colors.blue), // Add a border color + borderRadius: + BorderRadius.circular(8), // Optional: rounded corners + ), + child: ListView.builder( + shrinkWrap: + true, // Ensure the list takes only the required space + + itemCount: suggestions.length, + itemBuilder: (context, index) { + return ListTile( + title: Text(suggestions[index]), + onTap: () { + setState(() { + geographicalZone = suggestions[index]; + inputGeo.text = suggestions[index]; + suggestions.clear(); + }); + }, + ); + }, + ), + ), + ], ), ); } - // build function @override Widget build(BuildContext context) { return Scaffold( @@ -120,7 +153,6 @@ class _MyHomePageState extends State { ), body: Column( children: [ - // New Search Bar for Geographical Zone _buildGeographicalZoneSearchField(), Expanded( child: FutureBuilder>( @@ -144,7 +176,7 @@ class _MyHomePageState extends State { ); } - // function to display fetched data on screen + // Function to display fetched data on screen Widget buildPosts(List posts) { return ListView.separated( itemCount: posts.length, diff --git a/covas_mobile/pubspec.lock b/covas_mobile/pubspec.lock index 84f9170..cbc50cd 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile/pubspec.lock @@ -1,6 +1,14 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + archive: + dependency: transitive + description: + name: archive + sha256: cb6a278ef2dbb298455e1a713bda08524a175630ec643a242c399c932a0a1f7d + url: "https://pub.dev" + source: hosted + version: "3.6.1" async: dependency: transitive description: @@ -89,6 +97,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.4+2" + crypto: + dependency: transitive + description: + name: crypto + sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + url: "https://pub.dev" + source: hosted + version: "3.0.6" cupertino_icons: dependency: "direct main" description: @@ -248,6 +264,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + image: + dependency: transitive + description: + name: image + sha256: "8e9d133755c3e84c73288363e6343157c383a0c6c56fc51afcc5d4d7180306d6" + url: "https://pub.dev" + source: hosted + version: "3.3.0" image_picker: dependency: "direct main" description: @@ -320,6 +344,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.19.0" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" json_annotation: dependency: transitive description: @@ -360,6 +392,38 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + mapbox_gl: + dependency: "direct main" + description: + name: mapbox_gl + sha256: d78907338ff232e3cf6c1d6dba45e6a8814069496fd352e49bb1967d498f09af + url: "https://pub.dev" + source: hosted + version: "0.16.0" + mapbox_gl_dart: + dependency: transitive + description: + name: mapbox_gl_dart + sha256: de6d03718e5eb05c9eb1ddaae7f0383b28acb5afa16405e1deed7ff04dd34f3d + url: "https://pub.dev" + source: hosted + version: "0.2.1" + mapbox_gl_platform_interface: + dependency: transitive + description: + name: mapbox_gl_platform_interface + sha256: b7c1490b022e650afd20412bdf8ae45a1897118b7ce6049ef6c42df09193d4b2 + url: "https://pub.dev" + source: hosted + version: "0.16.0" + mapbox_gl_web: + dependency: transitive + description: + name: mapbox_gl_web + sha256: e77113bf95a4f321ff44938232517e0f2725aae991f0b283af1afaa7e7a58aca + url: "https://pub.dev" + source: hosted + version: "0.16.0" matcher: dependency: transitive description: @@ -448,6 +512,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.0" + petitparser: + dependency: transitive + description: + name: petitparser + sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27 + url: "https://pub.dev" + source: hosted + version: "6.0.2" platform: dependency: transitive description: @@ -629,6 +701,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + xml: + dependency: transitive + description: + name: xml + sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226 + url: "https://pub.dev" + source: hosted + version: "6.5.0" sdks: dart: ">=3.4.0 <4.0.0" flutter: ">=3.22.0" diff --git a/covas_mobile/pubspec.yaml b/covas_mobile/pubspec.yaml index 418204f..e289a3c 100644 --- a/covas_mobile/pubspec.yaml +++ b/covas_mobile/pubspec.yaml @@ -46,6 +46,7 @@ dependencies: image_picker: ^1.1.2 date_format_field: ^0.1.0 textfield_tags: ^3.0.1 + mapbox_gl: ^0.16.0 dev_dependencies: flutter_test: