From 56ae77137cc1f72d0afa60542345e0372ff4784f Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 19 Jan 2025 22:41:13 +0100 Subject: [PATCH] refactor listitemmenu --- covas_mobile/lib/pages/ListItemMenu.dart | 380 ++++++++++------------- 1 file changed, 158 insertions(+), 222 deletions(-) diff --git a/covas_mobile/lib/pages/ListItemMenu.dart b/covas_mobile/lib/pages/ListItemMenu.dart index 46dc868..dd7df3a 100644 --- a/covas_mobile/lib/pages/ListItemMenu.dart +++ b/covas_mobile/lib/pages/ListItemMenu.dart @@ -480,65 +480,33 @@ class _MyHomePageState extends State { ); } - Padding _buildGeographicalZoneSearchField() { + Widget _buildSearchField({ + required TextEditingController controller, + required String labelText, + required Function(String) onChanged, + required Function() onClear, + required List> suggestions, + required Function(Map) onSuggestionTap, + }) { return Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ TextField( - controller: inputGeo, + controller: controller, decoration: InputDecoration( - labelText: 'Search by geographical zone', + labelText: labelText, border: OutlineInputBorder(), - suffixIcon: inputGeo.text.isEmpty + suffixIcon: controller.text.isEmpty ? null : IconButton( icon: const Icon(Icons.clear), - 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 - suggestionsGeo.clear(); - showArrow = true; - showInputSearch = - true; // Optionally clear suggestions - /// Clear the filtered posts - showInputTag = true; - }); - fetchPostsByLocation(); - }, + onPressed: () => onClear(), ), ), - onChanged: (value) async { - if (value.isNotEmpty) { - setState(() { - geographicalZone = value; - searchSuggestionsGeo(value); - }); - } else { - 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 - suggestionsGeo.clear(); // Optionally clear suggestions - showArrow = true; - showInputSearch = true; - showInputTag = true; - - /// Clear the filted posts - }); - fetchPostsByLocation(); - } - }, + onChanged: onChanged, ), - if (suggestionsGeo.isNotEmpty) + if (suggestions.isNotEmpty) Container( height: 200, decoration: BoxDecoration( @@ -547,181 +515,13 @@ class _MyHomePageState extends State { ), child: ListView.builder( shrinkWrap: true, - itemCount: suggestionsGeo.length, + itemCount: suggestions.length, itemBuilder: (context, index) { + final suggestion = suggestions[index]; return ListTile( - title: Text(suggestionsGeo[index]['place_name']), - onTap: () async { - final latitude = - suggestionsGeo[index]['geometry']['coordinates'][1]; - final longitude = - suggestionsGeo[index]['geometry']['coordinates'][0]; - - setState(() { - geographicalZone = suggestionsGeo[index]['place_name']; - inputGeo.text = geographicalZone; - suggestionsGeo.clear(); - showArrow = true; - showInputSearch = true; - showInputTag = true; - }); - SharedPreferences prefs = - await SharedPreferences.getInstance(); - prefs.setDouble("city_lat", latitude); - prefs.setDouble("city_long", longitude); - await fetchPostsByLocation(); - }, - ); - }, - ), - ), - ], - ), - ); - } - - Padding _buildTagsField() { - return Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - children: [ - TextField( - controller: inputTags, - decoration: InputDecoration( - labelText: 'Search by tags', - border: OutlineInputBorder(), - suffixIcon: inputTags.text.isEmpty - ? null - : IconButton( - icon: const Icon(Icons.clear), - onPressed: () { - setState(() { - inputTags.clear(); - }); - fetchPostsByLocation(); - }, - ), - ), - onChanged: (value) { - if (value.isNotEmpty) { - setState(() { - itemTags = value; - searchSuggestionsByTag(value); - }); - } else { - setState(() { - inputTags.clear(); - showArrow = true; - showInputSearch = true; - showInputGeo = true; // Optionally clear suggestions - itemTags = ''; // Clear the text field - - /// Clear the filted posts - }); - fetchPostsByLocation(); - } - }), - if (suggestionsTags.isNotEmpty) - Container( - height: 200, - decoration: BoxDecoration( - border: Border.all(color: Colors.blue), - borderRadius: BorderRadius.circular(8), - ), - child: ListView.builder( - shrinkWrap: true, - itemCount: suggestionsTags.length, - itemBuilder: (context, index) { - return ListTile( - title: Text(suggestionsTags[index]['name']), - onTap: () async { - setState(() { - itemTags = suggestionsTags[index]['name']; - inputTags.text = itemTags; - suggestionsTags.clear(); - showArrow = true; - showInputSearch = true; - showInputGeo = true; - }); - await fetchPostsByLocation(); - }, - ); - }, - ), - ), - ], - ), - ); - } - - 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: inputItem.text.isEmpty - ? null - : IconButton( - icon: const Icon(Icons.clear), - onPressed: () { - setState(() { - inputItem.clear(); - itemName = ''; // Reset the geographical zone state - suggestionsItem.clear(); - showDateFields = true; - showArrow = true; - }); - fetchPostsByLocation(); - }, - ), - ), - onChanged: (value) { - if (value.isNotEmpty) { - setState(() { - itemName = value; - searchSuggestionsByItem(value); - }); - } else { - setState(() { - showDateFields = true; - showArrow = true; // Optionally clear suggestions - inputItem.clear(); // Clear the text field - itemName = ''; // Reset the geographical zone state - suggestionsItem.clear(); - - /// Clear the filted posts - }); - fetchPostsByLocation(); - } - }), - if (suggestionsItem.isNotEmpty) - Container( - height: 200, - decoration: BoxDecoration( - border: Border.all(color: Colors.blue), - borderRadius: BorderRadius.circular(8), - ), - child: ListView.builder( - shrinkWrap: true, - itemCount: suggestionsItem.length, - itemBuilder: (context, index) { - return ListTile( - title: Text(suggestionsItem[index]['name']), - onTap: () async { - setState(() { - itemName = suggestionsItem[index]['name']; - inputItem.text = itemName; - suggestionsItem.clear(); - showDateFields = true; - showArrow = true; - }); - await fetchPostsByLocation(); - }, + title: Text( + suggestion['name'] ?? suggestion['place_name'] ?? ''), + onTap: () => onSuggestionTap(suggestion), ); }, ), @@ -747,8 +547,89 @@ class _MyHomePageState extends State { drawer: MyDrawer(), body: Column( children: [ - if (showInputSearch) _buildItemZoneSearchField(), - if ((showDateFields) && (showInputTag)) _buildTagsField(), + if (showInputSearch) + _buildSearchField( + controller: inputItem, + labelText: 'Search by item', + onChanged: (value) { + if (value.isNotEmpty) { + setState(() { + itemName = value; + searchSuggestionsByItem(value); + }); + } else { + setState(() { + inputItem.clear(); + itemName = ''; + suggestionsItem.clear(); + showDateFields = true; + showArrow = true; + }); + fetchPostsByLocation(); + } + }, + onClear: () { + setState(() { + inputItem.clear(); + itemName = ''; + suggestionsItem.clear(); + showDateFields = true; + showArrow = true; + }); + fetchPostsByLocation(); + }, + suggestions: suggestionsItem, + onSuggestionTap: (suggestion) async { + setState(() { + itemName = suggestion['name']; + inputItem.text = itemName; + suggestionsItem.clear(); + showDateFields = true; + showArrow = true; + }); + await fetchPostsByLocation(); + }, + ), + if ((showDateFields) && (showInputTag)) + _buildSearchField( + controller: inputTags, + labelText: 'Search by tags', + onChanged: (value) { + if (value.isNotEmpty) { + setState(() { + itemTags = value; + searchSuggestionsByTag(value); + }); + } else { + setState(() { + inputTags.clear(); + showArrow = true; + showInputSearch = true; + showInputGeo = true; + itemTags = ''; + }); + fetchPostsByLocation(); + } + }, + onClear: () { + setState(() { + inputTags.clear(); + }); + fetchPostsByLocation(); + }, + suggestions: suggestionsTags, + onSuggestionTap: (suggestion) async { + setState(() { + itemTags = suggestion['name']; + inputTags.text = itemTags; + suggestionsTags.clear(); + showArrow = true; + showInputSearch = true; + showInputGeo = true; + }); + await fetchPostsByLocation(); + }, + ), if ((showDateFields) && (showArrow)) Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -757,7 +638,62 @@ class _MyHomePageState extends State { Flexible(child: _buildDateField("end")) ]), if ((showDateFields) && (showInputGeo)) - _buildGeographicalZoneSearchField(), + _buildSearchField( + controller: inputGeo, + labelText: 'Search by geographical zone', + onChanged: (value) async { + if (value.isNotEmpty) { + setState(() { + geographicalZone = value; + searchSuggestionsGeo(value); + }); + } else { + final prefs = await SharedPreferences.getInstance(); + prefs.remove("city_lat"); + prefs.remove("city_long"); + setState(() { + inputGeo.clear(); + geographicalZone = ''; + suggestionsGeo.clear(); + showArrow = true; + showInputSearch = true; + showInputTag = true; + }); + fetchPostsByLocation(); + } + }, + onClear: () async { + final prefs = await SharedPreferences.getInstance(); + prefs.remove("city_lat"); + prefs.remove("city_long"); + setState(() { + inputGeo.clear(); + geographicalZone = ''; + suggestionsGeo.clear(); + showArrow = true; + showInputSearch = true; + showInputTag = true; + }); + fetchPostsByLocation(); + }, + suggestions: suggestionsGeo, + onSuggestionTap: (suggestion) async { + final latitude = suggestion['geometry']['coordinates'][1]; + final longitude = suggestion['geometry']['coordinates'][0]; + setState(() { + geographicalZone = suggestion['place_name']; + inputGeo.text = geographicalZone; + suggestionsGeo.clear(); + showArrow = true; + showInputSearch = true; + showInputTag = true; + }); + final prefs = await SharedPreferences.getInstance(); + prefs.setDouble("city_lat", latitude); + prefs.setDouble("city_long", longitude); + await fetchPostsByLocation(); + }, + ), if (showArrow) IconButton( onPressed: () {