"use client"; import { useState, useEffect } from "react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { ImageUpload } from "@/components/forms/image-upload"; import { PricingTiers } from "@/components/forms/pricing-tiers"; import type { ProductModalProps, ProductData } from "@/lib/types"; import { toast } from "sonner"; import type React from "react"; import { Plus } from "lucide-react"; import { apiRequest } from "@/lib/storeHelper"; type CategorySelectProps = { categories: { _id: string; name: string }[]; value: string; setProductData: React.Dispatch>; onAddCategory: (newCategory: { _id: string; name: string }) => void; }; export const ProductModal: React.FC = ({ open, onClose, onSave, productData, categories, editing, handleChange, handleTieredPricingChange, handleAddTier, handleRemoveTier, setProductData, }) => { /** * 1) Store the selected file *separately* from productData.image */ const [selectedFile, setSelectedFile] = useState(null); const [imagePreview, setImagePreview] = useState(null); const [imageDimensions, setImageDimensions] = useState({ width: 300, height: 200 }); const [localCategories, setLocalCategories] = useState(categories); // If productData.image is a *URL* (string), show it as a default preview useEffect(() => { if (productData.image && typeof productData.image === "string") { setImagePreview(`${process.env.NEXT_PUBLIC_API_URL}/products/${productData._id}/image`); } }, [productData.image]); useEffect(() => { setLocalCategories(categories); }, [categories]); /** * 2) When user selects a file, store it and create an objectURL for preview */ const handleImageChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (!file) { // no file selected setSelectedFile(null); setImagePreview(null); return; } // For preview console.log(file) const objectUrl = URL.createObjectURL(file); setSelectedFile(file); setImagePreview(objectUrl); // Optionally, load the image to calculate dimensions const image = new Image(); image.onload = () => { const aspectRatio = image.naturalWidth / image.naturalHeight; const width = aspectRatio > 1 ? 300 : 200 * aspectRatio; const height = aspectRatio > 1 ? 300 / aspectRatio : 200; setImageDimensions({ width, height }); }; image.src = objectUrl; }; /** * 3) On 'Save', call the parent onSave(productData, selectedFile) */ const handleSave = async () => { if (!productData.category) { toast.error("Please select or add a category"); return; } onSave(productData, selectedFile); toast.success(editing ? "Product updated!" : "Product added!"); onClose(); }; const handleAddCategory = (newCategory: { _id: string; name: string }) => { setLocalCategories((prev) => [...prev, newCategory]); }; return ( {editing ? "Edit Product" : "Add Product"}
); }; const ProductBasicInfo: React.FC<{ productData: ProductData; handleChange: (e: React.ChangeEvent) => void; categories: { _id: string; name: string }[]; setProductData: React.Dispatch>; onAddCategory: (newCategory: { _id: string; name: string }) => void; }> = ({ productData, handleChange, categories, setProductData, onAddCategory }) => (