gcx/frontend/mobile/lib/features/profile/presentation/pages/profile_page.dart

232 lines
8.2 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/kyc_badge.dart';
/// A7. 个人中心
///
/// 头像、昵称、KYC等级标识、信用积分
/// KYC认证、支付管理、设置、Pro模式
class ProfilePage extends StatelessWidget {
const ProfilePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
// Profile Header
SliverToBoxAdapter(child: _buildProfileHeader(context)),
// Quick Stats
SliverToBoxAdapter(child: _buildQuickStats()),
// Menu Sections
SliverToBoxAdapter(child: _buildMenuSection('账户', [
_MenuItem(Icons.verified_user_outlined, 'KYC 认证', '已完成 L1 认证', true,
onTap: () => Navigator.pushNamed(context, '/kyc')),
_MenuItem(Icons.credit_card_rounded, '支付管理', '已绑定 2 张卡', true,
onTap: () => Navigator.pushNamed(context, '/payment/manage')),
_MenuItem(Icons.account_balance_wallet_outlined, '我的余额', '\$1,234.56', true,
onTap: () => Navigator.pushNamed(context, '/wallet')),
])),
SliverToBoxAdapter(child: _buildMenuSection('交易', [
_MenuItem(Icons.receipt_long_rounded, '交易记录', '', true,
onTap: () => Navigator.pushNamed(context, '/trading')),
_MenuItem(Icons.storefront_rounded, '我的挂单', '2笔出售中', true,
onTap: () => Navigator.pushNamed(context, '/trading')),
_MenuItem(Icons.favorite_border_rounded, '我的收藏', '', true),
])),
SliverToBoxAdapter(child: _buildMenuSection('设置', [
_MenuItem(Icons.notifications_outlined, '通知设置', '', true),
_MenuItem(Icons.language_rounded, '语言', '简体中文', true),
_MenuItem(Icons.shield_outlined, '安全设置', '', true),
_MenuItem(Icons.tune_rounded, '高级设置', 'Pro模式', true,
onTap: () => Navigator.pushNamed(context, '/pro-mode')),
_MenuItem(Icons.info_outline_rounded, '关于 Genex', 'v1.0.0', true),
])),
// Logout
SliverToBoxAdapter(
child: Padding(
padding: const EdgeInsets.fromLTRB(20, 8, 20, 40),
child: TextButton(
onPressed: () {
Navigator.of(context).pushNamedAndRemoveUntil('/', (_) => false);
},
child: Text('退出登录', style: AppTypography.labelMedium.copyWith(
color: AppColors.error,
)),
),
),
),
const SliverPadding(padding: EdgeInsets.only(bottom: 80)),
],
),
);
}
Widget _buildProfileHeader(BuildContext context) {
return Container(
padding: const EdgeInsets.fromLTRB(20, 60, 20, 24),
decoration: const BoxDecoration(
gradient: AppColors.primaryGradient,
),
child: Row(
children: [
// Avatar
Container(
width: 64,
height: 64,
decoration: BoxDecoration(
color: Colors.white24,
shape: BoxShape.circle,
border: Border.all(color: Colors.white38, width: 2),
),
child: const Icon(Icons.person_rounded, color: Colors.white, size: 32),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text('用户昵称', style: AppTypography.h2.copyWith(color: Colors.white)),
const SizedBox(width: 8),
Container(
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
decoration: BoxDecoration(
color: Colors.white24,
borderRadius: AppSpacing.borderRadiusFull,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.shield_rounded, size: 10, color: Colors.white),
const SizedBox(width: 2),
Text('L1', style: AppTypography.caption.copyWith(
color: Colors.white,
fontWeight: FontWeight.w600,
)),
],
),
),
],
),
const SizedBox(height: 4),
Text('信用积分: 750', style: AppTypography.bodySmall.copyWith(
color: Colors.white70,
)),
],
),
),
// Settings icon
IconButton(
icon: const Icon(Icons.settings_outlined, color: Colors.white),
onPressed: () {
Navigator.pushNamed(context, '/settings');
},
),
],
),
);
}
Widget _buildQuickStats() {
final stats = [
('持券', '12'),
('交易', '28'),
('节省', '\$156'),
('信用', '750'),
];
return Container(
margin: const EdgeInsets.fromLTRB(20, 16, 20, 8),
padding: const EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: AppSpacing.borderRadiusMd,
boxShadow: AppSpacing.shadowSm,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: stats.map((stat) {
return Column(
children: [
Text(stat.$2, style: AppTypography.h2.copyWith(color: AppColors.primary)),
const SizedBox(height: 4),
Text(stat.$1, style: AppTypography.caption),
],
);
}).toList(),
),
);
}
Widget _buildMenuSection(String title, List<_MenuItem> items) {
return Padding(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: AppTypography.labelSmall.copyWith(color: AppColors.textTertiary)),
const SizedBox(height: 8),
Container(
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: AppSpacing.borderRadiusMd,
border: Border.all(color: AppColors.borderLight),
),
child: Column(
children: items.asMap().entries.map((entry) {
final item = entry.value;
final isLast = entry.key == items.length - 1;
return Column(
children: [
ListTile(
leading: Icon(item.icon, color: AppColors.textPrimary, size: 22),
title: Text(item.title, style: AppTypography.bodyMedium),
trailing: Row(
mainAxisSize: MainAxisSize.min,
children: [
if (item.subtitle.isNotEmpty)
Text(item.subtitle, style: AppTypography.caption),
if (item.hasArrow) ...[
const SizedBox(width: 4),
const Icon(Icons.chevron_right_rounded,
color: AppColors.textTertiary, size: 20),
],
],
),
onTap: item.onTap ?? () {},
),
if (!isLast)
const Divider(indent: 56, height: 1),
],
);
}).toList(),
),
),
],
),
);
}
}
class _MenuItem {
final IconData icon;
final String title;
final String subtitle;
final bool hasArrow;
final VoidCallback? onTap;
const _MenuItem(this.icon, this.title, this.subtitle, this.hasArrow, {this.onTap});
}