136 lines
4.3 KiB
Dart
136 lines
4.3 KiB
Dart
/// ============================================================
|
||
/// 闲言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,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|