153 lines
5.5 KiB
Dart
153 lines
5.5 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
import 'package:go_router/go_router.dart';
|
|
|
|
import 'package:provider/provider.dart';
|
|
|
|
import 'package:sxchnge_wallet/sxchnge_wallet.dart';
|
|
|
|
import 'copy.dart';
|
|
import 'summary.dart';
|
|
|
|
import '../generated/i18n/app_localizations.dart';
|
|
|
|
class OperationPage extends StatefulWidget {
|
|
const OperationPage({super.key, required this.id});
|
|
final String id;
|
|
@override
|
|
State<OperationPage> createState() => _OperationPageState();
|
|
}
|
|
|
|
class _OperationPageState extends State<OperationPage> {
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
|
if (mounted) context.read<WalletProvider>().refresh();
|
|
});
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final p = context.watch<WalletProvider>();
|
|
final o = p.operation(widget.id);
|
|
final l = AppLocalizations.of(context)!;
|
|
final t = Theme.of(context);
|
|
final c = t.colorScheme;
|
|
return SingleChildScrollView(
|
|
padding: const EdgeInsets.all(24),
|
|
child: Center(
|
|
child: ConstrainedBox(
|
|
constraints: const BoxConstraints(maxWidth: 640),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
Align(
|
|
alignment: Alignment.centerLeft,
|
|
child: TextButton.icon(
|
|
onPressed: () => context.go('/activity'),
|
|
icon: const Icon(Icons.arrow_back),
|
|
label: Text(l.wActivity),
|
|
),
|
|
),
|
|
if (p.failed)
|
|
Text(l.wUnavailable, style: TextStyle(color: c.error)),
|
|
if (o == null) ...[
|
|
Text(p.loading ? l.wWorking : l.wNotFound),
|
|
TextButton(
|
|
onPressed: p.loading ? null : p.refresh,
|
|
child: Text(l.wRefresh),
|
|
),
|
|
] else ...[
|
|
Container(
|
|
padding: const EdgeInsets.all(28),
|
|
decoration: BoxDecoration(
|
|
color: o.status == OperationStatus.failed
|
|
? c.errorContainer
|
|
: c.primaryContainer,
|
|
borderRadius: BorderRadius.circular(28),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Icon(
|
|
o.status == OperationStatus.completed
|
|
? Icons.check_circle_outline
|
|
: o.status == OperationStatus.pending
|
|
? Icons.schedule
|
|
: Icons.info_outline,
|
|
size: 40,
|
|
color: o.status == OperationStatus.failed
|
|
? c.onErrorContainer
|
|
: c.onPrimaryContainer,
|
|
),
|
|
const SizedBox(height: 16),
|
|
Semantics(
|
|
header: true,
|
|
liveRegion: true,
|
|
child: Text(
|
|
statusText(l, o.status),
|
|
key: ValueKey('operation-${o.status.name}'),
|
|
style: t.textTheme.displaySmall?.copyWith(
|
|
color: o.status == OperationStatus.failed
|
|
? c.onErrorContainer
|
|
: c.onPrimaryContainer,
|
|
),
|
|
),
|
|
),
|
|
const SizedBox(height: 16),
|
|
Text(
|
|
fundsText(l, o),
|
|
style: TextStyle(
|
|
color: o.status == OperationStatus.failed
|
|
? c.onErrorContainer
|
|
: c.onPrimaryContainer,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 20),
|
|
TransferSummary(quote: o.quote),
|
|
const SizedBox(height: 16),
|
|
Text('${l.wReference}: ${o.id}'),
|
|
if (o.status == OperationStatus.pending) ...[
|
|
const SizedBox(height: 12),
|
|
Text(l.wPendingHint),
|
|
TextButton(
|
|
onPressed: p.loading ? null : p.refresh,
|
|
child: Text(l.wRefresh),
|
|
),
|
|
],
|
|
const SizedBox(height: 24),
|
|
if (o.status == OperationStatus.completed &&
|
|
o.quote.request.kind != TransferKind.payout)
|
|
FilledButton(
|
|
onPressed: () => context.go(
|
|
o.quote.request.kind == TransferKind.topUp
|
|
? '/exchange'
|
|
: '/payout',
|
|
extra:
|
|
o.quote.request.destination ?? o.quote.request.source,
|
|
),
|
|
child: Text(
|
|
o.quote.request.kind == TransferKind.topUp
|
|
? l.wExchange
|
|
: l.wPayout,
|
|
),
|
|
),
|
|
TextButton(
|
|
onPressed: () => context.go(
|
|
'/accounts/${o.quote.request.destination ?? o.quote.request.source}',
|
|
),
|
|
child: Text(l.wViewAccount),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|