Skip to content

Commit

Permalink
feat(cat-voices): registration transaction summary (#921)
Browse files Browse the repository at this point in the history
* feat(cat-voices): registration transaction summary

* chore: cleanup localizations

* refactor: apply bullet list
  • Loading branch information
dtscalac authored Oct 2, 2024
1 parent 980067a commit 07b6d96
Show file tree
Hide file tree
Showing 11 changed files with 436 additions and 33 deletions.
20 changes: 11 additions & 9 deletions catalyst_voices/lib/pages/account/account_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'package:catalyst_voices/pages/account/delete_keychain_dialog.dart';
import 'package:catalyst_voices/pages/account/keychain_deleted_dialog.dart';
import 'package:catalyst_voices/widgets/buttons/voices_icon_button.dart';
import 'package:catalyst_voices/widgets/buttons/voices_text_button.dart';
import 'package:catalyst_voices/widgets/list/bullet_list.dart';
import 'package:catalyst_voices/widgets/modals/voices_dialog.dart';
import 'package:catalyst_voices_assets/catalyst_voices_assets.dart';
import 'package:catalyst_voices_brands/catalyst_voices_brands.dart';
Expand Down Expand Up @@ -239,11 +240,14 @@ class _KeychainCard extends StatelessWidget {
),
),
if (roles.isNotEmpty)
Text(
roles
.map((e) => _formatRoleBullet(e, defaultRole, context))
.join('\n'),
style: Theme.of(context).textTheme.bodyLarge,
Padding(
padding: const EdgeInsets.only(left: 4),
child: BulletList(
items: roles
.map((e) => _formatRoleBullet(e, defaultRole, context))
.toList(),
style: Theme.of(context).textTheme.bodyLarge,
),
),
],
),
Expand All @@ -255,12 +259,10 @@ class _KeychainCard extends StatelessWidget {
AccountRole? defaultRole,
BuildContext context,
) {
String label;
if (role == defaultRole) {
label = '${role.getName(context)} (${context.l10n.defaultRole})';
return '${role.getName(context)} (${context.l10n.defaultRole})';
} else {
label = role.getName(context);
return role.getName(context);
}
return ' • $label';
}
}
Original file line number Diff line number Diff line change
@@ -1,32 +1,161 @@
import 'package:catalyst_voices/widgets/buttons/voices_filled_button.dart';
import 'package:catalyst_cardano_serialization/catalyst_cardano_serialization.dart';
import 'package:catalyst_voices/common/ext/account_role_ext.dart';
import 'package:catalyst_voices/widgets/widgets.dart';
import 'package:catalyst_voices_assets/catalyst_voices_assets.dart';
import 'package:catalyst_voices_blocs/catalyst_voices_blocs.dart';
import 'package:catalyst_voices_brands/catalyst_voices_brands.dart';
import 'package:catalyst_voices_localization/catalyst_voices_localization.dart';
import 'package:catalyst_voices_models/catalyst_voices_models.dart';
import 'package:catalyst_voices_shared/catalyst_voices_shared.dart';
import 'package:flutter/material.dart';

// TODO(dtscalac): define content
class RbacTransactionPanel extends StatelessWidget {
const RbacTransactionPanel({super.key});
final List<AccountRole> roles;
final Coin transactionFee;

const RbacTransactionPanel({
super.key,
required this.roles,
required this.transactionFee,
});

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
const SizedBox(height: 24),
Text(
context.l10n.walletLinkTransactionTitle,
style: Theme.of(context).textTheme.titleMedium,
),
const SizedBox(height: 12),
_Summary(
roles: roles,
transactionFee: transactionFee,
),
const SizedBox(height: 18),
const _PositiveSmallPrint(),
const Spacer(),
const _Navigation(),
],
);
}
}

class _Summary extends StatelessWidget {
final List<AccountRole> roles;
final Coin transactionFee;

const _Summary({
required this.roles,
required this.transactionFee,
});

@override
Widget build(BuildContext context) {
return Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8),
border: Border.all(
width: 1.5,
color: Theme.of(context).colors.outlineBorderVariant!,
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
context.l10n.walletLinkTransactionAccountCompletion,
style: Theme.of(context).textTheme.titleSmall,
),
for (final role in roles) ...[
const SizedBox(height: 12),
Text(
context.l10n.walletLinkTransactionRoleItem(
role.getName(context).toLowerCase(),
),
style: Theme.of(context).textTheme.bodySmall,
),
],
const Divider(height: 24),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
context.l10n.total,
style: Theme.of(context)
.textTheme
.titleSmall
?.copyWith(fontWeight: FontWeight.bold),
),
Text(
CryptocurrencyFormatter.formatAmount(transactionFee),
style: Theme.of(context).textTheme.bodySmall,
),
],
),
],
),
);
}
}

class _PositiveSmallPrint extends StatelessWidget {
const _PositiveSmallPrint();

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
context.l10n.walletLinkTransactionPositiveSmallPrint,
style: Theme.of(context)
.textTheme
.titleSmall
?.copyWith(fontWeight: FontWeight.bold),
),
const SizedBox(height: 12),
Padding(
padding: const EdgeInsets.only(left: 4),
child: BulletList(
items: [
context.l10n.walletLinkTransactionPositiveSmallPrintItem1,
context.l10n.walletLinkTransactionPositiveSmallPrintItem2,
context.l10n.walletLinkTransactionPositiveSmallPrintItem3,
],
spacing: 4,
),
),
],
);
}
}

