merge fixes

This commit is contained in:
Stephan D
2025-11-23 15:45:10 +01:00
228 changed files with 5100 additions and 5433 deletions

1
frontend/pweb/lib/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,779 +0,0 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get login => 'Login';
@override
String get logout => 'Logout';
@override
String get profile => 'Profile';
@override
String get signup => 'Sign up';
@override
String get username => 'Email';
@override
String get usernameHint => 'email@example.com';
@override
String get usernameErrorInvalid => 'Provide a valid email address';
@override
String usernameUnknownTLD(Object domain) {
return 'Domain .$domain is not known, please, check it';
}
@override
String get password => 'Password';
@override
String get confirmPassword => 'Confirm password';
@override
String get passwordValidationRuleDigit => 'has digit';
@override
String get passwordValidationRuleUpperCase => 'has uppercase letter';
@override
String get passwordValidationRuleLowerCase => 'has lowercase letter';
@override
String get passwordValidationRuleSpecialCharacter =>
'has special character letter';
@override
String passwordValidationRuleMinCharacters(Object charNum) {
return 'is $charNum characters long at least';
}
@override
String get passwordsDoNotMatch => 'Passwords do not match';
@override
String passwordValidationError(Object matchesCriteria) {
return 'Check that your password $matchesCriteria';
}
@override
String notificationError(Object error) {
return 'Error occurred: $error';
}
@override
String loginUserNotFound(Object account) {
return 'Account $account has not been registered in the system';
}
@override
String get loginPasswordIncorrect =>
'Authorization failed, please check your password';
@override
String internalErrorOccurred(Object error) {
return 'An internal server error occurred: $error, we already know about it and working hard to fix it';
}
@override
String get noErrorInformation =>
'Some error occurred, but we have not error information. We are already investigating the issue';
@override
String get yourName => 'Your name';
@override
String get nameHint => 'John Doe';
@override
String get errorPageNotFoundTitle => 'Page Not Found';
@override
String get errorPageNotFoundMessage => 'Oops! We couldn\'t find that page.';
@override
String get errorPageNotFoundHint =>
'The page you\'re looking for doesn\'t exist or has been moved. Please check the URL or return to the home page.';
@override
String get errorUnknown => 'Unknown error occurred';
@override
String get unknown => 'unknown';
@override
String get goToLogin => 'Go to Login';
@override
String get goBack => 'Go Back';
@override
String get goToMainPage => 'Go to Main Page';
@override
String get goToSignUp => 'Go to Sign Up';
@override
String signupError(Object error) {
return 'Failed to signup: $error';
}
@override
String signupSuccess(Object email) {
return 'Email confirmation message has been sent to $email. Please, open it and click link to activate your account.';
}
@override
String connectivityError(Object serverAddress) {
return 'Cannot reach the server at $serverAddress. Check your network and try again.';
}
@override
String get errorAccountExists => 'Account already exists';
@override
String get errorAccountNotVerified =>
'Your account hasn\'t been verified yet. Please check your email to complete the verification';
@override
String get errorLoginUnauthorized =>
'Login or password is incorrect. Please try again';
@override
String get errorInternalError =>
'An internal error occurred. We\'re aware of the issue and working to resolve it. Please try again later';
@override
String get errorVerificationTokenNotFound =>
'Account for verification not found. Sign up again';
@override
String get created => 'Created';
@override
String get edited => 'Edited';
@override
String get errorDataConflict =>
'We cant process your data because it has conflicting or contradictory information.';
@override
String get errorAccessDenied =>
'You do not have permission to access this resource. If you need access, please contact an administrator.';
@override
String get errorBrokenPayload =>
'The data you sent is invalid or incomplete. Please check your submission and try again.';
@override
String get errorInvalidArgument =>
'One or more arguments are invalid. Verify your input and try again.';
@override
String get errorBrokenReference =>
'The resource you\'re trying to access could not be referenced. It may have been moved or deleted.';
@override
String get errorInvalidQueryParameter =>
'One or more query parameters are missing or incorrect. Check them and try again.';
@override
String get errorNotImplemented =>
'This feature is not yet available. Please try again later or contact support.';
@override
String get errorLicenseRequired =>
'A valid license is required to perform this action. Please contact your administrator.';
@override
String get errorNotFound =>
'We couldn\'t find the resource you requested. It may have been removed or is temporarily unavailable.';
@override
String get errorNameMissing => 'Please provide a name before continuing.';
@override
String get errorEmailMissing =>
'Please provide an email address before continuing.';
@override
String get errorPasswordMissing =>
'Please provide a password before continuing.';
@override
String get errorEmailNotRegistered =>
'We could not find an account associated with that email address.';
@override
String get errorDuplicateEmail =>
'This email address is already in use. Try another one or reset your password.';
@override
String get showDetailsAction => 'Show Details';
@override
String get errorLogin => 'Error logging in';
@override
String get errorCreatingInvitation => 'Failed to create invitaiton';
@override
String get footerCompanyName => 'Sibilla Solutions LTD';
@override
String get footerAddress =>
'27, Pindarou Street, Alpha Business Centre, Block B 7th Floor, 1060 Nicosia, Cyprus';
@override
String get footerSupport => 'Support';
@override
String get footerEmail => 'Email TBD';
@override
String get footerPhoneLabel => 'Phone';
@override
String get footerPhone => '+357 22 000 253';
@override
String get footerTermsOfService => 'Terms of Service';
@override
String get footerPrivacyPolicy => 'Privacy Policy';
@override
String get footerCookiePolicy => 'Cookie Policy';
@override
String get navigationLogout => 'Logout';
@override
String get dashboard => 'Dashboard';
@override
String get navigationUsersSettings => 'Users';
@override
String get navigationRolesSettings => 'Roles';
@override
String get navigationPermissionsSettings => 'Permissions';
@override
String get usersManagement => 'User Management';
@override
String get navigationOrganizationSettings => 'Organization settings';
@override
String get navigationAccountSettings => 'Profile settings';
@override
String get twoFactorPrompt => 'Enter the 6-digit code we sent to your device';
@override
String get twoFactorResend => 'Didnt receive a code? Resend';
@override
String get twoFactorTitle => 'Two-Factor Authentication';
@override
String get twoFactorError => 'Invalid code. Please try again.';
@override
String get payoutNavDashboard => 'Dashboard';
@override
String get payoutNavSendPayout => 'Send payout';
@override
String get payoutNavRecipients => 'Recipients';
@override
String get payoutNavReports => 'Reports';
@override
String get payoutNavSettings => 'Settings';
@override
String get payoutNavLogout => 'Logout';
@override
String get payoutNavMethods => 'Payouts';
@override
String get expand => 'Expand';
@override
String get collapse => 'Collapse';
@override
String get pageTitleRecipients => 'Recipient address book';
@override
String get actionAddNew => 'Add new';
@override
String get colDataOwner => 'Data owner';
@override
String get colAvatar => 'Avatar';
@override
String get colName => 'Name';
@override
String get colEmail => 'Email';
@override
String get colStatus => 'Status';
@override
String get statusReady => 'Ready';
@override
String get statusRegistered => 'Registered';
@override
String get statusNotRegistered => 'Not registered';
@override
String get typeInternal => 'Managed by me';
@override
String get typeExternal => 'Selfmanaged';
@override
String get searchHint => 'Search recipients';
@override
String get colActions => 'Actions';
@override
String get menuEdit => 'Edit';
@override
String get menuSendPayout => 'Send payout';
@override
String get tooltipRowActions => 'More actions';
@override
String get accountSettings => 'Account Settings';
@override
String get accountNameUpdateError => 'Failed to update account name';
@override
String get settingsSuccessfullyUpdated => 'Settings successfully updated';
@override
String get language => 'Language';
@override
String get failedToUpdateLanguage => 'Failed to update language';
@override
String get settingsImageUpdateError => 'Couldn\'t update the image';
@override
String get settingsImageTitle => 'Image';
@override
String get settingsImageHint => 'Tap to change the image';
@override
String get accountName => 'Name';
@override
String get accountNameHint => 'Specify your name';
@override
String get avatar => 'Profile photo';
@override
String get avatarHint => 'Tap to update';
@override
String get avatarUpdateError => 'Failed to update profile photo';
@override
String get settings => 'Settings';
@override
String get notSet => 'not set';
@override
String get search => 'Search...';
@override
String get ok => 'Ok';
@override
String get cancel => 'Cancel';
@override
String get confirm => 'Confirm';
@override
String get back => 'Back';
@override
String get operationfryTitle => 'Operation history';
@override
String get filters => 'Filters';
@override
String get period => 'Period';
@override
String get selectPeriod => 'Select period';
@override
String get apply => 'Apply';
@override
String status(String status) {
return '$status';
}
@override
String get operationStatusSuccessful => 'Successful';
@override
String get operationStatusPending => 'Pending';
@override
String get operationStatusUnsuccessful => 'Unsuccessful';
@override
String get statusColumn => 'Status';
@override
String get fileNameColumn => 'File name';
@override
String get amountColumn => 'Amount';
@override
String get toAmountColumn => 'To amount';
@override
String get payIdColumn => 'Pay ID';
@override
String get cardNumberColumn => 'Card number';
@override
String get nameColumn => 'Name';
@override
String get dateColumn => 'Date';
@override
String get commentColumn => 'Comment';
@override
String get paymentConfigTitle => 'Where to receive money';
@override
String get paymentConfigSubtitle =>
'Add multiple methods and choose your primary one.';
@override
String get addPaymentMethod => 'Add payment method';
@override
String get makeMain => 'Make primary';
@override
String get advanced => 'Advanced';
@override
String get fallbackExplanation =>
'If the primary method is unavailable, we will try the next enabled one in the list.';
@override
String get delete => 'Delete';
@override
String get deletePaymentConfirmation =>
'Are you sure you want to delete this payment method?';
@override
String get edit => 'Edit';
@override
String get moreActions => 'More actions';
@override
String get noPayouts => 'No Payouts';
@override
String get enterBankName => 'Enter bank name';
@override
String get paymentType => 'Payment Method Type';
@override
String get selectPaymentType => 'Please select a payment method type';
@override
String get paymentTypeCard => 'Credit Card';
@override
String get paymentTypeBankAccount => 'Russian Bank Account';
@override
String get paymentTypeIban => 'IBAN';
@override
String get paymentTypeWallet => 'Wallet';
@override
String get cardNumber => 'Card Number';
@override
String get enterCardNumber => 'Enter the card number';
@override
String get cardholderName => 'Cardholder Name';
@override
String get iban => 'IBAN';
@override
String get enterIban => 'Enter IBAN';
@override
String get bic => 'BIC';
@override
String get bankName => 'Bank Name';
@override
String get accountHolder => 'Account Holder';
@override
String get enterAccountHolder => 'Enter account holder';
@override
String get enterBic => 'Enter BIC';
@override
String get walletId => 'Wallet ID';
@override
String get enterWalletId => 'Enter wallet ID';
@override
String get recipients => 'Recipients';
@override
String get recipientName => 'Recipient Name';
@override
String get enterRecipientName => 'Enter recipient name';
@override
String get inn => 'INN';
@override
String get enterInn => 'Enter INN';
@override
String get kpp => 'KPP';
@override
String get enterKpp => 'Enter KPP';
@override
String get accountNumber => 'Account Number';
@override
String get enterAccountNumber => 'Enter account number';
@override
String get correspondentAccount => 'Correspondent Account';
@override
String get enterCorrespondentAccount => 'Enter correspondent account';
@override
String get bik => 'BIK';
@override
String get enterBik => 'Enter BIK';
@override
String get add => 'Add';
@override
String get expiryDate => 'Expiry (MM/YY)';
@override
String get firstName => 'First Name';
@override
String get enterFirstName => 'Enter First Name';
@override
String get lastName => 'Last Name';
@override
String get enterLastName => 'Enter Last Name';
@override
String get sendSingle => 'Send single transaction';
@override
String get sendMultiple => 'Send multiple transactions';
@override
String get addFunds => 'Add Funds';
@override
String get close => 'Close';
@override
String get multiplePayout => 'Multiple Payout';
@override
String get howItWorks => 'How it works?';
@override
String get exampleTitle => 'File Format & Sample';
@override
String get downloadSampleCSV => 'Download sample.csv';
@override
String get tokenColumn => 'Token (required)';
@override
String get currency => 'Currency';
@override
String get amount => 'Amount';
@override
String get comment => 'Comment';
@override
String get uploadCSV => 'Upload your CSV';
@override
String get upload => 'Upload';
@override
String get hintUpload => 'Supported format: .CSV · Max size 1 MB';
@override
String get uploadHistory => 'Upload History';
@override
String get payout => 'Payout';
@override
String get sendTo => 'Send Payout To';
@override
String get send => 'Send Payout';
@override
String get recipientPaysFee => 'Recipient pays the fee';
@override
String sentAmount(String amount) {
return 'Sent amount: \$$amount';
}
@override
String fee(String fee) {
return 'Fee: \$$fee';
}
@override
String recipientWillReceive(String amount) {
return 'Recipient will receive: \$$amount';
}
@override
String total(String total) {
return 'Total: \$$total';
}
@override
String get hideDetails => 'Hide Details';
@override
String get showDetails => 'Show Details';
@override
String get whereGetMoney => 'Source of funds for debit';
@override
String get details => 'Details';
@override
String get addRecipient => 'Add Recipient';
@override
String get editRecipient => 'Edit Recipient';
@override
String get saveRecipient => 'Save Recipient';
@override
String get choosePaymentMethod => 'Payment Methods (choose at least 1)';
@override
String get recipientFormRule =>
'Recipient must have at least one payment method';
@override
String get allStatus => 'All';
@override
String get readyStatus => 'Ready';
@override
String get registeredStatus => 'Registered';
@override
String get notRegisteredStatus => 'Not registered';
@override
String get noRecipientSelected => 'No recipient selected';
@override
String get companyName => 'Name of your company';
@override
String get companynameRequired => 'Company name required';
@override
String get errorSignUp => 'Error occured while signing up, try again later';
@override
String get companyDescription => 'Company Description';
@override
String get companyDescriptionHint =>
'Describe any of the fields of the Company\'s business';
@override
String get optional => 'optional';
}

