Build exchange workspace and shared transaction services (#28)
This commit is contained in:
1 parent
52b7135eda
commit
c496da8a55
48 files changed
+4757
-120
No files matched your search
@@ -0,0 +1,152 @@
|
||||
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),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user