summaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx')
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/list/index.tsx204
1 files changed, 102 insertions, 102 deletions
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 cd62685ca..8a1f85b1c 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,81 +19,87 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
-import { HttpStatusCode, TalerErrorDetail, TalerMerchantApi } from "@gnu-taler/taler-util";
import {
- ErrorType,
- HttpError,
- useTranslationContext,
+ AbsoluteTime,
+ HttpStatusCode,
+ TalerError,
+ TalerMerchantApi,
+ assertUnreachable,
+} from "@gnu-taler/taler-util";
+import {
+ 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,
- useOrderAPI,
useOrderDetails,
} from "../../../../hooks/order.js";
import { Notification } from "../../../../utils/types.js";
+import { LoginPage } from "../../../login/index.js";
+import { NotFoundPageOrAdminCreate } from "../../../notfound/index.js";
import { ListPage } from "./ListPage.js";
import { RefundModal } from "./Table.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 { refundOrder, getPaymentURL } = useOrderAPI();
+ const result = useInstanceOrders(filter, (d) =>
+ setFilter({ ...filter, position: d }),
+ );
+ const { lib } = useSessionContext();
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);
+ 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.Unauthorized: {
+ return <LoginPage />
+ }
+ default: {
+ assertUnreachable(result)
+ }
+ }
}
- 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" : "";
+ 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"
: "";
@@ -102,18 +108,19 @@ export default function OrderList({
<NotificationCard notification={notif} />
<JumpToElementById
- testIfExist={getPaymentURL}
+ testIfExist={async (order) => {
+ const resp = await lib.instance.getOrderDetails(state.token, order);
+ return resp.type === "ok";
+ }}
onSelect={onSelect}
description={i18n.str`jump to order with the given product ID`}
placeholder={i18n.str`order id`}
/>
<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.isFirstPage ? undefined : result.loadFirst}
+ onLoadMoreAfter={result.isLastPage ? undefined : result.loadNext}
onSelectOrder={(order) => onSelect(order.id)}
onRefundOrder={(value) => setOrderToBeRefunded(value)}
isAllActive={isAllActive}
@@ -123,25 +130,36 @@ export default function OrderList({
isNotPaidActive={isNotPaidActive}
isRefundedActive={isRefundedActive}
jumpToDate={filter.date}
- onCopyURL={(id) =>
- getPaymentURL(id).then((resp) => copyToClipboard(resp.data))
- }
- onCreate={onCreate}
onSelectDate={setNewDate}
+ onCopyURL={async (id) => {
+ const resp = await lib.instance.getOrderDetails(state.token, id);
+ if (resp.type === "ok") {
+ if (resp.body.order_status === "unpaid") {
+ copyToClipboard(resp.body.taler_pay_uri);
+ } else {
+ if (resp.body.contract_terms.fulfillment_url) {
+ copyToClipboard(resp.body.contract_terms.fulfillment_url);
+ }
+ }
+ copyToClipboard(resp.body.order_status);
+ }
+ }}
+ onCreate={onCreate}
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 && (
<RefundModalForTable
id={orderToBeRefunded.order_id}
onCancel={() => setOrderToBeRefunded(undefined)}
- onConfirm={(value) =>
- refundOrder(orderToBeRefunded.order_id, value)
+ onConfirm={(value) => {
+ lib.instance
+ .addRefund(state.token, orderToBeRefunded.order_id, value)
.then(() =>
setNotif({
message: i18n.str`refund created successfully`,
@@ -155,26 +173,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));
}}
/>
)}
@@ -184,41 +183,42 @@ 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>
+ );
+ }
+ case HttpStatusCode.Unauthorized: {
+ return <LoginPage />
+ }
+ default: {
+ assertUnreachable(result);
+ }
+ }
}
return (
<RefundModal
- order={result.data}
+ order={result.body}
onCancel={onCancel}
onConfirm={onConfirm}
/>