/*
This file is part of GNU Taler
(C) 2021-2024 Taler Systems S.A.
GNU Taler is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
GNU Taler; see the file COPYING. If not, see
*/
/**
*
* @author Christian Blättler
*/
import { useTranslationContext } from "@gnu-taler/web-util/browser";
import { h } from "preact";
import { useCallback, useEffect, useState } from "preact/hooks";
import * as yup from "yup";
import { TokenFamilyCreateSchema } from "../../schemas/index.js";
import { FormErrors, FormProvider } from "../form/FormProvider.js";
import { Input } from "../form/Input.js";
import { InputWithAddon } from "../form/InputWithAddon.js";
import { InputDate } from "../form/InputDate.js";
import { InputDuration } from "../form/InputDuration.js";
import { InputSelector } from "../form/InputSelector.js";
import { useSessionContext } from "../../context/session.js";
import { TalerMerchantApi } from "@gnu-taler/taler-util";
type Entity = TalerMerchantApi.TokenFamilyCreateRequest;
interface Props {
onSubscribe: (c?: () => Entity | undefined) => void;
initial?: Partial;
alreadyExist?: boolean;
}
export function TokenFamilyForm({ onSubscribe }: Props) {
const [value, valueHandler] = useState>({
slug: "",
name: "",
description: "",
description_i18n: {},
kind: TalerMerchantApi.TokenFamilyKind.Discount,
duration: { d_us: "forever" },
valid_after: { t_s: "never" },
valid_before: { t_s: "never" },
});
let errors: FormErrors = {};
try {
TokenFamilyCreateSchema.validateSync(value, {
abortEarly: false,
});
} catch (err) {
if (err instanceof yup.ValidationError) {
const yupErrors = err.inner as yup.ValidationError[];
errors = yupErrors.reduce(
(prev, cur) =>
!cur.path ? prev : { ...prev, [cur.path]: cur.message },
{},
);
}
}
const hasErrors = Object.keys(errors).some(
(k) => (errors as any)[k] !== undefined,
);
const submit = useCallback((): Entity | undefined => {
// HACK: Think about how this can be done better
return value as Entity;
}, [value]);
useEffect(() => {
onSubscribe(hasErrors ? undefined : submit);
}, [submit, hasErrors]);
const { state } = useSessionContext();
const { i18n } = useTranslationContext();
return (
name="token_family"
errors={errors}
object={value}
valueHandler={valueHandler}
>
name="slug"
addonBefore={new URL("tokenfamily/", state.backendUrl.href).href}
label={i18n.str`Slug`}
tooltip={i18n.str`token family slug to use in URLs (for internal use only)`}
/>
name="kind"
label={i18n.str`Kind`}
tooltip={i18n.str`token family kind`}
values={["discount", "subscription"]}
/>
name="name"
inputType="text"
label={i18n.str`Name`}
tooltip={i18n.str`user-readable token family name`}
/>
name="description"
inputType="multiline"
label={i18n.str`Description`}
tooltip={i18n.str`token family description for customers`}
/>
name="valid_after"
label={i18n.str`Valid After`}
tooltip={i18n.str`token family can issue tokens after this date`}
withTimestampSupport
/>
name="valid_before"
label={i18n.str`Valid Before`}
tooltip={i18n.str`token family can issue tokens until this date`}
withTimestampSupport
/>
name="duration"
label={i18n.str`Duration`}
tooltip={i18n.str`validity duration of a issued token`}
withForever
/>