fix:comment

This commit is contained in:
Anang Yusman 2026-01-26 15:43:25 +08:00
parent c7f1832afc
commit 3a176536e7
10 changed files with 204 additions and 12 deletions

View File

@ -12,6 +12,7 @@ import { Check, CheckCheck, CheckCircle, Clock, X } from "lucide-react";
import { useEffect, useState } from "react";
import {
approveGalery,
commentGalery,
getGaleryFileData,
rejectGalery,
} from "@/service/galery";
@ -29,6 +30,7 @@ export function DialogDetailGaleri({ open, onClose, data }: any) {
const [userRoleId, setUserRoleId] = useState<string | null>(null);
const [openViewDialog, setOpenViewDialog] = useState(false);
const router = useRouter();
const MySwal = withReactContent(Swal);
// 🔹 Ambil userlevelId dari cookies
useEffect(() => {
@ -90,6 +92,39 @@ export function DialogDetailGaleri({ open, onClose, data }: any) {
fetchImages(); // refresh table
};
const handleCommentGalery = async (id: number) => {
const { value: message } = await MySwal.fire({
title: "Komen Galeri",
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 commentGalery(id, message || undefined);
if (res?.error) {
error(res.message || "Gagal komentar promotion");
close();
return;
}
close();
success("Galeri berhasil dikomentar");
// fetchData(); // refresh table
};
const handleRejectGalery = async (id: number) => {
const MySwal = withReactContent(Swal);
const { value: message } = await MySwal.fire({
@ -292,7 +327,7 @@ export function DialogDetailGaleri({ open, onClose, data }: any) {
className="bg-blue-200 hover:bg-blue-400"
onClick={(e) => {
e.stopPropagation();
setOpenCommentModal(true);
handleCommentGalery(data.id);
}}
>
Beri Tanggapan

View File

@ -17,6 +17,7 @@ import {
} from "lucide-react";
import {
approvePromotion,
commentPromotion,
getPromotionById,
rejectPromotion,
} from "@/service/promotion";
@ -71,6 +72,39 @@ export default function PromoDetailDialog({
setOpenApproverHistory(true);
};
const handleCommentPromotion = async (id: number) => {
const { value: message } = await MySwal.fire({
title: "Komen Promotion",
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 commentPromotion(id, message || undefined);
if (res?.error) {
error(res.message || "Gagal komentar promotion");
close();
return;
}
close();
success("Promotion berhasil dikomentar");
// fetchData(); // refresh table
};
const handleRejectPromotion = async (id: number) => {
const MySwal = withReactContent(Swal);
const { value: message } = await MySwal.fire({
@ -338,7 +372,7 @@ export default function PromoDetailDialog({
className="bg-blue-200 hover:bg-blue-400"
onClick={(e) => {
e.stopPropagation();
setOpenCommentModal(true);
handleCommentPromotion(promo.id);
}}
>
Beri Tanggapan

View File

@ -33,6 +33,7 @@ import Cookies from "js-cookie";
import { getProductDataById } from "@/service/product";
import {
approveAgent,
commentAgent,
getAgentById,
rejectAgent,
updateAgent,
@ -141,6 +142,39 @@ export default function DetailAgentForm(props: { isDetail: boolean }) {
setOpenApproverHistory(true);
};
const handleCommentAgent = async (id: number) => {
const { value: message } = await MySwal.fire({
title: "Komen Agent",
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 commentAgent(id, message || undefined);
if (res?.error) {
error(res.message || "Gagal komentar agent");
close();
return;
}
close();
success("Agent berhasil dikomentar");
fetchData(); // refresh table
};
const handleRejectAgent = async (id: number) => {
const MySwal = withReactContent(Swal);
const { value: message } = await MySwal.fire({
@ -326,7 +360,7 @@ export default function DetailAgentForm(props: { isDetail: boolean }) {
<Button
variant="secondary"
className="bg-blue-200 hover:bg-blue-400"
onClick={() => setOpenCommentModal(true)}
onClick={() => handleCommentAgent(data.id)}
>
Beri Tanggapan
</Button>

View File

@ -188,7 +188,14 @@ export default function Login() {
return (
<div className="min-h-screen flex">
{/* Left Side - Logo Section */}
<div className="hidden lg:flex lg:w-1/2 bg-gradient-to-br from-gray-600 via-gray-700 to-gray-800 relative overflow-hidden">
<div
className="hidden lg:flex lg:w-1/2
bg-gradient-to-b
from-[#1E5F73]
via-[#5F8FA0]
to-[#C7DDE6]
relative overflow-hidden"
>
<div className="absolute inset-0 bg-black/20"></div>
<div className="relative z-10 flex items-center justify-center w-full p-12">
<div className="text-center">
@ -483,7 +490,7 @@ export default function Login() {
<Button
size="lg"
className="w-full bg-gradient-to-r from-gray-500 to-gray-600 hover:from-gray-600 hover:to-gray-700 text-white font-semibold py-3 rounded-lg transition-all duration-200 shadow-lg hover:shadow-xl"
className="w-full bg-[#1F6779] hover:to-gray-700 text-white font-semibold py-3 rounded-lg transition-all duration-200 shadow-lg hover:shadow-xl"
onClick={onSubmit}
>
Masuk ke Portal

View File

@ -32,6 +32,7 @@ import { useParams, useRouter } from "next/navigation";
import Cookies from "js-cookie";
import {
approveProduct,
commentProduct,
getProductDataById,
rejectProduct,
updateProduct,
@ -119,10 +120,14 @@ export default function DetailProductForm(props: { isDetail: boolean }) {
const router = useRouter();
// 🔹 Ambil userlevelId dari cookies
const [userRoleId, setUserRoleId] = useState<string | null>(null);
const MySwal = withReactContent(Swal);
// 🔹 Ambil userlevelId dari cookies
useEffect(() => {
const ulne = Cookies.get("ulne"); // contoh: "3"
setUserLevelId(ulne ?? null);
const urie = Cookies.get("urie"); // contoh: "3"
setUserRoleId(urie ?? null);
}, []);
const { getRootProps, getInputProps } = useDropzone({
@ -304,6 +309,39 @@ export default function DetailProductForm(props: { isDetail: boolean }) {
}
}
const handleCommentProduct = async (id: number) => {
const { value: message } = await MySwal.fire({
title: "Komen Produk",
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 commentProduct(id, message || undefined);
if (res?.error) {
error(res.message || "Gagal komentar produk");
close();
return;
}
close();
success("Produk berhasil dikomentar");
initState(); // refresh table
};
const handleRejectProduct = async (id: number) => {
const MySwal = withReactContent(Swal);
const { value: message } = await MySwal.fire({
@ -597,14 +635,14 @@ export default function DetailProductForm(props: { isDetail: boolean }) {
<p>Jaecoo - Approver | 10/11/2026</p>
</div>
</div>
{userLevelId !== "2" && detailData && (
{userRoleId !== "2" && detailData && (
<div className="flex justify-between items-center gap-3 px-6 py-4 border-t bg-[#F2F7FA] mt-10">
{detailData.status_id === 1 ? (
<>
<Button
variant="secondary"
className="bg-blue-200 hover:bg-blue-400"
onClick={() => setOpenCommentModal(true)}
onClick={() => handleCommentProduct(detailData.id)}
>
Beri Tanggapan
</Button>
@ -617,7 +655,7 @@ export default function DetailProductForm(props: { isDetail: boolean }) {
Reject
</Button>
{userLevelId === "1" && (
{userRoleId === "1" && (
<Button
className="bg-green-600 hover:bg-green-700 text-white w-[180px]"
onClick={() => handleApproveProduct(detailData.id)}

View File

@ -319,13 +319,13 @@ export default function ArticleTable() {
const res = await commentBanner(id, message || undefined);
if (res?.error) {
error(res.message || "Gagal menolak banner");
error(res.message || "Gagal komentar banner");
close();
return;
}
close();
success("Banner berhasil ditolak");
success("Banner berhasil dikomentar");
initState(); // refresh table
};

View File

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

View File

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

View File

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

View File

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