gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-merchant-backoffice] 02/02: refactored order list page to split l


From: gnunet
Subject: [taler-merchant-backoffice] 02/02: refactored order list page to split logic / view
Date: Thu, 24 Jun 2021 16:24:11 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository merchant-backoffice.

commit 0399b8a12591a0529d7b399508b9b63d811bcb93
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Thu Jun 24 11:23:27 2021 -0300

    refactored order list page to split logic / view
---
 .../paths/instance/orders/list/List.stories.tsx    |  14 +-
 .../src/paths/instance/orders/list/ListPage.tsx    | 146 ++++++++++++++++++++
 .../src/paths/instance/orders/list/Table.tsx       |   1 -
 .../src/paths/instance/orders/list/index.tsx       | 151 ++++++---------------
 4 files changed, 201 insertions(+), 111 deletions(-)

diff --git a/packages/frontend/src/paths/instance/orders/list/List.stories.tsx 
b/packages/frontend/src/paths/instance/orders/list/List.stories.tsx
index e791f20..996c0aa 100644
--- a/packages/frontend/src/paths/instance/orders/list/List.stories.tsx
+++ b/packages/frontend/src/paths/instance/orders/list/List.stories.tsx
@@ -20,15 +20,25 @@
 */
 
 import { h, VNode, FunctionalComponent } from 'preact';
-import { CardTable as TestedComponent } from './Table';
+import { ListPage as TestedComponent } from './ListPage';
 
 
 export default {
   title: 'Pages/Order/List',
   component: TestedComponent,
   argTypes: {
+    onShowAll: { action: 'onShowAll' },
+    onShowPaid: { action: 'onShowPaid' },
+    onShowRefunded: { action: 'onShowRefunded' },
+    onShowNotWired: { action: 'onShowNotWired' },
+    onCopyURL: { action: 'onCopyURL' },
+    onSelectDate: { action: 'onSelectDate' },
+    onLoadMoreBefore: { action: 'onLoadMoreBefore' },
+    onLoadMoreAfter: { action: 'onLoadMoreAfter' },
+    onSelectOrder: { action: 'onSelectOrder' },
+    onRefundOrder: { action: 'onRefundOrder' },
+    onSearchOrderById: { action: 'onSearchOrderById' },
     onCreate: { action: 'onCreate' },
-    goBack: { action: 'goBack' },
   },
 };
 
