feat: add shimmer skeletons for various sections in the staff profile and onboarding features
- Implemented ProfilePageSkeleton for loading state in staff profile. - Added ReliabilityScoreSkeleton and ReliabilityStatsSkeleton for reliability metrics. - Created CertificatesSkeleton and related components for loading certificates. - Developed DocumentsSkeleton and associated document card skeletons. - Introduced TaxFormsSkeleton for loading tax forms. - Added BankAccountSkeleton and its components for bank account loading state. - Created TimeCardSkeleton for displaying time card loading state. - Implemented AttireSkeleton for loading attire items. - Added PersonalInfoSkeleton for loading personal information. - Developed FaqsSkeleton for loading FAQ sections. - Created PrivacySecuritySkeleton for loading privacy settings.
This commit is contained in:
@@ -10,6 +10,7 @@ import '../blocs/bank_account_cubit.dart';
|
||||
import '../blocs/bank_account_state.dart';
|
||||
import '../widgets/account_card.dart';
|
||||
import '../widgets/add_account_form.dart';
|
||||
import '../widgets/bank_account_skeleton/bank_account_skeleton.dart';
|
||||
import '../widgets/security_notice.dart';
|
||||
|
||||
class BankAccountPage extends StatelessWidget {
|
||||
@@ -49,7 +50,7 @@ class BankAccountPage extends StatelessWidget {
|
||||
builder: (BuildContext context, BankAccountState state) {
|
||||
if (state.status == BankAccountStatus.loading &&
|
||||
state.accounts.isEmpty) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
return const BankAccountSkeleton();
|
||||
}
|
||||
|
||||
if (state.status == BankAccountStatus.error) {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Shimmer placeholder for a single bank account card.
|
||||
class AccountCardSkeleton extends StatelessWidget {
|
||||
/// Creates an [AccountCardSkeleton].
|
||||
const AccountCardSkeleton({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: const Row(
|
||||
children: <Widget>[
|
||||
UiShimmerCircle(size: 40),
|
||||
SizedBox(width: UiConstants.space3),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
UiShimmerLine(width: 140, height: 14),
|
||||
SizedBox(height: UiConstants.space2),
|
||||
UiShimmerLine(width: 100, height: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
UiShimmerBox(width: 48, height: 24),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'account_card_skeleton.dart';
|
||||
import 'security_notice_skeleton.dart';
|
||||
|
||||
/// Full-page shimmer skeleton shown while bank accounts are loading.
|
||||
class BankAccountSkeleton extends StatelessWidget {
|
||||
/// Creates a [BankAccountSkeleton].
|
||||
const BankAccountSkeleton({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return UiShimmer(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.all(UiConstants.space4),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
const SecurityNoticeSkeleton(),
|
||||
const SizedBox(height: UiConstants.space4),
|
||||
UiShimmerList(
|
||||
itemCount: 2,
|
||||
spacing: UiConstants.space3,
|
||||
itemBuilder: (int index) => const AccountCardSkeleton(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Shimmer placeholder for the security notice banner.
|
||||
class SecurityNoticeSkeleton extends StatelessWidget {
|
||||
/// Creates a [SecurityNoticeSkeleton].
|
||||
const SecurityNoticeSkeleton({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: const Row(
|
||||
children: <Widget>[
|
||||
UiShimmerCircle(size: 24),
|
||||
SizedBox(width: UiConstants.space3),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
UiShimmerLine(width: 160, height: 14),
|
||||
SizedBox(height: UiConstants.space2),
|
||||
UiShimmerLine(height: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import 'package:krow_core/core.dart';
|
||||
import '../blocs/time_card_bloc.dart';
|
||||
import '../widgets/month_selector.dart';
|
||||
import '../widgets/shift_history_list.dart';
|
||||
import '../widgets/time_card_skeleton/time_card_skeleton.dart';
|
||||
import '../widgets/time_card_summary.dart';
|
||||
|
||||
/// The main page for displaying the staff time card.
|
||||
@@ -50,7 +51,7 @@ class _TimeCardPageState extends State<TimeCardPage> {
|
||||
},
|
||||
builder: (BuildContext context, TimeCardState state) {
|
||||
if (state is TimeCardLoading) {
|
||||
return const Center(child: CircularProgressIndicator());
|
||||
return const TimeCardSkeleton();
|
||||
} else if (state is TimeCardError) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Shimmer placeholder for the month selector row.
|
||||
class MonthSelectorSkeleton extends StatelessWidget {
|
||||
/// Creates a [MonthSelectorSkeleton].
|
||||
const MonthSelectorSkeleton({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: <Widget>[
|
||||
UiShimmerCircle(size: 32),
|
||||
UiShimmerLine(width: 120, height: 16),
|
||||
UiShimmerCircle(size: 32),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Shimmer placeholder for a single shift history row.
|
||||
class ShiftHistorySkeleton extends StatelessWidget {
|
||||
/// Creates a [ShiftHistorySkeleton].
|
||||
const ShiftHistorySkeleton({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: const Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
UiShimmerLine(width: 140, height: 14),
|
||||
SizedBox(height: UiConstants.space2),
|
||||
UiShimmerLine(width: 100, height: 12),
|
||||
],
|
||||
),
|
||||
),
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: <Widget>[
|
||||
UiShimmerLine(width: 60, height: 14),
|
||||
SizedBox(height: UiConstants.space2),
|
||||
UiShimmerLine(width: 40, height: 12),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'month_selector_skeleton.dart';
|
||||
import 'shift_history_skeleton.dart';
|
||||
import 'time_card_summary_skeleton.dart';
|
||||
|
||||
/// Full-page shimmer skeleton shown while time card data is loading.
|
||||
class TimeCardSkeleton extends StatelessWidget {
|
||||
/// Creates a [TimeCardSkeleton].
|
||||
const TimeCardSkeleton({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return UiShimmer(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: UiConstants.space5,
|
||||
vertical: UiConstants.space6,
|
||||
),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
const MonthSelectorSkeleton(),
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
const TimeCardSummarySkeleton(),
|
||||
const SizedBox(height: UiConstants.space6),
|
||||
UiShimmerList(
|
||||
itemCount: 5,
|
||||
spacing: UiConstants.space3,
|
||||
itemBuilder: (int index) => const ShiftHistorySkeleton(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
import 'package:design_system/design_system.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Shimmer placeholder for the time card summary (hours + earnings).
|
||||
class TimeCardSummarySkeleton extends StatelessWidget {
|
||||
/// Creates a [TimeCardSummarySkeleton].
|
||||
const TimeCardSummarySkeleton({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const Row(
|
||||
children: <Widget>[
|
||||
Expanded(child: UiShimmerStatsCard()),
|
||||
SizedBox(width: UiConstants.space3),
|
||||
Expanded(child: UiShimmerStatsCard()),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user