From ddd32a690bd13b1eb1aef1356a1d59fd64e254bf Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 8 Mar 2024 14:09:31 -0300 Subject: demobank => bank --- packages/bank-ui/.eslintrc.cjs | 28 + packages/bank-ui/.gitignore | 4 + packages/bank-ui/Makefile | 37 + packages/bank-ui/README.md | 24 + packages/bank-ui/TODO | 49 + packages/bank-ui/build.mjs | 28 + packages/bank-ui/contrib/po2ts | 42 + packages/bank-ui/copyleft-header.js | 15 + packages/bank-ui/dev.mjs | 41 + packages/bank-ui/package.json | 52 + packages/bank-ui/postcss.config.js | 6 + packages/bank-ui/src/Routing.tsx | 604 ++++ packages/bank-ui/src/app.tsx | 137 + packages/bank-ui/src/assets/empty.png | Bin 0 -> 2785 bytes packages/bank-ui/src/assets/example/id1.jpg | Bin 0 -> 103558 bytes packages/bank-ui/src/assets/favicon.ico | Bin 0 -> 15086 bytes .../src/assets/icons/android-chrome-192x192.png | Bin 0 -> 14058 bytes .../src/assets/icons/android-chrome-512x512.png | Bin 0 -> 51484 bytes .../bank-ui/src/assets/icons/apple-touch-icon.png | Bin 0 -> 12746 bytes .../bank-ui/src/assets/icons/favicon-16x16.png | Bin 0 -> 626 bytes .../bank-ui/src/assets/icons/favicon-32x32.png | Bin 0 -> 1487 bytes packages/bank-ui/src/assets/icons/languageicon.svg | 48 + .../bank-ui/src/assets/icons/mstile-150x150.png | Bin 0 -> 9050 bytes packages/bank-ui/src/assets/logo-2021.svg | 9 + packages/bank-ui/src/assets/logo-white.svg | 45 + packages/bank-ui/src/assets/logo.jpeg | Bin 0 -> 39336 bytes packages/bank-ui/src/components/Cashouts/index.ts | 86 + packages/bank-ui/src/components/Cashouts/state.ts | 51 + .../bank-ui/src/components/Cashouts/stories.tsx | 29 + packages/bank-ui/src/components/Cashouts/test.ts | 68 + packages/bank-ui/src/components/Cashouts/views.tsx | 217 ++ .../src/components/EmptyComponentExample/index.ts | 56 + .../src/components/EmptyComponentExample/state.ts | 25 + .../components/EmptyComponentExample/stories.tsx | 29 + .../src/components/EmptyComponentExample/test.ts | 28 + .../src/components/EmptyComponentExample/views.tsx | 25 + .../src/components/ErrorLoadingWithDebug.tsx | 24 + packages/bank-ui/src/components/QR.tsx | 51 + packages/bank-ui/src/components/Time.tsx | 71 + .../bank-ui/src/components/Transactions/index.ts | 80 + .../bank-ui/src/components/Transactions/state.ts | 80 + .../src/components/Transactions/stories.tsx | 44 + .../bank-ui/src/components/Transactions/test.ts | 202 ++ .../bank-ui/src/components/Transactions/views.tsx | 243 ++ packages/bank-ui/src/components/index.examples.ts | 17 + packages/bank-ui/src/context/config.ts | 263 ++ packages/bank-ui/src/context/navigation.ts | 92 + packages/bank-ui/src/context/settings.ts | 44 + packages/bank-ui/src/context/wallet-integration.ts | 83 + packages/bank-ui/src/declaration.d.ts | 35 + packages/bank-ui/src/hooks/account.ts | 294 ++ packages/bank-ui/src/hooks/bank-state.ts | 188 ++ packages/bank-ui/src/hooks/form.ts | 100 + packages/bank-ui/src/hooks/preferences.ts | 112 + packages/bank-ui/src/hooks/regional.ts | 484 ++++ packages/bank-ui/src/hooks/session.ts | 131 + packages/bank-ui/src/i18n/bank.pot | 1740 ++++++++++++ packages/bank-ui/src/i18n/de.po | 1778 ++++++++++++ packages/bank-ui/src/i18n/en.po | 1784 ++++++++++++ packages/bank-ui/src/i18n/es.po | 2063 ++++++++++++++ packages/bank-ui/src/i18n/fr.po | 1752 ++++++++++++ packages/bank-ui/src/i18n/it.po | 1843 +++++++++++++ packages/bank-ui/src/i18n/poheader | 26 + packages/bank-ui/src/i18n/strings.ts | 2295 ++++++++++++++++ packages/bank-ui/src/i18n/uk.po | 1743 ++++++++++++ packages/bank-ui/src/index.html | 41 + packages/bank-ui/src/index.tsx | 27 + packages/bank-ui/src/manifest.json | 21 + packages/bank-ui/src/pages/AccountPage/index.ts | 134 + packages/bank-ui/src/pages/AccountPage/state.ts | 117 + packages/bank-ui/src/pages/AccountPage/stories.tsx | 29 + packages/bank-ui/src/pages/AccountPage/test.ts | 31 + packages/bank-ui/src/pages/AccountPage/views.tsx | 144 + packages/bank-ui/src/pages/BankFrame.stories.tsx | 29 + packages/bank-ui/src/pages/BankFrame.tsx | 237 ++ packages/bank-ui/src/pages/LoginForm.tsx | 226 ++ packages/bank-ui/src/pages/OperationState/index.ts | 157 ++ packages/bank-ui/src/pages/OperationState/state.ts | 232 ++ .../bank-ui/src/pages/OperationState/stories.tsx | 29 + packages/bank-ui/src/pages/OperationState/test.ts | 31 + .../bank-ui/src/pages/OperationState/views.tsx | 440 +++ .../bank-ui/src/pages/PaymentOptions.stories.tsx | 35 + packages/bank-ui/src/pages/PaymentOptions.tsx | 237 ++ .../src/pages/PaytoWireTransferForm.stories.tsx | 35 + .../bank-ui/src/pages/PaytoWireTransferForm.tsx | 792 ++++++ packages/bank-ui/src/pages/ProfileNavigation.tsx | 202 ++ packages/bank-ui/src/pages/PublicHistoriesPage.tsx | 95 + .../bank-ui/src/pages/QrCodeSection.stories.tsx | 32 + packages/bank-ui/src/pages/QrCodeSection.tsx | 150 + packages/bank-ui/src/pages/RegistrationPage.tsx | 415 +++ packages/bank-ui/src/pages/SolveChallengePage.tsx | 716 +++++ packages/bank-ui/src/pages/WalletWithdrawForm.tsx | 366 +++ packages/bank-ui/src/pages/WireTransfer.tsx | 103 + .../src/pages/WithdrawalConfirmationQuestion.tsx | 355 +++ .../bank-ui/src/pages/WithdrawalOperationPage.tsx | 71 + packages/bank-ui/src/pages/WithdrawalQRCode.tsx | 310 +++ .../src/pages/account/CashoutListForAccount.tsx | 85 + .../src/pages/account/ShowAccountDetails.tsx | 244 ++ .../src/pages/account/UpdateAccountPassword.tsx | 301 ++ packages/bank-ui/src/pages/admin/AccountForm.tsx | 901 ++++++ packages/bank-ui/src/pages/admin/AccountList.tsx | 244 ++ packages/bank-ui/src/pages/admin/AdminHome.tsx | 541 ++++ .../bank-ui/src/pages/admin/CreateNewAccount.tsx | 204 ++ packages/bank-ui/src/pages/admin/DownloadStats.tsx | 585 ++++ packages/bank-ui/src/pages/admin/RemoveAccount.tsx | 267 ++ packages/bank-ui/src/pages/index.stories.tsx | 20 + .../src/pages/regional/ConversionConfig.tsx | 978 +++++++ .../bank-ui/src/pages/regional/CreateCashout.tsx | 809 ++++++ .../src/pages/regional/ShowCashoutDetails.tsx | 192 ++ packages/bank-ui/src/pages/rnd.ts | 2907 ++++++++++++++++++++ packages/bank-ui/src/route.ts | 130 + packages/bank-ui/src/scss/main.css | 3 + packages/bank-ui/src/settings.json | 11 + packages/bank-ui/src/settings.ts | 112 + packages/bank-ui/src/stories.test.ts | 84 + packages/bank-ui/src/stories.tsx | 41 + packages/bank-ui/src/utils.ts | 447 +++ packages/bank-ui/tailwind.config.js | 14 + packages/bank-ui/test.mjs | 32 + packages/bank-ui/tsconfig.json | 46 + packages/demobank-ui/.eslintrc.cjs | 28 - packages/demobank-ui/.gitignore | 4 - packages/demobank-ui/Makefile | 37 - packages/demobank-ui/README.md | 24 - packages/demobank-ui/TODO | 49 - packages/demobank-ui/build.mjs | 28 - packages/demobank-ui/contrib/po2ts | 42 - packages/demobank-ui/copyleft-header.js | 15 - packages/demobank-ui/dev.mjs | 41 - packages/demobank-ui/package.json | 52 - packages/demobank-ui/postcss.config.js | 6 - packages/demobank-ui/src/Routing.tsx | 604 ---- packages/demobank-ui/src/app.tsx | 137 - packages/demobank-ui/src/assets/empty.png | Bin 2785 -> 0 bytes packages/demobank-ui/src/assets/example/id1.jpg | Bin 103558 -> 0 bytes packages/demobank-ui/src/assets/favicon.ico | Bin 15086 -> 0 bytes .../src/assets/icons/android-chrome-192x192.png | Bin 14058 -> 0 bytes .../src/assets/icons/android-chrome-512x512.png | Bin 51484 -> 0 bytes .../src/assets/icons/apple-touch-icon.png | Bin 12746 -> 0 bytes .../demobank-ui/src/assets/icons/favicon-16x16.png | Bin 626 -> 0 bytes .../demobank-ui/src/assets/icons/favicon-32x32.png | Bin 1487 -> 0 bytes .../demobank-ui/src/assets/icons/languageicon.svg | 48 - .../src/assets/icons/mstile-150x150.png | Bin 9050 -> 0 bytes packages/demobank-ui/src/assets/logo-2021.svg | 9 - packages/demobank-ui/src/assets/logo-white.svg | 45 - packages/demobank-ui/src/assets/logo.jpeg | Bin 39336 -> 0 bytes .../demobank-ui/src/components/Cashouts/index.ts | 86 - .../demobank-ui/src/components/Cashouts/state.ts | 51 - .../src/components/Cashouts/stories.tsx | 29 - .../demobank-ui/src/components/Cashouts/test.ts | 68 - .../demobank-ui/src/components/Cashouts/views.tsx | 217 -- .../src/components/EmptyComponentExample/index.ts | 56 - .../src/components/EmptyComponentExample/state.ts | 25 - .../components/EmptyComponentExample/stories.tsx | 29 - .../src/components/EmptyComponentExample/test.ts | 28 - .../src/components/EmptyComponentExample/views.tsx | 25 - .../src/components/ErrorLoadingWithDebug.tsx | 24 - packages/demobank-ui/src/components/QR.tsx | 51 - packages/demobank-ui/src/components/Time.tsx | 71 - .../src/components/Transactions/index.ts | 80 - .../src/components/Transactions/state.ts | 80 - .../src/components/Transactions/stories.tsx | 44 - .../src/components/Transactions/test.ts | 202 -- .../src/components/Transactions/views.tsx | 243 -- .../demobank-ui/src/components/index.examples.ts | 17 - packages/demobank-ui/src/context/config.ts | 263 -- packages/demobank-ui/src/context/navigation.ts | 92 - packages/demobank-ui/src/context/settings.ts | 44 - .../demobank-ui/src/context/wallet-integration.ts | 83 - packages/demobank-ui/src/declaration.d.ts | 35 - packages/demobank-ui/src/hooks/account.ts | 294 -- packages/demobank-ui/src/hooks/bank-state.ts | 188 -- packages/demobank-ui/src/hooks/form.ts | 100 - packages/demobank-ui/src/hooks/preferences.ts | 112 - packages/demobank-ui/src/hooks/regional.ts | 484 ---- packages/demobank-ui/src/hooks/session.ts | 131 - packages/demobank-ui/src/i18n/bank.pot | 1740 ------------ packages/demobank-ui/src/i18n/de.po | 1778 ------------ packages/demobank-ui/src/i18n/en.po | 1784 ------------ packages/demobank-ui/src/i18n/es.po | 2063 -------------- packages/demobank-ui/src/i18n/fr.po | 1752 ------------ packages/demobank-ui/src/i18n/it.po | 1843 ------------- packages/demobank-ui/src/i18n/poheader | 26 - packages/demobank-ui/src/i18n/strings.ts | 2295 ---------------- packages/demobank-ui/src/i18n/uk.po | 1743 ------------ packages/demobank-ui/src/index.html | 41 - packages/demobank-ui/src/index.tsx | 27 - packages/demobank-ui/src/manifest.json | 21 - .../demobank-ui/src/pages/AccountPage/index.ts | 134 - .../demobank-ui/src/pages/AccountPage/state.ts | 117 - .../demobank-ui/src/pages/AccountPage/stories.tsx | 29 - packages/demobank-ui/src/pages/AccountPage/test.ts | 31 - .../demobank-ui/src/pages/AccountPage/views.tsx | 144 - .../demobank-ui/src/pages/BankFrame.stories.tsx | 29 - packages/demobank-ui/src/pages/BankFrame.tsx | 237 -- packages/demobank-ui/src/pages/LoginForm.tsx | 226 -- .../demobank-ui/src/pages/OperationState/index.ts | 157 -- .../demobank-ui/src/pages/OperationState/state.ts | 232 -- .../src/pages/OperationState/stories.tsx | 29 - .../demobank-ui/src/pages/OperationState/test.ts | 31 - .../demobank-ui/src/pages/OperationState/views.tsx | 440 --- .../src/pages/PaymentOptions.stories.tsx | 35 - packages/demobank-ui/src/pages/PaymentOptions.tsx | 237 -- .../src/pages/PaytoWireTransferForm.stories.tsx | 35 - .../src/pages/PaytoWireTransferForm.tsx | 792 ------ .../demobank-ui/src/pages/ProfileNavigation.tsx | 202 -- .../demobank-ui/src/pages/PublicHistoriesPage.tsx | 95 - .../src/pages/QrCodeSection.stories.tsx | 32 - packages/demobank-ui/src/pages/QrCodeSection.tsx | 150 - .../demobank-ui/src/pages/RegistrationPage.tsx | 415 --- .../demobank-ui/src/pages/SolveChallengePage.tsx | 716 ----- .../demobank-ui/src/pages/WalletWithdrawForm.tsx | 366 --- packages/demobank-ui/src/pages/WireTransfer.tsx | 103 - .../src/pages/WithdrawalConfirmationQuestion.tsx | 355 --- .../src/pages/WithdrawalOperationPage.tsx | 71 - .../demobank-ui/src/pages/WithdrawalQRCode.tsx | 310 --- .../src/pages/account/CashoutListForAccount.tsx | 85 - .../src/pages/account/ShowAccountDetails.tsx | 244 -- .../src/pages/account/UpdateAccountPassword.tsx | 301 -- .../demobank-ui/src/pages/admin/AccountForm.tsx | 901 ------ .../demobank-ui/src/pages/admin/AccountList.tsx | 244 -- packages/demobank-ui/src/pages/admin/AdminHome.tsx | 541 ---- .../src/pages/admin/CreateNewAccount.tsx | 204 -- .../demobank-ui/src/pages/admin/DownloadStats.tsx | 585 ---- .../demobank-ui/src/pages/admin/RemoveAccount.tsx | 267 -- packages/demobank-ui/src/pages/index.stories.tsx | 20 - .../src/pages/regional/ConversionConfig.tsx | 978 ------- .../src/pages/regional/CreateCashout.tsx | 809 ------ .../src/pages/regional/ShowCashoutDetails.tsx | 192 -- packages/demobank-ui/src/pages/rnd.ts | 2907 -------------------- packages/demobank-ui/src/route.ts | 130 - packages/demobank-ui/src/scss/main.css | 3 - packages/demobank-ui/src/settings.json | 11 - packages/demobank-ui/src/settings.ts | 112 - packages/demobank-ui/src/stories.test.ts | 84 - packages/demobank-ui/src/stories.tsx | 41 - packages/demobank-ui/src/utils.ts | 447 --- packages/demobank-ui/tailwind.config.js | 14 - packages/demobank-ui/test.mjs | 32 - packages/demobank-ui/tsconfig.json | 46 - 240 files changed, 34482 insertions(+), 34482 deletions(-) create mode 100644 packages/bank-ui/.eslintrc.cjs create mode 100644 packages/bank-ui/.gitignore create mode 100644 packages/bank-ui/Makefile create mode 100644 packages/bank-ui/README.md create mode 100644 packages/bank-ui/TODO create mode 100755 packages/bank-ui/build.mjs create mode 100755 packages/bank-ui/contrib/po2ts create mode 100644 packages/bank-ui/copyleft-header.js create mode 100755 packages/bank-ui/dev.mjs create mode 100644 packages/bank-ui/package.json create mode 100644 packages/bank-ui/postcss.config.js create mode 100644 packages/bank-ui/src/Routing.tsx create mode 100644 packages/bank-ui/src/app.tsx create mode 100644 packages/bank-ui/src/assets/empty.png create mode 100644 packages/bank-ui/src/assets/example/id1.jpg create mode 100644 packages/bank-ui/src/assets/favicon.ico create mode 100644 packages/bank-ui/src/assets/icons/android-chrome-192x192.png create mode 100644 packages/bank-ui/src/assets/icons/android-chrome-512x512.png create mode 100644 packages/bank-ui/src/assets/icons/apple-touch-icon.png create mode 100644 packages/bank-ui/src/assets/icons/favicon-16x16.png create mode 100644 packages/bank-ui/src/assets/icons/favicon-32x32.png create mode 100644 packages/bank-ui/src/assets/icons/languageicon.svg create mode 100644 packages/bank-ui/src/assets/icons/mstile-150x150.png create mode 100644 packages/bank-ui/src/assets/logo-2021.svg create mode 100644 packages/bank-ui/src/assets/logo-white.svg create mode 100644 packages/bank-ui/src/assets/logo.jpeg create mode 100644 packages/bank-ui/src/components/Cashouts/index.ts create mode 100644 packages/bank-ui/src/components/Cashouts/state.ts create mode 100644 packages/bank-ui/src/components/Cashouts/stories.tsx create mode 100644 packages/bank-ui/src/components/Cashouts/test.ts create mode 100644 packages/bank-ui/src/components/Cashouts/views.tsx create mode 100644 packages/bank-ui/src/components/EmptyComponentExample/index.ts create mode 100644 packages/bank-ui/src/components/EmptyComponentExample/state.ts create mode 100644 packages/bank-ui/src/components/EmptyComponentExample/stories.tsx create mode 100644 packages/bank-ui/src/components/EmptyComponentExample/test.ts create mode 100644 packages/bank-ui/src/components/EmptyComponentExample/views.tsx create mode 100644 packages/bank-ui/src/components/ErrorLoadingWithDebug.tsx create mode 100644 packages/bank-ui/src/components/QR.tsx create mode 100644 packages/bank-ui/src/components/Time.tsx create mode 100644 packages/bank-ui/src/components/Transactions/index.ts create mode 100644 packages/bank-ui/src/components/Transactions/state.ts create mode 100644 packages/bank-ui/src/components/Transactions/stories.tsx create mode 100644 packages/bank-ui/src/components/Transactions/test.ts create mode 100644 packages/bank-ui/src/components/Transactions/views.tsx create mode 100644 packages/bank-ui/src/components/index.examples.ts create mode 100644 packages/bank-ui/src/context/config.ts create mode 100644 packages/bank-ui/src/context/navigation.ts create mode 100644 packages/bank-ui/src/context/settings.ts create mode 100644 packages/bank-ui/src/context/wallet-integration.ts create mode 100644 packages/bank-ui/src/declaration.d.ts create mode 100644 packages/bank-ui/src/hooks/account.ts create mode 100644 packages/bank-ui/src/hooks/bank-state.ts create mode 100644 packages/bank-ui/src/hooks/form.ts create mode 100644 packages/bank-ui/src/hooks/preferences.ts create mode 100644 packages/bank-ui/src/hooks/regional.ts create mode 100644 packages/bank-ui/src/hooks/session.ts create mode 100644 packages/bank-ui/src/i18n/bank.pot create mode 100644 packages/bank-ui/src/i18n/de.po create mode 100644 packages/bank-ui/src/i18n/en.po create mode 100644 packages/bank-ui/src/i18n/es.po create mode 100644 packages/bank-ui/src/i18n/fr.po create mode 100644 packages/bank-ui/src/i18n/it.po create mode 100644 packages/bank-ui/src/i18n/poheader create mode 100644 packages/bank-ui/src/i18n/strings.ts create mode 100644 packages/bank-ui/src/i18n/uk.po create mode 100644 packages/bank-ui/src/index.html create mode 100644 packages/bank-ui/src/index.tsx create mode 100644 packages/bank-ui/src/manifest.json create mode 100644 packages/bank-ui/src/pages/AccountPage/index.ts create mode 100644 packages/bank-ui/src/pages/AccountPage/state.ts create mode 100644 packages/bank-ui/src/pages/AccountPage/stories.tsx create mode 100644 packages/bank-ui/src/pages/AccountPage/test.ts create mode 100644 packages/bank-ui/src/pages/AccountPage/views.tsx create mode 100644 packages/bank-ui/src/pages/BankFrame.stories.tsx create mode 100644 packages/bank-ui/src/pages/BankFrame.tsx create mode 100644 packages/bank-ui/src/pages/LoginForm.tsx create mode 100644 packages/bank-ui/src/pages/OperationState/index.ts create mode 100644 packages/bank-ui/src/pages/OperationState/state.ts create mode 100644 packages/bank-ui/src/pages/OperationState/stories.tsx create mode 100644 packages/bank-ui/src/pages/OperationState/test.ts create mode 100644 packages/bank-ui/src/pages/OperationState/views.tsx create mode 100644 packages/bank-ui/src/pages/PaymentOptions.stories.tsx create mode 100644 packages/bank-ui/src/pages/PaymentOptions.tsx create mode 100644 packages/bank-ui/src/pages/PaytoWireTransferForm.stories.tsx create mode 100644 packages/bank-ui/src/pages/PaytoWireTransferForm.tsx create mode 100644 packages/bank-ui/src/pages/ProfileNavigation.tsx create mode 100644 packages/bank-ui/src/pages/PublicHistoriesPage.tsx create mode 100644 packages/bank-ui/src/pages/QrCodeSection.stories.tsx create mode 100644 packages/bank-ui/src/pages/QrCodeSection.tsx create mode 100644 packages/bank-ui/src/pages/RegistrationPage.tsx create mode 100644 packages/bank-ui/src/pages/SolveChallengePage.tsx create mode 100644 packages/bank-ui/src/pages/WalletWithdrawForm.tsx create mode 100644 packages/bank-ui/src/pages/WireTransfer.tsx create mode 100644 packages/bank-ui/src/pages/WithdrawalConfirmationQuestion.tsx create mode 100644 packages/bank-ui/src/pages/WithdrawalOperationPage.tsx create mode 100644 packages/bank-ui/src/pages/WithdrawalQRCode.tsx create mode 100644 packages/bank-ui/src/pages/account/CashoutListForAccount.tsx create mode 100644 packages/bank-ui/src/pages/account/ShowAccountDetails.tsx create mode 100644 packages/bank-ui/src/pages/account/UpdateAccountPassword.tsx create mode 100644 packages/bank-ui/src/pages/admin/AccountForm.tsx create mode 100644 packages/bank-ui/src/pages/admin/AccountList.tsx create mode 100644 packages/bank-ui/src/pages/admin/AdminHome.tsx create mode 100644 packages/bank-ui/src/pages/admin/CreateNewAccount.tsx create mode 100644 packages/bank-ui/src/pages/admin/DownloadStats.tsx create mode 100644 packages/bank-ui/src/pages/admin/RemoveAccount.tsx create mode 100644 packages/bank-ui/src/pages/index.stories.tsx create mode 100644 packages/bank-ui/src/pages/regional/ConversionConfig.tsx create mode 100644 packages/bank-ui/src/pages/regional/CreateCashout.tsx create mode 100644 packages/bank-ui/src/pages/regional/ShowCashoutDetails.tsx create mode 100644 packages/bank-ui/src/pages/rnd.ts create mode 100644 packages/bank-ui/src/route.ts create mode 100644 packages/bank-ui/src/scss/main.css create mode 100644 packages/bank-ui/src/settings.json create mode 100644 packages/bank-ui/src/settings.ts create mode 100644 packages/bank-ui/src/stories.test.ts create mode 100644 packages/bank-ui/src/stories.tsx create mode 100644 packages/bank-ui/src/utils.ts create mode 100644 packages/bank-ui/tailwind.config.js create mode 100755 packages/bank-ui/test.mjs create mode 100644 packages/bank-ui/tsconfig.json delete mode 100644 packages/demobank-ui/.eslintrc.cjs delete mode 100644 packages/demobank-ui/.gitignore delete mode 100644 packages/demobank-ui/Makefile delete mode 100644 packages/demobank-ui/README.md delete mode 100644 packages/demobank-ui/TODO delete mode 100755 packages/demobank-ui/build.mjs delete mode 100755 packages/demobank-ui/contrib/po2ts delete mode 100644 packages/demobank-ui/copyleft-header.js delete mode 100755 packages/demobank-ui/dev.mjs delete mode 100644 packages/demobank-ui/package.json delete mode 100644 packages/demobank-ui/postcss.config.js delete mode 100644 packages/demobank-ui/src/Routing.tsx delete mode 100644 packages/demobank-ui/src/app.tsx delete mode 100644 packages/demobank-ui/src/assets/empty.png delete mode 100644 packages/demobank-ui/src/assets/example/id1.jpg delete mode 100644 packages/demobank-ui/src/assets/favicon.ico delete mode 100644 packages/demobank-ui/src/assets/icons/android-chrome-192x192.png delete mode 100644 packages/demobank-ui/src/assets/icons/android-chrome-512x512.png delete mode 100644 packages/demobank-ui/src/assets/icons/apple-touch-icon.png delete mode 100644 packages/demobank-ui/src/assets/icons/favicon-16x16.png delete mode 100644 packages/demobank-ui/src/assets/icons/favicon-32x32.png delete mode 100644 packages/demobank-ui/src/assets/icons/languageicon.svg delete mode 100644 packages/demobank-ui/src/assets/icons/mstile-150x150.png delete mode 100644 packages/demobank-ui/src/assets/logo-2021.svg delete mode 100644 packages/demobank-ui/src/assets/logo-white.svg delete mode 100644 packages/demobank-ui/src/assets/logo.jpeg delete mode 100644 packages/demobank-ui/src/components/Cashouts/index.ts delete mode 100644 packages/demobank-ui/src/components/Cashouts/state.ts delete mode 100644 packages/demobank-ui/src/components/Cashouts/stories.tsx delete mode 100644 packages/demobank-ui/src/components/Cashouts/test.ts delete mode 100644 packages/demobank-ui/src/components/Cashouts/views.tsx delete mode 100644 packages/demobank-ui/src/components/EmptyComponentExample/index.ts delete mode 100644 packages/demobank-ui/src/components/EmptyComponentExample/state.ts delete mode 100644 packages/demobank-ui/src/components/EmptyComponentExample/stories.tsx delete mode 100644 packages/demobank-ui/src/components/EmptyComponentExample/test.ts delete mode 100644 packages/demobank-ui/src/components/EmptyComponentExample/views.tsx delete mode 100644 packages/demobank-ui/src/components/ErrorLoadingWithDebug.tsx delete mode 100644 packages/demobank-ui/src/components/QR.tsx delete mode 100644 packages/demobank-ui/src/components/Time.tsx delete mode 100644 packages/demobank-ui/src/components/Transactions/index.ts delete mode 100644 packages/demobank-ui/src/components/Transactions/state.ts delete mode 100644 packages/demobank-ui/src/components/Transactions/stories.tsx delete mode 100644 packages/demobank-ui/src/components/Transactions/test.ts delete mode 100644 packages/demobank-ui/src/components/Transactions/views.tsx delete mode 100644 packages/demobank-ui/src/components/index.examples.ts delete mode 100644 packages/demobank-ui/src/context/config.ts delete mode 100644 packages/demobank-ui/src/context/navigation.ts delete mode 100644 packages/demobank-ui/src/context/settings.ts delete mode 100644 packages/demobank-ui/src/context/wallet-integration.ts delete mode 100644 packages/demobank-ui/src/declaration.d.ts delete mode 100644 packages/demobank-ui/src/hooks/account.ts delete mode 100644 packages/demobank-ui/src/hooks/bank-state.ts delete mode 100644 packages/demobank-ui/src/hooks/form.ts delete mode 100644 packages/demobank-ui/src/hooks/preferences.ts delete mode 100644 packages/demobank-ui/src/hooks/regional.ts delete mode 100644 packages/demobank-ui/src/hooks/session.ts delete mode 100644 packages/demobank-ui/src/i18n/bank.pot delete mode 100644 packages/demobank-ui/src/i18n/de.po delete mode 100644 packages/demobank-ui/src/i18n/en.po delete mode 100644 packages/demobank-ui/src/i18n/es.po delete mode 100644 packages/demobank-ui/src/i18n/fr.po delete mode 100644 packages/demobank-ui/src/i18n/it.po delete mode 100644 packages/demobank-ui/src/i18n/poheader delete mode 100644 packages/demobank-ui/src/i18n/strings.ts delete mode 100644 packages/demobank-ui/src/i18n/uk.po delete mode 100644 packages/demobank-ui/src/index.html delete mode 100644 packages/demobank-ui/src/index.tsx delete mode 100644 packages/demobank-ui/src/manifest.json delete mode 100644 packages/demobank-ui/src/pages/AccountPage/index.ts delete mode 100644 packages/demobank-ui/src/pages/AccountPage/state.ts delete mode 100644 packages/demobank-ui/src/pages/AccountPage/stories.tsx delete mode 100644 packages/demobank-ui/src/pages/AccountPage/test.ts delete mode 100644 packages/demobank-ui/src/pages/AccountPage/views.tsx delete mode 100644 packages/demobank-ui/src/pages/BankFrame.stories.tsx delete mode 100644 packages/demobank-ui/src/pages/BankFrame.tsx delete mode 100644 packages/demobank-ui/src/pages/LoginForm.tsx delete mode 100644 packages/demobank-ui/src/pages/OperationState/index.ts delete mode 100644 packages/demobank-ui/src/pages/OperationState/state.ts delete mode 100644 packages/demobank-ui/src/pages/OperationState/stories.tsx delete mode 100644 packages/demobank-ui/src/pages/OperationState/test.ts delete mode 100644 packages/demobank-ui/src/pages/OperationState/views.tsx delete mode 100644 packages/demobank-ui/src/pages/PaymentOptions.stories.tsx delete mode 100644 packages/demobank-ui/src/pages/PaymentOptions.tsx delete mode 100644 packages/demobank-ui/src/pages/PaytoWireTransferForm.stories.tsx delete mode 100644 packages/demobank-ui/src/pages/PaytoWireTransferForm.tsx delete mode 100644 packages/demobank-ui/src/pages/ProfileNavigation.tsx delete mode 100644 packages/demobank-ui/src/pages/PublicHistoriesPage.tsx delete mode 100644 packages/demobank-ui/src/pages/QrCodeSection.stories.tsx delete mode 100644 packages/demobank-ui/src/pages/QrCodeSection.tsx delete mode 100644 packages/demobank-ui/src/pages/RegistrationPage.tsx delete mode 100644 packages/demobank-ui/src/pages/SolveChallengePage.tsx delete mode 100644 packages/demobank-ui/src/pages/WalletWithdrawForm.tsx delete mode 100644 packages/demobank-ui/src/pages/WireTransfer.tsx delete mode 100644 packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx delete mode 100644 packages/demobank-ui/src/pages/WithdrawalOperationPage.tsx delete mode 100644 packages/demobank-ui/src/pages/WithdrawalQRCode.tsx delete mode 100644 packages/demobank-ui/src/pages/account/CashoutListForAccount.tsx delete mode 100644 packages/demobank-ui/src/pages/account/ShowAccountDetails.tsx delete mode 100644 packages/demobank-ui/src/pages/account/UpdateAccountPassword.tsx delete mode 100644 packages/demobank-ui/src/pages/admin/AccountForm.tsx delete mode 100644 packages/demobank-ui/src/pages/admin/AccountList.tsx delete mode 100644 packages/demobank-ui/src/pages/admin/AdminHome.tsx delete mode 100644 packages/demobank-ui/src/pages/admin/CreateNewAccount.tsx delete mode 100644 packages/demobank-ui/src/pages/admin/DownloadStats.tsx delete mode 100644 packages/demobank-ui/src/pages/admin/RemoveAccount.tsx delete mode 100644 packages/demobank-ui/src/pages/index.stories.tsx delete mode 100644 packages/demobank-ui/src/pages/regional/ConversionConfig.tsx delete mode 100644 packages/demobank-ui/src/pages/regional/CreateCashout.tsx delete mode 100644 packages/demobank-ui/src/pages/regional/ShowCashoutDetails.tsx delete mode 100644 packages/demobank-ui/src/pages/rnd.ts delete mode 100644 packages/demobank-ui/src/route.ts delete mode 100644 packages/demobank-ui/src/scss/main.css delete mode 100644 packages/demobank-ui/src/settings.json delete mode 100644 packages/demobank-ui/src/settings.ts delete mode 100644 packages/demobank-ui/src/stories.test.ts delete mode 100644 packages/demobank-ui/src/stories.tsx delete mode 100644 packages/demobank-ui/src/utils.ts delete mode 100644 packages/demobank-ui/tailwind.config.js delete mode 100755 packages/demobank-ui/test.mjs delete mode 100644 packages/demobank-ui/tsconfig.json (limited to 'packages') diff --git a/packages/bank-ui/.eslintrc.cjs b/packages/bank-ui/.eslintrc.cjs new file mode 100644 index 000000000..05618b499 --- /dev/null +++ b/packages/bank-ui/.eslintrc.cjs @@ -0,0 +1,28 @@ +module.exports = { + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react/recommended', + ], + parser: '@typescript-eslint/parser', + plugins: ['@typescript-eslint', 'header'], + root: true, + rules: { + "react/no-unknown-property": 0, + "react/no-unescaped-entities": 0, + "@typescript-eslint/no-namespace": 0, + "@typescript-eslint/no-unused-vars": [2,{argsIgnorePattern:"^_"}], + "header/header": [2,"copyleft-header.js"] + }, + parserOptions: { + ecmaVersion: 6, + sourceType: 'module', + jsx: true, + }, + settings: { + react: { + version: "18", + pragma: "h", + } + }, +}; diff --git a/packages/bank-ui/.gitignore b/packages/bank-ui/.gitignore new file mode 100644 index 000000000..30cb2774c --- /dev/null +++ b/packages/bank-ui/.gitignore @@ -0,0 +1,4 @@ +node_modules +/build +/*.log +/demobank-ui-settings.js diff --git a/packages/bank-ui/Makefile b/packages/bank-ui/Makefile new file mode 100644 index 000000000..036e6fd3e --- /dev/null +++ b/packages/bank-ui/Makefile @@ -0,0 +1,37 @@ +# This Makefile has been placed in the public domain + +ifeq ($(TOPLEVEL), yes) + $(info top-level build) + -include ../../.config.mk + override DESTDIR := $(TOP_DESTDIR) +else + $(info package-level build) + -include ../../.config.mk + -include .config.mk +endif + +$(info prefix is $(prefix)) + +.PHONY: all +all: + @echo run \'make install\' to install + +spa_dir=$(DESTDIR)$(prefix)/share/taler/bank-ui + +.PHONY: deps +deps: + pnpm install --frozen-lockfile --filter @gnu-taler/bank-ui... + pnpm run --filter @gnu-taler/bank-ui... compile + pnpm run check + pnpm run build + +.PHONY: install-nodeps +install-nodeps: + install -d $(spa_dir) + install ./dist/prod/* $(spa_dir) + +.PHONY: install +install: + $(MAKE) deps + $(MAKE) install-nodeps + diff --git a/packages/bank-ui/README.md b/packages/bank-ui/README.md new file mode 100644 index 000000000..3d2e991ff --- /dev/null +++ b/packages/bank-ui/README.md @@ -0,0 +1,24 @@ +# Taler Demobank UI + +Web-based user interface for the libeufin bank ui. + +## CLI Commands + +- `./dev.mjs` development setup. Will listen in :8080 and reload every time a file is save. +- `./build.mjs` build for production. +- `./test.mjs` build and run unit test + +## Testing + +By default, the bank-ui will expect the backend to be in `window.origin` but that can be overridden using the `settings.json` file or by session in the localStorage. + +``` +localStorage.setItem("bank-base-url", OTHER_URL); +``` + +## Customizing Per-Deployment Settings + +To customize per-deployment settings, make sure that the +`settings.json` file is served alongside the UI. + +For more information about the values check the file `settings.ts` in the src folder. diff --git a/packages/bank-ui/TODO b/packages/bank-ui/TODO new file mode 100644 index 000000000..cc578cce0 --- /dev/null +++ b/packages/bank-ui/TODO @@ -0,0 +1,49 @@ +Urgent TODOs: + +- General: + + - not only Nora dark-theme, but default light! (CSS) + - DONE: auto-focus on input fields is not working well + - DONE: buttons should be visibly insensitive + as long as required input fields are not + working + - DONE: next required invalid/missing input field is + not properly highlighted in red + - Logout button needs more padding to the right (CSS) + +- Error bar: + - DONE: hows JSON, should only show good error message + and numeric code, not JSON syntax + - should auto-hide after next action, no need for + "clear"! + - need variant "status bar" in green (or blue) + which shows status of last operation + +* H1-Titles: + - Center more (currently way on the left) (CSS) + +- Assets: + + - Numeric amount needs to be shown MUCH bigger (CSS) + - Center more? (CSS) + +- Payments: + + - Amount to withdraw currently shown in white-on-white (CSS) + - Big frame drawn around notebook-tabs is not nice (CSS) + - Center more? (CSS) + - "Wire to bank account" + - maybe split two types (payto and IBAN) into + two tabs? + - currently cannot switch back from payto to IBAN + +- Withdraw: + + - Should use new 'status' bar at the end, instead + of extra dialog with "close" button + - ditto for bank-wire-transfer final stage + +- Footer: + - overlaps with transaction history or other + content, needs to consistently show at the + end! => change rendering logic!? (CSS?) diff --git a/packages/bank-ui/build.mjs b/packages/bank-ui/build.mjs new file mode 100755 index 000000000..04a6f646b --- /dev/null +++ b/packages/bank-ui/build.mjs @@ -0,0 +1,28 @@ +#!/usr/bin/env node +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { build } from "@gnu-taler/web-util/build"; + +await build({ + type: "production", + source: { + js: ["src/index.tsx"], + assets: [{ base: "src", files: ["src/index.html"] }], + }, + destination: "./dist/prod", + css: "postcss", +}); diff --git a/packages/bank-ui/contrib/po2ts b/packages/bank-ui/contrib/po2ts new file mode 100755 index 000000000..a135da61b --- /dev/null +++ b/packages/bank-ui/contrib/po2ts @@ -0,0 +1,42 @@ +#!/usr/bin/env node +/* + This file is part of GNU Taler + (C) 2020 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * Convert a .po file into a JavaScript / TypeScript expression. + */ + +const po2json = require("po2json"); + +const filename = process.argv[2]; + +if (!filename) { + console.error("error: missing filename"); + process.exit(1); +} + +const m = filename.match(/([a-zA-Z0-9-_]+).po/); + +if (!m) { + console.error("error: unexpected filename (expected .po)"); + process.exit(1); +} + +const lang = m[1]; +const pojson = po2json.parseFileSync(filename, { format: "jed1.x", fuzzy: true }); +const s = + "strings['" + lang + "'] = " + JSON.stringify(pojson, null, " ") + ";\n"; +console.log(s); diff --git a/packages/bank-ui/copyleft-header.js b/packages/bank-ui/copyleft-header.js new file mode 100644 index 000000000..7fa276bea --- /dev/null +++ b/packages/bank-ui/copyleft-header.js @@ -0,0 +1,15 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ diff --git a/packages/bank-ui/dev.mjs b/packages/bank-ui/dev.mjs new file mode 100755 index 000000000..7b4f719ae --- /dev/null +++ b/packages/bank-ui/dev.mjs @@ -0,0 +1,41 @@ +#!/usr/bin/env node +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { serve } from "@gnu-taler/web-util/node"; +import { initializeDev } from "@gnu-taler/web-util/build"; + +const devEntryPoints = ["src/stories.tsx", "src/index.tsx"]; + +const build = initializeDev({ + type: "development", + source: { + js: devEntryPoints, + assets: [{ base: "src", files: ["src/index.html", "src/settings.json"] }], + }, + destination: "./dist/dev", + public: "/app", + css: "postcss", +}); + +await build(); + +serve({ + folder: "./dist/dev", + port: 8080, + source: "./src", + onSourceUpdate: build, +}); diff --git a/packages/bank-ui/package.json b/packages/bank-ui/package.json new file mode 100644 index 000000000..dd5589fe2 --- /dev/null +++ b/packages/bank-ui/package.json @@ -0,0 +1,52 @@ +{ + "private": true, + "name": "@gnu-taler/bank-ui", + "version": "0.9.3-dev.29", + "license": "AGPL-3.0-OR-LATER", + "type": "module", + "scripts": { + "build": "./build.mjs", + "check": "tsc", + "clean": "rm -rf dist lib tsconfig.tsbuildinfo", + "compile": "tsc && ./build.mjs", + "test": "./test.mjs && mocha --require source-map-support/register 'dist/test/**/*.test.js' 'dist/test/**/test.js'", + "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'", + "typedoc": "typedoc --out dist/typedoc ./src/", + "i18n:strings": "pogen extract && pogen merge", + "i18n:translations": "pogen emit", + "pretty": "prettier --write src" + }, + "dependencies": { + "@gnu-taler/taler-util": "workspace:*", + "@gnu-taler/web-util": "workspace:*", + "date-fns": "2.29.3", + "jed": "1.1.1", + "preact": "10.11.3", + "qrcode-generator": "^1.4.4", + "swr": "2.0.3" + }, + "devDependencies": { + "eslint": "^8.56.0", + "@gnu-taler/pogen": "^0.0.5", + "@tailwindcss/forms": "^0.5.3", + "@tailwindcss/typography": "^0.5.9", + "@types/chai": "^4.3.0", + "@types/history": "^4.7.8", + "@types/mocha": "^10.0.1", + "@types/node": "^18.11.17", + "@typescript-eslint/eslint-plugin": "^6.19.0", + "@typescript-eslint/parser": "^6.19.0", + "autoprefixer": "^10.4.14", + "chai": "^4.3.6", + "esbuild": "^0.19.9", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-react": "^7.33.2", + "mocha": "9.2.0", + "po2json": "^0.4.5", + "tailwindcss": "^3.3.2", + "typescript": "5.3.3" + }, + "pogen": { + "domain": "bank" + } +} diff --git a/packages/bank-ui/postcss.config.js b/packages/bank-ui/postcss.config.js new file mode 100644 index 000000000..2e7af2b7f --- /dev/null +++ b/packages/bank-ui/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/packages/bank-ui/src/Routing.tsx b/packages/bank-ui/src/Routing.tsx new file mode 100644 index 000000000..f9b388ed1 --- /dev/null +++ b/packages/bank-ui/src/Routing.tsx @@ -0,0 +1,604 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + LocalNotificationBanner, + useLocalNotification, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; +import { Fragment, VNode, h } from "preact"; + +import { + AccessToken, + HttpStatusCode, + TranslatedString, + assertUnreachable, +} from "@gnu-taler/taler-util"; +import { useEffect } from "preact/hooks"; +import { useBankCoreApiContext } from "./context/config.js"; +import { useNavigationContext } from "./context/navigation.js"; +import { useSettingsContext } from "./context/settings.js"; +import { useSessionState } from "./hooks/session.js"; +import { AccountPage } from "./pages/AccountPage/index.js"; +import { BankFrame } from "./pages/BankFrame.js"; +import { LoginForm } from "./pages/LoginForm.js"; +import { PublicHistoriesPage } from "./pages/PublicHistoriesPage.js"; +import { RegistrationPage } from "./pages/RegistrationPage.js"; +import { SolveChallengePage } from "./pages/SolveChallengePage.js"; +import { WireTransfer } from "./pages/WireTransfer.js"; +import { WithdrawalOperationPage } from "./pages/WithdrawalOperationPage.js"; +import { CashoutListForAccount } from "./pages/account/CashoutListForAccount.js"; +import { ShowAccountDetails } from "./pages/account/ShowAccountDetails.js"; +import { UpdateAccountPassword } from "./pages/account/UpdateAccountPassword.js"; +import { AdminHome } from "./pages/admin/AdminHome.js"; +import { CreateNewAccount } from "./pages/admin/CreateNewAccount.js"; +import { DownloadStats } from "./pages/admin/DownloadStats.js"; +import { RemoveAccount } from "./pages/admin/RemoveAccount.js"; +import { ConversionConfig } from "./pages/regional/ConversionConfig.js"; +import { CreateCashout } from "./pages/regional/CreateCashout.js"; +import { ShowCashoutDetails } from "./pages/regional/ShowCashoutDetails.js"; +import { urlPattern, useCurrentLocation } from "./route.js"; + +export function Routing(): VNode { + const session = useSessionState(); + + if (session.state.status === "loggedIn") { + const { isUserAdministrator, username } = session.state; + return ( + + + + ); + } + return ( + + { + session.logIn({ username, token: token }); + }} + /> + + ); +} + +const publicPages = { + login: urlPattern(/\/login/, () => "#/login"), + register: urlPattern(/\/register/, () => "#/register"), + publicAccounts: urlPattern(/\/public-accounts/, () => "#/public-accounts"), + operationDetails: urlPattern<{ wopid: string }>( + /\/operation\/(?[a-zA-Z0-9]+)/, + ({ wopid }) => `#/operation/${wopid}`, + ), + solveSecondFactor: urlPattern(/\/2fa/, () => "#/2fa"), +}; + +function PublicRounting({ + onLoggedUser, +}: { + onLoggedUser: (username: string, token: AccessToken) => void; +}): VNode { + const settings = useSettingsContext(); + const { i18n } = useTranslationContext(); + const location = useCurrentLocation(publicPages); + const { navigateTo } = useNavigationContext(); + const { bank, authenticator } = useBankCoreApiContext(); + const [notification, notify, handleError] = useLocalNotification(); + + useEffect(() => { + if (location === undefined) { + navigateTo(publicPages.login.url({})); + } + }, [location]); + + if (location === undefined) { + return ; + } + + async function doAutomaticLogin(username: string, password: string) { + await handleError(async () => { + const resp = await authenticator(username) + .createAccessToken(password, { + scope: "readwrite", + duration: { d_us: "forever" }, + refreshable: true, + }); + if (resp.type === "ok") { + onLoggedUser(username, resp.body.access_token); + } else { + switch (resp.case) { + case HttpStatusCode.Unauthorized: + return notify({ + type: "error", + title: i18n.str`Wrong credentials for "${username}"`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.NotFound: + return notify({ + type: "error", + title: i18n.str`Account not found`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + default: + assertUnreachable(resp); + } + } + }); + } + + switch (location.name) { + case "login": { + return ( + +
+

{i18n.str`Welcome to ${settings.bankName}!`}

+
+ +
+ ); + } + case "publicAccounts": { + return ; + } + case "operationDetails": { + return ( + navigateTo(publicPages.login.url({}))} + routeClose={publicPages.login} + onAuthorizationRequired={() => + navigateTo(publicPages.solveSecondFactor.url({})) + } + /> + ); + } + case "register": { + return ( + + + + + ); + } + case "solveSecondFactor": { + return ( + navigateTo(publicPages.login.url({}))} + routeClose={publicPages.login} + /> + ); + } + default: + assertUnreachable(location); + } +} + +export const privatePages = { + homeChargeWallet: urlPattern( + /\/account\/charge-wallet/, + () => "#/account/charge-wallet", + ), + homeWireTransfer: urlPattern<{ + account?: string, + subject?: string, + amount?: string, + }>( + /\/account\/wire-transfer/, + () => "#/account/wire-transfer", + ), + home: urlPattern(/\/account/, () => "#/account"), + solveSecondFactor: urlPattern(/\/2fa/, () => "#/2fa"), + cashoutCreate: urlPattern(/\/new-cashout/, () => "#/new-cashout"), + cashoutDetails: urlPattern<{ cid: string }>( + /\/cashout\/(?[a-zA-Z0-9]+)/, + ({ cid }) => `#/cashout/${cid}`, + ), + wireTranserCreate: urlPattern<{ + account?: string, + subject?: string, + amount?: string, + }>( + /\/wire-transfer\/(?[a-zA-Z0-9]+)/, + ({ account }) => `#/wire-transfer/${account}`, + ), + publicAccountList: urlPattern(/\/public-accounts/, () => "#/public-accounts"), + statsDownload: urlPattern(/\/download-stats/, () => "#/download-stats"), + accountCreate: urlPattern(/\/new-account/, () => "#/new-account"), + myAccountDelete: urlPattern( + /\/delete-my-account/, + () => "#/delete-my-account", + ), + myAccountDetails: urlPattern(/\/my-profile/, () => "#/my-profile"), + myAccountPassword: urlPattern(/\/my-password/, () => "#/my-password"), + myAccountCashouts: urlPattern(/\/my-cashouts/, () => "#/my-cashouts"), + conversionConfig: urlPattern(/\/conversion/, () => "#/conversion"), + accountDetails: urlPattern<{ account: string }>( + /\/profile\/(?[a-zA-Z0-9_-]+)\/details/, + ({ account }) => `#/profile/${account}/details`, + ), + accountChangePassword: urlPattern<{ account: string }>( + /\/profile\/(?[a-zA-Z0-9_-]+)\/change-password/, + ({ account }) => `#/profile/${account}/change-password`, + ), + accountDelete: urlPattern<{ account: string }>( + /\/profile\/(?[a-zA-Z0-9_-]+)\/delete/, + ({ account }) => `#/profile/${account}/delete`, + ), + accountCashouts: urlPattern<{ account: string }>( + /\/profile\/(?[a-zA-Z0-9_-]+)\/cashouts/, + ({ account }) => `#/profile/${account}/cashouts`, + ), + startOperation: urlPattern<{ wopid: string }>( + /\/start-operation\/(?[a-zA-Z0-9-]+)/, + ({ wopid }) => `#/start-operation/${wopid}`, + ), + operationDetails: urlPattern<{ wopid: string }>( + /\/operation\/(?[a-zA-Z0-9-]+)/, + ({ wopid }) => `#/operation/${wopid}`, + ), +}; + +function PrivateRouting({ + username, + isAdmin, +}: { + username: string; + isAdmin: boolean; +}): VNode { + const { navigateTo } = useNavigationContext(); + const location = useCurrentLocation(privatePages); + useEffect(() => { + if (location === undefined) { + navigateTo(privatePages.home.url({})); + } + }, [location]); + + if (location === undefined) { + return ; + } + + switch (location.name) { + case "operationDetails": { + + return ( + navigateTo(privatePages.home.url({}))} + routeClose={privatePages.home} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + /> + ); + } + case "startOperation": { + + return ( + navigateTo(privatePages.home.url({}))} + routeClose={privatePages.home} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + /> + ); + } + case "solveSecondFactor": { + return ( + navigateTo(privatePages.home.url({}))} + routeClose={privatePages.home} + /> + ); + } + case "publicAccountList": { + return ; + } + case "statsDownload": { + return ; + } + case "accountCreate": { + return ( + navigateTo(privatePages.home.url({}))} + /> + ); + } + case "accountDetails": { + return ( + navigateTo(privatePages.home.url({}))} + routeHere={privatePages.accountDetails} + routeMyAccountCashout={privatePages.myAccountCashouts} + routeMyAccountDelete={privatePages.myAccountDelete} + routeMyAccountDetails={privatePages.myAccountDetails} + routeMyAccountPassword={privatePages.myAccountPassword} + routeConversionConfig={privatePages.conversionConfig} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeClose={privatePages.home} + /> + ); + } + case "accountChangePassword": { + return ( + navigateTo(privatePages.home.url({}))} + routeMyAccountCashout={privatePages.myAccountCashouts} + routeMyAccountDelete={privatePages.myAccountDelete} + routeMyAccountDetails={privatePages.myAccountDetails} + routeMyAccountPassword={privatePages.myAccountPassword} + routeConversionConfig={privatePages.conversionConfig} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeClose={privatePages.home} + /> + ); + } + case "accountDelete": { + return ( + navigateTo(privatePages.home.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeCancel={privatePages.home} + /> + ); + } + case "accountCashouts": { + return ( + + navigateTo(privatePages.solveSecondFactor.url({})) + } + /> + ); + } + case "myAccountDelete": { + return ( + navigateTo(privatePages.home.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeCancel={privatePages.home} + /> + ); + } + case "myAccountDetails": { + return ( + navigateTo(privatePages.home.url({}))} + routeMyAccountCashout={privatePages.myAccountCashouts} + routeConversionConfig={privatePages.conversionConfig} + routeMyAccountDelete={privatePages.myAccountDelete} + routeMyAccountDetails={privatePages.myAccountDetails} + routeMyAccountPassword={privatePages.myAccountPassword} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeClose={privatePages.home} + /> + ); + } + case "myAccountPassword": { + return ( + navigateTo(privatePages.home.url({}))} + routeMyAccountCashout={privatePages.myAccountCashouts} + routeMyAccountDelete={privatePages.myAccountDelete} + routeMyAccountDetails={privatePages.myAccountDetails} + routeMyAccountPassword={privatePages.myAccountPassword} + routeConversionConfig={privatePages.conversionConfig} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeClose={privatePages.home} + /> + ); + } + case "myAccountCashouts": { + return ( + + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeClose={privatePages.home} + /> + ); + } + case "home": { + if (isAdmin) { + return ( + + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeCreate={privatePages.accountCreate} + routeRemoveAccount={privatePages.accountDelete} + routeShowAccount={privatePages.accountDetails} + routeShowCashoutsAccount={privatePages.accountCashouts} + routeUpdatePasswordAccount={privatePages.accountChangePassword} + routeCreateWireTransfer={privatePages.wireTranserCreate} + routeDownloadStats={privatePages.statsDownload} + /> + ); + } + return ( + navigateTo(privatePages.home.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + onOperationCreated={(wopid) => + navigateTo(privatePages.startOperation.url({ wopid })) + } + /> + ); + } + case "cashoutCreate": { + return ( + + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeClose={privatePages.home} + /> + ); + } + case "cashoutDetails": { + return ( + + ); + } + case "wireTranserCreate": { + return ( + + navigateTo(privatePages.solveSecondFactor.url({})) + } + routeCancel={privatePages.home} + onSuccess={() => navigateTo(privatePages.home.url({}))} + /> + ); + } + case "homeChargeWallet": { + return ( + navigateTo(privatePages.home.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + onOperationCreated={(wopid) => + navigateTo(privatePages.startOperation.url({ wopid })) + } + /> + ); + } + case "conversionConfig": { + return { + navigateTo(privatePages.home.url({})) + }} + />; + } + case "homeWireTransfer": { + return ( + navigateTo(privatePages.home.url({}))} + onAuthorizationRequired={() => + navigateTo(privatePages.solveSecondFactor.url({})) + } + onOperationCreated={(wopid) => + navigateTo(privatePages.startOperation.url({ wopid })) + } + /> + ); + } + default: + assertUnreachable(location); + } +} diff --git a/packages/bank-ui/src/app.tsx b/packages/bank-ui/src/app.tsx new file mode 100644 index 000000000..3a7fafccf --- /dev/null +++ b/packages/bank-ui/src/app.tsx @@ -0,0 +1,137 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + canonicalizeBaseUrl, + getGlobalLogLevel, + setGlobalLogLevelFromString, +} from "@gnu-taler/taler-util"; +import { Loading, TranslationProvider } from "@gnu-taler/web-util/browser"; +import { h } from "preact"; +import { useEffect, useState } from "preact/hooks"; +import { SWRConfig } from "swr"; +import { Routing } from "./Routing.js"; +import { BankCoreApiProvider } from "./context/config.js"; +import { BrowserHashNavigationProvider } from "./context/navigation.js"; +import { SettingsProvider } from "./context/settings.js"; +import { TalerWalletIntegrationBrowserProvider } from "./context/wallet-integration.js"; +import { strings } from "./i18n/strings.js"; +import { BankFrame } from "./pages/BankFrame.js"; +import { BankUiSettings, fetchSettings } from "./settings.js"; +const WITH_LOCAL_STORAGE_CACHE = false; + +export function App() { + const [settings, setSettings] = useState(); + useEffect(() => { + fetchSettings(setSettings); + }, []); + if (!settings) return ; + + const baseUrl = getInitialBackendBaseURL(settings.backendBaseURL); + return ( + + + + + + + + + + + + + + ); +}; + +// @ts-expect-error creating a new property for window object +window.setGlobalLogLevelFromString = setGlobalLogLevelFromString; +// @ts-expect-error creating a new property for window object +window.getGlobalLevel = getGlobalLogLevel; + +function localStorageProvider(): Map { + const map = new Map(JSON.parse(localStorage.getItem("app-cache") || "[]")); + + window.addEventListener("beforeunload", () => { + const appCache = JSON.stringify(Array.from(map.entries())); + localStorage.setItem("app-cache", appCache); + }); + return map; +} + +function getInitialBackendBaseURL( + backendFromSettings: string | undefined, +): string { + const overrideUrl = + typeof localStorage !== "undefined" + ? localStorage.getItem("corebank-api-base-url") + : undefined; + let result: string; + + if (!overrideUrl) { + // normal path + if (!backendFromSettings) { + console.error( + "ERROR: backendBaseURL was overridden by a setting file and missing. Setting value to 'window.origin'", + ); + result = window.origin; + } else { + result = backendFromSettings; + } + } else { + // testing/development path + result = overrideUrl; + } + try { + return canonicalizeBaseUrl(result); + } catch (e) { + // fall back + return canonicalizeBaseUrl(window.origin); + } +} diff --git a/packages/bank-ui/src/assets/empty.png b/packages/bank-ui/src/assets/empty.png new file mode 100644 index 000000000..5120d3138 Binary files /dev/null and b/packages/bank-ui/src/assets/empty.png differ diff --git a/packages/bank-ui/src/assets/example/id1.jpg b/packages/bank-ui/src/assets/example/id1.jpg new file mode 100644 index 000000000..5d022a379 Binary files /dev/null and b/packages/bank-ui/src/assets/example/id1.jpg differ diff --git a/packages/bank-ui/src/assets/favicon.ico b/packages/bank-ui/src/assets/favicon.ico new file mode 100644 index 000000000..07419145b Binary files /dev/null and b/packages/bank-ui/src/assets/favicon.ico differ diff --git a/packages/bank-ui/src/assets/icons/android-chrome-192x192.png b/packages/bank-ui/src/assets/icons/android-chrome-192x192.png new file mode 100644 index 000000000..93ebe2e2c Binary files /dev/null and b/packages/bank-ui/src/assets/icons/android-chrome-192x192.png differ diff --git a/packages/bank-ui/src/assets/icons/android-chrome-512x512.png b/packages/bank-ui/src/assets/icons/android-chrome-512x512.png new file mode 100644 index 000000000..52d1623ea Binary files /dev/null and b/packages/bank-ui/src/assets/icons/android-chrome-512x512.png differ diff --git a/packages/bank-ui/src/assets/icons/apple-touch-icon.png b/packages/bank-ui/src/assets/icons/apple-touch-icon.png new file mode 100644 index 000000000..254e4bb4d Binary files /dev/null and b/packages/bank-ui/src/assets/icons/apple-touch-icon.png differ diff --git a/packages/bank-ui/src/assets/icons/favicon-16x16.png b/packages/bank-ui/src/assets/icons/favicon-16x16.png new file mode 100644 index 000000000..e81177dcb Binary files /dev/null and b/packages/bank-ui/src/assets/icons/favicon-16x16.png differ diff --git a/packages/bank-ui/src/assets/icons/favicon-32x32.png b/packages/bank-ui/src/assets/icons/favicon-32x32.png new file mode 100644 index 000000000..40e9b5b47 Binary files /dev/null and b/packages/bank-ui/src/assets/icons/favicon-32x32.png differ diff --git a/packages/bank-ui/src/assets/icons/languageicon.svg b/packages/bank-ui/src/assets/icons/languageicon.svg new file mode 100644 index 000000000..22d58da65 --- /dev/null +++ b/packages/bank-ui/src/assets/icons/languageicon.svg @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/bank-ui/src/assets/icons/mstile-150x150.png b/packages/bank-ui/src/assets/icons/mstile-150x150.png new file mode 100644 index 000000000..9cfb889be Binary files /dev/null and b/packages/bank-ui/src/assets/icons/mstile-150x150.png differ diff --git a/packages/bank-ui/src/assets/logo-2021.svg b/packages/bank-ui/src/assets/logo-2021.svg new file mode 100644 index 000000000..8c5ff3e5b --- /dev/null +++ b/packages/bank-ui/src/assets/logo-2021.svg @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/packages/bank-ui/src/assets/logo-white.svg b/packages/bank-ui/src/assets/logo-white.svg new file mode 100644 index 000000000..cb1f023c5 --- /dev/null +++ b/packages/bank-ui/src/assets/logo-white.svg @@ -0,0 +1,45 @@ + + + + diff --git a/packages/bank-ui/src/assets/logo.jpeg b/packages/bank-ui/src/assets/logo.jpeg new file mode 100644 index 000000000..489832f7c Binary files /dev/null and b/packages/bank-ui/src/assets/logo.jpeg differ diff --git a/packages/bank-ui/src/components/Cashouts/index.ts b/packages/bank-ui/src/components/Cashouts/index.ts new file mode 100644 index 000000000..2c6bf681c --- /dev/null +++ b/packages/bank-ui/src/components/Cashouts/index.ts @@ -0,0 +1,86 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { Loading, utils } from "@gnu-taler/web-util/browser"; +import { + AbsoluteTime, + AmountJson, + TalerCoreBankErrorsByMethod, + TalerCorebankApi, + TalerError, +} from "@gnu-taler/taler-util"; +import { ErrorLoadingWithDebug } from "../ErrorLoadingWithDebug.js"; +import { useComponentState } from "./state.js"; +import { FailedView, ReadyView } from "./views.js"; +import { RouteDefinition } from "../../route.js"; + +export interface Props { + account: string; + routeCashoutDetails: RouteDefinition<{ cid: string }>; +} + +export type State = + | State.Loading + | State.Failed + | State.LoadingUriError + | State.Ready; + +export namespace State { + export interface Loading { + status: "loading"; + error: undefined; + } + + export interface LoadingUriError { + status: "loading-error"; + error: TalerError; + } + + export interface Failed { + status: "failed"; + error: TalerCoreBankErrorsByMethod<"getAccountCashouts">; + } + + export interface BaseInfo { + error: undefined; + } + export interface Ready extends BaseInfo { + status: "ready"; + error: undefined; + cashouts: (TalerCorebankApi.CashoutStatusResponse & { id: number })[]; + routeCashoutDetails: RouteDefinition<{ cid: string }>; + } +} + +export interface Transaction { + negative: boolean; + counterpart: string; + when: AbsoluteTime; + amount: AmountJson | undefined; + subject: string; +} + +const viewMapping: utils.StateViewMap = { + loading: Loading, + "loading-error": ErrorLoadingWithDebug, + failed: FailedView, + ready: ReadyView, +}; + +export const Cashouts = utils.compose( + (p: Props) => useComponentState(p), + viewMapping, +); diff --git a/packages/bank-ui/src/components/Cashouts/state.ts b/packages/bank-ui/src/components/Cashouts/state.ts new file mode 100644 index 000000000..8616faa1b --- /dev/null +++ b/packages/bank-ui/src/components/Cashouts/state.ts @@ -0,0 +1,51 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { TalerError } from "@gnu-taler/taler-util"; +import { useCashouts } from "../../hooks/regional.js"; +import { Props, State } from "./index.js"; + +export function useComponentState({ + account, + routeCashoutDetails, +}: Props): State { + const result = useCashouts(account); + if (!result) { + return { + status: "loading", + error: undefined, + }; + } + if (result instanceof TalerError) { + return { + status: "loading-error", + error: result, + }; + } + if (result.type === "fail") { + return { + status: "failed", + error: result, + }; + } + + return { + status: "ready", + error: undefined, + cashouts: result.body.cashouts, + routeCashoutDetails, + }; +} diff --git a/packages/bank-ui/src/components/Cashouts/stories.tsx b/packages/bank-ui/src/components/Cashouts/stories.tsx new file mode 100644 index 000000000..37ab64108 --- /dev/null +++ b/packages/bank-ui/src/components/Cashouts/stories.tsx @@ -0,0 +1,29 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { ReadyView } from "./views.js"; + +export default { + title: "transaction list", +}; + +export const Ready = tests.createExample(ReadyView, {}); diff --git a/packages/bank-ui/src/components/Cashouts/test.ts b/packages/bank-ui/src/components/Cashouts/test.ts new file mode 100644 index 000000000..4bd6b5eac --- /dev/null +++ b/packages/bank-ui/src/components/Cashouts/test.ts @@ -0,0 +1,68 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { SwrMockEnvironment } from "@gnu-taler/web-util/testing"; +import { expect } from "chai"; +import { Props } from "./index.js"; +import { useComponentState } from "./state.js"; +import { buildNullRoutDefinition } from "../../route.js"; + +describe("Cashout states", () => { + it.skip("should query backend and render transactions", async () => { + const env = new SwrMockEnvironment(); + + const props: Props = { + account: "123", + routeCashoutDetails: buildNullRoutDefinition(), + }; + + // env.addRequestExpectation(CASHOUT_API_EXAMPLE.LIST_FIRST_PAGE, { + // response: { + // cashouts: [], + // }, + // }); + + // env.addRequestExpectation(CASHOUT_API_EXAMPLE.MULTI_GET_EMPTY_FIRST_PAGE, { + // response: [], + // }); + + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + ({ status, error }) => { + expect(status).equals("ready"); + expect(error).undefined; + }, + ], + env.buildTestingContext(), + ); + + expect(hookBehavior).deep.eq({ result: "ok" }); + + expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" }); + }); +}); diff --git a/packages/bank-ui/src/components/Cashouts/views.tsx b/packages/bank-ui/src/components/Cashouts/views.tsx new file mode 100644 index 000000000..7f16d5840 --- /dev/null +++ b/packages/bank-ui/src/components/Cashouts/views.tsx @@ -0,0 +1,217 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AbsoluteTime, + Amounts, + Duration, + HttpStatusCode, + TalerError, + assertUnreachable, +} from "@gnu-taler/taler-util"; +import { + Attention, + Loading, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; +import { format } from "date-fns"; +import { Fragment, VNode, h } from "preact"; +import { useConversionInfo } from "../../hooks/regional.js"; +import { RenderAmount } from "../../pages/PaytoWireTransferForm.js"; +import { ErrorLoadingWithDebug } from "../ErrorLoadingWithDebug.js"; +import { State } from "./index.js"; +import { Time } from "../Time.js"; + +export function FailedView({ error }: State.Failed) { + const { i18n } = useTranslationContext(); + switch (error.case) { + case HttpStatusCode.NotImplemented: { + return ( + + Cashout should be enable by configuration and the conversion rate should be initialized with fee, ratio and rounding mode. + + ); + } + default: + assertUnreachable(error.case); + } +} + +export function ReadyView({ + cashouts, + routeCashoutDetails, +}: State.Ready): VNode { + const { i18n, dateLocale } = useTranslationContext(); + const resp = useConversionInfo(); + if (!resp) { + return ; + } + if (resp instanceof TalerError) { + return ; + } + if (resp.type === "fail") { + switch (resp.case) { + case HttpStatusCode.NotImplemented: { + return ( + + Cashout should be enable by configuration and the conversion rate should be initialized with fee, ratio and rounding mode. + + ); + } + default: + assertUnreachable(resp.case); + } + } + + if (!cashouts.length) return
; + const txByDate = cashouts.reduce( + (prev, cur) => { + const d = + cur.creation_time.t_s === "never" + ? "" + : format(cur.creation_time.t_s * 1000, "dd/MM/yyyy", { + locale: dateLocale, + }); + if (!prev[d]) { + prev[d] = []; + } + prev[d].push(cur); + return prev; + }, + {} as Record, + ); + return ( +
+
+
+

+ Latest cashouts +

+
+
+
+ + + + + + + + + + + {Object.entries(txByDate).map(([date, txs], idx) => { + return ( + + + + + {txs.map((item) => { + return ( + + + + + + + + ); + })} + + ); + })} + +
{i18n.str`Created`}
+ {date} +
+
+
+ { + //FIXME: implement responsive view + } + {/*
+
Amount
+
+ {item.negative ? i18n.str`sent` : i18n.str`received`} {item.amount ? ( + + + + ) : ( + <{i18n.str`invalid value`}> + )}
+ +
Counterpart
+
+ {item.negative ? i18n.str`to` : i18n.str`from`} {item.counterpart} +
+
+
+                            {item.subject}
+                          
+
+
*/} +
+
+
+ ); +} diff --git a/packages/bank-ui/src/components/EmptyComponentExample/index.ts b/packages/bank-ui/src/components/EmptyComponentExample/index.ts new file mode 100644 index 000000000..da84f9921 --- /dev/null +++ b/packages/bank-ui/src/components/EmptyComponentExample/index.ts @@ -0,0 +1,56 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { HookError, Loading, utils } from "@gnu-taler/web-util/browser"; +import { useComponentState } from "./state.js"; +import { LoadingUriView, ReadyView } from "./views.js"; + +export interface Props { + p: string; +} + +export type State = State.Loading | State.LoadingUriError | State.Ready; + +export namespace State { + export interface Loading { + status: "loading"; + error: undefined; + } + + export interface LoadingUriError { + status: "loading-error"; + error: HookError; + } + + export interface BaseInfo { + error: undefined; + } + export interface Ready extends BaseInfo { + status: "ready"; + error: undefined; + } +} + +const viewMapping: utils.StateViewMap = { + loading: Loading, + "loading-error": LoadingUriView, + ready: ReadyView, +}; + +export const ComponentName = utils.compose( + (p: Props) => useComponentState(p), + viewMapping, +); diff --git a/packages/bank-ui/src/components/EmptyComponentExample/state.ts b/packages/bank-ui/src/components/EmptyComponentExample/state.ts new file mode 100644 index 000000000..057664983 --- /dev/null +++ b/packages/bank-ui/src/components/EmptyComponentExample/state.ts @@ -0,0 +1,25 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +// import { wxApi } from "../../wxApi.js"; +import { Props, State } from "./index.js"; + +export function useComponentState({ p: _p }: Props): State { + return { + status: "ready", + error: undefined, + }; +} diff --git a/packages/bank-ui/src/components/EmptyComponentExample/stories.tsx b/packages/bank-ui/src/components/EmptyComponentExample/stories.tsx new file mode 100644 index 000000000..160acdf79 --- /dev/null +++ b/packages/bank-ui/src/components/EmptyComponentExample/stories.tsx @@ -0,0 +1,29 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { ReadyView } from "./views.js"; + +export default { + title: "example", +}; + +export const Ready = tests.createExample(ReadyView, {}); diff --git a/packages/bank-ui/src/components/EmptyComponentExample/test.ts b/packages/bank-ui/src/components/EmptyComponentExample/test.ts new file mode 100644 index 000000000..629948d91 --- /dev/null +++ b/packages/bank-ui/src/components/EmptyComponentExample/test.ts @@ -0,0 +1,28 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import { expect } from "chai"; + +describe("test description", () => { + it("should assert", () => { + expect([]).deep.equals([]); + }); +}); diff --git a/packages/bank-ui/src/components/EmptyComponentExample/views.tsx b/packages/bank-ui/src/components/EmptyComponentExample/views.tsx new file mode 100644 index 000000000..457933a5f --- /dev/null +++ b/packages/bank-ui/src/components/EmptyComponentExample/views.tsx @@ -0,0 +1,25 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { h, VNode } from "preact"; + +export function LoadingUriView(): VNode { + return
; +} + +export function ReadyView(): VNode { + return
; +} diff --git a/packages/bank-ui/src/components/ErrorLoadingWithDebug.tsx b/packages/bank-ui/src/components/ErrorLoadingWithDebug.tsx new file mode 100644 index 000000000..8679af050 --- /dev/null +++ b/packages/bank-ui/src/components/ErrorLoadingWithDebug.tsx @@ -0,0 +1,24 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ +import { TalerError } from "@gnu-taler/taler-util"; +import { ErrorLoading } from "@gnu-taler/web-util/browser"; +import { VNode, h } from "preact"; +import { usePreferences } from "../hooks/preferences.js"; + +export function ErrorLoadingWithDebug({ error }: { error: TalerError }): VNode { + const [pref] = usePreferences(); + return ; +} diff --git a/packages/bank-ui/src/components/QR.tsx b/packages/bank-ui/src/components/QR.tsx new file mode 100644 index 000000000..b039bbd1e --- /dev/null +++ b/packages/bank-ui/src/components/QR.tsx @@ -0,0 +1,51 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { h, VNode } from "preact"; +import { useEffect, useRef } from "preact/hooks"; +import qrcode from "qrcode-generator"; + +export function QR({ text }: { text: string }): VNode { + const divRef = useRef(null); + useEffect(() => { + const qr = qrcode(0, "L"); + qr.addData(text); + qr.make(); + if (divRef.current) + divRef.current.innerHTML = qr.createSvgTag({ + scalable: true, + }); + }); + + return ( +
+
+
+ ); +} diff --git a/packages/bank-ui/src/components/Time.tsx b/packages/bank-ui/src/components/Time.tsx new file mode 100644 index 000000000..39ce33f60 --- /dev/null +++ b/packages/bank-ui/src/components/Time.tsx @@ -0,0 +1,71 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { AbsoluteTime, Duration } from "@gnu-taler/taler-util"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { formatISO, format, formatDuration, intervalToDuration } from "date-fns"; +import { Fragment, h, VNode } from "preact"; + +/** + * + * @param timestamp time to be formatted + * @param relative duration threshold, if the difference is lower + * the timestamp will be formatted as relative time from "now" + * + * @returns + */ +export function Time({ + timestamp, + relative, + format: formatString, +}: { + timestamp: AbsoluteTime | undefined; + relative?: Duration, + format: string; +}): VNode { + const { i18n, dateLocale } = useTranslationContext() + if (!timestamp) return + + if (timestamp.t_ms === "never") { + return + } + + const now = AbsoluteTime.now(); + const diff = AbsoluteTime.difference(now, timestamp) + if (relative && now.t_ms !== "never" && Duration.cmp(diff, relative) === -1) { + const d = intervalToDuration({ + start: now.t_ms, + end: timestamp.t_ms + }) + d.seconds = 0 + const duration = formatDuration(d, { locale: dateLocale }) + const isFuture = AbsoluteTime.cmp(now, timestamp) < 0 + if (isFuture) { + return + } else { + return + } + } + return ( + + ); +} diff --git a/packages/bank-ui/src/components/Transactions/index.ts b/packages/bank-ui/src/components/Transactions/index.ts new file mode 100644 index 000000000..c8bb1e108 --- /dev/null +++ b/packages/bank-ui/src/components/Transactions/index.ts @@ -0,0 +1,80 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { AbsoluteTime, AmountJson, TalerError } from "@gnu-taler/taler-util"; +import { Loading, utils } from "@gnu-taler/web-util/browser"; +import { ErrorLoadingWithDebug } from "../ErrorLoadingWithDebug.js"; +import { useComponentState } from "./state.js"; +import { ReadyView } from "./views.js"; +import { RouteDefinition } from "../../route.js"; + +export interface Props { + account: string; + routeCreateWireTransfer: RouteDefinition<{ + account?: string, + subject?: string, + amount?: string, + }> | undefined; +} + +export type State = State.Loading | State.LoadingUriError | State.Ready; + +export namespace State { + export interface Loading { + status: "loading"; + error: undefined; + } + + export interface LoadingUriError { + status: "loading-error"; + error: TalerError; + } + + export interface BaseInfo { + error: undefined; + } + export interface Ready extends BaseInfo { + status: "ready"; + error: undefined; + routeCreateWireTransfer: RouteDefinition<{ + account?: string, + subject?: string, + amount?: string, + }> | undefined; + transactions: Transaction[]; + onGoStart?: () => void; + onGoNext?: () => void; + } +} + +export interface Transaction { + negative: boolean; + counterpart: string; + when: AbsoluteTime; + amount: AmountJson | undefined; + subject: string; +} + +const viewMapping: utils.StateViewMap = { + loading: Loading, + "loading-error": ErrorLoadingWithDebug, + ready: ReadyView, +}; + +export const Transactions = utils.compose( + (p: Props) => useComponentState(p), + viewMapping, +); diff --git a/packages/bank-ui/src/components/Transactions/state.ts b/packages/bank-ui/src/components/Transactions/state.ts new file mode 100644 index 000000000..3e9103b59 --- /dev/null +++ b/packages/bank-ui/src/components/Transactions/state.ts @@ -0,0 +1,80 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AbsoluteTime, + Amounts, + TalerError, + parsePaytoUri, +} from "@gnu-taler/taler-util"; +import { useTransactions } from "../../hooks/account.js"; +import { Props, State, Transaction } from "./index.js"; + +export function useComponentState({ account, routeCreateWireTransfer }: Props): State { + const txResult = useTransactions(account); + if (!txResult) { + return { + status: "loading", + error: undefined, + }; + } + if (txResult instanceof TalerError) { + return { + status: "loading-error", + error: txResult, + }; + } + + const transactions = + txResult.result + .map((tx) => { + const negative = tx.direction === "debit"; + const cp = parsePaytoUri( + negative ? tx.creditor_payto_uri : tx.debtor_payto_uri, + ); + const counterpart = + (cp === undefined || !cp.isKnown + ? undefined + : cp.targetType === "iban" + ? cp.iban + : cp.targetType === "x-taler-bank" + ? cp.account + : cp.targetType === "bitcoin" + ? `${cp.targetPath.substring(0, 6)}...` + : undefined) ?? "unknown"; + + const when = AbsoluteTime.fromProtocolTimestamp(tx.date); + const amount = Amounts.parse(tx.amount); + const subject = tx.subject; + return { + negative, + counterpart, + when, + amount, + subject, + }; + }) + .filter((x): x is Transaction => x !== undefined); + + return { + status: "ready", + error: undefined, + routeCreateWireTransfer, + transactions, + onGoNext: txResult.isLastPage ? undefined : txResult.loadNext, + onGoStart: txResult.isFirstPage ? undefined : txResult.loadFirst, + }; +} diff --git a/packages/bank-ui/src/components/Transactions/stories.tsx b/packages/bank-ui/src/components/Transactions/stories.tsx new file mode 100644 index 000000000..95014574b --- /dev/null +++ b/packages/bank-ui/src/components/Transactions/stories.tsx @@ -0,0 +1,44 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { ReadyView } from "./views.js"; +import { AbsoluteTime } from "@gnu-taler/taler-util"; + +export default { + title: "transaction list", +}; + +export const Ready = tests.createExample(ReadyView, { + transactions: [ + { + amount: { + currency: "USD", + fraction: 0, + value: 1, + }, + counterpart: "ASD", + negative: false, + subject: "Some", + when: AbsoluteTime.now(), + }, + ], +}); diff --git a/packages/bank-ui/src/components/Transactions/test.ts b/packages/bank-ui/src/components/Transactions/test.ts new file mode 100644 index 000000000..d9442c742 --- /dev/null +++ b/packages/bank-ui/src/components/Transactions/test.ts @@ -0,0 +1,202 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import { TalerErrorCode } from "@gnu-taler/taler-util"; +import * as tests from "@gnu-taler/web-util/testing"; +import { SwrMockEnvironment } from "@gnu-taler/web-util/testing"; +import { expect } from "chai"; +import { Props } from "./index.js"; +import { useComponentState } from "./state.js"; + +describe("Transaction states", () => { + it.skip("should query backend and render transactions", async () => { + const env = new SwrMockEnvironment(); + + const props: Props = { + account: "myAccount", + routeCreateWireTransfer: undefined, + }; + + // env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_FIRST_PAGE, { + // response: { + // data: { + // transactions: [ + // { + // creditorIban: "DE159593", + // creditorBic: "SANDBOXX", + // creditorName: "exchange company", + // debtorIban: "DE118695", + // debtorBic: "SANDBOXX", + // debtorName: "Name unknown", + // amount: "1", + // currency: "KUDOS", + // subject: + // "Taler Withdrawal N588V8XE9TR49HKAXFQ20P0EQ0EYW2AC9NNANV8ZP5P59N6N0410", + // date: "2022-12-12Z", + // uid: "8PPFR9EM", + // direction: "DBIT", + // pmtInfId: null, + // msgId: null, + // }, + // { + // creditorIban: "DE159593", + // creditorBic: "SANDBOXX", + // creditorName: "exchange company", + // debtorIban: "DE118695", + // debtorBic: "SANDBOXX", + // debtorName: "Name unknown", + // amount: "5.00", + // currency: "KUDOS", + // subject: "HNEWWT679TQC5P1BVXJS48FX9NW18FWM6PTK2N80Z8GVT0ACGNK0", + // date: "2022-12-07Z", + // uid: "7FZJC3RJ", + // direction: "DBIT", + // pmtInfId: null, + // msgId: null, + // }, + // { + // creditorIban: "DE118695", + // creditorBic: "SANDBOXX", + // creditorName: "Name unknown", + // debtorIban: "DE579516", + // debtorBic: "SANDBOXX", + // debtorName: "The Bank", + // amount: "100", + // currency: "KUDOS", + // subject: "Sign-up bonus", + // date: "2022-12-07Z", + // uid: "I31A06J8", + // direction: "CRDT", + // pmtInfId: null, + // msgId: null, + // }, + // ], + // }, + // }, + // }); + + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + ({ status, error }) => { + expect(status).equals("ready"); + expect(error).undefined; + }, + ], + env.buildTestingContext(), + ); + + expect(hookBehavior).deep.eq({ result: "ok" }); + + expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" }); + }); + + // it("should show error message on not found", async () => { + // const env = new SwrMockEnvironment(); + + // const props: Props = { + // account: "myAccount", + // }; + + // env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_NOT_FOUND, { + // response: { + // error: { + // description: "Transaction page 0 could not be retrieved.", + // }, + // }, + // }); + + // const hookBehavior = await tests.hookBehaveLikeThis( + // useComponentState, + // props, + // [ + // ({ status, error }) => { + // expect(status).equals("loading"); + // expect(error).undefined; + // }, + // ({ status, error }) => { + // expect(status).equals("loading-error"); + // if (error === undefined || error.type !== ErrorType.CLIENT) { + // throw Error("not the expected error"); + // } + // expect(error.payload).deep.equal({ + // error: { + // description: "Transaction page 0 could not be retrieved.", + // }, + // }); + // }, + // ], + // env.buildTestingContext(), + // ); + + // expect(hookBehavior).deep.eq({ result: "ok" }); + // expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" }); + // }); + + it.skip("should show error message on server error", async () => { + const env = new SwrMockEnvironment(); + + const props: Props = { + account: "myAccount", + routeCreateWireTransfer: undefined, + }; + + // env.addRequestExpectation(TRANSACTION_API_EXAMPLE.LIST_ERROR, { + // response: { + // error: { + // code: TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED, + // }, + // }, + // }); + + const hookBehavior = await tests.hookBehaveLikeThis( + useComponentState, + props, + [ + ({ status, error }) => { + expect(status).equals("loading"); + expect(error).undefined; + }, + ({ status, error }) => { + expect(status).equals("loading-error"); + if ( + error === undefined || + !error.hasErrorCode(TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED) + ) { + throw Error("not the expected error"); + } + expect(error.errorDetail.code).deep.equal( + TalerErrorCode.WALLET_HTTP_REQUEST_THROTTLED, + ); + }, + ], + env.buildTestingContext(), + ); + + expect(hookBehavior).deep.eq({ result: "ok" }); + expect(env.assertJustExpectedRequestWereMade()).deep.eq({ result: "ok" }); + }); +}); diff --git a/packages/bank-ui/src/components/Transactions/views.tsx b/packages/bank-ui/src/components/Transactions/views.tsx new file mode 100644 index 000000000..7da9fc5a9 --- /dev/null +++ b/packages/bank-ui/src/components/Transactions/views.tsx @@ -0,0 +1,243 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { Attention, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { format } from "date-fns"; +import { Fragment, VNode, h } from "preact"; +import { useBankCoreApiContext } from "../../context/config.js"; +import { RenderAmount } from "../../pages/PaytoWireTransferForm.js"; +import { State } from "./index.js"; +import { Duration } from "@gnu-taler/taler-util"; +import { Time } from "../Time.js"; + +export function ReadyView({ + transactions, + routeCreateWireTransfer, + onGoNext, + onGoStart, +}: State.Ready): VNode { + const { i18n, dateLocale } = useTranslationContext(); + const { config } = useBankCoreApiContext() + + if (!transactions.length) { + return
+
+
+

+ Transactions history +

+
+
+ + + + You can start sending a wire transfer or withdrawing to your wallet. + + +
; + } + + const txByDate = transactions.reduce( + (prev, cur) => { + const d = + cur.when.t_ms === "never" + ? "" + : format(cur.when.t_ms, "dd/MM/yyyy", { locale: dateLocale }); + if (!prev[d]) { + prev[d] = []; + } + prev[d].push(cur); + return prev; + }, + {} as Record, + ); + return ( +
+
+
+

+ Transactions history +

+
+
+
+ + + + + + + + + + + {Object.entries(txByDate).map(([date, txs], idx) => { + return ( + + + + + {txs.map((item) => { + return ( + + + + + + + ); + })} + + ); + })} + +
{i18n.str`Date`}
+ {date} +
+
+
+
+
+ Amount +
+
+ {item.negative + ? i18n.str`sent` + : i18n.str`received`}{" "} + {item.amount ? ( + + + + ) : ( + + <{i18n.str`Invalid value`}> + + )} +
+ +
+ Counterpart +
+
+ {item.negative ? i18n.str`to` : i18n.str`from`}{" "} + {!routeCreateWireTransfer ? item.counterpart : + + {item.counterpart} + + } +
+
+
+                                {item.subject}
+                              
+
+
+
+ + +
+
+ ); +} diff --git a/packages/bank-ui/src/components/index.examples.ts b/packages/bank-ui/src/components/index.examples.ts new file mode 100644 index 000000000..20e013070 --- /dev/null +++ b/packages/bank-ui/src/components/index.examples.ts @@ -0,0 +1,17 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +export * as tx from "./Transactions/stories.js"; diff --git a/packages/bank-ui/src/context/config.ts b/packages/bank-ui/src/context/config.ts new file mode 100644 index 000000000..39d12be86 --- /dev/null +++ b/packages/bank-ui/src/context/config.ts @@ -0,0 +1,263 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + assertUnreachable, + LibtoolVersion, + TalerBankConversionCacheEviction, + TalerBankConversionHttpClient, + TalerCorebankApi, + TalerAuthenticationHttpClient, + TalerCoreBankCacheEviction, + TalerCoreBankHttpClient, + TalerError +} from "@gnu-taler/taler-util"; +import { + BrowserHttpLib, + ErrorLoading, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; +import { + ComponentChildren, + createContext, + FunctionComponent, + h, + VNode, +} from "preact"; +import { useContext, useEffect, useState } from "preact/hooks"; +import { + revalidateAccountDetails, + revalidatePublicAccounts, + revalidateTransactions, +} from "../hooks/account.js"; +import { + revalidateBusinessAccounts, + revalidateCashouts, + revalidateConversionInfo, +} from "../hooks/regional.js"; + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +export type Type = { + url: URL; + config: TalerCorebankApi.Config; + bank: TalerCoreBankHttpClient; + conversion: TalerBankConversionHttpClient; + authenticator: (user: string) => TalerAuthenticationHttpClient; + hints: VersionHint[]; +}; + +// FIXME: below +// @ts-expect-error default value to undefined, should it be another thing? +const Context = createContext(undefined); + +export const useBankCoreApiContext = (): Type => useContext(Context); + +export enum VersionHint { + /** + * when this flag is on, server is running an old version with cashout before implementing 2fa API + */ + CASHOUT_BEFORE_2FA, +} + +export type ConfigResult = + | undefined + | { type: "ok"; config: TalerCorebankApi.Config; hints: VersionHint[] } + | { type: "incompatible"; result: TalerCorebankApi.Config; supported: string } + | { type: "error"; error: TalerError }; + +export const BankCoreApiProvider = ({ + baseUrl, + children, + frameOnError, +}: { + baseUrl: string; + children: ComponentChildren; + frameOnError: FunctionComponent<{ children: ComponentChildren }>; +}): VNode => { + const [checked, setChecked] = useState(); + const { i18n } = useTranslationContext(); + + const { bankClient, conversionClient, authClient } = buildApiClient(new URL(baseUrl)) + + useEffect(() => { + bankClient + .getConfig() + .then((resp) => { + if (bankClient.isCompatible(resp.body.version)) { + setChecked({ type: "ok", config: resp.body, hints: [] }); + } else { + // this API supports version 3.0.3 + const compare = LibtoolVersion.compare("3:0:3", resp.body.version); + if (compare?.compatible ?? false) { + setChecked({ + type: "ok", + config: resp.body, + hints: [VersionHint.CASHOUT_BEFORE_2FA], + }); + } else { + setChecked({ + type: "incompatible", + result: resp.body, + supported: bankClient.PROTOCOL_VERSION, + }); + } + } + }) + .catch((error: unknown) => { + if (error instanceof TalerError) { + setChecked({ type: "error", error }); + } + }); + }, []); + + if (checked === undefined) { + return h(frameOnError, { children: h("div", {}, "loading...") }); + } + if (checked.type === "error") { + return h(frameOnError, { + children: h(ErrorLoading, { error: checked.error, showDetail: true }), + }); + } + if (checked.type === "incompatible") { + return h(frameOnError, { + children: h( + "div", + {}, + i18n.str`The bank backend is not supported. Supported version "${checked.supported}", server version "${checked.result.version}"`, + ), + }); + } + const value: Type = { + url: new URL(bankClient.baseUrl), + config: checked.config, + bank: bankClient, + conversion: conversionClient, + authenticator: authClient, + hints: checked.hints, + }; + return h(Context.Provider, { + value, + children, + }); +}; + +/** + * build http client with cache breaker due to SWR + * @param url + * @returns + */ +function buildApiClient(url: URL) { + const httpLib = new BrowserHttpLib(); + + const bankClient = new TalerCoreBankHttpClient(url.href, httpLib, { + async notifySuccess(op) { + switch (op) { + case TalerCoreBankCacheEviction.DELELE_ACCOUNT: { + await Promise.all([ + revalidatePublicAccounts(), + revalidateBusinessAccounts(), + ]); + return + } + case TalerCoreBankCacheEviction.CREATE_ACCOUNT: { + // admin balance change on new account + await Promise.all([ + revalidateAccountDetails(), + revalidateTransactions(), + revalidatePublicAccounts(), + revalidateBusinessAccounts(), + ]) + return; + } + case TalerCoreBankCacheEviction.UPDATE_ACCOUNT: { + await Promise.all([ + revalidateAccountDetails(), + ]) + return; + } + case TalerCoreBankCacheEviction.CREATE_TRANSACTION: { + await Promise.all([ + revalidateAccountDetails(), + revalidateTransactions(), + ]) + return; + } + case TalerCoreBankCacheEviction.CONFIRM_WITHDRAWAL: { + await Promise.all([ + revalidateAccountDetails(), + revalidateTransactions(), + ]) + return; + } + case TalerCoreBankCacheEviction.CREATE_CASHOUT: { + await Promise.all([ + revalidateAccountDetails(), + revalidateCashouts(), + revalidateTransactions(), + ]) + return; + } + case TalerCoreBankCacheEviction.UPDATE_PASSWORD: + case TalerCoreBankCacheEviction.ABORT_WITHDRAWAL: + case TalerCoreBankCacheEviction.CREATE_WITHDRAWAL: + return; + default: + assertUnreachable(op) + } + } + }); + const conversionClient = new TalerBankConversionHttpClient(bankClient.getConversionInfoAPI(), httpLib, { + async notifySuccess(op) { + switch (op) { + case TalerBankConversionCacheEviction.UPDATE_RATE: { + await revalidateConversionInfo(); + return + } + default: + assertUnreachable(op) + } + } + }); + const authClient = (user: string) => new TalerAuthenticationHttpClient(bankClient.getAuthenticationAPI(user), user, httpLib); + return { bankClient, conversionClient, authClient } +} + +export const BankCoreApiProviderTesting = ({ + children, + state, + url, +}: { + children: ComponentChildren; + state: TalerCorebankApi.Config; + url: string; +}): VNode => { + const value: Type = { + url: new URL(url), + config: state, + // @ts-expect-error this API is not being used, not really needed + bank: undefined, + hints: [], + }; + + return h(Context.Provider, { + value, + children, + }); +}; diff --git a/packages/bank-ui/src/context/navigation.ts b/packages/bank-ui/src/context/navigation.ts new file mode 100644 index 000000000..9552bf899 --- /dev/null +++ b/packages/bank-ui/src/context/navigation.ts @@ -0,0 +1,92 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { ComponentChildren, createContext, h, VNode } from "preact"; +import { useContext, useEffect, useState } from "preact/hooks"; +import { AppLocation } from "../route.js"; + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +export type Type = { + path: string; + params: Record; + navigateTo: (path: AppLocation) => void; + // addNavigationListener: (listener: (path: string, params: Record) => void) => (() => void); +}; + +// @ts-expect-error should not be used without provider +const Context = createContext(undefined); + +export const useNavigationContext = (): Type => useContext(Context); + +function getPathAndParamsFromWindow() { + const path = + typeof window !== "undefined" ? window.location.hash.substring(1) : "/"; + const params: Record = {}; + if (typeof window !== "undefined") { + for (const [key, value] of new URLSearchParams(window.location.search)) { + params[key] = value; + } + } + return { path, params }; +} + +const { path: initialPath, params: initialParams } = + getPathAndParamsFromWindow(); + +// there is a possibility that if the browser does a redirection +// (which doesn't go through navigatTo function) and that executed +// too early (before addEventListener runs) it won't be taking +// into account +const PopStateEventType = "popstate"; + +export const BrowserHashNavigationProvider = ({ + children, +}: { + children: ComponentChildren; +}): VNode => { + const [{ path, params }, setState] = useState({ + path: initialPath, + params: initialParams, + }); + if (typeof window === "undefined") { + throw Error( + "Can't use BrowserHashNavigationProvider if there is no window object", + ); + } + function navigateTo(path: string) { + const { params } = getPathAndParamsFromWindow(); + setState({ path, params }); + window.location.href = path; + } + + useEffect(() => { + function eventListener() { + setState(getPathAndParamsFromWindow()); + } + window.addEventListener(PopStateEventType, eventListener); + return () => { + window.removeEventListener(PopStateEventType, eventListener); + }; + }, []); + return h(Context.Provider, { + value: { path, params, navigateTo }, + children, + }); +}; diff --git a/packages/bank-ui/src/context/settings.ts b/packages/bank-ui/src/context/settings.ts new file mode 100644 index 000000000..053fcbd12 --- /dev/null +++ b/packages/bank-ui/src/context/settings.ts @@ -0,0 +1,44 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { ComponentChildren, createContext, h, VNode } from "preact"; +import { useContext } from "preact/hooks"; +import { BankUiSettings } from "../settings.js"; + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +export type Type = BankUiSettings; + +const initial: BankUiSettings = {}; +const Context = createContext(initial); + +export const useSettingsContext = (): Type => useContext(Context); + +export const SettingsProvider = ({ + children, + value, +}: { + value: BankUiSettings; + children: ComponentChildren; +}): VNode => { + return h(Context.Provider, { + value, + children, + }); +}; diff --git a/packages/bank-ui/src/context/wallet-integration.ts b/packages/bank-ui/src/context/wallet-integration.ts new file mode 100644 index 000000000..e14988ed1 --- /dev/null +++ b/packages/bank-ui/src/context/wallet-integration.ts @@ -0,0 +1,83 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { stringifyTalerUri, TalerUri } from "@gnu-taler/taler-util"; +import { ComponentChildren, createContext, h, VNode } from "preact"; +import { useContext } from "preact/hooks"; + +/** + * https://docs.taler.net/design-documents/039-taler-browser-integration.html + * + * @param uri + */ +function createHeadMetaTag(uri: TalerUri, onNotFound?: () => void) { + const meta = document.createElement("meta"); + meta.setAttribute("name", "taler-uri"); + meta.setAttribute("content", stringifyTalerUri(uri)); + + document.head.appendChild(meta); + + let walletFound = false; + window.addEventListener("beforeunload", () => { + walletFound = true; + }); + setTimeout(() => { + if (!walletFound && onNotFound) { + onNotFound(); + } + }, 10); //very short timeout +} +interface Type { + /** + * Tell the active wallet that an action is found + * + * @param uri + * @returns + */ + publishTalerAction: (uri: TalerUri, onNotFound?: () => void) => void; +} + +// @ts-expect-error default value to undefined, should it be another thing? +const Context = createContext(undefined); + +export const useTalerWalletIntegrationAPI = (): Type => useContext(Context); + +export const TalerWalletIntegrationBrowserProvider = ({ + children, +}: { + children: ComponentChildren; +}): VNode => { + const value: Type = { + publishTalerAction: createHeadMetaTag, + }; + return h(Context.Provider, { + value, + children, + }); +}; + +export const TalerWalletIntegrationTestingProvider = ({ + children, + value, +}: { + children: ComponentChildren; + value: Type; +}): VNode => { + return h(Context.Provider, { + value, + children, + }); +}; diff --git a/packages/bank-ui/src/declaration.d.ts b/packages/bank-ui/src/declaration.d.ts new file mode 100644 index 000000000..581cbcd07 --- /dev/null +++ b/packages/bank-ui/src/declaration.d.ts @@ -0,0 +1,35 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +declare module "*.css" { + const mapping: Record; + export default mapping; +} +declare module "*.svg" { + const content: string; + export default content; +} +declare module "*.jpeg" { + const content: string; + export default content; +} +declare module "*.png" { + const content: string; + export default content; +} + +declare const __VERSION__: string; +declare const __GIT_HASH__: string; diff --git a/packages/bank-ui/src/hooks/account.ts b/packages/bank-ui/src/hooks/account.ts new file mode 100644 index 000000000..aa0745253 --- /dev/null +++ b/packages/bank-ui/src/hooks/account.ts @@ -0,0 +1,294 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AccessToken, + TalerCoreBankResultByMethod, + TalerHttpError, + WithdrawalOperationStatus, +} from "@gnu-taler/taler-util"; +import { useEffect, useState } from "preact/hooks"; +import { PAGE_SIZE } from "../utils.js"; +import { useSessionState } from "./session.js"; + +// FIX default import https://github.com/microsoft/TypeScript/issues/49189 +import _useSWR, { SWRHook, mutate } from "swr"; +import { useBankCoreApiContext } from "../context/config.js"; +const useSWR = _useSWR as unknown as SWRHook; + +export interface InstanceTemplateFilter { + // FIXME: add filter to the template list + position?: string; +} + +export function revalidateAccountDetails() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "getAccount", + undefined, + { revalidate: true }, + ); +} + +export function useAccountDetails(account: string) { + const { state: credentials } = useSessionState(); + const { bank: api } = useBankCoreApiContext(); + + async function fetcher([username, token]: [string, AccessToken]) { + return await api.getAccount({ username, token }); + } + const token = + credentials.status !== "loggedIn" ? undefined : credentials.token; + const { data, error } = useSWR< + TalerCoreBankResultByMethod<"getAccount">, + TalerHttpError + >([account, token, "getAccount"], fetcher, {}); + + if (data) return data; + if (error) return error; + return undefined; +} + +export function revalidateWithdrawalDetails() { + return mutate((key) => Array.isArray(key) && key[key.length - 1] === "getWithdrawalById", undefined, { revalidate: true }); +} + +export function useWithdrawalDetails(wid: string) { + const { bank: api } = useBankCoreApiContext(); + const [latestStatus, setLatestStatus] = useState(); + + async function fetcher([wid, old_state]: [ + string, + WithdrawalOperationStatus | undefined, + ]) { + return await api.getWithdrawalById( + wid, + old_state === undefined ? undefined : { old_state, timeoutMs: 15000 }, + ); + } + + const { data, error } = useSWR< + TalerCoreBankResultByMethod<"getWithdrawalById">, + TalerHttpError + >([wid, latestStatus, "getWithdrawalById"], fetcher, { + refreshInterval: 3000, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }); + + const currentStatus = + data !== undefined && data.type === "ok" ? data.body.status : undefined; + + useEffect(() => { + if (currentStatus !== undefined && currentStatus !== latestStatus) { + setLatestStatus(currentStatus); + } + }, [currentStatus]); + + if (data) return data; + if (error) return error; + return undefined; +} + +export function revalidateTransactionDetails() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "getTransactionById", undefined, { revalidate: true } + ); +} +export function useTransactionDetails(account: string, tid: number) { + const { state: credentials } = useSessionState(); + const token = + credentials.status !== "loggedIn" ? undefined : credentials.token; + const { bank: api } = useBankCoreApiContext(); + + async function fetcher([username, token, txid]: [ + string, + AccessToken, + number, + ]) { + return await api.getTransactionById({ username, token }, txid); + } + + const { data, error } = useSWR< + TalerCoreBankResultByMethod<"getTransactionById">, + TalerHttpError + >([account, token, tid, "getTransactionById"], fetcher, { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }); + + if (data) return data; + if (error) return error; + return undefined; +} + +export async function revalidatePublicAccounts() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "getPublicAccounts", undefined, { revalidate: true } + ); +} +export function usePublicAccounts( + filterAccount: string | undefined, + initial?: number, +) { + const [offset, setOffset] = useState(initial); + + const { bank: api } = useBankCoreApiContext(); + + async function fetcher([account, txid]: [ + string | undefined, + number | undefined, + ]) { + return await api.getPublicAccounts( + { account }, + { + limit: PAGE_SIZE, + offset: txid ? String(txid) : undefined, + order: "asc", + }, + ); + } + + const { data, error } = useSWR< + TalerCoreBankResultByMethod<"getPublicAccounts">, + TalerHttpError + >([filterAccount, offset, "getPublicAccounts"], fetcher, { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }); + + const isLastPage = + data && data.type === "ok" && data.body.public_accounts.length <= PAGE_SIZE; + const isFirstPage = !offset; + + const result = data && data.type == "ok" ? structuredClone(data.body.public_accounts) : [] + if (result.length == PAGE_SIZE+1) { + result.pop() + } + const pagination = { + result, + isLastPage, + isFirstPage, + loadNext: () => { + if (!result.length) return; + setOffset(result[result.length - 1].row_id); + }, + loadFirst: () => { + setOffset(0); + }, + }; + + // const public_accountslist = data?.type !== "ok" ? [] : data.body.public_accounts; + if (data) { + return { ok: true, data: data.body, ...pagination }; + } + if (error) { + return error; + } + return undefined; +} + +export function revalidateTransactions() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "getTransactions", + undefined, + { revalidate: true }, + ); +} +export function useTransactions(account: string, initial?: number) { + const { state: credentials } = useSessionState(); + const token = + credentials.status !== "loggedIn" ? undefined : credentials.token; + + const [offset, setOffset] = useState(initial); + const { bank: api } = useBankCoreApiContext(); + + async function fetcher([username, token, txid]: [ + string, + AccessToken, + number | undefined, + ]) { + return await api.getTransactions( + { username, token }, + { + limit: PAGE_SIZE +1 , + offset: txid ? String(txid) : undefined, + order: "dec", + }, + ); + } + + const { data, error } = useSWR< + TalerCoreBankResultByMethod<"getTransactions">, + TalerHttpError + >([account, token, offset, "getTransactions"], fetcher, { + refreshInterval: 0, + refreshWhenHidden: false, + refreshWhenOffline: false, + // revalidateOnMount: false, + revalidateIfStale: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + }); + + const isLastPage = + data && data.type === "ok" && data.body.transactions.length <= PAGE_SIZE; + const isFirstPage = !offset; + + const result = data && data.type == "ok" ? structuredClone(data.body.transactions) : [] + if (result.length == PAGE_SIZE+1) { + result.pop() + } + const pagination = { + result, + isLastPage, + isFirstPage, + loadNext: () => { + if (!result.length) return; + setOffset(result[result.length - 1].row_id); + }, + loadFirst: () => { + setOffset(0); + }, + }; + + if (data) { + return { ok: true, data, ...pagination }; + } + if (error) { + return error; + } + return undefined; +} diff --git a/packages/bank-ui/src/hooks/bank-state.ts b/packages/bank-ui/src/hooks/bank-state.ts new file mode 100644 index 000000000..83bb009cf --- /dev/null +++ b/packages/bank-ui/src/hooks/bank-state.ts @@ -0,0 +1,188 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AbsoluteTime, + Codec, + TalerCorebankApi, + buildCodecForObject, + buildCodecForUnion, + codecForAbsoluteTime, + codecForAny, + codecForConstString, + codecForString, + codecForTanTransmission, + codecOptional, +} from "@gnu-taler/taler-util"; +import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser"; +import { AppLocation } from "../route.js"; + +export type ChallengeInProgess = + | DeleteAccountChallenge + | UpdateAccountChallenge + | UpdatePasswordChallenge + | CreateTransactionChallenge + | ConfirmWithdrawalChallenge + | CashoutChallenge; + +type BaseChallenge = { + id: string; + operation: OpType; + sent: AbsoluteTime; + location: AppLocation; + info?: TalerCorebankApi.TanTransmission; + request: ReqType; +}; + +type DeleteAccountChallenge = BaseChallenge<"delete-account", string>; +type UpdateAccountChallenge = BaseChallenge< + "update-account", + TalerCorebankApi.AccountReconfiguration +>; +type UpdatePasswordChallenge = BaseChallenge< + "update-password", + TalerCorebankApi.AccountPasswordChange +>; +type CreateTransactionChallenge = BaseChallenge< + "create-transaction", + TalerCorebankApi.CreateTransactionRequest +>; +type ConfirmWithdrawalChallenge = BaseChallenge<"confirm-withdrawal", string>; +type CashoutChallenge = BaseChallenge< + "create-cashout", + TalerCorebankApi.CashoutRequest +>; + +const codecForChallengeUpdatePassword = (): Codec => + buildCodecForObject() + .property("operation", codecForConstString("update-password")) + .property("id", codecForString()) + .property("location", codecForAppLocation()) + .property("sent", codecForAbsoluteTime) + .property("info", codecOptional(codecForTanTransmission())) + .property("request", codecForAny()) + .build("UpdatePasswordChallenge"); + +const codecForChallengeDeleteAccount = (): Codec => + buildCodecForObject() + .property("operation", codecForConstString("delete-account")) + .property("id", codecForString()) + .property("location", codecForAppLocation()) + .property("sent", codecForAbsoluteTime) + .property("request", codecForString()) + .property("info", codecOptional(codecForTanTransmission())) + .build("DeleteAccountChallenge"); + +const codecForChallengeUpdateAccount = (): Codec => + buildCodecForObject() + .property("operation", codecForConstString("update-account")) + .property("id", codecForString()) + .property("location", codecForAppLocation()) + .property("sent", codecForAbsoluteTime) + .property("info", codecOptional(codecForTanTransmission())) + .property("request", codecForAny()) + .build("UpdateAccountChallenge"); + +const codecForChallengeCreateTransaction = + (): Codec => + buildCodecForObject() + .property("operation", codecForConstString("create-transaction")) + .property("id", codecForString()) + .property("location", codecForAppLocation()) + .property("sent", codecForAbsoluteTime) + .property("info", codecOptional(codecForTanTransmission())) + .property("request", codecForAny()) + .build("CreateTransactionChallenge"); + +const codecForChallengeConfirmWithdrawal = + (): Codec => + buildCodecForObject() + .property("operation", codecForConstString("confirm-withdrawal")) + .property("id", codecForString()) + .property("location", codecForAppLocation()) + .property("sent", codecForAbsoluteTime) + .property("info", codecOptional(codecForTanTransmission())) + .property("request", codecForString()) + .build("ConfirmWithdrawalChallenge"); + +const codecForAppLocation = codecForString as () => Codec + +const codecForChallengeCashout = (): Codec => + buildCodecForObject() + .property("operation", codecForConstString("create-cashout")) + .property("id", codecForString()) + .property("location", codecForAppLocation()) + .property("sent", codecForAbsoluteTime) + .property("info", codecOptional(codecForTanTransmission())) + .property("request", codecForAny()) + .build("CashoutChallenge"); + +const codecForChallenge = (): Codec => + buildCodecForUnion() + .discriminateOn("operation") + .alternative("confirm-withdrawal", codecForChallengeConfirmWithdrawal()) + .alternative("create-cashout", codecForChallengeCashout()) + .alternative("create-transaction", codecForChallengeCreateTransaction()) + .alternative("delete-account", codecForChallengeDeleteAccount()) + .alternative("update-account", codecForChallengeUpdateAccount()) + .alternative("update-password", codecForChallengeUpdatePassword()) + .build("ChallengeInProgess"); + + + +interface BankState { + currentWithdrawalOperationId: string | undefined; + currentChallenge: ChallengeInProgess | undefined; +} + +export const codecForBankState = (): Codec => + buildCodecForObject() + .property("currentWithdrawalOperationId", codecOptional(codecForString())) + .property("currentChallenge", codecOptional(codecForChallenge())) + .build("BankState"); + +const defaultBankState: BankState = { + currentWithdrawalOperationId: undefined, + currentChallenge: undefined, +}; + +const BANK_STATE_KEY = buildStorageKey("bank-app-state", codecForBankState()); + +/** + * Client state saved in local storage. + * + * This information is saved in the client because + * the backend server session API is not enough. + * + * @returns tuple of [state, update(), reset()] + */ +export function useBankState(): [ + Readonly, + (key: T, value: BankState[T]) => void, + () => void, +] { + const { value, update } = useLocalStorage(BANK_STATE_KEY, defaultBankState); + + function updateField(k: T, v: BankState[T]) { + const newValue = { ...value, [k]: v }; + update(newValue); + } + function reset() { + update(defaultBankState); + } + return [value, updateField, reset]; +} + diff --git a/packages/bank-ui/src/hooks/form.ts b/packages/bank-ui/src/hooks/form.ts new file mode 100644 index 000000000..26354b108 --- /dev/null +++ b/packages/bank-ui/src/hooks/form.ts @@ -0,0 +1,100 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { AmountJson, TalerBankConversionApi, TranslatedString } from "@gnu-taler/taler-util"; +import { useState } from "preact/hooks"; + +export type UIField = { + value: string | undefined; + onUpdate: (s: string) => void; + error: TranslatedString | undefined; +} + +type FormHandler = { + [k in keyof T]?: + T[k] extends string ? UIField : + T[k] extends AmountJson ? UIField : + FormHandler; +} + +export type FormValues = { + [k in keyof T]: + T[k] extends string ? (string | undefined) : + T[k] extends AmountJson ? (string | undefined) : + FormValues; +} + +export type RecursivePartial = { + [k in keyof T]?: + T[k] extends string ? (string) : + T[k] extends AmountJson ? (AmountJson) : + RecursivePartial; +} + +export type FormErrors = { + [k in keyof T]?: + T[k] extends string ? (TranslatedString) : + T[k] extends AmountJson ? (TranslatedString) : + FormErrors; +} + +export type FormStatus = { + status: "ok", + result: T, + errors: undefined, +} | { + status: "fail", + result: RecursivePartial, + errors: FormErrors, +} + + +function constructFormHandler(form: FormValues, updateForm: (d: FormValues) => void, errors: FormErrors | undefined): FormHandler { + const keys = (Object.keys(form) as Array) + + const handler = keys.reduce((prev, fieldName) => { + const currentValue: any = form[fieldName]; + const currentError: any = errors ? errors[fieldName] : undefined; + function updater(newValue: any) { + updateForm({ ...form, [fieldName]: newValue }) + } + if (typeof currentValue === "object") { + const group = constructFormHandler(currentValue, updater, currentError) + // @ts-expect-error asdasd + prev[fieldName] = group + return prev; + } + const field: UIField = { + error: currentError, + value: currentValue, + onUpdate: updater + } + // @ts-expect-error asdasd + prev[fieldName] = field + return prev + }, {} as FormHandler) + + return handler; +} + +export function useFormState(defaultValue: FormValues, check: (f: FormValues) => FormStatus): [FormHandler, FormStatus] { + const [form, updateForm] = useState>(defaultValue) + + const status = check(form) + const handler = constructFormHandler(form, updateForm, status.errors) + + return [handler, status] +} \ No newline at end of file diff --git a/packages/bank-ui/src/hooks/preferences.ts b/packages/bank-ui/src/hooks/preferences.ts new file mode 100644 index 000000000..454dc8d80 --- /dev/null +++ b/packages/bank-ui/src/hooks/preferences.ts @@ -0,0 +1,112 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + Codec, + TranslatedString, + buildCodecForObject, + codecForBoolean, + codecForNumber, +} from "@gnu-taler/taler-util"; +import { + buildStorageKey, + useLocalStorage, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; + +interface Preferences { + showWithdrawalSuccess: boolean; + showDemoDescription: boolean; + showInstallWallet: boolean; + maxWithdrawalAmount: number; + fastWithdrawal: boolean; + showDebugInfo: boolean; +} + +export const codecForPreferences = (): Codec => + buildCodecForObject() + .property("showWithdrawalSuccess", codecForBoolean()) + .property("showDemoDescription", codecForBoolean()) + .property("showInstallWallet", codecForBoolean()) + .property("fastWithdrawal", codecForBoolean()) + .property("showDebugInfo", codecForBoolean()) + .property("maxWithdrawalAmount", codecForNumber()) + .build("Settings"); + +const defaultPreferences: Preferences = { + showWithdrawalSuccess: true, + showDemoDescription: true, + showInstallWallet: true, + maxWithdrawalAmount: 25, + fastWithdrawal: false, + showDebugInfo: false, +}; + +const BANK_PREFERENCES_KEY = buildStorageKey( + "bank-preferences", + codecForPreferences(), +); +/** + * User preferences. + * + * @returns tuple of [state, update()] + */ +export function usePreferences(): [ + Readonly, + (key: T, value: Preferences[T]) => void, +] { + const { value, update } = useLocalStorage( + BANK_PREFERENCES_KEY, + defaultPreferences, + ); + + function updateField(k: T, v: Preferences[T]) { + const newValue = { ...value, [k]: v }; + update(newValue); + } + return [value, updateField]; +} + +export function getAllBooleanPreferences(): Array { + return [ + "fastWithdrawal", + "showDebugInfo", + "showDemoDescription", + "showInstallWallet", + "showWithdrawalSuccess", + ]; +} + +export function getLabelForPreferences( + k: keyof Preferences, + i18n: ReturnType["i18n"], +): TranslatedString { + switch (k) { + case "maxWithdrawalAmount": + return i18n.str`Max withdrawal amount`; + case "showWithdrawalSuccess": + return i18n.str`Show withdrawal confirmation`; + case "showDemoDescription": + return i18n.str`Show demo description`; + case "showInstallWallet": + return i18n.str`Show install wallet first`; + case "fastWithdrawal": + return i18n.str`Use fast withdrawal form`; + case "showDebugInfo": + return i18n.str`Show debug info`; + } +} + diff --git a/packages/bank-ui/src/hooks/regional.ts b/packages/bank-ui/src/hooks/regional.ts new file mode 100644 index 000000000..bf948d293 --- /dev/null +++ b/packages/bank-ui/src/hooks/regional.ts @@ -0,0 +1,484 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { PAGE_SIZE } from "../utils.js"; +import { useSessionState } from "./session.js"; + +import { + AccessToken, + AmountJson, + Amounts, + HttpStatusCode, + OperationOk, + TalerBankConversionResultByMethod, + TalerCoreBankErrorsByMethod, + TalerCoreBankResultByMethod, + TalerCorebankApi, + TalerError, + TalerHttpError, + opFixedSuccess, +} from "@gnu-taler/taler-util"; +import _useSWR, { SWRHook, mutate } from "swr"; +import { useBankCoreApiContext } from "../context/config.js"; +import { useState } from "preact/hooks"; + +// FIX default import https://github.com/microsoft/TypeScript/issues/49189 +const useSWR = _useSWR as unknown as SWRHook; + +export type TransferCalculation = { + debit: AmountJson; + credit: AmountJson; + beforeFee: AmountJson; +} | "amount-is-too-small"; +type EstimatorFunction = ( + amount: AmountJson, + fee: AmountJson, +) => Promise; + +type ConversionEstimators = { + estimateByCredit: EstimatorFunction; + estimateByDebit: EstimatorFunction; +}; + +export function revalidateConversionInfo() { + return mutate( + (key) => + Array.isArray(key) && key[key.length - 1] === "getConversionInfoAPI", + ); +} +export function useConversionInfo() { + const { conversion, config } = useBankCoreApiContext(); + + async function fetcher() { + return await conversion.getConfig(); + } + const { data, error } = useSWR< + TalerBankConversionResultByMethod<"getConfig">, + TalerHttpError + >(!config.allow_conversion ? undefined : ["getConversionInfoAPI"], fetcher, { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }); + + if (data) return data; + if (error) return error; + return undefined; +} + +export function useCashinEstimator(): ConversionEstimators { + const { conversion } = useBankCoreApiContext(); + return { + estimateByCredit: async (fiatAmount, fee) => { + const resp = await conversion.getCashinRate({ + credit: fiatAmount, + }); + if (resp.type === "fail") { + switch (resp.case) { + case HttpStatusCode.Conflict: { + return "amount-is-too-small" + } + // this below can't happen + case HttpStatusCode.NotImplemented: //it should not be able to call this function + case HttpStatusCode.BadRequest: //we are using just one parameter + throw TalerError.fromDetail(resp.detail.code, {}, resp.detail.hint); + } + } + const credit = Amounts.parseOrThrow(resp.body.amount_credit); + const debit = Amounts.parseOrThrow(resp.body.amount_debit); + const beforeFee = Amounts.sub(credit, fee).amount; + + return { + debit, + beforeFee, + credit, + }; + }, + estimateByDebit: async (regionalAmount, fee) => { + const resp = await conversion.getCashinRate({ + debit: regionalAmount, + }); + if (resp.type === "fail") { + switch (resp.case) { + case HttpStatusCode.Conflict: { + return "amount-is-too-small" + } + // this below can't happen + case HttpStatusCode.NotImplemented: //it should not be able to call this function + case HttpStatusCode.BadRequest: //we are using just one parameter + throw TalerError.fromDetail(resp.detail.code, {}, resp.detail.hint); + } + } + const credit = Amounts.parseOrThrow(resp.body.amount_credit); + const debit = Amounts.parseOrThrow(resp.body.amount_debit); + const beforeFee = Amounts.add(credit, fee).amount; + + return { + debit, + beforeFee, + credit, + }; + }, + }; +} + +export function useCashoutEstimator(): ConversionEstimators { + const { bank, conversion } = useBankCoreApiContext(); + return { + estimateByCredit: async (fiatAmount, fee) => { + const resp = await conversion.getCashoutRate({ + credit: fiatAmount, + }); + if (resp.type === "fail") { + switch (resp.case) { + case HttpStatusCode.Conflict: { + return "amount-is-too-small" + } + // this below can't happen + case HttpStatusCode.NotImplemented: //it should not be able to call this function + case HttpStatusCode.BadRequest: //we are using just one parameter + throw TalerError.fromDetail(resp.detail.code, {}, resp.detail.hint); + } + } + const credit = Amounts.parseOrThrow(resp.body.amount_credit); + const debit = Amounts.parseOrThrow(resp.body.amount_debit); + const beforeFee = Amounts.sub(credit, fee).amount; + + return { + debit, + beforeFee, + credit, + }; + }, + estimateByDebit: async (regionalAmount, fee) => { + const resp = await conversion.getCashoutRate({ + debit: regionalAmount, + }); + if (resp.type === "fail") { + switch (resp.case) { + case HttpStatusCode.Conflict: { + return "amount-is-too-small" + } + // this below can't happen + case HttpStatusCode.NotImplemented: //it should not be able to call this function + case HttpStatusCode.BadRequest: //we are using just one parameter + throw TalerError.fromDetail(resp.detail.code, {}, resp.detail.hint); + } + } + const credit = Amounts.parseOrThrow(resp.body.amount_credit); + const debit = Amounts.parseOrThrow(resp.body.amount_debit); + const beforeFee = Amounts.add(credit, fee).amount; + + return { + debit, + beforeFee, + credit, + }; + }, + }; +} + +/** + * @deprecated use useCashoutEstimator + */ +export function useEstimator(): ConversionEstimators { + return useCashoutEstimator() +} + +export async function revalidateBusinessAccounts() { + return mutate((key) => Array.isArray(key) && key[key.length - 1] === "getAccounts", undefined, { revalidate: true }); +} +export function useBusinessAccounts() { + const { state: credentials } = useSessionState(); + const token = + credentials.status !== "loggedIn" ? undefined : credentials.token; + const { bank: api } = useBankCoreApiContext(); + + const [offset, setOffset] = useState(); + + function fetcher([token, offset]: [AccessToken, number]) { + // FIXME: add account name filter + return api.getAccounts( + token, + {}, + { + limit: PAGE_SIZE + 1, + offset: String(offset), + order: "asc", + }, + ); + } + + const { data, error } = useSWR< + TalerCoreBankResultByMethod<"getAccounts">, + TalerHttpError + >([token, offset ?? 0, "getAccounts"], fetcher, { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }); + + const isLastPage = + data && data.type === "ok" && data.body.accounts.length <= PAGE_SIZE; + const isFirstPage = !offset; + + const result = data && data.type == "ok" ? structuredClone(data.body.accounts) : [] + if (result.length == PAGE_SIZE + 1) { + result.pop() + } + const pagination = { + result, + isLastPage, + isFirstPage, + loadNext: () => { + if (!result.length) return; + setOffset(result[result.length - 1].row_id); + }, + loadFirst: () => { + setOffset(0); + }, + }; + + if (data) return { ok: true, data, ...pagination }; + if (error) return error; + return undefined; +} + +type CashoutWithId = TalerCorebankApi.CashoutStatusResponse & { id: number }; +function notUndefined(c: CashoutWithId | undefined): c is CashoutWithId { + return c !== undefined; +} +export function revalidateOnePendingCashouts() { + return mutate( + (key) => + Array.isArray(key) && key[key.length - 1] === "useOnePendingCashouts", undefined, { revalidate: true } + ); +} +export function useOnePendingCashouts(account: string) { + const { state: credentials } = useSessionState(); + const { bank: api, config } = useBankCoreApiContext(); + const token = + credentials.status !== "loggedIn" ? undefined : credentials.token; + + async function fetcher([username, token]: [string, AccessToken]) { + const list = await api.getAccountCashouts({ username, token }); + if (list.type !== "ok") { + return list; + } + const pendingCashout = list.body.cashouts.length > 0 ? list.body.cashouts[0] : undefined; + if (!pendingCashout) return opFixedSuccess(undefined); + const cashoutInfo = await api.getCashoutById( + { username, token }, + pendingCashout.cashout_id, + ); + if (cashoutInfo.type !== "ok") { + return cashoutInfo; + } + return opFixedSuccess({ + ...cashoutInfo.body, + id: pendingCashout.cashout_id, + }); + } + + const { data, error } = useSWR< + | OperationOk + | TalerCoreBankErrorsByMethod<"getAccountCashouts"> + | TalerCoreBankErrorsByMethod<"getCashoutById">, + TalerHttpError + >( + !config.allow_conversion + ? undefined + : [account, token, "useOnePendingCashouts"], + fetcher, + { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }, + ); + + if (data) return data; + if (error) return error; + return undefined; +} + +export function revalidateCashouts() { + return mutate((key) => Array.isArray(key) && key[key.length - 1] === "useCashouts"); +} +export function useCashouts(account: string) { + const { state: credentials } = useSessionState(); + const { bank: api, config } = useBankCoreApiContext(); + const token = + credentials.status !== "loggedIn" ? undefined : credentials.token; + + async function fetcher([username, token]: [string, AccessToken]) { + const list = await api.getAccountCashouts({ username, token }); + if (list.type !== "ok") { + return list; + } + const all: Array = await Promise.all( + list.body.cashouts.map(async (c) => { + const r = await api.getCashoutById({ username, token }, c.cashout_id); + if (r.type === "fail") { + return undefined; + } + return { ...r.body, id: c.cashout_id }; + }), + ); + const cashouts = all.filter(notUndefined); + return { type: "ok" as const, body: { cashouts }}; + } + const { data, error } = useSWR< + | OperationOk<{ cashouts: CashoutWithId[] }> + | TalerCoreBankErrorsByMethod<"getAccountCashouts">, + TalerHttpError + >( + !config.allow_conversion ? undefined : [account, token, "useCashouts"], + fetcher, + { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }, + ); + + if (data) return data; + if (error) return error; + return undefined; +} + +export function revalidateCashoutDetails() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "getCashoutById", undefined, { revalidate: true } + ); +} +export function useCashoutDetails(cashoutId: number | undefined) { + const { state: credentials } = useSessionState(); + const creds = credentials.status !== "loggedIn" ? undefined : credentials; + const { bank: api } = useBankCoreApiContext(); + + async function fetcher([username, token, id]: [string, AccessToken, number]) { + return api.getCashoutById({ username, token }, id); + } + + const { data, error } = useSWR< + TalerCoreBankResultByMethod<"getCashoutById">, + TalerHttpError + >( + cashoutId === undefined + ? undefined + : [creds?.username, creds?.token, cashoutId, "getCashoutById"], + fetcher, + { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }, + ); + + if (data) return data; + if (error) return error; + return undefined; +} +export type MonitorMetrics = { + lastHour: TalerCoreBankResultByMethod<"getMonitor">; + lastDay: TalerCoreBankResultByMethod<"getMonitor">; + lastMonth: TalerCoreBankResultByMethod<"getMonitor">; +}; + +export type LastMonitor = { + current: TalerCoreBankResultByMethod<"getMonitor">; + previous: TalerCoreBankResultByMethod<"getMonitor">; +}; +export function revalidateLastMonitorInfo() { + return mutate( + (key) => Array.isArray(key) && key[key.length - 1] === "useLastMonitorInfo", undefined, { revalidate: true } + ); +} +export function useLastMonitorInfo( + currentMoment: number, + previousMoment: number, + timeframe: TalerCorebankApi.MonitorTimeframeParam, +) { + const { bank: api } = useBankCoreApiContext(); + const { state: credentials } = useSessionState(); + const token = + credentials.status !== "loggedIn" ? undefined : credentials.token; + + async function fetcher([token, timeframe]: [ + AccessToken, + TalerCorebankApi.MonitorTimeframeParam, + ]) { + const [current, previous] = await Promise.all([ + api.getMonitor(token, { timeframe, which: currentMoment }), + api.getMonitor(token, { timeframe, which: previousMoment }), + ]); + return { + current, + previous, + }; + } + + const { data, error } = useSWR( + !token ? undefined : [token, timeframe, "useLastMonitorInfo"], + fetcher, + { + refreshInterval: 0, + refreshWhenHidden: false, + revalidateOnFocus: false, + revalidateOnReconnect: false, + refreshWhenOffline: false, + errorRetryCount: 0, + errorRetryInterval: 1, + shouldRetryOnError: false, + keepPreviousData: true, + }, + ); + + if (data) return data; + if (error) return error; + return undefined; +} diff --git a/packages/bank-ui/src/hooks/session.ts b/packages/bank-ui/src/hooks/session.ts new file mode 100644 index 000000000..35f87e1be --- /dev/null +++ b/packages/bank-ui/src/hooks/session.ts @@ -0,0 +1,131 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AccessToken, + Codec, + buildCodecForObject, + buildCodecForUnion, + codecForBoolean, + codecForConstString, + codecForString, +} from "@gnu-taler/taler-util"; +import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser"; +import { mutate } from "swr"; + +/** + * Has the information to reach and + * authenticate at the bank's backend. + */ +export type SessionState = LoggedIn | LoggedOut | Expired; + +interface LoggedIn { + status: "loggedIn"; + isUserAdministrator: boolean; + username: string; + token: AccessToken; +} +interface Expired { + status: "expired"; + isUserAdministrator: boolean; + username: string; +} +interface LoggedOut { + status: "loggedOut"; +} + +export const codecForSessionStateLoggedIn = (): Codec => + buildCodecForObject() + .property("status", codecForConstString("loggedIn")) + .property("username", codecForString()) + .property("token", codecForString() as Codec) + .property("isUserAdministrator", codecForBoolean()) + .build("SessionState.LoggedIn"); + +export const codecForSessionStateExpired = (): Codec => + buildCodecForObject() + .property("status", codecForConstString("expired")) + .property("username", codecForString()) + .property("isUserAdministrator", codecForBoolean()) + .build("SessionState.Expired"); + +export const codecForSessionStateLoggedOut = (): Codec => + buildCodecForObject() + .property("status", codecForConstString("loggedOut")) + .build("SessionState.LoggedOut"); + +export const codecForSessionState = (): Codec => + buildCodecForUnion() + .discriminateOn("status") + .alternative("loggedIn", codecForSessionStateLoggedIn()) + .alternative("loggedOut", codecForSessionStateLoggedOut()) + .alternative("expired", codecForSessionStateExpired()) + .build("SessionState"); + +export const defaultState: SessionState = { + status: "loggedOut", +}; + +export interface SessionStateHandler { + state: SessionState; + logOut(): void; + expired(): void; + logIn(info: { username: string; token: AccessToken }): void; +} + +const SESSION_STATE_KEY = buildStorageKey("bank-state", codecForSessionState()); + +/** + * Return getters and setters for + * login credentials and backend's + * base URL. + */ +export function useSessionState(): SessionStateHandler { + const { value: state, update } = useLocalStorage( + SESSION_STATE_KEY, + defaultState, + ); + + return { + state, + logOut() { + update(defaultState); + }, + expired() { + if (state.status === "loggedOut") return; + const nextState: SessionState = { + status: "expired", + username: state.username, + isUserAdministrator: state.username === "admin", + }; + update(nextState); + }, + logIn(info) { + // admin is defined by the username + const nextState: SessionState = { + status: "loggedIn", + ...info, + isUserAdministrator: info.username === "admin", + }; + update(nextState); + cleanAllCache(); + }, + }; +} + +function cleanAllCache(): void { + mutate(() => true, undefined, { revalidate: false }); +} diff --git a/packages/bank-ui/src/i18n/bank.pot b/packages/bank-ui/src/i18n/bank.pot new file mode 100644 index 000000000..1f11b8f10 --- /dev/null +++ b/packages/bank-ui/src/i18n/bank.pot @@ -0,0 +1,1740 @@ +# This file is part of GNU Taler +# (C) 2022-2024 Taler Systems S.A. +# +# GNU Taler is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# +# GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Taler; see the file COPYING. If not, see +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Taler Bank\n" +"Report-Msgid-Bugs-To: taler@gnu.org\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +#: src/utils.ts:137 +#, c-format +msgid "Operation failed, please report" +msgstr "" + +#: src/utils.ts:156 +#, c-format +msgid "Request timeout" +msgstr "" + +#: src/utils.ts:165 +#, c-format +msgid "Request throttled" +msgstr "" + +#: src/utils.ts:174 +#, c-format +msgid "Malformed response" +msgstr "" + +#: src/utils.ts:183 +#, c-format +msgid "Network error" +msgstr "" + +#: src/utils.ts:192 +#, c-format +msgid "Unexpected request error" +msgstr "" + +#: src/utils.ts:201 +#, c-format +msgid "Unexpected error" +msgstr "" + +#: src/utils.ts:377 +#, c-format +msgid "IBAN numbers usually have more that 4 digits" +msgstr "" + +#: src/utils.ts:379 +#, c-format +msgid "IBAN numbers usually have less that 34 digits" +msgstr "" + +#: src/utils.ts:387 +#, c-format +msgid "IBAN country code not found" +msgstr "" + +#: src/utils.ts:401 +#, c-format +msgid "IBAN number is not valid, checksum is wrong" +msgstr "" + +#: src/context/config.ts:136 +#, c-format +msgid "" +"the bank backend is not supported. supported version \"%1$s\", server version " +"\"%2$s\"" +msgstr "" + +#: src/hooks/preferences.ts:55 +#, c-format +msgid "Max withdrawal amount" +msgstr "" + +#: src/hooks/preferences.ts:57 +#, c-format +msgid "Show withdrawal confirmation" +msgstr "" + +#: src/hooks/preferences.ts:59 +#, c-format +msgid "Show demo description" +msgstr "" + +#: src/hooks/preferences.ts:61 +#, c-format +msgid "Show install wallet first" +msgstr "" + +#: src/hooks/preferences.ts:63 +#, c-format +msgid "Use fast withdrawal form" +msgstr "" + +#: src/hooks/preferences.ts:65 +#, c-format +msgid "Show debug info" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:90 +#, c-format +msgid "required" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:92 +#, c-format +msgid "IBAN should have just uppercased letters and numbers" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:98 +#, c-format +msgid "not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:100 +#, c-format +msgid "should be greater than 0" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:102 +#, c-format +msgid "balance is not enough" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:112 +#, c-format +msgid "does not follow the pattern" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:114 +#, c-format +msgid "only \"IBAN\" target are supported" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:116 +#, c-format +msgid "use the \"amount\" parameter to specify the amount to be transferred" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:118 +#, c-format +msgid "the amount is not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:120 +#, c-format +msgid "use the \"message\" parameter to specify a reference text for the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:160 +#, c-format +msgid "The request was invalid or the payto://-URI used unacceptable features." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:167 +#, c-format +msgid "Not enough permission to complete the operation." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:174 +#, c-format +msgid "The destination account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:181 +#, c-format +msgid "The origin and the destination of the transfer can't be the same." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:188 +#, c-format +msgid "Your balance is not enough." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:195 +#, c-format +msgid "The origin account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:212 +#, c-format +msgid "Wire transfer created!" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:270 +#, c-format +msgid "Using a form" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:310 +#, c-format +msgid "Import payto:// URI" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:335 +#, c-format +msgid "Recipient" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:359 +#, c-format +msgid "IBAN of the recipient's account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:369 +#, c-format +msgid "Transfer subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:377 +#, c-format +msgid "subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:390 +#, c-format +msgid "some text to identify the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:400 +#, c-format +msgid "Amount" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:415 +#, c-format +msgid "amount to transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:425 +#, c-format +msgid "payto URI:" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:436 +#, c-format +msgid "uniform resource identifier of the target account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:437 +#, c-format +msgid "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:457 +#, c-format +msgid "Cancel" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:471 +#, c-format +msgid "Send" +msgstr "" + +#: src/pages/LoginForm.tsx:71 +#, c-format +msgid "Missing username" +msgstr "" + +#: src/pages/LoginForm.tsx:75 +#, c-format +msgid "Missing password" +msgstr "" + +#: src/pages/LoginForm.tsx:104 +#, c-format +msgid "Wrong credentials for \"%1$s\"" +msgstr "" + +#: src/pages/LoginForm.tsx:111 +#, c-format +msgid "Account not found" +msgstr "" + +#: src/pages/LoginForm.tsx:142 +#, c-format +msgid "Username" +msgstr "" + +#: src/pages/LoginForm.tsx:156 +#, c-format +msgid "username of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:175 +#, c-format +msgid "Password" +msgstr "" + +#: src/pages/LoginForm.tsx:188 +#, c-format +msgid "password of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:223 +#, c-format +msgid "Check" +msgstr "" + +#: src/pages/LoginForm.tsx:237 +#, c-format +msgid "Log in" +msgstr "" + +#: src/pages/LoginForm.tsx:249 +#, c-format +msgid "Register" +msgstr "" + +#: src/components/Transactions/views.tsx:52 +#, c-format +msgid "Latest transactions" +msgstr "" + +#: src/components/Transactions/views.tsx:63 +#, c-format +msgid "Date" +msgstr "" + +#: src/components/Transactions/views.tsx:71 +#, c-format +msgid "Counterpart" +msgstr "" + +#: src/components/Transactions/views.tsx:75 +#, c-format +msgid "Subject" +msgstr "" + +#: src/components/Transactions/views.tsx:111 +#, c-format +msgid "sent" +msgstr "" + +#: src/components/Transactions/views.tsx:112 +#, c-format +msgid "received" +msgstr "" + +#: src/components/Transactions/views.tsx:127 +#, c-format +msgid "invalid value" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "to" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "from" +msgstr "" + +#: src/components/Transactions/views.tsx:202 +#, c-format +msgid "First page" +msgstr "" + +#: src/components/Transactions/views.tsx:209 +#, c-format +msgid "Next" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:86 +#, c-format +msgid "Wire transfer completed!" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:93 +#, c-format +msgid "The withdrawal has been aborted previously and can't be confirmed" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:100 +#, c-format +msgid "" +"The withdrawal operation can't be confirmed before a wallet accepted the " +"transaction." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:107 +#, c-format +msgid "The operation id is invalid." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:114 +#, c-format +msgid "The operation was not found." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:121 +#, c-format +msgid "Your balance is not enough for the operation." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:155 +#, c-format +msgid "The reserve operation has been confirmed previously and can't be aborted" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:186 +#, c-format +msgid "Confirm the withdrawal operation" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:203 +#, c-format +msgid "Wire transfer details" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:217 +#, c-format +msgid "Taler Exchange operator's account" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:228 +#, c-format +msgid "Taler Exchange operator's name" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:317 +#, c-format +msgid "Transfer" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:342 +#, c-format +msgid "Authentication required" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:352 +#, c-format +msgid "This operation was created with other username" +msgstr "" + +#: src/pages/OperationState/views.tsx:209 +#, c-format +msgid "" +"Unauthorized to make the operation, maybe the session has expired or the " +"password changed." +msgstr "" + +#: src/pages/OperationState/views.tsx:218 +#, c-format +msgid "The operation was rejected due to insufficient funds." +msgstr "" + +#: src/pages/OperationState/views.tsx:268 +#, c-format +msgid "Withdrawal confirmed" +msgstr "" + +#: src/pages/OperationState/views.tsx:272 +#, c-format +msgid "" +"The wire transfer to the Taler operator has been initiated. You will soon " +"receive the requested amount in your Taler wallet." +msgstr "" + +#: src/pages/OperationState/views.tsx:287 +#, c-format +msgid "Do not show this again" +msgstr "" + +#: src/pages/OperationState/views.tsx:319 +#, c-format +msgid "Close" +msgstr "" + +#: src/pages/OperationState/views.tsx:399 +#, c-format +msgid "On this device" +msgstr "" + +#: src/pages/OperationState/views.tsx:404 +#, c-format +msgid "" +"If you are using a web browser on desktop you should access your wallet with the " +"GNU Taler WebExtension now or click the link if your WebExtension have the " +"\"Inject Taler support\" option enabled." +msgstr "" + +#: src/pages/OperationState/views.tsx:417 +#, c-format +msgid "Start" +msgstr "" + +#: src/pages/OperationState/views.tsx:426 +#, c-format +msgid "On a mobile phone" +msgstr "" + +#: src/pages/OperationState/views.tsx:431 +#, c-format +msgid "Scan the QR code with your mobile device." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:73 +#, c-format +msgid "There is an operation already" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:75 +#, c-format +msgid "Complete or cancel the operation in" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:84 +#, c-format +msgid "this page" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:101 +#, c-format +msgid "invalid" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:116 +#, c-format +msgid "Server responded with an invalid withdraw URI" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:117 +#, c-format +msgid "Withdraw URI: %1$s" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:132 +#, c-format +msgid "The operation was rejected due to insufficient funds" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:253 +#, c-format +msgid "Continue" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:282 +#, c-format +msgid "Prepare your wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:285 +#, c-format +msgid "" +"After using your wallet you will need to confirm or cancel the operation on this " +"site." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:295 +#, c-format +msgid "You need a GNU Taler Wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:300 +#, c-format +msgid "If you don't have one yet you can follow the instruction in" +msgstr "" + +#: src/pages/PaymentOptions.tsx:55 +#, c-format +msgid "Send money" +msgstr "" + +#: src/pages/PaymentOptions.tsx:73 +#, c-format +msgid "to a %1$s wallet" +msgstr "" + +#: src/pages/PaymentOptions.tsx:95 +#, c-format +msgid "Withdraw digital money into your mobile wallet or browser extension" +msgstr "" + +#: src/pages/PaymentOptions.tsx:109 +#, c-format +msgid "operation ready" +msgstr "" + +#: src/pages/PaymentOptions.tsx:129 +#, c-format +msgid "to another bank account" +msgstr "" + +#: src/pages/PaymentOptions.tsx:149 +#, c-format +msgid "Make a wire transfer to an account with known bank account number." +msgstr "" + +#: src/pages/PaymentOptions.tsx:171 +#, c-format +msgid "Transfer details" +msgstr "" + +#: src/pages/AccountPage/views.tsx:41 +#, c-format +msgid "This is a demo bank" +msgstr "" + +#: src/pages/AccountPage/views.tsx:46 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would work. " +"In addition to using your own bank account, you can also see the transaction " +"history of some %1$s." +msgstr "" + +#: src/pages/AccountPage/views.tsx:53 +#, c-format +msgid "This part of the demo shows how a bank that supports Taler directly would work." +msgstr "" + +#: src/pages/AccountPage/views.tsx:70 +#, c-format +msgid "Pending account delete operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:72 +#, c-format +msgid "Pending account update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:74 +#, c-format +msgid "Pending password update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:76 +#, c-format +msgid "Pending transaction operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:78 +#, c-format +msgid "Pending withdrawal operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:80 +#, c-format +msgid "Pending cashout operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:91 +#, c-format +msgid "You can complete or cancel the operation in" +msgstr "" + +#: src/pages/BankFrame.tsx:64 +#, c-format +msgid "Internal error, please report." +msgstr "" + +#: src/pages/BankFrame.tsx:100 +#, c-format +msgid "Preferences" +msgstr "" + +#: src/pages/BankFrame.tsx:184 +#, c-format +msgid "Welcome, %1$s" +msgstr "" + +#: src/pages/WireTransfer.tsx:79 +#, c-format +msgid "Make a wire transfer" +msgstr "" + +#: src/pages/admin/AccountList.tsx:72 +#, c-format +msgid "Accounts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:75 +#, c-format +msgid "A list of all business account in the bank." +msgstr "" + +#: src/pages/admin/AccountList.tsx:86 +#, c-format +msgid "Create account" +msgstr "" + +#: src/pages/admin/AccountList.tsx:106 +#, c-format +msgid "Name" +msgstr "" + +#: src/pages/admin/AccountList.tsx:110 +#, c-format +msgid "Balance" +msgstr "" + +#: src/pages/admin/AccountList.tsx:112 +#, c-format +msgid "Actions" +msgstr "" + +#: src/pages/admin/AccountList.tsx:151 +#, c-format +msgid "unknown" +msgstr "" + +#: src/pages/admin/AccountList.tsx:170 +#, c-format +msgid "change password" +msgstr "" + +#: src/pages/admin/AccountList.tsx:179 +#, c-format +msgid "cashouts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:189 +#, c-format +msgid "remove" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:168 +#, c-format +msgid "Cashout not implemented" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:184 +#, c-format +msgid "Select a section" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:202 +#, c-format +msgid "Last hour" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:208 +#, c-format +msgid "Last day" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:216 +#, c-format +msgid "Last month" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:222 +#, c-format +msgid "Last year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:310 +#, c-format +msgid "Last Year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:325 +#, c-format +msgid "Trading volume on %1$s compared to %2$s" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:342 +#, c-format +msgid "Cashin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:352 +#, c-format +msgid "Cashout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:364 +#, c-format +msgid "Payin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:374 +#, c-format +msgid "Payout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:388 +#, c-format +msgid "download stats as CSV" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:494 +#, c-format +msgid "Decreased by" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:498 +#, c-format +msgid "Increased by" +msgstr "" + +#: src/pages/DownloadStats.tsx:89 +#, c-format +msgid "Download bank stats" +msgstr "" + +#: src/pages/DownloadStats.tsx:110 +#, c-format +msgid "Include hour metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:143 +#, c-format +msgid "Include day metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:173 +#, c-format +msgid "Include month metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:206 +#, c-format +msgid "Include year metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:239 +#, c-format +msgid "Include table header" +msgstr "" + +#: src/pages/DownloadStats.tsx:272 +#, c-format +msgid "Add previous metric for compare" +msgstr "" + +#: src/pages/DownloadStats.tsx:307 +#, c-format +msgid "Fail on first error" +msgstr "" + +#: src/pages/DownloadStats.tsx:364 +#, c-format +msgid "Download" +msgstr "" + +#: src/pages/DownloadStats.tsx:381 +#, c-format +msgid "downloading... %1$s" +msgstr "" + +#: src/pages/DownloadStats.tsx:399 +#, c-format +msgid "Download completed" +msgstr "" + +#: src/pages/DownloadStats.tsx:400 +#, c-format +msgid "click here to save the file in your computer" +msgstr "" + +#: src/pages/PublicHistoriesPage.tsx:78 +#, c-format +msgid "History of public accounts" +msgstr "" + +#: src/pages/RegistrationPage.tsx:48 +#, c-format +msgid "Currently, the bank is not accepting new registrations!" +msgstr "" + +#: src/pages/RegistrationPage.tsx:87 +#, c-format +msgid "Missing name" +msgstr "" + +#: src/pages/RegistrationPage.tsx:91 +#, c-format +msgid "Use letters and numbers only, and start with a lowercase letter" +msgstr "" + +#: src/pages/RegistrationPage.tsx:107 +#, c-format +msgid "Passwords don't match" +msgstr "" + +#: src/pages/RegistrationPage.tsx:130 +#, c-format +msgid "Server replied with invalid phone or email." +msgstr "" + +#: src/pages/RegistrationPage.tsx:137 +#, c-format +msgid "Registration is disabled because the bank ran out of bonus credit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:144 +#, c-format +msgid "No enough permission to create that account." +msgstr "" + +#: src/pages/RegistrationPage.tsx:151 +#, c-format +msgid "That account id is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:158 +#, c-format +msgid "That username is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:165 +#, c-format +msgid "That username can't be used because is reserved." +msgstr "" + +#: src/pages/RegistrationPage.tsx:172 +#, c-format +msgid "Only admin is allow to set debt limit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:179 +#, c-format +msgid "No information for the selected authentication channel." +msgstr "" + +#: src/pages/RegistrationPage.tsx:186 +#, c-format +msgid "Authentication channel is not supported." +msgstr "" + +#: src/pages/RegistrationPage.tsx:193 +#, c-format +msgid "Only admin can create accounts with second factor authentication." +msgstr "" + +#: src/pages/RegistrationPage.tsx:233 +#, c-format +msgid "Account registration" +msgstr "" + +#: src/pages/RegistrationPage.tsx:315 +#, c-format +msgid "Repeat password" +msgstr "" + +#: src/pages/RegistrationPage.tsx:457 +#, c-format +msgid "Create a random temporary user" +msgstr "" + +#: src/pages/QrCodeSection.tsx:110 +#, c-format +msgid "If you have a Taler wallet installed in this device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:116 +#, c-format +msgid "" +"You will see the details of the operation in your wallet including the fees (if " +"applies). If you still don't have one you can install it following instructions " +"in" +msgstr "" + +#: src/pages/QrCodeSection.tsx:143 +#, c-format +msgid "Withdraw" +msgstr "" + +#: src/pages/QrCodeSection.tsx:152 +#, c-format +msgid "Or if you have the wallet in another device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:157 +#, c-format +msgid "Scan the QR below to start the withdrawal." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:79 +#, c-format +msgid "Operation aborted" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:82 +#, c-format +msgid "" +"The wire transfer to the Taler Exchange operator's account was aborted, your " +"balance was not affected." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:88 +#, c-format +msgid "You can close this page now or continue to the account page." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:147 +#, c-format +msgid "Done" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:158 +#, c-format +msgid "Operation canceled" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:173 +#, c-format +msgid "The operation is marked as 'selected' but some step in the withdrawal failed" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:175 +#, c-format +msgid "The account is selected but no withdrawal identification found." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:188 +#, c-format +msgid "" +"There is a withdrawal identification but no account has been selected or the " +"selected account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:202 +#, c-format +msgid "" +"No withdrawal ID found and no account has been selected or the selected account " +"is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:259 +#, c-format +msgid "Operation not found" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:263 +#, c-format +msgid "" +"This operation is not known by the server. The operation id is wrong or the " +"server deleted the operation information before reaching here." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:278 +#, c-format +msgid "Cotinue to dashboard" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:98 +#, c-format +msgid "Cashout not found. It may be also mean that it was already aborted." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:136 +#, c-format +msgid "Challenge not found." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:143 +#, c-format +msgid "This user is not authorized to complete this challenge." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:150 +#, c-format +msgid "Too many attempts, try another code." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:157 +#, c-format +msgid "The confirmation code is wrong, try again." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:164 +#, c-format +msgid "The operation expired." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:197 +#, c-format +msgid "The operation failed." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:212 +#, c-format +msgid "The operation needs another confirmation to complete." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:224 +#, c-format +msgid "Account delete" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:226 +#, c-format +msgid "Account update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:228 +#, c-format +msgid "Password update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:230 +#, c-format +msgid "Wire transfer" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:232 +#, c-format +msgid "Withdrawal" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:248 +#, c-format +msgid "Confirm the operation" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:271 +#, c-format +msgid "Enter the confirmation code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:313 +#, c-format +msgid "Confirm" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:348 +#, c-format +msgid "Send again" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:359 +#, c-format +msgid "Send code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:369 +#, c-format +msgid "Operation details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:529 +#, c-format +msgid "Challenge details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:536 +#, c-format +msgid "Sent at" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:551 +#, c-format +msgid "To phone" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:553 +#, c-format +msgid "To email" +msgstr "" + +#: src/pages/WithdrawalOperationPage.tsx:49 +#, c-format +msgid "The Withdrawal URI is not valid" +msgstr "" + +#: src/components/Cashouts/views.tsx:100 +#, c-format +msgid "Latest cashouts" +msgstr "" + +#: src/components/Cashouts/views.tsx:111 +#, c-format +msgid "Created" +msgstr "" + +#: src/components/Cashouts/views.tsx:115 +#, c-format +msgid "Total debit" +msgstr "" + +#: src/components/Cashouts/views.tsx:119 +#, c-format +msgid "Total credit" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:70 +#, c-format +msgid "Details" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:74 +#, c-format +msgid "Delete" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:78 +#, c-format +msgid "Credentials" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:82 +#, c-format +msgid "Cashouts" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:95 +#, c-format +msgid "Unable to create a cashout" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:96 +#, c-format +msgid "The bank configuration does not support cashout operations." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:223 +#, c-format +msgid "need to be higher due to fees" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:225 +#, c-format +msgid "the total transfer at destination will be zero" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:250 +#, c-format +msgid "Cashout created" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:272 +#, c-format +msgid "Duplicated request detected, check if the operation succeeded or try again." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:279 +#, c-format +msgid "The conversion rate was incorrectly applied" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:286 +#, c-format +msgid "The account does not have sufficient funds" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:293 +#, c-format +msgid "Cashouts are not supported" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:300 +#, c-format +msgid "Missing cashout URI in the profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:307 +#, c-format +msgid "" +"Sending the confirmation message failed, retry later or contact the " +"administrator." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:339 +#, c-format +msgid "Conversion rate" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:360 +#, c-format +msgid "Fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:374 +#, c-format +msgid "To account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:381 +#, c-format +msgid "No cashout account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:382 +#, c-format +msgid "Before doing a cashout you need to complete your profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:440 +#, c-format +msgid "Amount to send" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:441 +#, c-format +msgid "Amount to receive" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:490 +#, c-format +msgid "Total cost" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:505 +#, c-format +msgid "Balance left" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:520 +#, c-format +msgid "Before fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:533 +#, c-format +msgid "Total cashout transfer" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:553 +#, c-format +msgid "No cashout channel available" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:555 +#, c-format +msgid "" +"Before doing a cashout the server need to provide an second channel to confirm " +"the operation" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:567 +#, c-format +msgid "Second factor authentication" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:598 +#, c-format +msgid "Email" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:600 +#, c-format +msgid "add a email in your profile to enable this option" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:646 +#, c-format +msgid "SMS" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:648 +#, c-format +msgid "add a phone number in your profile to enable this option" +msgstr "" + +#: src/pages/account/CashoutListForAccount.tsx:52 +#, c-format +msgid "Cashout for account %1$s" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:165 +#, c-format +msgid "it doesn't have the pattern of an IBAN number" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:185 +#, c-format +msgid "it doesn't have the pattern of an email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:190 +#, c-format +msgid "should start with +" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:192 +#, c-format +msgid "phone number can't have other than numbers" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:329 +#, c-format +msgid "account identification in the bank" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:365 +#, c-format +msgid "name of the person owner the account" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:374 +#, c-format +msgid "Internal IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:377 +#, c-format +msgid "if empty a random account number will be assigned" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:378 +#, c-format +msgid "account identification for bank transfer" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:423 +#, c-format +msgid "Phone" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:451 +#, c-format +msgid "Cashout IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:452 +#, c-format +msgid "account number where the money is going to be sent when doing cashouts" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:470 +#, c-format +msgid "Max debt" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:494 +#, c-format +msgid "how much is user able to transfer after zero balance" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:508 +#, c-format +msgid "Is this a Taler Exchange?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:549 +#, c-format +msgid "This server doesn't support second factor authentication." +msgstr "" + +#: src/pages/admin/AccountForm.tsx:560 +#, c-format +msgid "Enable second factor authentication" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:596 +#, c-format +msgid "Using email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:654 +#, c-format +msgid "Using SMS" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:691 +#, c-format +msgid "Is this account public?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:719 +#, c-format +msgid "public accounts have their balance publicly accessible" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:100 +#, c-format +msgid "Account updated" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:107 +#, c-format +msgid "The rights to change the account are not sufficient" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:114 +#, c-format +msgid "The username was not found" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:121 +#, c-format +msgid "You can't change the legal name, please contact the your account administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:128 +#, c-format +msgid "You can't change the debt limit, please contact the your account administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:135 +#, c-format +msgid "" +"You can't change the cashout address, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:177 +#, c-format +msgid "Account \"%1$s\"" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:190 +#, c-format +msgid "Change details" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:235 +#, c-format +msgid "Update" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:78 +#, c-format +msgid "password doesn't match" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:95 +#, c-format +msgid "Password changed" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:102 +#, c-format +msgid "Not authorized to change the password, maybe the session is invalid." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:112 +#, c-format +msgid "" +"You need to provide the old password. If you don't have it contact your account " +"administrator." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:117 +#, c-format +msgid "Your current password doesn't match, can't change to a new password." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:149 +#, c-format +msgid "Update password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:167 +#, c-format +msgid "New password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:195 +#, c-format +msgid "Type it again" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:217 +#, c-format +msgid "repeat the same password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:227 +#, c-format +msgid "Current password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:248 +#, c-format +msgid "your current password, for security" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:272 +#, c-format +msgid "Change" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:74 +#, c-format +msgid "" +"Account created with password \"%1$s\". The user must change the password on the " +"next login." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:83 +#, c-format +msgid "Server replied that phone or email is invalid" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:90 +#, c-format +msgid "The rights to perform the operation are not sufficient" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:97 +#, c-format +msgid "Account username is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:104 +#, c-format +msgid "Account id is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:111 +#, c-format +msgid "Bank ran out of bonus credit." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:118 +#, c-format +msgid "Account username can't be used because is reserved" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:160 +#, c-format +msgid "Can't create accounts" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:161 +#, c-format +msgid "Only system admin can create accounts." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:183 +#, c-format +msgid "New business account" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:209 +#, c-format +msgid "Create" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:94 +#, c-format +msgid "Can't delete the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:95 +#, c-format +msgid "" +"The account can't be delete while still holding some balance. First make sure " +"that the owner make a complete cashout." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:117 +#, c-format +msgid "Account removed" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:124 +#, c-format +msgid "No enough permission to delete the account." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:131 +#, c-format +msgid "The username was not found." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:138 +#, c-format +msgid "Can't delete a reserved username." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:145 +#, c-format +msgid "Can't delete an account with balance different than zero." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:170 +#, c-format +msgid "name doesn't match" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:180 +#, c-format +msgid "You are going to remove the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:182 +#, c-format +msgid "This step can't be undone." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:188 +#, c-format +msgid "Deleting account \"%1$s\"" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:206 +#, c-format +msgid "Verification" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:231 +#, c-format +msgid "enter the account name that is going to be deleted" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:49 +#, c-format +msgid "cashout id should be a number" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:65 +#, c-format +msgid "This cashout not found. Maybe already aborted." +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:106 +#, c-format +msgid "Cashout detail" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:139 +#, c-format +msgid "Debited" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:154 +#, c-format +msgid "Credited" +msgstr "" + +#: src/Routing.tsx:140 +#, c-format +msgid "Welcome to %1$s!" +msgstr "" + diff --git a/packages/bank-ui/src/i18n/de.po b/packages/bank-ui/src/i18n/de.po new file mode 100644 index 000000000..b01edc57d --- /dev/null +++ b/packages/bank-ui/src/i18n/de.po @@ -0,0 +1,1778 @@ +# This file is part of GNU Taler +# (C) 2021 Taler Systems S.A. +# GNU Taler is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with +# GNU Taler; see the file COPYING. If not, see +# +msgid "" +msgstr "" +"Project-Id-Version: Taler Wallet\n" +"Report-Msgid-Bugs-To: taler@gnu.org\n" +"POT-Creation-Date: 2016-11-23 00:00+0100\n" +"PO-Revision-Date: 2022-12-26 23:30+0000\n" +"Last-Translator: Stefan Kügel \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.13.1\n" + +#: src/utils.ts:137 +#, c-format +msgid "Operation failed, please report" +msgstr "" + +#: src/utils.ts:156 +#, c-format +msgid "Request timeout" +msgstr "" + +#: src/utils.ts:165 +#, c-format +msgid "Request throttled" +msgstr "" + +#: src/utils.ts:174 +#, c-format +msgid "Malformed response" +msgstr "" + +#: src/utils.ts:183 +#, c-format +msgid "Network error" +msgstr "" + +#: src/utils.ts:192 +#, c-format +msgid "Unexpected request error" +msgstr "" + +#: src/utils.ts:201 +#, c-format +msgid "Unexpected error" +msgstr "" + +#: src/utils.ts:377 +#, c-format +msgid "IBAN numbers usually have more that 4 digits" +msgstr "" + +#: src/utils.ts:379 +#, c-format +msgid "IBAN numbers usually have less that 34 digits" +msgstr "" + +#: src/utils.ts:387 +#, c-format +msgid "IBAN country code not found" +msgstr "" + +#: src/utils.ts:401 +#, c-format +msgid "IBAN number is not valid, checksum is wrong" +msgstr "" + +#: src/context/config.ts:136 +#, c-format +msgid "" +"the bank backend is not supported. supported version \"%1$s\", server " +"version \"%2$s\"" +msgstr "" + +#: src/hooks/preferences.ts:55 +#, c-format +msgid "Max withdrawal amount" +msgstr "" + +#: src/hooks/preferences.ts:57 +#, c-format +msgid "Show withdrawal confirmation" +msgstr "" + +#: src/hooks/preferences.ts:59 +#, c-format +msgid "Show demo description" +msgstr "" + +#: src/hooks/preferences.ts:61 +#, c-format +msgid "Show install wallet first" +msgstr "" + +#: src/hooks/preferences.ts:63 +#, c-format +msgid "Use fast withdrawal form" +msgstr "" + +#: src/hooks/preferences.ts:65 +#, c-format +msgid "Show debug info" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:90 +#, c-format +msgid "required" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:92 +#, c-format +msgid "IBAN should have just uppercased letters and numbers" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:98 +#, c-format +msgid "not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:100 +#, c-format +msgid "should be greater than 0" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:102 +#, c-format +msgid "balance is not enough" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:112 +#, c-format +msgid "does not follow the pattern" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:114 +#, c-format +msgid "only \"IBAN\" target are supported" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:116 +#, c-format +msgid "use the \"amount\" parameter to specify the amount to be transferred" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:118 +#, c-format +msgid "the amount is not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:120 +#, c-format +msgid "" +"use the \"message\" parameter to specify a reference text for the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:160 +#, c-format +msgid "The request was invalid or the payto://-URI used unacceptable features." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:167 +#, c-format +msgid "Not enough permission to complete the operation." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:174 +#, c-format +msgid "The destination account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:181 +#, c-format +msgid "The origin and the destination of the transfer can't be the same." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:188 +#, c-format +msgid "Your balance is not enough." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:195 +#, c-format +msgid "The origin account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:212 +#, c-format +msgid "Wire transfer created!" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:270 +#, c-format +msgid "Using a form" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:310 +#, c-format +msgid "Import payto:// URI" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:335 +#, c-format +msgid "Recipient" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:359 +#, c-format +msgid "IBAN of the recipient's account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:369 +#, c-format +msgid "Transfer subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:377 +#, fuzzy, c-format +msgid "subject" +msgstr "Verwendungszweck" + +#: src/pages/PaytoWireTransferForm.tsx:390 +#, c-format +msgid "some text to identify the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:400 +#, c-format +msgid "Amount" +msgstr "Betrag" + +#: src/pages/PaytoWireTransferForm.tsx:415 +#, fuzzy, c-format +msgid "amount to transfer" +msgstr "Betrag" + +#: src/pages/PaytoWireTransferForm.tsx:425 +#, c-format +msgid "payto URI:" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:436 +#, c-format +msgid "uniform resource identifier of the target account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:437 +#, c-format +msgid "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:457 +#, c-format +msgid "Cancel" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:471 +#, c-format +msgid "Send" +msgstr "" + +#: src/pages/LoginForm.tsx:71 +#, c-format +msgid "Missing username" +msgstr "" + +#: src/pages/LoginForm.tsx:75 +#, c-format +msgid "Missing password" +msgstr "" + +#: src/pages/LoginForm.tsx:104 +#, c-format +msgid "Wrong credentials for \"%1$s\"" +msgstr "" + +#: src/pages/LoginForm.tsx:111 +#, c-format +msgid "Account not found" +msgstr "" + +#: src/pages/LoginForm.tsx:142 +#, c-format +msgid "Username" +msgstr "" + +#: src/pages/LoginForm.tsx:156 +#, c-format +msgid "username of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:175 +#, c-format +msgid "Password" +msgstr "" + +#: src/pages/LoginForm.tsx:188 +#, fuzzy, c-format +msgid "password of the account" +msgstr "Buchungen auf öffentlich sichtbaren Konten" + +#: src/pages/LoginForm.tsx:223 +#, c-format +msgid "Check" +msgstr "" + +#: src/pages/LoginForm.tsx:237 +#, c-format +msgid "Log in" +msgstr "" + +#: src/pages/LoginForm.tsx:249 +#, c-format +msgid "Register" +msgstr "" + +#: src/components/Transactions/views.tsx:52 +#, c-format +msgid "Latest transactions" +msgstr "" + +#: src/components/Transactions/views.tsx:63 +#, c-format +msgid "Date" +msgstr "Datum" + +#: src/components/Transactions/views.tsx:71 +#, c-format +msgid "Counterpart" +msgstr "Empfänger" + +#: src/components/Transactions/views.tsx:75 +#, c-format +msgid "Subject" +msgstr "Verwendungszweck" + +#: src/components/Transactions/views.tsx:111 +#, c-format +msgid "sent" +msgstr "" + +#: src/components/Transactions/views.tsx:112 +#, c-format +msgid "received" +msgstr "" + +#: src/components/Transactions/views.tsx:127 +#, c-format +msgid "invalid value" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "to" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "from" +msgstr "" + +#: src/components/Transactions/views.tsx:202 +#, c-format +msgid "First page" +msgstr "" + +#: src/components/Transactions/views.tsx:209 +#, c-format +msgid "Next" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:86 +#, c-format +msgid "Wire transfer completed!" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:93 +#, c-format +msgid "The withdrawal has been aborted previously and can't be confirmed" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:100 +#, c-format +msgid "" +"The withdrawal operation can't be confirmed before a wallet accepted the " +"transaction." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:107 +#, c-format +msgid "The operation id is invalid." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:114 +#, c-format +msgid "The operation was not found." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:121 +#, c-format +msgid "Your balance is not enough for the operation." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:155 +#, c-format +msgid "" +"The reserve operation has been confirmed previously and can't be aborted" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:186 +#, fuzzy, c-format +msgid "Confirm the withdrawal operation" +msgstr "Abhebung bestätigen" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:203 +#, c-format +msgid "Wire transfer details" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:217 +#, c-format +msgid "Taler Exchange operator's account" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:228 +#, c-format +msgid "Taler Exchange operator's name" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:317 +#, c-format +msgid "Transfer" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:342 +#, c-format +msgid "Authentication required" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:352 +#, c-format +msgid "This operation was created with other username" +msgstr "" + +#: src/pages/OperationState/views.tsx:209 +#, c-format +msgid "" +"Unauthorized to make the operation, maybe the session has expired or the " +"password changed." +msgstr "" + +#: src/pages/OperationState/views.tsx:218 +#, c-format +msgid "The operation was rejected due to insufficient funds." +msgstr "" + +#: src/pages/OperationState/views.tsx:268 +#, c-format +msgid "Withdrawal confirmed" +msgstr "" + +#: src/pages/OperationState/views.tsx:272 +#, c-format +msgid "" +"The wire transfer to the Taler operator has been initiated. You will soon " +"receive the requested amount in your Taler wallet." +msgstr "" + +#: src/pages/OperationState/views.tsx:287 +#, c-format +msgid "Do not show this again" +msgstr "" + +#: src/pages/OperationState/views.tsx:319 +#, c-format +msgid "Close" +msgstr "" + +#: src/pages/OperationState/views.tsx:399 +#, c-format +msgid "On this device" +msgstr "" + +#: src/pages/OperationState/views.tsx:404 +#, c-format +msgid "" +"If you are using a web browser on desktop you should access your wallet with " +"the GNU Taler WebExtension now or click the link if your WebExtension have " +"the \"Inject Taler support\" option enabled." +msgstr "" + +#: src/pages/OperationState/views.tsx:417 +#, c-format +msgid "Start" +msgstr "" + +#: src/pages/OperationState/views.tsx:426 +#, c-format +msgid "On a mobile phone" +msgstr "" + +#: src/pages/OperationState/views.tsx:431 +#, c-format +msgid "Scan the QR code with your mobile device." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:73 +#, c-format +msgid "There is an operation already" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:75 +#, fuzzy, c-format +msgid "Complete or cancel the operation in" +msgstr "Abhebung bestätigen" + +#: src/pages/WalletWithdrawForm.tsx:84 +#, c-format +msgid "this page" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:101 +#, c-format +msgid "invalid" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:116 +#, c-format +msgid "Server responded with an invalid withdraw URI" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:117 +#, c-format +msgid "Withdraw URI: %1$s" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:132 +#, c-format +msgid "The operation was rejected due to insufficient funds" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:253 +#, c-format +msgid "Continue" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:282 +#, c-format +msgid "Prepare your wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:285 +#, c-format +msgid "" +"After using your wallet you will need to confirm or cancel the operation on " +"this site." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:295 +#, c-format +msgid "You need a GNU Taler Wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:300 +#, c-format +msgid "If you don't have one yet you can follow the instruction in" +msgstr "" + +#: src/pages/PaymentOptions.tsx:55 +#, c-format +msgid "Send money" +msgstr "" + +#: src/pages/PaymentOptions.tsx:73 +#, c-format +msgid "to a %1$s wallet" +msgstr "" + +#: src/pages/PaymentOptions.tsx:95 +#, c-format +msgid "Withdraw digital money into your mobile wallet or browser extension" +msgstr "" + +#: src/pages/PaymentOptions.tsx:109 +#, c-format +msgid "operation ready" +msgstr "" + +#: src/pages/PaymentOptions.tsx:129 +#, c-format +msgid "to another bank account" +msgstr "" + +#: src/pages/PaymentOptions.tsx:149 +#, c-format +msgid "Make a wire transfer to an account with known bank account number." +msgstr "" + +#: src/pages/PaymentOptions.tsx:171 +#, c-format +msgid "Transfer details" +msgstr "" + +#: src/pages/AccountPage/views.tsx:41 +#, c-format +msgid "This is a demo bank" +msgstr "" + +#: src/pages/AccountPage/views.tsx:46 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work. In addition to using your own bank account, you can also see the " +"transaction history of some %1$s." +msgstr "" + +#: src/pages/AccountPage/views.tsx:53 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work." +msgstr "" + +#: src/pages/AccountPage/views.tsx:70 +#, c-format +msgid "Pending account delete operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:72 +#, c-format +msgid "Pending account update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:74 +#, c-format +msgid "Pending password update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:76 +#, c-format +msgid "Pending transaction operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:78 +#, c-format +msgid "Pending withdrawal operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:80 +#, c-format +msgid "Pending cashout operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:91 +#, c-format +msgid "You can complete or cancel the operation in" +msgstr "" + +#: src/pages/BankFrame.tsx:64 +#, c-format +msgid "Internal error, please report." +msgstr "" + +#: src/pages/BankFrame.tsx:100 +#, c-format +msgid "Preferences" +msgstr "" + +#: src/pages/BankFrame.tsx:184 +#, c-format +msgid "Welcome, %1$s" +msgstr "" + +#: src/pages/WireTransfer.tsx:79 +#, c-format +msgid "Make a wire transfer" +msgstr "" + +#: src/pages/admin/AccountList.tsx:72 +#, fuzzy, c-format +msgid "Accounts" +msgstr "Betrag" + +#: src/pages/admin/AccountList.tsx:75 +#, c-format +msgid "A list of all business account in the bank." +msgstr "" + +#: src/pages/admin/AccountList.tsx:86 +#, c-format +msgid "Create account" +msgstr "" + +#: src/pages/admin/AccountList.tsx:106 +#, c-format +msgid "Name" +msgstr "" + +#: src/pages/admin/AccountList.tsx:110 +#, c-format +msgid "Balance" +msgstr "" + +#: src/pages/admin/AccountList.tsx:112 +#, c-format +msgid "Actions" +msgstr "" + +#: src/pages/admin/AccountList.tsx:151 +#, c-format +msgid "unknown" +msgstr "" + +#: src/pages/admin/AccountList.tsx:170 +#, c-format +msgid "change password" +msgstr "" + +#: src/pages/admin/AccountList.tsx:179 +#, c-format +msgid "cashouts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:189 +#, c-format +msgid "remove" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:168 +#, c-format +msgid "Cashout not implemented" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:184 +#, c-format +msgid "Select a section" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:202 +#, c-format +msgid "Last hour" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:208 +#, c-format +msgid "Last day" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:216 +#, c-format +msgid "Last month" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:222 +#, c-format +msgid "Last year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:310 +#, c-format +msgid "Last Year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:325 +#, c-format +msgid "Trading volume on %1$s compared to %2$s" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:342 +#, c-format +msgid "Cashin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:352 +#, c-format +msgid "Cashout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:364 +#, c-format +msgid "Payin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:374 +#, c-format +msgid "Payout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:388 +#, c-format +msgid "download stats as CSV" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:494 +#, c-format +msgid "Decreased by" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:498 +#, c-format +msgid "Increased by" +msgstr "" + +#: src/pages/DownloadStats.tsx:89 +#, c-format +msgid "Download bank stats" +msgstr "" + +#: src/pages/DownloadStats.tsx:110 +#, c-format +msgid "Include hour metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:143 +#, c-format +msgid "Include day metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:173 +#, c-format +msgid "Include month metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:206 +#, c-format +msgid "Include year metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:239 +#, c-format +msgid "Include table header" +msgstr "" + +#: src/pages/DownloadStats.tsx:272 +#, c-format +msgid "Add previous metric for compare" +msgstr "" + +#: src/pages/DownloadStats.tsx:307 +#, c-format +msgid "Fail on first error" +msgstr "" + +#: src/pages/DownloadStats.tsx:364 +#, c-format +msgid "Download" +msgstr "" + +#: src/pages/DownloadStats.tsx:381 +#, c-format +msgid "downloading... %1$s" +msgstr "" + +#: src/pages/DownloadStats.tsx:399 +#, c-format +msgid "Download completed" +msgstr "" + +#: src/pages/DownloadStats.tsx:400 +#, c-format +msgid "click here to save the file in your computer" +msgstr "" + +#: src/pages/PublicHistoriesPage.tsx:78 +#, c-format +msgid "History of public accounts" +msgstr "Buchungen auf öffentlich sichtbaren Konten" + +#: src/pages/RegistrationPage.tsx:48 +#, c-format +msgid "Currently, the bank is not accepting new registrations!" +msgstr "" + +#: src/pages/RegistrationPage.tsx:87 +#, c-format +msgid "Missing name" +msgstr "" + +#: src/pages/RegistrationPage.tsx:91 +#, c-format +msgid "Use letters and numbers only, and start with a lowercase letter" +msgstr "" + +#: src/pages/RegistrationPage.tsx:107 +#, c-format +msgid "Passwords don't match" +msgstr "" + +#: src/pages/RegistrationPage.tsx:130 +#, c-format +msgid "Server replied with invalid phone or email." +msgstr "" + +#: src/pages/RegistrationPage.tsx:137 +#, c-format +msgid "Registration is disabled because the bank ran out of bonus credit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:144 +#, c-format +msgid "No enough permission to create that account." +msgstr "" + +#: src/pages/RegistrationPage.tsx:151 +#, c-format +msgid "That account id is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:158 +#, c-format +msgid "That username is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:165 +#, c-format +msgid "That username can't be used because is reserved." +msgstr "" + +#: src/pages/RegistrationPage.tsx:172 +#, c-format +msgid "Only admin is allow to set debt limit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:179 +#, c-format +msgid "No information for the selected authentication channel." +msgstr "" + +#: src/pages/RegistrationPage.tsx:186 +#, c-format +msgid "Authentication channel is not supported." +msgstr "" + +#: src/pages/RegistrationPage.tsx:193 +#, c-format +msgid "Only admin can create accounts with second factor authentication." +msgstr "" + +#: src/pages/RegistrationPage.tsx:233 +#, c-format +msgid "Account registration" +msgstr "" + +#: src/pages/RegistrationPage.tsx:315 +#, c-format +msgid "Repeat password" +msgstr "" + +#: src/pages/RegistrationPage.tsx:457 +#, c-format +msgid "Create a random temporary user" +msgstr "" + +#: src/pages/QrCodeSection.tsx:110 +#, c-format +msgid "If you have a Taler wallet installed in this device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:116 +#, c-format +msgid "" +"You will see the details of the operation in your wallet including the fees " +"(if applies). If you still don't have one you can install it following " +"instructions in" +msgstr "" + +#: src/pages/QrCodeSection.tsx:143 +#, c-format +msgid "Withdraw" +msgstr "" + +#: src/pages/QrCodeSection.tsx:152 +#, c-format +msgid "Or if you have the wallet in another device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:157 +#, c-format +msgid "Scan the QR below to start the withdrawal." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:79 +#, c-format +msgid "Operation aborted" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:82 +#, c-format +msgid "" +"The wire transfer to the Taler Exchange operator's account was aborted, your " +"balance was not affected." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:88 +#, c-format +msgid "You can close this page now or continue to the account page." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:147 +#, c-format +msgid "Done" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:158 +#, c-format +msgid "Operation canceled" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:173 +#, c-format +msgid "" +"The operation is marked as 'selected' but some step in the withdrawal failed" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:175 +#, c-format +msgid "The account is selected but no withdrawal identification found." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:188 +#, c-format +msgid "" +"There is a withdrawal identification but no account has been selected or the " +"selected account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:202 +#, c-format +msgid "" +"No withdrawal ID found and no account has been selected or the selected " +"account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:259 +#, c-format +msgid "Operation not found" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:263 +#, c-format +msgid "" +"This operation is not known by the server. The operation id is wrong or the " +"server deleted the operation information before reaching here." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:278 +#, c-format +msgid "Cotinue to dashboard" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:98 +#, c-format +msgid "Cashout not found. It may be also mean that it was already aborted." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:136 +#, c-format +msgid "Challenge not found." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:143 +#, c-format +msgid "This user is not authorized to complete this challenge." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:150 +#, c-format +msgid "Too many attempts, try another code." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:157 +#, c-format +msgid "The confirmation code is wrong, try again." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:164 +#, c-format +msgid "The operation expired." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:197 +#, c-format +msgid "The operation failed." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:212 +#, c-format +msgid "The operation needs another confirmation to complete." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:224 +#, c-format +msgid "Account delete" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:226 +#, c-format +msgid "Account update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:228 +#, c-format +msgid "Password update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:230 +#, c-format +msgid "Wire transfer" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:232 +#, fuzzy, c-format +msgid "Withdrawal" +msgstr "Abhebung bestätigen" + +#: src/pages/SolveChallengePage.tsx:248 +#, fuzzy, c-format +msgid "Confirm the operation" +msgstr "Abhebung bestätigen" + +#: src/pages/SolveChallengePage.tsx:271 +#, c-format +msgid "Enter the confirmation code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:313 +#, c-format +msgid "Confirm" +msgstr "Bestätigen" + +#: src/pages/SolveChallengePage.tsx:348 +#, c-format +msgid "Send again" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:359 +#, c-format +msgid "Send code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:369 +#, c-format +msgid "Operation details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:529 +#, c-format +msgid "Challenge details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:536 +#, c-format +msgid "Sent at" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:551 +#, c-format +msgid "To phone" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:553 +#, c-format +msgid "To email" +msgstr "" + +#: src/pages/WithdrawalOperationPage.tsx:49 +#, c-format +msgid "The Withdrawal URI is not valid" +msgstr "" + +#: src/components/Cashouts/views.tsx:100 +#, c-format +msgid "Latest cashouts" +msgstr "" + +#: src/components/Cashouts/views.tsx:111 +#, c-format +msgid "Created" +msgstr "" + +#: src/components/Cashouts/views.tsx:115 +#, c-format +msgid "Total debit" +msgstr "" + +#: src/components/Cashouts/views.tsx:119 +#, c-format +msgid "Total credit" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:70 +#, c-format +msgid "Details" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:74 +#, c-format +msgid "Delete" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:78 +#, c-format +msgid "Credentials" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:82 +#, c-format +msgid "Cashouts" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:95 +#, c-format +msgid "Unable to create a cashout" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:96 +#, c-format +msgid "The bank configuration does not support cashout operations." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:223 +#, c-format +msgid "need to be higher due to fees" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:225 +#, c-format +msgid "the total transfer at destination will be zero" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:250 +#, c-format +msgid "Cashout created" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:272 +#, c-format +msgid "" +"Duplicated request detected, check if the operation succeeded or try again." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:279 +#, c-format +msgid "The conversion rate was incorrectly applied" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:286 +#, c-format +msgid "The account does not have sufficient funds" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:293 +#, c-format +msgid "Cashouts are not supported" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:300 +#, c-format +msgid "Missing cashout URI in the profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:307 +#, c-format +msgid "" +"Sending the confirmation message failed, retry later or contact the " +"administrator." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:339 +#, c-format +msgid "Conversion rate" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:360 +#, c-format +msgid "Fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:374 +#, c-format +msgid "To account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:381 +#, c-format +msgid "No cashout account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:382 +#, c-format +msgid "Before doing a cashout you need to complete your profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:440 +#, fuzzy, c-format +msgid "Amount to send" +msgstr "Betrag" + +#: src/pages/business/CreateCashout.tsx:441 +#, c-format +msgid "Amount to receive" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:490 +#, c-format +msgid "Total cost" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:505 +#, c-format +msgid "Balance left" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:520 +#, c-format +msgid "Before fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:533 +#, c-format +msgid "Total cashout transfer" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:553 +#, c-format +msgid "No cashout channel available" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:555 +#, c-format +msgid "" +"Before doing a cashout the server need to provide an second channel to " +"confirm the operation" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:567 +#, c-format +msgid "Second factor authentication" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:598 +#, c-format +msgid "Email" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:600 +#, c-format +msgid "add a email in your profile to enable this option" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:646 +#, c-format +msgid "SMS" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:648 +#, c-format +msgid "add a phone number in your profile to enable this option" +msgstr "" + +#: src/pages/account/CashoutListForAccount.tsx:52 +#, c-format +msgid "Cashout for account %1$s" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:165 +#, c-format +msgid "it doesn't have the pattern of an IBAN number" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:185 +#, c-format +msgid "it doesn't have the pattern of an email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:190 +#, c-format +msgid "should start with +" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:192 +#, c-format +msgid "phone number can't have other than numbers" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:329 +#, c-format +msgid "account identification in the bank" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:365 +#, c-format +msgid "name of the person owner the account" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:374 +#, c-format +msgid "Internal IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:377 +#, c-format +msgid "if empty a random account number will be assigned" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:378 +#, c-format +msgid "account identification for bank transfer" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:423 +#, c-format +msgid "Phone" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:451 +#, c-format +msgid "Cashout IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:452 +#, c-format +msgid "account number where the money is going to be sent when doing cashouts" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:470 +#, c-format +msgid "Max debt" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:494 +#, c-format +msgid "how much is user able to transfer after zero balance" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:508 +#, c-format +msgid "Is this a Taler Exchange?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:549 +#, c-format +msgid "This server doesn't support second factor authentication." +msgstr "" + +#: src/pages/admin/AccountForm.tsx:560 +#, c-format +msgid "Enable second factor authentication" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:596 +#, c-format +msgid "Using email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:654 +#, c-format +msgid "Using SMS" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:691 +#, c-format +msgid "Is this account public?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:719 +#, c-format +msgid "public accounts have their balance publicly accessible" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:100 +#, c-format +msgid "Account updated" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:107 +#, c-format +msgid "The rights to change the account are not sufficient" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:114 +#, c-format +msgid "The username was not found" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:121 +#, c-format +msgid "" +"You can't change the legal name, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:128 +#, c-format +msgid "" +"You can't change the debt limit, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:135 +#, c-format +msgid "" +"You can't change the cashout address, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:177 +#, c-format +msgid "Account \"%1$s\"" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:190 +#, c-format +msgid "Change details" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:235 +#, c-format +msgid "Update" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:78 +#, c-format +msgid "password doesn't match" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:95 +#, c-format +msgid "Password changed" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:102 +#, c-format +msgid "Not authorized to change the password, maybe the session is invalid." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:112 +#, c-format +msgid "" +"You need to provide the old password. If you don't have it contact your " +"account administrator." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:117 +#, c-format +msgid "Your current password doesn't match, can't change to a new password." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:149 +#, c-format +msgid "Update password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:167 +#, c-format +msgid "New password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:195 +#, c-format +msgid "Type it again" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:217 +#, c-format +msgid "repeat the same password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:227 +#, c-format +msgid "Current password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:248 +#, c-format +msgid "your current password, for security" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:272 +#, c-format +msgid "Change" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:74 +#, c-format +msgid "" +"Account created with password \"%1$s\". The user must change the password on " +"the next login." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:83 +#, c-format +msgid "Server replied that phone or email is invalid" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:90 +#, c-format +msgid "The rights to perform the operation are not sufficient" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:97 +#, c-format +msgid "Account username is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:104 +#, c-format +msgid "Account id is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:111 +#, c-format +msgid "Bank ran out of bonus credit." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:118 +#, c-format +msgid "Account username can't be used because is reserved" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:160 +#, c-format +msgid "Can't create accounts" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:161 +#, c-format +msgid "Only system admin can create accounts." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:183 +#, c-format +msgid "New business account" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:209 +#, c-format +msgid "Create" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:94 +#, c-format +msgid "Can't delete the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:95 +#, c-format +msgid "" +"The account can't be delete while still holding some balance. First make " +"sure that the owner make a complete cashout." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:117 +#, c-format +msgid "Account removed" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:124 +#, c-format +msgid "No enough permission to delete the account." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:131 +#, c-format +msgid "The username was not found." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:138 +#, c-format +msgid "Can't delete a reserved username." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:145 +#, c-format +msgid "Can't delete an account with balance different than zero." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:170 +#, c-format +msgid "name doesn't match" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:180 +#, c-format +msgid "You are going to remove the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:182 +#, c-format +msgid "This step can't be undone." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:188 +#, c-format +msgid "Deleting account \"%1$s\"" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:206 +#, c-format +msgid "Verification" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:231 +#, c-format +msgid "enter the account name that is going to be deleted" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:49 +#, c-format +msgid "cashout id should be a number" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:65 +#, c-format +msgid "This cashout not found. Maybe already aborted." +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:106 +#, c-format +msgid "Cashout detail" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:139 +#, c-format +msgid "Debited" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:154 +#, c-format +msgid "Credited" +msgstr "" + +#: src/Routing.tsx:140 +#, c-format +msgid "Welcome to %1$s!" +msgstr "" + +#, fuzzy, c-format +#~ msgid "Confirmed" +#~ msgstr "Bestätigen" + +#, c-format +#~ msgid "Logout" +#~ msgstr "Abmelden" + +#, c-format +#~ msgid "Skip to main content" +#~ msgstr "Navigationsmenü überspringen" + +#, c-format +#~ msgid "Taler logo" +#~ msgstr "Taler-Logo" + +#, c-format +#~ msgid "Please login!" +#~ msgstr "Bitte melden Sie sich an!" + +#, c-format +#~ msgid "payto address" +#~ msgstr "payto-Adresse" + +#, c-format +#~ msgid "Bank account balance" +#~ msgstr "Kontostand" diff --git a/packages/bank-ui/src/i18n/en.po b/packages/bank-ui/src/i18n/en.po new file mode 100644 index 000000000..a9657bd32 --- /dev/null +++ b/packages/bank-ui/src/i18n/en.po @@ -0,0 +1,1784 @@ +# This file is part of GNU Taler +# (C) 2021 Taler Systems S.A. +# GNU Taler is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with +# GNU Taler; see the file COPYING. If not, see +# +msgid "" +msgstr "" +"Project-Id-Version: Taler Wallet\n" +"Report-Msgid-Bugs-To: taler@gnu.org\n" +"POT-Creation-Date: 2016-11-23 00:00+0100\n" +"PO-Revision-Date: 2022-01-08 09:57+0100\n" +"Last-Translator: \n" +"Language-Team: English\n" +"Language: en\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: src/utils.ts:137 +#, c-format +msgid "Operation failed, please report" +msgstr "" + +#: src/utils.ts:156 +#, c-format +msgid "Request timeout" +msgstr "" + +#: src/utils.ts:165 +#, c-format +msgid "Request throttled" +msgstr "" + +#: src/utils.ts:174 +#, c-format +msgid "Malformed response" +msgstr "" + +#: src/utils.ts:183 +#, c-format +msgid "Network error" +msgstr "" + +#: src/utils.ts:192 +#, c-format +msgid "Unexpected request error" +msgstr "" + +#: src/utils.ts:201 +#, c-format +msgid "Unexpected error" +msgstr "" + +#: src/utils.ts:377 +#, c-format +msgid "IBAN numbers usually have more that 4 digits" +msgstr "" + +#: src/utils.ts:379 +#, c-format +msgid "IBAN numbers usually have less that 34 digits" +msgstr "" + +#: src/utils.ts:387 +#, c-format +msgid "IBAN country code not found" +msgstr "" + +#: src/utils.ts:401 +#, c-format +msgid "IBAN number is not valid, checksum is wrong" +msgstr "" + +#: src/context/config.ts:136 +#, c-format +msgid "" +"the bank backend is not supported. supported version \"%1$s\", server " +"version \"%2$s\"" +msgstr "" + +#: src/hooks/preferences.ts:55 +#, fuzzy, c-format +msgid "Max withdrawal amount" +msgstr "" + +#: src/hooks/preferences.ts:57 +#, c-format +msgid "Show withdrawal confirmation" +msgstr "" + +#: src/hooks/preferences.ts:59 +#, c-format +msgid "Show demo description" +msgstr "" + +#: src/hooks/preferences.ts:61 +#, c-format +msgid "Show install wallet first" +msgstr "" + +#: src/hooks/preferences.ts:63 +#, fuzzy, c-format +msgid "Use fast withdrawal form" +msgstr "" + +#: src/hooks/preferences.ts:65 +#, c-format +msgid "Show debug info" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:90 +#, c-format +msgid "required" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:92 +#, c-format +msgid "IBAN should have just uppercased letters and numbers" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:98 +#, c-format +msgid "not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:100 +#, c-format +msgid "should be greater than 0" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:102 +#, c-format +msgid "balance is not enough" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:112 +#, c-format +msgid "does not follow the pattern" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:114 +#, c-format +msgid "only \"IBAN\" target are supported" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:116 +#, c-format +msgid "use the \"amount\" parameter to specify the amount to be transferred" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:118 +#, c-format +msgid "the amount is not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:120 +#, c-format +msgid "" +"use the \"message\" parameter to specify a reference text for the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:160 +#, c-format +msgid "The request was invalid or the payto://-URI used unacceptable features." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:167 +#, c-format +msgid "Not enough permission to complete the operation." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:174 +#, c-format +msgid "The destination account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:181 +#, c-format +msgid "The origin and the destination of the transfer can't be the same." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:188 +#, c-format +msgid "Your balance is not enough." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:195 +#, c-format +msgid "The origin account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:212 +#, c-format +msgid "Wire transfer created!" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:270 +#, c-format +msgid "Using a form" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:310 +#, c-format +msgid "Import payto:// URI" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:335 +#, c-format +msgid "Recipient" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:359 +#, c-format +msgid "IBAN of the recipient's account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:369 +#, c-format +msgid "Transfer subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:377 +#, c-format +msgid "subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:390 +#, c-format +msgid "some text to identify the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:400 +#, c-format +msgid "Amount" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:415 +#, fuzzy, c-format +msgid "amount to transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:425 +#, c-format +msgid "payto URI:" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:436 +#, c-format +msgid "uniform resource identifier of the target account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:437 +#, c-format +msgid "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:457 +#, c-format +msgid "Cancel" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:471 +#, c-format +msgid "Send" +msgstr "" + +#: src/pages/LoginForm.tsx:71 +#, c-format +msgid "Missing username" +msgstr "" + +#: src/pages/LoginForm.tsx:75 +#, c-format +msgid "Missing password" +msgstr "" + +#: src/pages/LoginForm.tsx:104 +#, c-format +msgid "Wrong credentials for \"%1$s\"" +msgstr "" + +#: src/pages/LoginForm.tsx:111 +#, c-format +msgid "Account not found" +msgstr "" + +#: src/pages/LoginForm.tsx:142 +#, c-format +msgid "Username" +msgstr "" + +#: src/pages/LoginForm.tsx:156 +#, c-format +msgid "username of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:175 +#, c-format +msgid "Password" +msgstr "" + +#: src/pages/LoginForm.tsx:188 +#, c-format +msgid "password of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:223 +#, c-format +msgid "Check" +msgstr "" + +#: src/pages/LoginForm.tsx:237 +#, c-format +msgid "Log in" +msgstr "" + +#: src/pages/LoginForm.tsx:249 +#, c-format +msgid "Register" +msgstr "" + +#: src/components/Transactions/views.tsx:52 +#, c-format +msgid "Latest transactions" +msgstr "" + +#: src/components/Transactions/views.tsx:63 +#, c-format +msgid "Date" +msgstr "" + +#: src/components/Transactions/views.tsx:71 +#, c-format +msgid "Counterpart" +msgstr "" + +#: src/components/Transactions/views.tsx:75 +#, c-format +msgid "Subject" +msgstr "" + +#: src/components/Transactions/views.tsx:111 +#, c-format +msgid "sent" +msgstr "" + +#: src/components/Transactions/views.tsx:112 +#, c-format +msgid "received" +msgstr "" + +#: src/components/Transactions/views.tsx:127 +#, c-format +msgid "invalid value" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "to" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "from" +msgstr "" + +#: src/components/Transactions/views.tsx:202 +#, c-format +msgid "First page" +msgstr "" + +#: src/components/Transactions/views.tsx:209 +#, c-format +msgid "Next" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:86 +#, c-format +msgid "Wire transfer completed!" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:93 +#, c-format +msgid "The withdrawal has been aborted previously and can't be confirmed" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:100 +#, c-format +msgid "" +"The withdrawal operation can't be confirmed before a wallet accepted the " +"transaction." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:107 +#, c-format +msgid "The operation id is invalid." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:114 +#, c-format +msgid "The operation was not found." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:121 +#, c-format +msgid "Your balance is not enough for the operation." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:155 +#, c-format +msgid "" +"The reserve operation has been confirmed previously and can't be aborted" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:186 +#, fuzzy, c-format +msgid "Confirm the withdrawal operation" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:203 +#, c-format +msgid "Wire transfer details" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:217 +#, c-format +msgid "Taler Exchange operator's account" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:228 +#, c-format +msgid "Taler Exchange operator's name" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:317 +#, c-format +msgid "Transfer" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:342 +#, c-format +msgid "Authentication required" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:352 +#, c-format +msgid "This operation was created with other username" +msgstr "" + +#: src/pages/OperationState/views.tsx:209 +#, c-format +msgid "" +"Unauthorized to make the operation, maybe the session has expired or the " +"password changed." +msgstr "" + +#: src/pages/OperationState/views.tsx:218 +#, c-format +msgid "The operation was rejected due to insufficient funds." +msgstr "" + +#: src/pages/OperationState/views.tsx:268 +#, c-format +msgid "Withdrawal confirmed" +msgstr "" + +#: src/pages/OperationState/views.tsx:272 +#, c-format +msgid "" +"The wire transfer to the Taler operator has been initiated. You will soon " +"receive the requested amount in your Taler wallet." +msgstr "" + +#: src/pages/OperationState/views.tsx:287 +#, c-format +msgid "Do not show this again" +msgstr "" + +#: src/pages/OperationState/views.tsx:319 +#, c-format +msgid "Close" +msgstr "" + +#: src/pages/OperationState/views.tsx:399 +#, c-format +msgid "On this device" +msgstr "" + +#: src/pages/OperationState/views.tsx:404 +#, c-format +msgid "" +"If you are using a web browser on desktop you should access your wallet with " +"the GNU Taler WebExtension now or click the link if your WebExtension have " +"the \"Inject Taler support\" option enabled." +msgstr "" + +#: src/pages/OperationState/views.tsx:417 +#, c-format +msgid "Start" +msgstr "" + +#: src/pages/OperationState/views.tsx:426 +#, c-format +msgid "On a mobile phone" +msgstr "" + +#: src/pages/OperationState/views.tsx:431 +#, c-format +msgid "Scan the QR code with your mobile device." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:73 +#, c-format +msgid "There is an operation already" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:75 +#, fuzzy, c-format +msgid "Complete or cancel the operation in" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:84 +#, c-format +msgid "this page" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:101 +#, c-format +msgid "invalid" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:116 +#, c-format +msgid "Server responded with an invalid withdraw URI" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:117 +#, fuzzy, c-format +msgid "Withdraw URI: %1$s" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:132 +#, c-format +msgid "The operation was rejected due to insufficient funds" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:253 +#, c-format +msgid "Continue" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:282 +#, c-format +msgid "Prepare your wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:285 +#, c-format +msgid "" +"After using your wallet you will need to confirm or cancel the operation on " +"this site." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:295 +#, fuzzy, c-format +msgid "You need a GNU Taler Wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:300 +#, c-format +msgid "If you don't have one yet you can follow the instruction in" +msgstr "" + +#: src/pages/PaymentOptions.tsx:55 +#, c-format +msgid "Send money" +msgstr "" + +#: src/pages/PaymentOptions.tsx:73 +#, c-format +msgid "to a %1$s wallet" +msgstr "" + +#: src/pages/PaymentOptions.tsx:95 +#, c-format +msgid "Withdraw digital money into your mobile wallet or browser extension" +msgstr "" + +#: src/pages/PaymentOptions.tsx:109 +#, c-format +msgid "operation ready" +msgstr "" + +#: src/pages/PaymentOptions.tsx:129 +#, c-format +msgid "to another bank account" +msgstr "" + +#: src/pages/PaymentOptions.tsx:149 +#, c-format +msgid "Make a wire transfer to an account with known bank account number." +msgstr "" + +#: src/pages/PaymentOptions.tsx:171 +#, fuzzy, c-format +msgid "Transfer details" +msgstr "" + +#: src/pages/AccountPage/views.tsx:41 +#, c-format +msgid "This is a demo bank" +msgstr "" + +#: src/pages/AccountPage/views.tsx:46 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work. In addition to using your own bank account, you can also see the " +"transaction history of some %1$s." +msgstr "" + +#: src/pages/AccountPage/views.tsx:53 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work." +msgstr "" + +#: src/pages/AccountPage/views.tsx:70 +#, c-format +msgid "Pending account delete operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:72 +#, c-format +msgid "Pending account update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:74 +#, c-format +msgid "Pending password update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:76 +#, c-format +msgid "Pending transaction operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:78 +#, c-format +msgid "Pending withdrawal operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:80 +#, c-format +msgid "Pending cashout operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:91 +#, c-format +msgid "You can complete or cancel the operation in" +msgstr "" + +#: src/pages/BankFrame.tsx:64 +#, c-format +msgid "Internal error, please report." +msgstr "" + +#: src/pages/BankFrame.tsx:100 +#, c-format +msgid "Preferences" +msgstr "" + +#: src/pages/BankFrame.tsx:184 +#, c-format +msgid "Welcome, %1$s" +msgstr "" + +#: src/pages/WireTransfer.tsx:79 +#, c-format +msgid "Make a wire transfer" +msgstr "" + +#: src/pages/admin/AccountList.tsx:72 +#, c-format +msgid "Accounts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:75 +#, c-format +msgid "A list of all business account in the bank." +msgstr "" + +#: src/pages/admin/AccountList.tsx:86 +#, c-format +msgid "Create account" +msgstr "" + +#: src/pages/admin/AccountList.tsx:106 +#, c-format +msgid "Name" +msgstr "" + +#: src/pages/admin/AccountList.tsx:110 +#, c-format +msgid "Balance" +msgstr "" + +#: src/pages/admin/AccountList.tsx:112 +#, c-format +msgid "Actions" +msgstr "" + +#: src/pages/admin/AccountList.tsx:151 +#, c-format +msgid "unknown" +msgstr "" + +#: src/pages/admin/AccountList.tsx:170 +#, c-format +msgid "change password" +msgstr "" + +#: src/pages/admin/AccountList.tsx:179 +#, c-format +msgid "cashouts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:189 +#, c-format +msgid "remove" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:168 +#, c-format +msgid "Cashout not implemented" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:184 +#, c-format +msgid "Select a section" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:202 +#, c-format +msgid "Last hour" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:208 +#, c-format +msgid "Last day" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:216 +#, c-format +msgid "Last month" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:222 +#, c-format +msgid "Last year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:310 +#, c-format +msgid "Last Year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:325 +#, c-format +msgid "Trading volume on %1$s compared to %2$s" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:342 +#, c-format +msgid "Cashin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:352 +#, c-format +msgid "Cashout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:364 +#, c-format +msgid "Payin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:374 +#, c-format +msgid "Payout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:388 +#, c-format +msgid "download stats as CSV" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:494 +#, c-format +msgid "Decreased by" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:498 +#, c-format +msgid "Increased by" +msgstr "" + +#: src/pages/DownloadStats.tsx:89 +#, c-format +msgid "Download bank stats" +msgstr "" + +#: src/pages/DownloadStats.tsx:110 +#, c-format +msgid "Include hour metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:143 +#, c-format +msgid "Include day metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:173 +#, c-format +msgid "Include month metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:206 +#, c-format +msgid "Include year metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:239 +#, c-format +msgid "Include table header" +msgstr "" + +#: src/pages/DownloadStats.tsx:272 +#, c-format +msgid "Add previous metric for compare" +msgstr "" + +#: src/pages/DownloadStats.tsx:307 +#, c-format +msgid "Fail on first error" +msgstr "" + +#: src/pages/DownloadStats.tsx:364 +#, c-format +msgid "Download" +msgstr "" + +#: src/pages/DownloadStats.tsx:381 +#, c-format +msgid "downloading... %1$s" +msgstr "" + +#: src/pages/DownloadStats.tsx:399 +#, c-format +msgid "Download completed" +msgstr "" + +#: src/pages/DownloadStats.tsx:400 +#, c-format +msgid "click here to save the file in your computer" +msgstr "" + +#: src/pages/PublicHistoriesPage.tsx:78 +#, c-format +msgid "History of public accounts" +msgstr "" + +#: src/pages/RegistrationPage.tsx:48 +#, c-format +msgid "Currently, the bank is not accepting new registrations!" +msgstr "" + +#: src/pages/RegistrationPage.tsx:87 +#, c-format +msgid "Missing name" +msgstr "" + +#: src/pages/RegistrationPage.tsx:91 +#, c-format +msgid "Use letters and numbers only, and start with a lowercase letter" +msgstr "" + +#: src/pages/RegistrationPage.tsx:107 +#, c-format +msgid "Passwords don't match" +msgstr "" + +#: src/pages/RegistrationPage.tsx:130 +#, c-format +msgid "Server replied with invalid phone or email." +msgstr "" + +#: src/pages/RegistrationPage.tsx:137 +#, c-format +msgid "Registration is disabled because the bank ran out of bonus credit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:144 +#, c-format +msgid "No enough permission to create that account." +msgstr "" + +#: src/pages/RegistrationPage.tsx:151 +#, c-format +msgid "That account id is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:158 +#, c-format +msgid "That username is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:165 +#, c-format +msgid "That username can't be used because is reserved." +msgstr "" + +#: src/pages/RegistrationPage.tsx:172 +#, c-format +msgid "Only admin is allow to set debt limit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:179 +#, c-format +msgid "No information for the selected authentication channel." +msgstr "" + +#: src/pages/RegistrationPage.tsx:186 +#, c-format +msgid "Authentication channel is not supported." +msgstr "" + +#: src/pages/RegistrationPage.tsx:193 +#, c-format +msgid "Only admin can create accounts with second factor authentication." +msgstr "" + +#: src/pages/RegistrationPage.tsx:233 +#, c-format +msgid "Account registration" +msgstr "" + +#: src/pages/RegistrationPage.tsx:315 +#, c-format +msgid "Repeat password" +msgstr "" + +#: src/pages/RegistrationPage.tsx:457 +#, c-format +msgid "Create a random temporary user" +msgstr "" + +#: src/pages/QrCodeSection.tsx:110 +#, c-format +msgid "If you have a Taler wallet installed in this device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:116 +#, c-format +msgid "" +"You will see the details of the operation in your wallet including the fees " +"(if applies). If you still don't have one you can install it following " +"instructions in" +msgstr "" + +#: src/pages/QrCodeSection.tsx:143 +#, fuzzy, c-format +msgid "Withdraw" +msgstr "" + +#: src/pages/QrCodeSection.tsx:152 +#, c-format +msgid "Or if you have the wallet in another device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:157 +#, fuzzy, c-format +msgid "Scan the QR below to start the withdrawal." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:79 +#, c-format +msgid "Operation aborted" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:82 +#, c-format +msgid "" +"The wire transfer to the Taler Exchange operator's account was aborted, your " +"balance was not affected." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:88 +#, c-format +msgid "You can close this page now or continue to the account page." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:147 +#, c-format +msgid "Done" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:158 +#, c-format +msgid "Operation canceled" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:173 +#, c-format +msgid "" +"The operation is marked as 'selected' but some step in the withdrawal failed" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:175 +#, c-format +msgid "The account is selected but no withdrawal identification found." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:188 +#, c-format +msgid "" +"There is a withdrawal identification but no account has been selected or the " +"selected account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:202 +#, c-format +msgid "" +"No withdrawal ID found and no account has been selected or the selected " +"account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:259 +#, c-format +msgid "Operation not found" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:263 +#, c-format +msgid "" +"This operation is not known by the server. The operation id is wrong or the " +"server deleted the operation information before reaching here." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:278 +#, c-format +msgid "Cotinue to dashboard" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:98 +#, c-format +msgid "Cashout not found. It may be also mean that it was already aborted." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:136 +#, c-format +msgid "Challenge not found." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:143 +#, c-format +msgid "This user is not authorized to complete this challenge." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:150 +#, c-format +msgid "Too many attempts, try another code." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:157 +#, c-format +msgid "The confirmation code is wrong, try again." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:164 +#, c-format +msgid "The operation expired." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:197 +#, c-format +msgid "The operation failed." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:212 +#, c-format +msgid "The operation needs another confirmation to complete." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:224 +#, c-format +msgid "Account delete" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:226 +#, c-format +msgid "Account update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:228 +#, c-format +msgid "Password update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:230 +#, c-format +msgid "Wire transfer" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:232 +#, fuzzy, c-format +msgid "Withdrawal" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:248 +#, fuzzy, c-format +msgid "Confirm the operation" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:271 +#, c-format +msgid "Enter the confirmation code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:313 +#, c-format +msgid "Confirm" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:348 +#, c-format +msgid "Send again" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:359 +#, c-format +msgid "Send code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:369 +#, c-format +msgid "Operation details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:529 +#, c-format +msgid "Challenge details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:536 +#, c-format +msgid "Sent at" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:551 +#, c-format +msgid "To phone" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:553 +#, c-format +msgid "To email" +msgstr "" + +#: src/pages/WithdrawalOperationPage.tsx:49 +#, c-format +msgid "The Withdrawal URI is not valid" +msgstr "" + +#: src/components/Cashouts/views.tsx:100 +#, c-format +msgid "Latest cashouts" +msgstr "" + +#: src/components/Cashouts/views.tsx:111 +#, c-format +msgid "Created" +msgstr "" + +#: src/components/Cashouts/views.tsx:115 +#, c-format +msgid "Total debit" +msgstr "" + +#: src/components/Cashouts/views.tsx:119 +#, c-format +msgid "Total credit" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:70 +#, c-format +msgid "Details" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:74 +#, c-format +msgid "Delete" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:78 +#, c-format +msgid "Credentials" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:82 +#, c-format +msgid "Cashouts" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:95 +#, c-format +msgid "Unable to create a cashout" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:96 +#, c-format +msgid "The bank configuration does not support cashout operations." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:223 +#, c-format +msgid "need to be higher due to fees" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:225 +#, c-format +msgid "the total transfer at destination will be zero" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:250 +#, c-format +msgid "Cashout created" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:272 +#, c-format +msgid "" +"Duplicated request detected, check if the operation succeeded or try again." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:279 +#, c-format +msgid "The conversion rate was incorrectly applied" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:286 +#, c-format +msgid "The account does not have sufficient funds" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:293 +#, c-format +msgid "Cashouts are not supported" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:300 +#, c-format +msgid "Missing cashout URI in the profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:307 +#, c-format +msgid "" +"Sending the confirmation message failed, retry later or contact the " +"administrator." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:339 +#, c-format +msgid "Conversion rate" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:360 +#, c-format +msgid "Fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:374 +#, c-format +msgid "To account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:381 +#, c-format +msgid "No cashout account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:382 +#, c-format +msgid "Before doing a cashout you need to complete your profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:440 +#, fuzzy, c-format +msgid "Amount to send" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:441 +#, fuzzy, c-format +msgid "Amount to receive" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:490 +#, c-format +msgid "Total cost" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:505 +#, c-format +msgid "Balance left" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:520 +#, c-format +msgid "Before fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:533 +#, c-format +msgid "Total cashout transfer" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:553 +#, c-format +msgid "No cashout channel available" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:555 +#, c-format +msgid "" +"Before doing a cashout the server need to provide an second channel to " +"confirm the operation" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:567 +#, c-format +msgid "Second factor authentication" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:598 +#, c-format +msgid "Email" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:600 +#, c-format +msgid "add a email in your profile to enable this option" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:646 +#, c-format +msgid "SMS" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:648 +#, c-format +msgid "add a phone number in your profile to enable this option" +msgstr "" + +#: src/pages/account/CashoutListForAccount.tsx:52 +#, c-format +msgid "Cashout for account %1$s" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:165 +#, c-format +msgid "it doesn't have the pattern of an IBAN number" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:185 +#, c-format +msgid "it doesn't have the pattern of an email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:190 +#, c-format +msgid "should start with +" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:192 +#, c-format +msgid "phone number can't have other than numbers" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:329 +#, c-format +msgid "account identification in the bank" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:365 +#, c-format +msgid "name of the person owner the account" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:374 +#, c-format +msgid "Internal IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:377 +#, c-format +msgid "if empty a random account number will be assigned" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:378 +#, c-format +msgid "account identification for bank transfer" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:423 +#, c-format +msgid "Phone" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:451 +#, c-format +msgid "Cashout IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:452 +#, c-format +msgid "account number where the money is going to be sent when doing cashouts" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:470 +#, c-format +msgid "Max debt" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:494 +#, c-format +msgid "how much is user able to transfer after zero balance" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:508 +#, c-format +msgid "Is this a Taler Exchange?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:549 +#, c-format +msgid "This server doesn't support second factor authentication." +msgstr "" + +#: src/pages/admin/AccountForm.tsx:560 +#, c-format +msgid "Enable second factor authentication" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:596 +#, c-format +msgid "Using email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:654 +#, c-format +msgid "Using SMS" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:691 +#, c-format +msgid "Is this account public?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:719 +#, c-format +msgid "public accounts have their balance publicly accessible" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:100 +#, c-format +msgid "Account updated" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:107 +#, c-format +msgid "The rights to change the account are not sufficient" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:114 +#, c-format +msgid "The username was not found" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:121 +#, c-format +msgid "" +"You can't change the legal name, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:128 +#, c-format +msgid "" +"You can't change the debt limit, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:135 +#, c-format +msgid "" +"You can't change the cashout address, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:177 +#, c-format +msgid "Account \"%1$s\"" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:190 +#, c-format +msgid "Change details" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:235 +#, c-format +msgid "Update" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:78 +#, c-format +msgid "password doesn't match" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:95 +#, c-format +msgid "Password changed" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:102 +#, c-format +msgid "Not authorized to change the password, maybe the session is invalid." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:112 +#, c-format +msgid "" +"You need to provide the old password. If you don't have it contact your " +"account administrator." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:117 +#, c-format +msgid "Your current password doesn't match, can't change to a new password." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:149 +#, c-format +msgid "Update password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:167 +#, c-format +msgid "New password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:195 +#, c-format +msgid "Type it again" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:217 +#, c-format +msgid "repeat the same password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:227 +#, c-format +msgid "Current password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:248 +#, c-format +msgid "your current password, for security" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:272 +#, c-format +msgid "Change" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:74 +#, c-format +msgid "" +"Account created with password \"%1$s\". The user must change the password on " +"the next login." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:83 +#, c-format +msgid "Server replied that phone or email is invalid" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:90 +#, c-format +msgid "The rights to perform the operation are not sufficient" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:97 +#, c-format +msgid "Account username is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:104 +#, c-format +msgid "Account id is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:111 +#, c-format +msgid "Bank ran out of bonus credit." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:118 +#, c-format +msgid "Account username can't be used because is reserved" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:160 +#, c-format +msgid "Can't create accounts" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:161 +#, c-format +msgid "Only system admin can create accounts." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:183 +#, c-format +msgid "New business account" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:209 +#, c-format +msgid "Create" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:94 +#, c-format +msgid "Can't delete the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:95 +#, c-format +msgid "" +"The account can't be delete while still holding some balance. First make " +"sure that the owner make a complete cashout." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:117 +#, c-format +msgid "Account removed" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:124 +#, c-format +msgid "No enough permission to delete the account." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:131 +#, c-format +msgid "The username was not found." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:138 +#, c-format +msgid "Can't delete a reserved username." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:145 +#, c-format +msgid "Can't delete an account with balance different than zero." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:170 +#, c-format +msgid "name doesn't match" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:180 +#, c-format +msgid "You are going to remove the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:182 +#, c-format +msgid "This step can't be undone." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:188 +#, c-format +msgid "Deleting account \"%1$s\"" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:206 +#, c-format +msgid "Verification" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:231 +#, c-format +msgid "enter the account name that is going to be deleted" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:49 +#, c-format +msgid "cashout id should be a number" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:65 +#, c-format +msgid "This cashout not found. Maybe already aborted." +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:106 +#, c-format +msgid "Cashout detail" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:139 +#, c-format +msgid "Debited" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:154 +#, c-format +msgid "Credited" +msgstr "" + +#: src/Routing.tsx:140 +#, c-format +msgid "Welcome to %1$s!" +msgstr "" + +#, c-format +#~ msgid "days" +#~ msgstr "" + +#, c-format +#~ msgid "hours" +#~ msgstr "" + +#, c-format +#~ msgid "minutes" +#~ msgstr "" + +#, c-format +#~ msgid "seconds" +#~ msgstr "" + +#~ msgid "Go back" +#~ msgstr "" + +#, fuzzy +#~ msgid "Withdraw Money into a Taler wallet" +#~ msgstr "" + +#~ msgid "Page has a problem: logged in but backend state is lost." +#~ msgstr "" + +#, fuzzy +#~ msgid "Welcome to the euFin bank!" +#~ msgstr "" + +#~ msgid "Page has a problem:" +#~ msgstr "" + +#~ msgid "Sign in" +#~ msgstr "" diff --git a/packages/bank-ui/src/i18n/es.po b/packages/bank-ui/src/i18n/es.po new file mode 100644 index 000000000..fb69822c5 --- /dev/null +++ b/packages/bank-ui/src/i18n/es.po @@ -0,0 +1,2063 @@ +# This file is part of GNU Taler +# (C) 2021 Taler Systems S.A. +# GNU Taler is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with +# GNU Taler; see the file COPYING. If not, see +# +msgid "" +msgstr "" +"Project-Id-Version: Taler Wallet\n" +"Report-Msgid-Bugs-To: taler@gnu.org\n" +"POT-Creation-Date: 2016-11-23 00:00+0100\n" +"PO-Revision-Date: 2024-02-13 14:40+0000\n" +"Last-Translator: Stefan Kügel \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.2.1\n" + +#: src/utils.ts:137 +#, c-format +msgid "Operation failed, please report" +msgstr "La operaicón falló, por favor reportelo" + +#: src/utils.ts:156 +#, c-format +msgid "Request timeout" +msgstr "La petición al servidor agoto su tiempo" + +#: src/utils.ts:165 +#, c-format +msgid "Request throttled" +msgstr "La petición al servidor interrumpida" + +#: src/utils.ts:174 +#, c-format +msgid "Malformed response" +msgstr "Respuesta malformada" + +#: src/utils.ts:183 +#, c-format +msgid "Network error" +msgstr "Error de conexión" + +#: src/utils.ts:192 +#, c-format +msgid "Unexpected request error" +msgstr "Error de pedido inesperado" + +#: src/utils.ts:201 +#, c-format +msgid "Unexpected error" +msgstr "Error inesperado" + +#: src/utils.ts:377 +#, c-format +msgid "IBAN numbers usually have more that 4 digits" +msgstr "Los números IBAN usualmente tienen mas de 4 digitos" + +#: src/utils.ts:379 +#, c-format +msgid "IBAN numbers usually have less that 34 digits" +msgstr "Los números IBAN usualmente tienen menos de 34 digitos" + +#: src/utils.ts:387 +#, c-format +msgid "IBAN country code not found" +msgstr "Código de pais de IBAN no encontrado" + +#: src/utils.ts:401 +#, c-format +msgid "IBAN number is not valid, checksum is wrong" +msgstr "El número IBAN no es válido, falló la verificación" + +#: src/context/config.ts:136 +#, c-format +msgid "" +"the bank backend is not supported. supported version \"%1$s\", server " +"version \"%2$s\"" +msgstr "" +"El servidor de bank no esta spoportado. Version soportada \"%1$s\", version " +"del server \"%2$s\"" + +#: src/hooks/preferences.ts:55 +#, c-format +msgid "Max withdrawal amount" +msgstr "Monto máximo de extracción" + +#: src/hooks/preferences.ts:57 +#, c-format +msgid "Show withdrawal confirmation" +msgstr "Mostrar confirmación de extracción" + +#: src/hooks/preferences.ts:59 +#, c-format +msgid "Show demo description" +msgstr "Mostrar descripción de demo" + +#: src/hooks/preferences.ts:61 +#, c-format +msgid "Show install wallet first" +msgstr "Mostrar instalar la billetera primero" + +#: src/hooks/preferences.ts:63 +#, c-format +msgid "Use fast withdrawal form" +msgstr "Usar formulario de extracción rápida" + +#: src/hooks/preferences.ts:65 +#, c-format +msgid "Show debug info" +msgstr "Mostrar información de depuración" + +#: src/pages/PaytoWireTransferForm.tsx:90 +#, c-format +msgid "required" +msgstr "requerido" + +#: src/pages/PaytoWireTransferForm.tsx:92 +#, c-format +msgid "IBAN should have just uppercased letters and numbers" +msgstr "IBAN debería tener letras mayúsculas y números" + +#: src/pages/PaytoWireTransferForm.tsx:98 +#, c-format +msgid "not valid" +msgstr "no válido" + +#: src/pages/PaytoWireTransferForm.tsx:100 +#, c-format +msgid "should be greater than 0" +msgstr "Debería ser mas grande que 0" + +#: src/pages/PaytoWireTransferForm.tsx:102 +#, c-format +msgid "balance is not enough" +msgstr "el saldo no es suficiente" + +#: src/pages/PaytoWireTransferForm.tsx:112 +#, c-format +msgid "does not follow the pattern" +msgstr "no tiene un patrón valido" + +#: src/pages/PaytoWireTransferForm.tsx:114 +#, c-format +msgid "only \"IBAN\" target are supported" +msgstr "solo cuentas \"IBAN\" son soportadas" + +#: src/pages/PaytoWireTransferForm.tsx:116 +#, c-format +msgid "use the \"amount\" parameter to specify the amount to be transferred" +msgstr "usa el parámetro \"amount\" para indicar el monto a ser transferido" + +#: src/pages/PaytoWireTransferForm.tsx:118 +#, c-format +msgid "the amount is not valid" +msgstr "el monto no es válido" + +#: src/pages/PaytoWireTransferForm.tsx:120 +#, c-format +msgid "" +"use the \"message\" parameter to specify a reference text for the transfer" +msgstr "" +"usa el parámetro \"message\" para indicar un texto de referencia en la " +"transferencia" + +#: src/pages/PaytoWireTransferForm.tsx:160 +#, c-format +msgid "The request was invalid or the payto://-URI used unacceptable features." +msgstr "" +"El pedido era inválido o el URI payto:// usado tiene características " +"inaceptables." + +#: src/pages/PaytoWireTransferForm.tsx:167 +#, c-format +msgid "Not enough permission to complete the operation." +msgstr "Sin permisos suficientes para completar la operación." + +#: src/pages/PaytoWireTransferForm.tsx:174 +#, c-format +msgid "The destination account \"%1$s\" was not found." +msgstr "La cuenta de destino \"%1$s\" no fue encontrada." + +#: src/pages/PaytoWireTransferForm.tsx:181 +#, c-format +msgid "The origin and the destination of the transfer can't be the same." +msgstr "El origen y destino de la transferencia no puede ser la misma." + +#: src/pages/PaytoWireTransferForm.tsx:188 +#, c-format +msgid "Your balance is not enough." +msgstr "El saldo no es suficiente." + +#: src/pages/PaytoWireTransferForm.tsx:195 +#, c-format +msgid "The origin account \"%1$s\" was not found." +msgstr "La cuenta origen \"%1$s\" no fue encontrada." + +#: src/pages/PaytoWireTransferForm.tsx:212 +#, c-format +msgid "Wire transfer created!" +msgstr "Transferencia bancaria creada!" + +#: src/pages/PaytoWireTransferForm.tsx:270 +#, c-format +msgid "Using a form" +msgstr "Usando un formulario" + +#: src/pages/PaytoWireTransferForm.tsx:310 +#, c-format +msgid "Import payto:// URI" +msgstr "Importando un URI payto://" + +#: src/pages/PaytoWireTransferForm.tsx:335 +#, c-format +msgid "Recipient" +msgstr "Destinatario" + +#: src/pages/PaytoWireTransferForm.tsx:359 +#, c-format +msgid "IBAN of the recipient's account" +msgstr "Numero IBAN de la cuenta destinataria" + +#: src/pages/PaytoWireTransferForm.tsx:369 +#, c-format +msgid "Transfer subject" +msgstr "Asunto de transferencia" + +#: src/pages/PaytoWireTransferForm.tsx:377 +#, c-format +msgid "subject" +msgstr "asunto" + +#: src/pages/PaytoWireTransferForm.tsx:390 +#, c-format +msgid "some text to identify the transfer" +msgstr "algún texto para identificar la transferencia" + +#: src/pages/PaytoWireTransferForm.tsx:400 +#, c-format +msgid "Amount" +msgstr "Monto" + +#: src/pages/PaytoWireTransferForm.tsx:415 +#, c-format +msgid "amount to transfer" +msgstr "monto a transferir" + +#: src/pages/PaytoWireTransferForm.tsx:425 +#, c-format +msgid "payto URI:" +msgstr "payto URI:" + +#: src/pages/PaytoWireTransferForm.tsx:436 +#, c-format +msgid "uniform resource identifier of the target account" +msgstr "identificador de recurso uniforme de la cuenta destino" + +#: src/pages/PaytoWireTransferForm.tsx:437 +#, c-format +msgid "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]" +msgstr "payto://iban/[iban-destinatario]?message=[asunto]&amount=[%1$s:X.Y]" + +#: src/pages/PaytoWireTransferForm.tsx:457 +#, c-format +msgid "Cancel" +msgstr "Cancelar" + +#: src/pages/PaytoWireTransferForm.tsx:471 +#, c-format +msgid "Send" +msgstr "Envíar" + +#: src/pages/LoginForm.tsx:71 +#, c-format +msgid "Missing username" +msgstr "Falta nombre de usuario" + +#: src/pages/LoginForm.tsx:75 +#, c-format +msgid "Missing password" +msgstr "Falta contraseña" + +#: src/pages/LoginForm.tsx:104 +#, c-format +msgid "Wrong credentials for \"%1$s\"" +msgstr "Credenciales incorrectas para \"%1$s\"" + +#: src/pages/LoginForm.tsx:111 +#, c-format +msgid "Account not found" +msgstr "Cuenta no encontrada" + +#: src/pages/LoginForm.tsx:142 +#, c-format +msgid "Username" +msgstr "Nombre de usuario" + +#: src/pages/LoginForm.tsx:156 +#, c-format +msgid "username of the account" +msgstr "nombre de usuario de la cuenta" + +#: src/pages/LoginForm.tsx:175 +#, c-format +msgid "Password" +msgstr "Contraseña" + +#: src/pages/LoginForm.tsx:188 +#, c-format +msgid "password of the account" +msgstr "contraseña de la cuenta" + +#: src/pages/LoginForm.tsx:223 +#, c-format +msgid "Check" +msgstr "Verificar" + +#: src/pages/LoginForm.tsx:237 +#, c-format +msgid "Log in" +msgstr "Acceso" + +#: src/pages/LoginForm.tsx:249 +#, c-format +msgid "Register" +msgstr "Registrarse" + +#: src/components/Transactions/views.tsx:52 +#, c-format +msgid "Latest transactions" +msgstr "Últimas transacciones" + +#: src/components/Transactions/views.tsx:63 +#, c-format +msgid "Date" +msgstr "Fecha" + +#: src/components/Transactions/views.tsx:71 +#, c-format +msgid "Counterpart" +msgstr "Contraparte" + +#: src/components/Transactions/views.tsx:75 +#, c-format +msgid "Subject" +msgstr "Asunto" + +#: src/components/Transactions/views.tsx:111 +#, c-format +msgid "sent" +msgstr "enviado" + +#: src/components/Transactions/views.tsx:112 +#, c-format +msgid "received" +msgstr "recibido" + +#: src/components/Transactions/views.tsx:127 +#, c-format +msgid "invalid value" +msgstr "valor inválido" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "to" +msgstr "hacia" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "from" +msgstr "desde" + +#: src/components/Transactions/views.tsx:202 +#, c-format +msgid "First page" +msgstr "Primera página" + +#: src/components/Transactions/views.tsx:209 +#, c-format +msgid "Next" +msgstr "Siguiente" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:86 +#, c-format +msgid "Wire transfer completed!" +msgstr "Transferencia bancaria completada!" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:93 +#, c-format +msgid "The withdrawal has been aborted previously and can't be confirmed" +msgstr "La extracción fue abortada anteriormente y no puede ser confirmada" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:100 +#, c-format +msgid "" +"The withdrawal operation can't be confirmed before a wallet accepted the " +"transaction." +msgstr "" +"La operación de extracción no puede ser confirmada antes de que una " +"billetera acepte la transaccion." + +#: src/pages/WithdrawalConfirmationQuestion.tsx:107 +#, c-format +msgid "The operation id is invalid." +msgstr "El id de operación es invalido." + +#: src/pages/WithdrawalConfirmationQuestion.tsx:114 +#, c-format +msgid "The operation was not found." +msgstr "La operación no se encontró." + +#: src/pages/WithdrawalConfirmationQuestion.tsx:121 +#, c-format +msgid "Your balance is not enough for the operation." +msgstr "El saldo no es suficiente para la operación." + +#: src/pages/WithdrawalConfirmationQuestion.tsx:155 +#, c-format +msgid "" +"The reserve operation has been confirmed previously and can't be aborted" +msgstr "" +"La operación en la reserva ya ha sido confirmada previamente y no puede ser " +"abortada" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:186 +#, c-format +msgid "Confirm the withdrawal operation" +msgstr "Confirme la operación de extracción" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:203 +#, c-format +msgid "Wire transfer details" +msgstr "Detalle de transferencia bancaria" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:217 +#, c-format +msgid "Taler Exchange operator's account" +msgstr "Cuenta del operador del Taler Exchange" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:228 +#, c-format +msgid "Taler Exchange operator's name" +msgstr "Nombre del operador del Taler Exchange" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:317 +#, c-format +msgid "Transfer" +msgstr "Transferencia" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:342 +#, c-format +msgid "Authentication required" +msgstr "Autenticación requerida" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:352 +#, c-format +msgid "This operation was created with other username" +msgstr "Esta operación fue creada con otro usuario" + +#: src/pages/OperationState/views.tsx:209 +#, c-format +msgid "" +"Unauthorized to make the operation, maybe the session has expired or the " +"password changed." +msgstr "" +"No autorizado para hacer la operación, quizá la sesión haya expirado or " +"cambió la contraseña." + +#: src/pages/OperationState/views.tsx:218 +#, c-format +msgid "The operation was rejected due to insufficient funds." +msgstr "La operación fue rechazada debido a saldo insuficiente." + +#: src/pages/OperationState/views.tsx:268 +#, c-format +msgid "Withdrawal confirmed" +msgstr "La extracción fue confirmada" + +#: src/pages/OperationState/views.tsx:272 +#, c-format +msgid "" +"The wire transfer to the Taler operator has been initiated. You will soon " +"receive the requested amount in your Taler wallet." +msgstr "" +"La transferencia bancaria al operador Taler fue iniciada. Pronto recibirás " +"el monto pedido en tu billetera Taler." + +#: src/pages/OperationState/views.tsx:287 +#, c-format +msgid "Do not show this again" +msgstr "No mostrar otra vez" + +#: src/pages/OperationState/views.tsx:319 +#, c-format +msgid "Close" +msgstr "Cerrar" + +#: src/pages/OperationState/views.tsx:399 +#, c-format +msgid "On this device" +msgstr "En este dispositivo" + +#: src/pages/OperationState/views.tsx:404 +#, c-format +msgid "" +"If you are using a web browser on desktop you should access your wallet with " +"the GNU Taler WebExtension now or click the link if your WebExtension have " +"the \"Inject Taler support\" option enabled." +msgstr "" +"Si esta usando un explorador web de escritorio deberías acceder ahora a tu " +"billletera con la GNU Taler WebExtension o hacer click en el link si tu " +"extensión tiene la configuración \"Inyectar soporte para Taler\" habilitada." + +#: src/pages/OperationState/views.tsx:417 +#, c-format +msgid "Start" +msgstr "Comenzar" + +#: src/pages/OperationState/views.tsx:426 +#, c-format +msgid "On a mobile phone" +msgstr "En un dispotivo mobile" + +#: src/pages/OperationState/views.tsx:431 +#, c-format +msgid "Scan the QR code with your mobile device." +msgstr "Escanear el código QR con tu dispotivo móvil." + +#: src/pages/WalletWithdrawForm.tsx:73 +#, c-format +msgid "There is an operation already" +msgstr "Ya hay una operación" + +#: src/pages/WalletWithdrawForm.tsx:75 +#, c-format +msgid "Complete or cancel the operation in" +msgstr "Completa o cancela la operación en" + +#: src/pages/WalletWithdrawForm.tsx:84 +#, c-format +msgid "this page" +msgstr "esta página" + +#: src/pages/WalletWithdrawForm.tsx:101 +#, c-format +msgid "invalid" +msgstr "inválido" + +#: src/pages/WalletWithdrawForm.tsx:116 +#, c-format +msgid "Server responded with an invalid withdraw URI" +msgstr "El servidor respondió con una URI de extracción inválida" + +#: src/pages/WalletWithdrawForm.tsx:117 +#, c-format +msgid "Withdraw URI: %1$s" +msgstr "URI de extracción: %1$s" + +#: src/pages/WalletWithdrawForm.tsx:132 +#, c-format +msgid "The operation was rejected due to insufficient funds" +msgstr "La operación fue rechazada debido a fundos insuficientes" + +#: src/pages/WalletWithdrawForm.tsx:253 +#, c-format +msgid "Continue" +msgstr "Continuar" + +#: src/pages/WalletWithdrawForm.tsx:282 +#, c-format +msgid "Prepare your wallet" +msgstr "Prepare su billetera" + +#: src/pages/WalletWithdrawForm.tsx:285 +#, c-format +msgid "" +"After using your wallet you will need to confirm or cancel the operation on " +"this site." +msgstr "" +"Despues de usar tu billetera necesitarás confirmar o cancelar la operación " +"en este sitio." + +#: src/pages/WalletWithdrawForm.tsx:295 +#, c-format +msgid "You need a GNU Taler Wallet" +msgstr "Necesitas una GNU Taler Wallet" + +#: src/pages/WalletWithdrawForm.tsx:300 +#, c-format +msgid "If you don't have one yet you can follow the instruction in" +msgstr "Si no tienes una todavía puedes seguir las instrucciones en" + +#: src/pages/PaymentOptions.tsx:55 +#, c-format +msgid "Send money" +msgstr "Enviar dinero" + +#: src/pages/PaymentOptions.tsx:73 +#, c-format +msgid "to a %1$s wallet" +msgstr "a una billetera %1$s" + +#: src/pages/PaymentOptions.tsx:95 +#, c-format +msgid "Withdraw digital money into your mobile wallet or browser extension" +msgstr "Extraer dinero digital a tu billetera móvil o extesión web" + +#: src/pages/PaymentOptions.tsx:109 +#, c-format +msgid "operation ready" +msgstr "operación lista" + +#: src/pages/PaymentOptions.tsx:129 +#, c-format +msgid "to another bank account" +msgstr "a otra cuenta bancaria" + +#: src/pages/PaymentOptions.tsx:149 +#, c-format +msgid "Make a wire transfer to an account with known bank account number." +msgstr "" +"Hacer una transferencia bancaria a una cuenta con un número de cuenta " +"conocido." + +#: src/pages/PaymentOptions.tsx:171 +#, c-format +msgid "Transfer details" +msgstr "Detalles de transferencia" + +#: src/pages/AccountPage/views.tsx:41 +#, c-format +msgid "This is a demo bank" +msgstr "Este es un banco de demostración" + +#: src/pages/AccountPage/views.tsx:46 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work. In addition to using your own bank account, you can also see the " +"transaction history of some %1$s." +msgstr "" +"Esta parte de la demostración muestra cómo funciona un banco que soporta " +"Taler directamente. Además de usar tu propia cuenta de banco, también podrás " +"ver el historial de transacciones de algunas %1$s." + +#: src/pages/AccountPage/views.tsx:53 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work." +msgstr "" +"Esta parte de la demostración muetra como un banco que soporta Taler " +"directamente funcionaría." + +#: src/pages/AccountPage/views.tsx:70 +#, c-format +msgid "Pending account delete operation" +msgstr "Operación pendiente de eliminación de cuenta" + +#: src/pages/AccountPage/views.tsx:72 +#, c-format +msgid "Pending account update operation" +msgstr "Operación pendiente de actualización de cuenta" + +#: src/pages/AccountPage/views.tsx:74 +#, c-format +msgid "Pending password update operation" +msgstr "Operación pendiente de actualización de password" + +#: src/pages/AccountPage/views.tsx:76 +#, c-format +msgid "Pending transaction operation" +msgstr "Operación pendiente de transacción" + +#: src/pages/AccountPage/views.tsx:78 +#, c-format +msgid "Pending withdrawal operation" +msgstr "Operación pendiente de extracción" + +#: src/pages/AccountPage/views.tsx:80 +#, c-format +msgid "Pending cashout operation" +msgstr "Operación pendiente de egreso" + +#: src/pages/AccountPage/views.tsx:91 +#, c-format +msgid "You can complete or cancel the operation in" +msgstr "Puedes completar o cancelar la operación en" + +#: src/pages/BankFrame.tsx:64 +#, c-format +msgid "Internal error, please report." +msgstr "Error interno, por favor reporte el error." + +#: src/pages/BankFrame.tsx:100 +#, c-format +msgid "Preferences" +msgstr "Preferencias" + +#: src/pages/BankFrame.tsx:184 +#, c-format +msgid "Welcome, %1$s" +msgstr "Bienvenido/a, %1$s" + +#: src/pages/WireTransfer.tsx:79 +#, c-format +msgid "Make a wire transfer" +msgstr "Hacer una transferencia bancaria" + +#: src/pages/admin/AccountList.tsx:72 +#, c-format +msgid "Accounts" +msgstr "Cuentas" + +#: src/pages/admin/AccountList.tsx:75 +#, c-format +msgid "A list of all business account in the bank." +msgstr "Una lista de todas las cuentas en el banco." + +#: src/pages/admin/AccountList.tsx:86 +#, c-format +msgid "Create account" +msgstr "Crear cuenta" + +#: src/pages/admin/AccountList.tsx:106 +#, c-format +msgid "Name" +msgstr "Nombre" + +#: src/pages/admin/AccountList.tsx:110 +#, c-format +msgid "Balance" +msgstr "Saldo" + +#: src/pages/admin/AccountList.tsx:112 +#, c-format +msgid "Actions" +msgstr "Acciones" + +#: src/pages/admin/AccountList.tsx:151 +#, c-format +msgid "unknown" +msgstr "desconocido" + +#: src/pages/admin/AccountList.tsx:170 +#, c-format +msgid "change password" +msgstr "cambiar contraseña" + +#: src/pages/admin/AccountList.tsx:179 +#, c-format +msgid "cashouts" +msgstr "egresos" + +#: src/pages/admin/AccountList.tsx:189 +#, c-format +msgid "remove" +msgstr "elimiar" + +#: src/pages/admin/AdminHome.tsx:168 +#, c-format +msgid "Cashout not implemented" +msgstr "Egreso no soportado" + +#: src/pages/admin/AdminHome.tsx:184 +#, c-format +msgid "Select a section" +msgstr "Seleccione una sección" + +#: src/pages/admin/AdminHome.tsx:202 +#, c-format +msgid "Last hour" +msgstr "Última hora" + +#: src/pages/admin/AdminHome.tsx:208 +#, c-format +msgid "Last day" +msgstr "Último día" + +#: src/pages/admin/AdminHome.tsx:216 +#, c-format +msgid "Last month" +msgstr "Último mes" + +#: src/pages/admin/AdminHome.tsx:222 +#, c-format +msgid "Last year" +msgstr "Último año" + +#: src/pages/admin/AdminHome.tsx:310 +#, c-format +msgid "Last Year" +msgstr "Último Año" + +#: src/pages/admin/AdminHome.tsx:325 +#, c-format +msgid "Trading volume on %1$s compared to %2$s" +msgstr "Vólumen de comercio en %1$s comparado con %2$s" + +#: src/pages/admin/AdminHome.tsx:342 +#, c-format +msgid "Cashin" +msgstr "Ingreso" + +#: src/pages/admin/AdminHome.tsx:352 +#, c-format +msgid "Cashout" +msgstr "Egreso" + +#: src/pages/admin/AdminHome.tsx:364 +#, c-format +msgid "Payin" +msgstr "Envios de dinero" + +#: src/pages/admin/AdminHome.tsx:374 +#, c-format +msgid "Payout" +msgstr "Recibos de dinero" + +#: src/pages/admin/AdminHome.tsx:388 +#, c-format +msgid "download stats as CSV" +msgstr "descargar estadísticas en CSV" + +#: src/pages/admin/AdminHome.tsx:494 +#, c-format +msgid "Decreased by" +msgstr "Descendiente por" + +#: src/pages/admin/AdminHome.tsx:498 +#, c-format +msgid "Increased by" +msgstr "Ascendente por" + +#: src/pages/DownloadStats.tsx:89 +#, c-format +msgid "Download bank stats" +msgstr "Descargar estadísticas del banco" + +#: src/pages/DownloadStats.tsx:110 +#, c-format +msgid "Include hour metric" +msgstr "Incluir métrica horaria" + +#: src/pages/DownloadStats.tsx:143 +#, c-format +msgid "Include day metric" +msgstr "Incluir métrica diaria" + +#: src/pages/DownloadStats.tsx:173 +#, c-format +msgid "Include month metric" +msgstr "Incluir métrica mensual" + +#: src/pages/DownloadStats.tsx:206 +#, c-format +msgid "Include year metric" +msgstr "Incluir métrica anual" + +#: src/pages/DownloadStats.tsx:239 +#, c-format +msgid "Include table header" +msgstr "Incluir encabezado de tabla" + +#: src/pages/DownloadStats.tsx:272 +#, c-format +msgid "Add previous metric for compare" +msgstr "Agregar métrica previa para comparar" + +#: src/pages/DownloadStats.tsx:307 +#, c-format +msgid "Fail on first error" +msgstr "Fallar en el primer error" + +#: src/pages/DownloadStats.tsx:364 +#, c-format +msgid "Download" +msgstr "Descargar" + +#: src/pages/DownloadStats.tsx:381 +#, c-format +msgid "downloading... %1$s" +msgstr "descargando... %1$s" + +#: src/pages/DownloadStats.tsx:399 +#, c-format +msgid "Download completed" +msgstr "Descarga completada" + +#: src/pages/DownloadStats.tsx:400 +#, c-format +msgid "click here to save the file in your computer" +msgstr "click aquí para guardar el archivo en su computadora" + +#: src/pages/PublicHistoriesPage.tsx:78 +#, c-format +msgid "History of public accounts" +msgstr "Historial de cuentas públicas" + +#: src/pages/RegistrationPage.tsx:48 +#, c-format +msgid "Currently, the bank is not accepting new registrations!" +msgstr "Actualmente, el banco no está aceptado nuevos registros!" + +#: src/pages/RegistrationPage.tsx:87 +#, c-format +msgid "Missing name" +msgstr "Falta nombre" + +#: src/pages/RegistrationPage.tsx:91 +#, c-format +msgid "Use letters and numbers only, and start with a lowercase letter" +msgstr "Solo use letras y números, y comience con una letra minúscula" + +#: src/pages/RegistrationPage.tsx:107 +#, c-format +msgid "Passwords don't match" +msgstr "La contraseña no coincide" + +#: src/pages/RegistrationPage.tsx:130 +#, c-format +msgid "Server replied with invalid phone or email." +msgstr "El servidor repondio con teléfono o dirección de correo inválido." + +#: src/pages/RegistrationPage.tsx:137 +#, c-format +msgid "Registration is disabled because the bank ran out of bonus credit." +msgstr "" +"El registro está deshabilitado porque el banco se quedó sin crédito bonus." + +#: src/pages/RegistrationPage.tsx:144 +#, c-format +msgid "No enough permission to create that account." +msgstr "Sin permisos suficientes para crear esa cuenta." + +#: src/pages/RegistrationPage.tsx:151 +#, c-format +msgid "That account id is already taken." +msgstr "El identificador de cuenta ya está tomado." + +#: src/pages/RegistrationPage.tsx:158 +#, c-format +msgid "That username is already taken." +msgstr "El nombre de usuario ya está tomado." + +#: src/pages/RegistrationPage.tsx:165 +#, c-format +msgid "That username can't be used because is reserved." +msgstr "El nombre de usuario no puede ser usado porque esta reservado." + +#: src/pages/RegistrationPage.tsx:172 +#, c-format +msgid "Only admin is allow to set debt limit." +msgstr "Solo el administrador tiene permitido cambiar el límite de deuda." + +#: src/pages/RegistrationPage.tsx:179 +#, c-format +msgid "No information for the selected authentication channel." +msgstr "No hay información para el canal de autenticación seleccionado." + +#: src/pages/RegistrationPage.tsx:186 +#, c-format +msgid "Authentication channel is not supported." +msgstr "Canal de autenticación no esta soportado." + +#: src/pages/RegistrationPage.tsx:193 +#, c-format +msgid "Only admin can create accounts with second factor authentication." +msgstr "" +"Solo el administrador puede crear cuentas con el segundo factor de " +"autenticación." + +#: src/pages/RegistrationPage.tsx:233 +#, c-format +msgid "Account registration" +msgstr "Registro de cuenta" + +#: src/pages/RegistrationPage.tsx:315 +#, c-format +msgid "Repeat password" +msgstr "Repita la contraseña" + +#: src/pages/RegistrationPage.tsx:457 +#, c-format +msgid "Create a random temporary user" +msgstr "Crear un usuario aleatorio temporal" + +#: src/pages/QrCodeSection.tsx:110 +#, c-format +msgid "If you have a Taler wallet installed in this device" +msgstr "Si tienes una billetera Taler instalada en este dispositivo" + +#: src/pages/QrCodeSection.tsx:116 +#, c-format +msgid "" +"You will see the details of the operation in your wallet including the fees " +"(if applies). If you still don't have one you can install it following " +"instructions in" +msgstr "" +"Veras los detalles de la operación en tu billetera incluyendo comisiones (si " +"aplicán). Si todavía no tienes una puedes instalarla siguiendo las " +"instrucciones en" + +#: src/pages/QrCodeSection.tsx:143 +#, c-format +msgid "Withdraw" +msgstr "Retirar" + +#: src/pages/QrCodeSection.tsx:152 +#, c-format +msgid "Or if you have the wallet in another device" +msgstr "O si tienes la billetera en otro dispositivo" + +#: src/pages/QrCodeSection.tsx:157 +#, c-format +msgid "Scan the QR below to start the withdrawal." +msgstr "Escanea el QR debajo para comenzar la extracción." + +#: src/pages/WithdrawalQRCode.tsx:79 +#, c-format +msgid "Operation aborted" +msgstr "Operación abortada" + +#: src/pages/WithdrawalQRCode.tsx:82 +#, c-format +msgid "" +"The wire transfer to the Taler Exchange operator's account was aborted, your " +"balance was not affected." +msgstr "" +"La transferencia bancaria a la cuenta del operador del Taler Exchange fue " +"abortada, su saldo no fue afectado." + +#: src/pages/WithdrawalQRCode.tsx:88 +#, c-format +msgid "You can close this page now or continue to the account page." +msgstr "" +"Ya puedes cerrar esta pagina or continuar a la página de estado de cuenta." + +#: src/pages/WithdrawalQRCode.tsx:147 +#, c-format +msgid "Done" +msgstr "Listo" + +#: src/pages/WithdrawalQRCode.tsx:158 +#, c-format +msgid "Operation canceled" +msgstr "Operación cancelada" + +#: src/pages/WithdrawalQRCode.tsx:173 +#, c-format +msgid "" +"The operation is marked as 'selected' but some step in the withdrawal failed" +msgstr "" +"La operación está marcada como 'seleccionada' pero algunos pasos en la " +"extracción fallaron" + +#: src/pages/WithdrawalQRCode.tsx:175 +#, c-format +msgid "The account is selected but no withdrawal identification found." +msgstr "" +"La cuenta está seleccionada pero no se encontró el identificador de " +"extracción." + +#: src/pages/WithdrawalQRCode.tsx:188 +#, c-format +msgid "" +"There is a withdrawal identification but no account has been selected or the " +"selected account is invalid." +msgstr "" +"Hay un identificador de extracción pero la cuenta no ha sido seleccionada o " +"la selccionada es inválida." + +#: src/pages/WithdrawalQRCode.tsx:202 +#, c-format +msgid "" +"No withdrawal ID found and no account has been selected or the selected " +"account is invalid." +msgstr "" +"No hay un identificador de extracción y ninguna cuenta a sido seleccionada o " +"la seleccionada es inválida." + +#: src/pages/WithdrawalQRCode.tsx:259 +#, c-format +msgid "Operation not found" +msgstr "Operación no encontrada" + +#: src/pages/WithdrawalQRCode.tsx:263 +#, c-format +msgid "" +"This operation is not known by the server. The operation id is wrong or the " +"server deleted the operation information before reaching here." +msgstr "" +"Esta operación no es conocida por el servidor. El identificador de operación " +"es incorrecto o el server borró la información de la operación antes de " +"llegar hasta aquí." + +#: src/pages/WithdrawalQRCode.tsx:278 +#, c-format +msgid "Cotinue to dashboard" +msgstr "Continuar al panel" + +#: src/pages/SolveChallengePage.tsx:98 +#, c-format +msgid "Cashout not found. It may be also mean that it was already aborted." +msgstr "Egreso no econtrado. También puede significar que ya ha sido abortado." + +#: src/pages/SolveChallengePage.tsx:136 +#, c-format +msgid "Challenge not found." +msgstr "Desafío no encontrado." + +#: src/pages/SolveChallengePage.tsx:143 +#, c-format +msgid "This user is not authorized to complete this challenge." +msgstr "Este usuario no está autorizado para completar este desafío." + +#: src/pages/SolveChallengePage.tsx:150 +#, c-format +msgid "Too many attempts, try another code." +msgstr "Demasiados intentos, intente otro código." + +#: src/pages/SolveChallengePage.tsx:157 +#, c-format +msgid "The confirmation code is wrong, try again." +msgstr "El código de confirmación es erroneo, intente otra vez." + +#: src/pages/SolveChallengePage.tsx:164 +#, c-format +msgid "The operation expired." +msgstr "La operación expiró." + +#: src/pages/SolveChallengePage.tsx:197 +#, c-format +msgid "The operation failed." +msgstr "La operación falló." + +#: src/pages/SolveChallengePage.tsx:212 +#, c-format +msgid "The operation needs another confirmation to complete." +msgstr "La operación necesita otra confirmación para completar." + +#: src/pages/SolveChallengePage.tsx:224 +#, c-format +msgid "Account delete" +msgstr "Eliminación de cuenta" + +#: src/pages/SolveChallengePage.tsx:226 +#, c-format +msgid "Account update" +msgstr "Actualización de cuenta" + +#: src/pages/SolveChallengePage.tsx:228 +#, c-format +msgid "Password update" +msgstr "Actualización de contraseña" + +#: src/pages/SolveChallengePage.tsx:230 +#, c-format +msgid "Wire transfer" +msgstr "Transferencia bancaria" + +#: src/pages/SolveChallengePage.tsx:232 +#, c-format +msgid "Withdrawal" +msgstr "Extracción" + +#: src/pages/SolveChallengePage.tsx:248 +#, c-format +msgid "Confirm the operation" +msgstr "Confirmar la operación" + +#: src/pages/SolveChallengePage.tsx:271 +#, c-format +msgid "Enter the confirmation code" +msgstr "Ingresar el código de confirmación" + +#: src/pages/SolveChallengePage.tsx:313 +#, c-format +msgid "Confirm" +msgstr "Confirmar" + +#: src/pages/SolveChallengePage.tsx:348 +#, c-format +msgid "Send again" +msgstr "Enviar otra vez" + +#: src/pages/SolveChallengePage.tsx:359 +#, c-format +msgid "Send code" +msgstr "Enviar código" + +#: src/pages/SolveChallengePage.tsx:369 +#, c-format +msgid "Operation details" +msgstr "Detalles de operación" + +#: src/pages/SolveChallengePage.tsx:529 +#, c-format +msgid "Challenge details" +msgstr "Detalles del desafío" + +#: src/pages/SolveChallengePage.tsx:536 +#, c-format +msgid "Sent at" +msgstr "Enviado a" + +#: src/pages/SolveChallengePage.tsx:551 +#, c-format +msgid "To phone" +msgstr "Al teléfono" + +#: src/pages/SolveChallengePage.tsx:553 +#, c-format +msgid "To email" +msgstr "Al email" + +#: src/pages/WithdrawalOperationPage.tsx:49 +#, c-format +msgid "The Withdrawal URI is not valid" +msgstr "El URI de estracción no es válido" + +#: src/components/Cashouts/views.tsx:100 +#, c-format +msgid "Latest cashouts" +msgstr "Últimos egresos" + +#: src/components/Cashouts/views.tsx:111 +#, c-format +msgid "Created" +msgstr "Creado" + +#: src/components/Cashouts/views.tsx:115 +#, c-format +msgid "Total debit" +msgstr "Débito total" + +#: src/components/Cashouts/views.tsx:119 +#, c-format +msgid "Total credit" +msgstr "Crédito total" + +#: src/pages/ProfileNavigation.tsx:70 +#, c-format +msgid "Details" +msgstr "Detalles" + +#: src/pages/ProfileNavigation.tsx:74 +#, c-format +msgid "Delete" +msgstr "Borrar" + +#: src/pages/ProfileNavigation.tsx:78 +#, c-format +msgid "Credentials" +msgstr "Credenciales" + +#: src/pages/ProfileNavigation.tsx:82 +#, c-format +msgid "Cashouts" +msgstr "Egresos" + +#: src/pages/business/CreateCashout.tsx:95 +#, c-format +msgid "Unable to create a cashout" +msgstr "Imposible crear un egreso" + +#: src/pages/business/CreateCashout.tsx:96 +#, c-format +msgid "The bank configuration does not support cashout operations." +msgstr "La configuración del banco no soporta operaciones de egreso." + +#: src/pages/business/CreateCashout.tsx:223 +#, c-format +msgid "need to be higher due to fees" +msgstr "necesita ser mayor debido a las comisiones" + +#: src/pages/business/CreateCashout.tsx:225 +#, c-format +msgid "the total transfer at destination will be zero" +msgstr "el total de la transferencia en destino será cero" + +#: src/pages/business/CreateCashout.tsx:250 +#, c-format +msgid "Cashout created" +msgstr "Egreso creado" + +#: src/pages/business/CreateCashout.tsx:272 +#, c-format +msgid "" +"Duplicated request detected, check if the operation succeeded or try again." +msgstr "" +"Se detectó una petición duplicada, verifique si la operación tuvo éxito o " +"intente otra vez." + +#: src/pages/business/CreateCashout.tsx:279 +#, c-format +msgid "The conversion rate was incorrectly applied" +msgstr "La tasa de conversión se aplicó incorrectamente" + +#: src/pages/business/CreateCashout.tsx:286 +#, c-format +msgid "The account does not have sufficient funds" +msgstr "La cuenta no tiene fondos suficientes" + +#: src/pages/business/CreateCashout.tsx:293 +#, c-format +msgid "Cashouts are not supported" +msgstr "Egresos no están soportados" + +#: src/pages/business/CreateCashout.tsx:300 +#, c-format +msgid "Missing cashout URI in the profile" +msgstr "Falta dirección de egreso en el perfíl" + +#: src/pages/business/CreateCashout.tsx:307 +#, c-format +msgid "" +"Sending the confirmation message failed, retry later or contact the " +"administrator." +msgstr "" +"El envío del mensaje de confirmación falló, intente mas tarde o contacte al " +"administrador." + +#: src/pages/business/CreateCashout.tsx:339 +#, c-format +msgid "Conversion rate" +msgstr "Tasa de conversión" + +#: src/pages/business/CreateCashout.tsx:360 +#, c-format +msgid "Fee" +msgstr "Comisión" + +#: src/pages/business/CreateCashout.tsx:374 +#, c-format +msgid "To account" +msgstr "Hacia cuenta" + +#: src/pages/business/CreateCashout.tsx:381 +#, c-format +msgid "No cashout account" +msgstr "No hay cuenta de egreso" + +#: src/pages/business/CreateCashout.tsx:382 +#, c-format +msgid "Before doing a cashout you need to complete your profile" +msgstr "Antes de hacer un egreso necesita completar su perfíl" + +#: src/pages/business/CreateCashout.tsx:440 +#, c-format +msgid "Amount to send" +msgstr "Monto a enviar" + +#: src/pages/business/CreateCashout.tsx:441 +#, c-format +msgid "Amount to receive" +msgstr "Monto a recibir" + +#: src/pages/business/CreateCashout.tsx:490 +#, c-format +msgid "Total cost" +msgstr "Costo total" + +#: src/pages/business/CreateCashout.tsx:505 +#, c-format +msgid "Balance left" +msgstr "Saldo remanente" + +#: src/pages/business/CreateCashout.tsx:520 +#, c-format +msgid "Before fee" +msgstr "Antes de comisión" + +#: src/pages/business/CreateCashout.tsx:533 +#, c-format +msgid "Total cashout transfer" +msgstr "Total de egreso" + +#: src/pages/business/CreateCashout.tsx:553 +#, c-format +msgid "No cashout channel available" +msgstr "No hay canal de egreso disponible" + +#: src/pages/business/CreateCashout.tsx:555 +#, c-format +msgid "" +"Before doing a cashout the server need to provide an second channel to " +"confirm the operation" +msgstr "" +"Antes de hacer un egreso el servidor necesita proveer un segundo canal para " +"confirmar la operación" + +#: src/pages/business/CreateCashout.tsx:567 +#, c-format +msgid "Second factor authentication" +msgstr "Segundo factor de autenticación" + +#: src/pages/business/CreateCashout.tsx:598 +#, c-format +msgid "Email" +msgstr "Correo eletrónico" + +#: src/pages/business/CreateCashout.tsx:600 +#, c-format +msgid "add a email in your profile to enable this option" +msgstr "agrege un correo en su perfíl para habilitar esta opción" + +#: src/pages/business/CreateCashout.tsx:646 +#, c-format +msgid "SMS" +msgstr "SMS" + +#: src/pages/business/CreateCashout.tsx:648 +#, c-format +msgid "add a phone number in your profile to enable this option" +msgstr "agregue un número de teléfono para habilitar esta opción" + +#: src/pages/account/CashoutListForAccount.tsx:52 +#, c-format +msgid "Cashout for account %1$s" +msgstr "Egreso para cuenta %1$s" + +#: src/pages/admin/AccountForm.tsx:165 +#, c-format +msgid "it doesn't have the pattern of an IBAN number" +msgstr "no tiene el patrón de un número IBAN" + +#: src/pages/admin/AccountForm.tsx:185 +#, c-format +msgid "it doesn't have the pattern of an email" +msgstr "no tiene el patrón de un correo electrónico" + +#: src/pages/admin/AccountForm.tsx:190 +#, c-format +msgid "should start with +" +msgstr "debería comenzar con un +" + +#: src/pages/admin/AccountForm.tsx:192 +#, c-format +msgid "phone number can't have other than numbers" +msgstr "número de teléfono no puede tener otra cosa que numeros" + +#: src/pages/admin/AccountForm.tsx:329 +#, c-format +msgid "account identification in the bank" +msgstr "identificador de cuenta en el banco" + +#: src/pages/admin/AccountForm.tsx:365 +#, c-format +msgid "name of the person owner the account" +msgstr "nombre de la persona dueña de la cuenta" + +#: src/pages/admin/AccountForm.tsx:374 +#, c-format +msgid "Internal IBAN" +msgstr "IBAN interno" + +#: src/pages/admin/AccountForm.tsx:377 +#, c-format +msgid "if empty a random account number will be assigned" +msgstr "si está vacío un número de cuenta aleatorio será asignado" + +#: src/pages/admin/AccountForm.tsx:378 +#, c-format +msgid "account identification for bank transfer" +msgstr "identificador de cuenta para transferencia bancaria" + +#: src/pages/admin/AccountForm.tsx:423 +#, c-format +msgid "Phone" +msgstr "Teléfono" + +#: src/pages/admin/AccountForm.tsx:451 +#, c-format +msgid "Cashout IBAN" +msgstr "IBAN de egreso" + +#: src/pages/admin/AccountForm.tsx:452 +#, c-format +msgid "account number where the money is going to be sent when doing cashouts" +msgstr "" +"numero de cuenta donde el dinero será enviado cuando se ejecuten egresos" + +#: src/pages/admin/AccountForm.tsx:470 +#, c-format +msgid "Max debt" +msgstr "Máxima deuda" + +#: src/pages/admin/AccountForm.tsx:494 +#, c-format +msgid "how much is user able to transfer after zero balance" +msgstr "cuanto tiene habilitado a transferir despues de un saldo en cero" + +#: src/pages/admin/AccountForm.tsx:508 +#, c-format +msgid "Is this a Taler Exchange?" +msgstr "Es un Taler Exchange?" + +#: src/pages/admin/AccountForm.tsx:549 +#, c-format +msgid "This server doesn't support second factor authentication." +msgstr "Este servidor no tiene soporte para segundo factor de autenticación." + +#: src/pages/admin/AccountForm.tsx:560 +#, c-format +msgid "Enable second factor authentication" +msgstr "Hábilitar segundo factor de autenticación" + +#: src/pages/admin/AccountForm.tsx:596 +#, c-format +msgid "Using email" +msgstr "Usando correo eletrónico" + +#: src/pages/admin/AccountForm.tsx:654 +#, c-format +msgid "Using SMS" +msgstr "Usando SMS" + +#: src/pages/admin/AccountForm.tsx:691 +#, c-format +msgid "Is this account public?" +msgstr "Es una cuenta pública?" + +#: src/pages/admin/AccountForm.tsx:719 +#, c-format +msgid "public accounts have their balance publicly accessible" +msgstr "las cuentas públicas tienen su saldo accesible al público" + +#: src/pages/account/ShowAccountDetails.tsx:100 +#, c-format +msgid "Account updated" +msgstr "Cuenta actualizada" + +#: src/pages/account/ShowAccountDetails.tsx:107 +#, c-format +msgid "The rights to change the account are not sufficient" +msgstr "Los permisos para cambiar la cuenta no son suficientes" + +#: src/pages/account/ShowAccountDetails.tsx:114 +#, c-format +msgid "The username was not found" +msgstr "El nombre de usaurio no se encontró" + +#: src/pages/account/ShowAccountDetails.tsx:121 +#, c-format +msgid "" +"You can't change the legal name, please contact the your account " +"administrator." +msgstr "" +"No puede cambiar el nombre legal, por favor contacte el administrador de la " +"cuenta." + +#: src/pages/account/ShowAccountDetails.tsx:128 +#, c-format +msgid "" +"You can't change the debt limit, please contact the your account " +"administrator." +msgstr "" +"No puede cambiar el límite de deuda, por favor contacte el administrador de " +"la cuenta." + +#: src/pages/account/ShowAccountDetails.tsx:135 +#, c-format +msgid "" +"You can't change the cashout address, please contact the your account " +"administrator." +msgstr "" +"No puede cambiar la dirección de egreso, por favor contacte al administrador " +"de la cuenta." + +#: src/pages/account/ShowAccountDetails.tsx:177 +#, c-format +msgid "Account \"%1$s\"" +msgstr "Cuenta \"%1$s\"" + +#: src/pages/account/ShowAccountDetails.tsx:190 +#, c-format +msgid "Change details" +msgstr "Cambiar detalles" + +#: src/pages/account/ShowAccountDetails.tsx:235 +#, c-format +msgid "Update" +msgstr "Actualizar" + +#: src/pages/account/UpdateAccountPassword.tsx:78 +#, c-format +msgid "password doesn't match" +msgstr "la contraseña no coincide" + +#: src/pages/account/UpdateAccountPassword.tsx:95 +#, c-format +msgid "Password changed" +msgstr "La contraseña cambió" + +#: src/pages/account/UpdateAccountPassword.tsx:102 +#, c-format +msgid "Not authorized to change the password, maybe the session is invalid." +msgstr "No está autorizado a cambiar el password, quizá la sesión es invalida." + +#: src/pages/account/UpdateAccountPassword.tsx:112 +#, c-format +msgid "" +"You need to provide the old password. If you don't have it contact your " +"account administrator." +msgstr "" +"Se necesita el password viejo para cambiar la contraseña. Si no lo tiene " +"contacte a su administrador." + +#: src/pages/account/UpdateAccountPassword.tsx:117 +#, c-format +msgid "Your current password doesn't match, can't change to a new password." +msgstr "" +"Su actual contraseña no coincide, no puede cambiar a una nueva contraseña." + +#: src/pages/account/UpdateAccountPassword.tsx:149 +#, c-format +msgid "Update password" +msgstr "Actualizar contraseña" + +#: src/pages/account/UpdateAccountPassword.tsx:167 +#, c-format +msgid "New password" +msgstr "Nueva contraseña" + +#: src/pages/account/UpdateAccountPassword.tsx:195 +#, c-format +msgid "Type it again" +msgstr "Escribalo otra vez" + +#: src/pages/account/UpdateAccountPassword.tsx:217 +#, c-format +msgid "repeat the same password" +msgstr "repita la misma contraseña" + +#: src/pages/account/UpdateAccountPassword.tsx:227 +#, c-format +msgid "Current password" +msgstr "Contraseña actual" + +#: src/pages/account/UpdateAccountPassword.tsx:248 +#, c-format +msgid "your current password, for security" +msgstr "su actual contraseña, por seguridad" + +#: src/pages/account/UpdateAccountPassword.tsx:272 +#, c-format +msgid "Change" +msgstr "Cambiar" + +#: src/pages/admin/CreateNewAccount.tsx:74 +#, c-format +msgid "" +"Account created with password \"%1$s\". The user must change the password on " +"the next login." +msgstr "" +"Cuenta creada con contraseña \"%1$s\". El usuario debe cambiar la contraseña " +"en el siguiente ingreso." + +#: src/pages/admin/CreateNewAccount.tsx:83 +#, c-format +msgid "Server replied that phone or email is invalid" +msgstr "El servidor respondió que el teléfono o correo eletrónico es invalido" + +#: src/pages/admin/CreateNewAccount.tsx:90 +#, c-format +msgid "The rights to perform the operation are not sufficient" +msgstr "Los permisos para ejecutar la operación no son suficientes" + +#: src/pages/admin/CreateNewAccount.tsx:97 +#, c-format +msgid "Account username is already taken" +msgstr "El nombre del usuario ya está tomado" + +#: src/pages/admin/CreateNewAccount.tsx:104 +#, c-format +msgid "Account id is already taken" +msgstr "El id de cuenta ya está tomado" + +#: src/pages/admin/CreateNewAccount.tsx:111 +#, c-format +msgid "Bank ran out of bonus credit." +msgstr "El banco no tiene mas crédito de bonus." + +#: src/pages/admin/CreateNewAccount.tsx:118 +#, c-format +msgid "Account username can't be used because is reserved" +msgstr "" +"El nombre de usuario de la cuenta no puede userse porque está reservado" + +#: src/pages/admin/CreateNewAccount.tsx:160 +#, c-format +msgid "Can't create accounts" +msgstr "No puede crear cuentas" + +#: src/pages/admin/CreateNewAccount.tsx:161 +#, c-format +msgid "Only system admin can create accounts." +msgstr "Solo los administradores del sistema pueden crear cuentas." + +#: src/pages/admin/CreateNewAccount.tsx:183 +#, c-format +msgid "New business account" +msgstr "Nueva cuenta" + +#: src/pages/admin/CreateNewAccount.tsx:209 +#, c-format +msgid "Create" +msgstr "Crear" + +#: src/pages/admin/RemoveAccount.tsx:94 +#, c-format +msgid "Can't delete the account" +msgstr "No se puede eliminar la cuenta" + +#: src/pages/admin/RemoveAccount.tsx:95 +#, c-format +msgid "" +"The account can't be delete while still holding some balance. First make " +"sure that the owner make a complete cashout." +msgstr "" +"La cuenta no puede ser eliminada mientras tiene saldo. Primero aseguresé que " +"el dueño haga un egreso completo." + +#: src/pages/admin/RemoveAccount.tsx:117 +#, c-format +msgid "Account removed" +msgstr "Cuenta eliminada" + +#: src/pages/admin/RemoveAccount.tsx:124 +#, c-format +msgid "No enough permission to delete the account." +msgstr "No tiene permisos suficientes para eliminar la cuenta." + +#: src/pages/admin/RemoveAccount.tsx:131 +#, c-format +msgid "The username was not found." +msgstr "El nombr ede usuario no se encontró." + +#: src/pages/admin/RemoveAccount.tsx:138 +#, c-format +msgid "Can't delete a reserved username." +msgstr "No se puede eliminar un nombre de usuario reservado." + +#: src/pages/admin/RemoveAccount.tsx:145 +#, c-format +msgid "Can't delete an account with balance different than zero." +msgstr "No se puede eliminar una cuenta con saldo diferente a cero." + +#: src/pages/admin/RemoveAccount.tsx:170 +#, c-format +msgid "name doesn't match" +msgstr "el nombre no coincide" + +#: src/pages/admin/RemoveAccount.tsx:180 +#, c-format +msgid "You are going to remove the account" +msgstr "Está por eliminar la cuenta" + +#: src/pages/admin/RemoveAccount.tsx:182 +#, c-format +msgid "This step can't be undone." +msgstr "Este paso no puede ser deshecho." + +#: src/pages/admin/RemoveAccount.tsx:188 +#, c-format +msgid "Deleting account \"%1$s\"" +msgstr "Borrando cuenta \"%1$s\"" + +#: src/pages/admin/RemoveAccount.tsx:206 +#, c-format +msgid "Verification" +msgstr "Verificación" + +#: src/pages/admin/RemoveAccount.tsx:231 +#, c-format +msgid "enter the account name that is going to be deleted" +msgstr "ingrese el nombre de cuenta que será eliminado" + +#: src/pages/business/ShowCashoutDetails.tsx:49 +#, c-format +msgid "cashout id should be a number" +msgstr "debería ser un correo electrónico" + +#: src/pages/business/ShowCashoutDetails.tsx:65 +#, c-format +msgid "This cashout not found. Maybe already aborted." +msgstr "Este egreso no se encontró. Quizá fue abortado." + +#: src/pages/business/ShowCashoutDetails.tsx:106 +#, c-format +msgid "Cashout detail" +msgstr "Detalles de egreso" + +#: src/pages/business/ShowCashoutDetails.tsx:139 +#, c-format +msgid "Debited" +msgstr "Debitado" + +#: src/pages/business/ShowCashoutDetails.tsx:154 +#, c-format +msgid "Credited" +msgstr "Acreditado" + +#: src/Routing.tsx:140 +#, c-format +msgid "Welcome to %1$s!" +msgstr "Bienvenido a %1$s!" + +#, c-format +#~ msgid "" +#~ "You can't change the contact data, please contact the your account " +#~ "administrator." +#~ msgstr "" +#~ "No puede cambiar los datos de contacto, por favor contacte al " +#~ "administrador de la cuenta." + +#, c-format +#~ msgid "Account not found." +#~ msgstr "Cuenta no encontrada." + +#, c-format +#~ msgid "Confirmed" +#~ msgstr "Confirmado" + +#, c-format +#~ msgid "Status" +#~ msgstr "Estado" + +#, c-format +#~ msgid "never" +#~ msgstr "nunca" + +#, c-format +#~ msgid "Cashout was already confimed." +#~ msgstr "Egreso ya fue confirmado." + +#, c-format +#~ msgid "Cashout operation is not supported." +#~ msgstr "Operación de egreso no soportada." + +#, c-format +#~ msgid "The cashout operation is already aborted." +#~ msgstr "La operación de egreso ya está abortada." + +#, c-format +#~ msgid "Missing destination account." +#~ msgstr "Falta cuenta destino." + +#, c-format +#~ msgid "Too many failed attempts." +#~ msgstr "Demasiados intentos fallidos." + +#, c-format +#~ msgid "The code for this cashout is invalid." +#~ msgstr "El código para este egreso es invalido." + +#, c-format +#~ msgid "Abort" +#~ msgstr "Abortar" + +#, fuzzy, c-format +#~ msgid "" +#~ "The Taler Exchange operator is selected but the Taler Exchange operator " +#~ "account is missing or invalid." +#~ msgstr "" +#~ "El operador esta seleccionado pero la URI payto del operador falta o es " +#~ "invalida." + +#, c-format +#~ msgid "could not be parsed" +#~ msgstr "inválido" + +#, c-format +#~ msgid "Confirmation the operation using" +#~ msgstr "Confirme la operación usando" + +#, c-format +#~ msgid "Is public" +#~ msgstr "es publica" + +#, c-format +#~ msgid "Logout" +#~ msgstr "Cierre de sesión" + +#, c-format +#~ msgid "Skip to main content" +#~ msgstr "Saltar el menú de navegación" + +#, c-format +#~ msgid "Taler logo" +#~ msgstr "Logo Taler" + +#, c-format +#~ msgid "Please login!" +#~ msgstr "Por favor inicia sesión!" + +#, c-format +#~ msgid "Login" +#~ msgstr "Iniciar sesión" + +#, c-format +#~ msgid "Missing IBAN" +#~ msgstr "Falta IBAN" + +#, c-format +#~ msgid "Missing subject" +#~ msgstr "Falta asunto" + +#, c-format +#~ msgid "Receiver IBAN:" +#~ msgstr "IBAN receptor:" + +#, c-format +#~ msgid "Amount:" +#~ msgstr "Monto:" + +#, c-format +#~ msgid "Field(s) missing." +#~ msgstr "Faltan campo(s)." + +#, c-format +#~ msgid "Want to try the raw payto://-format?" +#~ msgstr "Quieres probar el formato payto:// ?" + +#, c-format +#~ msgid "Missing payto address" +#~ msgstr "Falta direccion payto" + +#, c-format +#~ msgid "Transfer money to account identified by payto:// URI:" +#~ msgstr "Transferir dinero a la cuenta identificada por la URI payto://:" + +#, c-format +#~ msgid "payto address" +#~ msgstr "direccion payto" + +#, c-format +#~ msgid "Could not create the wire transfer" +#~ msgstr "No se pudo create la transferencia bancaria" + +#, c-format +#~ msgid "Transfer creation gave response error" +#~ msgstr "La creación de la transferencia dió una respuesta erronea" + +#, c-format +#~ msgid "No credentials given." +#~ msgstr "Se dieron las credenciales incorrectas." + +#, c-format +#~ msgid "Withdrawal creation gave response error" +#~ msgstr "La creación de retiro dió una respuesta errónea" + +#, c-format +#~ msgid "Obtain digital cash" +#~ msgstr "Obtener dinero digital" + +#, c-format +#~ msgid "Click %1$s to open your Taler wallet!" +#~ msgstr "Click %1$s para abrir una cartera Taler!" + +#, c-format +#~ msgid "Authorize withdrawal by solving challenge" +#~ msgstr "Autorizar retiro resolviendo una pregunta" + +#, c-format +#~ msgid "What is" +#~ msgstr "Cuanto es" + +#, c-format +#~ msgid "Answer is wrong." +#~ msgstr "La respuesta es incorrecta." + +#, c-format +#~ msgid "" +#~ "A this point, a %1$s bank would ask for an additional authentication " +#~ "proof (PIN/TAN, one time password, ..), instead of a simple calculation." +#~ msgstr "" +#~ "En este punto, un banco %1$s preguntaría por una prueba adicional de " +#~ "autenticación (PIN/TAN, password de un solo uso, ....), en vez de un " +#~ "simple cálculo." + +#, c-format +#~ msgid "Could not confirm the withdrawal" +#~ msgstr "No se pudo confirmar la retirada" + +#, c-format +#~ msgid "Withdrawal confirmation gave response error" +#~ msgstr "La confirmación de retiro dió una respuesta errónea" + +#, c-format +#~ msgid "Withdrawal aborted!" +#~ msgstr "Este retiro fue cancelado!" + +#, c-format +#~ msgid "withdrawal (%1$s) was never (correctly) created at the bank..." +#~ msgstr "retiro (%1$s) nunca fue (correctamente) generado en el banco..." + +#, c-format +#~ msgid "Username or account label '%1$s' not found. Won't login." +#~ msgstr "" +#~ "Nombre de usuario o etiqueta de cuenta '%1$s' no encontrada. No se " +#~ "iniciará sesión." + +#, c-format +#~ msgid "Account information could not be retrieved." +#~ msgstr "La información de la cuenta no pudo ser accedida." + +#, c-format +#~ msgid "Bank account balance" +#~ msgstr "Balance de cuenta bancaria" + +#, c-format +#~ msgid "Payments" +#~ msgstr "Pagos" + +#, c-format +#~ msgid "List of public accounts could not be retrieved." +#~ msgstr "La lista de cuentas públicas no pudo ser accedida." + +#, c-format +#~ msgid "Please register!" +#~ msgstr "Por favor, registrese!" + +#, c-format +#~ msgid "New registration gave response error" +#~ msgstr "Nuevo registro dió una respuesta errónea" + +#, c-format +#~ msgid "Bank menu" +#~ msgstr "Menu del banco" + +#, c-format +#~ msgid "Select option2" +#~ msgstr "Seleccione opción 2" + +#, c-format +#~ msgid "days" +#~ msgstr "días" + +#, c-format +#~ msgid "hours" +#~ msgstr "horas" + +#, c-format +#~ msgid "minutes" +#~ msgstr "minutos" + +#, c-format +#~ msgid "seconds" +#~ msgstr "segundos" + +#~ msgid "this link" +#~ msgstr "este link" diff --git a/packages/bank-ui/src/i18n/fr.po b/packages/bank-ui/src/i18n/fr.po new file mode 100644 index 000000000..b02cbe618 --- /dev/null +++ b/packages/bank-ui/src/i18n/fr.po @@ -0,0 +1,1752 @@ +# This file is part of GNU Taler +# (C) 2022-2024 Taler Systems S.A. +# +# GNU Taler is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# +# GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Taler; see the file COPYING. If not, see +# +msgid "" +msgstr "" +"Project-Id-Version: Taler Bank\n" +"Report-Msgid-Bugs-To: taler@gnu.org\n" +"PO-Revision-Date: 2024-02-28 08:07+0000\n" +"Last-Translator: d0p1 \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1;\n" +"X-Generator: Weblate 5.2.1\n" + +#: src/utils.ts:137 +#, c-format +msgid "Operation failed, please report" +msgstr "L'opération a échoué, veuillez le signaler" + +#: src/utils.ts:156 +#, c-format +msgid "Request timeout" +msgstr "" + +#: src/utils.ts:165 +#, c-format +msgid "Request throttled" +msgstr "" + +#: src/utils.ts:174 +#, c-format +msgid "Malformed response" +msgstr "" + +#: src/utils.ts:183 +#, c-format +msgid "Network error" +msgstr "Erreur réseau" + +#: src/utils.ts:192 +#, c-format +msgid "Unexpected request error" +msgstr "" + +#: src/utils.ts:201 +#, c-format +msgid "Unexpected error" +msgstr "" + +#: src/utils.ts:377 +#, c-format +msgid "IBAN numbers usually have more that 4 digits" +msgstr "" + +#: src/utils.ts:379 +#, c-format +msgid "IBAN numbers usually have less that 34 digits" +msgstr "" + +#: src/utils.ts:387 +#, c-format +msgid "IBAN country code not found" +msgstr "" + +#: src/utils.ts:401 +#, c-format +msgid "IBAN number is not valid, checksum is wrong" +msgstr "" + +#: src/context/config.ts:136 +#, c-format +msgid "" +"the bank backend is not supported. supported version \"%1$s\", server " +"version \"%2$s\"" +msgstr "" + +#: src/hooks/preferences.ts:55 +#, c-format +msgid "Max withdrawal amount" +msgstr "" + +#: src/hooks/preferences.ts:57 +#, c-format +msgid "Show withdrawal confirmation" +msgstr "" + +#: src/hooks/preferences.ts:59 +#, c-format +msgid "Show demo description" +msgstr "" + +#: src/hooks/preferences.ts:61 +#, c-format +msgid "Show install wallet first" +msgstr "" + +#: src/hooks/preferences.ts:63 +#, c-format +msgid "Use fast withdrawal form" +msgstr "" + +#: src/hooks/preferences.ts:65 +#, c-format +msgid "Show debug info" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:90 +#, c-format +msgid "required" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:92 +#, c-format +msgid "IBAN should have just uppercased letters and numbers" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:98 +#, c-format +msgid "not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:100 +#, c-format +msgid "should be greater than 0" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:102 +#, c-format +msgid "balance is not enough" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:112 +#, c-format +msgid "does not follow the pattern" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:114 +#, c-format +msgid "only \"IBAN\" target are supported" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:116 +#, c-format +msgid "use the \"amount\" parameter to specify the amount to be transferred" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:118 +#, c-format +msgid "the amount is not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:120 +#, c-format +msgid "" +"use the \"message\" parameter to specify a reference text for the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:160 +#, c-format +msgid "The request was invalid or the payto://-URI used unacceptable features." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:167 +#, c-format +msgid "Not enough permission to complete the operation." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:174 +#, c-format +msgid "The destination account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:181 +#, c-format +msgid "The origin and the destination of the transfer can't be the same." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:188 +#, c-format +msgid "Your balance is not enough." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:195 +#, c-format +msgid "The origin account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:212 +#, c-format +msgid "Wire transfer created!" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:270 +#, c-format +msgid "Using a form" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:310 +#, c-format +msgid "Import payto:// URI" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:335 +#, c-format +msgid "Recipient" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:359 +#, c-format +msgid "IBAN of the recipient's account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:369 +#, c-format +msgid "Transfer subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:377 +#, c-format +msgid "subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:390 +#, c-format +msgid "some text to identify the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:400 +#, c-format +msgid "Amount" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:415 +#, c-format +msgid "amount to transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:425 +#, c-format +msgid "payto URI:" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:436 +#, c-format +msgid "uniform resource identifier of the target account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:437 +#, c-format +msgid "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:457 +#, c-format +msgid "Cancel" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:471 +#, c-format +msgid "Send" +msgstr "" + +#: src/pages/LoginForm.tsx:71 +#, c-format +msgid "Missing username" +msgstr "" + +#: src/pages/LoginForm.tsx:75 +#, c-format +msgid "Missing password" +msgstr "" + +#: src/pages/LoginForm.tsx:104 +#, c-format +msgid "Wrong credentials for \"%1$s\"" +msgstr "" + +#: src/pages/LoginForm.tsx:111 +#, c-format +msgid "Account not found" +msgstr "" + +#: src/pages/LoginForm.tsx:142 +#, c-format +msgid "Username" +msgstr "" + +#: src/pages/LoginForm.tsx:156 +#, c-format +msgid "username of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:175 +#, c-format +msgid "Password" +msgstr "" + +#: src/pages/LoginForm.tsx:188 +#, c-format +msgid "password of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:223 +#, c-format +msgid "Check" +msgstr "" + +#: src/pages/LoginForm.tsx:237 +#, c-format +msgid "Log in" +msgstr "" + +#: src/pages/LoginForm.tsx:249 +#, c-format +msgid "Register" +msgstr "" + +#: src/components/Transactions/views.tsx:52 +#, c-format +msgid "Latest transactions" +msgstr "" + +#: src/components/Transactions/views.tsx:63 +#, c-format +msgid "Date" +msgstr "" + +#: src/components/Transactions/views.tsx:71 +#, c-format +msgid "Counterpart" +msgstr "" + +#: src/components/Transactions/views.tsx:75 +#, c-format +msgid "Subject" +msgstr "" + +#: src/components/Transactions/views.tsx:111 +#, c-format +msgid "sent" +msgstr "" + +#: src/components/Transactions/views.tsx:112 +#, c-format +msgid "received" +msgstr "" + +#: src/components/Transactions/views.tsx:127 +#, c-format +msgid "invalid value" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "to" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "from" +msgstr "" + +#: src/components/Transactions/views.tsx:202 +#, c-format +msgid "First page" +msgstr "" + +#: src/components/Transactions/views.tsx:209 +#, c-format +msgid "Next" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:86 +#, c-format +msgid "Wire transfer completed!" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:93 +#, c-format +msgid "The withdrawal has been aborted previously and can't be confirmed" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:100 +#, c-format +msgid "" +"The withdrawal operation can't be confirmed before a wallet accepted the " +"transaction." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:107 +#, c-format +msgid "The operation id is invalid." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:114 +#, c-format +msgid "The operation was not found." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:121 +#, c-format +msgid "Your balance is not enough for the operation." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:155 +#, c-format +msgid "" +"The reserve operation has been confirmed previously and can't be aborted" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:186 +#, c-format +msgid "Confirm the withdrawal operation" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:203 +#, c-format +msgid "Wire transfer details" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:217 +#, c-format +msgid "Taler Exchange operator's account" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:228 +#, c-format +msgid "Taler Exchange operator's name" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:317 +#, c-format +msgid "Transfer" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:342 +#, c-format +msgid "Authentication required" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:352 +#, c-format +msgid "This operation was created with other username" +msgstr "" + +#: src/pages/OperationState/views.tsx:209 +#, c-format +msgid "" +"Unauthorized to make the operation, maybe the session has expired or the " +"password changed." +msgstr "" + +#: src/pages/OperationState/views.tsx:218 +#, c-format +msgid "The operation was rejected due to insufficient funds." +msgstr "" + +#: src/pages/OperationState/views.tsx:268 +#, c-format +msgid "Withdrawal confirmed" +msgstr "" + +#: src/pages/OperationState/views.tsx:272 +#, c-format +msgid "" +"The wire transfer to the Taler operator has been initiated. You will soon " +"receive the requested amount in your Taler wallet." +msgstr "" + +#: src/pages/OperationState/views.tsx:287 +#, c-format +msgid "Do not show this again" +msgstr "" + +#: src/pages/OperationState/views.tsx:319 +#, c-format +msgid "Close" +msgstr "" + +#: src/pages/OperationState/views.tsx:399 +#, c-format +msgid "On this device" +msgstr "" + +#: src/pages/OperationState/views.tsx:404 +#, c-format +msgid "" +"If you are using a web browser on desktop you should access your wallet with " +"the GNU Taler WebExtension now or click the link if your WebExtension have " +"the \"Inject Taler support\" option enabled." +msgstr "" + +#: src/pages/OperationState/views.tsx:417 +#, c-format +msgid "Start" +msgstr "" + +#: src/pages/OperationState/views.tsx:426 +#, c-format +msgid "On a mobile phone" +msgstr "" + +#: src/pages/OperationState/views.tsx:431 +#, c-format +msgid "Scan the QR code with your mobile device." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:73 +#, c-format +msgid "There is an operation already" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:75 +#, c-format +msgid "Complete or cancel the operation in" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:84 +#, c-format +msgid "this page" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:101 +#, c-format +msgid "invalid" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:116 +#, c-format +msgid "Server responded with an invalid withdraw URI" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:117 +#, c-format +msgid "Withdraw URI: %1$s" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:132 +#, c-format +msgid "The operation was rejected due to insufficient funds" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:253 +#, c-format +msgid "Continue" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:282 +#, c-format +msgid "Prepare your wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:285 +#, c-format +msgid "" +"After using your wallet you will need to confirm or cancel the operation on " +"this site." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:295 +#, c-format +msgid "You need a GNU Taler Wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:300 +#, c-format +msgid "If you don't have one yet you can follow the instruction in" +msgstr "" + +#: src/pages/PaymentOptions.tsx:55 +#, c-format +msgid "Send money" +msgstr "" + +#: src/pages/PaymentOptions.tsx:73 +#, c-format +msgid "to a %1$s wallet" +msgstr "" + +#: src/pages/PaymentOptions.tsx:95 +#, c-format +msgid "Withdraw digital money into your mobile wallet or browser extension" +msgstr "" + +#: src/pages/PaymentOptions.tsx:109 +#, c-format +msgid "operation ready" +msgstr "" + +#: src/pages/PaymentOptions.tsx:129 +#, c-format +msgid "to another bank account" +msgstr "" + +#: src/pages/PaymentOptions.tsx:149 +#, c-format +msgid "Make a wire transfer to an account with known bank account number." +msgstr "" + +#: src/pages/PaymentOptions.tsx:171 +#, c-format +msgid "Transfer details" +msgstr "" + +#: src/pages/AccountPage/views.tsx:41 +#, c-format +msgid "This is a demo bank" +msgstr "" + +#: src/pages/AccountPage/views.tsx:46 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work. In addition to using your own bank account, you can also see the " +"transaction history of some %1$s." +msgstr "" + +#: src/pages/AccountPage/views.tsx:53 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work." +msgstr "" + +#: src/pages/AccountPage/views.tsx:70 +#, c-format +msgid "Pending account delete operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:72 +#, c-format +msgid "Pending account update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:74 +#, c-format +msgid "Pending password update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:76 +#, c-format +msgid "Pending transaction operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:78 +#, c-format +msgid "Pending withdrawal operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:80 +#, c-format +msgid "Pending cashout operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:91 +#, c-format +msgid "You can complete or cancel the operation in" +msgstr "" + +#: src/pages/BankFrame.tsx:64 +#, c-format +msgid "Internal error, please report." +msgstr "" + +#: src/pages/BankFrame.tsx:100 +#, c-format +msgid "Preferences" +msgstr "" + +#: src/pages/BankFrame.tsx:184 +#, c-format +msgid "Welcome, %1$s" +msgstr "" + +#: src/pages/WireTransfer.tsx:79 +#, c-format +msgid "Make a wire transfer" +msgstr "" + +#: src/pages/admin/AccountList.tsx:72 +#, c-format +msgid "Accounts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:75 +#, c-format +msgid "A list of all business account in the bank." +msgstr "" + +#: src/pages/admin/AccountList.tsx:86 +#, c-format +msgid "Create account" +msgstr "" + +#: src/pages/admin/AccountList.tsx:106 +#, c-format +msgid "Name" +msgstr "" + +#: src/pages/admin/AccountList.tsx:110 +#, c-format +msgid "Balance" +msgstr "" + +#: src/pages/admin/AccountList.tsx:112 +#, c-format +msgid "Actions" +msgstr "" + +#: src/pages/admin/AccountList.tsx:151 +#, c-format +msgid "unknown" +msgstr "" + +#: src/pages/admin/AccountList.tsx:170 +#, c-format +msgid "change password" +msgstr "" + +#: src/pages/admin/AccountList.tsx:179 +#, c-format +msgid "cashouts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:189 +#, c-format +msgid "remove" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:168 +#, c-format +msgid "Cashout not implemented" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:184 +#, c-format +msgid "Select a section" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:202 +#, c-format +msgid "Last hour" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:208 +#, c-format +msgid "Last day" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:216 +#, c-format +msgid "Last month" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:222 +#, c-format +msgid "Last year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:310 +#, c-format +msgid "Last Year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:325 +#, c-format +msgid "Trading volume on %1$s compared to %2$s" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:342 +#, c-format +msgid "Cashin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:352 +#, c-format +msgid "Cashout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:364 +#, c-format +msgid "Payin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:374 +#, c-format +msgid "Payout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:388 +#, c-format +msgid "download stats as CSV" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:494 +#, c-format +msgid "Decreased by" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:498 +#, c-format +msgid "Increased by" +msgstr "" + +#: src/pages/DownloadStats.tsx:89 +#, c-format +msgid "Download bank stats" +msgstr "" + +#: src/pages/DownloadStats.tsx:110 +#, c-format +msgid "Include hour metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:143 +#, c-format +msgid "Include day metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:173 +#, c-format +msgid "Include month metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:206 +#, c-format +msgid "Include year metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:239 +#, c-format +msgid "Include table header" +msgstr "" + +#: src/pages/DownloadStats.tsx:272 +#, c-format +msgid "Add previous metric for compare" +msgstr "" + +#: src/pages/DownloadStats.tsx:307 +#, c-format +msgid "Fail on first error" +msgstr "" + +#: src/pages/DownloadStats.tsx:364 +#, c-format +msgid "Download" +msgstr "" + +#: src/pages/DownloadStats.tsx:381 +#, c-format +msgid "downloading... %1$s" +msgstr "" + +#: src/pages/DownloadStats.tsx:399 +#, c-format +msgid "Download completed" +msgstr "" + +#: src/pages/DownloadStats.tsx:400 +#, c-format +msgid "click here to save the file in your computer" +msgstr "" + +#: src/pages/PublicHistoriesPage.tsx:78 +#, c-format +msgid "History of public accounts" +msgstr "" + +#: src/pages/RegistrationPage.tsx:48 +#, c-format +msgid "Currently, the bank is not accepting new registrations!" +msgstr "" + +#: src/pages/RegistrationPage.tsx:87 +#, c-format +msgid "Missing name" +msgstr "" + +#: src/pages/RegistrationPage.tsx:91 +#, c-format +msgid "Use letters and numbers only, and start with a lowercase letter" +msgstr "" + +#: src/pages/RegistrationPage.tsx:107 +#, c-format +msgid "Passwords don't match" +msgstr "" + +#: src/pages/RegistrationPage.tsx:130 +#, c-format +msgid "Server replied with invalid phone or email." +msgstr "" + +#: src/pages/RegistrationPage.tsx:137 +#, c-format +msgid "Registration is disabled because the bank ran out of bonus credit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:144 +#, c-format +msgid "No enough permission to create that account." +msgstr "" + +#: src/pages/RegistrationPage.tsx:151 +#, c-format +msgid "That account id is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:158 +#, c-format +msgid "That username is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:165 +#, c-format +msgid "That username can't be used because is reserved." +msgstr "" + +#: src/pages/RegistrationPage.tsx:172 +#, c-format +msgid "Only admin is allow to set debt limit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:179 +#, c-format +msgid "No information for the selected authentication channel." +msgstr "" + +#: src/pages/RegistrationPage.tsx:186 +#, c-format +msgid "Authentication channel is not supported." +msgstr "" + +#: src/pages/RegistrationPage.tsx:193 +#, c-format +msgid "Only admin can create accounts with second factor authentication." +msgstr "" + +#: src/pages/RegistrationPage.tsx:233 +#, c-format +msgid "Account registration" +msgstr "" + +#: src/pages/RegistrationPage.tsx:315 +#, c-format +msgid "Repeat password" +msgstr "" + +#: src/pages/RegistrationPage.tsx:457 +#, c-format +msgid "Create a random temporary user" +msgstr "" + +#: src/pages/QrCodeSection.tsx:110 +#, c-format +msgid "If you have a Taler wallet installed in this device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:116 +#, c-format +msgid "" +"You will see the details of the operation in your wallet including the fees " +"(if applies). If you still don't have one you can install it following " +"instructions in" +msgstr "" + +#: src/pages/QrCodeSection.tsx:143 +#, c-format +msgid "Withdraw" +msgstr "" + +#: src/pages/QrCodeSection.tsx:152 +#, c-format +msgid "Or if you have the wallet in another device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:157 +#, c-format +msgid "Scan the QR below to start the withdrawal." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:79 +#, c-format +msgid "Operation aborted" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:82 +#, c-format +msgid "" +"The wire transfer to the Taler Exchange operator's account was aborted, your " +"balance was not affected." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:88 +#, c-format +msgid "You can close this page now or continue to the account page." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:147 +#, c-format +msgid "Done" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:158 +#, c-format +msgid "Operation canceled" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:173 +#, c-format +msgid "" +"The operation is marked as 'selected' but some step in the withdrawal failed" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:175 +#, c-format +msgid "The account is selected but no withdrawal identification found." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:188 +#, c-format +msgid "" +"There is a withdrawal identification but no account has been selected or the " +"selected account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:202 +#, c-format +msgid "" +"No withdrawal ID found and no account has been selected or the selected " +"account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:259 +#, c-format +msgid "Operation not found" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:263 +#, c-format +msgid "" +"This operation is not known by the server. The operation id is wrong or the " +"server deleted the operation information before reaching here." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:278 +#, c-format +msgid "Cotinue to dashboard" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:98 +#, c-format +msgid "Cashout not found. It may be also mean that it was already aborted." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:136 +#, c-format +msgid "Challenge not found." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:143 +#, c-format +msgid "This user is not authorized to complete this challenge." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:150 +#, c-format +msgid "Too many attempts, try another code." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:157 +#, c-format +msgid "The confirmation code is wrong, try again." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:164 +#, c-format +msgid "The operation expired." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:197 +#, c-format +msgid "The operation failed." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:212 +#, c-format +msgid "The operation needs another confirmation to complete." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:224 +#, c-format +msgid "Account delete" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:226 +#, c-format +msgid "Account update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:228 +#, c-format +msgid "Password update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:230 +#, c-format +msgid "Wire transfer" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:232 +#, c-format +msgid "Withdrawal" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:248 +#, c-format +msgid "Confirm the operation" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:271 +#, c-format +msgid "Enter the confirmation code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:313 +#, c-format +msgid "Confirm" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:348 +#, c-format +msgid "Send again" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:359 +#, c-format +msgid "Send code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:369 +#, c-format +msgid "Operation details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:529 +#, c-format +msgid "Challenge details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:536 +#, c-format +msgid "Sent at" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:551 +#, c-format +msgid "To phone" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:553 +#, c-format +msgid "To email" +msgstr "" + +#: src/pages/WithdrawalOperationPage.tsx:49 +#, c-format +msgid "The Withdrawal URI is not valid" +msgstr "" + +#: src/components/Cashouts/views.tsx:100 +#, c-format +msgid "Latest cashouts" +msgstr "" + +#: src/components/Cashouts/views.tsx:111 +#, c-format +msgid "Created" +msgstr "" + +#: src/components/Cashouts/views.tsx:115 +#, c-format +msgid "Total debit" +msgstr "" + +#: src/components/Cashouts/views.tsx:119 +#, c-format +msgid "Total credit" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:70 +#, c-format +msgid "Details" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:74 +#, c-format +msgid "Delete" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:78 +#, c-format +msgid "Credentials" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:82 +#, c-format +msgid "Cashouts" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:95 +#, c-format +msgid "Unable to create a cashout" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:96 +#, c-format +msgid "The bank configuration does not support cashout operations." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:223 +#, c-format +msgid "need to be higher due to fees" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:225 +#, c-format +msgid "the total transfer at destination will be zero" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:250 +#, c-format +msgid "Cashout created" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:272 +#, c-format +msgid "" +"Duplicated request detected, check if the operation succeeded or try again." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:279 +#, c-format +msgid "The conversion rate was incorrectly applied" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:286 +#, c-format +msgid "The account does not have sufficient funds" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:293 +#, c-format +msgid "Cashouts are not supported" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:300 +#, c-format +msgid "Missing cashout URI in the profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:307 +#, c-format +msgid "" +"Sending the confirmation message failed, retry later or contact the " +"administrator." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:339 +#, c-format +msgid "Conversion rate" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:360 +#, c-format +msgid "Fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:374 +#, c-format +msgid "To account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:381 +#, c-format +msgid "No cashout account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:382 +#, c-format +msgid "Before doing a cashout you need to complete your profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:440 +#, c-format +msgid "Amount to send" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:441 +#, c-format +msgid "Amount to receive" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:490 +#, c-format +msgid "Total cost" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:505 +#, c-format +msgid "Balance left" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:520 +#, c-format +msgid "Before fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:533 +#, c-format +msgid "Total cashout transfer" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:553 +#, c-format +msgid "No cashout channel available" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:555 +#, c-format +msgid "" +"Before doing a cashout the server need to provide an second channel to " +"confirm the operation" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:567 +#, c-format +msgid "Second factor authentication" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:598 +#, c-format +msgid "Email" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:600 +#, c-format +msgid "add a email in your profile to enable this option" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:646 +#, c-format +msgid "SMS" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:648 +#, c-format +msgid "add a phone number in your profile to enable this option" +msgstr "" + +#: src/pages/account/CashoutListForAccount.tsx:52 +#, c-format +msgid "Cashout for account %1$s" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:165 +#, c-format +msgid "it doesn't have the pattern of an IBAN number" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:185 +#, c-format +msgid "it doesn't have the pattern of an email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:190 +#, c-format +msgid "should start with +" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:192 +#, c-format +msgid "phone number can't have other than numbers" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:329 +#, c-format +msgid "account identification in the bank" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:365 +#, c-format +msgid "name of the person owner the account" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:374 +#, c-format +msgid "Internal IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:377 +#, c-format +msgid "if empty a random account number will be assigned" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:378 +#, c-format +msgid "account identification for bank transfer" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:423 +#, c-format +msgid "Phone" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:451 +#, c-format +msgid "Cashout IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:452 +#, c-format +msgid "account number where the money is going to be sent when doing cashouts" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:470 +#, c-format +msgid "Max debt" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:494 +#, c-format +msgid "how much is user able to transfer after zero balance" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:508 +#, c-format +msgid "Is this a Taler Exchange?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:549 +#, c-format +msgid "This server doesn't support second factor authentication." +msgstr "" + +#: src/pages/admin/AccountForm.tsx:560 +#, c-format +msgid "Enable second factor authentication" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:596 +#, c-format +msgid "Using email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:654 +#, c-format +msgid "Using SMS" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:691 +#, c-format +msgid "Is this account public?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:719 +#, c-format +msgid "public accounts have their balance publicly accessible" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:100 +#, c-format +msgid "Account updated" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:107 +#, c-format +msgid "The rights to change the account are not sufficient" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:114 +#, c-format +msgid "The username was not found" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:121 +#, c-format +msgid "" +"You can't change the legal name, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:128 +#, c-format +msgid "" +"You can't change the debt limit, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:135 +#, c-format +msgid "" +"You can't change the cashout address, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:177 +#, c-format +msgid "Account \"%1$s\"" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:190 +#, c-format +msgid "Change details" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:235 +#, c-format +msgid "Update" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:78 +#, c-format +msgid "password doesn't match" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:95 +#, c-format +msgid "Password changed" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:102 +#, c-format +msgid "Not authorized to change the password, maybe the session is invalid." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:112 +#, c-format +msgid "" +"You need to provide the old password. If you don't have it contact your " +"account administrator." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:117 +#, c-format +msgid "Your current password doesn't match, can't change to a new password." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:149 +#, c-format +msgid "Update password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:167 +#, c-format +msgid "New password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:195 +#, c-format +msgid "Type it again" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:217 +#, c-format +msgid "repeat the same password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:227 +#, c-format +msgid "Current password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:248 +#, c-format +msgid "your current password, for security" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:272 +#, c-format +msgid "Change" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:74 +#, c-format +msgid "" +"Account created with password \"%1$s\". The user must change the password on " +"the next login." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:83 +#, c-format +msgid "Server replied that phone or email is invalid" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:90 +#, c-format +msgid "The rights to perform the operation are not sufficient" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:97 +#, c-format +msgid "Account username is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:104 +#, c-format +msgid "Account id is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:111 +#, c-format +msgid "Bank ran out of bonus credit." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:118 +#, c-format +msgid "Account username can't be used because is reserved" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:160 +#, c-format +msgid "Can't create accounts" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:161 +#, c-format +msgid "Only system admin can create accounts." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:183 +#, c-format +msgid "New business account" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:209 +#, c-format +msgid "Create" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:94 +#, c-format +msgid "Can't delete the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:95 +#, c-format +msgid "" +"The account can't be delete while still holding some balance. First make " +"sure that the owner make a complete cashout." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:117 +#, c-format +msgid "Account removed" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:124 +#, c-format +msgid "No enough permission to delete the account." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:131 +#, c-format +msgid "The username was not found." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:138 +#, c-format +msgid "Can't delete a reserved username." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:145 +#, c-format +msgid "Can't delete an account with balance different than zero." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:170 +#, c-format +msgid "name doesn't match" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:180 +#, c-format +msgid "You are going to remove the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:182 +#, c-format +msgid "This step can't be undone." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:188 +#, c-format +msgid "Deleting account \"%1$s\"" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:206 +#, c-format +msgid "Verification" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:231 +#, c-format +msgid "enter the account name that is going to be deleted" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:49 +#, c-format +msgid "cashout id should be a number" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:65 +#, c-format +msgid "This cashout not found. Maybe already aborted." +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:106 +#, c-format +msgid "Cashout detail" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:139 +#, c-format +msgid "Debited" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:154 +#, c-format +msgid "Credited" +msgstr "" + +#: src/Routing.tsx:140 +#, c-format +msgid "Welcome to %1$s!" +msgstr "" diff --git a/packages/bank-ui/src/i18n/it.po b/packages/bank-ui/src/i18n/it.po new file mode 100644 index 000000000..7aeaca3a8 --- /dev/null +++ b/packages/bank-ui/src/i18n/it.po @@ -0,0 +1,1843 @@ +# This file is part of GNU Taler +# (C) 2021 Taler Systems S.A. +# GNU Taler is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# You should have received a copy of the GNU General Public License along with +# GNU Taler; see the file COPYING. If not, see +# +msgid "" +msgstr "" +"Project-Id-Version: Taler Wallet\n" +"Report-Msgid-Bugs-To: taler@gnu.org\n" +"POT-Creation-Date: 2016-11-23 00:00+0100\n" +"PO-Revision-Date: 2023-08-15 07:28+0000\n" +"Last-Translator: Krystian Baran \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.13.1\n" + +#: src/utils.ts:137 +#, fuzzy, c-format +msgid "Operation failed, please report" +msgstr "Registrazione" + +#: src/utils.ts:156 +#, c-format +msgid "Request timeout" +msgstr "" + +#: src/utils.ts:165 +#, c-format +msgid "Request throttled" +msgstr "" + +#: src/utils.ts:174 +#, c-format +msgid "Malformed response" +msgstr "" + +#: src/utils.ts:183 +#, c-format +msgid "Network error" +msgstr "" + +#: src/utils.ts:192 +#, c-format +msgid "Unexpected request error" +msgstr "" + +#: src/utils.ts:201 +#, c-format +msgid "Unexpected error" +msgstr "" + +#: src/utils.ts:377 +#, c-format +msgid "IBAN numbers usually have more that 4 digits" +msgstr "" + +#: src/utils.ts:379 +#, c-format +msgid "IBAN numbers usually have less that 34 digits" +msgstr "" + +#: src/utils.ts:387 +#, c-format +msgid "IBAN country code not found" +msgstr "" + +#: src/utils.ts:401 +#, c-format +msgid "IBAN number is not valid, checksum is wrong" +msgstr "" + +#: src/context/config.ts:136 +#, c-format +msgid "" +"the bank backend is not supported. supported version \"%1$s\", server " +"version \"%2$s\"" +msgstr "" + +#: src/hooks/preferences.ts:55 +#, fuzzy, c-format +msgid "Max withdrawal amount" +msgstr "Questo ritiro è stato annullato!" + +#: src/hooks/preferences.ts:57 +#, fuzzy, c-format +msgid "Show withdrawal confirmation" +msgstr "Questo ritiro è stato annullato!" + +#: src/hooks/preferences.ts:59 +#, c-format +msgid "Show demo description" +msgstr "" + +#: src/hooks/preferences.ts:61 +#, c-format +msgid "Show install wallet first" +msgstr "" + +#: src/hooks/preferences.ts:63 +#, fuzzy, c-format +msgid "Use fast withdrawal form" +msgstr "Ritira contante" + +#: src/hooks/preferences.ts:65 +#, c-format +msgid "Show debug info" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:90 +#, c-format +msgid "required" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:92 +#, c-format +msgid "IBAN should have just uppercased letters and numbers" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:98 +#, c-format +msgid "not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:100 +#, c-format +msgid "should be greater than 0" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:102 +#, c-format +msgid "balance is not enough" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:112 +#, c-format +msgid "does not follow the pattern" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:114 +#, c-format +msgid "only \"IBAN\" target are supported" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:116 +#, c-format +msgid "use the \"amount\" parameter to specify the amount to be transferred" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:118 +#, c-format +msgid "the amount is not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:120 +#, c-format +msgid "" +"use the \"message\" parameter to specify a reference text for the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:160 +#, c-format +msgid "The request was invalid or the payto://-URI used unacceptable features." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:167 +#, fuzzy, c-format +msgid "Not enough permission to complete the operation." +msgstr "La banca sta creando l'operazione..." + +#: src/pages/PaytoWireTransferForm.tsx:174 +#, fuzzy, c-format +msgid "The destination account \"%1$s\" was not found." +msgstr "Lista conti pubblici non trovata." + +#: src/pages/PaytoWireTransferForm.tsx:181 +#, c-format +msgid "The origin and the destination of the transfer can't be the same." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:188 +#, c-format +msgid "Your balance is not enough." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:195 +#, fuzzy, c-format +msgid "The origin account \"%1$s\" was not found." +msgstr "Lista conti pubblici non trovata." + +#: src/pages/PaytoWireTransferForm.tsx:212 +#, fuzzy, c-format +msgid "Wire transfer created!" +msgstr "Bonifico" + +#: src/pages/PaytoWireTransferForm.tsx:270 +#, c-format +msgid "Using a form" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:310 +#, c-format +msgid "Import payto:// URI" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:335 +#, c-format +msgid "Recipient" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:359 +#, c-format +msgid "IBAN of the recipient's account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:369 +#, fuzzy, c-format +msgid "Transfer subject" +msgstr "Trasferisci fondi a un altro conto di questa banca:" + +#: src/pages/PaytoWireTransferForm.tsx:377 +#, fuzzy, c-format +msgid "subject" +msgstr "Soggetto" + +#: src/pages/PaytoWireTransferForm.tsx:390 +#, c-format +msgid "some text to identify the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:400 +#, c-format +msgid "Amount" +msgstr "Importo" + +#: src/pages/PaytoWireTransferForm.tsx:415 +#, fuzzy, c-format +msgid "amount to transfer" +msgstr "Somma da ritirare" + +#: src/pages/PaytoWireTransferForm.tsx:425 +#, c-format +msgid "payto URI:" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:436 +#, c-format +msgid "uniform resource identifier of the target account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:437 +#, c-format +msgid "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:457 +#, c-format +msgid "Cancel" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:471 +#, c-format +msgid "Send" +msgstr "" + +#: src/pages/LoginForm.tsx:71 +#, c-format +msgid "Missing username" +msgstr "" + +#: src/pages/LoginForm.tsx:75 +#, c-format +msgid "Missing password" +msgstr "" + +#: src/pages/LoginForm.tsx:104 +#, fuzzy, c-format +msgid "Wrong credentials for \"%1$s\"" +msgstr "Credenziali invalide." + +#: src/pages/LoginForm.tsx:111 +#, c-format +msgid "Account not found" +msgstr "" + +#: src/pages/LoginForm.tsx:142 +#, c-format +msgid "Username" +msgstr "" + +#: src/pages/LoginForm.tsx:156 +#, fuzzy, c-format +msgid "username of the account" +msgstr "Trasferisci fondi a un altro conto di questa banca:" + +#: src/pages/LoginForm.tsx:175 +#, c-format +msgid "Password" +msgstr "" + +#: src/pages/LoginForm.tsx:188 +#, fuzzy, c-format +msgid "password of the account" +msgstr "Storico dei conti pubblici" + +#: src/pages/LoginForm.tsx:223 +#, c-format +msgid "Check" +msgstr "" + +#: src/pages/LoginForm.tsx:237 +#, c-format +msgid "Log in" +msgstr "" + +#: src/pages/LoginForm.tsx:249 +#, c-format +msgid "Register" +msgstr "Registrati" + +#: src/components/Transactions/views.tsx:52 +#, fuzzy, c-format +msgid "Latest transactions" +msgstr "Ultime transazioni:" + +#: src/components/Transactions/views.tsx:63 +#, c-format +msgid "Date" +msgstr "Data" + +#: src/components/Transactions/views.tsx:71 +#, c-format +msgid "Counterpart" +msgstr "Controparte" + +#: src/components/Transactions/views.tsx:75 +#, c-format +msgid "Subject" +msgstr "Soggetto" + +#: src/components/Transactions/views.tsx:111 +#, c-format +msgid "sent" +msgstr "" + +#: src/components/Transactions/views.tsx:112 +#, c-format +msgid "received" +msgstr "" + +#: src/components/Transactions/views.tsx:127 +#, c-format +msgid "invalid value" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "to" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "from" +msgstr "" + +#: src/components/Transactions/views.tsx:202 +#, c-format +msgid "First page" +msgstr "" + +#: src/components/Transactions/views.tsx:209 +#, c-format +msgid "Next" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:86 +#, fuzzy, c-format +msgid "Wire transfer completed!" +msgstr "Bonifico" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:93 +#, c-format +msgid "The withdrawal has been aborted previously and can't be confirmed" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:100 +#, c-format +msgid "" +"The withdrawal operation can't be confirmed before a wallet accepted the " +"transaction." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:107 +#, c-format +msgid "The operation id is invalid." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:114 +#, fuzzy, c-format +msgid "The operation was not found." +msgstr "Lista conti pubblici non trovata." + +#: src/pages/WithdrawalConfirmationQuestion.tsx:121 +#, c-format +msgid "Your balance is not enough for the operation." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:155 +#, c-format +msgid "" +"The reserve operation has been confirmed previously and can't be aborted" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:186 +#, fuzzy, c-format +msgid "Confirm the withdrawal operation" +msgstr "Conferma il ritiro" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:203 +#, fuzzy, c-format +msgid "Wire transfer details" +msgstr "Bonifico" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:217 +#, c-format +msgid "Taler Exchange operator's account" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:228 +#, c-format +msgid "Taler Exchange operator's name" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:317 +#, c-format +msgid "Transfer" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:342 +#, c-format +msgid "Authentication required" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:352 +#, c-format +msgid "This operation was created with other username" +msgstr "" + +#: src/pages/OperationState/views.tsx:209 +#, c-format +msgid "" +"Unauthorized to make the operation, maybe the session has expired or the " +"password changed." +msgstr "" + +#: src/pages/OperationState/views.tsx:218 +#, c-format +msgid "The operation was rejected due to insufficient funds." +msgstr "" + +#: src/pages/OperationState/views.tsx:268 +#, fuzzy, c-format +msgid "Withdrawal confirmed" +msgstr "Questo ritiro è stato annullato!" + +#: src/pages/OperationState/views.tsx:272 +#, c-format +msgid "" +"The wire transfer to the Taler operator has been initiated. You will soon " +"receive the requested amount in your Taler wallet." +msgstr "" + +#: src/pages/OperationState/views.tsx:287 +#, c-format +msgid "Do not show this again" +msgstr "" + +#: src/pages/OperationState/views.tsx:319 +#, c-format +msgid "Close" +msgstr "" + +#: src/pages/OperationState/views.tsx:399 +#, c-format +msgid "On this device" +msgstr "" + +#: src/pages/OperationState/views.tsx:404 +#, c-format +msgid "" +"If you are using a web browser on desktop you should access your wallet with " +"the GNU Taler WebExtension now or click the link if your WebExtension have " +"the \"Inject Taler support\" option enabled." +msgstr "" + +#: src/pages/OperationState/views.tsx:417 +#, c-format +msgid "Start" +msgstr "" + +#: src/pages/OperationState/views.tsx:426 +#, c-format +msgid "On a mobile phone" +msgstr "" + +#: src/pages/OperationState/views.tsx:431 +#, fuzzy, c-format +msgid "Scan the QR code with your mobile device." +msgstr "Usa questo codice QR per ritirare contante nel tuo wallet:" + +#: src/pages/WalletWithdrawForm.tsx:73 +#, c-format +msgid "There is an operation already" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:75 +#, fuzzy, c-format +msgid "Complete or cancel the operation in" +msgstr "Conferma il ritiro" + +#: src/pages/WalletWithdrawForm.tsx:84 +#, c-format +msgid "this page" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:101 +#, c-format +msgid "invalid" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:116 +#, c-format +msgid "Server responded with an invalid withdraw URI" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:117 +#, fuzzy, c-format +msgid "Withdraw URI: %1$s" +msgstr "Prelevare" + +#: src/pages/WalletWithdrawForm.tsx:132 +#, c-format +msgid "The operation was rejected due to insufficient funds" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:253 +#, c-format +msgid "Continue" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:282 +#, c-format +msgid "Prepare your wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:285 +#, c-format +msgid "" +"After using your wallet you will need to confirm or cancel the operation on " +"this site." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:295 +#, fuzzy, c-format +msgid "You need a GNU Taler Wallet" +msgstr "Ritira contante nel portafoglio Taler" + +#: src/pages/WalletWithdrawForm.tsx:300 +#, c-format +msgid "If you don't have one yet you can follow the instruction in" +msgstr "" + +#: src/pages/PaymentOptions.tsx:55 +#, c-format +msgid "Send money" +msgstr "" + +#: src/pages/PaymentOptions.tsx:73 +#, c-format +msgid "to a %1$s wallet" +msgstr "" + +#: src/pages/PaymentOptions.tsx:95 +#, c-format +msgid "Withdraw digital money into your mobile wallet or browser extension" +msgstr "" + +#: src/pages/PaymentOptions.tsx:109 +#, c-format +msgid "operation ready" +msgstr "" + +#: src/pages/PaymentOptions.tsx:129 +#, fuzzy, c-format +msgid "to another bank account" +msgstr "Trasferisci fondi a un altro conto di questa banca:" + +#: src/pages/PaymentOptions.tsx:149 +#, c-format +msgid "Make a wire transfer to an account with known bank account number." +msgstr "" + +#: src/pages/PaymentOptions.tsx:171 +#, fuzzy, c-format +msgid "Transfer details" +msgstr "Effettua un bonifico" + +#: src/pages/AccountPage/views.tsx:41 +#, c-format +msgid "This is a demo bank" +msgstr "" + +#: src/pages/AccountPage/views.tsx:46 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work. In addition to using your own bank account, you can also see the " +"transaction history of some %1$s." +msgstr "" + +#: src/pages/AccountPage/views.tsx:53 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would " +"work." +msgstr "" + +#: src/pages/AccountPage/views.tsx:70 +#, c-format +msgid "Pending account delete operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:72 +#, c-format +msgid "Pending account update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:74 +#, c-format +msgid "Pending password update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:76 +#, c-format +msgid "Pending transaction operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:78 +#, c-format +msgid "Pending withdrawal operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:80 +#, c-format +msgid "Pending cashout operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:91 +#, c-format +msgid "You can complete or cancel the operation in" +msgstr "" + +#: src/pages/BankFrame.tsx:64 +#, fuzzy, c-format +msgid "Internal error, please report." +msgstr "Registrazione" + +#: src/pages/BankFrame.tsx:100 +#, c-format +msgid "Preferences" +msgstr "" + +#: src/pages/BankFrame.tsx:184 +#, c-format +msgid "Welcome, %1$s" +msgstr "" + +#: src/pages/WireTransfer.tsx:79 +#, fuzzy, c-format +msgid "Make a wire transfer" +msgstr "Chiudi il bonifico" + +#: src/pages/admin/AccountList.tsx:72 +#, fuzzy, c-format +msgid "Accounts" +msgstr "Importo" + +#: src/pages/admin/AccountList.tsx:75 +#, c-format +msgid "A list of all business account in the bank." +msgstr "" + +#: src/pages/admin/AccountList.tsx:86 +#, c-format +msgid "Create account" +msgstr "" + +#: src/pages/admin/AccountList.tsx:106 +#, c-format +msgid "Name" +msgstr "" + +#: src/pages/admin/AccountList.tsx:110 +#, c-format +msgid "Balance" +msgstr "" + +#: src/pages/admin/AccountList.tsx:112 +#, c-format +msgid "Actions" +msgstr "" + +#: src/pages/admin/AccountList.tsx:151 +#, c-format +msgid "unknown" +msgstr "" + +#: src/pages/admin/AccountList.tsx:170 +#, c-format +msgid "change password" +msgstr "" + +#: src/pages/admin/AccountList.tsx:179 +#, fuzzy, c-format +msgid "cashouts" +msgstr "Ultime transazioni:" + +#: src/pages/admin/AccountList.tsx:189 +#, c-format +msgid "remove" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:168 +#, c-format +msgid "Cashout not implemented" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:184 +#, c-format +msgid "Select a section" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:202 +#, c-format +msgid "Last hour" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:208 +#, c-format +msgid "Last day" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:216 +#, c-format +msgid "Last month" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:222 +#, c-format +msgid "Last year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:310 +#, c-format +msgid "Last Year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:325 +#, c-format +msgid "Trading volume on %1$s compared to %2$s" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:342 +#, c-format +msgid "Cashin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:352 +#, c-format +msgid "Cashout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:364 +#, c-format +msgid "Payin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:374 +#, c-format +msgid "Payout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:388 +#, c-format +msgid "download stats as CSV" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:494 +#, c-format +msgid "Decreased by" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:498 +#, c-format +msgid "Increased by" +msgstr "" + +#: src/pages/DownloadStats.tsx:89 +#, c-format +msgid "Download bank stats" +msgstr "" + +#: src/pages/DownloadStats.tsx:110 +#, c-format +msgid "Include hour metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:143 +#, c-format +msgid "Include day metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:173 +#, c-format +msgid "Include month metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:206 +#, c-format +msgid "Include year metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:239 +#, c-format +msgid "Include table header" +msgstr "" + +#: src/pages/DownloadStats.tsx:272 +#, c-format +msgid "Add previous metric for compare" +msgstr "" + +#: src/pages/DownloadStats.tsx:307 +#, c-format +msgid "Fail on first error" +msgstr "" + +#: src/pages/DownloadStats.tsx:364 +#, c-format +msgid "Download" +msgstr "" + +#: src/pages/DownloadStats.tsx:381 +#, c-format +msgid "downloading... %1$s" +msgstr "" + +#: src/pages/DownloadStats.tsx:399 +#, c-format +msgid "Download completed" +msgstr "" + +#: src/pages/DownloadStats.tsx:400 +#, c-format +msgid "click here to save the file in your computer" +msgstr "" + +#: src/pages/PublicHistoriesPage.tsx:78 +#, c-format +msgid "History of public accounts" +msgstr "Storico dei conti pubblici" + +#: src/pages/RegistrationPage.tsx:48 +#, c-format +msgid "Currently, the bank is not accepting new registrations!" +msgstr "" + +#: src/pages/RegistrationPage.tsx:87 +#, fuzzy, c-format +msgid "Missing name" +msgstr "indirizzo Payto" + +#: src/pages/RegistrationPage.tsx:91 +#, c-format +msgid "Use letters and numbers only, and start with a lowercase letter" +msgstr "" + +#: src/pages/RegistrationPage.tsx:107 +#, c-format +msgid "Passwords don't match" +msgstr "" + +#: src/pages/RegistrationPage.tsx:130 +#, c-format +msgid "Server replied with invalid phone or email." +msgstr "" + +#: src/pages/RegistrationPage.tsx:137 +#, c-format +msgid "Registration is disabled because the bank ran out of bonus credit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:144 +#, c-format +msgid "No enough permission to create that account." +msgstr "" + +#: src/pages/RegistrationPage.tsx:151 +#, c-format +msgid "That account id is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:158 +#, c-format +msgid "That username is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:165 +#, c-format +msgid "That username can't be used because is reserved." +msgstr "" + +#: src/pages/RegistrationPage.tsx:172 +#, c-format +msgid "Only admin is allow to set debt limit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:179 +#, c-format +msgid "No information for the selected authentication channel." +msgstr "" + +#: src/pages/RegistrationPage.tsx:186 +#, c-format +msgid "Authentication channel is not supported." +msgstr "" + +#: src/pages/RegistrationPage.tsx:193 +#, c-format +msgid "Only admin can create accounts with second factor authentication." +msgstr "" + +#: src/pages/RegistrationPage.tsx:233 +#, c-format +msgid "Account registration" +msgstr "" + +#: src/pages/RegistrationPage.tsx:315 +#, c-format +msgid "Repeat password" +msgstr "" + +#: src/pages/RegistrationPage.tsx:457 +#, c-format +msgid "Create a random temporary user" +msgstr "" + +#: src/pages/QrCodeSection.tsx:110 +#, c-format +msgid "If you have a Taler wallet installed in this device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:116 +#, c-format +msgid "" +"You will see the details of the operation in your wallet including the fees " +"(if applies). If you still don't have one you can install it following " +"instructions in" +msgstr "" + +#: src/pages/QrCodeSection.tsx:143 +#, c-format +msgid "Withdraw" +msgstr "Prelevare" + +#: src/pages/QrCodeSection.tsx:152 +#, c-format +msgid "Or if you have the wallet in another device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:157 +#, fuzzy, c-format +msgid "Scan the QR below to start the withdrawal." +msgstr "Chiudi il ritiro Taler" + +#: src/pages/WithdrawalQRCode.tsx:79 +#, c-format +msgid "Operation aborted" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:82 +#, c-format +msgid "" +"The wire transfer to the Taler Exchange operator's account was aborted, your " +"balance was not affected." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:88 +#, c-format +msgid "You can close this page now or continue to the account page." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:147 +#, c-format +msgid "Done" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:158 +#, c-format +msgid "Operation canceled" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:173 +#, c-format +msgid "" +"The operation is marked as 'selected' but some step in the withdrawal failed" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:175 +#, c-format +msgid "The account is selected but no withdrawal identification found." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:188 +#, c-format +msgid "" +"There is a withdrawal identification but no account has been selected or the " +"selected account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:202 +#, c-format +msgid "" +"No withdrawal ID found and no account has been selected or the selected " +"account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:259 +#, c-format +msgid "Operation not found" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:263 +#, c-format +msgid "" +"This operation is not known by the server. The operation id is wrong or the " +"server deleted the operation information before reaching here." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:278 +#, c-format +msgid "Cotinue to dashboard" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:98 +#, c-format +msgid "Cashout not found. It may be also mean that it was already aborted." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:136 +#, c-format +msgid "Challenge not found." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:143 +#, c-format +msgid "This user is not authorized to complete this challenge." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:150 +#, c-format +msgid "Too many attempts, try another code." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:157 +#, c-format +msgid "The confirmation code is wrong, try again." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:164 +#, c-format +msgid "The operation expired." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:197 +#, fuzzy, c-format +msgid "The operation failed." +msgstr "Questo ritiro è stato annullato!" + +#: src/pages/SolveChallengePage.tsx:212 +#, c-format +msgid "The operation needs another confirmation to complete." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:224 +#, c-format +msgid "Account delete" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:226 +#, c-format +msgid "Account update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:228 +#, c-format +msgid "Password update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:230 +#, fuzzy, c-format +msgid "Wire transfer" +msgstr "Bonifico" + +#: src/pages/SolveChallengePage.tsx:232 +#, fuzzy, c-format +msgid "Withdrawal" +msgstr "Prelevare" + +#: src/pages/SolveChallengePage.tsx:248 +#, fuzzy, c-format +msgid "Confirm the operation" +msgstr "Conferma il ritiro" + +#: src/pages/SolveChallengePage.tsx:271 +#, c-format +msgid "Enter the confirmation code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:313 +#, c-format +msgid "Confirm" +msgstr "Conferma" + +#: src/pages/SolveChallengePage.tsx:348 +#, c-format +msgid "Send again" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:359 +#, c-format +msgid "Send code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:369 +#, c-format +msgid "Operation details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:529 +#, c-format +msgid "Challenge details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:536 +#, c-format +msgid "Sent at" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:551 +#, c-format +msgid "To phone" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:553 +#, c-format +msgid "To email" +msgstr "" + +#: src/pages/WithdrawalOperationPage.tsx:49 +#, fuzzy, c-format +msgid "The Withdrawal URI is not valid" +msgstr "Questo ritiro è stato annullato!" + +#: src/components/Cashouts/views.tsx:100 +#, fuzzy, c-format +msgid "Latest cashouts" +msgstr "Ultime transazioni:" + +#: src/components/Cashouts/views.tsx:111 +#, c-format +msgid "Created" +msgstr "" + +#: src/components/Cashouts/views.tsx:115 +#, c-format +msgid "Total debit" +msgstr "" + +#: src/components/Cashouts/views.tsx:119 +#, c-format +msgid "Total credit" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:70 +#, c-format +msgid "Details" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:74 +#, c-format +msgid "Delete" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:78 +#, fuzzy, c-format +msgid "Credentials" +msgstr "Credenziali invalide." + +#: src/pages/ProfileNavigation.tsx:82 +#, c-format +msgid "Cashouts" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:95 +#, c-format +msgid "Unable to create a cashout" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:96 +#, c-format +msgid "The bank configuration does not support cashout operations." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:223 +#, c-format +msgid "need to be higher due to fees" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:225 +#, c-format +msgid "the total transfer at destination will be zero" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:250 +#, c-format +msgid "Cashout created" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:272 +#, c-format +msgid "" +"Duplicated request detected, check if the operation succeeded or try again." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:279 +#, c-format +msgid "The conversion rate was incorrectly applied" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:286 +#, c-format +msgid "The account does not have sufficient funds" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:293 +#, c-format +msgid "Cashouts are not supported" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:300 +#, c-format +msgid "Missing cashout URI in the profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:307 +#, c-format +msgid "" +"Sending the confirmation message failed, retry later or contact the " +"administrator." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:339 +#, c-format +msgid "Conversion rate" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:360 +#, c-format +msgid "Fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:374 +#, c-format +msgid "To account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:381 +#, c-format +msgid "No cashout account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:382 +#, c-format +msgid "Before doing a cashout you need to complete your profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:440 +#, fuzzy, c-format +msgid "Amount to send" +msgstr "Somma da ritirare" + +#: src/pages/business/CreateCashout.tsx:441 +#, fuzzy, c-format +msgid "Amount to receive" +msgstr "Somma da ritirare" + +#: src/pages/business/CreateCashout.tsx:490 +#, c-format +msgid "Total cost" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:505 +#, c-format +msgid "Balance left" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:520 +#, c-format +msgid "Before fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:533 +#, c-format +msgid "Total cashout transfer" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:553 +#, c-format +msgid "No cashout channel available" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:555 +#, c-format +msgid "" +"Before doing a cashout the server need to provide an second channel to " +"confirm the operation" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:567 +#, c-format +msgid "Second factor authentication" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:598 +#, c-format +msgid "Email" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:600 +#, c-format +msgid "add a email in your profile to enable this option" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:646 +#, c-format +msgid "SMS" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:648 +#, c-format +msgid "add a phone number in your profile to enable this option" +msgstr "" + +#: src/pages/account/CashoutListForAccount.tsx:52 +#, c-format +msgid "Cashout for account %1$s" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:165 +#, c-format +msgid "it doesn't have the pattern of an IBAN number" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:185 +#, c-format +msgid "it doesn't have the pattern of an email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:190 +#, c-format +msgid "should start with +" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:192 +#, c-format +msgid "phone number can't have other than numbers" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:329 +#, c-format +msgid "account identification in the bank" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:365 +#, c-format +msgid "name of the person owner the account" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:374 +#, c-format +msgid "Internal IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:377 +#, c-format +msgid "if empty a random account number will be assigned" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:378 +#, c-format +msgid "account identification for bank transfer" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:423 +#, c-format +msgid "Phone" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:451 +#, c-format +msgid "Cashout IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:452 +#, c-format +msgid "account number where the money is going to be sent when doing cashouts" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:470 +#, c-format +msgid "Max debt" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:494 +#, c-format +msgid "how much is user able to transfer after zero balance" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:508 +#, c-format +msgid "Is this a Taler Exchange?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:549 +#, c-format +msgid "This server doesn't support second factor authentication." +msgstr "" + +#: src/pages/admin/AccountForm.tsx:560 +#, c-format +msgid "Enable second factor authentication" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:596 +#, c-format +msgid "Using email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:654 +#, c-format +msgid "Using SMS" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:691 +#, c-format +msgid "Is this account public?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:719 +#, c-format +msgid "public accounts have their balance publicly accessible" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:100 +#, c-format +msgid "Account updated" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:107 +#, c-format +msgid "The rights to change the account are not sufficient" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:114 +#, c-format +msgid "The username was not found" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:121 +#, c-format +msgid "" +"You can't change the legal name, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:128 +#, c-format +msgid "" +"You can't change the debt limit, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:135 +#, c-format +msgid "" +"You can't change the cashout address, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:177 +#, c-format +msgid "Account \"%1$s\"" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:190 +#, c-format +msgid "Change details" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:235 +#, c-format +msgid "Update" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:78 +#, c-format +msgid "password doesn't match" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:95 +#, c-format +msgid "Password changed" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:102 +#, c-format +msgid "Not authorized to change the password, maybe the session is invalid." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:112 +#, c-format +msgid "" +"You need to provide the old password. If you don't have it contact your " +"account administrator." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:117 +#, c-format +msgid "Your current password doesn't match, can't change to a new password." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:149 +#, c-format +msgid "Update password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:167 +#, c-format +msgid "New password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:195 +#, c-format +msgid "Type it again" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:217 +#, c-format +msgid "repeat the same password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:227 +#, c-format +msgid "Current password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:248 +#, c-format +msgid "your current password, for security" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:272 +#, c-format +msgid "Change" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:74 +#, c-format +msgid "" +"Account created with password \"%1$s\". The user must change the password on " +"the next login." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:83 +#, c-format +msgid "Server replied that phone or email is invalid" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:90 +#, c-format +msgid "The rights to perform the operation are not sufficient" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:97 +#, c-format +msgid "Account username is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:104 +#, c-format +msgid "Account id is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:111 +#, c-format +msgid "Bank ran out of bonus credit." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:118 +#, c-format +msgid "Account username can't be used because is reserved" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:160 +#, c-format +msgid "Can't create accounts" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:161 +#, c-format +msgid "Only system admin can create accounts." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:183 +#, c-format +msgid "New business account" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:209 +#, c-format +msgid "Create" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:94 +#, c-format +msgid "Can't delete the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:95 +#, c-format +msgid "" +"The account can't be delete while still holding some balance. First make " +"sure that the owner make a complete cashout." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:117 +#, c-format +msgid "Account removed" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:124 +#, c-format +msgid "No enough permission to delete the account." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:131 +#, c-format +msgid "The username was not found." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:138 +#, c-format +msgid "Can't delete a reserved username." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:145 +#, c-format +msgid "Can't delete an account with balance different than zero." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:170 +#, c-format +msgid "name doesn't match" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:180 +#, c-format +msgid "You are going to remove the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:182 +#, c-format +msgid "This step can't be undone." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:188 +#, c-format +msgid "Deleting account \"%1$s\"" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:206 +#, c-format +msgid "Verification" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:231 +#, c-format +msgid "enter the account name that is going to be deleted" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:49 +#, c-format +msgid "cashout id should be a number" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:65 +#, c-format +msgid "This cashout not found. Maybe already aborted." +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:106 +#, c-format +msgid "Cashout detail" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:139 +#, c-format +msgid "Debited" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:154 +#, c-format +msgid "Credited" +msgstr "" + +#: src/Routing.tsx:140 +#, c-format +msgid "Welcome to %1$s!" +msgstr "" + +#, fuzzy, c-format +#~ msgid "Account not found." +#~ msgstr "Lista conti pubblici non trovata." + +#, fuzzy, c-format +#~ msgid "Confirmed" +#~ msgstr "Conferma" + +#, c-format +#~ msgid "Abort" +#~ msgstr "Annulla" + +#, c-format +#~ msgid "Skip to main content" +#~ msgstr "Saltare il menu di navigazione" + +#, c-format +#~ msgid "Please login!" +#~ msgstr "Accedi!" + +#, c-format +#~ msgid "Login" +#~ msgstr "Accedi" + +#, fuzzy, c-format +#~ msgid "Amount:" +#~ msgstr "Somma" + +#, c-format +#~ msgid "Want to try the raw payto://-format?" +#~ msgstr "Prova il trasferimento tramite il formato Payto!" + +#, fuzzy, c-format +#~ msgid "Transfer money to account identified by payto:// URI:" +#~ msgstr "Trasferisci fondi a un altro conto di questa banca:" + +#, c-format +#~ msgid "payto address" +#~ msgstr "indirizzo Payto" + +#, fuzzy, c-format +#~ msgid "No credentials given." +#~ msgstr "Credenziali invalide." + +#, c-format +#~ msgid "Username or account label '%1$s' not found. Won't login." +#~ msgstr "L'utente '%1$s' non esiste. Login impossibile" + +#, c-format +#~ msgid "Account information could not be retrieved." +#~ msgstr "Impossibile ricevere le informazioni relative al conto." + +#, fuzzy, c-format +#~ msgid "Bank account balance" +#~ msgstr "Bilancio:" + +#, c-format +#~ msgid "List of public accounts could not be retrieved." +#~ msgstr "Lista conti pubblici non pervenuta." + +#, fuzzy, c-format +#~ msgid "Please register!" +#~ msgstr "Accedi!" + +#~ msgid "this link" +#~ msgstr "questo link" + +#~ msgid "Clear" +#~ msgstr "Cancella" + +#~ msgid "Demo Bank" +#~ msgstr "Banca 'demo'" + +#~ msgid "Go back" +#~ msgstr "Indietro" + +#~ msgid "Transfer money via the Payto system:" +#~ msgstr "Effettua un bonifico tramite il sistema Payto:" + +#~ msgid "Withdraw Money into a Taler wallet" +#~ msgstr "Ritira contante nel portafoglio Taler" + +#~ msgid "Register to the euFin bank!" +#~ msgstr "Apri un conto in banca euFin!" + +#~ msgid "Page has a problem: logged in but backend state is lost." +#~ msgstr "" +#~ "Stato inconsistente: accesso utente effettuato ma stato con server perso." + +#, fuzzy +#~ msgid "Welcome to the euFin bank!" +#~ msgstr "Benvenuti in banca euFin!" diff --git a/packages/bank-ui/src/i18n/poheader b/packages/bank-ui/src/i18n/poheader new file mode 100644 index 000000000..d7a371934 --- /dev/null +++ b/packages/bank-ui/src/i18n/poheader @@ -0,0 +1,26 @@ +# This file is part of GNU Taler +# (C) 2022-2024 Taler Systems S.A. +# +# GNU Taler is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# +# GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Taler; see the file COPYING. If not, see +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Taler Bank\n" +"Report-Msgid-Bugs-To: taler@gnu.org\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" diff --git a/packages/bank-ui/src/i18n/strings.ts b/packages/bank-ui/src/i18n/strings.ts new file mode 100644 index 000000000..f55e5efbc --- /dev/null +++ b/packages/bank-ui/src/i18n/strings.ts @@ -0,0 +1,2295 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ +export interface StringsType { + // X-Domain or 'messages' + domain: string; + lang: string; + completeness: number; + plural_forms: string; + locale_data: { + messages: Record; + }; +} +export const strings: Record = {}; + +strings["it"] = { + locale_data: { + messages: { + "": { + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "it", + }, + "Operation failed, please report": ["Registrazione"], + "Request timeout": [""], + "Request throttled": [""], + "Malformed response": [""], + "Network error": [""], + "Unexpected request error": [""], + "Unexpected error": [""], + "IBAN numbers usually have more that 4 digits": [""], + "IBAN numbers usually have less that 34 digits": [""], + "IBAN country code not found": [""], + "IBAN number is not valid, checksum is wrong": [""], + "Max withdrawal amount": ["Questo ritiro è stato annullato!"], + "Show withdrawal confirmation": ["Questo ritiro è stato annullato!"], + "Show demo description": [""], + "Show install wallet first": [""], + "Use fast withdrawal form": ["Ritira contante"], + "Show debug info": [""], + "The reserve operation has been confirmed previously and can't be aborted": + [""], + "The operation id is invalid.": [""], + "The operation was not found.": ["Lista conti pubblici non trovata."], + "If you have a Taler wallet installed in this device": [""], + "You will see the details of the operation in your wallet including the fees (if applies). If you still don't have one you can install it following instructions in": + [""], + "this page": [""], + Withdraw: ["Prelevare"], + "Or if you have the wallet in another device": [""], + "Scan the QR below to start the withdrawal.": ["Chiudi il ritiro Taler"], + required: [""], + "IBAN should have just uppercased letters and numbers": [""], + "not valid": [""], + "should be greater than 0": [""], + "balance is not enough": [""], + "does not follow the pattern": [""], + 'only "IBAN" target are supported': [""], + 'use the "amount" parameter to specify the amount to be transferred': [ + "", + ], + "the amount is not valid": [""], + 'use the "message" parameter to specify a reference text for the transfer': + [""], + "The request was invalid or the payto://-URI used unacceptable features.": + [""], + "Not enough permission to complete the operation.": [ + "La banca sta creando l'operazione...", + ], + 'The destination account "%1$s" was not found.': [ + "Lista conti pubblici non trovata.", + ], + "The origin and the destination of the transfer can't be the same.": [""], + "Your balance is not enough.": [""], + 'The origin account "%1$s" was not found.': [ + "Lista conti pubblici non trovata.", + ], + "Using a form": [""], + "Import payto:// URI": [""], + Recipient: [""], + "IBAN of the recipient's account": [""], + "Transfer subject": [ + "Trasferisci fondi a un altro conto di questa banca:", + ], + subject: ["Soggetto"], + "some text to identify the transfer": [""], + Amount: ["Importo"], + "amount to transfer": ["Somma da ritirare"], + "payto URI:": [""], + "uniform resource identifier of the target account": [""], + "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]": [""], + Cancel: [""], + Send: [""], + "Missing username": [""], + "Missing password": [""], + 'Wrong credentials for "%1$s"': ["Credenziali invalide."], + "Account not found": [""], + Username: [""], + "username of the account": [ + "Trasferisci fondi a un altro conto di questa banca:", + ], + Password: [""], + "password of the account": ["Storico dei conti pubblici"], + Check: [""], + "Log in": [""], + Register: ["Registrati"], + "Wire transfer completed!": ["Bonifico"], + "The withdrawal has been aborted previously and can't be confirmed": [""], + "The withdrawal operation can't be confirmed before a wallet accepted the transaction.": + [""], + "Your balance is not enough for the operation.": [""], + "Confirm the withdrawal operation": ["Conferma il ritiro"], + "Wire transfer details": ["Bonifico"], + "Taler Exchange operator's account": [""], + "Taler Exchange operator's name": [""], + Transfer: [""], + "Authentication required": [""], + "This operation was created with other username": [""], + "Operation aborted": [""], + "The wire transfer to the Taler Exchange operator's account was aborted, your balance was not affected.": + [""], + "You can close this page now or continue to the account page.": [""], + Continue: [""], + "Withdrawal confirmed": ["Questo ritiro è stato annullato!"], + "The wire transfer to the Taler operator has been initiated. You will soon receive the requested amount in your Taler wallet.": + [""], + Done: [""], + "Operation canceled": [""], + "The operation is marked as 'selected' but some step in the withdrawal failed": + [""], + "The account is selected but no withdrawal identification found.": [""], + "There is a withdrawal identification but no account has been selected or the selected account is invalid.": + [""], + "No withdrawal ID found and no account has been selected or the selected account is invalid.": + [""], + "Operation not found": [""], + "This operation is not known by the server. The operation id is wrong or the server deleted the operation information before reaching here.": + [""], + "Cotinue to dashboard": [""], + "The Withdrawal URI is not valid": ["Questo ritiro è stato annullato!"], + 'the bank backend is not supported. supported version "%1$s", server version "%2$s"': + [""], + "Internal error, please report.": ["Registrazione"], + Preferences: [""], + "Welcome, %1$s": [""], + "Latest transactions": ["Ultime transazioni:"], + Date: ["Data"], + Counterpart: ["Controparte"], + Subject: ["Soggetto"], + sent: [""], + received: [""], + "invalid value": [""], + to: [""], + from: [""], + "First page": [""], + Next: [""], + "History of public accounts": ["Storico dei conti pubblici"], + "Currently, the bank is not accepting new registrations!": [""], + "Missing name": ["indirizzo Payto"], + "Use letters and numbers only, and start with a lowercase letter": [""], + "Passwords don't match": [""], + "Server replied with invalid phone or email.": [""], + "Registration is disabled because the bank ran out of bonus credit.": [ + "", + ], + "No enough permission to create that account.": [""], + "That account id is already taken.": [""], + "That username is already taken.": [""], + "That username can't be used because is reserved.": [""], + "Only admin is allow to set debt limit.": [""], + "No information for the selected authentication channel.": [""], + "Authentication channel is not supported.": [""], + "Only admin can create accounts with second factor authentication.": [""], + "Account registration": [""], + "Repeat password": [""], + Name: [""], + "Create a random temporary user": [""], + "Make a wire transfer": ["Chiudi il bonifico"], + "Wire transfer created!": ["Bonifico"], + Accounts: ["Importo"], + "A list of all business account in the bank.": [""], + "Create account": [""], + Balance: [""], + Actions: [""], + unknown: [""], + "change password": [""], + remove: [""], + "Select a section": [""], + "Last hour": [""], + "Last day": [""], + "Last month": [""], + "Last year": [""], + "Last Year": [""], + "Trading volume on %1$s compared to %2$s": [""], + Cashin: [""], + Cashout: [""], + Payin: [""], + Payout: [""], + "download stats as CSV": [""], + "Descreased by": [""], + "Increased by": [""], + "Unable to create a cashout": [""], + "The bank configuration does not support cashout operations.": [""], + invalid: [""], + "need to be higher due to fees": [""], + "the total transfer at destination will be zero": [""], + "Cashout created": [""], + "Duplicated request detected, check if the operation succeded or try again.": + [""], + "The conversion rate was incorrectly applied": [""], + "The account does not have sufficient funds": [""], + "Cashouts are not supported": [""], + "Missing cashout URI in the profile": [""], + "Sending the confirmation message failed, retry later or contact the administrator.": + [""], + "Convertion rate": [""], + Fee: [""], + "To account": [""], + "No cashout account": [""], + "Before doing a cashout you need to complete your profile": [""], + "Amount to send": ["Somma da ritirare"], + "Amount to receive": ["Somma da ritirare"], + "Total cost": [""], + "Balance left": [""], + "Before fee": [""], + "Total cashout transfer": [""], + "No cashout channel available": [""], + "Before doing a cashout the server need to provide an second channel to confirm the operation": + [""], + "Second factor authentication": [""], + Email: [""], + "add a email in your profile to enable this option": [""], + SMS: [""], + "add a phone number in your profile to enable this option": [""], + Details: [""], + Delete: [""], + Credentials: ["Credenziali invalide."], + Cashouts: [""], + "it doesnt have the pattern of an IBAN number": [""], + "it doesnt have the pattern of an email": [""], + "should start with +": [""], + "phone number can't have other than numbers": [""], + "account identification in the bank": [""], + "name of the person owner the account": [""], + "Internal IBAN": [""], + "if empty a random account number will be assigned": [""], + "account identification for bank transfer": [""], + Phone: [""], + "Cashout IBAN": [""], + "account number where the money is going to be sent when doing cashouts": + [""], + "Max debt": [""], + "how much is user able to transfer after zero balance": [""], + "Is this a Taler Exchange?": [""], + "This server doesn't support second factor authentication.": [""], + "Enable second factor authentication": [""], + "Using email": [""], + "Using SMS": [""], + "Is this account public?": [""], + "public accounts have their balance publicly accesible": [""], + "Account updated": [""], + "The rights to change the account are not sufficient": [""], + "The username was not found": [""], + "You can't change the legal name, please contact the your account administrator.": + [""], + "You can't change the debt limit, please contact the your account administrator.": + [""], + "You can't change the cashout address, please contact the your account administrator.": + [""], + "You can't change the contact data, please contact the your account administrator.": + [""], + 'Account "%1$s"': [""], + "Change details": [""], + Update: [""], + "password doesn't match": [""], + "Password changed": [""], + "Not authorized to change the password, maybe the session is invalid.": [ + "", + ], + "You need to provide the old password. If you don't have it contact your account administrator.": + [""], + "Your current password doesn't match, can't change to a new password.": [ + "", + ], + "Update password": [""], + "New password": [""], + "Type it again": [""], + "repeat the same password": [""], + "Current password": [""], + "your current password, for security": [""], + Change: [""], + "Can't delete the account": [""], + "The account can't be delete while still holding some balance. First make sure that the owner make a complete cashout.": + [""], + "Account removed": [""], + "No enough permission to delete the account.": [""], + "The username was not found.": [""], + "Can't delete a reserved username.": [""], + "Can't delete an account with balance different than zero.": [""], + "name doesn't match": [""], + "You are going to remove the account": [""], + "This step can't be undone.": [""], + 'Deleting account "%1$s"': [""], + Verification: [""], + "enter the account name that is going to be deleted": [""], + 'Account created with password "%1$s". The user must change the password on the next login.': + [""], + "Server replied that phone or email is invalid": [""], + "The rights to perform the operation are not sufficient": [""], + "Account username is already taken": [""], + "Account id is already taken": [""], + "Bank ran out of bonus credit.": [""], + "Account username can't be used because is reserved": [""], + "Can't create accounts": [""], + "Only system admin can create accounts.": [""], + "New business account": [""], + Create: [""], + "Cashout not supported.": [""], + "Account not found.": ["Lista conti pubblici non trovata."], + "Latest cashouts": ["Ultime transazioni:"], + Created: [""], + Confirmed: ["Conferma"], + "Total debit": [""], + "Total credit": [""], + Status: [""], + never: [""], + "Cashout for account %1$s": [""], + "This cashout not found. Maybe already aborted.": [""], + "Cashout not found. It may be also mean that it was already aborted.": [ + "", + ], + "Cashout was already confimed.": [""], + "Cashout operation is not supported.": [""], + "The cashout operation is already aborted.": [""], + "Missing destination account.": [""], + "Too many failed attempts.": [""], + "The code for this cashout is invalid.": [""], + "Cashout detail": [""], + Debited: [""], + Credited: [""], + "Enter the confirmation code": [""], + Abort: ["Annulla"], + Confirm: ["Conferma"], + "Unauthorized to make the operation, maybe the session has expired or the password changed.": + [""], + "The operation was rejected due to insufficient funds.": [""], + "Do not show this again": [""], + Close: [""], + "On this device": [""], + 'If you are using a web browser on desktop you should access your wallet with the GNU Taler WebExtension now or click the link if your WebExtension have the "Inject Taler support" option enabled.': + [""], + Start: [""], + "On a mobile phone": [""], + "Scan the QR code with your mobile device.": [ + "Usa questo codice QR per ritirare contante nel tuo wallet:", + ], + "There is an operation already": [""], + "Complete or cancel the operation in": ["Conferma il ritiro"], + "Server responded with an invalid withdraw URI": [""], + "Withdraw URI: %1$s": ["Prelevare"], + "The operation was rejected due to insufficient funds": [""], + "Prepare your wallet": [""], + "After using your wallet you will need to confirm or cancel the operation on this site.": + [""], + "You need a GNU Taler Wallet": ["Ritira contante nel portafoglio Taler"], + "If you don't have one yet you can follow the instruction in": [""], + "Send money": [""], + "to a %1$s wallet": [""], + "Withdraw digital money into your mobile wallet or browser extension": [ + "", + ], + "operation ready": [""], + "to another bank account": [ + "Trasferisci fondi a un altro conto di questa banca:", + ], + "Make a wire transfer to an account with known bank account number.": [ + "", + ], + "Transfer details": ["Effettua un bonifico"], + "This is a demo bank": [""], + "This part of the demo shows how a bank that supports Taler directly would work. In addition to using your own bank account, you can also see the transaction history of some %1$s.": + [""], + "This part of the demo shows how a bank that supports Taler directly would work.": + [""], + "Pending account delete operation": [""], + "Pending account update operation": [""], + "Pending password update operation": [""], + "Pending transaction operation": [""], + "Pending withdrawal operation": [""], + "Pending cashout operation": [""], + "You can complete or cancel the operation in": [""], + "Download bank stats": [""], + "Include hour metric": [""], + "Include day metric": [""], + "Include month metric": [""], + "Include year metric": [""], + "Include table header": [""], + "Add previous metric for compare": [""], + "Fail on first error": [""], + Download: [""], + "downloading... %1$s": [""], + "Download completed": [""], + "click here to save the file in your computer": [""], + "Challenge not found.": [""], + "This user is not authorized to complete this challenge.": [""], + "Too many attemps, try another code.": [""], + "The confirmation code is wrong, try again.": [""], + "The operation expired.": [""], + "The operation failed.": ["Questo ritiro è stato annullato!"], + "The operation needs another confirmation to complete.": [""], + "Account delete": [""], + "Account update": [""], + "Password update": [""], + "Wire transfer": ["Bonifico"], + Withdrawal: ["Prelevare"], + "Confirm the operation": ["Conferma il ritiro"], + "Send again": [""], + "Send code": [""], + "Operation details": [""], + "Challenge details": [""], + "Sent at": [""], + "To phone": [""], + "To email": [""], + "Welcome to %1$s!": [""], + }, + }, + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "it", + completeness: 14, +}; + +strings["fr"] = { + locale_data: { + messages: { + "": { + domain: "messages", + plural_forms: "nplurals=2; plural=n > 1;", + lang: "fr", + }, + "Operation failed, please report": [""], + "Request timeout": [""], + "Request throttled": [""], + "Malformed response": [""], + "Network error": [""], + "Unexpected request error": [""], + "Unexpected error": [""], + "IBAN numbers usually have more that 4 digits": [""], + "IBAN numbers usually have less that 34 digits": [""], + "IBAN country code not found": [""], + "IBAN number is not valid, checksum is wrong": [""], + "Max withdrawal amount": [""], + "Show withdrawal confirmation": [""], + "Show demo description": [""], + "Show install wallet first": [""], + "Use fast withdrawal form": [""], + "Show debug info": [""], + "The reserve operation has been confirmed previously and can't be aborted": + [""], + "The operation id is invalid.": [""], + "The operation was not found.": [""], + "If you have a Taler wallet installed in this device": [""], + "You will see the details of the operation in your wallet including the fees (if applies). If you still don't have one you can install it following instructions in": + [""], + "this page": [""], + Withdraw: [""], + "Or if you have the wallet in another device": [""], + "Scan the QR below to start the withdrawal.": [""], + required: [""], + "IBAN should have just uppercased letters and numbers": [""], + "not valid": [""], + "should be greater than 0": [""], + "balance is not enough": [""], + "does not follow the pattern": [""], + 'only "IBAN" target are supported': [""], + 'use the "amount" parameter to specify the amount to be transferred': [ + "", + ], + "the amount is not valid": [""], + 'use the "message" parameter to specify a reference text for the transfer': + [""], + "The request was invalid or the payto://-URI used unacceptable features.": + [""], + "Not enough permission to complete the operation.": [""], + 'The destination account "%1$s" was not found.': [""], + "The origin and the destination of the transfer can't be the same.": [""], + "Your balance is not enough.": [""], + 'The origin account "%1$s" was not found.': [""], + "Using a form": [""], + "Import payto:// URI": [""], + Recipient: [""], + "IBAN of the recipient's account": [""], + "Transfer subject": [""], + subject: [""], + "some text to identify the transfer": [""], + Amount: [""], + "amount to transfer": [""], + "payto URI:": [""], + "uniform resource identifier of the target account": [""], + "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]": [""], + Cancel: [""], + Send: [""], + "Missing username": [""], + "Missing password": [""], + 'Wrong credentials for "%1$s"': [""], + "Account not found": [""], + Username: [""], + "username of the account": [""], + Password: [""], + "password of the account": [""], + Check: [""], + "Log in": [""], + Register: [""], + "Wire transfer completed!": [""], + "The withdrawal has been aborted previously and can't be confirmed": [""], + "The withdrawal operation can't be confirmed before a wallet accepted the transaction.": + [""], + "Your balance is not enough for the operation.": [""], + "Confirm the withdrawal operation": [""], + "Wire transfer details": [""], + "Taler Exchange operator's account": [""], + "Taler Exchange operator's name": [""], + Transfer: [""], + "Authentication required": [""], + "This operation was created with other username": [""], + "Operation aborted": [""], + "The wire transfer to the Taler Exchange operator's account was aborted, your balance was not affected.": + [""], + "You can close this page now or continue to the account page.": [""], + Continue: [""], + "Withdrawal confirmed": [""], + "The wire transfer to the Taler operator has been initiated. You will soon receive the requested amount in your Taler wallet.": + [""], + Done: [""], + "Operation canceled": [""], + "The operation is marked as 'selected' but some step in the withdrawal failed": + [""], + "The account is selected but no withdrawal identification found.": [""], + "There is a withdrawal identification but no account has been selected or the selected account is invalid.": + [""], + "No withdrawal ID found and no account has been selected or the selected account is invalid.": + [""], + "Operation not found": [""], + "This operation is not known by the server. The operation id is wrong or the server deleted the operation information before reaching here.": + [""], + "Cotinue to dashboard": [""], + "The Withdrawal URI is not valid": [""], + 'the bank backend is not supported. supported version "%1$s", server version "%2$s"': + [""], + "Internal error, please report.": [""], + Preferences: [""], + "Welcome, %1$s": [""], + "Latest transactions": [""], + Date: [""], + Counterpart: [""], + Subject: [""], + sent: [""], + received: [""], + "invalid value": [""], + to: [""], + from: [""], + "First page": [""], + Next: [""], + "History of public accounts": [""], + "Currently, the bank is not accepting new registrations!": [""], + "Missing name": [""], + "Use letters and numbers only, and start with a lowercase letter": [""], + "Passwords don't match": [""], + "Server replied with invalid phone or email.": [""], + "Registration is disabled because the bank ran out of bonus credit.": [ + "", + ], + "No enough permission to create that account.": [""], + "That account id is already taken.": [""], + "That username is already taken.": [""], + "That username can't be used because is reserved.": [""], + "Only admin is allow to set debt limit.": [""], + "No information for the selected authentication channel.": [""], + "Authentication channel is not supported.": [""], + "Only admin can create accounts with second factor authentication.": [""], + "Account registration": [""], + "Repeat password": [""], + Name: [""], + "Create a random temporary user": [""], + "Make a wire transfer": [""], + "Wire transfer created!": [""], + Accounts: [""], + "A list of all business account in the bank.": [""], + "Create account": [""], + Balance: [""], + Actions: [""], + unknown: [""], + "change password": [""], + remove: [""], + "Select a section": [""], + "Last hour": [""], + "Last day": [""], + "Last month": [""], + "Last year": [""], + "Last Year": [""], + "Trading volume on %1$s compared to %2$s": [""], + Cashin: [""], + Cashout: [""], + Payin: [""], + Payout: [""], + "download stats as CSV": [""], + "Descreased by": [""], + "Increased by": [""], + "Unable to create a cashout": [""], + "The bank configuration does not support cashout operations.": [""], + invalid: [""], + "need to be higher due to fees": [""], + "the total transfer at destination will be zero": [""], + "Cashout created": [""], + "Duplicated request detected, check if the operation succeded or try again.": + [""], + "The conversion rate was incorrectly applied": [""], + "The account does not have sufficient funds": [""], + "Cashouts are not supported": [""], + "Missing cashout URI in the profile": [""], + "Sending the confirmation message failed, retry later or contact the administrator.": + [""], + "Convertion rate": [""], + Fee: [""], + "To account": [""], + "No cashout account": [""], + "Before doing a cashout you need to complete your profile": [""], + "Amount to send": [""], + "Amount to receive": [""], + "Total cost": [""], + "Balance left": [""], + "Before fee": [""], + "Total cashout transfer": [""], + "No cashout channel available": [""], + "Before doing a cashout the server need to provide an second channel to confirm the operation": + [""], + "Second factor authentication": [""], + Email: [""], + "add a email in your profile to enable this option": [""], + SMS: [""], + "add a phone number in your profile to enable this option": [""], + Details: [""], + Delete: [""], + Credentials: [""], + Cashouts: [""], + "it doesnt have the pattern of an IBAN number": [""], + "it doesnt have the pattern of an email": [""], + "should start with +": [""], + "phone number can't have other than numbers": [""], + "account identification in the bank": [""], + "name of the person owner the account": [""], + "Internal IBAN": [""], + "if empty a random account number will be assigned": [""], + "account identification for bank transfer": [""], + Phone: [""], + "Cashout IBAN": [""], + "account number where the money is going to be sent when doing cashouts": + [""], + "Max debt": [""], + "how much is user able to transfer after zero balance": [""], + "Is this a Taler Exchange?": [""], + "This server doesn't support second factor authentication.": [""], + "Enable second factor authentication": [""], + "Using email": [""], + "Using SMS": [""], + "Is this account public?": [""], + "public accounts have their balance publicly accesible": [""], + "Account updated": [""], + "The rights to change the account are not sufficient": [""], + "The username was not found": [""], + "You can't change the legal name, please contact the your account administrator.": + [""], + "You can't change the debt limit, please contact the your account administrator.": + [""], + "You can't change the cashout address, please contact the your account administrator.": + [""], + "You can't change the contact data, please contact the your account administrator.": + [""], + 'Account "%1$s"': [""], + "Change details": [""], + Update: [""], + "password doesn't match": [""], + "Password changed": [""], + "Not authorized to change the password, maybe the session is invalid.": [ + "", + ], + "You need to provide the old password. If you don't have it contact your account administrator.": + [""], + "Your current password doesn't match, can't change to a new password.": [ + "", + ], + "Update password": [""], + "New password": [""], + "Type it again": [""], + "repeat the same password": [""], + "Current password": [""], + "your current password, for security": [""], + Change: [""], + "Can't delete the account": [""], + "The account can't be delete while still holding some balance. First make sure that the owner make a complete cashout.": + [""], + "Account removed": [""], + "No enough permission to delete the account.": [""], + "The username was not found.": [""], + "Can't delete a reserved username.": [""], + "Can't delete an account with balance different than zero.": [""], + "name doesn't match": [""], + "You are going to remove the account": [""], + "This step can't be undone.": [""], + 'Deleting account "%1$s"': [""], + Verification: [""], + "enter the account name that is going to be deleted": [""], + 'Account created with password "%1$s". The user must change the password on the next login.': + [""], + "Server replied that phone or email is invalid": [""], + "The rights to perform the operation are not sufficient": [""], + "Account username is already taken": [""], + "Account id is already taken": [""], + "Bank ran out of bonus credit.": [""], + "Account username can't be used because is reserved": [""], + "Can't create accounts": [""], + "Only system admin can create accounts.": [""], + "New business account": [""], + Create: [""], + "Cashout not supported.": [""], + "Account not found.": [""], + "Latest cashouts": [""], + Created: [""], + Confirmed: [""], + "Total debit": [""], + "Total credit": [""], + Status: [""], + never: [""], + "Cashout for account %1$s": [""], + "This cashout not found. Maybe already aborted.": [""], + "Cashout not found. It may be also mean that it was already aborted.": [ + "", + ], + "Cashout was already confimed.": [""], + "Cashout operation is not supported.": [""], + "The cashout operation is already aborted.": [""], + "Missing destination account.": [""], + "Too many failed attempts.": [""], + "The code for this cashout is invalid.": [""], + "Cashout detail": [""], + Debited: [""], + Credited: [""], + "Enter the confirmation code": [""], + Abort: [""], + Confirm: [""], + "Unauthorized to make the operation, maybe the session has expired or the password changed.": + [""], + "The operation was rejected due to insufficient funds.": [""], + "Do not show this again": [""], + Close: [""], + "On this device": [""], + 'If you are using a web browser on desktop you should access your wallet with the GNU Taler WebExtension now or click the link if your WebExtension have the "Inject Taler support" option enabled.': + [""], + Start: [""], + "On a mobile phone": [""], + "Scan the QR code with your mobile device.": [""], + "There is an operation already": [""], + "Complete or cancel the operation in": [""], + "Server responded with an invalid withdraw URI": [""], + "Withdraw URI: %1$s": [""], + "The operation was rejected due to insufficient funds": [""], + "Prepare your wallet": [""], + "After using your wallet you will need to confirm or cancel the operation on this site.": + [""], + "You need a GNU Taler Wallet": [""], + "If you don't have one yet you can follow the instruction in": [""], + "Send money": [""], + "to a %1$s wallet": [""], + "Withdraw digital money into your mobile wallet or browser extension": [ + "", + ], + "operation ready": [""], + "to another bank account": [""], + "Make a wire transfer to an account with known bank account number.": [ + "", + ], + "Transfer details": [""], + "This is a demo bank": [""], + "This part of the demo shows how a bank that supports Taler directly would work. In addition to using your own bank account, you can also see the transaction history of some %1$s.": + [""], + "This part of the demo shows how a bank that supports Taler directly would work.": + [""], + "Pending account delete operation": [""], + "Pending account update operation": [""], + "Pending password update operation": [""], + "Pending transaction operation": [""], + "Pending withdrawal operation": [""], + "Pending cashout operation": [""], + "You can complete or cancel the operation in": [""], + "Download bank stats": [""], + "Include hour metric": [""], + "Include day metric": [""], + "Include month metric": [""], + "Include year metric": [""], + "Include table header": [""], + "Add previous metric for compare": [""], + "Fail on first error": [""], + Download: [""], + "downloading... %1$s": [""], + "Download completed": [""], + "click here to save the file in your computer": [""], + "Challenge not found.": [""], + "This user is not authorized to complete this challenge.": [""], + "Too many attemps, try another code.": [""], + "The confirmation code is wrong, try again.": [""], + "The operation expired.": [""], + "The operation failed.": [""], + "The operation needs another confirmation to complete.": [""], + "Account delete": [""], + "Account update": [""], + "Password update": [""], + "Wire transfer": [""], + Withdrawal: [""], + "Confirm the operation": [""], + "Send again": [""], + "Send code": [""], + "Operation details": [""], + "Challenge details": [""], + "Sent at": [""], + "To phone": [""], + "To email": [""], + "Welcome to %1$s!": [""], + }, + }, + domain: "messages", + plural_forms: "nplurals=2; plural=n > 1;", + lang: "fr", + completeness: 0, +}; + +strings["es"] = { + locale_data: { + messages: { + "": { + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "es", + }, + "Operation failed, please report": [ + "La operaicón falló, por favor reportelo", + ], + "Request timeout": ["La petición al servidor agoto su tiempo"], + "Request throttled": ["La petición al servidor interrumpida"], + "Malformed response": ["Respuesta malformada"], + "Network error": ["Error de conexión"], + "Unexpected request error": ["Error de pedido inesperado"], + "Unexpected error": ["Error inesperado"], + "IBAN numbers usually have more that 4 digits": [ + "Los números IBAN usualmente tienen mas de 4 digitos", + ], + "IBAN numbers usually have less that 34 digits": [ + "Los números IBAN usualmente tienen menos de 34 digitos", + ], + "IBAN country code not found": ["Código de pais de IBAN no encontrado"], + "IBAN number is not valid, checksum is wrong": [ + "El número IBAN no es válido, falló la verificación", + ], + "Max withdrawal amount": ["Monto máximo de extracción"], + "Show withdrawal confirmation": ["Mostrar confirmación de extracción"], + "Show demo description": ["Mostrar descripción de demo"], + "Show install wallet first": ["Mostrar instalar la billetera primero"], + "Use fast withdrawal form": ["Usar formulario de extracción rápida"], + "Show debug info": ["Mostrar información de depuración"], + "The reserve operation has been confirmed previously and can't be aborted": + [ + "La operación en la reserva ya ha sido confirmada previamente y no puede ser abortada", + ], + "The operation id is invalid.": ["El id de operación es invalido."], + "The operation was not found.": ["La operación no se encontró."], + "If you have a Taler wallet installed in this device": [ + "Si tienes una billetera Taler instalada en este dispositivo", + ], + "You will see the details of the operation in your wallet including the fees (if applies). If you still don't have one you can install it following instructions in": + [ + "Veras los detalles de la operación en tu billetera incluyendo comisiones (si aplicán). Si todavía no tienes una puedes instalarla siguiendo las instrucciones en", + ], + "this page": ["esta página"], + Withdraw: ["Retirar"], + "Or if you have the wallet in another device": [ + "O si tienes la billetera en otro dispositivo", + ], + "Scan the QR below to start the withdrawal.": [ + "Escanea el QR debajo para comenzar la extracción.", + ], + required: ["requerido"], + "IBAN should have just uppercased letters and numbers": [ + "IBAN debería tener letras mayúsculas y números", + ], + "not valid": ["no válido"], + "should be greater than 0": ["Debería ser mas grande que 0"], + "balance is not enough": ["el saldo no es suficiente"], + "does not follow the pattern": ["no tiene un patrón valido"], + 'only "IBAN" target are supported': [ + 'solo cuentas "IBAN" son soportadas', + ], + 'use the "amount" parameter to specify the amount to be transferred': [ + 'usa el parámetro "amount" para indicar el monto a ser transferido', + ], + "the amount is not valid": ["el monto no es válido"], + 'use the "message" parameter to specify a reference text for the transfer': + [ + 'usa el parámetro "message" para indicar un texto de referencia en la transferencia', + ], + "The request was invalid or the payto://-URI used unacceptable features.": + [ + "El pedido era inválido o el URI payto:// usado tiene características inaceptables.", + ], + "Not enough permission to complete the operation.": [ + "Sin permisos suficientes para completar la operación.", + ], + 'The destination account "%1$s" was not found.': [ + 'La cuenta de destino "%1$s" no fue encontrada.', + ], + "The origin and the destination of the transfer can't be the same.": [ + "El origen y destino de la transferencia no puede ser la misma.", + ], + "Your balance is not enough.": ["El saldo no es suficiente."], + 'The origin account "%1$s" was not found.': [ + 'La cuenta origen "%1$s" no fue encontrada.', + ], + "Using a form": ["Usando un formulario"], + "Import payto:// URI": ["Importando un URI payto://"], + Recipient: ["Destinatario"], + "IBAN of the recipient's account": [ + "Numero IBAN de la cuenta destinataria", + ], + "Transfer subject": ["Asunto de transferencia"], + subject: ["asunto"], + "some text to identify the transfer": [ + "algún texto para identificar la transferencia", + ], + Amount: ["Monto"], + "amount to transfer": ["monto a transferir"], + "payto URI:": ["payto URI:"], + "uniform resource identifier of the target account": [ + "identificador de recurso uniforme de la cuenta destino", + ], + "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]": [ + "payto://iban/[iban-destinatario]?message=[asunto]&amount=[%1$s:X.Y]", + ], + Cancel: ["Cancelar"], + Send: ["Envíar"], + "Missing username": ["Falta nombre de usuario"], + "Missing password": ["Falta contraseña"], + 'Wrong credentials for "%1$s"': ['Credenciales incorrectas para "%1$s"'], + "Account not found": ["Cuenta no encontrada"], + Username: ["Nombre de usuario"], + "username of the account": ["nombre de usuario de la cuenta"], + Password: ["Contraseña"], + "password of the account": ["contraseña de la cuenta"], + Check: ["Verificar"], + "Log in": ["Acceso"], + Register: ["Registrarse"], + "Wire transfer completed!": ["Transferencia bancaria completada!"], + "The withdrawal has been aborted previously and can't be confirmed": [ + "La extracción fue abortada anteriormente y no puede ser confirmada", + ], + "The withdrawal operation can't be confirmed before a wallet accepted the transaction.": + [ + "La operación de extracción no puede ser confirmada antes de que una billetera acepte la transaccion.", + ], + "Your balance is not enough for the operation.": [ + "El saldo no es suficiente para la operación.", + ], + "Confirm the withdrawal operation": [ + "Confirme la operación de extracción", + ], + "Wire transfer details": ["Detalle de transferencia bancaria"], + "Taler Exchange operator's account": [ + "Cuenta del operador del Taler Exchange", + ], + "Taler Exchange operator's name": [ + "Nombre del operador del Taler Exchange", + ], + Transfer: ["Transferencia"], + "Authentication required": ["Autenticación requerida"], + "This operation was created with other username": [ + "Esta operación fue creada con otro usuario", + ], + "Operation aborted": ["Operación abortada"], + "The wire transfer to the Taler Exchange operator's account was aborted, your balance was not affected.": + [ + "La transferencia bancaria a la cuenta del operador del Taler Exchange fue abortada, su saldo no fue afectado.", + ], + "You can close this page now or continue to the account page.": [ + "Ya puedes cerrar esta pagina or continuar a la página de estado de cuenta.", + ], + Continue: ["Continuar"], + "Withdrawal confirmed": ["La extracción fue confirmada"], + "The wire transfer to the Taler operator has been initiated. You will soon receive the requested amount in your Taler wallet.": + [ + "La transferencia bancaria al operador Taler fue iniciada. Pronto recibirás el monto pedido en tu billetera Taler.", + ], + Done: ["Listo"], + "Operation canceled": ["Operación cancelada"], + "The operation is marked as 'selected' but some step in the withdrawal failed": + [ + "La operación está marcada como 'seleccionada' pero algunos pasos en la extracción fallaron", + ], + "The account is selected but no withdrawal identification found.": [ + "La cuenta está seleccionada pero no se encontró el identificador de extracción.", + ], + "There is a withdrawal identification but no account has been selected or the selected account is invalid.": + [ + "Hay un identificador de extracción pero la cuenta no ha sido seleccionada o la selccionada es inválida.", + ], + "No withdrawal ID found and no account has been selected or the selected account is invalid.": + [ + "No hay un identificador de extracción y ninguna cuenta a sido seleccionada o la seleccionada es inválida.", + ], + "Operation not found": ["Operación no encontrada"], + "This operation is not known by the server. The operation id is wrong or the server deleted the operation information before reaching here.": + [ + "Esta operación no es conocida por el servidor. El identificador de operación es incorrecto o el server borró la información de la operación antes de llegar hasta aquí.", + ], + "Cotinue to dashboard": ["Continuar al panel"], + "The Withdrawal URI is not valid": ["El URI de estracción no es válido"], + 'the bank backend is not supported. supported version "%1$s", server version "%2$s"': + [ + 'El servidor de bank no esta spoportado. Version soportada "%1$s", version del server "%2$s"', + ], + "Internal error, please report.": [ + "Error interno, por favor reporte el error.", + ], + Preferences: ["Preferencias"], + "Welcome, %1$s": ["Bienvenido/a, %1$s"], + "Latest transactions": ["Últimas transacciones"], + Date: ["Fecha"], + Counterpart: ["Contraparte"], + Subject: ["Asunto"], + sent: ["enviado"], + received: ["recibido"], + "invalid value": ["valor inválido"], + to: ["hacia"], + from: ["desde"], + "First page": ["Primera página"], + Next: ["Siguiente"], + "History of public accounts": ["Historial de cuentas públicas"], + "Currently, the bank is not accepting new registrations!": [ + "Actualmente, el banco no está aceptado nuevos registros!", + ], + "Missing name": ["Falta nombre"], + "Use letters and numbers only, and start with a lowercase letter": [ + "Solo use letras y números, y comience con una letra minúscula", + ], + "Passwords don't match": ["La contraseña no coincide"], + "Server replied with invalid phone or email.": [ + "El servidor repondio con teléfono o dirección de correo inválido.", + ], + "Registration is disabled because the bank ran out of bonus credit.": [ + "El registro está deshabilitado porque el banco se quedó sin crédito bonus.", + ], + "No enough permission to create that account.": [ + "Sin permisos suficientes para crear esa cuenta.", + ], + "That account id is already taken.": [ + "El identificador de cuenta ya está tomado.", + ], + "That username is already taken.": [ + "El nombre de usuario ya está tomado.", + ], + "That username can't be used because is reserved.": [ + "El nombre de usuario no puede ser usado porque esta reservado.", + ], + "Only admin is allow to set debt limit.": [ + "Solo el administrador tiene permitido cambiar el límite de deuda.", + ], + "No information for the selected authentication channel.": [ + "No hay información para el canal de autenticación seleccionado.", + ], + "Authentication channel is not supported.": [ + "Canal de autenticación no esta soportado.", + ], + "Only admin can create accounts with second factor authentication.": [ + "Solo el administrador puede crear cuentas con el segundo factor de autenticación.", + ], + "Account registration": ["Registro de cuenta"], + "Repeat password": ["Repita la contraseña"], + Name: ["Nombre"], + "Create a random temporary user": ["Crear un usuario aleatorio temporal"], + "Make a wire transfer": ["Hacer una transferencia bancaria"], + "Wire transfer created!": ["Transferencia bancaria creada!"], + Accounts: ["Cuentas"], + "A list of all business account in the bank.": [ + "Una lista de todas las cuentas en el banco.", + ], + "Create account": ["Crear cuenta"], + Balance: ["Saldo"], + Actions: ["Acciones"], + unknown: ["desconocido"], + "change password": ["cambiar contraseña"], + remove: ["elimiar"], + "Select a section": ["Seleccione una sección"], + "Last hour": ["Última hora"], + "Last day": ["Último día"], + "Last month": ["Último mes"], + "Last year": ["Último año"], + "Last Year": ["Último Año"], + "Trading volume on %1$s compared to %2$s": [ + "Vólumen de comercio en %1$s comparado con %2$s", + ], + Cashin: ["Ingreso"], + Cashout: ["Egreso"], + Payin: ["Envios de dinero"], + Payout: ["Recibos de dinero"], + "download stats as CSV": ["descargar estadísticas en CSV"], + "Descreased by": ["Descendiente por"], + "Increased by": ["Ascendente por"], + "Unable to create a cashout": ["Imposible crear un egreso"], + "The bank configuration does not support cashout operations.": [ + "La configuración del banco no soporta operaciones de egreso.", + ], + invalid: ["inválido"], + "need to be higher due to fees": [ + "necesita ser mayor debido a las comisiones", + ], + "the total transfer at destination will be zero": [ + "el total de la transferencia en destino será cero", + ], + "Cashout created": ["Egreso creado"], + "Duplicated request detected, check if the operation succeded or try again.": + [ + "Se detectó una petición duplicada, verifique si la operación tuvo éxito o intente otra vez.", + ], + "The conversion rate was incorrectly applied": [ + "La tasa de conversión se aplicó incorrectamente", + ], + "The account does not have sufficient funds": [ + "La cuenta no tiene fondos suficientes", + ], + "Cashouts are not supported": ["Egresos no están soportados"], + "Missing cashout URI in the profile": [ + "Falta dirección de egreso en el perfíl", + ], + "Sending the confirmation message failed, retry later or contact the administrator.": + [ + "El envío del mensaje de confirmación falló, intente mas tarde o contacte al administrador.", + ], + "Convertion rate": ["Tasa de conversión"], + Fee: ["Comisión"], + "To account": ["Hacia cuenta"], + "No cashout account": ["No hay cuenta de egreso"], + "Before doing a cashout you need to complete your profile": [ + "Antes de hacer un egreso necesita completar su perfíl", + ], + "Amount to send": ["Monto a enviar"], + "Amount to receive": ["Monto a recibir"], + "Total cost": ["Costo total"], + "Balance left": ["Saldo remanente"], + "Before fee": ["Antes de comisión"], + "Total cashout transfer": ["Total de egreso"], + "No cashout channel available": ["No hay canal de egreso disponible"], + "Before doing a cashout the server need to provide an second channel to confirm the operation": + [ + "Antes de hacer un egreso el servidor necesita proveer un segundo canal para confirmar la operación", + ], + "Second factor authentication": ["Segundo factor de autenticación"], + Email: ["Correo eletrónico"], + "add a email in your profile to enable this option": [ + "agrege un correo en su perfíl para habilitar esta opción", + ], + SMS: ["SMS"], + "add a phone number in your profile to enable this option": [ + "agregue un número de teléfono para habilitar esta opción", + ], + Details: ["Detalles"], + Delete: ["Borrar"], + Credentials: ["Credenciales"], + Cashouts: ["Egresos"], + "it doesnt have the pattern of an IBAN number": [ + "no tiene el patrón de un número IBAN", + ], + "it doesnt have the pattern of an email": [ + "no tiene el patrón de un correo electrónico", + ], + "should start with +": ["debería comenzar con un +"], + "phone number can't have other than numbers": [ + "número de teléfono no puede tener otra cosa que numeros", + ], + "account identification in the bank": [ + "identificador de cuenta en el banco", + ], + "name of the person owner the account": [ + "nombre de la persona dueña de la cuenta", + ], + "Internal IBAN": ["IBAN interno"], + "if empty a random account number will be assigned": [ + "si está vacío un número de cuenta aleatorio será asignado", + ], + "account identification for bank transfer": [ + "identificador de cuenta para transferencia bancaria", + ], + Phone: ["Teléfono"], + "Cashout IBAN": ["IBAN de egreso"], + "account number where the money is going to be sent when doing cashouts": + [ + "numero de cuenta donde el dinero será enviado cuando se ejecuten egresos", + ], + "Max debt": ["Máxima deuda"], + "how much is user able to transfer after zero balance": [ + "cuanto tiene habilitado a transferir despues de un saldo en cero", + ], + "Is this a Taler Exchange?": ["Es un Taler Exchange?"], + "This server doesn't support second factor authentication.": [ + "Este servidor no tiene soporte para segundo factor de autenticación.", + ], + "Enable second factor authentication": [ + "Hábilitar segundo factor de autenticación", + ], + "Using email": ["Usando correo eletrónico"], + "Using SMS": ["Usando SMS"], + "Is this account public?": ["Es una cuenta pública?"], + "public accounts have their balance publicly accesible": [ + "las cuentas públicas tienen su saldo accesible al público", + ], + "Account updated": ["Cuenta actualizada"], + "The rights to change the account are not sufficient": [ + "Los permisos para cambiar la cuenta no son suficientes", + ], + "The username was not found": ["El nombre de usaurio no se encontró"], + "You can't change the legal name, please contact the your account administrator.": + [ + "No puede cambiar el nombre legal, por favor contacte el administrador de la cuenta.", + ], + "You can't change the debt limit, please contact the your account administrator.": + [ + "No puede cambiar el límite de deuda, por favor contacte el administrador de la cuenta.", + ], + "You can't change the cashout address, please contact the your account administrator.": + [ + "No puede cambiar la dirección de egreso, por favor contacte al administrador de la cuenta.", + ], + "You can't change the contact data, please contact the your account administrator.": + [ + "No puede cambiar los datos de contacto, por favor contacte al administrador de la cuenta.", + ], + 'Account "%1$s"': ['Cuenta "%1$s"'], + "Change details": ["Cambiar detalles"], + Update: ["Actualizar"], + "password doesn't match": ["la contraseña no coincide"], + "Password changed": ["La contraseña cambió"], + "Not authorized to change the password, maybe the session is invalid.": [ + "No está autorizado a cambiar el password, quizá la sesión es invalida.", + ], + "You need to provide the old password. If you don't have it contact your account administrator.": + [ + "Se necesita el password viejo para cambiar la contraseña. Si no lo tiene contacte a su administrador.", + ], + "Your current password doesn't match, can't change to a new password.": [ + "Su actual contraseña no coincide, no puede cambiar a una nueva contraseña.", + ], + "Update password": ["Actualizar contraseña"], + "New password": ["Nueva contraseña"], + "Type it again": ["Escribalo otra vez"], + "repeat the same password": ["repita la misma contraseña"], + "Current password": ["Contraseña actual"], + "your current password, for security": [ + "su actual contraseña, por seguridad", + ], + Change: ["Cambiar"], + "Can't delete the account": ["No se puede eliminar la cuenta"], + "The account can't be delete while still holding some balance. First make sure that the owner make a complete cashout.": + [ + "La cuenta no puede ser eliminada mientras tiene saldo. Primero aseguresé que el dueño haga un egreso completo.", + ], + "Account removed": ["Cuenta eliminada"], + "No enough permission to delete the account.": [ + "No tiene permisos suficientes para eliminar la cuenta.", + ], + "The username was not found.": ["El nombr ede usuario no se encontró."], + "Can't delete a reserved username.": [ + "No se puede eliminar un nombre de usuario reservado.", + ], + "Can't delete an account with balance different than zero.": [ + "No se puede eliminar una cuenta con saldo diferente a cero.", + ], + "name doesn't match": ["el nombre no coincide"], + "You are going to remove the account": ["Está por eliminar la cuenta"], + "This step can't be undone.": ["Este paso no puede ser deshecho."], + 'Deleting account "%1$s"': ['Borrando cuenta "%1$s"'], + Verification: ["Verificación"], + "enter the account name that is going to be deleted": [ + "ingrese el nombre de cuenta que será eliminado", + ], + 'Account created with password "%1$s". The user must change the password on the next login.': + [ + 'Cuenta creada con contraseña "%1$s". El usuario debe cambiar la contraseña en el siguiente ingreso.', + ], + "Server replied that phone or email is invalid": [ + "El servidor respondió que el teléfono o correo eletrónico es invalido", + ], + "The rights to perform the operation are not sufficient": [ + "Los permisos para ejecutar la operación no son suficientes", + ], + "Account username is already taken": [ + "El nombre del usuario ya está tomado", + ], + "Account id is already taken": ["El id de cuenta ya está tomado"], + "Bank ran out of bonus credit.": [ + "El banco no tiene mas crédito de bonus.", + ], + "Account username can't be used because is reserved": [ + "El nombre de usuario de la cuenta no puede userse porque está reservado", + ], + "Can't create accounts": ["No puede crear cuentas"], + "Only system admin can create accounts.": [ + "Solo los administradores del sistema pueden crear cuentas.", + ], + "New business account": ["Nueva cuenta"], + Create: ["Crear"], + "Cashout not supported.": ["Egreso no soportado."], + "Account not found.": ["Cuenta no encontrada."], + "Latest cashouts": ["Últimos egresos"], + Created: ["Creado"], + Confirmed: ["Confirmado"], + "Total debit": ["Débito total"], + "Total credit": ["Crédito total"], + Status: ["Estado"], + never: ["nunca"], + "Cashout for account %1$s": ["Egreso para cuenta %1$s"], + "This cashout not found. Maybe already aborted.": [ + "Este egreso no se encontró. Quizá fue abortado.", + ], + "Cashout not found. It may be also mean that it was already aborted.": [ + "Egreso no econtrado. También puede significar que ya ha sido abortado.", + ], + "Cashout was already confimed.": ["Egreso ya fue confirmado."], + "Cashout operation is not supported.": [ + "Operación de egreso no soportada.", + ], + "The cashout operation is already aborted.": [ + "La operación de egreso ya está abortada.", + ], + "Missing destination account.": ["Falta cuenta destino."], + "Too many failed attempts.": ["Demasiados intentos fallidos."], + "The code for this cashout is invalid.": [ + "El código para este egreso es invalido.", + ], + "Cashout detail": ["Detalles de egreso"], + Debited: ["Debitado"], + Credited: ["Acreditado"], + "Enter the confirmation code": ["Ingresar el código de confirmación"], + Abort: ["Abortar"], + Confirm: ["Confirmar"], + "Unauthorized to make the operation, maybe the session has expired or the password changed.": + [ + "No autorizado para hacer la operación, quizá la sesión haya expirado or cambió la contraseña.", + ], + "The operation was rejected due to insufficient funds.": [ + "La operación fue rechazada debido a saldo insuficiente.", + ], + "Do not show this again": ["No mostrar otra vez"], + Close: ["Cerrar"], + "On this device": ["En este dispositivo"], + 'If you are using a web browser on desktop you should access your wallet with the GNU Taler WebExtension now or click the link if your WebExtension have the "Inject Taler support" option enabled.': + [ + 'Si esta usando un explorador web de escritorio deberías acceder ahora a tu billletera con la GNU Taler WebExtension o hacer click en el link si tu extensión tiene la configuración "Inyectar soporte para Taler" habilitada.', + ], + Start: ["Comenzar"], + "On a mobile phone": ["En un dispotivo mobile"], + "Scan the QR code with your mobile device.": [ + "Escanear el código QR con tu dispotivo móvil.", + ], + "There is an operation already": ["Ya hay una operación"], + "Complete or cancel the operation in": [ + "Completa o cancela la operación en", + ], + "Server responded with an invalid withdraw URI": [ + "El servidor respondió con una URI de extracción inválida", + ], + "Withdraw URI: %1$s": ["URI de extracción: %1$s"], + "The operation was rejected due to insufficient funds": [ + "La operación fue rechazada debido a fundos insuficientes", + ], + "Prepare your wallet": ["Prepare su billetera"], + "After using your wallet you will need to confirm or cancel the operation on this site.": + [ + "Despues de usar tu billetera necesitarás confirmar o cancelar la operación en este sitio.", + ], + "You need a GNU Taler Wallet": ["Necesitas una GNU Taler Wallet"], + "If you don't have one yet you can follow the instruction in": [ + "Si no tienes una todavía puedes seguir las instrucciones en", + ], + "Send money": ["Enviar dinero"], + "to a %1$s wallet": ["a una billetera %1$s"], + "Withdraw digital money into your mobile wallet or browser extension": [ + "Extraer dinero digital a tu billetera móvil o extesión web", + ], + "operation ready": ["operación lista"], + "to another bank account": ["a otra cuenta bancaria"], + "Make a wire transfer to an account with known bank account number.": [ + "Hacer una transferencia bancaria a una cuenta con un número de cuenta conocido.", + ], + "Transfer details": ["Detalles de transferencia"], + "This is a demo bank": ["Este es un banco de demostración"], + "This part of the demo shows how a bank that supports Taler directly would work. In addition to using your own bank account, you can also see the transaction history of some %1$s.": + [ + "Esta parte de la demostración muestra cómo funciona un banco que soporta Taler directamente. Además de usar tu propia cuenta de banco, también podrás ver el historial de transacciones de algunas %1$s.", + ], + "This part of the demo shows how a bank that supports Taler directly would work.": + [ + "Esta parte de la demostración muetra como un banco que soporta Taler directamente funcionaría.", + ], + "Pending account delete operation": [ + "Operación pendiente de eliminación de cuenta", + ], + "Pending account update operation": [ + "Operación pendiente de actualización de cuenta", + ], + "Pending password update operation": [ + "Operación pendiente de actualización de password", + ], + "Pending transaction operation": ["Operación pendiente de transacción"], + "Pending withdrawal operation": ["Operación pendiente de extracción"], + "Pending cashout operation": ["Operación pendiente de egreso"], + "You can complete or cancel the operation in": [ + "Puedes completar o cancelar la operación en", + ], + "Download bank stats": ["Descargar estadísticas del banco"], + "Include hour metric": ["Incluir métrica horaria"], + "Include day metric": ["Incluir métrica diaria"], + "Include month metric": ["Incluir métrica mensual"], + "Include year metric": ["Incluir métrica anual"], + "Include table header": ["Incluir encabezado de tabla"], + "Add previous metric for compare": [ + "Agregar métrica previa para comparar", + ], + "Fail on first error": ["Fallar en el primer error"], + Download: ["Descargar"], + "downloading... %1$s": ["descargando... %1$s"], + "Download completed": ["Descarga completada"], + "click here to save the file in your computer": [ + "click aquí para guardar el archivo en su computadora", + ], + "Challenge not found.": ["Desafío no encontrado."], + "This user is not authorized to complete this challenge.": [ + "Este usuario no está autorizado para completar este desafío.", + ], + "Too many attemps, try another code.": [ + "Demasiados intentos, intente otro código.", + ], + "The confirmation code is wrong, try again.": [ + "El código de confirmación es erroneo, intente otra vez.", + ], + "The operation expired.": ["La operación expiró."], + "The operation failed.": ["La operación falló."], + "The operation needs another confirmation to complete.": [ + "La operación necesita otra confirmación para completar.", + ], + "Account delete": ["Eliminación de cuenta"], + "Account update": ["Actualización de cuenta"], + "Password update": ["Actualización de contraseña"], + "Wire transfer": ["Transferencia bancaria"], + Withdrawal: ["Extracción"], + "Confirm the operation": ["Confirmar la operación"], + "Send again": ["Enviar otra vez"], + "Send code": ["Enviar código"], + "Operation details": ["Detalles de operación"], + "Challenge details": ["Detalles del desafío"], + "Sent at": ["Enviado a"], + "To phone": ["Al teléfono"], + "To email": ["Al email"], + "Welcome to %1$s!": ["Bienvenido a %1$s!"], + }, + }, + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "es", + completeness: 100, +}; + +strings["en"] = { + locale_data: { + messages: { + "": { + domain: "messages", + plural_forms: "nplurals=2; plural=(n != 1);", + lang: "en", + }, + "Operation failed, please report": [""], + "Request timeout": [""], + "Request throttled": [""], + "Malformed response": [""], + "Network error": [""], + "Unexpected request error": [""], + "Unexpected error": [""], + "IBAN numbers usually have more that 4 digits": [""], + "IBAN numbers usually have less that 34 digits": [""], + "IBAN country code not found": [""], + "IBAN number is not valid, checksum is wrong": [""], + "Max withdrawal amount": [""], + "Show withdrawal confirmation": [""], + "Show demo description": [""], + "Show install wallet first": [""], + "Use fast withdrawal form": [""], + "Show debug info": [""], + "The reserve operation has been confirmed previously and can't be aborted": + [""], + "The operation id is invalid.": [""], + "The operation was not found.": [""], + "If you have a Taler wallet installed in this device": [""], + "You will see the details of the operation in your wallet including the fees (if applies). If you still don't have one you can install it following instructions in": + [""], + "this page": [""], + Withdraw: [""], + "Or if you have the wallet in another device": [""], + "Scan the QR below to start the withdrawal.": [""], + required: [""], + "IBAN should have just uppercased letters and numbers": [""], + "not valid": [""], + "should be greater than 0": [""], + "balance is not enough": [""], + "does not follow the pattern": [""], + 'only "IBAN" target are supported': [""], + 'use the "amount" parameter to specify the amount to be transferred': [ + "", + ], + "the amount is not valid": [""], + 'use the "message" parameter to specify a reference text for the transfer': + [""], + "The request was invalid or the payto://-URI used unacceptable features.": + [""], + "Not enough permission to complete the operation.": [""], + 'The destination account "%1$s" was not found.': [""], + "The origin and the destination of the transfer can't be the same.": [""], + "Your balance is not enough.": [""], + 'The origin account "%1$s" was not found.': [""], + "Using a form": [""], + "Import payto:// URI": [""], + Recipient: [""], + "IBAN of the recipient's account": [""], + "Transfer subject": [""], + subject: [""], + "some text to identify the transfer": [""], + Amount: [""], + "amount to transfer": [""], + "payto URI:": [""], + "uniform resource identifier of the target account": [""], + "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]": [""], + Cancel: [""], + Send: [""], + "Missing username": [""], + "Missing password": [""], + 'Wrong credentials for "%1$s"': [""], + "Account not found": [""], + Username: [""], + "username of the account": [""], + Password: [""], + "password of the account": [""], + Check: [""], + "Log in": [""], + Register: [""], + "Wire transfer completed!": [""], + "The withdrawal has been aborted previously and can't be confirmed": [""], + "The withdrawal operation can't be confirmed before a wallet accepted the transaction.": + [""], + "Your balance is not enough for the operation.": [""], + "Confirm the withdrawal operation": [""], + "Wire transfer details": [""], + "Taler Exchange operator's account": [""], + "Taler Exchange operator's name": [""], + Transfer: [""], + "Authentication required": [""], + "This operation was created with other username": [""], + "Operation aborted": [""], + "The wire transfer to the Taler Exchange operator's account was aborted, your balance was not affected.": + [""], + "You can close this page now or continue to the account page.": [""], + Continue: [""], + "Withdrawal confirmed": [""], + "The wire transfer to the Taler operator has been initiated. You will soon receive the requested amount in your Taler wallet.": + [""], + Done: [""], + "Operation canceled": [""], + "The operation is marked as 'selected' but some step in the withdrawal failed": + [""], + "The account is selected but no withdrawal identification found.": [""], + "There is a withdrawal identification but no account has been selected or the selected account is invalid.": + [""], + "No withdrawal ID found and no account has been selected or the selected account is invalid.": + [""], + "Operation not found": [""], + "This operation is not known by the server. The operation id is wrong or the server deleted the operation information before reaching here.": + [""], + "Cotinue to dashboard": [""], + "The Withdrawal URI is not valid": [""], + 'the bank backend is not supported. supported version "%1$s", server version "%2$s"': + [""], + "Internal error, please report.": [""], + Preferences: [""], + "Welcome, %1$s": [""], + "Latest transactions": [""], + Date: [""], + Counterpart: [""], + Subject: [""], + sent: [""], + received: [""], + "invalid value": [""], + to: [""], + from: [""], + "First page": [""], + Next: [""], + "History of public accounts": [""], + "Currently, the bank is not accepting new registrations!": [""], + "Missing name": [""], + "Use letters and numbers only, and start with a lowercase letter": [""], + "Passwords don't match": [""], + "Server replied with invalid phone or email.": [""], + "Registration is disabled because the bank ran out of bonus credit.": [ + "", + ], + "No enough permission to create that account.": [""], + "That account id is already taken.": [""], + "That username is already taken.": [""], + "That username can't be used because is reserved.": [""], + "Only admin is allow to set debt limit.": [""], + "No information for the selected authentication channel.": [""], + "Authentication channel is not supported.": [""], + "Only admin can create accounts with second factor authentication.": [""], + "Account registration": [""], + "Repeat password": [""], + Name: [""], + "Create a random temporary user": [""], + "Make a wire transfer": [""], + "Wire transfer created!": [""], + Accounts: [""], + "A list of all business account in the bank.": [""], + "Create account": [""], + Balance: [""], + Actions: [""], + unknown: [""], + "change password": [""], + remove: [""], + "Select a section": [""], + "Last hour": [""], + "Last day": [""], + "Last month": [""], + "Last year": [""], + "Last Year": [""], + "Trading volume on %1$s compared to %2$s": [""], + Cashin: [""], + Cashout: [""], + Payin: [""], + Payout: [""], + "download stats as CSV": [""], + "Descreased by": [""], + "Increased by": [""], + "Unable to create a cashout": [""], + "The bank configuration does not support cashout operations.": [""], + invalid: [""], + "need to be higher due to fees": [""], + "the total transfer at destination will be zero": [""], + "Cashout created": [""], + "Duplicated request detected, check if the operation succeded or try again.": + [""], + "The conversion rate was incorrectly applied": [""], + "The account does not have sufficient funds": [""], + "Cashouts are not supported": [""], + "Missing cashout URI in the profile": [""], + "Sending the confirmation message failed, retry later or contact the administrator.": + [""], + "Convertion rate": [""], + Fee: [""], + "To account": [""], + "No cashout account": [""], + "Before doing a cashout you need to complete your profile": [""], + "Amount to send": [""], + "Amount to receive": [""], + "Total cost": [""], + "Balance left": [""], + "Before fee": [""], + "Total cashout transfer": [""], + "No cashout channel available": [""], + "Before doing a cashout the server need to provide an second channel to confirm the operation": + [""], + "Second factor authentication": [""], + Email: [""], + "add a email in your profile to enable this option": [""], + SMS: [""], + "add a phone number in your profile to enable this option": [""], + Details: [""], + Delete: [""], + Credentials: [""], + Cashouts: [""], + "it doesnt have the pattern of an IBAN number": [""], + "it doesnt have the pattern of an email": [""], + "should start with +": [""], + "phone number can't have other than numbers": [""], + "account identification in the bank": [""], + "name of the person owner the account": [""], + "Internal IBAN": [""], + "if empty a random account number will be assigned": [""], + "account identification for bank transfer": [""], + Phone: [""], + "Cashout IBAN": [""], + "account number where the money is going to be sent when doing cashouts": + [""], + "Max debt": [""], + "how much is user able to transfer after zero balance": [""], + "Is this a Taler Exchange?": [""], + "This server doesn't support second factor authentication.": [""], + "Enable second factor authentication": [""], + "Using email": [""], + "Using SMS": [""], + "Is this account public?": [""], + "public accounts have their balance publicly accesible": [""], + "Account updated": [""], + "The rights to change the account are not sufficient": [""], + "The username was not found": [""], + "You can't change the legal name, please contact the your account administrator.": + [""], + "You can't change the debt limit, please contact the your account administrator.": + [""], + "You can't change the cashout address, please contact the your account administrator.": + [""], + "You can't change the contact data, please contact the your account administrator.": + [""], + 'Account "%1$s"': [""], + "Change details": [""], + Update: [""], + "password doesn't match": [""], + "Password changed": [""], + "Not authorized to change the password, maybe the session is invalid.": [ + "", + ], + "You need to provide the old password. If you don't have it contact your account administrator.": + [""], + "Your current password doesn't match, can't change to a new password.": [ + "", + ], + "Update password": [""], + "New password": [""], + "Type it again": [""], + "repeat the same password": [""], + "Current password": [""], + "your current password, for security": [""], + Change: [""], + "Can't delete the account": [""], + "The account can't be delete while still holding some balance. First make sure that the owner make a complete cashout.": + [""], + "Account removed": [""], + "No enough permission to delete the account.": [""], + "The username was not found.": [""], + "Can't delete a reserved username.": [""], + "Can't delete an account with balance different than zero.": [""], + "name doesn't match": [""], + "You are going to remove the account": [""], + "This step can't be undone.": [""], + 'Deleting account "%1$s"': [""], + Verification: [""], + "enter the account name that is going to be deleted": [""], + 'Account created with password "%1$s". The user must change the password on the next login.': + [""], + "Server replied that phone or email is invalid": [""], + "The rights to perform the operation are not sufficient": [""], + "Account username is already taken": [""], + "Account id is already taken": [""], + "Bank ran out of bonus credit.": [""], + "Account username can't be used because is reserved": [""], + "Can't create accounts": [""], + "Only system admin can create accounts.": [""], + "New business account": [""], + Create: [""], + "Cashout not supported.": [""], + "Account not found.": [""], + "Latest cashouts": [""], + Created: [""], + Confirmed: [""], + "Total debit": [""], + "Total credit": [""], + Status: [""], + never: [""], + "Cashout for account %1$s": [""], + "This cashout not found. Maybe already aborted.": [""], + "Cashout not found. It may be also mean that it was already aborted.": [ + "", + ], + "Cashout was already confimed.": [""], + "Cashout operation is not supported.": [""], + "The cashout operation is already aborted.": [""], + "Missing destination account.": [""], + "Too many failed attempts.": [""], + "The code for this cashout is invalid.": [""], + "Cashout detail": [""], + Debited: [""], + Credited: [""], + "Enter the confirmation code": [""], + Abort: [""], + Confirm: [""], + "Unauthorized to make the operation, maybe the session has expired or the password changed.": + [""], + "The operation was rejected due to insufficient funds.": [""], + "Do not show this again": [""], + Close: [""], + "On this device": [""], + 'If you are using a web browser on desktop you should access your wallet with the GNU Taler WebExtension now or click the link if your WebExtension have the "Inject Taler support" option enabled.': + [""], + Start: [""], + "On a mobile phone": [""], + "Scan the QR code with your mobile device.": [""], + "There is an operation already": [""], + "Complete or cancel the operation in": [""], + "Server responded with an invalid withdraw URI": [""], + "Withdraw URI: %1$s": [""], + "The operation was rejected due to insufficient funds": [""], + "Prepare your wallet": [""], + "After using your wallet you will need to confirm or cancel the operation on this site.": + [""], + "You need a GNU Taler Wallet": [""], + "If you don't have one yet you can follow the instruction in": [""], + "Send money": [""], + "to a %1$s wallet": [""], + "Withdraw digital money into your mobile wallet or browser extension": [ + "", + ], + "operation ready": [""], + "to another bank account": [""], + "Make a wire transfer to an account with known bank account number.": [ + "", + ], + "Transfer details": [""], + "This is a demo bank": [""], + "This part of the demo shows how a bank that supports Taler directly would work. In addition to using your own bank account, you can also see the transaction history of some %1$s.": + [""], + "This part of the demo shows how a bank that supports Taler directly would work.": + [""], + "Pending account delete operation": [""], + "Pending account update operation": [""], + "Pending password update operation": [""], + "Pending transaction operation": [""], + "Pending withdrawal operation": [""], + "Pending cashout operation": [""], + "You can complete or cancel the operation in": [""], + "Download bank stats": [""], + "Include hour metric": [""], + "Include day metric": [""], + "Include month metric": [""], + "Include year metric": [""], + "Include table header": [""], + "Add previous metric for compare": [""], + "Fail on first error": [""], + Download: [""], + "downloading... %1$s": [""], + "Download completed": [""], + "click here to save the file in your computer": [""], + "Challenge not found.": [""], + "This user is not authorized to complete this challenge.": [""], + "Too many attemps, try another code.": [""], + "The confirmation code is wrong, try again.": [""], + "The operation expired.": [""], + "The operation failed.": [""], + "The operation needs another confirmation to complete.": [""], + "Account delete": [""], + "Account update": [""], + "Password update": [""], + "Wire transfer": [""], + Withdrawal: [""], + "Confirm the operation": [""], + "Send again": [""], + "Send code": [""], + "Operation details": [""], + "Challenge details": [""], + "Sent at": [""], + "To phone": [""], + "To email": [""], + "Welcome to %1$s!": [""], + }, + }, + domain: "messages", + plural_forms: "nplurals=2; plural=(n != 1);", + lang: "en", + completeness: 100, +}; + +strings["de"] = { + locale_data: { + messages: { + "": { + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "de", + }, + "Operation failed, please report": [""], + "Request timeout": [""], + "Request throttled": [""], + "Malformed response": [""], + "Network error": [""], + "Unexpected request error": [""], + "Unexpected error": [""], + "IBAN numbers usually have more that 4 digits": [""], + "IBAN numbers usually have less that 34 digits": [""], + "IBAN country code not found": [""], + "IBAN number is not valid, checksum is wrong": [""], + "Max withdrawal amount": [""], + "Show withdrawal confirmation": [""], + "Show demo description": [""], + "Show install wallet first": [""], + "Use fast withdrawal form": [""], + "Show debug info": [""], + "The reserve operation has been confirmed previously and can't be aborted": + [""], + "The operation id is invalid.": [""], + "The operation was not found.": [""], + "If you have a Taler wallet installed in this device": [""], + "You will see the details of the operation in your wallet including the fees (if applies). If you still don't have one you can install it following instructions in": + [""], + "this page": [""], + Withdraw: [""], + "Or if you have the wallet in another device": [""], + "Scan the QR below to start the withdrawal.": [""], + required: [""], + "IBAN should have just uppercased letters and numbers": [""], + "not valid": [""], + "should be greater than 0": [""], + "balance is not enough": [""], + "does not follow the pattern": [""], + 'only "IBAN" target are supported': [""], + 'use the "amount" parameter to specify the amount to be transferred': [ + "", + ], + "the amount is not valid": [""], + 'use the "message" parameter to specify a reference text for the transfer': + [""], + "The request was invalid or the payto://-URI used unacceptable features.": + [""], + "Not enough permission to complete the operation.": [""], + 'The destination account "%1$s" was not found.': [""], + "The origin and the destination of the transfer can't be the same.": [""], + "Your balance is not enough.": [""], + 'The origin account "%1$s" was not found.': [""], + "Using a form": [""], + "Import payto:// URI": [""], + Recipient: [""], + "IBAN of the recipient's account": [""], + "Transfer subject": [""], + subject: ["Verwendungszweck"], + "some text to identify the transfer": [""], + Amount: ["Betrag"], + "amount to transfer": ["Betrag"], + "payto URI:": [""], + "uniform resource identifier of the target account": [""], + "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]": [""], + Cancel: [""], + Send: [""], + "Missing username": [""], + "Missing password": [""], + 'Wrong credentials for "%1$s"': [""], + "Account not found": [""], + Username: [""], + "username of the account": [""], + Password: [""], + "password of the account": ["Buchungen auf öffentlich sichtbaren Konten"], + Check: [""], + "Log in": [""], + Register: [""], + "Wire transfer completed!": [""], + "The withdrawal has been aborted previously and can't be confirmed": [""], + "The withdrawal operation can't be confirmed before a wallet accepted the transaction.": + [""], + "Your balance is not enough for the operation.": [""], + "Confirm the withdrawal operation": ["Abhebung bestätigen"], + "Wire transfer details": [""], + "Taler Exchange operator's account": [""], + "Taler Exchange operator's name": [""], + Transfer: [""], + "Authentication required": [""], + "This operation was created with other username": [""], + "Operation aborted": [""], + "The wire transfer to the Taler Exchange operator's account was aborted, your balance was not affected.": + [""], + "You can close this page now or continue to the account page.": [""], + Continue: [""], + "Withdrawal confirmed": [""], + "The wire transfer to the Taler operator has been initiated. You will soon receive the requested amount in your Taler wallet.": + [""], + Done: [""], + "Operation canceled": [""], + "The operation is marked as 'selected' but some step in the withdrawal failed": + [""], + "The account is selected but no withdrawal identification found.": [""], + "There is a withdrawal identification but no account has been selected or the selected account is invalid.": + [""], + "No withdrawal ID found and no account has been selected or the selected account is invalid.": + [""], + "Operation not found": [""], + "This operation is not known by the server. The operation id is wrong or the server deleted the operation information before reaching here.": + [""], + "Cotinue to dashboard": [""], + "The Withdrawal URI is not valid": [""], + 'the bank backend is not supported. supported version "%1$s", server version "%2$s"': + [""], + "Internal error, please report.": [""], + Preferences: [""], + "Welcome, %1$s": [""], + "Latest transactions": [""], + Date: ["Datum"], + Counterpart: ["Empfänger"], + Subject: ["Verwendungszweck"], + sent: [""], + received: [""], + "invalid value": [""], + to: [""], + from: [""], + "First page": [""], + Next: [""], + "History of public accounts": [ + "Buchungen auf öffentlich sichtbaren Konten", + ], + "Currently, the bank is not accepting new registrations!": [""], + "Missing name": [""], + "Use letters and numbers only, and start with a lowercase letter": [""], + "Passwords don't match": [""], + "Server replied with invalid phone or email.": [""], + "Registration is disabled because the bank ran out of bonus credit.": [ + "", + ], + "No enough permission to create that account.": [""], + "That account id is already taken.": [""], + "That username is already taken.": [""], + "That username can't be used because is reserved.": [""], + "Only admin is allow to set debt limit.": [""], + "No information for the selected authentication channel.": [""], + "Authentication channel is not supported.": [""], + "Only admin can create accounts with second factor authentication.": [""], + "Account registration": [""], + "Repeat password": [""], + Name: [""], + "Create a random temporary user": [""], + "Make a wire transfer": [""], + "Wire transfer created!": [""], + Accounts: ["Betrag"], + "A list of all business account in the bank.": [""], + "Create account": [""], + Balance: [""], + Actions: [""], + unknown: [""], + "change password": [""], + remove: [""], + "Select a section": [""], + "Last hour": [""], + "Last day": [""], + "Last month": [""], + "Last year": [""], + "Last Year": [""], + "Trading volume on %1$s compared to %2$s": [""], + Cashin: [""], + Cashout: [""], + Payin: [""], + Payout: [""], + "download stats as CSV": [""], + "Descreased by": [""], + "Increased by": [""], + "Unable to create a cashout": [""], + "The bank configuration does not support cashout operations.": [""], + invalid: [""], + "need to be higher due to fees": [""], + "the total transfer at destination will be zero": [""], + "Cashout created": [""], + "Duplicated request detected, check if the operation succeded or try again.": + [""], + "The conversion rate was incorrectly applied": [""], + "The account does not have sufficient funds": [""], + "Cashouts are not supported": [""], + "Missing cashout URI in the profile": [""], + "Sending the confirmation message failed, retry later or contact the administrator.": + [""], + "Convertion rate": [""], + Fee: [""], + "To account": [""], + "No cashout account": [""], + "Before doing a cashout you need to complete your profile": [""], + "Amount to send": ["Betrag"], + "Amount to receive": [""], + "Total cost": [""], + "Balance left": [""], + "Before fee": [""], + "Total cashout transfer": [""], + "No cashout channel available": [""], + "Before doing a cashout the server need to provide an second channel to confirm the operation": + [""], + "Second factor authentication": [""], + Email: [""], + "add a email in your profile to enable this option": [""], + SMS: [""], + "add a phone number in your profile to enable this option": [""], + Details: [""], + Delete: [""], + Credentials: [""], + Cashouts: [""], + "it doesnt have the pattern of an IBAN number": [""], + "it doesnt have the pattern of an email": [""], + "should start with +": [""], + "phone number can't have other than numbers": [""], + "account identification in the bank": [""], + "name of the person owner the account": [""], + "Internal IBAN": [""], + "if empty a random account number will be assigned": [""], + "account identification for bank transfer": [""], + Phone: [""], + "Cashout IBAN": [""], + "account number where the money is going to be sent when doing cashouts": + [""], + "Max debt": [""], + "how much is user able to transfer after zero balance": [""], + "Is this a Taler Exchange?": [""], + "This server doesn't support second factor authentication.": [""], + "Enable second factor authentication": [""], + "Using email": [""], + "Using SMS": [""], + "Is this account public?": [""], + "public accounts have their balance publicly accesible": [""], + "Account updated": [""], + "The rights to change the account are not sufficient": [""], + "The username was not found": [""], + "You can't change the legal name, please contact the your account administrator.": + [""], + "You can't change the debt limit, please contact the your account administrator.": + [""], + "You can't change the cashout address, please contact the your account administrator.": + [""], + "You can't change the contact data, please contact the your account administrator.": + [""], + 'Account "%1$s"': [""], + "Change details": [""], + Update: [""], + "password doesn't match": [""], + "Password changed": [""], + "Not authorized to change the password, maybe the session is invalid.": [ + "", + ], + "You need to provide the old password. If you don't have it contact your account administrator.": + [""], + "Your current password doesn't match, can't change to a new password.": [ + "", + ], + "Update password": [""], + "New password": [""], + "Type it again": [""], + "repeat the same password": [""], + "Current password": [""], + "your current password, for security": [""], + Change: [""], + "Can't delete the account": [""], + "The account can't be delete while still holding some balance. First make sure that the owner make a complete cashout.": + [""], + "Account removed": [""], + "No enough permission to delete the account.": [""], + "The username was not found.": [""], + "Can't delete a reserved username.": [""], + "Can't delete an account with balance different than zero.": [""], + "name doesn't match": [""], + "You are going to remove the account": [""], + "This step can't be undone.": [""], + 'Deleting account "%1$s"': [""], + Verification: [""], + "enter the account name that is going to be deleted": [""], + 'Account created with password "%1$s". The user must change the password on the next login.': + [""], + "Server replied that phone or email is invalid": [""], + "The rights to perform the operation are not sufficient": [""], + "Account username is already taken": [""], + "Account id is already taken": [""], + "Bank ran out of bonus credit.": [""], + "Account username can't be used because is reserved": [""], + "Can't create accounts": [""], + "Only system admin can create accounts.": [""], + "New business account": [""], + Create: [""], + "Cashout not supported.": [""], + "Account not found.": [""], + "Latest cashouts": [""], + Created: [""], + Confirmed: ["Bestätigen"], + "Total debit": [""], + "Total credit": [""], + Status: [""], + never: [""], + "Cashout for account %1$s": [""], + "This cashout not found. Maybe already aborted.": [""], + "Cashout not found. It may be also mean that it was already aborted.": [ + "", + ], + "Cashout was already confimed.": [""], + "Cashout operation is not supported.": [""], + "The cashout operation is already aborted.": [""], + "Missing destination account.": [""], + "Too many failed attempts.": [""], + "The code for this cashout is invalid.": [""], + "Cashout detail": [""], + Debited: [""], + Credited: [""], + "Enter the confirmation code": [""], + Abort: [""], + Confirm: ["Bestätigen"], + "Unauthorized to make the operation, maybe the session has expired or the password changed.": + [""], + "The operation was rejected due to insufficient funds.": [""], + "Do not show this again": [""], + Close: [""], + "On this device": [""], + 'If you are using a web browser on desktop you should access your wallet with the GNU Taler WebExtension now or click the link if your WebExtension have the "Inject Taler support" option enabled.': + [""], + Start: [""], + "On a mobile phone": [""], + "Scan the QR code with your mobile device.": [""], + "There is an operation already": [""], + "Complete or cancel the operation in": ["Abhebung bestätigen"], + "Server responded with an invalid withdraw URI": [""], + "Withdraw URI: %1$s": [""], + "The operation was rejected due to insufficient funds": [""], + "Prepare your wallet": [""], + "After using your wallet you will need to confirm or cancel the operation on this site.": + [""], + "You need a GNU Taler Wallet": [""], + "If you don't have one yet you can follow the instruction in": [""], + "Send money": [""], + "to a %1$s wallet": [""], + "Withdraw digital money into your mobile wallet or browser extension": [ + "", + ], + "operation ready": [""], + "to another bank account": [""], + "Make a wire transfer to an account with known bank account number.": [ + "", + ], + "Transfer details": [""], + "This is a demo bank": [""], + "This part of the demo shows how a bank that supports Taler directly would work. In addition to using your own bank account, you can also see the transaction history of some %1$s.": + [""], + "This part of the demo shows how a bank that supports Taler directly would work.": + [""], + "Pending account delete operation": [""], + "Pending account update operation": [""], + "Pending password update operation": [""], + "Pending transaction operation": [""], + "Pending withdrawal operation": [""], + "Pending cashout operation": [""], + "You can complete or cancel the operation in": [""], + "Download bank stats": [""], + "Include hour metric": [""], + "Include day metric": [""], + "Include month metric": [""], + "Include year metric": [""], + "Include table header": [""], + "Add previous metric for compare": [""], + "Fail on first error": [""], + Download: [""], + "downloading... %1$s": [""], + "Download completed": [""], + "click here to save the file in your computer": [""], + "Challenge not found.": [""], + "This user is not authorized to complete this challenge.": [""], + "Too many attemps, try another code.": [""], + "The confirmation code is wrong, try again.": [""], + "The operation expired.": [""], + "The operation failed.": [""], + "The operation needs another confirmation to complete.": [""], + "Account delete": [""], + "Account update": [""], + "Password update": [""], + "Wire transfer": [""], + Withdrawal: ["Abhebung bestätigen"], + "Confirm the operation": ["Abhebung bestätigen"], + "Send again": [""], + "Send code": [""], + "Operation details": [""], + "Challenge details": [""], + "Sent at": [""], + "To phone": [""], + "To email": [""], + "Welcome to %1$s!": [""], + }, + }, + domain: "messages", + plural_forms: "nplurals=2; plural=n != 1;", + lang: "de", + completeness: 4, +}; diff --git a/packages/bank-ui/src/i18n/uk.po b/packages/bank-ui/src/i18n/uk.po new file mode 100644 index 000000000..a8b41e32f --- /dev/null +++ b/packages/bank-ui/src/i18n/uk.po @@ -0,0 +1,1743 @@ +# This file is part of GNU Taler +# (C) 2022-2024 Taler Systems S.A. +# +# GNU Taler is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 3, or (at your option) any later version. +# +# GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR +# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along with +# GNU Taler; see the file COPYING. If not, see +# +msgid "" +msgstr "" +"Project-Id-Version: Taler Bank\n" +"Report-Msgid-Bugs-To: taler@gnu.org\n" +"PO-Revision-Date: 2024-03-07 07:04+0000\n" +"Last-Translator: Tim Vutor \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " +"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" +"X-Generator: Weblate 5.2.1\n" + +#: src/utils.ts:137 +#, c-format, fuzzy +msgid "Operation failed, please report" +msgstr "Помилка операції, повідомте" + +#: src/utils.ts:156 +#, c-format +msgid "Request timeout" +msgstr "Тайм-аут запиту" + +#: src/utils.ts:165 +#, c-format, fuzzy +msgid "Request throttled" +msgstr "Запит до сервера перервано" + +#: src/utils.ts:174 +#, c-format +msgid "Malformed response" +msgstr "Некоректна відповідь" + +#: src/utils.ts:183 +#, c-format +msgid "Network error" +msgstr "Мережева помилка" + +#: src/utils.ts:192 +#, c-format +msgid "Unexpected request error" +msgstr "Неочікувана помилка запиту" + +#: src/utils.ts:201 +#, c-format +msgid "Unexpected error" +msgstr "Неочікувана помилка" + +#: src/utils.ts:377 +#, c-format, fuzzy +msgid "IBAN numbers usually have more that 4 digits" +msgstr "Номера IBAN зазвичай мають більше 4ьох цифр" + +#: src/utils.ts:379 +#, c-format, fuzzy +msgid "IBAN numbers usually have less that 34 digits" +msgstr "Номера IBAN зазвичай мають менше 34ьох цифр" + +#: src/utils.ts:387 +#, c-format, fuzzy +msgid "IBAN country code not found" +msgstr "Код країни IBAN не знайдено" + +#: src/utils.ts:401 +#, c-format, fuzzy +msgid "IBAN number is not valid, checksum is wrong" +msgstr "Номер IBAN невірний, контрольна сума не сходиться" + +#: src/context/config.ts:136 +#, c-format +msgid "" +"the bank backend is not supported. supported version \"%1$s\", server version " +"\"%2$s\"" +msgstr "" + +#: src/hooks/preferences.ts:55 +#, c-format +msgid "Max withdrawal amount" +msgstr "Максимальна сумма для виведення" + +#: src/hooks/preferences.ts:57 +#, c-format +msgid "Show withdrawal confirmation" +msgstr "Показати підтвердження виводу" + +#: src/hooks/preferences.ts:59 +#, c-format +msgid "Show demo description" +msgstr "Показати демо опис" + +#: src/hooks/preferences.ts:61 +#, c-format +msgid "Show install wallet first" +msgstr "" + +#: src/hooks/preferences.ts:63 +#, c-format +msgid "Use fast withdrawal form" +msgstr "" + +#: src/hooks/preferences.ts:65 +#, c-format +msgid "Show debug info" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:90 +#, c-format +msgid "required" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:92 +#, c-format +msgid "IBAN should have just uppercased letters and numbers" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:98 +#, c-format +msgid "not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:100 +#, c-format +msgid "should be greater than 0" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:102 +#, c-format +msgid "balance is not enough" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:112 +#, c-format +msgid "does not follow the pattern" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:114 +#, c-format +msgid "only \"IBAN\" target are supported" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:116 +#, c-format +msgid "use the \"amount\" parameter to specify the amount to be transferred" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:118 +#, c-format +msgid "the amount is not valid" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:120 +#, c-format +msgid "use the \"message\" parameter to specify a reference text for the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:160 +#, c-format +msgid "The request was invalid or the payto://-URI used unacceptable features." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:167 +#, c-format +msgid "Not enough permission to complete the operation." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:174 +#, c-format +msgid "The destination account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:181 +#, c-format +msgid "The origin and the destination of the transfer can't be the same." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:188 +#, c-format +msgid "Your balance is not enough." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:195 +#, c-format +msgid "The origin account \"%1$s\" was not found." +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:212 +#, c-format +msgid "Wire transfer created!" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:270 +#, c-format +msgid "Using a form" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:310 +#, c-format +msgid "Import payto:// URI" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:335 +#, c-format +msgid "Recipient" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:359 +#, c-format +msgid "IBAN of the recipient's account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:369 +#, c-format +msgid "Transfer subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:377 +#, c-format +msgid "subject" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:390 +#, c-format +msgid "some text to identify the transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:400 +#, c-format +msgid "Amount" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:415 +#, c-format +msgid "amount to transfer" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:425 +#, c-format +msgid "payto URI:" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:436 +#, c-format +msgid "uniform resource identifier of the target account" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:437 +#, c-format +msgid "payto://iban/[receiver-iban]?message=[subject]&amount=[%1$s:X.Y]" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:457 +#, c-format +msgid "Cancel" +msgstr "" + +#: src/pages/PaytoWireTransferForm.tsx:471 +#, c-format +msgid "Send" +msgstr "" + +#: src/pages/LoginForm.tsx:71 +#, c-format +msgid "Missing username" +msgstr "" + +#: src/pages/LoginForm.tsx:75 +#, c-format +msgid "Missing password" +msgstr "" + +#: src/pages/LoginForm.tsx:104 +#, c-format +msgid "Wrong credentials for \"%1$s\"" +msgstr "" + +#: src/pages/LoginForm.tsx:111 +#, c-format +msgid "Account not found" +msgstr "" + +#: src/pages/LoginForm.tsx:142 +#, c-format +msgid "Username" +msgstr "" + +#: src/pages/LoginForm.tsx:156 +#, c-format +msgid "username of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:175 +#, c-format +msgid "Password" +msgstr "" + +#: src/pages/LoginForm.tsx:188 +#, c-format +msgid "password of the account" +msgstr "" + +#: src/pages/LoginForm.tsx:223 +#, c-format +msgid "Check" +msgstr "" + +#: src/pages/LoginForm.tsx:237 +#, c-format +msgid "Log in" +msgstr "" + +#: src/pages/LoginForm.tsx:249 +#, c-format +msgid "Register" +msgstr "" + +#: src/components/Transactions/views.tsx:52 +#, c-format +msgid "Latest transactions" +msgstr "" + +#: src/components/Transactions/views.tsx:63 +#, c-format +msgid "Date" +msgstr "" + +#: src/components/Transactions/views.tsx:71 +#, c-format +msgid "Counterpart" +msgstr "" + +#: src/components/Transactions/views.tsx:75 +#, c-format +msgid "Subject" +msgstr "" + +#: src/components/Transactions/views.tsx:111 +#, c-format +msgid "sent" +msgstr "" + +#: src/components/Transactions/views.tsx:112 +#, c-format +msgid "received" +msgstr "" + +#: src/components/Transactions/views.tsx:127 +#, c-format +msgid "invalid value" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "to" +msgstr "" + +#: src/components/Transactions/views.tsx:136 +#, c-format +msgid "from" +msgstr "" + +#: src/components/Transactions/views.tsx:202 +#, c-format +msgid "First page" +msgstr "" + +#: src/components/Transactions/views.tsx:209 +#, c-format +msgid "Next" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:86 +#, c-format +msgid "Wire transfer completed!" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:93 +#, c-format +msgid "The withdrawal has been aborted previously and can't be confirmed" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:100 +#, c-format +msgid "" +"The withdrawal operation can't be confirmed before a wallet accepted the " +"transaction." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:107 +#, c-format +msgid "The operation id is invalid." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:114 +#, c-format +msgid "The operation was not found." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:121 +#, c-format +msgid "Your balance is not enough for the operation." +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:155 +#, c-format +msgid "The reserve operation has been confirmed previously and can't be aborted" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:186 +#, c-format +msgid "Confirm the withdrawal operation" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:203 +#, c-format +msgid "Wire transfer details" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:217 +#, c-format +msgid "Taler Exchange operator's account" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:228 +#, c-format +msgid "Taler Exchange operator's name" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:317 +#, c-format +msgid "Transfer" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:342 +#, c-format +msgid "Authentication required" +msgstr "" + +#: src/pages/WithdrawalConfirmationQuestion.tsx:352 +#, c-format +msgid "This operation was created with other username" +msgstr "" + +#: src/pages/OperationState/views.tsx:209 +#, c-format +msgid "" +"Unauthorized to make the operation, maybe the session has expired or the " +"password changed." +msgstr "" + +#: src/pages/OperationState/views.tsx:218 +#, c-format +msgid "The operation was rejected due to insufficient funds." +msgstr "" + +#: src/pages/OperationState/views.tsx:268 +#, c-format +msgid "Withdrawal confirmed" +msgstr "" + +#: src/pages/OperationState/views.tsx:272 +#, c-format +msgid "" +"The wire transfer to the Taler operator has been initiated. You will soon " +"receive the requested amount in your Taler wallet." +msgstr "" + +#: src/pages/OperationState/views.tsx:287 +#, c-format +msgid "Do not show this again" +msgstr "" + +#: src/pages/OperationState/views.tsx:319 +#, c-format +msgid "Close" +msgstr "" + +#: src/pages/OperationState/views.tsx:399 +#, c-format +msgid "On this device" +msgstr "" + +#: src/pages/OperationState/views.tsx:404 +#, c-format +msgid "" +"If you are using a web browser on desktop you should access your wallet with the " +"GNU Taler WebExtension now or click the link if your WebExtension have the " +"\"Inject Taler support\" option enabled." +msgstr "" + +#: src/pages/OperationState/views.tsx:417 +#, c-format +msgid "Start" +msgstr "" + +#: src/pages/OperationState/views.tsx:426 +#, c-format +msgid "On a mobile phone" +msgstr "" + +#: src/pages/OperationState/views.tsx:431 +#, c-format +msgid "Scan the QR code with your mobile device." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:73 +#, c-format +msgid "There is an operation already" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:75 +#, c-format +msgid "Complete or cancel the operation in" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:84 +#, c-format +msgid "this page" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:101 +#, c-format +msgid "invalid" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:116 +#, c-format +msgid "Server responded with an invalid withdraw URI" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:117 +#, c-format +msgid "Withdraw URI: %1$s" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:132 +#, c-format +msgid "The operation was rejected due to insufficient funds" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:253 +#, c-format +msgid "Continue" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:282 +#, c-format +msgid "Prepare your wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:285 +#, c-format +msgid "" +"After using your wallet you will need to confirm or cancel the operation on this " +"site." +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:295 +#, c-format +msgid "You need a GNU Taler Wallet" +msgstr "" + +#: src/pages/WalletWithdrawForm.tsx:300 +#, c-format +msgid "If you don't have one yet you can follow the instruction in" +msgstr "" + +#: src/pages/PaymentOptions.tsx:55 +#, c-format +msgid "Send money" +msgstr "" + +#: src/pages/PaymentOptions.tsx:73 +#, c-format +msgid "to a %1$s wallet" +msgstr "" + +#: src/pages/PaymentOptions.tsx:95 +#, c-format +msgid "Withdraw digital money into your mobile wallet or browser extension" +msgstr "" + +#: src/pages/PaymentOptions.tsx:109 +#, c-format +msgid "operation ready" +msgstr "" + +#: src/pages/PaymentOptions.tsx:129 +#, c-format +msgid "to another bank account" +msgstr "" + +#: src/pages/PaymentOptions.tsx:149 +#, c-format +msgid "Make a wire transfer to an account with known bank account number." +msgstr "" + +#: src/pages/PaymentOptions.tsx:171 +#, c-format +msgid "Transfer details" +msgstr "" + +#: src/pages/AccountPage/views.tsx:41 +#, c-format +msgid "This is a demo bank" +msgstr "" + +#: src/pages/AccountPage/views.tsx:46 +#, c-format +msgid "" +"This part of the demo shows how a bank that supports Taler directly would work. " +"In addition to using your own bank account, you can also see the transaction " +"history of some %1$s." +msgstr "" + +#: src/pages/AccountPage/views.tsx:53 +#, c-format +msgid "This part of the demo shows how a bank that supports Taler directly would work." +msgstr "" + +#: src/pages/AccountPage/views.tsx:70 +#, c-format +msgid "Pending account delete operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:72 +#, c-format +msgid "Pending account update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:74 +#, c-format +msgid "Pending password update operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:76 +#, c-format +msgid "Pending transaction operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:78 +#, c-format +msgid "Pending withdrawal operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:80 +#, c-format +msgid "Pending cashout operation" +msgstr "" + +#: src/pages/AccountPage/views.tsx:91 +#, c-format +msgid "You can complete or cancel the operation in" +msgstr "" + +#: src/pages/BankFrame.tsx:64 +#, c-format +msgid "Internal error, please report." +msgstr "" + +#: src/pages/BankFrame.tsx:100 +#, c-format +msgid "Preferences" +msgstr "" + +#: src/pages/BankFrame.tsx:184 +#, c-format +msgid "Welcome, %1$s" +msgstr "" + +#: src/pages/WireTransfer.tsx:79 +#, c-format +msgid "Make a wire transfer" +msgstr "" + +#: src/pages/admin/AccountList.tsx:72 +#, c-format +msgid "Accounts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:75 +#, c-format +msgid "A list of all business account in the bank." +msgstr "" + +#: src/pages/admin/AccountList.tsx:86 +#, c-format +msgid "Create account" +msgstr "" + +#: src/pages/admin/AccountList.tsx:106 +#, c-format +msgid "Name" +msgstr "" + +#: src/pages/admin/AccountList.tsx:110 +#, c-format +msgid "Balance" +msgstr "" + +#: src/pages/admin/AccountList.tsx:112 +#, c-format +msgid "Actions" +msgstr "" + +#: src/pages/admin/AccountList.tsx:151 +#, c-format +msgid "unknown" +msgstr "" + +#: src/pages/admin/AccountList.tsx:170 +#, c-format +msgid "change password" +msgstr "" + +#: src/pages/admin/AccountList.tsx:179 +#, c-format +msgid "cashouts" +msgstr "" + +#: src/pages/admin/AccountList.tsx:189 +#, c-format +msgid "remove" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:168 +#, c-format +msgid "Cashout not implemented" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:184 +#, c-format +msgid "Select a section" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:202 +#, c-format +msgid "Last hour" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:208 +#, c-format +msgid "Last day" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:216 +#, c-format +msgid "Last month" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:222 +#, c-format +msgid "Last year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:310 +#, c-format +msgid "Last Year" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:325 +#, c-format +msgid "Trading volume on %1$s compared to %2$s" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:342 +#, c-format +msgid "Cashin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:352 +#, c-format +msgid "Cashout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:364 +#, c-format +msgid "Payin" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:374 +#, c-format +msgid "Payout" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:388 +#, c-format +msgid "download stats as CSV" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:494 +#, c-format +msgid "Decreased by" +msgstr "" + +#: src/pages/admin/AdminHome.tsx:498 +#, c-format +msgid "Increased by" +msgstr "" + +#: src/pages/DownloadStats.tsx:89 +#, c-format +msgid "Download bank stats" +msgstr "" + +#: src/pages/DownloadStats.tsx:110 +#, c-format +msgid "Include hour metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:143 +#, c-format +msgid "Include day metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:173 +#, c-format +msgid "Include month metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:206 +#, c-format +msgid "Include year metric" +msgstr "" + +#: src/pages/DownloadStats.tsx:239 +#, c-format +msgid "Include table header" +msgstr "" + +#: src/pages/DownloadStats.tsx:272 +#, c-format +msgid "Add previous metric for compare" +msgstr "" + +#: src/pages/DownloadStats.tsx:307 +#, c-format +msgid "Fail on first error" +msgstr "" + +#: src/pages/DownloadStats.tsx:364 +#, c-format +msgid "Download" +msgstr "" + +#: src/pages/DownloadStats.tsx:381 +#, c-format +msgid "downloading... %1$s" +msgstr "" + +#: src/pages/DownloadStats.tsx:399 +#, c-format +msgid "Download completed" +msgstr "" + +#: src/pages/DownloadStats.tsx:400 +#, c-format +msgid "click here to save the file in your computer" +msgstr "" + +#: src/pages/PublicHistoriesPage.tsx:78 +#, c-format +msgid "History of public accounts" +msgstr "" + +#: src/pages/RegistrationPage.tsx:48 +#, c-format +msgid "Currently, the bank is not accepting new registrations!" +msgstr "" + +#: src/pages/RegistrationPage.tsx:87 +#, c-format +msgid "Missing name" +msgstr "" + +#: src/pages/RegistrationPage.tsx:91 +#, c-format +msgid "Use letters and numbers only, and start with a lowercase letter" +msgstr "" + +#: src/pages/RegistrationPage.tsx:107 +#, c-format +msgid "Passwords don't match" +msgstr "" + +#: src/pages/RegistrationPage.tsx:130 +#, c-format +msgid "Server replied with invalid phone or email." +msgstr "" + +#: src/pages/RegistrationPage.tsx:137 +#, c-format +msgid "Registration is disabled because the bank ran out of bonus credit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:144 +#, c-format +msgid "No enough permission to create that account." +msgstr "" + +#: src/pages/RegistrationPage.tsx:151 +#, c-format +msgid "That account id is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:158 +#, c-format +msgid "That username is already taken." +msgstr "" + +#: src/pages/RegistrationPage.tsx:165 +#, c-format +msgid "That username can't be used because is reserved." +msgstr "" + +#: src/pages/RegistrationPage.tsx:172 +#, c-format +msgid "Only admin is allow to set debt limit." +msgstr "" + +#: src/pages/RegistrationPage.tsx:179 +#, c-format +msgid "No information for the selected authentication channel." +msgstr "" + +#: src/pages/RegistrationPage.tsx:186 +#, c-format +msgid "Authentication channel is not supported." +msgstr "" + +#: src/pages/RegistrationPage.tsx:193 +#, c-format +msgid "Only admin can create accounts with second factor authentication." +msgstr "" + +#: src/pages/RegistrationPage.tsx:233 +#, c-format +msgid "Account registration" +msgstr "" + +#: src/pages/RegistrationPage.tsx:315 +#, c-format +msgid "Repeat password" +msgstr "" + +#: src/pages/RegistrationPage.tsx:457 +#, c-format +msgid "Create a random temporary user" +msgstr "" + +#: src/pages/QrCodeSection.tsx:110 +#, c-format +msgid "If you have a Taler wallet installed in this device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:116 +#, c-format +msgid "" +"You will see the details of the operation in your wallet including the fees (if " +"applies). If you still don't have one you can install it following instructions " +"in" +msgstr "" + +#: src/pages/QrCodeSection.tsx:143 +#, c-format +msgid "Withdraw" +msgstr "" + +#: src/pages/QrCodeSection.tsx:152 +#, c-format +msgid "Or if you have the wallet in another device" +msgstr "" + +#: src/pages/QrCodeSection.tsx:157 +#, c-format +msgid "Scan the QR below to start the withdrawal." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:79 +#, c-format +msgid "Operation aborted" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:82 +#, c-format +msgid "" +"The wire transfer to the Taler Exchange operator's account was aborted, your " +"balance was not affected." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:88 +#, c-format +msgid "You can close this page now or continue to the account page." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:147 +#, c-format +msgid "Done" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:158 +#, c-format +msgid "Operation canceled" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:173 +#, c-format +msgid "The operation is marked as 'selected' but some step in the withdrawal failed" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:175 +#, c-format +msgid "The account is selected but no withdrawal identification found." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:188 +#, c-format +msgid "" +"There is a withdrawal identification but no account has been selected or the " +"selected account is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:202 +#, c-format +msgid "" +"No withdrawal ID found and no account has been selected or the selected account " +"is invalid." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:259 +#, c-format +msgid "Operation not found" +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:263 +#, c-format +msgid "" +"This operation is not known by the server. The operation id is wrong or the " +"server deleted the operation information before reaching here." +msgstr "" + +#: src/pages/WithdrawalQRCode.tsx:278 +#, c-format +msgid "Cotinue to dashboard" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:98 +#, c-format +msgid "Cashout not found. It may be also mean that it was already aborted." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:136 +#, c-format +msgid "Challenge not found." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:143 +#, c-format +msgid "This user is not authorized to complete this challenge." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:150 +#, c-format +msgid "Too many attempts, try another code." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:157 +#, c-format +msgid "The confirmation code is wrong, try again." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:164 +#, c-format +msgid "The operation expired." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:197 +#, c-format +msgid "The operation failed." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:212 +#, c-format +msgid "The operation needs another confirmation to complete." +msgstr "" + +#: src/pages/SolveChallengePage.tsx:224 +#, c-format +msgid "Account delete" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:226 +#, c-format +msgid "Account update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:228 +#, c-format +msgid "Password update" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:230 +#, c-format +msgid "Wire transfer" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:232 +#, c-format +msgid "Withdrawal" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:248 +#, c-format +msgid "Confirm the operation" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:271 +#, c-format +msgid "Enter the confirmation code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:313 +#, c-format +msgid "Confirm" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:348 +#, c-format +msgid "Send again" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:359 +#, c-format +msgid "Send code" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:369 +#, c-format +msgid "Operation details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:529 +#, c-format +msgid "Challenge details" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:536 +#, c-format +msgid "Sent at" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:551 +#, c-format +msgid "To phone" +msgstr "" + +#: src/pages/SolveChallengePage.tsx:553 +#, c-format +msgid "To email" +msgstr "" + +#: src/pages/WithdrawalOperationPage.tsx:49 +#, c-format +msgid "The Withdrawal URI is not valid" +msgstr "" + +#: src/components/Cashouts/views.tsx:100 +#, c-format +msgid "Latest cashouts" +msgstr "" + +#: src/components/Cashouts/views.tsx:111 +#, c-format +msgid "Created" +msgstr "" + +#: src/components/Cashouts/views.tsx:115 +#, c-format +msgid "Total debit" +msgstr "" + +#: src/components/Cashouts/views.tsx:119 +#, c-format +msgid "Total credit" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:70 +#, c-format +msgid "Details" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:74 +#, c-format +msgid "Delete" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:78 +#, c-format +msgid "Credentials" +msgstr "" + +#: src/pages/ProfileNavigation.tsx:82 +#, c-format +msgid "Cashouts" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:95 +#, c-format +msgid "Unable to create a cashout" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:96 +#, c-format +msgid "The bank configuration does not support cashout operations." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:223 +#, c-format +msgid "need to be higher due to fees" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:225 +#, c-format +msgid "the total transfer at destination will be zero" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:250 +#, c-format +msgid "Cashout created" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:272 +#, c-format +msgid "Duplicated request detected, check if the operation succeeded or try again." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:279 +#, c-format +msgid "The conversion rate was incorrectly applied" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:286 +#, c-format +msgid "The account does not have sufficient funds" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:293 +#, c-format +msgid "Cashouts are not supported" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:300 +#, c-format +msgid "Missing cashout URI in the profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:307 +#, c-format +msgid "" +"Sending the confirmation message failed, retry later or contact the " +"administrator." +msgstr "" + +#: src/pages/business/CreateCashout.tsx:339 +#, c-format +msgid "Conversion rate" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:360 +#, c-format +msgid "Fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:374 +#, c-format +msgid "To account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:381 +#, c-format +msgid "No cashout account" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:382 +#, c-format +msgid "Before doing a cashout you need to complete your profile" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:440 +#, c-format +msgid "Amount to send" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:441 +#, c-format +msgid "Amount to receive" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:490 +#, c-format +msgid "Total cost" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:505 +#, c-format +msgid "Balance left" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:520 +#, c-format +msgid "Before fee" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:533 +#, c-format +msgid "Total cashout transfer" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:553 +#, c-format +msgid "No cashout channel available" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:555 +#, c-format +msgid "" +"Before doing a cashout the server need to provide an second channel to confirm " +"the operation" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:567 +#, c-format +msgid "Second factor authentication" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:598 +#, c-format +msgid "Email" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:600 +#, c-format +msgid "add a email in your profile to enable this option" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:646 +#, c-format +msgid "SMS" +msgstr "" + +#: src/pages/business/CreateCashout.tsx:648 +#, c-format +msgid "add a phone number in your profile to enable this option" +msgstr "" + +#: src/pages/account/CashoutListForAccount.tsx:52 +#, c-format +msgid "Cashout for account %1$s" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:165 +#, c-format +msgid "it doesn't have the pattern of an IBAN number" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:185 +#, c-format +msgid "it doesn't have the pattern of an email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:190 +#, c-format +msgid "should start with +" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:192 +#, c-format +msgid "phone number can't have other than numbers" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:329 +#, c-format +msgid "account identification in the bank" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:365 +#, c-format +msgid "name of the person owner the account" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:374 +#, c-format +msgid "Internal IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:377 +#, c-format +msgid "if empty a random account number will be assigned" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:378 +#, c-format +msgid "account identification for bank transfer" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:423 +#, c-format +msgid "Phone" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:451 +#, c-format +msgid "Cashout IBAN" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:452 +#, c-format +msgid "account number where the money is going to be sent when doing cashouts" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:470 +#, c-format +msgid "Max debt" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:494 +#, c-format +msgid "how much is user able to transfer after zero balance" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:508 +#, c-format +msgid "Is this a Taler Exchange?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:549 +#, c-format +msgid "This server doesn't support second factor authentication." +msgstr "" + +#: src/pages/admin/AccountForm.tsx:560 +#, c-format +msgid "Enable second factor authentication" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:596 +#, c-format +msgid "Using email" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:654 +#, c-format +msgid "Using SMS" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:691 +#, c-format +msgid "Is this account public?" +msgstr "" + +#: src/pages/admin/AccountForm.tsx:719 +#, c-format +msgid "public accounts have their balance publicly accessible" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:100 +#, c-format +msgid "Account updated" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:107 +#, c-format +msgid "The rights to change the account are not sufficient" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:114 +#, c-format +msgid "The username was not found" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:121 +#, c-format +msgid "You can't change the legal name, please contact the your account administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:128 +#, c-format +msgid "You can't change the debt limit, please contact the your account administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:135 +#, c-format +msgid "" +"You can't change the cashout address, please contact the your account " +"administrator." +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:177 +#, c-format +msgid "Account \"%1$s\"" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:190 +#, c-format +msgid "Change details" +msgstr "" + +#: src/pages/account/ShowAccountDetails.tsx:235 +#, c-format +msgid "Update" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:78 +#, c-format +msgid "password doesn't match" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:95 +#, c-format +msgid "Password changed" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:102 +#, c-format +msgid "Not authorized to change the password, maybe the session is invalid." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:112 +#, c-format +msgid "" +"You need to provide the old password. If you don't have it contact your account " +"administrator." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:117 +#, c-format +msgid "Your current password doesn't match, can't change to a new password." +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:149 +#, c-format +msgid "Update password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:167 +#, c-format +msgid "New password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:195 +#, c-format +msgid "Type it again" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:217 +#, c-format +msgid "repeat the same password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:227 +#, c-format +msgid "Current password" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:248 +#, c-format +msgid "your current password, for security" +msgstr "" + +#: src/pages/account/UpdateAccountPassword.tsx:272 +#, c-format +msgid "Change" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:74 +#, c-format +msgid "" +"Account created with password \"%1$s\". The user must change the password on the " +"next login." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:83 +#, c-format +msgid "Server replied that phone or email is invalid" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:90 +#, c-format +msgid "The rights to perform the operation are not sufficient" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:97 +#, c-format +msgid "Account username is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:104 +#, c-format +msgid "Account id is already taken" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:111 +#, c-format +msgid "Bank ran out of bonus credit." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:118 +#, c-format +msgid "Account username can't be used because is reserved" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:160 +#, c-format +msgid "Can't create accounts" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:161 +#, c-format +msgid "Only system admin can create accounts." +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:183 +#, c-format +msgid "New business account" +msgstr "" + +#: src/pages/admin/CreateNewAccount.tsx:209 +#, c-format +msgid "Create" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:94 +#, c-format +msgid "Can't delete the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:95 +#, c-format +msgid "" +"The account can't be delete while still holding some balance. First make sure " +"that the owner make a complete cashout." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:117 +#, c-format +msgid "Account removed" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:124 +#, c-format +msgid "No enough permission to delete the account." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:131 +#, c-format +msgid "The username was not found." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:138 +#, c-format +msgid "Can't delete a reserved username." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:145 +#, c-format +msgid "Can't delete an account with balance different than zero." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:170 +#, c-format +msgid "name doesn't match" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:180 +#, c-format +msgid "You are going to remove the account" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:182 +#, c-format +msgid "This step can't be undone." +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:188 +#, c-format +msgid "Deleting account \"%1$s\"" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:206 +#, c-format +msgid "Verification" +msgstr "" + +#: src/pages/admin/RemoveAccount.tsx:231 +#, c-format +msgid "enter the account name that is going to be deleted" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:49 +#, c-format +msgid "cashout id should be a number" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:65 +#, c-format +msgid "This cashout not found. Maybe already aborted." +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:106 +#, c-format +msgid "Cashout detail" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:139 +#, c-format +msgid "Debited" +msgstr "" + +#: src/pages/business/ShowCashoutDetails.tsx:154 +#, c-format +msgid "Credited" +msgstr "" + +#: src/Routing.tsx:140 +#, c-format +msgid "Welcome to %1$s!" +msgstr "" diff --git a/packages/bank-ui/src/index.html b/packages/bank-ui/src/index.html new file mode 100644 index 000000000..0789ecf89 --- /dev/null +++ b/packages/bank-ui/src/index.html @@ -0,0 +1,41 @@ + + + + + + + + + + + + + Bank + + + + + + +
+ + diff --git a/packages/bank-ui/src/index.tsx b/packages/bank-ui/src/index.tsx new file mode 100644 index 000000000..f559288a3 --- /dev/null +++ b/packages/bank-ui/src/index.tsx @@ -0,0 +1,27 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { App } from "./app.js"; +import { h, render } from "preact"; +import "./scss/main.css"; + +const app = document.getElementById("app"); + +if (app) { + render(, app); +} else { + console.error("HTML element with id 'app' not found."); +} diff --git a/packages/bank-ui/src/manifest.json b/packages/bank-ui/src/manifest.json new file mode 100644 index 000000000..8790b10c9 --- /dev/null +++ b/packages/bank-ui/src/manifest.json @@ -0,0 +1,21 @@ +{ + "name": "taler-bank", + "short_name": "taler-bank", + "start_url": "/", + "display": "standalone", + "orientation": "portrait", + "background_color": "#fff", + "theme_color": "#673ab8", + "icons": [ + { + "src": "/assets/icons/android-chrome-192x192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "/assets/icons/android-chrome-512x512.png", + "type": "image/png", + "sizes": "512x512" + } + ] +} diff --git a/packages/bank-ui/src/pages/AccountPage/index.ts b/packages/bank-ui/src/pages/AccountPage/index.ts new file mode 100644 index 000000000..0223b12db --- /dev/null +++ b/packages/bank-ui/src/pages/AccountPage/index.ts @@ -0,0 +1,134 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AbsoluteTime, + AmountJson, + TalerCorebankApi, + TalerError, +} from "@gnu-taler/taler-util"; +import { Loading, utils } from "@gnu-taler/web-util/browser"; +import { ErrorLoadingWithDebug } from "../../components/ErrorLoadingWithDebug.js"; +import { LoginForm } from "../LoginForm.js"; +import { useComponentState } from "./state.js"; +import { InvalidIbanView, ReadyView } from "./views.js"; +import { RouteDefinition } from "../../route.js"; + +export interface Props { + account: string; + onAuthorizationRequired: () => void; + onOperationCreated: (wopid: string) => void; + onClose: () => void; + tab: "charge-wallet" | "wire-transfer" | undefined; + routeClose: RouteDefinition; + routeCashout: RouteDefinition; + routeChargeWallet: RouteDefinition; + routeWireTransfer: RouteDefinition<{ + account?: string; + subject?: string; + amount?: string; + }>; + routePublicAccounts: RouteDefinition; + routeCreateWireTransfer: RouteDefinition<{ + account?: string; + subject?: string; + amount?: string; + }>; + routeOperationDetails: RouteDefinition<{ wopid: string }>; + routeSolveSecondFactor: RouteDefinition; +} + +export type State = + | State.Loading + | State.LoadingError + | State.Ready + | State.InvalidIban + | State.UserNotFound; + +export namespace State { + export interface Loading { + status: "loading"; + error: undefined; + } + + export interface LoadingError { + status: "loading-error"; + error: TalerError; + } + + export interface BaseInfo { + error: undefined; + } + + export interface Ready extends BaseInfo { + status: "ready"; + error: undefined; + account: string; + tab: "charge-wallet" | "wire-transfer" | undefined; + limit: AmountJson; + onAuthorizationRequired: () => void; + onOperationCreated: (wopid: string) => void; + onClose: () => void; + routeClose: RouteDefinition; + routeCashout: RouteDefinition; + routeChargeWallet: RouteDefinition; + routePublicAccounts: RouteDefinition; + routeWireTransfer: RouteDefinition<{ + account?: string, + subject?: string, + amount?: string, + }>; + routeCreateWireTransfer: RouteDefinition<{ + account?: string, + subject?: string, + amount?: string, + }>; + routeOperationDetails: RouteDefinition<{ wopid: string }>; + routeSolveSecondFactor: RouteDefinition; + } + + export interface InvalidIban { + status: "invalid-iban"; + error: TalerCorebankApi.AccountData; + } + + export interface UserNotFound { + status: "login"; + reason: "not-found" | "forbidden"; + routeRegister?: RouteDefinition; + } +} + +export interface Transaction { + negative: boolean; + counterpart: string; + when: AbsoluteTime; + amount: AmountJson | undefined; + subject: string; +} + +const viewMapping: utils.StateViewMap = { + loading: Loading, + login: LoginForm, + "invalid-iban": InvalidIbanView, + "loading-error": ErrorLoadingWithDebug, + ready: ReadyView, +}; + +export const AccountPage = utils.compose( + (p: Props) => useComponentState(p), + viewMapping, +); diff --git a/packages/bank-ui/src/pages/AccountPage/state.ts b/packages/bank-ui/src/pages/AccountPage/state.ts new file mode 100644 index 000000000..e84fef025 --- /dev/null +++ b/packages/bank-ui/src/pages/AccountPage/state.ts @@ -0,0 +1,117 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + Amounts, + HttpStatusCode, + TalerError, + assertUnreachable, + parsePaytoUri, +} from "@gnu-taler/taler-util"; +import { useAccountDetails } from "../../hooks/account.js"; +import { Props, State } from "./index.js"; + +export function useComponentState({ + account, + tab, + routeChargeWallet, + routeCreateWireTransfer, + routePublicAccounts, + routeSolveSecondFactor, + routeOperationDetails, + routeWireTransfer, + routeCashout, + onOperationCreated, + onClose, + routeClose, + onAuthorizationRequired, +}: Props): State { + const result = useAccountDetails(account); + + if (!result) { + return { + status: "loading", + error: undefined, + }; + } + + if (result instanceof TalerError) { + return { + status: "loading-error", + error: result, + }; + } + + if (result.type === "fail") { + switch (result.case) { + case HttpStatusCode.Unauthorized: + return { + status: "login", + reason: "forbidden", + }; + case HttpStatusCode.NotFound: + return { + status: "login", + reason: "not-found", + }; + default: { + assertUnreachable(result); + } + } + } + + const { body: data } = result; + + const balance = Amounts.parseOrThrow(data.balance.amount); + + const debitThreshold = Amounts.parseOrThrow(data.debit_threshold); + const payto = parsePaytoUri(data.payto_uri); + + if ( + !payto || + !payto.isKnown || + (payto.targetType !== "iban" && payto.targetType !== "x-taler-bank") + ) { + return { + status: "invalid-iban", + error: data, + }; + } + + const balanceIsDebit = data.balance.credit_debit_indicator == "debit"; + const limit = balanceIsDebit + ? Amounts.sub(debitThreshold, balance).amount + : Amounts.add(balance, debitThreshold).amount; + + return { + status: "ready", + onOperationCreated, + error: undefined, + tab, + routeCashout, + routeOperationDetails, + routeCreateWireTransfer, + routePublicAccounts, + routeSolveSecondFactor, + onAuthorizationRequired, + onClose, + routeClose, + routeChargeWallet, + routeWireTransfer, + account, + limit, + }; +} diff --git a/packages/bank-ui/src/pages/AccountPage/stories.tsx b/packages/bank-ui/src/pages/AccountPage/stories.tsx new file mode 100644 index 000000000..fe09a4f89 --- /dev/null +++ b/packages/bank-ui/src/pages/AccountPage/stories.tsx @@ -0,0 +1,29 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { ReadyView } from "./views.js"; + +export default { + title: "account page", +}; + +export const Ready = tests.createExample(ReadyView, {}); diff --git a/packages/bank-ui/src/pages/AccountPage/test.ts b/packages/bank-ui/src/pages/AccountPage/test.ts new file mode 100644 index 000000000..14c8be948 --- /dev/null +++ b/packages/bank-ui/src/pages/AccountPage/test.ts @@ -0,0 +1,31 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +// import * as tests from "@gnu-taler/web-util/testing"; +// import { SwrMockEnvironment } from "@gnu-taler/web-util/testing"; +// import { expect } from "chai"; +// import { CASHOUT_API_EXAMPLE } from "../../endpoints.js"; +// import { Props } from "./index.js"; +// import { useComponentState } from "./state.js"; + +describe("Account states", () => { + it("should do some tests", async () => {}); +}); diff --git a/packages/bank-ui/src/pages/AccountPage/views.tsx b/packages/bank-ui/src/pages/AccountPage/views.tsx new file mode 100644 index 000000000..7165c28b6 --- /dev/null +++ b/packages/bank-ui/src/pages/AccountPage/views.tsx @@ -0,0 +1,144 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { TranslatedString } from "@gnu-taler/taler-util"; +import { Attention, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { Fragment, VNode, h } from "preact"; +import { Transactions } from "../../components/Transactions/index.js"; +import { useBankState } from "../../hooks/bank-state.js"; +import { usePreferences } from "../../hooks/preferences.js"; +import { PaymentOptions } from "../PaymentOptions.js"; +import { State } from "./index.js"; +import { RouteDefinition } from "../../route.js"; + +export function InvalidIbanView({ error }: State.InvalidIban) { + return ( +
Payto from server is not valid "{error.payto_uri}"
+ ); +} + +const IS_PUBLIC_ACCOUNT_ENABLED = false; + +function ShowDemoInfo({ routePublicAccounts }: { + routePublicAccounts: RouteDefinition; +}): VNode { + const { i18n } = useTranslationContext(); + const [settings, updateSettings] = usePreferences(); + if (!settings.showDemoDescription) return ; + return ( + { + updateSettings("showDemoDescription", false); + }} + > + {IS_PUBLIC_ACCOUNT_ENABLED ? ( + + This part of the demo shows how a bank that supports Taler directly + would work. In addition to using your own bank account, you can also + see the transaction history of some{" "} + Public Accounts. + + ) : ( + + This part of the demo shows how a bank that supports Taler directly + would work. + + )} + + ); +} + +function ShowPedingOperation({ routeSolveSecondFactor }: { + routeSolveSecondFactor: RouteDefinition; +}): VNode { + const { i18n } = useTranslationContext(); + const [bankState, updateBankState] = useBankState(); + if (!bankState.currentChallenge) return ; + const title = ((op): TranslatedString => { + switch (op) { + case "delete-account": + return i18n.str`Pending account delete operation`; + case "update-account": + return i18n.str`Pending account update operation`; + case "update-password": + return i18n.str`Pending password update operation`; + case "create-transaction": + return i18n.str`Pending transaction operation`; + case "confirm-withdrawal": + return i18n.str`Pending withdrawal operation`; + case "create-cashout": + return i18n.str`Pending cashout operation`; + } + })(bankState.currentChallenge.operation); + return ( + { + updateBankState("currentChallenge", undefined); + }} + > + + You can complete or cancel the operation in + {" "} + + this page + + + ); +} + +export function ReadyView({ + tab, + account, + routeChargeWallet, + routeWireTransfer, + limit, + routeCashout, + routeCreateWireTransfer, + routePublicAccounts, + routeOperationDetails, + routeSolveSecondFactor, + onClose, + routeClose, + onOperationCreated, + onAuthorizationRequired, +}: State.Ready): VNode { + return ( + + + + + + + ); +} diff --git a/packages/bank-ui/src/pages/BankFrame.stories.tsx b/packages/bank-ui/src/pages/BankFrame.stories.tsx new file mode 100644 index 000000000..c874ac4ca --- /dev/null +++ b/packages/bank-ui/src/pages/BankFrame.stories.tsx @@ -0,0 +1,29 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { BankFrame } from "./BankFrame.js"; + +export default { + title: "bank frame", +}; + +export const Ready = tests.createExample(BankFrame, {}); diff --git a/packages/bank-ui/src/pages/BankFrame.tsx b/packages/bank-ui/src/pages/BankFrame.tsx new file mode 100644 index 000000000..427e9a156 --- /dev/null +++ b/packages/bank-ui/src/pages/BankFrame.tsx @@ -0,0 +1,237 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { Amounts, TalerError, TranslatedString } from "@gnu-taler/taler-util"; +import { + Footer, + Header, + Loading, + ToastBanner, + notifyError, + notifyException, + useTranslationContext +} from "@gnu-taler/web-util/browser"; +import { ComponentChildren, VNode, h } from "preact"; +import { useEffect, useErrorBoundary } from "preact/hooks"; +import { useBankCoreApiContext } from "../context/config.js"; +import { useSettingsContext } from "../context/settings.js"; +import { useAccountDetails } from "../hooks/account.js"; +import { useSessionState } from "../hooks/session.js"; +import { useBankState } from "../hooks/bank-state.js"; +import { + getAllBooleanPreferences, + getLabelForPreferences, + usePreferences, +} from "../hooks/preferences.js"; +import { RouteDefinition } from "../route.js"; +import { RenderAmount } from "./PaytoWireTransferForm.js"; + +const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined; +const VERSION = typeof __VERSION__ !== "undefined" ? __VERSION__ : undefined; + +export function BankFrame({ + children, + account, + routeAccountDetails, +}: { + account?: string; + routeAccountDetails?: RouteDefinition; + children: ComponentChildren; +}): VNode { + const { i18n } = useTranslationContext(); + const session = useSessionState(); + const settings = useSettingsContext(); + const [preferences, updatePreferences] = usePreferences(); + const [, , resetBankState] = useBankState(); + + const [error, resetError] = useErrorBoundary(); + + useEffect(() => { + if (error) { + if (error instanceof Error) { + console.log("Internal error, please report", error); + notifyException(i18n.str`Internal error, please report.`, error); + } else { + console.log("Internal error, please report", error); + notifyError( + i18n.str`Internal error, please report.`, + String(error) as TranslatedString, + ); + } + resetError(); + } + }, [error]); + + return ( +
+
+
{ + session.logOut(); + resetBankState(); + } + } + sites={ + !settings.topNavSites ? [] : Object.entries(settings.topNavSites) + } + supportedLangs={["en", "es", "de"]} + > +
  • +
    + Preferences +
    +
      + {getAllBooleanPreferences().map((set) => { + const isOn: boolean = !!preferences[set]; + return ( +
    • +
      + + + {getLabelForPreferences(set, i18n)} + + + +
      +
    • + ); + })} +
    +
  • +
    +
    + +
    +
    + +
    +
    + +
    + {account && routeAccountDetails && ( +
    +
    +

    + + + + + + +

    +
    +
    + )} + +
    +
    + {children} +
    +
    +
    + +
    +
    + ); +} + +function WelcomeAccount({ account, routeAccountDetails }: { + account: string, + routeAccountDetails: RouteDefinition; +}): VNode { + const { i18n } = useTranslationContext(); + const result = useAccountDetails(account); + if (!result) { + return ; + } + if (result instanceof TalerError) { + return
    ; + } + if (result.type === "fail") { + return ( + + Welcome + + ); + } + return ( + + + Welcome, {result.body.name} + + + ); +} + +function AccountBalance({ account }: { account: string }): VNode { + const result = useAccountDetails(account); + const { config } = useBankCoreApiContext(); + if (!result) { + return ; + } + if (result instanceof TalerError) { + return
    ; + } + if (result.type === "fail") return
    ; + + return ( + + ); +} diff --git a/packages/bank-ui/src/pages/LoginForm.tsx b/packages/bank-ui/src/pages/LoginForm.tsx new file mode 100644 index 000000000..bd20e79c8 --- /dev/null +++ b/packages/bank-ui/src/pages/LoginForm.tsx @@ -0,0 +1,226 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + HttpStatusCode +} from "@gnu-taler/taler-util"; +import { + Button, + LocalNotificationBanner, + ShowInputErrorLabel, + useLocalNotificationHandler, + useTranslationContext +} from "@gnu-taler/web-util/browser"; +import { VNode, h } from "preact"; +import { useEffect, useRef, useState } from "preact/hooks"; +import { useBankCoreApiContext } from "../context/config.js"; +import { useSessionState } from "../hooks/session.js"; +import { RouteDefinition } from "../route.js"; +import { undefinedIfEmpty } from "../utils.js"; +import { doAutoFocus } from "./PaytoWireTransferForm.js"; + +/** + * Collect and submit login data. + */ +export function LoginForm({ + currentUser, + fixedUser, + routeRegister, +}: { + fixedUser?: boolean; + currentUser?: string; + routeRegister?: RouteDefinition; +}): VNode { + const session = useSessionState(); + + const sessionUser = + session.state.status !== "loggedOut" ? session.state.username : undefined; + const [username, setUsername] = useState( + currentUser ?? sessionUser, + ); + const [password, setPassword] = useState(); + const { i18n } = useTranslationContext(); + const { authenticator } = useBankCoreApiContext(); + const [notification, withErrorHandler] = useLocalNotificationHandler(); + const { config } = useBankCoreApiContext(); + + const ref = useRef(null); + useEffect(function focusInput() { + ref.current?.focus(); + }, []); + + const errors = + undefinedIfEmpty({ + username: !username + ? i18n.str`Missing username` + : // : !USERNAME_REGEX.test(username) + // ? i18n.str`Use letters and numbers only, and start with a lowercase letter` + undefined, + password: !password ? i18n.str`Missing password` : undefined, + }); + + async function doLogout() { + session.logOut(); + } + + const loginHandler = !username || !password ? undefined : withErrorHandler( + async () => authenticator(username) + .createAccessToken(password, { + // scope: "readwrite" as "write", // FIX: different than merchant + scope: "readwrite", + duration: { d_us: "forever" }, + refreshable: true, + }), + (result) => { + session.logIn({ username, token: result.body.access_token }) + }, + (fail) => { + switch (fail.case) { + case HttpStatusCode.Unauthorized: return i18n.str`Wrong credentials for "${username}"`; + case HttpStatusCode.NotFound: return i18n.str`Account not found`; + } + } + ) + + return ( +
    + +
    +
    { + e.preventDefault(); + }} + autoCapitalize="none" + autoCorrect="off" + > +
    + +
    + { + setUsername(e.currentTarget.value); + }} + /> + +
    +
    + +
    +
    + +
    +
    + { + setPassword(e.currentTarget.value); + }} + /> + +
    +
    + + {session.state.status !== "loggedOut" ? ( +
    + + + +
    + ) : ( +
    + +
    + )} +
    + + {config.allow_registrations && routeRegister && ( + + Register + + )} +
    +
    + ); +} diff --git a/packages/bank-ui/src/pages/OperationState/index.ts b/packages/bank-ui/src/pages/OperationState/index.ts new file mode 100644 index 000000000..e4d9d45e3 --- /dev/null +++ b/packages/bank-ui/src/pages/OperationState/index.ts @@ -0,0 +1,157 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AbsoluteTime, + AmountJson, + TalerCoreBankErrorsByMethod, + TalerError, + WithdrawUriResult, +} from "@gnu-taler/taler-util"; +import { Loading, utils } from "@gnu-taler/web-util/browser"; +import { ErrorLoadingWithDebug } from "../../components/ErrorLoadingWithDebug.js"; +import { useComponentState } from "./state.js"; +import { + AbortedView, + ConfirmedView, + FailedView, + InvalidPaytoView, + InvalidReserveView, + InvalidWithdrawalView, + NeedConfirmationView, + ReadyView, +} from "./views.js"; +import { RouteDefinition } from "../../route.js"; + +export interface Props { + currency: string; + onAuthorizationRequired: () => void; + routeClose: RouteDefinition; + onAbort: () => void; + routeHere: RouteDefinition<{ wopid: string }>; +} + +export type State = + | State.Loading + | State.LoadingError + | State.Ready + | State.Failed + | State.Aborted + | State.Confirmed + | State.InvalidPayto + | State.InvalidWithdrawal + | State.InvalidReserve + | State.NeedConfirmation; + +export namespace State { + export interface Loading { + status: "loading"; + error: undefined; + } + + export interface Failed { + status: "failed"; + error: TalerCoreBankErrorsByMethod<"createWithdrawal">; + } + + export interface LoadingError { + status: "loading-error"; + error: TalerError; + } + + /** + * Need to open the wallet + */ + export interface Ready { + status: "ready"; + error: undefined; + uri: WithdrawUriResult; + onAbort: () => Promise< + TalerCoreBankErrorsByMethod<"abortWithdrawalById"> | undefined + >; + routeClose: RouteDefinition; + } + + export interface InvalidPayto { + status: "invalid-payto"; + error: undefined; + payto: string | undefined; + } + export interface InvalidWithdrawal { + status: "invalid-withdrawal"; + error: undefined; + uri: string; + } + export interface InvalidReserve { + status: "invalid-reserve"; + error: undefined; + reserve: string | undefined; + } + export interface NeedConfirmation { + status: "need-confirmation"; + onAuthorizationRequired: () => void; + account: string; + routeHere: RouteDefinition<{ wopid: string }>; + onAbort: + | undefined + | (() => Promise< + TalerCoreBankErrorsByMethod<"abortWithdrawalById"> | undefined + >); + onConfirm: + | undefined + | (() => Promise< + TalerCoreBankErrorsByMethod<"confirmWithdrawalById"> | undefined + >); + error: undefined; + id: string; + } + export interface Aborted { + status: "aborted"; + error: undefined; + routeClose: RouteDefinition; + } + export interface Confirmed { + status: "confirmed"; + error: undefined; + routeClose: RouteDefinition; + } +} + +export interface Transaction { + negative: boolean; + counterpart: string; + when: AbsoluteTime; + amount: AmountJson | undefined; + subject: string; +} + +const viewMapping: utils.StateViewMap = { + loading: Loading, + failed: FailedView, + "invalid-payto": InvalidPaytoView, + "invalid-withdrawal": InvalidWithdrawalView, + "invalid-reserve": InvalidReserveView, + "need-confirmation": NeedConfirmationView, + aborted: AbortedView, + confirmed: ConfirmedView, + "loading-error": ErrorLoadingWithDebug, + ready: ReadyView, +}; + +export const OperationState = utils.compose( + (p: Props) => useComponentState(p), + viewMapping, +); diff --git a/packages/bank-ui/src/pages/OperationState/state.ts b/packages/bank-ui/src/pages/OperationState/state.ts new file mode 100644 index 000000000..5baf2d51c --- /dev/null +++ b/packages/bank-ui/src/pages/OperationState/state.ts @@ -0,0 +1,232 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + Amounts, + HttpStatusCode, + TalerCoreBankErrorsByMethod, + TalerError, + assertUnreachable, + parsePaytoUri, + parseWithdrawUri, + stringifyWithdrawUri, +} from "@gnu-taler/taler-util"; +import { utils } from "@gnu-taler/web-util/browser"; +import { useEffect, useState } from "preact/hooks"; +import { mutate } from "swr"; +import { useBankCoreApiContext } from "../../context/config.js"; +import { useWithdrawalDetails } from "../../hooks/account.js"; +import { useSessionState } from "../../hooks/session.js"; +import { useBankState } from "../../hooks/bank-state.js"; +import { usePreferences } from "../../hooks/preferences.js"; +import { Props, State } from "./index.js"; + +export function useComponentState({ + currency, + routeClose, + onAbort, + routeHere, + onAuthorizationRequired, +}: Props): utils.RecursiveState { + const [settings] = usePreferences(); + const [bankState, updateBankState] = useBankState(); + const { state: credentials } = useSessionState(); + const creds = credentials.status !== "loggedIn" ? undefined : credentials; + const { bank } = useBankCoreApiContext(); + + const [failure, setFailure] = useState< + TalerCoreBankErrorsByMethod<"createWithdrawal"> | undefined + >(); + const amount = settings.maxWithdrawalAmount; + + async function doSilentStart() { + // FIXME: if amount is not enough use balance + const parsedAmount = Amounts.parseOrThrow(`${currency}:${amount}`); + if (!creds) return; + const resp = await bank.createWithdrawal(creds, { + amount: Amounts.stringify(parsedAmount), + }); + if (resp.type === "fail") { + setFailure(resp); + return; + } + updateBankState("currentWithdrawalOperationId", resp.body.withdrawal_id); + } + + const withdrawalOperationId = bankState.currentWithdrawalOperationId; + useEffect(() => { + if (withdrawalOperationId === undefined) { + doSilentStart(); + } + }, [settings.fastWithdrawal, amount]); + + if (failure) { + return { + status: "failed", + error: failure, + }; + } + + if (!withdrawalOperationId) { + return { + status: "loading", + error: undefined, + }; + } + + const wid = withdrawalOperationId; + + async function doAbort() { + if (!creds) return; + const resp = await bank.abortWithdrawalById(creds, wid); + if (resp.type === "ok") { + // updateBankState("currentWithdrawalOperationId", undefined) + onAbort(); + } else { + return resp; + } + } + + async function doConfirm(): Promise< + TalerCoreBankErrorsByMethod<"confirmWithdrawalById"> | undefined + > { + if (!creds) return; + const resp = await bank.confirmWithdrawalById(creds, wid); + if (resp.type === "ok") { + mutate(() => true); //clean withdrawal state + } else { + return resp; + } + } + + const uri = stringifyWithdrawUri({ + bankIntegrationApiBaseUrl: bank.getIntegrationAPI(), + withdrawalOperationId, + }); + const parsedUri = parseWithdrawUri(uri); + if (!parsedUri) { + return { + status: "invalid-withdrawal", + error: undefined, + uri, + }; + } + + return (): utils.RecursiveState => { + const result = useWithdrawalDetails(withdrawalOperationId); + const shouldCreateNewOperation = result && !(result instanceof TalerError); + + useEffect(() => { + if (shouldCreateNewOperation) { + doSilentStart(); + } + }, []); + if (!result) { + return { + status: "loading", + error: undefined, + }; + } + if (result instanceof TalerError) { + return { + status: "loading-error", + error: result, + }; + } + + if (result.type === "fail") { + switch (result.case) { + case HttpStatusCode.BadRequest: + case HttpStatusCode.NotFound: { + return { + status: "aborted", + error: undefined, + routeClose, + }; + } + default: + assertUnreachable(result); + } + } + + const { body: data } = result; + if (data.status === "aborted") { + return { + status: "aborted", + error: undefined, + routeClose, + }; + } + + if (data.status === "confirmed") { + if (!settings.showWithdrawalSuccess) { + updateBankState("currentWithdrawalOperationId", undefined); + // onClose() + } + return { + status: "confirmed", + error: undefined, + routeClose, + }; + } + + if (data.status === "pending") { + return { + status: "ready", + error: undefined, + uri: parsedUri, + routeClose, + onAbort: !creds + ? async () => { + onAbort(); + return undefined; + } + : doAbort, + }; + } + + if (!data.selected_reserve_pub) { + return { + status: "invalid-reserve", + error: undefined, + reserve: data.selected_reserve_pub, + }; + } + + const account = !data.selected_exchange_account + ? undefined + : parsePaytoUri(data.selected_exchange_account); + + if (!account) { + return { + status: "invalid-payto", + error: undefined, + payto: data.selected_exchange_account, + }; + } + + return { + status: "need-confirmation", + error: undefined, + routeHere, + onAuthorizationRequired, + account: data.username, + id: withdrawalOperationId, + onAbort: !creds ? undefined : doAbort, + onConfirm: !creds ? undefined : doConfirm, + }; + }; +} diff --git a/packages/bank-ui/src/pages/OperationState/stories.tsx b/packages/bank-ui/src/pages/OperationState/stories.tsx new file mode 100644 index 000000000..82253b82c --- /dev/null +++ b/packages/bank-ui/src/pages/OperationState/stories.tsx @@ -0,0 +1,29 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { ReadyView } from "./views.js"; + +export default { + title: "operation status page", +}; + +export const Ready = tests.createExample(ReadyView, {}); diff --git a/packages/bank-ui/src/pages/OperationState/test.ts b/packages/bank-ui/src/pages/OperationState/test.ts new file mode 100644 index 000000000..d47cb64a2 --- /dev/null +++ b/packages/bank-ui/src/pages/OperationState/test.ts @@ -0,0 +1,31 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +// import * as tests from "@gnu-taler/web-util/testing"; +// import { SwrMockEnvironment } from "@gnu-taler/web-util/testing"; +// import { expect } from "chai"; +// import { CASHOUT_API_EXAMPLE } from "../../endpoints.js"; +// import { Props } from "./index.js"; +// import { useComponentState } from "./state.js"; + +describe("Withdrawal operation states", () => { + it("should do some tests", async () => {}); +}); diff --git a/packages/bank-ui/src/pages/OperationState/views.tsx b/packages/bank-ui/src/pages/OperationState/views.tsx new file mode 100644 index 000000000..6eee6daa9 --- /dev/null +++ b/packages/bank-ui/src/pages/OperationState/views.tsx @@ -0,0 +1,440 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AbsoluteTime, + HttpStatusCode, + TalerErrorCode, + TranslatedString, + assertUnreachable, + stringifyWithdrawUri, +} from "@gnu-taler/taler-util"; +import { + Attention, + LocalNotificationBanner, + notifyInfo, + useLocalNotification, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; +import { Fragment, VNode, h } from "preact"; +import { useEffect } from "preact/hooks"; +import { QR } from "../../components/QR.js"; +import { useBankState } from "../../hooks/bank-state.js"; +import { usePreferences } from "../../hooks/preferences.js"; +import { ShouldBeSameUser } from "../WithdrawalConfirmationQuestion.js"; +import { State } from "./index.js"; +import { useTalerWalletIntegrationAPI } from "../../context/wallet-integration.js"; + +export function InvalidPaytoView({ payto }: State.InvalidPayto) { + return
    Payto from server is not valid "{payto}"
    ; +} +export function InvalidWithdrawalView({ uri }: State.InvalidWithdrawal) { + return
    Withdrawal uri from server is not valid "{uri}"
    ; +} +export function InvalidReserveView({ reserve }: State.InvalidReserve) { + return
    Reserve from server is not valid "{reserve}"
    ; +} + +export function NeedConfirmationView({ + onAbort: doAbort, + onConfirm: doConfirm, + routeHere, + account, + id, + onAuthorizationRequired, +}: State.NeedConfirmation) { + const { i18n } = useTranslationContext(); + const [settings] = usePreferences(); + const [notification, notify, errorHandler] = useLocalNotification(); + const [, updateBankState] = useBankState(); + + async function onCancel() { + errorHandler(async () => { + if (!doAbort) return; + const resp = await doAbort(); + if (!resp) return; + switch (resp.case) { + case HttpStatusCode.Conflict: + return notify({ + type: "error", + title: i18n.str`The reserve operation has been confirmed previously and can't be aborted`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.BadRequest: + return notify({ + type: "error", + title: i18n.str`The operation id is invalid.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.NotFound: + return notify({ + type: "error", + title: i18n.str`The operation was not found.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + default: + assertUnreachable(resp); + } + }); + } + + async function onConfirm() { + errorHandler(async () => { + if (!doConfirm) return; + const resp = await doConfirm(); + if (!resp) { + if (!settings.showWithdrawalSuccess) { + notifyInfo(i18n.str`Wire transfer completed!`); + } + return; + } + switch (resp.case) { + case TalerErrorCode.BANK_CONFIRM_ABORT_CONFLICT: + return notify({ + type: "error", + title: i18n.str`The withdrawal has been aborted previously and can't be confirmed`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: + return notify({ + type: "error", + title: i18n.str`The withdrawal operation can't be confirmed before a wallet accepted the transaction.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.BadRequest: + return notify({ + type: "error", + title: i18n.str`The operation id is invalid.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.NotFound: + return notify({ + type: "error", + title: i18n.str`The operation was not found.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case TalerErrorCode.BANK_UNALLOWED_DEBIT: + return notify({ + type: "error", + title: i18n.str`Your balance is not enough.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.Accepted: { + updateBankState("currentChallenge", { + operation: "confirm-withdrawal", + id: String(resp.body.challenge_id), + sent: AbsoluteTime.never(), + location: routeHere.url({ wopid: id }), + request: id, + + }); + return onAuthorizationRequired(); + } + default: + assertUnreachable(resp); + } + }); + } + + return ( +
    + +
    +

    + Confirm the withdrawal operation +

    +
    + +
    { + e.preventDefault(); + }} + > +
    + + +
    +
    +
    +
    +
    +
    + ); +} +export function FailedView({ error }: State.Failed) { + const { i18n } = useTranslationContext(); + switch (error.case) { + case HttpStatusCode.Unauthorized: + return ( + +
    {error.detail.hint}
    +
    + ); + case HttpStatusCode.Conflict: + return ( + +
    {error.detail.hint}
    +
    + ); + case HttpStatusCode.NotFound: + return ( + +
    {error.detail.hint}
    +
    + ); + default: + assertUnreachable(error); + } +} + +export function AbortedView() { + return
    aborted
    ; +} + +export function ConfirmedView({ routeClose }: State.Confirmed) { + const { i18n } = useTranslationContext(); + const [settings, updateSettings] = usePreferences(); + return ( + +
    +
    + +
    +
    + +
    +

    + + The wire transfer to the Taler operator has been initiated. You + will soon receive the requested amount in your Taler wallet. + +

    +
    +
    +
    +
    +
    + + + Do not show this again + + + +
    +
    + +
    + ); +} + +export function ReadyView({ + uri, + onAbort: doAbort, +}: State.Ready): VNode { + const { i18n } = useTranslationContext(); + const walletInegrationApi = useTalerWalletIntegrationAPI(); + const [notification, notify, errorHandler] = useLocalNotification(); + + const talerWithdrawUri = stringifyWithdrawUri(uri); + useEffect(() => { + walletInegrationApi.publishTalerAction(uri); + }, []); + + async function onAbort() { + errorHandler(async () => { + const hasError = await doAbort(); + if (!hasError) return; + switch (hasError.case) { + case HttpStatusCode.Conflict: + return notify({ + type: "error", + title: i18n.str`The reserve operation has been confirmed previously and can't be aborted`, + description: hasError.detail.hint as TranslatedString, + debug: hasError.detail, + }); + case HttpStatusCode.BadRequest: + return notify({ + type: "error", + title: i18n.str`The operation id is invalid.`, + description: hasError.detail.hint as TranslatedString, + debug: hasError.detail, + }); + case HttpStatusCode.NotFound: + return notify({ + type: "error", + title: i18n.str`The operation was not found.`, + description: hasError.detail.hint as TranslatedString, + debug: hasError.detail, + }); + default: + assertUnreachable(hasError); + } + }); + } + + return ( + + + +
    + +
    + +
    +
    +

    + On this device +

    +
    +
    +

    + + If you are using a web browser on desktop you can also + +

    +
    + +
    +
    +
    +
    +
    +

    + On a mobile phone +

    +
    +
    +

    + + Scan the QR code with your mobile device. + +

    +
    +
    +
    + +
    +
    +
    +
    + ); +} diff --git a/packages/bank-ui/src/pages/PaymentOptions.stories.tsx b/packages/bank-ui/src/pages/PaymentOptions.stories.tsx new file mode 100644 index 000000000..78af886a8 --- /dev/null +++ b/packages/bank-ui/src/pages/PaymentOptions.stories.tsx @@ -0,0 +1,35 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { PaymentOptions } from "./PaymentOptions.js"; + +export default { + title: "PaymentOptions", +}; + +export const USD = tests.createExample(PaymentOptions, { + limit: { + currency: "USD", + fraction: 0, + value: 1, + }, +}); diff --git a/packages/bank-ui/src/pages/PaymentOptions.tsx b/packages/bank-ui/src/pages/PaymentOptions.tsx new file mode 100644 index 000000000..48ecc7525 --- /dev/null +++ b/packages/bank-ui/src/pages/PaymentOptions.tsx @@ -0,0 +1,237 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { AmountJson, TalerError } from "@gnu-taler/taler-util"; +import { Fragment, VNode, h } from "preact"; +import { useBankState } from "../hooks/bank-state.js"; +import { PaytoWireTransferForm } from "./PaytoWireTransferForm.js"; +import { WalletWithdrawForm } from "./WalletWithdrawForm.js"; +import { EmptyObject, RouteDefinition } from "../route.js"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { useWithdrawalDetails } from "../hooks/account.js"; +import { useEffect } from "preact/hooks"; +import { useSessionState } from "../hooks/session.js"; + +function ShowOperationPendingTag({ + woid, + onOperationAlreadyCompleted, +}: { + woid: string; + onOperationAlreadyCompleted?: () => void; +}): VNode { + const { i18n } = useTranslationContext(); + const { state: credentials } = useSessionState(); + const result = useWithdrawalDetails(woid); + const loading = !result + const error = + !loading && (result instanceof TalerError || result.type === "fail"); + const pending = + !loading && !error && + (result.body.status === "pending" || result.body.status === "selected") + && credentials.status === "loggedIn" + && credentials.username === result.body.username; + useEffect(() => { + if (!loading && !pending && onOperationAlreadyCompleted) { + onOperationAlreadyCompleted(); + } + }, [pending]); + + if (error || !pending) { + return ; + } + + return ( + + + Operation ready + + ); +} + +/** + * Let the user choose a payment option, + * then specify the details trigger the action. + */ +export function PaymentOptions({ + routeClose, + routeCashout, + routeChargeWallet, + routeWireTransfer, + tab, + limit, + onOperationCreated, + onClose, + routeOperationDetails, + onAuthorizationRequired, +}: { + limit: AmountJson; + tab: "charge-wallet" | "wire-transfer" | undefined; + onAuthorizationRequired: () => void; + onOperationCreated: (wopid: string) => void; + onClose: () => void; + + routeOperationDetails: RouteDefinition<{ wopid: string }>; + routeClose: RouteDefinition; + routeCashout: RouteDefinition; + routeChargeWallet: RouteDefinition; + routeWireTransfer: RouteDefinition<{ + account?: string, + subject?: string, + amount?: string, + }>; +}): VNode { + const { i18n } = useTranslationContext(); + const [bankState, updateBankState] = useBankState(); + + return ( + + ); +} diff --git a/packages/bank-ui/src/pages/PaytoWireTransferForm.stories.tsx b/packages/bank-ui/src/pages/PaytoWireTransferForm.stories.tsx new file mode 100644 index 000000000..61cfb5629 --- /dev/null +++ b/packages/bank-ui/src/pages/PaytoWireTransferForm.stories.tsx @@ -0,0 +1,35 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import * as tests from "@gnu-taler/web-util/testing"; +import { PaytoWireTransferForm } from "./PaytoWireTransferForm.js"; + +export default { + title: "PaytoWireTransferForm", +}; + +export const USD = tests.createExample(PaytoWireTransferForm, { + limit: { + currency: "USD", + fraction: 0, + value: 1, + }, +}); diff --git a/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx new file mode 100644 index 000000000..791a3b440 --- /dev/null +++ b/packages/bank-ui/src/pages/PaytoWireTransferForm.tsx @@ -0,0 +1,792 @@ +/* + This file is part of GNU Taler + (C) 2022-2024 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +import { + AbsoluteTime, + AmountJson, + AmountString, + Amounts, + CurrencySpecification, + FRAC_SEPARATOR, + HttpStatusCode, + PaytoString, + PaytoUri, + TalerErrorCode, + TranslatedString, + assertUnreachable, + buildPayto, + parsePaytoUri, + stringifyPaytoUri +} from "@gnu-taler/taler-util"; +import { + InternationalizationAPI, + LocalNotificationBanner, + ShowInputErrorLabel, + notifyInfo, + useLocalNotification, + useTranslationContext, +} from "@gnu-taler/web-util/browser"; +import { ComponentChildren, Fragment, Ref, VNode, h } from "preact"; +import { useState } from "preact/hooks"; +import { mutate } from "swr"; +import { useBankCoreApiContext } from "../context/config.js"; +import { useSessionState } from "../hooks/session.js"; +import { useBankState } from "../hooks/bank-state.js"; +import { EmptyObject, RouteDefinition } from "../route.js"; +import { undefinedIfEmpty, validateIBAN, validateTalerBank } from "../utils.js"; + +interface Props { + title: TranslatedString; + focus?: boolean; + withAccount?: string; + withSubject?: string; + withAmount?: string; + onSuccess: () => void; + onAuthorizationRequired: () => void; + routeCancel?: RouteDefinition; + routeCashout?: RouteDefinition; + routeHere: RouteDefinition<{ + account?: string, + subject?: string, + amount?: string, + }>; + limit: AmountJson; +} + +export function PaytoWireTransferForm({ + focus, + title, + withAccount, + withSubject, + withAmount, + onSuccess, + routeCancel, + routeCashout, + routeHere, + onAuthorizationRequired, + limit, +}: Props): VNode { + const [isRawPayto, setIsRawPayto] = useState(false); + const { state: credentials } = useSessionState(); + const { bank: api, config, url } = useBankCoreApiContext(); + + const sendingToFixedAccount = withAccount !== undefined; + + const [account, setAccount] = useState(withAccount); + const [subject, setSubject] = useState(withSubject); + const [amount, setAmount] = useState(withAmount); + const [, updateBankState] = useBankState(); + + const [rawPaytoInput, rawPaytoInputSetter] = useState( + undefined, + ); + const { i18n } = useTranslationContext(); + + const trimmedAmountStr = amount?.trim(); + const parsedAmount = Amounts.parse(`${limit.currency}:${trimmedAmountStr}`); + const [notification, notify, handleError] = useLocalNotification(); + + const paytoType = config.wire_type === "X_TALER_BANK" ? "x-taler-bank" as const : "iban" as const; + + const errorsWire = undefinedIfEmpty({ + account: !account + ? i18n.str`Required` + : paytoType === "iban" ? validateIBAN(account, i18n) : + paytoType === "x-taler-bank" ? validateTalerBank(account, i18n) : + undefined, + subject: !subject ? i18n.str`Required` : validateSubject(subject, i18n), + amount: !trimmedAmountStr + ? i18n.str`Required` + : !parsedAmount + ? i18n.str`Not valid` + : validateAmount(parsedAmount, limit, i18n), + }); + + const parsed = !rawPaytoInput ? undefined : parsePaytoUri(rawPaytoInput); + + + const errorsPayto = undefinedIfEmpty({ + rawPaytoInput: !rawPaytoInput + ? i18n.str`Required` + : !parsed ? i18n.str`Does not follow the pattern` + : validateRawPayto(parsed, limit, url.host, i18n, paytoType), + }); + + async function doSend() { + let payto_uri: PaytoString | undefined; + let sendingAmount: AmountString | undefined; + + if (credentials.status !== "loggedIn") return; + if (isRawPayto) { + const p = parsePaytoUri(rawPaytoInput!); + if (!p) return; + sendingAmount = p.params.amount as AmountString; + delete p.params.amount; + // if this payto is valid then it already have message + payto_uri = stringifyPaytoUri(p); + } else { + if (!account || !subject) return; + let payto; + switch (paytoType) { + case "x-taler-bank": { + payto = buildPayto("x-taler-bank", url.host, account); + break; + } + case "iban": { + payto = buildPayto("iban", account, undefined); + break; + } + default: assertUnreachable(paytoType) + } + + payto.params.message = encodeURIComponent(subject); + payto_uri = stringifyPaytoUri(payto); + sendingAmount = `${limit.currency}:${trimmedAmountStr}` as AmountString; + } + const puri = payto_uri; + const sAmount = sendingAmount; + + await handleError(async () => { + const request = { + payto_uri: puri, + amount: sAmount, + }; + const resp = await api.createTransaction(credentials, request); + mutate(() => true); + if (resp.type === "fail") { + switch (resp.case) { + case HttpStatusCode.BadRequest: + return notify({ + type: "error", + title: i18n.str`The request was invalid or the payto://-URI used unacceptable features.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.Unauthorized: + return notify({ + type: "error", + title: i18n.str`Not enough permission to complete the operation.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case TalerErrorCode.BANK_UNKNOWN_CREDITOR: + return notify({ + type: "error", + title: i18n.str`The destination account "${puri}" was not found.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case TalerErrorCode.BANK_SAME_ACCOUNT: + return notify({ + type: "error", + title: i18n.str`The origin and the destination of the transfer can't be the same.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case TalerErrorCode.BANK_UNALLOWED_DEBIT: + return notify({ + type: "error", + title: i18n.str`Your balance is not enough.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.NotFound: + return notify({ + type: "error", + title: i18n.str`The origin account "${puri}" was not found.`, + description: resp.detail.hint as TranslatedString, + debug: resp.detail, + }); + case HttpStatusCode.Accepted: { + updateBankState("currentChallenge", { + operation: "create-transaction", + id: String(resp.body.challenge_id), + location: routeHere.url({ account: account ?? "", amount, subject }), + sent: AbsoluteTime.never(), + request, + }); + return onAuthorizationRequired(); + } + default: + assertUnreachable(resp); + } + } + notifyInfo(i18n.str`Wire transfer created!`); + onSuccess(); + setAmount(undefined); + setAccount(undefined); + setSubject(undefined); + rawPaytoInputSetter(undefined); + }); + } + + return ( +
    + {/** + * FIXME: Scan a qr code + */} +
    +

    {title}

    +
    + + + {sendingToFixedAccount ? undefined : ( + + )} + {routeCashout ? ( + + Cashout + + ) : ( + undefined + )} +
    +
    + +
    { + e.preventDefault(); + }} + > +
    + {!isRawPayto ? ( +
    + {(() => { + switch (paytoType) { + case "x-taler-bank": { + return + } + case "iban": { + return setAccount(v.toUpperCase())} + value={account} + focus={focus} + disabled={sendingToFixedAccount} + /> + } + default: assertUnreachable(paytoType) + } + })()} + +
    + +
    + { + setSubject(e.currentTarget.value); + }} + /> + +
    +

    + + Some text to identify the transfer + +

    +
    + +
    + + { + setAmount(d); + }} + /> + +

    + Amount to transfer +

    +
    +
    + ) : ( +
    +
    + +
    +