Feat: add shimmer widget for features home

This commit is contained in:
orangdeso 2025-06-01 22:27:37 +07:00
parent ac1d7680bb
commit b9fdbfeae8
7 changed files with 242 additions and 20 deletions

View File

@ -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 'dart:developer';
import 'package:e_porter/domain/bindings/app_binding.dart'; import 'package:e_porter/domain/bindings/app_binding.dart';
import 'package:e_porter/presentation/screens/routes/app_rountes.dart'; import 'package:e_porter/presentation/screens/routes/app_rountes.dart';
import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_core/firebase_core.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';

View File

@ -74,6 +74,9 @@ class AuthController extends GetxController {
return; return;
} }
emailController.clear();
passwordController.clear();
await PreferencesService.saveUserData(userData); await PreferencesService.saveUserData(userData);
Get.offAllNamed(Routes.NAVBAR, arguments: effectiveRole); Get.offAllNamed(Routes.NAVBAR, arguments: effectiveRole);
} on AuthException catch (e) { } on AuthException catch (e) {

View File

@ -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,
),
],
),
);
}
}

View File

@ -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)),
],
),
],
),
),
],
);
}
}

View File

@ -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/card_service_porter.dart';
import 'package:e_porter/presentation/screens/home/component/date_setting.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/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/home/component/summary_card.dart';
import 'package:e_porter/presentation/screens/routes/app_rountes.dart'; import 'package:e_porter/presentation/screens/routes/app_rountes.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -193,7 +195,7 @@ class _HomeScreenState extends State<HomeScreen> {
builder: (context, snapshot) { builder: (context, snapshot) {
String userName = "Guest"; String userName = "Guest";
if (snapshot.connectionState == ConnectionState.waiting) { if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator()); return const HomeShimmer();
} else if (snapshot.hasData && snapshot.data?.name != null) { } else if (snapshot.hasData && snapshot.data?.name != null) {
userName = snapshot.data!.name!; userName = snapshot.data!.name!;
} }
@ -364,7 +366,7 @@ class _HomeScreenState extends State<HomeScreen> {
String userPorter = "Guest"; String userPorter = "Guest";
String userId = ''; String userId = '';
if (snapshot.connectionState == ConnectionState.waiting) { if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator()); return const HomePorterShimmer();
} else if (snapshot.hasData && snapshot.data?.name != null) { } else if (snapshot.hasData && snapshot.data?.name != null) {
userPorter = snapshot.data!.name!; userPorter = snapshot.data!.name!;

View File

@ -17,14 +17,6 @@ class _SplashScreenState extends State<SplashScreen> {
@override @override
void initState() { void initState() {
super.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(); _navigateAfterDelay();
} }

View File

@ -3,13 +3,13 @@ import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:shimmer/shimmer.dart'; import 'package:shimmer/shimmer.dart';
class SkeletonWidget extends StatelessWidget { class SkeletonWidget extends StatelessWidget {
final double height; final double? height;
final double width; final double? width;
const SkeletonWidget({ const SkeletonWidget({
Key? key, Key? key,
required this.height, this.height,
required this.width, this.width,
}) : super(key: key); }) : super(key: key);
@override @override