aboutsummaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/paths/instance/reserves
diff options
context:
space:
mode:
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/reserves')
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx14
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx22
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx8
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx36
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx6
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/reserves/details/RewardInfo.tsx (renamed from packages/merchant-backoffice-ui/src/paths/instance/reserves/details/TipInfo.tsx)23
-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
11 files changed, 168 insertions, 126 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
index fccb20121..2201e75a5 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatePage.tsx
@@ -36,7 +36,7 @@ import {
URL_REGEX,
} from "../../../../utils/constants.js";
-type Entity = MerchantBackend.Tips.ReserveCreateRequest;
+type Entity = MerchantBackend.Rewards.ReserveCreateRequest;
interface Props {
onCreate: (d: Entity) => Promise<void>;
@@ -80,15 +80,15 @@ function ViewStep({
initial_balance: !reserve.initial_balance
? "cannot be empty"
: !(parseInt(reserve.initial_balance.split(":")[1], 10) > 0)
- ? i18n.str`it should be greater than 0`
- : undefined,
+ ? i18n.str`it should be greater than 0`
+ : undefined,
exchange_url: !reserve.exchange_url
? i18n.str`cannot be empty`
: !URL_REGEX.test(reserve.exchange_url)
- ? i18n.str`must be a valid URL`
- : !exchangeQueryError
- ? undefined
- : exchangeQueryError,
+ ? i18n.str`must be a valid URL`
+ : !exchangeQueryError
+ ? undefined
+ : exchangeQueryError,
};
const hasErrors = Object.keys(errors).some(
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx
index 94fcdaff7..1d512c843 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/CreatedSuccessfully.tsx
@@ -22,8 +22,8 @@ import { CreatedSuccessfully as Template } from "../../../../components/notifica
import { MerchantBackend, WireAccount } from "../../../../declaration.js";
type Entity = {
- request: MerchantBackend.Tips.ReserveCreateRequest;
- response: MerchantBackend.Tips.ReserveCreateConfirmation;
+ request: MerchantBackend.Rewards.ReserveCreateRequest;
+ response: MerchantBackend.Rewards.ReserveCreateConfirmation;
};
interface Props {
@@ -98,15 +98,15 @@ export function ShowAccountsOfReserveAsQRWithLink({
const accountsInfo = !accounts
? []
: accounts
- .map((acc) => {
- const p = parsePaytoUri(acc.payto_uri);
- if (p) {
- p.params["message"] = message;
- p.params["amount"] = amount;
- }
- return p;
- })
- .filter(isNotUndefined);
+ .map((acc) => {
+ const p = parsePaytoUri(acc.payto_uri);
+ if (p) {
+ p.params["message"] = message;
+ p.params["amount"] = amount;
+ }
+ return p;
+ })
+ .filter(isNotUndefined);
const links = accountsInfo.map((a) => stringifyPaytoUri(a));
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx
index 8a4fe1565..4bbaf1459 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/create/index.tsx
@@ -39,9 +39,9 @@ export default function CreateReserve({ onBack, onConfirm }: Props): VNode {
const [createdOk, setCreatedOk] = useState<
| {
- request: MerchantBackend.Tips.ReserveCreateRequest;
- response: MerchantBackend.Tips.ReserveCreateConfirmation;
- }
+ request: MerchantBackend.Rewards.ReserveCreateRequest;
+ response: MerchantBackend.Rewards.ReserveCreateConfirmation;
+ }
| undefined
>(undefined);
@@ -54,7 +54,7 @@ export default function CreateReserve({ onBack, onConfirm }: Props): VNode {
<NotificationCard notification={notif} />
<CreatePage
onBack={onBack}
- onCreate={(request: MerchantBackend.Tips.ReserveCreateRequest) => {
+ onCreate={(request: MerchantBackend.Rewards.ReserveCreateRequest) => {
return createReserve(request)
.then((r) => setCreatedOk({ request, response: r.data }))
.catch((error) => {
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx
index b0173b5d3..d8840eeac 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/DetailPage.tsx
@@ -36,11 +36,12 @@ import { InputDate } from "../../../../components/form/InputDate.js";
import { TextField } from "../../../../components/form/TextField.js";
import { SimpleModal } from "../../../../components/modal/index.js";
import { MerchantBackend } from "../../../../declaration.js";
-import { useTipDetails } from "../../../../hooks/reserves.js";
-import { TipInfo } from "./TipInfo.js";
+import { useRewardDetails } from "../../../../hooks/reserves.js";
+import { RewardInfo } from "./RewardInfo.js";
import { ShowAccountsOfReserveAsQRWithLink } from "../create/CreatedSuccessfully.js";
+import { datetimeFormatForSettings, useSettings } from "../../../../hooks/useSettings.js";
-type Entity = MerchantBackend.Tips.ReserveDetail;
+type Entity = MerchantBackend.Rewards.ReserveDetail;
type CT = MerchantBackend.ContractTerms;
interface Props {
@@ -116,14 +117,14 @@ export function DetailPage({ id, selected, onBack }: Props): VNode {
<span class="icon">
<i class="mdi mdi-cash-register" />
</span>
- <i18n.Translate>Tips</i18n.Translate>
+ <i18n.Translate>Rewards</i18n.Translate>
</p>
</header>
<div class="card-content">
<div class="b-table has-pagination">
<div class="table-wrapper has-mobile-cards">
- {selected.tips && selected.tips.length > 0 ? (
- <Table tips={selected.tips} />
+ {selected.rewards && selected.rewards.length > 0 ? (
+ <Table rewards={selected.rewards} />
) : (
<EmptyTable />
)}
@@ -163,7 +164,7 @@ function EmptyTable(): VNode {
</p>
<p>
<i18n.Translate>
- No tips has been authorized from this reserve
+ No reward has been authorized from this reserve
</i18n.Translate>
</p>
</div>
@@ -171,10 +172,10 @@ function EmptyTable(): VNode {
}
interface TableProps {
- tips: MerchantBackend.Tips.TipStatusEntry[];
+ rewards: MerchantBackend.Rewards.RewardStatusEntry[];
}
-function Table({ tips }: TableProps): VNode {
+function Table({ rewards }: TableProps): VNode {
const { i18n } = useTranslationContext();
return (
<div class="table-container">
@@ -196,8 +197,8 @@ function Table({ tips }: TableProps): VNode {
</tr>
</thead>
<tbody>
- {tips.map((t, i) => {
- return <TipRow id={t.tip_id} key={i} entry={t} />;
+ {rewards.map((t, i) => {
+ return <RewardRow id={t.reward_id} key={i} entry={t} />;
})}
</tbody>
</table>
@@ -205,15 +206,16 @@ function Table({ tips }: TableProps): VNode {
);
}
-function TipRow({
+function RewardRow({
id,
entry,
}: {
id: string;
- entry: MerchantBackend.Tips.TipStatusEntry;
+ entry: MerchantBackend.Rewards.RewardStatusEntry;
}) {
const [selected, setSelected] = useState(false);
- const result = useTipDetails(id);
+ const result = useRewardDetails(id);
+ const [settings] = useSettings();
if (result.loading) {
return (
<tr>
@@ -242,11 +244,11 @@ function TipRow({
<Fragment>
{selected && (
<SimpleModal
- description="tip"
+ description="reward"
active
onCancel={() => setSelected(false)}
>
- <TipInfo id={id} amount={info.total_authorized} entity={info} />
+ <RewardInfo id={id} amount={info.total_authorized} entity={info} />
</SimpleModal>
)}
<tr>
@@ -256,7 +258,7 @@ function TipRow({
<td onClick={onSelect}>
{info.expiration.t_s === "never"
? "never"
- : format(info.expiration.t_s * 1000, "yyyy/MM/dd HH:mm:ss")}
+ : format(info.expiration.t_s * 1000, datetimeFormatForSettings(settings))}
</td>
</tr>
</Fragment>
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx
index 2592e2c6e..41c715f20 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/Details.stories.tsx
@@ -92,7 +92,7 @@ export const NotYetFunded = createExample(TestedComponent, {
},
});
-export const FundedWithEmptyTips = createExample(TestedComponent, {
+export const FundedWithEmptyRewards = createExample(TestedComponent, {
id: "THISISTHERESERVEID",
selected: {
active: true,
@@ -115,10 +115,10 @@ export const FundedWithEmptyTips = createExample(TestedComponent, {
},
],
exchange_url: "http://exchange.taler/",
- tips: [
+ rewards: [
{
reason: "asdasd",
- tip_id: "123",
+ reward_id: "123",
total_amount: "TESTKUDOS:1",
},
],
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/TipInfo.tsx b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/RewardInfo.tsx
index 360d39aba..57a051ed7 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/TipInfo.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/reserves/details/RewardInfo.tsx
@@ -17,8 +17,10 @@ import { format } from "date-fns";
import { Fragment, h, VNode } from "preact";
import { useBackendContext } from "../../../../context/backend.js";
import { MerchantBackend } from "../../../../declaration.js";
+import { datetimeFormatForSettings, useSettings } from "../../../../hooks/useSettings.js";
+import { stringifyRewardUri } from "@gnu-taler/taler-util";
-type Entity = MerchantBackend.Tips.TipDetails;
+type Entity = MerchantBackend.Rewards.RewardDetails;
interface Props {
id: string;
@@ -26,11 +28,10 @@ interface Props {
amount: string;
}
-export function TipInfo({ id, amount, entity }: Props): VNode {
- const { url } = useBackendContext();
- const tipHost = url.replace(/.*:\/\//, ""); // remove protocol part
- const proto = url.startsWith("http://") ? "taler+http" : "taler";
- const tipURL = `${proto}://tip/${tipHost}/${id}`;
+export function RewardInfo({ id: merchantRewardId, amount, entity }: Props): VNode {
+ const { url: merchantBaseUrl } = useBackendContext();
+ const [settings] = useSettings();
+ const rewardURL = stringifyRewardUri({ merchantBaseUrl, merchantRewardId })
return (
<Fragment>
<div class="field is-horizontal">
@@ -52,8 +53,8 @@ export function TipInfo({ id, amount, entity }: Props): VNode {
<div class="field-body is-flex-grow-3">
<div class="field" style={{ overflowWrap: "anywhere" }}>
<p class="control">
- <a target="_blank" rel="noreferrer" href={tipURL}>
- {tipURL}
+ <a target="_blank" rel="noreferrer" href={rewardURL}>
+ {rewardURL}
</a>
</p>
</div>
@@ -73,9 +74,9 @@ export function TipInfo({ id, amount, entity }: Props): VNode {
!entity.expiration || entity.expiration.t_s === "never"
? "never"
: format(
- entity.expiration.t_s * 1000,
- "yyyy/MM/dd HH:mm:ss",
- )
+ entity.expiration.t_s * 1000,
+ datetimeFormatForSettings(settings),
+ )
}
/>
</p>
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>
);
}