diff --git a/packages/frontend/src/paths/instance/orders/list/ListPage.tsx 
b/packages/frontend/src/paths/instance/orders/list/ListPage.tsx
new file mode 100644
index 0000000..032801b
--- /dev/null
+++ b/packages/frontend/src/paths/instance/orders/list/ListPage.tsx
@@ -0,0 +1,146 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 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 <http://www.gnu.org/licenses/>
+ */
+
+/**
+*
+* @author Sebastian Javier Marchano (sebasjm)
+*/
+
+import { format } from 'date-fns';
+import { h, VNode } from 'preact';
+import { useState } from 'preact/hooks';
+import { DatePicker } from '../../../../components/picker/DatePicker';
+import { MerchantBackend, WithId } from '../../../../declaration';
+import { Translate, useTranslator } from '../../../../i18n';
+import { CardTable } from './Table';
+
+export interface ListPageProps {
+  errorOrderId: string | undefined,
+
+  onShowAll: () => void,
+  onShowPaid: () => void,
+  onShowRefunded: () => void,
+  onShowNotWired: () => void,
+  onCopyURL: (id: string) => void;
+  isAllActive: string,
+  isPaidActive: string,
+  isRefundedActive: string,
+  isNotWiredActive: string,
+
+  jumpToDate?: Date,
+  onSelectDate: (date?: Date) => void,
+
+  orders: (MerchantBackend.Orders.OrderHistoryEntry & WithId)[];
+  onLoadMoreBefore?: () => void;
+  hasMoreBefore?: boolean;
+  hasMoreAfter?: boolean;
+  onLoadMoreAfter?: () => void;
+
+  onSelectOrder: (o: MerchantBackend.Orders.OrderHistoryEntry & WithId) => 
void;
+  onRefundOrder: (o: MerchantBackend.Orders.OrderHistoryEntry & WithId) => 
void;
+  onSearchOrderById: (id: string) => void;
+  onCreate: () => void;
+}
+
+export function ListPage({ orders, errorOrderId, isAllActive, onSelectOrder, 
onRefundOrder, onSearchOrderById, jumpToDate, onCopyURL, onShowAll, onShowPaid, 
onShowRefunded, onShowNotWired, onSelectDate, isPaidActive, isRefundedActive, 
isNotWiredActive, onCreate }: ListPageProps): VNode {
+  const i18n = useTranslator();
+  const dateTooltip = i18n`select date to show nearby orders`;
+  const [pickDate, setPickDate] = useState(false);
+  const [orderId, setOrderId] = useState<string>('');
+
+  return <section class="section is-main-section">
+
+    <div class="level">
+      <div class="level-left">
+        <div class="level-item">
+          <div class="field has-addons">
+            <div class="control">
+              <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>
+            <span class="has-tooltip-bottom" data-tooltip={i18n`jump to order 
with the given order ID`}>
+              <button class="button" onClick={(e) => 
onSearchOrderById(orderId)}>
+                <span class="icon"><i class="mdi mdi-arrow-right" /></span>
+              </button>
+            </span>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div class="columns">
+      <div class="column is-two-thirds">
+        <div class="tabs" style={{overflow:'inherit'}}>
+          <ul>
+            <li class={isAllActive}>
+              <div class="has-tooltip-right" data-tooltip={i18n`remove all 
filters`}>
+                <a onClick={onShowAll}><Translate>All</Translate></a>
+              </div>
+            </li>
+            <li class={isPaidActive}>
+              <div class="has-tooltip-right" data-tooltip={i18n`only show paid 
orders`}>
+                <a onClick={onShowPaid}><Translate>Paid</Translate></a>
+              </div>
+            </li>
+            <li class={isRefundedActive}>
+              <div class="has-tooltip-right" data-tooltip={i18n`only show 
orders with refunds`}>
+                <a onClick={onShowRefunded}><Translate>Refunded</Translate></a>
+              </div>
+            </li>
+            <li class={isNotWiredActive}>
+              <div class="has-tooltip-left" data-tooltip={i18n`only show 
orders where customers paid, but wire payments from payment provider are still 
pending`}>
+                <a onClick={onShowNotWired}><Translate>Not 
wired</Translate></a>
+              </div>
+            </li>
+          </ul>
+        </div>
+      </div>
+      <div class="column ">
+        <div class="buttons is-right">
+          <div class="field has-addons">
+            {jumpToDate && <div class="control">
+              <a class="button" onClick={() => onSelectDate(undefined)}>
+                <span class="icon" data-tooltip={i18n`clear date filter`}><i 
class="mdi mdi-close" /></span>
+              </a>
+            </div>}
+            <div class="control">
+              <span class="has-tooltip-top" data-tooltip={dateTooltip}>
+                <input class="input" type="text" readonly value={!jumpToDate ? 
'' : format(jumpToDate, 'yyyy/MM/dd')} placeholder={i18n`date (YYYY/MM/DD)`} 
onClick={() => { setPickDate(true); }} />
+              </span>
+            </div>
+            <div class="control">
+              <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>
+      </div>
+    </div>
+
+    <DatePicker
+      opened={pickDate}
+      closeFunction={() => setPickDate(false)}
+      dateReceiver={onSelectDate} />
+
+    <CardTable orders={orders}
+      onCreate={onCreate}
+      onCopyURL={onCopyURL}
+      onSelect={onSelectOrder}
+      onRefund={onRefundOrder} />
+  </section>;
+}
diff --git a/packages/frontend/src/paths/instance/orders/list/Table.tsx 
b/packages/frontend/src/paths/instance/orders/list/Table.tsx
index 64a5d22..50da549 100644
--- a/packages/frontend/src/paths/instance/orders/list/Table.tsx
+++ b/packages/frontend/src/paths/instance/orders/list/Table.tsx
@@ -32,7 +32,6 @@ import { MerchantBackend, WithId } from 
"../../../../declaration";
 import { Translate, useTranslator } from "../../../../i18n";
 import { RefundSchema } from "../../../../schemas";
 import { mergeRefunds } from "../../../../utils/amount";
-import { AMOUNT_ZERO_REGEX } from "../../../../utils/constants";
 import { Amounts } from "@gnu-taler/taler-util";
 import { useConfigContext } from "../../../../context/config";
 
