diff --git a/activmindback/activmind_backup_file.sql b/activmindback/activmind_backup_file.sql index 4cbac00..81407bd 100644 Binary files a/activmindback/activmind_backup_file.sql and b/activmindback/activmind_backup_file.sql differ diff --git a/activmindback/users/urls.py b/activmindback/users/urls.py index ddb1bdb..137286e 100644 --- a/activmindback/users/urls.py +++ b/activmindback/users/urls.py @@ -1,7 +1,7 @@ from django.urls import path from rest_framework_nested import routers # from .views import register_user, login_user, update_password, RegisterUser -from .views import AssociateUserViewSet, RegisterUserViewSet, AuthViewSet, check_token, get_csrf_token +from .views import AssociateUserViewSet, RegisterUserViewSet, AuthViewSet, check_token, get_csrf_token, forgot_password router = routers.DefaultRouter() @@ -15,5 +15,6 @@ urlpatterns = urlpatterns + [ path('check_token/', check_token, name='check_token'), path('csrf_token/', get_csrf_token, name='csrf_token'), + path('forgot_password/', forgot_password, name='forgot_password'), ] diff --git a/activmindback/users/views.py b/activmindback/users/views.py index 840916e..197398d 100644 --- a/activmindback/users/views.py +++ b/activmindback/users/views.py @@ -1,4 +1,5 @@ import logging +import re from django.forms import ValidationError from rest_framework import status from rest_framework.response import Response @@ -90,6 +91,25 @@ def get_csrf_token(request): return JsonResponse({'csrfToken': token}) +@api_view(['POST']) +def forgot_password(request): + email = request.data.get('email') + new_password = request.data.get('password') + if not email: + return JsonResponse({'error': 'Email and password required'}, status=400) + if not User.objects.filter(email=email).exists(): + return JsonResponse({'error': 'No user found with this email'}, status=400) + else : + user = User.objects.filter(email=email).first() + regex = r"^[^\s]{8,}$" + password_regex = re.compile(regex) + if re.match(password_regex, new_password) is None: + return JsonResponse({'error': 'Password must be at least 8 characters long'}, status=400) + user.set_password(new_password) + user.save() + return JsonResponse({'message': 'Password reset successfully'}, status=200) + + # API endpoints to associate and dissociate users class AssociateUserViewSet(viewsets.ViewSet): diff --git a/lib/Screens/Calendar.dart b/lib/Screens/Calendar.dart index 32cce4e..dcd43cb 100644 --- a/lib/Screens/Calendar.dart +++ b/lib/Screens/Calendar.dart @@ -1,9 +1,21 @@ +import 'dart:convert'; import 'package:activmind_app/Screens/HomeForm.dart'; import 'package:activmind_app/Screens/appsettingpage.dart'; import 'package:activmind_app/Screens/locationList.dart'; import 'package:activmind_app/Screens/tasklist.dart'; import 'package:activmind_app/common/appandfooterbar.dart'; import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'package:shared_preferences/shared_preferences.dart'; +import '../common/csrf.dart'; +import '../common/task_class.dart'; +import 'package:intl/intl.dart'; +import 'package:logger/logger.dart'; + +var logger = Logger( + level: Level.all +); + class Calendar extends StatefulWidget { @@ -13,161 +25,197 @@ class Calendar extends StatefulWidget { State createState() => __CalendarState(); } + + + + class __CalendarState extends State { - + + DateTime selectedDay = DateTime.now(); + String selectedDayFormatted = DateFormat('yyyy-MM-dd').format(DateTime.now()); + + void _selectDay(DateTime day) { + setState(() { + selectedDay = day; + selectedDayFormatted = DateFormat('yyyy-MM-dd').format(selectedDay); + }); + fetchTasks(selectedDayFormatted); + } + final _formKey = GlobalKey(); - final List> items = [ - { - "title": "médicament", - "description": "n'oubliez pas de prendre de médicament" - }, - { - "title": "visit le médecin", - "description": "n'oubliez pas aller chez médecin" - }, - { - "title": "médicament", - "description": - "n'oubliez pas de prendre de médicament, n'oubliez pas de prendre de médicament,n'oubliez pas de prendre de médicament,n'oubliez pas de prendre de médicament,n'oubliez pas de prendre de médicament," - }, - { - "title": "visit le médecin", - "description": "n'oubliez pas aller chez médecin" - }, - ]; - - void showFormDialog(BuildContext context, GlobalKey formKey) { - showDialog( - context: context, - builder: (BuildContext context) { - return AlertDialog(backgroundColor: const Color.fromARGB(255, 209, 193, 238), - content: Stack( - clipBehavior: Clip.none, - children: [ - Positioned( - right: -40, - top: -40, - child: InkResponse( - onTap: () { - Navigator.of(context).pop(); - }, - child: const CircleAvatar( - backgroundColor: Colors.red, - child: Icon(Icons.close), - ), - ), - ), - Form( - key: _formKey, - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const Padding( - padding: EdgeInsets.all(8), - child: Text( - 'Nom de l’activité', - textAlign: TextAlign.left, - style: TextStyle( - fontSize: 16.0, - color: Color.fromARGB(255, 23, 79, 124), - ), - ), - ), - const Padding( - padding: EdgeInsets.all(8), - child: TextField( - keyboardType: TextInputType.multiline, - maxLines: null, - decoration: InputDecoration( - hintText: - 'Veuillez entrer un nom de l\'activité ', - border: OutlineInputBorder(), - fillColor: - Color.fromARGB(255, 232, 217, 255), - filled: true, - ), - ), - ), - const Padding( - padding: EdgeInsets.all(8), - child: Text( - 'Description (optionnel)', - textAlign: TextAlign.left, - style: TextStyle( - fontSize: 16.0, - color: Color.fromARGB(255, 23, 79, 124), - ), - ), - ), - const Padding( - padding: EdgeInsets.all(8), - child: TextField( - keyboardType: TextInputType.multiline, - maxLines: 3, - decoration: InputDecoration( - hintText: - 'Si vous voulez, vous pouvez entrer votre description (c\'est optionnel)', - border: OutlineInputBorder(), - fillColor: - Color.fromARGB(255, 232, 217, 255), - filled: true, - ), - ), - ), - Row( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.only( - left: 10, top: 10), - child: ElevatedButton( - style: ElevatedButton.styleFrom( - foregroundColor: const Color.fromARGB( - 255, 255, 255, 255), backgroundColor: const Color.fromARGB(255, 65, 64, 155), - ), - onPressed: () { - if (_formKey.currentState! - .validate()) { - _formKey.currentState!.save(); - Navigator.of(context).pop(); - } - }, - child: const Text('Annuler'), - ), - ), - const Spacer(), - Padding( - padding: const EdgeInsets.only(top: 10), - child: ElevatedButton( - style: ElevatedButton.styleFrom( - foregroundColor: const Color.fromARGB(255, 44, 41, 223), backgroundColor: const Color.fromARGB(255, 255, 181, 70), - ), - onPressed: () { - if (_formKey.currentState! - .validate()) { - _formKey.currentState!.save(); - } - }, - child: const Text('Enregistrer'), - ), - ), - ], - ), - ], - ), - ), - ], - ), - ); - }, - ); -} + List items = []; + + // on charge les tâches de la date du jour lors de l'initialisation du calendrier + @override + void initState() { + super.initState(); + final DateTime now = DateTime.now(); + final DateFormat formatter = DateFormat('yyyy-MM-dd'); + final String formattedDate = formatter.format(now); + fetchTasks(formattedDate); + } + + Future fetchTasks(String date) async { + + SharedPreferences prefs = await SharedPreferences.getInstance(); + final token = prefs.getString('token'); + final csrfToken = await fetchCSRFToken(); + final response = await http.get( + Uri.parse('http://10.0.2.2:8000/tasks/?date=$date'), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + 'Authorization': 'Token $token', + 'X-CSRFToken': csrfToken, + } + ); + + if (response.statusCode == 200) { + final jsonBody = jsonDecode(response.body); + final tasks = jsonBody as List; + + List taskList = tasks.map((task) => Task.fromJson(task)).toList(); + + setState(() { + items = taskList; + }); + } else { + throw Exception('Failed to load tasks'); + } + } + + + // void showFormDialog(BuildContext context, GlobalKey formKey) { + // showDialog( + // context: context, + // builder: (BuildContext context) { + // return AlertDialog(backgroundColor: const Color.fromARGB(255, 209, 193, 238), + // content: Stack( + // clipBehavior: Clip.none, + // children: [ + // Positioned( + // right: -40, + // top: -40, + // child: InkResponse( + // onTap: () { + // Navigator.of(context).pop(); + // }, + // child: const CircleAvatar( + // backgroundColor: Colors.red, + // child: Icon(Icons.close), + // ), + // ), + // ), + // Form( + // key: _formKey, + // child: Column( + // mainAxisSize: MainAxisSize.min, + // crossAxisAlignment: CrossAxisAlignment.start, + // children: [ + // const Padding( + // padding: EdgeInsets.all(8), + // child: Text( + // 'Nom de l’activité', + // textAlign: TextAlign.left, + // style: TextStyle( + // fontSize: 16.0, + // color: Color.fromARGB(255, 23, 79, 124), + // ), + // ), + // ), + // const Padding( + // padding: EdgeInsets.all(8), + // child: TextField( + // keyboardType: TextInputType.multiline, + // maxLines: null, + // decoration: InputDecoration( + // hintText: + // 'Veuillez entrer un nom de l\'activité ', + // border: OutlineInputBorder(), + // fillColor: + // Color.fromARGB(255, 232, 217, 255), + // filled: true, + // ), + // ), + // ), + // const Padding( + // padding: EdgeInsets.all(8), + // child: Text( + // 'Description (optionnel)', + // textAlign: TextAlign.left, + // style: TextStyle( + // fontSize: 16.0, + // color: Color.fromARGB(255, 23, 79, 124), + // ), + // ), + // ), + // const Padding( + // padding: EdgeInsets.all(8), + // child: TextField( + // keyboardType: TextInputType.multiline, + // maxLines: 3, + // decoration: InputDecoration( + // hintText: + // 'Si vous voulez, vous pouvez entrer votre description (c\'est optionnel)', + // border: OutlineInputBorder(), + // fillColor: + // Color.fromARGB(255, 232, 217, 255), + // filled: true, + // ), + // ), + // ), + // Row( + // crossAxisAlignment: CrossAxisAlignment.center, + // children: [ + // Padding( + // padding: const EdgeInsets.only( + // left: 10, top: 10), + // child: ElevatedButton( + // style: ElevatedButton.styleFrom( + // foregroundColor: const Color.fromARGB( + // 255, 255, 255, 255), backgroundColor: const Color.fromARGB(255, 65, 64, 155), + // ), + // onPressed: () { + // if (_formKey.currentState! + // .validate()) { + // _formKey.currentState!.save(); + // Navigator.of(context).pop(); + // } + // }, + // child: const Text('Annuler'), + // ), + // ), + // const Spacer(), + // Padding( + // padding: const EdgeInsets.only(top: 10), + // child: ElevatedButton( + // style: ElevatedButton.styleFrom( + // foregroundColor: const Color.fromARGB(255, 44, 41, 223), backgroundColor: const Color.fromARGB(255, 255, 181, 70), + // ), + // onPressed: () { + // if (_formKey.currentState! + // .validate()) { + // _formKey.currentState!.save(); + // } + // }, + // child: const Text('Enregistrer'), + // ), + // ), + // ], + // ), + // ], + // ), + // ), + // ], + // ), + // ); + // }, + // ); + // } int _currentIndex = 1; - void _onItemTapped(int index) { + void _onItemTapped(int index) { if (index == 0) { Navigator.pushReplacement( context, @@ -208,11 +256,10 @@ class __CalendarState extends State { }); } - - + @override Widget build(BuildContext context) { - Widget currentPage; + Widget currentPage; switch (_currentIndex) { case 0: currentPage = const TaskList(); @@ -223,7 +270,7 @@ class __CalendarState extends State { case 2: currentPage = const HomeForm(); break; - case 3: + case 3: currentPage = const LocationList(); break; default: @@ -231,13 +278,13 @@ class __CalendarState extends State { } return Scaffold( appBar: const MyAppBar(), - + body: SingleChildScrollView( child: Column( children: [ - const Text( - 'Emploi du temps de la semaine', - style: TextStyle( + Text( + 'Emploi du temps du $selectedDayFormatted', + style: const TextStyle( fontWeight: FontWeight.bold, fontSize: 20, fontFamily: 'Arial', @@ -245,47 +292,52 @@ class __CalendarState extends State { ), Row( children: [ - const Padding( - padding: EdgeInsets.only(top: 8.0, left: 5), - child: Text( - 'passer à votre emploi du temps de la journée', - style: TextStyle(fontSize: 18), - ), + Padding( + padding: const EdgeInsets.only(top: 8.0, left: 5), + child: ElevatedButton( + onPressed: () { + _selectDay(DateTime(selectedDay.year, selectedDay.month, selectedDay.day - 1)); + }, + child: const Text('<'), + ) + ), const Spacer(), Padding( - padding: const EdgeInsets.only(right: 5), - child: ElevatedButton( - style: ElevatedButton.styleFrom( - foregroundColor: const Color.fromARGB(255, 255, 255, 255), backgroundColor: const Color.fromARGB(255, 240, 169, 37), - ), - onPressed: () {}, - child: const Text('jour'), - ), + padding: const EdgeInsets.only(top: 8.0, left: 5), + child: ElevatedButton( + onPressed: () { + _selectDay(DateTime(selectedDay.year, selectedDay.month, selectedDay.day + 1)); + }, + child: const Text('>'), + ) + ), ], ), ListView.builder( shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), + physics: const AlwaysScrollableScrollPhysics(), itemCount: items.length, itemBuilder: (context, index) { return Card( elevation: 5, - margin: const EdgeInsets.all(5), + margin: const EdgeInsets.all(10), child: ListTile( - title: Text(items[index]["title"]!), - subtitle: Text(items[index]["description"]!), + leading: Text(items[index].startTime.format(context)), + title: Text(items[index].title), + subtitle: Text(items[index].discription), + trailing: items[index].endTime == null ? null : Text(items[index].endTime!.format(context)), onTap: () => showDialog( context: context, builder: (context) => AlertDialog( - title: Text(items[index]["title"]!), - content: Text(items[index]["description"]!), + title: Text(items[index].title), + content: Text(items[index].discription), actions: [ - TextButton( - child: const Text('Modifier'), - onPressed: () => showFormDialog(context, _formKey), - ), + // TextButton( + // // child: const Text('Modifier'), + // // onPressed: () => showFormDialog(context, _formKey), + // ), TextButton( child: const Text('ّFermer'), onPressed: () => Navigator.of(context).pop(), @@ -297,13 +349,15 @@ class __CalendarState extends State { ); }, ), - Padding( - padding: const EdgeInsets.only(top: 8), - child: FloatingActionButton( - onPressed: () => showFormDialog(context, _formKey), - child: const Icon(Icons.add), - ), - ), + // Padding( + // padding: const EdgeInsets.only(top: 8), + // child: FloatingActionButton( + // onPressed: () => showFormDialog(context, _formKey), + // child: const Icon(Icons.add), + // ), + + + // ), ], ), ), @@ -343,5 +397,5 @@ class __CalendarState extends State { // ), ); } - -} \ No newline at end of file + +} diff --git a/lib/Screens/forgot_password.dart b/lib/Screens/forgot_password.dart new file mode 100644 index 0000000..4b33a14 --- /dev/null +++ b/lib/Screens/forgot_password.dart @@ -0,0 +1,167 @@ +// ignore_for_file: avoid_print +import 'package:activmind_app/Screens/login_form.dart'; +import 'package:activmind_app/common/gen_text_form_field.dart'; +import 'package:flutter/material.dart'; +import 'package:http/http.dart' as http; +import 'dart:convert'; + +class ForgotPasswordForm extends StatefulWidget { + const ForgotPasswordForm({super.key}); + + @override + State createState() => _ForgotPasswordFormState(); +} + +class _ForgotPasswordFormState extends State { + final _conemail = TextEditingController(); + final _conpassword = TextEditingController(); + final _conconfpassword = TextEditingController(); + + Future resetPassword() async { + if (_conpassword.text != _conconfpassword.text) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Les mots de passe ne correspondent pas.'), + backgroundColor: Colors.red, + ), + ); + return false; + } + + try { + final response = await http.post( + Uri.parse("http://10.0.2.2:8000/forgot_password/"), + headers: { + 'Content-Type': 'application/json; charset=UTF-8', + }, + body: jsonEncode({ + 'email': _conemail.text, + 'password': _conpassword.text, + }), + ); + + if (response.statusCode == 200 || response.statusCode == 201) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Réinitialisation du mot de passe réussie.'), + backgroundColor: Colors.green, + ), + ); + return true; + } + else { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text('Erreur lors de la réinitialisation du mot de passe: ${response.statusCode}'), + backgroundColor: Colors.red, + ), + ); + return false; + } + } catch (e) { + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Une erreur s\'est produite. Veuillez réessayer plus tard.'), + backgroundColor: Colors.red, + ), + ); + return false; + } + } + + void onResetPasswordSuccess(BuildContext context) { + if (mounted) { + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => const LoginForm()), + ); + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + backgroundColor: const Color.fromARGB(255, 139, 140, 242), + ), + backgroundColor: const Color.fromARGB(255, 139, 140, 242), + body: SingleChildScrollView( + scrollDirection: Axis.vertical, + child: Container( + color: const Color.fromARGB(255, 139, 140, 242), + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const SizedBox(height: 10.0), + Image.asset( + '././assets/images/logo.png', + height: 100.0, + width: 100.0, + ), + const SizedBox(height: 10.0), + const Text( + 'Reinitialiser le mot de passe', + style: TextStyle( + fontWeight: FontWeight.bold, + color: Colors.white, + fontSize: 25.0), + ), + const SizedBox(height: 30.0), + GetTextFormField( + controller: _conemail, + icon: Icons.person, + hintName: 'Email', + inputtype: TextInputType.text), + const SizedBox(height: 5.0), + GetTextFormField( + controller: _conpassword, + icon: Icons.lock, + hintName: 'mot de passe', + isObscureText: true, + ), + const SizedBox(height: 5.0), + GetTextFormField( + controller: _conconfpassword, + icon: Icons.lock, + hintName: 'confirmer mot de passe', + isObscureText: true, + ), + const SizedBox(height: 20.0), + TextButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const LoginForm()), + ); + }, + child: const Text('Retourner à la page de connexion'), + ), + Container( + margin: const EdgeInsets.all(30.0), + width: double.infinity, + decoration: BoxDecoration( + color: const Color.fromARGB(255, 76, 77, 166), + borderRadius: BorderRadius.circular(30.0)), + child: TextButton( + onPressed: () async { + if (await resetPassword()) { + await Future.delayed(const Duration(seconds: 1)); // Attendez 1 seconde + onResetPasswordSuccess(context); // Redirigez vers LoginForm uniquement si la réinitialisation du mot de passe a réussi + } + }, + child: const Text( + 'Reinitialiser le mot de passe', + style: TextStyle( + color: Color.fromARGB(255, 197, 198, 243)), + ), + ), + ), + ], + ), + ), + ), + ), + ); + } +} diff --git a/lib/Screens/login_form.dart b/lib/Screens/login_form.dart index 3bc7de0..af35d8d 100644 --- a/lib/Screens/login_form.dart +++ b/lib/Screens/login_form.dart @@ -11,6 +11,7 @@ import 'dart:convert'; import 'package:provider/provider.dart'; import 'package:activmind_app/common/globalvariable.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:activmind_app/Screens/forgot_password.dart'; class LoginForm extends StatefulWidget { const LoginForm({super.key}); @@ -118,8 +119,14 @@ class _LoginFormState extends State { hintName: 'mot de passe', isObscureText: true, ), - Container( - child: const Center(child: Text('mot de pass oublié')), + TextButton( + onPressed: () { + Navigator.push( + context, + MaterialPageRoute(builder: (context) => const ForgotPasswordForm()), + ); + }, + child: Text('Mot de passe oublié ?'), ), Container( margin: const EdgeInsets.all(30.0), @@ -150,21 +157,6 @@ class _LoginFormState extends State { color: Color.fromARGB(255, 197, 198, 243)), ))), ), - Center( - child: Container( - child: TextButton( - onPressed: () { - Navigator.push( - context, - MaterialPageRoute( - builder: (_) => const Calendar())); - }, - child: const Text( - 'calendar', - style: TextStyle( - color: Color.fromARGB(255, 197, 198, 243)), - ))), - ), ], ), ), diff --git a/lib/Screens/tasklist.dart b/lib/Screens/tasklist.dart index 6201716..fc1dda5 100644 --- a/lib/Screens/tasklist.dart +++ b/lib/Screens/tasklist.dart @@ -9,11 +9,11 @@ import 'package:activmind_app/common/defftappages.dart'; import 'package:activmind_app/common/taskform.dart'; import 'package:flutter/material.dart'; import 'package:activmind_app/common/appandfooterbar.dart'; -import 'package:activmind_app/common/csrf.dart'; + import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; -import '../common/myformpage.dart'; + class TaskList extends StatefulWidget { @@ -28,24 +28,24 @@ class _TaskListState extends State { Map? currentTask; void modifyTask(Map task) { - setState(() { - currentTask = Map.from(task); // Make a copy of the task data - }); - // Open the form dialog to modify the task - _openFormDialog(context, _formKey, currentTask,false); -} + setState(() { + currentTask = Map.from(task); // Make a copy of the task data + }); + // Open the form dialog to modify the task + _openFormDialog(context, _formKey, currentTask,false); + } -void createtask({Map? task}) { - Map initialTaskData = task ?? {}; // Use provided task, or empty map if task is null - setState(() { - currentTask = Map.from(initialTaskData); // Make a copy of the task data - }); - // Open the form dialog to modify the task - _openFormDialog(context, _formKey, currentTask,true); -} + void createtask({Map? task}) { + Map initialTaskData = task ?? {}; // Use provided task, or empty map if task is null + setState(() { + currentTask = Map.from(initialTaskData); // Make a copy of the task data + }); + // Open the form dialog to modify the task + _openFormDialog(context, _formKey, currentTask,true); + } - Future updateTask(Map? taskData) async { +Future updateTask(Map? taskData) async { try { SharedPreferences prefs = await SharedPreferences.getInstance(); final token = prefs.getString('token'); diff --git a/lib/common/task_class.dart b/lib/common/task_class.dart new file mode 100644 index 0000000..ca6d4f0 --- /dev/null +++ b/lib/common/task_class.dart @@ -0,0 +1,63 @@ +import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; + +class Task { + int? id; + String title; + String discription; + DateTime doDate; + TimeOfDay startTime; + TimeOfDay? endTime; + bool repetation; + bool alarm; + bool done; + int userId; + + Task({ + this.id, + required this.title, + required this.discription, + required this.doDate, + required this.startTime, + this.endTime, + this.repetation = false, + this.alarm = false, + this.done = false, + required this.userId, + }); + + factory Task.fromJson(Map json) { + return Task( + id: json['id'], + title: json['title'], + discription: json['discription'], + doDate: DateTime.parse(json['do_date']).toLocal(), + startTime: TimeOfDay.fromDateTime( + DateFormat("HH:mm:ss").parse(json['start_time']) + ), + endTime: TimeOfDay.fromDateTime( + DateFormat("HH:mm:ss").parse(json['end_time']) + ), + repetation: json['repetation'], + alarm: json['alarm'], + done: json['done'], + userId: json['user_id'], + ); + } + + Map toJson() { + return { + 'id': id, + 'title': title, + 'discription': discription, + 'do_date': doDate.toIso8601String(), + 'start_time': startTime.toString(), + 'end_time': endTime?.toString(), + 'repetition': repetation, + 'alarm': alarm, + 'done': done, + 'user': userId, + }; + } +} + diff --git a/lib/main.dart b/lib/main.dart index d5a1c79..400ebae 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,6 +1,6 @@ //import 'package:activmind_app/Screens/inscrire.dart'; import 'dart:convert'; - +import 'package:logger/logger.dart'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:provider/provider.dart'; diff --git a/pubspec.lock b/pubspec.lock index 9e92465..4b1f030 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -69,10 +69,10 @@ packages: dependency: transitive description: name: ffi - sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" + sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.2" file: dependency: transitive description: @@ -164,10 +164,10 @@ packages: dependency: "direct main" description: name: http - sha256: a2bbf9d017fcced29139daa8ed2bba4ece450ab222871df93ca9eec6f80c34ba + sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" url: "https://pub.dev" source: hosted - version: "1.2.0" + version: "1.2.1" http_parser: dependency: transitive description: @@ -184,6 +184,38 @@ packages: url: "https://pub.dev" source: hosted version: "0.0.4" + intl: + dependency: "direct main" + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" + leak_tracker: + dependency: transitive + description: + name: leak_tracker + sha256: "78eb209deea09858f5269f5a5b02be4049535f568c07b275096836f01ea323fa" + url: "https://pub.dev" + source: hosted + version: "10.0.0" + leak_tracker_flutter_testing: + dependency: transitive + description: + name: leak_tracker_flutter_testing + sha256: b46c5e37c19120a8a01918cfaf293547f47269f7cb4b0058f21531c2465d6ef0 + url: "https://pub.dev" + source: hosted + version: "2.0.1" + leak_tracker_testing: + dependency: transitive + description: + name: leak_tracker_testing + sha256: a597f72a664dbd293f3bfc51f9ba69816f84dcd403cdac7066cb3f6003f3ab47 + url: "https://pub.dev" + source: hosted + version: "2.0.1" lints: dependency: transitive description: @@ -192,30 +224,38 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + logger: + dependency: "direct main" + description: + name: logger + sha256: "8c94b8c219e7e50194efc8771cd0e9f10807d8d3e219af473d89b06cc2ee4e04" + url: "https://pub.dev" + source: hosted + version: "2.2.0" matcher: dependency: transitive description: name: matcher - sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb url: "https://pub.dev" source: hosted - version: "0.12.16" + version: "0.12.16+1" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" url: "https://pub.dev" source: hosted - version: "0.5.0" + version: "0.8.0" meta: dependency: transitive description: name: meta - sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04 url: "https://pub.dev" source: hosted - version: "1.10.0" + version: "1.11.0" nested: dependency: transitive description: @@ -228,10 +268,10 @@ packages: dependency: transitive description: name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" url: "https://pub.dev" source: hosted - version: "1.8.3" + version: "1.9.0" path_provider: dependency: "direct main" description: @@ -244,10 +284,10 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "477184d672607c0a3bf68fbbf601805f92ef79c82b64b4d6eb318cbca4c48668" + sha256: "51f0d2c554cfbc9d6a312ab35152fc77e2f0b758ce9f1a444a3a1e5b8f3c6b7f" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.2.3" path_provider_foundation: dependency: transitive description: @@ -348,10 +388,10 @@ packages: dependency: transitive description: name: shared_preferences_web - sha256: "7b15ffb9387ea3e237bb7a66b8a23d2147663d391cafc5c8f37b2e7b4bde5d21" + sha256: "9aee1089b36bd2aafe06582b7d7817fd317ef05fc30e6ba14bff247d0933042a" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.0" shared_preferences_windows: dependency: transitive description: @@ -360,6 +400,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.3.2" + simple_gesture_detector: + dependency: transitive + description: + name: simple_gesture_detector + sha256: ba2cd5af24ff20a0b8d609cec3f40e5b0744d2a71804a2616ae086b9c19d19a3 + url: "https://pub.dev" + source: hosted + version: "0.2.1" sky_engine: dependency: transitive description: flutter @@ -385,18 +433,18 @@ packages: dependency: "direct main" description: name: sqflite - sha256: a9016f495c927cb90557c909ff26a6d92d9bd54fc42ba92e19d4e79d61e798c6 + sha256: "5ce2e1a15e822c3b4bfb5400455775e421da7098eed8adc8f26298ada7c9308c" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.3" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: "28d8c66baee4968519fb8bd6cdbedad982d6e53359091f0b74544a9f32ec72d5" + sha256: "3da423ce7baf868be70e2c0976c28a1bb2f73644268b7ffa7d2e08eab71f16a4" url: "https://pub.dev" source: hosted - version: "2.5.3" + version: "2.5.4" stack_trace: dependency: transitive description: @@ -429,6 +477,14 @@ packages: url: "https://pub.dev" source: hosted version: "3.1.0+1" + table_calendar: + dependency: "direct main" + description: + name: table_calendar + sha256: b759eb6caa88dda8e51c70ee43c19d1682f8244458f84cced9138ee35b2ce416 + url: "https://pub.dev" + source: hosted + version: "3.1.1" term_glyph: dependency: transitive description: @@ -513,10 +569,10 @@ packages: dependency: transitive description: name: url_launcher_web - sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b + sha256: "3692a459204a33e04bc94f5fb91158faf4f2c8903281ddd82915adecdb1a901d" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.3.0" url_launcher_windows: dependency: transitive description: @@ -529,10 +585,10 @@ packages: dependency: transitive description: name: uuid - sha256: cd210a09f7c18cbe5a02511718e0334de6559871052c90a90c0cca46a4aa81c8 + sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" url: "https://pub.dev" source: hosted - version: "4.3.3" + version: "4.4.0" vector_math: dependency: transitive description: @@ -541,22 +597,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.4" + vm_service: + dependency: transitive + description: + name: vm_service + sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957 + url: "https://pub.dev" + source: hosted + version: "13.0.0" web: dependency: transitive description: name: web - sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" url: "https://pub.dev" source: hosted - version: "0.3.0" + version: "0.5.1" win32: dependency: transitive description: name: win32 - sha256: "464f5674532865248444b4c3daca12bd9bf2d7c47f759ce2617986e7229494a8" + sha256: "0a989dc7ca2bb51eac91e8fd00851297cfffd641aa7538b165c62637ca0eaa4a" url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.4.0" xdg_directories: dependency: transitive description: @@ -566,5 +630,5 @@ packages: source: hosted version: "1.0.4" sdks: - dart: ">=3.2.6 <4.0.0" - flutter: ">=3.16.6" + dart: ">=3.3.0 <4.0.0" + flutter: ">=3.19.0" diff --git a/pubspec.yaml b/pubspec.yaml index f9133d8..ce94cbb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -43,9 +43,13 @@ dependencies: provider: ^5.0.0 geolocator: ^11.0.0 url_launcher: ^6.2.5 + table_calendar: ^3.1.1 + logger: ^2.2.0 + intl: ^0.19.0 # fluttertoast: ^8.2.4 + dev_dependencies: flutter_test: sdk: flutter