feat: Add employee list skeleton loader for improved loading experience

This commit is contained in:
Vaibhav Surve 2025-06-19 16:22:48 +05:30
parent ef6521faa2
commit 97c873167f

View File

@ -76,9 +76,9 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
elevation: 0.5,
foregroundColor: Colors.black,
titleSpacing: 0,
centerTitle: false,
centerTitle: false,
leading: Padding(
padding: const EdgeInsets.only(top: 15.0),
padding: const EdgeInsets.only(top: 15.0),
child: IconButton(
icon: const Icon(Icons.arrow_back_ios_new,
color: Colors.black, size: 20),
@ -88,7 +88,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
),
),
title: Padding(
padding: const EdgeInsets.only(top: 15.0),
padding: const EdgeInsets.only(top: 15.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
@ -304,10 +304,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
),
),
if (isLoading)
const SizedBox(
height: 120,
child: Center(child: CircularProgressIndicator()),
)
employeeListSkeletonLoader()
else if (employees.isEmpty)
SizedBox(
height: 120,
@ -453,6 +450,80 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
});
}
Widget employeeListSkeletonLoader() {
return MyCard.bordered(
borderRadiusAll: 4,
paddingAll: 8,
child: Column(
children: List.generate(4, (index) {
return Column(
children: [
Padding(
padding: const EdgeInsets.only(bottom: 8),
child: Row(
children: [
// Avatar placeholder
Container(
width: 31,
height: 31,
decoration: BoxDecoration(
color: Colors.grey.shade300,
shape: BoxShape.circle,
),
),
MySpacing.width(16),
// Employee name/designation & buttons
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
height: 12,
width: 100,
color: Colors.grey.shade300,
),
MySpacing.height(8),
Container(
height: 10,
width: 80,
color: Colors.grey.shade300,
),
MySpacing.height(12),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Container(
height: 28,
width: 60,
color: Colors.grey.shade300,
),
MySpacing.width(8),
Container(
height: 28,
width: 60,
color: Colors.grey.shade300,
),
],
),
],
),
),
],
),
),
if (index != 3)
Divider(
color: Colors.grey.withOpacity(0.3),
thickness: 1,
height: 1,
),
],
);
}),
),
);
}
Widget employeeLog() {
return Obx(() {
final logs = List.of(attendanceController.attendanceLogs);
@ -503,10 +574,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
),
),
if (attendanceController.isLoadingAttendanceLogs.value)
const SizedBox(
height: 120,
child: Center(child: CircularProgressIndicator()),
)
employeeListSkeletonLoader()
else if (logs.isEmpty)
SizedBox(
height: 120,
@ -691,10 +759,7 @@ class _AttendanceScreenState extends State<AttendanceScreen> with UIMixin {
Obx(() {
final employees = attendanceController.regularizationLogs;
if (attendanceController.isLoadingRegularizationLogs.value) {
return SizedBox(
height: 120,
child: const Center(child: CircularProgressIndicator()),
);
return employeeListSkeletonLoader();
}
if (employees.isEmpty) {