From 0b7bbed99d155ba030a1328e357ab6751bdbb835 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 21 Sep 2023 13:10:16 -0300 Subject: more ui: business and admin --- .../src/pages/UpdateAccountPassword.tsx | 278 ++++++++++++--------- 1 file changed, 164 insertions(+), 114 deletions(-) (limited to 'packages/demobank-ui/src/pages/UpdateAccountPassword.tsx') diff --git a/packages/demobank-ui/src/pages/UpdateAccountPassword.tsx b/packages/demobank-ui/src/pages/UpdateAccountPassword.tsx index 084a5b643..d19c411f3 100644 --- a/packages/demobank-ui/src/pages/UpdateAccountPassword.tsx +++ b/packages/demobank-ui/src/pages/UpdateAccountPassword.tsx @@ -1,131 +1,181 @@ +import { HttpStatusCode, TranslatedString } from "@gnu-taler/taler-util"; import { ErrorType, HttpResponsePaginated, RequestError, notify, notifyError, useTranslationContext } from "@gnu-taler/web-util/browser"; +import { Fragment, VNode, h } from "preact"; +import { useEffect, useRef, useState } from "preact/hooks"; +import { ShowInputErrorLabel } from "../components/ShowInputErrorLabel.js"; import { useAdminAccountAPI, useBusinessAccountDetails } from "../hooks/circuit.js"; -import { useState } from "preact/hooks"; -import { HttpStatusCode, TranslatedString } from "@gnu-taler/taler-util"; -import { VNode,h ,Fragment} from "preact"; import { buildRequestErrorMessage, undefinedIfEmpty } from "../utils.js"; -import { ShowInputErrorLabel } from "../components/ShowInputErrorLabel.js"; export function UpdateAccountPassword({ - account, - onClear, - onUpdateSuccess, - onLoadNotOk, - }: { - onLoadNotOk: ( - error: HttpResponsePaginated, - ) => VNode; - onClear: () => void; - onUpdateSuccess: () => void; - account: string; - }): VNode { - const { i18n } = useTranslationContext(); - const result = useBusinessAccountDetails(account); - const { changePassword } = useAdminAccountAPI(); - const [password, setPassword] = useState(); - const [repeat, setRepeat] = useState(); - - if (!result.ok) { - if (result.loading || result.type === ErrorType.TIMEOUT) { - return onLoadNotOk(result); - } - if (result.status === HttpStatusCode.NotFound) { - return
account not found
; - } + account, + onCancel, + onUpdateSuccess, + onLoadNotOk, + focus, +}: { + onLoadNotOk: ( + error: HttpResponsePaginated, + ) => VNode; + onCancel: () => void; + focus?: boolean, + onUpdateSuccess: () => void; + account: string; +}): VNode { + const { i18n } = useTranslationContext(); + const result = useBusinessAccountDetails(account); + const { changePassword } = useAdminAccountAPI(); + const [password, setPassword] = useState(); + const [repeat, setRepeat] = useState(); + + const ref = useRef(null); + useEffect(() => { + if (focus) ref.current?.focus(); + }, [focus]); + + if (!result.ok) { + if (result.loading || result.type === ErrorType.TIMEOUT) { return onLoadNotOk(result); } - - const errors = undefinedIfEmpty({ - password: !password ? i18n.str`required` : undefined, - repeat: !repeat - ? i18n.str`required` - : password !== repeat - ? i18n.str`password doesn't match` - : undefined, - }); - - return ( -
-
-

- Update password for {account} -

-
- -
-
-
- - { - setPassword(e.currentTarget.value); - }} - /> - -
-
- - { - setRepeat(e.currentTarget.value); - }} - /> - -
-
-

-

-
+ if (result.status === HttpStatusCode.NotFound) { + return
account not found
; + } + return onLoadNotOk(result); + } + + const errors = undefinedIfEmpty({ + password: !password ? i18n.str`required` : undefined, + repeat: !repeat + ? i18n.str`required` + : password !== repeat + ? i18n.str`password doesn't match` + : undefined, + }); + + async function doChangePassword() { + if (!!errors || !password) return; + try { + const r = await changePassword(account, { + new_password: password, + }); + onUpdateSuccess(); + } catch (error) { + if (error instanceof RequestError) { + notify(buildRequestErrorMessage(i18n, error.cause)); + } else { + notifyError(i18n.str`Operation failed, please report`, (error instanceof Error + ? error.message + : JSON.stringify(error)) as TranslatedString) + } + } + } + + return ( +
+
+

+ Update password for account "{account}" +

+
+
{ + e.preventDefault() + }} + > +
+
+ +
+ +
{ - e.preventDefault(); - onClear(); + ref={ref} + type="password" + class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" + name="password" + id="password" + data-error={!!errors?.password && password !== undefined} + value={password ?? ""} + onChange={(e) => { + setPassword(e.currentTarget.value) }} + // placeholder="" + autocomplete="off" + /> +
-
+ {/*

+ user +

*/} +
+ +
+ +
{ - e.preventDefault(); - if (!!errors || !password) return; - try { - const r = await changePassword(account, { - new_password: password, - }); - onUpdateSuccess(); - } catch (error) { - if (error instanceof RequestError) { - notify(buildRequestErrorMessage(i18n, error.cause)); - } else { - notifyError(i18n.str`Operation failed, please report`, (error instanceof Error - ? error.message - : JSON.stringify(error)) as TranslatedString) - } - } + type="password" + class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 data-[error=true]:ring-red-500 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" + name="repeat" + id="repeat" + data-error={!!errors?.repeat && repeat !== undefined} + value={repeat ?? ""} + onChange={(e) => { + setRepeat(e.currentTarget.value) }} + // placeholder="" + autocomplete="off" + /> +
+

+ repeat the same password +

-

+ + + +
-
- ); - } \ No newline at end of file +
+ {onCancel ? + + :
+ } + +
+ +
+ + ); +} \ No newline at end of file -- cgit v1.2.3