From 8a46958e7c29c18e4409c516b8972b1a82c8e5c1 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 24 Nov 2024 21:41:01 +0100 Subject: [PATCH] add pint bar search by item --- covas_mobile/lib/pages/ListItemMenu.dart | 197 ++++++++------------- covas_mobile/lib/pages/SearchDelegate.dart | 133 -------------- 2 files changed, 70 insertions(+), 260 deletions(-) delete mode 100644 covas_mobile/lib/pages/SearchDelegate.dart diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 7bad5e0..dec8726 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -4,7 +4,6 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv import 'dart:convert'; import 'dart:io'; import 'ItemMenu.dart'; -import 'SearchDelegate.dart'; import '../classes/events.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:intl/intl.dart'; @@ -48,6 +47,7 @@ class _MyHomePageState extends State { TextEditingController inputGeo = TextEditingController(); TextEditingController startDatepicker = TextEditingController(); TextEditingController endDatepicker = TextEditingController(); + TextEditingController inputItem = TextEditingController(); bool showDateFields = false; // State to toggle date fields @@ -124,40 +124,6 @@ class _MyHomePageState extends State { return "${year}-${month}-${day}"; } - // Fetching events from API - Future> getAllPosts() async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - var accessToken = prefs.getString("access_token") ?? ""; - final List body = []; - if (accessToken.isNotEmpty) { - DateTime currentDateTime = DateTime.now(); - var url = Uri.parse( - "${globals.api}/events?current_datetime=${currentDateTime.toString()}"); - if (startDatepicker.text.isNotEmpty) { - var date = DateTime.parse(formatDate(startDatepicker.text)); - url = Uri.parse("${globals.api}/events?date_event=${date.toString()}"); - } - if (endDatepicker.text.isNotEmpty) { - var date = DateTime.parse(formatDate(endDatepicker.text)); - url = Uri.parse("${globals.api}/events?date_event=${date.toString()}"); - } - if ((startDatepicker.text.isNotEmpty) && - (endDatepicker.text.isNotEmpty)) { - var start_date = DateTime.parse(formatDate(startDatepicker.text)); - var end_date = DateTime.parse(formatDate(endDatepicker.text)); - url = Uri.parse( - "${globals.api}/events?start_date=${start_date.toString()}&end_date=${end_date.toString()}"); - } - 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; - } - @override void initState() { super.initState(); @@ -237,17 +203,17 @@ class _MyHomePageState extends State { inputGeo.text = "${city}, ${country}"; }); } else { - _fetchInitialData(); + fetchPostsByLocation(); } } else { - _fetchInitialData(); + fetchPostsByLocation(); } } else { - _fetchInitialData(); + fetchPostsByLocation(); throw Exception('Failed to load location data'); } } catch (e) { - _fetchInitialData(); + fetchPostsByLocation(); print("Error getting city and country: $e"); } } @@ -274,20 +240,6 @@ class _MyHomePageState extends State { return ''; } - // Fetch initial data from API or any other necessary initialization - Future _fetchInitialData() async { - try { - // Optionally, you can fetch posts initially if needed. - List initialPosts = await getAllPosts(); - setState(() { - // Assign to the postsFuture and update the filtered posts if needed - filteredPosts = initialPosts; - }); - } catch (e) { - print('Error fetching initial data: $e'); - } - } - Future searchSuggestions(String input) async { await dotenv.load(fileName: ".env"); // Load .env file @@ -319,46 +271,47 @@ class _MyHomePageState extends State { if (accessToken.isNotEmpty) { double latitude = prefs.getDouble("city_lat") ?? 0.0; double longitude = prefs.getDouble("city_long") ?? 0.0; + String stringParameter = ""; + String dateParameter = "current_datetime"; + if ((latitude != 0.0) && (longitude != 0.0)) { + // Calculate the boundaries + double radiusInKm = 50; + double latDistance = radiusInKm / 111.0; + double lonDistance = radiusInKm / (111.0 * cos(latitude * pi / 180)); - // 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; - double minLat = latitude - latDistance; - double maxLat = latitude + latDistance; - double minLon = longitude - lonDistance; - double maxLon = longitude + lonDistance; + stringParameter = "min_lat=$minLat&max_lat=$maxLat" + "&min_lon=$minLon&max_lon=$maxLon"; + } DateTime currentDate = DateTime.now(); - print("current_date : ${currentDate}"); - var url = Uri.parse("${globals.api}/events/search" - "?min_lat=$minLat&max_lat=$maxLat" - "&min_lon=$minLon&max_lon=$maxLon¤t_datetime=${currentDate.toString()}"); + dateParameter = "¤t_datetime=${currentDate.toString()}"; if (startDatepicker.text.isNotEmpty) { var date = DateTime.parse(formatDate(startDatepicker.text)); - url = Uri.parse("${globals.api}/events/search" - "?min_lat=$minLat&max_lat=$maxLat" - "&min_lon=$minLon&max_lon=$maxLon&date_event=" + - date.toString()); + dateParameter = "&date_event=" + date.toString(); } if (endDatepicker.text.isNotEmpty) { var date = DateTime.parse(formatDate(endDatepicker.text)); - url = Uri.parse("${globals.api}/events/search" - "?min_lat=$minLat&max_lat=$maxLat" - "&min_lon=$minLon&max_lon=$maxLon&date_event=" + - date.toString()); + dateParameter = "&date_event=" + date.toString(); } if ((startDatepicker.text.isNotEmpty) && (endDatepicker.text.isNotEmpty)) { - var start_date = DateTime.parse(formatDate(startDatepicker.text)); - var end_date = DateTime.parse(formatDate(endDatepicker.text)); - url = Uri.parse("${globals.api}/events/search" - "?min_lat=$minLat&max_lat=$maxLat" - "&min_lon=$minLon&max_lon=$maxLon&start_date=" + - start_date.toString() + + var startDate = DateTime.parse(formatDate(startDatepicker.text)); + var endDate = DateTime.parse(formatDate(endDatepicker.text)); + dateParameter = "&start_date=" + + startDate.toString() + "&end_date=" + - end_date.toString()); + endDate.toString(); } + stringParameter = stringParameter + dateParameter; + if (inputItem.text.isNotEmpty) { + stringParameter = stringParameter + "&item=${inputItem.text}"; + } + print("stringParameter : ${stringParameter}"); + var url = Uri.parse("${globals.api}/events/search?${stringParameter}"); final response = await http.get(url, headers: { "Content-Type": "application/json", HttpHeaders.cookieHeader: "access_token=$accessToken" @@ -400,23 +353,8 @@ class _MyHomePageState extends State { } else if (position == "end") { endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); } - SharedPreferences prefs = await SharedPreferences.getInstance(); - if (startDatepicker.text.isNotEmpty) { - prefs.setString("date_event", startDatepicker.text); - prefs.setString("start_date", startDatepicker.text); - } - if (endDatepicker.text.isNotEmpty) { - prefs.setString("date_event", endDatepicker.text); - prefs.setString("end_date", endDatepicker.text); - } - if ((startDatepicker.text.isNotEmpty) && (endDatepicker.text.isNotEmpty)) { - prefs.remove("date_event"); - } - if (inputGeo.text.isEmpty) { - _fetchInitialData(); - } else { - fetchPostsByLocation(); - } + + fetchPostsByLocation(); } Padding _buildDateField(String position) { @@ -440,23 +378,7 @@ class _MyHomePageState extends State { setState(() { datePicker.text = ''; }); - SharedPreferences prefs = - await SharedPreferences.getInstance(); - if (position == "start") { - prefs.remove("start_date"); - } - if (position == "end") { - prefs.remove("end_date"); - } - if ((startDatepicker.text.isEmpty) && - (endDatepicker.text.isEmpty)) { - prefs.remove("date_event"); - } - if (inputGeo.text.isNotEmpty) { - fetchPostsByLocation(); - } else { - _fetchInitialData(); - } + fetchPostsByLocation(); }, ), hintText: hintText), @@ -486,7 +408,9 @@ class _MyHomePageState extends State { inputGeo.clear(); // Clear the text field geographicalZone = ''; // Reset the geographical zone state suggestions.clear(); // Optionally clear suggestions - _fetchInitialData(); // Clear the filtered posts + fetchPostsByLocation(); + + /// Clear the filtered posts }); }, ), @@ -537,6 +461,35 @@ class _MyHomePageState extends State { ); } + Padding _buildItemZoneSearchField() { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + children: [ + TextField( + controller: inputItem, + decoration: InputDecoration( + labelText: 'Search by item', + border: OutlineInputBorder(), + suffixIcon: IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + setState(() { + inputItem.clear(); + }); + fetchPostsByLocation(); + }, + ), + ), + onSubmitted: (value) { + fetchPostsByLocation(); + }, + ), + ], + ), + ); + } + Future popCamera() async { await availableCameras().then((value) => Navigator.push(context, MaterialPageRoute(builder: (_) => Camera(camera: value.first)))); @@ -549,21 +502,11 @@ class _MyHomePageState extends State { title: const Text("Item list menu"), backgroundColor: Colors.blue, foregroundColor: Colors.white, - actions: [ - IconButton( - icon: const Icon(Icons.search), - onPressed: () { - showSearch( - context: context, - delegate: SearchDelegateExample(), - ); - }, - ), - ], ), body: Column( children: [ - _buildGeographicalZoneSearchField(), + _buildItemZoneSearchField(), + if (showDateFields) _buildGeographicalZoneSearchField(), if (showDateFields) _buildDateField("start"), if (showDateFields) _buildDateField("end"), IconButton( diff --git a/covas_mobile/lib/pages/SearchDelegate.dart b/covas_mobile/lib/pages/SearchDelegate.dart deleted file mode 100644 index c7c2fcb..0000000 --- a/covas_mobile/lib/pages/SearchDelegate.dart +++ /dev/null @@ -1,133 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:http/http.dart' as http; -import 'dart:convert'; -import 'dart:io'; -import 'ItemMenu.dart'; -import '../classes/events.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv -import 'dart:math'; - -import '../variable/globals.dart' as globals; - -class SearchDelegateExample extends SearchDelegate { - SearchDelegateExample(); - - @override - List buildActions(BuildContext context) { - return [ - IconButton( - icon: const Icon(Icons.clear), - onPressed: () { - query = ''; - }, - ), - ]; - } - - @override - Widget buildLeading(BuildContext context) { - return IconButton( - icon: const Icon(Icons.arrow_back), - onPressed: () { - close(context, null); - }, - ); - } - - @override - Widget buildResults(BuildContext context) { - // Perform the search and return the results - return FutureBuilder>( - future: searchPosts(query), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const Center(child: CircularProgressIndicator()); - } else if (snapshot.hasData) { - final posts = snapshot.data!; - return ListView.builder( - itemCount: posts.length, - itemBuilder: (context, index) { - final post = posts[index]; - return ListTile( - title: Text(post.name!), - subtitle: Text(post.place!), - onTap: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (_) => ItemMenu(title: post.id!), - ), - ); - }, - ); - }, - ); - } else { - return const Center(child: Text("No results found")); - } - }, - ); - } - - @override - Widget buildSuggestions(BuildContext context) { - return Container(); // Implement suggestions if needed - } - - String formatDate(String date) { - var splitedDate = date.split("-"); - var day = splitedDate[0]; - var month = splitedDate[1]; - var year = splitedDate[2]; - - return "${year}-${month}-${day}"; - } - - Future> searchPosts(String query) async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - var accessToken = prefs.getString("access_token") ?? ""; - var latitude = prefs.getDouble("city_lat") ?? 0.0; - var longitude = prefs.getDouble("city_long") ?? 0.0; - final List body = []; - if (accessToken.isNotEmpty) { - String parameter = "current_datetime"; - String currentDate = DateTime.now().toString(); - String date = prefs.getString("date_event") ?? ""; - String startDate = prefs.getString("start_date") ?? ""; - String endDate = prefs.getString("end_date") ?? ""; - if (date.isNotEmpty) { - currentDate = DateTime.parse(formatDate(date)).toString(); - parameter = "date_event"; - } - String parameterString = "${parameter}=${currentDate}"; - if ((startDate.isNotEmpty) && (endDate.isNotEmpty)) { - startDate = DateTime.parse(formatDate(startDate)).toString(); - endDate = DateTime.parse(formatDate(endDate)).toString(); - parameterString = "start_date=${startDate}&end_date=${endDate}"; - } - var url = Uri.parse( - "${globals.api}/events/search?item=${query}&${parameterString}"); - if ((latitude != 0.0) && (longitude != 0.0)) { - // Now use the latitude and longitude to get events within a 50km radius - 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; - // Construct the search URL with the item query and latitude/longitude bounds - url = Uri.parse( - "${globals.api}/events/search?item=${query}&min_lat=${minLat}&max_lat=${maxLat}&min_lon=${minLon}&max_lon=${maxLon}&${parameterString}"); - } - 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; - } -}