fix ( upload image )

deskripsi:
- perbaiki fungsi upload dan delete image di job
This commit is contained in:
2025-01-13 14:57:15 +08:00
parent 7cb3864aaa
commit 40d69ffc99
16 changed files with 149 additions and 282 deletions

View File

@@ -3,18 +3,18 @@ import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import sharp from "sharp"; import sharp from "sharp";
export async function POST(request: Request) { export async function POST(request: Request) {
let fixFormData;
const formData = await request.formData(); const formData = await request.formData();
const file: any = formData.get("file");
const mimeType = file.type;
console.log("MIME Type:", mimeType);
const valueOfDir = formData.get("dirId"); const valueOfDir = formData.get("dirId");
const keyOfDirectory = await funGetDirectoryNameByValue({ const keyOfDirectory = await funGetDirectoryNameByValue({
value: valueOfDir as string, value: valueOfDir as string,
}); });
if (request.method === "POST") { if (request.method === "POST") {
let fixFormData;
const file: any = formData.get("file");
const mimeType = file.type;
// console.log("MIME Type:", mimeType);
try { try {
if (mimeType != "application/pdf") { if (mimeType != "application/pdf") {
// Resize ukuran // Resize ukuran

View File

@@ -1,9 +1,6 @@
import { DIRECTORY_ID, prisma } from "@/app/lib"; import { prisma } from "@/app/lib";
import { NextResponse } from "next/server";
import fs from "fs";
import { funGlobal_DeleteFileById } from "@/app_modules/_global/fun";
import { apiDeleteImageById } from "@/app_modules/_global/lib/api_image";
import backendLogger from "@/util/backendLogger"; import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic"; export const dynamic = "force-dynamic";
// GET ONE DATA PORTOFOLIO BY ID PORTOFOLIO // GET ONE DATA PORTOFOLIO BY ID PORTOFOLIO

View File

@@ -20,8 +20,8 @@ if (process.env.NODE_ENV !== "production") {
} }
process.on("SIGINT", async () => { process.on("SIGINT", async () => {
console.log("Disconnecting PrismaClient..."); // console.log("Disconnecting PrismaClient...");
await prisma.$disconnect();3 await prisma.$disconnect();
process.exit(0); process.exit(0);
}); });

View File

@@ -1,52 +0,0 @@
"use server";
import _ from "lodash";
// import { v4 } from "uuid";
import fs from "fs";
import sharp from "sharp";
export default async function fun_upload({
file,
dirId,
}: {
file: File;
dirId: string;
}) {
// const file: any = formData.get("file");
// const fName = file.name;
// const fileSize = file.size;
// // Convert ke KB
// const fileSizeInKB = fileSize / 1024;
// // Convert ke MB
// const fileSizeInMB = fileSize / (1024 * 1024);
// console.log(`Ukuran file dalam bytes: ${fileSize}`);
// console.log(`Ukuran file dalam KB: ${fileSizeInKB.toFixed(2)} KB`);
// console.log(`Ukuran file dalam MB: ${fileSizeInMB.toFixed(2)} MB`);
const imageBuffer = await file.arrayBuffer();
const resize = await sharp(imageBuffer).resize(2000).toBuffer();
const newFile = Buffer.from(resize);
console.log("file new",newFile);
// fs.writeFileSync(`./public/upload/${fName}`, upFolder as any);
const formData = new FormData();
formData.append("file", file);
formData.append("dirId", dirId);
// const upload = await fetch("/api/image/upload", {
// method: "POST",
// body: formData,
// });
// const res = await upload.json();
// if (upload.ok) {
// return { success: true, data: res.data, message: res.message };
// } else {
// return { success: false, data: {}, message: res.message };
// }
}

View File

@@ -2,9 +2,7 @@
import { MainColor } from "@/app_modules/_global/color"; import { MainColor } from "@/app_modules/_global/color";
import { ComponentGlobal_BoxUploadImage } from "@/app_modules/_global/component"; import { ComponentGlobal_BoxUploadImage } from "@/app_modules/_global/component";
import { MAX_SIZE } from "@/app_modules/_global/lib"; import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun";
import { PemberitahuanMaksimalFile } from "@/app_modules/_global/lib/max_size";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
import { import {
UIGlobal_LayoutHeaderTamplate, UIGlobal_LayoutHeaderTamplate,
UIGlobal_LayoutTamplate, UIGlobal_LayoutTamplate,
@@ -20,8 +18,6 @@ import {
} from "@mantine/core"; } from "@mantine/core";
import { IconImageInPicture, IconUpload } from "@tabler/icons-react"; import { IconImageInPicture, IconUpload } from "@tabler/icons-react";
import { useState } from "react"; import { useState } from "react";
import fun_upload from "./fun_upload";
import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun";
export default function Page() { export default function Page() {
return ( return (

View File

@@ -2,15 +2,16 @@
import { clientLogger } from "@/util/clientLogger"; import { clientLogger } from "@/util/clientLogger";
import { Button, FileButton } from "@mantine/core"; import { Button, FileButton } from "@mantine/core";
import { IconCamera } from "@tabler/icons-react"; import { IconUpload } from "@tabler/icons-react";
import { useState } from "react"; import { useState } from "react";
import { MainColor } from "../color"; import { AccentColor, MainColor } from "../color";
import { ComponentGlobal_NotifikasiPeringatan } from "../notif_global";
export function ComponentGlobal_ButtonUploadFileImage({ export function ComponentGlobal_ButtonUploadFileImage({
onSetFile, onSetFile,
onSetImage, onSetImage,
}: { }: {
onSetFile: File | any; onSetFile: File | null | any;
onSetImage: any | null; onSetImage: any | null;
}) { }) {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
@@ -24,11 +25,11 @@ export function ComponentGlobal_ButtonUploadFileImage({
new Blob([new Uint8Array(await files.arrayBuffer())]) new Blob([new Uint8Array(await files.arrayBuffer())])
); );
// if (files.size > MAX_SIZE) { if (files.size > 100 * 1024 * 1024) {
// ComponentGlobal_NotifikasiPeringatan(PemberitahuanMaksimalFile); setIsLoading(false);
// return; ComponentGlobal_NotifikasiPeringatan("File terlalu besar");
// } else { }
// }
onSetFile(files); onSetFile(files);
onSetImage(buffer); onSetImage(buffer);
setIsLoading(false); setIsLoading(false);
@@ -37,7 +38,7 @@ export function ComponentGlobal_ButtonUploadFileImage({
clientLogger.error("Upload error:", error); clientLogger.error("Upload error:", error);
} }
}} }}
accept="image/png,image/jpeg" accept="image/png,image/png,image/jpeg,image/gif"
> >
{(props) => ( {(props) => (
<Button <Button
@@ -45,10 +46,12 @@ export function ComponentGlobal_ButtonUploadFileImage({
loading={isLoading} loading={isLoading}
loaderPosition="center" loaderPosition="center"
radius={"xl"} radius={"xl"}
leftIcon={<IconCamera />} style={{
bg={MainColor.yellow} backgroundColor: MainColor.yellow,
color="yellow" border: `1px solid ${AccentColor.yellow}`,
c={"black"} }}
leftIcon={<IconUpload color="black" size={20} />}
c={MainColor.darkblue}
> >
Upload Upload
</Button> </Button>

View File

@@ -1,6 +1,6 @@
import { clientLogger } from "@/util/clientLogger"; import { clientLogger } from "@/util/clientLogger";
export async function funGlobal_DeleteFileById({ export async function funDeteleteFileById({
fileId, fileId,
dirId, dirId,
}: { }: {
@@ -8,9 +8,23 @@ export async function funGlobal_DeleteFileById({
dirId?: string; dirId?: string;
}) { }) {
try { try {
const tokenResponse = await fetch("/api/get-cookie");
if (!tokenResponse.ok) {
throw new Error("Failed to get token");
}
const { token } = await tokenResponse.json();
if (!token) {
return { success: false, message: "Token not found" };
}
const res = await fetch("/api/image/delete", { const res = await fetch("/api/image/delete", {
method: "DELETE", method: "DELETE",
body: JSON.stringify({ fileId, dirId }), body: JSON.stringify({ fileId, dirId }),
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
}); });
const data = await res.json(); const data = await res.json();

View File

@@ -1,7 +1,7 @@
import { funGlobal_DeleteFileById } from "./delete/fun_delete_file_by_id"; import { funDeteleteFileById } from "./delete/fun_delete_file_by_id";
import { funGlobal_UploadToStorage } from "./upload/fun_upload_to_storage"; import { funUploadFileToStorage } from "./upload/fun_upload_to_storage";
import { funValidasiUploadCreatedFile } from "./upload/fun_validasi_upload_created_file"; import { funValidasiUploadCreatedFile } from "./upload/fun_validasi_upload_created_file";
export { funGlobal_UploadToStorage }; export { funUploadFileToStorage as funGlobal_UploadToStorage };
export { funGlobal_DeleteFileById }; export { funDeteleteFileById as funGlobal_DeleteFileById };
export { funValidasiUploadCreatedFile }; export { funValidasiUploadCreatedFile };

View File

@@ -1,55 +1,40 @@
import { TokenStorage } from "@/app/lib/token"; export async function funUploadFileToStorage({
export async function funGlobal_UploadToStorage({
file, file,
dirId, dirId,
}: { }: {
file: File; file: File;
dirId: string; dirId: string;
}) { }) {
const Env_WS_APIKEY = TokenStorage.value; try {
const tokenResponse = await fetch("/api/get-cookie");
if (!tokenResponse.ok) {
throw new Error("Failed to get token");
}
const { token } = await tokenResponse.json();
const allowedMimeTypes = [ if (!token) {
"image/heif", // Format HEIF standar return { success: false, message: "Token not found" };
"image/heic", // Format HEIF untuk container HEIC }
"image/heif-sequence", // Untuk sequence/animasi HEIF
"image/heic-sequence", // Untuk sequence/animasi HEIC
"image/png",
"image/jpeg",
"image/gif",
"text/csv",
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"text/plain",
];
// if (!allowedMimeTypes.includes(file.type)) console.log("File tidak sesuai"); const formData = new FormData();
if (!allowedMimeTypes.includes(file.type)) { formData.append("file", file);
console.error("File tidak sesuai"); formData.append("dirId", dirId);
return { success: false, message: "File type not allowed" };
}
if (file.size > 100 * 1024 * 1024) { const upload = await fetch("/api/image/upload", {
console.error("File terlalu besar"); method: "POST",
return { success: false, message: "File size exceeds limit" }; body: formData,
} headers: {
const formData = new FormData(); Authorization: `Bearer ${token}`,
formData.append("file", file); },
formData.append("dirId", dirId); });
const upload = await fetch("/api/image/upload", { const res = await upload.json();
method: "POST",
body: formData,
});
const res = await upload.json(); return upload.ok
? { success: true, data: res.data, message: res.message }
if (upload.ok) { : { success: false, data: {}, message: res.message };
return { success: true, data: res.data, message: res.message }; } catch (error) {
} else { console.log(error);
return { success: false, data: {}, message: res.message }; return { success: false, message: "An unexpected error occurred" };
} }
} }

View File

@@ -2,8 +2,8 @@ import { clientLogger } from "@/util/clientLogger";
import { MAX_SIZE } from "../../lib"; import { MAX_SIZE } from "../../lib";
import { PemberitahuanMaksimalFile } from "../../lib/max_size"; import { PemberitahuanMaksimalFile } from "../../lib/max_size";
import { ComponentGlobal_NotifikasiPeringatan } from "../../notif_global"; import { ComponentGlobal_NotifikasiPeringatan } from "../../notif_global";
import { funGlobal_DeleteFileById } from "../delete/fun_delete_file_by_id"; import { funDeteleteFileById } from "../delete/fun_delete_file_by_id";
import { funGlobal_UploadToStorage } from "./fun_upload_to_storage"; import { funUploadFileToStorage } from "./fun_upload_to_storage";
export async function funValidasiUploadCreatedFile({ export async function funValidasiUploadCreatedFile({
files, files,
@@ -31,7 +31,7 @@ export async function funValidasiUploadCreatedFile({
} }
if (fileId != "") { if (fileId != "") {
const deleteFotoProfile = await funGlobal_DeleteFileById({ const deleteFotoProfile = await funDeteleteFileById({
fileId: fileId, fileId: fileId,
dirId: dirId, dirId: dirId,
}); });
@@ -49,7 +49,7 @@ export async function funValidasiUploadCreatedFile({
onSetFileId(""); onSetFileId("");
onSetImageBuffer(null); onSetImageBuffer(null);
const uploadPhoto = await funGlobal_UploadToStorage({ const uploadPhoto = await funUploadFileToStorage({
file: files, file: files,
dirId: dirId, dirId: dirId,
}); });
@@ -73,7 +73,7 @@ export async function funValidasiUploadCreatedFile({
} }
} }
} else { } else {
const uploadPhoto = await funGlobal_UploadToStorage({ const uploadPhoto = await funUploadFileToStorage({
file: files, file: files,
dirId: dirId, dirId: dirId,
}); });

View File

@@ -1,16 +0,0 @@
export const apiDeleteImageById = async ({
fileId,
dirId,
}: {
fileId: string;
dirId?: string;
}) => {
const response = await fetch(`/api/image/delete`, {
method: "DELETE",
body: JSON.stringify({ fileId, dirId }),
});
console.log("delete api =>", await response.json());
return await response.json().catch(() => null);
};

View File

@@ -11,6 +11,7 @@ import {
ComponentGlobal_NotifikasiPeringatan, ComponentGlobal_NotifikasiPeringatan,
} from "@/app_modules/_global/notif_global"; } from "@/app_modules/_global/notif_global";
import { notifikasiToAdmin_funCreate } from "@/app_modules/notifikasi/fun"; import { notifikasiToAdmin_funCreate } from "@/app_modules/notifikasi/fun";
import { clientLogger } from "@/util/clientLogger";
import { Button } from "@mantine/core"; import { Button } from "@mantine/core";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
@@ -19,7 +20,6 @@ import { WibuRealtime } from "wibu-pkg";
import { job_funCreateNoFile, job_funCreateWithFile } from "../../fun"; import { job_funCreateNoFile, job_funCreateWithFile } from "../../fun";
import { gs_job_hot_menu } from "../../global_state"; import { gs_job_hot_menu } from "../../global_state";
import { MODEL_JOB } from "../../model/interface"; import { MODEL_JOB } from "../../model/interface";
import { envs } from "@/lib/envs";
function Job_ComponentButtonSaveCreate({ function Job_ComponentButtonSaveCreate({
value, value,
@@ -71,6 +71,8 @@ function Job_ComponentButtonSaveCreate({
ComponentGlobal_NotifikasiBerhasil(createNoFile.message); ComponentGlobal_NotifikasiBerhasil(createNoFile.message);
} }
} else { } else {
setIsLoading(false);
ComponentGlobal_NotifikasiGagal(createNoFile.message); ComponentGlobal_NotifikasiGagal(createNoFile.message);
} }
} else { } else {
@@ -80,6 +82,7 @@ function Job_ComponentButtonSaveCreate({
}); });
if (!uploadFile.success) { if (!uploadFile.success) {
setIsLoading(false);
ComponentGlobal_NotifikasiPeringatan("Gagal upload gambar"); ComponentGlobal_NotifikasiPeringatan("Gagal upload gambar");
return; return;
} }
@@ -120,15 +123,13 @@ function Job_ComponentButtonSaveCreate({
ComponentGlobal_NotifikasiBerhasil(createWithFile.message); ComponentGlobal_NotifikasiBerhasil(createWithFile.message);
} }
} else { } else {
setIsLoading(false);
ComponentGlobal_NotifikasiGagal(createWithFile.message); ComponentGlobal_NotifikasiGagal(createWithFile.message);
} }
} }
} catch (error) { } catch (error) {
console.log(error); setIsLoading(false);
} finally { clientLogger.error("Error create job", error);
if (window.location.pathname !== RouterJob.status({ id: "2" })) {
setIsLoading(false);
}
} }
} }

View File

@@ -17,6 +17,7 @@ import { useState } from "react";
import { job_EditById } from "../../fun/edit/fun_edit_by_id"; import { job_EditById } from "../../fun/edit/fun_edit_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 { MODEL_JOB } from "../../model/interface";
import { clientLogger } from "@/util/clientLogger";
export function Job_ComponentButtonUpdateData({ export function Job_ComponentButtonUpdateData({
value, value,
@@ -32,41 +33,56 @@ export function Job_ComponentButtonUpdateData({
const [opened, { open, close }] = useDisclosure(false); const [opened, { open, close }] = useDisclosure(false);
async function onUpdate() { async function onUpdate() {
if (file === null) { try {
const update = await job_EditById({ setIsLoading(true);
data: value,
});
if (update.status !== 200)
return ComponentGlobal_NotifikasiGagal(update.message);
} else {
const uploadFile = await funGlobal_UploadToStorage({
file: file,
dirId: DIRECTORY_ID.job_image,
});
if (!uploadFile.success) if (file === null) {
return ComponentGlobal_NotifikasiPeringatan("Gagal upload gambar"); const update = await job_EditById({
data: value,
if (value.imageId !== null) {
const delFile = await funGlobal_DeleteFileById({
fileId: value.imageId,
}); });
if (!delFile.success) if (update.status !== 200)
ComponentGlobal_NotifikasiPeringatan("Gagal hapus gambar lama"); return ComponentGlobal_NotifikasiGagal(update.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;
}
if (value.imageId !== null) {
const delFile = await funGlobal_DeleteFileById({
fileId: value.imageId,
});
if (!delFile.success) {
clientLogger.error("Error delete file:", delFile.message);
}
}
const updateWithFile = await job_EditById({
data: value,
fileId: uploadFile.data.id,
});
if (updateWithFile.status !== 200) {
setIsLoading(false);
ComponentGlobal_NotifikasiGagal(updateWithFile.message);
return;
}
} }
const updateWithFile = await job_EditById({ setHotMenu(2);
data: value, ComponentGlobal_NotifikasiBerhasil("Berhasil Update");
fileId: uploadFile.data.id, router.back();
}); } catch (error) {
if (updateWithFile.status !== 200) setIsLoading(false);
return ComponentGlobal_NotifikasiGagal(updateWithFile.message); clientLogger.error("Error update job:", error);
ComponentGlobal_NotifikasiGagal("Gagal update job");
} }
setHotMenu(2);
setIsLoading(true);
router.back();
return ComponentGlobal_NotifikasiBerhasil("Berhasil Update");
} }
return ( return (

View File

@@ -2,15 +2,13 @@
import { import {
AspectRatio, AspectRatio,
Button,
Center, Center,
FileButton,
Image, Image,
Stack, Stack,
Text, Text,
TextInput, TextInput,
} from "@mantine/core"; } from "@mantine/core";
import { IconCamera, IconUpload } from "@tabler/icons-react"; import { IconPhoto } from "@tabler/icons-react";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import { useState } from "react"; import { useState } from "react";
import "react-quill/dist/quill.snow.css"; import "react-quill/dist/quill.snow.css";
@@ -21,22 +19,15 @@ const ReactQuill = dynamic(
{ ssr: false } { ssr: false }
); );
import {
AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import { import {
ComponentGlobal_BoxInformation, ComponentGlobal_BoxInformation,
ComponentGlobal_BoxUploadImage, ComponentGlobal_BoxUploadImage,
ComponentGlobal_ButtonUploadFileImage,
ComponentGlobal_CardStyles, ComponentGlobal_CardStyles,
ComponentGlobal_InputCountDown, ComponentGlobal_InputCountDown,
} from "@/app_modules/_global/component"; } from "@/app_modules/_global/component";
import { Job_ComponentButtonSaveCreate } from "../component"; import { Job_ComponentButtonSaveCreate } from "../component";
import { defaultDeskripsi, defaultSyarat } from "../component/default_value"; import { defaultDeskripsi, defaultSyarat } from "../component/default_value";
import { MAX_SIZE } from "@/app_modules/_global/lib";
import { PemberitahuanMaksimalFile } from "@/app_modules/_global/lib/max_size";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global";
export default function Job_Create() { export default function Job_Create() {
const [value, setValue] = useState({ const [value, setValue] = useState({
@@ -55,7 +46,7 @@ export default function Job_Create() {
<Stack> <Stack>
<ComponentGlobal_BoxInformation informasi="Poster atau gambar lowongan kerja bersifat opsional, tidak wajib untuk dimasukkan dan upload lah gambar yang sesuai dengan deskripsi lowongan kerja. " /> <ComponentGlobal_BoxInformation informasi="Poster atau gambar lowongan kerja bersifat opsional, tidak wajib untuk dimasukkan dan upload lah gambar yang sesuai dengan deskripsi lowongan kerja. " />
<Stack spacing={"xs"}> <Stack spacing={0}>
<ComponentGlobal_BoxUploadImage> <ComponentGlobal_BoxUploadImage>
{img ? ( {img ? (
<AspectRatio ratio={1 / 1} mah={265} mx={"auto"}> <AspectRatio ratio={1 / 1} mah={265} mx={"auto"}>
@@ -68,53 +59,16 @@ export default function Job_Create() {
</AspectRatio> </AspectRatio>
) : ( ) : (
<Stack justify="center" align="center" h={"100%"}> <Stack justify="center" align="center" h={"100%"}>
<IconUpload color="white" /> <IconPhoto size={100} />
<Text fz={10} fs={"italic"} c={"white"} fw={"bold"}>
Upload Gambar
</Text>
</Stack> </Stack>
)} )}
</ComponentGlobal_BoxUploadImage> </ComponentGlobal_BoxUploadImage>
<Center> <Center>
<FileButton <ComponentGlobal_ButtonUploadFileImage
onChange={async (files: any | null) => { onSetFile={setFile}
try { onSetImage={setImg}
const buffer = URL.createObjectURL( />
new Blob([new Uint8Array(await files.arrayBuffer())])
);
if (files.size > MAX_SIZE) {
ComponentGlobal_NotifikasiPeringatan(
PemberitahuanMaksimalFile
);
setImg(null);
return;
}
setImg(buffer);
setFile(files);
} catch (error) {
console.log(error);
}
}}
accept="image/png,image/jpeg"
>
{(props) => (
<Button
{...props}
radius={"xl"}
w={100}
style={{
backgroundColor: MainColor.yellow,
border: `1px solid ${AccentColor.yellow}`,
}}
>
<IconCamera color="black" />
</Button>
)}
</FileButton>
</Center> </Center>
</Stack> </Stack>

View File

@@ -10,28 +10,25 @@ import {
Text, Text,
TextInput, TextInput,
} from "@mantine/core"; } from "@mantine/core";
import { IconCamera, IconUpload } from "@tabler/icons-react"; import { IconCamera } from "@tabler/icons-react";
import { useState } from "react"; import { useState } from "react";
import { MODEL_JOB } from "../model/interface"; import { MODEL_JOB } from "../model/interface";
import { APIs } from "@/app/lib";
import { import {
AccentColor, AccentColor,
MainColor, MainColor,
} from "@/app_modules/_global/color/color_pallet"; } from "@/app_modules/_global/color/color_pallet";
import { import {
ComponentGlobal_BoxUploadImage, ComponentGlobal_BoxUploadImage,
ComponentGlobal_ButtonUploadFileImage,
ComponentGlobal_CardStyles, ComponentGlobal_CardStyles,
ComponentGlobal_LoadImage, ComponentGlobal_LoadImage,
ComponentGlobal_LoadImageCustom,
} from "@/app_modules/_global/component"; } from "@/app_modules/_global/component";
import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown"; import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/input_countdown";
import { IconPhoto } from "@tabler/icons-react";
import dynamic from "next/dynamic"; import dynamic from "next/dynamic";
import "react-quill/dist/quill.snow.css"; import "react-quill/dist/quill.snow.css";
import { import { Job_ComponentButtonUpdate } from "../component";
Job_ComponentBoxUploadImage,
Job_ComponentButtonUpdate,
} from "../component";
const ReactQuill = dynamic( const ReactQuill = dynamic(
() => { () => {
return import("react-quill"); return import("react-quill");
@@ -51,7 +48,7 @@ export default function Job_Edit({ dataJob }: { dataJob: MODEL_JOB }) {
return ( return (
<> <>
<Stack> <Stack>
<Stack spacing={"xs"}> <Stack spacing={0}>
<ComponentGlobal_BoxUploadImage> <ComponentGlobal_BoxUploadImage>
{img ? ( {img ? (
<AspectRatio ratio={1 / 1} mt={5} maw={300} mx={"auto"}> <AspectRatio ratio={1 / 1} mt={5} maw={300} mx={"auto"}>
@@ -66,44 +63,16 @@ export default function Job_Edit({ dataJob }: { dataJob: MODEL_JOB }) {
<ComponentGlobal_LoadImage fileId={data.imageId} /> <ComponentGlobal_LoadImage fileId={data.imageId} />
) : ( ) : (
<Stack justify="center" align="center" h={"100%"}> <Stack justify="center" align="center" h={"100%"}>
<IconUpload color="white" /> <IconPhoto size={100} />
<Text fz={10} fs={"italic"} c={"white"} fw={"bold"}>
Upload Gambar
</Text>
</Stack> </Stack>
)} )}
</ComponentGlobal_BoxUploadImage> </ComponentGlobal_BoxUploadImage>
<Center> <Center>
<FileButton <ComponentGlobal_ButtonUploadFileImage
onChange={async (files: any | null) => { onSetFile={setFile}
try { onSetImage={setImg}
const buffer = URL.createObjectURL( />
new Blob([new Uint8Array(await files.arrayBuffer())])
);
setImg(buffer);
setFile(files);
} catch (error) {
console.log(error);
}
}}
accept="image/png,image/jpeg"
>
{(props) => (
<Button
{...props}
radius={"xl"}
w={100}
style={{
backgroundColor: MainColor.yellow,
border: `1px solid ${AccentColor.yellow}`,
}}
>
<IconCamera color="black" />
</Button>
)}
</FileButton>
</Center> </Center>
</Stack> </Stack>

View File

@@ -29,7 +29,7 @@ const middlewareConfig: MiddlewareConfig = {
"/api/collaboration/*", "/api/collaboration/*",
"/api/notifikasi/*", "/api/notifikasi/*",
"/api/logs/*", "/api/logs/*",
"/api/image/*", // "/api/image/*",
"/api/job/*", "/api/job/*",
"/api/auth/*", "/api/auth/*",
"/api/origin-url", "/api/origin-url",