diff --git a/lib/api/firebase_meal.dart b/lib/api/firebase_meal.dart index c721f21..94b2de8 100644 --- a/lib/api/firebase_meal.dart +++ b/lib/api/firebase_meal.dart @@ -10,18 +10,19 @@ class FirebaseMeal extends FirebaseAPI implements IMeal { FirebaseMeal(FirebaseFirestore db) : super(db, 'meal'); @override - void createMeal(Meal meal) { - collectionReference - .withConverter( - fromFirestore: Meal.fromFirestore, - toFirestore: (Meal meal, options) => meal.toFirestore()) - .doc(meal.uid) - .set(meal) - .then((value) => log("Meal Added")) - .catchError((error) { - log("Failed to add meal: $error"); - throw Exception(error); - }); + Future createMeal(Meal meal) async { + try { + await collectionReference + .withConverter( + fromFirestore: Meal.fromFirestore, + toFirestore: (Meal meal, options) => meal.toFirestore()) + .doc(meal.uid) + .set(meal); + log("Meal Added"); + } catch (e) { + log("Failed to add meal: $e"); + throw Exception(e); + } } @override @@ -41,15 +42,14 @@ class FirebaseMeal extends FirebaseAPI implements IMeal { } @override - void updateMeal(Meal meal) { - collectionReference - .doc(meal.uid) - .update(meal.toFirestore()) - .then((value) => log("Meal Updated")) - .catchError((error) { - log("Failed to update meal: $error"); - throw Exception(error); - }); + Future updateMeal(Meal meal) async { + try { + await collectionReference.doc(meal.uid).update(meal.toFirestore()); + log("Meal Updated"); + } catch (e) { + log("Failed to update meal: $e"); + throw Exception(e); + } } @override diff --git a/lib/api/imeal.dart b/lib/api/imeal.dart index 4d5068b..4c30d58 100644 --- a/lib/api/imeal.dart +++ b/lib/api/imeal.dart @@ -1,9 +1,9 @@ import 'package:pdg_app/model/meal.dart'; abstract class IMeal { - void createMeal(Meal meal); + Future createMeal(Meal meal); Future readMeal(String mealId); - void updateMeal(Meal meal); + Future updateMeal(Meal meal); void deleteMeal(String mealId); Future> getUsersMealForDay(String userId, DateTime day); Future> getUserMeal(String userId); diff --git a/lib/provider/meal_provider.dart b/lib/provider/meal_provider.dart index eb64377..14e6e54 100644 --- a/lib/provider/meal_provider.dart +++ b/lib/provider/meal_provider.dart @@ -38,7 +38,12 @@ class MealProvider extends ChangeNotifier { } Future addMeal(Meal meal) async { - _mealApi.createMeal(meal); + await _mealApi.createMeal(meal); + notifyListeners(); + } + + Future updateMeal(Meal meal) async { + await _mealApi.updateMeal(meal); notifyListeners(); } } diff --git a/lib/router/router.gr.dart b/lib/router/router.gr.dart index 09615d8..55f8821 100644 --- a/lib/router/router.gr.dart +++ b/lib/router/router.gr.dart @@ -122,7 +122,8 @@ class AppRouter extends _i17.RootStackRouter { final args = routeData.argsAs(); return _i17.MaterialPageX<_i23.Meal?>( routeData: routeData, - child: _i13.AddMealScreen(day: args.day, key: args.key)); + child: _i13.AddMealScreen( + day: args.day, meal: args.meal, key: args.key)); }, RegisterFirstPageRoute.name: (routeData) { return _i17.MaterialPageX( @@ -394,23 +395,26 @@ class DiaryScreenRoute extends _i17.PageRouteInfo { /// generated route for /// [_i13.AddMealScreen] class AddMealScreenRoute extends _i17.PageRouteInfo { - AddMealScreenRoute({required DateTime day, _i18.Key? key}) + AddMealScreenRoute({required DateTime day, _i23.Meal? meal, _i18.Key? key}) : super(AddMealScreenRoute.name, - path: 'add', args: AddMealScreenRouteArgs(day: day, key: key)); + path: 'add', + args: AddMealScreenRouteArgs(day: day, meal: meal, key: key)); static const String name = 'AddMealScreenRoute'; } class AddMealScreenRouteArgs { - const AddMealScreenRouteArgs({required this.day, this.key}); + const AddMealScreenRouteArgs({required this.day, this.meal, this.key}); final DateTime day; + final _i23.Meal? meal; + final _i18.Key? key; @override String toString() { - return 'AddMealScreenRouteArgs{day: $day, key: $key}'; + return 'AddMealScreenRouteArgs{day: $day, meal: $meal, key: $key}'; } } diff --git a/lib/screens/add_meal.dart b/lib/screens/add_meal.dart index 582d458..f1b898f 100644 --- a/lib/screens/add_meal.dart +++ b/lib/screens/add_meal.dart @@ -15,8 +15,11 @@ import '../widgets/slider_with_text.dart'; class AddMealScreen extends StatefulWidget { final DateTime _day; - const AddMealScreen({required DateTime day, Key? key}) + final Meal? _meal; + + const AddMealScreen({required DateTime day, Meal? meal, Key? key}) : _day = day, + _meal = meal, super(key: key); @override @@ -30,7 +33,7 @@ enum _TimeButtonEnum { } class _AddMealScreenState extends State { - double _hungerBeforeValue = 3; + double _hungerBeforeValue = 5; double _hungerAfterValue = 3; final ImagePicker _picker = ImagePicker(); XFile? _image; @@ -39,6 +42,31 @@ class _AddMealScreenState extends State { TimeOfDay? _startTime; TimeOfDay? _endTime; final TextEditingController _nameTextController = TextEditingController(); + final TextEditingController _settingsController = TextEditingController(); + final TextEditingController _commentController = TextEditingController(); + + @override + void initState() { + if (widget._meal != null) { + _nameTextController.text = widget._meal!.title; + + if (widget._meal!.setting != null) { + _settingsController.text = widget._meal!.setting!; + } + + if (widget._meal!.comment != null) { + _commentController.text = widget._meal!.comment!; + } + + _hungerBeforeValue = widget._meal!.hunger.toDouble(); + _hungerAfterValue = widget._meal!.satiety.toDouble(); + + _startTime = TimeOfDay.fromDateTime(widget._meal!.startTime); + _endTime = TimeOfDay.fromDateTime(widget._meal!.endTime); + } + + super.initState(); + } Future _takePicture() async { final XFile? image = await _picker.pickImage(source: ImageSource.camera); @@ -54,6 +82,8 @@ class _AddMealScreenState extends State { Widget build(BuildContext context) { return AddMeal( nameTextController: _nameTextController, + settingsController: _settingsController, + commentController: _commentController, hungerBeforeValue: _hungerBeforeValue, hungerAfterValue: _hungerAfterValue, onHungerAfterChanged: (value) => setState(() { @@ -125,12 +155,28 @@ class _AddMealScreenState extends State { _endTime?.hour ?? 0, _endTime?.minute ?? 0, ); + if (widget._meal == null) { + AutoRouter.of(context).pop(Meal( + title: _nameTextController.text, + startTime: selectedStartDate, + endTime: selectedEndDate, + hunger: _hungerBeforeValue.toInt(), + satiety: _hungerAfterValue.toInt(), + setting: _settingsController.text, + comment: _commentController.text, + owner: context.read().userUid, + )); + return; + } AutoRouter.of(context).pop(Meal( + uid: widget._meal!.uid, title: _nameTextController.text, startTime: selectedStartDate, endTime: selectedEndDate, - hunger: 0, - satiety: 0, + hunger: _hungerBeforeValue.toInt(), + satiety: _hungerAfterValue.toInt(), + setting: _settingsController.text, + comment: _commentController.text, owner: context.read().userUid, )); }, @@ -155,26 +201,30 @@ class AddMeal extends StatelessWidget { final String? _endTimeText; final void Function()? _onValidatePressed; final TextEditingController? _nameTextController; + final TextEditingController? _settingsController; + final TextEditingController? _commentController; - const AddMeal({ - Key? key, - required double hungerBeforeValue, - required double hungerAfterValue, - required void Function(double) onHungerBeforeChanged, - required void Function(double) onHungerAfterChanged, - required void Function() onCameraPressed, - required void Function() onGalleryPressed, - required void Function(TimeOfDay) onTimeSelected, - void Function()? onStartTimeSelected, - void Function()? onEndTimeSelected, - void Function()? onTimeSelectCanceled, - void Function()? onValidatePressed, - bool showTimePicker = false, - String? startTimeText, - String? endTimeText, - XFile? image, - TextEditingController? nameTextController, - }) : _hungerBeforeValue = hungerBeforeValue, + const AddMeal( + {Key? key, + required double hungerBeforeValue, + required double hungerAfterValue, + required void Function(double) onHungerBeforeChanged, + required void Function(double) onHungerAfterChanged, + required void Function() onCameraPressed, + required void Function() onGalleryPressed, + required void Function(TimeOfDay) onTimeSelected, + void Function()? onStartTimeSelected, + void Function()? onEndTimeSelected, + void Function()? onTimeSelectCanceled, + void Function()? onValidatePressed, + bool showTimePicker = false, + String? startTimeText, + String? endTimeText, + XFile? image, + TextEditingController? nameTextController, + TextEditingController? settingsController, + TextEditingController? commentController}) + : _hungerBeforeValue = hungerBeforeValue, _hungerAfterValue = hungerAfterValue, _onHungerAfterChanged = onHungerAfterChanged, _onHungerBeforeChanged = onHungerBeforeChanged, @@ -190,6 +240,8 @@ class AddMeal extends StatelessWidget { _endTimeText = endTimeText, _onValidatePressed = onValidatePressed, _nameTextController = nameTextController, + _settingsController = settingsController, + _commentController = commentController, super(key: key); @override @@ -207,6 +259,8 @@ class AddMeal extends StatelessWidget { Expanded( child: _ListView( nameTextController: _nameTextController, + settingsController: _settingsController, + commentController: _commentController, hungerAfterValue: _hungerAfterValue, hungerBeforeValue: _hungerBeforeValue, onHungerAfterChanged: _onHungerAfterChanged, @@ -331,19 +385,23 @@ class _ListView extends StatelessWidget { final String? _startTimeText; final String? _endTimeText; final TextEditingController? _nameTextController; + final TextEditingController? _settingsController; + final TextEditingController? _commentController; - const _ListView({ - Key? key, - required double hungerBeforeValue, - required double hungerAfterValue, - required void Function(double) onHungerBeforeChanged, - required void Function(double) onHungerAfterChanged, - void Function()? onStartTimePress, - void Function()? onEndTimePress, - String? startTimeText, - String? endTimeText, - TextEditingController? nameTextController, - }) : _hungerBeforeValue = hungerBeforeValue, + const _ListView( + {Key? key, + required double hungerBeforeValue, + required double hungerAfterValue, + required void Function(double) onHungerBeforeChanged, + required void Function(double) onHungerAfterChanged, + void Function()? onStartTimePress, + void Function()? onEndTimePress, + String? startTimeText, + String? endTimeText, + TextEditingController? nameTextController, + TextEditingController? settingsController, + TextEditingController? commentController}) + : _hungerBeforeValue = hungerBeforeValue, _hungerAfterValue = hungerAfterValue, _onHungerAfterChanged = onHungerAfterChanged, _onHungerBeforeChanged = onHungerBeforeChanged, @@ -352,6 +410,8 @@ class _ListView extends StatelessWidget { _startTimeText = startTimeText, _endTimeText = endTimeText, _nameTextController = nameTextController, + _settingsController = settingsController, + _commentController = commentController, super(key: key); List listViewContent(BuildContext context) => [ @@ -384,10 +444,12 @@ class _ListView extends StatelessWidget { value: _hungerBeforeValue, onChanged: _onHungerBeforeChanged, labels: const [ - "encore faim", - "inconfort", - "léger inconfort", - "confort" + "0 - not hungry", + "1", + "2", + "3", + "4", + "5 - really hungry" ]), SliderWithText( context: context, @@ -395,11 +457,23 @@ class _ListView extends StatelessWidget { value: _hungerAfterValue, onChanged: _onHungerAfterChanged, labels: const [ - "encore faim", - "inconfort", - "léger inconfort", - "confort" + "still hungry", + "discomfort", + "mild discomfort", + "comfort" ]), + MainTextField( + name: "Settings", + icon: const Icon(Icons.people_alt, color: Colors.black), + maxLines: null, + controller: _settingsController, + ), + MainTextField( + name: "Comments", + icon: const Icon(Icons.comment, color: Colors.black), + maxLines: null, + controller: _commentController, + ), ]; @override diff --git a/lib/screens/diary.dart b/lib/screens/diary.dart index e9a0569..551ba2f 100644 --- a/lib/screens/diary.dart +++ b/lib/screens/diary.dart @@ -40,23 +40,29 @@ class _DiaryScreenState extends State { builder: (context, child) { context.watch().meals; + MealProvider mealProvider = context.read(); return Diary( - onDaySelected: _onDaySelected, - getDiariesForDay: (day) { - return _getEventsForDay(context, day); - }, - clientName: GetIt.I.get().user!.firstName, - onAddPressed: () async { - final addedMeal = await AutoRouter.of(context) - .push(AddMealScreenRoute(day: _selectedDate)); - if (addedMeal != null) { - // ignore: use_build_context_synchronously - await context.read().addMeal(addedMeal); - // ignore: use_build_context_synchronously - context.read().fetchMeals(); - } - }, - ); + onDaySelected: _onDaySelected, + getDiariesForDay: (day) { + return _getEventsForDay(context, day); + }, + clientName: GetIt.I.get().user!.firstName, + onAddPressed: () async { + final addedMeal = await AutoRouter.of(context) + .push(AddMealScreenRoute(day: _selectedDate)); + if (addedMeal != null) { + mealProvider.addMeal(addedMeal); + mealProvider.fetchMeals(); + } + }, + onMealBlocPressed: (Meal meal) async { + final changedMeal = await AutoRouter.of(context).push( + AddMealScreenRoute(day: _selectedDate, meal: meal)); + if (changedMeal != null) { + mealProvider.updateMeal(changedMeal); + mealProvider.fetchMeals(); + } + }); }, ); } @@ -70,6 +76,7 @@ class Diary extends StatefulWidget { final String clientPicturePath; final void Function()? _onAddPressed; final void Function(DateTime)? _onDaySelected; + final void Function(Meal)? _onMealBlocPressed; const Diary({ this.screenWidth = 0, @@ -79,9 +86,11 @@ class Diary extends StatefulWidget { this.clientPicturePath = "assets/images/default_user_pic.png", void Function(DateTime)? onDaySelected, void Function()? onAddPressed, + void Function(Meal)? onMealBlocPressed, Key? key, }) : _onAddPressed = onAddPressed, _onDaySelected = onDaySelected, + _onMealBlocPressed = onMealBlocPressed, super(key: key); @override @@ -168,6 +177,7 @@ class _DiaryState extends State { child: _CalendarBody( hourFormatter: hourFormatter, meals: context.read().getMealsByDay(_selectedDay), + onMealBlocPressed: widget._onMealBlocPressed, ), ), ], @@ -183,11 +193,13 @@ class _DiaryState extends State { class _CalendarBody extends StatelessWidget { final List meals; + final void Function(Meal)? onMealBlocPressed; const _CalendarBody({ required this.meals, Key? key, required this.hourFormatter, + this.onMealBlocPressed, }) : super(key: key); final DateFormat hourFormatter; @@ -198,17 +210,22 @@ class _CalendarBody extends StatelessWidget { itemCount: meals.length, physics: const BouncingScrollPhysics(), itemBuilder: (context, index) { - return Container( - margin: const EdgeInsets.symmetric( - horizontal: 30.0, - vertical: 4.0, - ), - child: ArrowPicCard( - title: Text(meals[index].title, - style: const TextStyle(fontWeight: FontWeight.w600)), - subtitle: Text( - "${hourFormatter.format(meals[index].startTime)} - ${hourFormatter.format(meals[index].endTime)}", - style: TextStyle(color: Colors.black.withOpacity(0.6)), + return GestureDetector( + onTap: onMealBlocPressed != null + ? (() => onMealBlocPressed!(meals[index])) + : () {}, + child: Container( + margin: const EdgeInsets.symmetric( + horizontal: 30.0, + vertical: 4.0, + ), + child: ArrowPicCard( + title: Text(meals[index].title, + style: const TextStyle(fontWeight: FontWeight.w600)), + subtitle: Text( + "${hourFormatter.format(meals[index].startTime)} - ${hourFormatter.format(meals[index].endTime)}", + style: TextStyle(color: Colors.black.withOpacity(0.6)), + ), ), ), ); diff --git a/lib/screens/login.dart b/lib/screens/login.dart index 25bb4a2..2aec8f9 100644 --- a/lib/screens/login.dart +++ b/lib/screens/login.dart @@ -25,8 +25,8 @@ class _LoginScreenState extends State { @override void initState() { super.initState(); - _emailController.text = "luca.coduri@heig-vd.ch"; - _passwordController.text = "crepes"; + _emailController.text = "chloe.fontaine@heig-vd.ch"; + _passwordController.text = "crepes123"; } @override