"use client"; import { useState, useEffect } from "react"; import { Upload, Plus, Settings } from "lucide-react"; import Image from "next/image"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Button } from "@/components/ui/button"; import { Card, CardHeader, CardContent, CardTitle } from "@/components/ui/card"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { useParams } from "next/navigation"; import { getProductDataById, updateProduct } from "@/service/product"; import { useRouter } from "next/navigation"; import { success, error, close, loading } from "@/config/swal"; export default function UpdateProductForm() { const params = useParams(); const id = params?.id; const router = useRouter(); const [specs, setSpecs] = useState< { id: number; title: string; images: string[]; files: File[] }[] >([]); const [specFiles, setSpecFiles] = useState>(new Map()); type ColorType = { id: number; name: string; preview: string; colorSelected: string | null; }; const [colors, setColors] = useState([]); const [colorFiles, setColorFiles] = useState>(new Map()); const [thumbnail, setThumbnail] = useState(""); const [title, setTitle] = useState(""); const [variant, setVariant] = useState(""); const [price, setPrice] = useState(""); const palette = [ "#1E4E52", "#597E8D", "#6B6B6B", "#BEBEBE", "#E2E2E2", "#F4F4F4", "#FFFFFF", "#F9360A", "#9A2A00", "#7A1400", "#4B0200", "#B48B84", "#FFA598", ]; const handleAddSpec = () => { setSpecs((prev) => [ ...prev, { id: prev.length + 1, title: "", images: [], files: [], }, ]); }; const handleAddColor = () => { setColors((p) => [ ...p, { id: p.length + 1, name: "", preview: "/car-default.png", colorSelected: null, }, ]); }; const [isUploadDialogOpen, setIsUploadDialogOpen] = useState(false); const [uploadTarget, setUploadTarget] = useState<{ type: "spec" | "color"; index: number; } | null>(null); const fileInputId = "file-upload-input"; const handleFileSelected = (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file || !uploadTarget) return; const reader = new FileReader(); reader.onload = () => { const fileUrl = reader.result as string; if (uploadTarget.type === "spec") { setSpecs((prev) => { const updated = [...prev]; updated[uploadTarget.index].images.push(fileUrl); return updated; }); // Store the file for upload if (file) { setSpecFiles((prev) => { const newMap = new Map(prev); const existingFiles = newMap.get(uploadTarget.index) || []; newMap.set(uploadTarget.index, [...existingFiles, file]); return newMap; }); } } if (uploadTarget.type === "color") { setColors((prev) => { const updated = [...prev]; updated[uploadTarget.index].preview = fileUrl; return updated; }); // Store the file for upload if (file) { setColorFiles((prev) => { const newMap = new Map(prev); newMap.set(uploadTarget.index, file); return newMap; }); } } }; reader.readAsDataURL(file); setIsUploadDialogOpen(false); }; const formatRupiah = (value: string) => "Rp " + Number(value).toLocaleString("id-ID"); useEffect(() => { if (id) { initState(); } }, [id]); async function initState() { if (!id) return; try { loading(); const res = await getProductDataById(id); const data = res?.data?.data; if (!data) { error("Produk tidak ditemukan"); return; } close(); // Set form values setTitle(data.title || ""); setVariant(data.variant || ""); setPrice(formatRupiah(data.price || "0")); setThumbnail(data.thumbnail_url || ""); // Set colors if (data.colors?.length) { setColors( data.colors.map((color: any, index: number) => ({ id: index + 1, name: color.name || "", preview: color.image_url || data.thumbnail_url || "", colorSelected: color.name || null, })), ); } else { setColors([]); } // Set specifications if (data.specifications?.length) { setSpecs( data.specifications.map((spec: any, index: number) => ({ id: index + 1, title: spec.title || "", images: spec.image_urls || [], files: [], })), ); } else { setSpecs([]); } } catch (err) { error("Gagal memuat data produk"); console.error(err); } } const handleSubmit = async () => { if (!id) { error("ID produk tidak ditemukan"); return; } try { loading(); const formData = new FormData(); formData.append("title", title); if (variant) formData.append("variant", variant); if (price) { const priceValue = price.replace(/\D/g, ""); formData.append("price", priceValue); } // Colors JSON const colorsPayload = colors.map((c) => ({ name: c.name, })); formData.append("colors", JSON.stringify(colorsPayload)); // Color images (only new files if uploaded) // Append files in order of color indices colors.forEach((_, index) => { const file = colorFiles.get(index); if (file) { formData.append("color_images", file); } }); // Specifications JSON (include image count for new files only) const specificationsPayload = specs.map((s, index) => { const newFiles = specFiles.get(index) || []; return { title: s.title, imageCount: newFiles.length, // Only count new files being uploaded }; }); formData.append("specifications", JSON.stringify(specificationsPayload)); // Specification images (only new files if uploaded) specs.forEach((_, index) => { const files = specFiles.get(index) || []; files.forEach((file) => { formData.append("specification_images", file); }); }); await updateProduct(formData, id); success("Produk berhasil diperbarui"); router.push("/admin/product"); } catch (err) { error("Gagal memperbarui produk"); console.error(err); } }; return ( <> Edit Produk
setTitle(e.target.value)} placeholder="Masukkan nama produk" />
setVariant(e.target.value)} placeholder="Masukkan varian" />
{ const rawValue = e.target.value.replace(/\D/g, ""); setPrice(formatRupiah(rawValue)); }} placeholder="Masukkan harga" />
{thumbnail ? ( Thumbnail ) : (
No Image
)}
{colors.map((item, index) => (
{ setColors((prev) => { const updated = [...prev]; updated[index].name = e.target.value; updated[index].colorSelected = e.target.value; return updated; }); }} />
{palette.map((colorCode) => (
car color
))}
{specs.map((spec, index) => (
{spec.images.map((img, i) => ( spec ))}
))}
Upload File
document.getElementById(fileInputId)?.click()} >

Klik untuk upload atau drag & drop

PNG, JPG (max 2 MB)

); }