feat: add shimmer loading skeletons for various pages and components

- Implemented ReorderCardSkeleton and ReorderSectionSkeleton for the client home page.
- Added SpendingCardSkeleton and SpendingSectionSkeleton for spending-related UI.
- Created OrderCardSkeleton and associated skeletons for the view orders page.
- Developed MetricCardSkeleton and MetricsGridSkeleton for reports page metrics.
- Introduced HomePageSkeleton and its components for staff home page.
- Added PaymentItemSkeleton and PaymentsPageSkeleton for payments page.
- Created ShiftDetailsPageSkeleton and related components for shift details.
- Implemented ShiftsPageSkeleton and ShiftCardSkeleton for shifts page.
This commit is contained in:
Achintha Isuru
2026-03-10 14:25:56 -04:00
parent 2d6133aba8
commit 4423775fa1
52 changed files with 1603 additions and 1443 deletions

View File

@@ -1,102 +1 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
/// Shimmer loading skeleton that mimics the coverage page loaded layout.
///
/// Shows placeholder shapes for the quick stats row, shift section header,
/// and a list of shift cards with worker rows.
class CoveragePageSkeleton extends StatelessWidget {
/// Creates a [CoveragePageSkeleton].
const CoveragePageSkeleton({super.key});
@override
Widget build(BuildContext context) {
return UiShimmer(
child: Padding(
padding: const EdgeInsets.all(UiConstants.space5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Quick stats row (2 stat cards)
const Row(
children: [
Expanded(child: UiShimmerStatsCard()),
SizedBox(width: UiConstants.space2),
Expanded(child: UiShimmerStatsCard()),
],
),
const SizedBox(height: UiConstants.space6),
// Shifts section header
const UiShimmerLine(width: 140, height: 18),
const SizedBox(height: UiConstants.space6),
// Shift cards with worker rows
const _ShiftCardSkeleton(),
const SizedBox(height: UiConstants.space3),
const _ShiftCardSkeleton(),
const SizedBox(height: UiConstants.space3),
const _ShiftCardSkeleton(),
],
),
),
);
}
}
/// Shimmer placeholder for a single shift card with header and worker rows.
class _ShiftCardSkeleton extends StatelessWidget {
const _ShiftCardSkeleton();
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: UiColors.border),
borderRadius: UiConstants.radiusLg,
),
clipBehavior: Clip.antiAlias,
child: Column(
children: [
// Shift header
Padding(
padding: const EdgeInsets.all(UiConstants.space4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const UiShimmerLine(width: 180, height: 16),
const SizedBox(height: UiConstants.space2),
const UiShimmerLine(width: 120, height: 12),
const SizedBox(height: UiConstants.space2),
Row(
children: [
const UiShimmerLine(width: 80, height: 12),
const Spacer(),
UiShimmerBox(
width: 60,
height: 24,
borderRadius: UiConstants.radiusFull,
),
],
),
],
),
),
// Worker rows
Padding(
padding: const EdgeInsets.symmetric(
horizontal: UiConstants.space3,
).copyWith(bottom: UiConstants.space3),
child: const Column(
children: [
UiShimmerListItem(),
UiShimmerListItem(),
],
),
),
],
),
);
}
}
export 'coverage_page_skeleton/index.dart';

View File

@@ -0,0 +1,47 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'shift_card_skeleton.dart';
/// Shimmer loading skeleton that mimics the coverage page loaded layout.
///
/// Shows placeholder shapes for the quick stats row, shift section header,
/// and a list of shift cards with worker rows.
class CoveragePageSkeleton extends StatelessWidget {
/// Creates a [CoveragePageSkeleton].
const CoveragePageSkeleton({super.key});
@override
Widget build(BuildContext context) {
return UiShimmer(
child: Padding(
padding: const EdgeInsets.all(UiConstants.space5),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Quick stats row (2 stat cards)
const Row(
children: [
Expanded(child: UiShimmerStatsCard()),
SizedBox(width: UiConstants.space2),
Expanded(child: UiShimmerStatsCard()),
],
),
const SizedBox(height: UiConstants.space6),
// Shifts section header
const UiShimmerLine(width: 140, height: 18),
const SizedBox(height: UiConstants.space6),
// Shift cards with worker rows
const ShiftCardSkeleton(),
const SizedBox(height: UiConstants.space3),
const ShiftCardSkeleton(),
const SizedBox(height: UiConstants.space3),
const ShiftCardSkeleton(),
],
),
),
);
}
}

View File

@@ -0,0 +1,2 @@
export 'coverage_page_skeleton.dart';
export 'shift_card_skeleton.dart';

View File

@@ -0,0 +1,60 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
/// Shimmer placeholder for a single shift card with header and worker rows.
class ShiftCardSkeleton extends StatelessWidget {
/// Creates a [ShiftCardSkeleton].
const ShiftCardSkeleton({super.key});
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: UiColors.border),
borderRadius: UiConstants.radiusLg,
),
clipBehavior: Clip.antiAlias,
child: Column(
children: [
// Shift header
Padding(
padding: const EdgeInsets.all(UiConstants.space4),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const UiShimmerLine(width: 180, height: 16),
const SizedBox(height: UiConstants.space2),
const UiShimmerLine(width: 120, height: 12),
const SizedBox(height: UiConstants.space2),
Row(
children: [
const UiShimmerLine(width: 80, height: 12),
const Spacer(),
UiShimmerBox(
width: 60,
height: 24,
borderRadius: UiConstants.radiusFull,
),
],
),
],
),
),
// Worker rows
Padding(
padding: const EdgeInsets.symmetric(
horizontal: UiConstants.space3,
).copyWith(bottom: UiConstants.space3),
child: const Column(
children: [
UiShimmerListItem(),
UiShimmerListItem(),
],
),
),
],
),
);
}
}