feat: update all approval
This commit is contained in:
parent
5579ad8c20
commit
be02fb7b0e
|
|
@ -47,9 +47,9 @@ import {
|
|||
} from "@/components/ui/table";
|
||||
import CustomPagination from "../layout/custom-pagination";
|
||||
import { EditBannerDialog } from "../form/banner-edit-dialog";
|
||||
import { Eye, CheckCheck } from "lucide-react";
|
||||
import { Eye, CheckCheck, X } from "lucide-react";
|
||||
import AgentDetailDialog from "../dialog/agent-dialog";
|
||||
import { deleteAgent, getAgentData, approveAgent } from "@/service/agent";
|
||||
import { deleteAgent, getAgentData, approveAgent, rejectAgent } from "@/service/agent";
|
||||
|
||||
const columns = [
|
||||
{ name: "No", uid: "no" },
|
||||
|
|
@ -94,12 +94,12 @@ export default function AgentTable() {
|
|||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
const [userLevelId, setUserLevelId] = useState<string | null>(null);
|
||||
const [userRoleId, setUserRoleId] = useState<string | null>(null);
|
||||
|
||||
// 🔹 Ambil userlevelId dari cookies
|
||||
// 🔹 Ambil userRoleId dari cookies
|
||||
useEffect(() => {
|
||||
const ulne = Cookies.get("ulne"); // contoh: "3"
|
||||
setUserLevelId(ulne ?? null);
|
||||
const urie = Cookies.get("urie"); // userRoleId dari cookies
|
||||
setUserRoleId(urie ?? null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -202,6 +202,40 @@ export default function AgentTable() {
|
|||
initState(); // refresh table
|
||||
};
|
||||
|
||||
const handleRejectAgent = async (id: number) => {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const { value: message } = await MySwal.fire({
|
||||
title: "Tolak Agent",
|
||||
input: "textarea",
|
||||
inputLabel: "Alasan penolakan (opsional)",
|
||||
inputPlaceholder: "Masukkan alasan penolakan...",
|
||||
inputAttributes: {
|
||||
"aria-label": "Masukkan alasan penolakan",
|
||||
},
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Tolak",
|
||||
cancelButtonText: "Batal",
|
||||
confirmButtonColor: "#dc2626",
|
||||
});
|
||||
|
||||
if (message === undefined) {
|
||||
return; // User cancelled
|
||||
}
|
||||
|
||||
loading();
|
||||
const res = await rejectAgent(id, message || undefined);
|
||||
|
||||
if (res?.error) {
|
||||
error(res.message || "Gagal menolak agent");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
close();
|
||||
success("Agent berhasil ditolak");
|
||||
initState(); // refresh table
|
||||
};
|
||||
|
||||
const copyUrlArticle = async (id: number, slug: string) => {
|
||||
const url =
|
||||
`${window.location.protocol}//${window.location.host}` +
|
||||
|
|
@ -416,6 +450,10 @@ export default function AgentTable() {
|
|||
<span className="bg-green-100 text-green-700 text-xs px-3 py-1 rounded-full font-medium">
|
||||
Disetujui
|
||||
</span>
|
||||
) : item.status_id === 3 ? (
|
||||
<span className="bg-red-100 text-red-700 text-xs px-3 py-1 rounded-full font-medium">
|
||||
Ditolak
|
||||
</span>
|
||||
) : (
|
||||
<span className="bg-gray-100 text-gray-600 text-xs px-3 py-1 rounded-full font-medium">
|
||||
{item.status_id || "Tidak Diketahui"}
|
||||
|
|
@ -458,17 +496,28 @@ export default function AgentTable() {
|
|||
</Button>
|
||||
</Link>
|
||||
|
||||
{/* Tombol Approve - hanya untuk admin dan status pending */}
|
||||
{userLevelId === "1" && item.status_id === 1 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleApproveAgent(item.id)}
|
||||
className="text-green-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<CheckCheck className="w-4 h-4 mr-1" />
|
||||
Approve
|
||||
</Button>
|
||||
{/* Tombol Approve & Reject - hanya untuk admin dan status pending */}
|
||||
{userRoleId === "1" && item.status_id === 1 && (
|
||||
<>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleApproveAgent(item.id)}
|
||||
className="text-green-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<CheckCheck className="w-4 h-4 mr-1" />
|
||||
Approve
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleRejectAgent(item.id)}
|
||||
className="text-red-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<X className="w-4 h-4 mr-1" />
|
||||
Reject
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{/* Tombol Hapus */}
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ import {
|
|||
} from "@/components/ui/table";
|
||||
import CustomPagination from "../layout/custom-pagination";
|
||||
import { EditBannerDialog } from "../form/banner-edit-dialog";
|
||||
import { deleteBanner, getBannerData, updateBanner, approveBanner } from "@/service/banner";
|
||||
import { deleteBanner, getBannerData, updateBanner, approveBanner, rejectBanner, getApprovalHistory } from "@/service/banner";
|
||||
import { Check, CheckCheck, Clock, Eye, X } from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
|
|
@ -91,14 +91,14 @@ export default function ArticleTable() {
|
|||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
const [userLevelId, setUserLevelId] = useState<string | null>(null);
|
||||
const [userRoleId, setUserRoleId] = useState<string | null>(null);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
// 🔹 Ambil userlevelId dari cookies
|
||||
// 🔹 Ambil userRoleId dari cookies
|
||||
useEffect(() => {
|
||||
const ulne = Cookies.get("ulne"); // contoh: "3"
|
||||
setUserLevelId(ulne ?? null);
|
||||
const urie = Cookies.get("urie"); // userRoleId dari cookies
|
||||
setUserRoleId(urie ?? null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -254,6 +254,39 @@ export default function ArticleTable() {
|
|||
initState(); // refresh table
|
||||
};
|
||||
|
||||
const handleRejectBanner = async (id: number) => {
|
||||
const { value: message } = await MySwal.fire({
|
||||
title: "Tolak Banner",
|
||||
input: "textarea",
|
||||
inputLabel: "Alasan penolakan (opsional)",
|
||||
inputPlaceholder: "Masukkan alasan penolakan...",
|
||||
inputAttributes: {
|
||||
"aria-label": "Masukkan alasan penolakan",
|
||||
},
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Tolak",
|
||||
cancelButtonText: "Batal",
|
||||
confirmButtonColor: "#dc2626",
|
||||
});
|
||||
|
||||
if (message === undefined) {
|
||||
return; // User cancelled
|
||||
}
|
||||
|
||||
loading();
|
||||
const res = await rejectBanner(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 () => {
|
||||
if (!viewBanner) return;
|
||||
|
||||
|
|
@ -486,6 +519,10 @@ export default function ArticleTable() {
|
|||
<span className="bg-green-100 text-green-700 text-xs px-3 py-1 rounded-full font-medium">
|
||||
Disetujui
|
||||
</span>
|
||||
) : item.status_id === 3 ? (
|
||||
<span className="bg-red-100 text-red-700 text-xs px-3 py-1 rounded-full font-medium">
|
||||
Ditolak
|
||||
</span>
|
||||
) : (
|
||||
<span className="bg-gray-100 text-gray-600 text-xs px-3 py-1 rounded-full font-medium">
|
||||
{item.status_id || "Tidak Diketahui"}
|
||||
|
|
@ -505,7 +542,7 @@ export default function ArticleTable() {
|
|||
<Eye className="w-4 h-4 mr-1" />
|
||||
Lihat
|
||||
</Button>
|
||||
{userLevelId !== "3" && (
|
||||
{userRoleId !== "3" && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
|
|
@ -516,16 +553,27 @@ export default function ArticleTable() {
|
|||
Edit
|
||||
</Button>
|
||||
)}
|
||||
{userLevelId === "1" && item.status_id === 1 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-green-600 hover:bg-transparent hover:underline p-0"
|
||||
onClick={() => handleApproveBanner(item.id)}
|
||||
>
|
||||
<CheckCheck className="w-4 h-4 mr-1" />
|
||||
Approve
|
||||
</Button>
|
||||
{userRoleId === "1" && item.status_id === 1 && (
|
||||
<>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-green-600 hover:bg-transparent hover:underline p-0"
|
||||
onClick={() => handleApproveBanner(item.id)}
|
||||
>
|
||||
<CheckCheck className="w-4 h-4 mr-1" />
|
||||
Approve
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="text-red-600 hover:bg-transparent hover:underline p-0"
|
||||
onClick={() => handleRejectBanner(item.id)}
|
||||
>
|
||||
<X className="w-4 h-4 mr-1" />
|
||||
Reject
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
|
@ -801,7 +849,7 @@ export default function ArticleTable() {
|
|||
</div>
|
||||
|
||||
{/* FOOTER */}
|
||||
{userLevelId !== "2" && (
|
||||
{userRoleId !== "2" && (
|
||||
<div className="flex justify-between items-center gap-3 px-6 py-4 border-t bg-[#F2F7FA]">
|
||||
{viewBanner.status === "1" ? (
|
||||
<>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
import { useEffect, useState } from "react";
|
||||
import Image from "next/image";
|
||||
import { Eye, Pencil, Trash2, Calendar, MapPin, CheckCheck } from "lucide-react";
|
||||
import { Eye, Pencil, Trash2, Calendar, MapPin, CheckCheck, X } from "lucide-react";
|
||||
import {
|
||||
deleteGalery,
|
||||
getGaleryById,
|
||||
getGaleryData,
|
||||
getGaleryFileData,
|
||||
approveGalery,
|
||||
rejectGalery,
|
||||
} from "@/service/galery";
|
||||
import { DialogDetailGaleri } from "../dialog/galery-detail-dialog";
|
||||
import { DialogUpdateGaleri } from "../dialog/galery-update-dialog";
|
||||
|
|
@ -20,7 +21,7 @@ import Cookies from "js-cookie";
|
|||
export default function Galery() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const [data, setData] = useState<any[]>([]);
|
||||
const [userLevelId, setUserLevelId] = useState<string | null>(null);
|
||||
const [userRoleId, setUserRoleId] = useState<string | null>(null);
|
||||
|
||||
const [page, setPage] = useState(1);
|
||||
const [showData, setShowData] = useState("10");
|
||||
|
|
@ -73,10 +74,10 @@ export default function Galery() {
|
|||
}
|
||||
};
|
||||
|
||||
// 🔹 Ambil userlevelId dari cookies
|
||||
// 🔹 Ambil userRoleId dari cookies
|
||||
useEffect(() => {
|
||||
const ulne = Cookies.get("ulne"); // contoh: "3"
|
||||
setUserLevelId(ulne ?? null);
|
||||
const urie = Cookies.get("urie"); // userRoleId dari cookies
|
||||
setUserRoleId(urie ?? null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -144,6 +145,39 @@ export default function Galery() {
|
|||
fetchData(); // refresh table
|
||||
};
|
||||
|
||||
const handleRejectGalery = async (id: number) => {
|
||||
const { value: message } = await MySwal.fire({
|
||||
title: "Tolak Galery",
|
||||
input: "textarea",
|
||||
inputLabel: "Alasan penolakan (opsional)",
|
||||
inputPlaceholder: "Masukkan alasan penolakan...",
|
||||
inputAttributes: {
|
||||
"aria-label": "Masukkan alasan penolakan",
|
||||
},
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Tolak",
|
||||
cancelButtonText: "Batal",
|
||||
confirmButtonColor: "#dc2626",
|
||||
});
|
||||
|
||||
if (message === undefined) {
|
||||
return; // User cancelled
|
||||
}
|
||||
|
||||
loading();
|
||||
const res = await rejectGalery(id, message || undefined);
|
||||
|
||||
if (res?.error) {
|
||||
error(res.message || "Gagal menolak galery");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
close();
|
||||
success("Galery berhasil ditolak");
|
||||
fetchData(); // refresh table
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mt-6">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
|
||||
|
|
@ -170,11 +204,13 @@ export default function Galery() {
|
|||
{/* Status Badge */}
|
||||
<span
|
||||
className={`absolute top-3 left-3 text-xs px-3 py-1 rounded-full font-medium
|
||||
${
|
||||
$ {
|
||||
item.status_id === 2
|
||||
? "bg-green-100 text-green-700"
|
||||
: item.status_id === 1
|
||||
? "bg-yellow-100 text-yellow-700"
|
||||
: item.status_id === 3
|
||||
? "bg-red-100 text-red-700"
|
||||
: "bg-gray-100 text-gray-600"
|
||||
}`}
|
||||
>
|
||||
|
|
@ -182,6 +218,8 @@ export default function Galery() {
|
|||
? "Disetujui"
|
||||
: item.status_id === 1
|
||||
? "Menunggu"
|
||||
: item.status_id === 3
|
||||
? "Ditolak"
|
||||
: "Tidak Diketahui"}
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -219,14 +257,22 @@ export default function Galery() {
|
|||
<Pencil className="h-4 w-4" /> Edit
|
||||
</button>
|
||||
|
||||
{/* Tombol Approve - hanya untuk admin dan status pending */}
|
||||
{userLevelId === "1" && item.status_id === 1 && (
|
||||
<button
|
||||
className="flex items-center gap-1 text-green-600 hover:text-green-700 transition"
|
||||
onClick={() => handleApproveGalery(item.id)}
|
||||
>
|
||||
<CheckCheck className="h-4 w-4" /> Approve
|
||||
</button>
|
||||
{/* Tombol Approve & Reject - hanya untuk admin dan status pending */}
|
||||
{userRoleId === "1" && item.status_id === 1 && (
|
||||
<>
|
||||
<button
|
||||
className="flex items-center gap-1 text-green-600 hover:text-green-700 transition"
|
||||
onClick={() => handleApproveGalery(item.id)}
|
||||
>
|
||||
<CheckCheck className="h-4 w-4" /> Approve
|
||||
</button>
|
||||
<button
|
||||
className="flex items-center gap-1 text-red-600 hover:text-red-700 transition"
|
||||
onClick={() => handleRejectGalery(item.id)}
|
||||
>
|
||||
<X className="h-4 w-4" /> Reject
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -47,8 +47,8 @@ import {
|
|||
} from "@/components/ui/table";
|
||||
import CustomPagination from "../layout/custom-pagination";
|
||||
import { EditBannerDialog } from "../form/banner-edit-dialog";
|
||||
import { deleteProduct, getProductPagination, approveProduct } from "@/service/product";
|
||||
import { CheckCheck, Eye } from "lucide-react";
|
||||
import { deleteProduct, getProductPagination, approveProduct, rejectProduct } from "@/service/product";
|
||||
import { CheckCheck, Eye, X } from "lucide-react";
|
||||
import { useRouter } from "next/navigation";
|
||||
|
||||
const columns = [
|
||||
|
|
@ -92,14 +92,14 @@ export default function ProductTable() {
|
|||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
const [userLevelId, setUserLevelId] = useState<string | null>(null);
|
||||
const [userRoleId, setUserRoleId] = useState<string | null>(null);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
// 🔹 Ambil userlevelId dari cookies
|
||||
// 🔹 Ambil userRoleId dari cookies
|
||||
useEffect(() => {
|
||||
const ulne = Cookies.get("ulne"); // contoh: "3"
|
||||
setUserLevelId(ulne ?? null);
|
||||
const urie = Cookies.get("urie"); // userRoleId dari cookies
|
||||
setUserRoleId(urie ?? null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -209,6 +209,40 @@ export default function ProductTable() {
|
|||
initState(); // refresh table
|
||||
};
|
||||
|
||||
const handleRejectProduct = async (id: number) => {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const { value: message } = await MySwal.fire({
|
||||
title: "Tolak Product",
|
||||
input: "textarea",
|
||||
inputLabel: "Alasan penolakan (opsional)",
|
||||
inputPlaceholder: "Masukkan alasan penolakan...",
|
||||
inputAttributes: {
|
||||
"aria-label": "Masukkan alasan penolakan",
|
||||
},
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Tolak",
|
||||
cancelButtonText: "Batal",
|
||||
confirmButtonColor: "#dc2626",
|
||||
});
|
||||
|
||||
if (message === undefined) {
|
||||
return; // User cancelled
|
||||
}
|
||||
|
||||
loading();
|
||||
const res = await rejectProduct(id, message || undefined);
|
||||
|
||||
if (res?.error) {
|
||||
error(res.message || "Gagal menolak product");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
close();
|
||||
success("Product berhasil ditolak");
|
||||
initState(); // refresh table
|
||||
};
|
||||
|
||||
const copyUrlArticle = async (id: number, slug: string) => {
|
||||
const url =
|
||||
`${window.location.protocol}//${window.location.host}` +
|
||||
|
|
@ -448,6 +482,10 @@ export default function ProductTable() {
|
|||
<span className="bg-green-100 text-green-700 text-xs px-3 py-1 rounded-full font-medium">
|
||||
Disetujui
|
||||
</span>
|
||||
) : item.status_id === 3 ? (
|
||||
<span className="bg-red-100 text-red-700 text-xs px-3 py-1 rounded-full font-medium">
|
||||
Ditolak
|
||||
</span>
|
||||
) : (
|
||||
<span className="bg-gray-100 text-gray-600 text-xs px-3 py-1 rounded-full font-medium">
|
||||
{item.status_id || "Tidak Diketahui"}
|
||||
|
|
@ -468,7 +506,7 @@ export default function ProductTable() {
|
|||
Lihat
|
||||
</Button>
|
||||
</Link>
|
||||
{userLevelId !== "3" && (
|
||||
{userRoleId !== "3" && (
|
||||
<Link href={"/admin/product/update"}>
|
||||
<Button
|
||||
className="text-[#0F6C75] hover:bg-transparent hover:underline p-0"
|
||||
|
|
@ -479,16 +517,27 @@ export default function ProductTable() {
|
|||
</Button>
|
||||
</Link>
|
||||
)}
|
||||
{userLevelId === "1" && item.status_id === 1 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleApproveProduct(item.id)}
|
||||
className="text-green-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<CheckCheck className="w-4 h-4 mr-1" />
|
||||
Approve
|
||||
</Button>
|
||||
{userRoleId === "1" && item.status_id === 1 && (
|
||||
<>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleApproveProduct(item.id)}
|
||||
className="text-green-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<CheckCheck className="w-4 h-4 mr-1" />
|
||||
Approve
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleRejectProduct(item.id)}
|
||||
className="text-red-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<X className="w-4 h-4 mr-1" />
|
||||
Reject
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@ import {
|
|||
} from "@/components/ui/table";
|
||||
import CustomPagination from "../layout/custom-pagination";
|
||||
import { EditBannerDialog } from "../form/banner-edit-dialog";
|
||||
import { Eye, Trash2, CheckCheck } from "lucide-react";
|
||||
import { Eye, Trash2, CheckCheck, X } from "lucide-react";
|
||||
import AgentDetailDialog from "../dialog/agent-dialog";
|
||||
import PromoDetailDialog from "../dialog/promo-dialog";
|
||||
import { deletePromotion, getPromotionPagination, approvePromotion } from "@/service/promotion";
|
||||
import { deletePromotion, getPromotionPagination, approvePromotion, rejectPromotion } from "@/service/promotion";
|
||||
|
||||
const columns = [
|
||||
{ name: "No", uid: "no" },
|
||||
|
|
@ -96,12 +96,12 @@ export default function PromotionTable() {
|
|||
startDate: null,
|
||||
endDate: null,
|
||||
});
|
||||
const [userLevelId, setUserLevelId] = useState<string | null>(null);
|
||||
const [userRoleId, setUserRoleId] = useState<string | null>(null);
|
||||
|
||||
// 🔹 Ambil userlevelId dari cookies
|
||||
// 🔹 Ambil userRoleId dari cookies
|
||||
useEffect(() => {
|
||||
const ulne = Cookies.get("ulne"); // contoh: "3"
|
||||
setUserLevelId(ulne ?? null);
|
||||
const urie = Cookies.get("urie"); // userRoleId dari cookies
|
||||
setUserRoleId(urie ?? null);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -204,6 +204,40 @@ export default function PromotionTable() {
|
|||
initState(); // refresh table
|
||||
};
|
||||
|
||||
const handleRejectPromotion = async (id: number) => {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const { value: message } = await MySwal.fire({
|
||||
title: "Tolak Promotion",
|
||||
input: "textarea",
|
||||
inputLabel: "Alasan penolakan (opsional)",
|
||||
inputPlaceholder: "Masukkan alasan penolakan...",
|
||||
inputAttributes: {
|
||||
"aria-label": "Masukkan alasan penolakan",
|
||||
},
|
||||
showCancelButton: true,
|
||||
confirmButtonText: "Tolak",
|
||||
cancelButtonText: "Batal",
|
||||
confirmButtonColor: "#dc2626",
|
||||
});
|
||||
|
||||
if (message === undefined) {
|
||||
return; // User cancelled
|
||||
}
|
||||
|
||||
loading();
|
||||
const res = await rejectPromotion(id, message || undefined);
|
||||
|
||||
if (res?.error) {
|
||||
error(res.message || "Gagal menolak promotion");
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
close();
|
||||
success("Promotion berhasil ditolak");
|
||||
initState(); // refresh table
|
||||
};
|
||||
|
||||
const copyUrlArticle = async (id: number, slug: string) => {
|
||||
const url =
|
||||
`${window.location.protocol}//${window.location.host}` +
|
||||
|
|
@ -408,6 +442,10 @@ export default function PromotionTable() {
|
|||
<span className="bg-green-100 text-green-700 text-xs px-3 py-1 rounded-full font-medium">
|
||||
Disetujui
|
||||
</span>
|
||||
) : item.status_id === 3 ? (
|
||||
<span className="bg-red-100 text-red-700 text-xs px-3 py-1 rounded-full font-medium">
|
||||
Ditolak
|
||||
</span>
|
||||
) : (
|
||||
<span className="bg-gray-100 text-gray-600 text-xs px-3 py-1 rounded-full font-medium">
|
||||
{item.status_id || "Tidak Diketahui"}
|
||||
|
|
@ -432,17 +470,28 @@ export default function PromotionTable() {
|
|||
</Button>
|
||||
{/* Tombol Edit */}
|
||||
|
||||
{/* Tombol Approve - hanya untuk admin dan status pending */}
|
||||
{userLevelId === "1" && item.status_id === 1 && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleApprovePromotion(item.id)}
|
||||
className="text-green-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<CheckCheck className="w-4 h-4 mr-1" />
|
||||
Approve
|
||||
</Button>
|
||||
{/* Tombol Approve & Reject - hanya untuk admin dan status pending */}
|
||||
{userRoleId === "1" && item.status_id === 1 && (
|
||||
<>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleApprovePromotion(item.id)}
|
||||
className="text-green-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<CheckCheck className="w-4 h-4 mr-1" />
|
||||
Approve
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleRejectPromotion(item.id)}
|
||||
className="text-red-600 hover:bg-transparent hover:underline p-0"
|
||||
>
|
||||
<X className="w-4 h-4 mr-1" />
|
||||
Reject
|
||||
</Button>
|
||||
</>
|
||||
)}
|
||||
{/* Tombol Hapus */}
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -45,4 +45,18 @@ export async function approveAgent(id: string | number) {
|
|||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/sales-agents/${id}/approve`, {}, headers);
|
||||
}
|
||||
|
||||
export async function rejectAgent(id: string | number, message?: string) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/sales-agents/${id}/reject`, { message }, headers);
|
||||
}
|
||||
|
||||
export async function getApprovalHistory(moduleType: string, moduleId: string | number) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/approval-histories/${moduleType}/${moduleId}`, headers);
|
||||
}
|
||||
|
|
@ -55,4 +55,18 @@ export async function approveBanner(id: string | number) {
|
|||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/banners/${id}/approve`, {}, headers);
|
||||
}
|
||||
|
||||
export async function rejectBanner(id: string | number, message?: string) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/banners/${id}/reject`, { message }, headers);
|
||||
}
|
||||
|
||||
export async function getApprovalHistory(moduleType: string, moduleId: string | number) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/approval-histories/${moduleType}/${moduleId}`, headers);
|
||||
}
|
||||
|
|
@ -76,4 +76,18 @@ export async function approveGalery(id: string | number) {
|
|||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/galleries/${id}/approve`, {}, headers);
|
||||
}
|
||||
|
||||
export async function rejectGalery(id: string | number, message?: string) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/galleries/${id}/reject`, { message }, headers);
|
||||
}
|
||||
|
||||
export async function getApprovalHistory(moduleType: string, moduleId: string | number) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/approval-histories/${moduleType}/${moduleId}`, headers);
|
||||
}
|
||||
|
|
@ -48,4 +48,18 @@ export async function approveProduct(id: string | number) {
|
|||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/products/${id}/approve`, {}, headers);
|
||||
}
|
||||
|
||||
export async function rejectProduct(id: string | number, message?: string) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/products/${id}/reject`, { message }, headers);
|
||||
}
|
||||
|
||||
export async function getApprovalHistory(moduleType: string, moduleId: string | number) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/approval-histories/${moduleType}/${moduleId}`, headers);
|
||||
}
|
||||
|
|
@ -43,4 +43,18 @@ export async function approvePromotion(id: string | number) {
|
|||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/promotions/${id}/approve`, {}, headers);
|
||||
}
|
||||
|
||||
export async function rejectPromotion(id: string | number, message?: string) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpPutInterceptor(`/promotions/${id}/reject`, { message }, headers);
|
||||
}
|
||||
|
||||
export async function getApprovalHistory(moduleType: string, moduleId: string | number) {
|
||||
const headers = {
|
||||
"content-type": "application/json",
|
||||
};
|
||||
return await httpGetInterceptor(`/approval-histories/${moduleType}/${moduleId}`, headers);
|
||||
}
|
||||
Loading…
Reference in New Issue