Build exchange workspace and shared transaction services (#28)

This commit is contained in:
Stephan D committed 2026-09-12 12:01:36 +02:00
1 parent 52b7135eda
commit c496da8a55
48 files changed
+4757 -120

No files matched your search

@@ -1021,6 +1021,528 @@ abstract class AppLocalizations {
/// In en, this message translates to:
/// **'No capacity available'**
String get kycNoCapacity;
/// No description provided for @wAccounts.
///
/// In en, this message translates to:
/// **'Accounts'**
String get wAccounts;
/// No description provided for @wActivity.
///
/// In en, this message translates to:
/// **'Activity'**
String get wActivity;
/// No description provided for @wLimits.
///
/// In en, this message translates to:
/// **'Limits'**
String get wLimits;
/// No description provided for @wSettings.
///
/// In en, this message translates to:
/// **'Settings'**
String get wSettings;
/// No description provided for @wHeadline.
///
/// In en, this message translates to:
/// **'Your money.\nYour next move.'**
String get wHeadline;
/// No description provided for @wSubheading.
///
/// In en, this message translates to:
/// **'Top up. Exchange. Go further.'**
String get wSubheading;
/// No description provided for @wAvailable.
///
/// In en, this message translates to:
/// **'Available to you'**
String get wAvailable;
/// No description provided for @wTopUp.
///
/// In en, this message translates to:
/// **'Top up'**
String get wTopUp;
/// No description provided for @wExchange.
///
/// In en, this message translates to:
/// **'Exchange'**
String get wExchange;
/// No description provided for @wPayout.
///
/// In en, this message translates to:
/// **'Pay out'**
String get wPayout;
/// No description provided for @wRecent.
///
/// In en, this message translates to:
/// **'Recent activity'**
String get wRecent;
/// No description provided for @wSeeAll.
///
/// In en, this message translates to:
/// **'See all'**
String get wSeeAll;
/// No description provided for @wEmptyActivity.
///
/// In en, this message translates to:
/// **'Your next move starts here. Your transactions will appear below.'**
String get wEmptyActivity;
/// No description provided for @wEmptyAccounts.
///
/// In en, this message translates to:
/// **'Your accounts are not ready yet. Try refreshing.'**
String get wEmptyAccounts;
/// No description provided for @wRefresh.
///
/// In en, this message translates to:
/// **'Refresh'**
String get wRefresh;
/// No description provided for @wDemo.
///
/// In en, this message translates to:
/// **'Demo workspace · No real money moves.'**
String get wDemo;
/// No description provided for @wSource.
///
/// In en, this message translates to:
/// **'From account'**
String get wSource;
/// No description provided for @wDestination.
///
/// In en, this message translates to:
/// **'To account'**
String get wDestination;
/// No description provided for @wReceiveAccount.
///
/// In en, this message translates to:
/// **'Receiving account'**
String get wReceiveAccount;
/// No description provided for @wAmount.
///
/// In en, this message translates to:
/// **'Amount'**
String get wAmount;
/// No description provided for @wRecipient.
///
/// In en, this message translates to:
/// **'Recipient'**
String get wRecipient;
/// No description provided for @wRecipientHint.
///
/// In en, this message translates to:
/// **'Sample recipient — demo only'**
String get wRecipientHint;
/// No description provided for @wReview.
///
/// In en, this message translates to:
/// **'Review'**
String get wReview;
/// No description provided for @wReviewTitle.
///
/// In en, this message translates to:
/// **'One last look.'**
String get wReviewTitle;
/// No description provided for @wFee.
///
/// In en, this message translates to:
/// **'Fee'**
String get wFee;
/// No description provided for @wTotalDebit.
///
/// In en, this message translates to:
/// **'Leaves your account'**
String get wTotalDebit;
/// No description provided for @wCredit.
///
/// In en, this message translates to:
/// **'Arrives in your account'**
String get wCredit;
/// No description provided for @wRecipientGets.
///
/// In en, this message translates to:
/// **'Recipient receives'**
String get wRecipientGets;
/// No description provided for @wYouPay.
///
/// In en, this message translates to:
/// **'You pay'**
String get wYouPay;
/// No description provided for @wRate.
///
/// In en, this message translates to:
/// **'Exchange rate'**
String get wRate;
/// No description provided for @wQuoteNotice.
///
/// In en, this message translates to:
/// **'These terms are valid for 60 seconds. Confirm them before continuing.'**
String get wQuoteNotice;
/// No description provided for @wExpired.
///
/// In en, this message translates to:
/// **'This quote expired. Refresh it and review the new terms.'**
String get wExpired;
/// No description provided for @wNewQuote.
///
/// In en, this message translates to:
/// **'Refresh quote'**
String get wNewQuote;
/// No description provided for @wConfirm.
///
/// In en, this message translates to:
/// **'Confirm demo transaction'**
String get wConfirm;
/// No description provided for @wEdit.
///
/// In en, this message translates to:
/// **'Edit details'**
String get wEdit;
/// No description provided for @wClose.
///
/// In en, this message translates to:
/// **'Close'**
String get wClose;
/// No description provided for @wWorking.
///
/// In en, this message translates to:
/// **'Working on it…'**
String get wWorking;
/// No description provided for @wPending.
///
/// In en, this message translates to:
/// **'Processing'**
String get wPending;
/// No description provided for @wCompleted.
///
/// In en, this message translates to:
/// **'Completed'**
String get wCompleted;
/// No description provided for @wFailed.
///
/// In en, this message translates to:
/// **'Not completed'**
String get wFailed;
/// No description provided for @wPendingTopUp.
///
/// In en, this message translates to:
/// **'Your top-up is processing. Your available balance has not changed yet.'**
String get wPendingTopUp;
/// No description provided for @wPendingExchange.
///
/// In en, this message translates to:
/// **'The amount and fee have left your available balance. The exchanged amount will appear in the receiving account when completed.'**
String get wPendingExchange;
/// No description provided for @wPendingPayout.
///
/// In en, this message translates to:
/// **'The amount and fee have left your available balance. The payout is still processing.'**
String get wPendingPayout;
/// No description provided for @wCompleteTopUp.
///
/// In en, this message translates to:
/// **'Your account has been credited. The money is available to use.'**
String get wCompleteTopUp;
/// No description provided for @wCompleteExchange.
///
/// In en, this message translates to:
/// **'Your exchange is complete. The money is available in the receiving account.'**
String get wCompleteExchange;
/// No description provided for @wCompletePayout.
///
/// In en, this message translates to:
/// **'Your payout is complete. The amount and fee have been deducted from your account.'**
String get wCompletePayout;
/// No description provided for @wFailedTopUp.
///
/// In en, this message translates to:
/// **'The top-up did not complete. No money was added to your account.'**
String get wFailedTopUp;
/// No description provided for @wFailedOutgoing.
///
/// In en, this message translates to:
/// **'The transaction did not complete. The amount and fee are available in your account again.'**
String get wFailedOutgoing;
/// No description provided for @wDemoMethod.
///
/// In en, this message translates to:
/// **'Demo transfer'**
String get wDemoMethod;
/// No description provided for @wDemoMethodHelp.
///
/// In en, this message translates to:
/// **'Try the flow with sample data. No bank or payment provider is contacted.'**
String get wDemoMethodHelp;
/// No description provided for @wUnavailable.
///
/// In en, this message translates to:
/// **'Could not refresh. The displayed information may be out of date. Try again.'**
String get wUnavailable;
/// No description provided for @wInvalidAmount.
///
/// In en, this message translates to:
/// **'Enter an amount greater than zero, using the currency’s decimal precision.'**
String get wInvalidAmount;
/// No description provided for @wInsufficient.
///
/// In en, this message translates to:
/// **'Not enough available money for this amount and fee. Top up or enter a smaller amount.'**
String get wInsufficient;
/// No description provided for @wLimitError.
///
/// In en, this message translates to:
/// **'This amount exceeds your available limit. Check your limits before continuing.'**
String get wLimitError;
/// No description provided for @wRecipientError.
///
/// In en, this message translates to:
/// **'Enter a sample recipient between 6 and 140 characters.'**
String get wRecipientError;
/// No description provided for @wUnsupported.
///
/// In en, this message translates to:
/// **'This combination is unavailable. Choose another account.'**
String get wUnsupported;
/// No description provided for @wNotFound.
///
/// In en, this message translates to:
/// **'This item could not be found. Return to your accounts.'**
String get wNotFound;
/// No description provided for @wUncertain.
///
/// In en, this message translates to:
/// **'We could not confirm the outcome. Check it before trying another transaction.'**
String get wUncertain;
/// No description provided for @wCheckOutcome.
///
/// In en, this message translates to:
/// **'Check outcome'**
String get wCheckOutcome;
/// No description provided for @wNoSubmission.
///
/// In en, this message translates to:
/// **'No transaction was found. You can review and confirm again.'**
String get wNoSubmission;
/// No description provided for @wDiscardTitle.
///
/// In en, this message translates to:
/// **'Leave this transaction?'**
String get wDiscardTitle;
/// No description provided for @wDiscardBody.
///
/// In en, this message translates to:
/// **'Your entered details will be cleared. No new transaction will be submitted.'**
String get wDiscardBody;
/// No description provided for @wStay.
///
/// In en, this message translates to:
/// **'Keep editing'**
String get wStay;
/// No description provided for @wAll.
///
/// In en, this message translates to:
/// **'All'**
String get wAll;
/// No description provided for @wSearch.
///
/// In en, this message translates to:
/// **'Search by reference'**
String get wSearch;
/// No description provided for @wNoMatches.
///
/// In en, this message translates to:
/// **'No matching transactions. Try another filter.'**
String get wNoMatches;
/// No description provided for @wClearFilters.
///
/// In en, this message translates to:
/// **'Clear filters'**
String get wClearFilters;
/// No description provided for @wReference.
///
/// In en, this message translates to:
/// **'Reference'**
String get wReference;
/// No description provided for @wWhen.
///
/// In en, this message translates to:
/// **'Created'**
String get wWhen;
/// No description provided for @wViewAccount.
///
/// In en, this message translates to:
/// **'View account'**
String get wViewAccount;
/// No description provided for @wPreferences.
///
/// In en, this message translates to:
/// **'Make it yours.'**
String get wPreferences;
/// No description provided for @wLanguage.
///
/// In en, this message translates to:
/// **'Account language'**
String get wLanguage;
/// No description provided for @wLanguageHelp.
///
/// In en, this message translates to:
/// **'Used throughout your account.'**
String get wLanguageHelp;
/// No description provided for @wLanguageSaved.
///
/// In en, this message translates to:
/// **'Saved to your demo account.'**
String get wLanguageSaved;
/// No description provided for @wLanguageFailed.
///
/// In en, this message translates to:
/// **'Changed for this session, but not saved to your account. Retry below.'**
String get wLanguageFailed;
/// No description provided for @wProfileError.
///
/// In en, this message translates to:
/// **'Account preferences could not be loaded. Try again.'**
String get wProfileError;
/// No description provided for @wSecurity.
///
/// In en, this message translates to:
/// **'Security'**
String get wSecurity;
/// No description provided for @wSecurityBody.
///
/// In en, this message translates to:
/// **'Live sessions, password changes and two-step verification are not connected in this demo.'**
String get wSecurityBody;
/// No description provided for @wIdentity.
///
/// In en, this message translates to:
/// **'Identity verification'**
String get wIdentity;
/// No description provided for @wIdentityHelp.
///
/// In en, this message translates to:
/// **'Optional verification for higher limits.'**
String get wIdentityHelp;
/// No description provided for @wBackLogin.
///
/// In en, this message translates to:
/// **'Back to login'**
String get wBackLogin;
/// No description provided for @wEnter.
///
/// In en, this message translates to:
/// **'Explore your accounts'**
String get wEnter;
/// No description provided for @wUsage.
///
/// In en, this message translates to:
/// **'Used this period'**
String get wUsage;
/// No description provided for @wLimitsScope.
///
/// In en, this message translates to:
/// **'Outgoing activity · EUR equivalent'**
String get wLimitsScope;
/// No description provided for @wPendingHint.
///
/// In en, this message translates to:
/// **'Refresh to check the latest status. You can keep using your other accounts.'**
String get wPendingHint;
/// No description provided for @wFundsHeading.
///
/// In en, this message translates to:
/// **'Where is my money?'**
String get wFundsHeading;
/// No description provided for @wAnother.
///
/// In en, this message translates to:
/// **'Make another transaction'**
String get wAnother;
}
class _AppLocalizationsDelegate
@@ -518,4 +518,292 @@ class AppLocalizationsEn extends AppLocalizations {
@override
String get kycNoCapacity => 'No capacity available';
@override
String get wAccounts => 'Accounts';
@override
String get wActivity => 'Activity';
@override
String get wLimits => 'Limits';
@override
String get wSettings => 'Settings';
@override
String get wHeadline => 'Your money.\nYour next move.';
@override
String get wSubheading => 'Top up. Exchange. Go further.';
@override
String get wAvailable => 'Available to you';
@override
String get wTopUp => 'Top up';
@override
String get wExchange => 'Exchange';
@override
String get wPayout => 'Pay out';
@override
String get wRecent => 'Recent activity';
@override
String get wSeeAll => 'See all';
@override
String get wEmptyActivity =>
'Your next move starts here. Your transactions will appear below.';
@override
String get wEmptyAccounts =>
'Your accounts are not ready yet. Try refreshing.';
@override
String get wRefresh => 'Refresh';
@override
String get wDemo => 'Demo workspace · No real money moves.';
@override
String get wSource => 'From account';
@override
String get wDestination => 'To account';
@override
String get wReceiveAccount => 'Receiving account';
@override
String get wAmount => 'Amount';
@override
String get wRecipient => 'Recipient';
@override
String get wRecipientHint => 'Sample recipient — demo only';
@override
String get wReview => 'Review';
@override
String get wReviewTitle => 'One last look.';
@override
String get wFee => 'Fee';
@override
String get wTotalDebit => 'Leaves your account';
@override
String get wCredit => 'Arrives in your account';
@override
String get wRecipientGets => 'Recipient receives';
@override
String get wYouPay => 'You pay';
@override
String get wRate => 'Exchange rate';
@override
String get wQuoteNotice =>
'These terms are valid for 60 seconds. Confirm them before continuing.';
@override
String get wExpired =>
'This quote expired. Refresh it and review the new terms.';
@override
String get wNewQuote => 'Refresh quote';
@override
String get wConfirm => 'Confirm demo transaction';
@override
String get wEdit => 'Edit details';
@override
String get wClose => 'Close';
@override
String get wWorking => 'Working on it…';
@override
String get wPending => 'Processing';
@override
String get wCompleted => 'Completed';
@override
String get wFailed => 'Not completed';
@override
String get wPendingTopUp =>
'Your top-up is processing. Your available balance has not changed yet.';
@override
String get wPendingExchange =>
'The amount and fee have left your available balance. The exchanged amount will appear in the receiving account when completed.';
@override
String get wPendingPayout =>
'The amount and fee have left your available balance. The payout is still processing.';
@override
String get wCompleteTopUp =>
'Your account has been credited. The money is available to use.';
@override
String get wCompleteExchange =>
'Your exchange is complete. The money is available in the receiving account.';
@override
String get wCompletePayout =>
'Your payout is complete. The amount and fee have been deducted from your account.';
@override
String get wFailedTopUp =>
'The top-up did not complete. No money was added to your account.';
@override
String get wFailedOutgoing =>
'The transaction did not complete. The amount and fee are available in your account again.';
@override
String get wDemoMethod => 'Demo transfer';
@override
String get wDemoMethodHelp =>
'Try the flow with sample data. No bank or payment provider is contacted.';
@override
String get wUnavailable =>
'Could not refresh. The displayed information may be out of date. Try again.';
@override
String get wInvalidAmount =>
'Enter an amount greater than zero, using the currency’s decimal precision.';
@override
String get wInsufficient =>
'Not enough available money for this amount and fee. Top up or enter a smaller amount.';
@override
String get wLimitError =>
'This amount exceeds your available limit. Check your limits before continuing.';
@override
String get wRecipientError =>
'Enter a sample recipient between 6 and 140 characters.';
@override
String get wUnsupported =>
'This combination is unavailable. Choose another account.';
@override
String get wNotFound =>
'This item could not be found. Return to your accounts.';
@override
String get wUncertain =>
'We could not confirm the outcome. Check it before trying another transaction.';
@override
String get wCheckOutcome => 'Check outcome';
@override
String get wNoSubmission =>
'No transaction was found. You can review and confirm again.';
@override
String get wDiscardTitle => 'Leave this transaction?';
@override
String get wDiscardBody =>
'Your entered details will be cleared. No new transaction will be submitted.';
@override
String get wStay => 'Keep editing';
@override
String get wAll => 'All';
@override
String get wSearch => 'Search by reference';
@override
String get wNoMatches => 'No matching transactions. Try another filter.';
@override
String get wClearFilters => 'Clear filters';
@override
String get wReference => 'Reference';
@override
String get wWhen => 'Created';
@override
String get wViewAccount => 'View account';
@override
String get wPreferences => 'Make it yours.';
@override
String get wLanguage => 'Account language';
@override
String get wLanguageHelp => 'Used throughout your account.';
@override
String get wLanguageSaved => 'Saved to your demo account.';
@override
String get wLanguageFailed =>
'Changed for this session, but not saved to your account. Retry below.';
@override
String get wProfileError =>
'Account preferences could not be loaded. Try again.';
@override
String get wSecurity => 'Security';
@override
String get wSecurityBody =>
'Live sessions, password changes and two-step verification are not connected in this demo.';
@override
String get wIdentity => 'Identity verification';
@override
String get wIdentityHelp => 'Optional verification for higher limits.';
@override
String get wBackLogin => 'Back to login';
@override
String get wEnter => 'Explore your accounts';
@override
String get wUsage => 'Used this period';
@override
String get wLimitsScope => 'Outgoing activity · EUR equivalent';
@override
String get wPendingHint =>
'Refresh to check the latest status. You can keep using your other accounts.';
@override
String get wFundsHeading => 'Where is my money?';
@override
String get wAnother => 'Make another transaction';
}
@@ -519,4 +519,289 @@ class AppLocalizationsRu extends AppLocalizations {
@override
String get kycNoCapacity => 'Доступный объём исчерпан';
@override
String get wAccounts => 'Счета';
@override
String get wActivity => 'История';
@override
String get wLimits => 'Лимиты';
@override
String get wSettings => 'Настройки';
@override
String get wHeadline => 'Ваши деньги.\nВаш следующий шаг.';
@override
String get wSubheading => 'Пополняйте. Обменивайте. Двигайтесь дальше.';
@override
String get wAvailable => 'Вам доступно';
@override
String get wTopUp => 'Пополнить';
@override
String get wExchange => 'Обменять';
@override
String get wPayout => 'Вывести';
@override
String get wRecent => 'Последние операции';
@override
String get wSeeAll => 'Смотреть все';
@override
String get wEmptyActivity =>
'Ваш следующий шаг начинается здесь. Здесь появятся ваши операции.';
@override
String get wEmptyAccounts =>
'Ваши счета ещё не готовы. Попробуйте обновить страницу.';
@override
String get wRefresh => 'Обновить';
@override
String get wDemo => 'Демонстрация · Реальные деньги не переводятся.';
@override
String get wSource => 'Со счёта';
@override
String get wDestination => 'На счёт';
@override
String get wReceiveAccount => 'Счёт для зачисления';
@override
String get wAmount => 'Сумма';
@override
String get wRecipient => 'Получатель';
@override
String get wRecipientHint => 'Тестовый получатель — только демо';
@override
String get wReview => 'Проверить';
@override
String get wReviewTitle => 'Проверьте детали.';
@override
String get wFee => 'Комиссия';
@override
String get wTotalDebit => 'Спишется со счёта';
@override
String get wCredit => 'Поступит на счёт';
@override
String get wRecipientGets => 'Получатель получит';
@override
String get wYouPay => 'Вы платите';
@override
String get wRate => 'Курс обмена';
@override
String get wQuoteNotice =>
'Эти условия действуют 60 секунд. Подтвердите их, прежде чем продолжить.';
@override
String get wExpired =>
'Срок действия расчёта истёк. Обновите его и проверьте новые условия.';
@override
String get wNewQuote => 'Обновить расчёт';
@override
String get wConfirm => 'Подтвердить тестовую операцию';
@override
String get wEdit => 'Изменить данные';
@override
String get wClose => 'Закрыть';
@override
String get wWorking => 'Обрабатываем…';
@override
String get wPending => 'В обработке';
@override
String get wCompleted => 'Завершено';
@override
String get wFailed => 'Не выполнено';
@override
String get wPendingTopUp =>
'Пополнение обрабатывается. Доступный баланс пока не изменился.';
@override
String get wPendingExchange =>
'Сумма и комиссия уже вычтены из доступного баланса. После завершения обмена деньги появятся на счёте зачисления.';
@override
String get wPendingPayout =>
'Сумма и комиссия уже вычтены из доступного баланса. Вывод ещё обрабатывается.';
@override
String get wCompleteTopUp => 'Счёт пополнен. Деньги доступны для операций.';
@override
String get wCompleteExchange =>
'Обмен завершён. Деньги доступны на счёте зачисления.';
@override
String get wCompletePayout =>
'Вывод завершён. Сумма и комиссия списаны с вашего счёта.';
@override
String get wFailedTopUp =>
'Пополнение не выполнено. На счёт ничего не зачислено.';
@override
String get wFailedOutgoing =>
'Операция не выполнена. Сумма и комиссия снова доступны на вашем счёте.';
@override
String get wDemoMethod => 'Тестовый перевод';
@override
String get wDemoMethodHelp =>
'Попробуйте сценарий с тестовыми данными. Банки и платёжные системы не подключены.';
@override
String get wUnavailable =>
'Не удалось обновить данные. Информация может быть устаревшей. Повторите попытку.';
@override
String get wInvalidAmount =>
'Введите сумму больше нуля с допустимым для валюты числом знаков после запятой.';
@override
String get wInsufficient =>
'Для этой суммы и комиссии недостаточно доступных средств. Пополните счёт или уменьшите сумму.';
@override
String get wLimitError =>
'Сумма превышает доступный лимит. Проверьте лимиты перед продолжением.';
@override
String get wRecipientError =>
'Введите тестового получателя длиной от 6 до 140 символов.';
@override
String get wUnsupported => 'Эта комбинация недоступна. Выберите другой счёт.';
@override
String get wNotFound => 'Не удалось найти запись. Вернитесь к счетам.';
@override
String get wUncertain =>
'Не удалось подтвердить результат. Проверьте его, прежде чем создавать другую операцию.';
@override
String get wCheckOutcome => 'Проверить результат';
@override
String get wNoSubmission =>
'Операция не найдена. Вы можете снова проверить и подтвердить её.';
@override
String get wDiscardTitle => 'Выйти из операции?';
@override
String get wDiscardBody =>
'Введённые данные будут удалены. Новая операция не будет отправлена.';
@override
String get wStay => 'Продолжить';
@override
String get wAll => 'Все';
@override
String get wSearch => 'Поиск по номеру';
@override
String get wNoMatches => 'Операции не найдены. Измените фильтр.';
@override
String get wClearFilters => 'Сбросить фильтры';
@override
String get wReference => 'Номер операции';
@override
String get wWhen => 'Создано';
@override
String get wViewAccount => 'Открыть счёт';
@override
String get wPreferences => 'Настройте под себя.';
@override
String get wLanguage => 'Язык аккаунта';
@override
String get wLanguageHelp => 'Используется во всём аккаунте.';
@override
String get wLanguageSaved => 'Сохранено в тестовом аккаунте.';
@override
String get wLanguageFailed =>
'Изменено для текущей сессии, но не сохранено в аккаунте. Повторите попытку ниже.';
@override
String get wProfileError =>
'Не удалось загрузить настройки аккаунта. Повторите попытку.';
@override
String get wSecurity => 'Безопасность';
@override
String get wSecurityBody =>
'В этой демонстрации не подключены рабочие сессии, смена пароля и двухэтапная проверка.';
@override
String get wIdentity => 'Подтверждение личности';
@override
String get wIdentityHelp => 'Необязательная проверка для повышения лимитов.';
@override
String get wBackLogin => 'Вернуться ко входу';
@override
String get wEnter => 'Открыть свои счета';
@override
String get wUsage => 'Использовано за период';
@override
String get wLimitsScope => 'Исходящие операции · эквивалент в EUR';
@override
String get wPendingHint =>
'Обновите, чтобы узнать текущий статус. Остальными счетами можно пользоваться.';
@override
String get wFundsHeading => 'Где мои деньги?';
@override
String get wAnother => 'Создать новую операцию';
}