fix:comment

This commit is contained in:
Anang Yusman 2026-01-26 11:04:14 +08:00
parent 274c41bf88
commit 3a12d7baa7
4 changed files with 93 additions and 115 deletions

View File

@ -469,137 +469,67 @@ export default function DetailProductForm(props: { isDetail: boolean }) {
</div> </div>
<div> <div>
<Label className="font-semibold">Warna Produk *</Label> <Label className="font-semibold text-gray-700">Warna Produk</Label>
{colors.map((item, index) => ( <div className="mt-4 grid grid-cols-1 md:grid-cols-4 gap-6 border-2 rounded-lg border-black p-3 ">
<div key={item.id} className="mt-6 border-b pb-6"> {colors.map((item, index) => (
<Label>Pilih Warna {index + 1}</Label> <div key={item.id} className="space-y-3">
<Input <Label className="text-sm text-gray-500">
placeholder="Contoh: Silver / #E2E2E2" Warna {index + 1}
className="mt-1"
value={item.name}
readOnly
/>
<div className="flex items-center gap-2 mt-3">
<div className="w-10 h-10 rounded-full flex items-center justify-center bg-teal-900">
<Settings className="w-5 h-5 text-white" />
</div>
{palette.map((colorCode) => (
<button
key={colorCode}
type="button"
disabled={isDetail}
style={{ backgroundColor: colorCode }}
className={`w-10 h-10 rounded-full border-2
${
item.colorSelected === colorCode
? "border-teal-700 scale-110"
: "border-gray-300"
}
${isDetail ? "cursor-not-allowed opacity-70" : ""}
`}
onClick={() => {
setColors((prev) => {
const updated = [...prev];
updated[index].colorSelected = colorCode;
return updated;
});
}}
/>
))}
</div>
<div className="mt-4">
<Label className="font-semibold">
Foto Produk Warna {index + 1}
</Label> </Label>
<div className="flex items-center gap-4 mt-2"> {/* Preview warna */}
<div
className="w-12 h-12 rounded-full border"
style={{ backgroundColor: item.colorSelected ?? "#e5e7eb" }}
/>
{/* Foto mobil */}
<div className="w-full h-[90px] border rounded-lg overflow-hidden">
<Image <Image
src={item.preview} src={item.preview}
alt="car color" alt="warna"
width={120} width={200}
height={80} height={120}
className="object-cover rounded-md border" className="object-cover w-full h-full"
/> />
<Button
className="bg-teal-800 hover:bg-teal-900 text-white"
onClick={() => {
setUploadTarget({ type: "color", index });
setIsUploadDialogOpen(true);
}}
>
Upload File Baru
</Button>
</div> </div>
</div>
</div>
))}
{/* <Button <p className="text-xs text-gray-500 text-center">
type="button" Foto Produk Warna {index + 1}
onClick={handleAddColor} </p>
className="w-full bg-teal-800 hover:bg-teal-900 text-white mt-4" </div>
> ))}
<Plus className="w-4 h-4 mr-2" /> Tambah Warna Baru </div>
</Button> */}
</div> </div>
<div className="mt-10"> <div>
<Label className="text-lg font-semibold text-teal-900"> <Label className="text-lg font-semibold text-gray-800">
Spesifikasi Produk <span className="text-red-500">*</span> Spesifikasi Produk
</Label> </Label>
{specs.map((spec, index) => ( {specs.map((spec) => (
<div key={spec.id} className="mt-6"> <div
<Label className="font-semibold text-sm"> key={spec.id}
Judul Spesifikasi {index + 1} className="mt-4 space-y-3 border-2 rounded-lg border-black p-3"
</Label> >
<Input <Input value={spec.title} readOnly className="font-medium" />
defaultValue={spec.title}
placeholder="Masukkan Judul Spesifikasi"
className="mt-1"
/>
<Label className="font-semibold text-sm mt-4 block"> <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
Foto Spesifikasi {index + 1}
</Label>
<div className="flex flex-wrap gap-4 mt-2">
{spec.images.map((img, i) => ( {spec.images.map((img, i) => (
<Image <div key={i} className="border rounded-lg overflow-hidden">
key={i} <Image
src={img} src={img}
width={120} alt="spec"
height={120} width={200}
alt="spec" height={200}
className="rounded-lg border object-cover" className="object-cover w-full h-[120px]"
/> />
</div>
))} ))}
{/* <Button
className="bg-teal-800 hover:bg-teal-900 text-white"
onClick={() => {
setUploadTarget({ type: "spec", index });
setIsUploadDialogOpen(true);
}}
>
Upload File Baru
</Button> */}
</div> </div>
</div> </div>
))} ))}
{/* <Button
onClick={handleAddSpec}
className="w-full bg-teal-800 hover:bg-teal-900 text-white flex items-center justify-center gap-2 py-4 rounded-xl"
>
<Plus className="w-4 h-4" />
Tambahkan Spesifikasi Baru
</Button> */}
</div> </div>
<div> <div>
<h4 className="text-sm font-semibold text-gray-700 mb-3"> <h4 className="text-sm font-semibold text-gray-700 mb-3">

View File

@ -153,7 +153,10 @@ export default function UpdateProductForm() {
<Label className="font-semibold">Warna Produk *</Label> <Label className="font-semibold">Warna Produk *</Label>
{colors.map((item, index) => ( {colors.map((item, index) => (
<div key={item.id} className="mt-6 border-b pb-6"> <div
key={item.id}
className="mt-6 pb-6 border-2 rounded-lg border-black p-3"
>
<Label>Pilih Warna {index + 1}</Label> <Label>Pilih Warna {index + 1}</Label>
<Input <Input
placeholder="Contoh: Silver / #E2E2E2" placeholder="Contoh: Silver / #E2E2E2"

View File

@ -53,6 +53,7 @@ import {
approveBanner, approveBanner,
rejectBanner, rejectBanner,
getApprovalHistory, getApprovalHistory,
commentBanner,
} from "@/service/banner"; } from "@/service/banner";
import { Check, CheckCheck, Clock, Eye, X } from "lucide-react"; import { Check, CheckCheck, Clock, Eye, X } from "lucide-react";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
@ -295,6 +296,39 @@ export default function ArticleTable() {
initState(); // refresh table initState(); // refresh table
}; };
const handleCommentBanner = async (id: number) => {
const { value: message } = await MySwal.fire({
title: "Komen Banner",
input: "textarea",
inputLabel: "Komentar (opsional)",
inputPlaceholder: "Masukkan komentar...",
inputAttributes: {
"aria-label": "Masukkan komentar",
},
showCancelButton: true,
confirmButtonText: "Komentar",
cancelButtonText: "Batal",
confirmButtonColor: "#dc2626",
});
if (message === undefined) {
return; // User cancelled
}
loading();
const res = await commentBanner(id, message || undefined);
if (res?.error) {
error(res.message || "Gagal menolak banner");
close();
return;
}
close();
success("Banner berhasil ditolak");
initState(); // refresh table
};
const handleReject = async () => { const handleReject = async () => {
if (!viewBanner) return; if (!viewBanner) return;
@ -866,7 +900,7 @@ export default function ArticleTable() {
className="bg-blue-200 hover:bg-blue-400" className="bg-blue-200 hover:bg-blue-400"
onClick={(e) => { onClick={(e) => {
e.stopPropagation(); e.stopPropagation();
setOpenCommentModal(true); handleCommentBanner(viewBanner.id);
}} }}
> >
Beri Tanggapan Beri Tanggapan

View File

@ -68,6 +68,17 @@ export async function rejectBanner(id: string | number, message?: string) {
); );
} }
export async function commentBanner(id: string | number, message?: string) {
const headers = {
"content-type": "application/json",
};
return await httpPutInterceptor(
`/banners/${id}/comment`,
{ message },
headers,
);
}
export async function getApprovalHistory( export async function getApprovalHistory(
moduleType: string, moduleType: string,
moduleId: string | number, moduleId: string | number,