From b9fdbfeae8d3ac502beee1c86adb999f9d456c1b Mon Sep 17 00:00:00 2001 From: orangdeso Date: Sun, 1 Jun 2025 22:27:37 +0700 Subject: [PATCH] Feat: add shimmer widget for features home --- lib/main.dart | 5 - .../controllers/auth_controller.dart | 3 + .../shimmer/home_porter_shimmer.dart | 123 ++++++++++++++++++ .../home/component/shimmer/home_shimmer.dart | 107 +++++++++++++++ .../screens/home/pages/home_screen.dart | 6 +- .../screens/splash/splash_screen.dart | 8 -- .../widgets/shimer/skeleton_widget.dart | 10 +- 7 files changed, 242 insertions(+), 20 deletions(-) create mode 100644 lib/presentation/screens/home/component/shimmer/home_porter_shimmer.dart create mode 100644 lib/presentation/screens/home/component/shimmer/home_shimmer.dart diff --git a/lib/main.dart b/lib/main.dart index daf6a1b..71e25b5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,12 +1,7 @@ -// ignore_for_file: deprecated_member_use -// import 'package:firebase_dynamic_links/firebase_dynamic_links.dart'; -// import 'package:e_porter/presentation/controllers/profil_controller.dart'; -// import 'package:firebase_auth/firebase_auth.dart'; import 'dart:developer'; import 'package:e_porter/domain/bindings/app_binding.dart'; import 'package:e_porter/presentation/screens/routes/app_rountes.dart'; import 'package:firebase_core/firebase_core.dart'; - import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; diff --git a/lib/presentation/controllers/auth_controller.dart b/lib/presentation/controllers/auth_controller.dart index 0a24cec..45fd820 100644 --- a/lib/presentation/controllers/auth_controller.dart +++ b/lib/presentation/controllers/auth_controller.dart @@ -74,6 +74,9 @@ class AuthController extends GetxController { return; } + emailController.clear(); + passwordController.clear(); + await PreferencesService.saveUserData(userData); Get.offAllNamed(Routes.NAVBAR, arguments: effectiveRole); } on AuthException catch (e) { diff --git a/lib/presentation/screens/home/component/shimmer/home_porter_shimmer.dart b/lib/presentation/screens/home/component/shimmer/home_porter_shimmer.dart new file mode 100644 index 0000000..a386687 --- /dev/null +++ b/lib/presentation/screens/home/component/shimmer/home_porter_shimmer.dart @@ -0,0 +1,123 @@ +import 'package:e_porter/_core/component/card/custome_shadow_cotainner.dart'; +import 'package:e_porter/presentation/widgets/shimer/skeleton_widget.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +class HomePorterShimmer extends StatelessWidget { + const HomePorterShimmer({super.key}); + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Container( + width: double.infinity, + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), + decoration: BoxDecoration( + color: Colors.white, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.02), + offset: const Offset(0, 4), + blurRadius: 14, + spreadRadius: 10, + ), + ], + ), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + CircleAvatar( + radius: 24.r, + child: SkeletonWidget(), + ), + SizedBox(width: 16.w), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SizedBox(height: 8.h), + SkeletonWidget(height: 16.h, width: 120.w), + SizedBox(height: 6.h), + SkeletonWidget(height: 12.h, width: 200.w), + ], + ), + ], + ), + ), + SizedBox(height: 32.h), + Padding( + padding: EdgeInsets.symmetric(horizontal: 16.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _buildShimmerTitle(context), + SkeletonWidget( + width: MediaQuery.of(context).size.width * 0.21, + height: 24.h, + ), + ], + ), + SizedBox(height: 16.h), + _buildShimmerCard(context), + SizedBox(height: 32.h), + _buildShimmerTitle(context), + SizedBox(height: 16.h), + Row( + children: [ + Expanded(child: _buildShimmerCard(context)), + SizedBox(width: 16.w), + Expanded(child: _buildShimmerCard(context)), + ], + ), + SizedBox(height: 16.h), + Row( + children: [ + Expanded(child: _buildShimmerCard(context)), + SizedBox(width: 16.w), + Expanded(child: _buildShimmerCard(context)), + ], + ) + ], + ), + ) + ], + ), + ); + } + + Widget _buildShimmerTitle(BuildContext context) { + return SkeletonWidget( + width: MediaQuery.of(context).size.width * 0.51, + height: 24.h, + ); + } + + Widget _buildShimmerCard(BuildContext context) { + return CustomeShadowCotainner( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SkeletonWidget( + height: MediaQuery.of(context).size.width * 0.14, + width: MediaQuery.of(context).size.width * 0.14, + ), + SizedBox(height: 10.h), + SkeletonWidget( + height: 20.h, + width: MediaQuery.of(context).size.width * 0.34, + ), + SizedBox(height: 10.h), + SkeletonWidget( + height: 14.h, + width: MediaQuery.of(context).size.width * 0.6, + ), + ], + ), + ); + } +} diff --git a/lib/presentation/screens/home/component/shimmer/home_shimmer.dart b/lib/presentation/screens/home/component/shimmer/home_shimmer.dart new file mode 100644 index 0000000..82ab8c7 --- /dev/null +++ b/lib/presentation/screens/home/component/shimmer/home_shimmer.dart @@ -0,0 +1,107 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:e_porter/presentation/widgets/shimer/skeleton_widget.dart'; +import 'package:e_porter/_core/constants/colors.dart'; + +class HomeShimmer extends StatelessWidget { + const HomeShimmer({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Stack( + children: [ + Container( + height: 60.h, + width: double.infinity, + color: PrimaryColors.primary800, + ), + Container( + margin: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), + child: ListView( + children: [ + Container( + padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10.r), + border: Border.all( + strokeAlign: 1.w, + color: GrayColors.gray100, + ), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.06), + offset: const Offset(0, 4), + blurRadius: 14, + spreadRadius: 10, + ), + ], + ), + child: Column( + children: [ + Row( + children: [ + // Avatar shimmer + SkeletonWidget(height: 50.h, width: 50.w), + SizedBox(width: 16.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + SkeletonWidget(height: 16.h, width: 120.w), + SizedBox(height: 8.h), + SkeletonWidget(height: 12.h, width: 200.w), + ], + ), + ), + ], + ), + SizedBox(height: 20.h), + // Button shimmer + SkeletonWidget(height: 60.h, width: double.infinity), + ], + ), + ), + SizedBox(height: 32.h), + + // Carousel shimmer + SkeletonWidget(height: 140.h, width: double.infinity), + SizedBox(height: 10.h), + + // Dots indicator shimmer + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: List.generate( + 4, + (index) => Container( + width: 8.w, + height: 8.h, + margin: EdgeInsets.symmetric(horizontal: 4.w), + child: SkeletonWidget(height: 8.h, width: 8.w), + )), + ), + SizedBox(height: 32.h), + + // Services title shimmer + SkeletonWidget(height: 20.h, width: 150.w), + SizedBox(height: 4.h), + SkeletonWidget(height: 14.h, width: 250.w), + SizedBox(height: 16.h), + + // Service cards shimmer + Row( + children: [ + Expanded(child: SkeletonWidget(height: 80.h, width: double.infinity)), + SizedBox(width: 16.w), + Expanded(child: SkeletonWidget(height: 80.h, width: double.infinity)), + SizedBox(width: 16.w), + Expanded(child: SkeletonWidget(height: 80.h, width: double.infinity)), + ], + ), + ], + ), + ), + ], + ); + } +} diff --git a/lib/presentation/screens/home/pages/home_screen.dart b/lib/presentation/screens/home/pages/home_screen.dart index a0955b9..5dbda1b 100644 --- a/lib/presentation/screens/home/pages/home_screen.dart +++ b/lib/presentation/screens/home/pages/home_screen.dart @@ -16,6 +16,8 @@ import 'package:e_porter/presentation/screens/home/component/banners/welcome_ban import 'package:e_porter/presentation/screens/home/component/card_service_porter.dart'; import 'package:e_porter/presentation/screens/home/component/date_setting.dart'; import 'package:e_porter/presentation/screens/home/component/profile_avatar.dart'; +import 'package:e_porter/presentation/screens/home/component/shimmer/home_porter_shimmer.dart'; +import 'package:e_porter/presentation/screens/home/component/shimmer/home_shimmer.dart'; import 'package:e_porter/presentation/screens/home/component/summary_card.dart'; import 'package:e_porter/presentation/screens/routes/app_rountes.dart'; import 'package:flutter/material.dart'; @@ -193,7 +195,7 @@ class _HomeScreenState extends State { builder: (context, snapshot) { String userName = "Guest"; if (snapshot.connectionState == ConnectionState.waiting) { - return Center(child: CircularProgressIndicator()); + return const HomeShimmer(); } else if (snapshot.hasData && snapshot.data?.name != null) { userName = snapshot.data!.name!; } @@ -364,7 +366,7 @@ class _HomeScreenState extends State { String userPorter = "Guest"; String userId = ''; if (snapshot.connectionState == ConnectionState.waiting) { - return Center(child: CircularProgressIndicator()); + return const HomePorterShimmer(); } else if (snapshot.hasData && snapshot.data?.name != null) { userPorter = snapshot.data!.name!; diff --git a/lib/presentation/screens/splash/splash_screen.dart b/lib/presentation/screens/splash/splash_screen.dart index 8f2b79b..8ef1a6d 100644 --- a/lib/presentation/screens/splash/splash_screen.dart +++ b/lib/presentation/screens/splash/splash_screen.dart @@ -17,14 +17,6 @@ class _SplashScreenState extends State { @override void initState() { super.initState(); - // Future.delayed(Duration(seconds: 3), () async { - // final userData = await PreferencesService.getUserData(); - // if (userData != null) { - // Get.offAllNamed(Routes.NAVBAR, arguments: userData.role); - // } else { - // Get.offAllNamed(Routes.ONBOARDING); - // } - // }); _navigateAfterDelay(); } diff --git a/lib/presentation/widgets/shimer/skeleton_widget.dart b/lib/presentation/widgets/shimer/skeleton_widget.dart index dc9492e..49bddaf 100644 --- a/lib/presentation/widgets/shimer/skeleton_widget.dart +++ b/lib/presentation/widgets/shimer/skeleton_widget.dart @@ -3,13 +3,13 @@ import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:shimmer/shimmer.dart'; class SkeletonWidget extends StatelessWidget { - final double height; - final double width; + final double? height; + final double? width; const SkeletonWidget({ Key? key, - required this.height, - required this.width, + this.height, + this.width, }) : super(key: key); @override @@ -27,4 +27,4 @@ class SkeletonWidget extends StatelessWidget { ), ); } -} \ No newline at end of file +}