[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-merchant-backoffice] branch master updated: product list into the
From: |
gnunet |
Subject: |
[taler-merchant-backoffice] branch master updated: product list into the order detail |
Date: |
Wed, 14 Apr 2021 19:28:12 +0200 |
This is an automated email from the git hooks/post-receive script.
sebasjm pushed a commit to branch master
in repository merchant-backoffice.
The following commit(s) were added to refs/heads/master by this push:
new dd03dc5 product list into the order detail
dd03dc5 is described below
commit dd03dc5877bbeca17efb4dc5007f62a7dd90eb16
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed Apr 14 14:27:22 2021 -0300
product list into the order detail
---
.../src/components/product/ProductList.tsx | 49 ++++++++
.../paths/instance/orders/create/CreatePage.tsx | 140 ++++++++-------------
.../paths/instance/orders/details/DetailPage.tsx | 22 ++--
.../src/paths/instance/products/list/index.tsx | 15 ++-
packages/frontend/src/utils/amount.ts | 1 +
5 files changed, 126 insertions(+), 101 deletions(-)
diff --git a/packages/frontend/src/components/product/ProductList.tsx
b/packages/frontend/src/components/product/ProductList.tsx
new file mode 100644
index 0000000..098b559
--- /dev/null
+++ b/packages/frontend/src/components/product/ProductList.tsx
@@ -0,0 +1,49 @@
+import { h } from "preact"
+import { MerchantBackend } from "../../declaration"
+import { multiplyPrice } from "../../utils/amount"
+
+interface Props {
+ list: MerchantBackend.Product[],
+ actions?: {
+ name: string;
+ handler: (d: MerchantBackend.Product, index: number) => void;
+ }[]
+}
+export function ProductList({ list, actions = [] }: Props) {
+ return <div class="table-container">
+ <table class="table is-fullwidth is-striped is-hoverable is-fullwidth">
+ <thead>
+ <tr>
+ <th>image</th>
+ <th>description</th>
+ <th>quantity</th>
+ <th>unit price</th>
+ <th>total price</th>
+ <th />
+ </tr>
+ </thead>
+ <tbody>
+ {list.map((entry, index) => {
+ return <tr>
+ <td>image</td>
+ <td >{entry.description}</td>
+ <td >
+ {entry.quantity} {entry.unit}
+ </td>
+ <td >{entry.price}</td>
+ <td >{multiplyPrice(entry.price, entry.quantity)}</td>
+ <td class="is-actions-cell right-sticky">
+ {actions.map(a => {
+ <div class="buttons is-right">
+ <button class="button is-small is-danger jb-modal"
type="button" onClick={() => a.handler(entry, index)}>
+ {a.name}
+ </button>
+ </div>
+ })}
+ </td>
+ </tr>
+ })}
+ </tbody>
+ </table>
+ </div>
+}
diff --git a/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
b/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
index 46dad20..34079cf 100644
--- a/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
+++ b/packages/frontend/src/paths/instance/orders/create/CreatePage.tsx
@@ -36,6 +36,7 @@ import { InputDate } from
"../../../../components/form/InputDate";
import { useInstanceDetails } from "../../../../hooks/instance";
import { add } from "date-fns";
import { multiplyPrice, rate, subtractPrices, sumPrices } from
"../../../../utils/amount";
+import { ProductList } from "../../../../components/product/ProductList";
interface Props {
onCreate: (d: MerchantBackend.Orders.PostOrderRequest) => void;
@@ -52,11 +53,12 @@ function with_defaults(): Entity {
};
}
+interface ProductAndQuantity {
+ product: MerchantBackend.Products.ProductDetail & WithId,
+ quantity: number;
+}
export interface ProductMap {
- [id: string]: {
- product: MerchantBackend.Products.ProductDetail & WithId,
- quantity: number;
- }
+ [id: string]: ProductAndQuantity;
}
interface Pricing {
@@ -82,7 +84,7 @@ interface Entity {
products: MerchantBackend.Product[],
pricing: Pricing;
payments: Payments;
- extra:string;
+ extra: string;
}
export function CreatePage({ onCreate, onBack }: Props): VNode {
@@ -103,12 +105,12 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
summary: order.pricing.summary,
products: productList,
extra: value.extra,
- pay_deadline: value.payments.pay_deadline ? { t_ms:
value.payments.pay_deadline.getTime()*1000 } : undefined,
- wire_transfer_deadline: value.payments.pay_deadline ? { t_ms:
value.payments.pay_deadline.getTime()*1000 } : undefined,
- refund_deadline: value.payments.refund_deadline ? { t_ms:
value.payments.refund_deadline.getTime()*1000 } : undefined,
+ pay_deadline: value.payments.pay_deadline ? { t_ms:
value.payments.pay_deadline.getTime() * 1000 } : undefined,
+ wire_transfer_deadline: value.payments.pay_deadline ? { t_ms:
value.payments.pay_deadline.getTime() * 1000 } : undefined,
+ refund_deadline: value.payments.refund_deadline ? { t_ms:
value.payments.refund_deadline.getTime() * 1000 } : undefined,
max_fee: value.payments.max_fee,
max_wire_fee: value.payments.max_wire_fee,
- delivery_date: value.payments.delivery_date ? { t_ms:
value.payments.delivery_date.getTime()*1000 } : undefined,
+ delivery_date: value.payments.delivery_date ? { t_ms:
value.payments.delivery_date.getTime() * 1000 } : undefined,
delivery_location: value.payments.delivery_location,
},
inventory_products: inventoryList.map(p => ({
@@ -116,6 +118,7 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
quantity: p.quantity
})),
}
+
onCreate(request);
} catch (err) {
const errors = err.inner as yup.ValidationError[]
@@ -185,6 +188,7 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
const discountOrRise = rate(value.pricing.order_price, totalPrice)
+
useEffect(() => {
valueHandler(v => {
return ({
@@ -201,7 +205,7 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
useEffect(() => {
if (details_response.ok) {
valueHandler(v => {
- const defaultPayDeadline = !details_response.data.default_pay_delay ||
details_response.data.default_pay_delay.d_ms === "forever" ? undefined :
add(new Date(), {seconds: details_response.data.default_pay_delay.d_ms/1000})
+ const defaultPayDeadline = !details_response.data.default_pay_delay ||
details_response.data.default_pay_delay.d_ms === "forever" ? undefined :
add(new Date(), { seconds: details_response.data.default_pay_delay.d_ms / 1000
})
return ({
...v, payments: {
...v.payments,
@@ -235,41 +239,13 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
onAddProduct={addProductToTheInventoryList}
/>
- {inventoryList.length > 0 && <div class="table-container">
- <table class="table is-fullwidth is-striped is-hoverable
is-fullwidth">
- <thead>
- <tr>
- <th>image</th>
- <th>description</th>
- <th>quantity</th>
- <th>unit price</th>
- <th>total price</th>
- <th />
- </tr>
- </thead>
- <tbody>
- {inventoryList.map((entry, index) => {
- return <tr>
- <td>image</td>
- <td >{entry.product.description}</td>
- <td >
- {entry.quantity} {entry.product.unit}
- </td>
- <td >{entry.product.price}</td>
- <td >{multiplyPrice(entry.product.price,
entry.quantity)}</td>
- <td class="is-actions-cell right-sticky">
- <div class="buttons is-right">
- <button class="button is-small is-danger jb-modal"
type="button" onClick={(): void =>
removeProductFromTheInventoryList(entry.product.id)}>
- Remove
- </button>
- </div>
- </td>
- </tr>
- })}
-
- </tbody>
- </table>
- </div>}
+ {inventoryList.length > 0 &&
+ <ProductList list={inventoryList.map(asProduct)}
+ actions={[{
+ name: 'Remove', handler: (e) =>
removeProductFromTheInventoryList(e.product_id!)
+ }]}
+ />
+ }
</InputGroup>
<InputGroup name="products" alternative={
@@ -283,46 +259,22 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
setEditingProduct(undefined)
addNewProduct(p)
}} />
- {productList.length > 0 && <div class="table-container">
- <table class="table is-fullwidth is-striped is-hoverable
is-fullwidth">
- <thead>
- <tr>
- <th>image</th>
- <th>description</th>
- <th>quantity</th>
- <th>unit price</th>
- <th>total price</th>
- <th />
- </tr>
- </thead>
- <tbody>
- {productList.map((entry, index) => {
- return <tr>
- <td>image</td>
- <td >{entry.description}</td>
- <td >
- {entry.quantity} {entry.unit}
- </td>
- <td >{entry.price}</td>
- <td >{multiplyPrice(entry.price, entry.quantity)}</td>
- <td class="is-actions-cell right-sticky">
- <div class="buttons is-right">
- <button class="button is-small is-success jb-modal"
type="button" onClick={(): void => {
- removeFromNewProduct(index)
- setEditingProduct(entry)
- }}>
- Edit
- </button>
- <button class="button is-small is-danger jb-modal"
type="button" onClick={(): void => removeFromNewProduct(index)}>
- Remove
- </button>
- </div>
- </td>
- </tr>
- })}
- </tbody>
- </table>
- </div>}
+
+ {productList.length > 0 &&
+ <ProductList list={productList}
+ actions={[{
+ name: 'Update', handler: (e, index) => {
+ removeFromNewProduct(index);
+ setEditingProduct(e);
+ }
+ }, {
+ name: 'Remove', handler: (e, index) => {
+ removeFromNewProduct(index);
+ }
+ }]}
+ />
+
+ }
</InputGroup>
<FormProvider<Entity> errors={errors} object={value}
valueHandler={valueHandler as any}>
@@ -343,14 +295,13 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
<Input name="pricing.summary" inputType="multiline" />
-
<InputGroup name="payments">
<InputDate name="payments.auto_refund_deadline" />
<InputDate name="payments.refund_deadline" />
<InputDate name="payments.pay_deadline" />
<InputDate name="payments.delivery_date" />
- { value.payments.delivery_date && <InputGroup
name="payments.delivery_location" >
+ {value.payments.delivery_date && <InputGroup
name="payments.delivery_location" >
<Input name="payments.delivery_location.country" />
<Input name="payments.delivery_location.address_lines"
inputType="multiline"
toStr={(v: string[] | undefined) => !v ? '' : v.join('\n')}
@@ -364,13 +315,14 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
<Input name="payments.delivery_location.town" />
<Input name="payments.delivery_location.district" />
<Input name="payments.delivery_location.country_subdivision" />
- </InputGroup> }
+ </InputGroup>}
<InputCurrency name="payments.max_fee"
currency={config.currency} />
<InputCurrency name="payments.max_wire_fee"
currency={config.currency} />
<Input name="payments.wire_fee_amortization" />
<Input name="payments.fullfilment_url" />
</InputGroup>
+
<InputGroup name="extra">
<Input name="extra" inputType="multiline" />
</InputGroup>
@@ -389,4 +341,14 @@ export function CreatePage({ onCreate, onBack }: Props):
VNode {
</div>
}
-
+function asProduct(p: ProductAndQuantity) {
+ return ({
+ product_id: p.product.id,
+ image: p.product.image,
+ price: p.product.price,
+ unit: p.product.unit,
+ quantity: p.quantity,
+ description: p.product.description,
+ taxes: p.product.taxes
+ })
+}
\ No newline at end of file
diff --git a/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
b/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
index 85b8d8e..c71aca5 100644
--- a/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
+++ b/packages/frontend/src/paths/instance/orders/details/DetailPage.tsx
@@ -32,6 +32,7 @@ import { format } from "date-fns";
import { Event, Timeline } from "./Timeline";
import { RefundModal } from "../list/Table";
import { mergeRefunds } from "../../../../utils/amount";
+import { ProductList } from "../../../../components/product/ProductList";
type Entity = MerchantBackend.Orders.MerchantOrderStatusResponse;
interface Props {
@@ -162,14 +163,9 @@ function ClaimedPage({ id, order }: { id: string; order:
MerchantBackend.Orders.
<section class="section">
<div class="columns">
- <div class="column is-2" />
- <div class="column is-8" >
- <div class="title">Payment details</div>
- <FormProvider<Claimed> errors={errors} object={value}
valueHandler={valueHandler} >
- <Input name="contract_terms.summary" readonly
inputType="multiline" />
- <InputCurrency name="contract_terms.amount" readonly
currency={config.currency} />
- <Input<Claimed> name="order_status" readonly />
- </FormProvider>
+ <div class="column is-12" >
+ <div class="title">Product list</div>
+ <ProductList list={order.contract_terms.products} />
</div>
<div class="column" />
</div>
@@ -324,6 +320,16 @@ function PaidPage({ id, order, onRefund }: { id: string;
order: MerchantBackend.
</div>
</section>
+ {order.contract_terms.products.length ? <section class="section">
+ <div class="columns">
+ <div class="column is-12" >
+ <div class="title">Product list</div>
+ <ProductList list={order.contract_terms.products} />
+ </div>
+ <div class="column" />
+ </div>
+ </section> :undefined }
+
</div>
<div class="column" />
</div>
diff --git a/packages/frontend/src/paths/instance/products/list/index.tsx
b/packages/frontend/src/paths/instance/products/list/index.tsx
index 4502276..8bda1f2 100644
--- a/packages/frontend/src/paths/instance/products/list/index.tsx
+++ b/packages/frontend/src/paths/instance/products/list/index.tsx
@@ -20,11 +20,9 @@
*/
import { h, VNode } from 'preact';
-import { create } from 'yup/lib/Reference';
-import { HttpError, HttpResponseServerError, RequestInfo } from
'../../../../hooks/backend';
+import { HttpError } from '../../../../hooks/backend';
import { useProductAPI } from "../../../../hooks/product";
import { CardTable } from './Table';
-import logo from '../../../../assets/logo.jpeg';
import { useConfigContext } from '../../../../context/backend';
import { MerchantBackend, WithId } from '../../../../declaration';
import { Loading } from '../../../../components/exception/loading';
@@ -92,7 +90,16 @@ export default function ({ onUnauthorized, onLoadError,
onCreate, onSelect, onNo
}))
}
onSelect={(product) => onSelect(product.id)}
- onDelete={(prod: (MerchantBackend.Products.ProductDetail & WithId)) =>
deleteProduct(prod.id)}
+ onDelete={(prod: (MerchantBackend.Products.ProductDetail & WithId)) =>
deleteProduct(prod.id)
+ .then(() => setNotif({
+ message: 'product delete successfully',
+ type: "SUCCESS"
+ })).catch((error) => setNotif({
+ message: 'could not delete the product',
+ type: "ERROR",
+ description: error.message
+ }))
+ }
/>
</section>
}
\ No newline at end of file
diff --git a/packages/frontend/src/utils/amount.ts
b/packages/frontend/src/utils/amount.ts
index ac98f0d..384e755 100644
--- a/packages/frontend/src/utils/amount.ts
+++ b/packages/frontend/src/utils/amount.ts
@@ -57,6 +57,7 @@ export const rate = (one?: string, two?: string) => {
const intOne = parseInt(valueOne, 10)
const intTwo = parseInt(valueTwo, 10)
if (!intTwo) return intOne
+ if (!intOne) return 0
return intOne / intTwo
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [taler-merchant-backoffice] branch master updated: product list into the order detail,
gnunet <=