From cdae84090fab62cb1cf1265b8a53015680ba38ec Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 20 Nov 2024 23:48:01 +0100 Subject: [PATCH 1/9] add input date --- covas_mobile/lib/pages/ListItemMenu.dart | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 04761d1..047c501 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -46,6 +46,7 @@ class _MyHomePageState extends State { String query = ''; List> suggestions = []; TextEditingController inputGeo = TextEditingController(); + TextEditingController Datepicker = TextEditingController(); // Fetching events from API static Future> getPosts() async { @@ -118,6 +119,8 @@ class _MyHomePageState extends State { super.initState(); // Initialize data fetch when the page loads _getCurrentLocation(); + + Datepicker.text = DateFormat("dd-MM-yyyy").format(new DateTime.now()); } // Get the device's current location @@ -296,6 +299,31 @@ class _MyHomePageState extends State { } } + onTapFunctionDatePicker({required BuildContext context}) async { + DateTime dateEvent = DateTime.now(); + + DateTime? pickedDate = await showDatePicker( + context: context, + firstDate: dateEvent, + initialDate: dateEvent, + lastDate: DateTime(2104)); + if (pickedDate == null) return; + Datepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } + + Padding _BuildDateField() { + return Padding( + padding: const EdgeInsets.all(8.0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextFormField( + controller: Datepicker, + readOnly: true, + decoration: InputDecoration( + border: OutlineInputBorder(), hintText: 'Recherche par date'), + onTap: () => onTapFunctionDatePicker(context: context)), + ); + } + Padding _buildGeographicalZoneSearchField() { return Padding( padding: const EdgeInsets.all(8.0), @@ -388,6 +416,7 @@ class _MyHomePageState extends State { body: Column( children: [ _buildGeographicalZoneSearchField(), + _BuildDateField(), Expanded( child: FutureBuilder>( future: postsFuture, From f693ffa6b86b6e7925f93b23168262cc2e4fa384 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 23 Nov 2024 09:56:37 +0100 Subject: [PATCH 2/9] merge commit --- covas_mobile/lib/pages/ListItemMenu.dart | 42 ++++++++++++++---------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index f0f581c..e29ba66 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -137,8 +137,6 @@ class _MyHomePageState extends State { super.initState(); // Initialize data fetch when the page loads _getCurrentLocation(); - - Datepicker.text = DateFormat("dd-MM-yyyy").format(new DateTime.now()); } // Get the device's current location @@ -149,19 +147,32 @@ class _MyHomePageState extends State { print("Location permission granted"); // Get the current position with high accuracy - LocationSettings locationSettings = LocationSettings( - accuracy: LocationAccuracy.high, - distanceFilter: - 10, // Optional: Minimum distance (in meters) to trigger location update - ); - - Position position = await Geolocator.getCurrentPosition( - locationSettings: locationSettings, - ); + const LocationSettings locationSettings = LocationSettings( + accuracy: LocationAccuracy.medium, timeLimit: Duration(seconds: 5)); + Position? position; + try { + position = await Geolocator.getCurrentPosition( + locationSettings: locationSettings); + } on LocationServiceDisabledException { + // Handle location services disabled + print('Location services are disabled.'); + position = await Geolocator.getLastKnownPosition(); + if (position == null) { + print('No last known position available.'); + } + } catch (e) { + // Handle other errors + print('Failed to get location: $e'); + position = await Geolocator.getLastKnownPosition(); + if (position == null) { + print('No last known position available.'); + } + } // Reverse geocode: Get city and country from latitude and longitude using Mapbox Search API - final place = - await _getCityAndCountry(position.latitude, position.longitude); + if (position != null) { + _getCityAndCountry(position!.latitude, position!.longitude); + } } } @@ -321,10 +332,7 @@ class _MyHomePageState extends State { DateTime dateEvent = DateTime.now(); DateTime? pickedDate = await showDatePicker( - context: context, - firstDate: dateEvent, - initialDate: dateEvent, - lastDate: DateTime(2104)); + context: context, firstDate: dateEvent, lastDate: DateTime(2104)); if (pickedDate == null) return; Datepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); } From c6a0c2f4f14a14af2a7819be9b9d5595ae6f32a2 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 23 Nov 2024 10:42:32 +0100 Subject: [PATCH 3/9] add cache for position --- covas_mobile/lib/pages/ListItemMenu.dart | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index e29ba66..f3dd37d 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -172,6 +172,9 @@ class _MyHomePageState extends State { // Reverse geocode: Get city and country from latitude and longitude using Mapbox Search API if (position != null) { _getCityAndCountry(position!.latitude, position!.longitude); + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setDouble("city_lat", position!.latitude); + prefs.setDouble("city_long", position!.longitude); } } } @@ -335,6 +338,9 @@ class _MyHomePageState extends State { context: context, firstDate: dateEvent, lastDate: DateTime(2104)); if (pickedDate == null) return; Datepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + if (inputGeo.text.isEmpty) { + _fetchInitialData(); + } else {} } Padding _BuildDateField() { @@ -345,7 +351,16 @@ class _MyHomePageState extends State { controller: Datepicker, readOnly: true, decoration: InputDecoration( - border: OutlineInputBorder(), hintText: 'Recherche par date'), + border: OutlineInputBorder(), + suffixIcon: IconButton( + icon: const Icon(Icons.clear), + onPressed: () { + setState(() { + Datepicker.text = ''; + }); + }, + ), + hintText: 'Recherche par date'), onTap: () => onTapFunctionDatePicker(context: context)), ); } @@ -405,6 +420,10 @@ class _MyHomePageState extends State { }); await fetchPostsByLocation(latitude, longitude); + SharedPreferences prefs = + await SharedPreferences.getInstance(); + prefs.setDouble("city_lat", latitude); + prefs.setDouble("city_long", longitude); }, ); }, From a0ece6f9736bdcfa218e2cd97dd2675319c88460 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 23 Nov 2024 10:50:57 +0100 Subject: [PATCH 4/9] passing parameter --- covas_mobile/lib/pages/ListItemMenu.dart | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index f3dd37d..5020fcb 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -172,9 +172,6 @@ class _MyHomePageState extends State { // Reverse geocode: Get city and country from latitude and longitude using Mapbox Search API if (position != null) { _getCityAndCountry(position!.latitude, position!.longitude); - SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.setDouble("city_lat", position!.latitude); - prefs.setDouble("city_long", position!.longitude); } } } @@ -206,7 +203,10 @@ class _MyHomePageState extends State { String country = _getCountryFromFeatures(features); print("city : ${city} ${country}"); if (city.isNotEmpty && country.isNotEmpty) { - fetchPostsByLocation(latitude, longitude); + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setDouble("city_lat", latitude); + prefs.setDouble("city_long", longitude); + fetchPostsByLocation(); setState(() { inputGeo.text = "${city}, ${country}"; }); @@ -286,11 +286,14 @@ class _MyHomePageState extends State { } } - Future fetchPostsByLocation(double latitude, double longitude) async { + Future fetchPostsByLocation() async { SharedPreferences prefs = await SharedPreferences.getInstance(); var accessToken = prefs.getString("access_token") ?? ""; if (accessToken.isNotEmpty) { + double latitude = prefs.getDouble("city_lat") ?? 0.0; + double longitude = prefs.getDouble("city_long") ?? 0.0; + // Calculate the boundaries double radiusInKm = 50; double latDistance = radiusInKm / 111.0; @@ -418,12 +421,11 @@ class _MyHomePageState extends State { inputGeo.text = geographicalZone; suggestions.clear(); }); - - await fetchPostsByLocation(latitude, longitude); SharedPreferences prefs = await SharedPreferences.getInstance(); prefs.setDouble("city_lat", latitude); prefs.setDouble("city_long", longitude); + await fetchPostsByLocation(); }, ); }, From 23aec689f13469043b80a6cff97c9b6b9eed73fa Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 23 Nov 2024 13:14:24 +0100 Subject: [PATCH 5/9] add condition --- covas_mobile/lib/pages/ListItemMenu.dart | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 5020fcb..6012b06 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -1,4 +1,3 @@ -import 'package:covas_mobile/classes/alert.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv @@ -122,6 +121,10 @@ class _MyHomePageState extends State { DateTime currentDateTime = DateTime.now(); var url = Uri.parse( "${globals.api}/events?current_datetime=${currentDateTime.toString()}"); + if (Datepicker.text.isNotEmpty) { + url = Uri.parse( + "${globals.api}/events?current_datetime=${currentDateTime.toString()}"); + } final response = await http.get(url, headers: { "Content-Type": "application/json", HttpHeaders.cookieHeader: "access_token=${accessToken}" @@ -307,6 +310,11 @@ class _MyHomePageState extends State { var url = Uri.parse("${globals.api}/events/search" "?min_lat=$minLat&max_lat=$maxLat" "&min_lon=$minLon&max_lon=$maxLon¤t_datetime=${currentDate.toString()}"); + if (Datepicker.text.isNotEmpty) { + 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", @@ -343,7 +351,9 @@ class _MyHomePageState extends State { Datepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); if (inputGeo.text.isEmpty) { _fetchInitialData(); - } else {} + } else { + fetchPostsByLocation(); + } } Padding _BuildDateField() { From 627eb778ad6ee632fe0fe45e25fc681b5333d4ca Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 23 Nov 2024 13:29:25 +0100 Subject: [PATCH 6/9] add cache for latitude and use in searchdelagate --- covas_mobile/lib/pages/ListItemMenu.dart | 8 +++- covas_mobile/lib/pages/SearchDelegate.dart | 55 +++++++--------------- 2 files changed, 23 insertions(+), 40 deletions(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 6012b06..3ba5571 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -367,7 +367,11 @@ class _MyHomePageState extends State { border: OutlineInputBorder(), suffixIcon: IconButton( icon: const Icon(Icons.clear), - onPressed: () { + onPressed: () async { + SharedPreferences prefs = + await SharedPreferences.getInstance(); + prefs.remove("city_lat"); + prefs.remove("city_long"); setState(() { Datepicker.text = ''; }); @@ -464,7 +468,7 @@ class _MyHomePageState extends State { onPressed: () { showSearch( context: context, - delegate: SearchDelegateExample(geoQuery: inputGeo.text), + delegate: SearchDelegateExample(), ); }, ), diff --git a/covas_mobile/lib/pages/SearchDelegate.dart b/covas_mobile/lib/pages/SearchDelegate.dart index e49b17e..c534e79 100644 --- a/covas_mobile/lib/pages/SearchDelegate.dart +++ b/covas_mobile/lib/pages/SearchDelegate.dart @@ -11,11 +11,7 @@ import 'dart:math'; import '../variable/globals.dart' as globals; class SearchDelegateExample extends SearchDelegate { - final String geoQuery; - - SearchDelegateExample({ - required this.geoQuery, - }); + SearchDelegateExample(); @override List buildActions(BuildContext context) { @@ -43,7 +39,7 @@ class SearchDelegateExample extends SearchDelegate { Widget buildResults(BuildContext context) { // Perform the search and return the results return FutureBuilder>( - future: searchPosts(query, geoQuery), + future: searchPosts(query), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); @@ -79,45 +75,28 @@ class SearchDelegateExample extends SearchDelegate { return Container(); // Implement suggestions if needed } - Future> searchPosts(String query, String geoQuery) async { + 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) { DateTime currentDate = DateTime.now(); var url = Uri.parse( "${globals.api}/events/search?item=${query}¤t_dateime=${currentDate.toString()}"); - if (geoQuery.isNotEmpty) { - await dotenv.load( - fileName: ".env"); // Load your .env for the Mapbox access token - final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? ''; - final geocodeUrl = Uri.parse( - 'https://api.mapbox.com/geocoding/v5/mapbox.places/$geoQuery.json?access_token=$mapboxAccessToken'); - final geocodeResponse = await http.get(geocodeUrl); - if (geocodeResponse.statusCode == 200) { - final geocodeData = json.decode(geocodeResponse.body); - if (geocodeData['features'].isNotEmpty) { - final coordinates = - geocodeData['features'][0]['geometry']['coordinates']; - final longitude = coordinates[0]; // Longitude - final latitude = coordinates[1]; // Latitude - - // 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}¤t_dateime=${currentDate.toString()}"); - } - } + 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}¤t_dateime=${currentDate.toString()}"); } final response = await http.get(url, headers: { "Content-Type": "application/json", From d4f8ee2182ed875bcd91f6e51eb3297c85d61532 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 23 Nov 2024 17:24:46 +0100 Subject: [PATCH 7/9] add parameter --- covas_mobile/lib/pages/ListItemMenu.dart | 34 +++++++++++++++++----- covas_mobile/lib/pages/SearchDelegate.dart | 21 +++++++++++-- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 3ba5571..b6a92ef 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -112,6 +112,15 @@ class _MyHomePageState extends State { return body; } + String formatDate(String date) { + var splitedDate = date.split("-"); + var day = splitedDate[0]; + var month = splitedDate[1]; + var year = splitedDate[2]; + + return "${year}-${month}-${day}"; + } + // Fetching events from API Future> getAllPosts() async { SharedPreferences prefs = await SharedPreferences.getInstance(); @@ -122,8 +131,9 @@ class _MyHomePageState extends State { var url = Uri.parse( "${globals.api}/events?current_datetime=${currentDateTime.toString()}"); if (Datepicker.text.isNotEmpty) { - url = Uri.parse( - "${globals.api}/events?current_datetime=${currentDateTime.toString()}"); + TimeOfDay time = TimeOfDay.now(); + var date = formatDate(Datepicker.text) + "T" + time.toString(); + url = Uri.parse("${globals.api}/events?date_event=${date}"); } final response = await http.get(url, headers: { "Content-Type": "application/json", @@ -311,9 +321,12 @@ class _MyHomePageState extends State { "?min_lat=$minLat&max_lat=$maxLat" "&min_lon=$minLon&max_lon=$maxLon¤t_datetime=${currentDate.toString()}"); if (Datepicker.text.isNotEmpty) { + TimeOfDay time = TimeOfDay.now(); + var date = formatDate(Datepicker.text) + "T" + time.toString(); url = Uri.parse("${globals.api}/events/search" - "?min_lat=$minLat&max_lat=$maxLat" - "&min_lon=$minLon&max_lon=$maxLon"); + "?min_lat=$minLat&max_lat=$maxLat" + "&min_lon=$minLon&max_lon=$maxLon&date_event=" + + date); } final response = await http.get(url, headers: { @@ -349,6 +362,8 @@ class _MyHomePageState extends State { context: context, firstDate: dateEvent, lastDate: DateTime(2104)); if (pickedDate == null) return; Datepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + SharedPreferences prefs = await SharedPreferences.getInstance(); + prefs.setString("date_event", Datepicker.text); if (inputGeo.text.isEmpty) { _fetchInitialData(); } else { @@ -370,8 +385,8 @@ class _MyHomePageState extends State { onPressed: () async { SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.remove("city_lat"); - prefs.remove("city_long"); + + prefs.remove("date_event"); setState(() { Datepicker.text = ''; }); @@ -394,7 +409,11 @@ class _MyHomePageState extends State { border: OutlineInputBorder(), suffixIcon: IconButton( icon: const Icon(Icons.clear), - onPressed: () { + onPressed: () async { + SharedPreferences prefs = + await SharedPreferences.getInstance(); + prefs.remove("city_lat"); + prefs.remove("city_long"); setState(() { inputGeo.clear(); // Clear the text field geographicalZone = ''; // Reset the geographical zone state @@ -527,7 +546,6 @@ class _MyHomePageState extends State { final startDate = DateTime.parse(post.startDate!); final date = DateFormat.yMd().format(startDate); final time = DateFormat.Hm().format(startDate); - return ListTile( title: Text('${post.name!}'), subtitle: Text('${post.place!}\n${date} ${time}'), diff --git a/covas_mobile/lib/pages/SearchDelegate.dart b/covas_mobile/lib/pages/SearchDelegate.dart index c534e79..40c8f88 100644 --- a/covas_mobile/lib/pages/SearchDelegate.dart +++ b/covas_mobile/lib/pages/SearchDelegate.dart @@ -75,6 +75,15 @@ class SearchDelegateExample extends SearchDelegate { 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") ?? ""; @@ -82,9 +91,15 @@ class SearchDelegateExample extends SearchDelegate { var longitude = prefs.getDouble("city_long") ?? 0.0; final List body = []; if (accessToken.isNotEmpty) { - DateTime currentDate = DateTime.now(); + String parameter = "current_datetime"; + String currentDate = DateTime.now().toString(); + String date = prefs.getString("date_event") ?? ""; + if (date.isNotEmpty) { + currentDate = formatDate(date) + "T" + TimeOfDay.now().toString(); + parameter = "date_event"; + } var url = Uri.parse( - "${globals.api}/events/search?item=${query}¤t_dateime=${currentDate.toString()}"); + "${globals.api}/events/search?item=${query}&${parameter}=${currentDate}"); if ((latitude != 0.0) && (longitude != 0.0)) { // Now use the latitude and longitude to get events within a 50km radius double radiusInKm = 50; @@ -96,7 +111,7 @@ class SearchDelegateExample extends SearchDelegate { 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}¤t_dateime=${currentDate.toString()}"); + "${globals.api}/events/search?item=${query}&min_lat=${minLat}&max_lat=${maxLat}&min_lon=${minLon}&max_lon=${maxLon}&${parameter}=${currentDate}"); } final response = await http.get(url, headers: { "Content-Type": "application/json", From 431b8d78ada13647018fb288a3cb002868161d69 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 23 Nov 2024 17:59:52 +0100 Subject: [PATCH 8/9] search by date work --- covas_mobile/lib/pages/ListItemMenu.dart | 17 +++++++++++------ covas_mobile/lib/pages/SearchDelegate.dart | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index b6a92ef..3afaecb 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -131,9 +131,8 @@ class _MyHomePageState extends State { var url = Uri.parse( "${globals.api}/events?current_datetime=${currentDateTime.toString()}"); if (Datepicker.text.isNotEmpty) { - TimeOfDay time = TimeOfDay.now(); - var date = formatDate(Datepicker.text) + "T" + time.toString(); - url = Uri.parse("${globals.api}/events?date_event=${date}"); + var date = DateTime.parse(formatDate(Datepicker.text)); + url = Uri.parse("${globals.api}/events?date_event=${date.toString()}"); } final response = await http.get(url, headers: { "Content-Type": "application/json", @@ -317,16 +316,17 @@ class _MyHomePageState extends State { double minLon = longitude - lonDistance; double maxLon = longitude + lonDistance; 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()}"); if (Datepicker.text.isNotEmpty) { - TimeOfDay time = TimeOfDay.now(); - var date = formatDate(Datepicker.text) + "T" + time.toString(); + var date = DateTime.parse(formatDate(Datepicker.text)); + print("date_event ${date.toString()}"); url = Uri.parse("${globals.api}/events/search" "?min_lat=$minLat&max_lat=$maxLat" "&min_lon=$minLon&max_lon=$maxLon&date_event=" + - date); + date.toString()); } final response = await http.get(url, headers: { @@ -390,6 +390,11 @@ class _MyHomePageState extends State { setState(() { Datepicker.text = ''; }); + if (inputGeo.text.isNotEmpty) { + fetchPostsByLocation(); + } else { + _fetchInitialData(); + } }, ), hintText: 'Recherche par date'), diff --git a/covas_mobile/lib/pages/SearchDelegate.dart b/covas_mobile/lib/pages/SearchDelegate.dart index 40c8f88..b996837 100644 --- a/covas_mobile/lib/pages/SearchDelegate.dart +++ b/covas_mobile/lib/pages/SearchDelegate.dart @@ -95,7 +95,7 @@ class SearchDelegateExample extends SearchDelegate { String currentDate = DateTime.now().toString(); String date = prefs.getString("date_event") ?? ""; if (date.isNotEmpty) { - currentDate = formatDate(date) + "T" + TimeOfDay.now().toString(); + currentDate = DateTime.parse(formatDate(date)).toString(); parameter = "date_event"; } var url = Uri.parse( From bae64ebd359ca07f643e56adcee0b5b56c79ec15 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 23 Nov 2024 21:52:50 +0100 Subject: [PATCH 9/9] add start_date and end_date --- covas_mobile/lib/pages/ListItemMenu.dart | 102 +++++++++++++++++---- covas_mobile/lib/pages/SearchDelegate.dart | 12 ++- 2 files changed, 92 insertions(+), 22 deletions(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 3afaecb..e9fee28 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -46,7 +46,8 @@ class _MyHomePageState extends State { String query = ''; List> suggestions = []; TextEditingController inputGeo = TextEditingController(); - TextEditingController Datepicker = TextEditingController(); + TextEditingController startDatepicker = TextEditingController(); + TextEditingController endDatepicker = TextEditingController(); // Fetching events from API static Future> getPosts() async { @@ -130,10 +131,21 @@ class _MyHomePageState extends State { DateTime currentDateTime = DateTime.now(); var url = Uri.parse( "${globals.api}/events?current_datetime=${currentDateTime.toString()}"); - if (Datepicker.text.isNotEmpty) { - var date = DateTime.parse(formatDate(Datepicker.text)); + 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}" @@ -320,15 +332,31 @@ class _MyHomePageState extends State { var url = Uri.parse("${globals.api}/events/search" "?min_lat=$minLat&max_lat=$maxLat" "&min_lon=$minLon&max_lon=$maxLon¤t_datetime=${currentDate.toString()}"); - if (Datepicker.text.isNotEmpty) { - var date = DateTime.parse(formatDate(Datepicker.text)); - print("date_event ${date.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()); } - + 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()); + } + 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() + + "&end_date=" + + end_date.toString()); + } final response = await http.get(url, headers: { "Content-Type": "application/json", HttpHeaders.cookieHeader: "access_token=$accessToken" @@ -355,15 +383,33 @@ class _MyHomePageState extends State { } } - onTapFunctionDatePicker({required BuildContext context}) async { + onTapFunctionDatePicker( + {required BuildContext context, String position = ""}) async { DateTime dateEvent = DateTime.now(); + if (startDatepicker.text.isNotEmpty) { + dateEvent = DateTime.parse(formatDate(startDatepicker.text)); + } DateTime? pickedDate = await showDatePicker( context: context, firstDate: dateEvent, lastDate: DateTime(2104)); if (pickedDate == null) return; - Datepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + if (position == "start") { + startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } else if (position == "end") { + endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } SharedPreferences prefs = await SharedPreferences.getInstance(); - prefs.setString("date_event", Datepicker.text); + 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 { @@ -371,25 +417,39 @@ class _MyHomePageState extends State { } } - Padding _BuildDateField() { + Padding _buildDateField(String position) { + TextEditingController datePicker = startDatepicker; + String hintText = "Date de début"; + if (position == "end") { + datePicker = endDatepicker; + hintText = "Date de fin"; + } return Padding( padding: const EdgeInsets.all(8.0), //padding: EdgeInsets.symmetric(horizontal: 15), child: TextFormField( - controller: Datepicker, + controller: datePicker, readOnly: true, decoration: InputDecoration( border: OutlineInputBorder(), suffixIcon: IconButton( icon: const Icon(Icons.clear), onPressed: () async { + setState(() { + datePicker.text = ''; + }); SharedPreferences prefs = await SharedPreferences.getInstance(); - - prefs.remove("date_event"); - setState(() { - Datepicker.text = ''; - }); + 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 { @@ -397,8 +457,9 @@ class _MyHomePageState extends State { } }, ), - hintText: 'Recherche par date'), - onTap: () => onTapFunctionDatePicker(context: context)), + hintText: hintText), + onTap: () => + onTapFunctionDatePicker(context: context, position: position)), ); } @@ -501,7 +562,8 @@ class _MyHomePageState extends State { body: Column( children: [ _buildGeographicalZoneSearchField(), - _BuildDateField(), + _buildDateField("start"), + _buildDateField("end"), Expanded( child: FutureBuilder>( future: postsFuture, diff --git a/covas_mobile/lib/pages/SearchDelegate.dart b/covas_mobile/lib/pages/SearchDelegate.dart index b996837..c7c2fcb 100644 --- a/covas_mobile/lib/pages/SearchDelegate.dart +++ b/covas_mobile/lib/pages/SearchDelegate.dart @@ -94,12 +94,20 @@ class SearchDelegateExample extends SearchDelegate { 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}&${parameter}=${currentDate}"); + "${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; @@ -111,7 +119,7 @@ class SearchDelegateExample extends SearchDelegate { 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}&${parameter}=${currentDate}"); + "${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",