gcx/frontend/mobile/lib/shared/widgets/empty_state.dart

106 lines
3.4 KiB
Dart

import 'package:flutter/material.dart';
import '../../app/i18n/app_localizations.dart';
import '../../app/theme/app_colors.dart';
import '../../app/theme/app_typography.dart';
import '../../app/theme/app_spacing.dart';
/// 空状态页组件
///
/// 各场景的空状态插画 + 引导操作
/// 使用场景:列表为空、搜索无结果、网络错误
class EmptyState extends StatelessWidget {
final IconData icon;
final String title;
final String? subtitle;
final String? actionText;
final VoidCallback? onAction;
const EmptyState({
super.key,
required this.icon,
required this.title,
this.subtitle,
this.actionText,
this.onAction,
});
@override
Widget build(BuildContext context) {
return Center(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 60),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 80,
height: 80,
decoration: BoxDecoration(
color: AppColors.primarySurface,
shape: BoxShape.circle,
),
child: Icon(icon, size: 36, color: AppColors.primary.withValues(alpha: 0.5)),
),
const SizedBox(height: AppSpacing.xxl),
Text(
title,
style: AppTypography.h3.copyWith(color: AppColors.textSecondary),
textAlign: TextAlign.center,
),
if (subtitle != null) ...[
const SizedBox(height: AppSpacing.sm),
Text(
subtitle!,
style: AppTypography.bodySmall,
textAlign: TextAlign.center,
),
],
if (actionText != null && onAction != null) ...[
const SizedBox(height: AppSpacing.xxl),
ElevatedButton(
onPressed: onAction,
child: Text(actionText!),
),
],
],
),
),
);
}
// 快捷工厂方法
factory EmptyState.noCoupons({required BuildContext context, VoidCallback? onBrowse}) => EmptyState(
icon: Icons.confirmation_number_outlined,
title: context.t('empty.noCoupons'),
subtitle: context.t('empty.noCouponsHint'),
actionText: context.t('empty.browse'),
onAction: onBrowse,
);
factory EmptyState.noOrders({required BuildContext context}) => EmptyState(
icon: Icons.receipt_long_outlined,
title: context.t('empty.noTrades'),
subtitle: context.t('empty.noTradesHint'),
);
factory EmptyState.noResults({required BuildContext context}) => EmptyState(
icon: Icons.search_off_rounded,
title: context.t('empty.noResults'),
subtitle: context.t('empty.noResultsHint'),
);
factory EmptyState.noMessages({required BuildContext context}) => EmptyState(
icon: Icons.notifications_none_rounded,
title: context.t('empty.noMessages'),
subtitle: context.t('empty.noMessagesHint'),
);
factory EmptyState.networkError({required BuildContext context, VoidCallback? onRetry}) => EmptyState(
icon: Icons.wifi_off_rounded,
title: context.t('empty.networkError'),
subtitle: context.t('empty.networkErrorHint'),
actionText: context.t('common.retry'),
onAction: onRetry,
);
}