View File

@@ -1,782 +0,0 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for Russian (`ru`).
class AppLocalizationsRu extends AppLocalizations {
AppLocalizationsRu([String locale = 'ru']) : super(locale);
@override
String get login => 'Войти';
@override
String get logout => 'Выйти';
@override
String get profile => 'Профиль';
@override
String get signup => 'Регистрация';
@override
String get username => 'Email';
@override
String get usernameHint => 'email@example.com';
@override
String get usernameErrorInvalid =>
'Укажите действительный адрес электронной почты';
@override
String usernameUnknownTLD(Object domain) {
return 'Домен .$domain неизвестен, пожалуйста, проверьте его';
}
@override
String get password => 'Пароль';
@override
String get confirmPassword => 'Подтвердите пароль';
@override
String get passwordValidationRuleDigit => 'содержит цифру';
@override
String get passwordValidationRuleUpperCase => 'содержит заглавную букву';
@override
String get passwordValidationRuleLowerCase => 'содержит строчную букву';
@override
String get passwordValidationRuleSpecialCharacter =>
'содержит специальный символ';
@override
String passwordValidationRuleMinCharacters(Object charNum) {
return 'длина не менее $charNum символов';
}
@override
String get passwordsDoNotMatch => 'Пароли не совпадают';
@override
String passwordValidationError(Object matchesCriteria) {
return 'Убедитесь, что ваш пароль $matchesCriteria';
}
@override
String notificationError(Object error) {
return 'Произошла ошибка: $error';
}
@override
String loginUserNotFound(Object account) {
return 'Аккаунт $account не зарегистрирован в системе';
}
@override
String get loginPasswordIncorrect =>
'Ошибка авторизации, пожалуйста, проверьте пароль';
@override
String internalErrorOccurred(Object error) {
return 'Произошла внутренняя ошибка сервера: $error, мы уже знаем о ней и усердно работаем над исправлением';
}
@override
String get noErrorInformation =>
'Произошла ошибка, но у нас нет информации о ней. Мы уже расследуем этот вопрос';
@override
String get yourName => 'Ваше имя';
@override
String get nameHint => 'Иван Иванов';
@override
String get errorPageNotFoundTitle => 'Страница не найдена';
@override
String get errorPageNotFoundMessage =>
'Упс! Мы не смогли найти эту страницу.';
@override
String get errorPageNotFoundHint =>
'Запрашиваемая страница не существует или была перемещена. Пожалуйста, проверьте URL или вернитесь на главную страницу.';
@override
String get errorUnknown => 'Произошла неизвестная ошибка';
@override
String get unknown => 'неизвестно';
@override
String get goToLogin => 'Перейти к входу';
@override
String get goBack => 'Назад';
@override
String get goToMainPage => 'На главную';
@override
String get goToSignUp => 'Перейти к регистрации';
@override
String signupError(Object error) {
return 'Не удалось зарегистрироваться: $error';
}
@override
String signupSuccess(Object email) {
return 'Письмо с подтверждением email отправлено на $email. Пожалуйста, откройте его и перейдите по ссылке для активации вашего аккаунта.';
}
@override
String connectivityError(Object serverAddress) {
return 'Не удается связаться с сервером $serverAddress. Проверьте ваше интернет-соединение и попробуйте снова.';
}
@override
String get errorAccountExists => 'Account already exists';
@override
String get errorAccountNotVerified =>
'Ваш аккаунт еще не подтвержден. Пожалуйста, проверьте вашу электронную почту для завершения верификации';
@override
String get errorLoginUnauthorized =>
'Неверный логин или пароль. Пожалуйста, попробуйте снова';
@override
String get errorInternalError =>
'Произошла внутренняя ошибка. Мы в курсе проблемы и работаем над ее решением. Пожалуйста, попробуйте позже';
@override
String get errorVerificationTokenNotFound =>
'Аккаунт для верификации не найден. Зарегистрируйтесь снова';
@override
String get created => 'Создано';
@override
String get edited => 'Изменено';
@override
String get errorDataConflict =>
'Мы не можем обработать ваши данные, так как они содержат конфликтующую или противоречивую информацию.';
@override
String get errorAccessDenied =>
'У вас нет разрешения на доступ к этому ресурсу. Если вам нужен доступ, пожалуйста, обратитесь к администратору.';
@override
String get errorBrokenPayload =>
'Отправленные данные недействительны или неполны. Пожалуйста, проверьте введенные данные и попробуйте снова.';
@override
String get errorInvalidArgument =>
'Один или несколько аргументов недействительны. Проверьте введенные данные и попробуйте снова.';
@override
String get errorBrokenReference =>
'Ресурс, к которому вы пытаетесь получить доступ, не может быть найден. Возможно, он был перемещен или удален.';
@override
String get errorInvalidQueryParameter =>
'Один или несколько параметров запроса отсутствуют или указаны неверно. Проверьте их и попробуйте снова.';
@override
String get errorNotImplemented =>
'Эта функция еще недоступна. Пожалуйста, попробуйте позже или обратитесь в службу поддержки.';
@override
String get errorLicenseRequired =>
'Для выполнения этого действия требуется действующая лицензия. Пожалуйста, обратитесь к вашему администратору.';
@override
String get errorNotFound =>
'Мы не смогли найти запрошенный ресурс. Возможно, он был удален или временно недоступен.';
@override
String get errorNameMissing => 'Пожалуйста, укажите имя для продолжения.';
@override
String get errorEmailMissing =>
'Пожалуйста, укажите адрес электронной почты для продолжения.';
@override
String get errorPasswordMissing =>
'Пожалуйста, укажите пароль для продолжения.';
@override
String get errorEmailNotRegistered =>
'Мы не нашли аккаунт, связанный с этим адресом электронной почты.';
@override
String get errorDuplicateEmail =>
'Этот адрес электронной почты уже используется. Попробуйте другой или восстановите пароль.';
@override
String get showDetailsAction => 'Показать детали';
@override
String get errorLogin => 'Ошибка входа';
@override
String get errorCreatingInvitation => 'Не удалось создать приглашение';
@override
String get footerCompanyName => 'Sibilla Solutions LTD';
@override
String get footerAddress =>
'27, Pindarou Street, Alpha Business Centre, Block B 7th Floor, 1060 Nicosia, Cyprus';
@override
String get footerSupport => 'Поддержка';
@override
String get footerEmail => 'Email TBD';
@override
String get footerPhoneLabel => 'Телефон';
@override
String get footerPhone => '+357 22 000 253';
@override
String get footerTermsOfService => 'Условия обслуживания';
@override
String get footerPrivacyPolicy => 'Политика конфиденциальности';
@override
String get footerCookiePolicy => 'Политика использования файлов cookie';
@override
String get navigationLogout => 'Выйти';
@override
String get dashboard => 'Дашборд';
@override
String get navigationUsersSettings => 'Пользователи';
@override
String get navigationRolesSettings => 'Роли';
@override
String get navigationPermissionsSettings => 'Разрешения';
@override
String get usersManagement => 'Управление пользователями';
@override
String get navigationOrganizationSettings => 'Настройки организации';
@override
String get navigationAccountSettings => 'Настройки профиля';
@override
String get twoFactorPrompt =>
'Введите 6-значный код, отправленный на ваше устройство';
@override
String get twoFactorResend => 'Не получили код? Отправить снова';
@override
String get twoFactorTitle => 'Двухфакторная аутентификация';
@override
String get twoFactorError => 'Неверный код. Пожалуйста, попробуйте снова.';
@override
String get payoutNavDashboard => 'Дашборд';
@override
String get payoutNavSendPayout => 'Отправить выплату';
@override
String get payoutNavRecipients => 'Получатели';
@override
String get payoutNavReports => 'Отчеты';
@override
String get payoutNavSettings => 'Настройки';
@override
String get payoutNavLogout => 'Выйти';
@override
String get payoutNavMethods => 'Выплаты';
@override
String get expand => 'Развернуть';
@override
String get collapse => 'Свернуть';
@override
String get pageTitleRecipients => 'Адресная книга получателей';
@override
String get actionAddNew => 'Добавить';
@override
String get colDataOwner => 'Владелец данных';
@override
String get colAvatar => 'Аватар';
@override
String get colName => 'Имя';
@override
String get colEmail => 'Email';
@override
String get colStatus => 'Статус';
@override
String get statusReady => 'Готов';
@override
String get statusRegistered => 'Зарегистрирован';
@override
String get statusNotRegistered => 'Не зарегистрирован';
@override
String get typeInternal => 'Управляется мной';
@override
String get typeExternal => 'Самоуправляемый';
@override
String get searchHint => 'Поиск получателей';
@override
String get colActions => 'Действия';
@override
String get menuEdit => 'Редактировать';
@override
String get menuSendPayout => 'Отправить выплату';
@override
String get tooltipRowActions => 'Другие действия';
@override
String get accountSettings => 'Настройки аккаунта';
@override
String get accountNameUpdateError => 'Не удалось обновить имя аккаунта';
@override
String get settingsSuccessfullyUpdated => 'Настройки успешно обновлены';
@override
String get language => 'Язык';
@override
String get failedToUpdateLanguage => 'Не удалось обновить язык';
@override
String get settingsImageUpdateError => 'Не удалось обновить изображение';
@override
String get settingsImageTitle => 'Изображение';
@override
String get settingsImageHint => 'Нажмите, чтобы изменить изображение';
@override
String get accountName => 'Имя';
@override
String get accountNameHint => 'Укажите ваше имя';
@override
String get avatar => 'Фото профиля';
@override
String get avatarHint => 'Нажмите для обновления';
@override
String get avatarUpdateError => 'Не удалось обновить фото профиля';
@override
String get settings => 'Настройки';
@override
String get notSet => 'не задано';
@override
String get search => 'Поиск...';
@override
String get ok => 'Ок';
@override
String get cancel => 'Отмена';
@override
String get confirm => 'Подтвердить';
@override
String get back => 'Назад';
@override
String get operationfryTitle => 'История операций';
@override
String get filters => 'Фильтры';
@override
String get period => 'Период';
@override
String get selectPeriod => 'Выберите период';
@override
String get apply => 'Применить';
@override
String status(String status) {
return '$status';
}
@override
String get operationStatusSuccessful => 'Успешно';
@override
String get operationStatusPending => 'В ожидании';
@override
String get operationStatusUnsuccessful => 'Неуспешно';
@override
String get statusColumn => 'Статус';
@override
String get fileNameColumn => 'Имя файла';
@override
String get amountColumn => 'Сумма';
@override
String get toAmountColumn => 'На сумму';
@override
String get payIdColumn => 'Pay ID';
@override
String get cardNumberColumn => 'Номер карты';
@override
String get nameColumn => 'Имя';
@override
String get dateColumn => 'Дата';
@override
String get commentColumn => 'Комментарий';
@override
String get paymentConfigTitle => 'Куда получать деньги';
@override
String get paymentConfigSubtitle =>
'Добавьте несколько методов и выберите основной.';
@override
String get addPaymentMethod => 'Добавить способ оплаты';
@override
String get makeMain => 'Сделать основным';
@override
String get advanced => 'Дополнительно';
@override
String get fallbackExplanation =>
'Если основной метод недоступен, мы попробуем следующий включенный метод в списке.';
@override
String get delete => 'Удалить';
@override
String get deletePaymentConfirmation =>
'Вы уверены, что хотите удалить этот способ оплаты?';
@override
String get edit => 'Редактировать';
@override
String get moreActions => 'Еще действия';
@override
String get noPayouts => 'Нет выплат';
@override
String get enterBankName => 'Введите название банка';
@override
String get paymentType => 'Тип способа оплаты';
@override
String get selectPaymentType => 'Пожалуйста, выберите тип способа оплаты';
@override
String get paymentTypeCard => 'Кредитная карта';
@override
String get paymentTypeBankAccount => 'Российский банковский счет';
@override
String get paymentTypeIban => 'IBAN';
@override
String get paymentTypeWallet => 'Кошелек';
@override
String get cardNumber => 'Номер карты';
@override
String get enterCardNumber => 'Введите номер карты';
@override
String get cardholderName => 'Имя держателя карты';
@override
String get iban => 'IBAN';
@override
String get enterIban => 'Введите IBAN';
@override
String get bic => 'BIC';
@override
String get bankName => 'Название банка';
@override
String get accountHolder => 'Владелец счета';
@override
String get enterAccountHolder => 'Введите владельца счета';
@override
String get enterBic => 'Введите BIC';
@override
String get walletId => 'ID кошелька';
@override
String get enterWalletId => 'Введите ID кошелька';
@override
String get recipients => 'Получатели';
@override
String get recipientName => 'Имя получателя';
@override
String get enterRecipientName => 'Введите имя получателя';
@override
String get inn => 'ИНН';
@override
String get enterInn => 'Введите ИНН';
@override
String get kpp => 'КПП';
@override
String get enterKpp => 'Введите КПП';
@override
String get accountNumber => 'Номер счета';
@override
String get enterAccountNumber => 'Введите номер счета';
@override
String get correspondentAccount => 'Корреспондентский счет';
@override
String get enterCorrespondentAccount => 'Введите корреспондентский счет';
@override
String get bik => 'БИК';
@override
String get enterBik => 'Введите БИК';
@override
String get add => 'Добавить';
@override
String get expiryDate => 'Срок действия (ММ/ГГ)';
@override
String get firstName => 'Имя';
@override
String get enterFirstName => 'Введите имя';
@override
String get lastName => 'Фамилия';
@override
String get enterLastName => 'Введите фамилию';
@override
String get sendSingle => 'Отправить одну транзакцию';
@override
String get sendMultiple => 'Отправить несколько транзакций';
@override
String get addFunds => 'Пополнить счет';
@override
String get close => 'Закрыть';
@override
String get multiplePayout => 'Множественная выплата';
@override
String get howItWorks => 'Как это работает?';
@override
String get exampleTitle => 'Формат файла и образец';
@override
String get downloadSampleCSV => 'Скачать sample.csv';
@override
String get tokenColumn => 'Токен (обязательно)';
@override
String get currency => 'Валюта';
@override
String get amount => 'Сумма';
@override
String get comment => 'Комментарий';
@override
String get uploadCSV => 'Загрузите ваш CSV';
@override
String get upload => 'Загрузить';
@override
String get hintUpload => 'Поддерживаемый формат: .CSV · Макс. размер 1 МБ';
@override
String get uploadHistory => 'История загрузок';
@override
String get payout => 'Выплата';
@override
String get sendTo => 'Отправить выплату';
@override
String get send => 'Отправить выплату';
@override
String get recipientPaysFee => 'Получатель оплачивает комиссию';
@override
String sentAmount(String amount) {
return 'Отправленная сумма: \$$amount';
}
@override
String fee(String fee) {
return 'Комиссия: \$$fee';
}
@override
String recipientWillReceive(String amount) {
return 'Получатель получит: \$$amount';
}
@override
String total(String total) {
return 'Итого: \$$total';
}
@override
String get hideDetails => 'Скрыть детали';
@override
String get showDetails => 'Показать детали';
@override
String get whereGetMoney => 'Источник средств для списания';
@override
String get details => 'Детали';
@override
String get addRecipient => 'Добавить получателя';
@override
String get editRecipient => 'Редактировать получателя';
@override
String get saveRecipient => 'Сохранить получателя';
@override
String get choosePaymentMethod => 'Способы оплаты (выберите хотя бы 1)';
@override
String get recipientFormRule =>
'Получатель должен иметь хотя бы один способ оплаты';
@override
String get allStatus => 'Все';
@override
String get readyStatus => 'Готов';
@override
String get registeredStatus => 'Зарегистрирован';
@override
String get notRegisteredStatus => 'Не зарегистрирован';
@override
String get noRecipientSelected => 'Получатель не выбран';
@override
String get companyName => 'Name of your company';
@override
String get companynameRequired => 'Company name required';
@override
String get errorSignUp => 'Error occured while signing up, try again later';
@override
String get companyDescription => 'Company Description';
@override
String get companyDescriptionHint =>
'Describe any of the fields of the Company\'s business';
@override
String get optional => 'optional';
}

