summaryrefslogtreecommitdiff
path: root/packages/frontend/src/paths/instance/orders
diff options
context:
space:
mode:
Diffstat (limited to 'packages/frontend/src/paths/instance/orders')
-rw-r--r--packages/frontend/src/paths/instance/orders/create/CreatePage.tsx2
-rw-r--r--packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx8
-rw-r--r--packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx20
-rw-r--r--packages/frontend/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx9
-rw-r--r--packages/frontend/src/paths/instance/orders/details/DetailPage.tsx171
-rw-r--r--packages/frontend/src/paths/instance/orders/details/Timeline.tsx5
-rw-r--r--packages/frontend/src/paths/instance/orders/list/Table.tsx7
-rw-r--r--packages/frontend/src/paths/instance/orders/list/index.tsx51
8 files changed, 159 insertions, 114 deletions
diff --git a/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx b/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
index 1b47564..ae32dac 100644
--- a/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
+++ b/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
@@ -257,7 +257,7 @@ export function CreatePage({ onCreate, onBack }: Props): VNode {
with a total price of {totalPriceProducts}
</p>
} tooltip={i18n`Add products without inventory management to the order.`}>
- <NonInventoryProductFrom value={editingProduct} onAddProduct={(p) => {
+ <NonInventoryProductFrom productToEdit={editingProduct} onAddProduct={(p) => {
setEditingProduct(undefined)
return addNewProduct(p)
}} />
diff --git a/packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx b/packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx
index 6cf48f8..b97b39a 100644
--- a/packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx
+++ b/packages/frontend/src/paths/instance/orders/create/InventoryProductForm.tsx
@@ -39,12 +39,14 @@ export function InventoryProductForm({ currentProducts, onAddProduct }: Props):
const i18n = useTranslator()
+ const productWithInfiniteStock = state.product && state.product.total_stock === -1
+
const submit = (): void => {
if (!state.product) {
setErrors({ product: i18n`You must enter a valid product identifier.` });
return;
}
- if (state.product.total_stock === -1) {
+ if (productWithInfiniteStock) {
onAddProduct(state.product, 1)
} else {
if (!state.quantity || state.quantity <= 0) {
@@ -73,9 +75,9 @@ export function InventoryProductForm({ currentProducts, onAddProduct }: Props):
return <FormProvider<Form> errors={errors} object={state} valueHandler={setState}>
<InputSearchProduct selected={state.product} onChange={(p) => setState(v => ({ ...v, product: p }))} />
- <InputNumber<Form> name="quantity" label={i18n`Quantity`} tooltip={i18n`how many products will be added`} />
+ { state.product && !productWithInfiniteStock && <InputNumber<Form> name="quantity" label={i18n`Quantity`} tooltip={i18n`how many products will be added`} /> }
<div class="buttons is-right mt-5">
- <button class="button is-success" onClick={submit}><Translate>Add</Translate></button>
+ <button class="button is-success" disabled={!state.product} onClick={submit}><Translate>Add</Translate></button>
</div>
</FormProvider>
}
diff --git a/packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx b/packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx
index 967f1cb..756ec23 100644
--- a/packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx
+++ b/packages/frontend/src/paths/instance/orders/create/NonInventoryProductForm.tsx
@@ -28,22 +28,22 @@ import {
NonInventoryProductSchema as schema
} from '../../../../schemas';
import * as yup from 'yup';
-import { useTranslator } from "../../../../i18n";
+import { Translate, useTranslator } from "../../../../i18n";
type Entity = MerchantBackend.Product
interface Props {
onAddProduct: (p: Entity) => Promise<void>;
- value?: Entity;
+ productToEdit?: Entity;
}
-export function NonInventoryProductFrom({ value, onAddProduct }: Props): VNode {
+export function NonInventoryProductFrom({ productToEdit, onAddProduct }: Props): VNode {
const [showCreateProduct, setShowCreateProduct] = useState(false)
- const editing = !!value
+ const isEditing = !!productToEdit
useEffect(() => {
- setShowCreateProduct(editing)
- }, [editing])
+ setShowCreateProduct(isEditing)
+ }, [isEditing])
const [submitForm, addFormSubmitter] = useListener<Partial<MerchantBackend.Product> | undefined>((result) => {
if (result) {
@@ -62,10 +62,12 @@ export function NonInventoryProductFrom({ value, onAddProduct }: Props): VNode {
return <Fragment>
<div class="buttons">
- <button class="button is-success" onClick={() => setShowCreateProduct(true)} >add new product</button>
+ <button class="button is-success" onClick={() => setShowCreateProduct(true)} ><Translate>add new product</Translate></button>
</div>
- {showCreateProduct && <ConfirmModal active onCancel={() => setShowCreateProduct(false)} onConfirm={submitForm}>
- <ProductForm initial={value} onSubscribe={addFormSubmitter} />
+ {showCreateProduct && <ConfirmModal active
+ description="alskdj alsk jdalksjd laksjd lkasjd"
+ onCancel={() => setShowCreateProduct(false)} onConfirm={submitForm}>
+ <ProductForm initial={productToEdit} onSubscribe={addFormSubmitter} />
</ConfirmModal>}
</Fragment>
}
diff --git a/packages/frontend/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx b/packages/frontend/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
index db0be90..14c5d68 100644
--- a/packages/frontend/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
+++ b/packages/frontend/src/paths/instance/orders/create/OrderCreatedSuccessfully.tsx
@@ -17,6 +17,7 @@ import { h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks";
import { CreatedSuccessfully } from "../../../../components/notifications/CreatedSuccessfully";
import { useOrderAPI } from "../../../../hooks/order";
+import { Translate } from "../../../../i18n";
import { Entity } from "./index";
interface Props {
@@ -38,7 +39,7 @@ export function OrderCreatedSuccessfully({ entity, onConfirm, onCreateAnother }:
return <CreatedSuccessfully onConfirm={onConfirm} onCreateAnother={onCreateAnother}>
<div class="field is-horizontal">
<div class="field-label is-normal">
- <label class="label">Amount</label>
+ <label class="label"><Translate>Amount</Translate></label>
</div>
<div class="field-body is-flex-grow-3">
<div class="field">
@@ -50,7 +51,7 @@ export function OrderCreatedSuccessfully({ entity, onConfirm, onCreateAnother }:
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
- <label class="label">Summary</label>
+ <label class="label"><Translate>Summary</Translate></label>
</div>
<div class="field-body is-flex-grow-3">
<div class="field">
@@ -62,7 +63,7 @@ export function OrderCreatedSuccessfully({ entity, onConfirm, onCreateAnother }:
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
- <label class="label">Order ID</label>
+ <label class="label"><Translate>Order ID</Translate></label>
</div>
<div class="field-body is-flex-grow-3">
<div class="field">
@@ -74,7 +75,7 @@ export function OrderCreatedSuccessfully({ entity, onConfirm, onCreateAnother }:
</div>
<div class="field is-horizontal">
<div class="field-label is-normal">
- <label class="label">Payment URL</label>
+ <label class="label"><Translate>Payment URL</Translate></label>
</div>
<div class="field-body is-flex-grow-3">
<div class="field">
diff --git a/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx b/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
index be05b43..9f148b6 100644
--- a/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
+++ b/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
@@ -19,6 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm)
*/
+import { AmountJson, Amounts } from "@gnu-taler/taler-util";
import { format } from "date-fns";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
@@ -29,7 +30,7 @@ import { InputDate } from "../../../../components/form/InputDate";
import { InputDuration } from "../../../../components/form/InputDuration";
import { InputGroup } from "../../../../components/form/InputGroup";
import { InputLocation } from "../../../../components/form/InputLocation";
-import { NotificationCard } from "../../../../components/menu";
+import { TextField } from "../../../../components/form/TextField";
import { ProductList } from "../../../../components/product/ProductList";
import { MerchantBackend } from "../../../../declaration";
import { Translate, useTranslator } from "../../../../i18n";
@@ -52,6 +53,35 @@ type Unpaid = MerchantBackend.Orders.CheckPaymentUnpaidResponse
type Claimed = MerchantBackend.Orders.CheckPaymentClaimedResponse
+function ContractTerms({ value }: { value: CT }) {
+ const i18n = useTranslator()
+
+ return <InputGroup name="contract_terms" label={i18n`Contract Terms`}>
+ <FormProvider<CT> object={value} valueHandler={null} >
+ <Input<CT> readonly name="summary" label={i18n`Summary`} tooltip={i18n`human-readable description of the whole purchase`} />
+ <InputCurrency<CT> readonly name="amount" label={i18n`Amount`} tooltip={i18n`total price for the transaction`} />
+ {value.fulfillment_url &&
+ <Input<CT> readonly name="fulfillment_url" label={i18n`Fulfillment URL`} tooltip={i18n`URL for this purchase`} />
+ }
+ <Input<CT> readonly name="max_fee" label={i18n`Max fee`} tooltip={i18n`maximum total deposit fee accepted by the merchant for this contract`} />
+ <Input<CT> readonly name="max_wire_fee" label={i18n`Max wire fee`} tooltip={i18n`maximum wire fee accepted by the merchant`} />
+ <Input<CT> readonly name="wire_fee_amortization" label={i18n`Wire fee amortization`} tooltip={i18n`over how many customer transactions does the merchant expect to amortize wire fees on average`} />
+ <InputDate<CT> readonly name="timestamp" label={i18n`Created at`} tooltip={i18n`time when this contract was generated`} />
+ <InputDate<CT> readonly name="refund_deadline" label={i18n`Refund deadline`} tooltip={i18n`after this deadline has passed no refunds will be accepted`} />
+ <InputDate<CT> readonly name="pay_deadline" label={i18n`Payment deadline`} tooltip={i18n`after this deadline, the merchant won't accept payments for the contract`} />
+ <InputDate<CT> readonly name="wire_transfer_deadline" label={i18n`Wire transfer deadline`} tooltip={i18n`transfer deadline for the exchange`} />
+ <InputDate<CT> readonly name="delivery_date" label={i18n`Delivery date`} tooltip={i18n`time indicating when the order should be delivered`} />
+ {value.delivery_date &&
+ <InputGroup name="delivery_location" label={i18n`Location`} tooltip={i18n`where the order will be delivered`} >
+ <InputLocation name="payments.delivery_location" />
+ </InputGroup>
+ }
+ <InputDuration<CT> readonly name="auto_refund" label={i18n`Auto-refund delay`} tooltip={i18n`how long the wallet should try to get an automatic refund for the purchase`} />
+ <Input<CT> readonly name="extra" label={i18n`Extra info`} tooltip={i18n`extra data that is only interpreted by the merchant frontend`} />
+ </FormProvider>
+ </InputGroup>
+}
+
function ClaimedPage({ id, order }: { id: string; order: MerchantBackend.Orders.CheckPaymentClaimedResponse }) {
const events: Event[] = []
events.push({
@@ -126,11 +156,8 @@ function ClaimedPage({ id, order }: { id: string; order: MerchantBackend.Orders.
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
- // maxWidth: '100%',
}}>
- {/* <a href={order.order_status_url} rel="nofollow" target="new">{order.order_status_url}</a> */}
- <p><Translate>pay at</Translate>: <b>missing value, there is no order_status_url</b></p>
- <p><Translate>created at</Translate>: {format(new Date(order.contract_terms.timestamp.t_ms), 'yyyy-MM-dd HH:mm:ss')}</p>
+ <p><b><Translate>claimed at</Translate>:</b> {format(new Date(order.contract_terms.timestamp.t_ms), 'yyyy-MM-dd HH:mm:ss')}</p>
</div>
</div>
</div>
@@ -155,18 +182,12 @@ function ClaimedPage({ id, order }: { id: string; order: MerchantBackend.Orders.
</div>
</section>
- {order.contract_terms.products.length > 0 &&
- <section class="section">
- <div class="columns">
- <div class="column is-12" >
- <div class="title"><Translate>Product list</Translate></div>
- <ProductList list={order.contract_terms.products} />
- </div>
- <div class="column" />
- </div>
- </section>
- }
+ {order.contract_terms.products.length ? <Fragment>
+ <div class="title"><Translate>Product list</Translate></div>
+ <ProductList list={order.contract_terms.products} />
+ </Fragment> : undefined}
+ {value.contract_terms && <ContractTerms value={value.contract_terms} />}
</div>
<div class="column" />
</div>
@@ -207,19 +228,43 @@ function PaidPage({ id, order, onRefund }: { id: string; order: MerchantBackend.
type: 'refund',
})
})
- order.wire_details.forEach(e => {
- events.push({
- when: new Date(e.execution_time.t_ms),
- description: `wired`,
- type: 'wired',
- })
- })
- if (order.contract_terms.wire_transfer_deadline.t_ms !== 'never' &&
- order.contract_terms.wire_transfer_deadline.t_ms < new Date().getTime()) events.push({
- when: new Date(order.contract_terms.wire_transfer_deadline.t_ms - 1000 * 10),
- description: `wired (faked)`,
- type: 'wired',
- })
+ if (order.wire_details && order.wire_details.length) {
+ if (order.wire_details.length > 1) {
+ let last: MerchantBackend.Orders.TransactionWireTransfer | null = null
+ let first: MerchantBackend.Orders.TransactionWireTransfer | null = null
+ let total: AmountJson | null = null
+
+ order.wire_details.forEach(w => {
+ if (last === null || last.execution_time.t_ms < w.execution_time.t_ms) {
+ last = w
+ }
+ if (first === null || first.execution_time.t_ms > w.execution_time.t_ms) {
+ first = w
+ }
+ total = total === null ? Amounts.parseOrThrow(w.amount) : Amounts.add(total, Amounts.parseOrThrow(w.amount)).amount
+ })
+ events.push({
+ when: new Date(last!.execution_time.t_ms),
+ description: `wired ${Amounts.stringify(total!)}`,
+ type: 'wired-range',
+ })
+ events.push({
+ when: new Date(first!.execution_time.t_ms),
+ description: `wire transfer started...`,
+ type: 'wired-range',
+ })
+ } else {
+ order.wire_details.forEach(e => {
+ events.push({
+ when: new Date(e.execution_time.t_ms),
+ description: `wired ${e.amount}`,
+ type: 'wired',
+ })
+ })
+
+ }
+
+ }
const [value, valueHandler] = useState<Partial<Paid>>(order)
@@ -261,10 +306,9 @@ function PaidPage({ id, order, onRefund }: { id: string; order: MerchantBackend.
<div class="level-item">
<h1 class="title">
<div class="buttons">
- {refundable && <button class="button is-danger" onClick={() => onRefund(id)}><Translate>refund</Translate></button>}
- <button class="button is-info" onClick={() => {
- if (order.contract_terms.fulfillment_url) copyToClipboard(order.contract_terms.fulfillment_url)
- }}><Translate>copy url</Translate></button>
+ <span class="has-tooltip-left" data-tooltip={refundable ? i18n`refund order`: i18n`not refundable`}>
+ <button class="button is-danger" disabled={!refundable} onClick={() => onRefund(id)}><Translate>refund</Translate></button>
+ </span>
</div>
</h1>
</div>
@@ -301,53 +345,23 @@ function PaidPage({ id, order, onRefund }: { id: string; order: MerchantBackend.
<InputCurrency<Paid> name="deposit_total" readonly label={i18n`Deposit total`} />
{order.refunded && <InputCurrency<Paid> name="refund_amount" readonly label={i18n`Refunded amount`} />}
<Input<Paid> name="order_status" readonly label={i18n`Order status`} />
- {order.order_status_url && <Input<Paid> name="order_status_url" readonly label={i18n`Status URL`} />}
+ <TextField<Paid> name="order_status_url" label={i18n`Status URL`} >
+ <a target="_blank" href={order.order_status_url}>
+ {order.order_status_url}
+ </a>
+ </TextField>
</FormProvider>
</div>
</div>
</section>
- {value.contract_terms && <section class="section">
- <div class="columns">
- <div class="column is-12" >
- <div class="title"><Translate>Contract Terms</Translate></div>
- <FormProvider<CT> object={value.contract_terms} valueHandler={null} >
- <Input<CT> readonly name="summary" label={i18n`Summary`} tooltip={i18n`human-readable description of the whole purchase`} />
- <InputCurrency<CT> readonly name="amount" label={i18n`Amount`} tooltip={i18n`total price for the transaction`} />
- {value.contract_terms.fulfillment_url &&
- <Input<CT> readonly name="fulfillment_url" label={i18n`Fulfillment URL`} tooltip={i18n`URL for this purchase`} />
- }
- <Input<CT> readonly name="max_fee" label={i18n`Max fee`} tooltip={i18n`maximum total deposit fee accepted by the merchant for this contract`} />
- <Input<CT> readonly name="max_wire_fee" label={i18n`Max wire fee`} tooltip={i18n`maximum wire fee accepted by the merchant`} />
- <Input<CT> readonly name="wire_fee_amortization" label={i18n`Wire fee amortization`} tooltip={i18n`over how many customer transactions does the merchant expect to amortize wire fees on average`} />
- <InputDate<CT> readonly name="timestamp" label={i18n`Created at`} tooltip={i18n`time when this contract was generated`} />
- <InputDate<CT> readonly name="refund_deadline" label={i18n`Refund deadline`} tooltip={i18n`after this deadline has passed no refunds will be accepted`} />
- <InputDate<CT> readonly name="pay_deadline" label={i18n`Payment deadline`} tooltip={i18n`after this deadline, the merchant won't accept payments for the contract`} />
- <InputDate<CT> readonly name="wire_transfer_deadline" label={i18n`Wire transfer deadline`} tooltip={i18n`transfer deadline for the exchange`} />
- <InputDate<CT> readonly name="delivery_date" label={i18n`Delivery date`} tooltip={i18n`time indicating when the order should be delivered`} />
- {value.contract_terms.delivery_date &&
- <InputGroup name="delivery_location" label={i18n`Location`} tooltip={i18n`where the order will be delivered`} >
- <InputLocation name="payments.delivery_location" />
- </InputGroup>
- }
- <InputDuration<CT> readonly name="auto_refund" label={i18n`Auto-refund delay`} tooltip={i18n`how long the wallet should try to get an automatic refund for the purchase`} />
- <Input<CT> readonly name="extra" label={i18n`Extra info`} tooltip={i18n`extra data that is only interpreted by the merchant frontend`} />
- </FormProvider>
- </div>
- <div class="column" />
- </div>
- </section>}
- {order.contract_terms.products.length ? <section class="section">
- <div class="columns">
- <div class="column is-12" >
- <div class="title"><Translate>Product list</Translate></div>
- <ProductList list={order.contract_terms.products} />
- </div>
- <div class="column" />
- </div>
- </section> : undefined}
+ {order.contract_terms.products.length ? <Fragment>
+ <div class="title"><Translate>Product list</Translate></div>
+ <ProductList list={order.contract_terms.products} />
+ </Fragment> : undefined}
+ {value.contract_terms && <ContractTerms value={value.contract_terms} />}
</div>
<div class="column" />
</div>
@@ -380,10 +394,9 @@ function UnpaidPage({ id, order }: { id: string; order: MerchantBackend.Orders.C
whiteSpace: 'nowrap',
overflow: 'hidden',
textOverflow: 'ellipsis',
- // maxWidth: '100%',
}}>
- <p><Translate>pay at</Translate>: <a href={order.order_status_url} rel="nofollow" target="new">{order.order_status_url}</a></p>
- <p><Translate>created at</Translate>: <b>missing value, there is no contract term yet</b></p>
+ <p><b><Translate>pay at</Translate>:</b> <a href={order.order_status_url} rel="nofollow" target="new">{order.order_status_url}</a></p>
+ <p><b><Translate>created at</Translate>:</b> {format(new Date(order.creation_time.t_ms), 'yyyy-MM-dd HH:mm:ss')}</p>
</div>
</div>
</div>
@@ -394,8 +407,10 @@ function UnpaidPage({ id, order }: { id: string; order: MerchantBackend.Orders.C
<section class="section is-main-section">
<div class="columns">
<div class="column" />
- <div class="column is-6">
+ <div class="column is-four-fifths">
<FormProvider<Unpaid> object={value} valueHandler={valueHandler} >
+ <Input<Unpaid> readonly name="summary" label={i18n`Summary`} tooltip={i18n`human-readable description of the whole purchase`} />
+ <InputCurrency<Unpaid> readonly name="total_amount" label={i18n`Amount`} tooltip={i18n`total price for the transaction`} />
<Input<Unpaid> name="order_status" readonly label={i18n`Order status`} />
<Input<Unpaid> name="order_status_url" readonly label={i18n`Order status URL`} />
<Input<Unpaid> name="taler_pay_uri" readonly label={i18n`Payment URI`} />
@@ -432,7 +447,7 @@ export function DetailPage({ id, selected, onRefund, onBack }: Props): VNode {
/>}
<div class="columns">
<div class="column" />
- <div class="column is-two-thirds">
+ <div class="column is-four-fifths">
<div class="buttons is-right mt-5">
<button class="button" onClick={onBack}><Translate>Back</Translate></button>
</div>
diff --git a/packages/frontend/src/paths/instance/orders/details/Timeline.tsx b/packages/frontend/src/paths/instance/orders/details/Timeline.tsx
index d4f17c4..16adbcb 100644
--- a/packages/frontend/src/paths/instance/orders/details/Timeline.tsx
+++ b/packages/frontend/src/paths/instance/orders/details/Timeline.tsx
@@ -47,7 +47,7 @@ export function Timeline({ events:e }: Props) {
}
})
return <div class="timeline">
- {events.map((e,i) => {
+ {state.map((e,i) => {
return <div key={i} class="timeline-item">
{(() => {
switch (e.type) {
@@ -55,6 +55,7 @@ export function Timeline({ events:e }: Props) {
case "delivery": return <div class="timeline-marker is-icon "><i class="mdi mdi-delivery" /></div>
case "start": return <div class="timeline-marker is-icon is-success"><i class="mdi mdi-flag " /></div>
case "wired": return <div class="timeline-marker is-icon is-success"><i class="mdi mdi-cash" /></div>
+ case "wired-range": return <div class="timeline-marker is-icon is-success"><i class="mdi mdi-cash" /></div>
case "refund": return <div class="timeline-marker is-icon is-danger"><i class="mdi mdi-cash" /></div>
case "now": return <div class="timeline-marker is-icon is-info"><i class="mdi mdi-clock" /></div>
}
@@ -71,5 +72,5 @@ export function Timeline({ events:e }: Props) {
export interface Event {
when: Date;
description: string;
- type: 'start' | 'refund' | 'wired' | 'deadline' | 'delivery' | 'now'
+ type: 'start' | 'refund' | 'wired' | 'wired-range' |'deadline' | 'delivery' | 'now'
}
diff --git a/packages/frontend/src/paths/instance/orders/list/Table.tsx b/packages/frontend/src/paths/instance/orders/list/Table.tsx
index 4057ca2..41c7293 100644
--- a/packages/frontend/src/paths/instance/orders/list/Table.tsx
+++ b/packages/frontend/src/paths/instance/orders/list/Table.tsx
@@ -31,7 +31,7 @@ import { ConfirmModal } from "../../../../components/modal";
import { MerchantBackend, WithId } from "../../../../declaration";
import { useOrderDetails } from "../../../../hooks/order";
import { Translate, useTranslator } from "../../../../i18n";
-import { AuthorizeTipSchema, RefundSchema as RefundSchema } from "../../../../schemas";
+import { RefundSchema as RefundSchema } from "../../../../schemas";
import { mergeRefunds, subtractPrices, sumPrices } from "../../../../utils/amount";
import { AMOUNT_ZERO_REGEX } from "../../../../utils/constants";
@@ -54,6 +54,7 @@ export function CardTable({ instances, onCreate, onRefund, onCopyURL, onSelect,
const [showRefund, setShowRefund] = useState<string | undefined>(undefined)
+ const i18n = useTranslator()
return <div class="card has-table">
<header class="card-header">
@@ -62,9 +63,11 @@ export function CardTable({ instances, onCreate, onRefund, onCopyURL, onSelect,
<div class="card-header-icon" aria-label="more options" />
<div class="card-header-icon" aria-label="more options">
+ <span class="has-tooltip-left" data-tooltip={i18n`add new order`}>
<button class="button is-info" type="button" onClick={onCreate}>
<span class="icon is-small" ><i class="mdi mdi-plus mdi-36px" /></span>
</button>
+ </span>
</div>
</header>
@@ -114,7 +117,7 @@ function Table({ instances, onSelect, onRefund, onCopyURL, onLoadMoreAfter, onLo
<tr>
<th style={{ minWidth: 100 }}><Translate>Date</Translate></th>
<th style={{ minWidth: 100 }}><Translate>Amount</Translate></th>
- <th style={{ minWidth: 500 }}><Translate>Summary</Translate></th>
+ <th style={{ minWidth: 400 }}><Translate>Summary</Translate></th>
<th style={{ minWidth: 50 }} />
</tr>
</thead>
diff --git a/packages/frontend/src/paths/instance/orders/list/index.tsx b/packages/frontend/src/paths/instance/orders/list/index.tsx
index c85db0b..8bfe23d 100644
--- a/packages/frontend/src/paths/instance/orders/list/index.tsx
+++ b/packages/frontend/src/paths/instance/orders/list/index.tsx
@@ -41,7 +41,7 @@ interface Props {
export default function ({ onUnauthorized, onLoadError, onCreate, onSelect, onNotFound }: Props): VNode {
- const [filter, setFilter] = useState<InstanceOrderFilter>({ })
+ const [filter, setFilter] = useState<InstanceOrderFilter>({})
const [pickDate, setPickDate] = useState(false)
const setNewDate = (date: Date) => setFilter(prev => ({ ...prev, date }))
@@ -66,7 +66,7 @@ export default function ({ onUnauthorized, onLoadError, onCreate, onSelect, onNo
async function testIfOrderExistAndSelect() {
if (!orderId) {
- setErrorOrderId('Enter an order id')
+ setErrorOrderId(i18n`Enter an order id`)
return;
}
try {
@@ -74,11 +74,12 @@ export default function ({ onUnauthorized, onLoadError, onCreate, onSelect, onNo
onSelect(orderId)
setErrorOrderId(undefined)
} catch {
- setErrorOrderId('order not found')
+ setErrorOrderId(i18n`order not found`)
}
}
const i18n = useTranslator()
+ const dateTooltip = i18n`jump to order closer to a given date`
return <section class="section is-main-section">
<NotificationCard notification={notif} />
@@ -91,11 +92,11 @@ export default function ({ onUnauthorized, onLoadError, onCreate, onSelect, onNo
<input class={errorOrderId ? "input is-danger" : "input"} type="text" value={orderId} onChange={e => setOrderId(e.currentTarget.value)} placeholder={i18n`order id`} />
{errorOrderId && <p class="help is-danger">{errorOrderId}</p>}
</div>
- <div class="control">
- <a class="button" onClick={testIfOrderExistAndSelect}>
+ <span class="has-tooltip-bottom" data-tooltip={i18n`view order details`}>
+ <button class="button" onClick={testIfOrderExistAndSelect}>
<span class="icon"><i class="mdi mdi-arrow-right" /></span>
- </a>
- </div>
+ </button>
+ </span>
</div>
</div>
</div>
@@ -104,10 +105,26 @@ export default function ({ onUnauthorized, onLoadError, onCreate, onSelect, onNo
<div class="column">
<div class="tabs">
<ul>
- <li class={isAllActive}><a onClick={() => setFilter({})}><Translate>All</Translate></a></li>
- <li class={isPaidActive}><a onClick={() => setFilter({ paid: 'yes' })}><Translate>Paid</Translate></a></li>
- <li class={isRefundedActive}><a onClick={() => setFilter({ refunded: 'yes' })}><Translate>Refunded</Translate></a></li>
- <li class={isNotWiredActive}><a onClick={() => setFilter({ wired: 'no' })}><Translate>Not wired</Translate></a></li>
+ <li class={isAllActive}>
+ <div class="has-tooltip-right" data-tooltip={i18n`remove all filters`}>
+ <a onClick={() => setFilter({})}><Translate>All</Translate></a>
+ </div>
+ </li>
+ <li class={isPaidActive}>
+ <div class="has-tooltip-right" data-tooltip={i18n`filter paid orders`}>
+ <a onClick={() => setFilter({ paid: 'yes' })}><Translate>Paid</Translate></a>
+ </div>
+ </li>
+ <li class={isRefundedActive}>
+ <div class="has-tooltip-right" data-tooltip={i18n`filter refunded orders`}>
+ <a onClick={() => setFilter({ refunded: 'yes' })}><Translate>Refunded</Translate></a>
+ </div>
+ </li>
+ <li class={isNotWiredActive}>
+ <div class="has-tooltip-left" data-tooltip={i18n`filter not yet wired orders`}>
+ <a onClick={() => setFilter({ wired: 'no' })}><Translate>Not wired</Translate></a>
+ </div>
+ </li>
</ul>
</div>
</div>
@@ -120,12 +137,16 @@ export default function ({ onUnauthorized, onLoadError, onCreate, onSelect, onNo
</a>
</div>}
<div class="control">
- <input class="input" type="text" readonly value={!filter.date ? '' : format(filter.date, 'yyyy/MM/dd')} placeholder={i18n`date (YYYY/MM/DD)`} />
+ <span class="has-tooltip-top" data-tooltip={dateTooltip}>
+ <input class="input" type="text" readonly value={!filter.date ? '' : format(filter.date, 'yyyy/MM/dd')} placeholder={i18n`date (YYYY/MM/DD)`} onClick={() => { setPickDate(true) }} />
+ </span>
</div>
<div class="control">
- <a class="button" onClick={() => { setPickDate(true) }}>
- <span class="icon"><i class="mdi mdi-calendar" /></span>
- </a>
+ <span class="has-tooltip-left" data-tooltip={dateTooltip}>
+ <a class="button" onClick={() => { setPickDate(true) }}>
+ <span class="icon"><i class="mdi mdi-calendar" /></span>
+ </a>
+ </span>
</div>
</div>
</div>