fixing sabda

This commit is contained in:
Sabda Yagra 2025-09-23 11:47:39 +07:00
parent 9fa3148d48
commit 78a4f6d1f8
16 changed files with 544 additions and 221 deletions

View File

@ -42,7 +42,7 @@ const AudioVisualTabs = () => {
<TabsContent value="pending" className="mt-0"> <TabsContent value="pending" className="mt-0">
<div className="bg-white rounded-lg border border-gray-200 shadow-sm"> <div className="bg-white rounded-lg border border-gray-200 shadow-sm">
<PendingApprovalTable /> <PendingApprovalTable typeId={2} />
</div> </div>
</TabsContent> </TabsContent>
</Tabs> </Tabs>

View File

@ -42,7 +42,11 @@ import TablePagination from "@/components/table/table-pagination";
import { listPendingApproval, PendingApprovalData } from "@/service/content/content"; import { listPendingApproval, PendingApprovalData } from "@/service/content/content";
import usePendingApprovalColumns from "./pending-approval-columns"; import usePendingApprovalColumns from "./pending-approval-columns";
const PendingApprovalTable = () => { type PendingApprovalTableProps = {
typeId?: number;
};
const PendingApprovalTable = ({ typeId }: PendingApprovalTableProps) => {
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const [dataTable, setDataTable] = React.useState<PendingApprovalData[]>([]); const [dataTable, setDataTable] = React.useState<PendingApprovalData[]>([]);
const [totalData, setTotalData] = React.useState<number>(0); const [totalData, setTotalData] = React.useState<number>(0);
@ -111,7 +115,7 @@ const PendingApprovalTable = () => {
async function fetchPendingData() { async function fetchPendingData() {
try { try {
console.log("fetchPendingData: page =", page, "showData =", showData, "Number(showData) =", Number(showData)); console.log("fetchPendingData: page =", page, "showData =", showData, "Number(showData) =", Number(showData));
const res = await listPendingApproval(page, Number(showData)); const res = await listPendingApproval(page, Number(showData), typeId);
if (res && !res.error && res.data) { if (res && !res.error && res.data) {
// Filter data based on search if provided // Filter data based on search if provided

View File

@ -39,12 +39,12 @@ import columns from "./columns";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { format } from "date-fns"; import { format } from "date-fns";
import useTableColumns from "./columns"; import useTableColumns from "./columns";
import { import {
listEnableCategory, listEnableCategory,
listDataVideo, listDataVideo,
listArticles, listArticles,
listArticlesWithFilters, listArticlesWithFilters,
ArticleFilters ArticleFilters,
} from "@/service/content"; } from "@/service/content";
import { import {
SortingState, SortingState,
@ -174,6 +174,7 @@ const TableVideo = () => {
const formattedEndDate = endDate const formattedEndDate = endDate
? format(new Date(endDate), "yyyy-MM-dd") ? format(new Date(endDate), "yyyy-MM-dd")
: ""; : "";
try { try {
// Using the new interface-based approach for video content // Using the new interface-based approach for video content
const filters: ArticleFilters = { const filters: ArticleFilters = {
@ -182,15 +183,15 @@ const TableVideo = () => {
title: search || undefined, title: search || undefined,
categoryId: categoryFilter ? Number(categoryFilter) : undefined, categoryId: categoryFilter ? Number(categoryFilter) : undefined,
typeId: 2, // video content type typeId: 2, // video content type
statusId: statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined, statusId:
statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined,
startDate: formattedStartDate || undefined, startDate: formattedStartDate || undefined,
endDate: formattedEndDate || undefined, endDate: formattedEndDate || undefined,
}; };
const res = await listArticlesWithFilters(filters); const res = await listArticlesWithFilters(filters);
const data = res?.data?.data; const data = res?.data?.data;
// Handle new articles API response structure
if (Array.isArray(data)) { if (Array.isArray(data)) {
data.forEach((item: any, index: number) => { data.forEach((item: any, index: number) => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
@ -198,21 +199,80 @@ const TableVideo = () => {
setDataTable(data); setDataTable(data);
setTotalData(data.length); setTotalData(data.length);
setTotalPage(Math.ceil(data.length / Number(showData))); setTotalPage(Math.ceil(data.length / Number(showData)));
} else { } else if (Array.isArray(data?.content)) {
// Fallback to old structure if API still returns old format const contentData = data.content;
const contentData = data?.content;
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements ?? contentData.length);
setTotalPage(data?.totalPages); setTotalPage(
data?.totalPages ?? Math.ceil(contentData.length / Number(showData))
);
} else {
setDataTable([]);
setTotalData(0);
setTotalPage(1);
} }
} catch (error) { } catch (error) {
console.error("Error fetching tasks:", error); console.error("Error fetching tasks:", error);
setDataTable([]);
setTotalData(0);
setTotalPage(1);
} }
} }
// async function fetchData() {
// const formattedStartDate = startDate
// ? format(new Date(startDate), "yyyy-MM-dd")
// : "";
// const formattedEndDate = endDate
// ? format(new Date(endDate), "yyyy-MM-dd")
// : "";
// try {
// // Using the new interface-based approach for video content
// const filters: ArticleFilters = {
// page: page,
// totalPage: Number(showData),
// title: search || undefined,
// categoryId: categoryFilter ? Number(categoryFilter) : undefined,
// typeId: 2, // video content type
// statusId:
// statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined,
// startDate: formattedStartDate || undefined,
// endDate: formattedEndDate || undefined,
// };
// const res = await listArticlesWithFilters(filters);
// const data = res?.data?.data;
// // Handle new articles API response structure
// if (Array.isArray(data)) {
// data.forEach((item: any, index: number) => {
// item.no = (page - 1) * Number(showData) + index + 1;
// });
// setDataTable(data);
// setTotalData(data.length);
// setTotalPage(Math.ceil(data.length / Number(showData)));
// } else {
// // Fallback to old structure if API still returns old format
// const contentData = data?.content;
// contentData.forEach((item: any, index: number) => {
// item.no = (page - 1) * Number(showData) + index + 1;
// });
// setDataTable(contentData);
// setTotalData(data?.totalElements ?? contentData.length);
// setTotalPage(
// data?.totalPages ?? Math.ceil(contentData.length / Number(showData))
// );
// // setTotalData(data?.totalElements);
// // setTotalPage(data?.totalPages);
// }
// } catch (error) {
// console.error("Error fetching tasks:", error);
// }
// }
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => { const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value); // Perbarui state search setSearch(e.target.value); // Perbarui state search
table.getColumn("title")?.setFilterValue(e.target.value); // Set filter tabel table.getColumn("title")?.setFilterValue(e.target.value); // Set filter tabel

View File

@ -42,7 +42,7 @@ const AudioTabs = () => {
<TabsContent value="pending" className="mt-0"> <TabsContent value="pending" className="mt-0">
<div className="bg-white rounded-lg border border-gray-200 shadow-sm"> <div className="bg-white rounded-lg border border-gray-200 shadow-sm">
<PendingApprovalTable /> <PendingApprovalTable typeId={4} />
</div> </div>
</TabsContent> </TabsContent>
</Tabs> </Tabs>

View File

@ -42,7 +42,11 @@ import TablePagination from "@/components/table/table-pagination";
import { listPendingApproval, PendingApprovalData } from "@/service/content/content"; import { listPendingApproval, PendingApprovalData } from "@/service/content/content";
import usePendingApprovalColumns from "./pending-approval-columns"; import usePendingApprovalColumns from "./pending-approval-columns";
const PendingApprovalTable = () => { type PendingApprovalTableProps = {
typeId?: number;
};
const PendingApprovalTable = ({ typeId }: PendingApprovalTableProps) => {
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const [dataTable, setDataTable] = React.useState<PendingApprovalData[]>([]); const [dataTable, setDataTable] = React.useState<PendingApprovalData[]>([]);
const [totalData, setTotalData] = React.useState<number>(0); const [totalData, setTotalData] = React.useState<number>(0);
@ -111,7 +115,7 @@ const PendingApprovalTable = () => {
async function fetchPendingData() { async function fetchPendingData() {
try { try {
console.log("fetchPendingData: page =", page, "showData =", showData, "Number(showData) =", Number(showData)); console.log("fetchPendingData: page =", page, "showData =", showData, "Number(showData) =", Number(showData));
const res = await listPendingApproval(page, Number(showData)); const res = await listPendingApproval(page, Number(showData), typeId);
if (res && !res.error && res.data) { if (res && !res.error && res.data) {
// Filter data based on search if provided // Filter data based on search if provided

View File

@ -171,51 +171,106 @@ const TableAudio = () => {
}); });
}; };
async function fetchData() { async function fetchData() {
const formattedStartDate = startDate const formattedStartDate = startDate
? format(new Date(startDate), "yyyy-MM-dd") ? format(new Date(startDate), "yyyy-MM-dd")
: ""; : "";
const formattedEndDate = endDate const formattedEndDate = endDate
? format(new Date(endDate), "yyyy-MM-dd") ? format(new Date(endDate), "yyyy-MM-dd")
: ""; : "";
try {
// Using the new interface-based approach for audio content try {
const filters: ArticleFilters = { // Using the new interface-based approach for video content
page: page, const filters: ArticleFilters = {
totalPage: Number(showData), page: page,
title: search || undefined, totalPage: Number(showData),
categoryId: categoryFilter ? Number(categoryFilter) : undefined, title: search || undefined,
typeId: 4, // audio content type categoryId: categoryFilter ? Number(categoryFilter) : undefined,
statusId: statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined, typeId: 2, // video content type
startDate: formattedStartDate || undefined, statusId:
endDate: formattedEndDate || undefined, statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined,
}; startDate: formattedStartDate || undefined,
endDate: formattedEndDate || undefined,
const res = await listArticlesWithFilters(filters); };
const data = res?.data?.data; const res = await listArticlesWithFilters(filters);
// Handle new articles API response structure const data = res?.data?.data;
if (Array.isArray(data)) {
data.forEach((item: any, index: number) => { if (Array.isArray(data)) {
item.no = (page - 1) * Number(showData) + index + 1; data.forEach((item: any, index: number) => {
}); item.no = (page - 1) * Number(showData) + index + 1;
setDataTable(data); });
setTotalData(data.length); setDataTable(data);
setTotalPage(Math.ceil(data.length / Number(showData))); setTotalData(data.length);
} else { setTotalPage(Math.ceil(data.length / Number(showData)));
// Fallback to old structure if API still returns old format } else if (Array.isArray(data?.content)) {
const contentData = data?.content; const contentData = data.content;
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements ?? contentData.length);
setTotalPage(data?.totalPages); setTotalPage(
data?.totalPages ?? Math.ceil(contentData.length / Number(showData))
);
} else {
setDataTable([]);
setTotalData(0);
setTotalPage(1);
}
} catch (error) {
console.error("Error fetching tasks:", error);
setDataTable([]);
setTotalData(0);
setTotalPage(1);
} }
} catch (error) {
console.error("Error fetching tasks:", error);
} }
}
// async function fetchData() {
// const formattedStartDate = startDate
// ? format(new Date(startDate), "yyyy-MM-dd")
// : "";
// const formattedEndDate = endDate
// ? format(new Date(endDate), "yyyy-MM-dd")
// : "";
// try {
// // Using the new interface-based approach for audio content
// const filters: ArticleFilters = {
// page: page,
// totalPage: Number(showData),
// title: search || undefined,
// categoryId: categoryFilter ? Number(categoryFilter) : undefined,
// typeId: 4, // audio content type
// statusId: statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined,
// startDate: formattedStartDate || undefined,
// endDate: formattedEndDate || undefined,
// };
// const res = await listArticlesWithFilters(filters);
// const data = res?.data?.data;
// // Handle new articles API response structure
// if (Array.isArray(data)) {
// data.forEach((item: any, index: number) => {
// item.no = (page - 1) * Number(showData) + index + 1;
// });
// setDataTable(data);
// setTotalData(data.length);
// setTotalPage(Math.ceil(data.length / Number(showData)));
// } else {
// // Fallback to old structure if API still returns old format
// const contentData = data?.content;
// contentData.forEach((item: any, index: number) => {
// item.no = (page - 1) * Number(showData) + index + 1;
// });
// setDataTable(contentData);
// setTotalData(data?.totalElements);
// setTotalPage(data?.totalPages);
// }
// } catch (error) {
// console.error("Error fetching tasks:", error);
// }
// }
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => { const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value); // Perbarui state search setSearch(e.target.value); // Perbarui state search

View File

@ -42,7 +42,7 @@ const DocumentTabs = () => {
<TabsContent value="pending" className="mt-0"> <TabsContent value="pending" className="mt-0">
<div className="bg-white rounded-lg border border-gray-200 shadow-sm"> <div className="bg-white rounded-lg border border-gray-200 shadow-sm">
<PendingApprovalTable /> <PendingApprovalTable typeId={3} />
</div> </div>
</TabsContent> </TabsContent>
</Tabs> </Tabs>

View File

@ -42,7 +42,11 @@ import TablePagination from "@/components/table/table-pagination";
import { listPendingApproval, PendingApprovalData } from "@/service/content/content"; import { listPendingApproval, PendingApprovalData } from "@/service/content/content";
import usePendingApprovalColumns from "./pending-approval-columns"; import usePendingApprovalColumns from "./pending-approval-columns";
const PendingApprovalTable = () => { type PendingApprovalTableProps = {
typeId?: number;
};
const PendingApprovalTable = ({ typeId }: PendingApprovalTableProps) => {
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const [dataTable, setDataTable] = React.useState<PendingApprovalData[]>([]); const [dataTable, setDataTable] = React.useState<PendingApprovalData[]>([]);
const [totalData, setTotalData] = React.useState<number>(0); const [totalData, setTotalData] = React.useState<number>(0);
@ -95,7 +99,7 @@ const PendingApprovalTable = () => {
async function fetchPendingData() { async function fetchPendingData() {
try { try {
const res = await listPendingApproval(page, Number(showData)); const res = await listPendingApproval(page, Number(showData), typeId);
if (res && !res.error && res.data) { if (res && !res.error && res.data) {
// Filter data based on search if provided // Filter data based on search if provided

View File

@ -177,23 +177,24 @@ const TableTeks = () => {
const formattedEndDate = endDate const formattedEndDate = endDate
? format(new Date(endDate), "yyyy-MM-dd") ? format(new Date(endDate), "yyyy-MM-dd")
: ""; : "";
try { try {
// Using the new interface-based approach for cleaner code // Using the new interface-based approach for video content
const filters: ArticleFilters = { const filters: ArticleFilters = {
page: page, page: page,
totalPage: Number(showData), totalPage: Number(showData),
title: search || undefined, title: search || undefined,
categoryId: categoryFilter ? Number(categoryFilter) : undefined, categoryId: categoryFilter ? Number(categoryFilter) : undefined,
typeId: 3, // text content type typeId: 2, // video content type
statusId: statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined, statusId:
statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined,
startDate: formattedStartDate || undefined, startDate: formattedStartDate || undefined,
endDate: formattedEndDate || undefined, endDate: formattedEndDate || undefined,
}; };
const res = await listArticlesWithFilters(filters); const res = await listArticlesWithFilters(filters);
const data = res?.data?.data; const data = res?.data?.data;
// Handle new articles API response structure
if (Array.isArray(data)) { if (Array.isArray(data)) {
data.forEach((item: any, index: number) => { data.forEach((item: any, index: number) => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
@ -201,21 +202,75 @@ const TableTeks = () => {
setDataTable(data); setDataTable(data);
setTotalData(data.length); setTotalData(data.length);
setTotalPage(Math.ceil(data.length / Number(showData))); setTotalPage(Math.ceil(data.length / Number(showData)));
} else { } else if (Array.isArray(data?.content)) {
// Fallback to old structure if API still returns old format const contentData = data.content;
const contentData = data?.content;
contentData.forEach((item: any, index: number) => { contentData.forEach((item: any, index: number) => {
item.no = (page - 1) * Number(showData) + index + 1; item.no = (page - 1) * Number(showData) + index + 1;
}); });
setDataTable(contentData); setDataTable(contentData);
setTotalData(data?.totalElements); setTotalData(data?.totalElements ?? contentData.length);
setTotalPage(data?.totalPages); setTotalPage(
data?.totalPages ?? Math.ceil(contentData.length / Number(showData))
);
} else {
setDataTable([]);
setTotalData(0);
setTotalPage(1);
} }
} catch (error) { } catch (error) {
console.error("Error fetching tasks:", error); console.error("Error fetching tasks:", error);
setDataTable([]);
setTotalData(0);
setTotalPage(1);
} }
} }
// async function fetchData() {
// const formattedStartDate = startDate
// ? format(new Date(startDate), "yyyy-MM-dd")
// : "";
// const formattedEndDate = endDate
// ? format(new Date(endDate), "yyyy-MM-dd")
// : "";
// try {
// // Using the new interface-based approach for cleaner code
// const filters: ArticleFilters = {
// page: page,
// totalPage: Number(showData),
// title: search || undefined,
// categoryId: categoryFilter ? Number(categoryFilter) : undefined,
// typeId: 3, // text content type
// statusId: statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined,
// startDate: formattedStartDate || undefined,
// endDate: formattedEndDate || undefined,
// };
// const res = await listArticlesWithFilters(filters);
// const data = res?.data?.data;
// // Handle new articles API response structure
// if (Array.isArray(data)) {
// data.forEach((item: any, index: number) => {
// item.no = (page - 1) * Number(showData) + index + 1;
// });
// setDataTable(data);
// setTotalData(data.length);
// setTotalPage(Math.ceil(data.length / Number(showData)));
// } else {
// // Fallback to old structure if API still returns old format
// const contentData = data?.content;
// contentData.forEach((item: any, index: number) => {
// item.no = (page - 1) * Number(showData) + index + 1;
// });
// setDataTable(contentData);
// setTotalData(data?.totalElements);
// setTotalPage(data?.totalPages);
// }
// } catch (error) {
// console.error("Error fetching tasks:", error);
// }
// }
const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => { const handleSearch = (e: React.ChangeEvent<HTMLInputElement>) => {
setSearch(e.target.value); // Perbarui state search setSearch(e.target.value); // Perbarui state search
table.getColumn("judul")?.setFilterValue(e.target.value); // Set filter tabel table.getColumn("judul")?.setFilterValue(e.target.value); // Set filter tabel

View File

@ -42,7 +42,7 @@ const ImageTabs = () => {
<TabsContent value="pending" className="mt-0"> <TabsContent value="pending" className="mt-0">
<div className="bg-white rounded-lg border border-gray-200 shadow-sm"> <div className="bg-white rounded-lg border border-gray-200 shadow-sm">
<PendingApprovalTable /> <PendingApprovalTable typeId={1} />
</div> </div>
</TabsContent> </TabsContent>
</Tabs> </Tabs>

View File

@ -43,7 +43,11 @@ import { listPendingApproval, PendingApprovalData } from "@/service/content/cont
import usePendingApprovalColumns from "./pending-approval-columns"; import usePendingApprovalColumns from "./pending-approval-columns";
import { fi } from "date-fns/locale"; import { fi } from "date-fns/locale";
const PendingApprovalTable = () => { type PendingApprovalTableProps = {
typeId?: number;
};
const PendingApprovalTable = ({ typeId }: PendingApprovalTableProps) => {
const searchParams = useSearchParams(); const searchParams = useSearchParams();
const [dataTable, setDataTable] = React.useState<PendingApprovalData[]>([]); const [dataTable, setDataTable] = React.useState<PendingApprovalData[]>([]);
const [totalData, setTotalData] = React.useState<number>(0); const [totalData, setTotalData] = React.useState<number>(0);
@ -112,7 +116,7 @@ const PendingApprovalTable = () => {
async function fetchPendingData() { async function fetchPendingData() {
try { try {
console.log("fetchPendingData: page =", page, "showData =", showData, "Number(showData) =", Number(showData)); console.log("fetchPendingData: page =", page, "showData =", showData, "Number(showData) =", Number(showData));
const res = await listPendingApproval(page, Number(showData)); const res = await listPendingApproval(page, Number(showData), typeId);
if (res && !res.error && res.data.data) { if (res && !res.error && res.data.data) {
// Filter data based on search if provided // Filter data based on search if provided

View File

@ -123,6 +123,7 @@ export default function FormVideo() {
const [publishedForError, setPublishedForError] = useState<string | null>( const [publishedForError, setPublishedForError] = useState<string | null>(
null null
); );
const userId = Cookies.get("userId");
const [selectedSize, setSelectedSize] = useState(""); const [selectedSize, setSelectedSize] = useState("");
const [detailData, setDetailData] = useState<any>(null); const [detailData, setDetailData] = useState<any>(null);
const [articleImages, setArticleImages] = useState<string[]>([]); const [articleImages, setArticleImages] = useState<string[]>([]);
@ -478,24 +479,26 @@ export default function FormVideo() {
// Use new Article Categories API // Use new Article Categories API
const category = await listArticleCategories(1, 100); const category = await listArticleCategories(1, 100);
console.log("Article categories response:", category); console.log("Article categories response:", category);
if (category?.error) { if (category?.error) {
console.error("Failed to fetch article categories:", category.message); console.error("Failed to fetch article categories:", category.message);
// Fallback to old API if new one fails // Fallback to old API if new one fails
const fallbackCategory = await listEnableCategory(fileTypeId); const fallbackCategory = await listEnableCategory(fileTypeId);
const resCategory: Category[] = fallbackCategory?.data.data.content || []; const resCategory: Category[] =
fallbackCategory?.data.data.content || [];
setCategories(resCategory); setCategories(resCategory);
return; return;
} }
// Handle new API response structure // Handle new API response structure
const resCategory: Category[] = category?.data?.data?.map((item: any) => ({ const resCategory: Category[] =
id: item.id, category?.data?.data?.map((item: any) => ({
name: item.title, // map title to name for backward compatibility id: item.id,
title: item.title, name: item.title, // map title to name for backward compatibility
description: item.description, title: item.title,
...item description: item.description,
})) || []; ...item,
})) || [];
setCategories(resCategory); setCategories(resCategory);
console.log("Article categories loaded:", resCategory); console.log("Article categories loaded:", resCategory);
@ -516,7 +519,8 @@ export default function FormVideo() {
// Fallback to old API if error occurs // Fallback to old API if error occurs
try { try {
const fallbackCategory = await listEnableCategory(fileTypeId); const fallbackCategory = await listEnableCategory(fileTypeId);
const resCategory: Category[] = fallbackCategory?.data.data.content || []; const resCategory: Category[] =
fallbackCategory?.data.data.content || [];
setCategories(resCategory); setCategories(resCategory);
} catch (fallbackError) { } catch (fallbackError) {
console.error("Fallback category fetch also failed:", fallbackError); console.error("Fallback category fetch also failed:", fallbackError);
@ -577,6 +581,23 @@ export default function FormVideo() {
return; return;
} }
function formatDateForBackend(date: Date) {
const pad = (n: number) => (n < 10 ? "0" + n : n);
return (
date.getFullYear() +
"-" +
pad(date.getMonth() + 1) +
"-" +
pad(date.getDate()) +
" " +
pad(date.getHours()) +
":" +
pad(date.getMinutes()) +
":" +
pad(date.getSeconds())
);
}
let requestData: { let requestData: {
title: string; title: string;
description: string; description: string;
@ -618,16 +639,22 @@ export default function FormVideo() {
if (id == undefined) { if (id == undefined) {
// New Articles API request data structure // New Articles API request data structure
const articleData: CreateArticleData = { const articleData: CreateArticleData = {
title: finalTitle, aiArticleId: 0, // default 0
categoryIds: selectedCategory.toString(),
createdAt: formatDateForBackend(new Date()), // ✅ format sesuai backend
createdById: Number(userId), // isi dengan userId valid
description: htmlToString(finalDescription), description: htmlToString(finalDescription),
htmlDescription: finalDescription, htmlDescription: finalDescription,
categoryIds: selectedCategory.toString(),
typeId: 4, // Video content type
tags: finalTags,
isDraft: true, isDraft: true,
isPublish: false, isPublish: false,
oldId: 0, oldId: 0,
slug: finalTitle.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''), slug: finalTitle
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, ""),
tags: finalTags,
title: finalTitle,
typeId: 1, // Image content type
}; };
// Use new Articles API // Use new Articles API
@ -636,7 +663,11 @@ export default function FormVideo() {
console.log("Article API Response:", response); console.log("Article API Response:", response);
if (response?.error) { if (response?.error) {
MySwal.fire("Error", response.message || "Failed to create article", "error"); MySwal.fire(
"Error",
response.message || "Failed to create article",
"error"
);
return false; return false;
} }
@ -647,53 +678,69 @@ export default function FormVideo() {
// Upload files using new article-files API // Upload files using new article-files API
const formData = new FormData(); const formData = new FormData();
// Add all files to FormData // Add all files to FormData
files.forEach((file, index) => { files.forEach((file, index) => {
formData.append('files', file); formData.append("files", file);
}); });
console.log("Uploading files to article:", articleId); console.log("Uploading files to article:", articleId);
console.log("Files to upload:", files.length); console.log("Files to upload:", files.length);
try { try {
const uploadResponse = await uploadArticleFiles(articleId, formData); const uploadResponse = await uploadArticleFiles(articleId, formData);
if (uploadResponse?.error) { if (uploadResponse?.error) {
MySwal.fire("Error", uploadResponse.message || "Failed to upload files", "error"); MySwal.fire(
"Error",
uploadResponse.message || "Failed to upload files",
"error"
);
return false; return false;
} }
console.log("Files uploaded successfully:", uploadResponse); console.log("Files uploaded successfully:", uploadResponse);
// Upload thumbnail using first file as thumbnail // Upload thumbnail using first file as thumbnail
if (files.length > 0) { if (files.length > 0) {
const thumbnailFormData = new FormData(); const thumbnailFormData = new FormData();
thumbnailFormData.append('files', files[0]); // Use first file as thumbnail thumbnailFormData.append("files", files[0]); // Use first file as thumbnail
console.log("Uploading thumbnail for article:", articleId); console.log("Uploading thumbnail for article:", articleId);
try { try {
const thumbnailResponse = await uploadArticleThumbnail(articleId, thumbnailFormData); const thumbnailResponse = await uploadArticleThumbnail(
articleId,
thumbnailFormData
);
if (thumbnailResponse?.error) { if (thumbnailResponse?.error) {
console.warn("Thumbnail upload failed:", thumbnailResponse.message); console.warn(
"Thumbnail upload failed:",
thumbnailResponse.message
);
// Don't fail the whole process if thumbnail upload fails // Don't fail the whole process if thumbnail upload fails
} else { } else {
console.log("Thumbnail uploaded successfully:", thumbnailResponse); console.log(
"Thumbnail uploaded successfully:",
thumbnailResponse
);
} }
} catch (thumbnailError) { } catch (thumbnailError) {
console.warn("Thumbnail upload error:", thumbnailError); console.warn("Thumbnail upload error:", thumbnailError);
// Don't fail the whole process if thumbnail upload fails // Don't fail the whole process if thumbnail upload fails
} }
} }
} catch (uploadError) { } catch (uploadError) {
console.error("Upload error:", uploadError); console.error("Upload error:", uploadError);
MySwal.fire("Error", "Failed to upload files. Please try again.", "error"); MySwal.fire(
"Error",
"Failed to upload files. Please try again.",
"error"
);
return false; return false;
} }
// Show success message // Show success message
MySwal.fire({ MySwal.fire({
title: "Sukses", title: "Sukses",
@ -702,13 +749,13 @@ export default function FormVideo() {
confirmButtonColor: "#3085d6", confirmButtonColor: "#3085d6",
confirmButtonText: "OK", confirmButtonText: "OK",
}).then(() => { }).then(() => {
router.push("/admin/content/video"); router.push("/admin/content/audio-visual");
}); });
Cookies.remove("idCreate"); Cookies.remove("idCreate");
return; return;
} }
Cookies.remove("idCreate"); Cookies.remove("idCreate");
}; };
@ -985,7 +1032,6 @@ export default function FormVideo() {
name="categoryId" name="categoryId"
render={({ field }) => ( render={({ field }) => (
<div className="w-full"> <div className="w-full">
<Label>Category</Label>
<Select <Select
value={field.value} value={field.value}
onValueChange={(value) => { onValueChange={(value) => {

View File

@ -147,6 +147,7 @@ export default function FormAudio() {
const [publishedFor, setPublishedFor] = useState<string[]>([]); const [publishedFor, setPublishedFor] = useState<string[]>([]);
const [fileError, setFileError] = useState<string | null>(null); const [fileError, setFileError] = useState<string | null>(null);
type FileWithPreview = File & { preview: string }; type FileWithPreview = File & { preview: string };
const userId = Cookies.get("userId");
const options: Option[] = [ const options: Option[] = [
{ id: "all", label: "SEMUA" }, { id: "all", label: "SEMUA" },
@ -220,8 +221,7 @@ export default function FormAudio() {
file.size <= 100 * 1024 * 1024 file.size <= 100 * 1024 * 1024
), ),
{ {
message: message: "Hanya file .mp3, .wav, maksimal 100MB yang diperbolehkan.",
"Hanya file .mp3, .wav, maksimal 100MB yang diperbolehkan.",
} }
), ),
categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }), categoryId: z.string().min(1, { message: "Kategori wajib dipilih." }),
@ -480,24 +480,26 @@ export default function FormAudio() {
// Use new Article Categories API // Use new Article Categories API
const category = await listArticleCategories(1, 100); const category = await listArticleCategories(1, 100);
console.log("Article categories response:", category); console.log("Article categories response:", category);
if (category?.error) { if (category?.error) {
console.error("Failed to fetch article categories:", category.message); console.error("Failed to fetch article categories:", category.message);
// Fallback to old API if new one fails // Fallback to old API if new one fails
const fallbackCategory = await listEnableCategory(fileTypeId); const fallbackCategory = await listEnableCategory(fileTypeId);
const resCategory: Category[] = fallbackCategory?.data.data.content || []; const resCategory: Category[] =
fallbackCategory?.data.data.content || [];
setCategories(resCategory); setCategories(resCategory);
return; return;
} }
// Handle new API response structure // Handle new API response structure
const resCategory: Category[] = category?.data?.data?.map((item: any) => ({ const resCategory: Category[] =
id: item.id, category?.data?.data?.map((item: any) => ({
name: item.title, // map title to name for backward compatibility id: item.id,
title: item.title, name: item.title, // map title to name for backward compatibility
description: item.description, title: item.title,
...item description: item.description,
})) || []; ...item,
})) || [];
setCategories(resCategory); setCategories(resCategory);
console.log("Article categories loaded:", resCategory); console.log("Article categories loaded:", resCategory);
@ -518,7 +520,8 @@ export default function FormAudio() {
// Fallback to old API if error occurs // Fallback to old API if error occurs
try { try {
const fallbackCategory = await listEnableCategory(fileTypeId); const fallbackCategory = await listEnableCategory(fileTypeId);
const resCategory: Category[] = fallbackCategory?.data.data.content || []; const resCategory: Category[] =
fallbackCategory?.data.data.content || [];
setCategories(resCategory); setCategories(resCategory);
} catch (fallbackError) { } catch (fallbackError) {
console.error("Fallback category fetch also failed:", fallbackError); console.error("Fallback category fetch also failed:", fallbackError);
@ -575,6 +578,23 @@ export default function FormAudio() {
return; return;
} }
function formatDateForBackend(date: Date) {
const pad = (n: number) => (n < 10 ? "0" + n : n);
return (
date.getFullYear() +
"-" +
pad(date.getMonth() + 1) +
"-" +
pad(date.getDate()) +
" " +
pad(date.getHours()) +
":" +
pad(date.getMinutes()) +
":" +
pad(date.getSeconds())
);
}
let requestData: { let requestData: {
title: string; title: string;
description: string; description: string;
@ -616,16 +636,22 @@ export default function FormAudio() {
if (id == undefined) { if (id == undefined) {
// New Articles API request data structure // New Articles API request data structure
const articleData: CreateArticleData = { const articleData: CreateArticleData = {
title: finalTitle, aiArticleId: 0, // default 0
categoryIds: selectedCategory.toString(),
createdAt: formatDateForBackend(new Date()), // ✅ format sesuai backend
createdById: Number(userId), // isi dengan userId valid
description: htmlToString(finalDescription), description: htmlToString(finalDescription),
htmlDescription: finalDescription, htmlDescription: finalDescription,
categoryIds: selectedCategory.toString(),
typeId: 3, // Audio content type
tags: finalTags,
isDraft: true, isDraft: true,
isPublish: false, isPublish: false,
oldId: 0, oldId: 0,
slug: finalTitle.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''), slug: finalTitle
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, ""),
tags: finalTags,
title: finalTitle,
typeId: 1, // Image content type
}; };
// Use new Articles API // Use new Articles API
@ -634,7 +660,11 @@ export default function FormAudio() {
console.log("Article API Response:", response); console.log("Article API Response:", response);
if (response?.error) { if (response?.error) {
MySwal.fire("Error", response.message || "Failed to create article", "error"); MySwal.fire(
"Error",
response.message || "Failed to create article",
"error"
);
return false; return false;
} }
@ -645,53 +675,69 @@ export default function FormAudio() {
// Upload files using new article-files API // Upload files using new article-files API
const formData = new FormData(); const formData = new FormData();
// Add all files to FormData // Add all files to FormData
files.forEach((file, index) => { files.forEach((file, index) => {
formData.append('files', file); formData.append("files", file);
}); });
console.log("Uploading files to article:", articleId); console.log("Uploading files to article:", articleId);
console.log("Files to upload:", files.length); console.log("Files to upload:", files.length);
try { try {
const uploadResponse = await uploadArticleFiles(articleId, formData); const uploadResponse = await uploadArticleFiles(articleId, formData);
if (uploadResponse?.error) { if (uploadResponse?.error) {
MySwal.fire("Error", uploadResponse.message || "Failed to upload files", "error"); MySwal.fire(
"Error",
uploadResponse.message || "Failed to upload files",
"error"
);
return false; return false;
} }
console.log("Files uploaded successfully:", uploadResponse); console.log("Files uploaded successfully:", uploadResponse);
// Upload thumbnail using first file as thumbnail // Upload thumbnail using first file as thumbnail
if (files.length > 0) { if (files.length > 0) {
const thumbnailFormData = new FormData(); const thumbnailFormData = new FormData();
thumbnailFormData.append('files', files[0]); // Use first file as thumbnail thumbnailFormData.append("files", files[0]); // Use first file as thumbnail
console.log("Uploading thumbnail for article:", articleId); console.log("Uploading thumbnail for article:", articleId);
try { try {
const thumbnailResponse = await uploadArticleThumbnail(articleId, thumbnailFormData); const thumbnailResponse = await uploadArticleThumbnail(
articleId,
thumbnailFormData
);
if (thumbnailResponse?.error) { if (thumbnailResponse?.error) {
console.warn("Thumbnail upload failed:", thumbnailResponse.message); console.warn(
"Thumbnail upload failed:",
thumbnailResponse.message
);
// Don't fail the whole process if thumbnail upload fails // Don't fail the whole process if thumbnail upload fails
} else { } else {
console.log("Thumbnail uploaded successfully:", thumbnailResponse); console.log(
"Thumbnail uploaded successfully:",
thumbnailResponse
);
} }
} catch (thumbnailError) { } catch (thumbnailError) {
console.warn("Thumbnail upload error:", thumbnailError); console.warn("Thumbnail upload error:", thumbnailError);
// Don't fail the whole process if thumbnail upload fails // Don't fail the whole process if thumbnail upload fails
} }
} }
} catch (uploadError) { } catch (uploadError) {
console.error("Upload error:", uploadError); console.error("Upload error:", uploadError);
MySwal.fire("Error", "Failed to upload files. Please try again.", "error"); MySwal.fire(
"Error",
"Failed to upload files. Please try again.",
"error"
);
return false; return false;
} }
// Show success message // Show success message
MySwal.fire({ MySwal.fire({
title: "Sukses", title: "Sukses",
@ -702,11 +748,11 @@ export default function FormAudio() {
}).then(() => { }).then(() => {
router.push("/admin/content/audio"); router.push("/admin/content/audio");
}); });
Cookies.remove("idCreate"); Cookies.remove("idCreate");
return; return;
} }
Cookies.remove("idCreate"); Cookies.remove("idCreate");
}; };
@ -975,7 +1021,6 @@ export default function FormAudio() {
name="categoryId" name="categoryId"
render={({ field }) => ( render={({ field }) => (
<div className="w-full"> <div className="w-full">
<Label>Category</Label>
<Select <Select
value={field.value} value={field.value}
onValueChange={(value) => { onValueChange={(value) => {

View File

@ -131,7 +131,7 @@ export default function FormTeks() {
polda: false, polda: false,
polres: false, polres: false,
}); });
const userId = Cookies.get("userId");
let fileTypeId = "2"; let fileTypeId = "2";
let progressInfo: any = []; let progressInfo: any = [];
let counterUpdateProgress = 0; let counterUpdateProgress = 0;
@ -476,24 +476,26 @@ export default function FormTeks() {
// Use new Article Categories API // Use new Article Categories API
const category = await listArticleCategories(1, 100); const category = await listArticleCategories(1, 100);
console.log("Article categories response:", category); console.log("Article categories response:", category);
if (category?.error) { if (category?.error) {
console.error("Failed to fetch article categories:", category.message); console.error("Failed to fetch article categories:", category.message);
// Fallback to old API if new one fails // Fallback to old API if new one fails
const fallbackCategory = await listEnableCategory(fileTypeId); const fallbackCategory = await listEnableCategory(fileTypeId);
const resCategory: Category[] = fallbackCategory?.data.data.content || []; const resCategory: Category[] =
fallbackCategory?.data.data.content || [];
setCategories(resCategory); setCategories(resCategory);
return; return;
} }
// Handle new API response structure // Handle new API response structure
const resCategory: Category[] = category?.data?.data?.map((item: any) => ({ const resCategory: Category[] =
id: item.id, category?.data?.data?.map((item: any) => ({
name: item.title, // map title to name for backward compatibility id: item.id,
title: item.title, name: item.title, // map title to name for backward compatibility
description: item.description, title: item.title,
...item description: item.description,
})) || []; ...item,
})) || [];
setCategories(resCategory); setCategories(resCategory);
console.log("Article categories loaded:", resCategory); console.log("Article categories loaded:", resCategory);
@ -514,7 +516,8 @@ export default function FormTeks() {
// Fallback to old API if error occurs // Fallback to old API if error occurs
try { try {
const fallbackCategory = await listEnableCategory(fileTypeId); const fallbackCategory = await listEnableCategory(fileTypeId);
const resCategory: Category[] = fallbackCategory?.data.data.content || []; const resCategory: Category[] =
fallbackCategory?.data.data.content || [];
setCategories(resCategory); setCategories(resCategory);
} catch (fallbackError) { } catch (fallbackError) {
console.error("Fallback category fetch also failed:", fallbackError); console.error("Fallback category fetch also failed:", fallbackError);
@ -579,6 +582,23 @@ export default function FormTeks() {
return; return;
} }
function formatDateForBackend(date: Date) {
const pad = (n: number) => (n < 10 ? "0" + n : n);
return (
date.getFullYear() +
"-" +
pad(date.getMonth() + 1) +
"-" +
pad(date.getDate()) +
" " +
pad(date.getHours()) +
":" +
pad(date.getMinutes()) +
":" +
pad(date.getSeconds())
);
}
let requestData: { let requestData: {
title: string; title: string;
description: string; description: string;
@ -620,25 +640,34 @@ export default function FormTeks() {
if (id == undefined) { if (id == undefined) {
// New Articles API request data structure // New Articles API request data structure
const articleData: CreateArticleData = { const articleData: CreateArticleData = {
title: finalTitle, aiArticleId: 0, // default 0
categoryIds: selectedCategory.toString(),
createdAt: formatDateForBackend(new Date()), // ✅ format sesuai backend
createdById: Number(userId), // isi dengan userId valid
description: htmlToString(finalDescription), description: htmlToString(finalDescription),
htmlDescription: finalDescription, htmlDescription: finalDescription,
categoryIds: selectedCategory.toString(),
typeId: 2, // Document content type
tags: finalTags,
isDraft: true, isDraft: true,
isPublish: false, isPublish: false,
oldId: 0, oldId: 0,
slug: finalTitle.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''), slug: finalTitle
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, ""),
tags: finalTags,
title: finalTitle,
typeId: 1, // Image content type
}; };
// Use new Articles API // Use new Articles API
const response = await createArticle(articleData); const response = await createArticle(articleData);
console.log("Article Data Submitted:", articleData); console.log("Article Data Submitted:", articleData);
console.log("Article API Response:", response); console.log("Article API Response:", response);
if (response?.error) { if (response?.error) {
MySwal.fire("Error", response.message || "Failed to create article", "error"); MySwal.fire(
"Error",
response.message || "Failed to create article",
"error"
);
return false; return false;
} }
@ -649,53 +678,69 @@ export default function FormTeks() {
// Upload files using new article-files API // Upload files using new article-files API
const formData = new FormData(); const formData = new FormData();
// Add all files to FormData // Add all files to FormData
files.forEach((file, index) => { files.forEach((file, index) => {
formData.append('files', file); formData.append("files", file);
}); });
console.log("Uploading files to article:", articleId); console.log("Uploading files to article:", articleId);
console.log("Files to upload:", files.length); console.log("Files to upload:", files.length);
try { try {
const uploadResponse = await uploadArticleFiles(articleId, formData); const uploadResponse = await uploadArticleFiles(articleId, formData);
if (uploadResponse?.error) { if (uploadResponse?.error) {
MySwal.fire("Error", uploadResponse.message || "Failed to upload files", "error"); MySwal.fire(
"Error",
uploadResponse.message || "Failed to upload files",
"error"
);
return false; return false;
} }
console.log("Files uploaded successfully:", uploadResponse); console.log("Files uploaded successfully:", uploadResponse);
// Upload thumbnail using first file as thumbnail // Upload thumbnail using first file as thumbnail
if (files.length > 0) { if (files.length > 0) {
const thumbnailFormData = new FormData(); const thumbnailFormData = new FormData();
thumbnailFormData.append('files', files[0]); // Use first file as thumbnail thumbnailFormData.append("files", files[0]); // Use first file as thumbnail
console.log("Uploading thumbnail for article:", articleId); console.log("Uploading thumbnail for article:", articleId);
try { try {
const thumbnailResponse = await uploadArticleThumbnail(articleId, thumbnailFormData); const thumbnailResponse = await uploadArticleThumbnail(
articleId,
thumbnailFormData
);
if (thumbnailResponse?.error) { if (thumbnailResponse?.error) {
console.warn("Thumbnail upload failed:", thumbnailResponse.message); console.warn(
"Thumbnail upload failed:",
thumbnailResponse.message
);
// Don't fail the whole process if thumbnail upload fails // Don't fail the whole process if thumbnail upload fails
} else { } else {
console.log("Thumbnail uploaded successfully:", thumbnailResponse); console.log(
"Thumbnail uploaded successfully:",
thumbnailResponse
);
} }
} catch (thumbnailError) { } catch (thumbnailError) {
console.warn("Thumbnail upload error:", thumbnailError); console.warn("Thumbnail upload error:", thumbnailError);
// Don't fail the whole process if thumbnail upload fails // Don't fail the whole process if thumbnail upload fails
} }
} }
} catch (uploadError) { } catch (uploadError) {
console.error("Upload error:", uploadError); console.error("Upload error:", uploadError);
MySwal.fire("Error", "Failed to upload files. Please try again.", "error"); MySwal.fire(
"Error",
"Failed to upload files. Please try again.",
"error"
);
return false; return false;
} }
// Show success message // Show success message
MySwal.fire({ MySwal.fire({
title: "Sukses", title: "Sukses",
@ -706,11 +751,11 @@ export default function FormTeks() {
}).then(() => { }).then(() => {
router.push("/admin/content/document"); router.push("/admin/content/document");
}); });
Cookies.remove("idCreate"); Cookies.remove("idCreate");
return; return;
} }
Cookies.remove("idCreate"); Cookies.remove("idCreate");
}; };
@ -963,42 +1008,41 @@ export default function FormTeks() {
<div className="flex items-center"> <div className="flex items-center">
<div className="py-3 w-full space-y-2"> <div className="py-3 w-full space-y-2">
<Label>Category</Label> <Label>Category</Label>
<Controller <Controller
control={control} control={control}
name="categoryId" name="categoryId"
render={({ field }) => ( render={({ field }) => (
<div className="w-full"> <div className="w-full">
<Label>Category</Label> <Select
<Select value={field.value}
value={field.value} onValueChange={(value) => {
onValueChange={(value) => { field.onChange(value);
field.onChange(value); setSelectedCategory(value);
setSelectedCategory(value); }}
}} >
> <SelectTrigger>
<SelectTrigger> <SelectValue placeholder="Pilih" />
<SelectValue placeholder="Pilih" /> </SelectTrigger>
</SelectTrigger> <SelectContent>
<SelectContent> {categories.map((category) => (
{categories.map((category) => ( <SelectItem
<SelectItem key={category.id}
key={category.id} value={category.id.toString()}
value={category.id.toString()} >
> {category.name}
{category.name} </SelectItem>
</SelectItem> ))}
))} </SelectContent>
</SelectContent> </Select>
</Select>
{errors.categoryId && ( {errors.categoryId && (
<p className="text-sm text-red-500 mt-1"> <p className="text-sm text-red-500 mt-1">
{errors.categoryId.message} {errors.categoryId.message}
</p> </p>
)}
</div>
)} )}
</div> />
)}
/>
</div> </div>
</div> </div>
<div className="flex flex-row items-center gap-3 py-2"> <div className="flex flex-row items-center gap-3 py-2">

1
package-lock.json generated
View File

@ -2338,6 +2338,7 @@
"version": "1.1.13", "version": "1.1.13",
"resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz", "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.13.tgz",
"integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==", "integrity": "sha512-7xdcatg7/U+7+Udyoj2zodtI9H/IIopqo+YOIcZOq1nJwXWBZ9p8xiu5llXlekDbZkca79a/fozEYQXIA4sW6A==",
"license": "MIT",
"dependencies": { "dependencies": {
"@radix-ui/primitive": "1.1.3", "@radix-ui/primitive": "1.1.3",
"@radix-ui/react-context": "1.1.2", "@radix-ui/react-context": "1.1.2",

View File

@ -456,9 +456,10 @@ export interface PendingApprovalResponse {
// Function to fetch pending approval data // Function to fetch pending approval data
export async function listPendingApproval( export async function listPendingApproval(
page: number = 1, page: number = 1,
limit: number = 10 limit: number = 10,
typeId?: number
) { ) {
const url = `articles/pending-approval?page=${page}&limit=${limit}`; const url = `articles/pending-approval?page=${page}&limit=${limit}&typeId=${typeId}`;
return await httpGetInterceptor(url); return await httpGetInterceptor(url);
} }