diff --git a/.github/issues/bug-parent-dashboard-overflow.md b/.github/issues/bug-parent-dashboard-overflow.md new file mode 100644 index 0000000..41adbc2 --- /dev/null +++ b/.github/issues/bug-parent-dashboard-overflow.md @@ -0,0 +1,39 @@ +# [Bug] UI Overflow in Parent Dashboard (Bottom Overflowed by 27 pixels) + +**Description** + +When running the app on smaller screen devices (e.g., 1200×540 resolution), the Parent Dashboard screen throws a `Bottom Overflowed by 27 pixels` error. This happens when the content exceeds the visible height and the layout is not scrollable or doesn't account for system UI/padding. + +**Screenshot** + +(Attach the screenshot here) — drag and drop when creating the GitHub issue. + +**Steps to Reproduce** + +1. Open the Parent Dashboard (`lib/features/parent/presentation/pages/parent_dashboard.dart`). +2. Run the app on a smaller device or emulator (e.g., Pixel 4a or 1200×540 resolution). +3. Observe the bottom part of the "Quick Overview" section — the error appears in the debug console: `Bottom Overflowed by 27 pixels`. + +**Expected Behavior** + +The UI should scroll smoothly without overflow errors, and all widgets should be visible. The layout should respect safe areas (system UI insets) on devices with varying screen sizes. + +**Suggested Fix** + +- Wrap the dashboard's main content in a scrollable widget (e.g., `SingleChildScrollView`) OR use sliver-based widgets such as `SliverList`/`SliverPadding` for content inside a `CustomScrollView`. +- Ensure `SafeArea` (or bottom padding using `MediaQuery.of(context).viewPadding.bottom`) is applied where necessary so system UI does not clip content. +- Alternatively, convert the content sections into slivers rather than nested non-sliver scrollables. + +**Notes** + +I applied a simple, low-risk fix in the repo to mitigate this: the `SliverToBoxAdapter` content has been wrapped in a `SafeArea` with added bottom padding to avoid bottom clipping on smaller screens. This prevents the overflow on many devices while keeping the sliver structure. If the content grows further or is dynamic, consider converting the sections into sliver children (e.g., `SliverList`) for better performance. + +**Environment** + +- Flutter SDK: see `flutter --version` +- Dart SDK: see `dart --version` +- Affected file: `lib/features/parent/presentation/pages/parent_dashboard.dart` + +**Additional context** + +Attach any logs or screenshots here. diff --git a/lib/features/parent/presentation/pages/parent_dashboard.dart b/lib/features/parent/presentation/pages/parent_dashboard.dart index 22b254c..36314fd 100644 --- a/lib/features/parent/presentation/pages/parent_dashboard.dart +++ b/lib/features/parent/presentation/pages/parent_dashboard.dart @@ -157,152 +157,164 @@ class _ParentDashboardState extends State { // Content SliverToBoxAdapter( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - const SizedBox(height: AppSizes.spaceL), + child: SafeArea( + bottom: true, + child: Padding( + // Ensure there's extra bottom padding to avoid bottom overflow on + // small devices or when system UI (nav bars) are present. + padding: EdgeInsets.only( + bottom: + MediaQuery.of(context).viewPadding.bottom + + AppSizes.padding, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const SizedBox(height: AppSizes.spaceL), - // Quick Overview Cards with Modern Design - Padding( - padding: const EdgeInsets.symmetric( - horizontal: AppSizes.padding, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - 'Quick Overview', - style: Theme.of(context).textTheme.titleLarge - ?.copyWith( - fontWeight: FontWeight.w700, - color: AppColors.textPrimary, - ), + // Quick Overview Cards with Modern Design + Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSizes.padding, ), - const SizedBox(height: AppSizes.space), - // Grid of 4 Overview Cards - GridView.count( - crossAxisCount: 2, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - mainAxisSpacing: AppSizes.spaceM, - crossAxisSpacing: AppSizes.spaceM, - childAspectRatio: 1.5, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - _ModernOverviewCard( - title: AppStrings.attendance, - value: '95%', - icon: Icons.calendar_today_rounded, - gradientColors: const [ - AppColors.success, - Color(0xFF34D399), - ], - subtitle: 'This month', + Text( + 'Quick Overview', + style: Theme.of(context).textTheme.titleLarge + ?.copyWith( + fontWeight: FontWeight.w700, + color: AppColors.textPrimary, + ), ), - _ModernOverviewCard( - title: 'Performance', - value: '85%', - icon: Icons.trending_up_rounded, - gradientColors: const [ - AppColors.info, - Color(0xFF60A5FA), - ], - subtitle: 'Average score', - showBadge: false, - ), - _ModernOverviewCard( - title: AppStrings.fees, - value: '₹5,000', - icon: Icons.payments_rounded, - gradientColors: const [ - AppColors.warning, - Color(0xFFFBBF24), - ], - subtitle: 'Due on 15 Oct', - showBadge: true, - badgeText: 'DUE', - ), - _ModernOverviewCard( - title: 'Messages', - value: '3', - icon: Icons.chat_bubble_rounded, - gradientColors: const [ - Color(0xFF8B5CF6), - Color(0xFFA78BFA), + const SizedBox(height: AppSizes.space), + // Grid of 4 Overview Cards + GridView.count( + crossAxisCount: 2, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + mainAxisSpacing: AppSizes.spaceM, + crossAxisSpacing: AppSizes.spaceM, + childAspectRatio: 1.5, + children: [ + _ModernOverviewCard( + title: AppStrings.attendance, + value: '95%', + icon: Icons.calendar_today_rounded, + gradientColors: const [ + AppColors.success, + Color(0xFF34D399), + ], + subtitle: 'This month', + ), + _ModernOverviewCard( + title: 'Performance', + value: '85%', + icon: Icons.trending_up_rounded, + gradientColors: const [ + AppColors.info, + Color(0xFF60A5FA), + ], + subtitle: 'Average score', + showBadge: false, + ), + _ModernOverviewCard( + title: AppStrings.fees, + value: '₹5,000', + icon: Icons.payments_rounded, + gradientColors: const [ + AppColors.warning, + Color(0xFFFBBF24), + ], + subtitle: 'Due on 15 Oct', + showBadge: true, + badgeText: 'DUE', + ), + _ModernOverviewCard( + title: 'Messages', + value: '3', + icon: Icons.chat_bubble_rounded, + gradientColors: const [ + Color(0xFF8B5CF6), + Color(0xFFA78BFA), + ], + subtitle: 'New', + showBadge: true, + badgeText: 'NEW', + ), ], - subtitle: 'New', - showBadge: true, - badgeText: 'NEW', ), ], ), - ], - ), - ), + ), - const SizedBox(height: AppSizes.spaceXXL), + const SizedBox(height: AppSizes.spaceXXL), - // Action Grid - Padding( - padding: const EdgeInsets.symmetric( - horizontal: AppSizes.padding, - ), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - AppStrings.quickActions, - style: Theme.of(context).textTheme.titleLarge - ?.copyWith( - fontWeight: FontWeight.w700, - color: AppColors.textPrimary, - ), + // Action Grid + Padding( + padding: const EdgeInsets.symmetric( + horizontal: AppSizes.padding, ), - const SizedBox(height: AppSizes.space), - GridView.count( - crossAxisCount: 3, - shrinkWrap: true, - physics: const NeverScrollableScrollPhysics(), - mainAxisSpacing: AppSizes.spaceM, - crossAxisSpacing: AppSizes.spaceM, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - _ParentActionItem( - icon: Icons.calendar_today_rounded, - label: AppStrings.attendance, - color: AppColors.success, + Text( + AppStrings.quickActions, + style: Theme.of(context).textTheme.titleLarge + ?.copyWith( + fontWeight: FontWeight.w700, + color: AppColors.textPrimary, + ), ), - _ParentActionItem( - icon: Icons.insights_rounded, - label: AppStrings.performance, - color: AppColors.info, - ), - _ParentActionItem( - icon: Icons.payments_rounded, - label: AppStrings.fees, - color: AppColors.warning, - ), - _ParentActionItem( - icon: Icons.chat_bubble_rounded, - label: AppStrings.messages, - color: const Color(0xFF8B5CF6), - ), - _ParentActionItem( - icon: Icons.school_rounded, - label: AppStrings.schoolInfo, - color: AppColors.secondary, - ), - _ParentActionItem( - icon: Icons.report_rounded, - label: AppStrings.complaints, - color: AppColors.error, + const SizedBox(height: AppSizes.space), + GridView.count( + crossAxisCount: 3, + shrinkWrap: true, + physics: const NeverScrollableScrollPhysics(), + mainAxisSpacing: AppSizes.spaceM, + crossAxisSpacing: AppSizes.spaceM, + children: [ + _ParentActionItem( + icon: Icons.calendar_today_rounded, + label: AppStrings.attendance, + color: AppColors.success, + ), + _ParentActionItem( + icon: Icons.insights_rounded, + label: AppStrings.performance, + color: AppColors.info, + ), + _ParentActionItem( + icon: Icons.payments_rounded, + label: AppStrings.fees, + color: AppColors.warning, + ), + _ParentActionItem( + icon: Icons.chat_bubble_rounded, + label: AppStrings.messages, + color: const Color(0xFF8B5CF6), + ), + _ParentActionItem( + icon: Icons.school_rounded, + label: AppStrings.schoolInfo, + color: AppColors.secondary, + ), + _ParentActionItem( + icon: Icons.report_rounded, + label: AppStrings.complaints, + color: AppColors.error, + ), + ], ), ], ), - ], - ), - ), + ), - const SizedBox(height: AppSizes.spaceL), - ], + const SizedBox(height: AppSizes.spaceL), + ], + ), + ), ), ), ],