aboutsummaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/paths/instance/reserves/list
diff options
context:
space:
mode:
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/reserves/list')
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeRewardModal.tsx (renamed from packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeTipModal.tsx)40
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx18
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx6
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx39
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx82
5 files changed, 112 insertions, 73 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeTipModal.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeRewardModal.tsx
index 1882f50d3..e205ee621 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeTipModal.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/AutorizeRewardModal.tsx
@@ -34,32 +34,32 @@ import {
ContinueModal,
} from "../../../../components/modal/index.js";
import { MerchantBackend } from "../../../../declaration.js";
-import { AuthorizeTipSchema } from "../../../../schemas/index.js";
+import { AuthorizeRewardSchema } from "../../../../schemas/index.js";
import { CreatedSuccessfully } from "./CreatedSuccessfully.js";
-interface AuthorizeTipModalProps {
+interface AuthorizeRewardModalProps {
onCancel: () => void;
- onConfirm: (value: MerchantBackend.Tips.TipCreateRequest) => void;
- tipAuthorized?: {
- response: MerchantBackend.Tips.TipCreateConfirmation;
- request: MerchantBackend.Tips.TipCreateRequest;
+ onConfirm: (value: MerchantBackend.Rewards.RewardCreateRequest) => void;
+ rewardAuthorized?: {
+ response: MerchantBackend.Rewards.RewardCreateConfirmation;
+ request: MerchantBackend.Rewards.RewardCreateRequest;
};
}
-export function AuthorizeTipModal({
+export function AuthorizeRewardModal({
onCancel,
onConfirm,
- tipAuthorized,
-}: AuthorizeTipModalProps): VNode {
+ rewardAuthorized,
+}: AuthorizeRewardModalProps): VNode {
// const result = useOrderDetails(id)
- type State = MerchantBackend.Tips.TipCreateRequest;
+ type State = MerchantBackend.Rewards.RewardCreateRequest;
const [form, setValue] = useState<Partial<State>>({});
const { i18n } = useTranslationContext();
// const [errors, setErrors] = useState<FormErrors<State>>({})
let errors: FormErrors<State> = {};
try {
- AuthorizeTipSchema.validateSync(form, { abortEarly: false });
+ AuthorizeRewardSchema.validateSync(form, { abortEarly: false });
} catch (err) {
if (err instanceof yup.ValidationError) {
const yupErrors = err.inner as any[];
@@ -77,12 +77,12 @@ export function AuthorizeTipModal({
const validateAndConfirm = () => {
onConfirm(form as State);
};
- if (tipAuthorized) {
+ if (rewardAuthorized) {
return (
- <ContinueModal description="tip" active onConfirm={onCancel}>
+ <ContinueModal description="reward" active onConfirm={onCancel}>
<CreatedSuccessfully
- entity={tipAuthorized.response}
- request={tipAuthorized.request}
+ entity={rewardAuthorized.response}
+ request={rewardAuthorized.request}
onConfirm={onCancel}
/>
</ContinueModal>
@@ -91,7 +91,7 @@ export function AuthorizeTipModal({
return (
<ConfirmModal
- description="tip"
+ description="New reward"
active
onCancel={onCancel}
disabled={hasErrors}
@@ -105,18 +105,18 @@ export function AuthorizeTipModal({
<InputCurrency<State>
name="amount"
label={i18n.str`Amount`}
- tooltip={i18n.str`amount of tip`}
+ tooltip={i18n.str`amount of reward`}
/>
<Input<State>
name="justification"
label={i18n.str`Justification`}
inputType="multiline"
- tooltip={i18n.str`reason for the tip`}
+ tooltip={i18n.str`reason for the reward`}
/>
<Input<State>
name="next_url"
- label={i18n.str`URL after tip`}
- tooltip={i18n.str`URL to visit after tip payment`}
+ label={i18n.str`URL after reward`}
+ tooltip={i18n.str`URL to visit after reward payment`}
/>
</FormProvider>
</ConfirmModal>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx
index 643651b52..b78236bc7 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/CreatedSuccessfully.tsx
@@ -17,12 +17,13 @@ import { format } from "date-fns";
import { Fragment, h, VNode } from "preact";
import { CreatedSuccessfully as Template } from "../../../../components/notifications/CreatedSuccessfully.js";
import { MerchantBackend } from "../../../../declaration.js";
+import { datetimeFormatForSettings, useSettings } from "../../../../hooks/useSettings.js";
-type Entity = MerchantBackend.Tips.TipCreateConfirmation;
+type Entity = MerchantBackend.Rewards.RewardCreateConfirmation;
interface Props {
entity: Entity;
- request: MerchantBackend.Tips.TipCreateRequest;
+ request: MerchantBackend.Rewards.RewardCreateRequest;
onConfirm: () => void;
onCreateAnother?: () => void;
}
@@ -33,6 +34,7 @@ export function CreatedSuccessfully({
onConfirm,
onCreateAnother,
}: Props): VNode {
+ const [settings] = useSettings();
return (
<Fragment>
<div class="field is-horizontal">
@@ -66,7 +68,7 @@ export function CreatedSuccessfully({
<div class="field-body is-flex-grow-3">
<div class="field">
<p class="control">
- <input readonly class="input" value={entity.tip_status_url} />
+ <input readonly class="input" value={entity.reward_status_url} />
</p>
</div>
</div>
@@ -82,13 +84,13 @@ export function CreatedSuccessfully({
class="input"
readonly
value={
- !entity.tip_expiration ||
- entity.tip_expiration.t_s === "never"
+ !entity.reward_expiration ||
+ entity.reward_expiration.t_s === "never"
? "never"
: format(
- entity.tip_expiration.t_s * 1000,
- "yyyy/MM/dd HH:mm:ss",
- )
+ entity.reward_expiration.t_s * 1000,
+ datetimeFormatForSettings(settings),
+ )
}
/>
</p>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx
index fe305f4fd..b070bbde3 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/List.stories.tsx
@@ -25,12 +25,6 @@ import { CardTable as TestedComponent } from "./Table.js";
export default {
title: "Pages/Reserve/List",
component: TestedComponent,
- argTypes: {
- onCreate: { action: "onCreate" },
- onDelete: { action: "onDelete" },
- onNewTip: { action: "onNewTip" },
- onSelect: { action: "onSelect" },
- },
};
function createExample<Props>(
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx
index 1f229d7cb..795e7ec82 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/Table.tsx
@@ -23,12 +23,13 @@ import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { format } from "date-fns";
import { Fragment, h, VNode } from "preact";
import { MerchantBackend, WithId } from "../../../../declaration.js";
+import { datetimeFormatForSettings, useSettings } from "../../../../hooks/useSettings.js";
-type Entity = MerchantBackend.Tips.ReserveStatusEntry & WithId;
+type Entity = MerchantBackend.Rewards.ReserveStatusEntry & WithId;
interface Props {
instances: Entity[];
- onNewTip: (id: Entity) => void;
+ onNewReward: (id: Entity) => void;
onSelect: (id: Entity) => void;
onDelete: (id: Entity) => void;
onCreate: () => void;
@@ -38,7 +39,7 @@ export function CardTable({
instances,
onCreate,
onSelect,
- onNewTip,
+ onNewReward,
onDelete,
}: Props): VNode {
const [withoutFunds, withFunds] = instances.reduce((prev, current) => {
@@ -70,7 +71,7 @@ export function CardTable({
<div class="table-wrapper has-mobile-cards">
<TableWithoutFund
instances={withoutFunds}
- onNewTip={onNewTip}
+ onNewReward={onNewReward}
onSelect={onSelect}
onDelete={onDelete}
/>
@@ -108,7 +109,7 @@ export function CardTable({
{withFunds.length > 0 ? (
<Table
instances={withFunds}
- onNewTip={onNewTip}
+ onNewReward={onNewReward}
onSelect={onSelect}
onDelete={onDelete}
/>
@@ -124,13 +125,14 @@ export function CardTable({
}
interface TableProps {
instances: Entity[];
- onNewTip: (id: Entity) => void;
+ onNewReward: (id: Entity) => void;
onDelete: (id: Entity) => void;
onSelect: (id: Entity) => void;
}
-function Table({ instances, onNewTip, onSelect, onDelete }: TableProps): VNode {
+function Table({ instances, onNewReward, onSelect, onDelete }: TableProps): VNode {
const { i18n } = useTranslationContext();
+ const [settings] = useSettings();
return (
<div class="table-container">
<table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
@@ -164,7 +166,7 @@ function Table({ instances, onNewTip, onSelect, onDelete }: TableProps): VNode {
>
{i.creation_time.t_s === "never"
? "never"
- : format(i.creation_time.t_s * 1000, "yyyy/MM/dd HH:mm:ss")}
+ : format(i.creation_time.t_s * 1000, datetimeFormatForSettings(settings))}
</td>
<td
onClick={(): void => onSelect(i)}
@@ -173,9 +175,9 @@ function Table({ instances, onNewTip, onSelect, onDelete }: TableProps): VNode {
{i.expiration_time.t_s === "never"
? "never"
: format(
- i.expiration_time.t_s * 1000,
- "yyyy/MM/dd HH:mm:ss",
- )}
+ i.expiration_time.t_s * 1000,
+ datetimeFormatForSettings(settings),
+ )}
</td>
<td
onClick={(): void => onSelect(i)}
@@ -207,11 +209,11 @@ function Table({ instances, onNewTip, onSelect, onDelete }: TableProps): VNode {
</button>
<button
class="button is-small is-info has-tooltip-left"
- data-tooltip={i18n.str`authorize new tip from selected reserve`}
+ data-tooltip={i18n.str`authorize new reward from selected reserve`}
type="button"
- onClick={(): void => onNewTip(i)}
+ onClick={(): void => onNewReward(i)}
>
- New Tip
+ New Reward
</button>
</div>
</td>
@@ -249,6 +251,7 @@ function TableWithoutFund({
onDelete,
}: TableProps): VNode {
const { i18n } = useTranslationContext();
+ const [settings] = useSettings();
return (
<div class="table-container">
<table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
@@ -276,7 +279,7 @@ function TableWithoutFund({
>
{i.creation_time.t_s === "never"
? "never"
- : format(i.creation_time.t_s * 1000, "yyyy/MM/dd HH:mm:ss")}
+ : format(i.creation_time.t_s * 1000, datetimeFormatForSettings(settings))}
</td>
<td
onClick={(): void => onSelect(i)}
@@ -285,9 +288,9 @@ function TableWithoutFund({
{i.expiration_time.t_s === "never"
? "never"
: format(
- i.expiration_time.t_s * 1000,
- "yyyy/MM/dd HH:mm:ss",
- )}
+ i.expiration_time.t_s * 1000,
+ datetimeFormatForSettings(settings),
+ )}
</td>
<td
onClick={(): void => onSelect(i)}
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
index 14387c2a9..b26ff0000 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/list/index.tsx
@@ -34,9 +34,10 @@ import {
useReservesAPI,
} from "../../../../hooks/reserves.js";
import { Notification } from "../../../../utils/types.js";
-import { AuthorizeTipModal } from "./AutorizeTipModal.js";
+import { AuthorizeRewardModal } from "./AutorizeRewardModal.js";
import { CardTable } from "./Table.js";
import { HttpStatusCode } from "@gnu-taler/taler-util";
+import { ConfirmModal } from "../../../../components/modal/index.js";
interface Props {
onUnauthorized: () => VNode;
@@ -46,12 +47,12 @@ interface Props {
onCreate: () => void;
}
-interface TipConfirmation {
- response: MerchantBackend.Tips.TipCreateConfirmation;
- request: MerchantBackend.Tips.TipCreateRequest;
+interface RewardConfirmation {
+ response: MerchantBackend.Rewards.RewardCreateConfirmation;
+ request: MerchantBackend.Rewards.RewardCreateRequest;
}
-export default function ListTips({
+export default function ListRewards({
onUnauthorized,
onLoadError,
onNotFound,
@@ -59,14 +60,16 @@ export default function ListTips({
onCreate,
}: Props): VNode {
const result = useInstanceReserves();
- const { deleteReserve, authorizeTipReserve } = useReservesAPI();
+ const { deleteReserve, authorizeRewardReserve } = useReservesAPI();
const [notif, setNotif] = useState<Notification | undefined>(undefined);
const { i18n } = useTranslationContext();
- const [reserveForTip, setReserveForTip] = useState<string | undefined>(
+ const [reserveForReward, setReserveForReward] = useState<string | undefined>(
undefined,
);
- const [tipAuthorized, setTipAuthorized] = useState<
- TipConfirmation | undefined
+ const [deleting, setDeleting] =
+ useState<MerchantBackend.Rewards.ReserveStatusEntry | null>(null);
+ const [rewardAuthorized, setRewardAuthorized] = useState<
+ RewardConfirmation | undefined
>(undefined);
if (result.loading) return <Loading />;
@@ -88,30 +91,30 @@ export default function ListTips({
<section class="section is-main-section">
<NotificationCard notification={notif} />
- {reserveForTip && (
- <AuthorizeTipModal
+ {reserveForReward && (
+ <AuthorizeRewardModal
onCancel={() => {
- setReserveForTip(undefined);
- setTipAuthorized(undefined);
+ setReserveForReward(undefined);
+ setRewardAuthorized(undefined);
}}
- tipAuthorized={tipAuthorized}
+ rewardAuthorized={rewardAuthorized}
onConfirm={async (request) => {
try {
- const response = await authorizeTipReserve(
- reserveForTip,
+ const response = await authorizeRewardReserve(
+ reserveForReward,
request,
);
- setTipAuthorized({
+ setRewardAuthorized({
request,
response: response.data,
});
} catch (error) {
setNotif({
- message: i18n.str`could not create the tip`,
+ message: i18n.str`could not create the reward`,
type: "ERROR",
description: error instanceof Error ? error.message : undefined,
});
- setReserveForTip(undefined);
+ setReserveForReward(undefined);
}
}}
/>
@@ -122,10 +125,47 @@ export default function ListTips({
.filter((r) => r.active)
.map((o) => ({ ...o, id: o.reserve_pub }))}
onCreate={onCreate}
- onDelete={(reserve) => deleteReserve(reserve.reserve_pub)}
+ onDelete={(reserve) => {
+ setDeleting(reserve)
+ }}
onSelect={(reserve) => onSelect(reserve.id)}
- onNewTip={(reserve) => setReserveForTip(reserve.id)}
+ onNewReward={(reserve) => setReserveForReward(reserve.id)}
/>
+
+ {deleting && (
+ <ConfirmModal
+ label={`Delete reserve`}
+ description={`Delete the reserve`}
+ danger
+ active
+ onCancel={() => setDeleting(null)}
+ onConfirm={async (): Promise<void> => {
+ try {
+ await deleteReserve(deleting.reserve_pub);
+ setNotif({
+ message: i18n.str`Reserve for "${deleting.merchant_initial_amount}" (ID: ${deleting.reserve_pub}) has been deleted`,
+ type: "SUCCESS",
+ });
+ } catch (error) {
+ setNotif({
+ message: i18n.str`Failed to delete reserve`,
+ type: "ERROR",
+ description: error instanceof Error ? error.message : undefined,
+ });
+ }
+ setDeleting(null);
+ }}
+ >
+ <p>
+ If you delete the reserve for <b>&quot;{deleting.merchant_initial_amount}&quot;</b> you won't be able to create more rewards. <br />
+ Reserve ID: <b>{deleting.reserve_pub}</b>
+ </p>
+ <p class="warning">
+ Deleting an template <b>cannot be undone</b>.
+ </p>
+ </ConfirmModal>
+ )}
+
</section>
);
}