View File

@@ -431,5 +431,7 @@
"errorSignUp": "Error occured while signing up, try again later",
"companyDescription": "Company Description",
"companyDescriptionHint": "Describe any of the fields of the Company's business",
"optional": "optional"
"optional": "optional",
"ownerRole": "Organization Owner",
"ownerRoleDescription": "This role is granted to the organizations creator, providing full administrative privileges"
}

View File

@@ -422,5 +422,8 @@
"registeredStatus": "Зарегистрирован",
"notRegisteredStatus": "Не зарегистрирован",
"noRecipientSelected": "Получатель не выбран"
"noRecipientSelected": "Получатель не выбран",
"ownerRole": "Владелец организации",
"ownerRoleDescription": "Эта роль предоставляется создателю организации и даёт ему полные административные права"
}

View File

@@ -11,7 +11,6 @@ import 'package:pshared/config/constants.dart';
import 'package:pshared/provider/account.dart';
import 'package:pshared/provider/locale.dart';
import 'package:pshared/provider/organizations.dart';
import 'package:pshared/provider/pfe/provider.dart';
import 'package:pweb/app/app.dart';
import 'package:pweb/app/timeago.dart';
@@ -26,7 +25,6 @@ import 'package:pweb/providers/upload_history.dart';
import 'package:pweb/providers/wallets.dart';
import 'package:pweb/providers/wallet_transactions.dart';
import 'package:pweb/services/amplitude.dart';
import 'package:pweb/services/auth.dart';
import 'package:pweb/services/operations.dart';
import 'package:pweb/services/payments/payment_methods.dart';
import 'package:pweb/services/payments/upload_history.dart';
@@ -56,19 +54,18 @@ void main() async {
runApp(
MultiProvider(
providers: [
Provider<AuthenticationService>(
create: (_) => AuthenticationService(),
),
ChangeNotifierProxyProvider<AuthenticationService, TwoFactorProvider>(
create: (context) => TwoFactorProvider(
context.read<AuthenticationService>(),
),
update: (context, authService, previous) => TwoFactorProvider(authService),
),
ChangeNotifierProvider(create: (_) => LocaleProvider(null)),
ChangeNotifierProvider(create: (_) => AccountProvider()),
ChangeNotifierProxyProvider<AccountProvider, TwoFactorProvider>(
create: (context) => TwoFactorProvider(
accountProvider: context.read<AccountProvider>(),
),
update: (context, accountProvider, previous) => TwoFactorProvider(
accountProvider: accountProvider,
),
),
ChangeNotifierProvider(create: (_) => OrganizationsProvider()),
ChangeNotifierProvider(create: (_) => PfeProvider()),
ChangeNotifierProvider(create: (_) => AccountProvider()),
ChangeNotifierProvider(create: (_) => CarouselIndexProvider()),
ChangeNotifierProvider(

View File

@@ -1,6 +1,9 @@
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pweb/generated/i18n/app_localizations.dart';
import 'package:pweb/providers/two_factor.dart';
class ResendCodeButton extends StatelessWidget {
@@ -12,9 +15,7 @@ class ResendCodeButton extends StatelessWidget {
final localizations = AppLocalizations.of(context)!;
return TextButton(
onPressed: () {
// TODO: Add resend logic
},
onPressed: () => context.read<TwoFactorProvider>().resendCode(),
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
minimumSize: const Size(0, 0),
@@ -28,4 +29,4 @@ class ResendCodeButton extends StatelessWidget {
child: Text(localizations.twoFactorResend),
);
}
}
}

View File

@@ -2,7 +2,8 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:pshared/provider/pfe/provider.dart';
import 'package:pshared/provider/account.dart';
import 'package:pshared/provider/locale.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/pages/login/buttons.dart';
@@ -34,17 +35,22 @@ class _LoginFormState extends State<LoginForm> {
final ValueNotifier<bool> _isPasswordAcceptable = ValueNotifier<bool>(false);
Future<String?> _login(BuildContext context, VoidCallback onLogin, void Function(Object e) onError) async {
final pfeProvider = Provider.of<PfeProvider>(context, listen: false);
final provider = Provider.of<AccountProvider>(context, listen: false);
try {
// final account = await pfeProvider.login(
// email: _usernameController.text,
// password: _passwordController.text,
// );
onLogin();
final outcome = await provider.login(
email: _usernameController.text,
password: _passwordController.text,
locale: context.read<LocaleProvider>().locale.languageCode,
);
if (outcome.isPending) {
navigateAndReplace(context, Pages.sfactor);
} else {
onLogin();
}
return 'ok';
} catch (e) {
onError(pfeProvider.error == null ? e : pfeProvider.error!);
onError(provider.error ?? e);
}
return null;
}
@@ -89,7 +95,7 @@ class _LoginFormState extends State<LoginForm> {
onSignUp: () => navigate(context, Pages.signup),
login: () => _login(
context,
() => navigateAndReplace(context, Pages.sfactor),
() => navigateAndReplace(context, Pages.dashboard),
(e) => postNotifyUserOfErrorX(
context: context,
errorSituation: AppLocalizations.of(context)!.errorLogin,

View File

@@ -1,10 +1,15 @@
import 'package:flutter/material.dart';
import 'package:flutter_timezone/flutter_timezone.dart';
import 'package:go_router/go_router.dart';
import 'package:provider/provider.dart';
import 'package:pshared/provider/pfe/provider.dart';
import 'package:pshared/api/requests/login_data.dart';
import 'package:pshared/models/describable.dart';
import 'package:pshared/provider/account.dart';
import 'package:pshared/provider/locale.dart';
import 'package:pweb/app/router/pages.dart';
import 'package:pweb/pages/signup/form/content.dart';
@@ -31,7 +36,7 @@ class SignUpFormState extends State<SignUpForm> {
VoidCallback onSignUp,
void Function(Object e) onError,
) async {
final pfeProvider = Provider.of<PfeProvider>(context, listen: false);
final provider = Provider.of<AccountProvider>(context, listen: false);
setState(() {
_autoValidateMode = true;
@@ -42,20 +47,34 @@ class SignUpFormState extends State<SignUpForm> {
}
try {
// final account = await pfeProvider.signUp(
// companyName: controllers.companyName.text.trim(),
// description: controllers.description.text.trim().isEmpty
// ? null
// : controllers.description.text.trim(),
// firstName: controllers.firstName.text.trim(),
// lastName: controllers.lastName.text.trim(),
// email: controllers.email.text.trim(),
// password: controllers.password.text,
// );
final orgDescription = controllers.description.text.trim();
final locs = AppLocalizations.of(context)!;
final locale = context.read<LocaleProvider>().locale;
final timezone = await FlutterTimezone.getLocalTimezone(locale.toString());
await provider.signup(
account: AccountData.build(
login: LoginData.build(
login: controllers.email.text.trim(),
password: controllers.password.text,
locale: locale.toLanguageTag(),
),
name: controllers.password.text,
lastName: controllers.lastName.text.trim(),
),
organization: newDescribable(
name: controllers.companyName.text.trim(),
description: orgDescription.isEmpty ? null : orgDescription,
),
timezone: timezone.identifier,
ownerRole: newDescribable(
name: locs.ownerRole,
description: locs.ownerRoleDescription,
),
);
onSignUp();
return 'ok';
} catch (e) {
onError(pfeProvider.error ?? e);
onError(provider.error ?? e);
}
return null;
}

View File

@@ -1,38 +1,69 @@
import 'package:flutter/material.dart';
import 'package:logging/logging.dart';
import 'package:pweb/services/auth.dart';
import 'package:pshared/models/auth/pending_login.dart';
import 'package:pshared/provider/account.dart';
import 'package:pshared/service/account.dart';
class TwoFactorProvider extends ChangeNotifier {
final AuthenticationService _authService;
static final _logger = Logger('provider.two_factor');
final AccountProvider _accountProvider;
TwoFactorProvider(this._authService);
TwoFactorProvider({required AccountProvider accountProvider}) : _accountProvider = accountProvider;
bool _isSubmitting = false;
bool _hasError = false;
bool _verificationSuccess = false;
String? _errorMessage;
bool get isSubmitting => _isSubmitting;
bool get hasError => _hasError;
bool get verificationSuccess => _verificationSuccess;
String? get errorMessage => _errorMessage;
PendingLogin? get pendingLogin => _accountProvider.pendingLogin;
Future<void> submitCode(String code) async {
_isSubmitting = true;
_hasError = false;
_errorMessage = null;
_verificationSuccess = false;
notifyListeners();
try {
final success = await _authService.verifyTwoFactorCode(code);
if (success) {
_verificationSuccess = true;
final pending = _accountProvider.pendingLogin;
if (pending == null) {
throw Exception('No pending login available');
}
final account = await AccountService.confirmLoginCode(
pending: pending,
code: code,
);
_accountProvider.completePendingLogin(account);
_verificationSuccess = true;
} catch (e) {
_hasError = true;
_errorMessage = e.toString();
_logger.warning('Failed to verify code', e);
} finally {
_isSubmitting = false;
notifyListeners();
}
}
}
Future<void> resendCode() async {
final pending = _accountProvider.pendingLogin;
if (pending == null) {
_logger.warning('No pending login to resend code for');
return;
}
try {
await AccountService.resendLoginCode(pending);
} catch (e) {
_logger.warning('Failed to resend login code', e);
_hasError = true;
_errorMessage = e.toString();
notifyListeners();
}
}
}

View File

@@ -1,12 +0,0 @@
class AuthenticationService {
Future<bool> verifyTwoFactorCode(String code) async {
await Future.delayed(const Duration(seconds: 2));
if (code == '000000') {
return true;
} else {
throw Exception('Wrong Code'); //TODO Localize
}
}
}