Skip to content
This repository has been archived by the owner on Mar 24, 2024. It is now read-only.

Commit

Permalink
The most significant changes revolve around the modification of metho…
Browse files Browse the repository at this point in the history
…ds and classes related to product photos in an e-commerce application. The changes aim to improve readability, efficiency, and real-time responsiveness of the application. The changes also allow the application to handle more complex scenarios, better track and manage photos, and improve cache management.

1. `ProductDetachCategory` method in `Delete.cs` has been refactored for improved readability and efficiency. It now checks if the product has a category before removing it and deletes the category if it has no associated products. The method now returns a boolean indicating the success of the operation.

2. `ProductPostPhoto` method in `Post.cs` has been modified to return the ID of the newly added photo instead of a boolean, providing more useful information to the caller.

3. `PhotoEntity` method in `Entity.cs` has been simplified to return a single photo entity based on its ID.

4. `AdminProductPhotoEdit` function in `Edit.tsx` now takes an additional `ProductId` property, allowing it to perform operations related to the product that the photo belongs to.

5. `AdminProductPhoto` function in `index.tsx` now uses the `useLiveQuery` hook from `dexie-react-hooks` to fetch photo data, improving the real-time responsiveness of the application.

6. `usePhoto` methods in `Delete.ts` and `Post.ts` have been updated to take additional parameters and perform additional operations, allowing them to handle more complex scenarios.

7. `Photo` type in `Data.ts` has been updated to include `PhotoId` and `ProductId` properties, allowing the application to better track and manage photos.

8. `PhotoList` method in `Get.ts` has been updated to use a constant for the cache key, and a new `PhotoListUpdate` method has been added, improving the cache management of the application.
  • Loading branch information
