feat: update pagination and create image, update login
This commit is contained in:
parent
4b25136c6f
commit
d07e92aa2a
|
|
@ -51,11 +51,17 @@ const useTableColumns = () => {
|
|||
{
|
||||
accessorKey: "categoryName",
|
||||
header: "Category Name",
|
||||
cell: ({ row }) => (
|
||||
cell: ({ row }) => {
|
||||
const categoryName = row.getValue("categoryName");
|
||||
const categories = row.original.categories;
|
||||
// Handle new API structure with categories array
|
||||
const displayName = categoryName || (categories && categories.length > 0 ? categories[0].title : "-");
|
||||
return (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("categoryName")}
|
||||
{displayName}
|
||||
</span>
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "createdAt",
|
||||
|
|
@ -77,7 +83,9 @@ const useTableColumns = () => {
|
|||
accessorKey: "creatorName",
|
||||
header: "Creator Group",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("creatorName")}</span>
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorName") || row.getValue("createdByName")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
@ -85,7 +93,7 @@ const useTableColumns = () => {
|
|||
header: "Source",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorGroupLevelName")}
|
||||
{row.getValue("creatorGroupLevelName") || "-"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -39,7 +39,13 @@ import columns from "./columns";
|
|||
import { Label } from "@/components/ui/label";
|
||||
import { format } from "date-fns";
|
||||
import useTableColumns from "./columns";
|
||||
import { listEnableCategory, listDataVideo } from "@/service/content";
|
||||
import {
|
||||
listEnableCategory,
|
||||
listDataVideo,
|
||||
listArticles,
|
||||
listArticlesWithFilters,
|
||||
ArticleFilters
|
||||
} from "@/service/content";
|
||||
import {
|
||||
SortingState,
|
||||
ColumnFiltersState,
|
||||
|
|
@ -169,32 +175,39 @@ const TableVideo = () => {
|
|||
? format(new Date(endDate), "yyyy-MM-dd")
|
||||
: "";
|
||||
try {
|
||||
const isForSelf = Number(roleId) === 4;
|
||||
const res = await listDataVideo(
|
||||
showData,
|
||||
page - 1,
|
||||
isForSelf,
|
||||
!isForSelf,
|
||||
categoryFilter,
|
||||
statusFilter,
|
||||
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
|
||||
filterByCreator,
|
||||
filterBySource,
|
||||
formattedStartDate, // Pastikan format sesuai
|
||||
formattedEndDate, // Pastikan format sesuai
|
||||
search,
|
||||
filterByCreatorGroup
|
||||
);
|
||||
// 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);
|
||||
setTotalPage(data?.totalPages);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching tasks:", error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,11 +51,17 @@ const useTableColumns = () => {
|
|||
{
|
||||
accessorKey: "categoryName",
|
||||
header: "Category Name",
|
||||
cell: ({ row }) => (
|
||||
cell: ({ row }) => {
|
||||
const categoryName = row.getValue("categoryName");
|
||||
const categories = row.original.categories;
|
||||
// Handle new API structure with categories array
|
||||
const displayName = categoryName || (categories && categories.length > 0 ? categories[0].title : "-");
|
||||
return (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("categoryName")}
|
||||
{displayName}
|
||||
</span>
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "createdAt",
|
||||
|
|
@ -77,7 +83,9 @@ const useTableColumns = () => {
|
|||
accessorKey: "creatorName",
|
||||
header: "Creator Group",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("creatorName")}</span>
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorName") || row.getValue("createdByName")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
@ -85,7 +93,7 @@ const useTableColumns = () => {
|
|||
header: "Source",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorGroupLevelName")}
|
||||
{row.getValue("creatorGroupLevelName") || "-"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -55,7 +55,10 @@ import {
|
|||
listDataAudio,
|
||||
listDataImage,
|
||||
listDataVideo,
|
||||
listArticles,
|
||||
listArticlesWithFilters,
|
||||
listEnableCategory,
|
||||
ArticleFilters,
|
||||
} from "@/service/content/content";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { format } from "date-fns";
|
||||
|
|
@ -176,32 +179,39 @@ const TableAudio = () => {
|
|||
? format(new Date(endDate), "yyyy-MM-dd")
|
||||
: "";
|
||||
try {
|
||||
const isForSelf = Number(roleId) === 4;
|
||||
const res = await listDataAudio(
|
||||
showData,
|
||||
page - 1,
|
||||
isForSelf,
|
||||
!isForSelf,
|
||||
categoryFilter,
|
||||
statusFilter,
|
||||
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
|
||||
filterByCreator,
|
||||
filterBySource,
|
||||
formattedStartDate, // Pastikan format sesuai
|
||||
formattedEndDate, // Pastikan format sesuai
|
||||
search,
|
||||
filterByCreatorGroup
|
||||
);
|
||||
// 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -51,11 +51,17 @@ const useTableColumns = () => {
|
|||
{
|
||||
accessorKey: "categoryName",
|
||||
header: "Category Name",
|
||||
cell: ({ row }) => (
|
||||
cell: ({ row }) => {
|
||||
const categoryName = row.getValue("categoryName");
|
||||
const categories = row.original.categories;
|
||||
// Handle new API structure with categories array
|
||||
const displayName = categoryName || (categories && categories.length > 0 ? categories[0].title : "-");
|
||||
return (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("categoryName")}
|
||||
{displayName}
|
||||
</span>
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "createdAt",
|
||||
|
|
@ -77,7 +83,9 @@ const useTableColumns = () => {
|
|||
accessorKey: "creatorName",
|
||||
header: "Creator Group",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("creatorName")}</span>
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorName") || row.getValue("createdByName")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
@ -85,7 +93,7 @@ const useTableColumns = () => {
|
|||
header: "Source",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorGroupLevelName")}
|
||||
{row.getValue("creatorGroupLevelName") || "-"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -54,7 +54,10 @@ import columns from "./columns";
|
|||
import {
|
||||
listDataImage,
|
||||
listDataTeks,
|
||||
listArticles,
|
||||
listArticlesWithFilters,
|
||||
listEnableCategory,
|
||||
ArticleFilters,
|
||||
} from "@/service/content/content";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { format } from "date-fns";
|
||||
|
|
@ -175,32 +178,39 @@ const TableTeks = () => {
|
|||
? format(new Date(endDate), "yyyy-MM-dd")
|
||||
: "";
|
||||
try {
|
||||
const isForSelf = Number(roleId) === 4;
|
||||
const res = await listDataTeks(
|
||||
showData,
|
||||
page - 1,
|
||||
isForSelf,
|
||||
!isForSelf,
|
||||
categoryFilter,
|
||||
statusFilter,
|
||||
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
|
||||
filterByCreator,
|
||||
filterBySource,
|
||||
formattedStartDate, // Pastikan format sesuai
|
||||
formattedEndDate, // Pastikan format sesuai
|
||||
search,
|
||||
filterByCreatorGroup
|
||||
);
|
||||
// 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,11 +53,17 @@ const useTableColumns = () => {
|
|||
{
|
||||
accessorKey: "categoryName",
|
||||
header: "Category Name",
|
||||
cell: ({ row }) => (
|
||||
cell: ({ row }) => {
|
||||
const categoryName = row.getValue("categoryName");
|
||||
const categories = row.original.categories;
|
||||
// Handle new API structure with categories array
|
||||
const displayName = categoryName || (categories && categories.length > 0 ? categories[0].title : "-");
|
||||
return (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("categoryName")}
|
||||
{displayName}
|
||||
</span>
|
||||
),
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
accessorKey: "createdAt",
|
||||
|
|
@ -79,7 +85,9 @@ const useTableColumns = () => {
|
|||
accessorKey: "creatorName",
|
||||
header: "Creator Group",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">{row.getValue("creatorName")}</span>
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorName") || row.getValue("createdByName")}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
{
|
||||
|
|
@ -87,7 +95,7 @@ const useTableColumns = () => {
|
|||
header: "Source",
|
||||
cell: ({ row }) => (
|
||||
<span className="whitespace-nowrap">
|
||||
{row.getValue("creatorGroupLevelName")}
|
||||
{row.getValue("creatorGroupLevelName") || "-"}
|
||||
</span>
|
||||
),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -54,7 +54,10 @@ import TablePagination from "@/components/table/table-pagination";
|
|||
import {
|
||||
deleteMedia,
|
||||
listDataImage,
|
||||
listArticles,
|
||||
listArticlesWithFilters,
|
||||
listEnableCategory,
|
||||
ArticleFilters,
|
||||
} from "@/service/content/content";
|
||||
import { loading } from "@/config/swal";
|
||||
|
||||
|
|
@ -183,33 +186,39 @@ const TableImage = () => {
|
|||
? format(new Date(endDate), "yyyy-MM-dd")
|
||||
: "";
|
||||
try {
|
||||
const isForSelf = Number(roleId) === 4;
|
||||
const res = await listDataImage(
|
||||
showData,
|
||||
page - 1,
|
||||
isForSelf,
|
||||
!isForSelf,
|
||||
categoryFilter,
|
||||
statusFilter,
|
||||
statusFilter?.sort().join(",").includes("1") ? userLevelId : "",
|
||||
filterByCreator,
|
||||
filterBySource,
|
||||
formattedStartDate,
|
||||
formattedEndDate,
|
||||
search,
|
||||
filterByCreatorGroup,
|
||||
locale == "en"
|
||||
);
|
||||
// Using the new interface-based approach for image content
|
||||
const filters: ArticleFilters = {
|
||||
page: page,
|
||||
totalPage: Number(showData),
|
||||
title: search || undefined,
|
||||
categoryId: categoryFilter ? Number(categoryFilter) : undefined,
|
||||
typeId: 1, // image 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ const AuthPage = () => {
|
|||
setLoginCredentials(data);
|
||||
try {
|
||||
const result = await validateEmail(data);
|
||||
console.log("result : ", result);
|
||||
switch (result) {
|
||||
case "skip":
|
||||
handleOTPSuccess();
|
||||
|
|
|
|||
|
|
@ -32,9 +32,14 @@ import { Switch } from "@/components/ui/switch";
|
|||
import Cookies from "js-cookie";
|
||||
import {
|
||||
createMedia,
|
||||
createArticle,
|
||||
getTagsBySubCategoryId,
|
||||
listEnableCategory,
|
||||
listArticleCategories,
|
||||
uploadThumbnail,
|
||||
uploadArticleFiles,
|
||||
uploadArticleThumbnail,
|
||||
CreateArticleData,
|
||||
} from "@/service/content/content";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import {
|
||||
|
|
@ -466,11 +471,30 @@ export default function FormImage() {
|
|||
|
||||
const getCategories = async () => {
|
||||
try {
|
||||
const category = await listEnableCategory(fileTypeId);
|
||||
const resCategory: Category[] = category?.data.data.content;
|
||||
// Use new Article Categories API
|
||||
const category = await listArticleCategories(1, 100);
|
||||
console.log("Article categories response:", category);
|
||||
|
||||
if (category?.error) {
|
||||
console.error("Failed to fetch article categories:", category.message);
|
||||
// Fallback to old API if new one fails
|
||||
const fallbackCategory = await listEnableCategory(fileTypeId);
|
||||
const resCategory: Category[] = fallbackCategory?.data.data.content || [];
|
||||
setCategories(resCategory);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle new API response structure
|
||||
const resCategory: Category[] = category?.data?.data?.map((item: any) => ({
|
||||
id: item.id,
|
||||
name: item.title, // map title to name for backward compatibility
|
||||
title: item.title,
|
||||
description: item.description,
|
||||
...item
|
||||
})) || [];
|
||||
|
||||
setCategories(resCategory);
|
||||
console.log("data category", resCategory);
|
||||
console.log("Article categories loaded:", resCategory);
|
||||
|
||||
if (scheduleId && scheduleType === "3") {
|
||||
const findCategory = resCategory.find((o) =>
|
||||
|
|
@ -478,7 +502,6 @@ export default function FormImage() {
|
|||
);
|
||||
|
||||
if (findCategory) {
|
||||
// setValue("categoryId", findCategory.id);
|
||||
setSelectedCategory(findCategory.id);
|
||||
const response = await getTagsBySubCategoryId(findCategory.id);
|
||||
setTags(response?.data?.data);
|
||||
|
|
@ -486,6 +509,14 @@ export default function FormImage() {
|
|||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch categories:", error);
|
||||
// Fallback to old API if error occurs
|
||||
try {
|
||||
const fallbackCategory = await listEnableCategory(fileTypeId);
|
||||
const resCategory: Category[] = fallbackCategory?.data.data.content || [];
|
||||
setCategories(resCategory);
|
||||
} catch (fallbackError) {
|
||||
console.error("Fallback category fetch also failed:", fallbackError);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -541,6 +572,21 @@ export default function FormImage() {
|
|||
return;
|
||||
}
|
||||
|
||||
// New Articles API request data structure
|
||||
const articleData: CreateArticleData = {
|
||||
title: finalTitle,
|
||||
description: htmlToString(finalDescription),
|
||||
htmlDescription: finalDescription,
|
||||
categoryIds: selectedCategory.toString(),
|
||||
typeId: 1, // Image content type
|
||||
tags: finalTags,
|
||||
isDraft: true,
|
||||
isPublish: false,
|
||||
oldId: 0,
|
||||
slug: finalTitle.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, ''),
|
||||
};
|
||||
|
||||
// Keep old structure for backward compatibility if needed
|
||||
let requestData: {
|
||||
title: string;
|
||||
description: string;
|
||||
|
|
@ -580,38 +626,103 @@ export default function FormImage() {
|
|||
}
|
||||
|
||||
if (id == undefined) {
|
||||
const response = await createMedia(requestData);
|
||||
console.log("Form Data Submitted:", requestData);
|
||||
// Use new Articles API
|
||||
const response = await createArticle(articleData);
|
||||
console.log("Article Data Submitted:", articleData);
|
||||
console.log("Article API Response:", response);
|
||||
|
||||
Cookies.set("idCreate", response?.data?.data, { expires: 1 });
|
||||
id = response?.data?.data;
|
||||
const formMedia = new FormData();
|
||||
const thumbnail = files[0];
|
||||
formMedia.append("file", thumbnail);
|
||||
const responseThumbnail = await uploadThumbnail(id, formMedia);
|
||||
if (responseThumbnail?.error == true) {
|
||||
error(responseThumbnail?.message);
|
||||
if (response?.error) {
|
||||
MySwal.fire("Error", response.message || "Failed to create article", "error");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
const progressInfoArr = files.map((item) => ({
|
||||
percentage: 0,
|
||||
fileName: item.name,
|
||||
}));
|
||||
progressInfo = progressInfoArr;
|
||||
setIsStartUpload(true);
|
||||
setProgressList(progressInfoArr);
|
||||
|
||||
close();
|
||||
files.map(async (item: any, index: number) => {
|
||||
await uploadResumableFile(
|
||||
index,
|
||||
String(id),
|
||||
item,
|
||||
fileTypeId == "2" || fileTypeId == "4" ? item.duration : "0"
|
||||
);
|
||||
// Get the article ID from the new API response
|
||||
const articleId = response?.data?.data?.id;
|
||||
Cookies.set("idCreate", articleId, { expires: 1 });
|
||||
id = articleId;
|
||||
|
||||
// Upload files using new article-files API
|
||||
const formData = new FormData();
|
||||
|
||||
// Add all files to FormData
|
||||
files.forEach((file, index) => {
|
||||
formData.append('files', file);
|
||||
});
|
||||
|
||||
console.log("Uploading files to article:", articleId);
|
||||
console.log("Files to upload:", files.length);
|
||||
|
||||
try {
|
||||
const uploadResponse = await uploadArticleFiles(articleId, formData);
|
||||
|
||||
if (uploadResponse?.error) {
|
||||
MySwal.fire("Error", uploadResponse.message || "Failed to upload files", "error");
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log("Files uploaded successfully:", uploadResponse);
|
||||
|
||||
// Upload thumbnail using first file as thumbnail
|
||||
if (files.length > 0) {
|
||||
const thumbnailFormData = new FormData();
|
||||
thumbnailFormData.append('files', files[0]); // Use first file as thumbnail
|
||||
|
||||
console.log("Uploading thumbnail for article:", articleId);
|
||||
|
||||
try {
|
||||
const thumbnailResponse = await uploadArticleThumbnail(articleId, thumbnailFormData);
|
||||
|
||||
if (thumbnailResponse?.error) {
|
||||
console.warn("Thumbnail upload failed:", thumbnailResponse.message);
|
||||
// Don't fail the whole process if thumbnail upload fails
|
||||
} else {
|
||||
console.log("Thumbnail uploaded successfully:", thumbnailResponse);
|
||||
}
|
||||
} catch (thumbnailError) {
|
||||
console.warn("Thumbnail upload error:", thumbnailError);
|
||||
// Don't fail the whole process if thumbnail upload fails
|
||||
}
|
||||
}
|
||||
|
||||
} catch (uploadError) {
|
||||
console.error("Upload error:", uploadError);
|
||||
MySwal.fire("Error", "Failed to upload files. Please try again.", "error");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Show success message
|
||||
MySwal.fire({
|
||||
title: "Sukses",
|
||||
text: "Article dan files berhasil disimpan.",
|
||||
icon: "success",
|
||||
confirmButtonColor: "#3085d6",
|
||||
confirmButtonText: "OK",
|
||||
}).then(() => {
|
||||
router.push("/admin/content/image");
|
||||
});
|
||||
|
||||
Cookies.remove("idCreate");
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep old upload logic for backward compatibility
|
||||
// const progressInfoArr = files.map((item) => ({
|
||||
// percentage: 0,
|
||||
// fileName: item.name,
|
||||
// }));
|
||||
// progressInfo = progressInfoArr;
|
||||
// setIsStartUpload(true);
|
||||
// setProgressList(progressInfoArr);
|
||||
|
||||
// files.map(async (item: any, index: number) => {
|
||||
// await uploadResumableFile(
|
||||
// index,
|
||||
// String(id),
|
||||
// item,
|
||||
// fileTypeId == "2" || fileTypeId == "4" ? item.duration : "0"
|
||||
// );
|
||||
// });
|
||||
|
||||
Cookies.remove("idCreate");
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -82,9 +82,7 @@ export const useAuth = (): AuthContextType => {
|
|||
|
||||
// Attempt login
|
||||
const response = await doLogin({
|
||||
...credentials,
|
||||
grantType: AUTH_CONSTANTS.GRANT_TYPE,
|
||||
clientId: AUTH_CONSTANTS.CLIENT_ID,
|
||||
...credentials
|
||||
});
|
||||
|
||||
if (response?.error) {
|
||||
|
|
@ -92,7 +90,12 @@ export const useAuth = (): AuthContextType => {
|
|||
throw new Error("Invalid username or password");
|
||||
}
|
||||
|
||||
const { access_token, refresh_token } = response?.data || {};
|
||||
console.log("response : ", response?.data);
|
||||
|
||||
const { access_token, refresh_token } = response?.data?.data || {};
|
||||
|
||||
console.log("access_token : ", access_token);
|
||||
console.log("refresh_token : ", refresh_token);
|
||||
|
||||
if (!access_token || !refresh_token) {
|
||||
throw new Error("Invalid response from server");
|
||||
|
|
@ -103,7 +106,9 @@ export const useAuth = (): AuthContextType => {
|
|||
|
||||
// Get user profile
|
||||
const profileResponse = await getProfile(access_token);
|
||||
const profile: ProfileData = profileResponse?.data?.data;
|
||||
const profile: any = profileResponse?.data?.data;
|
||||
|
||||
console.log("profile : ", profile);
|
||||
|
||||
if (!profile) {
|
||||
throw new Error("Failed to fetch user profile");
|
||||
|
|
@ -124,12 +129,17 @@ export const useAuth = (): AuthContextType => {
|
|||
|
||||
loginRateLimiter.resetAttempts(credentials.username);
|
||||
|
||||
|
||||
console.log("navigationPath : ", profile.userRoleId);
|
||||
|
||||
const navigationPath = getNavigationPath(
|
||||
profile.roleId,
|
||||
profile.userLevel?.id,
|
||||
profile.userLevel?.parentLevelId
|
||||
profile.userRoleId,
|
||||
profile.userLevelId,
|
||||
profile.userLevelGroup
|
||||
);
|
||||
|
||||
console.log("navigationPath : ", navigationPath);
|
||||
|
||||
setState({
|
||||
isAuthenticated: true,
|
||||
user: profile,
|
||||
|
|
@ -198,7 +208,7 @@ export const useEmailValidation = () => {
|
|||
throw new Error(response?.message || "Email validation failed");
|
||||
}
|
||||
|
||||
const message = response?.data?.message;
|
||||
const message = response?.data?.messages[0];
|
||||
|
||||
switch (message) {
|
||||
case "Continue to setup email":
|
||||
|
|
@ -301,8 +311,12 @@ export const useOTPVerification = () => {
|
|||
if (otp.length !== 6) {
|
||||
throw new Error("OTP must be exactly 6 digits");
|
||||
}
|
||||
const data = {
|
||||
username : username,
|
||||
otpCode : otp,
|
||||
};
|
||||
|
||||
const response = await verifyOTPByUsername(username, otp);
|
||||
const response = await verifyOTPByUsername(data);
|
||||
|
||||
if (response?.error) {
|
||||
throw new Error(response.message || "OTP verification failed");
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export const NAVIGATION_CONFIG: NavigationConfig[] = [
|
|||
path: "/admin/dashboard/executive",
|
||||
label: "Executive Dashboard",
|
||||
},
|
||||
{ roleId: 3, path: "/admin/dashboard", label: "Dashboard" },
|
||||
{ roleId: 1, path: "/admin/dashboard", label: "Dashboard" },
|
||||
{ roleId: 4, path: "/admin/dashboard", label: "Dashboard" },
|
||||
{ roleId: 9, path: "/in/supervisor/ticketing", label: "Ticketing" },
|
||||
{ roleId: 10, path: "/admin/dashboard", label: "Dashboard" },
|
||||
|
|
@ -49,30 +49,29 @@ export const setAuthCookies = (
|
|||
});
|
||||
};
|
||||
|
||||
export const setProfileCookies = (profile: ProfileData): void => {
|
||||
Cookies.set("home_path", profile.homePath || "", { expires: 1 });
|
||||
Cookies.set("profile_picture", profile.profilePictureUrl || "", {
|
||||
expires: 1,
|
||||
});
|
||||
Cookies.set("state", profile.userLevel?.name || "", { expires: 1 });
|
||||
Cookies.set("state-prov", profile.userLevel?.province?.provName || "", {
|
||||
expires: 1,
|
||||
});
|
||||
export const setProfileCookies = (profile: any): void => {
|
||||
// Cookies.set("home_path", profile.homePath || "", { expires: 1 });
|
||||
// Cookies.set("profile_picture", profile.profilePictureUrl || "", {
|
||||
// expires: 1,
|
||||
// });
|
||||
// Cookies.set("state", profile.userLevel?.name || "", { expires: 1 });
|
||||
// Cookies.set("state-prov", profile.userLevel?.province?.provName || "", {
|
||||
// expires: 1,
|
||||
// });
|
||||
|
||||
setCookiesEncrypt("uie", profile.id, { expires: 1 });
|
||||
setCookiesEncrypt("urie", profile.roleId.toString(), { expires: 1 });
|
||||
setCookiesEncrypt("urne", profile.role?.name || "", { expires: 1 });
|
||||
setCookiesEncrypt("ulie", profile.userLevel?.id.toString() || "", {
|
||||
expires: 1,
|
||||
});
|
||||
setCookiesEncrypt(
|
||||
"uplie",
|
||||
profile.userLevel?.parentLevelId?.toString() || "",
|
||||
{ expires: 1 }
|
||||
);
|
||||
setCookiesEncrypt("ulne", profile.userLevel?.levelNumber.toString() || "", {
|
||||
setCookiesEncrypt("urie", profile.userRoleId.toString(), { expires: 1 });
|
||||
setCookiesEncrypt("ulie", profile.userLevelId.toString() || "", {
|
||||
expires: 1,
|
||||
});
|
||||
// setCookiesEncrypt(
|
||||
// "uplie",
|
||||
// profile.userLevel?.parentLevelId?.toString() || "",
|
||||
// { expires: 1 }
|
||||
// );
|
||||
// setCookiesEncrypt("ulne", profile.userLevel?.levelNumber.toString() || "", {
|
||||
// expires: 1,
|
||||
// });
|
||||
setCookiesEncrypt("ufne", profile.fullname, { expires: 1 });
|
||||
setCookiesEncrypt("ulnae", profile.userLevel?.name || "", { expires: 1 });
|
||||
setCookiesEncrypt("uinse", profile.instituteId || "", { expires: 1 });
|
||||
|
|
@ -130,7 +129,7 @@ export const isSpecialLevel = (
|
|||
export const getNavigationPath = (
|
||||
roleId: number,
|
||||
userLevelId?: number,
|
||||
parentLevelId?: number
|
||||
userLevelGroup?: number
|
||||
): string => {
|
||||
const config = NAVIGATION_CONFIG.find((nav) => nav.roleId === roleId);
|
||||
|
||||
|
|
@ -139,12 +138,11 @@ export const getNavigationPath = (
|
|||
if (config) {
|
||||
// Special handling for role 2 with specific level conditions
|
||||
if (
|
||||
roleId === 2 &&
|
||||
userLevelId &&
|
||||
parentLevelId &&
|
||||
isSpecialLevel(userLevelId, parentLevelId)
|
||||
roleId === 1 &&
|
||||
userLevelId
|
||||
// isSpecialLevel(userLevelId, parentLevelId)
|
||||
) {
|
||||
return "/in/dashboard";
|
||||
return "/admin/dashboard";
|
||||
}
|
||||
return config.path;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import type { NextConfig } from "next";
|
|||
|
||||
const nextConfig = {
|
||||
images: {
|
||||
domains: ["netidhub.com"],
|
||||
domains: ["kontenhumas.com"],
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ export async function login(data: any) {
|
|||
}
|
||||
|
||||
export async function doLogin(data: any) {
|
||||
const pathUrl = "signin";
|
||||
const pathUrl = "users/login";
|
||||
return httpPost(pathUrl, data);
|
||||
}
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ export async function getCsrfToken() {
|
|||
"content-type": "application/json",
|
||||
};
|
||||
return httpGet(pathUrl, headers);
|
||||
// const url = 'https://netidhub.com/api/csrf';
|
||||
// const url = 'https://kontenhumas.com/api/csrf';
|
||||
// try {
|
||||
// const response = await fetch(url, {
|
||||
// method: 'GET',
|
||||
|
|
@ -69,8 +69,8 @@ export async function getProfile(token: any) {
|
|||
}
|
||||
|
||||
export async function postEmailValidation(data: any) {
|
||||
const url = "public/users/email-validation";
|
||||
return httpPostInterceptor(url, data);
|
||||
const url = "users/email-validation";
|
||||
return httpPost(url, data);
|
||||
}
|
||||
|
||||
export async function postSetupEmail(data: any) {
|
||||
|
|
@ -78,9 +78,9 @@ export async function postSetupEmail(data: any) {
|
|||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function verifyOTPByUsername(username: any, otp: any) {
|
||||
const url = `public/users/verify-otp?username=${username}&otp=${otp}`;
|
||||
return httpPost(url);
|
||||
export async function verifyOTPByUsername(data: any) {
|
||||
const url = `users/otp-validation`;
|
||||
return httpPost(url, data);
|
||||
}
|
||||
|
||||
export async function getSubjects() {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,60 @@ import {
|
|||
httpPostInterceptor,
|
||||
} from "./http-config/http-interceptor-service";
|
||||
|
||||
// Interface for Articles API filters
|
||||
export interface ArticleFilters {
|
||||
page?: number;
|
||||
totalPage?: number;
|
||||
title?: string;
|
||||
description?: string;
|
||||
categoryId?: number;
|
||||
category?: string;
|
||||
typeId?: number;
|
||||
tags?: string;
|
||||
createdById?: number;
|
||||
statusId?: number;
|
||||
isBanner?: boolean;
|
||||
isPublish?: boolean;
|
||||
isDraft?: boolean;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
}
|
||||
|
||||
// Interface for creating new article
|
||||
export interface CreateArticleData {
|
||||
title: string;
|
||||
description: string;
|
||||
htmlDescription: string;
|
||||
categoryIds: string;
|
||||
typeId: number;
|
||||
tags: string;
|
||||
isDraft: boolean;
|
||||
isPublish: boolean;
|
||||
oldId: number;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
// Interface for Article Category
|
||||
export interface ArticleCategory {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
thumbnailUrl: string;
|
||||
slug: string | null;
|
||||
tags: string[];
|
||||
thumbnailPath: string | null;
|
||||
parentId: number;
|
||||
oldCategoryId: number | null;
|
||||
createdById: number;
|
||||
statusId: number;
|
||||
isPublish: boolean;
|
||||
publishedAt: string | null;
|
||||
isEnabled: boolean | null;
|
||||
isActive: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export async function listDataAll(
|
||||
isForSelf: any,
|
||||
isApproval: any,
|
||||
|
|
@ -150,6 +204,12 @@ export async function createMedia(data: any) {
|
|||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
// New Articles API - Create Article
|
||||
export async function createArticle(data: CreateArticleData) {
|
||||
const url = "articles";
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function uploadThumbnail(id: any, data: any) {
|
||||
const url = `media/upload?id=${id}&operation=thumbnail`;
|
||||
const headers = {
|
||||
|
|
@ -158,6 +218,30 @@ export async function uploadThumbnail(id: any, data: any) {
|
|||
return httpPostInterceptor(url, data, headers);
|
||||
}
|
||||
|
||||
// New Articles API - Upload Article Files
|
||||
export async function uploadArticleFiles(articleId: string | number, files: FormData) {
|
||||
const url = `article-files/${articleId}`;
|
||||
const headers = {
|
||||
"Content-Type": "multipart/form-data",
|
||||
};
|
||||
return httpPostInterceptor(url, files, headers);
|
||||
}
|
||||
|
||||
// New Articles API - Upload Article Thumbnail
|
||||
export async function uploadArticleThumbnail(articleId: string | number, thumbnail: FormData) {
|
||||
const url = `articles/thumbnail/${articleId}`;
|
||||
const headers = {
|
||||
"Content-Type": "multipart/form-data",
|
||||
};
|
||||
return httpPostInterceptor(url, thumbnail, headers);
|
||||
}
|
||||
|
||||
// New Articles API - Get Article Categories
|
||||
export async function listArticleCategories(page: number = 1, limit: number = 100) {
|
||||
const url = `article-categories?page=${page}&limit=${limit}`;
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
export async function detailSPIT(id: any) {
|
||||
const url = `media/spit?id=${id}`;
|
||||
return httpGetInterceptor(url);
|
||||
|
|
@ -211,3 +295,101 @@ export async function postActivityLog(data: any) {
|
|||
const url = `activity`;
|
||||
return httpPost(url, data);
|
||||
}
|
||||
|
||||
// New Articles API function with complete filter support
|
||||
export async function listArticles(
|
||||
page: number = 1,
|
||||
totalPage: number = 10,
|
||||
title?: string,
|
||||
description?: string,
|
||||
categoryId?: number,
|
||||
category?: string,
|
||||
typeId?: number,
|
||||
tags?: string,
|
||||
createdById?: number,
|
||||
statusId?: number,
|
||||
isBanner?: boolean,
|
||||
isPublish?: boolean,
|
||||
isDraft?: boolean,
|
||||
startDate?: string,
|
||||
endDate?: string
|
||||
) {
|
||||
let url = `articles?page=${page}&totalPage=${totalPage}`;
|
||||
|
||||
// Add optional query parameters based on available filters
|
||||
if (title) url += `&title=${encodeURIComponent(title)}`;
|
||||
if (description) url += `&description=${encodeURIComponent(description)}`;
|
||||
if (categoryId !== undefined) url += `&categoryId=${categoryId}`;
|
||||
if (category) url += `&category=${encodeURIComponent(category)}`;
|
||||
if (typeId !== undefined) url += `&typeId=${typeId}`;
|
||||
if (tags) url += `&tags=${encodeURIComponent(tags)}`;
|
||||
if (createdById !== undefined) url += `&createdById=${createdById}`;
|
||||
if (statusId !== undefined) url += `&statusId=${statusId}`;
|
||||
if (isBanner !== undefined) url += `&isBanner=${isBanner}`;
|
||||
if (isPublish !== undefined) url += `&isPublish=${isPublish}`;
|
||||
if (isDraft !== undefined) url += `&isDraft=${isDraft}`;
|
||||
if (startDate) url += `&startDate=${startDate}`;
|
||||
if (endDate) url += `&endDate=${endDate}`;
|
||||
|
||||
return await httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
// Alternative function using interface for better type safety
|
||||
export async function listArticlesWithFilters(filters: ArticleFilters) {
|
||||
return await listArticles(
|
||||
filters.page,
|
||||
filters.totalPage,
|
||||
filters.title,
|
||||
filters.description,
|
||||
filters.categoryId,
|
||||
filters.category,
|
||||
filters.typeId,
|
||||
filters.tags,
|
||||
filters.createdById,
|
||||
filters.statusId,
|
||||
filters.isBanner,
|
||||
filters.isPublish,
|
||||
filters.isDraft,
|
||||
filters.startDate,
|
||||
filters.endDate
|
||||
);
|
||||
}
|
||||
|
||||
// Backward compatible wrapper for listDataTeks with new articles API
|
||||
export async function listDataTeksNew(
|
||||
size: any,
|
||||
page: any,
|
||||
isForSelf: any,
|
||||
isApproval: any,
|
||||
categoryFilter: any,
|
||||
statusFilter: any,
|
||||
needApprovalFromLevel: any,
|
||||
creator: any,
|
||||
source: any,
|
||||
startDate: any,
|
||||
endDate: any,
|
||||
title: string = "",
|
||||
creatorGroup: string = ""
|
||||
) {
|
||||
// Convert old parameters to new API format
|
||||
const categoryId = categoryFilter ? Number(categoryFilter) : undefined;
|
||||
const statusId = statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined;
|
||||
|
||||
return await listArticles(
|
||||
page + 1, // API expects 1-based page
|
||||
Number(size),
|
||||
title,
|
||||
undefined, // description
|
||||
categoryId,
|
||||
undefined, // category name
|
||||
3, // typeId for text content
|
||||
undefined, // tags
|
||||
undefined, // createdById
|
||||
statusId,
|
||||
undefined, // isBanner
|
||||
undefined, // isPublish
|
||||
undefined, // isDraft
|
||||
startDate,
|
||||
endDate
|
||||
);
|
||||
}
|
||||
|
|
@ -5,6 +5,60 @@ import {
|
|||
httpPostInterceptor,
|
||||
} from "../http-config/http-interceptor-service";
|
||||
|
||||
// Interface for Articles API filters
|
||||
export interface ArticleFilters {
|
||||
page?: number;
|
||||
totalPage?: number;
|
||||
title?: string;
|
||||
description?: string;
|
||||
categoryId?: number;
|
||||
category?: string;
|
||||
typeId?: number;
|
||||
tags?: string;
|
||||
createdById?: number;
|
||||
statusId?: number;
|
||||
isBanner?: boolean;
|
||||
isPublish?: boolean;
|
||||
isDraft?: boolean;
|
||||
startDate?: string;
|
||||
endDate?: string;
|
||||
}
|
||||
|
||||
// Interface for creating new article
|
||||
export interface CreateArticleData {
|
||||
title: string;
|
||||
description: string;
|
||||
htmlDescription: string;
|
||||
categoryIds: string;
|
||||
typeId: number;
|
||||
tags: string;
|
||||
isDraft: boolean;
|
||||
isPublish: boolean;
|
||||
oldId: number;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
// Interface for Article Category
|
||||
export interface ArticleCategory {
|
||||
id: number;
|
||||
title: string;
|
||||
description: string;
|
||||
thumbnailUrl: string;
|
||||
slug: string | null;
|
||||
tags: string[];
|
||||
thumbnailPath: string | null;
|
||||
parentId: number;
|
||||
oldCategoryId: number | null;
|
||||
createdById: number;
|
||||
statusId: number;
|
||||
isPublish: boolean;
|
||||
publishedAt: string | null;
|
||||
isEnabled: boolean | null;
|
||||
isActive: boolean;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
// export async function listDataAll(
|
||||
// isForSelf,
|
||||
// isApproval,
|
||||
|
|
@ -171,6 +225,12 @@ export async function createMedia(data: any) {
|
|||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
// New Articles API - Create Article
|
||||
export async function createArticle(data: CreateArticleData) {
|
||||
const url = "articles";
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function uploadThumbnail(id: any, data: any) {
|
||||
const url = `media/upload?id=${id}&operation=thumbnail`;
|
||||
const headers = {
|
||||
|
|
@ -179,6 +239,30 @@ export async function uploadThumbnail(id: any, data: any) {
|
|||
return httpPostInterceptor(url, data, headers);
|
||||
}
|
||||
|
||||
// New Articles API - Upload Article Files
|
||||
export async function uploadArticleFiles(articleId: string | number, files: FormData) {
|
||||
const url = `article-files/${articleId}`;
|
||||
const headers = {
|
||||
"Content-Type": "multipart/form-data",
|
||||
};
|
||||
return httpPostInterceptor(url, files, headers);
|
||||
}
|
||||
|
||||
// New Articles API - Upload Article Thumbnail
|
||||
export async function uploadArticleThumbnail(articleId: string | number, thumbnail: FormData) {
|
||||
const url = `articles/thumbnail/${articleId}`;
|
||||
const headers = {
|
||||
"Content-Type": "multipart/form-data",
|
||||
};
|
||||
return httpPostInterceptor(url, thumbnail, headers);
|
||||
}
|
||||
|
||||
// New Articles API - Get Article Categories
|
||||
export async function listArticleCategories(page: number = 1, limit: number = 100) {
|
||||
const url = `article-categories?page=${page}&limit=${limit}`;
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
export async function detailSPIT(id: any) {
|
||||
const url = `media/spit?id=${id}`;
|
||||
return httpGetInterceptor(url);
|
||||
|
|
@ -232,3 +316,101 @@ export async function postActivityLog(data: any) {
|
|||
const url = `activity`;
|
||||
return httpPost(url, data);
|
||||
}
|
||||
|
||||
// New Articles API function with complete filter support
|
||||
export async function listArticles(
|
||||
page: number = 1,
|
||||
totalPage: number = 10,
|
||||
title?: string,
|
||||
description?: string,
|
||||
categoryId?: number,
|
||||
category?: string,
|
||||
typeId?: number,
|
||||
tags?: string,
|
||||
createdById?: number,
|
||||
statusId?: number,
|
||||
isBanner?: boolean,
|
||||
isPublish?: boolean,
|
||||
isDraft?: boolean,
|
||||
startDate?: string,
|
||||
endDate?: string
|
||||
) {
|
||||
let url = `articles?page=${page}&totalPage=${totalPage}`;
|
||||
|
||||
// Add optional query parameters based on available filters
|
||||
if (title) url += `&title=${encodeURIComponent(title)}`;
|
||||
if (description) url += `&description=${encodeURIComponent(description)}`;
|
||||
if (categoryId !== undefined) url += `&categoryId=${categoryId}`;
|
||||
if (category) url += `&category=${encodeURIComponent(category)}`;
|
||||
if (typeId !== undefined) url += `&typeId=${typeId}`;
|
||||
if (tags) url += `&tags=${encodeURIComponent(tags)}`;
|
||||
if (createdById !== undefined) url += `&createdById=${createdById}`;
|
||||
if (statusId !== undefined) url += `&statusId=${statusId}`;
|
||||
if (isBanner !== undefined) url += `&isBanner=${isBanner}`;
|
||||
if (isPublish !== undefined) url += `&isPublish=${isPublish}`;
|
||||
if (isDraft !== undefined) url += `&isDraft=${isDraft}`;
|
||||
if (startDate) url += `&startDate=${startDate}`;
|
||||
if (endDate) url += `&endDate=${endDate}`;
|
||||
|
||||
return await httpGetInterceptor(url);
|
||||
}
|
||||
|
||||
// Alternative function using interface for better type safety
|
||||
export async function listArticlesWithFilters(filters: ArticleFilters) {
|
||||
return await listArticles(
|
||||
filters.page,
|
||||
filters.totalPage,
|
||||
filters.title,
|
||||
filters.description,
|
||||
filters.categoryId,
|
||||
filters.category,
|
||||
filters.typeId,
|
||||
filters.tags,
|
||||
filters.createdById,
|
||||
filters.statusId,
|
||||
filters.isBanner,
|
||||
filters.isPublish,
|
||||
filters.isDraft,
|
||||
filters.startDate,
|
||||
filters.endDate
|
||||
);
|
||||
}
|
||||
|
||||
// Backward compatible wrapper for listDataTeks with new articles API
|
||||
export async function listDataTeksNew(
|
||||
size: any,
|
||||
page: any,
|
||||
isForSelf: any,
|
||||
isApproval: any,
|
||||
categoryFilter: any,
|
||||
statusFilter: any,
|
||||
needApprovalFromLevel: any,
|
||||
creator: any,
|
||||
source: any,
|
||||
startDate: any,
|
||||
endDate: any,
|
||||
title: string = "",
|
||||
creatorGroup: string = ""
|
||||
) {
|
||||
// Convert old parameters to new API format
|
||||
const categoryId = categoryFilter ? Number(categoryFilter) : undefined;
|
||||
const statusId = statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined;
|
||||
|
||||
return await listArticles(
|
||||
page + 1, // API expects 1-based page
|
||||
Number(size),
|
||||
title,
|
||||
undefined, // description
|
||||
categoryId,
|
||||
undefined, // category name
|
||||
3, // typeId for text content
|
||||
undefined, // tags
|
||||
undefined, // createdById
|
||||
statusId,
|
||||
undefined, // isBanner
|
||||
undefined, // isPublish
|
||||
undefined, // isDraft
|
||||
startDate,
|
||||
endDate
|
||||
);
|
||||
}
|
||||
|
|
@ -1,11 +1,12 @@
|
|||
import axios from "axios";
|
||||
|
||||
const baseURL = "https://netidhub.com/api/";
|
||||
const baseURL = "https://kontenhumas.com/api/";
|
||||
|
||||
const axiosBaseInstance = axios.create({
|
||||
baseURL,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
"X-Client-Key": "b1ce6602-07ad-46c2-85eb-0cd6decfefa3",
|
||||
},
|
||||
withCredentials: true,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import axios from "axios";
|
|||
import Cookies from "js-cookie";
|
||||
import { getCsrfToken, login } from "../auth";
|
||||
|
||||
const baseURL = "https://netidhub.com/api/";
|
||||
const baseURL = "https://kontenhumas.com/api/";
|
||||
|
||||
const refreshToken = Cookies.get("refresh_token");
|
||||
|
||||
|
|
@ -10,6 +10,7 @@ const axiosInterceptorInstance = axios.create({
|
|||
baseURL,
|
||||
headers: {
|
||||
"content-type": "application/json",
|
||||
"X-Client-Key": "b1ce6602-07ad-46c2-85eb-0cd6decfefa3",
|
||||
},
|
||||
withCredentials: true,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ export async function getCsrfToken() {
|
|||
"content-type": "application/json",
|
||||
};
|
||||
return httpGet(pathUrl, headers);
|
||||
// const url = 'https://netidhub.com/api/csrf';
|
||||
// const url = 'https://kontenhumas.com/api/csrf';
|
||||
// try {
|
||||
// const response = await fetch(url, {
|
||||
// method: 'GET',
|
||||
|
|
|
|||
Loading…
Reference in New Issue