From ece4f8d128bd38a5c1f8353b0b2ba68db19de954 Mon Sep 17 00:00:00 2001 From: Aloento <11802769+Aloento@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:21:13 +0100 Subject: [PATCH] The most significant changes include the handling of null `TrackingNumber` values in the `AdminHub` class in `Export.cs`, the addition of pagination functionality in `Get.cs` and `index.tsx`, and the enhancement of user interaction with the `GalleryCard` function in `Card.tsx`. 1. The `AdminHub` class in `Export.cs` has been updated to handle null `TrackingNumber` values. If the `TrackingNumber` is null, it will now be replaced with a "/". This change ensures that the system can handle null values without crashing or causing errors. 2. A new method `OrderGetCount` has been added to the `AdminHub` class in `Get.cs`. This method returns the total number of orders. Additionally, the `OrderGetList` method has been updated to include pagination functionality, allowing the retrieval of orders in chunks of 30. This change improves the efficiency of data retrieval and presentation. 3. In `index.tsx`, several Fluent UI components have been imported, including `Label`, `SpinButton`, and `tokens`. The `AdminOrder` function has been updated to include a new pagination feature. This feature displays the total number of records and allows users to navigate through pages of order data. This change enhances the user interface and improves the user experience. 4. The `GalleryCard` function in `Card.tsx` has been updated to wrap the entire card in a link, rather than just the product name. This means users can click anywhere on the card to navigate to the product page. The product name text color has also been updated. This change improves the user interaction with the product cards. 5. In `Get.ts`, a new `Count` method has been added to the `AdminOrderGet` class. This method returns the total number of orders. The `List` method has been updated to include a page parameter, allowing the retrieval of orders in chunks. The returned items are no longer sorted by `OrderDate` within this method. This change improves the efficiency of data retrieval and presentation. --- SoarCraft.AwaiShop/AdminHub/Order/Export.cs | 2 +- SoarCraft.AwaiShop/AdminHub/Order/Get.cs | 16 ++++++- src/Pages/Admin/Order/index.tsx | 51 +++++++++++++++++++-- src/Pages/Gallery/Card.tsx | 27 ++++++----- src/ShopNet/Admin/Order/Get.ts | 18 ++++++-- 5 files changed, 91 insertions(+), 23 deletions(-) diff --git a/SoarCraft.AwaiShop/AdminHub/Order/Export.cs b/SoarCraft.AwaiShop/AdminHub/Order/Export.cs index b9f6acc4..29fc4764 100644 --- a/SoarCraft.AwaiShop/AdminHub/Order/Export.cs +++ b/SoarCraft.AwaiShop/AdminHub/Order/Export.cs @@ -115,7 +115,7 @@ public async IAsyncEnumerable ExportOrder() { types, record.Quantity.ToString(), order.Status.ToString(), - order.TrackingNumber, + order.TrackingNumber ?? "/", user.Name ]); diff --git a/SoarCraft.AwaiShop/AdminHub/Order/Get.cs b/SoarCraft.AwaiShop/AdminHub/Order/Get.cs index c6e83adf..397df413 100644 --- a/SoarCraft.AwaiShop/AdminHub/Order/Get.cs +++ b/SoarCraft.AwaiShop/AdminHub/Order/Get.cs @@ -3,20 +3,32 @@ namespace SoarCraft.AwaiShop.AdminHub; using Microsoft.EntityFrameworkCore; internal partial class AdminHub { + /** + * + * @author Aloento + * @since 1.3.0 + * @version 0.1.0 + * + */ + public Task OrderGetCount() => this.Db.Orders.LongCountAsync(); + /** * * @author Aloento * @since 0.1.0 - * @version 0.2.0 + * @version 0.3.0 * */ - public async Task OrderGetList() => + public async Task OrderGetList(uint page) => await this.Db.Orders .Select(x => new { x.OrderId, Products = x.Combos.Select(c => c.ProductId).ToArray(), Quantity = (ushort)x.OrderCombos.Sum(o => o.Quantity) }) + .OrderByDescending(x => x.OrderId) + .Skip((int)(page - 1) * 30) + .Take(30) .ToArrayAsync(); /** diff --git a/src/Pages/Admin/Order/index.tsx b/src/Pages/Admin/Order/index.tsx index f12195a0..1796182d 100644 --- a/src/Pages/Admin/Order/index.tsx +++ b/src/Pages/Admin/Order/index.tsx @@ -1,7 +1,8 @@ -import { DataGridCell, DataGridHeaderCell, TableColumnDefinition, createTableColumn, makeStyles } from "@fluentui/react-components"; +import { DataGridCell, DataGridHeaderCell, Label, SpinButton, TableColumnDefinition, createTableColumn, makeStyles, tokens } from "@fluentui/react-components"; import { useRequest } from "ahooks"; import { DelegateDataGrid } from "~/Components/DataGrid"; import { Logger } from "~/Helpers/Logger"; +import { Flex } from "~/Helpers/Styles"; import { IOrderItem } from "~/Pages/History"; import { HistoryColumns } from "~/Pages/History/Columns"; import { AdminHub } from "~/ShopNet/Admin"; @@ -26,6 +27,16 @@ const useStyles = makeStyles({ flexBasis: "10%", flexGrow: 0 }, + page: { + ...Flex, + alignItems: "center", + justifyContent: "flex-end", + paddingTop: tokens.spacingVerticalXL, + columnGap: tokens.spacingHorizontalM + }, + spin: { + width: "4rem", + } }); /** @@ -85,14 +96,44 @@ const columns: TableColumnDefinition[] = [ /** * @author Aloento * @since 0.1.0 - * @version 0.2.0 + * @version 1.0.0 */ export function AdminOrder() { - const { data } = useRequest(() => AdminHub.Order.Get.List(log), { + const style = useStyles(); + + const { data: count } = useRequest(() => AdminHub.Order.Get.Count(), { + onError: log.error + }); + const page = Math.ceil((count || 1) / 30); + + const { data, run } = useRequest((go) => AdminHub.Order.Get.List(go, log), { + defaultParams: [1], + debounceWait: 300, onError: log.error }); - return ( + return <> - ) + +
+ + + { + const value = parseInt(data.value || data.displayValue as any); + + if (!Number.isNaN(value) && value && value <= page) + run(value); + }} + /> + + + + +
+ } diff --git a/src/Pages/Gallery/Card.tsx b/src/Pages/Gallery/Card.tsx index 0b7c72f5..997d0087 100644 --- a/src/Pages/Gallery/Card.tsx +++ b/src/Pages/Gallery/Card.tsx @@ -16,6 +16,9 @@ const useStyles = makeStyles({ ...Cover, borderTopLeftRadius: tokens.borderRadiusMedium, borderTopRightRadius: tokens.borderRadiusMedium, + }, + fore: { + color: tokens.colorBrandForegroundLink } }); @@ -24,7 +27,7 @@ const log = new Logger("Gallery", "Category", "Card"); /** * @author Aloento * @since 0.5.0 - * @version 0.1.6 + * @version 0.2.0 */ export function GalleryCard({ Id }: { Id: number }) { const style = useStyles(); @@ -33,16 +36,18 @@ export function GalleryCard({ Id }: { Id: number }) { }); return ( - - - - + + + + + - - - {data?.Name || "Loading..."} - - - + + + {data?.Name || "Loading..."} + + + + ) } diff --git a/src/ShopNet/Admin/Order/Get.ts b/src/ShopNet/Admin/Order/Get.ts index 689846cb..c41cd450 100644 --- a/src/ShopNet/Admin/Order/Get.ts +++ b/src/ShopNet/Admin/Order/Get.ts @@ -19,12 +19,22 @@ export abstract class AdminOrderGet extends AdminNet { /** "Order", "Get" */ protected static override readonly Log = [...super.Log, "Order", "Get"]; + /** + * @author Aloento + * @since 1.3.5 + * @version 0.1.0 + */ + public static Count(): Promise { + this.EnsureLogin(); + return this.GetTimeCache("", "OrderGetCount", (x) => x.add(1, "m")); + } + /** * @author Aloento * @since 0.5.0 - * @version 0.1.1 + * @version 1.0.0 */ - public static async List(pLog: Logger): Promise { + public static async List(page: number, pLog: Logger): Promise { this.EnsureLogin(); const log = pLog.With(...this.Log, "List"); @@ -34,7 +44,7 @@ export abstract class AdminOrderGet extends AdminNet { Products: number[]; Quantity: number; }[] - >("", "OrderGetList", (x) => x.add(1, "m")); + >(page, "OrderGetList", (x) => x.add(1, "m"), page); const items: IAdminOrderItem[] = []; @@ -77,7 +87,7 @@ export abstract class AdminOrderGet extends AdminNet { }); } - return items.sort((a, b) => b.OrderDate.getTime() - a.OrderDate.getTime()); + return items; } /**