Aloento committed Jan 24, 2024
1 parent 514e56a commit fbc3ba2
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 58 deletions.
18 changes: 10 additions & 8 deletions SoarCraft.AwaiShop/AdminHub/Product/Delete.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ public async Task<bool> ProductDeletePhoto(uint photoId) {
* <summary>
* Include Types -> Combos
* </summary>
*
* <remarks>
* @author Aloento
* @since 0.5.0
Expand Down Expand Up @@ -71,7 +70,6 @@ await this.Db.Variants
* <summary>
* Include Combos
* </summary>
*
* <remarks>
* @author Aloento
* @since 0.5.0
Expand Down Expand Up @@ -185,24 +183,28 @@ public async Task<bool> ProductDeleteProduct(uint prodId) {
* <remarks>
* @author Aloento
* @since 1.2.0
* @version 0.1.0
* @version 0.1.1
* </remarks>
*/
public async Task<bool> ProductDetachCategory(uint prodId) {
var prod = await this.Db.Products
.SingleAsync(x => x.ProductId == prodId);

if (prod.CategoryId is null)
var cate = prod.CategoryId;

if (cate is null)
return false;

prod.CategoryId = null;

var res = await this.Db.SaveChangesAsync();

await this.Db.Categories
.Where(x =>
x.CategoryId == prod.CategoryId &&
x.CategoryId == cate &&
x.Products.Count == 0)
.ExecuteDeleteAsync();

prod.CategoryId = null;

return await this.Db.SaveChangesAsync() > 0;
return res > 0;
}
}
8 changes: 4 additions & 4 deletions SoarCraft.AwaiShop/AdminHub/Product/Post.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ public async Task<bool> ProductPostMovePhoto(uint photoId, bool up) {
* <remarks>
* @author Aloento
* @since 0.5.0
* @version 0.1.0
* @version 0.1.1
* </remarks>
*/
public async Task<bool> ProductPostPhoto(uint prodId, IAsyncEnumerable<byte[]> input) {
public async Task<uint> ProductPostPhoto(uint prodId, IAsyncEnumerable<byte[]> input) {
var exist = await this.Db.Products.AnyAsync(x => x.ProductId == prodId);
if (!exist)
throw new HubException($"Product {prodId} not found");
Expand All @@ -95,14 +95,14 @@ public async Task<bool> ProductPostPhoto(uint prodId, IAsyncEnumerable<byte[]> i

var next = (byte)(await this.Db.Photos.CountAsync(x => x.ProductId == prodId) + 1);

await this.Db.Photos.AddAsync(new() {
var photo = await this.Db.Photos.AddAsync(new() {
ProductId = prodId,
Object = obj.Entity,
Order = next
});

await this.Db.SaveChangesAsync();
return true;
return photo.Entity.PhotoId;
}

/**
Expand Down
9 changes: 1 addition & 8 deletions SoarCraft.AwaiShop/Hub/Product/Entity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ internal partial class ShopHub {
* <remarks>
* @author Aloento
* @since 0.5.0
* @version 0.1.0
* @version 0.1.1
* </remarks>
*/
public async Task<dynamic?> PhotoEntity(uint key, uint? version) {
Expand All @@ -69,13 +69,6 @@ internal partial class ShopHub {

return await this.Db.Photos
.Where(x => x.PhotoId == key)
.Select(x => new {
x.Cover,
x.Caption,
x.Order,
x.ObjectId,
x.Version
})
.SingleOrDefaultAsync();
}

Expand Down
6 changes: 3 additions & 3 deletions src/Pages/Admin/Product/Photo/Edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ const log = new Logger("Admin", "Product", "Detail", "Photo", "Edit");
/**
* @author Aloento
* @since 0.5.0
* @version 0.3.3
* @version 0.3.4
*/
export function AdminProductPhotoEdit({ Photo: { Id, Cover, Caption }, Refresh }: IAdminProductPhotoEdit) {
export function AdminProductPhotoEdit({ Photo: { Id, Cover, Caption, ProductId }, Refresh }: IAdminProductPhotoEdit) {
const style = useStyles();
const [cap, setCap] = useState(Caption || "");

Expand Down Expand Up @@ -166,7 +166,7 @@ export function AdminProductPhotoEdit({ Photo: { Id, Cover, Caption }, Refresh }
Replace
</Button>

<Button appearance="primary" onClick={() => deletePhoto(Id)}>
<Button appearance="primary" onClick={() => deletePhoto(ProductId, Id)}>
Delete
</Button>
</div>
Expand Down
46 changes: 25 additions & 21 deletions src/Pages/Admin/Product/Photo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Button, DataGridCell, DataGridHeaderCell, Subtitle1, TableColumnDefinition, Toast, ToastTitle, createTableColumn, makeStyles } from "@fluentui/react-components";
import { AddRegular, ArrowDownRegular, ArrowUpRegular } from "@fluentui/react-icons";
import { useRequest } from "ahooks";
import { useState } from "react";
import { useLiveQuery } from "dexie-react-hooks";
import { DelegateDataGrid } from "~/Components/DataGrid";
import { MakeCoverCol } from "~/Helpers/CoverCol";
import { Logger } from "~/Helpers/Logger";
Expand Down Expand Up @@ -32,13 +31,15 @@ const log = new Logger("Admin", "Product", "Detail", "Photo");
/**
* @author Aloento
* @since 0.5.0
* @version 0.1.0
* @version 0.2.0
*/
export interface IPhotoItem {
/** PhotoId */
Id: number;
/** ObjectId */
Cover: string;
Caption?: string;
ProductId: number;
}

/**
Expand Down Expand Up @@ -107,34 +108,39 @@ const columns: TableColumnDefinition<IPhotoItem>[] = [
* @since 0.5.0
* @version 0.1.0
*/
let refreshCarousel: () => void;
let refreshCarousel: () => void = () => { };

/**
* @author Aloento
* @since 0.5.0
* @version 0.4.0
* @version 0.5.0
*/
export function AdminProductPhoto({ ProdId }: { ProdId: number }) {
const [list, setList] = useState<IPhotoItem[]>([]);

const { run } = useRequest(() => Hub.Product.Get.PhotoList(ProdId, log), {
onError: log.error,
onSuccess([raw]) {
const map = raw.map(x => ({
Id: x.Order,
Cover: x.ObjectId,
Caption: x.Caption || "No Caption"
}));

setList(map);
}
const list = useLiveQuery<IPhotoItem[]>(async () => {
const [raw] = await Hub.Product.Get.PhotoList(ProdId, log);

const map = raw.map(x => ({
Id: x.PhotoId,
Cover: x.ObjectId,
Caption: x.Caption || "No Caption",
ProductId: x.ProductId
}));

return map;
});
refreshCarousel = run;

const { dispatch, dispatchToast } = useErrorToast(log);

const { run: newPhoto } = AdminHub.Product.Post.usePhoto(log, {
manual: true,
onBefore([prodId, file]) {
dispatchToast(
<Toast>
<ToastTitle>Uploading Photo {file.name} for Product {prodId}</ToastTitle>
</Toast>,
{ intent: "info" }
);
},
onError(e, params) {
dispatch({
Message: "Failed Upload Photo",
Expand All @@ -149,8 +155,6 @@ export function AdminProductPhoto({ ProdId }: { ProdId: number }) {
</Toast>,
{ intent: "success" }
);

run();
}
});

Expand Down
9 changes: 6 additions & 3 deletions src/ShopNet/Admin/Product/Delete.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useRequest } from "ahooks";
import { Options } from "ahooks/lib/useRequest/src/types";
import { ProductData } from "~/ShopNet/Product/Data";
import { ProductGet } from "~/ShopNet/Product/Get";
import { AdminNet } from "../AdminNet";
import { AdminProductGet } from "./Get";

Expand All @@ -13,12 +14,14 @@ export abstract class AdminProductDelete extends AdminNet {
/**
* @author Aloento
* @since 0.5.0
* @version 0.2.0
* @version 0.3.0
*/
public static usePhoto(options: Options<true, [number]>) {
return useRequest(async photoId => {
public static usePhoto(options: Options<true, [number, number]>) {
return useRequest(async (prodId, photoId) => {
const res = await this.Invoke<boolean>("ProductDeletePhoto", photoId);
this.EnsureTrue(res);

ProductGet.PhotoListUpdate(prodId, x => x!.filter(x => x !== photoId));
return res;
}, options);
}
Expand Down
13 changes: 8 additions & 5 deletions src/ShopNet/Admin/Product/Post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Options } from "ahooks/lib/useRequest/src/types";
import { Subject } from "rxjs";
import { Logger } from "~/Helpers/Logger";
import { CurrentEditor } from "~/Lexical/Utils";
import { ProductGet } from "~/ShopNet/Product/Get";
import { AdminNet } from "../AdminNet";
import { AdminProductGet } from "./Get";

Expand Down Expand Up @@ -45,9 +46,9 @@ export abstract class AdminProductPost extends AdminNet {
/**
* @author Aloento
* @since 0.5.0
* @version 1.0.3
* @version 1.0.5
*/
public static usePhoto(pLog: Logger, options: Options<true, [number, File]>) {
public static usePhoto(pLog: Logger, options: Options<number, [number, File]>) {
const log = useConst(() => pLog.With(...this.Log, "Photo"));

return useRequest(async (prodId, file) => {
Expand All @@ -58,11 +59,13 @@ export abstract class AdminProductPost extends AdminNet {
throw new RangeError("File is too large, max 10MB");

const subject = new Subject<Uint8Array>();
const res = this.Invoke<boolean>("ProductPostPhoto", prodId, subject);
const res = this.Invoke<number>("ProductPostPhoto", prodId, subject);
await this.HandleFileStream(file, subject, log);

this.EnsureTrue(await res);
return true as const;
const id = await res;
ProductGet.PhotoListUpdate(prodId, x => [...x, id]);

return id;
}, options);
}

Expand Down
7 changes: 2 additions & 5 deletions src/ShopNet/Product/Data.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { IConcurrency } from "../Database";
import { ShopNet } from "../ShopNet";

/**
* @author Aloento
* @since 1.3.0
* @version 0.1.0
*/
export namespace ProductData {
export type Product = {
Name: string;
Expand All @@ -17,10 +12,12 @@ export namespace ProductData {
} & IConcurrency;

export type Photo = {
PhotoId: number;
Cover?: boolean;
Caption?: string;
Order: number;
ObjectId: string;
ProductId: number;
} & IConcurrency;

export type Type = {
Expand Down
8 changes: 7 additions & 1 deletion src/ShopNet/Product/Get.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import dayjs from "dayjs";
import type { Logger } from "~/Helpers/Logger";
import { IComboItem } from "~/Pages/Admin/Product/Combo";
import type { IGallery } from "~/Pages/Gallery";
Expand Down Expand Up @@ -106,6 +107,8 @@ export abstract class ProductGet extends ProductData {
return this.GetTimeCache(prodId, "ProductGetComboList", (x) => x.add(1, "m"), prodId);
}

public static readonly photoList = "ProductGetPhotoList";

/**
* @author Aloento
* @since 1.0.0
Expand All @@ -115,7 +118,7 @@ export abstract class ProductGet extends ProductData {
public static async PhotoList(prodId: number, pLog: Logger): Promise<[ProductData.Photo[], string]> {
const log = pLog.With(...this.Log, "PhotoList");

const ids = await this.GetTimeCache<number[]>(prodId, "ProductGetPhotoList", (x) => x.add(1, "m"), prodId).catch(log.error);
const ids = await this.GetTimeCache<number[]>(prodId, this.photoList, (x) => x.add(1, "m"), prodId).catch(log.error);
let list = [];
let cover = "";

Expand All @@ -140,4 +143,7 @@ export abstract class ProductGet extends ProductData {

return [list, cover];
}
public static PhotoListUpdate(prodId: number, action: (list: number[]) => number[]) {
return this.UpdateCache(action, prodId, this.photoList, dayjs().add(1, "m"));
}
}

0 comments on commit fbc3ba2

Please sign in to comment.