/* 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, HttpStatusCode, TalerError, TalerErrorCode, TranslatedString, assertUnreachable, } from "@gnu-taler/taler-util"; import { Attention, Loading, LocalNotificationBanner, ShowInputErrorLabel, notifyInfo, useLocalNotification, useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useState } from "preact/hooks"; import { ErrorLoadingWithDebug } from "../../components/ErrorLoadingWithDebug.js"; import { useBankCoreApiContext } from "../../context/config.js"; import { useAccountDetails } from "../../hooks/account.js"; import { useSessionState } from "../../hooks/session.js"; import { undefinedIfEmpty } from "../../utils.js"; import { LoginForm } from "../LoginForm.js"; import { doAutoFocus } from "../PaytoWireTransferForm.js"; import { useBankState } from "../../hooks/bank-state.js"; import { RouteDefinition } from "../../route.js"; export function RemoveAccount({ account, routeCancel, onUpdateSuccess, onAuthorizationRequired, focus, routeHere, }: { focus?: boolean; routeHere: RouteDefinition<{ account: string }>; onAuthorizationRequired: () => void; routeCancel: RouteDefinition; onUpdateSuccess: () => void; account: string; }): VNode { const { i18n } = useTranslationContext(); const result = useAccountDetails(account); const [accountName, setAccountName] = useState(); const { state } = useSessionState(); const token = state.status !== "loggedIn" ? undefined : state.token; const { bank: api } = useBankCoreApiContext(); const [notification, notify, handleError] = useLocalNotification(); const [, updateBankState] = useBankState(); if (!result) { return ; } if (result instanceof TalerError) { return ; } if (result.type === "fail") { switch (result.case) { case HttpStatusCode.Unauthorized: return ; case HttpStatusCode.NotFound: return ; default: assertUnreachable(result); } } const balance = Amounts.parse(result.body.balance.amount); if (!balance) { return
there was an error reading the balance
; } const isBalanceEmpty = Amounts.isZero(balance); if (!isBalanceEmpty) { return ( The account can't be delete while still holding some balance. First make sure that the owner make a complete cashout. ); } async function doRemove() { if (!token) return; await handleError(async () => { const resp = await api.deleteAccount({ username: account, token }); if (resp.type === "ok") { notifyInfo(i18n.str`Account removed`); onUpdateSuccess(); } else { switch (resp.case) { case HttpStatusCode.Unauthorized: return notify({ type: "error", title: i18n.str`No enough permission to delete the account.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.NotFound: return notify({ type: "error", title: i18n.str`The username was not found.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case TalerErrorCode.BANK_RESERVED_USERNAME_CONFLICT: return notify({ type: "error", title: i18n.str`Can't delete a reserved username.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case TalerErrorCode.BANK_ACCOUNT_BALANCE_NOT_ZERO: return notify({ type: "error", title: i18n.str`Can't delete an account with balance different than zero.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.Accepted: { updateBankState("currentChallenge", { operation: "delete-account", id: String(resp.body.challenge_id), sent: AbsoluteTime.never(), location: routeHere.url({ account }), request: account, }); return onAuthorizationRequired(); } default: { assertUnreachable(resp); } } } }); } const errors = undefinedIfEmpty({ accountName: !accountName ? i18n.str`Required` : account !== accountName ? i18n.str`Name doesn't match` : undefined, }); return (
This step can't be undone.

Deleting account "{account}"

{ e.preventDefault(); }} >
{ setAccountName(e.currentTarget.value); }} placeholder={account} autocomplete="off" />

Enter the account name that is going to be deleted

Cancel
); }