diff --git a/app/(admin)/admin/content-website/page.tsx b/app/(admin)/admin/content-website/page.tsx
index eb5f4ce..adc8d97 100644
--- a/app/(admin)/admin/content-website/page.tsx
+++ b/app/(admin)/admin/content-website/page.tsx
@@ -1,15 +1,20 @@
"use client";
+import Cookies from "js-cookie";
import ContentWebsite from "@/components/main/content-website";
-import DashboardContainer from "@/components/main/dashboard/dashboard-container";
+
import { motion } from "framer-motion";
import { useEffect, useState } from "react";
+import ApproverContentWebsite from "@/components/main/content-website-approver";
export default function ContentWebsitePage() {
const [mounted, setMounted] = useState(false);
+ const [levelId, setLevelId] = useState();
useEffect(() => {
setMounted(true);
+ const ulne = Cookies.get("ulne");
+ setLevelId(ulne);
}, []);
if (!mounted) {
@@ -28,7 +33,7 @@ export default function ContentWebsitePage() {
transition={{ duration: 0.3 }}
>
-
+ {levelId === "2" ?
:
}
);
diff --git a/components/form/article/edit-article-form.tsx b/components/form/article/edit-article-form.tsx
index f4f5844..b22d3b6 100644
--- a/components/form/article/edit-article-form.tsx
+++ b/components/form/article/edit-article-form.tsx
@@ -161,6 +161,13 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
const [startDateValue, setStartDateValue] = useState();
const [startTimeValue, setStartTimeValue] = useState("");
+ const [levelId, setLevelId] = useState();
+
+ useEffect(() => {
+ const ulne = Cookies.get("ulne");
+ setLevelId(ulne);
+ }, []);
+
const { getRootProps, getInputProps } = useDropzone({
onDrop: (acceptedFiles) => {
setFiles((prevFiles) => [
@@ -333,7 +340,7 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
return;
}
- successSubmit("/admin/article");
+ successSubmit("/admin/news-article/image");
};
const publishScheduled = async () => {
@@ -391,7 +398,7 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
return;
}
- successSubmit("/admin/article");
+ successSubmit("/admin/news-article/image");
};
const save = async (values: z.infer) => {
@@ -521,7 +528,7 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
return;
}
- successSubmit("/admin/article");
+ successSubmit("/admin/news-article/image");
}
});
};
@@ -793,18 +800,65 @@ export default function EditArticleForm(props: { isDetail: boolean }) {
Suggestion Box (0)
+
+
+ Description :
+
+ {detailData?.isPublish === true ? (
+
+ Approved
+
+ ) : (
+
+ Pending
+
+ )}
+
Comment
+
View Approver History
+
- {/* Action Button */}
-
-
-
-
+ {/* ================= ACTION BUTTON ================= */}
+
+ {levelId === "2" && !detailData?.isPublish && (
+ <>
+
+
+
+
+
+ >
+ )}
+
+ {/* 🔥 Jika levelId 3 → hanya tampilkan Cancel */}
+ {levelId === "3" && (
+
+
+
+ )}
diff --git a/components/form/form-master-user.tsx b/components/form/form-master-user.tsx
index d9a12a6..9523027 100644
--- a/components/form/form-master-user.tsx
+++ b/components/form/form-master-user.tsx
@@ -49,7 +49,7 @@ const masterUserSchema = z.object({
genderType: z.string().min(1, { message: "Required" }),
phoneNumber: z.string().min(1, { message: "Required" }),
address: z.string().min(1, { message: "Required" }),
- userLevelType: userSchema,
+ // userLevelType: userSchema,
userRoleType: userSchema,
});
@@ -98,7 +98,7 @@ export default function FormMasterUser() {
identityNumber: data.identityNumber,
identityType: "nrp",
phoneNumber: data.phoneNumber,
- userLevelId: data.userLevelType.id,
+ userLevelId: 3,
userRoleId: data.userRoleType.id,
username: data.username,
};
@@ -206,6 +206,7 @@ export default function FormMasterUser() {
close();
if (res?.data?.data) {
setupParent(res?.data?.data, "role");
+ console.log("role", res?.data?.data);
}
};
@@ -408,7 +409,7 @@ export default function FormMasterUser() {
{errors.phoneNumber?.message}
)}
- (
@@ -438,7 +439,7 @@ export default function FormMasterUser() {
{errors.userLevelType?.message}
- )}
+ )} */}
{
- if (roleId === "1") {
+const getSidebarByLevel = (levelId: string | null) => {
+ if (levelId === "1") {
return [
{
title: "Dashboard",
@@ -64,7 +64,7 @@ const getSidebarByRole = (roleId: string | null) => {
];
}
- if (roleId === "2" || roleId === "3") {
+ if (levelId === "3") {
return [
{
title: "Dashboard",
@@ -141,7 +141,66 @@ const getSidebarByRole = (roleId: string | null) => {
];
}
- // fallback kalau role tidak dikenal
+ if (levelId === "2") {
+ return [
+ {
+ title: "Dashboard",
+ items: [
+ {
+ title: "Dashboard",
+ icon: () => (
+
+ ),
+ link: "/admin/dashboard",
+ },
+ ],
+ },
+ {
+ items: [
+ {
+ title: "Content Website",
+ icon: () => ,
+ link: "/admin/content-website",
+ },
+ ],
+ },
+ {
+ title: "News & Article",
+ items: [
+ {
+ title: "News & Article",
+ icon: () => (
+
+ ),
+ children: [
+ {
+ title: "Text",
+ icon: () => ,
+ link: "/admin/news-article/text",
+ },
+ {
+ title: "Image",
+ icon: () => ,
+ link: "/admin/news-article/image",
+ },
+ {
+ title: "Video",
+ icon: () => ,
+ link: "/admin/news-article/video",
+ },
+ {
+ title: "Audio",
+ icon: () => ,
+ link: "/admin/news-article/audio",
+ },
+ ],
+ },
+ ],
+ },
+ ];
+ }
+
+ // fallback kalau Level tidak dikenal
return [];
};
@@ -260,7 +319,7 @@ const SidebarContent = ({
const { theme, toggleTheme } = useTheme();
const [username, setUsername] = useState("Guest");
- const [roleId, setRoleId] = useState(null);
+ const [LevelId, setLevelId] = useState(null);
const [openMenus, setOpenMenus] = useState([]);
// ===============================
@@ -275,10 +334,10 @@ const SidebarContent = ({
};
const cookieUsername = getCookie("username");
- const cookieRoleId = getCookie("urie");
+ const cookieLevelId = getCookie("ulne");
if (cookieUsername) setUsername(cookieUsername);
- if (cookieRoleId) setRoleId(cookieRoleId);
+ if (cookieLevelId) setLevelId(cookieLevelId);
}, []);
// ===============================
@@ -298,7 +357,7 @@ const SidebarContent = ({
);
};
- const sidebarSections = getSidebarByRole(roleId);
+ const sidebarSections = getSidebarByLevel(LevelId);
return (
diff --git a/components/main/content-website-approver.tsx b/components/main/content-website-approver.tsx
new file mode 100644
index 0000000..bf874cc
--- /dev/null
+++ b/components/main/content-website-approver.tsx
@@ -0,0 +1,149 @@
+"use client";
+
+import { Input } from "@/components/ui/input";
+import { Button } from "@/components/ui/button";
+import { Eye, Pencil, Trash2, Filter } from "lucide-react";
+
+export default function ApproverContentWebsite() {
+ const tabs = [
+ "Hero Section",
+ "About Us",
+ "Our Products",
+ "Our Services",
+ "Technology Partners",
+ "Pop Up",
+ ];
+
+ const data = [
+ {
+ title: "Beyond Expectations to Build Reputation.",
+ subtitle: "-",
+ author: "John Kontributor",
+ status: "Published",
+ date: "2024-01-15",
+ },
+ {
+ title: "Manajemen Reputasi untuk Institusi",
+ subtitle: "-",
+ author: "Sarah Kontributor",
+ status: "Pending",
+ date: "2024-01-14",
+ },
+ ];
+
+ return (
+
+ {/* HEADER */}
+
+
Content Website
+
+ Update homepage content, products, services, and partners
+
+
+
+ {/* TABS */}
+
+ {tabs.map((tab, i) => (
+
+ ))}
+
+
+ {/* SEARCH & FILTER */}
+
+
+
+
+
+ {/* TABLE */}
+
+
+
+
+ | Main Title |
+ Subtitle |
+ Author |
+ Status |
+ Date |
+ Actions |
+
+
+
+
+ {data.map((item, i) => (
+
+ |
+ {item.title}
+ |
+
+ {item.subtitle} |
+
+ {item.author} |
+
+
+
+ {item.status}
+
+ |
+
+ {item.date} |
+
+
+
+ |
+
+ ))}
+
+
+
+ {/* FOOTER */}
+
+
Showing 1 to 2 of 2 items
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/components/main/dashboard/dashboard-container.tsx b/components/main/dashboard/dashboard-container.tsx
index 4f0330f..4ab91ff 100644
--- a/components/main/dashboard/dashboard-container.tsx
+++ b/components/main/dashboard/dashboard-container.tsx
@@ -52,10 +52,10 @@ interface PostCount {
}
export default function DashboardContainer() {
- const [roleName, setRoleName] = useState
();
+ const [levelName, setLevelName] = useState();
useEffect(() => {
- const role = Cookies.get("roleName");
- setRoleName(role);
+ const levelId = Cookies.get("ulne");
+ setLevelName(levelId);
}, []);
const username = Cookies.get("username");
@@ -135,7 +135,7 @@ export default function DashboardContainer() {
return month + " " + year;
};
- if (!roleName) return null;
+ if (!levelName) return null;
const AdminDashboard = () => {
const tasks = [
{
@@ -494,7 +494,199 @@ export default function DashboardContainer() {
);
};
+ const ApproverDashboard = () => {
+ const stats = [
+ {
+ title: "Pending Review",
+ value: 12,
+ growth: "+3",
+ color: "bg-yellow-500",
+ },
+ {
+ title: "Approved Today",
+ value: 8,
+ growth: "+5",
+ color: "bg-green-600",
+ },
+ {
+ title: "Total Published",
+ value: 156,
+ growth: "+12%",
+ color: "bg-blue-600",
+ },
+ {
+ title: "Rejected",
+ value: 5,
+ growth: "-1",
+ color: "bg-red-600",
+ },
+ ];
+
+ const pendingList = [
+ {
+ title: "MediaHUB Content Aggregator",
+ author: "John Kontributor",
+ category: "Product",
+ time: "2 hours ago",
+ status: "Pending",
+ },
+ {
+ title: "Artifintel Services Update",
+ author: "John Kontributor",
+ category: "Service",
+ time: "2 hours ago",
+ status: "Pending",
+ },
+ ];
+
+ const activities = [
+ {
+ status: "Approved",
+ title: "Technology Summit Event",
+ time: "10 mins ago",
+ },
+ {
+ status: "Rejected",
+ title: "Product Update Draft",
+ time: "25 mins ago",
+ },
+ {
+ status: "Approved",
+ title: "Partner Logo Update",
+ time: "1 hour ago",
+ },
+ ];
+
+ return (
+
+ {/* HEADER */}
+
+
+ Approver Dashboard
+
+
+ Review and manage content submissions
+
+
+
+ {/* ================= STAT CARDS ================= */}
+
+ {stats.map((card, i) => (
+
+
+
{card.title}
+
+ {card.value}
+
+
+
+
+
+ ))}
+
+
+ {/* ================= CONTENT SECTION ================= */}
+
+ {/* LEFT - Pending Review */}
+
+
+
+ Pending Review{" "}
+
+ {pendingList.length} Items
+
+
+
+
+
+ {pendingList.map((item, i) => (
+
+
+
+
+ {item.title}
+
+
+ {item.author} • {item.category} • {item.time}
+
+
+
+
+ {item.status}
+
+
+
+
+
+
+
+
+
+
+
+ ))}
+
+
+ {/* RIGHT - Recent Activity */}
+
+
Recent Activity
+
+
+ {activities.map((item, i) => (
+
+
+
+ {item.status}
+
+
{item.title}
+
{item.time}
+
+
+ ))}
+
+
+
+
+
+
+ );
+ };
+
return (
- <>{roleName === "Admin" ? : }>
+ <>
+ {levelName === "1" && }
+ {levelName === "3" && }
+ {levelName === "2" && }
+ >
);
}
diff --git a/components/main/news-image.tsx b/components/main/news-image.tsx
index deb8782..826ecb9 100644
--- a/components/main/news-image.tsx
+++ b/components/main/news-image.tsx
@@ -18,12 +18,19 @@ import Link from "next/link";
import { getArticlePagination } from "@/service/article";
import { formatDate } from "@/utils/global";
import { close, loading } from "@/config/swal";
+import Cookies from "js-cookie";
export default function NewsImage() {
const [articles, setArticles] = useState([]);
const [page, setPage] = useState(1);
const [totalPage, setTotalPage] = useState(1);
const [search, setSearch] = useState("");
+ const [levelId, setLevelId] = useState();
+
+ useEffect(() => {
+ const ulne = Cookies.get("ulne");
+ setLevelId(ulne);
+ }, []);
useEffect(() => {
fetchData();
@@ -52,18 +59,21 @@ export default function NewsImage() {
}
const statusVariant = (status: string) => {
- switch (status?.toLowerCase()) {
- case "publish":
- return "bg-green-100 text-green-700";
- case "pending":
- return "bg-yellow-100 text-yellow-700";
- case "draft":
- return "bg-gray-200 text-gray-600";
- case "reject":
- return "bg-red-100 text-red-600";
- default:
- return "bg-gray-200 text-gray-600";
+ const value = status?.toLowerCase();
+
+ if (value === "published") {
+ return "bg-green-100 text-green-700";
}
+
+ if (value === "pending") {
+ return "bg-yellow-100 text-yellow-700";
+ }
+
+ if (value === "cancel") {
+ return "bg-red-100 text-red-700";
+ }
+
+ return "bg-gray-200 text-gray-600";
};
return (
@@ -78,12 +88,14 @@ export default function NewsImage() {
Create and manage news articles and blog posts
-
-
-
+ {levelId === "3" && (
+
+
+
+ )}
{/* ================= SEARCH ================= */}
diff --git a/service/article.ts b/service/article.ts
index 2d55bb2..b0ae2dc 100644
--- a/service/article.ts
+++ b/service/article.ts
@@ -30,7 +30,7 @@ export async function getListArticle(props: PaginationRequest) {
}&categoryId=${category || ""}&sortBy=${sortBy || "created_at"}&sort=${
sort || "desc"
}&category=${categorySlug || ""}&isBanner=${isBanner || ""}`,
- null
+ null,
);
}
@@ -50,7 +50,7 @@ export async function getArticlePagination(props: PaginationRequest) {
source,
} = props;
- return await httpGetInterceptor(
+ return await httpGet(
`/articles?limit=${limit}&page=${page}&title=${search}&startDate=${
startDate || ""
}&endDate=${endDate || ""}&categoryId=${category || ""}&source=${
@@ -59,7 +59,7 @@ export async function getArticlePagination(props: PaginationRequest) {
sortBy || "created_at"
}&sort=${sort || "asc"}&category=${categorySlug || ""}&isBanner=${
isBanner || ""
- }`
+ }`,
);
}
@@ -75,7 +75,7 @@ export async function getTopArticles(props: PaginationRequest) {
}&title=${search}&startDate=${startDate || ""}&endDate=${
endDate || ""
}&category=${category || ""}&sortBy=view_count&sort=desc`,
- headers
+ headers,
);
}
@@ -121,11 +121,11 @@ export async function deleteArticle(id: string) {
}
export async function getArticleByCategory() {
- return await httpGetInterceptor(`/article-categories?limit=1000`);
+ return await httpGet(`/article-categories?limit=1000`);
}
export async function getCategoryPagination(data: any) {
return await httpGet(
- `/article-categories?limit=${data?.limit}&page=${data?.page}&title=${data?.search}`
+ `/article-categories?limit=${data?.limit}&page=${data?.page}&title=${data?.search}`,
);
}
@@ -159,7 +159,7 @@ export async function deleteArticleFiles(id: number) {
export async function getUserLevelDataStat(startDate: string, endDate: string) {
return await httpGet(
- `/articles/statistic/user-levels?startDate=${startDate}&endDate=${endDate}`
+ `/articles/statistic/user-levels?startDate=${startDate}&endDate=${endDate}`,
);
}
export async function getStatisticMonthly(year: string) {