aboutsummaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/paths/instance/orders/create
diff options
context:
space:
mode:
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/orders/create')
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx7
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx161
-rw-r--r--packages/merchant-backoffice-ui/src/paths/instance/orders/create/index.tsx6
3 files changed, 129 insertions, 45 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
index fcf611c3c..bd9f65718 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/Create.stories.tsx
@@ -42,12 +42,13 @@ function createExample<Props>(
export const Example = createExample(TestedComponent, {
instanceConfig: {
- default_max_deposit_fee: "",
- default_max_wire_fee: "",
default_pay_delay: {
d_us: 1000 * 1000 * 60 * 60, //one hour
},
- default_wire_fee_amortization: 1,
+ default_wire_transfer_delay: {
+ d_us: 1000 * 1000 * 60 * 60, //one hour
+ },
+ use_stefan: true,
},
instanceInventory: [
{
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
index fa9347c6e..ea2cf849a 100644
--- a/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
+++ b/packages/merchant-backoffice-ui/src/paths/instance/orders/create/CreatePage.tsx
@@ -44,6 +44,7 @@ import { OrderCreateSchema as schema } from "../../../../schemas/index.js";
import { rate } from "../../../../utils/amount.js";
import { undefinedIfEmpty } from "../../../../utils/table.js";
import { useSettings } from "../../../../hooks/useSettings.js";
+import { InputToggle } from "../../../../components/form/InputToggle.js";
interface Props {
onCreate: (d: MerchantBackend.Orders.PostOrderRequest) => void;
@@ -52,34 +53,38 @@ interface Props {
instanceInventory: (MerchantBackend.Products.ProductDetail & WithId)[];
}
interface InstanceConfig {
- default_max_wire_fee: string;
- default_max_deposit_fee: string;
- default_wire_fee_amortization: number;
+ use_stefan: boolean;
default_pay_delay: Duration;
+ default_wire_transfer_delay: Duration;
}
-function with_defaults(config: InstanceConfig): Partial<Entity> {
+function with_defaults(config: InstanceConfig, currency: string): Partial<Entity> {
const defaultPayDeadline =
!config.default_pay_delay || config.default_pay_delay.d_us === "forever"
? undefined
: add(new Date(), {
seconds: config.default_pay_delay.d_us / (1000 * 1000),
});
+ const defaultWireDeadline =
+ !config.default_wire_transfer_delay || config.default_wire_transfer_delay.d_us === "forever"
+ ? undefined
+ : add(new Date(), {
+ seconds: config.default_wire_transfer_delay.d_us / (1000 * 1000),
+ });
return {
inventoryProducts: {},
products: [],
pricing: {},
payments: {
- max_wire_fee: config.default_max_wire_fee,
- max_fee: config.default_max_deposit_fee,
- wire_fee_amortization: config.default_wire_fee_amortization,
+ max_fee: undefined,
pay_deadline: defaultPayDeadline,
refund_deadline: defaultPayDeadline,
createToken: true,
+ wire_transfer_deadline: defaultWireDeadline,
},
shipping: {},
- extra: "",
+ extra: {},
};
}
@@ -107,8 +112,6 @@ interface Payments {
wire_transfer_deadline?: Date;
auto_refund_deadline?: Date;
max_fee?: string;
- max_wire_fee?: string;
- wire_fee_amortization?: number;
createToken: boolean;
minimum_age?: number;
}
@@ -118,7 +121,7 @@ interface Entity {
pricing: Partial<Pricing>;
payments: Partial<Payments>;
shipping: Partial<Shipping>;
- extra: string;
+ extra: Record<string, string>;
}
const stringIsValidJSON = (value: string) => {
@@ -136,8 +139,9 @@ export function CreatePage({
instanceConfig,
instanceInventory,
}: Props): VNode {
- const [value, valueHandler] = useState(with_defaults(instanceConfig));
const config = useConfigContext();
+ const instance_default = with_defaults(instanceConfig, config.currency)
+ const [value, valueHandler] = useState(instance_default);
const zero = Amounts.zeroOfCurrency(config.currency);
const [settings] = useSettings()
const inventoryList = Object.values(value.inventoryProducts || {});
@@ -160,10 +164,10 @@ export function CreatePage({
? i18n.str`must be greater than 0`
: undefined,
}),
- extra:
- value.extra && !stringIsValidJSON(value.extra)
- ? i18n.str`not a valid json`
- : undefined,
+ // extra:
+ // value.extra && !stringIsValidJSON(value.extra)
+ // ? i18n.str`not a valid json`
+ // : undefined,
payments: undefinedIfEmpty({
refund_deadline: !value.payments?.refund_deadline
? undefined
@@ -202,6 +206,7 @@ export function CreatePage({
)
? i18n.str`auto refund cannot be after refund deadline`
: undefined,
+
}),
shipping: undefinedIfEmpty({
delivery_date: !value.shipping?.delivery_date
@@ -225,7 +230,7 @@ export function CreatePage({
amount: order.pricing.order_price,
summary: order.pricing.summary,
products: productList,
- extra: value.extra,
+ extra: JSON.stringify(value.extra),
pay_deadline: value.payments.pay_deadline
? {
t_s: Math.floor(value.payments.pay_deadline.getTime() / 1000),
@@ -250,9 +255,7 @@ export function CreatePage({
),
}
: undefined,
- wire_fee_amortization: value.payments.wire_fee_amortization as number,
max_fee: value.payments.max_fee as string,
- max_wire_fee: value.payments.max_wire_fee as string,
delivery_date: value.shipping.delivery_date
? { t_s: value.shipping.delivery_date.getTime() / 1000 }
@@ -326,6 +329,8 @@ export function CreatePage({
const totalAsString = Amounts.stringify(totalPrice.amount);
const allProducts = productList.concat(inventoryList.map(asProduct));
+ const [newField, setNewField] = useState("")
+
useEffect(() => {
valueHandler((v) => {
return {
@@ -486,16 +491,61 @@ export function CreatePage({
name="payments.pay_deadline"
label={i18n.str`Payment deadline`}
tooltip={i18n.str`Deadline for the customer to pay for the offer before it expires. Inventory products will be reserved until this deadline.`}
+ side={
+ <span>
+ <button class="button" onClick={() => {
+ valueHandler({
+ ...value,
+ payments: {
+ ...(value.payments ?? {}),
+ pay_deadline: instance_default.payments?.pay_deadline
+ }
+ })
+ }}>
+ <i18n.Translate>default</i18n.Translate>
+ </button>
+ </span>
+ }
/>
<InputDate
name="payments.refund_deadline"
label={i18n.str`Refund deadline`}
tooltip={i18n.str`Time until which the order can be refunded by the merchant.`}
+ side={
+ <span>
+ <button class="button" onClick={() => {
+ valueHandler({
+ ...value,
+ payments: {
+ ...(value.payments ?? {}),
+ refund_deadline: instance_default.payments?.refund_deadline
+ }
+ })
+ }}>
+ <i18n.Translate>default</i18n.Translate>
+ </button>
+ </span>
+ }
/>
<InputDate
name="payments.wire_transfer_deadline"
label={i18n.str`Wire transfer deadline`}
tooltip={i18n.str`Deadline for the exchange to make the wire transfer.`}
+ side={
+ <span>
+ <button class="button" onClick={() => {
+ valueHandler({
+ ...value,
+ payments: {
+ ...(value.payments ?? {}),
+ wire_transfer_deadline: instance_default.payments?.wire_transfer_deadline
+ }
+ })
+ }}>
+ <i18n.Translate>default</i18n.Translate>
+ </button>
+ </span>
+ }
/>
<InputDate
name="payments.auto_refund_deadline"
@@ -505,23 +555,13 @@ export function CreatePage({
<InputCurrency
name="payments.max_fee"
- label={i18n.str`Maximum deposit fee`}
- tooltip={i18n.str`Maximum deposit fees the merchant is willing to cover for this order. Higher deposit fees must be covered in full by the consumer.`}
+ label={i18n.str`Maximum fee`}
+ tooltip={i18n.str`Maximum fees the merchant is willing to cover for this order. Higher deposit fees must be covered in full by the consumer.`}
/>
- <InputCurrency
- name="payments.max_wire_fee"
- label={i18n.str`Maximum wire fee`}
- tooltip={i18n.str`Maximum aggregate wire fees the merchant is willing to cover for this order. Wire fees exceeding this amount are to be covered by the customers.`}
- />
- <InputNumber
- name="payments.wire_fee_amortization"
- label={i18n.str`Wire fee amortization`}
- tooltip={i18n.str`Factor by which wire fees exceeding the above threshold are divided to determine the share of excess wire fees to be paid explicitly by the consumer.`}
- />
- <InputBoolean
+ <InputToggle
name="payments.createToken"
label={i18n.str`Create token`}
- tooltip={i18n.str`Uncheck this option if the merchant backend generated an order ID with enough entropy to prevent adversarial claims.`}
+ tooltip={i18n.str`If the order ID is easy to guess the token will prevent user to steal orders from others.`}
/>
<InputNumber
name="payments.minimum_age"
@@ -530,7 +570,7 @@ export function CreatePage({
help={
minAgeByProducts > 0
? i18n.str`Min age defined by the producs is ${minAgeByProducts}`
- : undefined
+ : i18n.str`No product with age restriction in this order`
}
/>
</InputGroup>
@@ -542,12 +582,53 @@ export function CreatePage({
label={i18n.str`Additional information`}
tooltip={i18n.str`Custom information to be included in the contract for this order.`}
>
- <Input
- name="extra"
- inputType="multiline"
- label={`Value`}
- tooltip={i18n.str`You must enter a value in JavaScript Object Notation (JSON).`}
- />
+ {Object.keys(value.extra ?? {}).map((key) => {
+
+ return <Input
+ name={`extra.${key}`}
+ inputType="multiline"
+ label={key}
+ tooltip={i18n.str`You must enter a value in JavaScript Object Notation (JSON).`}
+ side={
+ <button class="button" onClick={(e) => {
+ if (value.extra && value.extra[key] !== undefined) {
+ console.log(value.extra)
+ delete value.extra[key]
+ }
+ valueHandler({
+ ...value,
+ })
+ }}>remove</button>
+ }
+ />
+ })}
+ <div class="field is-horizontal">
+ <div class="field-label is-normal">
+ <label class="label">
+ <i18n.Translate>Custom field name</i18n.Translate>
+ <span class="icon has-tooltip-right" data-tooltip={"new extra field"}>
+ <i class="mdi mdi-information" />
+ </span>
+ </label>
+ </div>
+ <div class="field-body is-flex-grow-3">
+ <div class="field">
+ <p class="control">
+ <input class="input " value={newField} onChange={(e) => setNewField(e.currentTarget.value)} />
+ </p>
+ </div>
+ </div>
+ <button class="button" onClick={(e) => {
+ setNewField("")
+ valueHandler({
+ ...value,
+ extra: {
+ ...(value.extra ?? {}),
+ [newField]: ""
+ }
+ })
+ }}>add</button>
+ </div>
</InputGroup>
}
</FormProvider>
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 ffefd5302..2474fd042 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
@@ -38,7 +38,7 @@ export type Entity = {
};
interface Props {
onBack?: () => void;
- onConfirm: () => void;
+ onConfirm: (id: string) => void;
onUnauthorized: () => VNode;
onNotFound: () => VNode;
onLoadError: (error: HttpError<MerchantBackend.ErrorDetail>) => VNode;
@@ -95,7 +95,9 @@ export default function OrderCreate({
onBack={onBack}
onCreate={(request: MerchantBackend.Orders.PostOrderRequest) => {
createOrder(request)
- .then(onConfirm)
+ .then((r) => {
+ return onConfirm(r.data.order_id)
+ })
.catch((error) => {
setNotif({
message: "could not create order",