From 65b9387105d0505a5323c9f354eeefd88be123ce Mon Sep 17 00:00:00 2001 From: TakahashiNg <83152264+TakahashiNguyen@users.noreply.github.com> Date: Wed, 13 May 2026 03:56:42 +0000 Subject: [PATCH] chore: updat --- components/organisms/manager/ProductModal.tsx | 59 ++++++------------- components/organisms/manager/ProductsTab.tsx | 26 +++----- lib/manager-context.tsx | 31 +++++++++- lib/types.ts | 3 +- 4 files changed, 56 insertions(+), 63 deletions(-) diff --git a/components/organisms/manager/ProductModal.tsx b/components/organisms/manager/ProductModal.tsx index 5c11a14..ba3239e 100644 --- a/components/organisms/manager/ProductModal.tsx +++ b/components/organisms/manager/ProductModal.tsx @@ -1,6 +1,6 @@ "use client"; -import type { Product } from "@/lib/types"; +import type { MenuItemEntity } from "@/lib/types"; import { useState } from "react"; import type { ProductModalProps } from "./Manager.types"; @@ -12,11 +12,10 @@ export default function ProductModal({ onClose, }: ProductModalProps) { const isEdit = product !== null; - const [form, setForm] = useState>({ + const [form, setForm] = useState>({ name: product?.name ?? "", - category: product?.category ?? categories[0]?.id ?? "", price: product?.price ?? 0, - image: product?.image ?? "/imgs/products/placeholder.jpg", + imageUrl: product?.image ?? "/imgs/products/placeholder.jpg", description: product?.description ?? "", available: product?.available ?? true, }); @@ -67,42 +66,22 @@ export default function ProductModal({ /> -
-
- - -
-
- - - setForm({ ...form, price: Number(e.target.value) }) - } - className={inputCls} - placeholder="25000" - /> -
+
+ + + setForm({ ...form, price: Number(e.target.value) }) + } + className={inputCls} + placeholder="25000" + />
diff --git a/components/organisms/manager/ProductsTab.tsx b/components/organisms/manager/ProductsTab.tsx index 12f7fbf..5cf3e39 100644 --- a/components/organisms/manager/ProductsTab.tsx +++ b/components/organisms/manager/ProductsTab.tsx @@ -1,7 +1,7 @@ "use client"; import { useManager } from "@/lib/manager-context"; -import type { Product } from "@/lib/types"; +import type { MenuItemEntity } from "@/lib/types"; import { useState } from "react"; import DeleteConfirm from "./DeleteConfirm"; @@ -27,13 +27,12 @@ export default function ProductsTab() { "all" | "available" | "unavailable" >("all"); const [search, setSearch] = useState(""); - const [modalProduct, setModalProduct] = useState( - null, - ); - const [deleteTarget, setDeleteTarget] = useState(null); + const [modalProduct, setModalProduct] = useState< + MenuItemEntity | null | "new" + >(null); + const [deleteTarget, setDeleteTarget] = useState(null); const filtered = products.filter((p) => { - if (filterCategory !== "all" && p.category !== filterCategory) return false; if (filterStatus === "available" && p.available === false) return false; if (filterStatus === "unavailable" && p.available !== false) return false; if ( @@ -125,9 +124,6 @@ export default function ProductsTab() { Tên món - - Danh mục - Giá @@ -166,14 +162,6 @@ export default function ProductsTab() { )}
- - - c.id === p.category)?.icon ?? "fa-solid fa-tag"} text-[10px]`} - > - {getCategoryName(p.category)} - - {formatPrice(p.price)} @@ -215,9 +203,9 @@ export default function ProductsTab() { { + onSave={(data: MenuItemEntity) => { if ("id" in data) { - updateProduct(data as Product); + updateProduct(data); } else { addProduct(data); } diff --git a/lib/manager-context.tsx b/lib/manager-context.tsx index ba4bed0..7f65edc 100644 --- a/lib/manager-context.tsx +++ b/lib/manager-context.tsx @@ -1,7 +1,7 @@ "use client"; import { gql } from "@apollo/client"; -import { useQuery } from "@apollo/client/react"; +import { useMutation, useQuery } from "@apollo/client/react"; import { ReactNode, createContext, @@ -16,6 +16,7 @@ import type { Combo, MenuCategory, MenuItemEntity, + addMenuItemMutation, allEateriesQuery, } from "./types"; @@ -64,12 +65,26 @@ const GET_EATERY_MENU = gql` menuItems { id name + available + description price } } } `; +const ADD_MENU_ITEM = gql` + mutation addMenuItem($menuItem: AddMenuItemInput!) { + addMenuItem(menuItem: $menuItem) { + id + name + available + description + price + } + } +`; + // ─── Provider ───────────────────────────────────────────────────────────────── export function ManagerProvider({ children }: { children: ReactNode }) { @@ -86,6 +101,10 @@ export function ManagerProvider({ children }: { children: ReactNode }) { fetchPolicy: "network-only", }); + const [mutateAddMenuItem] = useMutation(ADD_MENU_ITEM, { + client: eateryClient, + }); + useEffect(() => { if (data?.allEateries?.[0]) { setProducts(data.allEateries[0].menuItems); @@ -94,8 +113,14 @@ export function ManagerProvider({ children }: { children: ReactNode }) { // ── MenuItemEntity actions ────────────────────────────────────────────────────── - const addProduct = (product: MenuItemEntity) => { - setProducts((prev) => [...prev, product]); + const addProduct = async (product: MenuItemEntity) => { + const { data } = await mutateAddMenuItem({ + variables: { + menuItem: product, + }, + }); + + if (data) setProducts((prev) => [...prev, data.addMenuItem]); }; const updateProduct = (product: MenuItemEntity) => { diff --git a/lib/types.ts b/lib/types.ts index 09ca4b4..abe4a1c 100644 --- a/lib/types.ts +++ b/lib/types.ts @@ -139,9 +139,10 @@ export interface MenuItemEntity { id: string; name: string; price: number; - eatery: EateryEntity; + eatery?: EateryEntity; imageUrl: string; available: boolean; + description: string; } export interface ShiftEntity {}