diff --git a/packages/frontend/src/paths/instance/orders/list/index.tsx 
b/packages/frontend/src/paths/instance/orders/list/index.tsx
index 85ba58b..a4e8b15 100644
--- a/packages/frontend/src/paths/instance/orders/list/index.tsx
+++ b/packages/frontend/src/paths/instance/orders/list/index.tsx
@@ -19,18 +19,17 @@
 * @author Sebastian Javier Marchano (sebasjm)
 */
 
-import { format } from 'date-fns';
-import { h, VNode } from 'preact';
+import { h, VNode, Fragment } from 'preact';
 import { useState } from 'preact/hooks';
 import { Loading } from '../../../../components/exception/loading';
-import { DatePicker } from '../../../../components/form/DatePicker';
 import { NotificationCard } from '../../../../components/menu';
-import { MerchantBackend } from '../../../../declaration';
+import { MerchantBackend, WithId } from '../../../../declaration';
 import { HttpError } from '../../../../hooks/backend';
 import { InstanceOrderFilter, useInstanceOrders, useOrderAPI, useOrderDetails 
} from '../../../../hooks/order';
-import { Translate, useTranslator } from '../../../../i18n';
+import { useTranslator } from '../../../../i18n';
 import { Notification } from '../../../../utils/types';
-import { CardTable, RefundModal } from './Table';
+import { RefundModal } from './Table';
+import { ListPage } from './ListPage';
 
 interface Props {
   onUnauthorized: () => VNode;
@@ -40,22 +39,17 @@ interface Props {
   onCreate: () => void;
 }
 
-
 export default function ({ onUnauthorized, onLoadError, onCreate, onSelect, 
onNotFound }: Props): VNode {
   const [filter, setFilter] = useState<InstanceOrderFilter>({})
-  const [pickDate, setPickDate] = useState(false)
   const [orderToBeRefunded, setOrderToBeRefunded] = 
useState<MerchantBackend.Orders.OrderHistoryEntry | undefined>(undefined)
 
-  const setNewDate = (date: Date) => setFilter(prev => ({ ...prev, date }))
+  const setNewDate = (date?: Date) => setFilter(prev => ({ ...prev, date }))
 
   const result = useInstanceOrders(filter, setNewDate)
   const { refundOrder, getPaymentURL } = useOrderAPI()
 
   const [notif, setNotif] = useState<Notification | undefined>(undefined)
 
-  const [orderId, setOrderId] = useState<string | undefined>(undefined)
-  const [errorOrderId, setErrorOrderId] = useState<string | 
undefined>(undefined)
-
   if (result.clientError && result.isUnauthorized) return onUnauthorized()
   if (result.clientError && result.isNotfound) return onNotFound()
   if (result.loading) return <Loading />
@@ -66,7 +60,10 @@ export default function ({ onUnauthorized, onLoadError, 
onCreate, onSelect, onNo
   const isNotWiredActive = filter.wired === 'no' ? "is-active" : ''
   const isAllActive = filter.paid === undefined && filter.refunded === 
undefined && filter.wired === undefined ? 'is-active' : ''
 
-  async function testIfOrderExistAndSelect() {
+  const i18n = useTranslator()
+  const [errorOrderId, setErrorOrderId] = useState<string | 
undefined>(undefined)
+
+  async function testIfOrderExistAndSelect(orderId: string) {
     if (!orderId) {
       setErrorOrderId(i18n`Enter an order id`)
       return;
@@ -80,95 +77,35 @@ export default function ({ onUnauthorized, onLoadError, 
onCreate, onSelect, onNo
     }
   }
 
-  const i18n = useTranslator()
-  const dateTooltip = i18n`select date to show nearby orders`
-
-  return <section class="section is-main-section">
+  return <Fragment>
     <NotificationCard notification={notif} />
 
-    <div class="level">
-      <div class="level-left">
-        <div class="level-item">
-          <div class="field has-addons">
-            <div class="control">
-              <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>
-            <span class="has-tooltip-bottom" data-tooltip={i18n`jump to order 
with the given order ID`}>
-              <button class="button" onClick={testIfOrderExistAndSelect}>
-                <span class="icon"><i class="mdi mdi-arrow-right" /></span>
-              </button>
-            </span>
-          </div>
-        </div>
-      </div>
-    </div>
-    <div class="columns">
-      <div class="column">
-        <div class="tabs">
-          <ul>
-            <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`only show paid 
orders`}>
-                <a onClick={() => setFilter({ paid: 'yes' 
})}><Translate>Paid</Translate></a>
-              </div>
-            </li>
-            <li class={isRefundedActive}>
-              <div class="has-tooltip-right" data-tooltip={i18n`only show 
orders with refunds`}>
-                <a onClick={() => setFilter({ refunded: 'yes' 
})}><Translate>Refunded</Translate></a>
-              </div>
-            </li>
-            <li class={isNotWiredActive}>
-              <div class="has-tooltip-left" data-tooltip={i18n`only show 
orders where customers paid, but wire payments from payment provider are still 
pending`}>
-                <a onClick={() => setFilter({ wired: 'no' })}><Translate>Not 
wired</Translate></a>
-              </div>
-            </li>
-          </ul>
-        </div>
-      </div>
-      <div class="column ">
-        <div class="buttons is-right">
-          <div class="field has-addons">
-            {filter.date && <div class="control">
-              <a class="button" onClick={() => { setFilter(prev => ({ ...prev, 
date: undefined })) }}>
-                <span class="icon" data-tooltip={i18n`clear date filter`}><i 
class="mdi mdi-close" /></span>
-              </a>
-            </div>}
-            <div class="control">
-              <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">
-              <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>
-      </div>
-    </div>
-
-    <DatePicker
-      opened={pickDate}
-      closeFunction={() => setPickDate(false)}
-      dateReceiver={setNewDate}
-    />
-
-    <CardTable orders={result.data.orders.map(o => ({ ...o, id: o.order_id }))}
-      onCreate={onCreate}
-      onSelect={(order) => onSelect(order.id)}
-      onCopyURL={(id) => getPaymentURL(id).then((resp) => 
copyToClipboard(resp.data))}
-      onRefund={(value) => setOrderToBeRefunded(value)}
+    <ListPage
+      orders={result.data.orders.map(o => ({ ...o, id: o.order_id }))}
       onLoadMoreBefore={result.loadMorePrev} 
hasMoreBefore={!result.isReachingStart}
       onLoadMoreAfter={result.loadMore} hasMoreAfter={!result.isReachingEnd}
+
+      onSelectOrder={(order) => onSelect(order.id)}
+      onRefundOrder={(value) => setOrderToBeRefunded(value)}
+
+      errorOrderId={errorOrderId}
+      isAllActive={isAllActive}
+      isNotWiredActive={isNotWiredActive}
+      isPaidActive={isPaidActive}
+      isRefundedActive={isRefundedActive}
+      jumpToDate={filter.date}
+      onCopyURL={(id) => getPaymentURL(id).then((resp) => 
copyToClipboard(resp.data))}
+
+      onCreate={onCreate}
+      onSearchOrderById={testIfOrderExistAndSelect}
+      onSelectDate={setNewDate}
+      onShowAll={() => setFilter({})}
+      onShowNotWired={() => setFilter({ paid: 'yes' })}
+      onShowPaid={() => setFilter({ refunded: 'yes' })}
+      onShowRefunded={() => setFilter({ wired: 'no' })}
+
     />
+
     {orderToBeRefunded && <RefundModalForTable
       id={orderToBeRefunded.order_id}
       onCancel={() => setOrderToBeRefunded(undefined)}
@@ -182,16 +119,15 @@ export default function ({ onUnauthorized, onLoadError, 
onCreate, onSelect, onNo
           type: "ERROR",
           description: error.message
         }))
-        .then(() => setOrderToBeRefunded(undefined))
-      }
+        .then(() => setOrderToBeRefunded(undefined))}
       onLoadError={(error) => {
         setNotif({
           message: i18n`could not create the refund`,
           type: "ERROR",
           description: error.message
-        })
-        setOrderToBeRefunded(undefined)
-        return <div />
+        });
+        setOrderToBeRefunded(undefined);
+        return <div />;
       }}
       onUnauthorized={onUnauthorized}
       onNotFound={() => {
@@ -199,12 +135,11 @@ export default function ({ onUnauthorized, onLoadError, 
onCreate, onSelect, onNo
           message: i18n`could not get the order to refund`,
           type: "ERROR",
           // description: error.message
-        })
-        setOrderToBeRefunded(undefined)
-        return <div />
-      }}
-    />}
-  </section>
+        });
+        setOrderToBeRefunded(undefined);
+        return <div />;
+      }} />}
+  </Fragment>
 }
 
 interface RefundProps {

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]