Add optional KYC flow and service-backed account limits
This commit is contained in:
1 parent
61ccfc1844
commit
3397f04ab7
38 files changed
+3443
-36
No files matched your search
@@ -0,0 +1,158 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:sxchnge_kyc/sxchnge_kyc.dart';
|
||||
|
||||
import 'copy.dart';
|
||||
|
||||
import '../generated/i18n/app_localizations.dart';
|
||||
|
||||
class StatusPanel extends StatelessWidget {
|
||||
const StatusPanel({super.key, required this.provider});
|
||||
final IdentityProvider provider;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l = AppLocalizations.of(context)!;
|
||||
final t = Theme.of(context);
|
||||
final p = provider;
|
||||
final record = p.record!;
|
||||
final status = record.status;
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Container(
|
||||
padding: const EdgeInsets.all(24),
|
||||
decoration: BoxDecoration(
|
||||
color: t.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(24),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Icon(
|
||||
switch (status) {
|
||||
IdentityStatus.approved => Icons.verified_outlined,
|
||||
IdentityStatus.pending => Icons.hourglass_top,
|
||||
IdentityStatus.changesRequested ||
|
||||
IdentityStatus.denied => Icons.info_outline,
|
||||
_ => Icons.shield_outlined,
|
||||
},
|
||||
color: t.colorScheme.onPrimaryContainer,
|
||||
size: 36,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Semantics(
|
||||
header: true,
|
||||
liveRegion: true,
|
||||
child: Text(
|
||||
statusTitle(l, status),
|
||||
key: ValueKey('kyc-${status.name}'),
|
||||
style: t.textTheme.headlineMedium?.copyWith(
|
||||
color: t.colorScheme.onPrimaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
statusBody(l, status),
|
||||
style: TextStyle(color: t.colorScheme.onPrimaryContainer),
|
||||
),
|
||||
if (record.reason != null) ...[
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
reasonText(l, record.reason!),
|
||||
style: TextStyle(
|
||||
color: t.colorScheme.onPrimaryContainer,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if (record.canSubmit)
|
||||
FilledButton(
|
||||
key: const ValueKey('kyc-start'),
|
||||
onPressed: p.busy || p.stale ? null : p.start,
|
||||
child: Text(
|
||||
status == IdentityStatus.changesRequested
|
||||
? l.kycResubmit
|
||||
: l.kycStart,
|
||||
),
|
||||
),
|
||||
if (status == IdentityStatus.denied)
|
||||
OutlinedButton(
|
||||
onPressed: () => showDialog<void>(
|
||||
context: context,
|
||||
builder: (context) => AlertDialog(
|
||||
title: Text(l.kycSupport),
|
||||
content: Text(l.kycSupportBody),
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(context),
|
||||
child: Text(l.kycBack),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Text(l.kycSupport),
|
||||
),
|
||||
if (status == IdentityStatus.pending &&
|
||||
p.service is DummyIdentityService)
|
||||
ExpansionTile(
|
||||
title: Text(l.kycDemoControls),
|
||||
children: [
|
||||
Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
TextButton(
|
||||
onPressed: p.busy
|
||||
? null
|
||||
: () => p.demoReview(IdentityStatus.approved),
|
||||
child: Text(l.kycDemoApprove),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: p.busy
|
||||
? null
|
||||
: () => p.demoReview(
|
||||
IdentityStatus.changesRequested,
|
||||
reason: ReviewReason.passportUnreadable,
|
||||
),
|
||||
child: Text(l.kycDemoCorrect),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: p.busy
|
||||
? null
|
||||
: () => p.demoReview(
|
||||
IdentityStatus.changesRequested,
|
||||
reason: ReviewReason.selfieUnreadable,
|
||||
),
|
||||
child: Text(l.kycDemoSelfie),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: p.busy
|
||||
? null
|
||||
: () => p.demoReview(
|
||||
IdentityStatus.changesRequested,
|
||||
reason: ReviewReason.passportExpired,
|
||||
),
|
||||
child: Text(l.kycDemoExpired),
|
||||
),
|
||||
TextButton(
|
||||
onPressed: p.busy
|
||||
? null
|
||||
: () => p.demoReview(
|
||||
IdentityStatus.denied,
|
||||
reason: ReviewReason.unableToVerify,
|
||||
),
|
||||
child: Text(l.kycDemoDeny),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user