gcx/frontend/genex-mobile/lib/features/trading/presentation/pages/trading_page.dart

205 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/status_tag.dart';
import '../../../../shared/widgets/empty_state.dart';
import '../../../../app/i18n/app_localizations.dart';
/// A5. 交易模块(二级市场)
///
/// 我的挂单、我的交易记录
class TradingPage extends StatefulWidget {
const TradingPage({super.key});
@override
State<TradingPage> createState() => _TradingPageState();
}
class _TradingPageState extends State<TradingPage>
with SingleTickerProviderStateMixin {
late TabController _tabController;
@override
void initState() {
super.initState();
_tabController = TabController(length: 2, vsync: this);
}
@override
void dispose() {
_tabController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(context.t('tradingPage.title')),
bottom: TabBar(
controller: _tabController,
tabs: [
Tab(text: context.t('tradingPage.pendingOrders')),
Tab(text: context.t('tradingPage.tradeRecords')),
],
),
),
body: TabBarView(
controller: _tabController,
children: [
_buildMyListings(),
_buildTransactionHistory(),
],
),
);
}
Widget _buildMyListings() {
return ListView.separated(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 100),
itemCount: 3,
separatorBuilder: (_, __) => const SizedBox(height: 12),
itemBuilder: (context, index) {
final statuses = [
StatusTags.onSale(context),
StatusTags.completed(context),
StatusTags.cancelled(context),
];
return Container(
padding: AppSpacing.cardPadding,
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: AppSpacing.borderRadiusMd,
border: Border.all(color: AppColors.borderLight),
),
child: Column(
children: [
Row(
children: [
Container(
width: 48,
height: 48,
decoration: BoxDecoration(
color: AppColors.primarySurface,
borderRadius: AppSpacing.borderRadiusSm,
),
child: Icon(Icons.confirmation_number_outlined,
color: AppColors.primary.withValues(alpha: 0.4), size: 22),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(['星巴克 \$25', 'Amazon \$50', 'Nike \$80'][index],
style: AppTypography.labelMedium),
const SizedBox(height: 4),
Row(
children: [
Text('${context.t('tradingPage.listPrice')} ', style: AppTypography.caption),
Text('\$${[21.25, 42.50, 68.00][index]}',
style: AppTypography.priceSmall.copyWith(fontSize: 14)),
],
),
],
),
),
statuses[index],
],
),
const SizedBox(height: 12),
Container(
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
decoration: BoxDecoration(
color: AppColors.gray50,
borderRadius: AppSpacing.borderRadiusSm,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text('${context.t('tradingPage.listTime')}: 2026/02/${9 - index}',
style: AppTypography.caption),
if (index == 0)
GestureDetector(
onTap: () {},
child: Text(context.t('tradingPage.cancelOrder'), style: AppTypography.labelSmall.copyWith(
color: AppColors.error,
)),
),
],
),
),
],
),
);
},
);
}
Widget _buildTransactionHistory() {
return ListView.separated(
padding: const EdgeInsets.fromLTRB(20, 16, 20, 100),
itemCount: 6,
separatorBuilder: (_, __) => const SizedBox(height: 8),
itemBuilder: (context, index) {
final isBuy = index % 2 == 0;
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration(
color: AppColors.surface,
borderRadius: AppSpacing.borderRadiusSm,
border: Border.all(color: AppColors.borderLight),
),
child: Row(
children: [
Container(
width: 36,
height: 36,
decoration: BoxDecoration(
color: isBuy ? AppColors.successLight : AppColors.errorLight,
shape: BoxShape.circle,
),
child: Icon(
isBuy ? Icons.arrow_downward_rounded : Icons.arrow_upward_rounded,
size: 18,
color: isBuy ? AppColors.success : AppColors.error,
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
isBuy ? context.t('trading.buy') : context.t('trading.sell'),
style: AppTypography.labelMedium,
),
Text(
'品牌 ${index + 1} 礼品卡',
style: AppTypography.caption,
),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(
'${isBuy ? "-" : "+"}\$${(index + 1) * 15}.00',
style: AppTypography.labelMedium.copyWith(
color: isBuy ? AppColors.textPrimary : AppColors.success,
),
),
Text('02/${10 - index} 14:${30 + index}',
style: AppTypography.caption),
],
),
],
),
);
},
);
}
}