210 lines
6.9 KiB
Dart
210 lines
6.9 KiB
Dart
import 'package:flutter/material.dart';
|
||
import '../../../../app/theme/app_colors.dart';
|
||
import '../../../../app/theme/app_typography.dart';
|
||
import '../../../../app/theme/app_spacing.dart';
|
||
import '../../../../shared/widgets/genex_button.dart';
|
||
import '../../../../app/i18n/app_localizations.dart';
|
||
|
||
/// A1. 欢迎页 - 品牌展示 + 注册/登录入口
|
||
///
|
||
/// 品牌Logo、Slogan、手机号注册、邮箱注册、社交登录入口(WeChat/Google/Apple)
|
||
class WelcomePage extends StatelessWidget {
|
||
const WelcomePage({super.key});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return Scaffold(
|
||
body: SafeArea(
|
||
child: Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||
child: Column(
|
||
children: [
|
||
const Spacer(flex: 2),
|
||
|
||
// Brand Logo
|
||
ClipRRect(
|
||
borderRadius: AppSpacing.borderRadiusXl,
|
||
child: Image.asset(
|
||
'assets/images/logo_icon.png',
|
||
width: 80,
|
||
height: 80,
|
||
),
|
||
),
|
||
const SizedBox(height: 12),
|
||
|
||
// Brand Name — 遵循 lockup 设计: "GEN" 深色 + "EX" 渐变
|
||
Row(
|
||
mainAxisSize: MainAxisSize.min,
|
||
children: [
|
||
Text(
|
||
'GEN',
|
||
style: AppTypography.displayLarge.copyWith(
|
||
color: const Color(0xFF1A103A),
|
||
fontWeight: FontWeight.w800,
|
||
letterSpacing: -0.3,
|
||
),
|
||
),
|
||
ShaderMask(
|
||
shaderCallback: (bounds) => const LinearGradient(
|
||
colors: [Color(0xFF9B8FFF), Color(0xFFB8ADFF)],
|
||
).createShader(bounds),
|
||
child: Text(
|
||
'EX',
|
||
style: AppTypography.displayLarge.copyWith(
|
||
color: Colors.white,
|
||
fontWeight: FontWeight.w800,
|
||
letterSpacing: -0.3,
|
||
),
|
||
),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 6),
|
||
|
||
// Slogan
|
||
Text(
|
||
context.t('welcome.slogan'),
|
||
style: AppTypography.bodyLarge.copyWith(
|
||
color: AppColors.textSecondary,
|
||
),
|
||
),
|
||
|
||
const Spacer(flex: 3),
|
||
|
||
// Phone Register
|
||
GenexButton(
|
||
label: context.t('welcome.phoneRegister'),
|
||
icon: Icons.phone_android_rounded,
|
||
onPressed: () {
|
||
Navigator.pushNamed(context, '/register');
|
||
},
|
||
),
|
||
const SizedBox(height: 12),
|
||
|
||
// Email Register
|
||
GenexButton(
|
||
label: context.t('welcome.emailRegister'),
|
||
icon: Icons.email_outlined,
|
||
variant: GenexButtonVariant.outline,
|
||
onPressed: () {
|
||
Navigator.pushNamed(context, '/register');
|
||
},
|
||
),
|
||
const SizedBox(height: 24),
|
||
|
||
// Social Login Divider
|
||
Row(
|
||
children: [
|
||
const Expanded(child: Divider(color: AppColors.border)),
|
||
Padding(
|
||
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||
child: Text(context.t('welcome.otherLogin'), style: AppTypography.caption),
|
||
),
|
||
const Expanded(child: Divider(color: AppColors.border)),
|
||
],
|
||
),
|
||
const SizedBox(height: 16),
|
||
|
||
// Social Login Buttons — WeChat + Google + Apple
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
_SocialLoginButton(
|
||
icon: Icons.wechat,
|
||
label: context.t('welcome.wechat'),
|
||
color: const Color(0xFF07C160),
|
||
onTap: () {
|
||
Navigator.pushReplacementNamed(context, '/main');
|
||
},
|
||
),
|
||
const SizedBox(width: 24),
|
||
_SocialLoginButton(
|
||
icon: Icons.g_mobiledata_rounded,
|
||
label: 'Google',
|
||
onTap: () {
|
||
Navigator.pushReplacementNamed(context, '/main');
|
||
},
|
||
),
|
||
const SizedBox(width: 24),
|
||
_SocialLoginButton(
|
||
icon: Icons.apple_rounded,
|
||
label: 'Apple',
|
||
onTap: () {
|
||
Navigator.pushReplacementNamed(context, '/main');
|
||
},
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 32),
|
||
|
||
// Already have account
|
||
Row(
|
||
mainAxisAlignment: MainAxisAlignment.center,
|
||
children: [
|
||
Text(context.t('welcome.hasAccount'), style: AppTypography.bodyMedium.copyWith(
|
||
color: AppColors.textSecondary,
|
||
)),
|
||
GestureDetector(
|
||
onTap: () {
|
||
Navigator.pushNamed(context, '/login');
|
||
},
|
||
child: Text(context.t('welcome.login'), style: AppTypography.labelMedium.copyWith(
|
||
color: AppColors.primary,
|
||
)),
|
||
),
|
||
],
|
||
),
|
||
const SizedBox(height: 16),
|
||
|
||
// Terms
|
||
Text(
|
||
context.t('welcome.agreement'),
|
||
style: AppTypography.caption.copyWith(fontSize: 10),
|
||
textAlign: TextAlign.center,
|
||
),
|
||
const SizedBox(height: 16),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
}
|
||
}
|
||
|
||
class _SocialLoginButton extends StatelessWidget {
|
||
final IconData icon;
|
||
final String label;
|
||
final Color? color;
|
||
final VoidCallback onTap;
|
||
|
||
const _SocialLoginButton({
|
||
required this.icon,
|
||
required this.label,
|
||
required this.onTap,
|
||
this.color,
|
||
});
|
||
|
||
@override
|
||
Widget build(BuildContext context) {
|
||
return GestureDetector(
|
||
onTap: onTap,
|
||
child: Column(
|
||
children: [
|
||
Container(
|
||
width: 52,
|
||
height: 52,
|
||
decoration: BoxDecoration(
|
||
color: color != null ? color!.withValues(alpha: 0.1) : AppColors.gray50,
|
||
shape: BoxShape.circle,
|
||
border: Border.all(color: color?.withValues(alpha: 0.3) ?? AppColors.border),
|
||
),
|
||
child: Icon(icon, size: 28, color: color ?? AppColors.textPrimary),
|
||
),
|
||
const SizedBox(height: 6),
|
||
Text(label, style: AppTypography.caption),
|
||
],
|
||
),
|
||
);
|
||
}
|
||
}
|