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 '../variable/globals.dart' as globals; // app starting point void main() { initializeDateFormatting("fr_FR", null).then((_) => (const MyApp())); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( home: const ListItemMenu(), debugShowCheckedModeBanner: false, ); } } // homepage class class ListItemMenu extends StatefulWidget { const ListItemMenu({super.key}); @override State createState() => _MyHomePageState(); } // homepage state class _MyHomePageState extends State { // variable to call and store future list of posts Future> postsFuture = getPosts(); List filteredPosts = []; late SearchBar searchBar; String geographicalZone = ''; String query = ''; // function to fetch data from api and return future list of posts static Future> getPosts() async { SharedPreferences prefs = await SharedPreferences.getInstance(); var accessToken = prefs.getString("access_token") ?? ""; final List body = []; if (accessToken.isNotEmpty) { var url = Uri.parse("${globals.api}/events"); 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> searchPosts(String query) async { SharedPreferences prefs = await SharedPreferences.getInstance(); var accessToken = prefs.getString("access_token") ?? ""; final List 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 popCamera() async { await availableCameras().then((value) => Navigator.push(context, MaterialPageRoute(builder: (_) => Camera(camera: value.first)))); } void _filterPosts() async { if (query.isNotEmpty || geographicalZone.isNotEmpty) { List results = await searchPosts(query); setState(() { filteredPosts = _applyFilters(results); }); } else { setState(() { filteredPosts.clear(); }); } } List _applyFilters(List posts) { return posts.where((post) { final matchesQuery = post.name!.toLowerCase().contains(query.toLowerCase()); final matchesZone = geographicalZone.isEmpty || post.place!.toLowerCase().contains(geographicalZone.toLowerCase()); return matchesQuery && matchesZone; }).toList(); } // build function @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( 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: [ // New Search Bar for Geographical Zone Padding( padding: const EdgeInsets.all(8.0), child: TextField( decoration: InputDecoration( labelText: 'Search by geographical zone', border: OutlineInputBorder(), ), onChanged: (value) { setState(() { geographicalZone = value; }); _filterPosts(); // Call the filtering function }, ), ), Expanded( child: FutureBuilder>( future: postsFuture, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const CircularProgressIndicator(); } else if (snapshot.hasData) { final posts = snapshot.data!; final displayedPosts = filteredPosts.isEmpty ? posts : filteredPosts; return buildPosts(displayedPosts); } else { return const Text("No data available"); } }, ), ), ], ), ); } // function to display fetched data on screen Widget buildPosts(List posts) { // ListView Builder to show data in a list return Scaffold( body: ListView.separated( itemCount: posts.length, itemBuilder: (context, index) { final post = posts[index]; final startDate = DateTime.parse(post.startDate!); final date = DateFormat.yMd().format(startDate); final time = DateFormat.Hm().format(startDate); return ListTile( title: Text('${post.name!}'), subtitle: Text('${post.place!}\n${date} ${time}'), onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => ItemMenu(title: post.id!))); }); }, separatorBuilder: (context, index) { return Divider(); }, ), floatingActionButton: FloatingActionButton( onPressed: popCamera, backgroundColor: Colors.blue, tooltip: 'Recherche', child: const Icon(Icons.camera_alt, color: Colors.white), ), ); } } class SearchDelegateExample extends SearchDelegate { @override List 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>( 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) { // Show suggestions as the user types return Container(); // Implement suggestions if needed } Future> searchPosts(String query) async { SharedPreferences prefs = await SharedPreferences.getInstance(); var accessToken = prefs.getString("access_token") ?? ""; final List 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; } }