From 30fb2aaaab9ee40c0b33c4db27a84e1a174ee6a7 Mon Sep 17 00:00:00 2001 From: g Date: Sat, 8 Feb 2025 00:31:53 +0000 Subject: [PATCH] Fix --- app/dashboard/products/page.tsx | 36 ++++++++++++++--------------- components/modals/product-modal.tsx | 28 ++++++++++------------ models/products.ts | 4 ++-- 3 files changed, 32 insertions(+), 36 deletions(-) diff --git a/app/dashboard/products/page.tsx b/app/dashboard/products/page.tsx index f777fd3..be6ec6e 100644 --- a/app/dashboard/products/page.tsx +++ b/app/dashboard/products/page.tsx @@ -27,8 +27,8 @@ export default function ProductsPage() { description: "", unitType: "pcs", category: "", - tieredPricing: [{ minQuantity: 1, pricePerUnit: 0 }], - image: null, + pricing: [{ minQuantity: 1, pricePerUnit: 0 }], + image: null }); // Fetch products and categories @@ -61,7 +61,7 @@ export default function ProductsPage() { // Ensure all products have tieredPricing const processedProducts = fetchedProducts.map((product: Product) => ({ ...product, - tieredPricing: product.tieredPricing || [{ minQuantity: 1, pricePerUnit: 0 }], + pricing: product.pricing || [{ minQuantity: 1, pricePerUnit: 0 }], })); setProducts(processedProducts); @@ -85,41 +85,41 @@ export default function ProductsPage() { e: ChangeEvent, index: number ) => { - const updatedPricing = [...productData.tieredPricing]; + const updatedPricing = [...productData.pricing]; const name = e.target.name as "minQuantity" | "pricePerUnit"; updatedPricing[index][name] = e.target.valueAsNumber || 0; - setProductData({ ...productData, tieredPricing: updatedPricing }); + setProductData({ ...productData, pricing: updatedPricing }); }; // Save product data after modal form submission const handleSaveProduct = async (data: Product) => { - const adjustedPricing = data.tieredPricing.map((tier) => ({ + const adjustedPricing = data.pricing.map((tier) => ({ minQuantity: tier.minQuantity, pricePerUnit: typeof tier.pricePerUnit === "string" - ? parseFloat(tier.pricePerUnit) // Convert string to number + ? parseFloat(tier.pricePerUnit) : tier.pricePerUnit, })); - - const productToSave = { + + const productToSave: Product = { ...data, pricing: adjustedPricing, - imageBase64: imagePreview || "", + image: data.image ?? "", // ✅ Prevents undefined error }; - + try { const authToken = document.cookie.split("Authorization=")[1]; const apiUrl = editing ? `${process.env.NEXT_PUBLIC_API_URL}/products/${data._id}` : `${process.env.NEXT_PUBLIC_API_URL}/products`; - + const savedProduct = await saveProductData( apiUrl, productToSave, authToken, editing ? "PUT" : "POST" ); - + setProducts((prevProducts) => { if (editing) { return prevProducts.map((product) => @@ -129,8 +129,8 @@ export default function ProductsPage() { return [...prevProducts, savedProduct]; } }); - - setModalOpen(false); // Close modal after saving + + setModalOpen(false); } catch (error) { console.error("Error saving product:", error); } @@ -158,8 +158,8 @@ export default function ProductsPage() { const handleEditProduct = (product: Product) => { setProductData({ ...product, - tieredPricing: product.tieredPricing - ? product.tieredPricing.map(tier => ({ + pricing: product.pricing + ? product.pricing.map(tier => ({ minQuantity: tier.minQuantity, pricePerUnit: tier.pricePerUnit })) @@ -176,7 +176,7 @@ export default function ProductsPage() { description: "", unitType: "pcs", category: "", - tieredPricing: [{ minQuantity: 1, pricePerUnit: 0 }], + pricing: [{ minQuantity: 1, pricePerUnit: 0 }], image: null, }); setEditing(false); diff --git a/components/modals/product-modal.tsx b/components/modals/product-modal.tsx index 0e1d31e..3d61932 100644 --- a/components/modals/product-modal.tsx +++ b/components/modals/product-modal.tsx @@ -18,9 +18,9 @@ import { SelectTrigger, SelectValue, } from "@/components/ui/select"; -import { Product } from "@/models/products"; import { Trash, PlusCircle } from "lucide-react"; import { toast } from "sonner"; +import { Product } from "@/models/products"; interface Category { _id: string; @@ -39,7 +39,7 @@ interface ProductData { unitType: string; category: string; pricing: PricingTier[]; - image: string | File | null; + image?: string | File | null | undefined; } interface ProductModalProps { @@ -47,11 +47,10 @@ interface ProductModalProps { onClose: () => void; onSave: (productData: ProductData) => void; productData: ProductData; - categories: Category[]; + categories: any[]; editing: boolean; - handleChange: ( - e: ChangeEvent - ) => void; + handleChange: (e: ChangeEvent) => void; + handleTieredPricingChange: (e: ChangeEvent, index: number) => void; // ✅ Added this setProductData: React.Dispatch>; } @@ -72,15 +71,6 @@ export const ProductModal = ({ height: 200, }); - useEffect(() => { - if (productData?.pricing) { - setProductData((prev) => ({ - ...prev, - tieredPricing: productData.pricing, - })); - } - }, [productData.pricing]); - useEffect(() => { if (productData.image && typeof productData.image === "string") { setImagePreview(productData.image); @@ -137,13 +127,19 @@ export const ProductModal = ({ updatedPricing[index] = { ...updatedPricing[index], - [name]: isNaN(valueAsNumber) ? 0 : valueAsNumber, // Ensure valid numbers + [name]: isNaN(valueAsNumber) ? 0 : valueAsNumber, }; setProductData((prev) => ({ ...prev, tieredPricing: updatedPricing, + image: prev.image ?? null, })); + + const convertToProductData = (product: Product): ProductData => ({ + ...product, + image: product.image ?? null, // ✅ Ensures the type is correct + }); }; return ( diff --git a/models/products.ts b/models/products.ts index 51dae4f..d043755 100644 --- a/models/products.ts +++ b/models/products.ts @@ -4,9 +4,9 @@ export interface Product { description: string; unitType: string; category: string; - tieredPricing: Array<{ + pricing: Array<{ minQuantity: number; pricePerUnit: number; }>; - image?: string | File | null; + image?: string | File | null | undefined; } \ No newline at end of file