From f5d9242daa75b37ed1175b54785d0c218717652e Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Wed, 19 Mar 2025 14:08:23 +0800 Subject: [PATCH] fix admin job - fix table publish" --- src/app/api/admin/job/[id]/route.ts | 53 +++++++ src/app/dev/admin/job/[id]/[status]/page.tsx | 11 ++ src/app/dev/admin/job/main/page.tsx | 26 +--- .../_component/button/detail_button.tsx | 28 ++++ .../_component/comp_admin_boxstyle.tsx | 26 ++++ .../admin/job/_components/detail_status.tsx | 78 ++++++++++ src/app_modules/admin/job/_view/detail.tsx | 54 +++++++ .../admin/job/child/publish/index.tsx | 113 +++++++------- .../admin/job/lib/api_fetch_admin_job.ts | 145 +++++++++++------- src/app_modules/admin/job/main/index.tsx | 12 +- 10 files changed, 403 insertions(+), 143 deletions(-) create mode 100644 src/app/api/admin/job/[id]/route.ts create mode 100644 src/app/dev/admin/job/[id]/[status]/page.tsx create mode 100644 src/app_modules/admin/_admin_global/_component/button/detail_button.tsx create mode 100644 src/app_modules/admin/_admin_global/_component/comp_admin_boxstyle.tsx create mode 100644 src/app_modules/admin/job/_components/detail_status.tsx create mode 100644 src/app_modules/admin/job/_view/detail.tsx 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 ( + <> + + + ); +} 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() { ) : ( - - + +
- 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);
@@ -215,16 +217,13 @@ function TableStatus() {
Status
- Judul +
Judul
Poster
- Syarat Ketentuan - - Deskripsi +
Aksi