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,71 +1 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
/// Shimmer loading skeleton for the reports metrics grid.
///
/// Shows a 2-column grid of 6 placeholder cards matching the [MetricsGrid]
/// loaded layout.
class MetricsGridSkeleton extends StatelessWidget {
/// Creates a [MetricsGridSkeleton].
const MetricsGridSkeleton({super.key});
@override
Widget build(BuildContext context) {
return UiShimmer(
child: GridView.count(
padding: const EdgeInsets.symmetric(vertical: UiConstants.space6),
crossAxisCount: 2,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
mainAxisSpacing: UiConstants.space3,
crossAxisSpacing: UiConstants.space3,
childAspectRatio: 1.32,
children: List.generate(6, (int index) {
return const _MetricCardSkeleton();
}),
),
);
}
}
/// Shimmer placeholder for a single metric card.
class _MetricCardSkeleton extends StatelessWidget {
const _MetricCardSkeleton();
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(UiConstants.space4),
decoration: BoxDecoration(
border: Border.all(color: UiColors.border),
borderRadius: UiConstants.radiusLg,
color: UiColors.cardViewBackground,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Icon + label row
Row(
children: [
const UiShimmerCircle(size: UiConstants.space6),
const SizedBox(width: UiConstants.space2),
const Expanded(
child: UiShimmerLine(width: 60, height: 10),
),
],
),
const Spacer(),
// Value
const UiShimmerLine(width: 80, height: 22),
const SizedBox(height: UiConstants.space2),
// Badge
UiShimmerBox(
width: 60,
height: 20,
borderRadius: UiConstants.radiusSm,
),
],
),
);
}
}
export 'metrics_grid_skeleton/index.dart';

View File

@@ -0,0 +1,2 @@
export 'metric_card_skeleton.dart';
export 'metrics_grid_skeleton.dart';

View File

@@ -0,0 +1,45 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
/// Shimmer placeholder for a single metric card.
class MetricCardSkeleton extends StatelessWidget {
/// Creates a [MetricCardSkeleton].
const MetricCardSkeleton({super.key});
@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(UiConstants.space4),
decoration: BoxDecoration(
border: Border.all(color: UiColors.border),
borderRadius: UiConstants.radiusLg,
color: UiColors.cardViewBackground,
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Icon + label row
Row(
children: [
const UiShimmerCircle(size: UiConstants.space6),
const SizedBox(width: UiConstants.space2),
const Expanded(
child: UiShimmerLine(width: 60, height: 10),
),
],
),
const Spacer(),
// Value
const UiShimmerLine(width: 80, height: 22),
const SizedBox(height: UiConstants.space2),
// Badge
UiShimmerBox(
width: 60,
height: 20,
borderRadius: UiConstants.radiusSm,
),
],
),
);
}
}

View File

@@ -0,0 +1,31 @@
import 'package:design_system/design_system.dart';
import 'package:flutter/material.dart';
import 'metric_card_skeleton.dart';
/// Shimmer loading skeleton for the reports metrics grid.
///
/// Shows a 2-column grid of 6 placeholder cards matching the [MetricsGrid]
/// loaded layout.
class MetricsGridSkeleton extends StatelessWidget {
/// Creates a [MetricsGridSkeleton].
const MetricsGridSkeleton({super.key});
@override
Widget build(BuildContext context) {
return UiShimmer(
child: GridView.count(
padding: const EdgeInsets.symmetric(vertical: UiConstants.space6),
crossAxisCount: 2,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
mainAxisSpacing: UiConstants.space3,
crossAxisSpacing: UiConstants.space3,
childAspectRatio: 1.32,
children: List.generate(6, (int index) {
return const MetricCardSkeleton();
}),
),
);
}
}