commit 884733943159794b61549dea53e8fcea671403d1
parent ee1c914f9ff1326c588cbaea257f85a2fca4ba78
Author: Sebastian <sebasjm@gmail.com>
Date: Wed, 21 May 2025 15:40:18 -0300
fix #9992
Diffstat:
1 file changed, 177 insertions(+), 85 deletions(-)
diff --git a/packages/kyc-ui/src/pages/Start.tsx b/packages/kyc-ui/src/pages/Start.tsx
@@ -34,6 +34,7 @@ import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js";
import { useKycInfo } from "../hooks/kyc.js";
import { FillForm } from "./FillForm.js";
import { useSessionState } from "../hooks/session.js";
+import { AbsoluteTime } from "@gnu-taler/taler-util";
const TALER_SCREEN_ID = 104;
@@ -41,7 +42,7 @@ type Props = {
token: AccessToken;
};
-export function ShowReqList({
+function ShowReqList({
token,
onFormSelected,
}: {
@@ -120,17 +121,12 @@ export function ShowReqList({
>
{requirements.map((req, idx) => {
return (
- <li
- key={idx}
- class="relative flex justify-between gap-x-6 px-4 py-5 hover:bg-gray-50 sm:px-6"
- >
- <RequirementRow
- requirement={req}
- onFormSelected={() => {
- onFormSelected(req);
- }}
- />
- </li>
+ <RequirementRow
+ requirement={req}
+ onFormSelected={() => {
+ onFormSelected(req);
+ }}
+ />
);
})}
</ul>
@@ -141,31 +137,14 @@ export function ShowReqList({
}
export function Start({ token }: Props): VNode {
const [req, setReq] = useState<KycRequirementInformation>();
- const { lib } = useExchangeApiContext();
- const [notification, withErrorHandler] = useLocalNotificationHandler();
- const { state, start } = useSessionState();
if (!req) {
return (
<Fragment>
- <LocalNotificationBanner notification={notification} />
-
<ShowReqList
token={token}
onFormSelected={async (r) => {
const reqId = r.id;
if (r.form === "LINK" && reqId) {
- const action = withErrorHandler(
- async () => {
- return lib.exchange.startExternalKycProcess(reqId);
- },
- (res) => {
- if (state) {
- start(state.accessToken)
- }
- window.open(res.body.redirect_url, "_blank");
- },
- );
- await action.onClick();
} else {
setReq(r);
}
@@ -176,7 +155,6 @@ export function Start({ token }: Props): VNode {
}
return (
<Fragment>
- <LocalNotificationBanner notification={notification} />
<FillForm
formId={req.form}
requirement={req}
@@ -189,6 +167,164 @@ export function Start({ token }: Props): VNode {
);
}
+function LinkGenerator({ req }: { req: KycRequirementInformation }): VNode {
+ const { i18n } = useTranslationContext();
+
+ const [notification, , notify] = useLocalNotificationHandler();
+ const { lib } = useExchangeApiContext();
+
+ const [redirectUrl, setRedirectUrl] = useState<string>();
+ const row = (
+ <Fragment>
+ <div class="flex min-w-0 gap-x-4">
+ <LocalNotificationBanner notification={notification} />
+ <div class="inline-block h-10 w-10 rounded-full">
+ {!redirectUrl ? (
+ <svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ viewBox="0 0 24 24"
+ stroke-width="1.5"
+ stroke="currentColor"
+ class="size-6"
+ >
+ <path
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ d="M16.023 9.348h4.992v-.001M2.985 19.644v-4.992m0 0h4.992m-4.993 0 3.181 3.183a8.25 8.25 0 0 0 13.803-3.7M4.031 9.865a8.25 8.25 0 0 1 13.803-3.7l3.181 3.182m0-4.991v4.99"
+ />
+ </svg>
+ ) : (
+ <svg
+ xmlns="http://www.w3.org/2000/svg"
+ fill="none"
+ viewBox="0 0 24 24"
+ stroke-width="1.5"
+ stroke="currentColor"
+ class="size-6"
+ >
+ <path
+ stroke-linecap="round"
+ stroke-linejoin="round"
+ d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"
+ />
+ </svg>
+ )}
+ </div>
+ <div class="min-w-0 flex-auto">
+ {redirectUrl ? (
+ <p class="text-sm font-semibold leading-6 text-gray-900">
+ <span class="absolute inset-x-0 -top-px bottom-0"></span>
+ <i18n.Translate>{req.description}</i18n.Translate>
+ </p>
+ ) : (
+ // href={redirectUrl}
+ <p class="text-sm font-semibold leading-6 text-gray-900">
+ <button
+ onClick={async () => {
+ const res = await lib.exchange.startExternalKycProcess(
+ req.id!,
+ );
+ if (res.type === "ok") {
+ setRedirectUrl(res.body.redirect_url);
+ notify({
+ type: "info",
+ title: i18n.str`Link generated, you can proceed.`,
+ when: AbsoluteTime.now(),
+ });
+ } else {
+ switch (res.case) {
+ case HttpStatusCode.NotFound: {
+ notify({
+ type: "error",
+ title: i18n.str`could not create redirect url`,
+ description: i18n.str`not found`,
+ when: AbsoluteTime.now(),
+ });
+ break;
+ }
+ case HttpStatusCode.Conflict: {
+ notify({
+ type: "error",
+ title: i18n.str`could not create redirect url`,
+ description: i18n.str`conflict`,
+ when: AbsoluteTime.now(),
+ });
+ break;
+ }
+ case HttpStatusCode.PayloadTooLarge: {
+ notify({
+ type: "error",
+ title: i18n.str`could not create redirect url`,
+ description: i18n.str`payload too large`,
+ when: AbsoluteTime.now(),
+ });
+ break;
+ }
+ }
+ }
+ }}
+ >
+ <span class="absolute inset-x-0 -top-px bottom-0"></span>
+ <i18n.Translate context="KYC_REQUIREMENT_LINK_DESCRIPTION">
+ {req.description}
+ </i18n.Translate>
+ </button>
+ </p>
+ )}
+ </div>
+ </div>
+ <div class="flex shrink-0 items-center gap-x-4">
+ <div class="hidden sm:flex sm:flex-col sm:items-end">
+ {!redirectUrl ? (
+ <p class="text-sm leading-6 text-gray-900">
+ <i18n.Translate>Generate link</i18n.Translate>
+ </p>
+ ) : (
+ <p class="text-sm leading-6 text-gray-900">
+ <i18n.Translate>Open link</i18n.Translate>
+ </p>
+ )}
+ </div>
+ <svg
+ class="h-5 w-5 flex-none text-gray-400"
+ viewBox="0 0 20 20"
+ fill="currentColor"
+ aria-hidden="true"
+ >
+ <path
+ fill-rule="evenodd"
+ d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
+ clip-rule="evenodd"
+ />
+ </svg>
+ </div>
+ </Fragment>
+ );
+ if (redirectUrl) {
+ return (
+ <li key={req.id} class="hover:bg-gray-50 sm:px-6 px-4 py-5">
+ <a
+ href={redirectUrl}
+ target="_blank"
+ rel="noreferrer"
+ class="relative flex justify-between gap-x-6 "
+ >
+ {row}
+ </a>
+ </li>
+ );
+ }
+ return (
+ <li
+ key={req.id}
+ class="relative flex justify-between gap-x-6 px-4 py-5 hover:bg-gray-50 sm:px-6"
+ >
+ {row}
+ </li>
+ );
+}
+
function RequirementRow({
requirement: req,
onFormSelected,
@@ -201,7 +337,10 @@ function RequirementRow({
switch (req.form) {
case "INFO": {
return (
- <Fragment>
+ <li
+ key={req.id}
+ class="relative flex justify-between gap-x-6 px-4 py-5 hover:bg-gray-50 sm:px-6"
+ >
<div class="flex min-w-0 gap-x-4">
<div class="inline-block h-10 w-10 rounded-full">
<svg
@@ -231,65 +370,18 @@ function RequirementRow({
</p> */}
</div>
</div>
- </Fragment>
+ </li>
);
}
case "LINK": {
- return (
- <Fragment>
- <div class="flex min-w-0 gap-x-4">
- <div class="inline-block h-10 w-10 rounded-full">
- <svg
- xmlns="http://www.w3.org/2000/svg"
- fill="none"
- viewBox="0 0 24 24"
- stroke-width="1.5"
- stroke="currentColor"
- class="size-6"
- >
- <path
- stroke-linecap="round"
- stroke-linejoin="round"
- d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25"
- />
- </svg>
- </div>
- <div class="min-w-0 flex-auto">
- <p class="text-sm font-semibold leading-6 text-gray-900">
- <button onClick={onFormSelected}>
- <span class="absolute inset-x-0 -top-px bottom-0"></span>
- <i18n.Translate context="KYC_REQUIREMENT_LINK_DESCRIPTION">
- {req.description}
- </i18n.Translate>
- </button>
- </p>
- </div>
- </div>
- <div class="flex shrink-0 items-center gap-x-4">
- <div class="hidden sm:flex sm:flex-col sm:items-end">
- <p class="text-sm leading-6 text-gray-900">
- <i18n.Translate>Start</i18n.Translate>
- </p>
- </div>
- <svg
- class="h-5 w-5 flex-none text-gray-400"
- viewBox="0 0 20 20"
- fill="currentColor"
- aria-hidden="true"
- >
- <path
- fill-rule="evenodd"
- d="M7.21 14.77a.75.75 0 01.02-1.06L11.168 10 7.23 6.29a.75.75 0 111.04-1.08l4.5 4.25a.75.75 0 010 1.08l-4.5 4.25a.75.75 0 01-1.06-.02z"
- clip-rule="evenodd"
- />
- </svg>
- </div>
- </Fragment>
- );
+ return <LinkGenerator key={req.id} req={req} />;
}
default: {
return (
- <Fragment>
+ <li
+ key={req.id}
+ class="relative flex justify-between gap-x-6 px-4 py-5 hover:bg-gray-50 sm:px-6"
+ >
<div class="flex min-w-0 gap-x-4">
<div class="inline-block h-10 w-10 rounded-full">
<svg
@@ -338,7 +430,7 @@ function RequirementRow({
/>
</svg>
</div>
- </Fragment>
+ </li>
);
}
}