diff --git a/app/[locale]/(admin)/admin/categories/detail/[id]/page.tsx b/app/[locale]/(admin)/admin/categories/detail/[id]/page.tsx
index a3ea843..10d8860 100644
--- a/app/[locale]/(admin)/admin/categories/detail/[id]/page.tsx
+++ b/app/[locale]/(admin)/admin/categories/detail/[id]/page.tsx
@@ -1,11 +1,12 @@
import CategoriesDetailForm from "@/components/form/categories/categories-detail-form";
import FormImageDetail from "@/components/form/content/image/image-detail-form";
+import SiteBreadcrumb from "@/components/site-breadcrumb";
const CategoriesDetailPage = async () => {
return (
- {/*
*/}
-
diff --git a/app/[locale]/(admin)/admin/categories/update/[id]/page.tsx b/app/[locale]/(admin)/admin/categories/update/[id]/page.tsx
new file mode 100644
index 0000000..a58c3fd
--- /dev/null
+++ b/app/[locale]/(admin)/admin/categories/update/[id]/page.tsx
@@ -0,0 +1,16 @@
+import CategoriesUpdateForm from "@/components/form/categories/categories-update-form";
+import SiteBreadcrumb from "@/components/site-breadcrumb";
+import React from "react";
+
+const page = () => {
+ return (
+
+ );
+};
+
+export default page;
diff --git a/app/[locale]/(admin)/admin/content/audio-visual/components/columns.tsx b/app/[locale]/(admin)/admin/content/audio-visual/components/columns.tsx
index 9e152ad..e03ec4c 100644
--- a/app/[locale]/(admin)/admin/content/audio-visual/components/columns.tsx
+++ b/app/[locale]/(admin)/admin/content/audio-visual/components/columns.tsx
@@ -17,6 +17,7 @@ import withReactContent from "sweetalert2-react-content";
import { error } from "@/lib/swal";
import Link from "next/link";
import { deleteMedia } from "@/service/content";
+import { deleteArticle } from "@/service/content/content";
const useTableColumns = () => {
const MySwal = withReactContent(Swal);
@@ -55,12 +56,10 @@ const useTableColumns = () => {
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 (
-
- {displayName}
-
- );
+ const displayName =
+ categoryName ||
+ (categories && categories.length > 0 ? categories[0].title : "-");
+ return
{displayName};
},
},
{
@@ -191,13 +190,8 @@ const useTableColumns = () => {
const MySwal = withReactContent(Swal);
async function doDelete(id: any) {
- // loading();
- const data = {
- id,
- };
-
- const response = await deleteMedia(data);
-
+ const data = { id };
+ const response = await deleteArticle(id);
if (response?.error) {
error(response.message);
return false;
@@ -275,8 +269,8 @@ const useTableColumns = () => {
Edit
*/}
- {(Number(row.original.uploadedById) === Number(userId) ||
- isMabesApprover) && (
+ {/* {(Number(row.original.uploadedById) === Number(userId) ||
+ isMabesApprover) && ( */}
@@ -285,7 +279,7 @@ const useTableColumns = () => {
Edit
- )}
+ {/* )} */}
handleDeleteMedia(row.original.id)}
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-white rounded-none"
diff --git a/app/[locale]/(admin)/admin/content/audio-visual/components/table-video.tsx b/app/[locale]/(admin)/admin/content/audio-visual/components/table-video.tsx
index 68ace44..d75f01b 100644
--- a/app/[locale]/(admin)/admin/content/audio-visual/components/table-video.tsx
+++ b/app/[locale]/(admin)/admin/content/audio-visual/components/table-video.tsx
@@ -176,13 +176,12 @@ const TableVideo = () => {
: "";
try {
- // Using the new interface-based approach for video content
const filters: ArticleFilters = {
- page: page,
+ page,
totalPage: Number(showData),
title: search || undefined,
categoryId: categoryFilter ? Number(categoryFilter) : undefined,
- typeId: 2, // video content type
+ typeId: 2, // ✅ untuk video
statusId:
statusFilter?.length > 0 ? Number(statusFilter[0]) : undefined,
startDate: formattedStartDate || undefined,
@@ -197,28 +196,28 @@ const TableVideo = () => {
item.no = (page - 1) * Number(showData) + index + 1;
});
setDataTable(data);
- setTotalData(data.length);
- setTotalPage(Math.ceil(data.length / Number(showData)));
+ setTotalData(res?.data?.meta?.count || data.length);
+ setTotalPage(
+ Math.ceil((res?.data?.meta?.count || data.length) / Number(showData))
+ );
} else if (Array.isArray(data?.content)) {
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);
+ setTotalData(res?.data?.meta?.count || contentData.length);
setTotalPage(
- data?.totalPages ?? Math.ceil(contentData.length / Number(showData))
+ Math.ceil(
+ (res?.data?.meta?.count || contentData.length) / Number(showData)
+ )
);
} else {
setDataTable([]);
- setTotalData(0);
- setTotalPage(1);
}
- } catch (error) {
- console.error("Error fetching tasks:", error);
+ } catch (err) {
+ console.error("Error fetching tasks:", err);
setDataTable([]);
- setTotalData(0);
- setTotalPage(1);
}
}
diff --git a/app/[locale]/(admin)/admin/content/audio-visual/create/page.tsx b/app/[locale]/(admin)/admin/content/audio-visual/create/page.tsx
index efbd24d..bb682d9 100644
--- a/app/[locale]/(admin)/admin/content/audio-visual/create/page.tsx
+++ b/app/[locale]/(admin)/admin/content/audio-visual/create/page.tsx
@@ -4,7 +4,8 @@ import SiteBreadcrumb from "@/components/site-breadcrumb";
const VideoCreatePage = async () => {
return (
-
diff --git a/app/[locale]/(admin)/admin/content/image/components/columns.tsx b/app/[locale]/(admin)/admin/content/image/components/columns.tsx
index af11de1..00afed8 100644
--- a/app/[locale]/(admin)/admin/content/image/components/columns.tsx
+++ b/app/[locale]/(admin)/admin/content/image/components/columns.tsx
@@ -14,11 +14,11 @@ import { Button } from "@/components/ui/button";
import { Badge } from "@/components/ui/badge";
import { format } from "date-fns";
import { useRouter } from "next/navigation";
-import { deleteMedia } from "@/service/content/content";
import { error } from "@/lib/swal";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
import Link from "next/link";
+import { deleteArticle } from "@/service/content/content";
const useTableColumns = () => {
const MySwal = withReactContent(Swal);
@@ -172,7 +172,7 @@ const useTableColumns = () => {
async function doDelete(id: any) {
const data = { id };
- const response = await deleteMedia(data);
+ const response = await deleteArticle(id);
if (response?.error) {
error(response.message);
return false;
@@ -240,14 +240,14 @@ const useTableColumns = () => {
View
- {(Number(row.original.uploadedById) === Number(userId) || isMabesApprover) && (
+ {/* {(Number(row.original.uploadedById) === Number(userId) || isMabesApprover) && ( */}
Edit
- )}
+ {/* )} */}
handleDeleteMedia(row.original.id)}
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-white rounded-none"
diff --git a/app/[locale]/(admin)/admin/content/image/components/table-image.tsx b/app/[locale]/(admin)/admin/content/image/components/table-image.tsx
index 0b90c73..4f4f4ed 100644
--- a/app/[locale]/(admin)/admin/content/image/components/table-image.tsx
+++ b/app/[locale]/(admin)/admin/content/image/components/table-image.tsx
@@ -52,7 +52,6 @@ import { useParams, useRouter, useSearchParams } from "next/navigation";
import TablePagination from "@/components/table/table-pagination";
import {
- deleteMedia,
listDataImage,
listArticles,
listArticlesWithFilters,
diff --git a/app/[locale]/(admin)/admin/content/image/create/page.tsx b/app/[locale]/(admin)/admin/content/image/create/page.tsx
index f551973..52c7c8e 100644
--- a/app/[locale]/(admin)/admin/content/image/create/page.tsx
+++ b/app/[locale]/(admin)/admin/content/image/create/page.tsx
@@ -4,8 +4,8 @@ import SiteBreadcrumb from "@/components/site-breadcrumb";
const ImageCreatePage = async () => {
return (
- {/*
*/}
-
diff --git a/app/[locale]/(admin)/admin/content/image/detail/[id]/page.tsx b/app/[locale]/(admin)/admin/content/image/detail/[id]/page.tsx
index 6562882..51bfcac 100644
--- a/app/[locale]/(admin)/admin/content/image/detail/[id]/page.tsx
+++ b/app/[locale]/(admin)/admin/content/image/detail/[id]/page.tsx
@@ -1,10 +1,11 @@
import FormImageDetail from "@/components/form/content/image/image-detail-form";
+import SiteBreadcrumb from "@/components/site-breadcrumb";
const ImageDetailPage = async () => {
return (
- {/*
*/}
-
diff --git a/app/[locale]/(admin)/admin/content/image/update/[id]/page.tsx b/app/[locale]/(admin)/admin/content/image/update/[id]/page.tsx
index cd94205..12382a6 100644
--- a/app/[locale]/(admin)/admin/content/image/update/[id]/page.tsx
+++ b/app/[locale]/(admin)/admin/content/image/update/[id]/page.tsx
@@ -1,8 +1,10 @@
import FormImageUpdate from "@/components/form/content/image/image-update-form";
+import SiteBreadcrumb from "@/components/site-breadcrumb";
const ImageUpdatePage = async () => {
return (
+
diff --git a/app/[locale]/(admin)/admin/settings/tenant/component/columns.tsx b/app/[locale]/(admin)/admin/settings/tenant/component/columns.tsx
index 87b645d..695fb96 100644
--- a/app/[locale]/(admin)/admin/settings/tenant/component/columns.tsx
+++ b/app/[locale]/(admin)/admin/settings/tenant/component/columns.tsx
@@ -11,17 +11,21 @@ import {
DropdownMenuItem,
} from "@/components/ui/dropdown-menu";
import { Button } from "@/components/ui/button";
-import { Badge } from "@/components/ui/badge";
-import { format } from "date-fns";
import { useRouter } from "next/navigation";
-import { deleteMedia } from "@/service/content/content";
import { error } from "@/lib/swal";
import Swal from "sweetalert2";
import withReactContent from "sweetalert2-react-content";
-import Link from "next/link";
import { deleteUserLevel } from "@/service/tenant";
+import {
+ Dialog,
+ DialogContent,
+ DialogHeader,
+ DialogTitle,
+ DialogDescription,
+} from "@/components/ui/dialog";
+import { getUserLevelDetail } from "@/service/tenant";
-const useTableColumns = () => {
+const useTableColumns = (onEdit?: (data: any) => void) => {
const MySwal = withReactContent(Swal);
const userLevelId = getCookiesDecrypt("ulie");
@@ -185,6 +189,23 @@ const useTableColumns = () => {
cell: ({ row }) => {
const router = useRouter();
const MySwal = withReactContent(Swal);
+ const [isDialogOpen, setIsDialogOpen] = React.useState(false);
+ const [detailData, setDetailData] = React.useState
(null);
+
+ const handleView = async (id: number) => {
+ try {
+ const res = await getUserLevelDetail(id);
+ if (!res?.error) {
+ setDetailData(res?.data?.data);
+ setIsDialogOpen(true);
+ } else {
+ error(res?.message || "Gagal memuat detail user level");
+ }
+ } catch (err) {
+ console.error("View error:", err);
+ error("Terjadi kesalahan saat memuat data.");
+ }
+ };
async function doDelete(id: number) {
const response = await deleteUserLevel(id);
@@ -242,7 +263,6 @@ const useTableColumns = () => {
const userId = getCookiesDecrypt("uie");
const userLevelId = getCookiesDecrypt("ulie");
const roleId = getCookiesDecrypt("urie");
-
React.useEffect(() => {
if (userLevelId !== undefined && roleId !== undefined) {
setIsMabesApprover(
@@ -251,43 +271,91 @@ const useTableColumns = () => {
}
}, [userLevelId, roleId]);
+ const [open, setOpen] = React.useState(false);
+
return (
-
+
- {/*
-
-
- View
-
- */}
- {/* {(Number(row.original.uploadedById) === Number(userId) || isMabesApprover) && ( */}
-
-
-
- Edit
-
-
- {/* )} */}
handleDeleteMedia(row.original.id)}
+ onClick={() => {
+ setOpen(false);
+ handleView(row.original.id);
+ }}
+ className="p-2 border-b text-default-700 rounded-none cursor-pointer"
+ >
+
+ View
+
+ {
+ setOpen(false); // ⬅️ tutup dropdown manual
+ onEdit?.(row.original);
+ }}
+ className="p-2 border-b text-default-700 rounded-none cursor-pointer"
+ >
+
+ Edit
+
+
+ {
+ setOpen(false); // ⬅️ pastikan dropdown tertutup sebelum alert
+ handleDeleteMedia(row.original.id);
+ }}
className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-white rounded-none"
>
Delete
+ {/* ✅ Dialog Detail User Level */}
+
);
},
diff --git a/app/[locale]/(admin)/admin/settings/tenant/component/table-user-level.tsx b/app/[locale]/(admin)/admin/settings/tenant/component/table-user-level.tsx
index 32725cd..da9d1a3 100644
--- a/app/[locale]/(admin)/admin/settings/tenant/component/table-user-level.tsx
+++ b/app/[locale]/(admin)/admin/settings/tenant/component/table-user-level.tsx
@@ -48,6 +48,9 @@ import {
} from "@tanstack/react-table";
import TablePagination from "@/components/table/table-pagination";
import useTableColumns from "./columns";
+import TenantUpdateForm from "@/components/form/tenant/tenant-update-form";
+import { errorAutoClose, successAutoClose } from "@/lib/swal";
+import { close, loading } from "@/config/swal";
function TenantSettingsContentTable() {
const [activeTab, setActiveTab] = useState("workflows");
@@ -59,6 +62,14 @@ function TenantSettingsContentTable() {
const [isEditingWorkflow, setIsEditingWorkflow] = useState(false);
const { checkWorkflowStatus } = useWorkflowStatusCheck();
const { showWorkflowModal } = useWorkflowModal();
+ const [isEditDialogOpen, setIsEditDialogOpen] = React.useState(false);
+ const [editingUserLevel, setEditingUserLevel] =
+ React.useState(null);
+
+ const handleEditUserLevel = (userLevel: UserLevel) => {
+ setEditingUserLevel(userLevel);
+ setIsEditDialogOpen(true);
+ };
React.useEffect(() => {
loadData();
@@ -90,6 +101,8 @@ function TenantSettingsContentTable() {
});
setUserLevels(data);
console.log("LLL", data);
+ setTotalData(data.length);
+ setTotalPage(Math.ceil(data.length / Number(showData)));
}
} catch (error) {
console.error("Error loading data:", error);
@@ -107,19 +120,29 @@ function TenantSettingsContentTable() {
const handleUserLevelSave = async (data: UserLevelsCreateRequest) => {
try {
+ loading();
+
const response = await createUserLevel(data);
+ close();
+
if (response?.error) {
- console.error("Error creating user level:", response?.message);
- } else {
- console.log("User level created successfully:", response);
+ errorAutoClose(response.message || "Gagal membuat user level.");
+ return;
}
+
+ successAutoClose("User level berhasil dibuat.");
+
+ setIsUserLevelDialogOpen(false);
+
+ setTimeout(async () => {
+ await loadData();
+ }, 3000);
} catch (error) {
+ close();
+ errorAutoClose("Terjadi kesalahan saat membuat user level.");
console.error("Error creating user level:", error);
}
-
- setIsUserLevelDialogOpen(false);
- await loadData();
};
const handleBulkUserLevelSave = async (data: UserLevelsCreateRequest[]) => {
@@ -127,7 +150,10 @@ function TenantSettingsContentTable() {
await loadData();
};
- const columns = useTableColumns();
+ const columns = React.useMemo(
+ () => useTableColumns((data) => handleEditUserLevel(data)),
+ []
+ );
const [showData, setShowData] = React.useState("10");
const [page, setPage] = React.useState(1);
const [totalPage, setTotalPage] = React.useState(1);
@@ -759,7 +785,7 @@ function TenantSettingsContentTable() {
)}
-
+
{table.getHeaderGroups().map((headerGroup) => (
{headerGroup.headers.map((header) => (
@@ -805,6 +831,45 @@ function TenantSettingsContentTable() {
)}
+
+
{
- return (
- page
- )
-}
-
-export default page
\ No newline at end of file
diff --git a/components/form/UserLevelsForm.tsx b/components/form/UserLevelsForm.tsx
index 458e3bc..82538b9 100644
--- a/components/form/UserLevelsForm.tsx
+++ b/components/form/UserLevelsForm.tsx
@@ -44,28 +44,21 @@ export const UserLevelsForm: React.FC = ({
isActive: true,
});
- // Bulk form state
const [bulkFormData, setBulkFormData] = useState([]);
-
- // API data
const [userLevels, setUserLevels] = useState([]);
const [provinces, setProvinces] = useState([]);
-
- // UI state
const [errors, setErrors] = useState>({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [expandedHierarchy, setExpandedHierarchy] = useState(false);
const [isLoadingData, setIsLoadingData] = useState(true);
const [activeTab, setActiveTab] = useState(mode === "single" ? "basic" : "bulk");
- // Load initial data
useEffect(() => {
if (initialData) {
setFormData(initialData);
}
}, [initialData]);
- // Load API data
useEffect(() => {
const loadData = async () => {
try {
@@ -86,7 +79,6 @@ export const UserLevelsForm: React.FC = ({
loadData();
}, []);
- // Validation
const validateForm = (data: UserLevelsCreateRequest): Record => {
const newErrors: Record = {};
@@ -133,7 +125,6 @@ export const UserLevelsForm: React.FC = ({
return isValid;
};
- // Form handlers
const handleFieldChange = (field: keyof UserLevelsCreateRequest, value: any) => {
setFormData(prev => ({ ...prev, [field]: value }));
if (errors[field]) {
@@ -151,11 +142,8 @@ export const UserLevelsForm: React.FC = ({
const handleTabChange = (value: string) => {
setActiveTab(value);
- // Update mode based on active tab
if (value === "bulk") {
- // Mode will be determined by activeTab in handleSubmit
} else {
- // Mode will be determined by activeTab in handleSubmit
}
};
diff --git a/components/form/categories/categories-detail-form.tsx b/components/form/categories/categories-detail-form.tsx
index 28fb13c..f9f9428 100644
--- a/components/form/categories/categories-detail-form.tsx
+++ b/components/form/categories/categories-detail-form.tsx
@@ -49,9 +49,9 @@ export default function CategoriesDetailForm() {
return (