diff --git a/bun.lockb b/bun.lockb index d9e86731..6ecc0fa0 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index d0cba3cf..e68364b8 100644 --- a/package.json +++ b/package.json @@ -87,6 +87,7 @@ "react-quill": "^2.0.0", "react-responsive-carousel": "^3.2.23", "react-toastify": "^9.1.3", + "sharp": "^0.33.5", "socket.io-client": "^4.7.2", "tailwindcss": "3.3.3", "ts-node": "^10.9.2", diff --git a/prisma/migrations/20250108154615_new_database/migration.sql b/prisma/migrations/20250108154615_new_database/migration.sql new file mode 100644 index 00000000..3476e5af --- /dev/null +++ b/prisma/migrations/20250108154615_new_database/migration.sql @@ -0,0 +1,198 @@ +/* + Warnings: + + - You are about to drop the column `imagesId` on the `Job` table. All the data in the column will be lost. + - You are about to drop the column `active` on the `MasterBank` table. All the data in the column will be lost. + - You are about to drop the column `name` on the `MasterBank` table. All the data in the column will be lost. + - You are about to drop the column `imagesBackgroundId` on the `Profile` table. All the data in the column will be lost. + - You are about to drop the column `imagesId` on the `Profile` table. All the data in the column will be lost. + - You are about to drop the `ImagesBackground` table. If the table is not empty, all the data it contains will be lost. + - Added the required column `namaAkun` to the `MasterBank` table without a default value. This is not possible if the table is not empty. + - Added the required column `namaBank` to the `MasterBank` table without a default value. This is not possible if the table is not empty. + +*/ +-- DropForeignKey +ALTER TABLE "Job" DROP CONSTRAINT "Job_imagesId_fkey"; + +-- DropForeignKey +ALTER TABLE "Notifikasi" DROP CONSTRAINT "NotifikasiAdmin"; + +-- DropForeignKey +ALTER TABLE "Notifikasi" DROP CONSTRAINT "NotifikasiUser"; + +-- DropForeignKey +ALTER TABLE "Portofolio" DROP CONSTRAINT "Portofolio_logoId_fkey"; + +-- DropForeignKey +ALTER TABLE "Profile" DROP CONSTRAINT "Profile_imagesBackgroundId_fkey"; + +-- DropForeignKey +ALTER TABLE "Profile" DROP CONSTRAINT "Profile_imagesId_fkey"; + +-- DropIndex +DROP INDEX "Profile_imagesBackgroundId_key"; + +-- DropIndex +DROP INDEX "Profile_imagesId_key"; + +-- AlterTable +ALTER TABLE "BeritaInvestasi" ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "DokumenInvestasi" ADD COLUMN "fileId" TEXT, +ALTER COLUMN "url" DROP NOT NULL; + +-- AlterTable +ALTER TABLE "Donasi" ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "Donasi_Cerita" ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "Donasi_Invoice" ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "Donasi_Kabar" ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "Donasi_PencairanDana" ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "Donasi_TemporaryCreate" ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "Event" ADD COLUMN "isArsip" BOOLEAN DEFAULT false, +ADD COLUMN "tanggalSelesai" TIMESTAMP(3), +ALTER COLUMN "tanggal" DROP NOT NULL; + +-- AlterTable +ALTER TABLE "Event_Peserta" ADD COLUMN "isPresent" BOOLEAN NOT NULL DEFAULT false; + +-- AlterTable +ALTER TABLE "Investasi" ADD COLUMN "imageId" TEXT, +ADD COLUMN "prospektusFileId" TEXT; + +-- AlterTable +ALTER TABLE "Job" DROP COLUMN "imagesId", +ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "MasterBank" DROP COLUMN "active", +DROP COLUMN "name", +ADD COLUMN "isActive" BOOLEAN NOT NULL DEFAULT true, +ADD COLUMN "namaAkun" TEXT NOT NULL, +ADD COLUMN "namaBank" TEXT NOT NULL; + +-- AlterTable +ALTER TABLE "Notifikasi" ALTER COLUMN "userId" DROP NOT NULL, +ALTER COLUMN "adminId" DROP NOT NULL; + +-- AlterTable +ALTER TABLE "Profile" DROP COLUMN "imagesBackgroundId", +DROP COLUMN "imagesId", +ADD COLUMN "imageBackgroundId" TEXT, +ADD COLUMN "imageId" TEXT; + +-- AlterTable +ALTER TABLE "ProspektusInvestasi" ADD COLUMN "fileId" TEXT, +ADD COLUMN "title" TEXT; + +-- AlterTable +ALTER TABLE "User" ALTER COLUMN "active" SET DEFAULT false; + +-- AlterTable +ALTER TABLE "UserSession" ALTER COLUMN "expires" DROP NOT NULL; + +-- AlterTable +ALTER TABLE "Voting" ADD COLUMN "isArsip" BOOLEAN NOT NULL DEFAULT false; + +-- DropTable +DROP TABLE "ImagesBackground"; + +-- CreateTable +CREATE TABLE "Investasi_Invoice" ( + "id" TEXT NOT NULL, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "nominal" TEXT NOT NULL, + "lembarTerbeli" TEXT NOT NULL, + "investasiId" TEXT, + "masterBankId" TEXT, + "statusInvoiceId" TEXT, + "authorId" TEXT, + "imagesId" TEXT, + "imageId" TEXT, + + CONSTRAINT "Investasi_Invoice_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "InvestasiMaster_StatusInvoice" ( + "id" TEXT NOT NULL, + "name" TEXT NOT NULL, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "InvestasiMaster_StatusInvoice_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "BusinessMaps" ( + "id" TEXT NOT NULL, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "namePin" TEXT NOT NULL, + "latitude" DOUBLE PRECISION NOT NULL, + "longitude" DOUBLE PRECISION NOT NULL, + "authorId" TEXT, + "portofolioId" TEXT, + "imageId" TEXT, + "pinId" TEXT, + + CONSTRAINT "BusinessMaps_pkey" PRIMARY KEY ("id") +); + +-- CreateTable +CREATE TABLE "MasterKategoriApp" ( + "id" TEXT NOT NULL, + "isActive" BOOLEAN NOT NULL DEFAULT true, + "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updatedAt" TIMESTAMP(3) NOT NULL, + "name" TEXT NOT NULL, + "value" TEXT, + + CONSTRAINT "MasterKategoriApp_pkey" PRIMARY KEY ("id") +); + +-- CreateIndex +CREATE UNIQUE INDEX "BusinessMaps_portofolioId_key" ON "BusinessMaps"("portofolioId"); + +-- AddForeignKey +ALTER TABLE "Investasi_Invoice" ADD CONSTRAINT "Investasi_Invoice_investasiId_fkey" FOREIGN KEY ("investasiId") REFERENCES "Investasi"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Investasi_Invoice" ADD CONSTRAINT "Investasi_Invoice_masterBankId_fkey" FOREIGN KEY ("masterBankId") REFERENCES "MasterBank"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Investasi_Invoice" ADD CONSTRAINT "Investasi_Invoice_statusInvoiceId_fkey" FOREIGN KEY ("statusInvoiceId") REFERENCES "InvestasiMaster_StatusInvoice"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Investasi_Invoice" ADD CONSTRAINT "Investasi_Invoice_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Investasi_Invoice" ADD CONSTRAINT "Investasi_Invoice_imagesId_fkey" FOREIGN KEY ("imagesId") REFERENCES "Images"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Notifikasi" ADD CONSTRAINT "NotifikasiUser" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "Notifikasi" ADD CONSTRAINT "NotifikasiAdmin" FOREIGN KEY ("adminId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "BusinessMaps" ADD CONSTRAINT "BusinessMaps_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE; + +-- AddForeignKey +ALTER TABLE "BusinessMaps" ADD CONSTRAINT "BusinessMaps_portofolioId_fkey" FOREIGN KEY ("portofolioId") REFERENCES "Portofolio"("id") ON DELETE SET NULL ON UPDATE CASCADE; diff --git a/src/app/api/auth/register/route.ts b/src/app/api/auth/register/route.ts index af61f470..53f83014 100644 --- a/src/app/api/auth/register/route.ts +++ b/src/app/api/auth/register/route.ts @@ -24,7 +24,7 @@ export async function POST(req: Request) { data: { username: data.username, nomor: data.nomor, - active: true, + active: false, }, }); diff --git a/src/app/api/image/upload/route.ts b/src/app/api/image/upload/route.ts index a1004088..d0aef5e2 100644 --- a/src/app/api/image/upload/route.ts +++ b/src/app/api/image/upload/route.ts @@ -1,6 +1,7 @@ import { funGetDirectoryNameByValue } from "@/app_modules/_global/fun/get"; import backendLogger from "@/util/backendLogger"; import { NextResponse } from "next/server"; +import sharp from "sharp"; export async function POST(request: Request) { const formData = await request.formData(); @@ -11,9 +12,30 @@ export async function POST(request: Request) { if (request.method === "POST") { try { + const file: any = formData.get("file"); + console.log("ini file baru>", file); + + // Resize ukuran + const imageBuffer = await file.arrayBuffer(); + const resize = await sharp(imageBuffer).resize(2000).toBuffer(); + + // Convert buffer ke Blob + const blob = new Blob([resize], { type: file.type }); + + // Convert Blob ke File + const resizedFile = new File([blob], file.name, { + type: file.type, + lastModified: new Date().getTime(), + }); + + // Buat FormData baru + const newFormData = new FormData(); + newFormData.append("file", resizedFile); + newFormData.append("dirId", formData.get("dirId") as string); + const res = await fetch("https://wibu-storage.wibudev.com/api/upload", { method: "POST", - body: formData, + body: newFormData, headers: { Authorization: `Bearer ${process.env.WS_APIKEY}`, }, diff --git a/src/app/api/new/home/route.ts b/src/app/api/new/home/route.ts index bdb110d8..7ef3a890 100644 --- a/src/app/api/new/home/route.ts +++ b/src/app/api/new/home/route.ts @@ -43,7 +43,7 @@ export async function GET(request: Request) { where: { id: userLoginId, }, - select: { + include: { Profile: { select: { id: true, diff --git a/src/app/lib/global_state.ts b/src/app/lib/global_state.ts index d8792fc0..4efaf286 100644 --- a/src/app/lib/global_state.ts +++ b/src/app/lib/global_state.ts @@ -19,27 +19,30 @@ export type ITypeStatusNotifikasi = | "Menunggu" | "Gagal"; - /** * @param kategoriApp | "JOB", "VOTING", "EVENT", "DONASI", "INVESTASI", "COLLABORATION", "FORUM" * @type string */ export type IRealtimeData = { status?: ITypeStatusNotifikasi; - appId: string; + appId?: string; userId: string; - pesan: string; - title: string; - kategoriApp: + pesan?: string; + title?: string; + kategoriApp?: | "JOB" | "VOTING" | "EVENT" | "DONASI" | "INVESTASI" | "COLLABORATION" - | "FORUM"; + | "FORUM" + | "ACCESS"; // Untuk trigger akses user }; +// Access User +export const gs_access_user = atom(false); + export const gs_realtimeData = atom(null); export const gs_admin_ntf = atom(0); export const gs_user_ntf = atom(0); @@ -63,4 +66,4 @@ export const gs_donasiTriggerBeranda = atom(false); // investasi export const gs_adminInvestasi_triggerReview = atom(false); -export const gs_investasiTriggerBeranda = atom(false); \ No newline at end of file +export const gs_investasiTriggerBeranda = atom(false); diff --git a/src/app/lib/realtime_provider.tsx b/src/app/lib/realtime_provider.tsx index 6ae944d7..d85d0186 100644 --- a/src/app/lib/realtime_provider.tsx +++ b/src/app/lib/realtime_provider.tsx @@ -4,6 +4,7 @@ import { useShallowEffect } from "@mantine/hooks"; import { useAtom } from "jotai"; import { WibuRealtime } from "wibu-pkg"; import { + gs_access_user, gs_admin_ntf, gs_adminDonasi_triggerReview, gs_adminEvent_triggerReview, @@ -31,6 +32,9 @@ export type TypeNotification = { userId?: string; }; +// Tambahkan flag global untuk mencegah inisialisasi ulang +let isWibuRealtimeInitialized = false; + export default function RealtimeProvider({ userId, WIBU_REALTIME_TOKEN, @@ -42,6 +46,9 @@ export default function RealtimeProvider({ const [newAdminNtf, setNewAdminNtf] = useAtom(gs_admin_ntf); const [newUserNtf, setNewUserNtf] = useAtom(gs_user_ntf); + // ACCESS USER + const [isAccessUser, setIsAccessUser] = useAtom(gs_access_user); + // JOB const [isTriggerJobBeranda, setIsTriggerJobBeranda] = useAtom(gs_jobTiggerBeranda); @@ -83,152 +90,168 @@ export default function RealtimeProvider({ useShallowEffect(() => { try { - WibuRealtime.init({ - project: "hipmi", - WIBU_REALTIME_TOKEN: WIBU_REALTIME_TOKEN, - onData(data: TypeNotification) { - if ( - data.type == "notification" && - data.pushNotificationTo == "ADMIN" - ) { - setNewAdminNtf((e) => e + 1); - } + if (!isWibuRealtimeInitialized) { + WibuRealtime.init({ + project: "hipmi", + WIBU_REALTIME_TOKEN: WIBU_REALTIME_TOKEN, + onData(data: TypeNotification) { + // Notifikasi ke admin + if ( + data.type == "notification" && + data.pushNotificationTo == "ADMIN" + ) { + setNewAdminNtf((e) => e + 1); + } - // Notifikasi ke semua user , yang datanya di acc admin - if ( - data.type == "notification" && - data.pushNotificationTo == "USER" && - data.dataMessage?.userId == userId - ) { - setNewUserNtf((e) => e + 1); - setDataRealtime(data.dataMessage as any); - } + // trigger access + if ( + data.type == "trigger" && + data.pushNotificationTo == "USER" && + data.dataMessage?.kategoriApp == "ACCESS" && + data.dataMessage?.userId == userId + ) { + setIsAccessUser(data.dataMessage.status as any); + } - // ---------------------- JOB ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "ADMIN" && - data.dataMessage?.kategoriApp == "JOB" - ) { - setIsAdminJob_TriggerReview(true); - } + // Notifikasi ke semua user , yang datanya di acc admin + if ( + data.type == "notification" && + data.pushNotificationTo == "USER" && + data.dataMessage?.userId == userId + ) { + setNewUserNtf((e) => e + 1); + setDataRealtime(data.dataMessage as any); + } - if ( - data.type == "trigger" && - data.pushNotificationTo == "USER" && - data.dataMessage?.kategoriApp == "JOB" && - data.dataMessage.status == "Publish" - ) { - setIsTriggerJobBeranda(true); - } - // ---------------------- JOB ------------------------- // + // ---------------------- JOB ------------------------- // + if ( + data.type == "trigger" && + data.pushNotificationTo == "ADMIN" && + data.dataMessage?.kategoriApp == "JOB" + ) { + setIsAdminJob_TriggerReview(true); + } - // ---------------------- EVENT ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "ADMIN" && - data.dataMessage?.kategoriApp == "EVENT" - ) { - setIsAdminEvent_TriggerReview(true); - } + if ( + data.type == "trigger" && + data.pushNotificationTo == "USER" && + data.dataMessage?.kategoriApp == "JOB" && + data.dataMessage.status == "Publish" + ) { + setIsTriggerJobBeranda(true); + } + // ---------------------- JOB ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "USER" && - data.dataMessage?.kategoriApp == "EVENT" && - data.dataMessage.status == "Publish" - ) { - setIsTriggerEventBeranda(true); - } + // ---------------------- EVENT ------------------------- // + if ( + data.type == "trigger" && + data.pushNotificationTo == "ADMIN" && + data.dataMessage?.kategoriApp == "EVENT" + ) { + setIsAdminEvent_TriggerReview(true); + } - if ( - data.type == "notification" && - data.pushNotificationTo == "USER" && - data.dataMessage?.status == "Peserta Event" && - userId !== data.dataMessage?.userId - ) { - setNewUserNtf((e) => e + 1); - } - // ---------------------- EVENT ------------------------- // + if ( + data.type == "trigger" && + data.pushNotificationTo == "USER" && + data.dataMessage?.kategoriApp == "EVENT" && + data.dataMessage.status == "Publish" + ) { + setIsTriggerEventBeranda(true); + } - // ---------------------- VOTING ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "ADMIN" && - data.dataMessage?.kategoriApp == "VOTING" - ) { - setIsAdminVoting_TriggerReview(true); - } + if ( + data.type == "notification" && + data.pushNotificationTo == "USER" && + data.dataMessage?.status == "Peserta Event" && + userId !== data.dataMessage?.userId + ) { + setNewUserNtf((e) => e + 1); + } + // ---------------------- EVENT ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "USER" && - data.dataMessage?.kategoriApp == "VOTING" && - data.dataMessage.status == "Publish" - ) { - setIsTriggerVotingBeranda(true); - } + // ---------------------- VOTING ------------------------- // + if ( + data.type == "trigger" && + data.pushNotificationTo == "ADMIN" && + data.dataMessage?.kategoriApp == "VOTING" + ) { + setIsAdminVoting_TriggerReview(true); + } - if ( - data.type == "notification" && - data.pushNotificationTo == "USER" && - data.dataMessage?.status == "Voting Masuk" && - userId !== data.dataMessage?.userId - ) { - setNewUserNtf((e) => e + 1); - } - // ---------------------- VOTING ------------------------- // + if ( + data.type == "trigger" && + data.pushNotificationTo == "USER" && + data.dataMessage?.kategoriApp == "VOTING" && + data.dataMessage.status == "Publish" + ) { + setIsTriggerVotingBeranda(true); + } - // ---------------------- DONASI ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "ADMIN" && - data.dataMessage?.kategoriApp == "DONASI" - ) { - setIsAdminDonasi_TriggerReview(true); - } + if ( + data.type == "notification" && + data.pushNotificationTo == "USER" && + data.dataMessage?.status == "Voting Masuk" && + userId !== data.dataMessage?.userId + ) { + setNewUserNtf((e) => e + 1); + } + // ---------------------- VOTING ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "USER" && - data.dataMessage?.kategoriApp == "DONASI" && - data.dataMessage.status == "Publish" - ) { - setIsTriggerDonasiBeranda(true); - } + // ---------------------- DONASI ------------------------- // + if ( + data.type == "trigger" && + data.pushNotificationTo == "ADMIN" && + data.dataMessage?.kategoriApp == "DONASI" + ) { + setIsAdminDonasi_TriggerReview(true); + } - // if ( - // data.type == "notification" && - // data.pushNotificationTo == "ADMIN" && - // data.dataMessage?.status == "Menunggu" && - // userId !== data.dataMessage?.userId - // ) { + if ( + data.type == "trigger" && + data.pushNotificationTo == "USER" && + data.dataMessage?.kategoriApp == "DONASI" && + data.dataMessage.status == "Publish" + ) { + setIsTriggerDonasiBeranda(true); + } - // } - // ---------------------- DONASI ------------------------- // + // if ( + // data.type == "notification" && + // data.pushNotificationTo == "ADMIN" && + // data.dataMessage?.status == "Menunggu" && + // userId !== data.dataMessage?.userId + // ) { - // ---------------------- INVESTASI ------------------------- // + // } + // ---------------------- DONASI ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "ADMIN" && - data.dataMessage?.kategoriApp == "INVESTASI" - ) { - setIsAdminInvestasi_TriggerReview(true); - } + // ---------------------- INVESTASI ------------------------- // - if ( - data.type == "trigger" && - data.pushNotificationTo == "USER" && - data.dataMessage?.kategoriApp == "INVESTASI" && - data.dataMessage.status == "Publish" - ) { - setIsTriggerInvestasiBeranda(true); - } + if ( + data.type == "trigger" && + data.pushNotificationTo == "ADMIN" && + data.dataMessage?.kategoriApp == "INVESTASI" + ) { + setIsAdminInvestasi_TriggerReview(true); + } - // ---------------------- INVESTASI ------------------------- // - }, - }); + if ( + data.type == "trigger" && + data.pushNotificationTo == "USER" && + data.dataMessage?.kategoriApp == "INVESTASI" && + data.dataMessage.status == "Publish" + ) { + setIsTriggerInvestasiBeranda(true); + } + + // ---------------------- INVESTASI ------------------------- // + }, + }); + + // Tandai bahwa WibuRealtime telah diinisialisasi + isWibuRealtimeInitialized = true; + } } catch (error) { console.log("Error Realtime:", error); } diff --git a/src/app/zCoba/upload/fun_upload.ts b/src/app/zCoba/upload/fun_upload.ts new file mode 100644 index 00000000..baa3e4e2 --- /dev/null +++ b/src/app/zCoba/upload/fun_upload.ts @@ -0,0 +1,52 @@ +"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 }; + // } +} diff --git a/src/app/zCoba/upload/page.tsx b/src/app/zCoba/upload/page.tsx new file mode 100644 index 00000000..26b6bfdc --- /dev/null +++ b/src/app/zCoba/upload/page.tsx @@ -0,0 +1,137 @@ +"use client"; + +import { MainColor } from "@/app_modules/_global/color"; +import { ComponentGlobal_BoxUploadImage } from "@/app_modules/_global/component"; +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"; +import { + UIGlobal_LayoutHeaderTamplate, + UIGlobal_LayoutTamplate, +} from "@/app_modules/_global/ui"; +import { clientLogger } from "@/util/clientLogger"; +import { + AspectRatio, + Button, + Center, + FileButton, + Image, + Stack, +} from "@mantine/core"; +import { IconImageInPicture, IconUpload } from "@tabler/icons-react"; +import { useState } from "react"; +import fun_upload from "./fun_upload"; +import { funGlobal_UploadToStorage } from "@/app_modules/_global/fun"; + +export default function Page() { + return ( + <> + } + > + + + + ); +} + +function Upload() { + const [file, setFile] = useState(null); + const [image, setImage] = useState(null); + const [isLoading, setLoading] = useState(false); + + async function onUpload() { + if (!file) return alert("File Kosong"); + try { + setLoading(true); + const formData = new FormData(); + formData.append("file", file as File); + + const uploadPhoto = await funGlobal_UploadToStorage({ + file: file, + dirId: "cm5ohsepe002bq4nlxeejhg7q", + }); + + if (uploadPhoto.success) { + setLoading(false); + alert("berhasil upload"); + console.log("uploadPhoto", uploadPhoto); + } else { + setLoading(false); + console.log("gagal upload", uploadPhoto); + } + } catch (error) { + console.error("Error upload img:", error); + } + } + + return ( + <> + + + {image ? ( + + Avatar + + ) : ( +
+ +
+ )} +
+ +
+ { + try { + const buffer = URL.createObjectURL( + new Blob([new Uint8Array(await files.arrayBuffer())]) + ); + + // if (files.size > MAX_SIZE) { + // ComponentGlobal_NotifikasiPeringatan( + // PemberitahuanMaksimalFile + // ); + // return; + // } else { + + // } + + console.log("ini buffer", buffer); + + setFile(files); + setImage(buffer); + } catch (error) { + clientLogger.error("Upload error:", error); + } + }} + accept="image/png,image/jpeg" + > + {(props) => ( + + )} + +
+ + +
+ + ); +} diff --git a/src/app_modules/admin/developer/index.tsx b/src/app_modules/admin/developer/index.tsx index a04161b1..481e636f 100644 --- a/src/app_modules/admin/developer/index.tsx +++ b/src/app_modules/admin/developer/index.tsx @@ -256,6 +256,10 @@ function NewTableAdmin({ search: isSearch, page: isChoosePage, }); + + + + setDataAdmin(loadData.data); setNPage(loadData.nPage); const loadDataUser = await adminDeveloper_funGetListAllUser({ page: 1 }); diff --git a/src/app_modules/admin/user-access/fun/edit/fun_edit_access.ts b/src/app_modules/admin/user-access/fun/edit/fun_edit_access.ts index a8a9dc15..46e4703d 100644 --- a/src/app_modules/admin/user-access/fun/edit/fun_edit_access.ts +++ b/src/app_modules/admin/user-access/fun/edit/fun_edit_access.ts @@ -1,11 +1,14 @@ "use server"; import prisma from "@/app/lib/prisma"; +import backendLogger from "@/util/backendLogger"; import { revalidatePath } from "next/cache"; +import { headers } from "next/headers"; export default async function adminUserAccess_funEditAccess( userId: string, - value: boolean + value: boolean, + nomor?: string ) { const updt = await prisma.user.update({ where: { @@ -16,6 +19,31 @@ export default async function adminUserAccess_funEditAccess( }, }); + const headersList = headers(); + const host = headersList.get("host"); + const protocol = headersList.get("x-forwarded-proto") || "http"; + const path = headersList.get("x-invoke-path"); + const baseUrl = `${protocol}://${host}`; + // const fullUrl = `${protocol}://${host}${path}`; + + if (value === true) { + const message = `Hallo rekan HIPMI, Anda telah diberikan akses ke HIPMI Apps. Silakan mulai jelajahi fitur-fitur yang tersedia melalui link berikut: ${baseUrl}`; + const encodedMessage = encodeURIComponent(message); + + const res = await fetch( + `https://wa.wibudev.com/code?nom=${nomor}&text=${encodedMessage} + ` + ); + + if (!res.ok) { + backendLogger.error("Error send message", res); + } + + const result = await res.json(); + + backendLogger.info("Success send message", result); + } + if (!updt) return { status: 400, message: "Update gagal" }; revalidatePath("/dev/admin/user-access"); return { status: 200, message: "Update berhasil" }; diff --git a/src/app_modules/admin/user-access/view/index.tsx b/src/app_modules/admin/user-access/view/index.tsx index 6180b6b5..9a23c1e4 100644 --- a/src/app_modules/admin/user-access/view/index.tsx +++ b/src/app_modules/admin/user-access/view/index.tsx @@ -20,6 +20,9 @@ import { IconSearch } from "@tabler/icons-react"; import { useState } from "react"; import adminUserAccess_funEditAccess from "../fun/edit/fun_edit_access"; import adminUserAccess_getListUser from "../fun/get/get_list_all_user"; +import { WibuRealtime } from "wibu-pkg"; +import { gs_access_user, IRealtimeData } from "@/app/lib/global_state"; +import { useAtom } from "jotai"; export default function AdminUserAccess_View({ listUser }: { listUser: any }) { const [data, setData] = useState(listUser.data); @@ -30,11 +33,11 @@ export default function AdminUserAccess_View({ listUser }: { listUser: any }) { const [isLoadingDelete, setIsLoadingDelete] = useState(false); const [userId, setUserId] = useState(""); - async function onAccess(id: string) { + async function onAccess(id: string, nomor: string) { try { setUserId(id); setIsLoadingAccess(true); - await adminUserAccess_funEditAccess(id, true).then(async (res) => { + await adminUserAccess_funEditAccess(id, true, nomor).then(async (res) => { if (res.status === 200) { const value = await adminUserAccess_getListUser({ page: 1, @@ -42,6 +45,19 @@ export default function AdminUserAccess_View({ listUser }: { listUser: any }) { }); setData(value.data as any); setNPage(value.nPage); + + const dataNotifikasi: IRealtimeData = { + status: true as any, + userId: id, + kategoriApp: "ACCESS", + }; + + WibuRealtime.setData({ + type: "trigger", + pushNotificationTo: "USER", + dataMessage: dataNotifikasi, + }); + ComponentGlobal_NotifikasiBerhasil(res.message); } else { ComponentGlobal_NotifikasiGagal(res.message); @@ -118,7 +134,7 @@ export default function AdminUserAccess_View({ listUser }: { listUser: any }) { radius={"xl"} color="Green" onClick={() => { - onAccess(e.id); + onAccess(e.id, e.nomor); }} > Grand Access diff --git a/src/app_modules/auth/login/view.tsx b/src/app_modules/auth/login/view.tsx index 1e32fb9e..e6452f7d 100644 --- a/src/app_modules/auth/login/view.tsx +++ b/src/app_modules/auth/login/view.tsx @@ -69,7 +69,7 @@ export default function Login({ version }: { version: string }) { WELCOME TO - HIPMI APPS + HIPMI BADUNG APPS diff --git a/src/app_modules/auth/register/view.tsx b/src/app_modules/auth/register/view.tsx index 6d39af6c..37276b59 100644 --- a/src/app_modules/auth/register/view.tsx +++ b/src/app_modules/auth/register/view.tsx @@ -13,6 +13,7 @@ import { useRouter } from "next/navigation"; import { useState } from "react"; import { auth_funDeleteAktivasiKodeOtpByNomor } from "../fun/fun_edit_aktivasi_kode_otp_by_id"; import Register_SkeletonView from "./skeleton"; +import { clientLogger } from "@/util/clientLogger"; export default function Register() { const router = useRouter(); @@ -70,28 +71,31 @@ export default function Register() { await auth_funDeleteAktivasiKodeOtpByNomor({ nomor: data.nomor, }); - router.push("/dev/home", { scroll: false }); + + router.push("/waiting-room", { scroll: false }); return; } if (res.status === 400) { + setLoading(false); ComponentGlobal_NotifikasiPeringatan(result.message); return; } if (res.status === 405) { + setLoading(false); ComponentGlobal_NotifikasiPeringatan(result.message); return; } if (res.status === 500) { + setLoading(false); ComponentGlobal_NotifikasiPeringatan(result.message); return; } } catch (error) { - console.log(error); - } finally { setLoading(false); + clientLogger.error("Error registrasi", error); } } diff --git a/src/app_modules/auth/validasi/view.tsx b/src/app_modules/auth/validasi/view.tsx index dc20747a..65b603b9 100644 --- a/src/app_modules/auth/validasi/view.tsx +++ b/src/app_modules/auth/validasi/view.tsx @@ -87,9 +87,6 @@ export default function Validasi() { body: JSON.stringify({ nomor: data.nomor, }), - headers: { - "Content-Type": "application/json", - }, }); const result = await res.json(); @@ -100,6 +97,7 @@ export default function Validasi() { await auth_funDeleteAktivasiKodeOtpByNomor({ nomor: data.nomor, }); + router.push(RouterHome.main_home, { scroll: false }); return; } @@ -110,30 +108,33 @@ export default function Validasi() { await auth_funDeleteAktivasiKodeOtpByNomor({ nomor: data.nomor, }); + router.push(RouterAdminDashboard.splash_admin, { scroll: false }); return; } if (res.status === 404) { + setLoading(false); router.push("/register", { scroll: false }); ComponentGlobal_NotifikasiBerhasil(result.message); return; } if (res.status === 400) { + setLoading(false); ComponentGlobal_NotifikasiPeringatan(result.message); return; } if (res.status == 500) { + setLoading(false); ComponentGlobal_NotifikasiGagal(result.message); return; } } catch (error) { - clientLogger.error("Error validasi:", error); - } finally { setLoading(false); - } + clientLogger.error("Error validasi:", error); + } } async function onBack() { diff --git a/src/app_modules/home/component/body_home.tsx b/src/app_modules/home/component/body_home.tsx index ebd7a75a..9ecff402 100644 --- a/src/app_modules/home/component/body_home.tsx +++ b/src/app_modules/home/component/body_home.tsx @@ -26,8 +26,8 @@ import { clientLogger } from "@/util/clientLogger"; export default function BodyHome() { const router = useRouter(); - const [dataUser, setDataUser] = useState({}); - const [dataJob, setDataJob] = useState([]); + const [dataUser, setDataUser] = useState(null); + const [dataJob, setDataJob] = useState(null); const [loadingJob, setLoadingJob] = useState(true); const [loading, setLoading] = useState(true); @@ -46,10 +46,12 @@ export default function BodyHome() { setDataUser(response.data); } } catch (error) { - clientLogger.error("Error get data user", error); - } + clientLogger.error("Error get data profile", error); + } } + + async function getHomeJob() { try { setLoadingJob(true); @@ -70,19 +72,6 @@ export default function BodyHome() { return ( - {/* - - */} - { - if ( - dataUser.profile == undefined || - dataUser?.profile == null || - dataJob.length == undefined || - dataJob.length == null - ) { + if (dataUser == null) { return null; } else if ( - dataUser.profile == undefined || - dataUser?.profile == null + Object.keys(dataUser).length == 0 || + dataJob?.length == null ) { router.push(RouterProfile.create, { scroll: false }); } else { @@ -163,16 +147,11 @@ export default function BodyHome() { > { - if ( - dataUser.profile == undefined || - dataUser?.profile == null || - dataJob.length == undefined || - dataJob.length == null - ) { + if (dataUser == null) { return null; } else if ( - dataUser.profile == undefined || - dataUser?.profile == null + Object.keys(dataUser).length == 0 || + dataJob?.length == null ) { router.push(RouterProfile.create, { scroll: false }); } else { @@ -229,7 +208,7 @@ export default function BodyHome() { ) : ( - {dataJob.map((e, i) => ( + {dataJob?.map((e, i) => ( diff --git a/src/app_modules/home/component/footer_home.tsx b/src/app_modules/home/component/footer_home.tsx index 696acbd4..87a6a4f2 100644 --- a/src/app_modules/home/component/footer_home.tsx +++ b/src/app_modules/home/component/footer_home.tsx @@ -51,7 +51,7 @@ export default function FooterHome() { bottom={0} h={"9vh"} > - {dataUser?.profile === undefined || dataUser?.profile === null ? ( + {dataUser == null ? ( {Array.from(new Array(4)).map((_, i) => (
@@ -69,15 +69,9 @@ export default function FooterHome() { align="center" spacing={0} onClick={() => { - if ( - dataUser.profile === undefined || - dataUser?.profile === null - ) { + if (dataUser == null) { return null; - } else if ( - dataUser.profile === undefined || - dataUser?.profile === null - ) { + } else if (Object.keys(dataUser).length === 0) { router.push(RouterProfile.create, { scroll: false }); } else { if (e.link == "") { diff --git a/src/app_modules/home/state/global_state.ts b/src/app_modules/home/component/global_state.ts similarity index 79% rename from src/app_modules/home/state/global_state.ts rename to src/app_modules/home/component/global_state.ts index 638d7246..5b97c4ef 100644 --- a/src/app_modules/home/state/global_state.ts +++ b/src/app_modules/home/component/global_state.ts @@ -1,3 +1,4 @@ import { atomWithStorage } from "jotai/utils"; +import { atom } from "jotai"; export const gs_token = atomWithStorage("gs_token", null); diff --git a/src/app_modules/home/view_home_new.tsx b/src/app_modules/home/view_home_new.tsx index c632663a..7673e2f2 100644 --- a/src/app_modules/home/view_home_new.tsx +++ b/src/app_modules/home/view_home_new.tsx @@ -68,7 +68,7 @@ export default function HomeViewNew() { ) : ( ) : ( (null); + const [isAccess, setIsAccess] = useState(null); + const [isAccessUser, setIsAccessUser] = useAtom(gs_access_user); + + useShallowEffect(() => { + if (isAccessUser) { + setIsAccess(true); + setIsAccessUser(false); + } + }, [isAccessUser]); useShallowEffect(() => { onLoadData(); @@ -41,7 +55,7 @@ export default function WaitingRoom_View({ try { const respone = await apiGetACtivationUser(); if (respone) { - setData(respone.data); + setIsAccess(respone.data); } } catch (error) { clientLogger.error("Error get cookies user", error); @@ -53,11 +67,12 @@ export default function WaitingRoom_View({ - {_.isNull(data) ? ( - - {Array.from(new Array(4)).map((e, i) => ( - - ))} + {_.isNull(isAccess) ? ( + + + + + ) : ( @@ -71,16 +86,28 @@ export default function WaitingRoom_View({ Whatsapp setelah disetujui. - - {/* */} + {isAccess && ( + + )} )} diff --git a/src/middleware.ts b/src/middleware.ts index 24571420..817e8bde 100644 --- a/src/middleware.ts +++ b/src/middleware.ts @@ -5,6 +5,8 @@ import { apies, pages } from "./lib/routes"; type MiddlewareConfig = { apiPath: string; loginPath: string; + // validasiPath: string; + // registarasiPath: string; userPath: string; publicRoutes: string[]; encodedKey: string; @@ -16,6 +18,8 @@ type MiddlewareConfig = { const middlewareConfig: MiddlewareConfig = { apiPath: "/api", loginPath: "/login", + // validasiPath: "/validasi", + // registarasiPath: "/register", userPath: "/dev/home", publicRoutes: [ // API @@ -45,6 +49,7 @@ const middlewareConfig: MiddlewareConfig = { "/auth/login", "/auth/api/login", "/waiting-room", + "/zCoba/*", // ASSETS "/aset/global/main_background.png", @@ -61,6 +66,8 @@ export const middleware = async (req: NextRequest) => { apiPath, encodedKey, loginPath, + // validasiPath, + // registarasiPath, publicRoutes, sessionKey, validationApiRoute, @@ -75,7 +82,12 @@ export const middleware = async (req: NextRequest) => { } // Skip authentication for public routes - const isPublicRoute = [...publicRoutes, loginPath].some((route) => { + const isPublicRoute = [ + ...publicRoutes, + loginPath, + // validasiPath, + // registarasiPath, + ].some((route) => { const pattern = route.replace(/\*/g, ".*"); return new RegExp(`^${pattern}$`).test(pathname); }); @@ -88,7 +100,13 @@ export const middleware = async (req: NextRequest) => { } } - if (isPublicRoute && pathname !== loginPath) { + if ( + isPublicRoute && + pathname !== loginPath + // && + // pathname !== validasiPath && + // pathname !== registarasiPath + ) { return setCorsHeaders(NextResponse.next()); } @@ -96,6 +114,7 @@ export const middleware = async (req: NextRequest) => { req.cookies.get(sessionKey)?.value || req.headers.get("Authorization")?.split(" ")[1]; + // ==================== Authentication: Login, Validasi, Registrasi ==================== // // Token verification const user = await verifyToken({ token, encodedKey }); @@ -107,10 +126,27 @@ export const middleware = async (req: NextRequest) => { return setCorsHeaders(NextResponse.next()); } + // // Handle validation page access + // if (pathname === validasiPath) { + // if (user) { + // return setCorsHeaders(NextResponse.redirect(new URL(userPath, req.url))); + // } + // return setCorsHeaders(NextResponse.next()); + // } + + // // Handle register page access + // if (pathname === registarasiPath) { + // if (user) { + // return setCorsHeaders(NextResponse.redirect(new URL(userPath, req.url))); + // } + // return setCorsHeaders(NextResponse.next()); + // } + // Handle protected routes if (!user) { return setCorsHeaders(NextResponse.redirect(new URL(loginPath, req.url))); } + // ==================== Authentication: Login, Validasi, Registrasi ==================== // if (pathname.startsWith("/dev")) { const userValidate = await fetch(new URL("/api/user-validate", req.url), {