add searchbar with mapbox and suggesstionbar
This commit is contained in:
@@ -1,17 +1,18 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'ItemMenu.dart';
|
||||
import 'Camera.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:flutter/material.dart';
|
||||
import '../classes/events.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:intl/date_symbol_data_local.dart';
|
||||
import 'package:camera/camera.dart';
|
||||
import 'package:mapbox_gl/mapbox_gl.dart'; // Add this import
|
||||
import '../variable/globals.dart' as globals;
|
||||
|
||||
// app starting point
|
||||
void main() {
|
||||
initializeDateFormatting("fr_FR", null).then((_) => runApp(const MyApp()));
|
||||
}
|
||||
@@ -28,7 +29,6 @@ class MyApp extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// homepage class
|
||||
class ListItemMenu extends StatefulWidget {
|
||||
const ListItemMenu({super.key});
|
||||
|
||||
@@ -36,14 +36,15 @@ class ListItemMenu extends StatefulWidget {
|
||||
State<ListItemMenu> createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
// homepage state
|
||||
class _MyHomePageState extends State<ListItemMenu> {
|
||||
Future<List<Events>> postsFuture = getPosts();
|
||||
List<Events> filteredPosts = [];
|
||||
String geographicalZone = '';
|
||||
String query = '';
|
||||
List<String> suggestions = []; // Store suggestions
|
||||
TextEditingController inputGeo = TextEditingController();
|
||||
|
||||
// function to fetch data from api and return future list of posts
|
||||
// Fetching events from API
|
||||
static Future<List<Events>> getPosts() async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
var accessToken = prefs.getString("access_token") ?? "";
|
||||
@@ -60,45 +61,77 @@ class _MyHomePageState extends State<ListItemMenu> {
|
||||
return body;
|
||||
}
|
||||
|
||||
Future<List<Events>> searchPosts(String query) async {
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
var accessToken = prefs.getString("access_token") ?? "";
|
||||
final List<Events> body = [];
|
||||
if (accessToken.isNotEmpty) {
|
||||
var url = Uri.parse("${globals.api}/events/search?item=$query");
|
||||
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;
|
||||
}
|
||||
Future<void> searchSuggestions(String input) async {
|
||||
await dotenv.load(fileName: ".env"); // Load .env file
|
||||
|
||||
Future<void> popCamera() async {
|
||||
await availableCameras().then((value) => Navigator.push(context,
|
||||
MaterialPageRoute(builder: (_) => Camera(camera: value.first))));
|
||||
final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? '';
|
||||
final url =
|
||||
'https://api.mapbox.com/geocoding/v5/mapbox.places/${input}.json?access_token=${mapboxAccessToken}&proximity=ip'; // Replace with your Mapbox token
|
||||
final response = await http.get(Uri.parse(url));
|
||||
|
||||
if (response.statusCode == 200) {
|
||||
final data = json.decode(response.body);
|
||||
setState(() {
|
||||
suggestions = (data['features'] as List)
|
||||
.map((feature) =>
|
||||
feature['place_name'] as String) // Cast to String explicitly
|
||||
.toList();
|
||||
});
|
||||
} else {
|
||||
throw Exception('Failed to load suggestions');
|
||||
}
|
||||
}
|
||||
|
||||
Padding _buildGeographicalZoneSearchField() {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: TextField(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Search by geographical zone',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
geographicalZone = value; // Update geographical zone
|
||||
});
|
||||
},
|
||||
child: Column(
|
||||
children: [
|
||||
TextField(
|
||||
controller: inputGeo,
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Search by geographical zone',
|
||||
border: OutlineInputBorder(),
|
||||
),
|
||||
onChanged: (value) {
|
||||
setState(() {
|
||||
geographicalZone = value;
|
||||
searchSuggestions(value);
|
||||
});
|
||||
},
|
||||
),
|
||||
if (suggestions.isNotEmpty)
|
||||
Container(
|
||||
height: 200,
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: Colors.blue), // Add a border color
|
||||
borderRadius:
|
||||
BorderRadius.circular(8), // Optional: rounded corners
|
||||
),
|
||||
child: ListView.builder(
|
||||
shrinkWrap:
|
||||
true, // Ensure the list takes only the required space
|
||||
|
||||
itemCount: suggestions.length,
|
||||
itemBuilder: (context, index) {
|
||||
return ListTile(
|
||||
title: Text(suggestions[index]),
|
||||
onTap: () {
|
||||
setState(() {
|
||||
geographicalZone = suggestions[index];
|
||||
inputGeo.text = suggestions[index];
|
||||
suggestions.clear();
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// build function
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -120,7 +153,6 @@ class _MyHomePageState extends State<ListItemMenu> {
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
// New Search Bar for Geographical Zone
|
||||
_buildGeographicalZoneSearchField(),
|
||||
Expanded(
|
||||
child: FutureBuilder<List<Events>>(
|
||||
@@ -144,7 +176,7 @@ class _MyHomePageState extends State<ListItemMenu> {
|
||||
);
|
||||
}
|
||||
|
||||
// function to display fetched data on screen
|
||||
// Function to display fetched data on screen
|
||||
Widget buildPosts(List<Events> posts) {
|
||||
return ListView.separated(
|
||||
itemCount: posts.length,
|
||||
|
Reference in New Issue
Block a user