From 8a3ce376ce282937b67dc0f177ddf43862331ac8 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 27 Jul 2024 18:53:02 +0200 Subject: [PATCH 01/28] add classes --- ...scriptionImage.dart => addEventImage.dart} | 0 covas_mobile/lib/classes/getEventImage.dart | 67 +++++++++++++++++++ .../lib/classes/updateEventImage.dart | 67 +++++++++++++++++++ .../lib/pages/DisplayPictureScreen.dart | 2 +- 4 files changed, 135 insertions(+), 1 deletion(-) rename covas_mobile/lib/classes/{descriptionImage.dart => addEventImage.dart} (100%) create mode 100644 covas_mobile/lib/classes/getEventImage.dart create mode 100644 covas_mobile/lib/classes/updateEventImage.dart diff --git a/covas_mobile/lib/classes/descriptionImage.dart b/covas_mobile/lib/classes/addEventImage.dart similarity index 100% rename from covas_mobile/lib/classes/descriptionImage.dart rename to covas_mobile/lib/classes/addEventImage.dart diff --git a/covas_mobile/lib/classes/getEventImage.dart b/covas_mobile/lib/classes/getEventImage.dart new file mode 100644 index 0000000..6144171 --- /dev/null +++ b/covas_mobile/lib/classes/getEventImage.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'events.dart'; +import '../variable/globals.dart' as globals; +import 'package:http/http.dart' as http; +import 'dart:io'; +import 'dart:convert'; + +import 'package:shared_preferences/shared_preferences.dart'; + +mixin ShowDescImageGet on State { + Future getEvents(var events) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + List send = ["toto"]; + + if (accessToken.isNotEmpty) { + var urlPut = Uri.parse("${globals.api}/events"); + print("start date : ${events["start_date"]}"); + var responsePut = await http.put(urlPut, + headers: { + HttpHeaders.cookieHeader: 'access_token=${accessToken}', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }, + body: jsonEncode({ + 'name': events["name"], + 'place': events["place"], + 'start_date': events['date'], + 'end_date': events['date'], + 'organizers': send, + 'latitude': '0.0', + 'longitude': '0.0', + })); + + print("http put code status : ${responsePut.statusCode}"); + print("http put body : ${responsePut.body}"); + } + } + + void showDescImageUpdateDialog(BuildContext context, var events) { + // Create AlertDialog + String name = events['name']; + AlertDialog dialog = AlertDialog( + title: Text("Voir la description de l'evenement"), + content: Text("${name} a été trouvé. Voulez-vous voir sa description ? "), + actions: [ + TextButton( + child: Text("Annuler"), + onPressed: () { + Navigator.of(context).pop("Yes, Of course!"); // Return value + }), + TextButton( + child: Text("Oui"), + onPressed: () { + getEvents(events); // Return value + }), + ], + ); + + // Call showDialog function to show dialog. + Future futureValue = showDialog( + context: context, + builder: (BuildContext context) { + return dialog; + }); + } +} diff --git a/covas_mobile/lib/classes/updateEventImage.dart b/covas_mobile/lib/classes/updateEventImage.dart new file mode 100644 index 0000000..33804df --- /dev/null +++ b/covas_mobile/lib/classes/updateEventImage.dart @@ -0,0 +1,67 @@ +import 'package:flutter/material.dart'; +import 'events.dart'; +import '../variable/globals.dart' as globals; +import 'package:http/http.dart' as http; +import 'dart:io'; +import 'dart:convert'; + +import 'package:shared_preferences/shared_preferences.dart'; + +mixin ShowDescImageUpdate on State { + Future updateEvents(var events) async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + List send = ["toto"]; + + if (accessToken.isNotEmpty) { + var urlPut = Uri.parse("${globals.api}/events"); + print("start date : ${events["start_date"]}"); + var responsePut = await http.put(urlPut, + headers: { + HttpHeaders.cookieHeader: 'access_token=${accessToken}', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' + }, + body: jsonEncode({ + 'name': events["name"], + 'place': events["place"], + 'start_date': events['date'], + 'end_date': events['date'], + 'organizers': send, + 'latitude': '0.0', + 'longitude': '0.0', + })); + + print("http put code status : ${responsePut.statusCode}"); + print("http put body : ${responsePut.body}"); + } + } + + void showDescImageUpdateDialog(BuildContext context, var events) { + // Create AlertDialog + String name = events['name']; + AlertDialog dialog = AlertDialog( + title: Text("Modifier un evenement"), + content: Text("${name} a été trouvé. Voulez-vous le modifier ou voir ? "), + actions: [ + TextButton( + child: Text("Annuler"), + onPressed: () { + Navigator.of(context).pop("Yes, Of course!"); // Return value + }), + TextButton( + child: Text("Oui"), + onPressed: () { + updateEvents(events); // Return value + }), + ], + ); + + // Call showDialog function to show dialog. + Future futureValue = showDialog( + context: context, + builder: (BuildContext context) { + return dialog; + }); + } +} diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index 64a7e58..9256a28 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; import 'dart:io'; -import '../classes/descriptionImage.dart'; +import '../classes/addEventImage.dart'; import '../classes/alert.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_gemini/flutter_gemini.dart'; From 0ae1311b53aed99a98843f4f5f794cc7485d440a Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 27 Jul 2024 19:40:02 +0200 Subject: [PATCH 02/28] redirect to itemmenu --- covas_mobile/lib/classes/getEventImage.dart | 2 +- covas_mobile/lib/pages/DisplayPictureScreen.dart | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/covas_mobile/lib/classes/getEventImage.dart b/covas_mobile/lib/classes/getEventImage.dart index 6144171..a0db5dc 100644 --- a/covas_mobile/lib/classes/getEventImage.dart +++ b/covas_mobile/lib/classes/getEventImage.dart @@ -37,7 +37,7 @@ mixin ShowDescImageGet on State { } } - void showDescImageUpdateDialog(BuildContext context, var events) { + void showDescImageGetDialog(BuildContext context, var events) { // Create AlertDialog String name = events['name']; AlertDialog dialog = AlertDialog( diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index 9256a28..aef62c5 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -6,6 +6,7 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_gemini/flutter_gemini.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; +import "ItemMenu.dart"; import 'dart:convert'; @@ -85,6 +86,11 @@ class DisplayPictureScreenState extends State print("reponse http : ${events.length}"); if (events.length == 0) { showDescImageAddDialog(context, jsonData); + } else { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => ItemMenu(title: events[0]["id"]))); } } } else { From ceacbc72eeddf765916b9873aee55703d4af1552 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 28 Jul 2024 21:54:37 +0200 Subject: [PATCH 03/28] add classes update event by image wip --- .../lib/classes/updateEventImage.dart | 67 ----- covas_mobile/lib/pages/UpdateEventImage.dart | 242 ++++++++++++++++++ 2 files changed, 242 insertions(+), 67 deletions(-) delete mode 100644 covas_mobile/lib/classes/updateEventImage.dart create mode 100644 covas_mobile/lib/pages/UpdateEventImage.dart diff --git a/covas_mobile/lib/classes/updateEventImage.dart b/covas_mobile/lib/classes/updateEventImage.dart deleted file mode 100644 index 33804df..0000000 --- a/covas_mobile/lib/classes/updateEventImage.dart +++ /dev/null @@ -1,67 +0,0 @@ -import 'package:flutter/material.dart'; -import 'events.dart'; -import '../variable/globals.dart' as globals; -import 'package:http/http.dart' as http; -import 'dart:io'; -import 'dart:convert'; - -import 'package:shared_preferences/shared_preferences.dart'; - -mixin ShowDescImageUpdate on State { - Future updateEvents(var events) async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - var accessToken = prefs.getString("access_token") ?? ""; - List send = ["toto"]; - - if (accessToken.isNotEmpty) { - var urlPut = Uri.parse("${globals.api}/events"); - print("start date : ${events["start_date"]}"); - var responsePut = await http.put(urlPut, - headers: { - HttpHeaders.cookieHeader: 'access_token=${accessToken}', - HttpHeaders.acceptHeader: 'application/json, text/plain, */*', - HttpHeaders.contentTypeHeader: 'application/json' - }, - body: jsonEncode({ - 'name': events["name"], - 'place': events["place"], - 'start_date': events['date'], - 'end_date': events['date'], - 'organizers': send, - 'latitude': '0.0', - 'longitude': '0.0', - })); - - print("http put code status : ${responsePut.statusCode}"); - print("http put body : ${responsePut.body}"); - } - } - - void showDescImageUpdateDialog(BuildContext context, var events) { - // Create AlertDialog - String name = events['name']; - AlertDialog dialog = AlertDialog( - title: Text("Modifier un evenement"), - content: Text("${name} a été trouvé. Voulez-vous le modifier ou voir ? "), - actions: [ - TextButton( - child: Text("Annuler"), - onPressed: () { - Navigator.of(context).pop("Yes, Of course!"); // Return value - }), - TextButton( - child: Text("Oui"), - onPressed: () { - updateEvents(events); // Return value - }), - ], - ); - - // Call showDialog function to show dialog. - Future futureValue = showDialog( - context: context, - builder: (BuildContext context) { - return dialog; - }); - } -} diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart new file mode 100644 index 0000000..c9ecbdd --- /dev/null +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -0,0 +1,242 @@ +import 'package:flutter/material.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:http/http.dart' as http; + +import 'dart:convert'; +import 'dart:io'; + +//import 'MyHomePage.dart'; +import 'ListItemMenu.dart'; + +import '../classes/alert.dart'; + +import '../variable/globals.dart' as globals; + +void main() { + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + debugShowCheckedModeBanner: false, + home: UpdateeventImage(), + ); + } +} + +class UpdateeventImage extends StatefulWidget { + @override + _UpdateeventImageState createState() => _UpdateeventImageState(); +} + +class _UpdateeventImageState extends State + with ShowErrorDialog { + TextEditingController inputPseudo = TextEditingController(); + TextEditingController inputPassword = TextEditingController(); + Future _login(BuildContext context) async { + var url = Uri.parse("${globals.api}/token"); + var pseudo = inputPseudo.text; + var password = inputPassword.text; + print("get login"); + print(pseudo.isNotEmpty); + print(password.isNotEmpty); + if ((pseudo.isNotEmpty) && (password.isNotEmpty)) { + print(url); + try { + //String credentials = "${pseudo}:${password}"; + //Codec stringToBase64 = utf8.fuse(base64); + //String encoded = stringToBase64.encode(credentials); + var response = await http.post(url, + // headers: { + // HttpHeaders.authorizationHeader: 'Basic $encoded', + //} + headers: { + 'accept': 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + }, + body: { + "username": "${pseudo}", + "password": "${password}" + }); + print(response.statusCode); + if ((response.statusCode == 200) || (response.statusCode == 201)) { + SharedPreferences prefs = await SharedPreferences.getInstance(); + + var cookies = response.headers["set-cookie"].toString().split(";"); + for (var cookie in cookies) { + var cookiesMany = cookie.split(","); + for (var cookie2 in cookiesMany) { + switch (cookie2.split("=")[0]) { + case "access_token": + { + prefs.setString("access_token", cookie2.split("=")[1]); + } + break; + default: + break; + } + } + } + Navigator.push( + context, MaterialPageRoute(builder: (_) => ListItemMenu())); + } else { + var text = ""; + switch (response.statusCode) { + case 400: + { + text = "Requête mal construite"; + } + break; + case 406: + { + text = "Mot de passe incorrect"; + } + break; + case 404: + { + text = "Utilisateur inconnu"; + } + break; + case 403: + { + text = "Utilisateur desactive"; + } + break; + case 410: + { + text = "Token invalide"; + } + break; + case 500: + { + text = "Probleme interne du serveur"; + } + break; + default: + { + text = "Probleme d'authentification inconnu"; + } + break; + } + showErrorDialog(context, text); + } + } catch (e) { + showErrorDialog(context, "${e}"); + } + } else { + showErrorDialog(context, "Champ vide"); + } + } + + void start() async { + SharedPreferences prefs = await SharedPreferences.getInstance(); + var access_token = prefs.getString("access_token") ?? ""; + print("Get access token"); + + if (access_token.isNotEmpty) { + print("Appel HTTP"); + var urlToken = Uri.parse("${globals.api}/token"); + + var responseToken = await http.get(urlToken, + headers: {HttpHeaders.cookieHeader: 'access_token: ${access_token}'}); + print(responseToken.statusCode); + if (responseToken.statusCode == 200) { + print("route to item list"); + Navigator.push( + context, MaterialPageRoute(builder: (_) => ListItemMenu())); + } else { + prefs.remove("access_token"); + } + } + } + + @override + void initState() { + start(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.white, + appBar: AppBar( + title: Text("Login Page"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + ), + body: SingleChildScrollView( + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(top: 60.0), + child: Center( + child: Container( + width: 200, + height: 150, + decoration: BoxDecoration( + color: Colors.red, + borderRadius: BorderRadius.circular(50.0)), + child: Image.asset('./images/flutter.png')), + ), + ), + Padding( + //padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0), + padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputPseudo, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Pseudo', + hintText: 'Enter pseudo existent'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputPassword, + obscureText: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Password', + hintText: 'Enter secure password'), + ), + ), + TextButton( + onPressed: () { + //TODO FORGOT PASSWORD SCREEN GOES HERE + }, + child: Text( + 'Forgot Password', + style: TextStyle(color: Colors.blue, fontSize: 15), + ), + ), + Container( + height: 50, + width: 250, + decoration: BoxDecoration( + color: Colors.blue, borderRadius: BorderRadius.circular(20)), + child: TextButton( + onPressed: () { + _login(context); + }, + child: Text( + 'Login', + style: TextStyle(color: Colors.white, fontSize: 25), + ), + ), + ), + SizedBox( + height: 130, + ), + Text('New User? Create Account') + ], + ), + ), + ); + } +} From b4b09db5efc9a7068e7093b2cc80a9fc80a01b4e Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Tue, 30 Jul 2024 23:19:37 +0200 Subject: [PATCH 04/28] =?UTF-8?q?texte=20par=20d=C3=A9faut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/pages/DisplayPictureScreen.dart | 6 +- covas_mobile/lib/pages/UpdateEventImage.dart | 68 +++++++------------ 2 files changed, 28 insertions(+), 46 deletions(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index aef62c5..9546380 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -7,6 +7,7 @@ import 'package:flutter_gemini/flutter_gemini.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import "ItemMenu.dart"; +import 'UpdateEventImage.dart'; import 'dart:convert'; @@ -85,7 +86,10 @@ class DisplayPictureScreenState extends State var events = jsonDecode(utf8.decode(responseGet.bodyBytes)); print("reponse http : ${events.length}"); if (events.length == 0) { - showDescImageAddDialog(context, jsonData); + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => UpdateeventImage(events: jsonData))); } else { Navigator.push( context, diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index c9ecbdd..ca699c5 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -17,28 +17,34 @@ void main() { } class MyApp extends StatelessWidget { + Map events = {}; @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, - home: UpdateeventImage(), + home: UpdateeventImage(events: events), ); } } class UpdateeventImage extends StatefulWidget { + const UpdateeventImage({Key? key, required this.events}) : super(key: key); + final Map events; + @override _UpdateeventImageState createState() => _UpdateeventImageState(); } class _UpdateeventImageState extends State with ShowErrorDialog { - TextEditingController inputPseudo = TextEditingController(); - TextEditingController inputPassword = TextEditingController(); + TextEditingController inputName = TextEditingController(); + TextEditingController inputPlace = TextEditingController(); + TextEditingController inputDate = TextEditingController(); + Future _login(BuildContext context) async { var url = Uri.parse("${globals.api}/token"); - var pseudo = inputPseudo.text; - var password = inputPassword.text; + var pseudo = inputName.text; + var password = inputPlace.text; print("get login"); print(pseudo.isNotEmpty); print(password.isNotEmpty); @@ -131,25 +137,8 @@ class _UpdateeventImageState extends State } void start() async { - SharedPreferences prefs = await SharedPreferences.getInstance(); - var access_token = prefs.getString("access_token") ?? ""; - print("Get access token"); - - if (access_token.isNotEmpty) { - print("Appel HTTP"); - var urlToken = Uri.parse("${globals.api}/token"); - - var responseToken = await http.get(urlToken, - headers: {HttpHeaders.cookieHeader: 'access_token: ${access_token}'}); - print(responseToken.statusCode); - if (responseToken.statusCode == 200) { - print("route to item list"); - Navigator.push( - context, MaterialPageRoute(builder: (_) => ListItemMenu())); - } else { - prefs.remove("access_token"); - } - } + inputName.text = widget.events["name"]; + inputPlace.text = widget.events["place"]; } @override @@ -186,11 +175,11 @@ class _UpdateeventImageState extends State //padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0), padding: EdgeInsets.symmetric(horizontal: 15), child: TextField( - controller: inputPseudo, + controller: inputName, decoration: InputDecoration( border: OutlineInputBorder(), - labelText: 'Pseudo', - hintText: 'Enter pseudo existent'), + labelText: 'Nom', + hintText: 'Modifier le nom de l\'évènement'), ), ), Padding( @@ -198,22 +187,15 @@ class _UpdateeventImageState extends State left: 15.0, right: 15.0, top: 15, bottom: 0), //padding: EdgeInsets.symmetric(horizontal: 15), child: TextField( - controller: inputPassword, - obscureText: true, + controller: inputPlace, decoration: InputDecoration( border: OutlineInputBorder(), - labelText: 'Password', - hintText: 'Enter secure password'), + labelText: 'Lieu', + hintText: 'Entrer le lieu'), ), ), - TextButton( - onPressed: () { - //TODO FORGOT PASSWORD SCREEN GOES HERE - }, - child: Text( - 'Forgot Password', - style: TextStyle(color: Colors.blue, fontSize: 15), - ), + SizedBox( + height: 30, ), Container( height: 50, @@ -225,15 +207,11 @@ class _UpdateeventImageState extends State _login(context); }, child: Text( - 'Login', + 'Ajouter', style: TextStyle(color: Colors.white, fontSize: 25), ), ), - ), - SizedBox( - height: 130, - ), - Text('New User? Create Account') + ) ], ), ), From cadd3ef2bf0581c71facc3027e87d04485100bfa Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Tue, 30 Jul 2024 23:37:21 +0200 Subject: [PATCH 05/28] add http put event --- covas_mobile/lib/classes/eventAdded.dart | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 covas_mobile/lib/classes/eventAdded.dart diff --git a/covas_mobile/lib/classes/eventAdded.dart b/covas_mobile/lib/classes/eventAdded.dart new file mode 100644 index 0000000..68a09fa --- /dev/null +++ b/covas_mobile/lib/classes/eventAdded.dart @@ -0,0 +1,31 @@ +import 'package:flutter/material.dart'; + +import '../main.dart'; + +mixin ShowEventDialog on State { + void showEventDialog(BuildContext context, String text) { + // Create AlertDialog + AlertDialog dialog = AlertDialog( + title: Text("Evenement ajoute"), + content: Text(text), + actions: [ + ElevatedButton( + child: Text("OK"), + style: ElevatedButton.styleFrom( + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 20), + textStyle: + TextStyle(fontSize: 15, fontWeight: FontWeight.normal)), + onPressed: () { + Navigator.of(context).pop("Yes, Of course!"); // Return value + }), + ], + ); + + // Call showDialog function to show dialog. + Future futureValue = showDialog( + context: context, + builder: (BuildContext context) { + return dialog; + }); + } +} From c3937a3e305dd5342363fd55784eb247168703a8 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Tue, 30 Jul 2024 23:46:15 +0200 Subject: [PATCH 06/28] redirect to item list menu --- covas_mobile/lib/classes/eventAdded.dart | 7 +- covas_mobile/lib/pages/UpdateEventImage.dart | 71 ++++++++------------ 2 files changed, 34 insertions(+), 44 deletions(-) diff --git a/covas_mobile/lib/classes/eventAdded.dart b/covas_mobile/lib/classes/eventAdded.dart index 68a09fa..d2c75b7 100644 --- a/covas_mobile/lib/classes/eventAdded.dart +++ b/covas_mobile/lib/classes/eventAdded.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../main.dart'; +import '../pages/ListItemMenu.dart'; mixin ShowEventDialog on State { void showEventDialog(BuildContext context, String text) { @@ -16,7 +16,10 @@ mixin ShowEventDialog on State { textStyle: TextStyle(fontSize: 15, fontWeight: FontWeight.normal)), onPressed: () { - Navigator.of(context).pop("Yes, Of course!"); // Return value + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => ListItemMenu())); // Return value }), ], ); diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index ca699c5..af00c93 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -9,6 +9,7 @@ import 'dart:io'; import 'ListItemMenu.dart'; import '../classes/alert.dart'; +import '../classes/eventAdded.dart'; import '../variable/globals.dart' as globals; @@ -36,60 +37,46 @@ class UpdateeventImage extends StatefulWidget { } class _UpdateeventImageState extends State - with ShowErrorDialog { + with ShowErrorDialog, ShowEventDialog { TextEditingController inputName = TextEditingController(); TextEditingController inputPlace = TextEditingController(); TextEditingController inputDate = TextEditingController(); - Future _login(BuildContext context) async { + Future _updateEvent(BuildContext context) async { var url = Uri.parse("${globals.api}/token"); - var pseudo = inputName.text; - var password = inputPlace.text; - print("get login"); - print(pseudo.isNotEmpty); - print(password.isNotEmpty); - if ((pseudo.isNotEmpty) && (password.isNotEmpty)) { - print(url); + var name = inputName.text; + var place = inputPlace.text; + SharedPreferences prefs = await SharedPreferences.getInstance(); + var accessToken = prefs.getString("access_token") ?? ""; + List send = ["toto"]; + if (accessToken.isNotEmpty) { try { //String credentials = "${pseudo}:${password}"; //Codec stringToBase64 = utf8.fuse(base64); //String encoded = stringToBase64.encode(credentials); - var response = await http.post(url, - // headers: { - // HttpHeaders.authorizationHeader: 'Basic $encoded', - //} + var urlPut = Uri.parse("${globals.api}/events"); + var responsePut = await http.put(urlPut, headers: { - 'accept': 'application/json', - 'Content-Type': 'application/x-www-form-urlencoded', + HttpHeaders.cookieHeader: 'access_token=${accessToken}', + HttpHeaders.acceptHeader: 'application/json, text/plain, */*', + HttpHeaders.contentTypeHeader: 'application/json' }, - body: { - "username": "${pseudo}", - "password": "${password}" - }); - print(response.statusCode); - if ((response.statusCode == 200) || (response.statusCode == 201)) { - SharedPreferences prefs = await SharedPreferences.getInstance(); - - var cookies = response.headers["set-cookie"].toString().split(";"); - for (var cookie in cookies) { - var cookiesMany = cookie.split(","); - for (var cookie2 in cookiesMany) { - switch (cookie2.split("=")[0]) { - case "access_token": - { - prefs.setString("access_token", cookie2.split("=")[1]); - } - break; - default: - break; - } - } - } - Navigator.push( - context, MaterialPageRoute(builder: (_) => ListItemMenu())); + body: jsonEncode({ + 'name': name, + 'place': place, + 'start_date': widget.events["date"], + 'end_date': widget.events['date'], + 'organizers': send, + 'latitude': '0.0', + 'longitude': '0.0', + })); + print(responsePut.statusCode); + if ((responsePut.statusCode == 200) || + (responsePut.statusCode == 201)) { + showEventDialog(context, "Evenement ${name} ajoute"); } else { var text = ""; - switch (response.statusCode) { + switch (responsePut.statusCode) { case 400: { text = "Requête mal construite"; @@ -204,7 +191,7 @@ class _UpdateeventImageState extends State color: Colors.blue, borderRadius: BorderRadius.circular(20)), child: TextButton( onPressed: () { - _login(context); + _updateEvent(context); }, child: Text( 'Ajouter', From e12962089c48b216f4d4798b993e8c14d26fa7b7 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Thu, 8 Aug 2024 23:39:56 +0200 Subject: [PATCH 07/28] fix back item --- covas_mobile/lib/pages/ItemMenu.dart | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/covas_mobile/lib/pages/ItemMenu.dart b/covas_mobile/lib/pages/ItemMenu.dart index 63f83b7..e42162e 100644 --- a/covas_mobile/lib/pages/ItemMenu.dart +++ b/covas_mobile/lib/pages/ItemMenu.dart @@ -14,6 +14,8 @@ import '../variable/globals.dart' as globals; import '../classes/events.dart'; +import 'ListItemMenu.dart'; + void main() { initializeDateFormatting("fr_FR", null).then((_) => (const MyApp())); } @@ -181,12 +183,18 @@ class _ItemMenuState extends State with ShowErrorDialog { // than having to individually change instances of widgets. return Scaffold( appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. - title: Text("${eventName}"), - backgroundColor: Colors.blue, - foregroundColor: Colors.white, - ), + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: Text("${eventName}"), + backgroundColor: Colors.blue, + foregroundColor: Colors.white, + leading: IconButton( + icon: Icon(Icons.arrow_back), + onPressed: () { + Navigator.push( + context, MaterialPageRoute(builder: (_) => ListItemMenu())); + }, + )), body: SingleChildScrollView( child: Column( children: [ From e0bdc7a6338a9b1bd2739fc1e81616d5fb59376d Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Thu, 8 Aug 2024 23:57:59 +0200 Subject: [PATCH 08/28] add install date format --- covas_mobile/pubspec.lock | 8 ++++++++ covas_mobile/pubspec.yaml | 1 + 2 files changed, 9 insertions(+) diff --git a/covas_mobile/pubspec.lock b/covas_mobile/pubspec.lock index db6c022..91a3f37 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile/pubspec.lock @@ -97,6 +97,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.8" + date_format_field: + dependency: "direct main" + description: + name: date_format_field + sha256: d07a428bd253454ff3123f2e57511cf6ec101d1135af3b79cebb40e1bee8bab8 + url: "https://pub.dev" + source: hosted + version: "0.1.0" dio: dependency: transitive description: diff --git a/covas_mobile/pubspec.yaml b/covas_mobile/pubspec.yaml index d0d79eb..1bc13d8 100644 --- a/covas_mobile/pubspec.yaml +++ b/covas_mobile/pubspec.yaml @@ -44,6 +44,7 @@ dependencies: flutter_gemini: ^2.0.4 flutter_dotenv: ^5.1.0 image_picker: ^1.1.2 + date_format_field: ^0.1.0 dev_dependencies: flutter_test: From 30d485d0e78d3f7537b1ba612ed94133cd6aa207 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 14 Aug 2024 22:11:38 +0200 Subject: [PATCH 09/28] loading circular --- .../lib/pages/DisplayPictureScreen.dart | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index 9546380..b69e025 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -54,14 +54,30 @@ class DisplayPictureScreen extends StatefulWidget { // A widget that displays the picture taken by the user. class DisplayPictureScreenState extends State - with ShowDescImageAdd, ShowErrorDialog { + with ShowDescImageAdd, ShowErrorDialog, TickerProviderStateMixin { + late AnimationController controller; @override void initState() { + controller = AnimationController( + /// [AnimationController]s can be created with `vsync: this` because of + /// [TickerProviderStateMixin]. + vsync: this, + duration: const Duration(seconds: 5), + )..addListener(() { + setState(() {}); + }); + controller.repeat(reverse: false); super.initState(); _getEventInfosFromImage(); } + @override + void dispose() { + controller.dispose(); + super.dispose(); + } + Future displayError(String e) async { print("problem gemini : ${e}"); showErrorDialog(context, @@ -128,10 +144,19 @@ class DisplayPictureScreenState extends State appBar: AppBar(title: const Text('Display the Picture')), // The image is stored as a file on the device. Use the `Image.file` // constructor with the given path to display the image. - body: SingleChildScrollView( - child: Column(children: [ - Image.file(File(widget.imagePath)), - Text("Analyse en cours...") - ]))); + body: Padding( + padding: const EdgeInsets.all(20.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text( + 'Analyse de l\'image en cours', + style: Theme.of(context).textTheme.titleLarge, + ), + CircularProgressIndicator( + value: controller.value, + semanticsLabel: 'Loading progress', + ), + ]))); } } From 00bc3bb0aa63bb72e3c71b3982f6a6c29b866317 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 14 Aug 2024 22:55:41 +0200 Subject: [PATCH 10/28] add datepicker --- covas_mobile/lib/pages/UpdateEventImage.dart | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index af00c93..04ca787 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; +import 'package:flutter/widgets.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; +import 'package:intl/intl.dart'; import 'dart:convert'; import 'dart:io'; @@ -41,6 +43,17 @@ class _UpdateeventImageState extends State TextEditingController inputName = TextEditingController(); TextEditingController inputPlace = TextEditingController(); TextEditingController inputDate = TextEditingController(); + TextEditingController startDatepicker = TextEditingController(); + + onTapFunctionDatePicker({required BuildContext context}) async { + DateTime? pickedDate = await showDatePicker( + context: context, + firstDate: DateTime.now(), + initialDate: DateTime.now(), + lastDate: DateTime(2026)); + if (pickedDate == null) return; + startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } Future _updateEvent(BuildContext context) async { var url = Uri.parse("${globals.api}/token"); @@ -181,6 +194,19 @@ class _UpdateeventImageState extends State hintText: 'Entrer le lieu'), ), ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: startDatepicker, + readOnly: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Date de debut de l\'évènement', + hintText: 'Cliquez ici pour selectionner une date'), + onTap: () => onTapFunctionDatePicker(context: context)), + ), SizedBox( height: 30, ), From 2d8737743f2ab9e5cf16ed6fa98ee2dd4dbde496 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 14 Aug 2024 23:15:30 +0200 Subject: [PATCH 11/28] add timepicker --- covas_mobile/lib/pages/UpdateEventImage.dart | 21 ++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 04ca787..3f242a5 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -44,6 +44,7 @@ class _UpdateeventImageState extends State TextEditingController inputPlace = TextEditingController(); TextEditingController inputDate = TextEditingController(); TextEditingController startDatepicker = TextEditingController(); + TextEditingController startTimepicker = TextEditingController(); onTapFunctionDatePicker({required BuildContext context}) async { DateTime? pickedDate = await showDatePicker( @@ -55,6 +56,13 @@ class _UpdateeventImageState extends State startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); } + onTapFunctionTimePicker({required BuildContext context}) async { + TimeOfDay? pickedDate = + await showTimePicker(context: context, initialTime: TimeOfDay.now()); + if (pickedDate == null) return; + startTimepicker.text = pickedDate.format(context); + } + Future _updateEvent(BuildContext context) async { var url = Uri.parse("${globals.api}/token"); var name = inputName.text; @@ -207,6 +215,19 @@ class _UpdateeventImageState extends State hintText: 'Cliquez ici pour selectionner une date'), onTap: () => onTapFunctionDatePicker(context: context)), ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: startTimepicker, + readOnly: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Heure de debut de l\'évènement', + hintText: 'Cliquez ici pour selectionner une heure'), + onTap: () => onTapFunctionTimePicker(context: context)), + ), SizedBox( height: 30, ), From b2b142ae71b799e1f589c02ce6fd59a587a20d04 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 14 Aug 2024 23:20:31 +0200 Subject: [PATCH 12/28] add end input date and time --- covas_mobile/lib/pages/UpdateEventImage.dart | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 3f242a5..8868464 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -45,6 +45,8 @@ class _UpdateeventImageState extends State TextEditingController inputDate = TextEditingController(); TextEditingController startDatepicker = TextEditingController(); TextEditingController startTimepicker = TextEditingController(); + TextEditingController endDatepicker = TextEditingController(); + TextEditingController endTimepicker = TextEditingController(); onTapFunctionDatePicker({required BuildContext context}) async { DateTime? pickedDate = await showDatePicker( @@ -228,6 +230,32 @@ class _UpdateeventImageState extends State hintText: 'Cliquez ici pour selectionner une heure'), onTap: () => onTapFunctionTimePicker(context: context)), ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: endDatepicker, + readOnly: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Date de fin de l\'évènement', + hintText: 'Cliquez ici pour selectionner une date'), + onTap: () => onTapFunctionDatePicker(context: context)), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: endTimepicker, + readOnly: true, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Heure de fin de l\'évènement', + hintText: 'Cliquez ici pour selectionner une heure'), + onTap: () => onTapFunctionTimePicker(context: context)), + ), SizedBox( height: 30, ), From 27cdc85b5d31e2a6ed5cece20a01a47dd985b86d Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 14 Aug 2024 23:34:42 +0200 Subject: [PATCH 13/28] add position parameter --- covas_mobile/lib/pages/UpdateEventImage.dart | 32 +++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 8868464..af9b8de 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -48,21 +48,33 @@ class _UpdateeventImageState extends State TextEditingController endDatepicker = TextEditingController(); TextEditingController endTimepicker = TextEditingController(); - onTapFunctionDatePicker({required BuildContext context}) async { + onTapFunctionDatePicker( + {required BuildContext context, required String position}) async { DateTime? pickedDate = await showDatePicker( context: context, firstDate: DateTime.now(), initialDate: DateTime.now(), lastDate: DateTime(2026)); if (pickedDate == null) return; - startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + if (position == "start") { + startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } + if (position == "end") { + endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + } } - onTapFunctionTimePicker({required BuildContext context}) async { + onTapFunctionTimePicker( + {required BuildContext context, required String position}) async { TimeOfDay? pickedDate = await showTimePicker(context: context, initialTime: TimeOfDay.now()); if (pickedDate == null) return; - startTimepicker.text = pickedDate.format(context); + if (position == "start") { + startTimepicker.text = pickedDate.format(context); + } + if (position == "end") { + endTimepicker.text = pickedDate.format(context); + } } Future _updateEvent(BuildContext context) async { @@ -215,7 +227,8 @@ class _UpdateeventImageState extends State border: OutlineInputBorder(), labelText: 'Date de debut de l\'évènement', hintText: 'Cliquez ici pour selectionner une date'), - onTap: () => onTapFunctionDatePicker(context: context)), + onTap: () => onTapFunctionDatePicker( + context: context, position: "start")), ), Padding( padding: const EdgeInsets.only( @@ -228,7 +241,8 @@ class _UpdateeventImageState extends State border: OutlineInputBorder(), labelText: 'Heure de debut de l\'évènement', hintText: 'Cliquez ici pour selectionner une heure'), - onTap: () => onTapFunctionTimePicker(context: context)), + onTap: () => onTapFunctionTimePicker( + context: context, position: "start")), ), Padding( padding: const EdgeInsets.only( @@ -241,7 +255,8 @@ class _UpdateeventImageState extends State border: OutlineInputBorder(), labelText: 'Date de fin de l\'évènement', hintText: 'Cliquez ici pour selectionner une date'), - onTap: () => onTapFunctionDatePicker(context: context)), + onTap: () => onTapFunctionDatePicker( + context: context, position: "end")), ), Padding( padding: const EdgeInsets.only( @@ -254,7 +269,8 @@ class _UpdateeventImageState extends State border: OutlineInputBorder(), labelText: 'Heure de fin de l\'évènement', hintText: 'Cliquez ici pour selectionner une heure'), - onTap: () => onTapFunctionTimePicker(context: context)), + onTap: () => onTapFunctionTimePicker( + context: context, position: "end")), ), SizedBox( height: 30, From 6a7b147286509ba8417dedf94bd41654433e1b8e Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 14 Aug 2024 23:52:06 +0200 Subject: [PATCH 14/28] format timestamp --- covas_mobile/lib/pages/DisplayPictureScreen.dart | 2 +- covas_mobile/lib/pages/UpdateEventImage.dart | 12 +++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index b69e025..a62daf8 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -131,7 +131,7 @@ class DisplayPictureScreenState extends State gemini .textAndImage( text: - "Peux-tu donner le nom, la date et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place et date avec le format suivant YYYY-MM-ddTTHH:mm, et sans la présence de json dans la chaîne de caractère", + "Peux-tu donner le nom, la date et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place et date avec le format timestamp, et sans la présence de json dans la chaîne de caractère", images: [file.readAsBytesSync()], modelName: "models/gemini-1.5-flash-latest") .then((value) => searchEvents(value?.content?.parts?.last.text ?? '')) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index af9b8de..9a48c42 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -52,9 +52,9 @@ class _UpdateeventImageState extends State {required BuildContext context, required String position}) async { DateTime? pickedDate = await showDatePicker( context: context, - firstDate: DateTime.now(), - initialDate: DateTime.now(), - lastDate: DateTime(2026)); + firstDate: DateTime.fromMicrosecondsSinceEpoch(widget.events["date"]), + initialDate: DateTime.fromMicrosecondsSinceEpoch(widget.events["date"]), + lastDate: DateTime(2104)); if (pickedDate == null) return; if (position == "start") { startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); @@ -66,8 +66,10 @@ class _UpdateeventImageState extends State onTapFunctionTimePicker( {required BuildContext context, required String position}) async { - TimeOfDay? pickedDate = - await showTimePicker(context: context, initialTime: TimeOfDay.now()); + TimeOfDay? pickedDate = await showTimePicker( + context: context, + initialTime: TimeOfDay.fromDateTime( + DateTime.fromMicrosecondsSinceEpoch(widget.events["date"]))); if (pickedDate == null) return; if (position == "start") { startTimepicker.text = pickedDate.format(context); From 5950050c7839960e518bd0c63ff746580e671c00 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 14 Aug 2024 23:58:28 +0200 Subject: [PATCH 15/28] fix timestamp and json in caracter --- covas_mobile/lib/pages/DisplayPictureScreen.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index a62daf8..1dccbb9 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -131,7 +131,7 @@ class DisplayPictureScreenState extends State gemini .textAndImage( text: - "Peux-tu donner le nom, la date et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place et date avec le format timestamp, et sans la présence de json dans la chaîne de caractère", + "Peux-tu donner le nom, la date et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place et date en timestamp, et sans la présence du mot json dans la chaîne de caractère", images: [file.readAsBytesSync()], modelName: "models/gemini-1.5-flash-latest") .then((value) => searchEvents(value?.content?.parts?.last.text ?? '')) From da57be9608ee4314f7af3d0b0efd1b22b3b9b1c1 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sat, 17 Aug 2024 00:52:33 +0200 Subject: [PATCH 16/28] default value --- covas_mobile/lib/pages/UpdateEventImage.dart | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 9a48c42..1ba6d47 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -163,6 +163,13 @@ class _UpdateeventImageState extends State void start() async { inputName.text = widget.events["name"]; inputPlace.text = widget.events["place"]; + DateTime pickedDate = + DateTime.fromMicrosecondsSinceEpoch(widget.events["date"]); + startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); + TimeOfDay pickedTime = TimeOfDay.fromDateTime(pickedDate); + startTimepicker.text = pickedTime.format(context); + endTimepicker.text = pickedTime.format(context); } @override From 218504c9df56f97e5ed79b78df61c42007c540c5 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 18 Aug 2024 19:14:01 +0200 Subject: [PATCH 17/28] fix ai date --- .../lib/pages/DisplayPictureScreen.dart | 4 +- covas_mobile/lib/pages/UpdateEventImage.dart | 14 +-- covas_mobile/pubspec.lock | 96 +++++++++---------- 3 files changed, 54 insertions(+), 60 deletions(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index 1dccbb9..8d9780c 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -131,9 +131,9 @@ class DisplayPictureScreenState extends State gemini .textAndImage( text: - "Peux-tu donner le nom, la date et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place et date en timestamp, et sans la présence du mot json dans la chaîne de caractère", + "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place, date sous le format en DD:MM:yyyy HH:SS et le convertir en timestamp , et sans la présence du mot json dans la chaîne de caractère", images: [file.readAsBytesSync()], - modelName: "models/gemini-1.5-flash-latest") + modelName: "models/gemini-1.5-pro-latest") .then((value) => searchEvents(value?.content?.parts?.last.text ?? '')) .catchError((e) => displayError); } diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 1ba6d47..a13a56c 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -52,8 +52,10 @@ class _UpdateeventImageState extends State {required BuildContext context, required String position}) async { DateTime? pickedDate = await showDatePicker( context: context, - firstDate: DateTime.fromMicrosecondsSinceEpoch(widget.events["date"]), - initialDate: DateTime.fromMicrosecondsSinceEpoch(widget.events["date"]), + firstDate: + DateTime.fromMicrosecondsSinceEpoch(widget.events["timestamp"]), + initialDate: + DateTime.fromMicrosecondsSinceEpoch(widget.events["timestamp"]), lastDate: DateTime(2104)); if (pickedDate == null) return; if (position == "start") { @@ -163,13 +165,13 @@ class _UpdateeventImageState extends State void start() async { inputName.text = widget.events["name"]; inputPlace.text = widget.events["place"]; + print(widget.events["timestamp"]); DateTime pickedDate = - DateTime.fromMicrosecondsSinceEpoch(widget.events["date"]); + DateTime.fromMicrosecondsSinceEpoch(widget.events["timestamp"]); startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); - TimeOfDay pickedTime = TimeOfDay.fromDateTime(pickedDate); - startTimepicker.text = pickedTime.format(context); - endTimepicker.text = pickedTime.format(context); + startTimepicker.text = DateFormat("HH-mm").format(pickedDate); + endTimepicker.text = DateFormat("HH-mm").format(pickedDate); } @override diff --git a/covas_mobile/pubspec.lock b/covas_mobile/pubspec.lock index 91a3f37..0527810 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile/pubspec.lock @@ -21,26 +21,26 @@ packages: dependency: "direct main" description: name: camera - sha256: "2170a943dcb67be2af2c6bcda8775e74b41d4c02d6a4eb10bdc832ee185c4eea" + sha256: "26ff41045772153f222ffffecba711a206f670f5834d40ebf5eed3811692f167" url: "https://pub.dev" source: hosted - version: "0.11.0+1" + version: "0.11.0+2" camera_android_camerax: dependency: transitive description: name: camera_android_camerax - sha256: "7c03940cb8c92eb5b184952674a07cc4a73c6ba2b3568aad70255ad4cb913660" + sha256: "8bd9cab67551642eb33ceb33ece7acc0890014fc90ddfae637c7e2b683657e65" url: "https://pub.dev" source: hosted - version: "0.6.7+1" + version: "0.6.7+2" camera_avfoundation: dependency: transitive description: name: camera_avfoundation - sha256: b5093a82537b64bb88d4244f8e00b5ba69e822a5994f47b31d11400e1db975e5 + sha256: "7c28969a975a7eb2349bc2cb2dfe3ad218a33dba9968ecfb181ce08c87486655" url: "https://pub.dev" source: hosted - version: "0.9.17+1" + version: "0.9.17+3" camera_platform_interface: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: "direct main" description: name: camera_web - sha256: b9235ec0a2ce949daec546f1f3d86f05c3921ed31c7d9ab6b7c03214d152fc2d + sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f" url: "https://pub.dev" source: hosted - version: "0.3.4" + version: "0.3.5" characters: dependency: transitive description: @@ -85,10 +85,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "55d7b444feb71301ef6b8838dbc1ae02e63dd48c8773f3810ff53bb1e2945b32" + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" url: "https://pub.dev" source: hosted - version: "0.3.4+1" + version: "0.3.4+2" cupertino_icons: dependency: "direct main" description: @@ -173,10 +173,10 @@ packages: dependency: transitive description: name: file_selector_windows - sha256: d3547240c20cabf205c7c7f01a50ecdbc413755814d6677f3cb366f04abcead0 + sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69" url: "https://pub.dev" source: hosted - version: "0.9.3+1" + version: "0.9.3+2" flutter: dependency: "direct main" description: flutter @@ -194,10 +194,10 @@ packages: dependency: "direct main" description: name: flutter_gemini - sha256: c6079dc6f95c6191e609e9cc627c268ef0bf2526cbba6a2f61aa41ea0053e9a0 + sha256: "993765fafb595e5d32153f393b9c5e71f853caa5bef123d292c21f672d2b9675" url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.0.5" flutter_lints: dependency: "direct dev" description: @@ -210,10 +210,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: c6b0b4c05c458e1c01ad9bcc14041dd7b1f6783d487be4386f793f47a8a4d03e + sha256: "9d98bd47ef9d34e803d438f17fd32b116d31009f534a6fa5ce3a1167f189a6de" url: "https://pub.dev" source: hosted - version: "2.0.20" + version: "2.0.21" flutter_test: dependency: "direct dev" description: flutter @@ -236,10 +236,10 @@ packages: dependency: "direct main" description: name: http - sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" + sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.2" http_parser: dependency: transitive description: @@ -260,18 +260,18 @@ packages: dependency: transitive description: name: image_picker_android - sha256: cea2bd5b9fcff039a4901d3b13c67fe747f940be9ba76bde1bcd218d168eeb7f + sha256: c0e72ecd170b00a5590bb71238d57dc8ad22ee14c60c6b0d1a4e05cafbc5db4b url: "https://pub.dev" source: hosted - version: "0.8.12+6" + version: "0.8.12+11" image_picker_for_web: dependency: transitive description: name: image_picker_for_web - sha256: "5d6eb13048cd47b60dbf1a5495424dea226c5faf3950e20bf8120a58efb5b5f3" + sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50" url: "https://pub.dev" source: hosted - version: "3.0.4" + version: "3.0.5" image_picker_ios: dependency: transitive description: @@ -404,18 +404,18 @@ packages: dependency: "direct main" description: name: path_provider - sha256: c9e7d3a4cd1410877472158bee69963a4579f78b68c65a2b7d40d1a7a88bb161 + sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378 url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: "30c5aa827a6ae95ce2853cdc5fe3971daaac00f6f081c419c013f7f57bff2f5e" + sha256: "490539678396d4c3c0b06efdaab75ae60675c3e0c66f72bc04c2e2c1e0e2abeb" url: "https://pub.dev" source: hosted - version: "2.2.7" + version: "2.2.9" path_provider_foundation: dependency: transitive description: @@ -444,10 +444,10 @@ packages: dependency: transitive description: name: path_provider_windows - sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.0" platform: dependency: transitive description: @@ -468,58 +468,58 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180 + sha256: c272f9cabca5a81adc9b0894381e9c1def363e980f960fa903c604c471b22f68 url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.1" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "93d0ec9dd902d85f326068e6a899487d1f65ffcd5798721a95330b26c8131577" + sha256: a7e8467e9181cef109f601e3f65765685786c1a738a83d7fbbde377589c0d974 url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.1" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "0a8a893bf4fd1152f93fec03a415d11c27c74454d96e2318a7ac38dd18683ab7" + sha256: "776786cff96324851b656777648f36ac772d88bc4c669acff97b7fce5de3c849" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.5.1" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: "22e2ecac9419b4246d7c22bfbbda589e3acf5c0351137d87dd2939d984d37c3b" + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.2" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.4.1" sky_engine: dependency: transitive description: flutter @@ -609,18 +609,10 @@ packages: dependency: transitive description: name: web - sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" + sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062 url: "https://pub.dev" source: hosted - version: "0.5.1" - win32: - dependency: transitive - description: - name: win32 - sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4 - url: "https://pub.dev" - source: hosted - version: "5.5.1" + version: "1.0.0" xdg_directories: dependency: transitive description: From 5f958af3f112000fa91ee1c5410f64d01a6711a9 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Mon, 19 Aug 2024 23:31:00 +0200 Subject: [PATCH 18/28] fix date input start --- covas_mobile/lib/pages/DisplayPictureScreen.dart | 2 +- covas_mobile/lib/pages/UpdateEventImage.dart | 15 ++++++--------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index 8d9780c..bc4424b 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -131,7 +131,7 @@ class DisplayPictureScreenState extends State gemini .textAndImage( text: - "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place, date sous le format en DD:MM:yyyy HH:SS et le convertir en timestamp , et sans la présence du mot json dans la chaîne de caractère", + "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place, date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère", images: [file.readAsBytesSync()], modelName: "models/gemini-1.5-pro-latest") .then((value) => searchEvents(value?.content?.parts?.last.text ?? '')) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index a13a56c..0523aaa 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -52,10 +52,8 @@ class _UpdateeventImageState extends State {required BuildContext context, required String position}) async { DateTime? pickedDate = await showDatePicker( context: context, - firstDate: - DateTime.fromMicrosecondsSinceEpoch(widget.events["timestamp"]), - initialDate: - DateTime.fromMicrosecondsSinceEpoch(widget.events["timestamp"]), + firstDate: DateTime.parse(widget.events["date"]), + initialDate: DateTime.parse(widget.events["date"]), lastDate: DateTime(2104)); if (pickedDate == null) return; if (position == "start") { @@ -70,8 +68,8 @@ class _UpdateeventImageState extends State {required BuildContext context, required String position}) async { TimeOfDay? pickedDate = await showTimePicker( context: context, - initialTime: TimeOfDay.fromDateTime( - DateTime.fromMicrosecondsSinceEpoch(widget.events["date"]))); + initialTime: + TimeOfDay.fromDateTime(DateTime.parse(widget.events["date"]))); if (pickedDate == null) return; if (position == "start") { startTimepicker.text = pickedDate.format(context); @@ -165,9 +163,8 @@ class _UpdateeventImageState extends State void start() async { inputName.text = widget.events["name"]; inputPlace.text = widget.events["place"]; - print(widget.events["timestamp"]); - DateTime pickedDate = - DateTime.fromMicrosecondsSinceEpoch(widget.events["timestamp"]); + print("date start : ${widget.events["date"]}"); + DateTime pickedDate = DateTime.parse(widget.events["date"]); startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); startTimepicker.text = DateFormat("HH-mm").format(pickedDate); From af673b1abddcb11ec925e47dd9b9a8b0fde1bdda Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Wed, 21 Aug 2024 23:46:19 +0200 Subject: [PATCH 19/28] test mapbox complete search --- covas_mobile/images/search.png | Bin 0 -> 18266 bytes covas_mobile/lib/pages/UpdateEventImage.dart | 22 ++++++++ covas_mobile/pubspec.lock | 56 +++++++++++++++++++ covas_mobile/pubspec.yaml | 3 + 4 files changed, 81 insertions(+) create mode 100644 covas_mobile/images/search.png diff --git a/covas_mobile/images/search.png b/covas_mobile/images/search.png new file mode 100644 index 0000000000000000000000000000000000000000..9454673d0b6e090e4b9d0cdd598a591c1e9334a0 GIT binary patch literal 18266 zcmZ{Mc_7pO|M*HML@80ucZPDbqH@!XgnAb$wJAwSM#5Z8yrmI}vP$T9mr6{@Q8qJ2 zT8?#Tgw0K^9nLY^@A(?NKdJBU^^e-?@w^__^Krg#`yFkTO0AKC!C*`6YFE zxL6iJsa}`6Shpjt(<<`O+E-7n(v~X(e_efGf3^SiW6J_pHtmY|&~Zg9YVp;DQm?kM zT5^@Uho0yf>gwqk4JTkPF?o!X5B#yN1Z986cNcPdIUQB;iU=eTQ#Tq|wxCl?ev76A zd-fURo}Nmg7s*-7J|)CEE~=%w-2Y*o9lIPWdgx(<6zs8?=m*Ow`eYe3(SwvDISM$o zYqzew+l{AGh@OE5bgFf(fO2Iy=U2E|{i!{H!6(*!+Pq_ibu?DEac%|{X+gvn_nbax zNb2&sBbQds?tsV$ZCd)zkTk4Q-6`Qr9k=H7+)hLLmnu0e?NWqI)!{hUvg-n@*NCT~ z*J3%*L(oA6iJdsJ5+)XcPE0r`w>~;Sw0p0|c*`vtkHB7MuUyl7Jj^|hBbsiIE8qES zfirA!D0g|~o&_II&Hesj0&F|u85ZTb_{f6m8yhjA=UYh6L9v9EC)=l`(Elb;r*di5K-0FZmyj#qAq1gdY*$af%!9X_YZ_GbSzsi>;G$gS0oWuQ zI}0~JI_bn(Ee@LlAm}pmU00r*+l&5$lFBStvUPN{=rlH5ueq1D0-3F|m;_^KX6Tuz zKxw>z+biEwrzYE@qobW1lixik_+EB`+p7sjZs4rJVQ*pLE0@S;+1}Ije^uEGPrQX8 zRUQx%6GNQe+=17!<34oB=3RU6U^J39(tG}D=b2J|MC1@)0vm31MOv7XR?7jLgFNll zq%khZE_`Q)q1`w7WGObQQcQStN{q`?zfPu^eC_?(8$g_f`z9Cf=)l73Q!)4rh8Y^1 z{kVUI;$vg!@m;9NAJ!7egi56S$w!s(S_~bI0}f@^vL*gh>rj_#3{5vXZcDGZL;bb^gkW-mzr9FTQ zE&9O3YH$|d@V0}9<)V?NZ}Vq%h)2H6@cZE2Io2rMKlXhOPa*uG(iNcrj-9khYXBJ% zY|nq6R*YyrD<6Lw3kYsXwRU6akYOLuj-v$OP0G7852u;C5igAWAGHQ+{b>Dh_|@>O ziE}ukt^fqG*pCw0qpqfwQQvz5Ib{6){0xDqGJp~qc$_~0j+(|eihBgFzfqhYMGdVd zX)M09diSSkx165s6%{*|f`Lda(&6e;3qI!leMU)qTRi36Kvb6e#}y=8+SsL?uZG_Q z$5y&(A^&=Lmv=4JbqV4V&q5Ez527zV`3QE#uo08bUW|4LY*9#-AmaF6r^L6FyLSe*#mGA)Prj}^4?m|zjMqZyyo>^q_WpxUC()!L z*CBZHz`$i|=+a6)#ByYgOV~|5uTviT*PEjQ=Wo!CFRSJZxa534Avq58#W~W~b+C>g zu)nOm)lPQVZbHa+|4H-KPD@Qim#Jt^= zKC@Jg_BY{6CC%NOHKb$L7N0CLth2hKyRw0?YiE}Bw6a5WV_+g5-H3X!zqUpsZx*q+5YuySU)v9V8g+}Oe**&6wVq+@$*FSmT) zRhF6c^Q!bcb3?khviq~9?2wp%!B$<)D%{N(MY*J|BsvPMj$edYf)_+9En&Hna8u*Au$PrD<*}L}?YG`fCsz6nk}(*| zu~*-OF=>kmlzh%vHazVPhAR`3LnmTROukeNQgW*k#K+Q8x>$<3uxn%g9F%A_V?B^( zYBseU>1h3arV`!w`fTUMX@nZ%o|e#ul*wPXjcodfEC7IO5I0Tg)B2hmUs3Yw4i3f8 z11!oa212<>qu%80z602qp2NZ^^y+icMvdL$<0-}WPDOjY2~MiyFg80$`vKUrmx=?o z^R;Z*;7bY^+wXvq2;U&K9CZ0d= z)@*UYfVfPMDajI^yVkVLxwgc$!@$Gi(Sm9*3t}PCdnL@jBu!AeP(!yx>ndgVaaKnH zqtfATxFm6J==L^L@tIHMttMdQ?)fU59L~6a8?lqcVBB(=Q~u@1Cn7L_h0i_+o4mHL zOoxa69QM326M8SlwbI0*FN9Mn!mhgx{;+%m)8OIXyXBw06?&|57doyg%oaeUFc9#d zj>)K4`epjr4zIl4`uK-u9`Jd}a7hc|4#xSZeXFY#Ei6(O7t*uo17RVi(v#O!*z6}m ztNo&k{qyyqm&xSg$egWy#e5!1rIy1s8?V20yP6{o7!4g$pz*^HcmqeI&gT`?HA@b6IjRDFh>tS{bwBT)J)SQ+rM z#A}@jYHC#SA;$an>^-Ko$7{eav@gjdkwN81$)S}4A}K#o=-yj0btRuQo80bfAFG{q z;)T8END(@a-=@fZDfd@Jw^|ZDT}A0iJ_<91AX=t#E0XP0owY4u=J*nyR#ThRzLJIVO+VZP(Vi~juC{ZFAFzDxB7GCoZ8#sV_kJwba_1!WV>@&eBi!Sup!-;D+ge& zl?Llc8)dA^D2j4~n~W{;=S-39rh{5$nO@?N%;7cLeOAI8Bub3XBRw;F$~R6fl4SlJ zHeq*6hjS1&0=LouS4@!|(WT>-yv<$}WOhRaP#cptSfzLA~5E<0&Gci>m6gO z(zAz?g;}PPspZpQ%NAMR81jF@55Cpd5Gvg%ucyUVtHYnb#oAdobTn|W)ze+VCuoVw zLdin(dSaT*o+}gDO>L%Ko?fi{g&H611%by^|9LmIP@-hyi$J}ntyz(En%Cm`Xk9p- zzt`G_62%K+6)~+wK3Je2-5yJ!eCzBM4nOLmsoyBxmwCs1di-0-iBAv3m2J0T5;4yX zz$%A)r;MZ{pZei7B*LC|3DsmvEk|;1PCgYllT&t%p!buGcNoYsZx*NX3@4DwCg~fF zzGgpwD_cksU%+fHjJy%-Z^i7n-o<>NxcgJH>16%0;P}cr^09mMb3gJA1`iD*{E3y1 z<=t*00(zcJZ%y^%SLCj|mN(jAkrt|x!q5G)g3HKC)e*_kC3F%_mdf?&FlFSW{#U5vWM z?Cqun8w%g{JTo#_KO#pvE4nb8b^#M(tz^=)ogjZa7jJUlq~!>~gRq{n4;P>{>?NrC zK3%x0j9=k_bC;Oj&iJ^0%GMOqLZQ6!U|I24s1&mGZdC7SK_IP}lGf+tr#gamVN~D2 zV&GVbFlBUmx%fbL8^=aARW$^A?O|V~#$uO^!k(6cF%2p3Qr(v^Jo=3ZZD1czGbxNU zdak)jDbdy4D*9eMcI9M4yETaByc2ZZ;JpaWH|qH0ZJ+oOTY=GdMg_k@ljjQCmUrWrf92$f*EcY!~&2)R7kKr+ecLY{t) zU57OqgXzm`G_CoObG+pAGoLIEB2FMx+gq3+#EVP!u&P9h81cxdU8wid8T<~czIoP` zjL;Sb%b*awkvFZL`a;)p^ju^;pq(jC@zPWhC4=o<@cmIYZ6cW;&?&zESKK+XwYq`AjUp%KD&lHs9 zPL;MDxj9dn=vg&prSP+4#*XoHgB*KFcWdJ{Jri5@ayH?qFJ5eNJfS2orZUsK>mqOSqFhfRzHORy zI)HQWyw5#5V-%~yL$C0%t@Y@Ak&A~@^G}r?bK)|!t;)hFde88E;lS;CB@^`i0V1Vq(a36V z+q&8-WJOZ!%YcsaEK3KJWN(HNt;Fu+5^xAOGHBdN5B8AQg`ziXKXVN6wBJ1&_14W+ zz!;K`eQDHQz)7_WujxE+SfQ7@P9JGUoM+oz4~r(1rD2|s`l%?(@!~7#O9=O~5)}zI zikq`B%t&w(ya$K4j8}l!`C8G{pDWWA%O1kyk#}(?98(s9?VGW;?mgD)T!Jn;KGKsg zNDHS7`3i|=+n5xg4rzVvM7~jbU`=*|x3}eGH=_5} zrBgR{CGetbxQMK*OFTxOGvM=E)FiqlS_j9(G!UzM*7ZmOfw{+6t*}qf|F!GEzDq>4 zu>R%E(z?au8RwJYBjQP2s12-0DYa`~(*;Q$+|DuTIoo@k&a6-037b&BrtIb%A_$o- zZ2Wu8JA6#U_zoNb(=ecf0hLK&LpWp; znwpr{j}h9R!?6XnR0(ZsB-J7iW=1-xD#k1qp?6k9eB`1P$Pc_M{spP$V59G zdg{@p3IYPhssW$}cS2eL_Aa#i+0N+vBICNfSXpgh^XP;pxAWGwW?~5W#zq<1^S#yE zc)4D{otm02L8@!+sk^{=%)egZs7YSYMXb`Wdby}JJ?9@vCYx_sUExL1JG<0>G+c^q z`6isIdnp)W8h%?<7~z+3{6-fRUwL`oC5trTtmM8yiknGDT*fvHmk32DF#Pc8+Z zHKZze@<rEWf7p9dDodVumU(r&4PN&6^FVFujGc@}L|mZWF{^;!1mjPuZ-C95|6f#KnZmIAApzyAUCSVb zD~u6jfc?;kiihrFu&YPJ(Xzi@iGF1dD5mc?(bYNf=Kxp8hGm8M7D<;P*PbqI3v8OZ z0ZTooSlbSoth&WlRiV=fu-)O9SL(<5FePo+6A+x<_-Mufn2gC*6Lb(CU%>&)sfz*R z4!t_4Xl&ZDVR8?;Nu#5Y%g9a4w@awvw7sX&-b zJ^k1WkcMd{eoe?L!VKpq_+^&XQo<=|`J$kMn}ipnr(bEd4!Cp4pVJQ4-=-$T77Y#f z(dr5oGAQF!X_|<0GpJ&_{WVu8xXwuv$rN(`coAUiSmU9A=8UkRQfH6*kwfvulK)*h zp6d5F9EXbSZNhqr_FoY5w0D<&{lPU?9h~;x*sMsXnHNZSJs53d(ir+Ynu^-Ow}W=e zLo^W*{n?+G0ZpZtQ9`~OD@VWHqElF(Pam!fJ`7o2spCK60Y-@+ng z7)gusu*xbvTOj&Om^tvZCJkLnF5E@LJ(Sycgu{N@Z*Z%)Il$||{b&FY@S|zebKJjg z4Ko5r+)>)8s)~WP6aKXHn5g=b(;YYXI!GPUWPZaK2>}i6scfza@VZq-4te*g%?Cw% zu8kd=de-}XsTBwfb?$SqAim+8!kW{;sbt-!JDe?fhyX2~Z9O$cOGu8(2vs&m ze$p3k!L1Z>D5)%tADs-|yJ&nis)&evjWU;6qEW3CmSiR$hAh z1qKr^uw_jG-Q@M&HYtEzpA>9+mT>R5=hwfl6ovX)d>;uCEfRL_+lw`~W`<;G3C;_X zPEB{zmDd~ayj!>ZRtKdes5kKJ$tIkM=yoOMucFKVxo3A0h&xdfx?* zdJVyWL;EdTAed&Yg<#8)^MzvdcnnKq_Y3!&{z@SEOk)9j-;g?E6+Rs4C23{T*3 zTEjsaJf`k)(cHtTou(hRZ;pG2^#Hq^=j`p}dTurU{AoZ290`dcZpjc+-Bq#CBz7p? z^`reoE1DFH+`1*IaUJZg`v4ZaYXm`OCo$c`?*V~jrK1df;Z`@OMu#PeOX@lxu)!hEqI3+oTiF|&(42Xr3j zPy|T3FyHFhpHy1Q=Z%c}|BIjKgy^tLlVeHy*75pvMwL1 zK#?SnQjCHgId#pu!QyF--1-$FEoW`?{ zRe*izr3XI|v)JhHAu!W?FFlx;RD+gs1}icOd=3+y?J70Qv=k ztM5IspslE6&oX84ZTU1*j|2eT^T;0#oo`6JGnSzimF!&qZG3--c3(dnya~ z1!4x)1`~QBSQ6YW5rQ>=cD$RGF+RawEgp$V?IKv=K}^Q&($QgMNR@KKcJBPqsqZMz z-5}b-Pi`Oe1d)St(0t2h=K~i?Za%cQD!9=!K_tMMj?zwiv_jw7Ab2f=B0i(dJ^QRb z*OlX1h{!l-zsTmmhEbBAjys%30p6hJtr zX)MJ!!m(pyPcF8J`{jbusSEAxM>>z622;K?YF4D-x(FnK8$hiOq*#x1M$~k45l%vj z=}}Rn`h5P~7DsR-i*rQUk$Zggr}Tkoh}rFc6o}Ojs6%Cd>iO@c|IMMIA~rZk%0XJY zOl93P{!JtI+y#3`NWNjzUjlie*)L$jfv&nyNthO_1WLXC3!ZnUo8Hv}$>s}=WBwMN zo|j+V7#8eVJeiDo3fuT?h2!+7XYOm>-DAn{^#CEXHLOE!K&n6jNgvFW)|Htvk%EHt z8S6~ZvEQ>00R?sRuB|?efmXA?a0nQF)*@*r9-l(fBz;F;Z=OPtO}~)^ZtuRAlLUtJ z@8J%<;o)C4&JHjE1E!cDPH74R>Fhjn#|hQrod%9vK(AN@={>OJ*IRh!SVsWldg89$ zkryy_^Ks3q2@CHxRU-m!ft>^~LWb5s6Uzb)K4<_KA_G`|fP?4fOFs7^MvTDJIfpkD ziiyC1ohb)VMWuGU%7{2P7~ulj6+$KFW=DT4Mt)==0&rmV@{NbzLFliDf5?`J2M5&w zCWg#>hhTFNsz)*vmEuMbK}uJ!_d$@=fQW@*-h{`rF1gp!P>?K7hKf3#V$K9qGlvK= z$o>~L8C69^RcQixG#?pawHtxEOCO^1;wbcyOAfy3fQd6yGgQ#^5Dz!T55;@!61mUr z_xGW+WugQ0$=VZ(W`PFD)`b8Fvlu9{cgQRpS(4sm<;C0brgxV50y@NZHvuQt%2N)k z%-l(E|_Tut^7E!(BE9<)G8oL$DykyzdWoE8X^Y{yFm*( z_T8O#_Ko@MkZPcM8hT5?osssybpJTQ=rr%Fse(OpQ9hoq^7iLqHDoH1z&7HvFSSl& zfhe>~X6Zhk5H9vUk}w2WW_qNF^AKZ&tJvrO%u8wij75)gYFf?&crwmxM!pxp1s4EG zGPV1RF$Ef78<+NNnu>sprmdJ6upa8fzj@#D!6NQqun{28-k~j8g^hRl&N8xv8Sloc z&ix#;a;LCsk9#x0URDaAGAa$Li9Zl=BSJ z=rVF5bQ^lJ7NSUB9}TV*$;3mNd~69)3f3NlXMfKhA8o zq_ozJ-sk%q{$EI>q z!4azgHNf->HK=vHQ#%7YS5qzyX-M;SAB+Q{$bIE@rqa4y$qZLxC&z+Yr%h*^aM$S*lxfx`4A^`bEC?H z>D^SJ8V)#a^p~@?3$T>}prMW)(1EIzRgb^T7xP+$1zI2=6zATwB&g7WmtA~MWV#TV z_96Sq?oWj)JCvlaO_x2ywy`3%bmc zXD0SY*6XW5ri~>qUu=ME=nCS&%ycXPNnj0a~ zkA*NFF_voA!fL`geIf(Gn%VK+vYgtrx922>-wE(>6qxz86#KJ8mmZVoYI>dTJXkkg zHK4(pj*)_SShl~0qk0Ylqw1URcy@y~Xbo`EINEJ7WY4ke52Ecz;{tTnGun;M>E$0BO{qz43c}j04j!GsA z#SW}Yhot)QuSvvP-8JvKfK579;%spP!d?K&kd}~z%K(siee<$5b%3YVNjU-I6MbH) z5-|6`v!X0%D(W72&XGhe_$}#T*Cb)%Tq+C4DopIvKLMSycKW^;Rd`uraXoM)6#kHi z9}->!l3L-mpeV9gUK~E|5rl0^&RzMUrVPGwr9WRAT!Rbd>-?{=lp9i$HNabVajO>w z?h|x9sp7b;K=(>)?D*^|^8`aKad0JKyyftFkF*9NSVhyvIiOPi_42fJf=QsiCA&J<-BMgb8p$nVBB| zxt~KaF@g`li&3!yy&%)I5(04qKGI8e5|A86^uyI_00kW_(n@Ou8{pWX)-7gleRLpc zrIRMillji!xS@C(ZYJhg{wliJb^e$k<T#+OgvoB1N=+Q7AVXkq!6-I-@cnL z#>GHykA$&;)`6?bs#!6qOV~y?S23%bh%9{pDTjd;H{I!mbXhHI-~<*r<7qB}KZ>G~ zYt<5+r@XyTBF_s$Wq(mIQ+qn80+f3ET&B|Hj-*Y{eWuCl{On032oXJqrXsbq{z)Fy z(U3#&_P=71qdicNC`Wc^Q1?)0vL&Q#j7Fj~Cf|Bcg?pUo5bXR|X^n-+b6n!!z6rBr ze*UC72y-F*2@T$AU5B}u;~5$t)CTR`$0OhRit&S)fk1y{5vZB?tsE-K%3~#FDTj1 zljyYvmwrW<7zhZl)EWH^damyU92?0L;VPUe2t4MG{(6-xh?n%rkEU7=EGyQ8B1q*@ z73_l`mQ9Vp-iBa5?-2O~=nyUqsc4$Y&oBO%_GJBH5c1p$(zoG-kAS@ApzypXkLDpOf59=TFM& z%*`OK8LZ+Uko)Q_77IY9y5Ed?CSKUc^Wu=@cY*-u^ALX()lP3No_4&XH$%BcloH4v zy<69FfABiiea;-gnROBW4yp&6-{q@c@905^!mS%ZKnA?#6WG`}pckCk z@80ckr3(BLde3lOCpN!uEBaz6%1_ucKHSoCaeTcvaNM^&>>NnG0q_lB&zGbQsxyO( zdGu~NHe3ZtI50gCapfs0rKg`>OG^b+WQo+I-sd_a{8RW8^4mjizBrn1@G5P)!7mxy zvW9b&&x4}RhqBw^je$+S9PD!o!6jQ2#J64P0%kqnfIvvzGR2|;u4PNgd5|LWgP_bF zm^2Q=3ny+^Gutmfu)&Za4)Qy(bHbO}9sMP_xT&EFjX`^HJKwZXiAXJMDTUKT$ekhM zM9GAo^(>MSy@823LVaXeS9L(!tJdyZ9U-tJP#~kb1BjB`ysPP%SoD|clhK_(!=)^c zmjrU*GrDTSJ#}g(4Z4-D@96aeX#q9uKgtO5hN1(CJApUXtThfKu&FEONd8`fi(^f? za4b#_AYKftmGrAaQgefHK!Nrc+S=C?xspv_DfZ~n7wXx2xCHC{*$rw?^6SR@e4ncF zy;xTbo|pfl%KE{5m{k~7&R#BFcxeN`jSVuj0_5@En~$*ur2f)_$=gWw)=I&J`j-$d zlR2 zLE1$5P;~Zwt}7NRCt6}&QOx_#K(Y0yD%b&I1F@T?{_o<(G_cSv#xn(bL4R_~GSQG< zTym4PsWywz2XaSr?Kp1%Vk$~PFqkt~u*{{C+9m(X?Ik$-VN06R zC<$0_?u^iM?MpTiUN)VE?eytq|X{}0{SDVSK2^N=dM zgqslwAUDjL_sJZpOqqOE=?(Vei-AhnP6<>WA+|Vg;(2+|fy#kn?TN0=n|V&T>Kf$6 zjLQ0djFr)Kcby*@3QN132Y%cgVusz?RU1yxp4FVs}CNEx_OdGqd%(g0V~&|Ge%3 zyP)wB)8g|10bk5XL!lCR0WLMlYxb(^RdJkGR#(Ntdeo6ilCl4~PA|RSCLA!X2H}L7 z!*0cK(KCj!zH)I)TZ_Bt`9~Sw3$pPb1asgH0%WwS;v+Z8;5Q1{Q-iQv#g!>11HLK}la?tu@gqWL|76g~AB^Fs-A~^2DMTDw?xl zL1BixfVaI6Wt10DcrDA!&7F=Le%cKikt5)LmsN={?&G84%yPLMDg6B>91b28H zS3ucIIVe3^+dOWSj4iSd?hQ1JJFfYfgXjTfo@<-c^~O%}3wZ6xoSvHgD~nZoic zJ49QXOXETN@{Av=6aHy5ogUtzm6%+7_mo5RHVd7fbmea$}svm-|T()z->Y(}z zjCaWQq_7q74cA}%P`VmxT%s6lX|)+-(yk2-2K)OBOn!Q5-bKdl5R|Hq5C#}mEA_N4 zz2iUf&;W&NSYINjiwG_a@Jmb2TBQOQ1Y6LWs!;i%-gICjmbo-TO`d9bU8>3Ju8`1NBG~Z zTw1GWCUGJBohEOB8KxsyWNPU!)x1v18rWnRrI%*jYB}GP56oOL+fs#?W{1hgW~Ywx{v%z-qn zDjKBoLIAo4O6Tfps@!Rf2ZKE_t0*}u8S3!*TPDs{!H4qiSa>jqH)g)&G@m^p*Bd{@ ztkK$PXW`UQC!fjHPQ6nKLQ1`#HZ3E7dY8HC8=3K16r{bQH6|BI7X6LdGnvAlsOe%c zlP5vR^ubntP+=JxyH{l`XERO*vm%LpKD7~bk_fl~8Hd{mmvu<)x(X@{4dWgf$4`Lb zogejBd;b0oIwNQ)rcn(8?Rn?CsEcQw`N&o@0}Yp{5Vo}e4+>C-X!Ym)4axv7i^}QZ zBEOgxx3{-L`ETxE`nRtClNs$!hb`K}}=0L*5*RA~YA=chZNq4$3ai2p;$ zSmD&_9%L;E%7KYTTFOA71kvJ8IS%Mmh5Jj+0%7{!l~t)Yfk?>Tk6>4uTSvWC!49-< z*e)~fLnLVl-cy#!$pQInUmMvO@c7sA08lY!j(%+XiIfO!m*Hb3v7rYOSCrnM|DBzc z%UYnpn_wuXrcZ^-`hpVneD)KAg(g<6pU>6(+lo%_Vp^kVmd3Rp)@U?)pr%cJo2tD) zop%;4lQLXN2L+4x^cl6;!F@`_w>#G}?v*MHzTtQm-0e3OO8)oeX6Jfv5ji?pGN&U% zKcEU#MhlCecyg@bmui%&YmKW!Jf}sR`ZHcBMCOVhQfSz2hF|mX}RJBtQQf zEZFDTVLs;f^uFO=)KHZbDV@+dwWRmV1p#aG->fG%RZ&UfBhElSQ34{AZzRB33=n| zKJ2|9j(zfV&2%+;UmUDZQdLZK^tTA$g6N@0kV<*5PKs$@K6xC}nahXZsZ3*9yWqgn z#qMDrH+?)XKiE;}?$&8=^tE5`Gd6i2C}|%-I0WwLU(5^3k({>iU0ybR-{XG8{3|H9 z5maCa;n>ofT`_bI78*o>KKg8x3?pLq9a)qIPSIC9S27l!jD1Xuh6~iG(&$7|$)j}^ z5j?JE_H;4U=is8eh#yLa7ZA3j1d#)iv09b|b(w$pi&LcuH4M@TrAywNj@<+HudqG_ z3mZ#;UTGdygApneqld0#2?WP*s1zdm^pDm@^1_F^rGxdF1rN+61hAS`(O$p4@~O8{dta3?KnWp6V7THR5Av!?bYs)GRI_tcr4 z!7}_!&3M4%GP1}-V>IJ^Ma9O+YbuL|+udPCpk4ysoetzUQ>;nt~ZCXvivJ=h=m95roi4;phW$)?_7 z`zD(lIav@r@@D_?vhb#N2c4FF+H}2(=I+|!ww|*UH(+wuthbeb9m+n5xEOBLyJ|r# zem!IwRDa>lwH#o?k=_wMbnL>BtxM}EpS@X%P-hA9CC|bWOi3O4zG{JrlYQ_1x^i}t z3eM5>&u>jp1UbqEocL9f!$;d@2$kkqYAzfe(E*HF-{s)8$j`#S^Jmc+Xw#zOATj-P z^nBZX-iRxFxX1m7E~^OiDGl~IT>R&hl`^nbJohl7<6w!{$NL0Lq1HU{$V&kau`^jR zTak(uf$o;OI#vKqei1f&9z?rAprf6Pit zx-nT=NrDfUa(qF=ARu8+XO+dp(A-eb8m|c zm-T)+9-b4hCSkJg#*OyaBq)U|2ps;jDeqC@WmoX$(ENHE&}$YtG(;Tv{)s}NWIY}0 z?7q)+;EkMD3D3HQvI{@j@pvpWBG_(nXD!fEFf|2b zlbP7r*9D9jP`h$)cP%LLc_80hL`3>7-^R`IaL3KR?~+`_owS-`JkU)q4(L{$9B|Ywta6p-?XN1bYdO)xWR8M#~Bg%JPK+4x=CjS~;MFT+30x>Dc=u zW1gD95)%?6eB^Y9>*Ha`)~aImJ&$9Cq2yU+R}$#0qmLIj%x+=HPumr0+Cxk1hEX#U zFS~>R2NUY~BYZ$UTAuU~!fP%NV_-EfWQbeNxg>~C4GOyRcYMRrc#zHgp#p*J9 zJHbVn!RTMZ?||5lNij0})@VS<1PTEIJNggShFbMHedo2JiZ01^CFTAPbOS2cXRy zMenMLA>h0(K>0$iT`kdPw0Fadmwlf5q1UCltZhaPP)kZ{(o{h746nZ5#Iq|I~7=0(p-#(${CLA!Vk7~wi# z1e56hgAsZwK|inF<)7zpU+`;)`Q+?dyoj4uvFG=2nd?B*Fts$3_`GRj^>69)^4X||1rNlWEKe@Iv$IpV^S{be+lwgw0dP3djjbt9IGyy ztNBY2(eT9tF!yW)w+59C&oyE}?C_@jyaD+2qKuE^#ha5&A`E|M*_5|wUv=5)Fjvrq z(h+{bs~lh<;JsT((AWil-^S?>6`K(|0SM25$0cmVZWy3Ohux>qnTUzj04pk}GzWO6 zc{?4KW%ntWXoC8{i4;DF;(+HE`)_b+BTnJ#qjg!y|NRIlR-qlsn-><{MXUb@5XPpu ztpE5PlWzqg`47^D+JDU?LK{ez*)F&fHa+%p?NsI~0HOghNd1g$lM*)nDS_GLfT`p> zA+aM6Q5M-fujuIJ>>eTMOyM_&rh!_R-|J0J%q}Wv*}92+G8yZ8@8pm1gkQR*Krugf zTE>AQh_@4bc}LT4DV-lO5v@U3lQFC`shKRi=}$KHr~PBlY&<{zyhL;aWH<4m_U>&} zz8Wpeh-zSr?a> ze`@-)__pLU+E{G=JEN#sp(37*k9a){*N4z3x~f(Ua5{w(D$%DniS841#h7XqiD^a^;Mi~)MH|4z34NtJB+Cib>@ z|Mgox#~*+VGJ?0qBnu1RSdah$4?`vnW|N@?B#{P+svyZbyvSsn~ zbZ~_bh!IS`ZUSi%_#ct)jUa~tDUuvW4|Hwgl6Ri09u?tes zN%IPBsI&VRsQjWTCT%ROdxUF^dU%>M{(gR;P5In89(#FImkns89wu7;eih7ZMmfVl zRSb=9tl$paSR=lzW%!A8KJ2Pg@Dh-DfsXX%%clLUqZ780g*Ly$r)@z4JA@}`LanNp zGZ*_>vsrUqBRzYD_6cbiNxjdtY0NJKLQ=ZbI17#Vw5Qw ziv`&T+TB#&7}*b11*hbzaSv^jXjs9=z>{j1U!HdNtO zoU5%&o+xDql*!D*p`>di1sJN zo1;bdNUT?Ekz>ah918?f`k_cYd;{LZq2s0eg8u*rSuU@_Y(WpVH)NJ!+*E8>*G&#| zoZ+!(sbm(gkyg9&xpfO9Bq1`(5zOY|zpH+JI3eN}8y(t8tXJS~p0J2B*)JUaR3eZS z1RmOkc~{4O-&mM`Yy4a={g2qnJBVyh{!- zmjQH|WrvD<#;?~soBg~4B=kgP6wtcH7ITP6>Y}x^K@@Di!Tk`nX5k!xs z$j$&jw>Hf-yUp$-;Ag4y&u==saQa`=VGezuYGj^E1F@1?M#2B-v55B3)ctE*d+sw3 z8G-+oB?b(X|NjRq{`3k&N6DxCVdq0v9>#Ozmu&0yWRda$t@A%CbU;JD==l~_mB9dJ z^&9}wndrFUC%SsCRR0f`D$wNywZ8v{%m01bVs z?}RYN)s5+kZA(6GP!frv97wY22#eqB*_JImBr;vWtrFT7$W7AOgKa;p_+4D2@_?fH znD)ck%KgRij~iDhDwWN$cYZ}p?HzvSjhB12S=0nk=EyU{>EE5UXsObe6a@FTV zVSv;NeR9B9a?j-P$?91qXHRu1=)(G&V~yh#Mf?qlt%;X|8g|rOy?jK_IX9mcM__&W YHR=JUF!u!bW)945x8ttd9qv*855h*y*#H0l literal 0 HcmV?d00001 diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 0523aaa..f7ff85a 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -3,6 +3,8 @@ import 'package:flutter/widgets.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; +import 'package:mapbox_place_search/mapbox_place_search.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'dart:convert'; import 'dart:io'; @@ -48,6 +50,8 @@ class _UpdateeventImageState extends State TextEditingController endDatepicker = TextEditingController(); TextEditingController endTimepicker = TextEditingController(); + String MAPBOX_API_KEY = ""; + onTapFunctionDatePicker( {required BuildContext context, required String position}) async { DateTime? pickedDate = await showDatePicker( @@ -161,6 +165,9 @@ class _UpdateeventImageState extends State } void start() async { + await dotenv.load(); + MAPBOX_API_KEY = dotenv.env['MAPBOX_API_KEY']!; + inputName.text = widget.events["name"]; inputPlace.text = widget.events["place"]; print("date start : ${widget.events["date"]}"); @@ -224,6 +231,21 @@ class _UpdateeventImageState extends State hintText: 'Entrer le lieu'), ), ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: MapBoxPlaceSearchWidget( + popOnSelect: true, + apiKey: MAPBOX_API_KEY, + searchHint: widget.events["place"], + onSelected: (place) { + print("place : ${place.center}"); + }, + context: context, + //iconAssetPath: './images/search.png', + ), + ), Padding( padding: const EdgeInsets.only( left: 15.0, right: 15.0, top: 15, bottom: 0), diff --git a/covas_mobile/pubspec.lock b/covas_mobile/pubspec.lock index 0527810..d95e826 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile/pubspec.lock @@ -81,6 +81,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + color: + dependency: transitive + description: + name: color + sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb + url: "https://pub.dev" + source: hosted + version: "3.0.0" cross_file: dependency: transitive description: @@ -89,6 +97,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.4+2" + crypto: + dependency: transitive + description: + name: crypto + sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 + url: "https://pub.dev" + source: hosted + version: "3.0.5" cupertino_icons: dependency: "direct main" description: @@ -177,6 +193,14 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.3+2" + fixnum: + dependency: transitive + description: + name: fixnum + sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" + url: "https://pub.dev" + source: hosted + version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -360,6 +384,22 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + mapbox_place_search: + dependency: "direct main" + description: + name: mapbox_place_search + sha256: "36e213d66e38c3494321177a80b65f6b420068e54eaf9978cb312da97e4af250" + url: "https://pub.dev" + source: hosted + version: "1.0.2" + mapbox_search: + dependency: "direct main" + description: + name: mapbox_search + sha256: "6606ab1af8f34a22b5b096d6037d95117e4b51d48c63161d817130c91c736e7e" + url: "https://pub.dev" + source: hosted + version: "4.2.2" matcher: dependency: transitive description: @@ -533,6 +573,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" stack_trace: dependency: transitive description: @@ -589,6 +637,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" + uuid: + dependency: transitive + description: + name: uuid + sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" + url: "https://pub.dev" + source: hosted + version: "4.4.2" vector_math: dependency: transitive description: diff --git a/covas_mobile/pubspec.yaml b/covas_mobile/pubspec.yaml index 1bc13d8..0119c6f 100644 --- a/covas_mobile/pubspec.yaml +++ b/covas_mobile/pubspec.yaml @@ -45,6 +45,8 @@ dependencies: flutter_dotenv: ^5.1.0 image_picker: ^1.1.2 date_format_field: ^0.1.0 + mapbox_search: ^4.2.2 + mapbox_place_search: ^1.0.2 dev_dependencies: flutter_test: @@ -72,6 +74,7 @@ flutter: assets: - images/flutter.png - .env + - images/search.png # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see From 0c2ab76cc94f968b9821eaeb8b11f3fa926a140b Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Thu, 29 Aug 2024 22:59:57 +0200 Subject: [PATCH 20/28] add google place : NOK --- covas_mobile/lib/pages/UpdateEventImage.dart | 46 ++++++++++++++------ covas_mobile/pubspec.lock | 16 +++++++ covas_mobile/pubspec.yaml | 1 + 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index f7ff85a..107f013 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -3,8 +3,9 @@ import 'package:flutter/widgets.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; -import 'package:mapbox_place_search/mapbox_place_search.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:google_places_autocomplete_text_field/google_places_autocomplete_text_field.dart'; +import 'package:google_places_autocomplete_text_field/model/prediction.dart'; import 'dart:convert'; import 'dart:io'; @@ -50,7 +51,7 @@ class _UpdateeventImageState extends State TextEditingController endDatepicker = TextEditingController(); TextEditingController endTimepicker = TextEditingController(); - String MAPBOX_API_KEY = ""; + String GOOGLEMAP_API_KEY = ""; onTapFunctionDatePicker( {required BuildContext context, required String position}) async { @@ -166,7 +167,7 @@ class _UpdateeventImageState extends State void start() async { await dotenv.load(); - MAPBOX_API_KEY = dotenv.env['MAPBOX_API_KEY']!; + GOOGLEMAP_API_KEY = dotenv.env['GOOGLEMAP_API_KEY']!; inputName.text = widget.events["name"]; inputPlace.text = widget.events["place"]; @@ -219,7 +220,7 @@ class _UpdateeventImageState extends State hintText: 'Modifier le nom de l\'évènement'), ), ), - Padding( + /* Padding( padding: const EdgeInsets.only( left: 15.0, right: 15.0, top: 15, bottom: 0), //padding: EdgeInsets.symmetric(horizontal: 15), @@ -230,20 +231,39 @@ class _UpdateeventImageState extends State labelText: 'Lieu', hintText: 'Entrer le lieu'), ), - ), + ),*/ Padding( padding: const EdgeInsets.only( left: 15.0, right: 15.0, top: 15, bottom: 0), //padding: EdgeInsets.symmetric(horizontal: 15), - child: MapBoxPlaceSearchWidget( - popOnSelect: true, - apiKey: MAPBOX_API_KEY, - searchHint: widget.events["place"], - onSelected: (place) { - print("place : ${place.center}"); + child: GooglePlacesAutoCompleteTextFormField( + textEditingController: inputPlace, + googleAPIKey: GOOGLEMAP_API_KEY, + decoration: const InputDecoration( + hintText: 'Enter your address', + labelText: 'Lieu', + labelStyle: TextStyle(color: Colors.purple), + border: OutlineInputBorder(), + ), + validator: (value) { + if (value!.isEmpty) { + return 'Please enter some text'; + } + return null; }, - context: context, - //iconAssetPath: './images/search.png', + // proxyURL: _yourProxyURL, + maxLines: 1, + overlayContainer: (child) => Material( + elevation: 1.0, + color: Colors.green, + borderRadius: BorderRadius.circular(12), + child: child, + ), + getPlaceDetailWithLatLng: (prediction) { + print('placeDetails${prediction.lng}'); + }, + itmClick: (Prediction prediction) => + inputPlace.text = prediction.description!, ), ), Padding( diff --git a/covas_mobile/pubspec.lock b/covas_mobile/pubspec.lock index d95e826..b0ddc63 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile/pubspec.lock @@ -256,6 +256,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.4" + google_places_autocomplete_text_field: + dependency: "direct main" + description: + name: google_places_autocomplete_text_field + sha256: "86615529ffdef8901d6c4f9b23f2526884dcb69d28e411beceb8093f5a23911c" + url: "https://pub.dev" + source: hosted + version: "0.1.3" http: dependency: "direct main" description: @@ -504,6 +512,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + rxdart: + dependency: transitive + description: + name: rxdart + sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" + url: "https://pub.dev" + source: hosted + version: "0.27.7" shared_preferences: dependency: "direct main" description: diff --git a/covas_mobile/pubspec.yaml b/covas_mobile/pubspec.yaml index 0119c6f..001f36c 100644 --- a/covas_mobile/pubspec.yaml +++ b/covas_mobile/pubspec.yaml @@ -47,6 +47,7 @@ dependencies: date_format_field: ^0.1.0 mapbox_search: ^4.2.2 mapbox_place_search: ^1.0.2 + google_places_autocomplete_text_field: ^0.1.3 dev_dependencies: flutter_test: From 26a9d4a034e0a8a06200ebe9a59d74fa2e638a6b Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Fri, 30 Aug 2024 23:27:34 +0200 Subject: [PATCH 21/28] remove useless package --- covas_mobile/lib/pages/UpdateEventImage.dart | 38 +---------- covas_mobile/pubspec.lock | 72 -------------------- covas_mobile/pubspec.yaml | 3 - 3 files changed, 1 insertion(+), 112 deletions(-) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 107f013..d645afc 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -4,8 +4,6 @@ import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:google_places_autocomplete_text_field/google_places_autocomplete_text_field.dart'; -import 'package:google_places_autocomplete_text_field/model/prediction.dart'; import 'dart:convert'; import 'dart:io'; @@ -220,7 +218,7 @@ class _UpdateeventImageState extends State hintText: 'Modifier le nom de l\'évènement'), ), ), - /* Padding( + Padding( padding: const EdgeInsets.only( left: 15.0, right: 15.0, top: 15, bottom: 0), //padding: EdgeInsets.symmetric(horizontal: 15), @@ -231,40 +229,6 @@ class _UpdateeventImageState extends State labelText: 'Lieu', hintText: 'Entrer le lieu'), ), - ),*/ - Padding( - padding: const EdgeInsets.only( - left: 15.0, right: 15.0, top: 15, bottom: 0), - //padding: EdgeInsets.symmetric(horizontal: 15), - child: GooglePlacesAutoCompleteTextFormField( - textEditingController: inputPlace, - googleAPIKey: GOOGLEMAP_API_KEY, - decoration: const InputDecoration( - hintText: 'Enter your address', - labelText: 'Lieu', - labelStyle: TextStyle(color: Colors.purple), - border: OutlineInputBorder(), - ), - validator: (value) { - if (value!.isEmpty) { - return 'Please enter some text'; - } - return null; - }, - // proxyURL: _yourProxyURL, - maxLines: 1, - overlayContainer: (child) => Material( - elevation: 1.0, - color: Colors.green, - borderRadius: BorderRadius.circular(12), - child: child, - ), - getPlaceDetailWithLatLng: (prediction) { - print('placeDetails${prediction.lng}'); - }, - itmClick: (Prediction prediction) => - inputPlace.text = prediction.description!, - ), ), Padding( padding: const EdgeInsets.only( diff --git a/covas_mobile/pubspec.lock b/covas_mobile/pubspec.lock index b0ddc63..0527810 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile/pubspec.lock @@ -81,14 +81,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" - color: - dependency: transitive - description: - name: color - sha256: ddcdf1b3badd7008233f5acffaf20ca9f5dc2cd0172b75f68f24526a5f5725cb - url: "https://pub.dev" - source: hosted - version: "3.0.0" cross_file: dependency: transitive description: @@ -97,14 +89,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.3.4+2" - crypto: - dependency: transitive - description: - name: crypto - sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27 - url: "https://pub.dev" - source: hosted - version: "3.0.5" cupertino_icons: dependency: "direct main" description: @@ -193,14 +177,6 @@ packages: url: "https://pub.dev" source: hosted version: "0.9.3+2" - fixnum: - dependency: transitive - description: - name: fixnum - sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" - url: "https://pub.dev" - source: hosted - version: "1.1.0" flutter: dependency: "direct main" description: flutter @@ -256,14 +232,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.4.4" - google_places_autocomplete_text_field: - dependency: "direct main" - description: - name: google_places_autocomplete_text_field - sha256: "86615529ffdef8901d6c4f9b23f2526884dcb69d28e411beceb8093f5a23911c" - url: "https://pub.dev" - source: hosted - version: "0.1.3" http: dependency: "direct main" description: @@ -392,22 +360,6 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" - mapbox_place_search: - dependency: "direct main" - description: - name: mapbox_place_search - sha256: "36e213d66e38c3494321177a80b65f6b420068e54eaf9978cb312da97e4af250" - url: "https://pub.dev" - source: hosted - version: "1.0.2" - mapbox_search: - dependency: "direct main" - description: - name: mapbox_search - sha256: "6606ab1af8f34a22b5b096d6037d95117e4b51d48c63161d817130c91c736e7e" - url: "https://pub.dev" - source: hosted - version: "4.2.2" matcher: dependency: transitive description: @@ -512,14 +464,6 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" - rxdart: - dependency: transitive - description: - name: rxdart - sha256: "0c7c0cedd93788d996e33041ffecda924cc54389199cde4e6a34b440f50044cb" - url: "https://pub.dev" - source: hosted - version: "0.27.7" shared_preferences: dependency: "direct main" description: @@ -589,14 +533,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.10.0" - sprintf: - dependency: transitive - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" - url: "https://pub.dev" - source: hosted - version: "7.0.0" stack_trace: dependency: transitive description: @@ -653,14 +589,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.2" - uuid: - dependency: transitive - description: - name: uuid - sha256: "83d37c7ad7aaf9aa8e275490669535c8080377cfa7a7004c24dfac53afffaa90" - url: "https://pub.dev" - source: hosted - version: "4.4.2" vector_math: dependency: transitive description: diff --git a/covas_mobile/pubspec.yaml b/covas_mobile/pubspec.yaml index 001f36c..59db286 100644 --- a/covas_mobile/pubspec.yaml +++ b/covas_mobile/pubspec.yaml @@ -45,9 +45,6 @@ dependencies: flutter_dotenv: ^5.1.0 image_picker: ^1.1.2 date_format_field: ^0.1.0 - mapbox_search: ^4.2.2 - mapbox_place_search: ^1.0.2 - google_places_autocomplete_text_field: ^0.1.3 dev_dependencies: flutter_test: From 80dc1155c2e2dd843f4b318b24d2cf6b88e46e98 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Fri, 30 Aug 2024 23:28:08 +0200 Subject: [PATCH 22/28] remove useless variable --- covas_mobile/lib/pages/UpdateEventImage.dart | 3 --- 1 file changed, 3 deletions(-) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index d645afc..7c7b7ab 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -164,9 +164,6 @@ class _UpdateeventImageState extends State } void start() async { - await dotenv.load(); - GOOGLEMAP_API_KEY = dotenv.env['GOOGLEMAP_API_KEY']!; - inputName.text = widget.events["name"]; inputPlace.text = widget.events["place"]; print("date start : ${widget.events["date"]}"); From 70d18ea9806760d7d04fab5c943f0f32a54ffac6 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Fri, 30 Aug 2024 23:57:10 +0200 Subject: [PATCH 23/28] more precision place --- .../lib/pages/DisplayPictureScreen.dart | 2 +- covas_mobile/lib/pages/UpdateEventImage.dart | 57 +++++++++++++++++-- 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index bc4424b..0543f90 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -131,7 +131,7 @@ class DisplayPictureScreenState extends State gemini .textAndImage( text: - "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, place, date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère", + "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, address, city, zip_code, country, date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère", images: [file.readAsBytesSync()], modelName: "models/gemini-1.5-pro-latest") .then((value) => searchEvents(value?.content?.parts?.last.text ?? '')) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 7c7b7ab..fe1e2c3 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -42,7 +42,12 @@ class UpdateeventImage extends StatefulWidget { class _UpdateeventImageState extends State with ShowErrorDialog, ShowEventDialog { TextEditingController inputName = TextEditingController(); - TextEditingController inputPlace = TextEditingController(); + TextEditingController inputAddress = TextEditingController(); + TextEditingController inputZipCode = TextEditingController(); + + TextEditingController inputCity = TextEditingController(); + TextEditingController inputCountry = TextEditingController(); + TextEditingController inputDate = TextEditingController(); TextEditingController startDatepicker = TextEditingController(); TextEditingController startTimepicker = TextEditingController(); @@ -85,7 +90,7 @@ class _UpdateeventImageState extends State Future _updateEvent(BuildContext context) async { var url = Uri.parse("${globals.api}/token"); var name = inputName.text; - var place = inputPlace.text; + var place = inputCity.text; SharedPreferences prefs = await SharedPreferences.getInstance(); var accessToken = prefs.getString("access_token") ?? ""; List send = ["toto"]; @@ -165,7 +170,11 @@ class _UpdateeventImageState extends State void start() async { inputName.text = widget.events["name"]; - inputPlace.text = widget.events["place"]; + inputCity.text = widget.events["city"]; + inputAddress.text = widget.events["address"]; + inputZipCode.text = widget.events["zip_code"]; + inputCountry.text = widget.events["country"]; + print("date start : ${widget.events["date"]}"); DateTime pickedDate = DateTime.parse(widget.events["date"]); startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); @@ -220,11 +229,47 @@ class _UpdateeventImageState extends State left: 15.0, right: 15.0, top: 15, bottom: 0), //padding: EdgeInsets.symmetric(horizontal: 15), child: TextField( - controller: inputPlace, + controller: inputAddress, decoration: InputDecoration( border: OutlineInputBorder(), - labelText: 'Lieu', - hintText: 'Entrer le lieu'), + labelText: 'Adresse', + hintText: 'Entrer une adresse'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputZipCode, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Code postal', + hintText: 'Entrer un code postal'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputCity, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Ville', + hintText: 'Entrer une ville'), + ), + ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputCountry, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Pays', + hintText: 'Entrer un pays'), ), ), Padding( From 99fbdfae8918e2df1c38957c9e1d6a6af13d97b5 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 1 Sep 2024 22:27:18 +0200 Subject: [PATCH 24/28] add image in update image --- covas_mobile/lib/pages/DisplayPictureScreen.dart | 8 +++++--- covas_mobile/lib/pages/UpdateEventImage.dart | 10 +++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index 0543f90..a2ac462 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -84,7 +84,7 @@ class DisplayPictureScreenState extends State "L'IA de Google n'a pas su analyser l'image. Recommecer avec une autre"); } - Future searchEvents(String json) async { + Future searchEvents(String json, String imagePath) async { print(json); SharedPreferences prefs = await SharedPreferences.getInstance(); @@ -105,7 +105,8 @@ class DisplayPictureScreenState extends State Navigator.push( context, MaterialPageRoute( - builder: (_) => UpdateeventImage(events: jsonData))); + builder: (_) => UpdateeventImage( + events: jsonData, imagePath: imagePath))); } else { Navigator.push( context, @@ -134,7 +135,8 @@ class DisplayPictureScreenState extends State "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, address, city, zip_code, country, date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère", images: [file.readAsBytesSync()], modelName: "models/gemini-1.5-pro-latest") - .then((value) => searchEvents(value?.content?.parts?.last.text ?? '')) + .then((value) => searchEvents( + value?.content?.parts?.last.text ?? '', widget.imagePath)) .catchError((e) => displayError); } diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index fe1e2c3..41a38f8 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -22,18 +22,22 @@ void main() { class MyApp extends StatelessWidget { Map events = {}; + String imagePath = ""; @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, - home: UpdateeventImage(events: events), + home: UpdateeventImage(events: events, imagePath: imagePath), ); } } class UpdateeventImage extends StatefulWidget { - const UpdateeventImage({Key? key, required this.events}) : super(key: key); + const UpdateeventImage( + {Key? key, required this.events, required this.imagePath}) + : super(key: key); final Map events; + final String imagePath; @override _UpdateeventImageState createState() => _UpdateeventImageState(); @@ -210,7 +214,7 @@ class _UpdateeventImageState extends State decoration: BoxDecoration( color: Colors.red, borderRadius: BorderRadius.circular(50.0)), - child: Image.asset('./images/flutter.png')), + child: Image.file(File(widget.imagePath))), ), ), Padding( From 6dfa0aa9ce5bb03c2aeae648927fad0bca34a0b6 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 1 Sep 2024 22:57:16 +0200 Subject: [PATCH 25/28] add description more --- .../lib/pages/DisplayPictureScreen.dart | 2 +- covas_mobile/lib/pages/UpdateEventImage.dart | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index a2ac462..451fa08 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -132,7 +132,7 @@ class DisplayPictureScreenState extends State gemini .textAndImage( text: - "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, address, city, zip_code, country, date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère", + "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, address, city, zip_code, country, description, date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère", images: [file.readAsBytesSync()], modelName: "models/gemini-1.5-pro-latest") .then((value) => searchEvents( diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 41a38f8..09ac912 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -53,6 +53,8 @@ class _UpdateeventImageState extends State TextEditingController inputCountry = TextEditingController(); TextEditingController inputDate = TextEditingController(); + TextEditingController inputDesc = TextEditingController(); + TextEditingController startDatepicker = TextEditingController(); TextEditingController startTimepicker = TextEditingController(); TextEditingController endDatepicker = TextEditingController(); @@ -178,6 +180,7 @@ class _UpdateeventImageState extends State inputAddress.text = widget.events["address"]; inputZipCode.text = widget.events["zip_code"]; inputCountry.text = widget.events["country"]; + inputDesc.text = widget.events["description"]; print("date start : ${widget.events["date"]}"); DateTime pickedDate = DateTime.parse(widget.events["date"]); @@ -332,6 +335,20 @@ class _UpdateeventImageState extends State onTap: () => onTapFunctionTimePicker( context: context, position: "end")), ), + Padding( + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 15, bottom: 0), + //padding: EdgeInsets.symmetric(horizontal: 15), + child: TextField( + controller: inputDesc, + keyboardType: TextInputType.multiline, + maxLines: 10, + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Description', + hintText: 'Décrire l\'evènement'), + ), + ), SizedBox( height: 30, ), From a120cd28a1d6c45ef1fc9db9737ea68cbd3f2276 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Sun, 1 Sep 2024 23:03:18 +0200 Subject: [PATCH 26/28] remove red border --- covas_mobile/lib/pages/UpdateEventImage.dart | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 09ac912..199c0b3 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -215,8 +215,7 @@ class _UpdateeventImageState extends State width: 200, height: 150, decoration: BoxDecoration( - color: Colors.red, - borderRadius: BorderRadius.circular(50.0)), + borderRadius: BorderRadius.circular(100.0)), child: Image.file(File(widget.imagePath))), ), ), From 1118a3c100a1d159facf8c65795a4a813c13c0ce Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Mon, 2 Sep 2024 22:25:46 +0200 Subject: [PATCH 27/28] add start_date and end_date --- .../lib/pages/DisplayPictureScreen.dart | 2 +- covas_mobile/lib/pages/UpdateEventImage.dart | 26 +++++++------------ covas_mobile/pubspec.lock | 24 ++++++++--------- 3 files changed, 23 insertions(+), 29 deletions(-) diff --git a/covas_mobile/lib/pages/DisplayPictureScreen.dart b/covas_mobile/lib/pages/DisplayPictureScreen.dart index 451fa08..9815034 100644 --- a/covas_mobile/lib/pages/DisplayPictureScreen.dart +++ b/covas_mobile/lib/pages/DisplayPictureScreen.dart @@ -132,7 +132,7 @@ class DisplayPictureScreenState extends State gemini .textAndImage( text: - "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, address, city, zip_code, country, description, date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère", + "Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, address, city, zip_code, country, description, start_date et end_date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère", images: [file.readAsBytesSync()], modelName: "models/gemini-1.5-pro-latest") .then((value) => searchEvents( diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 199c0b3..38b1248 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -1,16 +1,11 @@ import 'package:flutter/material.dart'; -import 'package:flutter/widgets.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import 'package:intl/intl.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'dart:convert'; import 'dart:io'; -//import 'MyHomePage.dart'; -import 'ListItemMenu.dart'; - import '../classes/alert.dart'; import '../classes/eventAdded.dart'; @@ -60,8 +55,6 @@ class _UpdateeventImageState extends State TextEditingController endDatepicker = TextEditingController(); TextEditingController endTimepicker = TextEditingController(); - String GOOGLEMAP_API_KEY = ""; - onTapFunctionDatePicker( {required BuildContext context, required String position}) async { DateTime? pickedDate = await showDatePicker( @@ -115,8 +108,8 @@ class _UpdateeventImageState extends State body: jsonEncode({ 'name': name, 'place': place, - 'start_date': widget.events["date"], - 'end_date': widget.events['date'], + 'start_date': widget.events["start_date"], + 'end_date': widget.events['end_date'], 'organizers': send, 'latitude': '0.0', 'longitude': '0.0', @@ -182,12 +175,13 @@ class _UpdateeventImageState extends State inputCountry.text = widget.events["country"]; inputDesc.text = widget.events["description"]; - print("date start : ${widget.events["date"]}"); - DateTime pickedDate = DateTime.parse(widget.events["date"]); - startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); - endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate); - startTimepicker.text = DateFormat("HH-mm").format(pickedDate); - endTimepicker.text = DateFormat("HH-mm").format(pickedDate); + DateTime pickedStartDate = DateTime.parse(widget.events["start_date"]); + DateTime pickedEndDate = DateTime.parse(widget.events["end_date"]); + + startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedStartDate); + endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedEndDate); + startTimepicker.text = DateFormat("HH-mm").format(pickedStartDate); + endTimepicker.text = DateFormat("HH-mm").format(pickedEndDate); } @override @@ -201,7 +195,7 @@ class _UpdateeventImageState extends State return Scaffold( backgroundColor: Colors.white, appBar: AppBar( - title: Text("Login Page"), + title: Text("Add or Update a event"), backgroundColor: Colors.blue, foregroundColor: Colors.white, ), diff --git a/covas_mobile/pubspec.lock b/covas_mobile/pubspec.lock index 0527810..e3c01b0 100644 --- a/covas_mobile/pubspec.lock +++ b/covas_mobile/pubspec.lock @@ -332,18 +332,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -372,18 +372,18 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" meta: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" mime: dependency: transitive description: @@ -577,10 +577,10 @@ packages: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" typed_data: dependency: transitive description: @@ -601,10 +601,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d" url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.5" web: dependency: transitive description: From a2cc6baa802aff3607de812859cc9628012741e0 Mon Sep 17 00:00:00 2001 From: Valentin CZERYBA Date: Tue, 3 Sep 2024 15:54:37 +0200 Subject: [PATCH 28/28] more detail for a event --- covas_mobile/lib/pages/UpdateEventImage.dart | 31 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/covas_mobile/lib/pages/UpdateEventImage.dart b/covas_mobile/lib/pages/UpdateEventImage.dart index 38b1248..d770ab3 100644 --- a/covas_mobile/lib/pages/UpdateEventImage.dart +++ b/covas_mobile/lib/pages/UpdateEventImage.dart @@ -86,10 +86,31 @@ class _UpdateeventImageState extends State } } + 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 _updateEvent(BuildContext context) async { var url = Uri.parse("${globals.api}/token"); var name = inputName.text; - var place = inputCity.text; + var place = inputAddress.text; + var city = inputCity.text; + var country = inputCountry.text; + var zipCode = inputZipCode.text; + var description = inputDesc.text; + + var startDateFormat = formatDate(startDatepicker.text); + var endDateFormat = formatDate(endDatepicker.text); + var startDate = + "${startDateFormat}T${startTimepicker.text.replaceAll('-', ':')}"; + var endDate = "${endDateFormat}T${endTimepicker.text.replaceAll('-', ':')}"; + print("start date : ${startDate}"); + print("end date : ${endDate}"); SharedPreferences prefs = await SharedPreferences.getInstance(); var accessToken = prefs.getString("access_token") ?? ""; List send = ["toto"]; @@ -108,11 +129,15 @@ class _UpdateeventImageState extends State body: jsonEncode({ 'name': name, 'place': place, - 'start_date': widget.events["start_date"], - 'end_date': widget.events['end_date'], + 'start_date': startDate, + 'end_date': endDate, + 'zip_code': zipCode, + 'country': country, + 'city': city, 'organizers': send, 'latitude': '0.0', 'longitude': '0.0', + 'description': description })); print(responsePut.statusCode); if ((responsePut.statusCode == 200) ||