From 4a5f2ea0eefcd0a336271f5f35b9158bc88f8c72 Mon Sep 17 00:00:00 2001 From: Jules Date: Thu, 14 Mar 2024 13:46:46 +0100 Subject: [PATCH 1/6] =?UTF-8?q?=F0=9F=9A=A7=F0=9F=92=84:=20design=20of=20p?= =?UTF-8?q?lanning=20view=20=F0=9F=91=94:=20added=20usercubit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../lib/api/events/entities/event_entity.dart | 3 + .../lib/api/events/models/event_model.dart | 1 + .../class_groups/cubit/class_group_cubit.dart | 3 - .../class_groups/views/class_group_page.dart | 3 +- .../lib/login/widgets/header/header_text.dart | 5 +- frontend/app_student/lib/routes.dart | 67 ++++++++++++++++--- .../lib/users/cubit/user_cubit.dart | 31 +++++++++ .../lib/users/cubit/user_state.dart | 20 ++++++ .../cubit/week_schedule_cubit.dart | 37 ++++++++-- .../cubit/week_schedule_state.dart | 24 ++++++- .../week_schedule/views/week_schedule.dart | 34 +++++----- .../components/app_bar_week_schedule.dart | 45 +++++++++++++ .../widgets/components/custom_appbar.dart | 23 ------- .../widgets/components/datepicker_button.dart | 48 +++++++++++-- .../views/widgets/events/event_card.dart | 19 +++++- .../views/widgets/events/event_details.dart | 2 +- 16 files changed, 292 insertions(+), 73 deletions(-) create mode 100644 frontend/app_student/lib/users/cubit/user_cubit.dart create mode 100644 frontend/app_student/lib/users/cubit/user_state.dart create mode 100644 frontend/app_student/lib/week_schedule/views/widgets/components/app_bar_week_schedule.dart delete mode 100644 frontend/app_student/lib/week_schedule/views/widgets/components/custom_appbar.dart diff --git a/frontend/app_student/lib/api/events/entities/event_entity.dart b/frontend/app_student/lib/api/events/entities/event_entity.dart index a5baeac..2390cb8 100644 --- a/frontend/app_student/lib/api/events/entities/event_entity.dart +++ b/frontend/app_student/lib/api/events/entities/event_entity.dart @@ -8,6 +8,7 @@ class EventEntity { final EventHoursEntity horaires; final String salle; final bool visio; + final bool repas; EventEntity({ required this.id, @@ -17,6 +18,7 @@ class EventEntity { required this.horaires, required this.salle, required this.visio, + required this.repas, }); factory EventEntity.fromJson(Map json) { @@ -28,6 +30,7 @@ class EventEntity { horaires: EventHoursEntity.fromJson(json['horaire']), salle: json['salle'] ?? 'null', visio: json['visio'] ?? false, + repas: json['repas'] ?? false, ); } } diff --git a/frontend/app_student/lib/api/events/models/event_model.dart b/frontend/app_student/lib/api/events/models/event_model.dart index 659d7e4..9bdaddc 100644 --- a/frontend/app_student/lib/api/events/models/event_model.dart +++ b/frontend/app_student/lib/api/events/models/event_model.dart @@ -13,4 +13,5 @@ class EventModel { EventHoursModel get horaires => EventHoursModel(entity: entity.horaires); String get salle => entity.salle; bool get visio => entity.visio; + bool get repas => entity.repas; } diff --git a/frontend/app_student/lib/class_groups/cubit/class_group_cubit.dart b/frontend/app_student/lib/class_groups/cubit/class_group_cubit.dart index 1622392..2df33fc 100644 --- a/frontend/app_student/lib/class_groups/cubit/class_group_cubit.dart +++ b/frontend/app_student/lib/class_groups/cubit/class_group_cubit.dart @@ -26,9 +26,6 @@ class ClassGroupCubit extends Cubit { } } - Future getConnectedUser() async { - return userRepository.getUser(); - } Future saveClass(ClassGroupModel classGroup) async { await userRepository.saveUserClass(classGroup.name.toString()); diff --git a/frontend/app_student/lib/class_groups/views/class_group_page.dart b/frontend/app_student/lib/class_groups/views/class_group_page.dart index 174b001..a056c98 100644 --- a/frontend/app_student/lib/class_groups/views/class_group_page.dart +++ b/frontend/app_student/lib/class_groups/views/class_group_page.dart @@ -4,6 +4,7 @@ import 'package:app_student/class_groups/views/widgets/card_list.dart'; import 'package:app_student/class_groups/views/widgets/header/header_logo.dart'; import 'package:app_student/class_groups/views/widgets/header/header_text.dart'; import 'package:app_student/class_groups/views/widgets/header/header_title.dart'; +import 'package:app_student/users/cubit/user_cubit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; @@ -25,7 +26,7 @@ class ClassGroupPage extends StatelessWidget { return BlocProvider( create: (context) => classCubit..fetchClasses(), child: FutureBuilder( - future: context.read().getConnectedUser(), + future: context.read().getConnectedUser(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); diff --git a/frontend/app_student/lib/login/widgets/header/header_text.dart b/frontend/app_student/lib/login/widgets/header/header_text.dart index 5e41d40..b6c3cd7 100644 --- a/frontend/app_student/lib/login/widgets/header/header_text.dart +++ b/frontend/app_student/lib/login/widgets/header/header_text.dart @@ -8,10 +8,7 @@ class HeaderText extends StatelessWidget { @override Widget build(BuildContext context) { return Padding( - padding: const EdgeInsets.only( - top: 35.0, - left: 25.0, - bottom: 40), // Ajout d'un espacement à gauche de 10px + padding: const EdgeInsets.only(top: 35.0, left: 25.0, bottom: 40), child: Align( alignment: Alignment.centerLeft, child: Text( diff --git a/frontend/app_student/lib/routes.dart b/frontend/app_student/lib/routes.dart index f0417d9..1acd35d 100644 --- a/frontend/app_student/lib/routes.dart +++ b/frontend/app_student/lib/routes.dart @@ -5,6 +5,7 @@ import 'package:app_student/api/users/repositories/user_repository.dart'; import 'package:app_student/api/week_schedule/repositories/week_schedule_repository.dart'; import 'package:app_student/class_groups/cubit/class_group_cubit.dart'; import 'package:app_student/config/config.dart'; +import 'package:app_student/users/cubit/user_cubit.dart'; import 'package:app_student/week_schedule/cubit/week_schedule_cubit.dart'; import 'package:app_student/week_schedule/views/week_schedule.dart'; import 'package:flutter/material.dart'; @@ -56,20 +57,64 @@ class AppRoutes { pageBuilder: (context, state) => MaterialPage( key: state.pageKey, child: MultiRepositoryProvider( - providers: [ - RepositoryProvider(create: (context) { - return WeekScheduleRepository( + providers: [ + RepositoryProvider( + create: (context) => WeekScheduleRepository( apiService: - ApiService(apiUrl: context.read().apiUrl)); - }), + ApiService(apiUrl: context.read().apiUrl))), + RepositoryProvider(create: (context) => UserRepository()), + ], + child: MultiBlocProvider( + providers: [ + BlocProvider( + create: (context) => UserCubit( + userRepository: context.read()), + ), + BlocProvider( + create: (context) => WeekScheduleCubit( + weekScheduleRepository: WeekScheduleRepository( + apiService: ApiService( + apiUrl: context.read().apiUrl)), + userRepository: context.read(), + initialDate: DateTime.now()), + ), + ], + child: const WeekSchedulePage(), + ), + ))), + GoRoute( + name: 'schedule_date', + path: '/schedule:date', + pageBuilder: (context, state) { + final date = DateTime.parse(state.pathParameters['date']!); + return MaterialPage( + key: state.pageKey, + child: MultiRepositoryProvider( + providers: [ + RepositoryProvider( + create: (context) => WeekScheduleRepository( + apiService: ApiService( + apiUrl: context.read().apiUrl))), RepositoryProvider(create: (context) => UserRepository()), ], - child: BlocProvider( - create: (context) => WeekScheduleCubit( - weekScheduleRepository: - context.read(), + child: MultiBlocProvider( + providers: [ + BlocProvider( + create: (context) => UserCubit( + userRepository: context.read()), + ), + BlocProvider( + create: (context) => WeekScheduleCubit( + weekScheduleRepository: WeekScheduleRepository( + apiService: ApiService( + apiUrl: context.read().apiUrl)), userRepository: context.read(), - ), - child: const WeekSchedulePage())))), + initialDate: DateTime.now()), + ), + ], + child: const WeekSchedulePage(), + ), + )); + }), ]; } diff --git a/frontend/app_student/lib/users/cubit/user_cubit.dart b/frontend/app_student/lib/users/cubit/user_cubit.dart new file mode 100644 index 0000000..ea45401 --- /dev/null +++ b/frontend/app_student/lib/users/cubit/user_cubit.dart @@ -0,0 +1,31 @@ +import 'package:app_student/api/users/models/user_model.dart'; +import 'package:bloc/bloc.dart'; +import 'package:meta/meta.dart'; + +import '../../api/users/repositories/user_repository.dart'; + +part 'user_state.dart'; + +class UserCubit extends Cubit { + final UserRepository userRepository; + + UserCubit({required this.userRepository}) : super(UserInitial()); + + Future fetchUser() async { + try { + emit(UserLoading()); + final user = await userRepository.getUser(); + emit(UserLoaded(user)); + } catch (e) { + emit(UserError(e.toString())); + } + } + + Future getConnectedUser() async { + return userRepository.getUser(); + } + + Future saveUserClass(String className) async { + await userRepository.saveUserClass(className); + } +} diff --git a/frontend/app_student/lib/users/cubit/user_state.dart b/frontend/app_student/lib/users/cubit/user_state.dart new file mode 100644 index 0000000..14a1c97 --- /dev/null +++ b/frontend/app_student/lib/users/cubit/user_state.dart @@ -0,0 +1,20 @@ +part of 'user_cubit.dart'; + +@immutable +abstract class UserState {} + +class UserInitial extends UserState {} + +class UserLoading extends UserState {} + +class UserLoaded extends UserState { + final UserModel user; + + UserLoaded(this.user); +} + +class UserError extends UserState { + final String message; + + UserError(this.message); +} \ No newline at end of file diff --git a/frontend/app_student/lib/week_schedule/cubit/week_schedule_cubit.dart b/frontend/app_student/lib/week_schedule/cubit/week_schedule_cubit.dart index 65b7672..6cdc54d 100644 --- a/frontend/app_student/lib/week_schedule/cubit/week_schedule_cubit.dart +++ b/frontend/app_student/lib/week_schedule/cubit/week_schedule_cubit.dart @@ -1,3 +1,6 @@ +import 'package:app_student/api/day_schedule/models/day_schedule_model.dart'; +import 'package:app_student/api/users/models/user_model.dart'; +import 'package:app_student/api/week_schedule/models/week_schedule_model.dart'; import 'package:app_student/api/week_schedule/repositories/week_schedule_repository.dart'; import 'package:bloc/bloc.dart'; import 'package:meta/meta.dart'; @@ -9,12 +12,15 @@ part 'week_schedule_state.dart'; class WeekScheduleCubit extends Cubit { final WeekScheduleRepository weekScheduleRepository; final UserRepository userRepository; + late DateTime? initialDate; WeekScheduleCubit( - {required this.weekScheduleRepository, required this.userRepository}) + {required this.weekScheduleRepository, + required this.userRepository, + required this.initialDate}) : super(WeekScheduleInitial()); - Future getUser() async { + Future getUser() async { return await userRepository.getUser(); } @@ -23,7 +29,18 @@ class WeekScheduleCubit extends Cubit { emit(WeekScheduleLoading()); final weekSchedule = await weekScheduleRepository.getWeeksSchedule(className); - emit(WeekScheduleLoaded(weekSchedule)); + + final allEvents = + weekSchedule.expand((week) => week.daySchedules).toList(); + + initialDate ??= DateTime.now(); + + final todayIndex = allEvents.indexWhere((daySchedule) => + daySchedule.date.day == initialDate!.day && + daySchedule.date.month == initialDate!.month && + daySchedule.date.year == initialDate!.year); + + emit(WeekScheduleLoaded(weekSchedule, todayIndex, allEvents)); } catch (e) { emit(WeekScheduleError(e.toString())); } @@ -31,6 +48,18 @@ class WeekScheduleCubit extends Cubit { void fetchUserAndSchedule() async { final user = await getUser(); - fetchWeekSchedule(user.className); + fetchWeekSchedule(user.className!); + } + + void updateTodayIndex(int index) { + if (state is WeekScheduleLoaded) { + emit((state as WeekScheduleLoaded).copyWith(todayIndex: index)); + } + } + + void changeDate(DateTime newDate) { + initialDate = newDate; + emit(WeekScheduleDateChanged(newDate)); + fetchUserAndSchedule(); } } diff --git a/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart b/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart index cea2f6f..2165a93 100644 --- a/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart +++ b/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart @@ -8,9 +8,29 @@ class WeekScheduleInitial extends WeekScheduleState {} class WeekScheduleLoading extends WeekScheduleState {} class WeekScheduleLoaded extends WeekScheduleState { - final List weekSchedule; + final List weekSchedule; + final int todayIndex; + final List allDaySchedules; - WeekScheduleLoaded(this.weekSchedule); + WeekScheduleLoaded(this.weekSchedule, this.todayIndex, this.allDaySchedules); + + WeekScheduleLoaded copyWith({ + List? weekSchedule, + int? todayIndex, + List? allDaySchedules, + }) { + return WeekScheduleLoaded( + weekSchedule ?? this.weekSchedule, + todayIndex ?? this.todayIndex, + allDaySchedules ?? this.allDaySchedules, + ); + } +} + +class WeekScheduleDateChanged extends WeekScheduleState { + final DateTime date; + + WeekScheduleDateChanged(this.date); } class WeekScheduleError extends WeekScheduleState { diff --git a/frontend/app_student/lib/week_schedule/views/week_schedule.dart b/frontend/app_student/lib/week_schedule/views/week_schedule.dart index 57ca24d..ddbad0c 100644 --- a/frontend/app_student/lib/week_schedule/views/week_schedule.dart +++ b/frontend/app_student/lib/week_schedule/views/week_schedule.dart @@ -1,14 +1,15 @@ import 'package:app_student/api/week_schedule/repositories/week_schedule_repository.dart'; import 'package:app_student/week_schedule/cubit/week_schedule_cubit.dart'; import 'package:app_student/week_schedule/views/widgets/day_schedule_widget.dart'; -import 'package:app_student/week_schedule/views/widgets/components/custom_appbar.dart'; +import 'package:app_student/week_schedule/views/widgets/components/app_bar_week_schedule.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import '../../api/users/repositories/user_repository.dart'; class WeekSchedulePage extends StatelessWidget { - const WeekSchedulePage({super.key}); + final DateTime? initialDate; + const WeekSchedulePage({super.key, this.initialDate}); @override Widget build(BuildContext context) { @@ -17,7 +18,8 @@ class WeekSchedulePage extends StatelessWidget { final userRepository = RepositoryProvider.of(context); final weekScheduleCubit = WeekScheduleCubit( weekScheduleRepository: weekScheduleRepository, - userRepository: userRepository); + userRepository: userRepository, + initialDate: initialDate); return BlocProvider( create: (context) => weekScheduleCubit..fetchUserAndSchedule(), @@ -28,23 +30,23 @@ class WeekSchedulePage extends StatelessWidget { if (state is WeekScheduleLoading) { return const Center(child: CircularProgressIndicator()); } else if (state is WeekScheduleLoaded) { + final allEvents = state.weekSchedule + .expand((week) => week.daySchedules) + .toList(); + return Padding( - padding: const EdgeInsets.only( - top: 30.0), // Ajoutez un espacement en haut + padding: const EdgeInsets.only(top: 30.0), child: SizedBox( height: MediaQuery.of(context).size.height, child: PageView.builder( - itemCount: state.weekSchedule.length, // Nombre de semaines - itemBuilder: (context, weekIndex) { - final week = state.weekSchedule[weekIndex]; - return PageView.builder( - itemCount: week.daySchedules - .length, // Nombre de jours dans la semaine - itemBuilder: (context, dayIndex) { - final daySchedule = week.daySchedules[dayIndex]; - return DayScheduleWidget(daySchedule: daySchedule); - }, - ); + controller: PageController( + initialPage: + state.todayIndex != -1 ? state.todayIndex : 0, + ), + itemCount: allEvents.length, + itemBuilder: (context, index) { + final daySchedule = allEvents[index]; + return DayScheduleWidget(daySchedule: daySchedule); }, ), ), diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/app_bar_week_schedule.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/app_bar_week_schedule.dart new file mode 100644 index 0000000..1ef91aa --- /dev/null +++ b/frontend/app_student/lib/week_schedule/views/widgets/components/app_bar_week_schedule.dart @@ -0,0 +1,45 @@ +import 'package:app_student/api/users/repositories/user_repository.dart'; +import 'package:app_student/users/cubit/user_cubit.dart'; +import 'package:app_student/week_schedule/views/widgets/components/datepicker_button.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; + +class AppBarWeekSchedule extends StatelessWidget + implements PreferredSizeWidget { + const AppBarWeekSchedule({super.key}); + + @override + Widget build(BuildContext context) { + final userRepository = RepositoryProvider.of(context); + return AppBar( + backgroundColor: const Color(0xFF005067), + toolbarHeight: 70.0, + title: Stack( + alignment: Alignment.center, + children: [ + Opacity( + opacity: 0.5, + child: Image.asset( + 'assets/images/3il-icon-white.png', + fit: BoxFit.contain, + ), + ), + Text( + context.read()().state.user?.name ?? '', + style: const TextStyle( + color: Colors.white, + fontSize: 20.0, + ), + ), + ], + ), + actions: const [ + DatePickerButton(), + ], + centerTitle: true, + ); + } + + @override + Size get preferredSize => const Size.fromHeight(70.0); +} diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/custom_appbar.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/custom_appbar.dart deleted file mode 100644 index bb524d4..0000000 --- a/frontend/app_student/lib/week_schedule/views/widgets/components/custom_appbar.dart +++ /dev/null @@ -1,23 +0,0 @@ -import 'package:app_student/week_schedule/views/widgets/components/datepicker_button.dart'; -import 'package:flutter/material.dart'; - -class AppBarWeekSchedule extends StatelessWidget - implements PreferredSizeWidget { - const AppBarWeekSchedule({super.key}); - - @override - Widget build(BuildContext context) { - return AppBar( - backgroundColor: const Color(0xFF005067), - leading: Image.asset('assets/images/3il-logo.jpg'), - title: const Center( - child: Text('Classe Name', style: TextStyle(color: Colors.white))), - actions: const [ - DatePickerButton(), - ], - ); - } - - @override - Size get preferredSize => const Size.fromHeight(70.0); -} diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart index 73e05d3..088a8b8 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart @@ -1,21 +1,55 @@ +import 'package:app_student/week_schedule/cubit/week_schedule_cubit.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:go_router/go_router.dart'; class DatePickerButton extends StatelessWidget { const DatePickerButton({super.key}); + Future navigateToDate( + BuildContext context, WeekScheduleCubit cubit, DateTime date) async { + final index = (cubit.state as WeekScheduleLoaded) + .allDaySchedules + .indexWhere((event) => + DateTime(event.date.year, event.date.month, event.date.day) == + DateTime(date.year, date.month, date.day)); + if (index != -1) { + cubit.changeDate(date); + context + .goNamed('schedule_date', pathParameters: {'date': date.toString()}); + } + } + + Future selectDate( + BuildContext context, WeekScheduleCubit cubit, DateTime today) async { + return await showDatePicker( + context: context, + initialDate: cubit.state is WeekScheduleLoaded + ? (cubit.state as WeekScheduleLoaded) + .allDaySchedules[(cubit.state as WeekScheduleLoaded).todayIndex] + .date + : today, + firstDate: DateTime(2000), + lastDate: DateTime(2100), + selectableDayPredicate: (date) { + return cubit.state is WeekScheduleLoaded && + (cubit.state as WeekScheduleLoaded).allDaySchedules.any((event) => + DateTime(event.date.year, event.date.month, event.date.day) == + DateTime(date.year, date.month, date.day)); + }, + ); + } + @override Widget build(BuildContext context) { + final cubit = context.read(); return IconButton( icon: const Icon(Icons.calendar_month, color: Colors.white), onPressed: () async { - final date = await showDatePicker( - context: context, - initialDate: DateTime.now(), - firstDate: DateTime(2000), - lastDate: DateTime(2100), - ); + final today = DateTime.now(); + final date = await selectDate(context, cubit, today); if (date != null) { - // Utilisez la date sélectionnée + navigateToDate(context, cubit, date); } }, ); diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart index c800d90..a817f6d 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart @@ -12,6 +12,23 @@ class EventCard extends StatelessWidget { @override Widget build(BuildContext context) { + if (event.activite == 'Pas cours' && event.creneau != 3) { + return Card( + color: Colors.grey.shade200, + child: Container( + decoration: const BoxDecoration( + border: Border( + left: BorderSide( + color: Colors.grey, + width: 10.0, + ), + ), + ), + width: 300, + height: 90, + ), + ); + } return Card( color: const Color(0xFF007A8D).withOpacity(0.3), child: Container( @@ -33,7 +50,7 @@ class EventCard extends StatelessWidget { mainAxisAlignment: event.creneau == 3 ? MainAxisAlignment.center : MainAxisAlignment.spaceEvenly, - children: event.creneau == 3 + children: event.repas == true ? [ Center( child: ColorFiltered( diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart index d61ad2d..c07a6c8 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart @@ -11,7 +11,7 @@ class EventDetails extends StatelessWidget { @override Widget build(BuildContext context) { return Row( - mainAxisAlignment: MainAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ EventHours(event: event), EventCard(event: event), From 0196b139b1fe78094973b38d86adf7a8ca4e832b Mon Sep 17 00:00:00 2001 From: Jules Artaud Date: Thu, 14 Mar 2024 18:06:26 +0100 Subject: [PATCH 2/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=F0=9F=8E=A8=F0=9F=92=84:?= =?UTF-8?q?=20-=20added=20final=20design=3F=20and=20improved=20the=20struc?= =?UTF-8?q?ture=20of=20widgets=20=F0=9F=91=94:=20classcubit=20=F0=9F=91=94?= =?UTF-8?q?:=20usercubit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app_student/lib/api/api_service.dart | 9 +- .../class_groups/cubit/class_group_cubit.dart | 12 +-- .../class_groups/cubit/class_group_state.dart | 1 - .../class_groups/views/class_group_page.dart | 55 ++++++------ .../class_groups/views/widgets/card_list.dart | 5 +- frontend/app_student/lib/main_dev.dart | 16 ++-- frontend/app_student/lib/routes.dart | 89 +++++++------------ .../lib/users/cubit/user_cubit.dart | 9 +- .../lib/users/cubit/user_state.dart | 4 +- .../cubit/week_schedule_cubit.dart | 23 +++-- .../cubit/week_schedule_state.dart | 7 +- .../week_schedule/views/week_schedule.dart | 79 ++++++++-------- .../components/app_bar_week_schedule.dart | 41 +++++---- .../widgets/components/datepicker_button.dart | 5 +- .../views/widgets/day_schedule_widget.dart | 23 ++++- .../views/widgets/events/event_card.dart | 88 ++++++------------ .../views/widgets/events/event_details.dart | 23 +++-- .../widgets/events/event_empty_card.dart | 25 ++++++ .../views/widgets/events/event_info.dart | 24 +++++ .../views/widgets/events/event_meal_card.dart | 39 ++++++++ frontend/app_student/pubspec.lock | 8 ++ frontend/app_student/pubspec.yaml | 1 + 22 files changed, 335 insertions(+), 251 deletions(-) create mode 100644 frontend/app_student/lib/week_schedule/views/widgets/events/event_empty_card.dart create mode 100644 frontend/app_student/lib/week_schedule/views/widgets/events/event_info.dart create mode 100644 frontend/app_student/lib/week_schedule/views/widgets/events/event_meal_card.dart diff --git a/frontend/app_student/lib/api/api_service.dart b/frontend/app_student/lib/api/api_service.dart index a6cbf06..6e2e742 100644 --- a/frontend/app_student/lib/api/api_service.dart +++ b/frontend/app_student/lib/api/api_service.dart @@ -1,3 +1,4 @@ +import 'dart:async'; import 'dart:convert'; import 'package:http/http.dart' as http; @@ -12,7 +13,9 @@ class ApiService { String fullUrl = '$apiUrl$endpoint'; fullUrl = Uri.encodeFull(fullUrl); try { - final response = await http.get(Uri.parse(fullUrl)); + final response = await http.get(Uri.parse(fullUrl)).timeout(const Duration(seconds: 20), onTimeout: () { + throw TimeoutException('The connection has timed out!'); + }); if (response.statusCode == 200) { List jsonResponse = json.decode(response.body); @@ -26,8 +29,10 @@ class ApiService { } else { throw Exception('ERROR ${response.statusCode} Failed to load data'); } + } on TimeoutException catch (e) { + throw Exception('Request time out: $e'); } catch (e) { throw Exception('Failed to load data: $e'); } } -} +} \ No newline at end of file diff --git a/frontend/app_student/lib/class_groups/cubit/class_group_cubit.dart b/frontend/app_student/lib/class_groups/cubit/class_group_cubit.dart index 2df33fc..46a4375 100644 --- a/frontend/app_student/lib/class_groups/cubit/class_group_cubit.dart +++ b/frontend/app_student/lib/class_groups/cubit/class_group_cubit.dart @@ -1,19 +1,15 @@ import 'package:app_student/api/class_groups/models/class_group_model.dart'; -import 'package:app_student/api/users/models/user_model.dart'; import 'package:bloc/bloc.dart'; import 'package:meta/meta.dart'; import '../../api/class_groups/repositories/class_group_repository.dart'; -import '../../api/users/repositories/user_repository.dart'; part 'class_group_state.dart'; class ClassGroupCubit extends Cubit { final ClassGroupRepository classRepository; - final UserRepository userRepository; - ClassGroupCubit({required this.classRepository, required this.userRepository}) - : super(ClassGroupInitial()); + ClassGroupCubit({required this.classRepository}) : super(ClassGroupInitial()); Future fetchClasses() async { try { @@ -25,10 +21,4 @@ class ClassGroupCubit extends Cubit { emit(ClassGroupError(e.toString())); } } - - - Future saveClass(ClassGroupModel classGroup) async { - await userRepository.saveUserClass(classGroup.name.toString()); - emit(ClassGroupSelected()); - } } diff --git a/frontend/app_student/lib/class_groups/cubit/class_group_state.dart b/frontend/app_student/lib/class_groups/cubit/class_group_state.dart index b1ac586..0ea0c92 100644 --- a/frontend/app_student/lib/class_groups/cubit/class_group_state.dart +++ b/frontend/app_student/lib/class_groups/cubit/class_group_state.dart @@ -19,4 +19,3 @@ class ClassGroupError extends ClassGroupState { ClassGroupError([this.message = 'An error occurred']); } -class ClassGroupSelected extends ClassGroupState {} diff --git a/frontend/app_student/lib/class_groups/views/class_group_page.dart b/frontend/app_student/lib/class_groups/views/class_group_page.dart index a056c98..8f98f17 100644 --- a/frontend/app_student/lib/class_groups/views/class_group_page.dart +++ b/frontend/app_student/lib/class_groups/views/class_group_page.dart @@ -10,7 +10,6 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:go_router/go_router.dart'; import '../../api/users/models/user_model.dart'; -import '../../api/users/repositories/user_repository.dart'; class ClassGroupPage extends StatelessWidget { const ClassGroupPage({super.key}); @@ -19,14 +18,14 @@ class ClassGroupPage extends StatelessWidget { Widget build(BuildContext context) { final classRepository = RepositoryProvider.of(context); - final userRepository = RepositoryProvider.of(context); final classCubit = ClassGroupCubit( - classRepository: classRepository, userRepository: userRepository); + classRepository: classRepository, + )..fetchClasses(); return BlocProvider( - create: (context) => classCubit..fetchClasses(), + create: (context) => classCubit, child: FutureBuilder( - future: context.read().getConnectedUser(), + future: context.read().getCurrentUser(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return const Center(child: CircularProgressIndicator()); @@ -35,32 +34,36 @@ class ClassGroupPage extends StatelessWidget { } else { final user = snapshot.data; return Scaffold( - body: BlocBuilder( - builder: (context, state) { - if (state is ClassGroupLoading) { - return const Center(child: CircularProgressIndicator()); - } else if (state is ClassGroupSelected) { + body: BlocListener( + listener: (context, state) { + if (state is UserClassesSelected) { WidgetsBinding.instance.addPostFrameCallback((_) { context.go('/schedule'); }); - return const SizedBox.shrink(); - } else if (state is ClassGroupLoaded) { - return Column( - children: [ - const HeaderLogo(), - HeaderTitle('Bonjour, ${user?.name}'), - const HeaderText('Choisis ta promotion :'), - Expanded( - child: CardList(classesList: state.classes), - ), - ], - ); - } else if (state is ClassGroupError) { - return Center(child: Text(state.message)); - } else { - return const SizedBox.shrink(); } }, + child: BlocBuilder( + builder: (context, state) { + if (state is ClassGroupLoading) { + return const Center(child: CircularProgressIndicator()); + } else if (state is ClassGroupLoaded) { + return Column( + children: [ + const HeaderLogo(), + HeaderTitle('Bonjour, ${user?.name}'), + const HeaderText('Choisis ta promotion :'), + Expanded( + child: CardList(classesList: state.classes), + ), + ], + ); + } else if (state is ClassGroupError) { + return Center(child: Text(state.message)); + } else { + return const SizedBox.shrink(); + } + }, + ), ), ); } diff --git a/frontend/app_student/lib/class_groups/views/widgets/card_list.dart b/frontend/app_student/lib/class_groups/views/widgets/card_list.dart index c20ecb0..0d7dca5 100644 --- a/frontend/app_student/lib/class_groups/views/widgets/card_list.dart +++ b/frontend/app_student/lib/class_groups/views/widgets/card_list.dart @@ -1,9 +1,8 @@ import 'package:app_student/api/class_groups/models/class_group_model.dart'; +import 'package:app_student/users/cubit/user_cubit.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; -import '../../cubit/class_group_cubit.dart'; - class CardList extends StatelessWidget { final List classesList; @@ -21,7 +20,7 @@ class CardList extends StatelessWidget { classesList[index].name, ), onTap: () { - context.read().saveClass(classesList[index]); + context.read().saveUserClass(classesList[index]); }, ), ); diff --git a/frontend/app_student/lib/main_dev.dart b/frontend/app_student/lib/main_dev.dart index aa4b195..f1cbdda 100644 --- a/frontend/app_student/lib/main_dev.dart +++ b/frontend/app_student/lib/main_dev.dart @@ -2,17 +2,20 @@ import 'package:app_student/config/dev_config.dart'; import 'package:app_student/routes.dart'; import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; +import 'package:intl/date_symbol_data_local.dart'; import 'package:provider/provider.dart'; import 'config/config.dart'; void main() { - runApp( - Provider( - create: (_) => DevConfig(), - child: const MyApp(), - ), - ); + initializeDateFormatting('fr_FR', null).then((_) { + runApp( + Provider( + create: (_) => DevConfig(), + child: const MyApp(), + ), + ); + }); } class MyApp extends StatelessWidget { @@ -35,6 +38,7 @@ class MyApp extends StatelessWidget { ); return MaterialApp.router( + debugShowCheckedModeBanner: false, title: '3iL Student App', theme: ThemeData( primarySwatch: Colors.blue, diff --git a/frontend/app_student/lib/routes.dart b/frontend/app_student/lib/routes.dart index 1acd35d..4f0fe7d 100644 --- a/frontend/app_student/lib/routes.dart +++ b/frontend/app_student/lib/routes.dart @@ -23,22 +23,32 @@ class AppRoutes { static final routes = [ GoRoute( - path: classListPage, - pageBuilder: (context, state) => MaterialPage( - key: state.pageKey, - child: MultiRepositoryProvider( - providers: [ - RepositoryProvider( - create: (context) => ClassGroupRepository( - apiService: ApiService( - apiUrl: context.read().apiUrl))), - RepositoryProvider(create: (context) => UserRepository()), - ], - child: BlocProvider( - create: (context) => ClassGroupCubit( - classRepository: context.read(), - userRepository: context.read()), - child: const ClassGroupPage())))), + path: classListPage, + pageBuilder: (context, state) => MaterialPage( + key: state.pageKey, + child: MultiRepositoryProvider( + providers: [ + RepositoryProvider( + create: (context) => ClassGroupRepository( + apiService: + ApiService(apiUrl: context.read().apiUrl))), + RepositoryProvider(create: (context) => UserRepository()), + ], + child: MultiBlocProvider(providers: [ + BlocProvider( + create: (context) => ClassGroupCubit( + classRepository: context.read(), + )..fetchClasses(), + ), + BlocProvider( + create: (context) => + UserCubit(userRepository: context.read()) + ..fetchUser(), + ), + ], child: const ClassGroupPage()), + ), + ), + ), GoRoute( path: loginPage, pageBuilder: (context, state) => MaterialPage( @@ -66,55 +76,22 @@ class AppRoutes { ], child: MultiBlocProvider( providers: [ - BlocProvider( - create: (context) => UserCubit( - userRepository: context.read()), - ), BlocProvider( create: (context) => WeekScheduleCubit( weekScheduleRepository: WeekScheduleRepository( apiService: ApiService( apiUrl: context.read().apiUrl)), - userRepository: context.read(), - initialDate: DateTime.now()), + initialDate: DateTime.now(), + userCubit: context.read()), + ), + BlocProvider( + create: (context) => UserCubit( + userRepository: context.read()) + ..fetchUser(), ), ], child: const WeekSchedulePage(), ), ))), - GoRoute( - name: 'schedule_date', - path: '/schedule:date', - pageBuilder: (context, state) { - final date = DateTime.parse(state.pathParameters['date']!); - return MaterialPage( - key: state.pageKey, - child: MultiRepositoryProvider( - providers: [ - RepositoryProvider( - create: (context) => WeekScheduleRepository( - apiService: ApiService( - apiUrl: context.read().apiUrl))), - RepositoryProvider(create: (context) => UserRepository()), - ], - child: MultiBlocProvider( - providers: [ - BlocProvider( - create: (context) => UserCubit( - userRepository: context.read()), - ), - BlocProvider( - create: (context) => WeekScheduleCubit( - weekScheduleRepository: WeekScheduleRepository( - apiService: ApiService( - apiUrl: context.read().apiUrl)), - userRepository: context.read(), - initialDate: DateTime.now()), - ), - ], - child: const WeekSchedulePage(), - ), - )); - }), ]; } diff --git a/frontend/app_student/lib/users/cubit/user_cubit.dart b/frontend/app_student/lib/users/cubit/user_cubit.dart index ea45401..148a6c1 100644 --- a/frontend/app_student/lib/users/cubit/user_cubit.dart +++ b/frontend/app_student/lib/users/cubit/user_cubit.dart @@ -1,3 +1,4 @@ +import 'package:app_student/api/class_groups/models/class_group_model.dart'; import 'package:app_student/api/users/models/user_model.dart'; import 'package:bloc/bloc.dart'; import 'package:meta/meta.dart'; @@ -21,11 +22,13 @@ class UserCubit extends Cubit { } } - Future getConnectedUser() async { + Future getCurrentUser() async { return userRepository.getUser(); } - Future saveUserClass(String className) async { - await userRepository.saveUserClass(className); + Future saveUserClass(ClassGroupModel classGroup) async { + await userRepository.saveUserClass(classGroup.name.toString()); + emit(UserClassesSelected()); } + } diff --git a/frontend/app_student/lib/users/cubit/user_state.dart b/frontend/app_student/lib/users/cubit/user_state.dart index 14a1c97..c08adbb 100644 --- a/frontend/app_student/lib/users/cubit/user_state.dart +++ b/frontend/app_student/lib/users/cubit/user_state.dart @@ -13,8 +13,10 @@ class UserLoaded extends UserState { UserLoaded(this.user); } +class UserClassesSelected extends UserState {} + class UserError extends UserState { final String message; UserError(this.message); -} \ No newline at end of file +} diff --git a/frontend/app_student/lib/week_schedule/cubit/week_schedule_cubit.dart b/frontend/app_student/lib/week_schedule/cubit/week_schedule_cubit.dart index 6cdc54d..a42eb8b 100644 --- a/frontend/app_student/lib/week_schedule/cubit/week_schedule_cubit.dart +++ b/frontend/app_student/lib/week_schedule/cubit/week_schedule_cubit.dart @@ -2,33 +2,31 @@ import 'package:app_student/api/day_schedule/models/day_schedule_model.dart'; import 'package:app_student/api/users/models/user_model.dart'; import 'package:app_student/api/week_schedule/models/week_schedule_model.dart'; import 'package:app_student/api/week_schedule/repositories/week_schedule_repository.dart'; +import 'package:app_student/users/cubit/user_cubit.dart'; import 'package:bloc/bloc.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:meta/meta.dart'; -import '../../api/users/repositories/user_repository.dart'; - part 'week_schedule_state.dart'; class WeekScheduleCubit extends Cubit { final WeekScheduleRepository weekScheduleRepository; - final UserRepository userRepository; + final UserCubit userCubit; late DateTime? initialDate; WeekScheduleCubit( {required this.weekScheduleRepository, - required this.userRepository, + required this.userCubit, required this.initialDate}) : super(WeekScheduleInitial()); - Future getUser() async { - return await userRepository.getUser(); - } - - Future fetchWeekSchedule(String className) async { + Future fetchWeekSchedule() async { try { + if (isClosed) return; emit(WeekScheduleLoading()); + final user = await userCubit.getCurrentUser(); final weekSchedule = - await weekScheduleRepository.getWeeksSchedule(className); + await weekScheduleRepository.getWeeksSchedule(user.className!); final allEvents = weekSchedule.expand((week) => week.daySchedules).toList(); @@ -40,15 +38,14 @@ class WeekScheduleCubit extends Cubit { daySchedule.date.month == initialDate!.month && daySchedule.date.year == initialDate!.year); - emit(WeekScheduleLoaded(weekSchedule, todayIndex, allEvents)); + emit(WeekScheduleLoaded(weekSchedule, todayIndex, allEvents, user)); } catch (e) { emit(WeekScheduleError(e.toString())); } } void fetchUserAndSchedule() async { - final user = await getUser(); - fetchWeekSchedule(user.className!); + fetchWeekSchedule(); } void updateTodayIndex(int index) { diff --git a/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart b/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart index 2165a93..ec098e0 100644 --- a/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart +++ b/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart @@ -11,18 +11,21 @@ class WeekScheduleLoaded extends WeekScheduleState { final List weekSchedule; final int todayIndex; final List allDaySchedules; + final UserModel user; // Ajout du champ UserModel - WeekScheduleLoaded(this.weekSchedule, this.todayIndex, this.allDaySchedules); + WeekScheduleLoaded(this.weekSchedule, this.todayIndex, this.allDaySchedules, this.user); // Ajout du UserModel au constructeur WeekScheduleLoaded copyWith({ List? weekSchedule, int? todayIndex, List? allDaySchedules, + UserModel? user, // Ajout du UserModel à la méthode copyWith }) { return WeekScheduleLoaded( weekSchedule ?? this.weekSchedule, todayIndex ?? this.todayIndex, allDaySchedules ?? this.allDaySchedules, + user ?? this.user, // Utilisation du UserModel dans la méthode copyWith ); } } @@ -37,4 +40,4 @@ class WeekScheduleError extends WeekScheduleState { final String message; WeekScheduleError(this.message); -} +} \ No newline at end of file diff --git a/frontend/app_student/lib/week_schedule/views/week_schedule.dart b/frontend/app_student/lib/week_schedule/views/week_schedule.dart index ddbad0c..83a6229 100644 --- a/frontend/app_student/lib/week_schedule/views/week_schedule.dart +++ b/frontend/app_student/lib/week_schedule/views/week_schedule.dart @@ -1,4 +1,5 @@ import 'package:app_student/api/week_schedule/repositories/week_schedule_repository.dart'; +import 'package:app_student/users/cubit/user_cubit.dart'; import 'package:app_student/week_schedule/cubit/week_schedule_cubit.dart'; import 'package:app_student/week_schedule/views/widgets/day_schedule_widget.dart'; import 'package:app_student/week_schedule/views/widgets/components/app_bar_week_schedule.dart'; @@ -9,6 +10,7 @@ import '../../api/users/repositories/user_repository.dart'; class WeekSchedulePage extends StatelessWidget { final DateTime? initialDate; + const WeekSchedulePage({super.key, this.initialDate}); @override @@ -17,48 +19,51 @@ class WeekSchedulePage extends StatelessWidget { RepositoryProvider.of(context); final userRepository = RepositoryProvider.of(context); final weekScheduleCubit = WeekScheduleCubit( + userCubit: context.read(), weekScheduleRepository: weekScheduleRepository, - userRepository: userRepository, initialDate: initialDate); return BlocProvider( - create: (context) => weekScheduleCubit..fetchUserAndSchedule(), - child: Scaffold( - appBar: const AppBarWeekSchedule(), - body: BlocBuilder( - builder: (context, state) { - if (state is WeekScheduleLoading) { - return const Center(child: CircularProgressIndicator()); - } else if (state is WeekScheduleLoaded) { - final allEvents = state.weekSchedule - .expand((week) => week.daySchedules) - .toList(); + create: (context) => weekScheduleCubit..fetchUserAndSchedule(), + child: BlocProvider( + create: (context) => + UserCubit(userRepository: userRepository)..fetchUser(), + child: Scaffold( + appBar: const AppBarWeekSchedule(), + body: BlocBuilder( + builder: (context, state) { + if (state is WeekScheduleLoading) { + return const Center(child: CircularProgressIndicator()); + } else if (state is WeekScheduleLoaded) { + final allEvents = state.weekSchedule + .expand((week) => week.daySchedules) + .toList(); - return Padding( - padding: const EdgeInsets.only(top: 30.0), - child: SizedBox( - height: MediaQuery.of(context).size.height, - child: PageView.builder( - controller: PageController( - initialPage: - state.todayIndex != -1 ? state.todayIndex : 0, + return Padding( + padding: const EdgeInsets.only(top: 30.0), + child: SizedBox( + height: MediaQuery.of(context).size.height, + child: PageView.builder( + controller: PageController( + initialPage: + state.todayIndex != -1 ? state.todayIndex : 0, + ), + itemCount: allEvents.length, + itemBuilder: (context, index) { + final daySchedule = allEvents[index]; + return DayScheduleWidget(daySchedule: daySchedule); + }, + ), ), - itemCount: allEvents.length, - itemBuilder: (context, index) { - final daySchedule = allEvents[index]; - return DayScheduleWidget(daySchedule: daySchedule); - }, - ), - ), - ); - } else if (state is WeekScheduleError) { - return Center(child: Text(state.message)); - } else { - return const SizedBox.shrink(); - } - }, - ), - ), - ); + ); + } else if (state is WeekScheduleError) { + return Center(child: Text(state.message)); + } else { + return const SizedBox.shrink(); + } + }, + ), + ), + )); } } diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/app_bar_week_schedule.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/app_bar_week_schedule.dart index 1ef91aa..811b4a9 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/components/app_bar_week_schedule.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/components/app_bar_week_schedule.dart @@ -1,4 +1,3 @@ -import 'package:app_student/api/users/repositories/user_repository.dart'; import 'package:app_student/users/cubit/user_cubit.dart'; import 'package:app_student/week_schedule/views/widgets/components/datepicker_button.dart'; import 'package:flutter/material.dart'; @@ -10,33 +9,45 @@ class AppBarWeekSchedule extends StatelessWidget @override Widget build(BuildContext context) { - final userRepository = RepositoryProvider.of(context); + final userState = context.watch().state; + String className = ''; + if (userState is UserLoaded) { + className = userState.user.entity.className ?? ''; + } return AppBar( backgroundColor: const Color(0xFF005067), - toolbarHeight: 70.0, - title: Stack( + title: const SizedBox.shrink(), // Make the title empty + flexibleSpace: Stack( alignment: Alignment.center, children: [ - Opacity( - opacity: 0.5, - child: Image.asset( - 'assets/images/3il-icon-white.png', - fit: BoxFit.contain, + ClipRect( + child: Center( + child: Opacity( + opacity: 0.5, + child: Transform.scale( + scale: 3.0, // Adjust the scale factor to zoom the image + child: Image.asset( + 'assets/images/3il-icon-white.png', + fit: BoxFit.cover, + ), + ), + ), ), ), Text( - context.read()().state.user?.name ?? '', + className, style: const TextStyle( color: Colors.white, - fontSize: 20.0, + fontSize: 25.0, + fontWeight: FontWeight.bold, ), ), + const Positioned( + right: 0, + child: DatePickerButton(), + ), ], ), - actions: const [ - DatePickerButton(), - ], - centerTitle: true, ); } diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart index 088a8b8..ec576a6 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart @@ -15,8 +15,7 @@ class DatePickerButton extends StatelessWidget { DateTime(date.year, date.month, date.day)); if (index != -1) { cubit.changeDate(date); - context - .goNamed('schedule_date', pathParameters: {'date': date.toString()}); + context.go('/schedule'); } } @@ -44,7 +43,7 @@ class DatePickerButton extends StatelessWidget { Widget build(BuildContext context) { final cubit = context.read(); return IconButton( - icon: const Icon(Icons.calendar_month, color: Colors.white), + icon: const Icon(Icons.calendar_month, color: Colors.white, size: 30,), onPressed: () async { final today = DateTime.now(); final date = await selectDate(context, cubit, today); diff --git a/frontend/app_student/lib/week_schedule/views/widgets/day_schedule_widget.dart b/frontend/app_student/lib/week_schedule/views/widgets/day_schedule_widget.dart index bb3667a..34a1ae6 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/day_schedule_widget.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/day_schedule_widget.dart @@ -1,6 +1,7 @@ import 'package:app_student/api/day_schedule/models/day_schedule_model.dart'; import 'package:app_student/week_schedule/views/widgets/events/event_details.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; class DayScheduleWidget extends StatelessWidget { final DayScheduleModel daySchedule; @@ -9,12 +10,26 @@ class DayScheduleWidget extends StatelessWidget { @override Widget build(BuildContext context) { + String formattedDate = DateFormat('EEEE dd MMMM yyyy', 'fr_FR').format(daySchedule.date); + String capitalizedDate = formattedDate[0].toUpperCase() + formattedDate.substring(1); return SingleChildScrollView( child: Column( - children: daySchedule.events.map((event) { - return EventDetails(event: event); - }).toList(), + children: [ + Center( + child: Text( + capitalizedDate, + style: const TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(height: 30), + ...daySchedule.events.map((event) { + return EventDetails(event: event); + }), + ], ), ); } -} +} \ No newline at end of file diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart index a817f6d..c4d8889 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart @@ -12,23 +12,6 @@ class EventCard extends StatelessWidget { @override Widget build(BuildContext context) { - if (event.activite == 'Pas cours' && event.creneau != 3) { - return Card( - color: Colors.grey.shade200, - child: Container( - decoration: const BoxDecoration( - border: Border( - left: BorderSide( - color: Colors.grey, - width: 10.0, - ), - ), - ), - width: 300, - height: 90, - ), - ); - } return Card( color: const Color(0xFF007A8D).withOpacity(0.3), child: Container( @@ -40,59 +23,44 @@ class EventCard extends StatelessWidget { ), ), ), - width: 300, - height: 90, + height: 110, child: Padding( padding: - const EdgeInsets.only(left: 20.0, right: 20, bottom: 3, top: 3), + const EdgeInsets.only(left: 20.0, right: 20, bottom: 3, top: 3), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: event.creneau == 3 ? MainAxisAlignment.center : MainAxisAlignment.spaceEvenly, - children: event.repas == true - ? [ - Center( - child: ColorFiltered( - colorFilter: const ColorFilter.mode( - Colors.white, BlendMode.srcIn), - child: SvgPicture.asset( - 'assets/images/eating.svg', - width: 40, - height: 40, - ), - ), - ) - ] - : [ - const Text('1h30', - style: TextStyle(color: Colors.white, fontSize: 12)), - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(event.activite, - style: const TextStyle( - fontSize: 18, fontWeight: FontWeight.bold)), - ColorFiltered( - colorFilter: const ColorFilter.mode( - Colors.white, BlendMode.srcIn), - child: SvgPicture.asset( - event.visio - ? 'assets/images/teams.svg' - : 'assets/images/school.svg', - width: 40, - height: 40, - ), - ), - ], + children: [ + const Text('1h30', + style: TextStyle(color: Colors.white, fontSize: 12)), + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(event.activite, + style: const TextStyle( + fontSize: 18, fontWeight: FontWeight.bold)), + ColorFiltered( + colorFilter: const ColorFilter.mode( + Colors.white, BlendMode.srcIn), + child: SvgPicture.asset( + event.visio + ? 'assets/images/teams.svg' + : 'assets/images/school.svg', + width: 50, + height: 50, ), - Text('Salle ${event.salle}', - style: const TextStyle( - fontSize: 15, fontWeight: FontWeight.bold)), - ], + ), + ], + ), + Text('Salle ${event.salle}', + style: const TextStyle( + fontSize: 15, fontWeight: FontWeight.bold)), + ], ), ), ), ); } -} +} \ No newline at end of file diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart index c07a6c8..2328cdd 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart @@ -1,6 +1,6 @@ import 'package:app_student/api/events/models/event_model.dart'; -import 'package:app_student/week_schedule/views/widgets/events/event_card.dart'; import 'package:app_student/week_schedule/views/widgets/events/event_hours.dart'; +import 'package:app_student/week_schedule/views/widgets/events/event_info.dart'; import 'package:flutter/material.dart'; class EventDetails extends StatelessWidget { @@ -10,12 +10,19 @@ class EventDetails extends StatelessWidget { @override Widget build(BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - EventHours(event: event), - EventCard(event: event), - ], + return LayoutBuilder( + builder: (BuildContext context, BoxConstraints constraints) { + return Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + EventHours(event: event), + SizedBox( + width: constraints.maxWidth - 50, // Subtract the width of EventHours + child: EventInfo(event: event), + ), + ], + ); + }, ); } -} +} \ No newline at end of file diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_empty_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_empty_card.dart new file mode 100644 index 0000000..f851792 --- /dev/null +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_empty_card.dart @@ -0,0 +1,25 @@ +import 'package:flutter/material.dart'; + +class EventEmptyCard extends StatelessWidget { + const EventEmptyCard({ + super.key, + }); + + @override + Widget build(BuildContext context) { + return Card( + color: Colors.grey.shade200, + child: Container( + decoration: const BoxDecoration( + border: Border( + left: BorderSide( + color: Colors.grey, + width: 10.0, + ), + ), + ), + height: 110, + ), + ); + } +} \ No newline at end of file diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_info.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_info.dart new file mode 100644 index 0000000..f9bc8cf --- /dev/null +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_info.dart @@ -0,0 +1,24 @@ +import 'package:app_student/api/events/models/event_model.dart'; +import 'package:flutter/material.dart'; +import 'event_card.dart'; +import 'event_empty_card.dart'; +import 'event_meal_card.dart'; + +class EventInfo extends StatelessWidget { + const EventInfo({ + super.key, + required this.event, + }); + + final EventModel event; + + @override + Widget build(BuildContext context) { + if (event.activite == 'Pas cours' && event.creneau != 3) { + return const EventEmptyCard(); + } + return event.repas == true + ? const EventMealCard() + : EventCard(event: event); + } +} diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_meal_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_meal_card.dart new file mode 100644 index 0000000..35d7305 --- /dev/null +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_meal_card.dart @@ -0,0 +1,39 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; + +class EventMealCard extends StatelessWidget { + const EventMealCard({super.key}); + + @override + Widget build(BuildContext context) { + return Card( + color: const Color(0xFF007A8D), + child: Container( + decoration: const BoxDecoration( + border: Border( + left: BorderSide( + color: Color(0xFF005067), + width: 10.0, + ), + ), + ), + height: 90, + child: Padding( + padding: + const EdgeInsets.only(left: 20.0, right: 20, bottom: 3, top: 3), + child: Center( + child: ColorFiltered( + colorFilter: const ColorFilter.mode( + Colors.white, BlendMode.srcIn), + child: SvgPicture.asset( + 'assets/images/eating.svg', + width: 50, + height: 50, + ), + ), + ), + ), + ), + ); + } +} diff --git a/frontend/app_student/pubspec.lock b/frontend/app_student/pubspec.lock index 7bae58c..53d83f4 100644 --- a/frontend/app_student/pubspec.lock +++ b/frontend/app_student/pubspec.lock @@ -152,6 +152,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.2" + intl: + dependency: "direct main" + description: + name: intl + sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf + url: "https://pub.dev" + source: hosted + version: "0.19.0" leak_tracker: dependency: transitive description: diff --git a/frontend/app_student/pubspec.yaml b/frontend/app_student/pubspec.yaml index 78eaa91..b5bb6b0 100644 --- a/frontend/app_student/pubspec.yaml +++ b/frontend/app_student/pubspec.yaml @@ -43,6 +43,7 @@ dependencies: meta: ^1.11.0 flutter_svg: ^2.0.10+1 go_router: ^13.2.0 + intl: ^0.19.0 dev_dependencies: flutter_test: From 57e4e439e01589df7ebcdb13d440ae5a66d0f328 Mon Sep 17 00:00:00 2001 From: Jules Artaud Date: Thu, 14 Mar 2024 18:06:26 +0100 Subject: [PATCH 3/6] =?UTF-8?q?=E2=99=BB=EF=B8=8F=F0=9F=8E=A8=F0=9F=92=84:?= =?UTF-8?q?=20-=20added=20final=20design=3F=20and=20improved=20the=20struc?= =?UTF-8?q?ture=20of=20widgets=20=F0=9F=91=94:=20classcubit=20=F0=9F=91=94?= =?UTF-8?q?:=20usercubit?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app_student/lib/api/api_service.dart | 6 +++-- .../class_groups/cubit/class_group_state.dart | 1 - .../cubit/week_schedule_state.dart | 5 +++-- .../widgets/components/datepicker_button.dart | 6 ++++- .../views/widgets/day_schedule_widget.dart | 8 ++++--- .../views/widgets/events/event_card.dart | 8 +++---- .../views/widgets/events/event_details.dart | 5 +++-- .../widgets/events/event_empty_card.dart | 2 +- .../views/widgets/events/event_meal_card.dart | 22 +++++++++---------- 9 files changed, 36 insertions(+), 27 deletions(-) diff --git a/frontend/app_student/lib/api/api_service.dart b/frontend/app_student/lib/api/api_service.dart index 6e2e742..9d73118 100644 --- a/frontend/app_student/lib/api/api_service.dart +++ b/frontend/app_student/lib/api/api_service.dart @@ -13,7 +13,9 @@ class ApiService { String fullUrl = '$apiUrl$endpoint'; fullUrl = Uri.encodeFull(fullUrl); try { - final response = await http.get(Uri.parse(fullUrl)).timeout(const Duration(seconds: 20), onTimeout: () { + final response = await http + .get(Uri.parse(fullUrl)) + .timeout(const Duration(seconds: 20), onTimeout: () { throw TimeoutException('The connection has timed out!'); }); @@ -35,4 +37,4 @@ class ApiService { throw Exception('Failed to load data: $e'); } } -} \ No newline at end of file +} diff --git a/frontend/app_student/lib/class_groups/cubit/class_group_state.dart b/frontend/app_student/lib/class_groups/cubit/class_group_state.dart index 0ea0c92..acdc666 100644 --- a/frontend/app_student/lib/class_groups/cubit/class_group_state.dart +++ b/frontend/app_student/lib/class_groups/cubit/class_group_state.dart @@ -18,4 +18,3 @@ class ClassGroupError extends ClassGroupState { ClassGroupError([this.message = 'An error occurred']); } - diff --git a/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart b/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart index ec098e0..6a21522 100644 --- a/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart +++ b/frontend/app_student/lib/week_schedule/cubit/week_schedule_state.dart @@ -13,7 +13,8 @@ class WeekScheduleLoaded extends WeekScheduleState { final List allDaySchedules; final UserModel user; // Ajout du champ UserModel - WeekScheduleLoaded(this.weekSchedule, this.todayIndex, this.allDaySchedules, this.user); // Ajout du UserModel au constructeur + WeekScheduleLoaded(this.weekSchedule, this.todayIndex, this.allDaySchedules, + this.user); // Ajout du UserModel au constructeur WeekScheduleLoaded copyWith({ List? weekSchedule, @@ -40,4 +41,4 @@ class WeekScheduleError extends WeekScheduleState { final String message; WeekScheduleError(this.message); -} \ No newline at end of file +} diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart index ec576a6..be9e41e 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart @@ -43,7 +43,11 @@ class DatePickerButton extends StatelessWidget { Widget build(BuildContext context) { final cubit = context.read(); return IconButton( - icon: const Icon(Icons.calendar_month, color: Colors.white, size: 30,), + icon: const Icon( + Icons.calendar_month, + color: Colors.white, + size: 30, + ), onPressed: () async { final today = DateTime.now(); final date = await selectDate(context, cubit, today); diff --git a/frontend/app_student/lib/week_schedule/views/widgets/day_schedule_widget.dart b/frontend/app_student/lib/week_schedule/views/widgets/day_schedule_widget.dart index 34a1ae6..f22a2bf 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/day_schedule_widget.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/day_schedule_widget.dart @@ -10,8 +10,10 @@ class DayScheduleWidget extends StatelessWidget { @override Widget build(BuildContext context) { - String formattedDate = DateFormat('EEEE dd MMMM yyyy', 'fr_FR').format(daySchedule.date); - String capitalizedDate = formattedDate[0].toUpperCase() + formattedDate.substring(1); + String formattedDate = + DateFormat('EEEE dd MMMM yyyy', 'fr_FR').format(daySchedule.date); + String capitalizedDate = + formattedDate[0].toUpperCase() + formattedDate.substring(1); return SingleChildScrollView( child: Column( children: [ @@ -32,4 +34,4 @@ class DayScheduleWidget extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart index c4d8889..e6dc09c 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart @@ -26,7 +26,7 @@ class EventCard extends StatelessWidget { height: 110, child: Padding( padding: - const EdgeInsets.only(left: 20.0, right: 20, bottom: 3, top: 3), + const EdgeInsets.only(left: 20.0, right: 20, bottom: 3, top: 3), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: event.creneau == 3 @@ -42,8 +42,8 @@ class EventCard extends StatelessWidget { style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold)), ColorFiltered( - colorFilter: const ColorFilter.mode( - Colors.white, BlendMode.srcIn), + colorFilter: + const ColorFilter.mode(Colors.white, BlendMode.srcIn), child: SvgPicture.asset( event.visio ? 'assets/images/teams.svg' @@ -63,4 +63,4 @@ class EventCard extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart index 2328cdd..d05ce55 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_details.dart @@ -17,7 +17,8 @@ class EventDetails extends StatelessWidget { children: [ EventHours(event: event), SizedBox( - width: constraints.maxWidth - 50, // Subtract the width of EventHours + width: + constraints.maxWidth - 50, // Subtract the width of EventHours child: EventInfo(event: event), ), ], @@ -25,4 +26,4 @@ class EventDetails extends StatelessWidget { }, ); } -} \ No newline at end of file +} diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_empty_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_empty_card.dart index f851792..1da7d49 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_empty_card.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_empty_card.dart @@ -22,4 +22,4 @@ class EventEmptyCard extends StatelessWidget { ), ); } -} \ No newline at end of file +} diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_meal_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_meal_card.dart index 35d7305..67e4898 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_meal_card.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_meal_card.dart @@ -19,19 +19,19 @@ class EventMealCard extends StatelessWidget { ), height: 90, child: Padding( - padding: - const EdgeInsets.only(left: 20.0, right: 20, bottom: 3, top: 3), - child: Center( - child: ColorFiltered( - colorFilter: const ColorFilter.mode( - Colors.white, BlendMode.srcIn), - child: SvgPicture.asset( - 'assets/images/eating.svg', - width: 50, - height: 50, - ), + padding: + const EdgeInsets.only(left: 20.0, right: 20, bottom: 3, top: 3), + child: Center( + child: ColorFiltered( + colorFilter: + const ColorFilter.mode(Colors.white, BlendMode.srcIn), + child: SvgPicture.asset( + 'assets/images/eating.svg', + width: 50, + height: 50, ), ), + ), ), ), ); From a39118c4abce4b0e1f04df970d3344ea6dab92a5 Mon Sep 17 00:00:00 2001 From: Jules Artaud Date: Thu, 14 Mar 2024 18:59:33 +0100 Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=8C=90:=20i10n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/app_student/lib/l10n/app_fr.arb | 88 +++++++++++-------- .../widgets/components/datepicker_button.dart | 16 ++-- .../views/widgets/events/event_card.dart | 10 +-- 3 files changed, 63 insertions(+), 51 deletions(-) diff --git a/frontend/app_student/lib/l10n/app_fr.arb b/frontend/app_student/lib/l10n/app_fr.arb index 57e0c37..0b9c6f7 100644 --- a/frontend/app_student/lib/l10n/app_fr.arb +++ b/frontend/app_student/lib/l10n/app_fr.arb @@ -10,27 +10,27 @@ } }, "genericError": "Une erreur est survenue", - "@genericError": { - "description": "Message d'erreur générique", - "placeholders": { - "error": { - "type": "String", - "example": "Une erreur est survenue" - } - } - }, + "@genericError": { + "description": "Message d'erreur générique", + "placeholders": { + "error": { + "type": "String", + "example": "Une erreur est survenue" + } + } + }, "loginButton": "Connexion", - "@loginButton": { - "description": "Texte du bouton de connexion" - }, + "@loginButton": { + "description": "Texte du bouton de connexion" + }, "loginFirstNameLabel": "Prénom", - "@loginFirstName": { - "description": "Texte du label pour le prénom" - }, + "@loginFirstName": { + "description": "Texte du label pour le prénom" + }, "loginFirstNameHint": "Entrez votre prénom", - "@loginFirstNameHint": { - "description": "Texte de l'attribut placeholder pour le prénom" - }, + "@loginFirstNameHint": { + "description": "Texte de l'attribut placeholder pour le prénom" + }, "loginIneLabel": "INE", "@loginIneLabel": { "description": "Texte du label pour le numéro INE" @@ -44,29 +44,39 @@ "description": "Texte du label pour la date de naissance" }, "loginWelcomeTitle": "Bonjour :)", - "@loginWelcomeTitle": { - "description": "Texte d'accueil de la page de connexion" - }, + "@loginWelcomeTitle": { + "description": "Texte d'accueil de la page de connexion" + }, "loginWelcomeTitleError": "Oops, ca va aller", - "@loginWelcomeTitleError": { - "description": "Texte d'erreur d'accueil de la page de connexion" - }, + "@loginWelcomeTitleError": { + "description": "Texte d'erreur d'accueil de la page de connexion" + }, "loginFieldError": "Veuillez remplir tous les champs", - "@loginFieldError": { - "description": "Message d'erreur pour les champs de connexion" - }, + "@loginFieldError": { + "description": "Message d'erreur pour les champs de connexion" + }, "classSelectionTitle": "Salut {firstName} !", - "@classSelectionTitle": { - "description": "Texte d'accueil de la page de sélection de classe", - "placeholders": { - "firstName": { - "type": "String", - "example": "John" - } - } - }, - "classSelectionSubtitle": "Sélectionne ta classe", - "@classSelectionSubtitle": { - "description": "Texte de sous-titre de la page de sélection de classe" + "@classSelectionTitle": { + "description": "Texte d'accueil de la page de sélection de classe", + "placeholders": { + "firstName": { + "type": "String", + "example": "John" + } } + }, + "classSelectionSubtitle": "Sélectionne ta classe", + "@classSelectionSubtitle": { + "description": "Texte de sous-titre de la page de sélection de classe" + }, + "eventDuration": "1h30", + "@eventDuration": { + "description": "La durée de l'événement", + "example": "1h30" + }, + "roomLabel": "Salle", + "@roomLabel": { + "description": "Label pour la salle", + "example": "Salle" + } } \ No newline at end of file diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart index be9e41e..3b99a32 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart @@ -11,11 +11,11 @@ class DatePickerButton extends StatelessWidget { final index = (cubit.state as WeekScheduleLoaded) .allDaySchedules .indexWhere((event) => - DateTime(event.date.year, event.date.month, event.date.day) == - DateTime(date.year, date.month, date.day)); + DateTime(event.date.year, event.date.month, event.date.day) == + DateTime(date.year, date.month, date.day)); if (index != -1) { cubit.changeDate(date); - context.go('/schedule'); + context.go('/schedule'); // Replace with the appropriate navigation logic } } @@ -25,15 +25,15 @@ class DatePickerButton extends StatelessWidget { context: context, initialDate: cubit.state is WeekScheduleLoaded ? (cubit.state as WeekScheduleLoaded) - .allDaySchedules[(cubit.state as WeekScheduleLoaded).todayIndex] - .date + .allDaySchedules[(cubit.state as WeekScheduleLoaded).todayIndex] + .date : today, firstDate: DateTime(2000), lastDate: DateTime(2100), selectableDayPredicate: (date) { return cubit.state is WeekScheduleLoaded && (cubit.state as WeekScheduleLoaded).allDaySchedules.any((event) => - DateTime(event.date.year, event.date.month, event.date.day) == + DateTime(event.date.year, event.date.month, event.date.day) == DateTime(date.year, date.month, date.day)); }, ); @@ -52,9 +52,11 @@ class DatePickerButton extends StatelessWidget { final today = DateTime.now(); final date = await selectDate(context, cubit, today); if (date != null) { - navigateToDate(context, cubit, date); + // ignore: use_build_context_synchronously + await navigateToDate(context, cubit, date); // Await the navigation } }, ); } } + diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart index e6dc09c..9733ae9 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart @@ -1,6 +1,7 @@ import 'package:app_student/api/events/models/event_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter_svg/svg.dart'; +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; class EventCard extends StatelessWidget { const EventCard({ @@ -33,8 +34,8 @@ class EventCard extends StatelessWidget { ? MainAxisAlignment.center : MainAxisAlignment.spaceEvenly, children: [ - const Text('1h30', - style: TextStyle(color: Colors.white, fontSize: 12)), + Text(AppLocalizations.of(context)!.eventDuration, + style: const TextStyle(color: Colors.white, fontSize: 12)), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -54,9 +55,8 @@ class EventCard extends StatelessWidget { ), ], ), - Text('Salle ${event.salle}', - style: const TextStyle( - fontSize: 15, fontWeight: FontWeight.bold)), + Text('${AppLocalizations.of(context)!.roomLabel} ${event.salle}', + style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold)), ], ), ), From f3be926f4857673960ebae62ff3e03e66cf56992 Mon Sep 17 00:00:00 2001 From: Jules Artaud Date: Thu, 14 Mar 2024 19:02:34 +0100 Subject: [PATCH 5/6] =?UTF-8?q?=F0=9F=9A=A8:=20linter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../views/widgets/components/datepicker_button.dart | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart index 3b99a32..c7c8b62 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart @@ -52,8 +52,9 @@ class DatePickerButton extends StatelessWidget { final today = DateTime.now(); final date = await selectDate(context, cubit, today); if (date != null) { - // ignore: use_build_context_synchronously - await navigateToDate(context, cubit, date); // Await the navigation + if (context.mounted) { + await navigateToDate(context, cubit, date); // Await the navigation + } } }, ); From 4b2a4d6c5ffd8233ebaaa8bda7fe323c6d748ccf Mon Sep 17 00:00:00 2001 From: Jules Artaud Date: Thu, 14 Mar 2024 19:02:34 +0100 Subject: [PATCH 6/6] =?UTF-8?q?=F0=9F=9A=A8:=20linter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../widgets/components/datepicker_button.dart | 16 ++++++++-------- .../views/widgets/events/event_card.dart | 3 ++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart index 3b99a32..f8fb5c8 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/components/datepicker_button.dart @@ -11,8 +11,8 @@ class DatePickerButton extends StatelessWidget { final index = (cubit.state as WeekScheduleLoaded) .allDaySchedules .indexWhere((event) => - DateTime(event.date.year, event.date.month, event.date.day) == - DateTime(date.year, date.month, date.day)); + DateTime(event.date.year, event.date.month, event.date.day) == + DateTime(date.year, date.month, date.day)); if (index != -1) { cubit.changeDate(date); context.go('/schedule'); // Replace with the appropriate navigation logic @@ -25,15 +25,15 @@ class DatePickerButton extends StatelessWidget { context: context, initialDate: cubit.state is WeekScheduleLoaded ? (cubit.state as WeekScheduleLoaded) - .allDaySchedules[(cubit.state as WeekScheduleLoaded).todayIndex] - .date + .allDaySchedules[(cubit.state as WeekScheduleLoaded).todayIndex] + .date : today, firstDate: DateTime(2000), lastDate: DateTime(2100), selectableDayPredicate: (date) { return cubit.state is WeekScheduleLoaded && (cubit.state as WeekScheduleLoaded).allDaySchedules.any((event) => - DateTime(event.date.year, event.date.month, event.date.day) == + DateTime(event.date.year, event.date.month, event.date.day) == DateTime(date.year, date.month, date.day)); }, ); @@ -52,11 +52,11 @@ class DatePickerButton extends StatelessWidget { final today = DateTime.now(); final date = await selectDate(context, cubit, today); if (date != null) { - // ignore: use_build_context_synchronously - await navigateToDate(context, cubit, date); // Await the navigation + if (context.mounted) { + await navigateToDate(context, cubit, date); // Await the navigation + } } }, ); } } - diff --git a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart index 9733ae9..90eb2d2 100644 --- a/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart +++ b/frontend/app_student/lib/week_schedule/views/widgets/events/event_card.dart @@ -56,7 +56,8 @@ class EventCard extends StatelessWidget { ], ), Text('${AppLocalizations.of(context)!.roomLabel} ${event.salle}', - style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold)), + style: const TextStyle( + fontSize: 15, fontWeight: FontWeight.bold)), ], ), ),