diff --git a/src/app/api/admin/job/[id]/route.ts b/src/app/api/admin/job/[id]/route.ts
new file mode 100644
index 00000000..45e4996d
--- /dev/null
+++ b/src/app/api/admin/job/[id]/route.ts
@@ -0,0 +1,53 @@
+import backendLogger from "@/util/backendLogger";
+import { NextResponse } from "next/server";
+import prisma from "@/lib/prisma";
+
+export { GET };
+
+async function GET(request: Request, { params }: { params: { id: string } }) {
+ try {
+ const { id } = params;
+ const data = await prisma.job.findUnique({
+ where: {
+ id: id,
+ },
+ include: {
+ Author: {
+ select: {
+ username: true,
+ nomor: true,
+ Profile: {
+ select: {
+ name: true,
+ alamat: true,
+ },
+ },
+ },
+ },
+ MasterStatus: {
+ select: {
+ name: true,
+ },
+ },
+ },
+ });
+ return NextResponse.json(
+ {
+ success: true,
+ message: "Success get data job-vacancy",
+ data: data,
+ },
+ { status: 200 }
+ );
+ } catch (error) {
+ backendLogger.error("Error get data job-vacancy", error);
+ return NextResponse.json(
+ {
+ success: false,
+ message: "Error get data job-vacancy",
+ reason: (error as Error).message,
+ },
+ { status: 500 }
+ );
+ }
+}
diff --git a/src/app/dev/admin/job/[id]/[status]/page.tsx b/src/app/dev/admin/job/[id]/[status]/page.tsx
new file mode 100644
index 00000000..770dba26
--- /dev/null
+++ b/src/app/dev/admin/job/[id]/[status]/page.tsx
@@ -0,0 +1,11 @@
+import { AdminJob_ViewDetailPublish } from "@/app_modules/admin/job/_view/detail";
+
+async function Page() {
+ return (
+ <>
+
+ >
+ );
+}
+
+export default Page;
diff --git a/src/app/dev/admin/job/main/page.tsx b/src/app/dev/admin/job/main/page.tsx
index ce9c1d7b..ab68e029 100644
--- a/src/app/dev/admin/job/main/page.tsx
+++ b/src/app/dev/admin/job/main/page.tsx
@@ -1,23 +1,9 @@
import { AdminJob_Main } from "@/app_modules/admin/job";
-import { AdminJob_funCountStatusByStatusId } from "@/app_modules/admin/job/fun/count/fun_count_job_by_status_id";
export default async function Page() {
- // const countPublish = await AdminJob_funCountStatusByStatusId("1")
- // const countReview = await AdminJob_funCountStatusByStatusId("2");
- // const countReject = await AdminJob_funCountStatusByStatusId("4");
- // const countArsip = await AdminJob_funCountStatusByStatusId("0")
-
-
-
-
- return (
- <>
-
- >
- );
-}
\ No newline at end of file
+ return (
+ <>
+
+ >
+ );
+}
diff --git a/src/app_modules/admin/_admin_global/_component/button/detail_button.tsx b/src/app_modules/admin/_admin_global/_component/button/detail_button.tsx
new file mode 100644
index 00000000..db0d770c
--- /dev/null
+++ b/src/app_modules/admin/_admin_global/_component/button/detail_button.tsx
@@ -0,0 +1,28 @@
+import { Button } from "@mantine/core";
+import { IconEye } from "@tabler/icons-react";
+import { useRouter } from "next/navigation";
+import { useState } from "react";
+
+export default function Admin_DetailButton({ path }: { path: string }) {
+ const router = useRouter();
+ const [isLoading, setLoading] = useState(false);
+
+ return (
+ <>
+ }
+ onClick={() => {
+ setLoading(true);
+ router.push(path);
+ }}
+ >
+ Detail
+
+ >
+ );
+}
diff --git a/src/app_modules/admin/_admin_global/_component/comp_admin_boxstyle.tsx b/src/app_modules/admin/_admin_global/_component/comp_admin_boxstyle.tsx
new file mode 100644
index 00000000..7324985a
--- /dev/null
+++ b/src/app_modules/admin/_admin_global/_component/comp_admin_boxstyle.tsx
@@ -0,0 +1,26 @@
+import { AdminColor } from "@/app_modules/_global/color/color_pallet";
+import { Paper } from "@mantine/core";
+
+export function Admin_ComponentBoxStyle({
+ children,
+ style,
+}: {
+ children: React.ReactNode;
+ style?: React.CSSProperties;
+}) {
+ return (
+ <>
+
+ {children}
+
+ >
+ );
+}
diff --git a/src/app_modules/admin/job/_components/detail_status.tsx b/src/app_modules/admin/job/_components/detail_status.tsx
new file mode 100644
index 00000000..222fd0c7
--- /dev/null
+++ b/src/app_modules/admin/job/_components/detail_status.tsx
@@ -0,0 +1,78 @@
+"use client";
+
+import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
+import { Admin_ComponentBoxStyle } from "@/app_modules/admin/_admin_global/_component/comp_admin_boxstyle";
+import { MODEL_JOB } from "@/app_modules/job/model/interface";
+import { APIs } from "@/lib";
+import { Badge, Center, Grid, Image, SimpleGrid, Text } from "@mantine/core";
+import { IconImageInPicture } from "@tabler/icons-react";
+import { useState } from "react";
+
+export function AdminJob_DetailPublish({ data }: { data: MODEL_JOB }) {
+ const [isLoading, setLoading] = useState(false);
+ const listData = [
+ {
+ title: "Username",
+ value: data.Author.username,
+ },
+ {
+ title: "Judul",
+ value: data.title,
+ },
+ {
+ title: "Status",
+ value: data.isArsip ? (
+ Arsip
+ ) : (
+ Publish
+ ),
+ },
+
+ {
+ title: "Konten",
+ value:
,
+ },
+ {
+ title: "Deskripsi",
+ value: ,
+ },
+ ];
+
+ return (
+ <>
+
+
+ {listData.map((item, index) => (
+
+
+ {item.title}
+
+
+ :
+
+
+ {item.value}
+
+
+ ))}
+
+
+ {data.imageId && (
+
+
+ setLoading(false)}
+ alt="Foto"
+ src={APIs.GET({ fileId: data.imageId })}
+ mah={500}
+ maw={300}
+ />
+
+
+ )}
+
+
+ {/* {JSON.stringify(data, null, 2)} */}
+ >
+ );
+}
diff --git a/src/app_modules/admin/job/_view/detail.tsx b/src/app_modules/admin/job/_view/detail.tsx
new file mode 100644
index 00000000..107039a7
--- /dev/null
+++ b/src/app_modules/admin/job/_view/detail.tsx
@@ -0,0 +1,54 @@
+"use client";
+
+import { SimpleGrid, Stack, Text } from "@mantine/core";
+import { useParams } from "next/navigation";
+import AdminGlobal_ComponentBackButton from "../../_admin_global/back_button";
+import ComponentAdminGlobal_HeaderTamplate from "../../_admin_global/header_tamplate";
+import { useState } from "react";
+import { useShallowEffect } from "@mantine/hooks";
+import { clientLogger } from "@/util/clientLogger";
+import { apiGetOneJobById } from "../lib/api_fetch_admin_job";
+import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
+import { AdminJob_DetailPublish } from "../_components/detail_status";
+
+export function AdminJob_ViewDetailPublish() {
+ const param = useParams<{ id: string; status: string }>();
+ const [data, setData] = useState();
+
+ useShallowEffect(() => {
+ handleLoadData();
+ }, []);
+
+ const handleLoadData = async () => {
+ try {
+ const response = await apiGetOneJobById({
+ id: param.id,
+ });
+
+ if (response) {
+ console.log(response.data);
+ setData(response.data);
+ }
+ } catch (error) {
+ clientLogger.error("Error get data job", error);
+ }
+ };
+
+ return (
+ <>
+
+
+
+
+ {!data ? (
+
+
+
+
+ ) : (
+
+ )}
+
+ >
+ );
+}
diff --git a/src/app_modules/admin/job/child/publish/index.tsx b/src/app_modules/admin/job/child/publish/index.tsx
index 3379288f..eb6a4ae6 100644
--- a/src/app_modules/admin/job/child/publish/index.tsx
+++ b/src/app_modules/admin/job/child/publish/index.tsx
@@ -1,32 +1,38 @@
"use client";
-import { RouterAdminJob } from "@/lib/router_admin/router_admin_job";
+import { AdminColor } from "@/app_modules/_global/color/color_pallet";
import { ComponentAdminGlobal_TitlePage } from "@/app_modules/admin/_admin_global/_component";
import ComponentAdminGlobal_HeaderTamplate from "@/app_modules/admin/_admin_global/header_tamplate";
+import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { MODEL_JOB } from "@/app_modules/job/model/interface";
+import { RouterAdminGlobal } from "@/lib";
+import { clientLogger } from "@/util/clientLogger";
import {
+ ActionIcon,
Badge,
+ Box,
Button,
Center,
Pagination,
Paper,
ScrollArea,
- Spoiler,
Stack,
Table,
Text,
TextInput,
} from "@mantine/core";
-import { IconPhotoCheck, IconSearch, IconSettingsSearch } from "@tabler/icons-react";
+import { useShallowEffect } from "@mantine/hooks";
+import {
+ IconEye,
+ IconEyeSearch,
+ IconPencilSearch,
+ IconPhotoCheck,
+ IconSearch,
+} from "@tabler/icons-react";
import { useRouter } from "next/navigation";
import { useState } from "react";
-import adminJob_getListPublish from "../../fun/get/get_list_publish";
-import { RouterAdminGlobal } from "@/lib";
-import { AdminColor } from "@/app_modules/_global/color/color_pallet";
-import { useShallowEffect } from "@mantine/hooks";
import { apiGetAdminJobByStatus } from "../../lib/api_fetch_admin_job";
-import { clientLogger } from "@/util/clientLogger";
-import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
+import Admin_DetailButton from "@/app_modules/admin/_admin_global/_component/button/detail_button";
export default function AdminJob_TablePublish() {
return (
@@ -51,36 +57,36 @@ function TableStatus() {
useShallowEffect(() => {
loadInitialData();
- }, [activePage, isSearch])
+ }, [activePage, isSearch]);
const loadInitialData = async () => {
try {
const response = await apiGetAdminJobByStatus({
name: "Publish",
page: `${activePage}`,
- search: isSearch
- })
+ search: isSearch,
+ });
if (response?.success && response?.data.data) {
setData(response.data.data);
setNPage(response.data.nPage || 1);
} else {
- console.error("Invalid data format recieved", response)
- setData([])
+ console.error("Invalid data format recieved", response);
+ setData([]);
}
} catch (error) {
- clientLogger.error("Invalid data format recieved:", error)
- setData([])
+ clientLogger.error("Invalid data format recieved:", error);
+ setData([]);
}
- }
+ };
const onSearch = async (searchTerm: string) => {
setSearch(searchTerm);
setActivePage(1);
- }
+ };
const onPageClick = (page: number) => {
setActivePage(page);
- }
+ };
const renderTableBody = () => {
if (!Array.isArray(data) || data.length === 0) {
@@ -92,39 +98,35 @@ function TableStatus() {
- )
+ );
}
return data?.map((e, i) => (
|
-
+
{e?.Author?.username}
|
-
-
- {e?.isArsip ? (
- Arsip
- ) : (
- Publish
- )}
-
+
+ {e?.isArsip ? (
+ Arsip
+ ) : (
+ Publish
+ )}
|
-
- {e.title}
-
+
+
+
+ {e.title}
+
+
+
|
-
+
{e.imageId ? (
) : (
-
+
Tidak ada poster
@@ -150,6 +154,11 @@ function TableStatus() {
|
+
+
+
+ |
+ {/*
- |
+ */}
));
- }
+ };
return (
<>
@@ -197,15 +206,8 @@ function TableStatus() {
) : (
-
-
+
+
|
@@ -215,16 +217,13 @@ function TableStatus() {
Status
|
- Judul
+ Judul
|
Poster
|
- Syarat Ketentuan
- |
-
- Deskripsi
+ Aksi
|
diff --git a/src/app_modules/admin/job/lib/api_fetch_admin_job.ts b/src/app_modules/admin/job/lib/api_fetch_admin_job.ts
index bd036243..e6970ff8 100644
--- a/src/app_modules/admin/job/lib/api_fetch_admin_job.ts
+++ b/src/app_modules/admin/job/lib/api_fetch_admin_job.ts
@@ -1,67 +1,102 @@
export {
- apiGetAdminJobStatusCountDashboard as apiGetJobStatusCountDashboard ,
- apiGetAdminJobArsipCount as apiGetJobArsipCount,
- apiGetAdminJobByStatus
-}
+ apiGetAdminJobStatusCountDashboard as apiGetJobStatusCountDashboard,
+ apiGetAdminJobArsipCount as apiGetJobArsipCount,
+ apiGetAdminJobByStatus,
+ apiGetOneJobById,
+};
-const apiGetAdminJobStatusCountDashboard = async ({ name }: {
- name: "Publish" | "Review" | "Reject";
+const apiGetAdminJobStatusCountDashboard = async ({
+ name,
+}: {
+ name: "Publish" | "Review" | "Reject";
}) => {
- const { token } = await fetch("/api/get-cookie").then((res) => res.json());
- if (!token) return await token.json().catch(() => null);
+ const { token } = await fetch("/api/get-cookie").then((res) => res.json());
+ if (!token) return await token.json().catch(() => null);
- const response = await fetch(`/api/admin/job/dashboard/${name}`, {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- "Access-Control-Allow-Origin": "*",
- Authorization: `Bearer ${token}`,
- },
- });
- return await response.json().catch(() => null)
-}
+ const response = await fetch(`/api/admin/job/dashboard/${name}`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ "Access-Control-Allow-Origin": "*",
+ Authorization: `Bearer ${token}`,
+ },
+ });
+ return await response.json().catch(() => null);
+};
const apiGetAdminJobArsipCount = async () => {
- const { token } = await fetch("/api/get-cookie").then((res) => res.json());
- if (!token) return await token.json().catch(() => null);
-
- const response = await fetch(`/api/admin/job/dashboard/arsip`, {
- method: "GET",
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- "Access-Control-Allow-Origin": "*",
- Authorization: `Bearer ${token}`,
- }
- });
- return await response.json().catch(() => null)
+ const { token } = await fetch("/api/get-cookie").then((res) => res.json());
+ if (!token) return await token.json().catch(() => null);
+ const response = await fetch(`/api/admin/job/dashboard/arsip`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ "Access-Control-Allow-Origin": "*",
+ Authorization: `Bearer ${token}`,
+ },
+ });
+ return await response.json().catch(() => null);
};
const apiGetAdminJobByStatus = async ({
- name,
- page,
- search
+ name,
+ page,
+ search,
}: {
- name: "Publish" | "Review" | "Reject";
- page: string;
- search: string;
+ name: "Publish" | "Review" | "Reject";
+ page: string;
+ search: string;
}) => {
- const { token } = await fetch("/api/get-cookie").then((res) => res.json());
- if (!token) return await token.json().catch(() => null);
+ const { token } = await fetch("/api/get-cookie").then((res) => res.json());
+ if (!token) return await token.json().catch(() => null);
- const isPage = page ? `?page=${page}` : "";
- const isSearch = search ? `&search=${search}` : "";
- const response = await fetch(
- `/api/admin/job/status/${name}${isPage}${isSearch}`,
- {
- headers: {
- "Content-Type": "application/json",
- Accept: "application/json",
- "Access-Control-Allow-Origin": "*",
- Authorization: `Bearer ${token}`
- }
- }
- )
- return await response.json().catch(() => null)
-}
\ No newline at end of file
+ const isPage = page ? `?page=${page}` : "";
+ const isSearch = search ? `&search=${search}` : "";
+ const response = await fetch(
+ `/api/admin/job/status/${name}${isPage}${isSearch}`,
+ {
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ "Access-Control-Allow-Origin": "*",
+ Authorization: `Bearer ${token}`,
+ },
+ }
+ );
+ return await response.json().catch(() => null);
+};
+
+const apiGetOneJobById = async ({ id }: { id: string }) => {
+ try {
+ // Fetch token from cookie
+ const { token } = await fetch("/api/get-cookie").then((res) => res.json());
+ if (!token) {
+ console.error("No token found");
+ return null;
+ }
+
+ const response = await fetch(`/api/admin/job/${id}`, {
+ method: "GET",
+ headers: {
+ "Content-Type": "application/json",
+ Accept: "application/json",
+ Authorization: `Bearer ${token}`,
+ },
+ });
+
+ // Check if the response is OK
+ if (!response.ok) {
+ const errorData = await response.json().catch(() => null);
+ console.error("Failed to get one job", response.statusText, errorData);
+ throw new Error(errorData?.message || "Failed to get one job");
+ }
+
+ // Return the JSON response
+ return await response.json();
+ } catch (error) {
+ console.error("Error get one job", error);
+ throw error; // Re-throw the error to handle it in the calling function
+ }
+};
diff --git a/src/app_modules/admin/job/main/index.tsx b/src/app_modules/admin/job/main/index.tsx
index 1cea0fdd..bf4f702c 100644
--- a/src/app_modules/admin/job/main/index.tsx
+++ b/src/app_modules/admin/job/main/index.tsx
@@ -13,17 +13,7 @@ import global_limit from "@/lib/limit";
import { useShallowEffect } from "@mantine/hooks";
import { apiGetJobArsipCount, apiGetJobStatusCountDashboard } from "../lib/api_fetch_admin_job";
-export default function AdminJob_Main({
- // countPublish,
- // countReview,
- // countReject,
- // countArsip,
-}: {
- // countPublish: number;
- // countReview: number;
- // countReject: number;
- // countArsip: number
- }) {
+export default function AdminJob_Main() {
const [countPublish, setCountPublish] = useState(null);
const [countReview, setCountReview] = useState(null);
const [countReject, setCountReject] = useState(null);