Update Versi 1.5.27 #32

Merged
bagasbanuna merged 1009 commits from staging into main 2025-12-17 12:22:28 +08:00
1438 changed files with 50134 additions and 14468 deletions
Showing only changes of commit f55d4c601f - Show all commits

View File

@@ -1,9 +1,52 @@
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export { GET };
async function GET(request: Request) {
return NextResponse.json({
success: true,
});
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 }
);
}
}

View File

@@ -1,12 +1,9 @@
import { Job_DetailArsip } from "@/app_modules/job";
import { job_getOneById } from "@/app_modules/job/fun/get/get_one_by_id";
import { Job_DetailArsip } from "@/app_modules/job";
export default async function Page({params}:{params: {id: string}}) {
let jobId = params.id
const dataJob = await job_getOneById(jobId)
export default async function Page() {
return (
<>
<Job_DetailArsip dataJob={dataJob as any} />
<Job_DetailArsip />
</>
);
}

View File

@@ -1,14 +1,11 @@
import Job_DetailDraft from "@/app_modules/job/detail/draft/view";
import { job_getOneById } from "@/app_modules/job/fun/get/get_one_by_id";
export default async function Page({params}: {params: {id: string}}) {
let jobId = params.id
const dataJob = await job_getOneById(jobId)
export default async function Page() {
return (
<>
<Job_DetailDraft dataJob={dataJob as any} jobId={jobId} />
<Job_DetailDraft />
</>
);
}

View File

@@ -1,13 +1,10 @@
import { Job_MainDetail } from "@/app_modules/job";
import { job_getOneById } from "@/app_modules/job/fun/get/get_one_by_id";
export default async function Page({ params }: { params: { id: string } }) {
const idJob = params.id;
const dataJob = await job_getOneById(idJob);
export default async function Page() {
return (
<>
<Job_MainDetail dataJob={dataJob as any} />
<Job_MainDetail />
</>
);
}

View File

@@ -1,13 +1,9 @@
import { Job_DetailPublish } from "@/app_modules/job";
import { job_getOneById } from "@/app_modules/job/fun/get/get_one_by_id";
export default async function Page({params}: {params: {id: string}}) {
let jobId = params.id
const dataJob = await job_getOneById(jobId)
export default async function Page() {
return (
<>
<Job_DetailPublish dataJob={dataJob as any} />
<Job_DetailPublish />
</>
);
}

View File

@@ -1,14 +1,11 @@
import Job_DetailReject from "@/app_modules/job/detail/reject/view";
import { job_getOneById } from "@/app_modules/job/fun/get/get_one_by_id";
export default async function Page({params}: {params: {id: string}}) {
let jobId = params.id
const dataJob = await job_getOneById(jobId)
export default async function Page() {
return (
<>
<Job_DetailReject dataJob={dataJob as any} />
<Job_DetailReject />
</>
);
}

View File

@@ -1,18 +1,9 @@
import Job_DetailReview from "@/app_modules/job/detail/review/view";
import { job_getOneById } from "@/app_modules/job/fun/get/get_one_by_id";
import React from "react";
export default async function Page({
params,
}: {
params: { id: React.ReactNode };
}) {
let jobId = params.id;
const dataJob = await job_getOneById(jobId)
export default async function Page() {
return (
<>
<Job_DetailReview dataJob={dataJob as any} />
<Job_DetailReview />
</>
);
}

View File

@@ -1,13 +1,11 @@
import { Job_Edit } from "@/app_modules/job";
import { job_getOneById } from "@/app_modules/job/fun/get/get_one_by_id";
export default async function Page({ params }: { params: { id: string } }) {
let jobId = params.id;
const dataJob = await job_getOneById(jobId);
export default async function Page() {
return (
<>
<Job_Edit dataJob={dataJob as any} />
<Job_Edit />
</>
);
}

View File

@@ -16,7 +16,15 @@ export default function Voting_ComponentSkeletonViewPuh() {
header={<UIGlobal_LayoutHeaderTamplate title="Skeleton Maker" />}
>
<Stack>
<Grid align="center">
<CustomSkeleton height={300} width={"100%"} />
<Center>
<CustomSkeleton height={40} radius={"xl"} width={"50%"} />
</Center>
<CustomSkeleton height={500} width={"100%"} />
<CustomSkeleton height={40} radius={"xl"} width={"100%"} />
</Stack>
{/* <Grid align="center">
<Grid.Col span={2}>
<CustomSkeleton height={40} width={40} circle />
</Grid.Col>
@@ -33,8 +41,7 @@ export default function Voting_ComponentSkeletonViewPuh() {
<Stack>
<CustomSkeleton height={20} width={"100%"} radius={"xl"} />
<CustomSkeleton height={20} width={"100%"} radius={"xl"} />
</Stack>
</Stack>
</Stack> */}
{/* <Stack spacing={"xl"} p={"sm"}>
{Array.from({ length: 4 }).map((_, i) => (

View File

@@ -1,4 +1,4 @@
export { apiGetJobByStatus, apiGetJob, apiGetJobArsip };
export { apiGetJobByStatus, apiGetJob, apiGetJobArsip, apiGetJobById };
const apiGetJobByStatus = async ({
status,
@@ -124,3 +124,40 @@ const apiGetJobArsip = async ({
throw error; // Re-throw the error to handle it in the calling function
}
};
const apiGetJobById = 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;
}
// Send PUT request to update portfolio logo
const response = await fetch(`/api/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(
"Error updating portfolio logo:",
errorData?.message || "Unknown error"
);
return null;
}
return await response.json();
} catch (error) {
console.error("Error updating portfolio logo:", error);
throw error; // Re-throw the error to handle it in the calling function
}
};

View File

@@ -4,14 +4,11 @@ import {
ComponentGlobal_CardStyles,
ComponentGlobal_LoadImage,
} from "@/app_modules/_global/component";
import { Box, Center, Skeleton, Stack, Text } from "@mantine/core";
import { Center, Stack, Text } from "@mantine/core";
import { MODEL_JOB } from "../../model/interface";
import { Job_SkeletonDetailJob } from "../skeleton/comp_skeleton_beranda";
export default function ComponentJob_DetailData({
data,
}: {
data?: MODEL_JOB;
}) {
export default function ComponentJob_DetailData({ data }: { data: MODEL_JOB }) {
return (
<>
{data ? (
@@ -39,24 +36,7 @@ export default function ComponentJob_DetailData({
</Stack>
</ComponentGlobal_CardStyles>
) : (
<ComponentGlobal_CardStyles>
<Stack spacing={"xl"}>
<Stack align="center">
<Skeleton h={250} w={200} radius="md" />
<Skeleton h={10} w={200} />
</Stack>
{Array.from(new Array(2)).map((e, i) => (
<Stack key={i}>
<Skeleton h={10} w={100} />
{Array.from({ length: 3 }).map((_, ii) => (
<Skeleton h={10} key={ii} />
))}
</Stack>
))}
</Stack>
</ComponentGlobal_CardStyles>
<Job_SkeletonDetailJob />
)}
</>
);

View File

@@ -2,7 +2,7 @@ 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";
import { Job_ComponentSkeletonBeranda } from "./skeleton/comp_skeleton_beranda";
export { Job_ComponentButtonSaveCreate };
export { Job_ComponentBoxUploadImage };

View File

@@ -1,8 +1,14 @@
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { Box, Center, Group, Skeleton, Stack } from "@mantine/core";
import { Box, Center, Group, Stack } from "@mantine/core";
export default function Job_ComponentSkeletonBeranda() {
export {
Job_ComponentSkeletonBeranda,
Job_SkeletonDetailJob,
Job_SkeletonEdit
};
function Job_ComponentSkeletonBeranda() {
return (
<>
<Box>
@@ -24,3 +30,43 @@ export default function Job_ComponentSkeletonBeranda() {
</>
);
}
function Job_SkeletonDetailJob() {
return (
<>
<ComponentGlobal_CardStyles>
<Stack spacing={"xl"}>
<Stack align="center">
<CustomSkeleton h={250} w={200} radius="md" />
<CustomSkeleton h={10} w={200} />
</Stack>
{Array.from(new Array(2)).map((e, i) => (
<Stack key={i}>
<CustomSkeleton h={10} w={100} />
{Array.from({ length: 3 }).map((_, ii) => (
<CustomSkeleton h={10} key={ii} />
))}
</Stack>
))}
</Stack>
</ComponentGlobal_CardStyles>
</>
);
}
function Job_SkeletonEdit() {
return (
<>
<Stack>
<CustomSkeleton height={300} width={"100%"} />
<Center>
<CustomSkeleton height={40} radius={"xl"} width={"50%"} />
</Center>
<CustomSkeleton height={500} width={"100%"} />
<CustomSkeleton height={40} radius={"xl"} width={"100%"} />
</Stack>
</>
);
}

View File

@@ -1,9 +1,9 @@
"use client";
import { Button, Stack } from "@mantine/core";
import { Button, Center, Stack } from "@mantine/core";
import ComponentJob_DetailData from "../../component/detail/detail_data";
import { MODEL_JOB } from "../../model/interface";
import { useRouter } from "next/navigation";
import { useParams, useRouter } from "next/navigation";
import { RouterJob } from "@/lib/router_hipmi/router_job";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
@@ -11,15 +11,49 @@ import { useAtom } from "jotai";
import { Job_funEditArsipById } from "../../fun/edit/fun_edit_arsip_by_id";
import { gs_job_hot_menu } from "../../global_state";
import { useState } from "react";
import { useDisclosure } from "@mantine/hooks";
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 CustomSkeleton from "@/app_modules/components/CustomSkeleton";
export default function Job_DetailArsip() {
const param = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_JOB | null>(null);
useShallowEffect(() => {
handleLoadData();
}, []);
const handleLoadData = async () => {
try {
const response = await apiGetJobById({
id: param.id,
});
if (response.success) {
setData(response.data);
} else {
setData(null);
}
} catch (error) {
clientLogger.error("Error get data job", error);
setData(null);
}
};
export default function Job_DetailArsip({ dataJob }: { dataJob: MODEL_JOB }) {
return (
<>
<Stack>
<ComponentJob_DetailData data={dataJob} />
<ButtonAction jobId={dataJob.id} />
<ComponentJob_DetailData data={data as any} />
{!data ? (
<Center>
<CustomSkeleton height={40} width={"50%"} radius={"xl"} />
</Center>
) : (
<ButtonAction jobId={param.id} />
)}
</Stack>
</>
);
@@ -74,18 +108,21 @@ function ButtonAction({ jobId }: { jobId: string }) {
}
/>
<Button
loaderPosition="center"
loading={isLoading ? true : false}
radius={"xl"}
color="green"
my={"lg"}
onClick={() => {
open();
}}
>
Publish Lagi
</Button>
<Center>
<Button
w="50%"
loaderPosition="center"
loading={isLoading ? true : false}
radius={"xl"}
color="green"
my={"lg"}
onClick={() => {
open();
}}
>
Publish Lagi
</Button>
</Center>
</>
);
}

View File

@@ -9,7 +9,7 @@ import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
import mqtt_client from "@/util/mqtt_client";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
import ComponentJob_DetailData from "../../component/detail/detail_data";
import { Job_funDeleteById } from "../../fun/delete/fun_delete_by_id";
@@ -20,33 +20,41 @@ import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/noti
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 CustomSkeleton from "@/app_modules/components/CustomSkeleton";
export default function Job_DetailDraft({
dataJob,
jobId,
}: {
dataJob: MODEL_JOB;
jobId: string;
}) {
const [data, setData] = useState<MODEL_JOB | null>(dataJob);
export default function Job_DetailDraft() {
const param = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_JOB | null>(null);
useShallowEffect(() => {
onLoadData({
loadData(val) {
setData(val);
},
});
}, [setData]);
handleLoadData();
}, []);
async function onLoadData({ loadData }: { loadData: (val: any) => void }) {
const dataJob = await job_getOneById(jobId);
loadData(dataJob as any);
}
const handleLoadData = async () => {
try {
const response = await apiGetJobById({
id: param.id,
});
if (response.success) {
setData(response.data);
} else {
setData(null);
}
} catch (error) {
clientLogger.error("Error get data job", error);
setData(null);
}
};
return (
<>
<Stack>
{data?.catatan ? (
{!data ? (
<CustomSkeleton height={50} />
) : data?.catatan ? (
<ComponentGlobal_BoxInformation
informasi={data?.catatan}
isReport={true}
@@ -55,7 +63,18 @@ export default function Job_DetailDraft({
""
)}
<ComponentJob_DetailData data={data as any} />
<ButtonAction jobId={data?.id as any} imageId={data?.imageId as any} />
{!data ? (
<Group grow>
<CustomSkeleton height={40} width={"50%"} radius={"xl"} />
<CustomSkeleton height={40} width={"50%"} radius={"xl"} />
</Group>
) : (
<ButtonAction
jobId={param.id as any}
imageId={data?.imageId as any}
/>
)}
</Stack>
</>
);

View File

@@ -1,20 +1,56 @@
"use client";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { RouterJob } from "@/lib/router_hipmi/router_job";
import { clientLogger } from "@/util/clientLogger";
import { Button, Center, Stack } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
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 ComponentJob_DetailData from "../../component/detail/detail_data";
import { MODEL_JOB } from "../../model/interface";
export default function Job_MainDetail({ dataJob }: { dataJob: MODEL_JOB }) {
export default function Job_MainDetail() {
const param = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_JOB | null>(null);
useShallowEffect(() => {
handleLoadData();
}, []);
const handleLoadData = async () => {
try {
const response = await apiGetJobById({
id: param.id,
});
if (response.success) {
setData(response.data);
} else {
setData(null);
}
} catch (error) {
clientLogger.error("Error get data job", error);
setData(null);
}
};
return (
<>
<Stack>
<ComponentJob_DetailData data={dataJob} />
<ButtonAction jobId={dataJob.id} />
<ComponentJob_DetailData data={data as any} />
{!data ? (
<Center>
<CustomSkeleton height={40} width={"50%"} radius={"xl"} />
</Center>
) : (
<ButtonAction jobId={param.id} />
)}
</Stack>
</>
);

View File

@@ -1,29 +1,62 @@
"use client";
import { RouterJob } from "@/lib/router_hipmi/router_job";
import {
AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { Button, Group, Modal, Paper, Stack, Title } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { RouterJob } from "@/lib/router_hipmi/router_job";
import { clientLogger } from "@/util/clientLogger";
import {
Button,
Center,
Stack
} from "@mantine/core";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { useAtom } from "jotai";
import { useRouter } from "next/navigation";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
import { apiGetJobById } from "../../component/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";
import { gs_job_hot_menu } from "../../global_state";
import { MODEL_JOB } from "../../model/interface";
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
export default function Job_DetailPublish({ dataJob }: { dataJob: MODEL_JOB }) {
export default function Job_DetailPublish() {
const param = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_JOB | null>(null);
useShallowEffect(() => {
handleLoadData();
}, []);
const handleLoadData = async () => {
try {
const response = await apiGetJobById({
id: param.id,
});
if (response.success) {
setData(response.data);
} else {
setData(null);
}
} catch (error) {
clientLogger.error("Error get data job", error);
setData(null);
}
};
return (
<>
<Stack>
<ComponentJob_DetailData data={dataJob as any} />
<ButtonAction jobId={dataJob.id} />
<ComponentJob_DetailData data={data as any} />
{!data ? (
<Center>
<CustomSkeleton height={40} width={"50%"} radius={"xl"} />
</Center>
) : (
<ButtonAction jobId={param.id} />
)}
</Stack>
</>
);
@@ -34,13 +67,11 @@ function ButtonAction({ jobId }: { jobId: string }) {
const [isLoading, setLoading] = useState(false);
const [opened, { open, close }] = useDisclosure();
const [hotMenu, setHotMenu] = useAtom(gs_job_hot_menu);
async function onArsipkan() {
await Job_funEditArsipById(jobId, true).then((res) => {
if (res.status === 200) {
setHotMenu(3);
ComponentGlobal_NotifikasiBerhasil("Berhasil Diarsipkan");
setLoading(true);
@@ -52,47 +83,6 @@ function ButtonAction({ jobId }: { jobId: string }) {
}
return (
<>
{/* <Modal
opened={opened}
onClose={close}
centered
withCloseButton={false}
styles={{
content: {
backgroundColor: MainColor.darkblue,
border: `2px solid ${AccentColor.blue}`,
},
}}
>
<Stack>
<Title order={6} color="white" align="center">
Mengarsipkan akan menghilangkan info lowongan kerja dari beranda,
anda yakin ?
</Title>
<Group grow>
<Button
radius={"xl"}
onClick={() => {
close();
}}
>
Batal
</Button>
<Button
loading={isLoading ? true : false}
loaderPosition="center"
radius={"xl"}
color="teal"
onClick={() => {
onArsipkan();
}}
>
Arsip
</Button>
</Group>
</Stack>
</Modal> */}
<UIGlobal_Modal
opened={opened}
close={() => close()}
@@ -122,16 +112,19 @@ function ButtonAction({ jobId }: { jobId: string }) {
}
/>
<Button
radius={"xl"}
color="teal"
my={"lg"}
onClick={() => {
open();
}}
>
Arsipkan
</Button>
<Center>
<Button
w="50%"
radius={"xl"}
color="teal"
my={"lg"}
onClick={() => {
open();
}}
>
Arsipkan
</Button>
</Center>
</>
);
}

View File

@@ -3,32 +3,71 @@
import { RouterJob } from "@/lib/router_hipmi/router_job";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { Button, Group, Stack } from "@mantine/core";
import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information";
import { funGlobal_DeleteFileById } from "@/app_modules/_global/fun";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
import { useDisclosure } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
import ComponentJob_DetailData from "../../component/detail/detail_data";
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 CustomSkeleton from "@/app_modules/components/CustomSkeleton";
export default function Job_DetailReject({ dataJob }: { dataJob: MODEL_JOB }) {
const [data, setData] = useState(dataJob);
export default function Job_DetailReject() {
const param = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_JOB | null>(null);
useShallowEffect(() => {
handleLoadData();
}, []);
const handleLoadData = async () => {
try {
const response = await apiGetJobById({
id: param.id,
});
if (response.success) {
setData(response.data);
} else {
setData(null);
}
} catch (error) {
clientLogger.error("Error get data job", error);
setData(null);
}
};
return (
<>
<Stack>
<ComponentGlobal_BoxInformation
informasi={data.catatan}
isReport={true}
/>
<ComponentJob_DetailData data={data} />
<ButtonAction jobId={data.id} imageId={data.imageId} />
{!data ? (
<CustomSkeleton height={50} />
) : (
<ComponentGlobal_BoxInformation
informasi={data.catatan}
isReport={true}
/>
)}
<ComponentJob_DetailData data={data as any} />
{!data ? (
<Group grow>
<CustomSkeleton height={40} width={"50%"} radius={"xl"} />
<CustomSkeleton height={40} width={"50%"} radius={"xl"} />
</Group>
) : (
<ButtonAction
jobId={param.id as any}
imageId={data?.imageId as any}
/>
)}
</Stack>
</>
);

View File

@@ -6,20 +6,53 @@ import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_glo
import UIGlobal_Modal from "@/app_modules/_global/ui/ui_modal";
import notifikasiToAdmin_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_admin";
import mqtt_client from "@/util/mqtt_client";
import { Button, Stack } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { useRouter } from "next/navigation";
import { Button, Center, Stack } from "@mantine/core";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
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 CustomSkeleton from "@/app_modules/components/CustomSkeleton";
export default function Job_DetailReview() {
const param = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_JOB | null>(null);
useShallowEffect(() => {
handleLoadData();
}, []);
const handleLoadData = async () => {
try {
const response = await apiGetJobById({
id: param.id,
});
if (response.success) {
setData(response.data);
} else {
setData(null);
}
} catch (error) {
clientLogger.error("Error get data job", error);
setData(null);
}
};
export default function Job_DetailReview({ dataJob }: { dataJob: MODEL_JOB }) {
return (
<>
<Stack>
<ComponentJob_DetailData data={dataJob} />
<ButtonAction jobId={dataJob.id} />
<ComponentJob_DetailData data={data as any} />
{!data ? (
<Center>
<CustomSkeleton height={40} width={"50%"} radius={"xl"} />
</Center>
) : (
<ButtonAction jobId={param.id} />
)}
</Stack>
</>
);
@@ -92,16 +125,19 @@ function ButtonAction({ jobId }: { jobId: string }) {
}
/>
<Button
radius={"xl"}
color="orange"
my={"xl"}
onClick={() => {
setOpen(true);
}}
>
Batalkan Review
</Button>
<Center>
<Button
w="50%"
radius={"xl"}
color="orange"
my={"xl"}
onClick={() => {
setOpen(true);
}}
>
Batalkan Review
</Button>
</Center>
</>
);
}

View File

@@ -22,6 +22,11 @@ import { IconPhoto } from "@tabler/icons-react";
import dynamic from "next/dynamic";
import "react-quill/dist/quill.snow.css";
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 { Job_SkeletonEdit } from "../component/skeleton/comp_skeleton_beranda";
const ReactQuill = dynamic(
() => {
return import("react-quill");
@@ -29,14 +34,35 @@ const ReactQuill = dynamic(
{ ssr: false }
);
export default function Job_Edit({ dataJob }: { dataJob: MODEL_JOB }) {
const [data, setData] = useState(dataJob);
export default function Job_Edit() {
const [file, setFile] = useState<File | null>(null);
const [img, setImg] = useState<any | null>();
// useShallowEffect(() => {
// if (window && window.document) setReload(true);
// }, []);
const param = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_JOB | null>(null);
useShallowEffect(() => {
handleLoadData();
}, []);
const handleLoadData = async () => {
try {
const response = await apiGetJobById({
id: param.id,
});
if (response.success) {
setData(response.data);
} else {
setData(null);
}
} catch (error) {
clientLogger.error("Error get data job", error);
setData(null);
}
};
if (!data) return <Job_SkeletonEdit />;
return (
<>

View File

@@ -6,32 +6,39 @@ import { revalidatePath } from "next/cache";
import { MODEL_JOB } from "../../model/interface";
export async function job_funCreateNoFile({ data }: { data: MODEL_JOB }) {
const authorId = await funGetUserIdByToken();
try {
const authorId = await funGetUserIdByToken();
const createNoImage = await prisma.job.create({
data: {
title: data.title,
content: data.content,
deskripsi: data.deskripsi,
authorId: authorId,
},
select: {
id: true,
authorId: true,
MasterStatus: {
select: {
name: true,
},
const createNoImage = await prisma.job.create({
data: {
title: data.title,
content: data.content,
deskripsi: data.deskripsi,
authorId: authorId,
},
title: true,
},
});
select: {
id: true,
authorId: true,
MasterStatus: {
select: {
name: true,
},
},
title: true,
},
});
if (!createNoImage) return { status: 400, message: "Gagal Disimpan" };
revalidatePath("/dev/job/main/status/2");
return {
status: 201,
message: "Berhasil Disimpan",
data: createNoImage,
};
if (!createNoImage) return { status: 400, message: "Gagal Disimpan" };
revalidatePath("/dev/job/main/status/2");
return {
status: 201,
message: "Berhasil Disimpan",
data: createNoImage,
};
} catch (error) {
return {
status: 500,
message: "Error create job",
};
}
}

View File

@@ -11,42 +11,46 @@ export async function job_EditById({
data: MODEL_JOB;
fileId?: string;
}) {
if (fileId == undefined) {
const updt = await prisma.job.update({
where: {
id: data.id,
},
data: {
title: data.title,
content: data.content,
deskripsi: data.deskripsi,
},
});
if (!updt) return { status: 400, message: "Gagal Update" };
revalidatePath("/dev/job/detail/draft");
try {
if (fileId == undefined) {
const updt = await prisma.job.update({
where: {
id: data.id,
},
data: {
title: data.title,
content: data.content,
deskripsi: data.deskripsi,
},
});
if (!updt) return { status: 400, message: "Gagal Update" };
revalidatePath("/dev/job/detail/draft");
return {
status: 200,
message: "Berhasil Update",
};
} else {
const updtWithFile = await prisma.job.update({
where: {
id: data.id,
},
data: {
title: data.title,
content: data.content,
deskripsi: data.deskripsi,
imageId: fileId,
},
});
if (!updtWithFile) return { status: 400, message: "Gagal Update" };
revalidatePath("/dev/job/detail/draft");
return {
status: 200,
message: "Berhasil Update",
};
} else {
const updtWithFile = await prisma.job.update({
where: {
id: data.id,
},
data: {
title: data.title,
content: data.content,
deskripsi: data.deskripsi,
imageId: fileId,
},
});
if (!updtWithFile) return { status: 400, message: "Gagal Update" };
revalidatePath("/dev/job/detail/draft");
return {
status: 200,
message: "Berhasil Update",
};
return {
status: 200,
message: "Berhasil Update",
};
}
} catch (error) {
return { status: 500, message: "Error Update" };
}
}

View File

@@ -1,21 +1,18 @@
"use client";
import { Box, Center, Stack } from "@mantine/core";
import { MODEL_JOB } from "../../model/interface";
import { Job_UI_Arsip } from "./ui_arsip";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { RouterJob } from "@/lib/router_hipmi/router_job";
import { clientLogger } from "@/util/clientLogger";
import { Box, Stack } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react";
import ComponentJob_CardStatus from "../../component/card/card_view";
import { job_getAllArsipById } from "../../fun/get/get_all_arsip";
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
import { clientLogger } from "@/util/clientLogger";
import { useShallowEffect } from "@mantine/hooks";
import { apiGetJob, apiGetJobArsip } from "../../component/api_fetch_job";
import { Job_ComponentSkeletonBeranda } from "../../component";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import ComponentJob_CardStatus from "../../component/card/card_view";
import { MODEL_JOB } from "../../model/interface";
export default function Job_ViewArsip() {
const [data, setData] = useState<MODEL_JOB[]>([]);