feat: order shimmer

This commit is contained in:
efrilm 2025-08-19 11:44:50 +07:00
parent 5b91b5978f
commit 9b51bf2bee

View File

@ -4,6 +4,7 @@ import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:line_icons/line_icons.dart'; import 'package:line_icons/line_icons.dart';
import 'package:shimmer/shimmer.dart';
import '../../../../application/order/order_loader/order_loader_bloc.dart'; import '../../../../application/order/order_loader/order_loader_bloc.dart';
import '../../../../common/theme/theme.dart'; import '../../../../common/theme/theme.dart';
@ -76,6 +77,104 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
super.dispose(); super.dispose();
} }
Widget _buildShimmerOrderCard() {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Container(
margin: const EdgeInsets.only(bottom: 12),
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(12),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 2),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 120,
height: 16,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
Container(
width: 60,
height: 20,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(10),
),
),
],
),
const SizedBox(height: 8),
Container(
width: double.infinity,
height: 14,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 6),
Container(
width: 200,
height: 14,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
const SizedBox(height: 12),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
width: 80,
height: 14,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
Container(
width: 100,
height: 16,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(4),
),
),
],
),
],
),
),
);
}
Widget _buildShimmerList() {
return ListView.builder(
itemCount: 5, // Show 5 shimmer cards
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
padding: EdgeInsets.zero,
itemBuilder: (context, index) => _buildShimmerOrderCard(),
);
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return Scaffold( return Scaffold(
@ -180,7 +279,7 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
child: Column( child: Column(
children: [ children: [
// Show filtered transaction count // Show filtered transaction count
if (state.status != 'all') if (state.status != 'all' && !state.isFetching)
Padding( Padding(
padding: const EdgeInsets.only(bottom: 16), padding: const EdgeInsets.only(bottom: 16),
child: Row( child: Row(
@ -196,30 +295,33 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
), ),
), ),
// Transaction List // Order List with Shimmer Loading
state.orders.isEmpty if (state.isFetching)
? EmptyWidget( _buildShimmerList()
title: 'Order', else if (state.orders.isEmpty)
message: EmptyWidget(
'No ${state.status.toLowerCase()} orders found', title: 'Order',
) message:
: ListView.builder( 'No ${state.status.toLowerCase()} orders found',
itemCount: state.orders.length, )
shrinkWrap: true, else
physics: ListView.builder(
const NeverScrollableScrollPhysics(), itemCount: state.orders.length,
padding: EdgeInsets.zero, shrinkWrap: true,
itemBuilder: (context, index) { physics:
return OrderTile( const NeverScrollableScrollPhysics(),
onTap: () => context.router.push( padding: EdgeInsets.zero,
OrderDetailRoute( itemBuilder: (context, index) {
order: state.orders[index], return OrderTile(
), onTap: () => context.router.push(
), OrderDetailRoute(
order: state.orders[index], order: state.orders[index],
); ),
}, ),
), order: state.orders[index],
);
},
),
], ],
), ),
), ),
@ -236,5 +338,3 @@ class _OrderPageState extends State<OrderPage> with TickerProviderStateMixin {
); );
} }
} }
// Custom delegate for pinned filter header