Merge pull request 'feature/suggestion-item' (#25) from feature/suggestion-item into main
Reviewed-on: #25
This commit is contained in:
commit
6b53dc170d
@ -42,8 +42,10 @@ class _MyHomePageState extends State<ListItemMenu> {
|
|||||||
Future<List<Events>> postsFuture = getPosts();
|
Future<List<Events>> postsFuture = getPosts();
|
||||||
List<Events> filteredPosts = [];
|
List<Events> filteredPosts = [];
|
||||||
String geographicalZone = '';
|
String geographicalZone = '';
|
||||||
|
String itemName = '';
|
||||||
String query = '';
|
String query = '';
|
||||||
List<Map<String, dynamic>> suggestions = [];
|
List<Map<String, dynamic>> suggestions = [];
|
||||||
|
List<Map<String, dynamic>> suggestionsItem = [];
|
||||||
TextEditingController inputGeo = TextEditingController();
|
TextEditingController inputGeo = TextEditingController();
|
||||||
TextEditingController startDatepicker = TextEditingController();
|
TextEditingController startDatepicker = TextEditingController();
|
||||||
TextEditingController endDatepicker = TextEditingController();
|
TextEditingController endDatepicker = TextEditingController();
|
||||||
@ -51,6 +53,7 @@ class _MyHomePageState extends State<ListItemMenu> {
|
|||||||
|
|
||||||
bool showDateFields = false; // State to toggle date fields
|
bool showDateFields = false; // State to toggle date fields
|
||||||
bool showArrow = true;
|
bool showArrow = true;
|
||||||
|
bool showInputSearch = true;
|
||||||
// Fetching events from API
|
// Fetching events from API
|
||||||
static Future<List<Events>> getPosts() async {
|
static Future<List<Events>> getPosts() async {
|
||||||
PermissionStatus status = await Permission.location.status;
|
PermissionStatus status = await Permission.location.status;
|
||||||
@ -260,6 +263,7 @@ class _MyHomePageState extends State<ListItemMenu> {
|
|||||||
.toList();
|
.toList();
|
||||||
if (suggestions.isNotEmpty) {
|
if (suggestions.isNotEmpty) {
|
||||||
showArrow = false;
|
showArrow = false;
|
||||||
|
showInputSearch = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} 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 {
|
Future<void> fetchPostsByLocation() async {
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
var accessToken = prefs.getString("access_token") ?? "";
|
var accessToken = prefs.getString("access_token") ?? "";
|
||||||
|
|
||||||
if (accessToken.isNotEmpty) {
|
if (accessToken.isNotEmpty) {
|
||||||
double latitude = prefs.getDouble("city_lat") ?? 0.0;
|
var url = await getUrlForEvents();
|
||||||
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}");
|
|
||||||
final response = await http.get(url, headers: {
|
final response = await http.get(url, headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
HttpHeaders.cookieHeader: "access_token=$accessToken"
|
HttpHeaders.cookieHeader: "access_token=$accessToken"
|
||||||
@ -421,7 +455,8 @@ class _MyHomePageState extends State<ListItemMenu> {
|
|||||||
inputGeo.clear(); // Clear the text field
|
inputGeo.clear(); // Clear the text field
|
||||||
geographicalZone = ''; // Reset the geographical zone state
|
geographicalZone = ''; // Reset the geographical zone state
|
||||||
suggestions.clear();
|
suggestions.clear();
|
||||||
showArrow = true; // Optionally clear suggestions
|
showArrow = true;
|
||||||
|
showInputSearch = true; // Optionally clear suggestions
|
||||||
/// Clear the filtered posts
|
/// Clear the filtered posts
|
||||||
});
|
});
|
||||||
fetchPostsByLocation();
|
fetchPostsByLocation();
|
||||||
@ -443,6 +478,7 @@ class _MyHomePageState extends State<ListItemMenu> {
|
|||||||
geographicalZone = ''; // Reset the geographical zone state
|
geographicalZone = ''; // Reset the geographical zone state
|
||||||
suggestions.clear(); // Optionally clear suggestions
|
suggestions.clear(); // Optionally clear suggestions
|
||||||
showArrow = true;
|
showArrow = true;
|
||||||
|
showInputSearch = true;
|
||||||
|
|
||||||
/// Clear the filted posts
|
/// Clear the filted posts
|
||||||
});
|
});
|
||||||
@ -474,6 +510,7 @@ class _MyHomePageState extends State<ListItemMenu> {
|
|||||||
inputGeo.text = geographicalZone;
|
inputGeo.text = geographicalZone;
|
||||||
suggestions.clear();
|
suggestions.clear();
|
||||||
showArrow = true;
|
showArrow = true;
|
||||||
|
showInputSearch = true;
|
||||||
});
|
});
|
||||||
SharedPreferences prefs =
|
SharedPreferences prefs =
|
||||||
await SharedPreferences.getInstance();
|
await SharedPreferences.getInstance();
|
||||||
@ -496,24 +533,70 @@ class _MyHomePageState extends State<ListItemMenu> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
TextField(
|
TextField(
|
||||||
controller: inputItem,
|
controller: inputItem,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
labelText: 'Search by item',
|
labelText: 'Search by item',
|
||||||
border: OutlineInputBorder(),
|
border: OutlineInputBorder(),
|
||||||
suffixIcon: IconButton(
|
suffixIcon: IconButton(
|
||||||
icon: const Icon(Icons.clear),
|
icon: const Icon(Icons.clear),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
inputItem.clear();
|
||||||
|
itemName = ''; // Reset the geographical zone state
|
||||||
|
suggestionsItem.clear();
|
||||||
|
showDateFields = true;
|
||||||
|
showArrow = true;
|
||||||
|
});
|
||||||
|
fetchPostsByLocation();
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value.isNotEmpty) {
|
||||||
setState(() {
|
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();
|
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(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
if (showArrow) _buildItemZoneSearchField(),
|
if (showInputSearch) _buildItemZoneSearchField(),
|
||||||
if ((showDateFields) && (showArrow))
|
if ((showDateFields) && (showArrow))
|
||||||
Row(
|
Row(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user