aboutsummaryrefslogtreecommitdiff
path: root/packages/demobank-ui/src/pages/ShowAccountDetails.tsx
diff options
context:
space:
mode:
authorÖzgür Kesim <oec-taler@kesim.org>2023-10-06 16:33:05 +0200
committerÖzgür Kesim <oec-taler@kesim.org>2023-10-06 16:33:05 +0200
commitfe7b51ef2736edbf04f5bbd9d19f2a2d04baccc2 (patch)
tree66c68c8d6a666f6e74dc663c9ee4f07879f6626c /packages/demobank-ui/src/pages/ShowAccountDetails.tsx
parent35611f0bf9cf67638b171c2a300fab1797d3d8f0 (diff)
parent97d7be7503168f4f3bbd05905d32aa76ca1636b2 (diff)
Merge branch 'master' into age-withdraw
Diffstat (limited to 'packages/demobank-ui/src/pages/ShowAccountDetails.tsx')
-rw-r--r--packages/demobank-ui/src/pages/ShowAccountDetails.tsx167
1 files changed, 167 insertions, 0 deletions
diff --git a/packages/demobank-ui/src/pages/ShowAccountDetails.tsx b/packages/demobank-ui/src/pages/ShowAccountDetails.tsx
new file mode 100644
index 000000000..6acf0361e
--- /dev/null
+++ b/packages/demobank-ui/src/pages/ShowAccountDetails.tsx
@@ -0,0 +1,167 @@
+import { ErrorType, HttpResponsePaginated, RequestError, notify, notifyError, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { VNode, h } from "preact";
+import { useAdminAccountAPI, useBusinessAccountDetails } from "../hooks/circuit.js";
+import { useState } from "preact/hooks";
+import { HttpStatusCode, TranslatedString } from "@gnu-taler/taler-util";
+import { buildRequestErrorMessage } from "../utils.js";
+import { AccountForm } from "./admin/AccountForm.js";
+
+export function ShowAccountDetails({
+ account,
+ onClear,
+ onUpdateSuccess,
+ onLoadNotOk,
+ onChangePassword,
+}: {
+ onLoadNotOk: <T>(
+ error: HttpResponsePaginated<T, SandboxBackend.SandboxError>,
+ ) => VNode;
+ onClear?: () => void;
+ onChangePassword: () => void;
+ onUpdateSuccess: () => void;
+ account: string;
+}): VNode {
+ const { i18n } = useTranslationContext();
+ const result = useBusinessAccountDetails(account);
+ const { updateAccount } = useAdminAccountAPI();
+ const [update, setUpdate] = useState(false);
+ const [submitAccount, setSubmitAccount] = useState<
+ SandboxBackend.Circuit.CircuitAccountData | undefined
+ >();
+
+ if (!result.ok) {
+ if (result.loading || result.type === ErrorType.TIMEOUT) {
+ return onLoadNotOk(result);
+ }
+ if (result.status === HttpStatusCode.NotFound) {
+ return <div>account not found</div>;
+ }
+ return onLoadNotOk(result);
+ }
+
+ async function doUpdate() {
+ if (!update) {
+ setUpdate(true);
+ } else {
+ if (!submitAccount) return;
+ try {
+ await updateAccount(account, {
+ cashout_address: submitAccount.cashout_address,
+ contact_data: submitAccount.contact_data,
+ });
+ onUpdateSuccess();
+ } catch (error) {
+ if (error instanceof RequestError) {
+ notify(
+ buildRequestErrorMessage(i18n, error.cause, {
+ onClientError: (status) =>
+ status === HttpStatusCode.Forbidden
+ ? i18n.str`The rights to change the account are not sufficient`
+ : status === HttpStatusCode.NotFound
+ ? i18n.str`The username was not found`
+ : undefined,
+ }),
+ );
+ } else {
+ notifyError(
+ i18n.str`Operation failed, please report`,
+ (error instanceof Error
+ ? error.message
+ : JSON.stringify(error)) as TranslatedString
+ )
+ }
+ }
+ }
+ }
+
+ return (
+ <div>
+ <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-10 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg">
+ <div class="px-4 sm:px-0">
+ <h2 class="text-base font-semibold leading-7 text-gray-900">
+ {update ?
+ <i18n.Translate>Update account</i18n.Translate>
+ :
+ <i18n.Translate>Account details</i18n.Translate>
+ }
+ </h2>
+ <div class="mt-4">
+ <div class="flex items-center justify-between">
+ <span class="flex flex-grow flex-col">
+ <span class="text-sm text-black font-medium leading-6 " id="availability-label">
+ <i18n.Translate>change the account details</i18n.Translate>
+ </span>
+ </span>
+ <button type="button" data-enabled={!update} class="bg-indigo-600 data-[enabled=true]:bg-gray-200 relative inline-flex h-5 w-10 flex-shrink-0 cursor-pointer rounded-full ring-2 border-gray-600 transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" role="switch" aria-checked="false" aria-labelledby="availability-label" aria-describedby="availability-description"
+ onClick={() => {
+ setUpdate(!update)
+ }}>
+ <span aria-hidden="true" data-enabled={!update} class="translate-x-5 data-[enabled=true]:translate-x-0 pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"></span>
+ </button>
+ </div>
+ </div>
+
+ </div>
+ <AccountForm
+ template={result.data}
+ purpose={update ? "update" : "show"}
+ onChange={(a) => setSubmitAccount(a)}
+ >
+
+ </AccountForm>
+
+ <p class="buttons-account">
+ <div
+ style={{
+ display: "flex",
+ justifyContent: "space-between",
+ flexFlow: "wrap-reverse",
+ }}
+ >
+ <div>
+ {onClear ? (
+ <input
+ class="pure-button"
+ type="submit"
+ value={i18n.str`Close`}
+ onClick={async (e) => {
+ e.preventDefault();
+ onClear();
+ }}
+ />
+ ) : undefined}
+ </div>
+ <div style={{ display: "flex" }}>
+ <div>
+ <input
+ id="select-exchange"
+ class="pure-button pure-button-primary content"
+ disabled={update && !submitAccount}
+ type="submit"
+ value={i18n.str`Change password`}
+ onClick={async (e) => {
+ e.preventDefault();
+ onChangePassword();
+ }}
+ />
+ </div>
+ <div>
+ <input
+ id="select-exchange"
+ class="pure-button pure-button-primary content"
+ disabled={update && !submitAccount}
+ type="submit"
+ value={update ? i18n.str`Confirm` : i18n.str`Update`}
+ onClick={async (e) => {
+ e.preventDefault();
+ doUpdate()
+ }}
+ />
+ </div>
+ </div>
+ </div>
+ </p>
+ </div>
+ </div>
+ );
+}