google_auth_screen.dart 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. import 'package:flutter/material.dart';
  2. import 'package:go_router/go_router.dart';
  3. import '../../../core/l10n/app_localizations.dart';
  4. import '../../../core/theme/app_colors.dart';
  5. class GoogleAuthScreen extends StatelessWidget {
  6. const GoogleAuthScreen({super.key});
  7. @override
  8. Widget build(BuildContext context) {
  9. final cs = Theme.of(context).colorScheme;
  10. final isDark = Theme.of(context).brightness == Brightness.dark;
  11. return Scaffold(
  12. appBar: AppBar(
  13. elevation: 0,
  14. leading: IconButton(
  15. icon: Icon(Icons.chevron_left, size: 28),
  16. onPressed: () => context.pop(),
  17. ),
  18. title: Text(
  19. AppLocalizations.of(context)!.authenticator,
  20. style: const TextStyle(
  21. fontSize: 18,
  22. fontWeight: FontWeight.w600,
  23. ),
  24. ),
  25. centerTitle: true,
  26. ),
  27. body: Column(
  28. children: [
  29. Expanded(
  30. child: SingleChildScrollView(
  31. padding: const EdgeInsets.all(20),
  32. child: Column(
  33. crossAxisAlignment: CrossAxisAlignment.start,
  34. children: [
  35. // ── 步骤标题 ────────────────────────────────
  36. Text(
  37. AppLocalizations.of(context)!.googleAuthStep1,
  38. style: TextStyle(
  39. color: cs.onSurface,
  40. fontSize: 16,
  41. fontWeight: FontWeight.w600,
  42. ),
  43. ),
  44. const SizedBox(height: 8),
  45. Text(
  46. AppLocalizations.of(context)!.googleAuthDownloadHint,
  47. style: TextStyle(
  48. color: cs.onSurface.withAlpha(153),
  49. fontSize: 13,
  50. height: 1.5,
  51. ),
  52. ),
  53. const SizedBox(height: 20),
  54. Text(
  55. AppLocalizations.of(context)!.recommendDownload,
  56. style: TextStyle(
  57. color: cs.onSurface.withAlpha(153),
  58. fontSize: 13,
  59. ),
  60. ),
  61. const SizedBox(height: 12),
  62. // ── App 推荐列表 ─────────────────────────────
  63. Container(
  64. decoration: BoxDecoration(
  65. color: isDark ? AppColors.darkBgSecondary : AppColors.lightBgSecondary,
  66. borderRadius: BorderRadius.circular(12),
  67. ),
  68. child: Column(
  69. children: [
  70. _AuthAppItem(
  71. color: const Color(0xFF0078D4),
  72. letter: 'M',
  73. name: 'Microsoft Authenticator',
  74. ),
  75. Divider(height: 1, indent: 68, color: cs.outline),
  76. _AuthAppItem(
  77. color: const Color(0xFF4285F4),
  78. letter: 'G',
  79. name: 'Google Authenticator',
  80. letterColor: Colors.white,
  81. ),
  82. Divider(height: 1, indent: 68, color: cs.outline),
  83. _AuthAppItem(
  84. color: const Color(0xFFe53935),
  85. letter: '2',
  86. name: '2FA Authenticator(2FAS)',
  87. isLast: true,
  88. ),
  89. ],
  90. ),
  91. ),
  92. ],
  93. ),
  94. ),
  95. ),
  96. // ── 底部按钮 ─────────────────────────────────────
  97. Padding(
  98. padding: const EdgeInsets.fromLTRB(20, 0, 20, 32),
  99. child: SizedBox(
  100. width: double.infinity,
  101. height: 50,
  102. child: ElevatedButton(
  103. onPressed: () => context.push('/user/security/google-auth/bind'),
  104. style: ElevatedButton.styleFrom(
  105. backgroundColor: AppColors.brand,
  106. foregroundColor: Colors.black,
  107. shape: RoundedRectangleBorder(
  108. borderRadius: BorderRadius.circular(10),
  109. ),
  110. ),
  111. child: Text(
  112. AppLocalizations.of(context)!.alreadyDownloaded,
  113. style: const TextStyle(fontSize: 15, fontWeight: FontWeight.w600),
  114. ),
  115. ),
  116. ),
  117. ),
  118. ],
  119. ),
  120. );
  121. }
  122. }
  123. class _AuthAppItem extends StatelessWidget {
  124. const _AuthAppItem({
  125. required this.color,
  126. required this.letter,
  127. required this.name,
  128. this.letterColor = Colors.white,
  129. this.isLast = false,
  130. });
  131. final Color color;
  132. final String letter;
  133. final String name;
  134. final Color letterColor;
  135. final bool isLast;
  136. @override
  137. Widget build(BuildContext context) {
  138. final cs = Theme.of(context).colorScheme;
  139. return InkWell(
  140. onTap: () {},
  141. borderRadius: isLast
  142. ? const BorderRadius.vertical(bottom: Radius.circular(12))
  143. : BorderRadius.zero,
  144. child: Padding(
  145. padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
  146. child: Row(
  147. children: [
  148. Container(
  149. width: 40,
  150. height: 40,
  151. decoration: BoxDecoration(
  152. color: color,
  153. borderRadius: BorderRadius.circular(10),
  154. ),
  155. child: Center(
  156. child: Text(
  157. letter,
  158. style: TextStyle(
  159. color: letterColor,
  160. fontSize: 20,
  161. fontWeight: FontWeight.w700,
  162. ),
  163. ),
  164. ),
  165. ),
  166. const SizedBox(width: 14),
  167. Text(
  168. name,
  169. style: TextStyle(
  170. color: cs.onSurface,
  171. fontSize: 15,
  172. fontWeight: FontWeight.w500,
  173. ),
  174. ),
  175. ],
  176. ),
  177. ),
  178. );
  179. }
  180. }