class _Navigation extends StatelessWidget {
const _Navigation();

@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
VoicesFilledButton(
leading: VoicesAssets.icons.wallet.buildIcon(),
onTap: () {
RegistrationCubit.of(context).previousStep();
RegistrationCubit.of(context).submitRegistration();
},
child: const Text('Previous'),
child: Text(context.l10n.walletLinkTransactionSign),
),
const SizedBox(height: 12),
VoicesFilledButton(
const SizedBox(height: 10),
VoicesTextButton(
leading: VoicesAssets.icons.wallet.buildIcon(),
onTap: () {
RegistrationCubit.of(context).nextStep();
RegistrationCubit.of(context).changeRoleSetup();
},
child: const Text('Next'),
child: Text(context.l10n.walletLinkTransactionChangeRoles),
),
],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,10 @@ class _WalletSummary extends StatelessWidget {
),
),
const SizedBox(height: 6),
Text(
context.l10n.walletLinkWalletDetailsNoticeTopUpLink,
BulletList(
items: [
context.l10n.walletLinkWalletDetailsNoticeTopUpLink,
],
style: Theme.of(context).textTheme.labelSmall,
),
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import 'package:catalyst_cardano_serialization/catalyst_cardano_serialization.dart';
import 'package:catalyst_voices/pages/registration/wallet_link/stage/intro_panel.dart';
import 'package:catalyst_voices/pages/registration/wallet_link/stage/rbac_transaction_panel.dart';
import 'package:catalyst_voices/pages/registration/wallet_link/stage/roles_chooser_panel.dart';
Expand Down Expand Up @@ -31,7 +32,11 @@ class WalletLinkPanel extends StatelessWidget {
),
WalletLinkStage.rolesChooser => const RolesChooserPanel(),
WalletLinkStage.rolesSummary => const RolesSummaryPanel(),
WalletLinkStage.rbacTransaction => const RbacTransactionPanel(),
// TODO(dtscalac): pass valid parameters
WalletLinkStage.rbacTransaction => RbacTransactionPanel(
roles: AccountRole.values,
transactionFee: Coin.fromAda(0.9438),
),
};
}
}
65 changes: 65 additions & 0 deletions catalyst_voices/lib/widgets/list/bullet_list.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import 'package:catalyst_voices_shared/catalyst_voices_shared.dart';
import 'package:flutter/material.dart';

/// Displays a list of bulleted points. Similar to <ul><li></li></ul> in html.
class BulletList extends StatelessWidget {
/// The list of items without the bullet.
final List<String> items;

/// The text style applied to the bullet point and the [items].
///
/// Defaults to Theme.of(context).textTheme.bodySmall,
final TextStyle? style;

/// The amount of vertical space between the [items].
final double spacing;

const BulletList({
super.key,
required this.items,
this.style,
this.spacing = 4,
});

@override
Widget build(BuildContext context) {
return Column(
children: <Widget>[
for (final item in items)
_BulletItem(
text: item,
style: style ?? Theme.of(context).textTheme.bodySmall,
),
].separatedBy(SizedBox(height: spacing)).toList(),
);
}
}

class _BulletItem extends StatelessWidget {
final String text;
final TextStyle? style;

const _BulletItem({
required this.text,
this.style,
});

@override
Widget build(BuildContext context) {
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'• ',
style: style,
),
Flexible(
child: Text(
text,
style: style,
),
),
],
);
}
}
1 change: 1 addition & 0 deletions catalyst_voices/lib/widgets/widgets.dart
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export 'indicators/voices_linear_progress_indicator.dart';
export 'indicators/voices_no_internet_connection_banner.dart';
export 'indicators/voices_password_strength_indicator.dart';
export 'indicators/voices_status_indicator.dart';
export 'list/bullet_list.dart';
export 'menu/voices_list_tile.dart';
export 'menu/voices_menu.dart';
export 'menu/voices_node_menu.dart';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ final class RegistrationCubit extends Cubit<RegistrationState> {
}
}

void changeRoleSetup() {
_goToStep(const WalletLinkStep(stage: WalletLinkStage.rolesChooser));
}

void nextStep() {
final nextStep = _nextStep();
if (nextStep != null) {
Expand Down Expand Up @@ -88,14 +92,6 @@ final class RegistrationCubit extends Cubit<RegistrationState> {
_keychainCreationCubit.setSeedPhraseStoredConfirmed(confirmed);
}

void refreshWallets() {
unawaited(_walletLinkCubit.refreshWallets());
}

Future<void> selectWallet(CardanoWallet wallet) {
return _walletLinkCubit.selectWallet(wallet);
}

Future<void> downloadSeedPhrase() {
return _keychainCreationCubit.downloadSeedPhrase();
}
Expand All @@ -108,6 +104,18 @@ final class RegistrationCubit extends Cubit<RegistrationState> {
);
}

void refreshWallets() {
unawaited(_walletLinkCubit.refreshWallets());
}

Future<void> selectWallet(CardanoWallet wallet) {
return _walletLinkCubit.selectWallet(wallet);
}

void submitRegistration() {
// TODO(dtscalac): submit RBAC transaction
}

RegistrationStep? _nextStep({RegistrationStep? from}) {
final step = from ?? state.step;

Expand Down
Loading

0 comments on commit 07b6d96

Please sign in to comment.