feat:select color form
This commit is contained in:
parent
01df3f41d4
commit
7d3ac22960
|
|
@ -37,7 +37,7 @@ export default function AddProductForm() {
|
||||||
{ id: number; name: string; file: File | null }[]
|
{ id: number; name: string; file: File | null }[]
|
||||||
>([{ id: 1, name: "", file: null }]);
|
>([{ id: 1, name: "", file: null }]);
|
||||||
|
|
||||||
const [selectedColor, setSelectedColor] = useState<string | null>(null);
|
// const [selectedColor, setSelectedColor] = useState<string | null>(null);
|
||||||
const [specs, setSpecs] = useState<
|
const [specs, setSpecs] = useState<
|
||||||
{ id: number; title: string; images: string[]; files: File[] }[]
|
{ id: number; title: string; images: string[]; files: File[] }[]
|
||||||
>([{ id: 1, title: "", images: [], files: [] }]);
|
>([{ id: 1, title: "", images: [], files: [] }]);
|
||||||
|
|
@ -234,7 +234,9 @@ export default function AddProductForm() {
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
|
<form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
|
||||||
<div className="grid md:grid-cols-3 gap-4">
|
<div className="grid md:grid-cols-3 gap-4">
|
||||||
<div>
|
<div>
|
||||||
<Label>Nama Produk *</Label>
|
<Label>
|
||||||
|
Nama Produk <span className="text-red-500">*</span>
|
||||||
|
</Label>
|
||||||
<Input placeholder="Masukkan Nama Produk" {...register("name")} />
|
<Input placeholder="Masukkan Nama Produk" {...register("name")} />
|
||||||
{errors.name && (
|
{errors.name && (
|
||||||
<p className="text-sm text-red-500 mt-1">
|
<p className="text-sm text-red-500 mt-1">
|
||||||
|
|
@ -244,7 +246,9 @@ export default function AddProductForm() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Label>Tipe Varian *</Label>
|
<Label>
|
||||||
|
Tipe Varian <span className="text-red-500">*</span>
|
||||||
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Contoh: AWD, SHS, EV"
|
placeholder="Contoh: AWD, SHS, EV"
|
||||||
{...register("variant")}
|
{...register("variant")}
|
||||||
|
|
@ -257,7 +261,9 @@ export default function AddProductForm() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Label>Harga Produk *</Label>
|
<Label>
|
||||||
|
Harga Produk <span className="text-red-500">*</span>
|
||||||
|
</Label>
|
||||||
<Input
|
<Input
|
||||||
placeholder="Masukkan Harga Produk"
|
placeholder="Masukkan Harga Produk"
|
||||||
value={priceDisplay}
|
value={priceDisplay}
|
||||||
|
|
@ -302,7 +308,9 @@ export default function AddProductForm() {
|
||||||
|
|
||||||
{/* Upload Produk */}
|
{/* Upload Produk */}
|
||||||
<div>
|
<div>
|
||||||
<Label>Upload Produk *</Label>
|
<Label>
|
||||||
|
Upload Produk <span className="text-red-500">*</span>
|
||||||
|
</Label>
|
||||||
{colors.map((color, index) => (
|
{colors.map((color, index) => (
|
||||||
<div
|
<div
|
||||||
key={color.id}
|
key={color.id}
|
||||||
|
|
@ -342,15 +350,16 @@ export default function AddProductForm() {
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const updated = [...colors];
|
const updated = [...colors];
|
||||||
updated[index].name = colorCode; // 🔥 INI KUNCINYA
|
updated[index].name = colorCode;
|
||||||
setColors(updated);
|
setColors(updated);
|
||||||
setSelectedColor(colorCode);
|
|
||||||
}}
|
}}
|
||||||
className={`w-8 h-8 rounded-full border-2 transition ${
|
className={`w-8 h-8 rounded-full border-2 transition
|
||||||
selectedColor === colorCode
|
${
|
||||||
|
colors[index].name === colorCode
|
||||||
? "border-teal-700 scale-110"
|
? "border-teal-700 scale-110"
|
||||||
: "border-gray-200"
|
: "border-gray-200"
|
||||||
}`}
|
}
|
||||||
|
`}
|
||||||
style={{ backgroundColor: colorCode }}
|
style={{ backgroundColor: colorCode }}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
|
|
|
||||||
|
|
@ -536,7 +536,7 @@ export default function DetailProductForm(props: { isDetail: boolean }) {
|
||||||
|
|
||||||
{/* Foto mobil */}
|
{/* Foto mobil */}
|
||||||
<div className="w-full h-[90px] border rounded-lg overflow-hidden">
|
<div className="w-full h-[90px] border rounded-lg overflow-hidden">
|
||||||
<Image
|
<img
|
||||||
src={item.preview}
|
src={item.preview}
|
||||||
alt={`warna-${index}`}
|
alt={`warna-${index}`}
|
||||||
width={200}
|
width={200}
|
||||||
|
|
@ -582,7 +582,7 @@ export default function DetailProductForm(props: { isDetail: boolean }) {
|
||||||
key={i}
|
key={i}
|
||||||
className="border rounded-lg overflow-hidden"
|
className="border rounded-lg overflow-hidden"
|
||||||
>
|
>
|
||||||
<Image
|
<img
|
||||||
src={img}
|
src={img}
|
||||||
alt={`spec-${i}`}
|
alt={`spec-${i}`}
|
||||||
width={200}
|
width={200}
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,7 @@ export default function UpdateProductForm() {
|
||||||
name: string;
|
name: string;
|
||||||
preview: string;
|
preview: string;
|
||||||
colorSelected: string | null;
|
colorSelected: string | null;
|
||||||
|
isImageChanged: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const [colors, setColors] = useState<ColorType[]>([]);
|
const [colors, setColors] = useState<ColorType[]>([]);
|
||||||
|
|
@ -43,6 +44,7 @@ export default function UpdateProductForm() {
|
||||||
const [price, setPrice] = useState<string>("");
|
const [price, setPrice] = useState<string>("");
|
||||||
|
|
||||||
const palette = [
|
const palette = [
|
||||||
|
"#000000",
|
||||||
"#1E4E52",
|
"#1E4E52",
|
||||||
"#597E8D",
|
"#597E8D",
|
||||||
"#6B6B6B",
|
"#6B6B6B",
|
||||||
|
|
@ -78,6 +80,7 @@ export default function UpdateProductForm() {
|
||||||
name: "",
|
name: "",
|
||||||
preview: "/car-default.png",
|
preview: "/car-default.png",
|
||||||
colorSelected: null,
|
colorSelected: null,
|
||||||
|
isImageChanged: false, // ✅ WAJIB
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
@ -124,19 +127,19 @@ export default function UpdateProductForm() {
|
||||||
// ===================== COLOR =====================
|
// ===================== COLOR =====================
|
||||||
if (uploadTarget.type === "color") {
|
if (uploadTarget.type === "color") {
|
||||||
if (uploadTarget.index === undefined) return;
|
if (uploadTarget.index === undefined) return;
|
||||||
|
|
||||||
const index = uploadTarget.index;
|
const index = uploadTarget.index;
|
||||||
|
|
||||||
setColors((prev) => {
|
setColors((prev) => {
|
||||||
const updated = [...prev];
|
const updated = [...prev];
|
||||||
updated[index].preview = previewUrl;
|
updated[index].preview = previewUrl;
|
||||||
|
updated[index].isImageChanged = true; // 🔥 PENTING
|
||||||
return updated;
|
return updated;
|
||||||
});
|
});
|
||||||
|
|
||||||
setColorFiles((prev) => {
|
setColorFiles((prev) => {
|
||||||
const newMap = new Map(prev);
|
const map = new Map(prev);
|
||||||
newMap.set(index, file);
|
map.set(index, file);
|
||||||
return newMap;
|
return map;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -185,8 +188,9 @@ export default function UpdateProductForm() {
|
||||||
data.colors.map((color: any, index: number) => ({
|
data.colors.map((color: any, index: number) => ({
|
||||||
id: index + 1,
|
id: index + 1,
|
||||||
name: color.name || "",
|
name: color.name || "",
|
||||||
preview: color.image_url || data.thumbnail_url || "",
|
preview: color.image_url || "",
|
||||||
colorSelected: color.name || null,
|
colorSelected: color.name || null,
|
||||||
|
isImageChanged: false, // 🔥 default
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -235,12 +239,18 @@ export default function UpdateProductForm() {
|
||||||
}));
|
}));
|
||||||
formData.append("colors", JSON.stringify(colorsPayload));
|
formData.append("colors", JSON.stringify(colorsPayload));
|
||||||
|
|
||||||
// Color images (only new files if uploaded)
|
colors.forEach((color, index) => {
|
||||||
// Append files in order of color indices
|
if (color.isImageChanged) {
|
||||||
colors.forEach((_, index) => {
|
// image diganti → kirim file baru
|
||||||
const file = colorFiles.get(index);
|
const file = colorFiles.get(index);
|
||||||
if (file) {
|
if (file) {
|
||||||
formData.append("color_images", file);
|
formData.append("color_images", file);
|
||||||
|
} else {
|
||||||
|
formData.append("color_images", new Blob([])); // safety
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// image tidak diganti → kirim placeholder
|
||||||
|
formData.append("color_images", new Blob([]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -473,7 +483,6 @@ export default function UpdateProductForm() {
|
||||||
className="rounded-lg border object-cover"
|
className="rounded-lg border object-cover"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 🔴 TOMBOL HAPUS GAMBAR */}
|
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
google-site-verification: google162462b69256f396.html
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
google-site-verification: googlee3f6c9cb1d4e657b.html
|
|
||||||
Loading…
Reference in New Issue