gcx/frontend/mobile/lib/features/trading/presentation/pages/transfer_page.dart

212 lines
7.1 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.

import 'package:flutter/material.dart';
import '../../../../app/theme/app_colors.dart';
import '../../../../app/theme/app_typography.dart';
import '../../../../app/theme/app_spacing.dart';
/// A9. P2P转赠页面
///
/// 选择好友 → 确认转赠 → 转赠成功
/// 零区块链术语:使用"转赠"而非"转移NFT"
class TransferPage extends StatefulWidget {
const TransferPage({super.key});
@override
State<TransferPage> createState() => _TransferPageState();
}
class _TransferPageState extends State<TransferPage> {
final _searchController = TextEditingController();
String? _selectedFriend;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('转赠给好友')),
body: Column(
children: [
// Coupon Info
Container(
margin: const EdgeInsets.all(20),
padding: AppSpacing.cardPadding,
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: AppSpacing.borderRadiusMd,
border: Border.all(color: AppColors.borderLight),
),
child: Row(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: AppColors.primarySurface,
borderRadius: AppSpacing.borderRadiusSm,
),
child: const Icon(Icons.card_giftcard_rounded, color: AppColors.primary),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text('星巴克 \$25 礼品卡', style: AppTypography.labelMedium),
Text('面值 \$25.00', style: AppTypography.bodySmall),
],
),
),
],
),
),
// Search Friend
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20),
child: TextField(
controller: _searchController,
decoration: const InputDecoration(
hintText: '搜索好友(手机号/用户名)',
prefixIcon: Icon(Icons.search_rounded),
),
),
),
const SizedBox(height: 16),
// Friends List
Expanded(
child: ListView(
padding: const EdgeInsets.symmetric(horizontal: 20),
children: [
_buildFriendTile('Alice', 'alice@example.com', 'A'),
_buildFriendTile('Bob', 'bob@example.com', 'B'),
_buildFriendTile('Charlie', 'charlie@example.com', 'C'),
_buildFriendTile('Diana', 'diana@example.com', 'D'),
],
),
),
// Transfer Button
Container(
padding: const EdgeInsets.all(20),
child: SizedBox(
width: double.infinity,
height: AppSpacing.buttonHeight,
child: ElevatedButton(
onPressed: _selectedFriend != null ? () => _showConfirm(context) : null,
child: Text(_selectedFriend != null ? '转赠给 $_selectedFriend' : '请选择好友'),
),
),
),
],
),
);
}
Widget _buildFriendTile(String name, String email, String avatar) {
final isSelected = _selectedFriend == name;
return GestureDetector(
onTap: () => setState(() => _selectedFriend = name),
child: Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.all(14),
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: AppSpacing.borderRadiusMd,
border: Border.all(
color: isSelected ? AppColors.primary : AppColors.borderLight,
width: isSelected ? 1.5 : 1,
),
),
child: Row(
children: [
CircleAvatar(
radius: 20,
backgroundColor: AppColors.primaryContainer,
child: Text(avatar, style: const TextStyle(color: AppColors.primary, fontWeight: FontWeight.w600)),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(name, style: AppTypography.labelMedium),
Text(email, style: AppTypography.caption),
],
),
),
if (isSelected) const Icon(Icons.check_circle_rounded, color: AppColors.primary, size: 22),
],
),
),
);
}
void _showConfirm(BuildContext context) {
showModalBottomSheet(
context: context,
builder: (ctx) => Padding(
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.card_giftcard_rounded, color: AppColors.primary, size: 48),
const SizedBox(height: 16),
Text('确认转赠', style: AppTypography.h2),
const SizedBox(height: 8),
Text('将 星巴克 \$25 礼品卡 转赠给 $_selectedFriend', style: AppTypography.bodyMedium.copyWith(color: AppColors.textSecondary)),
const SizedBox(height: 8),
Text('转赠后您将不再持有此券', style: AppTypography.caption.copyWith(color: AppColors.warning)),
const SizedBox(height: 24),
Row(
children: [
Expanded(
child: OutlinedButton(
onPressed: () => Navigator.pop(ctx),
child: const Text('取消'),
),
),
const SizedBox(width: 12),
Expanded(
child: ElevatedButton(
onPressed: () {
Navigator.pop(ctx);
_showSuccess(context);
},
child: const Text('确认转赠'),
),
),
],
),
],
),
),
);
}
void _showSuccess(BuildContext context) {
showDialog(
context: context,
builder: (ctx) => AlertDialog(
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.check_circle_rounded, color: AppColors.success, size: 56),
const SizedBox(height: 16),
Text('转赠成功', style: AppTypography.h2),
const SizedBox(height: 8),
Text('$_selectedFriend 已收到您的券', style: AppTypography.bodyMedium.copyWith(color: AppColors.textSecondary)),
],
),
actions: [
TextButton(
onPressed: () {
Navigator.pop(ctx);
Navigator.pop(context);
},
child: const Text('确定'),
),
],
),
);
}
}