summaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/paths
diff options
context:
space:
mode:
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths')
-rw-r--r--packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx16
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx37
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx46
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx57
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx60
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx70
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx12
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx196
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx67
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx98
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx42
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx44
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx5
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx53
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx53
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx5
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx44
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx44
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx28
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx17
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx62
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx22
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx72
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx46
-rw-r--r--packages/merchant-backoffice-ui/src/paths/notfound/index.tsx40
25 files changed, 572 insertions, 664 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
index b7551df04..7dd5d74bb 100644
--- a/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/admin/list/index.tsx
@@ -19,37 +19,29 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerError, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
+import { TalerError, TalerMerchantApi } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../components/exception/loading.js";
import { NotificationCard } from "../../../components/menu/index.js";
import { DeleteModal, PurgeModal } from "../../../components/modal/index.js";
+import { useSessionContext } from "../../../context/session.js";
import { useBackendInstances } from "../../../hooks/instance.js";
import { Notification } from "../../../utils/types.js";
import { View } from "./View.js";
-import { useSessionContext } from "../../../context/session.js";
-import { ErrorLoadingMerchant } from "../../../components/ErrorLoadingMerchant.js";
interface Props {
onCreate: () => void;
onUpdate: (id: string) => void;
instances: TalerMerchantApi.Instance[];
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
}
export default function Instances({
- onUnauthorized,
- onLoadError,
- onNotFound,
onCreate,
onUpdate,
}: Props): VNode {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx
index ab63d0d5f..1d5c523a4 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/list/index.tsx
@@ -19,37 +19,30 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerError, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
+import { useSessionContext } from "../../../../context/session.js";
import { useInstanceBankAccounts } from "../../../../hooks/bank.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { ListPage } from "./ListPage.js";
-import { useSessionContext } from "../../../../context/session.js";
-import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
interface Props {
- onUnauthorized: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
- onNotFound: () => VNode;
onCreate: () => void;
onSelect: (id: string) => void;
}
export default function ListOtpDevices({
- onUnauthorized,
- onLoadError,
onCreate,
onSelect,
- onNotFound,
}: Props): VNode {
const { i18n } = useTranslationContext();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
@@ -61,11 +54,21 @@ export default function ListOtpDevices({
if (result instanceof TalerError) {
return <ErrorLoadingMerchant error={result} />
}
+ if (result.type === "fail") {
+ switch(result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />
+ }
+ default: {
+ assertUnreachable(result.case)
+ }
+ }
+ }
return (
<Fragment>
<NotificationCard notification={notif} />
- {result.result.length < 1 &&
+ {result.body.length < 1 &&
<NotificationCard notification={{
type: "WARN",
message: i18n.str`You need to associate a bank account to receive revenue.`,
@@ -73,17 +76,17 @@ export default function ListOtpDevices({
}} />
}
<ListPage
- devices={result.result}
+ devices={result.body}
onLoadMoreBefore={
- result.isReachingStart ? result.loadMorePrev : undefined
+ result.isFirstPage ? undefined: result.loadFirst
}
- onLoadMoreAfter={result.isReachingEnd ? result.loadMore : undefined}
+ onLoadMoreAfter={result.isLastPage ? undefined : result.loadNext}
onCreate={onCreate}
onSelect={(e) => {
onSelect(e.h_wire);
}}
onDelete={(e: TalerMerchantApi.BankAccountEntry) => {
- return api.management.deleteAccount(state.token, e.h_wire)
+ return api.management.deleteBankAccount(state.token, e.h_wire)
.then(() =>
setNotif({
message: i18n.str`bank account delete successfully`,
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx
index f83020ed1..f5b7436d4 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/accounts/update/index.tsx
@@ -19,39 +19,33 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
+import { useSessionContext } from "../../../../context/session.js";
import { useBankAccountDetails } from "../../../../hooks/bank.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { UpdatePage } from "./UpdatePage.js";
-import { useSessionContext } from "../../../../context/session.js";
export type Entity = TalerMerchantApi.AccountPatchDetails & WithId;
interface Props {
onBack?: () => void;
onConfirm: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
bid: string;
}
export default function UpdateValidator({
bid,
onConfirm,
onBack,
- onUnauthorized,
- onNotFound,
- onLoadError,
}: Props): VNode {
const { lib: api } = useMerchantApiContext();
const { state } = useSessionContext();
@@ -60,29 +54,29 @@ export default function UpdateValidator({
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ default: {
+ assertUnreachable(result.case);
+ }
+ }
}
return (
<Fragment>
<NotificationCard notification={notif} />
<UpdatePage
- account={{ ...result.data, id: bid }}
+ account={{ ...result.body, id: bid }}
onBack={onBack}
onUpdate={(data) => {
- return api.management.updateAccount(state.token, bid, data)
+ return api.management.updateBankAccount(state.token, bid, data)
.then(onConfirm)
.catch((error) => {
setNotif({
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
index be631c1e0..d7abc4fbe 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
@@ -13,52 +13,55 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { ErrorType, HttpError, Loading, useTranslationContext } from "@gnu-taler/web-util/browser";
-import { h, VNode } from "preact";
-import { useEffect, useState } from "preact/hooks";
+import { HttpStatusCode, TalerError, assertUnreachable } from "@gnu-taler/taler-util";
+import { Loading, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { VNode, h } from "preact";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { CreatedSuccessfully } from "../../../../components/notifications/CreatedSuccessfully.js";
-import { Entity } from "./index.js";
import { useOrderDetails } from "../../../../hooks/order.js";
-import { HttpStatusCode, TalerErrorDetail } from "@gnu-taler/taler-util";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
+import { Entity } from "./index.js";
interface Props {
entity: Entity;
onConfirm: () => void;
onCreateAnother?: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
}
export function OrderCreatedSuccessfully({
entity,
onConfirm,
onCreateAnother,
- onLoadError,
- onNotFound,
- onUnauthorized,
}: Props): VNode {
const result = useOrderDetails(entity.response.order_id)
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />
+ }
+ if (result.type === "fail") {
+ switch(result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />
+ }
+ case HttpStatusCode.BadGateway: {
+ return <div>Failed to obtain a response from the exchange</div>;
+ }
+ case HttpStatusCode.GatewayTimeout: {
+ return (
+ <div>The merchant's interaction with the exchange took too long</div>
+ );
+ }
+ default: {
+ assertUnreachable(result)
+ }
+ }
}
- const url = result.data.order_status === "unpaid" ?
- result.data.taler_pay_uri :
- result.data.contract_terms.fulfillment_url
+ const url = result.body.order_status === "unpaid" ?
+ result.body.taler_pay_uri :
+ result.body.contract_terms.fulfillment_url
return (
<CreatedSuccessfully
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
index 54d8c7b47..e40e766dd 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx
@@ -19,18 +19,19 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerError, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
-import { ErrorType, HttpError, useMerchantApiContext } from "@gnu-taler/web-util/browser";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
+import { useMerchantApiContext } from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
+import { useSessionContext } from "../../../../context/session.js";
import { useInstanceDetails } from "../../../../hooks/instance.js";
import { useInstanceProducts } from "../../../../hooks/product.js";
import { Notification } from "../../../../utils/types.js";
import { CreatePage } from "./CreatePage.js";
-import { useSessionContext } from "../../../../context/session.js";
-import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
export type Entity = {
request: TalerMerchantApi.PostOrderRequest;
@@ -39,16 +40,10 @@ export type Entity = {
interface Props {
onBack?: () => void;
onConfirm: (id: string) => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
}
export default function OrderCreate({
onConfirm,
onBack,
- onLoadError,
- onNotFound,
- onUnauthorized,
}: Props): VNode {
const { lib } = useMerchantApiContext();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
@@ -60,36 +55,19 @@ export default function OrderCreate({
if (detailsResult instanceof TalerError) {
return <ErrorLoadingMerchant error={detailsResult} />
}
-
- // if (detailsResult.loading) return <Loading />;
- if (inventoryResult.loading) return <Loading />;
-
- // if (!detailsResult.ok) {
- // if (
- // detailsResult.type === ErrorType.CLIENT &&
- // detailsResult.status === HttpStatusCode.Unauthorized
- // )
- // return onUnauthorized();
- // if (
- // detailsResult.type === ErrorType.CLIENT &&
- // detailsResult.status === HttpStatusCode.NotFound
- // )
- // return onNotFound();
- // return onLoadError(detailsResult);
- // }
-
- if (!inventoryResult.ok) {
- if (
- inventoryResult.type === ErrorType.CLIENT &&
- inventoryResult.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- inventoryResult.type === ErrorType.CLIENT &&
- inventoryResult.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(inventoryResult);
+ if (!inventoryResult) return <Loading />
+ if (inventoryResult instanceof TalerError) {
+ return <ErrorLoadingMerchant error={inventoryResult} />
+ }
+ if (inventoryResult.type === "fail") {
+ switch (inventoryResult.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ default: {
+ assertUnreachable(inventoryResult.case);
+ }
+ }
}
return (
@@ -119,7 +97,7 @@ export default function OrderCreate({
});
}}
instanceConfig={detailsResult.body}
- instanceInventory={inventoryResult.data}
+ instanceInventory={inventoryResult.body}
/>
</Fragment>
);
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
index c0c4862a1..1c8ceb90e 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/details/index.tsx
@@ -13,58 +13,60 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { HttpStatusCode, TalerErrorDetail } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
+ HttpStatusCode,
+ TalerError,
+ assertUnreachable,
+} from "@gnu-taler/taler-util";
+import {
useMerchantApiContext,
useTranslationContext,
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
+import { useSessionContext } from "../../../../context/session.js";
import { useOrderDetails } from "../../../../hooks/order.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { DetailPage } from "./DetailPage.js";
-import { useSessionContext } from "../../../../context/session.js";
export interface Props {
oid: string;
-
onBack: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
}
-export default function Update({
- oid,
- onBack,
- onLoadError,
- onNotFound,
- onUnauthorized,
-}: Props): VNode {
+export default function Update({ oid, onBack }: Props): VNode {
const result = useOrderDetails(oid);
const [notif, setNotif] = useState<Notification | undefined>(undefined);
- const { lib: api } = useMerchantApiContext()
+ const { lib: api } = useMerchantApiContext();
const { state } = useSessionContext();
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ case HttpStatusCode.BadGateway: {
+ return <div>Failed to obtain a response from the exchange</div>;
+ }
+ case HttpStatusCode.GatewayTimeout: {
+ return (
+ <div>The merchant's interaction with the exchange took too long</div>
+ );
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return (
@@ -78,7 +80,8 @@ export default function Update({
if (state.status !== "loggedIn") {
return;
}
- api.management.addRefund(state.token, id, value)
+ api.management
+ .addRefund(state.token, id, value)
.then(() =>
setNotif({
message: i18n.str`refund created successfully`,
@@ -91,10 +94,9 @@ export default function Update({
type: "ERROR",
description: error.message,
}),
- )
- }
- }
- selected={result.data}
+ );
+ }}
+ selected={result.body}
/>
</Fragment>
);
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
index 7b88985dc..12762c3b3 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/ListPage.tsx
@@ -19,7 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { TalerMerchantApi } from "@gnu-taler/taler-util";
+import { AbsoluteTime, TalerMerchantApi } from "@gnu-taler/taler-util";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { format } from "date-fns";
import { Fragment, VNode, h } from "preact";
@@ -43,8 +43,8 @@ export interface ListPageProps {
isNotWiredActive: string;
isWiredActive: string;
- jumpToDate?: Date;
- onSelectDate: (date?: Date) => void;
+ jumpToDate?: AbsoluteTime;
+ onSelectDate: (date?: AbsoluteTime) => void;
orders: (TalerMerchantApi.OrderHistoryEntry & WithId)[];
onLoadMoreBefore?: () => void;
@@ -177,7 +177,7 @@ export function ListPage({
class="input"
type="text"
readonly
- value={!jumpToDate ? "" : format(jumpToDate, dateFormatForSettings(settings))}
+ value={!jumpToDate || jumpToDate.t_ms === "never" ? "" : format(jumpToDate.t_ms, dateFormatForSettings(settings))}
placeholder={i18n.str`date (${dateFormatForSettings(settings)})`}
onClick={() => {
setPickDate(true);
@@ -207,7 +207,9 @@ export function ListPage({
<DatePicker
opened={pickDate}
closeFunction={() => setPickDate(false)}
- dateReceiver={onSelectDate}
+ dateReceiver={(d) => {
+ onSelectDate(AbsoluteTime.fromMilliseconds(d.getTime()))
+ }}
/>
<CardTable
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
index a50f02a2d..7a3fb2d22 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
@@ -19,83 +19,84 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi, stringifyPayUri } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
+ AbsoluteTime,
+ HttpStatusCode,
+ TalerError,
+ TalerMerchantApi,
+ assertUnreachable,
+} from "@gnu-taler/taler-util";
+import {
useMerchantApiContext,
useTranslationContext,
} from "@gnu-taler/web-util/browser";
-import { Fragment, VNode, h } from "preact";
+import { VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { JumpToElementById } from "../../../../components/form/JumpToElementById.js";
import { NotificationCard } from "../../../../components/menu/index.js";
+import { useSessionContext } from "../../../../context/session.js";
import {
InstanceOrderFilter,
useInstanceOrders,
useOrderDetails,
} from "../../../../hooks/order.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { ListPage } from "./ListPage.js";
import { RefundModal } from "./Table.js";
-import { useSessionContext } from "../../../../context/session.js";
interface Props {
- onUnauthorized: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
- onNotFound: () => VNode;
onSelect: (id: string) => void;
onCreate: () => void;
}
-export default function OrderList({
- onUnauthorized,
- onLoadError,
- onCreate,
- onSelect,
- onNotFound,
-}: Props): VNode {
- const [filter, setFilter] = useState<InstanceOrderFilter>({ paid: "no" });
+export default function OrderList({ onCreate, onSelect }: Props): VNode {
+ const [filter, setFilter] = useState<InstanceOrderFilter>({ paid: false });
const [orderToBeRefunded, setOrderToBeRefunded] = useState<
TalerMerchantApi.OrderHistoryEntry | undefined
>(undefined);
- const setNewDate = (date?: Date): void =>
+ const setNewDate = (date?: AbsoluteTime): void =>
setFilter((prev) => ({ ...prev, date }));
- const result = useInstanceOrders(filter, setNewDate);
+ const result = useInstanceOrders(filter, (d) =>
+ setFilter({ ...filter, position: d }),
+ );
const { lib } = useMerchantApiContext();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
const { i18n } = useTranslationContext();
- const { state } = useSessionContext()
-
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
- }
+ const { state } = useSessionContext();
- const isNotPaidActive = filter.paid === "no" ? "is-active" : "";
- const isPaidActive = filter.paid === "yes" && filter.wired === undefined ? "is-active" : "";
- const isRefundedActive = filter.refunded === "yes" ? "is-active" : "";
- const isNotWiredActive = filter.wired === "no" && filter.paid === "yes" ? "is-active" : "";
- const isWiredActive = filter.wired === "yes" ? "is-active" : "";
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ // if (result.type === "fail") {
+ // switch (result.case) {
+ // case HttpStatusCode.NotFound: {
+ // return <NotFoundPageOrAdminCreate />;
+ // }
+ // default: {
+ // assertUnreachable(result.case);
+ // }
+ // }
+ // }
+
+ const isNotPaidActive = filter.paid === false ? "is-active" : "";
+ const isPaidActive =
+ filter.paid === true && filter.wired === undefined ? "is-active" : "";
+ const isRefundedActive = filter.refunded === true ? "is-active" : "";
+ const isNotWiredActive =
+ filter.wired === false && filter.paid === true ? "is-active" : "";
+ const isWiredActive = filter.wired === true ? "is-active" : "";
const isAllActive =
filter.paid === undefined &&
- filter.refunded === undefined &&
- filter.wired === undefined
+ filter.refunded === undefined &&
+ filter.wired === undefined
? "is-active"
: "";
@@ -105,11 +106,8 @@ export default function OrderList({
<JumpToElementById
testIfExist={async (order) => {
- if (state.status !== "loggedIn") {
- return false;
- }
- const resp = await lib.management.getOrder(state.token, order)
- return resp.type === "ok"
+ const resp = await lib.management.getOrderDetails(state.token, order);
+ return resp.type === "ok";
}}
onSelect={onSelect}
description={i18n.str`jump to order with the given product ID`}
@@ -117,11 +115,11 @@ export default function OrderList({
/>
<ListPage
- orders={result.data.orders.map((o) => ({ ...o, id: o.order_id }))}
- onLoadMoreBefore={result.loadMorePrev}
- hasMoreBefore={!result.isReachingStart}
- onLoadMoreAfter={result.loadMore}
- hasMoreAfter={!result.isReachingEnd}
+ orders={result.body.map((o) => ({ ...o, id: o.order_id }))}
+ onLoadMoreBefore={result.loadFirst}
+ hasMoreBefore={!result.isFirstPage}
+ onLoadMoreAfter={result.loadNext}
+ hasMoreAfter={!result.isLastPage}
onSelectOrder={(order) => onSelect(order.id)}
onRefundOrder={(value) => setOrderToBeRefunded(value)}
isAllActive={isAllActive}
@@ -131,30 +129,27 @@ export default function OrderList({
isNotPaidActive={isNotPaidActive}
isRefundedActive={isRefundedActive}
jumpToDate={filter.date}
+ onSelectDate={setNewDate}
onCopyURL={async (id) => {
- if (state.status !== "loggedIn") {
- return false;
- }
- const resp = await lib.management.getOrder(state.token, id)
+ const resp = await lib.management.getOrderDetails(state.token, id);
if (resp.type === "ok") {
if (resp.body.order_status === "unpaid") {
- copyToClipboard(resp.body.taler_pay_uri)
+ copyToClipboard(resp.body.taler_pay_uri);
} else {
if (resp.body.contract_terms.fulfillment_url) {
- copyToClipboard(resp.body.contract_terms.fulfillment_url)
+ copyToClipboard(resp.body.contract_terms.fulfillment_url);
}
}
- copyToClipboard(resp.body.order_status)
+ copyToClipboard(resp.body.order_status);
}
}}
onCreate={onCreate}
- onSelectDate={setNewDate}
onShowAll={() => setFilter({})}
- onShowNotPaid={() => setFilter({ paid: "no" })}
- onShowPaid={() => setFilter({ paid: "yes" })}
- onShowRefunded={() => setFilter({ refunded: "yes" })}
- onShowNotWired={() => setFilter({ wired: "no", paid: "yes" })}
- onShowWired={() => setFilter({ wired: "yes" })}
+ onShowNotPaid={() => setFilter({ paid: false })}
+ onShowPaid={() => setFilter({ paid: true })}
+ onShowRefunded={() => setFilter({ refunded: true })}
+ onShowNotWired={() => setFilter({ wired: false, paid: true })}
+ onShowWired={() => setFilter({ wired: true })}
/>
{orderToBeRefunded && (
@@ -162,7 +157,8 @@ export default function OrderList({
id={orderToBeRefunded.order_id}
onCancel={() => setOrderToBeRefunded(undefined)}
onConfirm={(value) => {
- lib.management.addRefund(state.token, orderToBeRefunded.order_id, value)
+ lib.management
+ .addRefund(state.token, orderToBeRefunded.order_id, value)
.then(() =>
setNotif({
message: i18n.str`refund created successfully`,
@@ -176,27 +172,7 @@ export default function OrderList({
description: error.message,
}),
)
- .then(() => setOrderToBeRefunded(undefined))
-
- }}
- onLoadError={(error) => {
- setNotif({
- message: i18n.str`could not create the refund`,
- type: "ERROR",
- description: error.message,
- });
- setOrderToBeRefunded(undefined);
- return <div />;
- }}
- onUnauthorized={onUnauthorized}
- onNotFound={() => {
- setNotif({
- message: i18n.str`could not get the order to refund`,
- type: "ERROR",
- // description: error.message
- });
- setOrderToBeRefunded(undefined);
- return <div />;
+ .then(() => setOrderToBeRefunded(undefined));
}}
/>
)}
@@ -206,41 +182,39 @@ export default function OrderList({
interface RefundProps {
id: string;
- onUnauthorized: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
- onNotFound: () => VNode;
onCancel: () => void;
onConfirm: (m: TalerMerchantApi.RefundRequest) => void;
}
-function RefundModalForTable({
- id,
- onUnauthorized,
- onLoadError,
- onNotFound,
- onConfirm,
- onCancel,
-}: RefundProps): VNode {
+function RefundModalForTable({ id, onConfirm, onCancel }: RefundProps): VNode {
const result = useOrderDetails(id);
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ case HttpStatusCode.BadGateway: {
+ return <div>Failed to obtain a response from the exchange</div>;
+ }
+ case HttpStatusCode.GatewayTimeout: {
+ return (
+ <div>The merchant's interaction with the exchange took too long</div>
+ );
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return (
<RefundModal
- order={result.data}
+ order={result.body}
onCancel={onCancel}
onConfirm={onConfirm}
/>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx
index 06a9f4a55..c240b99cb 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/list/index.tsx
@@ -19,57 +19,53 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
+ HttpStatusCode,
+ TalerError,
+ TalerMerchantApi,
+ assertUnreachable
+} from "@gnu-taler/taler-util";
+import {
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
import { useSessionContext } from "../../../../context/session.js";
import { useInstanceOtpDevices } from "../../../../hooks/otp.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { ListPage } from "./ListPage.js";
interface Props {
- onUnauthorized: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
- onNotFound: () => VNode;
onCreate: () => void;
onSelect: (id: string) => void;
}
-export default function ListOtpDevices({
- onUnauthorized,
- onLoadError,
- onCreate,
- onSelect,
- onNotFound,
-}: Props): VNode {
- const [position, setPosition] = useState<string | undefined>(undefined);
+export default function ListOtpDevices({ onCreate, onSelect }: Props): VNode {
+ // const [position, setPosition] = useState<string | undefined>(undefined);
const { i18n } = useTranslationContext();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
const { lib } = useMerchantApiContext();
const { state } = useSessionContext();
- const result = useInstanceOtpDevices({ position }, (id) => setPosition(id));
+ const result = useInstanceOtpDevices();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ default: {
+ assertUnreachable(result.case);
+ }
+ }
}
return (
@@ -77,17 +73,16 @@ export default function ListOtpDevices({
<NotificationCard notification={notif} />
<ListPage
- devices={result.data.otp_devices}
- onLoadMoreBefore={
- result.isReachingStart ? result.loadMorePrev : undefined
- }
- onLoadMoreAfter={result.isReachingEnd ? result.loadMore : undefined}
+ devices={result.body}
+ onLoadMoreBefore={result.isFirstPage ? undefined : result.loadFirst}
+ onLoadMoreAfter={result.isLastPage ? undefined : result.loadNext}
onCreate={onCreate}
onSelect={(e) => {
onSelect(e.otp_device_id);
}}
onDelete={(e: TalerMerchantApi.OtpDeviceEntry) => {
- return lib.management.deleteOtpDevice(state.token, e.otp_device_id)
+ return lib.management
+ .deleteOtpDevice(state.token, e.otp_device_id)
.then(() =>
setNotif({
message: i18n.str`validator delete successfully`,
@@ -100,7 +95,7 @@ export default function ListOtpDevices({
type: "ERROR",
description: error.message,
}),
- )
+ );
}}
/>
</Fragment>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx
index 6b9970eab..43adbe253 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/otp_devices/update/index.tsx
@@ -19,20 +19,25 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
+ HttpStatusCode,
+ TalerError,
+ TalerMerchantApi,
+ assertUnreachable
+} from "@gnu-taler/taler-util";
+import {
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
import { useSessionContext } from "../../../../context/session.js";
import { useOtpDeviceDetails } from "../../../../hooks/otp.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { CreatedSuccessfully } from "../create/CreatedSuccessfully.js";
import { UpdatePage } from "./UpdatePage.js";
@@ -41,44 +46,39 @@ export type Entity = TalerMerchantApi.OtpDevicePatchDetails & WithId;
interface Props {
onBack?: () => void;
onConfirm: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
vid: string;
}
export default function UpdateValidator({
vid,
onConfirm,
onBack,
- onUnauthorized,
- onNotFound,
- onLoadError,
}: Props): VNode {
const result = useOtpDeviceDetails(vid);
const [notif, setNotif] = useState<Notification | undefined>(undefined);
- const [keyUpdated, setKeyUpdated] = useState<TalerMerchantApi.OtpDeviceAddDetails | null>(null)
+ const [keyUpdated, setKeyUpdated] =
+ useState<TalerMerchantApi.OtpDeviceAddDetails | null>(null);
const { lib } = useMerchantApiContext();
const { state } = useSessionContext();
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ default: {
+ assertUnreachable(result.case);
+ }
+ }
}
if (keyUpdated) {
- return <CreatedSuccessfully entity={keyUpdated} onConfirm={onConfirm} />
+ return <CreatedSuccessfully entity={keyUpdated} onConfirm={onConfirm} />;
}
return (
@@ -87,25 +87,47 @@ export default function UpdateValidator({
<UpdatePage
device={{
id: vid,
- otp_algorithm: result.data.otp_algorithm,
- otp_device_description: result.data.device_description,
+ otp_algorithm: result.body.otp_algorithm,
+ otp_device_description: result.body.device_description,
otp_key: "",
- otp_ctr: result.data.otp_ctr
+ otp_ctr: result.body.otp_ctr,
}}
onBack={onBack}
onUpdate={async (newInfo) => {
- return lib.management.updateOtpDevice(state.token, vid, newInfo)
+ return lib.management
+ .updateOtpDevice(state.token, vid, newInfo)
.then((d) => {
- if (newInfo.otp_key) {
- setKeyUpdated({
- otp_algorithm: newInfo.otp_algorithm,
- otp_device_description: newInfo.otp_device_description,
- otp_device_id: newInfo.id,
- otp_key: newInfo.otp_key,
- otp_ctr: newInfo.otp_ctr,
- })
+ if (d.type === "ok") {
+ if (newInfo.otp_key) {
+ setKeyUpdated({
+ otp_algorithm: newInfo.otp_algorithm,
+ otp_device_description: newInfo.otp_device_description,
+ otp_device_id: newInfo.id,
+ otp_key: newInfo.otp_key,
+ otp_ctr: newInfo.otp_ctr,
+ });
+ } else {
+ onConfirm();
+ }
} else {
- onConfirm()
+ switch(d.case) {
+ case HttpStatusCode.NotFound: {
+ setNotif({
+ message: i18n.str`Could not update template`,
+ type: "ERROR",
+ description: i18n.str`Template id is unknown`,
+ });
+ break;
+ }
+ case HttpStatusCode.Conflict: {
+ setNotif({
+ message: i18n.str`Could not update template`,
+ type: "ERROR",
+ description: i18n.str`The provided information is inconsistent with the current state of the template`,
+ });
+ break;
+ }
+ }
}
})
.catch((error) => {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
index ff54c487a..eb38f25d9 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/list/index.tsx
@@ -19,15 +19,14 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { JumpToElementById } from "../../../../components/form/JumpToElementById.js";
import { NotificationCard } from "../../../../components/menu/index.js";
@@ -37,21 +36,16 @@ import {
useInstanceProducts
} from "../../../../hooks/product.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { CardTable } from "./Table.js";
interface Props {
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
onCreate: () => void;
onSelect: (id: string) => void;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
}
export default function ProductList({
- onUnauthorized,
- onLoadError,
onCreate,
onSelect,
- onNotFound,
}: Props): VNode {
const result = useInstanceProducts();
const { lib } = useMerchantApiContext();
@@ -62,19 +56,19 @@ export default function ProductList({
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ default: {
+ assertUnreachable(result.case);
+ }
+ }
}
return (
@@ -92,7 +86,7 @@ export default function ProductList({
/>
<CardTable
- instances={result.data}
+ instances={result.body}
onCreate={onCreate}
onUpdate={async (id, prod) => {
try {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
index b9470ddac..9de632218 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/products/update/index.tsx
@@ -19,38 +19,32 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
+import { useSessionContext } from "../../../../context/session.js";
import { useProductDetails } from "../../../../hooks/product.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { UpdatePage } from "./UpdatePage.js";
-import { useSessionContext } from "../../../../context/session.js";
export type Entity = TalerMerchantApi.ProductAddDetail;
interface Props {
onBack?: () => void;
onConfirm: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
pid: string;
}
export default function UpdateProduct({
pid,
onConfirm,
onBack,
- onUnauthorized,
- onNotFound,
- onLoadError,
}: Props): VNode {
const result = useProductDetails(pid);
const [notif, setNotif] = useState<Notification | undefined>(undefined);
@@ -59,26 +53,26 @@ export default function UpdateProduct({
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ default: {
+ assertUnreachable(result.case);
+ }
+ }
}
return (
<Fragment>
<NotificationCard notification={notif} />
<UpdatePage
- product={{ ...result.data, product_id: pid }}
+ product={{ ...result.body, product_id: pid }}
onBack={onBack}
onUpdate={(data) => {
return lib.management.updateProduct(state.token, pid, data)
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
index 31e525226..82c0d0e53 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/create/CreatePage.tsx
@@ -23,6 +23,7 @@ import {
AmountString,
Amounts,
Duration,
+ TalerError,
TalerMerchantApi,
assertUnreachable,
} from "@gnu-taler/taler-util";
@@ -126,7 +127,7 @@ export function CreatePage({ onCreate, onBack }: Props): VNode {
};
const hasErrors = Object.keys(errors).some(
- (k) => (errors as any)[k] !== undefined,
+ (k) => (errors as Record<string,unknown>)[k] !== undefined,
);
const submitForm = () => {
@@ -185,7 +186,7 @@ export function CreatePage({ onCreate, onBack }: Props): VNode {
// return onCreate(state);
}
};
- const deviceList = !devices.ok ? [] : devices.data.otp_devices;
+ const deviceList = !devices || devices instanceof TalerError || devices.type === "fail" ? [] : devices.body;
return (
<div>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx
index adbfb93cd..5a8be71b0 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/list/index.tsx
@@ -19,15 +19,14 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
-import { Fragment, VNode, h } from "preact";
+import { VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { JumpToElementById } from "../../../../components/form/JumpToElementById.js";
import { NotificationCard } from "../../../../components/menu/index.js";
@@ -37,12 +36,10 @@ import {
useInstanceTemplates
} from "../../../../hooks/templates.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { ListPage } from "./ListPage.js";
interface Props {
- onUnauthorized: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
- onNotFound: () => VNode;
onCreate: () => void;
onSelect: (id: string) => void;
onNewOrder: (id: string) => void;
@@ -50,36 +47,32 @@ interface Props {
}
export default function ListTemplates({
- onUnauthorized,
- onLoadError,
onCreate,
onQR,
onSelect,
onNewOrder,
- onNotFound,
}: Props): VNode {
- const [position, setPosition] = useState<string | undefined>(undefined);
const { i18n } = useTranslationContext();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
const { lib } = useMerchantApiContext();
- const result = useInstanceTemplates({ position }, (id) => setPosition(id));
+ const result = useInstanceTemplates();
const [deleting, setDeleting] =
useState<TalerMerchantApi.TemplateEntry | null>(null);
const { state } = useSessionContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />
+ }
+ if (result.type === "fail") {
+ switch(result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />
+ }
+ default: {
+ assertUnreachable(result.case)
+ }
+ }
}
return (
@@ -88,7 +81,7 @@ export default function ListTemplates({
<JumpToElementById
testIfExist={async (id) => {
- const resp = await lib.management.getTemplate(state.token, id)
+ const resp = await lib.management.getTemplateDetails(state.token, id)
return resp.type === "ok"
}}
onSelect={onSelect}
@@ -97,11 +90,11 @@ export default function ListTemplates({
/>
<ListPage
- templates={result.data.templates}
+ templates={result.body}
onLoadMoreBefore={
- result.isReachingStart ? result.loadMorePrev : undefined
+ result.isFirstPage ? undefined: result.loadFirst
}
- onLoadMoreAfter={result.isReachingEnd ? result.loadMore : undefined}
+ onLoadMoreAfter={result.isLastPage ? undefined : result.loadNext}
onCreate={onCreate}
onSelect={(e) => {
onSelect(e.template_id);
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx
index 37f0e5c74..3464fb04e 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx
@@ -19,59 +19,44 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
-import {
- ErrorType,
- HttpError
-} from "@gnu-taler/web-util/browser";
-import { Fragment, VNode, h } from "preact";
-import { useState } from "preact/hooks";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
+import { VNode, h } from "preact";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
-import { NotificationCard } from "../../../../components/menu/index.js";
import {
useTemplateDetails
} from "../../../../hooks/templates.js";
-import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { QrPage } from "./QrPage.js";
export type Entity = TalerMerchantApi.TransferInformation;
interface Props {
onBack?: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
tid: string;
}
export default function TemplateQrPage({
tid,
onBack,
- onLoadError,
- onNotFound,
- onUnauthorized,
}: Props): VNode {
const result = useTemplateDetails(tid);
- const [notif, setNotif] = useState<Notification | undefined>(undefined);
-
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />
}
+ if (result.type === "fail") {
+ switch(result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />
+ }
+ default: {
+ assertUnreachable(result.case)
+ }
+ }
+ }
+
return (
- <>
- <NotificationCard notification={notif} />
- <QrPage contract={result.data.template_contract} id={tid} onBack={onBack} />
- </>
+ <QrPage contract={result.body.template_contract} id={tid} onBack={onBack} />
);
}
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
index f4092b61b..cf1c13fc4 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/UpdatePage.tsx
@@ -23,6 +23,7 @@ import {
AmountString,
Amounts,
Duration,
+ TalerError,
TalerMerchantApi,
assertUnreachable
} from "@gnu-taler/taler-util";
@@ -91,7 +92,7 @@ export function UpdatePage({ template, onUpdate, onBack }: Props): VNode {
type: intialStep,
});
const devices = useInstanceOtpDevices()
- const deviceList = !devices.ok ? [] : devices.data.otp_devices
+ const deviceList = !devices || devices instanceof TalerError || devices.type === "fail" ? [] : devices.body
const parsedPrice = !state.amount
? undefined
@@ -129,7 +130,7 @@ export function UpdatePage({ template, onUpdate, onBack }: Props): VNode {
};
const hasErrors = Object.keys(errors).some(
- (k) => (errors as any)[k] !== undefined,
+ (k) => (errors as Record<string,unknown>)[k] !== undefined,
);
const submitForm = () => {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
index fc436056a..1ff4b56cf 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/update/index.tsx
@@ -19,41 +19,35 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
+import { useSessionContext } from "../../../../context/session.js";
import {
useTemplateDetails,
} from "../../../../hooks/templates.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { UpdatePage } from "./UpdatePage.js";
-import { useSessionContext } from "../../../../context/session.js";
export type Entity = TalerMerchantApi.TemplatePatchDetails & WithId;
interface Props {
onBack?: () => void;
onConfirm: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
tid: string;
}
export default function UpdateTemplate({
tid,
onConfirm,
onBack,
- onUnauthorized,
- onNotFound,
- onLoadError,
}: Props): VNode {
const { lib } = useMerchantApiContext();
const { state } = useSessionContext();
@@ -62,26 +56,26 @@ export default function UpdateTemplate({
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />
+ }
+ if (result.type === "fail") {
+ switch(result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />
+ }
+ default: {
+ assertUnreachable(result.case)
+ }
+ }
}
return (
<Fragment>
<NotificationCard notification={notif} />
<UpdatePage
- template={{ ...result.data }}
+ template={result.body}
onBack={onBack}
onUpdate={(data) => {
return lib.management.updateTemplate(state.token, tid, data)
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx
index dd5d4aea3..0073ca574 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/use/index.tsx
@@ -19,31 +19,27 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
import {
useTemplateDetails
} from "../../../../hooks/templates.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { UsePage } from "./UsePage.js";
-import { useSessionContext } from "../../../../context/session.js";
export type Entity = TalerMerchantApi.TransferInformation;
interface Props {
onBack?: () => void;
onOrderCreated: (id: string) => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
tid: string;
}
@@ -51,36 +47,32 @@ export default function TemplateUsePage({
tid,
onOrderCreated,
onBack,
- onLoadError,
- onNotFound,
- onUnauthorized,
}: Props): VNode {
const { lib } = useMerchantApiContext();
- const { state } = useSessionContext();
const result = useTemplateDetails(tid);
const [notif, setNotif] = useState<Notification | undefined>(undefined);
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />
+ }
+ if (result.type === "fail") {
+ switch(result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />
+ }
+ default: {
+ assertUnreachable(result.case)
+ }
+ }
}
return (
<>
<NotificationCard notification={notif} />
<UsePage
- template={result.data}
+ template={result.body}
id={tid}
onBack={onBack}
onCreateOrder={(
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
index 16a4bda22..444283b13 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/token/index.tsx
@@ -13,38 +13,31 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { HttpStatusCode, TalerError, TalerErrorDetail } from "@gnu-taler/taler-util";
-import { ErrorType, HttpError, useMerchantApiContext, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { TalerError } from "@gnu-taler/taler-util";
+import { useMerchantApiContext, useTranslationContext } from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../components/exception/loading.js";
import { NotificationCard } from "../../../components/menu/index.js";
import { useSessionContext } from "../../../context/session.js";
import { useInstanceDetails } from "../../../hooks/instance.js";
import { Notification } from "../../../utils/types.js";
import { DetailPage } from "./DetailPage.js";
-import { ErrorLoadingMerchant } from "../../../components/ErrorLoadingMerchant.js";
interface Props {
- onUnauthorized: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
onChange: () => void;
- onNotFound: () => VNode;
onCancel: () => void;
}
export default function Token({
- onLoadError,
onChange,
- onUnauthorized,
- onNotFound,
onCancel,
}: Props): VNode {
const { i18n } = useTranslationContext();
const { lib } = useMerchantApiContext();
const { logIn } = useSessionContext();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
- // const { clearAccessToken } = useInstanceAPI();
const result = useInstanceDetails()
if (!result) return <Loading />
@@ -52,21 +45,6 @@ export default function Token({
return <ErrorLoadingMerchant error={result} />
}
- // if (result.loading) return <Loading />;
- // if (!result.ok) {
- // if (
- // result.type === ErrorType.CLIENT &&
- // result.status === HttpStatusCode.Unauthorized
- // )
- // return onUnauthorized();
- // if (
- // result.type === ErrorType.CLIENT &&
- // result.status === HttpStatusCode.NotFound
- // )
- // return onNotFound();
- // return onLoadError(result);
- // }
-
const hasToken = result.body.auth.method === "token"
return (
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
index ac1d692a4..35389f5f5 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/transfers/create/index.tsx
@@ -19,8 +19,11 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { TalerMerchantApi } from "@gnu-taler/taler-util";
-import { useMerchantApiContext, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { TalerError, TalerMerchantApi } from "@gnu-taler/taler-util";
+import {
+ useMerchantApiContext,
+ useTranslationContext,
+} from "@gnu-taler/web-util/browser";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
import { NotificationCard } from "../../../../components/menu/index.js";
@@ -41,9 +44,10 @@ export default function CreateTransfer({ onConfirm, onBack }: Props): VNode {
const [notif, setNotif] = useState<Notification | undefined>(undefined);
const { i18n } = useTranslationContext();
const instance = useInstanceBankAccounts();
- const accounts = !instance.ok
- ? []
- : instance.data.accounts.map((a) => a.payto_uri);
+ const accounts =
+ !instance || instance instanceof TalerError || instance.type === "fail"
+ ? []
+ : instance.body.map((a) => a.payto_uri);
return (
<>
@@ -52,7 +56,8 @@ export default function CreateTransfer({ onConfirm, onBack }: Props): VNode {
onBack={onBack}
accounts={accounts}
onCreate={(request: TalerMerchantApi.TransferInformation) => {
- return lib.management.informWireTransfer(state.token, request)
+ return lib.management
+ .informWireTransfer(state.token, request)
.then(() => onConfirm())
.catch((error) => {
setNotif({
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
index 15706b4c5..5edea377f 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/transfers/list/index.tsx
@@ -19,40 +19,34 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail } from "@gnu-taler/taler-util";
-import { ErrorType, HttpError } from "@gnu-taler/web-util/browser";
+import { TalerError } from "@gnu-taler/taler-util";
import { VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { useInstanceBankAccounts } from "../../../../hooks/bank.js";
import { useInstanceTransfers } from "../../../../hooks/transfer.js";
import { ListPage } from "./ListPage.js";
interface Props {
- onUnauthorized: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
- onNotFound: () => VNode;
onCreate: () => void;
}
interface Form {
- verified?: "yes" | "no";
+ verified?: boolean;
payto_uri?: string;
}
export default function ListTransfer({
- onUnauthorized,
- onLoadError,
onCreate,
- onNotFound,
}: Props): VNode {
- const setFilter = (s?: "yes" | "no") => setForm({ ...form, verified: s });
+ const setFilter = (s?: boolean) => setForm({ ...form, verified: s });
const [position, setPosition] = useState<string | undefined>(undefined);
const instance = useInstanceBankAccounts();
- const accounts = !instance.ok
+ const accounts = !instance || (instance instanceof TalerError) || instance.type === "fail"
? []
- : instance.data.accounts.map((a) => a.payto_uri);
+ : instance.body.map((a) => a.payto_uri);
const [form, setForm] = useState<Form>({ payto_uri: "" });
const shoulUseDefaultAccount = accounts.length === 1
@@ -62,8 +56,8 @@ export default function ListTransfer({
}
}, [shoulUseDefaultAccount])
- const isVerifiedTransfers = form.verified === "yes";
- const isNonVerifiedTransfers = form.verified === "no";
+ const isVerifiedTransfers = form.verified === true;
+ const isNonVerifiedTransfers = form.verified === false;
const isAllTransfers = form.verified === undefined;
const result = useInstanceTransfers(
@@ -75,37 +69,35 @@ export default function ListTransfer({
(id) => setPosition(id),
);
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
}
+ // if (result.type === "fail") {
+ // switch (result.case) {
+ // case HttpStatusCode.NotFound: {
+ // return <NotFoundPageOrAdminCreate />;
+ // }
+ // default: {
+ // assertUnreachable(result.case);
+ // }
+ // }
+ // }
+
return (
<ListPage
accounts={accounts}
- transfers={result.data.transfers}
- onLoadMoreBefore={
- result.isReachingStart ? result.loadMorePrev : undefined
- }
- onLoadMoreAfter={result.isReachingEnd ? result.loadMore : undefined}
+ transfers={result.body}
+ onLoadMoreBefore={result.isFirstPage ? undefined: result.loadFirst }
+ onLoadMoreAfter={result.isLastPage ? undefined : result.loadNext}
onCreate={onCreate}
onDelete={() => {
null;
}}
- // position={position} setPosition={setPosition}
onShowAll={() => setFilter(undefined)}
- onShowUnverified={() => setFilter("no")}
- onShowVerified={() => setFilter("yes")}
+ onShowUnverified={() => setFilter(false)}
+ onShowVerified={() => setFilter(true)}
isAllTransfers={isAllTransfers}
isVerifiedTransfers={isVerifiedTransfers}
isNonVerifiedTransfers={isNonVerifiedTransfers}
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
index 290bfa214..6dc5b9b02 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/update/index.tsx
@@ -13,35 +13,32 @@
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { HttpStatusCode, OperationOk, TalerError, TalerErrorDetail, TalerMerchantApi, TalerMerchantInstanceHttpClient } from "@gnu-taler/taler-util";
+import { OperationOk, TalerError, TalerMerchantApi, TalerMerchantInstanceHttpClient } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
- HttpResponse,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../components/exception/loading.js";
import { NotificationCard } from "../../../components/menu/index.js";
+import { useSessionContext } from "../../../context/session.js";
import {
useInstanceDetails,
useManagedInstanceDetails,
} from "../../../hooks/instance.js";
import { Notification } from "../../../utils/types.js";
import { UpdatePage } from "./UpdatePage.js";
-import { useSessionContext } from "../../../context/session.js";
-import { ErrorLoadingMerchant } from "../../../components/ErrorLoadingMerchant.js";
export interface Props {
onBack: () => void;
onConfirm: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
- onUpdateError: (e: HttpError<TalerErrorDetail>) => void;
+ // onUnauthorized: () => VNode;
+ // onNotFound: () => VNode;
+ // onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
+ // onUpdateError: (e: HttpError<TalerErrorDetail>) => void;
}
export default function Update(props: Props): VNode {
@@ -64,9 +61,6 @@ function CommonUpdate(
{
onBack,
onConfirm,
- onLoadError,
- onNotFound,
- onUnauthorized,
}: Props,
result: OperationOk<TalerMerchantApi.QueryInstancesResponse> | TalerError | undefined,
updateInstance: typeof TalerMerchantInstanceHttpClient.prototype.updateCurrentInstance,
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx
index 2923a8096..7c24a7228 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/list/index.tsx
@@ -20,58 +20,51 @@
*/
import {
- ErrorType,
- HttpError,
+ HttpStatusCode,
+ TalerError,
+ TalerMerchantApi,
+ assertUnreachable,
+} from "@gnu-taler/taler-util";
+import {
useMerchantApiContext,
useTranslationContext,
} from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
-import {
- useInstanceWebhooks,
-} from "../../../../hooks/webhooks.js";
+import { useSessionContext } from "../../../../context/session.js";
+import { useInstanceWebhooks } from "../../../../hooks/webhooks.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { ListPage } from "./ListPage.js";
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
-import { useSessionContext } from "../../../../context/session.js";
interface Props {
- onUnauthorized: () => VNode;
- onLoadError: (error: HttpError<TalerErrorDetail>) => VNode;
- onNotFound: () => VNode;
onCreate: () => void;
onSelect: (id: string) => void;
}
-export default function ListWebhooks({
- onUnauthorized,
- onLoadError,
- onCreate,
- onSelect,
- onNotFound,
-}: Props): VNode {
- const [position, setPosition] = useState<string | undefined>(undefined);
+export default function ListWebhooks({ onCreate, onSelect }: Props): VNode {
const { i18n } = useTranslationContext();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
const { lib } = useMerchantApiContext();
const { state } = useSessionContext();
- const result = useInstanceWebhooks({ position }, (id) => setPosition(id));
+ const result = useInstanceWebhooks();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ default: {
+ assertUnreachable(result.case);
+ }
+ }
}
return (
@@ -79,17 +72,16 @@ export default function ListWebhooks({
<NotificationCard notification={notif} />
<ListPage
- webhooks={result.data.webhooks}
- onLoadMoreBefore={
- result.isReachingStart ? result.loadMorePrev : undefined
- }
- onLoadMoreAfter={result.isReachingEnd ? result.loadMore : undefined}
+ webhooks={result.body}
+ onLoadMoreBefore={result.isFirstPage ? undefined : result.loadFirst}
+ onLoadMoreAfter={result.isLastPage ? undefined : result.loadNext}
onCreate={onCreate}
onSelect={(e) => {
onSelect(e.webhook_id);
}}
onDelete={(e: TalerMerchantApi.WebhookEntry) => {
- return lib.management.deleteWebhook(state.token, e.webhook_id)
+ return lib.management
+ .deleteWebhook(state.token, e.webhook_id)
.then(() =>
setNotif({
message: i18n.str`webhook delete successfully`,
@@ -102,7 +94,7 @@ export default function ListWebhooks({
type: "ERROR",
description: error.message,
}),
- )
+ );
}}
/>
</Fragment>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx
index aecb4b947..1c3172ffd 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/webhooks/update/index.tsx
@@ -19,41 +19,35 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
+import { HttpStatusCode, TalerError, TalerMerchantApi, assertUnreachable } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
useMerchantApiContext,
- useTranslationContext,
+ useTranslationContext
} from "@gnu-taler/web-util/browser";
-import { Fragment, h, VNode } from "preact";
+import { Fragment, VNode, h } from "preact";
import { useState } from "preact/hooks";
+import { ErrorLoadingMerchant } from "../../../../components/ErrorLoadingMerchant.js";
import { Loading } from "../../../../components/exception/loading.js";
import { NotificationCard } from "../../../../components/menu/index.js";
+import { useSessionContext } from "../../../../context/session.js";
import {
useWebhookDetails,
} from "../../../../hooks/webhooks.js";
import { Notification } from "../../../../utils/types.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { UpdatePage } from "./UpdatePage.js";
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
-import { useSessionContext } from "../../../../context/session.js";
export type Entity = TalerMerchantApi.WebhookPatchDetails & WithId;
interface Props {
onBack?: () => void;
onConfirm: () => void;
- onUnauthorized: () => VNode;
- onNotFound: () => VNode;
- onLoadError: (e: HttpError<TalerErrorDetail>) => VNode;
tid: string;
}
export default function UpdateWebhook({
tid,
onConfirm,
onBack,
- onUnauthorized,
- onNotFound,
- onLoadError,
}: Props): VNode {
const { lib } = useMerchantApiContext();
const { state } = useSessionContext();
@@ -62,26 +56,26 @@ export default function UpdateWebhook({
const { i18n } = useTranslationContext();
- if (result.loading) return <Loading />;
- if (!result.ok) {
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.Unauthorized
- )
- return onUnauthorized();
- if (
- result.type === ErrorType.CLIENT &&
- result.status === HttpStatusCode.NotFound
- )
- return onNotFound();
- return onLoadError(result);
+ if (!result) return <Loading />;
+ if (result instanceof TalerError) {
+ return <ErrorLoadingMerchant error={result} />;
+ }
+ if (result.type === "fail") {
+ switch (result.case) {
+ case HttpStatusCode.NotFound: {
+ return <NotFoundPageOrAdminCreate />;
+ }
+ default: {
+ assertUnreachable(result.case);
+ }
+ }
}
return (
<Fragment>
<NotificationCard notification={notif} />
<UpdatePage
- webhook={{ ...result.data, id: tid }}
+ webhook={{ ...result.body, id: tid }}
onBack={onBack}
onUpdate={(data) => {
return lib.management.updateWebhook(state.token, tid, data)
diff --git a/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
index 68adb79bf..d780b5988 100644
--- a/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/notfound/index.tsx
@@ -19,10 +19,18 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { h, VNode } from "preact";
-import { Link } from "preact-router";
+import { useTranslationContext } from "@gnu-taler/web-util/browser";
+import { Fragment, h, VNode } from "preact";
+import { Link, route } from "preact-router";
+import { NotificationCard } from "../../components/menu/index.js";
+import {
+ DEFAULT_ADMIN_USERNAME,
+ useSessionContext,
+} from "../../context/session.js";
+import InstanceCreatePage from "../../paths/admin/create/index.js";
+import { InstancePaths } from "../../Routing.js";
-export default function NotFoundPage(): VNode {
+export function NotFoundPage(): VNode {
return (
<div>
<p>That page doesn&apos;t exist.</p>
@@ -32,3 +40,29 @@ export default function NotFoundPage(): VNode {
</div>
);
}
+
+export function NotFoundPageOrAdminCreate(): VNode {
+ const { state } = useSessionContext();
+ const { i18n } = useTranslationContext();
+ if (state.isAdmin && state.instance === DEFAULT_ADMIN_USERNAME) {
+ return (
+ <Fragment>
+ <NotificationCard
+ notification={{
+ message: i18n.str`No 'default' instance configured yet.`,
+ description: i18n.str`Create a 'default' instance to begin using the merchant backoffice.`,
+ type: "INFO",
+ }}
+ />
+ <InstanceCreatePage
+ forceId={DEFAULT_ADMIN_USERNAME}
+ onConfirm={() => {
+ route(InstancePaths.bank_list);
+ }}
+ />
+ </Fragment>
+ );
+ }
+
+ return <NotFoundPage />
+}