add pint bar search by item #21

Merged
v4l3n71n merged 1 commits from feature/model-input into main 2024-11-24 20:44:04 +00:00
2 changed files with 70 additions and 260 deletions

View File

@ -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<ListItemMenu> {
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<ListItemMenu> {
return "${year}-${month}-${day}";
}
// Fetching events from API
Future<List<Events>> getAllPosts() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
final List<Events> 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<ListItemMenu> {
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<ListItemMenu> {
return '';
}
// Fetch initial data from API or any other necessary initialization
Future<void> _fetchInitialData() async {
try {
// Optionally, you can fetch posts initially if needed.
List<Events> 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<void> searchSuggestions(String input) async {
await dotenv.load(fileName: ".env"); // Load .env file
@ -319,46 +271,47 @@ class _MyHomePageState extends State<ListItemMenu> {
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&current_datetime=${currentDate.toString()}");
dateParameter = "&current_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<ListItemMenu> {
} 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<ListItemMenu> {
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<ListItemMenu> {
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<ListItemMenu> {
);
}
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<void> popCamera() async {
await availableCameras().then((value) => Navigator.push(context,
MaterialPageRoute(builder: (_) => Camera(camera: value.first))));
@ -549,21 +502,11 @@ class _MyHomePageState extends State<ListItemMenu> {
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(

View File

@ -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<Widget> 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<List<Events>>(
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<List<Events>> 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<Events> 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;
}
}