Files
xianyan/lib/shared/widgets/feedback/login_guard_widget.dart
2026-06-07 08:16:20 +08:00

136 lines
4.3 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/// ============================================================
/// 闲言APP — 登录守卫组件
/// 创建时间: 2026-06-07
/// 更新时间: 2026-06-07
/// 作用: 未登录时显示提示+登录按钮,已登录时显示正常内容
/// 上次更新: 接入i18n翻译、新增onLogin回调
/// ============================================================
import 'package:flutter/cupertino.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/router/app_nav_extension.dart';
import '../../../core/router/app_routes.dart';
import '../../../core/theme/app_spacing.dart';
import '../../../core/theme/app_theme.dart';
import '../../../core/theme/app_typography.dart';
import '../../../core/theme/app_radius.dart';
import '../../../features/auth/providers/auth_provider.dart';
import '../../../l10n/translations.dart';
import '../containers/glass_container.dart';
/// 登录守卫组件 — 未登录时展示提示视图,已登录时展示 child
///
/// 用法:
/// ```dart
/// LoginGuardWidget(
/// child: MyPageContent(),
/// )
/// ```
class LoginGuardWidget extends ConsumerWidget {
const LoginGuardWidget({
super.key,
required this.child,
this.icon = CupertinoIcons.person_crop_circle_badge_xmark,
this.title,
this.subtitle,
this.buttonText,
this.onLogin,
});
/// 已登录时展示的内容
final Widget child;
/// 未登录提示图标
final IconData icon;
/// 未登录提示标题(默认: 使用i18n翻译
final String? title;
/// 未登录提示副标题(默认: 登录后即可查看个人信息和数据)
final String? subtitle;
/// 登录按钮文字(默认: 使用i18n翻译
final String? buttonText;
/// 登录成功后的回调(可选)
final VoidCallback? onLogin;
@override
Widget build(BuildContext context, WidgetRef ref) {
final authState = ref.watch(authProvider);
// 未初始化时显示加载
if (!authState.isInitialized) {
return const Center(child: CupertinoActivityIndicator());
}
// 已登录时显示正常内容
if (authState.isLoggedIn) {
return child;
}
// 未登录时显示提示视图
return _buildLoggedOutView(context, ref);
}
Widget _buildLoggedOutView(BuildContext context, WidgetRef ref) {
final ext = AppTheme.ext(context);
final t = ref.watch(translationsProvider);
// 使用 i18n 翻译fallback 到中文
final displayTitle = title ?? t.profile.loginToViewProfile;
final displaySubtitle = subtitle ?? '登录后即可查看个人信息和数据';
final displayButtonText = buttonText ?? t.profile.goLogin;
return Semantics(
label: '$displayTitle. $displaySubtitle',
child: Center(
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: AppSpacing.lg,
vertical: AppSpacing.xxl,
),
child: GlassContainer(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Icon(icon, size: 48, color: ext.textHint),
const SizedBox(height: AppSpacing.md),
Text(
displayTitle,
style: AppTypography.title3.copyWith(color: ext.textPrimary),
),
const SizedBox(height: AppSpacing.sm),
Text(
displaySubtitle,
style: AppTypography.subhead.copyWith(
color: ext.textSecondary,
),
textAlign: TextAlign.center,
),
const SizedBox(height: AppSpacing.md),
CupertinoButton(
color: ext.accent,
borderRadius: AppRadius.pillBorder,
onPressed: () {
context.appPush(AppRoutes.login);
onLogin?.call();
},
child: Text(
displayButtonText,
style: AppTypography.body.copyWith(
color: CupertinoColors.white,
fontWeight: FontWeight.w600,
),
),
),
],
),
),
),
),
);
}
}