From c94ecd8f9c0f87761900e62d96e307b7ec291d24 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Thu, 27 Mar 2025 15:37:44 +0800 Subject: [PATCH] fix job deskripsi: - fix server action to API notification to admin - fix api created job --- src/app/api/job/route.ts | 71 ++++++- src/app/api/notifications/to-admin/route.ts | 72 +++++++ src/app/api/season/route.ts | 65 +++++++ src/app/dev/job/create/page.tsx | 5 +- .../_global/lib/api_fetch_global.ts | 72 ++++++- .../button/comp_button_save_create.tsx | 182 ++++++++++++++---- src/app_modules/job/create/view.tsx | 8 +- src/app_modules/job/detail/arsip/view.tsx | 2 +- src/app_modules/job/detail/draft/view.tsx | 2 +- src/app_modules/job/detail/main/view.tsx | 2 +- src/app_modules/job/detail/publish/view.tsx | 2 +- src/app_modules/job/detail/reject/view.tsx | 2 +- src/app_modules/job/detail/review/view.tsx | 2 +- src/app_modules/job/edit/view.tsx | 2 +- .../job/{component => lib}/api_fetch_job.ts | 41 +++- src/app_modules/job/main/arsip/view_arsip.tsx | 2 +- .../job/main/beranda/view_beranda.tsx | 2 +- src/app_modules/job/main/status/publish.tsx | 2 +- src/app_modules/job/main/status/review.tsx | 2 +- .../job/main/status/view_status.tsx | 2 +- 20 files changed, 482 insertions(+), 58 deletions(-) create mode 100644 src/app/api/notifications/to-admin/route.ts create mode 100644 src/app/api/season/route.ts rename src/app_modules/job/{component => lib}/api_fetch_job.ts (79%) diff --git a/src/app/api/job/route.ts b/src/app/api/job/route.ts index 61b1acb6..031ba4e7 100644 --- a/src/app/api/job/route.ts +++ b/src/app/api/job/route.ts @@ -1,8 +1,6 @@ +import { prisma } from "@/lib"; import backendLogger from "@/util/backendLogger"; import { NextResponse } from "next/server"; -import { prisma } from "@/lib"; -export const dynamic = "force-dynamic"; - export async function GET(request: Request) { try { @@ -10,7 +8,7 @@ export async function GET(request: Request) { const { searchParams } = new URL(request.url); const search = searchParams.get("search"); const page = searchParams.get("page"); - const dataTake = 10 + const dataTake = 10; const dataSkip = Number(page) * dataTake - dataTake; if (!page) { @@ -83,3 +81,68 @@ export async function GET(request: Request) { }); } } + +export async function POST(request: Request) { + if (request.method !== "POST") { + return NextResponse.json( + { + success: false, + message: "Method not allowed", + }, + { status: 405 } + ); + } + + try { + const { data } = await request.json(); + + const fixData = await prisma.job.create({ + data: { + title: data.title, + content: data.content, + deskripsi: data.deskripsi, + authorId: data.authorId, + imageId: data.imageId ?? null, + }, + select: { + id: true, + authorId: true, + MasterStatus: { + select: { + name: true, + }, + }, + title: true, + }, + }); + + if (!fixData) { + return NextResponse.json( + { + success: false, + message: "Failed created job", + }, + { status: 400 } + ); + } + + return NextResponse.json( + { + success: true, + message: "Success created job", + data: fixData, + }, + { status: 201 } + ); + } catch (error) { + console.log("Error created job", error); + return NextResponse.json( + { + success: false, + message: "Error created job", + error: (error as Error).message || error, + }, + { status: 500 } + ); + } +} diff --git a/src/app/api/notifications/to-admin/route.ts b/src/app/api/notifications/to-admin/route.ts new file mode 100644 index 00000000..bd1e921f --- /dev/null +++ b/src/app/api/notifications/to-admin/route.ts @@ -0,0 +1,72 @@ +import { NextResponse } from "next/server"; +import {prisma} from "@/lib" + +interface NotificationData { + userId: string; + appId: string; + status: string; + title: string; + pesan: string; + kategoriApp: string; +} + +export async function POST(request: Request) { + try { + const { data }: { data: NotificationData } = await request.json(); + + // Validasi input + if (!data || !data.userId || !data.title || !data.pesan) { + return NextResponse.json( + { + success: false, + message: "Missing required fields", + }, + { status: 400 } + ); + } + + // Ambil semua admin aktif + const getAdmin = await prisma.user.findMany({ + where: { + active: true, + masterUserRoleId: "2", + }, + }); + + // Buat notifikasi untuk semua admin secara paralel + const createPromises = getAdmin.map((a) => + prisma.notifikasi.create({ + data: { + adminId: a.id, + userId: data.userId, + appId: data.appId, + status: data.status, + title: data.title, + pesan: data.pesan, + kategoriApp: data.kategoriApp, + userRoleId: "2", + }, + }) + ); + + await Promise.all(createPromises); + + return NextResponse.json( + { + success: true, + message: "Successfully created notifications for admins", + }, + { status: 201 } + ); + } catch (error) { + console.error("Error creating notification for admin:", error); + return NextResponse.json( + { + success: false, + message: "Error creating notification for admin", + error: (error as Error).message || "Unknown error", + }, + { status: 500 } + ); + } +} diff --git a/src/app/api/season/route.ts b/src/app/api/season/route.ts new file mode 100644 index 00000000..6eb04b61 --- /dev/null +++ b/src/app/api/season/route.ts @@ -0,0 +1,65 @@ +import { NextResponse } from "next/server"; +import { decrypt } from "../../../app/(auth)/_lib/decrypt"; +import { cookies } from "next/headers"; +export const dynamic = "force-dynamic"; + + +interface DecryptedUser { + id: string; + [key: string]: any; +} + +export async function GET(request: Request) { + const SESSION_KEY = process.env.NEXT_PUBLIC_BASE_SESSION_KEY; + const TOKEN_KEY = process.env.NEXT_PUBLIC_BASE_TOKEN_KEY; + + if (!SESSION_KEY || !TOKEN_KEY) { + return NextResponse.json( + { success: false, message: "Server configuration error" }, + { status: 500 } + ); + } + + try { + const cookieStore = cookies(); + const sessionCookie = cookieStore.get(SESSION_KEY); + + if (!sessionCookie || !sessionCookie.value) { + return NextResponse.json( + { success: false, message: "Unauthorized: No session found" }, + { status: 401 } + ); + } + + const cekUser = (await decrypt({ + token: sessionCookie.value, + encodedKey: TOKEN_KEY, + })) as DecryptedUser | null; + + if (!cekUser || !cekUser.id) { + return NextResponse.json( + { success: false, message: "Unauthorized: Invalid session" }, + { status: 401 } + ); + } + + return NextResponse.json( + { + success: true, + message: "User session retrieved successfully", + data: { id: cekUser.id }, + }, + { status: 200 } + ); + } catch (error) { + console.error("Error retrieving user session:", error); + return NextResponse.json( + { + success: false, + message: "Error retrieving user session", + error: (error as Error).message || "Unknown error", + }, + { status: 500 } + ); + } +} diff --git a/src/app/dev/job/create/page.tsx b/src/app/dev/job/create/page.tsx index 94c001b8..aac0feab 100644 --- a/src/app/dev/job/create/page.tsx +++ b/src/app/dev/job/create/page.tsx @@ -1,9 +1,12 @@ +import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; import { Job_Create } from "@/app_modules/job"; export default async function Page() { + const userLoginId = await funGetUserIdByToken(); + return ( <> - + ); } diff --git a/src/app_modules/_global/lib/api_fetch_global.ts b/src/app_modules/_global/lib/api_fetch_global.ts index 00a7cf12..992f4326 100644 --- a/src/app_modules/_global/lib/api_fetch_global.ts +++ b/src/app_modules/_global/lib/api_fetch_global.ts @@ -1,4 +1,4 @@ -export { apiGetPdfToImage }; +export { apiGetPdfToImage, apiCreatedNotificationToAdmin, apiGetSeasonUserId }; export interface PageData { imageUrl: string; @@ -35,10 +35,7 @@ const apiGetPdfToImage = async ({ id }: { id: string }) => { // Check if the response is OK if (!response.ok) { const errorData = await response.json().catch(() => null); - console.error( - "Failed get file", - errorData?.message || "Unknown error" - ); + console.error("Failed get file", errorData?.message || "Unknown error"); return null; } @@ -50,3 +47,68 @@ const apiGetPdfToImage = async ({ id }: { id: string }) => { throw error; // Re-throw the error to handle it in the calling function } }; + +const apiCreatedNotificationToAdmin = async ({ data }: { data: any }) => { + try { + 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/notifications/to-admin`, { + method: "POST", + body: JSON.stringify({ data }), + 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 created notifications", + response.statusText, + errorData + ); + throw new Error(errorData?.message || "Failed to created notifications"); + } + + // Return the JSON response + return await response.json(); + } catch (error) { + console.error("Error to created notifications", error); + throw error; // Re-throw the error to handle it in the calling function + } +}; + +const apiGetSeasonUserId = async () => { + try { + const response = await fetch(`/api/season`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Accept: "application/json", + }, + }); + + // Check if the response is OK + if (!response.ok) { + const errorData = await response.json().catch(() => null); + console.error( + "Failed to created notifications", + response.statusText, + errorData + ); + throw new Error(errorData?.message || "Failed to created notifications"); + } + + return await response.json(); + } catch (error) { + console.error("Error get user id", error); + throw error; // Re-throw the error to handle it in the calling function + } +}; diff --git a/src/app_modules/job/component/button/comp_button_save_create.tsx b/src/app_modules/job/component/button/comp_button_save_create.tsx index 3844160f..8a43f5ad 100644 --- a/src/app_modules/job/component/button/comp_button_save_create.tsx +++ b/src/app_modules/job/component/button/comp_button_save_create.tsx @@ -20,41 +20,157 @@ import { WibuRealtime } from "wibu-pkg"; import { job_funCreateNoFile, job_funCreateWithFile } from "../../fun"; import { gs_job_hot_menu } from "../../global_state"; import { MODEL_JOB } from "../../model/interface"; +import { apiCreatedJob } from "../../lib/api_fetch_job"; +import { + apiCreatedNotificationToAdmin, + apiGetSeasonUserId, +} from "@/app_modules/_global/lib/api_fetch_global"; +import { useShallowEffect } from "@mantine/hooks"; +import { apiGetUserId } from "@/app_modules/_global/lib/api_user"; function Job_ComponentButtonSaveCreate({ value, file, + userLoginId, }: { value: MODEL_JOB; file: File; + userLoginId: string; }) { const router = useRouter(); const [isLoading, setIsLoading] = useState(false); const [hotMenu, setHotMenu] = useAtom(gs_job_hot_menu); - async function onCreate() { + // async function onCreate() { + // try { + // setIsLoading(true); + // if (file === null) { + // const createNoFile = await job_funCreateNoFile({ + // data: value, + // }); + + // if (createNoFile.status === 201) { + // const dataNotifikasi: IRealtimeData = { + // appId: createNoFile.data?.id as any, + // status: createNoFile.data?.MasterStatus?.name as any, + // userId: createNoFile.data?.authorId as any, + // pesan: createNoFile.data?.title as any, + // kategoriApp: "JOB", + // title: "Job baru", + // }; + + // const notif = await notifikasiToAdmin_funCreate({ + // data: dataNotifikasi as any, + // }); + + // if (notif.status === 201) { + // WibuRealtime.setData({ + // type: "notification", + // pushNotificationTo: "ADMIN", + // }); + + // WibuRealtime.setData({ + // type: "trigger", + // pushNotificationTo: "ADMIN", + // dataMessage: dataNotifikasi, + // }); + + // setHotMenu(2); + // router.replace(RouterJob.status({ id: "2" })); + // ComponentGlobal_NotifikasiBerhasil(createNoFile.message); + // } + // } else { + // setIsLoading(false); + + // ComponentGlobal_NotifikasiGagal(createNoFile.message); + // } + // } else { + // const uploadFile = await funGlobal_UploadToStorage({ + // file: file, + // dirId: DIRECTORY_ID.job_image, + // }); + + // if (!uploadFile.success) { + // setIsLoading(false); + // ComponentGlobal_NotifikasiPeringatan("Gagal upload gambar"); + // return; + // } + + // const createWithFile = await job_funCreateWithFile({ + // data: value, + // fileId: uploadFile.data.id, + // }); + + // if (createWithFile.status === 201) { + // const dataNotifikasi: IRealtimeData = { + // appId: createWithFile.data?.id as any, + // status: createWithFile.data?.MasterStatus?.name as any, + // userId: createWithFile.data?.authorId as any, + // pesan: createWithFile.data?.title as any, + // kategoriApp: "JOB", + // title: "Job baru", + // }; + + // const notif = await notifikasiToAdmin_funCreate({ + // data: dataNotifikasi as any, + // }); + + // if (notif.status === 201) { + // WibuRealtime.setData({ + // type: "notification", + // pushNotificationTo: "ADMIN", + // }); + + // WibuRealtime.setData({ + // type: "trigger", + // pushNotificationTo: "ADMIN", + // dataMessage: dataNotifikasi, + // }); + + // setHotMenu(2); + // router.replace(RouterJob.status({ id: "2" })); + // ComponentGlobal_NotifikasiBerhasil(createWithFile.message); + // } + // } else { + // setIsLoading(false); + // ComponentGlobal_NotifikasiGagal(createWithFile.message); + // } + // } + // } catch (error) { + // setIsLoading(false); + // clientLogger.error("Error create job", error); + // } + // } + + async function handleCreated() { try { + let fixData; setIsLoading(true); + if (file === null) { - const createNoFile = await job_funCreateNoFile({ - data: value, + fixData = { + ...value, + authorId: userLoginId, + }; + const responseNoFile = await apiCreatedJob({ + data: fixData, }); - if (createNoFile.status === 201) { + if (responseNoFile) { const dataNotifikasi: IRealtimeData = { - appId: createNoFile.data?.id as any, - status: createNoFile.data?.MasterStatus?.name as any, - userId: createNoFile.data?.authorId as any, - pesan: createNoFile.data?.title as any, + appId: responseNoFile.data?.id as any, + status: responseNoFile.data?.MasterStatus?.name as any, + userId: responseNoFile.data?.authorId as any, + pesan: responseNoFile.data?.title as any, kategoriApp: "JOB", title: "Job baru", }; - const notif = await notifikasiToAdmin_funCreate({ - data: dataNotifikasi as any, + const responseNotification = await apiCreatedNotificationToAdmin({ + data: dataNotifikasi, }); - if (notif.status === 201) { + if (responseNotification) { WibuRealtime.setData({ type: "notification", pushNotificationTo: "ADMIN", @@ -68,13 +184,13 @@ function Job_ComponentButtonSaveCreate({ setHotMenu(2); router.replace(RouterJob.status({ id: "2" })); - ComponentGlobal_NotifikasiBerhasil(createNoFile.message); + ComponentGlobal_NotifikasiBerhasil(responseNoFile.message); } - } else { - setIsLoading(false); - - ComponentGlobal_NotifikasiGagal(createNoFile.message); - } + } + // else { + // setIsLoading(false); + // ComponentGlobal_NotifikasiGagal(responseNoFile.message); + // } } else { const uploadFile = await funGlobal_UploadToStorage({ file: file, @@ -87,17 +203,22 @@ function Job_ComponentButtonSaveCreate({ return; } - const createWithFile = await job_funCreateWithFile({ - data: value, - fileId: uploadFile.data.id, + fixData = { + ...value, + authorId: userLoginId, + imageId: uploadFile.data.id, + }; + + const responseWithFile = await apiCreatedJob({ + data: fixData, }); - if (createWithFile.status === 201) { + if (responseWithFile.status === 201) { const dataNotifikasi: IRealtimeData = { - appId: createWithFile.data?.id as any, - status: createWithFile.data?.MasterStatus?.name as any, - userId: createWithFile.data?.authorId as any, - pesan: createWithFile.data?.title as any, + appId: responseWithFile.data?.id as any, + status: responseWithFile.data?.MasterStatus?.name as any, + userId: responseWithFile.data?.authorId as any, + pesan: responseWithFile.data?.title as any, kategoriApp: "JOB", title: "Job baru", }; @@ -120,12 +241,9 @@ function Job_ComponentButtonSaveCreate({ setHotMenu(2); router.replace(RouterJob.status({ id: "2" })); - ComponentGlobal_NotifikasiBerhasil(createWithFile.message); + ComponentGlobal_NotifikasiBerhasil(responseWithFile.message); } - } else { - setIsLoading(false); - ComponentGlobal_NotifikasiGagal(createWithFile.message); - } + } } } catch (error) { setIsLoading(false); @@ -169,9 +287,7 @@ function Job_ComponentButtonSaveCreate({ loading={isLoading ? true : false} w={"100%"} radius={"xl"} - onClick={() => { - onCreate(); - }} + onClick={handleCreated} > Simpan diff --git a/src/app_modules/job/create/view.tsx b/src/app_modules/job/create/view.tsx index 1a7858d2..bd52ca7c 100644 --- a/src/app_modules/job/create/view.tsx +++ b/src/app_modules/job/create/view.tsx @@ -29,7 +29,7 @@ import { import { Job_ComponentButtonSaveCreate } from "../component"; import { defaultDeskripsi, defaultSyarat } from "../component/default_value"; -export default function Job_Create() { +export default function Job_Create({userLoginId}: {userLoginId: string}) { const [value, setValue] = useState({ title: "", content: "", @@ -174,7 +174,11 @@ export default function Job_Create() { - + ); } diff --git a/src/app_modules/job/detail/arsip/view.tsx b/src/app_modules/job/detail/arsip/view.tsx index d53c9aec..1fcdde35 100644 --- a/src/app_modules/job/detail/arsip/view.tsx +++ b/src/app_modules/job/detail/arsip/view.tsx @@ -14,7 +14,7 @@ import { useState } from "react"; import { useDisclosure, useShallowEffect } from "@mantine/hooks"; import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal"; import { clientLogger } from "@/util/clientLogger"; -import { apiGetJobById } from "../../component/api_fetch_job"; +import { apiGetJobById } from "../../lib/api_fetch_job"; import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; export default function Job_DetailArsip() { diff --git a/src/app_modules/job/detail/draft/view.tsx b/src/app_modules/job/detail/draft/view.tsx index 31d567c9..c0e10791 100644 --- a/src/app_modules/job/detail/draft/view.tsx +++ b/src/app_modules/job/detail/draft/view.tsx @@ -21,7 +21,7 @@ import { job_getOneById } from "../../fun/get/get_one_by_id"; import { IRealtimeData } from "@/lib/global_state"; import { WibuRealtime } from "wibu-pkg"; import { clientLogger } from "@/util/clientLogger"; -import { apiGetJobById } from "../../component/api_fetch_job"; +import { apiGetJobById } from "../../lib/api_fetch_job"; import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; export default function Job_DetailDraft() { diff --git a/src/app_modules/job/detail/main/view.tsx b/src/app_modules/job/detail/main/view.tsx index a2bd8b0b..9d315e5a 100644 --- a/src/app_modules/job/detail/main/view.tsx +++ b/src/app_modules/job/detail/main/view.tsx @@ -9,7 +9,7 @@ import { IconBrandWhatsapp } from "@tabler/icons-react"; import Link from "next/link"; import { useParams } from "next/navigation"; import { useState } from "react"; -import { apiGetJobById } from "../../component/api_fetch_job"; +import { apiGetJobById } from "../../lib/api_fetch_job"; import ComponentJob_DetailData from "../../component/detail/detail_data"; import { MODEL_JOB } from "../../model/interface"; diff --git a/src/app_modules/job/detail/publish/view.tsx b/src/app_modules/job/detail/publish/view.tsx index 022c7eb6..96d121f6 100644 --- a/src/app_modules/job/detail/publish/view.tsx +++ b/src/app_modules/job/detail/publish/view.tsx @@ -15,7 +15,7 @@ import { useDisclosure, useShallowEffect } from "@mantine/hooks"; import { useAtom } from "jotai"; import { useParams, useRouter } from "next/navigation"; import { useState } from "react"; -import { apiGetJobById } from "../../component/api_fetch_job"; +import { apiGetJobById } from "../../lib/api_fetch_job"; import ComponentJob_DetailData from "../../component/detail/detail_data"; import { Job_funEditArsipById } from "../../fun/edit/fun_edit_arsip_by_id"; import { gs_job_hot_menu } from "../../global_state"; diff --git a/src/app_modules/job/detail/reject/view.tsx b/src/app_modules/job/detail/reject/view.tsx index 24ec238e..15774317 100644 --- a/src/app_modules/job/detail/reject/view.tsx +++ b/src/app_modules/job/detail/reject/view.tsx @@ -16,7 +16,7 @@ import { Job_funDeleteById } from "../../fun/delete/fun_delete_by_id"; import { Job_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_status_id"; import { MODEL_JOB } from "../../model/interface"; import { clientLogger } from "@/util/clientLogger"; -import { apiGetJobById } from "../../component/api_fetch_job"; +import { apiGetJobById } from "../../lib/api_fetch_job"; import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; export default function Job_DetailReject() { diff --git a/src/app_modules/job/detail/review/view.tsx b/src/app_modules/job/detail/review/view.tsx index a2536984..c358dfcd 100644 --- a/src/app_modules/job/detail/review/view.tsx +++ b/src/app_modules/job/detail/review/view.tsx @@ -14,7 +14,7 @@ import ComponentJob_DetailData from "../../component/detail/detail_data"; import { Job_funEditStatusByStatusId } from "../../fun/edit/fun_edit_status_by_status_id"; import { MODEL_JOB } from "../../model/interface"; import { clientLogger } from "@/util/clientLogger"; -import { apiGetJobById } from "../../component/api_fetch_job"; +import { apiGetJobById } from "../../lib/api_fetch_job"; import CustomSkeleton from "@/app_modules/components/CustomSkeleton"; export default function Job_DetailReview() { diff --git a/src/app_modules/job/edit/view.tsx b/src/app_modules/job/edit/view.tsx index 2b76dad9..2e16b729 100644 --- a/src/app_modules/job/edit/view.tsx +++ b/src/app_modules/job/edit/view.tsx @@ -25,7 +25,7 @@ import { Job_ComponentButtonUpdate } from "../component"; import { clientLogger } from "@/util/clientLogger"; import { useShallowEffect } from "@mantine/hooks"; import { useParams } from "next/navigation"; -import { apiGetJobById } from "../component/api_fetch_job"; +import { apiGetJobById } from "../lib/api_fetch_job"; import { Job_SkeletonEdit } from "../component/skeleton/comp_skeleton_beranda"; const ReactQuill = dynamic( () => { diff --git a/src/app_modules/job/component/api_fetch_job.ts b/src/app_modules/job/lib/api_fetch_job.ts similarity index 79% rename from src/app_modules/job/component/api_fetch_job.ts rename to src/app_modules/job/lib/api_fetch_job.ts index 2da05b40..8e4e61fb 100644 --- a/src/app_modules/job/component/api_fetch_job.ts +++ b/src/app_modules/job/lib/api_fetch_job.ts @@ -1,4 +1,10 @@ -export { apiGetJob, apiGetJobArsip, apiGetJobById, apiGetJobByStatus }; +export { + apiGetJob, + apiGetJobArsip, + apiGetJobById, + apiGetJobByStatus, + apiCreatedJob, +}; const apiGetJobByStatus = async ({ status, @@ -166,3 +172,36 @@ const apiGetJobById = async ({ id }: { id: string }) => { throw error; // Re-throw the error to handle it in the calling function } }; + + +const apiCreatedJob = async ({ data }: { data: any }) => { + try { + 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/job`, { + method: "POST", + body: JSON.stringify({ data }), + 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 created job", response.statusText, errorData); + throw new Error(errorData?.message || "Failed created job"); + } + + // Return the JSON response + return await response.json(); + } catch (error) { + console.error("Error created job", error); + throw error; // Re-throw the error to handle it in the calling function + } +}; diff --git a/src/app_modules/job/main/arsip/view_arsip.tsx b/src/app_modules/job/main/arsip/view_arsip.tsx index b7c47a7f..773a444a 100644 --- a/src/app_modules/job/main/arsip/view_arsip.tsx +++ b/src/app_modules/job/main/arsip/view_arsip.tsx @@ -10,7 +10,7 @@ import { useShallowEffect } from "@mantine/hooks"; import _ from "lodash"; import { ScrollOnly } from "next-scroll-loader"; import { useState } from "react"; -import { apiGetJob, apiGetJobArsip } from "../../component/api_fetch_job"; +import { apiGetJob, apiGetJobArsip } from "../../lib/api_fetch_job"; import ComponentJob_CardStatus from "../../component/card/card_view"; import { MODEL_JOB } from "../../model/interface"; diff --git a/src/app_modules/job/main/beranda/view_beranda.tsx b/src/app_modules/job/main/beranda/view_beranda.tsx index 0198f402..2b9bc61c 100644 --- a/src/app_modules/job/main/beranda/view_beranda.tsx +++ b/src/app_modules/job/main/beranda/view_beranda.tsx @@ -16,7 +16,7 @@ import { Job_ComponentButtonUpdateBeranda, Job_ComponentSkeletonBeranda, } from "../../component"; -import { apiGetJob } from "../../component/api_fetch_job"; +import { apiGetJob } from "../../lib/api_fetch_job"; import ComponentJob_BerandaCardView from "../../component/beranda/card_view"; import { MODEL_JOB } from "../../model/interface"; diff --git a/src/app_modules/job/main/status/publish.tsx b/src/app_modules/job/main/status/publish.tsx index 8656ee28..ae95154c 100644 --- a/src/app_modules/job/main/status/publish.tsx +++ b/src/app_modules/job/main/status/publish.tsx @@ -9,7 +9,7 @@ import { useState } from "react"; import ComponentJob_CardStatus from "../../component/card/card_view"; import job_getAllStatusPublish from "../../fun/get/status/get_list_publish"; import { useShallowEffect } from "@mantine/hooks"; -import { apiGetJobByStatus } from "../../component/api_fetch_job"; +import { apiGetJobByStatus } from "../../lib/api_fetch_job"; export default function Job_Publish({ nameStatus }: { nameStatus: string }) { const [data, setData] = useState(null); diff --git a/src/app_modules/job/main/status/review.tsx b/src/app_modules/job/main/status/review.tsx index 6821804a..d3647ffc 100644 --- a/src/app_modules/job/main/status/review.tsx +++ b/src/app_modules/job/main/status/review.tsx @@ -9,7 +9,7 @@ import { useState } from "react"; import ComponentJob_CardStatus from "../../component/card/card_view"; import job_getAllStatusReview from "../../fun/get/status/get_list_review"; import { useShallowEffect } from "@mantine/hooks"; -import { apiGetJobByStatus } from "../../component/api_fetch_job"; +import { apiGetJobByStatus } from "../../lib/api_fetch_job"; export default function Job_Review({ nameStatus }: { nameStatus: string }) { const [data, setData] = useState(null); diff --git a/src/app_modules/job/main/status/view_status.tsx b/src/app_modules/job/main/status/view_status.tsx index 57133f60..6c290fd9 100644 --- a/src/app_modules/job/main/status/view_status.tsx +++ b/src/app_modules/job/main/status/view_status.tsx @@ -11,7 +11,7 @@ import _ from "lodash"; import { ScrollOnly } from "next-scroll-loader"; import { useParams } from "next/navigation"; import { useState } from "react"; -import { apiGetJobByStatus } from "../../component/api_fetch_job"; +import { apiGetJobByStatus } from "../../lib/api_fetch_job"; import ComponentJob_CardStatus from "../../component/card/card_view"; export default function Job_NewViewStatus() {