Repository navigation
feat: see other student's schedule #1906
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
muralhaplays
wants to merge
4
commits into
develop
Choose a base branch
from
feat/others-students-schedule
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
27 changes: 27 additions & 0 deletions
27
packages/uni_app/lib/model/providers/riverpod/student_lectures_provider.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
| import 'package:uni/controller/fetchers/academics/schedule/schedule_fetcher_new_api.dart'; | ||
| import 'package:uni/model/entities/course_units/course_unit_class.dart'; | ||
| import 'package:uni/model/entities/lecture.dart'; | ||
| import 'package:uni/model/providers/riverpod/session_provider.dart'; | ||
|
|
||
| /// Fetches the list of lectures for a specific student. | ||
| /// | ||
| /// Optionally filters by lective year if provided. | ||
| /// Uses the same deduplication strategy as the main lectureProvider. | ||
| final studentLecturesProvider = FutureProvider.autoDispose | ||
| .family<List<Lecture>, (CourseUnitStudent, int?)>((ref, params) async { | ||
| final (student, lectiveYear) = params; | ||
|
|
||
| final session = await ref.watch(sessionProvider.future); | ||
| if (session == null) { | ||
| return []; | ||
| } | ||
|
|
||
| final lectures = await ScheduleFetcherNewApiStudent( | ||
| studentNumber: student.number.toString(), | ||
| ).getLectures(session, lectiveYear: lectiveYear); | ||
|
|
||
| // Use the same deduplication as lectureProvider: convert to Set and back | ||
| // This relies on Lecture's equality implementation | ||
| return lectures.toSet().toList(); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
107 changes: 107 additions & 0 deletions
107
packages/uni_app/lib/view/student/student_schedule_page.dart
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| import 'package:flutter/material.dart'; | ||
| import 'package:flutter_riverpod/flutter_riverpod.dart'; | ||
| import 'package:uni/generated/l10n.dart'; | ||
| import 'package:uni/model/entities/course_units/course_unit_class.dart'; | ||
| import 'package:uni/model/entities/lecture.dart'; | ||
| import 'package:uni/model/providers/riverpod/default_consumer.dart'; | ||
| import 'package:uni/model/providers/riverpod/student_lectures_provider.dart'; | ||
| import 'package:uni/view/academic_path/widgets/schedule_page_shimmer.dart'; | ||
| import 'package:uni/view/academic_path/widgets/schedule_page_view.dart'; | ||
| import 'package:uni/view/widgets/pages_layouts/secondary/secondary.dart'; | ||
| import 'package:uni_ui/common_widgets/empty_state_widget.dart'; | ||
|
|
||
| class StudentSchedulePage extends ConsumerWidget { | ||
| StudentSchedulePage({super.key, required this.student, DateTime? now}) | ||
| : now = now ?? DateTime.now(); | ||
|
|
||
| final CourseUnitStudent student; | ||
| final DateTime now; | ||
|
|
||
| @override | ||
| Widget build(BuildContext context, WidgetRef ref) { | ||
| return MediaQuery.removePadding( | ||
| context: context, | ||
| removeBottom: true, | ||
| child: DefaultConsumer<List<Lecture>>( | ||
| provider: studentLecturesProvider((student, null)), | ||
| builder: (context, ref, lectures) { | ||
| final startOfWeek = _getStartOfWeek(now, lectures); | ||
|
|
||
| return SchedulePageView( | ||
| lectures, | ||
| startOfWeek: startOfWeek, | ||
| now: now, | ||
| showClassNumber: true, | ||
| ); | ||
| }, | ||
| nullContentWidget: LayoutBuilder( | ||
| builder: (context, constraints) => SingleChildScrollView( | ||
| physics: const AlwaysScrollableScrollPhysics(), | ||
| child: Container( | ||
| height: constraints.maxHeight, | ||
| padding: const EdgeInsets.only(bottom: 120), | ||
| child: Center( | ||
| child: EmptyStateWidget( | ||
| imagePath: 'assets/images/school.png', | ||
| title: S.of(context).no_classes, | ||
| subtitle: S.of(context).no_classes_this_week, | ||
| ), | ||
| ), | ||
| ), | ||
| ), | ||
| ), | ||
| hasContent: (lectures) => lectures.isNotEmpty, | ||
| mapper: (lectures) { | ||
| final startOfWeek = _getStartOfWeek(now, lectures); | ||
| final endOfNextWeek = startOfWeek.add(const Duration(days: 14)); | ||
|
|
||
| return lectures | ||
| .where( | ||
| (lecture) => | ||
| lecture.startTime.isAfter(startOfWeek) && | ||
| lecture.startTime.isBefore(endOfNextWeek), | ||
| ) | ||
| .toList(); | ||
| }, | ||
| loadingWidget: const ShimmerSchedulePage(), | ||
| ), | ||
| ); | ||
| } | ||
|
|
||
| DateTime _getStartOfWeek(DateTime now, List<Lecture> lectures) { | ||
| final initialSunday = now.subtract(Duration(days: now.weekday % 7)); | ||
| final secondSunday = initialSunday.add(const Duration(days: 7)); | ||
| final hasLecturesThisWeek = lectures.any( | ||
| (lecture) => | ||
| lecture.endTime.isAfter(now) && | ||
| lecture.startTime.isBefore(secondSunday), | ||
| ); | ||
| return !hasLecturesThisWeek ? secondSunday : initialSunday; | ||
| } | ||
| } | ||
|
|
||
| class StudentSchedulePageView extends ConsumerStatefulWidget { | ||
| const StudentSchedulePageView(this.student, {super.key}); | ||
|
|
||
| final CourseUnitStudent student; | ||
|
|
||
| @override | ||
| ConsumerState<StudentSchedulePageView> createState() => | ||
| _StudentSchedulePageViewState(); | ||
| } | ||
|
|
||
| class _StudentSchedulePageViewState | ||
| extends SecondaryPageViewState<StudentSchedulePageView> { | ||
| @override | ||
| Future<void> onRefresh() async { | ||
| ref.invalidate(studentLecturesProvider((widget.student, null))); | ||
| } | ||
|
|
||
| @override | ||
| String? getTitle() => widget.student.name; | ||
|
|
||
| @override | ||
| Widget getBody(BuildContext context) { | ||
| return StudentSchedulePage(student: widget.student); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: NIAEFEUP/uni
Length of output: 9840
🏁 Script executed:
Repository: NIAEFEUP/uni
Length of output: 45533
🏁 Script executed:
Repository: NIAEFEUP/uni
Length of output: 20157
Handle
/horario_estudantewithout route arguments.When
Navigator.pushNamedselects this known route without arguments,settings.argumentsisnull. Line 203 assignsnulltostudent, and the route closure then evaluatesstudent!, which throws before the page renders. The unknown-route fallback does not apply to this route. Validate the argument and return a safe fallback instead of dereferencingstudent!.🤖 Prompt for AI Agents