Merge pull request 'feature/suggestion-item' (#25) from feature/suggestion-item into main

Reviewed-on: #25
This commit is contained in:
v4l3n71n 2024-11-30 19:00:07 +01:00
commit 6b53dc170d

View File

@ -42,8 +42,10 @@ class _MyHomePageState extends State<ListItemMenu> {
Future<List<Events>> postsFuture = getPosts();
List<Events> filteredPosts = [];
String geographicalZone = '';
String itemName = '';
String query = '';
List<Map<String, dynamic>> suggestions = [];
List<Map<String, dynamic>> suggestionsItem = [];
TextEditingController inputGeo = TextEditingController();
TextEditingController startDatepicker = TextEditingController();
TextEditingController endDatepicker = TextEditingController();
@ -51,6 +53,7 @@ class _MyHomePageState extends State<ListItemMenu> {
bool showDateFields = false; // State to toggle date fields
bool showArrow = true;
bool showInputSearch = true;
// Fetching events from API
static Future<List<Events>> getPosts() async {
PermissionStatus status = await Permission.location.status;
@ -260,6 +263,7 @@ class _MyHomePageState extends State<ListItemMenu> {
.toList();
if (suggestions.isNotEmpty) {
showArrow = false;
showInputSearch = false;
}
});
} else {
@ -267,64 +271,94 @@ class _MyHomePageState extends State<ListItemMenu> {
}
}
Future<Uri> getUrlForEvents() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
double latitude = prefs.getDouble("city_lat") ?? 0.0;
double longitude = prefs.getDouble("city_long") ?? 0.0;
String stringParameter = "";
String endpoint = "events";
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));
double minLat = latitude - latDistance;
double maxLat = latitude + latDistance;
double minLon = longitude - lonDistance;
double maxLon = longitude + lonDistance;
endpoint = "events/search";
stringParameter = "min_lat=$minLat&max_lat=$maxLat"
"&min_lon=$minLon&max_lon=$maxLon";
}
DateTime currentDate = DateTime.now();
String dateParameter = "current_datetime=${currentDate.toString()}";
if (startDatepicker.text.isNotEmpty) {
var date = DateTime.parse(formatDate(startDatepicker.text));
dateParameter = "date_event=" + date.toString();
endpoint = "events/search";
}
if (endDatepicker.text.isNotEmpty) {
var date = DateTime.parse(formatDate(endDatepicker.text));
dateParameter = "date_event=" + date.toString();
endpoint = "events/search";
}
if ((startDatepicker.text.isNotEmpty) && (endDatepicker.text.isNotEmpty)) {
var startDate = DateTime.parse(formatDate(startDatepicker.text));
var endDate = DateTime.parse(formatDate(endDatepicker.text));
dateParameter = "&start_date=" +
startDate.toString() +
"&end_date=" +
endDate.toString();
endpoint = "events/search";
}
if (inputItem.text.isNotEmpty) {
stringParameter = stringParameter + "&item=${inputItem.text}";
endpoint = "events/search";
}
if (stringParameter.isNotEmpty) {
stringParameter = "$stringParameter&$dateParameter";
} else {
stringParameter = dateParameter;
}
return Uri.parse("${globals.api}/${endpoint}?${stringParameter}");
}
Future<void> searchSuggestionsByItem(String input) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
if (accessToken.isNotEmpty) {
var url = await getUrlForEvents();
final response = await http.get(url, headers: {
"Content-Type": "application/json",
HttpHeaders.cookieHeader: "access_token=$accessToken"
});
if (response.statusCode == 200) {
final data = json.decode(utf8.decode(response.bodyBytes));
setState(() {
suggestionsItem = (data as List)
.map((feature) => {'name': feature['name']})
.toList();
if (suggestionsItem.isNotEmpty) {
showDateFields = false;
showArrow = false;
}
});
print("status code : ${response.statusCode}");
}
}
}
Future<void> 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;
String stringParameter = "";
String endpoint = "events";
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));
double minLat = latitude - latDistance;
double maxLat = latitude + latDistance;
double minLon = longitude - lonDistance;
double maxLon = longitude + lonDistance;
endpoint = "events/search";
stringParameter = "min_lat=$minLat&max_lat=$maxLat"
"&min_lon=$minLon&max_lon=$maxLon";
}
DateTime currentDate = DateTime.now();
String dateParameter = "current_datetime=${currentDate.toString()}";
if (startDatepicker.text.isNotEmpty) {
var date = DateTime.parse(formatDate(startDatepicker.text));
dateParameter = "date_event=" + date.toString();
endpoint = "events/search";
}
if (endDatepicker.text.isNotEmpty) {
var date = DateTime.parse(formatDate(endDatepicker.text));
dateParameter = "date_event=" + date.toString();
endpoint = "events/search";
}
if ((startDatepicker.text.isNotEmpty) &&
(endDatepicker.text.isNotEmpty)) {
var startDate = DateTime.parse(formatDate(startDatepicker.text));
var endDate = DateTime.parse(formatDate(endDatepicker.text));
dateParameter = "&start_date=" +
startDate.toString() +
"&end_date=" +
endDate.toString();
endpoint = "events/search";
}
if (inputItem.text.isNotEmpty) {
stringParameter = stringParameter + "&item=${inputItem.text}";
endpoint = "events/search";
}
if (stringParameter.isNotEmpty) {
stringParameter = "$stringParameter&$dateParameter";
} else {
stringParameter = dateParameter;
}
print("stringParameter : ${stringParameter}");
var url = Uri.parse("${globals.api}/${endpoint}?${stringParameter}");
var url = await getUrlForEvents();
final response = await http.get(url, headers: {
"Content-Type": "application/json",
HttpHeaders.cookieHeader: "access_token=$accessToken"
@ -421,7 +455,8 @@ class _MyHomePageState extends State<ListItemMenu> {
inputGeo.clear(); // Clear the text field
geographicalZone = ''; // Reset the geographical zone state
suggestions.clear();
showArrow = true; // Optionally clear suggestions
showArrow = true;
showInputSearch = true; // Optionally clear suggestions
/// Clear the filtered posts
});
fetchPostsByLocation();
@ -443,6 +478,7 @@ class _MyHomePageState extends State<ListItemMenu> {
geographicalZone = ''; // Reset the geographical zone state
suggestions.clear(); // Optionally clear suggestions
showArrow = true;
showInputSearch = true;
/// Clear the filted posts
});
@ -474,6 +510,7 @@ class _MyHomePageState extends State<ListItemMenu> {
inputGeo.text = geographicalZone;
suggestions.clear();
showArrow = true;
showInputSearch = true;
});
SharedPreferences prefs =
await SharedPreferences.getInstance();
@ -496,24 +533,70 @@ class _MyHomePageState extends State<ListItemMenu> {
child: Column(
children: [
TextField(
controller: inputItem,
decoration: InputDecoration(
labelText: 'Search by item',
border: OutlineInputBorder(),
suffixIcon: IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
controller: inputItem,
decoration: InputDecoration(
labelText: 'Search by item',
border: OutlineInputBorder(),
suffixIcon: 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(() {
inputItem.clear();
itemName = value;
searchSuggestionsByItem(value);
});
} else {
setState(() {
inputItem.clear(); // Clear the text field
itemName = ''; // Reset the geographical zone state
suggestionsItem.clear();
showDateFields = true;
showArrow = true; // Optionally clear suggestions
/// 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();
},
);
},
),
),
onSubmitted: (value) {
fetchPostsByLocation();
},
),
],
),
);
@ -534,7 +617,7 @@ class _MyHomePageState extends State<ListItemMenu> {
),
body: Column(
children: [
if (showArrow) _buildItemZoneSearchField(),
if (showInputSearch) _buildItemZoneSearchField(),
if ((showDateFields) && (showArrow))
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,