From 80b6d35fe949cd04b04e258f58961254f1e32c64 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Thu, 12 Dec 2024 14:44:51 +0800 Subject: [PATCH 1/2] chore(release): 1.2.25 --- CHANGELOG.md | 2 ++ package.json | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f6be3ff..309eb639 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. +## [1.2.25](https://github.com/bipproduction/hipmi/compare/v1.2.24...v1.2.25) (2024-12-12) + ## [1.2.24](https://github.com/bipproduction/hipmi/compare/v1.2.23...v1.2.24) (2024-12-11) diff --git a/package.json b/package.json index 06b12f78..73e48807 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hipmi", - "version": "1.2.24", + "version": "1.2.25", "private": true, "prisma": { "seed": "npx tsx prisma/seed.ts --yes" From d1f79661232f1816026f9d2d64dbcb495b5a11f2 Mon Sep 17 00:00:00 2001 From: Bagasbanuna02 Date: Thu, 12 Dec 2024 14:46:06 +0800 Subject: [PATCH 2/2] Fix Job Deskripsi: - Di beranda diganti menggunakan API - Skeleton beranda - V 1.2.25 --- src/app/api/job/get-all/route.ts | 16 ++ src/app/dev/job/main/beranda/page.tsx | 5 +- src/app/lib/api_user_router/route_api_job.ts | 4 + src/app/lib/prisma.ts | 2 + .../fun/upload/fun_upload_to_storage.ts | 26 ++- .../donasi/fun/get/fun_check_status.tsx | 1 - .../button/comp_button_save_create.tsx | 165 +++++++++--------- src/app_modules/job/component/index.ts | 2 + .../skeleton/comp_skeleton_beranda.tsx | 25 +++ src/app_modules/job/detail/main/view.tsx | 17 +- .../job/main/beranda/ui_beranda.tsx | 48 ++--- .../job/main/beranda/view_beranda.tsx | 4 +- .../button/comp_create_new_profile.tsx | 29 +-- .../katalog/profile/fun/fun_create_profile.ts | 76 ++++---- src/middleware.ts | 1 + 15 files changed, 253 insertions(+), 168 deletions(-) create mode 100644 src/app/api/job/get-all/route.ts create mode 100644 src/app/lib/api_user_router/route_api_job.ts create mode 100644 src/app_modules/job/component/skeleton/comp_skeleton_beranda.tsx diff --git a/src/app/api/job/get-all/route.ts b/src/app/api/job/get-all/route.ts new file mode 100644 index 00000000..21db076c --- /dev/null +++ b/src/app/api/job/get-all/route.ts @@ -0,0 +1,16 @@ +import { job_getAllListPublish } from "@/app_modules/job/fun/get/get_all_publish"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +export async function GET(params: Request) { + const { searchParams } = new URL(params.url); + const page = searchParams.get("page"); + const search = searchParams.get("search"); + + const data = await job_getAllListPublish({ + page: _.toNumber(page), + search: search as string, + }); + + return NextResponse.json({ data }); +} diff --git a/src/app/dev/job/main/beranda/page.tsx b/src/app/dev/job/main/beranda/page.tsx index 1a4bce82..c8cf14d0 100644 --- a/src/app/dev/job/main/beranda/page.tsx +++ b/src/app/dev/job/main/beranda/page.tsx @@ -1,12 +1,9 @@ import { Job_ViewBeranda } from "@/app_modules/job"; -import { job_getAllListPublish } from "@/app_modules/job/fun/get/get_all_publish"; export default async function Page() { - const listJob = await job_getAllListPublish({ page: 1 }); - return ( <> - + ); } diff --git a/src/app/lib/api_user_router/route_api_job.ts b/src/app/lib/api_user_router/route_api_job.ts new file mode 100644 index 00000000..66234665 --- /dev/null +++ b/src/app/lib/api_user_router/route_api_job.ts @@ -0,0 +1,4 @@ +export const API_RouteJob = { + get_all: ({ page, search }: { page: number; search?: string }) => + `/api/job/get-all?page=${page}&search=${search || ""}`, +}; diff --git a/src/app/lib/prisma.ts b/src/app/lib/prisma.ts index a0d1a749..25a08ef9 100644 --- a/src/app/lib/prisma.ts +++ b/src/app/lib/prisma.ts @@ -23,4 +23,6 @@ process.on('SIGINT', async () => { process.exit(0); }); +// console.log('==> Test prisma'); + export default prisma; diff --git a/src/app_modules/_global/fun/upload/fun_upload_to_storage.ts b/src/app_modules/_global/fun/upload/fun_upload_to_storage.ts index 52155b9b..06ed38f4 100644 --- a/src/app_modules/_global/fun/upload/fun_upload_to_storage.ts +++ b/src/app_modules/_global/fun/upload/fun_upload_to_storage.ts @@ -1,6 +1,4 @@ -import { ServerEnv } from "@/app/lib/server_env"; import { TokenStorage } from "@/app/lib/token"; -import { envs } from "@/lib/envs"; export async function funGlobal_UploadToStorage({ file, @@ -24,9 +22,19 @@ export async function funGlobal_UploadToStorage({ "text/plain", ]; - if (!allowedMimeTypes.includes(file.type)) console.log("File tidak sesuai"); + // if (!allowedMimeTypes.includes(file.type)) console.log("File tidak sesuai"); + if (!allowedMimeTypes.includes(file.type)) { + console.error("File tidak sesuai"); + return { success: false, message: "File type not allowed" }; + } - if (file.size > 100 * 1024 * 1024) console.log("File terlalu besar"); + if (file.size > 100 * 1024 * 1024) { + console.error("File terlalu besar"); + return { success: false, message: "File size exceeds limit" }; + } + + const controller = new AbortController(); + const timeoutId = setTimeout(() => controller.abort(), 30000); // Timeout 30 detik const formData = new FormData(); formData.append("file", file); @@ -39,19 +47,23 @@ export async function funGlobal_UploadToStorage({ headers: { Authorization: `Bearer ${Env_WS_APIKEY}`, }, + signal: controller.signal, }); - const dataRes = await res.json(); + clearTimeout(timeoutId); // Bersihkan timeout jika selesai tepat waktu if (res.ok) { + const dataRes = await res.json(); return { success: true, data: dataRes.data }; } else { const errorText = await res.text(); console.error("Error:", errorText); - return { success: false, data: {} }; + return { success: false, message: errorText }; } } catch (error) { + clearTimeout(timeoutId); // + console.error("Error:", error); - return { success: false, data: {} }; + return { success: false, message: "An unexpected error occurred" }; } } diff --git a/src/app_modules/donasi/fun/get/fun_check_status.tsx b/src/app_modules/donasi/fun/get/fun_check_status.tsx index 1b751153..2ff3fad7 100644 --- a/src/app_modules/donasi/fun/get/fun_check_status.tsx +++ b/src/app_modules/donasi/fun/get/fun_check_status.tsx @@ -9,7 +9,6 @@ export async function donasi_checkStatus({ id }: { id: string }) { }, }); - console.log(checkStatus?.donasiMaster_StatusDonasiId, "ini status nya") if (checkStatus?.donasiMaster_StatusDonasiId == "2") return true; return false; 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 00a5e2e2..ccbe263c 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 @@ -33,92 +33,101 @@ function Job_ComponentButtonSaveCreate({ const [hotMenu, setHotMenu] = useAtom(gs_job_hot_menu); async function onCreate() { - 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, + try { + setIsLoading(true); + if (file === null) { + const createNoFile = await job_funCreateNoFile({ + data: value, }); - if (notif.status === 201) { - WibuRealtime.setData({ - type: "notification", - pushNotificationTo: "ADMIN", + 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, }); - WibuRealtime.setData({ - type: "trigger", - pushNotificationTo: "ADMIN", - dataMessage: dataNotifikasi, - }); + if (notif.status === 201) { + WibuRealtime.setData({ + type: "notification", + pushNotificationTo: "ADMIN", + }); - setHotMenu(2); - router.replace(RouterJob.status({ id: "2" })); - setIsLoading(true); - ComponentGlobal_NotifikasiBerhasil(createNoFile.message); + WibuRealtime.setData({ + type: "trigger", + pushNotificationTo: "ADMIN", + dataMessage: dataNotifikasi, + }); + + setHotMenu(2); + router.replace(RouterJob.status({ id: "2" })); + ComponentGlobal_NotifikasiBerhasil(createNoFile.message); + } + } else { + ComponentGlobal_NotifikasiGagal(createNoFile.message); } } else { - ComponentGlobal_NotifikasiGagal(createNoFile.message); + const uploadFile = await funGlobal_UploadToStorage({ + file: file, + dirId: DIRECTORY_ID.job_image, + }); + + if (!uploadFile.success) { + 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 { + ComponentGlobal_NotifikasiGagal(createWithFile.message); + } } - } else { - const uploadFile = await funGlobal_UploadToStorage({ - file: file, - dirId: DIRECTORY_ID.job_image, - }); - - if (!uploadFile.success) - return ComponentGlobal_NotifikasiPeringatan("Gagal upload gambar"); - - 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" })); - setIsLoading(true); - ComponentGlobal_NotifikasiBerhasil(createWithFile.message); - } - } else { - ComponentGlobal_NotifikasiGagal(createWithFile.message); + } catch (error) { + console.log(error); + } finally { + if (window.location.pathname !== RouterJob.status({ id: "2" })) { + setIsLoading(false); } } } diff --git a/src/app_modules/job/component/index.ts b/src/app_modules/job/component/index.ts index 810f60b3..156a94cd 100644 --- a/src/app_modules/job/component/index.ts +++ b/src/app_modules/job/component/index.ts @@ -2,8 +2,10 @@ import Job_ComponentButtonSaveCreate from "./button/comp_button_save_create"; import { Job_ComponentButtonUpdateBeranda } from "./button/comp_button_update_beranda"; import { Job_ComponentButtonUpdateData } from "./button/comp_button_update_data"; import { Job_ComponentBoxUploadImage } from "./detail/comp_box_upload_image"; +import Job_ComponentSkeletonBeranda from "./skeleton/comp_skeleton_beranda"; export { Job_ComponentButtonSaveCreate }; export { Job_ComponentBoxUploadImage }; export { Job_ComponentButtonUpdateData as Job_ComponentButtonUpdate }; export { Job_ComponentButtonUpdateBeranda }; +export { Job_ComponentSkeletonBeranda }; diff --git a/src/app_modules/job/component/skeleton/comp_skeleton_beranda.tsx b/src/app_modules/job/component/skeleton/comp_skeleton_beranda.tsx new file mode 100644 index 00000000..7e773ed6 --- /dev/null +++ b/src/app_modules/job/component/skeleton/comp_skeleton_beranda.tsx @@ -0,0 +1,25 @@ +import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component"; +import { Box, Center, Group, Skeleton, Stack } from "@mantine/core"; + +export default function Job_ComponentSkeletonBeranda() { + return ( + <> + + {Array.from(new Array(10)).map((e, i) => ( + + + + + + + +
+ +
+
+
+ ))} +
+ + ); +} diff --git a/src/app_modules/job/detail/main/view.tsx b/src/app_modules/job/detail/main/view.tsx index a9e21aec..e2bcdf6d 100644 --- a/src/app_modules/job/detail/main/view.tsx +++ b/src/app_modules/job/detail/main/view.tsx @@ -24,19 +24,10 @@ function ButtonAction({ jobId }: { jobId: string }) { const [origin, setOrigin] = useState(""); useShallowEffect(() => { - onLoadOrigin(setOrigin); - // if (typeof window !== "undefined") { - // setOrigin(window.location.origin); - // } - - }, [setOrigin]); - - async function onLoadOrigin(setOrigin: any) { - const res = await fetch("/api/origin-url"); - const result = await res.json(); - console.log(result); - setOrigin(result.origin); - } + if (typeof window !== "undefined") { + setOrigin(window.location.origin); + } + }, []); return ( <> diff --git a/src/app_modules/job/main/beranda/ui_beranda.tsx b/src/app_modules/job/main/beranda/ui_beranda.tsx index 6b0a8505..0783e9f7 100644 --- a/src/app_modules/job/main/beranda/ui_beranda.tsx +++ b/src/app_modules/job/main/beranda/ui_beranda.tsx @@ -4,20 +4,24 @@ import { gs_jobTiggerBeranda } from "@/app/lib/global_state"; import { RouterJob } from "@/app/lib/router_hipmi/router_job"; import ComponentGlobal_CreateButton from "@/app_modules/_global/component/button_create"; import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; -import { Center, Loader, Stack, TextInput } from "@mantine/core"; +import { Box, Center, Loader, Stack, TextInput } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks"; import { IconSearch } from "@tabler/icons-react"; import { useAtom } from "jotai"; import _ from "lodash"; import { ScrollOnly } from "next-scroll-loader"; -import { useEffect, useState } from "react"; +import { useState } from "react"; +import { + Job_ComponentButtonUpdateBeranda, + Job_ComponentSkeletonBeranda, +} from "../../component"; import ComponentJob_BerandaCardView from "../../component/beranda/card_view"; import { job_getAllListPublish } from "../../fun/get/get_all_publish"; import { MODEL_JOB } from "../../model/interface"; -import { Job_ComponentButtonUpdateBeranda } from "../../component"; +import { API_RouteJob } from "@/app/lib/api_user_router/route_api_job"; -export function Job_UiBeranda({ listData }: { listData: MODEL_JOB[] }) { - const [data, setData] = useState(listData); +export function Job_UiBeranda() { + const [data, setData] = useState(null); const [activePage, setActivePage] = useState(1); const [isSearch, setIsSearch] = useState(""); @@ -26,19 +30,16 @@ export function Job_UiBeranda({ listData }: { listData: MODEL_JOB[] }) { const [isTriggerJob, setIsTriggerJob] = useAtom(gs_jobTiggerBeranda); useShallowEffect(() => { - onLoadNewData({ - onLoad(val) { - setData(val); - }, - }); - }, [setData]); + if (isTriggerJob == true) { + setIsShowUpdate(true); + } + }, [isTriggerJob]); useShallowEffect(() => { - if (isTriggerJob) { - setIsShowUpdate(true); - // setIsTriggerJob(false); - } - }, [isTriggerJob, setIsShowUpdate]); + setIsTriggerJob(false); + setIsShowUpdate(false); + onLoadNewData(); + }, []); async function onSearch(text: string) { setIsSearch(text); @@ -50,9 +51,11 @@ export function Job_UiBeranda({ listData }: { listData: MODEL_JOB[] }) { setActivePage(1); } - async function onLoadNewData({ onLoad }: { onLoad: (val: any) => void }) { - const loadData = await job_getAllListPublish({ page: 1 }); - onLoad(loadData); + async function onLoadNewData() { + const loadData = await fetch(API_RouteJob.get_all({ page: activePage })); + const res = await loadData.json(); + + setData(res.data); } return ( @@ -62,6 +65,7 @@ export function Job_UiBeranda({ listData }: { listData: MODEL_JOB[] }) { { setIsShowUpdate(val); + setIsTriggerJob(val); }} onSetData={(val: any[]) => { setData(val); @@ -85,7 +89,9 @@ export function Job_UiBeranda({ listData }: { listData: MODEL_JOB[] }) { }} /> - {_.isEmpty(data) ? ( + {_.isNull(data) ? ( + + ) : _.isEmpty(data) ? ( ) : ( // --- Main component --- // @@ -97,7 +103,7 @@ export function Job_UiBeranda({ listData }: { listData: MODEL_JOB[] }) { )} data={data} - setData={setData} + setData={setData as any} moreData={async () => { const loadData = await job_getAllListPublish({ page: activePage + 1, diff --git a/src/app_modules/job/main/beranda/view_beranda.tsx b/src/app_modules/job/main/beranda/view_beranda.tsx index c56f1feb..d6004905 100644 --- a/src/app_modules/job/main/beranda/view_beranda.tsx +++ b/src/app_modules/job/main/beranda/view_beranda.tsx @@ -1,10 +1,10 @@ import { MODEL_JOB } from "../../model/interface"; import { Job_UiBeranda } from "./ui_beranda"; -export default function Job_ViewBeranda({ listJob }: { listJob: MODEL_JOB[] }) { +export default function Job_ViewBeranda() { return ( <> - + ); } diff --git a/src/app_modules/katalog/profile/_component/button/comp_create_new_profile.tsx b/src/app_modules/katalog/profile/_component/button/comp_create_new_profile.tsx index d649d346..104afedf 100644 --- a/src/app_modules/katalog/profile/_component/button/comp_create_new_profile.tsx +++ b/src/app_modules/katalog/profile/_component/button/comp_create_new_profile.tsx @@ -56,10 +56,8 @@ export function Profile_ComponentCreateNewProfile({ dirId: DIRECTORY_ID.profile_foto, }); if (!uploadPhoto.success) { - setLoading(false); - return ComponentGlobal_NotifikasiPeringatan( - "Gagal upload foto profile" - ); + ComponentGlobal_NotifikasiPeringatan("Gagal upload foto profile"); + return; } const uploadBackground = await funGlobal_UploadToStorage({ @@ -67,10 +65,8 @@ export function Profile_ComponentCreateNewProfile({ dirId: DIRECTORY_ID.profile_background, }); if (!uploadBackground.success) { - setLoading(false); - return ComponentGlobal_NotifikasiPeringatan( - "Gagal upload background profile" - ); + ComponentGlobal_NotifikasiPeringatan("Gagal upload background profile"); + return; } const create = await funCreateNewProfile({ @@ -78,15 +74,24 @@ export function Profile_ComponentCreateNewProfile({ imageId: uploadPhoto.data.id, imageBackgroundId: uploadBackground.data.id, }); + if (create.status === 201) { ComponentGlobal_NotifikasiBerhasil("Berhasil membuat profile", 3000); router.push(RouterHome.main_home, { scroll: false }); - } else { - ComponentGlobal_NotifikasiGagal(create.message); - setLoading(false); } + + if (create.status === 400) { + ComponentGlobal_NotifikasiGagal(create.message); + } + + if (create.status === 500) { + ComponentGlobal_NotifikasiGagal(create.message); + } + } catch (error) { - console.log(error); + console.log("Terjadi kesalahan", error); + } finally { + setLoading(false); } } diff --git a/src/app_modules/katalog/profile/fun/fun_create_profile.ts b/src/app_modules/katalog/profile/fun/fun_create_profile.ts index eb49f756..ff8eb96d 100644 --- a/src/app_modules/katalog/profile/fun/fun_create_profile.ts +++ b/src/app_modules/katalog/profile/fun/fun_create_profile.ts @@ -1,14 +1,10 @@ "use server"; import prisma from "@/app/lib/prisma"; -import { MODEL_PROFILE } from "../model/interface"; -import _ from "lodash"; -import { v4 } from "uuid"; -import fs from "fs"; -import { revalidatePath } from "next/cache"; import { RouterHome } from "@/app/lib/router_hipmi/router_home"; -import { Prisma } from "@prisma/client"; import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; +import { Prisma } from "@prisma/client"; +import { revalidatePath } from "next/cache"; export default async function funCreateNewProfile({ data, @@ -19,33 +15,53 @@ export default async function funCreateNewProfile({ imageId: string; imageBackgroundId: string; }) { - const userLoginId = await funGetUserIdByToken(); + try { + const userLoginId = await funGetUserIdByToken(); - const findEmail = await prisma.profile.findUnique({ - where: { - email: data.email, - }, - }); + if (!userLoginId) { + return { status: 400, message: "User tidak terautentikasi" }; // Validasi user login + } - if (findEmail) return { status: 400, message: "Email telah digunakan" }; + const findEmail = await prisma.profile.findUnique({ + where: { + email: data.email, + }, + }); - const createProfile = await prisma.profile.create({ - data: { - userId: userLoginId, - name: data.name, - email: data.email, - alamat: data.alamat, - jenisKelamin: data.jenisKelamin, - imageId: imageId, - imageBackgroundId: imageBackgroundId, - }, - }); + if (findEmail) { + return { status: 400, message: "Email telah digunakan" }; + } - if (!createProfile) return { status: 400, message: "Gagal membuat profile" }; - revalidatePath(RouterHome.main_home); + const createProfile = await prisma.profile.create({ + data: { + userId: userLoginId, + name: data.name, + email: data.email, + alamat: data.alamat, + jenisKelamin: data.jenisKelamin, + imageId: imageId, + imageBackgroundId: imageBackgroundId, + }, + }); - return { - status: 201, - message: "Berhasil", - }; + if (!createProfile) { + return { status: 400, message: "Gagal membuat profile" }; + } + + // Revalidate cache halaman home + try { + revalidatePath(RouterHome.main_home); + } catch (cacheError) { + console.error("Cache revalidation failed:", cacheError); + // Tidak membuat fungsi gagal, cukup log error cache + } + + return { + status: 201, + message: "Berhasil", + }; + } catch (error) { + console.error("Error creating profile:", error); + return { status: 500, message: "Terjadi kesalahan pada server" }; + } } diff --git a/src/middleware.ts b/src/middleware.ts index f4cd23ab..705192f2 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -20,6 +20,7 @@ const middlewareConfig: MiddlewareConfig = { publicRoutes: [ "/", "/api/upload", + "/api/job/*", "/api/validation", "/api/auth/*", "/api/origin-url",