Merge pull request #237 from bipproduction/join

Fix access user and image upload
This commit is contained in:
Bagasbanuna02
2025-01-12 22:08:39 +08:00
committed by GitHub
219 changed files with 6659 additions and 2890 deletions

View File

@@ -2,6 +2,17 @@
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines. All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
## [1.2.39](https://github.com/bipproduction/hipmi/compare/v1.2.38...v1.2.39) (2025-01-12)
## [1.2.38](https://github.com/bipproduction/hipmi/compare/v1.2.37...v1.2.38) (2025-01-03)
### Bug Fixes
* user ([215accb](https://github.com/bipproduction/hipmi/commit/215accbcaa989e43f43dfc5f400d5411013f4ef3))
## [1.2.37](https://github.com/bipproduction/hipmi/compare/v1.2.36...v1.2.37) (2025-01-02)
## [1.2.36](https://github.com/bipproduction/hipmi/compare/v1.2.35...v1.2.36) (2024-12-30) ## [1.2.36](https://github.com/bipproduction/hipmi/compare/v1.2.35...v1.2.36) (2024-12-30)
## [1.2.35](https://github.com/bipproduction/hipmi/compare/v1.2.34...v1.2.35) (2024-12-27) ## [1.2.35](https://github.com/bipproduction/hipmi/compare/v1.2.34...v1.2.35) (2024-12-27)

BIN
bun.lockb

Binary file not shown.

View File

@@ -1,6 +1,6 @@
{ {
"name": "hipmi", "name": "hipmi",
"version": "1.2.36", "version": "1.2.39",
"private": true, "private": true,
"prisma": { "prisma": {
"seed": "npx tsx prisma/seed.ts --yes" "seed": "npx tsx prisma/seed.ts --yes"
@@ -87,6 +87,7 @@
"react-quill": "^2.0.0", "react-quill": "^2.0.0",
"react-responsive-carousel": "^3.2.23", "react-responsive-carousel": "^3.2.23",
"react-toastify": "^9.1.3", "react-toastify": "^9.1.3",
"sharp": "^0.33.5",
"socket.io-client": "^4.7.2", "socket.io-client": "^4.7.2",
"tailwindcss": "3.3.3", "tailwindcss": "3.3.3",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",

View File

@@ -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;

View File

@@ -1,19 +1,12 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { funGlobal_checkActivationUseById } from "@/app_modules/_global/fun/get/fun_check_activation_use_by_id";
import WaitingRoom_View from "@/app_modules/waiting_room/view"; import WaitingRoom_View from "@/app_modules/waiting_room/view";
export default async function Page() { export default async function Page() {
const userLoginId = await funGetUserIdByToken(); const userLoginId = await funGetUserIdByToken();
const activationUser = await funGlobal_checkActivationUseById({
userId: userLoginId as string,
});
return ( return (
<> <>
<WaitingRoom_View <WaitingRoom_View userLoginId={userLoginId as string} />
activationUser={activationUser as boolean}
userLoginId={userLoginId as string}
/>
</> </>
); );
} }

View File

@@ -1,5 +1,6 @@
import { prisma } from "@/app/lib"; import { prisma } from "@/app/lib";
import { randomOTP } from "@/app_modules/auth/fun/rondom_otp"; import { randomOTP } from "@/app_modules/auth/fun/rondom_otp";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
export async function POST(req: Request) { export async function POST(req: Request) {
@@ -17,12 +18,13 @@ export async function POST(req: Request) {
); );
const sendWa = await res.json(); const sendWa = await res.json();
if (sendWa.status !== "success") if (sendWa.status !== "success")
return NextResponse.json( return NextResponse.json(
{ success: false, message: "Nomor Whatsapp Tidak Aktif" }, { success: false, message: "Nomor Whatsapp Tidak Aktif" },
{ status: 400 } { status: 400 }
); );
const createOtpId = await prisma.kodeOtp.create({ const createOtpId = await prisma.kodeOtp.create({
data: { data: {
nomor: nomor, nomor: nomor,
@@ -45,14 +47,14 @@ export async function POST(req: Request) {
{ status: 200 } { status: 200 }
); );
} catch (error) { } catch (error) {
console.log(error); backendLogger.log("Error Login", error);
return NextResponse.json( return NextResponse.json(
{ success: false, message: "Server Whatsapp Error !! " }, { success: false, message: error as Error },
{ status: 500 } { status: 500 }
); );
} }
} }
return NextResponse.json( return NextResponse.json(
{ success: false, message: "Method Not Allowed" }, { success: false, message: "Method Not Allowed" },
{ status: 405 } { status: 405 }

View File

@@ -1,5 +1,6 @@
import { sessionCreate } from "@/app/auth/_lib/session_create"; import { sessionCreate } from "@/app/auth/_lib/session_create";
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
export async function POST(req: Request) { export async function POST(req: Request) {
@@ -23,7 +24,7 @@ export async function POST(req: Request) {
data: { data: {
username: data.username, username: data.username,
nomor: data.nomor, nomor: data.nomor,
active: true, active: false,
}, },
}); });
@@ -38,7 +39,15 @@ export async function POST(req: Request) {
{ status: 200 } { status: 200 }
); );
} catch (error) { } catch (error) {
console.log(error); backendLogger.log("Error registrasi:", error);
return NextResponse.json(
{
success: false,
message: "Server Error",
reason: (error as Error).message,
},
{ status: 500 }
);
} }
} }

View File

@@ -1,5 +1,6 @@
import { sessionCreate } from "@/app/auth/_lib/session_create"; import { sessionCreate } from "@/app/auth/_lib/session_create";
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
export async function POST(req: Request) { export async function POST(req: Request) {
@@ -42,7 +43,15 @@ export async function POST(req: Request) {
{ status: 200 } { status: 200 }
); );
} catch (error) { } catch (error) {
console.log(error); backendLogger.log("Error Validasi:", error);
return NextResponse.json(
{
success: false,
message: "Server Error",
reason: (error as Error).message,
},
{ status: 500 }
);
} }
} }
return NextResponse.json( return NextResponse.json(

View File

@@ -0,0 +1,113 @@
import { prisma } from "@/app/lib";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET(
request: Request,
context: { params: { id: string } }
) {
try {
let fixData;
const { id } = context.params;
const { searchParams } = new URL(request.url);
const kategori = searchParams.get("kategori");
const page = searchParams.get("page");
const takeData = 10;
const dataSkip = Number(page) * takeData - takeData;
// Buatkan api untuk list partisipasi
const userLoginId = await funGetUserIdByToken();
if (userLoginId == null) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data, user id tidak ada",
},
{ status: 500 }
);
}
if (kategori == "detail") {
fixData = await prisma.projectCollaboration.findFirst({
where: {
id: id,
},
select: {
id: true,
isActive: true,
title: true,
lokasi: true,
purpose: true,
benefit: true,
createdAt: true,
// jumlah_partisipan: true,
Author: {
select: {
id: true,
Profile: true,
},
},
ProjectCollaborationMaster_Industri: true,
ProjectCollaboration_Partisipasi: {
where: {
isActive: true,
},
},
},
});
} else if (kategori == "list_partisipan") {
fixData = await prisma.projectCollaboration_Partisipasi.findMany({
take: takeData,
skip: dataSkip,
where: {
projectCollaborationId: id,
isActive: true,
},
select: {
id: true,
User: {
select: {
id: true,
Profile: true,
},
},
deskripsi_diri: true,
},
});
} else if (kategori == "cek_partisipasi") {
const cek = await prisma.projectCollaboration_Partisipasi.findFirst({
where: {
projectCollaborationId: id,
userId: userLoginId,
},
});
if (cek === null) {
fixData = false;
} else {
fixData = true;
}
}
return NextResponse.json(
{ success: true, message: "Berhasil mendapatkan data", data: fixData },
{ status: 200 }
);
} catch (error) {
backendLogger.error("Error get collaboration by id", error);
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data",
reason: (error as Error).message,
},
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,176 @@
import { prisma } from "@/app/lib";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET(request: Request) {
try {
let fixData;
const { searchParams } = new URL(request.url);
const kategori = searchParams.get("kategori");
const page = searchParams.get("page");
const takeData = 5;
const skipData = page ? Number(page) * takeData - takeData : 0;
const userLoginId = await funGetUserIdByToken();
if (userLoginId == null) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data, user id tidak ada",
},
{ status: 500 }
);
}
if (kategori == "beranda") {
fixData = await prisma.projectCollaboration.findMany({
take: takeData,
skip: skipData,
orderBy: {
createdAt: "desc",
},
where: {
projectCollaborationMaster_StatusId: 1,
isActive: true,
},
select: {
id: true,
isActive: true,
title: true,
lokasi: true,
purpose: true,
benefit: true,
Author: {
select: {
id: true,
Profile: true,
},
},
ProjectCollaborationMaster_Industri: true,
ProjectCollaboration_Partisipasi: {
where: {
isActive: true,
},
},
},
});
} else if (kategori == "partisipasi") {
fixData = await prisma.projectCollaboration_Partisipasi.findMany({
take: takeData,
skip: skipData,
orderBy: {
createdAt: "desc",
},
where: {
userId: userLoginId,
isActive: true,
AND: {
ProjectCollaboration: {
isActive: true,
},
},
},
select: {
id: true,
isActive: true,
ProjectCollaboration: {
select: {
id: true,
isActive: true,
title: true,
lokasi: true,
purpose: true,
benefit: true,
Author: {
select: {
id: true,
Profile: true,
},
},
ProjectCollaborationMaster_Industri: true,
ProjectCollaboration_Partisipasi: {
where: {
isActive: true,
},
},
},
},
},
});
} else if (kategori == "proyeksaya") {
fixData = await prisma.projectCollaboration.findMany({
take: takeData,
skip: skipData,
orderBy: { createdAt: "desc" },
where: { userId: userLoginId, isActive: true },
select: {
id: true,
isActive: true,
title: true,
lokasi: true,
purpose: true,
benefit: true,
// jumlah_partisipan: true,
Author: {
select: {
id: true,
Profile: true,
},
},
ProjectCollaborationMaster_Industri: true,
ProjectCollaboration_Partisipasi: {
where: {
isActive: true,
},
},
},
});
} else if (kategori == "grup") {
fixData = await prisma.projectCollaboration_AnggotaRoomChat.findMany({
take: takeData,
skip: skipData,
orderBy: {
createdAt: "desc",
},
where: {
userId: userLoginId as string,
},
select: {
ProjectCollaboration_RoomChat: {
select: {
id: true,
name: true,
isActive: true,
ProjectCollaboration_AnggotaRoomChat: {
select: {
User: true,
},
},
},
},
},
});
}
return NextResponse.json(
{ success: true, message: "Berhasil mendapatkan data", data: fixData },
{ status: 200 }
);
} catch (error) {
backendLogger.error("Error get collaboration: ", error);
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data",
reason: (error as Error).message,
},
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,82 @@
import { prisma } from "@/app/lib";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET(
request: Request,
context: { params: { id: string } }
) {
try {
let fixData;
const { id } = context.params;
const { searchParams } = new URL(request.url);
const kategori = searchParams.get("kategori");
const page = searchParams.get("page");
const takeData = 10;
const skipData = Number(page) * takeData - takeData;
// data room { id, grup_name}
if (kategori == "detail") {
fixData = await prisma.projectCollaboration_RoomChat.findFirst({
where: {
id: id,
},
select: {
id: true,
name: true,
},
});
} else if (kategori == "info_group") {
fixData = await prisma.projectCollaboration_RoomChat.findFirst({
where: {
id: id,
},
select: {
id: true,
name: true,
ProjectCollaboration: {
select: {
id: true,
isActive: true,
title: true,
lokasi: true,
purpose: true,
benefit: true,
createdAt: true,
ProjectCollaborationMaster_Industri: true,
},
},
ProjectCollaboration_AnggotaRoomChat: {
select: {
User: {
select: {
id: true,
Profile: {
select: {
id: true,
name: true,
imageId: true,
},
},
},
},
},
},
},
});
}
return NextResponse.json(
{ success: true, message: "Berhasil mendapatkan data", data: fixData },
{ status: 200 }
);
} catch (error) {
backendLogger.error("Gagal mendapatkan data", error);
return NextResponse.json(
{ success: false, message: "Gagal mendapatkan data" },
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,15 @@
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server';
export const dynamic = "force-dynamic";
export async function GET(request: Request) {
try {
const cookiesKey = process.env.NEXT_PUBLIC_BASE_SESSION_KEY!
const cookieStore = cookies();
const hipmiKey = cookieStore.get(cookiesKey)?.value || '';
return NextResponse.json({ token: hipmiKey });
} catch (error) {
console.error(error);
return NextResponse.json({ error }, { status: 500 });
}
}

View File

@@ -25,9 +25,7 @@ export async function DELETE(req: Request) {
backendLogger.info("Server status code: " + res.status); backendLogger.info("Server status code: " + res.status);
const data = await res.json(); const data = await res.json();
if (res.ok) { if (res.ok) {
backendLogger.info( backendLogger.info(`Success delete ${keyOfDirectory}`);
`Success delete ${keyOfDirectory}`
);
return NextResponse.json({ success: true }); return NextResponse.json({ success: true });
} else { } else {
const errorText = await res.json(); const errorText = await res.json();

View File

@@ -1,8 +1,13 @@
import { funGetDirectoryNameByValue } from "@/app_modules/_global/fun/get"; import { funGetDirectoryNameByValue } from "@/app_modules/_global/fun/get";
import backendLogger from "@/util/backendLogger"; import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
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({
@@ -11,9 +16,33 @@ export async function POST(request: Request) {
if (request.method === "POST") { if (request.method === "POST") {
try { try {
if (mimeType != "application/pdf") {
// 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);
fixFormData = newFormData;
} else {
fixFormData = formData;
}
const res = await fetch("https://wibu-storage.wibudev.com/api/upload", { const res = await fetch("https://wibu-storage.wibudev.com/api/upload", {
method: "POST", method: "POST",
body: formData, body: fixFormData,
headers: { headers: {
Authorization: `Bearer ${process.env.WS_APIKEY}`, Authorization: `Bearer ${process.env.WS_APIKEY}`,
}, },

View File

@@ -43,7 +43,7 @@ export async function GET(request: Request) {
where: { where: {
id: userLoginId, id: userLoginId,
}, },
select: { include: {
Profile: { Profile: {
select: { select: {
id: true, id: true,

View File

@@ -14,7 +14,8 @@ export async function GET(request: Request) {
const kategori = searchParams.get("cat") const kategori = searchParams.get("cat")
const status = searchParams.get("status") const status = searchParams.get("status")
const page = searchParams.get("page") const page = searchParams.get("page")
const dataSkip = Number(page) * 5 - 5; const dataTake = 10
const dataSkip = Number(page) * dataTake - dataTake;
if (kategori == "bursa") { if (kategori == "bursa") {
const data = await prisma.investasi.findMany({ const data = await prisma.investasi.findMany({
@@ -61,7 +62,7 @@ export async function GET(request: Request) {
// cek data yang lewat // cek data yang lewat
// klo ada, update status // klo ada, update status
const dataAwal = await prisma.investasi.findMany({ const dataAwal = await prisma.investasi.findMany({
take: 5, take: dataTake,
skip: dataSkip, skip: dataSkip,
orderBy: [ orderBy: [
{ {
@@ -100,28 +101,28 @@ export async function GET(request: Request) {
} }
const data = await prisma.investasi.findMany({ const data = await prisma.investasi.findMany({
take: 5, take: dataTake,
skip: dataSkip, skip: dataSkip,
orderBy: { orderBy: {
updatedAt: "desc", updatedAt: "desc",
}, },
where: { where: {
authorId: userLoginId, authorId: userLoginId,
masterStatusInvestasiId: status, masterStatusInvestasiId: status,
}, },
select: { select: {
id: true, id: true,
title: true, title: true,
targetDana: true, targetDana: true,
imageId: true, imageId: true,
countDown: true, countDown: true,
updatedAt: true, updatedAt: true,
MasterPencarianInvestor: { MasterPencarianInvestor: {
select: { select: {
name: true name: true,
} },
} },
} },
}); });
dataFix = data.map((v: any) => ({ dataFix = data.map((v: any) => ({

View File

@@ -1,173 +1,234 @@
import { prisma } from "@/app/lib"; import { DIRECTORY_ID, prisma } from "@/app/lib";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
import fs from "fs"; 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";
export const dynamic = "force-dynamic"; export const dynamic = "force-dynamic";
// GET ONE DATA PORTOFOLIO BY ID PORTOFOLIO // GET ONE DATA PORTOFOLIO BY ID PORTOFOLIO
export async function GET(request: Request, context: { params: { id: string } }) { export async function GET(
try { request: Request,
let dataFix context: { params: { id: string } }
const { id } = context.params; ) {
const { searchParams } = new URL(request.url); try {
const kategori = searchParams.get('cat'); let dataFix;
const { id } = context.params;
const { searchParams } = new URL(request.url);
const kategori = searchParams.get("cat");
if (kategori == "bisnis") { if (kategori == "bisnis") {
const data = await prisma.portofolio.findUnique({ const data = await prisma.portofolio.findUnique({
where: { where: {
id: id, id: id,
}, },
select: {
id_Portofolio: true,
namaBisnis: true,
alamatKantor: true,
tlpn: true,
deskripsi: true,
logoId: true,
MasterBidangBisnis: {
select: { select: {
id_Portofolio: true, name: true,
namaBisnis: true,
alamatKantor: true,
tlpn: true,
deskripsi: true,
logoId: true,
MasterBidangBisnis: {
select: {
name: true
}
},
Profile: {
select: {
userId: true
}
}
}
});
dataFix = {
id_Portofolio: data?.id_Portofolio,
namaBisnis: data?.namaBisnis,
alamatKantor: data?.alamatKantor,
tlpn: data?.tlpn,
deskripsi: data?.deskripsi,
logoId: data?.logoId,
bidangBisnis: data?.MasterBidangBisnis?.name,
authorId: data?.Profile?.userId
}
} else if (kategori == "lokasi") {
const data = await prisma.portofolio.findUnique({
where: {
id: id,
}, },
},
Profile: {
select: { select: {
logoId: true, userId: true,
BusinessMaps: {
select: {
id: true,
namePin: true,
latitude: true,
longitude: true,
imageId: true,
pinId: true
}
}
}
});
dataFix = {
mapId: data?.BusinessMaps?.id,
logoId: data?.logoId,
namePin: data?.BusinessMaps?.namePin,
latitude: data?.BusinessMaps?.latitude,
longitude: data?.BusinessMaps?.longitude,
imageId: data?.BusinessMaps?.imageId,
pinId: data?.BusinessMaps?.pinId
}
} else if (kategori == "sosmed") {
const data = await prisma.portofolio.findUnique({
where: {
id: id,
}, },
},
},
});
dataFix = {
id_Portofolio: data?.id_Portofolio,
namaBisnis: data?.namaBisnis,
alamatKantor: data?.alamatKantor,
tlpn: data?.tlpn,
deskripsi: data?.deskripsi,
logoId: data?.logoId,
bidangBisnis: data?.MasterBidangBisnis?.name,
authorId: data?.Profile?.userId,
};
} else if (kategori == "lokasi") {
const data = await prisma.portofolio.findUnique({
where: {
id: id,
},
select: {
logoId: true,
BusinessMaps: {
select: { select: {
Portofolio_MediaSosial: { id: true,
select: { namePin: true,
facebook: true, latitude: true,
twitter: true, longitude: true,
instagram: true, imageId: true,
tiktok: true, pinId: true,
youtube: true },
} },
} },
} });
});
dataFix = { dataFix = {
facebook: data?.Portofolio_MediaSosial?.facebook, mapId: data?.BusinessMaps?.id,
twitter: data?.Portofolio_MediaSosial?.twitter, logoId: data?.logoId,
instagram: data?.Portofolio_MediaSosial?.instagram, namePin: data?.BusinessMaps?.namePin,
tiktok: data?.Portofolio_MediaSosial?.tiktok, latitude: data?.BusinessMaps?.latitude,
youtube: data?.Portofolio_MediaSosial?.youtube longitude: data?.BusinessMaps?.longitude,
} imageId: data?.BusinessMaps?.imageId,
} pinId: data?.BusinessMaps?.pinId,
};
} else if (kategori == "sosmed") {
const data = await prisma.portofolio.findUnique({
where: {
id: id,
},
select: {
Portofolio_MediaSosial: {
select: {
facebook: true,
twitter: true,
instagram: true,
tiktok: true,
youtube: true,
},
},
},
});
return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", data: dataFix }, { status: 200 }); dataFix = {
facebook: data?.Portofolio_MediaSosial?.facebook,
twitter: data?.Portofolio_MediaSosial?.twitter,
instagram: data?.Portofolio_MediaSosial?.instagram,
tiktok: data?.Portofolio_MediaSosial?.tiktok,
youtube: data?.Portofolio_MediaSosial?.youtube,
};
}
} catch (error) { return NextResponse.json(
console.error(error); { success: true, message: "Berhasil mendapatkan data", data: dataFix },
return NextResponse.json({ success: false, message: "Gagal mendapatkan data, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); { status: 200 }
} );
} catch (error) {
console.error(error);
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data, coba lagi nanti (error: 500)",
reason: (error as Error).message,
},
{ status: 500 }
);
}
} }
// DELETE ONE DATA PORTOFOLIO // DELETE ONE DATA PORTOFOLIO
export async function DELETE(request: Request, context: { params: { id: string } }) { export async function DELETE(
try { request: Request,
const { id } = context.params context: { params: { id: string } }
) {
try {
const { id } = context.params;
const data = await prisma.portofolio.findUnique({ const data = await prisma.portofolio.findUnique({
where: { where: {
id: id id: id,
} },
}) include: {
BusinessMaps: {
select: {
pinId: true,
imageId: true,
},
},
},
});
const findLogo = await prisma.images.findFirst({ try {
where: { const id = data?.logoId;
id: String(data?.logoId), const deleteLogo = await fetch(
}, `https://wibu-storage.wibudev.com/api/files/${id}/delete`,
select: { {
id: true, method: "DELETE",
url: true, headers: {
}, Authorization: `Bearer ${process.env.WS_APIKEY}`,
}); },
}
);
if (findLogo) { if (deleteLogo.ok) {
fs.unlinkSync(`./public/portofolio/logo/${findLogo.url}`) backendLogger.info(`Success delete logo`);
const deleteLogo = await prisma.images.delete({
where: {
id: String(findLogo?.id),
},
});
} }
if (data?.BusinessMaps?.pinId != null) {
const pinId = data?.BusinessMaps?.pinId;
const deletePin = await fetch(
`https://wibu-storage.wibudev.com/api/files/${pinId}/delete`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.WS_APIKEY}`,
},
}
);
if (deletePin.ok) {
backendLogger.info(`Success delete pin`);
}
const deletePortoMedsos = await prisma.portofolio_MediaSosial.delete({ const imageId = data?.BusinessMaps?.imageId;
where: { const deleteImage = await fetch(
portofolioId: id, `https://wibu-storage.wibudev.com/api/files/${imageId}/delete`,
}, {
}); method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.WS_APIKEY}`,
},
}
);
const deleteMap = await prisma.businessMaps.delete({ if (deleteImage.ok) {
where: { backendLogger.info(`Success delete image`);
portofolioId: id }
} }
}) } catch (error) {
backendLogger.error("Error delete logo", error);
}
const deletePortofolio = await prisma.portofolio.delete({ const deletePortoMedsos = await prisma.portofolio_MediaSosial.delete({
where: { where: {
id: id, portofolioId: id,
}, },
}); });
return NextResponse.json({ success: true, message: "Berhasil menghapus data" }, { status: 200 }); const deleteMap = await prisma.businessMaps.delete({
where: {
portofolioId: id,
},
});
} catch (error) { const deletePortofolio = await prisma.portofolio.delete({
console.error(error); where: {
return NextResponse.json({ success: false, message: "Gagal menghapus data, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); id: id,
} },
} });
return NextResponse.json(
{ success: true, message: "Berhasil menghapus data" },
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json(
{
success: false,
message: "Gagal menghapus data, coba lagi nanti (error: 500)",
reason: (error as Error).message,
},
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,33 @@
import { decrypt } from "@/app/auth/_lib/decrypt";
import { prisma } from "@/app/lib";
import { cookies } from 'next/headers'
import { NextRequest, NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET(req: NextRequest) {
const token = req.headers.get('Authorization')?.split(' ')[1];
const decripted = await decrypt({
token: token!,
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!
})
if (!decripted) {
return NextResponse.json({
success: false,
message: "Unauthorized"
}, { status: 401 })
}
const user = await prisma.user.findUnique({
where: {
id: decripted.id
}
})
return NextResponse.json({
success: true,
message: "Berhasil mendapatkan data",
data: user
})
}

View File

@@ -0,0 +1,53 @@
import { prisma } from "@/app/lib";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET(request: Request) {
try {
let fixData
const userLoginId = await funGetUserIdByToken();
if (userLoginId == null) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data, user id tidak ada",
},
{ status: 500 }
);
}
const activationUser = await prisma.user.findFirst({
where: {
id: userLoginId,
},
select: {
active: true,
},
});
fixData = activationUser?.active
return NextResponse.json(
{
success: true,
message: "Berhasil mendapatkan data",
data: fixData,
},
{ status: 200 }
);
} catch (error) {
backendLogger.error("Error get activation user: ", error);
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan data",
reason: (error as Error).message,
},
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,24 @@
import { decrypt } from "@/app/auth/_lib/decrypt";
import _ from "lodash";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET() {
// const data = await req.text();
// console.log(data);
const c = cookies().get(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!);
if (!c || !c?.value || _.isEmpty(c?.value) || _.isUndefined(c?.value)) {
return NextResponse.json({ status: 401, message: "Unauthorized" });
}
const token = c.value;
const dataUser = await decrypt({
token: token,
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
});
return NextResponse.json({ status: 200, message: "OK", data: dataUser });
}

View File

@@ -1,11 +1,12 @@
import { decrypt } from "@/app/auth/_lib/decrypt"; import { decrypt } from "@/app/auth/_lib/decrypt";
import _ from "lodash"; import _ from "lodash";
import { cookies } from "next/headers"; import { cookies } from "next/headers";
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
export const dynamic = "force-dynamic";
export async function GET() { export async function GET() {
// const data = await req.text();
// console.log(data);
const c = cookies().get(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!); const c = cookies().get(process.env.NEXT_PUBLIC_BASE_SESSION_KEY!);
if (!c || !c?.value || _.isEmpty(c?.value) || _.isUndefined(c?.value)) { if (!c || !c?.value || _.isEmpty(c?.value) || _.isUndefined(c?.value)) {
@@ -18,5 +19,7 @@ export async function GET() {
encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!, encodedKey: process.env.NEXT_PUBLIC_BASE_TOKEN_KEY!,
}); });
return NextResponse.json({ status: 200, message: "OK", data: dataUser }); const id = dataUser?.id
return NextResponse.json({ status: 200, message: "OK", data: id });
} }

View File

@@ -1,9 +1,11 @@
import { NextResponse } from "next/server"; import { NextResponse } from "next/server";
export async function GET(req: Request) { export async function GET(req: Request) {
const auth = req.headers.get("Authorization"); const auth = req.headers.get("Authorization");
const token = auth?.split(" ")[1]; const token = auth?.split(" ")[1];
if (!token) return NextResponse.json({ success: false }, { status: 401 }); if (!token) return NextResponse.json({ success: false }, { status: 401 });
return NextResponse.json({ success: true });
return NextResponse.json({ success: true });
} }

View File

@@ -15,6 +15,8 @@ export default async function Page({ params }: { params: { id: string } }) {
"ProjectCollaboration", "ProjectCollaboration",
"ProjectCollaboration_AnggotaRoomChat", "ProjectCollaboration_AnggotaRoomChat",
]); ]);
let listMsg = await colab_getMessageByRoomId({ roomId: roomId, page: 1 }); let listMsg = await colab_getMessageByRoomId({ roomId: roomId, page: 1 });
const dataUserLogin = await user_getOneByUserId(userLoginId as string); const dataUserLogin = await user_getOneByUserId(userLoginId as string);

View File

@@ -1,14 +1,9 @@
import prisma from "@/app/lib/prisma";
import { Colab_DetailInfoGrup } from "@/app_modules/colab"; import { Colab_DetailInfoGrup } from "@/app_modules/colab";
import colab_getListAnggotaByRoomId from "@/app_modules/colab/fun/get/room_chat/get_list_anggota_by_room_id";
export default async function Page({ params }: { params: { id: string } }) {
let roomId = params.id;
const dataRoom = await colab_getListAnggotaByRoomId(roomId);
export default async function Page() {
return ( return (
<> <>
<Colab_DetailInfoGrup dataRoom={dataRoom as any} /> <Colab_DetailInfoGrup />
</> </>
); );
} }

View File

@@ -1,24 +1,13 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { Colab_MainDetail } from "@/app_modules/colab"; import { Colab_MainDetail } from "@/app_modules/colab";
import colab_funCekPartisipasiById from "@/app_modules/colab/fun/get/cek_partisipasi_by_user_id";
import colab_getListPartisipanByColabId from "@/app_modules/colab/fun/get/get_list_partisipan_by_id";
import colab_getOneCollaborationById from "@/app_modules/colab/fun/get/get_one_by_id";
export default async function Page({ params }: { params: { id: string } }) { export default async function Page() {
let colabId = params.id;
const userLoginId = await funGetUserIdByToken(); const userLoginId = await funGetUserIdByToken();
const dataColab = await colab_getOneCollaborationById(colabId);
const listPartisipan = await colab_getListPartisipanByColabId(colabId);
const cekPartisipan = await colab_funCekPartisipasiById(colabId);
return ( return (
<> <>
<Colab_MainDetail <Colab_MainDetail
dataColab={dataColab as any}
userLoginId={userLoginId as string} userLoginId={userLoginId as string}
listPartisipan={listPartisipan as any}
cekPartisipan={cekPartisipan}
/> />
</> </>
); );

View File

@@ -3,7 +3,9 @@ import { LayoutColab_DetailPartisipasiProyek } from "@/app_modules/colab";
export default async function Layout({ children }: { children: any }) { export default async function Layout({ children }: { children: any }) {
return ( return (
<> <>
<LayoutColab_DetailPartisipasiProyek>{children}</LayoutColab_DetailPartisipasiProyek> <LayoutColab_DetailPartisipasiProyek>
{children}
</LayoutColab_DetailPartisipasiProyek>
</> </>
); );
} }

View File

@@ -1,18 +1,9 @@
import { Colab_DetailPartisipasiProyek } from "@/app_modules/colab"; import { Colab_DetailPartisipasiProyek } from "@/app_modules/colab";
import colab_getListPartisipanByColabId from "@/app_modules/colab/fun/get/get_list_partisipan_by_id";
import colab_getOneCollaborationById from "@/app_modules/colab/fun/get/get_one_by_id";
export default async function Page({params}: {params: {id: string}}) {
const colabId = params.id
const dataColab = await colab_getOneCollaborationById(colabId)
const listPartisipan = await colab_getListPartisipanByColabId(colabId)
export default async function Page() {
return ( return (
<> <>
<Colab_DetailPartisipasiProyek <Colab_DetailPartisipasiProyek />
dataColab={dataColab as any}
listPartisipan={listPartisipan as any}
/>
</> </>
); );
} }

View File

@@ -3,19 +3,12 @@ import React from "react";
export default async function Layout({ export default async function Layout({
children, children,
params,
}: { }: {
children: React.ReactNode; children: React.ReactNode;
params: { id: string };
}) { }) {
let colabId = params.id;
return ( return (
<> <>
<LayoutColab_DetailProyekSaya colabId={colabId}> <LayoutColab_DetailProyekSaya>{children}</LayoutColab_DetailProyekSaya>
{children}
</LayoutColab_DetailProyekSaya>
</> </>
); );
} }

View File

@@ -1,19 +1,9 @@
import { Colab_DetailProyekSaya } from "@/app_modules/colab"; import { Colab_DetailProyekSaya } from "@/app_modules/colab";
import colab_getListPartisipanByColabId from "@/app_modules/colab/fun/get/get_list_partisipan_by_id";
import colab_getOneCollaborationById from "@/app_modules/colab/fun/get/get_one_by_id";
export default async function Page({ params }: { params: { id: string } }) {
const colabId = params.id;
const dataColab = await colab_getOneCollaborationById(colabId);
const listPartisipan = await colab_getListPartisipanByColabId(colabId);
export default async function Page() {
return ( return (
<> <>
{/* <pre>{JSON.stringify(listPartisipan, null,2)}</pre> */} <Colab_DetailProyekSaya />
<Colab_DetailProyekSaya
dataColab={dataColab as any}
listPartisipan={listPartisipan as any}
/>
</> </>
); );
} }

View File

@@ -1,14 +1,12 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get"; import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { Colab_Beranda } from "@/app_modules/colab"; import { Colab_Beranda } from "@/app_modules/colab";
import colab_getListAllProyek from "@/app_modules/colab/fun/get/get_list_all_proyek";
export default async function Page() { export default async function Page() {
const listData = await colab_getListAllProyek({ page: 1 });
const userLoginId = await funGetUserIdByToken(); const userLoginId = await funGetUserIdByToken();
return ( return (
<> <>
<Colab_Beranda listData={listData as any} userLoginId={userLoginId as string} /> <Colab_Beranda userLoginId={userLoginId as string} />
</> </>
); );
} }

View File

@@ -1,12 +1,10 @@
import colab_getListRoomChatByAuthorId from "@/app_modules/colab/fun/get/room_chat/get_list_room_by_author_id";
import Colab_GrupDiskus from "@/app_modules/colab/main/grup"; import Colab_GrupDiskus from "@/app_modules/colab/main/grup";
export default async function Page() { export default async function Page() {
const listRoom = await colab_getListRoomChatByAuthorId({page: 1}); // const listRoom = await colab_getListRoomChatByAuthorId({page: 1});
return ( return (
<> <>
<Colab_GrupDiskus listRoom={listRoom as any} /> <Colab_GrupDiskus />
</> </>
); );
} }

View File

@@ -1,17 +1,12 @@
import { Colab_Proyek } from "@/app_modules/colab"; import { Colab_Proyek } from "@/app_modules/colab";
import colab_getListPartisipasiProyekByAuthorId from "@/app_modules/colab/fun/get/pasrtisipan/get_list_partisipasi_proyek_by_author_id";
import colab_getListAllProyekSayaByAuthorId from "@/app_modules/colab/fun/get/pasrtisipan/get_list_proyek_saya_by_author_id";
export default async function Page() { export default async function Page() {
const listPartisipasiProyek = await colab_getListPartisipasiProyekByAuthorId({page: 1}) // const listPartisipasiProyek = await colab_getListPartisipasiProyekByAuthorId({page: 1})
const listProyekSaya = await colab_getListAllProyekSayaByAuthorId({page: 1}) // const listProyekSaya = await colab_getListAllProyekSayaByAuthorId({page: 1})
return ( return (
<> <>
<Colab_Proyek <Colab_Proyek />
listPartisipasiUser={listPartisipasiProyek as any}
listProyekSaya={listProyekSaya as any}
/>
</> </>
); );
} }

View File

@@ -4,6 +4,7 @@ import { Donasi_getOneById } from "@/app_modules/donasi/fun/get/get_one_donasi_b
export default async function Page({ params }: { params: { id: string } }) { export default async function Page({ params }: { params: { id: string } }) {
const donasiId = params.id const donasiId = params.id
const dataDonasi = await Donasi_getOneById(donasiId); const dataDonasi = await Donasi_getOneById(donasiId);
return ( return (
<> <>

View File

@@ -1,24 +1,12 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { LayoutKatalogNew } from "@/app_modules/katalog/main"; import { LayoutKatalogNew } from "@/app_modules/katalog/main";
export default async function Layout({ children, params, }: { children: any; params: { id: string } }) { export default async function Layout({ children }: { children: any }) {
// const profileId = params.id; const userLoginId = await funGetUserIdByToken();
// const dataProfile = await Profile_getOneProfileAndUserById(profileId);
// const authorId = dataProfile?.userId;
// const userLoginId = await funGetUserIdByToken();
// const userRoleId = dataProfile?.User?.masterUserRoleId;
return ( return (
<> <>
{/* <KatalogLayout <LayoutKatalogNew userLoginId={userLoginId}>{children}</LayoutKatalogNew>
profileId={profileId}
userLoginId={userLoginId as string}
authorId={authorId as any}
userRoleId={userRoleId as string}
>
{children}
</KatalogLayout> */}
<LayoutKatalogNew>{children}</LayoutKatalogNew>
</> </>
); );
} }

View File

@@ -1,20 +1,8 @@
import { ViewKatalogNew } from "@/app_modules/katalog"; import { ViewKatalogNew } from "@/app_modules/katalog";
export default async function Page({ params }: { params: { id: string } }) { export default async function Page() {
// let profileId = params.id;
// const userLoginId = await funGetUserIdByToken();
// const listPorto = await funGetListPortofolio(profileId);
// const dataProfile = await Profile_getOneProfileAndUserById(profileId);
return ( return (
<> <>
{/* <Katalog_MainView
profile={dataProfile as any}
listPorto={listPorto as any}
userLoginId={userLoginId as any}
/> */}
<ViewKatalogNew /> <ViewKatalogNew />
</> </>
); );

View File

@@ -1,16 +1,8 @@
import { ListDetailPortofolioNew } from "@/app_modules/katalog/portofolio"; import { ListDetailPortofolioNew } from "@/app_modules/katalog/portofolio";
export default async function Page({ params }: { params: { id: string } }) { export default async function Page() {
// const profileId = params.id;
// const dataPortofolio = await portofolio_funGetAllDaftarByid({
// profileId,
// page: 1,
// });
return ( return (
<> <>
{/* <Portofolio_ViewListDetail dataPortofolio={dataPortofolio as any} profileId={profileId} /> */}
<ListDetailPortofolioNew /> <ListDetailPortofolioNew />
</> </>
); );

View File

@@ -1,20 +1,14 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { PortofolioLayoutNew } from "@/app_modules/katalog/portofolio"; import { PortofolioLayoutNew } from "@/app_modules/katalog/portofolio";
export default async function Layout({ children, params, }: { children: any; params: { id: string }; }) { export default async function Layout({ children, }: { children: any; }) {
// let portoId = params.id; const userLoginId = await funGetUserIdByToken();
// const getPorto = await portofolio_getOneById(portoId);
// const userLoginId = await funGetUserIdByToken();
return ( return (
<> <>
{/* <PortofolioLayout <PortofolioLayoutNew userLoginId={userLoginId}>
portoId={portoId}
userLoginId={userLoginId as string}
authorId={getPorto?.Profile?.User?.id as any}
>
{children} {children}
</PortofolioLayout> */} </PortofolioLayoutNew>
<PortofolioLayoutNew>{children}</PortofolioLayoutNew>
</> </>
); );
} }

View File

@@ -1,19 +1,16 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { Portofolio_UiDetailNew } from "@/app_modules/katalog/portofolio"; import { Portofolio_UiDetailNew } from "@/app_modules/katalog/portofolio";
const mapboxToken = process.env.MAPBOX_TOKEN!; const mapboxToken = process.env.MAPBOX_TOKEN!;
export default async function Page({ params }: { params: { id: string } }) { export default async function Page() {
// const portofolioId = params.id; const userLoginId = await funGetUserIdByToken()
// const dataPortofolio = await portofolio_getOneById(portofolioId);
// const userLoginId = await funGetUserIdByToken();
return ( return (
<> <>
{/* <ViewPortofolio <Portofolio_UiDetailNew
dataPorto={dataPortofolio as any}
userLoginId={userLoginId as any}
mapboxToken={mapboxToken} mapboxToken={mapboxToken}
/> */} userLoginId={userLoginId}
<Portofolio_UiDetailNew mapboxToken={mapboxToken} /> />
</> </>
); );
} }

View File

@@ -1,13 +1,9 @@
import { Vote_DetailKontribusi } from "@/app_modules/vote"; import { Vote_DetailKontribusi } from "@/app_modules/vote";
import { voting_funGetOneVotingbyId } from "@/app_modules/vote/fun/get/fun_get_one_by_id";
export default async function Page({ params }: { params: { id: string } }) {
let voteId = params.id;
const dataVote = await voting_funGetOneVotingbyId(voteId);
export default async function Page() {
return ( return (
<> <>
<Vote_DetailKontribusi dataVote={dataVote as any} /> <Vote_DetailKontribusi />
</> </>
); );
} }

View File

@@ -2,7 +2,6 @@ import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { Vote_MainDetail } from "@/app_modules/vote"; import { Vote_MainDetail } from "@/app_modules/vote";
export default async function Page({ params }: { params: { id: string } }) { export default async function Page({ params }: { params: { id: string } }) {
const voteId = params.id;
const userLoginId = await funGetUserIdByToken(); const userLoginId = await funGetUserIdByToken();
return ( return (
<> <>

View File

@@ -1,19 +1,9 @@
import { Vote_DetailSemuaRiwayat } from "@/app_modules/vote"; import { Vote_DetailSemuaRiwayat } from "@/app_modules/vote";
import { Vote_getListKontributorById } from "@/app_modules/vote/fun/get/get_list_kontributor_by_id";
import { Vote_getOnePublishbyId } from "@/app_modules/vote/fun/get/get_one_publish_by_id";
export default async function Page({params}: {params: {id: string}}) {
let voteId = params.id
const dataVote = await Vote_getOnePublishbyId(voteId)
const listKontributor = await Vote_getListKontributorById(voteId)
export default async function Page() {
return ( return (
<> <>
<Vote_DetailSemuaRiwayat <Vote_DetailSemuaRiwayat />
dataVote={dataVote as any}
listKontributor={listKontributor as any}
/>
</> </>
); );
} }

View File

@@ -19,27 +19,30 @@ export type ITypeStatusNotifikasi =
| "Menunggu" | "Menunggu"
| "Gagal"; | "Gagal";
/** /**
* @param kategoriApp | "JOB", "VOTING", "EVENT", "DONASI", "INVESTASI", "COLLABORATION", "FORUM" * @param kategoriApp | "JOB", "VOTING", "EVENT", "DONASI", "INVESTASI", "COLLABORATION", "FORUM"
* @type string * @type string
*/ */
export type IRealtimeData = { export type IRealtimeData = {
status?: ITypeStatusNotifikasi; status?: ITypeStatusNotifikasi;
appId: string; appId?: string;
userId: string; userId: string;
pesan: string; pesan?: string;
title: string; title?: string;
kategoriApp: kategoriApp?:
| "JOB" | "JOB"
| "VOTING" | "VOTING"
| "EVENT" | "EVENT"
| "DONASI" | "DONASI"
| "INVESTASI" | "INVESTASI"
| "COLLABORATION" | "COLLABORATION"
| "FORUM"; | "FORUM"
| "ACCESS"; // Untuk trigger akses user
}; };
// Access User
export const gs_access_user = atom<boolean>(false);
export const gs_realtimeData = atom<IRealtimeData | null>(null); export const gs_realtimeData = atom<IRealtimeData | null>(null);
export const gs_admin_ntf = atom<number>(0); export const gs_admin_ntf = atom<number>(0);
export const gs_user_ntf = atom<number>(0); export const gs_user_ntf = atom<number>(0);
@@ -63,4 +66,4 @@ export const gs_donasiTriggerBeranda = atom<boolean>(false);
// investasi // investasi
export const gs_adminInvestasi_triggerReview = atom<boolean>(false); export const gs_adminInvestasi_triggerReview = atom<boolean>(false);
export const gs_investasiTriggerBeranda = atom<boolean>(false); export const gs_investasiTriggerBeranda = atom<boolean>(false);

View File

@@ -1,6 +1,6 @@
const DIRECTORY_ID = { const DIRECTORY_ID = {
profile_foto: "cm0x93rgo000jbp5tj8baoaus", profile_foto: "cm5ni43ub001pxpug0qw4p11e",
profile_background: "cm0x93ze8000lbp5t1a8uc9wl", profile_background: "cm5ni4hnq001l12p9gpagxgtv",
portofolio_logo: "cm0yjl6ug000310njwmk6j0tx", portofolio_logo: "cm0yjl6ug000310njwmk6j0tx",
map_pin: "cm0yjq8up000710njv5klra32", map_pin: "cm0yjq8up000710njv5klra32",
map_image: "cm0yjqnxl000910njplqho07w", map_image: "cm0yjqnxl000910njplqho07w",

View File

@@ -4,6 +4,7 @@ import { useShallowEffect } from "@mantine/hooks";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { WibuRealtime } from "wibu-pkg"; import { WibuRealtime } from "wibu-pkg";
import { import {
gs_access_user,
gs_admin_ntf, gs_admin_ntf,
gs_adminDonasi_triggerReview, gs_adminDonasi_triggerReview,
gs_adminEvent_triggerReview, gs_adminEvent_triggerReview,
@@ -31,6 +32,9 @@ export type TypeNotification = {
userId?: string; userId?: string;
}; };
// Tambahkan flag global untuk mencegah inisialisasi ulang
let isWibuRealtimeInitialized = false;
export default function RealtimeProvider({ export default function RealtimeProvider({
userId, userId,
WIBU_REALTIME_TOKEN, WIBU_REALTIME_TOKEN,
@@ -42,6 +46,9 @@ export default function RealtimeProvider({
const [newAdminNtf, setNewAdminNtf] = useAtom(gs_admin_ntf); const [newAdminNtf, setNewAdminNtf] = useAtom(gs_admin_ntf);
const [newUserNtf, setNewUserNtf] = useAtom(gs_user_ntf); const [newUserNtf, setNewUserNtf] = useAtom(gs_user_ntf);
// ACCESS USER
const [isAccessUser, setIsAccessUser] = useAtom(gs_access_user);
// JOB // JOB
const [isTriggerJobBeranda, setIsTriggerJobBeranda] = const [isTriggerJobBeranda, setIsTriggerJobBeranda] =
useAtom(gs_jobTiggerBeranda); useAtom(gs_jobTiggerBeranda);
@@ -83,152 +90,168 @@ export default function RealtimeProvider({
useShallowEffect(() => { useShallowEffect(() => {
try { try {
WibuRealtime.init({ if (!isWibuRealtimeInitialized) {
project: "hipmi", WibuRealtime.init({
WIBU_REALTIME_TOKEN: WIBU_REALTIME_TOKEN, project: "hipmi",
onData(data: TypeNotification) { WIBU_REALTIME_TOKEN: WIBU_REALTIME_TOKEN,
if ( onData(data: TypeNotification) {
data.type == "notification" && // Notifikasi ke admin
data.pushNotificationTo == "ADMIN" if (
) { data.type == "notification" &&
setNewAdminNtf((e) => e + 1); data.pushNotificationTo == "ADMIN"
} ) {
setNewAdminNtf((e) => e + 1);
}
// Notifikasi ke semua user , yang datanya di acc admin // trigger access
if ( if (
data.type == "notification" && data.type == "trigger" &&
data.pushNotificationTo == "USER" && data.pushNotificationTo == "USER" &&
data.dataMessage?.userId == userId data.dataMessage?.kategoriApp == "ACCESS" &&
) { data.dataMessage?.userId == userId
setNewUserNtf((e) => e + 1); ) {
setDataRealtime(data.dataMessage as any); setIsAccessUser(data.dataMessage.status as any);
} }
// ---------------------- JOB ------------------------- // // Notifikasi ke semua user , yang datanya di acc admin
if ( if (
data.type == "trigger" && data.type == "notification" &&
data.pushNotificationTo == "ADMIN" && data.pushNotificationTo == "USER" &&
data.dataMessage?.kategoriApp == "JOB" data.dataMessage?.userId == userId
) { ) {
setIsAdminJob_TriggerReview(true); setNewUserNtf((e) => e + 1);
} setDataRealtime(data.dataMessage as any);
}
if ( // ---------------------- JOB ------------------------- //
data.type == "trigger" && if (
data.pushNotificationTo == "USER" && data.type == "trigger" &&
data.dataMessage?.kategoriApp == "JOB" && data.pushNotificationTo == "ADMIN" &&
data.dataMessage.status == "Publish" data.dataMessage?.kategoriApp == "JOB"
) { ) {
setIsTriggerJobBeranda(true); setIsAdminJob_TriggerReview(true);
} }
// ---------------------- JOB ------------------------- //
// ---------------------- EVENT ------------------------- // if (
if ( data.type == "trigger" &&
data.type == "trigger" && data.pushNotificationTo == "USER" &&
data.pushNotificationTo == "ADMIN" && data.dataMessage?.kategoriApp == "JOB" &&
data.dataMessage?.kategoriApp == "EVENT" data.dataMessage.status == "Publish"
) { ) {
setIsAdminEvent_TriggerReview(true); setIsTriggerJobBeranda(true);
} }
// ---------------------- JOB ------------------------- //
if ( // ---------------------- EVENT ------------------------- //
data.type == "trigger" && if (
data.pushNotificationTo == "USER" && data.type == "trigger" &&
data.dataMessage?.kategoriApp == "EVENT" && data.pushNotificationTo == "ADMIN" &&
data.dataMessage.status == "Publish" data.dataMessage?.kategoriApp == "EVENT"
) { ) {
setIsTriggerEventBeranda(true); setIsAdminEvent_TriggerReview(true);
} }
if ( if (
data.type == "notification" && data.type == "trigger" &&
data.pushNotificationTo == "USER" && data.pushNotificationTo == "USER" &&
data.dataMessage?.status == "Peserta Event" && data.dataMessage?.kategoriApp == "EVENT" &&
userId !== data.dataMessage?.userId data.dataMessage.status == "Publish"
) { ) {
setNewUserNtf((e) => e + 1); setIsTriggerEventBeranda(true);
} }
// ---------------------- EVENT ------------------------- //
// ---------------------- VOTING ------------------------- // if (
if ( data.type == "notification" &&
data.type == "trigger" && data.pushNotificationTo == "USER" &&
data.pushNotificationTo == "ADMIN" && data.dataMessage?.status == "Peserta Event" &&
data.dataMessage?.kategoriApp == "VOTING" userId !== data.dataMessage?.userId
) { ) {
setIsAdminVoting_TriggerReview(true); setNewUserNtf((e) => e + 1);
} }
// ---------------------- EVENT ------------------------- //
if ( // ---------------------- VOTING ------------------------- //
data.type == "trigger" && if (
data.pushNotificationTo == "USER" && data.type == "trigger" &&
data.dataMessage?.kategoriApp == "VOTING" && data.pushNotificationTo == "ADMIN" &&
data.dataMessage.status == "Publish" data.dataMessage?.kategoriApp == "VOTING"
) { ) {
setIsTriggerVotingBeranda(true); setIsAdminVoting_TriggerReview(true);
} }
if ( if (
data.type == "notification" && data.type == "trigger" &&
data.pushNotificationTo == "USER" && data.pushNotificationTo == "USER" &&
data.dataMessage?.status == "Voting Masuk" && data.dataMessage?.kategoriApp == "VOTING" &&
userId !== data.dataMessage?.userId data.dataMessage.status == "Publish"
) { ) {
setNewUserNtf((e) => e + 1); setIsTriggerVotingBeranda(true);
} }
// ---------------------- VOTING ------------------------- //
// ---------------------- DONASI ------------------------- // if (
if ( data.type == "notification" &&
data.type == "trigger" && data.pushNotificationTo == "USER" &&
data.pushNotificationTo == "ADMIN" && data.dataMessage?.status == "Voting Masuk" &&
data.dataMessage?.kategoriApp == "DONASI" userId !== data.dataMessage?.userId
) { ) {
setIsAdminDonasi_TriggerReview(true); setNewUserNtf((e) => e + 1);
} }
// ---------------------- VOTING ------------------------- //
if ( // ---------------------- DONASI ------------------------- //
data.type == "trigger" && if (
data.pushNotificationTo == "USER" && data.type == "trigger" &&
data.dataMessage?.kategoriApp == "DONASI" && data.pushNotificationTo == "ADMIN" &&
data.dataMessage.status == "Publish" data.dataMessage?.kategoriApp == "DONASI"
) { ) {
setIsTriggerDonasiBeranda(true); setIsAdminDonasi_TriggerReview(true);
} }
// if ( if (
// data.type == "notification" && data.type == "trigger" &&
// data.pushNotificationTo == "ADMIN" && data.pushNotificationTo == "USER" &&
// data.dataMessage?.status == "Menunggu" && data.dataMessage?.kategoriApp == "DONASI" &&
// userId !== data.dataMessage?.userId data.dataMessage.status == "Publish"
// ) { ) {
setIsTriggerDonasiBeranda(true);
}
// } // if (
// ---------------------- DONASI ------------------------- // // data.type == "notification" &&
// data.pushNotificationTo == "ADMIN" &&
// data.dataMessage?.status == "Menunggu" &&
// userId !== data.dataMessage?.userId
// ) {
// ---------------------- INVESTASI ------------------------- // // }
// ---------------------- DONASI ------------------------- //
if ( // ---------------------- INVESTASI ------------------------- //
data.type == "trigger" &&
data.pushNotificationTo == "ADMIN" &&
data.dataMessage?.kategoriApp == "INVESTASI"
) {
setIsAdminInvestasi_TriggerReview(true);
}
if ( if (
data.type == "trigger" && data.type == "trigger" &&
data.pushNotificationTo == "USER" && data.pushNotificationTo == "ADMIN" &&
data.dataMessage?.kategoriApp == "INVESTASI" && data.dataMessage?.kategoriApp == "INVESTASI"
data.dataMessage.status == "Publish" ) {
) { setIsAdminInvestasi_TriggerReview(true);
setIsTriggerInvestasiBeranda(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) { } catch (error) {
console.log("Error Realtime:", error); console.log("Error Realtime:", error);
} }

View File

@@ -8,8 +8,8 @@ export const NEW_RouterInvestasi = {
* @param param status id | 1: Publish, 2: Review, 3: Draft, 4: Reject * @param param status id | 1: Publish, 2: Review, 3: Draft, 4: Reject
* @type string * @type string
*/ */
portofolio: ({ id }: { id: "1" | "2" | "3" | "4" }) => portofolio: ({ id }: { id: "1" | "2" | "3" | "4" }) => `/dev/investasi/main/portofolio/${id}`,
`/dev/investasi/main/portofolio/${id}`, // portofolio: ({ id }: { id?: string }) => `/dev/investasi/main/portofolio/${id}`,
// TRANSAKSI // TRANSAKSI
pembelian: "/dev/investasi/transaksi/pembelian/", pembelian: "/dev/investasi/transaksi/pembelian/",

View File

@@ -5,7 +5,8 @@ import {
UIGlobal_LayoutHeaderTamplate, UIGlobal_LayoutHeaderTamplate,
UIGlobal_LayoutTamplate, UIGlobal_LayoutTamplate,
} from "@/app_modules/_global/ui"; } from "@/app_modules/_global/ui";
import { Center, Grid, Group, Skeleton, Stack } from "@mantine/core"; import { Button, Grid, Skeleton, Stack } from "@mantine/core";
import Link from "next/link";
export default function Voting_ComponentSkeletonViewPuh() { export default function Voting_ComponentSkeletonViewPuh() {
return ( return (
@@ -13,8 +14,44 @@ export default function Voting_ComponentSkeletonViewPuh() {
<UIGlobal_LayoutTamplate <UIGlobal_LayoutTamplate
header={<UIGlobal_LayoutHeaderTamplate title="Skeleton Maker" />} header={<UIGlobal_LayoutHeaderTamplate title="Skeleton Maker" />}
> >
<Button
>
<Link
color="white"
style={{
color: "white",
textDecoration: "none",
}}
target="_blank"
href={
"https://wa.me/+6281339158911?text=Hallo , Apa boleh saya minta informasi tentang DariBaliMice?"
}
>
{" "}
Kirim
</Link>
</Button>
<Stack> <Stack>
<ComponentGlobal_CardStyles marginBottom={"0"}> <ComponentGlobal_CardStyles marginBottom={"0"}>
<Stack>
<Skeleton h={20} w={100} />
{Array.from(new Array(2)).map((e, i) => (
<Grid align="center" gutter={"md"} key={i}>
<Grid.Col span={"content"}>
<Skeleton circle height={40} />
</Grid.Col>
<Grid.Col span={3}>
<Skeleton height={20} w={150} />
</Grid.Col>
</Grid>
))}
</Stack>
</ComponentGlobal_CardStyles>
{/* <ComponentGlobal_CardStyles marginBottom={"0"}>
<Stack spacing={"xl"}> <Stack spacing={"xl"}>
<Grid align="center" gutter={"md"}> <Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}> <Grid.Col span={"content"}>
@@ -23,12 +60,35 @@ export default function Voting_ComponentSkeletonViewPuh() {
<Grid.Col span={3}> <Grid.Col span={3}>
<Skeleton height={20} w={150} /> <Skeleton height={20} w={150} />
</Grid.Col> </Grid.Col>
<Grid.Col span={3} offset={3}> </Grid>
<Skeleton height={20} w={150} /> <Center>
<Skeleton height={15} w={200} />
</Center>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<Skeleton h={15} w={70} />
</Grid.Col>
<Grid.Col span={3}>
<Skeleton height={15} w={200} />
</Grid.Col> </Grid.Col>
</Grid> </Grid>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<Skeleton h={15} w={70} />
</Grid.Col>
<Grid.Col span={3}>
<Skeleton height={15} w={200} />
</Grid.Col>
</Grid>
<Skeleton height={15} w={100} />
<Skeleton height={15} w={"100%"} />
<Skeleton height={15} w={100} />
<Skeleton height={15} w={"100%"} />
</Stack> </Stack>
</ComponentGlobal_CardStyles> </ComponentGlobal_CardStyles> */}
{/* <ComponentGlobal_CardStyles> {/* <ComponentGlobal_CardStyles>
<Stack> <Stack>

View File

@@ -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 };
// }
}

View File

@@ -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 (
<>
<UIGlobal_LayoutTamplate
header={<UIGlobal_LayoutHeaderTamplate title="Upload" />}
>
<Upload />
</UIGlobal_LayoutTamplate>
</>
);
}
function Upload() {
const [file, setFile] = useState<File | null>(null);
const [image, setImage] = useState<any | null>(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 (
<>
<Stack>
<ComponentGlobal_BoxUploadImage>
{image ? (
<AspectRatio ratio={1 / 1} mt={5} maw={300} mx={"auto"}>
<Image style={{ maxHeight: 250 }} alt="Avatar" src={image} />
</AspectRatio>
) : (
<Center h={"100%"}>
<IconImageInPicture size={50} />
</Center>
)}
</ComponentGlobal_BoxUploadImage>
<Center>
<FileButton
onChange={async (files: any | null) => {
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) => (
<Button
{...props}
radius={"sm"}
leftIcon={<IconUpload />}
bg={MainColor.yellow}
color="yellow"
c={"black"}
>
Upload
</Button>
)}
</FileButton>
</Center>
<Button
loaderPosition="center"
loading={isLoading}
onClick={() => {
onUpload();
}}
>
Simpan
</Button>
</Stack>
</>
);
}

View File

@@ -1,12 +1,10 @@
"use client"; "use client";
import { clientLogger } from "@/util/clientLogger";
import { Button, FileButton } from "@mantine/core"; import { Button, FileButton } from "@mantine/core";
import { IconCamera } from "@tabler/icons-react"; import { IconCamera } from "@tabler/icons-react";
import { useState } from "react";
import { MainColor } from "../color"; import { MainColor } from "../color";
import { MAX_SIZE } from "../lib";
import { PemberitahuanMaksimalFile } from "../lib/max_size";
import { ComponentGlobal_NotifikasiPeringatan } from "../notif_global";
import { clientLogger } from "@/util/clientLogger";
export function ComponentGlobal_ButtonUploadFileImage({ export function ComponentGlobal_ButtonUploadFileImage({
onSetFile, onSetFile,
@@ -15,22 +13,27 @@ export function ComponentGlobal_ButtonUploadFileImage({
onSetFile: File | any; onSetFile: File | any;
onSetImage: any | null; onSetImage: any | null;
}) { }) {
const [isLoading, setIsLoading] = useState(false);
return ( return (
<FileButton <FileButton
onChange={async (files: any | null) => { onChange={async (files: any | null) => {
try { try {
setIsLoading(true);
const buffer = URL.createObjectURL( const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())]) new Blob([new Uint8Array(await files.arrayBuffer())])
); );
if (files.size > MAX_SIZE) { // if (files.size > MAX_SIZE) {
ComponentGlobal_NotifikasiPeringatan(PemberitahuanMaksimalFile); // ComponentGlobal_NotifikasiPeringatan(PemberitahuanMaksimalFile);
return; // return;
} else { // } else {
onSetFile(files); // }
onSetImage(buffer); onSetFile(files);
} onSetImage(buffer);
setIsLoading(false);
} catch (error) { } catch (error) {
setIsLoading(false);
clientLogger.error("Upload error:", error); clientLogger.error("Upload error:", error);
} }
}} }}
@@ -39,6 +42,8 @@ export function ComponentGlobal_ButtonUploadFileImage({
{(props) => ( {(props) => (
<Button <Button
{...props} {...props}
loading={isLoading}
loaderPosition="center"
radius={"xl"} radius={"xl"}
leftIcon={<IconCamera />} leftIcon={<IconCamera />}
bg={MainColor.yellow} bg={MainColor.yellow}

View File

@@ -3,8 +3,10 @@ export const MainColor = {
darkblue: "#001D3D", darkblue: "#001D3D",
yellow: "#E1B525", yellow: "#E1B525",
white: "#D4D0D0", white: "#D4D0D0",
red: "#C74E4E", red: "#FF4B4C",
orange: "#E58958" orange: "#FF7043",
green: "#4CAF4F",
login: "#EDEBEBFF"
}; };
export const AccentColor = { export const AccentColor = {
@@ -13,7 +15,11 @@ export const AccentColor = {
blue: "#00447D", blue: "#00447D",
softblue: "#007CBA", softblue: "#007CBA",
skyblue: "#00BFFF", skyblue: "#00BFFF",
yellow: "#E1B525", yellow: "#F8A824",
white: "#FEFFFE"
}; };
//yellow: "#FFC300" //yellow: "#FFC300"
//yellow: "#FFD60A" //yellow: "#FFD60A"
// white: "#FEFFFE"

View File

@@ -47,7 +47,7 @@ export function ComponentGlobal_AvatarAndUsername({
onClick={() => onCheckProfile()} onClick={() => onCheckProfile()}
> >
{visible ? ( {visible ? (
<Avatar radius={"xl"} size={40}> <Avatar radius={"xl"} size={40}>
<ComponentGlobal_Loader /> <ComponentGlobal_Loader />
</Avatar> </Avatar>
) : ( ) : (
@@ -63,7 +63,7 @@ export function ComponentGlobal_AvatarAndUsername({
<Text <Text
c={MainColor.white} c={MainColor.white}
fw={"bold"} fw={"bold"}
fz={fontSize ? fontSize : "sm"} fz={fontSize ? fontSize : "md"}
lineClamp={1} lineClamp={1}
onClick={() => onCheckProfile()} onClick={() => onCheckProfile()}
> >

View File

@@ -1,7 +1,21 @@
import { AccentColor } from "@/app_modules/_global/color"; import { AccentColor, MainColor } from "@/app_modules/_global/color";
import { Card } from "@mantine/core"; import { Card } from "@mantine/core";
import React from "react"; import React from "react";
/**
* ComponentGlobal_CardStyles
*
* A React component that renders a customizable card element.
*
* Props:
* - children (React.ReactNode): Content to be displayed inside the card.
* - backgroundColor (string, optional): Background color of the card. Defaults to AccentColor.darkblue.
* - border (string, optional): Border color of the card. Defaults to AccentColor.blue.
* - marginBottom (string | number, optional): Margin below the card. Defaults to "15px".
* - height (string | number, optional): Height of the card. Defaults to "auto".
* - color (string, optional): Text color inside the card. Defaults to MainColor.white.
* - onClickHandler (React.MouseEventHandler<HTMLDivElement>, optional): Function to handle click events on the card.
*/
export function ComponentGlobal_CardStyles({ export function ComponentGlobal_CardStyles({
children, children,
backgroundColor, backgroundColor,
@@ -30,7 +44,7 @@ export function ComponentGlobal_CardStyles({
paddingInline: "16px", paddingInline: "16px",
paddingBlock: "16px", paddingBlock: "16px",
borderRadius: "10px", borderRadius: "10px",
color: color ? color : "white", color: color ? color : MainColor.white,
height: height ? height : "auto", height: height ? height : "auto",
marginBottom: marginBottom ? marginBottom : "15px", marginBottom: marginBottom ? marginBottom : "15px",
}} }}

View File

@@ -3,10 +3,12 @@
import { APIs } from "@/app/lib"; import { APIs } from "@/app/lib";
import { pathAssetImage } from "@/app/lib/path_asset_image"; import { pathAssetImage } from "@/app/lib/path_asset_image";
import { RouterImagePreview } from "@/app/lib"; import { RouterImagePreview } from "@/app/lib";
import { Center, Image, Skeleton } from "@mantine/core"; import { Center, Image } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { MainColor } from "../color";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
export function ComponentGlobal_LoadImageLandscape({ export function ComponentGlobal_LoadImageLandscape({
fileId, fileId,
@@ -34,12 +36,12 @@ export function ComponentGlobal_LoadImageLandscape({
} }
} }
if (isImage === null) return <Skeleton h={200} w={"100%"} />; if (isImage === null) return <CustomSkeleton h={200} w={"100%"} />;
if (!isImage) if (!isImage)
return ( return (
<> <>
<Center h={200} bg={"white"} style={{ borderRadius: "5px" }}> <Center h={200} bg={MainColor.white} style={{ borderRadius: "5px", borderColor: MainColor.white }}>
<Image <Image
alt="No Image" alt="No Image"
maw={150} maw={150}

View File

@@ -1,4 +1,5 @@
import { Group, Text } from "@mantine/core"; import { Group, Text } from "@mantine/core";
import { MainColor } from "../color";
export default function ComponentGlobal_TampilanAngkaRatusan({ export default function ComponentGlobal_TampilanAngkaRatusan({
nominal, nominal,
@@ -32,7 +33,7 @@ export default function ComponentGlobal_TampilanAngkaRatusan({
fw={fontWeight ? fontWeight : "bold"} fw={fontWeight ? fontWeight : "bold"}
fz={fontSize ? fontSize : "md"} fz={fontSize ? fontSize : "md"}
style={{ style={{
color: color ? color : "white", color: color ? color : MainColor.white,
}} }}
> >
{new Intl.NumberFormat("id-ID", { maximumFractionDigits: 10 }).format( {new Intl.NumberFormat("id-ID", { maximumFractionDigits: 10 }).format(
@@ -43,6 +44,9 @@ export default function ComponentGlobal_TampilanAngkaRatusan({
<Text <Text
fw={fontWeight ? fontWeight : "bold"} fw={fontWeight ? fontWeight : "bold"}
fz={fontSize ? fontSize : "md"} fz={fontSize ? fontSize : "md"}
style={{
color: color ? color : MainColor.white,
}}
> >
{textAfter} {textAfter}
</Text> </Text>

View File

@@ -1,4 +1,5 @@
import { Text } from "@mantine/core"; import { Text } from "@mantine/core";
import { MainColor } from "../color";
export default function ComponentGlobal_TampilanRupiah({ export default function ComponentGlobal_TampilanRupiah({
nominal, nominal,
@@ -17,7 +18,7 @@ export default function ComponentGlobal_TampilanRupiah({
fw={fontWeight ? fontWeight : "bold"} fw={fontWeight ? fontWeight : "bold"}
fz={fontSize ? fontSize : "md"} fz={fontSize ? fontSize : "md"}
style={{ style={{
color: color ? color : "white", color: color ? color : MainColor.white,
}} }}
> >
Rp.{" "} Rp.{" "}

View File

@@ -22,29 +22,7 @@ export async function funGlobal_DeleteFileById({
return { success: false, message: data.message }; return { success: false, message: data.message };
} }
} catch (error) { } catch (error) {
console.error("Upload error:", error); clientLogger.error("Upload error:", error);
return { success: false, message: "An unexpected error occurred" }; return { success: false, message: "An unexpected error occurred" };
} }
// try {
// const res = await fetch(
// `https://wibu-storage.wibudev.com/api/files/${fileId}/delete`,
// {
// method: "DELETE",
// headers: {
// Authorization: `Bearer ${process.env.WS_APIKEY}`,
// },
// }
// );
// if (res.ok) {
// const hasil = await res.json();
// return { success: true, message: "File berhasil dihapus" };
// } else {
// const errorText = await res.json();
// return { success: false, message: errorText.message };
// }
// } catch (error) {
// console.error("Upload error:", error);
// return { success: false, message: "An unexpected error occurred" };
// }
} }

View File

@@ -1,6 +1,5 @@
"use server"; "use server";
import { jwtVerify } from "jose";
import { cookies } from "next/headers"; import { cookies } from "next/headers";
import { decrypt } from "../../../../app/auth/_lib/decrypt"; import { decrypt } from "../../../../app/auth/_lib/decrypt";
@@ -16,21 +15,3 @@ export async function funGetUserIdByToken() {
return cekUser?.id; return cekUser?.id;
} }
// async function decrypt({
// token,
// encodedKey,
// }: {
// token: string;
// encodedKey: string;
// }): Promise<Record<string, any> | null> {
// try {
// const enc = new TextEncoder().encode(encodedKey);
// const { payload } = await jwtVerify(token, enc, {
// algorithms: ["HS256"],
// });
// return (payload.user as Record<string, any>) || null;
// } catch (error) {
// console.error("Gagal verifikasi session", error);
// return null;
// }
// }

View File

@@ -10,6 +10,10 @@ export async function funGlobal_UploadToStorage({
const Env_WS_APIKEY = TokenStorage.value; const Env_WS_APIKEY = TokenStorage.value;
const allowedMimeTypes = [ const allowedMimeTypes = [
"image/heif", // Format HEIF standar
"image/heic", // Format HEIF untuk container HEIC
"image/heif-sequence", // Untuk sequence/animasi HEIF
"image/heic-sequence", // Untuk sequence/animasi HEIC
"image/png", "image/png",
"image/jpeg", "image/jpeg",
"image/gif", "image/gif",

View File

@@ -0,0 +1,16 @@
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

@@ -0,0 +1,39 @@
export const apiGetUserId = async () => {
const { token } = await fetch("/api/get-cookie").then((res) => res.json());
if (!token) return await token.json().catch(() => null);
const response = await fetch(`/api/user`, {
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"Access-Control-Allow-Origin": "*",
Authorization: `Bearer ${token}`,
},
});
console.log("Ini di pemanggilan API",await response.json());
if (!response.ok) return null;
const data: Record<string, any> = await response.json();
return data;
};
export const apiGetCookiesUser = async () => {
const response = await fetch(`/api/user/get`);
return await response.json().catch(() => null);
};
export const apiGetACtivationUser = async () => {
const { token } = await fetch("/api/get-cookie").then((res) => res.json());
if (!token) return await token.json().catch(() => null);
const response = await fetch(`/api/user/activation`, {
headers: {
"Content-Type": "application/json",
Accept: "application/json",
"Access-Control-Allow-Origin": "*",
Authorization: `Bearer ${token}`,
},
});
return await response.json().catch(() => null);
};

View File

@@ -64,7 +64,7 @@ export default function UIGlobal_Drawer({
borderRight: `1px solid ${AccentColor.blue}`, borderRight: `1px solid ${AccentColor.blue}`,
borderLeft: `1px solid ${AccentColor.blue}`, borderLeft: `1px solid ${AccentColor.blue}`,
borderRadius: "20px 20px 0px 0px", borderRadius: "20px 20px 0px 0px",
color: "white", color: MainColor.white,
paddingBottom: "5%", paddingBottom: "5%",
}, },
}} }}
@@ -86,7 +86,7 @@ export default function UIGlobal_Drawer({
> >
<ActionIcon <ActionIcon
variant="transparent" variant="transparent"
c="white" c={MainColor.white}
> >
{/* PAKE LOADING */} {/* PAKE LOADING */}
{/* {isLoading && e?.id === pageId ? ( {/* {isLoading && e?.id === pageId ? (

View File

@@ -44,7 +44,7 @@ export default function AdminDeveloper({
return ( return (
<> <>
<Stack> <Stack>
<ComponentAdminGlobal_HeaderTamplate name="Developer" /> <ComponentAdminGlobal_HeaderTamplate name="Super Admin" />
<SimpleGrid cols={2} spacing={50}> <SimpleGrid cols={2} spacing={50}>
{/* <TableAdmin {/* <TableAdmin
dataAdmin={dataAdmin} dataAdmin={dataAdmin}
@@ -148,7 +148,7 @@ function NewTableUser({
p={"xs"} p={"xs"}
style={{ borderRadius: "6px" }} style={{ borderRadius: "6px" }}
> >
<Title order={4}>Table User NEW</Title> <Title order={4}>Table User</Title>
<TextInput <TextInput
icon={<IconSearch size={20} />} icon={<IconSearch size={20} />}
radius={"xl"} radius={"xl"}
@@ -256,6 +256,10 @@ function NewTableAdmin({
search: isSearch, search: isSearch,
page: isChoosePage, page: isChoosePage,
}); });
setDataAdmin(loadData.data); setDataAdmin(loadData.data);
setNPage(loadData.nPage); setNPage(loadData.nPage);
const loadDataUser = await adminDeveloper_funGetListAllUser({ page: 1 }); const loadDataUser = await adminDeveloper_funGetListAllUser({ page: 1 });

View File

@@ -297,10 +297,10 @@ export const newListAdminPage = [
child: [], child: [],
}, },
// Developer // Developer | Super Admin
{ {
id: "Developer", id: "Super Admin",
name: "Developer", name: "Super Admin",
path: RouterAdminDeveloper.main, path: RouterAdminDeveloper.main,
icon: <IconDashboard />, icon: <IconDashboard />,
child: [], child: [],

View File

@@ -1,11 +1,14 @@
"use server"; "use server";
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
import backendLogger from "@/util/backendLogger";
import { revalidatePath } from "next/cache"; import { revalidatePath } from "next/cache";
import { headers } from "next/headers";
export default async function adminUserAccess_funEditAccess( export default async function adminUserAccess_funEditAccess(
userId: string, userId: string,
value: boolean value: boolean,
nomor?: string
) { ) {
const updt = await prisma.user.update({ const updt = await prisma.user.update({
where: { 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" }; if (!updt) return { status: 400, message: "Update gagal" };
revalidatePath("/dev/admin/user-access"); revalidatePath("/dev/admin/user-access");
return { status: 200, message: "Update berhasil" }; return { status: 200, message: "Update berhasil" };

View File

@@ -1,6 +1,9 @@
"use client"; "use client";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { MODEL_USER } from "@/app_modules/home/model/interface"; import { MODEL_USER } from "@/app_modules/home/model/interface";
import { clientLogger } from "@/util/clientLogger";
import { import {
Button, Button,
Center, Center,
@@ -14,48 +17,83 @@ import {
Title, Title,
} from "@mantine/core"; } from "@mantine/core";
import { IconSearch } from "@tabler/icons-react"; import { IconSearch } from "@tabler/icons-react";
import adminUserAccess_funEditAccess from "../fun/edit/fun_edit_access";
import { useState } from "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 adminUserAccess_getListUser from "../fun/get/get_list_all_user";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { WibuRealtime } from "wibu-pkg";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { gs_access_user, IRealtimeData } from "@/app/lib/global_state";
import { useAtom } from "jotai";
export default function AdminUserAccess_View({ listUser }: { listUser: any }) { export default function AdminUserAccess_View({ listUser }: { listUser: any }) {
const [data, setData] = useState<MODEL_USER[]>(listUser.data); const [data, setData] = useState<MODEL_USER[]>(listUser.data);
const [isActivePage, setActivePage] = useState(1); const [isActivePage, setActivePage] = useState(1);
const [isNPage, setNPage] = useState(listUser.nPage); const [isNPage, setNPage] = useState(listUser.nPage);
const [isSearch, setSearch] = useState(""); const [isSearch, setSearch] = useState("");
const [isLoadingAccess, setIsLoadingAccess] = useState(false);
const [isLoadingDelete, setIsLoadingDelete] = useState(false);
const [userId, setUserId] = useState("");
async function onAccess(id: string) { async function onAccess(id: string, nomor: string) {
await adminUserAccess_funEditAccess(id, true).then(async (res) => { try {
if (res.status === 200) { setUserId(id);
const value = await adminUserAccess_getListUser({ setIsLoadingAccess(true);
page: 1, await adminUserAccess_funEditAccess(id, true, nomor).then(async (res) => {
search: isSearch, if (res.status === 200) {
}); const value = await adminUserAccess_getListUser({
setData(value.data as any); page: 1,
setNPage(value.nPage); search: isSearch,
ComponentGlobal_NotifikasiBerhasil(res.message); });
} else { setData(value.data as any);
ComponentGlobal_NotifikasiGagal(res.message); 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);
}
});
} catch (error) {
clientLogger.error("Error grand access", error);
} finally {
setIsLoadingAccess(false);
setUserId("");
}
} }
async function onDelAccess(id: string) { async function onDelete(id: string) {
await adminUserAccess_funEditAccess(id, false).then(async (res) => { try {
if (res.status === 200) { setUserId(id);
const value = await adminUserAccess_getListUser({ setIsLoadingDelete(true);
page: 1, await adminUserAccess_funEditAccess(id, false).then(async (res) => {
search: isSearch, if (res.status === 200) {
}); const value = await adminUserAccess_getListUser({
setData(value.data as any); page: 1,
setNPage(value.nPage); search: isSearch,
ComponentGlobal_NotifikasiBerhasil(res.message); });
} else { setData(value.data as any);
ComponentGlobal_NotifikasiGagal(res.message); setNPage(value.nPage);
} ComponentGlobal_NotifikasiBerhasil(res.message);
}); } else {
ComponentGlobal_NotifikasiGagal(res.message);
}
});
} catch (error) {
clientLogger.error("Error delete access", error);
} finally {
setIsLoadingDelete(false);
setUserId("");
}
} }
async function onSearch(s: any) { async function onSearch(s: any) {
@@ -91,22 +129,26 @@ export default function AdminUserAccess_View({ listUser }: { listUser: any }) {
{e.active === false ? ( {e.active === false ? (
<Center> <Center>
<Button <Button
loaderPosition="center"
loading={isLoadingAccess && userId === e.id}
radius={"xl"} radius={"xl"}
color="Green" color="Green"
onClick={() => { onClick={() => {
onAccess(e.id); onAccess(e.id, e.nomor);
}} }}
> >
Give Access Grand Access
</Button> </Button>
</Center> </Center>
) : ( ) : (
<Center> <Center>
<Button <Button
loaderPosition="center"
loading={isLoadingDelete && userId === e.id}
radius={"xl"} radius={"xl"}
color="red" color="red"
onClick={() => { onClick={() => {
onDelAccess(e.id); onDelete(e.id);
}} }}
> >
Delete Access Delete Access

View File

@@ -11,7 +11,8 @@ import {
ComponentGlobal_NotifikasiPeringatan, ComponentGlobal_NotifikasiPeringatan,
} from "@/app_modules/_global/notif_global"; } from "@/app_modules/_global/notif_global";
import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui"; import { UIGlobal_LayoutDefault } from "@/app_modules/_global/ui";
import { Box, Button, Center, Stack, Text, Title } from "@mantine/core"; import { clientLogger } from "@/util/clientLogger";
import { Box, Button, Center, Group, Stack, Text, Title } from "@mantine/core";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { PhoneInput } from "react-international-phone"; import { PhoneInput } from "react-international-phone";
@@ -27,8 +28,8 @@ export default function Login({ version }: { version: string }) {
const nomor = phone.substring(1); const nomor = phone.substring(1);
if (nomor.length <= 4) return setError(true); if (nomor.length <= 4) return setError(true);
setLoading(true);
try { try {
setLoading(true);
const res = await fetch("/api/auth/login", { const res = await fetch("/api/auth/login", {
method: "POST", method: "POST",
body: JSON.stringify({ nomor: nomor }), body: JSON.stringify({ nomor: nomor }),
@@ -38,6 +39,12 @@ export default function Login({ version }: { version: string }) {
}); });
const result = await res.json(); const result = await res.json();
if (res.status == 500) {
ComponentGlobal_NotifikasiGagal("Server Error");
return;
}
if (res.status === 200) { if (res.status === 200) {
localStorage.setItem("hipmi_auth_code_id", result.kodeId); localStorage.setItem("hipmi_auth_code_id", result.kodeId);
ComponentGlobal_NotifikasiBerhasil(result.message, 2000); ComponentGlobal_NotifikasiBerhasil(result.message, 2000);
@@ -46,8 +53,10 @@ export default function Login({ version }: { version: string }) {
ComponentGlobal_NotifikasiPeringatan(result.message); ComponentGlobal_NotifikasiPeringatan(result.message);
} }
} catch (error) { } catch (error) {
console.error(error); clientLogger.error("Error login:", error);
ComponentGlobal_NotifikasiGagal("Terjadi Kesalahan"); ComponentGlobal_NotifikasiGagal("Terjadi Kesalahan");
} finally {
setLoading(false);
} }
} }
@@ -55,23 +64,32 @@ export default function Login({ version }: { version: string }) {
<> <>
<UIGlobal_LayoutDefault> <UIGlobal_LayoutDefault>
<Stack align="center" justify="center" h={"100vh"} spacing={100}> <Stack align="center" justify="center" h={"100vh"} spacing={100}>
<Stack align="center" spacing={0}> <Stack spacing={0}>
<Title order={3} c={MainColor.yellow} > <Stack align="center" spacing={0}>
WELCOME TO <Title order={3} c={MainColor.yellow}>
</Title> WELCOME TO
<Title c={MainColor.yellow} > </Title>
HIPMI APPS <Title order={2} c={MainColor.yellow}>
</Title> HIPMI BADUNG APPS
</Title>
</Stack>
<Group position="right" w={"100%"}>
<Text c={MainColor.white} ff={"serif"} fz={10}>
powered by muku.id
</Text>
</Group>
</Stack> </Stack>
<Stack w={300}> <Stack w={300}>
<Center> <Center>
<Text c={MainColor.white} > <Text c={MainColor.white}>Nomor telepon</Text>
Nomor telepon
</Text>
</Center> </Center>
<PhoneInput <PhoneInput
inputStyle={{ width: "100%" }} countrySelectorStyleProps={{
buttonStyle: {
backgroundColor: MainColor.login,
},
}}
inputStyle={{ width: "100%", backgroundColor: MainColor.login }}
defaultCountry="id" defaultCountry="id"
onChange={(val) => { onChange={(val) => {
setPhone(val); setPhone(val);

View File

@@ -13,6 +13,7 @@ import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { auth_funDeleteAktivasiKodeOtpByNomor } from "../fun/fun_edit_aktivasi_kode_otp_by_id"; import { auth_funDeleteAktivasiKodeOtpByNomor } from "../fun/fun_edit_aktivasi_kode_otp_by_id";
import Register_SkeletonView from "./skeleton"; import Register_SkeletonView from "./skeleton";
import { clientLogger } from "@/util/clientLogger";
export default function Register() { export default function Register() {
const router = useRouter(); const router = useRouter();
@@ -70,18 +71,31 @@ export default function Register() {
await auth_funDeleteAktivasiKodeOtpByNomor({ await auth_funDeleteAktivasiKodeOtpByNomor({
nomor: data.nomor, nomor: data.nomor,
}); });
router.push("/dev/home", { scroll: false });
router.push("/waiting-room", { scroll: false });
return; return;
} }
if (res.status === 400) { 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); ComponentGlobal_NotifikasiPeringatan(result.message);
return; return;
} }
} catch (error) { } catch (error) {
console.log(error);
} finally {
setLoading(false); setLoading(false);
clientLogger.error("Error registrasi", error);
} }
} }

View File

@@ -25,6 +25,7 @@ import { useEffect, useState } from "react";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global";
import { auth_funDeleteAktivasiKodeOtpByNomor } from "../fun/fun_edit_aktivasi_kode_otp_by_id"; import { auth_funDeleteAktivasiKodeOtpByNomor } from "../fun/fun_edit_aktivasi_kode_otp_by_id";
import Validasi_SkeletonView from "./skeleton"; import Validasi_SkeletonView from "./skeleton";
import { clientLogger } from "@/util/clientLogger";
export default function Validasi() { export default function Validasi() {
const router = useRouter(); const router = useRouter();
@@ -86,9 +87,6 @@ export default function Validasi() {
body: JSON.stringify({ body: JSON.stringify({
nomor: data.nomor, nomor: data.nomor,
}), }),
headers: {
"Content-Type": "application/json",
},
}); });
const result = await res.json(); const result = await res.json();
@@ -99,6 +97,7 @@ export default function Validasi() {
await auth_funDeleteAktivasiKodeOtpByNomor({ await auth_funDeleteAktivasiKodeOtpByNomor({
nomor: data.nomor, nomor: data.nomor,
}); });
router.push(RouterHome.main_home, { scroll: false }); router.push(RouterHome.main_home, { scroll: false });
return; return;
} }
@@ -109,25 +108,33 @@ export default function Validasi() {
await auth_funDeleteAktivasiKodeOtpByNomor({ await auth_funDeleteAktivasiKodeOtpByNomor({
nomor: data.nomor, nomor: data.nomor,
}); });
router.push(RouterAdminDashboard.splash_admin, { scroll: false }); router.push(RouterAdminDashboard.splash_admin, { scroll: false });
return; return;
} }
if (res.status === 404) { if (res.status === 404) {
setLoading(false);
router.push("/register", { scroll: false }); router.push("/register", { scroll: false });
ComponentGlobal_NotifikasiBerhasil(result.message); ComponentGlobal_NotifikasiBerhasil(result.message);
return; return;
} }
if (res.status === 400) { if (res.status === 400) {
setLoading(false);
ComponentGlobal_NotifikasiPeringatan(result.message); ComponentGlobal_NotifikasiPeringatan(result.message);
return; return;
} }
if (res.status == 500) {
setLoading(false);
ComponentGlobal_NotifikasiGagal(result.message);
return;
}
} catch (error) { } catch (error) {
console.error(error);
} finally {
setLoading(false); setLoading(false);
} clientLogger.error("Error validasi:", error);
}
} }
async function onBack() { async function onBack() {
@@ -207,14 +214,13 @@ export default function Validasi() {
</Text> </Text>
</Stack> </Stack>
<Center> <Center>
<PinInput <PinInput
size="xl" size="xl"
type={"number"} type={"number"}
ref={focusTrapRef} ref={focusTrapRef}
spacing={"md"} spacing={"md"}
mt={"md"} mt={"md"}
styles={{ input: { backgroundColor: MainColor.white } }} styles={{ input: { backgroundColor: MainColor.white } }}
onChange={(val) => { onChange={(val) => {
setInputOtp(val); setInputOtp(val);
}} }}

View File

@@ -0,0 +1,43 @@
export const apiGetAllCollaboration = async ({
kategori,
page,
}: {
kategori: "beranda" | "partisipasi" | "proyeksaya" | "grup";
page: string;
}) => {
const respone = await fetch(
`/api/collaboration/get?kategori=${kategori}&page=${page}`
);
return await respone.json().catch(() => null);
};
export const apiGetOneCollaborationById = async ({
id,
kategori,
page,
}: {
id: string;
kategori: "detail" | "list_partisipan" | "cek_partisipasi";
page?: string;
}) => {
const respone = await fetch(
`/api/collaboration/${id}?kategori=${kategori}&page=${page}`
);
return await respone.json().catch(() => null);
};
export const apiGetDataGroupById = async ({
id,
kategori,
page,
}: {
id: string;
kategori: "detail" | "info_group"
page?: string;
}) => {
const respone = await fetch(
`/api/collaboration/group/${id}?kategori=${kategori}&page=${page}`
);
return await respone.json().catch(() => null)
}

View File

@@ -40,15 +40,15 @@ export default function ComponentColab_CardSectionData({
<Stack spacing={"xs"}> <Stack spacing={"xs"}>
<Grid> <Grid>
<Grid.Col span={2}> <Grid.Col span={2}>
<Text fw={"bold"} fz={"xs"}> <Text fw={"bold"} >
Industri Industri
</Text> </Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={1}> <Grid.Col span={1}>
<Text fz={"xs"}>:</Text> <Text >:</Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
<Text fz={"xs"} lineClamp={1}> <Text lineClamp={1}>
{data?.ProjectCollaborationMaster_Industri.name {data?.ProjectCollaborationMaster_Industri.name
? data?.ProjectCollaborationMaster_Industri?.name ? data?.ProjectCollaborationMaster_Industri?.name
: "Industri"} : "Industri"}
@@ -58,25 +58,25 @@ export default function ComponentColab_CardSectionData({
<Grid> <Grid>
<Grid.Col span={2}> <Grid.Col span={2}>
<Text fw={"bold"} fz={"xs"}> <Text fw={"bold"} >
Lokasi Lokasi
</Text> </Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={1}> <Grid.Col span={1}>
<Text fz={"xs"}>:</Text> <Text >:</Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
<Text fz={"xs"} lineClamp={1}> <Text lineClamp={1}>
{data?.lokasi ? data?.lokasi : "Lokasi dari proyek"} {data?.lokasi ? data?.lokasi : "Lokasi dari proyek"}
</Text> </Text>
</Grid.Col> </Grid.Col>
</Grid> </Grid>
<Stack spacing={5}> <Stack spacing={5}>
<Text fw={"bold"} fz={"xs"}> <Text fw={"bold"} >
Tujuan proyek Tujuan proyek
</Text> </Text>
<Text lineClamp={3} fz={"xs"}> <Text lineClamp={2} >
{data?.purpose {data?.purpose
? data?.purpose ? data?.purpose
: "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maiores odio nihil in animi expedita, suscipit excepturi pariatur totam esse officiis enim cumque. Quidem, facere aliquam. Sunt laboriosam incidunt iste amet"} : "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Maiores odio nihil in animi expedita, suscipit excepturi pariatur totam esse officiis enim cumque. Quidem, facere aliquam. Sunt laboriosam incidunt iste amet"}

View File

@@ -1,5 +1,6 @@
"use client"; "use client";
import { MainColor } from "@/app_modules/_global/color";
import { Card, Center, Divider, Grid, Stack, Text } from "@mantine/core"; import { Card, Center, Divider, Grid, Stack, Text } from "@mantine/core";
export default function ComponentColab_JumlahPartisipan({ export default function ComponentColab_JumlahPartisipan({
@@ -15,12 +16,12 @@ export default function ComponentColab_JumlahPartisipan({
<Center> <Center>
<Grid> <Grid>
<Grid.Col span={"content"}> <Grid.Col span={"content"}>
<Text c={"white"} fz={"xs"} fw={"bold"}> <Text c={MainColor.white} fz={"xs"} fw={"bold"}>
{jumlah?.length ? jumlah?.length : 0} {jumlah?.length ? jumlah?.length : 0}
</Text> </Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
<Text c={"white"} fz={"xs"} fw={"bold"}> <Text c={MainColor.white} fz={"xs"} fw={"bold"}>
Partisipan Partisipan
</Text> </Text>
</Grid.Col> </Grid.Col>

View File

@@ -1,5 +1,5 @@
import { RouterColab } from "@/app/lib/router_hipmi/router_colab"; import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import { AccentColor } from "@/app_modules/_global/color/color_pallet"; import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader"; import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
import { Paper, Grid, Stack, Center, Loader, Text } from "@mantine/core"; import { Paper, Grid, Stack, Center, Loader, Text } from "@mantine/core";
import { IconChevronRight } from "@tabler/icons-react"; import { IconChevronRight } from "@tabler/icons-react";
@@ -17,7 +17,7 @@ export function ComponentColab_CardGrup({ data }: { data: any }) {
style={{ style={{
border: `2px solid ${AccentColor.blue}`, border: `2px solid ${AccentColor.blue}`,
backgroundColor: AccentColor.darkblue, backgroundColor: AccentColor.darkblue,
color: "white", color: MainColor.white,
borderRadius: "10px", borderRadius: "10px",
marginBottom: "20px", marginBottom: "20px",
padding: "15px", padding: "15px",
@@ -37,7 +37,7 @@ export function ComponentColab_CardGrup({ data }: { data: any }) {
<Text fw={"bold"} lineClamp={1}> <Text fw={"bold"} lineClamp={1}>
{data?.ProjectCollaboration_RoomChat?.name} {data?.ProjectCollaboration_RoomChat?.name}
</Text> </Text>
<Text fz={"xs"} c={"white"}> <Text fz={"xs"} >
{ {
data?.ProjectCollaboration_RoomChat data?.ProjectCollaboration_RoomChat
?.ProjectCollaboration_AnggotaRoomChat.length ?.ProjectCollaboration_AnggotaRoomChat.length
@@ -51,7 +51,7 @@ export function ComponentColab_CardGrup({ data }: { data: any }) {
{data?.ProjectCollaboration_RoomChat?.id === idRoom ? ( {data?.ProjectCollaboration_RoomChat?.id === idRoom ? (
<ComponentGlobal_Loader /> <ComponentGlobal_Loader />
) : ( ) : (
<IconChevronRight color="white" /> <IconChevronRight color={MainColor.white} />
)} )}
</Center> </Center>
</Grid.Col> </Grid.Col>

View File

@@ -19,15 +19,15 @@ export default function ComponentColab_DetailData({
<Stack spacing={"sm"}> <Stack spacing={"sm"}>
<Grid> <Grid>
<Grid.Col span={2}> <Grid.Col span={2}>
<Text fw={"bold"} fz={"sm"}> <Text fw={"bold"} >
Industri Industri
</Text> </Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={1}> <Grid.Col span={1}>
<Text fz={"sm"}>:</Text> <Text >:</Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
<Text fz={"sm"}> <Text >
{data?.ProjectCollaborationMaster_Industri.name {data?.ProjectCollaborationMaster_Industri.name
? data.ProjectCollaborationMaster_Industri.name ? data.ProjectCollaborationMaster_Industri.name
: "Industri"} : "Industri"}
@@ -37,31 +37,31 @@ export default function ComponentColab_DetailData({
<Grid> <Grid>
<Grid.Col span={2}> <Grid.Col span={2}>
<Text fw={"bold"} fz={"sm"}> <Text fw={"bold"} >
Lokasi Lokasi
</Text> </Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={1}> <Grid.Col span={1}>
<Text fz={"sm"}>:</Text> <Text >:</Text>
</Grid.Col> </Grid.Col>
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
<Text fz={"sm"} lineClamp={1}> <Text lineClamp={1}>
{data?.lokasi ? data.lokasi : " Lokasi dari proyek"} {data?.lokasi ? data.lokasi : " Lokasi dari proyek"}
</Text> </Text>
</Grid.Col> </Grid.Col>
</Grid> </Grid>
<Stack spacing={5}> <Stack spacing={5}>
<Text fw={"bold"} fz={"sm"}> <Text fw={"bold"} >
Tujuan proyek Tujuan proyek
</Text> </Text>
<Text fz={"sm"}>{data?.purpose ? data?.purpose : "-"}</Text> <Text >{data?.purpose ? data?.purpose : "-"}</Text>
</Stack> </Stack>
<Stack spacing={5}> <Stack spacing={5}>
<Text fw={"bold"} fz={"sm"}> <Text fw={"bold"} >
Keuntungan Keuntungan
</Text> </Text>
<Text fz={"sm"}>{data?.benefit ? data?.benefit : "-"}</Text> <Text >{data?.benefit ? data?.benefit : "-"}</Text>
</Stack> </Stack>
</Stack> </Stack>
</Box> </Box>

View File

@@ -4,9 +4,14 @@ import {
AccentColor, AccentColor,
MainColor, MainColor,
} from "@/app_modules/_global/color/color_pallet"; } from "@/app_modules/_global/color/color_pallet";
import { ComponentGlobal_CardStyles } 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 ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import notifikasiToUser_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_user";
import { clientLogger } from "@/util/clientLogger";
import mqtt_client from "@/util/mqtt_client";
import { import {
ActionIcon, ActionIcon,
Box, Box,
@@ -14,83 +19,219 @@ import {
Center, Center,
Drawer, Drawer,
Group, Group,
Paper, Loader,
ScrollArea,
Stack, Stack,
Text, Text,
Textarea, Textarea,
Title, Title,
} from "@mantine/core"; } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks"; import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { IconX } from "@tabler/icons-react"; import { IconX } from "@tabler/icons-react";
import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader";
import { useParams } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { apiGetOneCollaborationById } from "../../_lib/api_collaboration";
import colab_funCreatePartisipan from "../../fun/create/fun_create_partisipan_by_user_id"; import colab_funCreatePartisipan from "../../fun/create/fun_create_partisipan_by_user_id";
import colab_getListPartisipanByColabId from "../../fun/get/get_list_partisipan_by_id";
import { MODEL_COLLABORATION_PARTISIPASI } from "../../model/interface"; import { MODEL_COLLABORATION_PARTISIPASI } from "../../model/interface";
import { Collaboration_SkeletonListPrtisipanIsUser } from "../skeleton_view";
import ComponentColab_AuthorNameOnListPartisipan from "./header_author_list_partisipan"; import ComponentColab_AuthorNameOnListPartisipan from "./header_author_list_partisipan";
import notifikasiToUser_funCreate from "@/app_modules/notifikasi/fun/create/create_notif_to_user";
import mqtt_client from "@/util/mqtt_client";
export default function ComponentColab_DetailListPartisipasiUser({ export default function ComponentColab_DetailListPartisipasiUser({
listPartisipan,
userLoginId, userLoginId,
authorId, authorId,
colabId,
cekPartisipan,
}: { }: {
listPartisipan?: MODEL_COLLABORATION_PARTISIPASI[];
userLoginId?: string; userLoginId?: string;
authorId?: string; authorId?: string;
colabId?: string;
cekPartisipan?: boolean;
}) { }) {
const [apply, setApply] = useState(false); const params = useParams<{ id: string }>();
const [data, setData] = useState(listPartisipan); const [data, setData] = useState<MODEL_COLLABORATION_PARTISIPASI[] | null>(
null
);
const [isPartisipan, setCekPartisipan] = useState<boolean | null>(null);
const [activePage, setActivePage] = useState(1);
const [opened, { open, close }] = useDisclosure(false); const [opened, { open, close }] = useDisclosure(false);
const [deskripsi, setDeskripsi] = useState(""); const [deskripsi, setDeskripsi] = useState("");
const [isLoading, setIsLoading] = useState(false);
async function onJoin() { useShallowEffect(() => {
const res = await colab_funCreatePartisipan( onLoadDataPartisipan();
colabId as any, }, []);
userLoginId as any,
deskripsi
);
if (res.status === 201) {
const dataNotif = {
appId: res?.data?.ProjectCollaboration?.id,
userId: res?.data?.ProjectCollaboration?.userId,
pesan: res?.data?.ProjectCollaboration?.title,
status: "Partisipan Project",
kategoriApp: "COLLABORATION",
title: "Partisipan baru telah bergabung !",
};
const createNotifikasi = await notifikasiToUser_funCreate({ async function onLoadDataPartisipan() {
data: dataNotif as any, try {
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "list_partisipan",
page: `${activePage}`,
}); });
if (createNotifikasi.status === 201) { if (respone) {
mqtt_client.publish( setData(respone.data);
"USER",
JSON.stringify({
userId: dataNotif.userId,
count: 1,
})
);
} }
} catch (error) {
const resList = await colab_getListPartisipanByColabId(colabId as any); clientLogger.error("Error get list partisipan", error);
setApply(true);
close();
setData(resList as any);
ComponentGlobal_NotifikasiBerhasil(res.message);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
} }
} }
useShallowEffect(() => {
onCheckPartisipasi();
}, []);
async function onCheckPartisipasi() {
try {
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "cek_partisipasi",
});
if (respone) {
setCekPartisipan(respone.data);
}
} catch (error) {
clientLogger.error("Error cek partisipasi", error);
}
}
async function onJoin() {
try {
setIsLoading(true);
const res = await colab_funCreatePartisipan({
id: params.id,
deskripsi: deskripsi,
});
if (res.status === 201) {
// const dataNotif = {
// appId: res?.data?.ProjectCollaboration?.id,
// userId: res?.data?.ProjectCollaboration?.userId,
// pesan: res?.data?.ProjectCollaboration?.title,
// status: "Partisipan Project",
// kategoriApp: "COLLABORATION",
// title: "Partisipan baru telah bergabung !",
// };
// const createNotifikasi = await notifikasiToUser_funCreate({
// data: dataNotif as any,
// });
// if (createNotifikasi.status === 201) {
// mqtt_client.publish(
// "USER",
// JSON.stringify({
// userId: dataNotif.userId,
// count: 1,
// })
// );
// }
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "list_partisipan",
page: `${activePage}`,
});
if (respone) {
setData(respone.data);
}
const cekPartisipan = await apiGetOneCollaborationById({
id: params.id,
kategori: "cek_partisipasi",
});
if (cekPartisipan) {
setCekPartisipan(cekPartisipan);
}
close();
ComponentGlobal_NotifikasiBerhasil(res.message);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
}
} catch (error) {
clientLogger.error("Error create partisipan", error);
} finally {
setIsLoading(false);
}
}
if (_.isNull(data) || _.isNull(isPartisipan)) {
return <Collaboration_SkeletonListPrtisipanIsUser />;
}
return ( return (
<> <>
<Stack>
{userLoginId !== authorId && (
<Center>
<Button
radius={"xl"}
disabled={isPartisipan}
color={isPartisipan ? "green" : "yellow"}
onClick={open}
// bg={MainColor.yellow}
>
{isPartisipan ? "Telah Berpartisipasi" : "Partisipasi"}
</Button>
</Center>
)}
{_.isEmpty(data) ? (
<ComponentGlobal_CardStyles>
<Stack>
<Center>
<Title order={5}>Partispasi User ({data?.length})</Title>
</Center>
<ComponentGlobal_IsEmptyData
height={10}
text=" Tidak ada partisipan"
/>
</Stack>
</ComponentGlobal_CardStyles>
) : (
<ComponentGlobal_CardStyles>
<Stack spacing={"xl"}>
<Center>
<Title order={5}>Partispasi User ({data?.length})</Title>
</Center>{" "}
<Box>
<ScrollOnly
height="50vh"
renderLoading={() => (
<Center mt={"lg"}>
<Loader color={"yellow"} />
</Center>
)}
data={data}
setData={setData as any}
moreData={async () => {
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "list_partisipan",
page: `${activePage + 1}`,
});
setActivePage((val) => val + 1);
return respone.data;
}}
>
{(item) => (
<ComponentColab_AuthorNameOnListPartisipan
isPembatas={true}
author={item.User}
deskripsi={item.deskripsi_diri}
/>
)}
</ScrollOnly>
</Box>
</Stack>
</ComponentGlobal_CardStyles>
)}
</Stack>
<Drawer <Drawer
opened={opened} opened={opened}
onClose={close} onClose={close}
@@ -113,21 +254,29 @@ export default function ComponentColab_DetailListPartisipasiUser({
borderRight: `1px solid ${AccentColor.blue}`, borderRight: `1px solid ${AccentColor.blue}`,
borderLeft: `1px solid ${AccentColor.blue}`, borderLeft: `1px solid ${AccentColor.blue}`,
borderRadius: "20px 20px 0px 0px", borderRadius: "20px 20px 0px 0px",
color: "white", color: MainColor.white,
paddingBottom: "5%", paddingBottom: "5%",
}, },
}} }}
> >
<Stack spacing={"xs"}> <Stack spacing={"xs"}>
<Group position="right"> <Group position="right">
<ActionIcon onClick={close} variant="transparent"> <ActionIcon onClick={close} variant="transparent">
<IconX color="white" /> <IconX color={MainColor.white} />
</ActionIcon> </ActionIcon>
</Group> </Group>
<Textarea <Textarea
maxLength={300} maxLength={300}
label={<Text c={"white"} mb={"sm"} fw={"bold"}>Deskripsi Diri</Text>} label={
<Text c={MainColor.white} mb={"sm"} fw={"bold"}>
Deskripsi Diri
</Text>
}
styles={{
input: {
backgroundColor: MainColor.white
}
}}
placeholder="Deskripsikan diri anda yang sesuai dengan proyek ini.." placeholder="Deskripsikan diri anda yang sesuai dengan proyek ini.."
minRows={4} minRows={4}
onChange={(val) => { onChange={(val) => {
@@ -143,6 +292,8 @@ export default function ComponentColab_DetailListPartisipasiUser({
maxInput={300} maxInput={300}
/> />
<Button <Button
loaderPosition="center"
loading={isLoading}
disabled={!deskripsi} disabled={!deskripsi}
radius={"xl"} radius={"xl"}
color="yellow" color="yellow"
@@ -157,63 +308,6 @@ export default function ComponentColab_DetailListPartisipasiUser({
</Group> </Group>
</Stack> </Stack>
</Drawer> </Drawer>
<Stack>
{userLoginId !== authorId ? (
<Center>
<Button
radius={"xl"}
disabled={cekPartisipan ? true : false}
color={cekPartisipan ? "green" : "yellow"}
onClick={open}
// bg={MainColor.yellow}
>
{cekPartisipan ? "Telah Berpartisipasi" : "Partisipasi"}
</Button>
</Center>
) : (
""
)}
<Paper
style={{
border: `2px solid ${AccentColor.softblue}`,
backgroundColor: AccentColor.blue,
color: "white",
borderRadius: "10px",
padding: "15px",
}}
>
<Stack spacing={"xl"}>
<Center>
<Title order={5}>Partispasi User ({data?.length})</Title>
</Center>{" "}
<ScrollArea h={data?.length === 0 ? 30 : 400}>
<Box>
<Stack>
{data?.length === 0 ? (
<Center>
<Text fz={"xs"} fw={"bold"} c={"gray"}>
Tidak ada partisipan
</Text>
</Center>
) : (
data?.map((e, i) => (
<Box key={i}>
<ComponentColab_AuthorNameOnListPartisipan
isPembatas={true}
author={e.User}
deskripsi={e.deskripsi_diri}
/>
</Box>
))
)}
</Stack>
</Box>
</ScrollArea>
</Stack>
</Paper>
</Stack>
</> </>
); );
} }

View File

@@ -3,6 +3,8 @@
import { ComponentGlobal_AvatarAndUsername } from "@/app_modules/_global/component"; import { ComponentGlobal_AvatarAndUsername } from "@/app_modules/_global/component";
import { Group, Stack, Text } from "@mantine/core"; import { Group, Stack, Text } from "@mantine/core";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import moment from "moment";
import "moment/locale/id";
export default function ComponentColab_AuthorNameOnHeader({ export default function ComponentColab_AuthorNameOnHeader({
tglPublish, tglPublish,
@@ -19,10 +21,8 @@ export default function ComponentColab_AuthorNameOnHeader({
component={ component={
<Group position="right"> <Group position="right">
{tglPublish ? ( {tglPublish ? (
<Text fz={"xs"}> <Text lineClamp={1}>
{new Intl.DateTimeFormat("id-ID", { {moment(tglPublish).locale("id").format("ll")}
dateStyle: "medium",
}).format(tglPublish)}
</Text> </Text>
) : ( ) : (
"" ""
@@ -65,7 +65,7 @@ export default function ComponentColab_AuthorNameOnHeader({
<Grid.Col span={"content"}> <Grid.Col span={"content"}>
<Stack justify="center" h={"100%"}> <Stack justify="center" h={"100%"}>
{tglPublish ? ( {tglPublish ? (
<Text fz={"xs"}> <Text >
{new Intl.DateTimeFormat("id-ID", { {new Intl.DateTimeFormat("id-ID", {
dateStyle: "medium" dateStyle: "medium"

View File

@@ -1,27 +1,277 @@
import { Skeleton, Stack } from "@mantine/core"; import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { Center, Grid, Group, Skeleton, Stack } from "@mantine/core";
export function Collaboration_SkeletonCreate() { export {
Collaboration_SkeletonBeranda,
Collaboration_SkeletonCreate,
Collaboration_SkeletonDetail,
Collaboration_SkeletonDetailInfoGroup,
Collaboration_SkeletonGrup,
Collaboration_SkeletonListPartisipan,
Collaboration_SkeletonListPrtisipanIsUser,
};
function Collaboration_SkeletonCreate() {
return ( return (
<> <>
<Stack px={"xl"} spacing={"lg"}> <Stack px={"xl"} spacing={"md"}>
<Stack spacing={"xs"}> <Stack spacing={"xs"}>
<Skeleton height={10} width={50} /> <CustomSkeleton height={15} width={50} />
<Skeleton height={40} /> <CustomSkeleton height={40} />
</Stack> </Stack>
<Stack spacing={"xs"}> <Stack spacing={"xs"}>
<Skeleton height={10} width={50} /> <CustomSkeleton height={15} width={50} />
<Skeleton height={40} /> <CustomSkeleton height={40} />
</Stack> </Stack>
<Stack spacing={"xs"}> <Stack spacing={"xs"}>
<Skeleton height={10} width={50} /> <CustomSkeleton height={15} width={50} />
<Skeleton height={130} /> <CustomSkeleton height={40} />
</Stack> </Stack>
<Stack spacing={"xs"}> <Stack spacing={"xs"}>
<Skeleton height={10} width={50} /> <CustomSkeleton height={15} width={50} />
<Skeleton height={130} /> <CustomSkeleton height={130} />
</Stack>
<Stack spacing={"xs"}>
<CustomSkeleton height={15} width={50} />
<CustomSkeleton height={130} />
</Stack> </Stack>
<Skeleton mt={50} height={40} radius={"xl"} /> <CustomSkeleton mt={50} height={40} radius={"xl"} />
</Stack>
</>
);
}
function Collaboration_SkeletonBeranda() {
return (
<>
{Array.from(new Array(2)).map((e, i) => (
<ComponentGlobal_CardStyles marginBottom={"15px"} key={i}>
<Stack spacing={"xl"}>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<CustomSkeleton circle height={40} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={150} />
</Grid.Col>
{/* <Grid.Col span={3} offset={3}>
<CustomSkeleton height={20} w={150} />
</Grid.Col> */}
</Grid>
<Center>
<CustomSkeleton height={15} w={200} />
</Center>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<CustomSkeleton h={15} w={70} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={15} w={200} />
</Grid.Col>
</Grid>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<CustomSkeleton h={15} w={70} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={15} w={200} />
</Grid.Col>
</Grid>
<Stack spacing={"md"}>
<CustomSkeleton height={15} w={150} />
<CustomSkeleton height={15} w={"100%"} />
<CustomSkeleton height={15} w={"100%"} />
</Stack>
<Center>
<CustomSkeleton height={15} w={100} />
</Center>
</Stack>
</ComponentGlobal_CardStyles>
))}
</>
);
}
function Collaboration_SkeletonGrup() {
return (
<>
{Array.from(new Array(2)).map((e, i) => (
<ComponentGlobal_CardStyles marginBottom={"15px"} key={i}>
<Group position="apart">
<Stack>
<CustomSkeleton h={15} w={100} />
<CustomSkeleton h={15} w={50} />
</Stack>
<CustomSkeleton circle height={20} />
</Group>
</ComponentGlobal_CardStyles>
))}
</>
);
}
function Collaboration_SkeletonDetail() {
return (
<>
<ComponentGlobal_CardStyles marginBottom={"0"}>
<Stack spacing={"xl"}>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<CustomSkeleton circle height={40} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={150} />
</Grid.Col>
</Grid>
<Center>
<CustomSkeleton height={20} w={200} />
</Center>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<CustomSkeleton h={20} w={70} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={200} />
</Grid.Col>
</Grid>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<CustomSkeleton h={20} w={70} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={200} />
</Grid.Col>
</Grid>
<CustomSkeleton height={20} w={100} />
<CustomSkeleton height={20} w={"100%"} />
<CustomSkeleton height={20} w={100} />
<CustomSkeleton height={20} w={"100%"} />
</Stack>
</ComponentGlobal_CardStyles>
</>
);
}
function Collaboration_SkeletonListPrtisipanIsUser() {
return (
<>
<Stack>
<ComponentGlobal_CardStyles marginBottom={"0"}>
<Stack>
<Center>
<CustomSkeleton h={20} w={100} />
</Center>
{Array.from(new Array(2)).map((e, i) => (
<Grid align="center" gutter={"md"} key={i}>
<Grid.Col span={"content"}>
<CustomSkeleton circle height={40} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={150} />
</Grid.Col>
</Grid>
))}
</Stack>
</ComponentGlobal_CardStyles>
</Stack>
</>
);
}
function Collaboration_SkeletonListPartisipan() {
return (
<>
<Stack>
<Center>
<CustomSkeleton h={40} w={150} radius={"xl"} />
</Center>
<ComponentGlobal_CardStyles marginBottom={"0"}>
<Stack>
<Center>
<CustomSkeleton h={20} w={100} />
</Center>
{Array.from(new Array(2)).map((e, i) => (
<Grid align="center" gutter={"md"} key={i}>
<Grid.Col span={"content"}>
<CustomSkeleton circle height={40} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={150} />
</Grid.Col>
</Grid>
))}
</Stack>
</ComponentGlobal_CardStyles>
</Stack>
</>
);
}
function Collaboration_SkeletonDetailInfoGroup() {
return (
<>
<Stack>
<ComponentGlobal_CardStyles marginBottom={"0"}>
<Stack spacing={"xl"}>
<Center>
<CustomSkeleton height={20} w={200} />
</Center>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<CustomSkeleton h={20} w={70} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={200} />
</Grid.Col>
</Grid>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
<CustomSkeleton h={20} w={70} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={200} />
</Grid.Col>
</Grid>
<CustomSkeleton height={20} w={100} />
<CustomSkeleton height={20} w={"100%"} />
<CustomSkeleton height={20} w={"100%"} />
<CustomSkeleton height={20} w={100} />
<CustomSkeleton height={20} w={"100%"} />
<CustomSkeleton height={20} w={"100%"} />
</Stack>
</ComponentGlobal_CardStyles>
<ComponentGlobal_CardStyles marginBottom={"0"}>
<Stack>
<CustomSkeleton h={20} w={100} />
{Array.from(new Array(2)).map((e, i) => (
<Grid align="center" gutter={"md"} key={i}>
<Grid.Col span={"content"}>
<CustomSkeleton circle height={40} />
</Grid.Col>
<Grid.Col span={3}>
<CustomSkeleton height={20} w={150} />
</Grid.Col>
</Grid>
))}
</Stack>
</ComponentGlobal_CardStyles>
</Stack> </Stack>
</> </>
); );

View File

@@ -5,26 +5,22 @@ import ComponentGlobal_InputCountDown from "@/app_modules/_global/component/inpu
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import { clientLogger } from "@/util/clientLogger";
import mqtt_client from "@/util/mqtt_client";
import { import {
Button, Button,
Center,
Select, Select,
Stack, Stack,
TextInput, TextInput,
Textarea, Textarea
Loader,
} from "@mantine/core"; } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import { Collaboration_SkeletonCreate } from "../component";
import { apiGetMasterCollaboration } from "../component/lib/api_collaboration";
import colab_funCreateProyek from "../fun/create/fun_create_proyek"; import colab_funCreateProyek from "../fun/create/fun_create_proyek";
import { MODEL_COLLABORATION_MASTER } from "../model/interface"; import { MODEL_COLLABORATION_MASTER } from "../model/interface";
import mqtt_client from "@/util/mqtt_client";
import { useHookstate } from "@hookstate/core";
import { useGsCollabCreate } from "../global_state/state";
import { useShallowEffect } from "@mantine/hooks";
import { apiGetMasterCollaboration } from "../component/lib/api_collaboration";
import { clientLogger } from "@/util/clientLogger";
import { Collaboration_SkeletonCreate } from "../component";
export default function Colab_Create() { export default function Colab_Create() {
const [value, setValue] = useState({ const [value, setValue] = useState({
@@ -55,7 +51,7 @@ export default function Colab_Create() {
} }
} }
if (listIndustri == null) { if (listIndustri == null) {
return ( return (
<> <>
@@ -70,9 +66,9 @@ export default function Colab_Create() {
<TextInput <TextInput
maxLength={100} maxLength={100}
styles={{ styles={{
label: { label: { color: MainColor.white },
color: "white", input: { backgroundColor: MainColor.white },
}, required: { color: MainColor.red },
}} }}
label="Judul" label="Judul"
withAsterisk withAsterisk
@@ -87,9 +83,9 @@ export default function Colab_Create() {
<TextInput <TextInput
styles={{ styles={{
label: { label: { color: MainColor.white },
color: "white", input: { backgroundColor: MainColor.white },
}, required: { color: MainColor.red },
}} }}
maxLength={100} maxLength={100}
label="Lokasi" label="Lokasi"
@@ -103,11 +99,12 @@ export default function Colab_Create() {
}} }}
/> />
{/* <Select <Select
styles={{ styles={{
label: { label: { color: MainColor.white },
color: "white", input: { backgroundColor: MainColor.white },
}, required: { color: MainColor.red },
dropdown: { backgroundColor: MainColor.white },
}} }}
placeholder="Pilih kategori industri" placeholder="Pilih kategori industri"
label="Pilih Industri" label="Pilih Industri"
@@ -122,32 +119,14 @@ export default function Colab_Create() {
projectCollaborationMaster_IndustriId: val as any, projectCollaborationMaster_IndustriId: val as any,
}); });
}} }}
/> */} />
{/* <TextInput
description={
<Text fz={10}>
minimal partisipan yang akan di pilih untuk mendiskusikan proyek
</Text>
}
type="number"
withAsterisk
label="Jumlah Partisipan"
placeholder={"2"}
onChange={(val) => {
setValue({
...value,
jumlah_partisipan: val.currentTarget.value as any,
});
}}
/> */}
<Stack spacing={5}> <Stack spacing={5}>
<Textarea <Textarea
styles={{ styles={{
label: { label: { color: MainColor.white },
color: "white", input: { backgroundColor: MainColor.white },
}, required: { color: MainColor.red },
}} }}
maxLength={500} maxLength={500}
label="Tujuan Proyek" label="Tujuan Proyek"
@@ -170,9 +149,8 @@ export default function Colab_Create() {
<Stack spacing={5}> <Stack spacing={5}>
<Textarea <Textarea
styles={{ styles={{
label: { label: { color: MainColor.white },
color: "white", input: { backgroundColor: MainColor.white },
},
}} }}
maxLength={500} maxLength={500}
label="Keuntungan " label="Keuntungan "
@@ -207,7 +185,6 @@ function ButtonAction({ value }: { value: any }) {
JSON.stringify({ isNewPost: true, count: 1 }) JSON.stringify({ isNewPost: true, count: 1 })
); );
console.log(value.jumlah_partisipan);
if (value.title === "") if (value.title === "")
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data"); return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
if (value.lokasi === "") if (value.lokasi === "")
@@ -218,26 +195,33 @@ function ButtonAction({ value }: { value: any }) {
return ComponentGlobal_NotifikasiPeringatan("Pilih Industri"); return ComponentGlobal_NotifikasiPeringatan("Pilih Industri");
const res = await colab_funCreateProyek(value); const res = await colab_funCreateProyek(value);
if (res.status === 201) { try {
setLoading(true); setLoading(true)
router.back(); if (res.status === 201) {
ComponentGlobal_NotifikasiBerhasil(res.message); setLoading(true);
} else { router.back();
ComponentGlobal_NotifikasiGagal(res.message); ComponentGlobal_NotifikasiBerhasil(res.message);
} else {
setLoading(false)
ComponentGlobal_NotifikasiGagal(res.message);
}
} catch (error) {
setLoading(false)
clientLogger.error("Error create proyek", error);
} }
} }
// console.log(value);
return ( return (
<> <>
<Button <Button
disabled={ disabled={
!value.title || !value.title ||
!value.lokasi || !value.lokasi ||
!value.purpose || !value.purpose ||
!value.benefit || !value.benefit ||
value.projectCollaborationMaster_IndustriId === 0 value.projectCollaborationMaster_IndustriId === 0
? true ? true
: false : false
} }

View File

@@ -26,7 +26,7 @@ import {
IconSend, IconSend,
} from "@tabler/icons-react"; } from "@tabler/icons-react";
import _ from "lodash"; import _ from "lodash";
import { useRouter } from "next/navigation"; import { useParams, useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
import useInfiniteScroll, { import useInfiniteScroll, {
ScrollDirection, ScrollDirection,
@@ -43,6 +43,8 @@ import {
MainColor, MainColor,
} from "@/app_modules/_global/color/color_pallet"; } from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_Loader from "@/app_modules/_global/component/loader"; import ComponentGlobal_Loader from "@/app_modules/_global/component/loader";
import { apiGetDataGroupById } from "../../_lib/api_collaboration";
import { clientLogger } from "@/util/clientLogger";
export default function Colab_GroupChatView({ export default function Colab_GroupChatView({
userLoginId, userLoginId,
@@ -55,6 +57,7 @@ export default function Colab_GroupChatView({
selectRoom: MODEL_COLLABORATION_ROOM_CHAT; selectRoom: MODEL_COLLABORATION_ROOM_CHAT;
dataUserLogin: MODEL_USER; dataUserLogin: MODEL_USER;
}) { }) {
const params = useParams<{ id: string }>();
const router = useRouter(); const router = useRouter();
const [loadingBack, setLoadingBack] = useState(false); const [loadingBack, setLoadingBack] = useState(false);
const [loadingInfo, setLoadingInfo] = useState(false); const [loadingInfo, setLoadingInfo] = useState(false);
@@ -66,6 +69,30 @@ export default function Colab_GroupChatView({
const [isGet, setIsGet] = useState(true); const [isGet, setIsGet] = useState(true);
const [newMessageId, setIdMessage] = useState(""); const [newMessageId, setIdMessage] = useState("");
// NEW
const [dataGroup, setDataGroup] =
useState<MODEL_COLLABORATION_ROOM_CHAT | null>(null);
useShallowEffect(() => {
onLoadDataGroup();
}, []);
async function onLoadDataGroup() {
try {
const respone = await apiGetDataGroupById({
id: params.id,
kategori: "detail",
});
if (respone) {
setDataGroup(respone.data);
}
} catch (error) {
clientLogger.error("Error get data group", error);
}
}
const next = async (direction: ScrollDirection) => { const next = async (direction: ScrollDirection) => {
try { try {
setIsLoading(true); setIsLoading(true);
@@ -202,13 +229,13 @@ export default function Colab_GroupChatView({
{loadingBack ? ( {loadingBack ? (
<ComponentGlobal_Loader /> <ComponentGlobal_Loader />
) : ( ) : (
<IconChevronLeft color="white" /> <IconChevronLeft color={MainColor.white} />
)} )}
</ActionIcon> </ActionIcon>
</Grid.Col> </Grid.Col>
<Grid.Col span={8}> <Grid.Col span={8}>
<Center> <Center>
<Title c={"white"} order={5} lineClamp={1}> <Title color={MainColor.white} order={5} lineClamp={1}>
{selectRoom?.name} {selectRoom?.name}
</Title> </Title>
</Center> </Center>
@@ -220,13 +247,15 @@ export default function Colab_GroupChatView({
radius={"xl"} radius={"xl"}
onClick={() => { onClick={() => {
setLoadingInfo(true); setLoadingInfo(true);
router.push(RouterColab.info_grup + selectRoom.id, {scroll: false}); router.push(RouterColab.info_grup + selectRoom.id, {
scroll: false,
});
}} }}
> >
{loadingInfo ? ( {loadingInfo ? (
<ComponentGlobal_Loader /> <ComponentGlobal_Loader />
) : ( ) : (
<IconInfoSquareRounded color="white" /> <IconInfoSquareRounded color={MainColor.white} />
)} )}
</ActionIcon> </ActionIcon>
</Group> </Group>
@@ -351,10 +380,11 @@ export default function Colab_GroupChatView({
> >
KIzRIM PESAN KIzRIM PESAN
</Button> */} </Button> */}
<Stack justify="center" h={"100%"} px={"sm"}> <Stack justify="center" h={"100%"} px={"sm"}>
<Grid align="center"> <Grid align="center">
<Grid.Col span={"auto"}> <Grid.Col span={"auto"}>
<Textarea <Textarea
styles={{ input: { backgroundColor: MainColor.white} }}
minRows={1} minRows={1}
radius={"md"} radius={"md"}
placeholder="Ketik pesan anda..." placeholder="Ketik pesan anda..."
@@ -366,8 +396,12 @@ export default function Colab_GroupChatView({
<ActionIcon <ActionIcon
disabled={msg === "" ? true : false} disabled={msg === "" ? true : false}
variant="filled" variant="filled"
bg={AccentColor.softblue} styles={{
color={"cyan"} root: {
backgroundColor: MainColor.white,
},
}}
color={MainColor.darkblue}
radius={"xl"} radius={"xl"}
size={"xl"} size={"xl"}
onClick={() => { onClick={() => {

View File

@@ -1,56 +1,90 @@
"use client"; "use client";
import { AccentColor } from "@/app_modules/_global/color/color_pallet"; import {
import { ComponentGlobal_AvatarAndUsername, ComponentGlobal_CardStyles } from "@/app_modules/_global/component"; ComponentGlobal_AvatarAndUsername,
ComponentGlobal_CardStyles,
} from "@/app_modules/_global/component";
import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate"; import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_tamplate";
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate"; import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate";
import { Box, Paper, Stack, Title } from "@mantine/core"; import { clientLogger } from "@/util/clientLogger";
import { Box, Stack, Title } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { useParams } from "next/navigation";
import { useState } from "react";
import {
apiGetDataGroupById
} from "../../_lib/api_collaboration";
import ComponentColab_DetailData from "../../component/detail/detail_data"; import ComponentColab_DetailData from "../../component/detail/detail_data";
import { MODEL_COLLABORATION_ROOM_CHAT } from "../../model/interface"; import {
Collaboration_SkeletonDetailInfoGroup
} from "../../component/skeleton_view";
import {
MODEL_COLLABORATION_ROOM_CHAT
} from "../../model/interface";
export default function Colab_DetailInfoGrup({ export default function Colab_DetailInfoGrup() {
dataRoom,
}: {
dataRoom: MODEL_COLLABORATION_ROOM_CHAT;
}) {
return ( return (
<> <>
<UIGlobal_LayoutTamplate <UIGlobal_LayoutTamplate
header={<UIGlobal_LayoutHeaderTamplate title="Info Grup" />} header={<UIGlobal_LayoutHeaderTamplate title="Info Grup" />}
> >
<InfoGroup dataRoom={dataRoom} /> <InfoGroup />
</UIGlobal_LayoutTamplate> </UIGlobal_LayoutTamplate>
</> </>
); );
} }
function InfoGroup({ dataRoom }: { dataRoom: MODEL_COLLABORATION_ROOM_CHAT }) { function InfoGroup() {
const params = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_COLLABORATION_ROOM_CHAT | null>(null);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const respone = await apiGetDataGroupById({
id: params.id,
kategori: "info_group",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get data info group", error);
}
}
if (_.isNull(data)) {
return (
<>
<Collaboration_SkeletonDetailInfoGroup />
</>
);
}
return ( return (
<> <>
<ComponentGlobal_CardStyles> <Stack>
<Stack> <ComponentGlobal_CardStyles marginBottom={"0px"}>
<ComponentColab_DetailData data={dataRoom.ProjectCollaboration} /> <ComponentColab_DetailData data={data?.ProjectCollaboration} />
<Paper </ComponentGlobal_CardStyles>
style={{ <ComponentGlobal_CardStyles>
border: `2px solid ${AccentColor.softblue}`, <Stack>
backgroundColor: AccentColor.blue, <Title order={6}>Anggota Grup</Title>
color: "white", {data?.ProjectCollaboration_AnggotaRoomChat.map((e, i) => (
borderRadius: "10px", <Box mb={"sm"} key={i}>
padding: "15px", <ComponentGlobal_AvatarAndUsername
}} profile={e.User.Profile as any}
> />
<Stack> </Box>
<Title order={6}>Anggota Grup</Title> ))}
{dataRoom.ProjectCollaboration_AnggotaRoomChat.map((e, i) => ( </Stack>
<Box key={i}> </ComponentGlobal_CardStyles>
</Stack>
<ComponentGlobal_AvatarAndUsername profile={e.User.Profile as any}/>
</Box>
))}
</Stack>
</Paper>
</Stack>
</ComponentGlobal_CardStyles>
</> </>
); );
} }

View File

@@ -1,42 +1,68 @@
"use client"; "use client";
import { AccentColor } from "@/app_modules/_global/color/color_pallet"; import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import { clientLogger } from "@/util/clientLogger";
import { Stack } from "@mantine/core"; import { Stack } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { useParams } from "next/navigation";
import { useState } from "react";
import { apiGetOneCollaborationById } from "../../_lib/api_collaboration";
import ComponentColab_DetailData from "../../component/detail/detail_data"; import ComponentColab_DetailData from "../../component/detail/detail_data";
import ComponentColab_DetailListPartisipasiUser from "../../component/detail/list_partisipasi_user"; import ComponentColab_DetailListPartisipasiUser from "../../component/detail/list_partisipasi_user";
import ComponentColab_AuthorNameOnHeader from "../../component/header_author_name"; import ComponentColab_AuthorNameOnHeader from "../../component/header_author_name";
import { Collaboration_SkeletonDetail } from "../../component/skeleton_view";
import { MODEL_COLLABORATION } from "../../model/interface"; import { MODEL_COLLABORATION } from "../../model/interface";
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
export default function Colab_MainDetail({ export default function Colab_MainDetail({
dataColab,
userLoginId, userLoginId,
listPartisipan,
cekPartisipan,
}: { }: {
dataColab?: MODEL_COLLABORATION;
userLoginId?: string; userLoginId?: string;
listPartisipan?: any[];
cekPartisipan: boolean;
}) { }) {
const params = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_COLLABORATION | null>(null);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "detail",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get all collaboration", error);
}
}
return ( return (
<> <>
<ComponentGlobal_CardStyles> <Stack>
<Stack> {_.isNull(data) ? (
<ComponentColab_AuthorNameOnHeader <Collaboration_SkeletonDetail />
tglPublish={new Date()} ) : (
profile={dataColab?.Author?.Profile as any} <ComponentGlobal_CardStyles>
/> <Stack>
<ComponentColab_DetailData data={dataColab} /> <ComponentColab_AuthorNameOnHeader
<ComponentColab_DetailListPartisipasiUser tglPublish={data.createdAt}
listPartisipan={listPartisipan} profile={data?.Author?.Profile as any}
userLoginId={userLoginId} />
authorId={dataColab?.Author.id} <ComponentColab_DetailData data={data as any} />
colabId={dataColab?.id} </Stack>
cekPartisipan={cekPartisipan} </ComponentGlobal_CardStyles>
/> )}
</Stack>
</ComponentGlobal_CardStyles> <ComponentColab_DetailListPartisipasiUser
userLoginId={userLoginId}
authorId={data?.Author.id}
/>
</Stack>
</> </>
); );
} }

View File

@@ -1,36 +1,60 @@
"use client"; "use client";
import { AccentColor } from "@/app_modules/_global/color/color_pallet";
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component"; import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import { apiGetOneCollaborationById } from "@/app_modules/colab/_lib/api_collaboration";
import ComponentColab_DetailData from "@/app_modules/colab/component/detail/detail_data"; import ComponentColab_DetailData from "@/app_modules/colab/component/detail/detail_data";
import ComponentColab_DetailListPartisipasiUser from "@/app_modules/colab/component/detail/list_partisipasi_user"; import ComponentColab_DetailListPartisipasiUser from "@/app_modules/colab/component/detail/list_partisipasi_user";
import ComponentColab_AuthorNameOnHeader from "@/app_modules/colab/component/header_author_name"; import ComponentColab_AuthorNameOnHeader from "@/app_modules/colab/component/header_author_name";
import { import { Collaboration_SkeletonDetail } from "@/app_modules/colab/component/skeleton_view";
MODEL_COLLABORATION, import { MODEL_COLLABORATION } from "@/app_modules/colab/model/interface";
MODEL_COLLABORATION_PARTISIPASI, import { clientLogger } from "@/util/clientLogger";
} from "@/app_modules/colab/model/interface"; import { Stack } from "@mantine/core";
import { Stack, Text } from "@mantine/core"; import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash";
import { useParams } from "next/navigation";
import { useState } from "react";
export default function Colab_DetailPartisipasiProyek() {
const params = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_COLLABORATION | null>(null);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "detail",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get all collaboration", error);
}
}
export default function Colab_DetailPartisipasiProyek({
dataColab,
listPartisipan,
}: {
dataColab: MODEL_COLLABORATION;
listPartisipan: MODEL_COLLABORATION_PARTISIPASI[];
}) {
return ( return (
<> <>
<ComponentGlobal_CardStyles> {_.isNull(data) ? (
<Collaboration_SkeletonDetail />
) : (
<Stack> <Stack>
<ComponentColab_AuthorNameOnHeader <ComponentGlobal_CardStyles>
profile={dataColab.Author.Profile} <Stack>
/> <ComponentColab_AuthorNameOnHeader
<ComponentColab_DetailData data={dataColab} /> profile={data.Author.Profile}
<ComponentColab_DetailListPartisipasiUser />
listPartisipan={listPartisipan} <ComponentColab_DetailData data={data} />
/> </Stack>
</ComponentGlobal_CardStyles>
<ComponentColab_DetailListPartisipasiUser />
</Stack> </Stack>
</ComponentGlobal_CardStyles> )}
</> </>
); );
} }

View File

@@ -9,137 +9,185 @@ import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil"; import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan"; import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import { apiGetOneCollaborationById } from "@/app_modules/colab/_lib/api_collaboration";
import ComponentColab_DetailData from "@/app_modules/colab/component/detail/detail_data"; import ComponentColab_DetailData from "@/app_modules/colab/component/detail/detail_data";
import ComponentColab_AuthorNameOnListPartisipan from "@/app_modules/colab/component/detail/header_author_list_partisipan"; import ComponentColab_AuthorNameOnListPartisipan from "@/app_modules/colab/component/detail/header_author_list_partisipan";
import ComponentColab_IsEmptyData from "@/app_modules/colab/component/is_empty_data"; import ComponentColab_IsEmptyData from "@/app_modules/colab/component/is_empty_data";
import {
Collaboration_SkeletonDetail,
Collaboration_SkeletonListPrtisipanIsUser,
} from "@/app_modules/colab/component/skeleton_view";
import colab_funCreateRoomChat from "@/app_modules/colab/fun/create/fun_create_room_chat"; import colab_funCreateRoomChat from "@/app_modules/colab/fun/create/fun_create_room_chat";
import { gs_colab_hot_menu } from "@/app_modules/colab/global_state"; import { gs_colab_hot_menu } from "@/app_modules/colab/global_state";
import { import {
MODEL_COLLABORATION, MODEL_COLLABORATION,
MODEL_COLLABORATION_PARTISIPASI, MODEL_COLLABORATION_PARTISIPASI,
} from "@/app_modules/colab/model/interface"; } from "@/app_modules/colab/model/interface";
import mqtt_client from "@/util/mqtt_client"; import { clientLogger } from "@/util/clientLogger";
import { import {
ActionIcon, ActionIcon,
Box,
Button, Button,
Center,
Checkbox, Checkbox,
Drawer, Drawer,
Grid, Grid,
Group, Group,
Paper, Loader,
ScrollArea,
Stack, Stack,
Text, Text,
TextInput, TextInput,
Title, Title,
} from "@mantine/core"; } from "@mantine/core";
import { useDisclosure } from "@mantine/hooks"; import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { IconX } from "@tabler/icons-react"; import { IconX } from "@tabler/icons-react";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import _ from "lodash"; import _ from "lodash";
import { useRouter } from "next/navigation"; import { ScrollOnly } from "next-scroll-loader";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react"; import { useState } from "react";
export default function Colab_DetailProyekSaya({ export default function Colab_DetailProyekSaya() {
dataColab, const params = useParams<{ id: string }>();
listPartisipan, const [data, setData] = useState<MODEL_COLLABORATION | null>(null);
}: {
dataColab: MODEL_COLLABORATION;
listPartisipan: MODEL_COLLABORATION_PARTISIPASI[];
}) {
return (
<>
<ComponentGlobal_CardStyles marginBottom={"15px"}>
<Stack>
<ComponentColab_DetailData data={dataColab} />
<CheckBoxPartisipan
listPartisipan={listPartisipan}
colabId={dataColab.id}
/>
</Stack>
</ComponentGlobal_CardStyles>
</>
);
}
function CheckBoxPartisipan({ useShallowEffect(() => {
listPartisipan, onLoadData();
colabId, }, []);
}: {
listPartisipan: MODEL_COLLABORATION_PARTISIPASI[]; async function onLoadData() {
colabId: string; try {
}) { const respone = await apiGetOneCollaborationById({
const [value, setValue] = useState<string[]>([]); id: params.id,
kategori: "detail",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get all collaboration", error);
}
}
return ( return (
<> <>
<Stack> <Stack>
{/* <pre>{JSON.stringify(listPartisipan,null,2)}</pre> */} {_.isNull(data) ? (
<Paper <Collaboration_SkeletonDetail />
style={{ ) : (
border: `2px solid ${AccentColor.softblue}`, <ComponentGlobal_CardStyles marginBottom={"15px"}>
backgroundColor: AccentColor.blue, <ComponentColab_DetailData data={data} />
color: "white", </ComponentGlobal_CardStyles>
borderRadius: "10px", )}
marginBottom: "20px",
padding: "15px", <CheckBoxPartisipan />
}}
>
{/* {JSON.stringify(value, null, 2)} */}
<Stack>
<Stack spacing={5}>
<Text c={"red"} fz={10}>
*
<Text px={"xs"} span inherit c={"white"}>
Pilih user yang akan menjadi tim proyek anda
</Text>
</Text>
{/* <Text c={"red"} fz={10}>
*
<Text px={"xs"} span inherit c={"white"}>
Room chat dapat dibentuk jika ada 2 user yang dipilih
</Text>
</Text> */}
</Stack>
<ScrollArea h={400} offsetScrollbars>
<Checkbox.Group value={value} onChange={setValue}>
<Stack mt="xs">
{_.isEmpty(listPartisipan) ? (
<ComponentColab_IsEmptyData text="Tidak Ada Pertisipan" />
) : (
listPartisipan.map((e, i) => (
<Grid key={i} align="center">
<Grid.Col span={2}>
<Checkbox color={"yellow"} value={e?.User?.id} />
</Grid.Col>
<Grid.Col span={"auto"}>
<ComponentColab_AuthorNameOnListPartisipan
isPembatas={true}
author={e?.User}
deskripsi={e?.deskripsi_diri}
/>
</Grid.Col>
</Grid>
))
)}
</Stack>
</Checkbox.Group>
</ScrollArea>
</Stack>
</Paper>
<ButtonAction value={value} colabId={colabId} />
</Stack> </Stack>
</> </>
); );
} }
function ButtonAction({ function CheckBoxPartisipan() {
value, const params = useParams<{ id: string }>();
colabId, const [value, setValue] = useState<string[]>([]);
}: { const [data, setData] = useState<MODEL_COLLABORATION_PARTISIPASI[] | null>(
value: string[]; null
colabId: string; );
}) { const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoadDataPartisipan();
}, []);
async function onLoadDataPartisipan() {
try {
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "list_partisipan",
page: `${activePage}`,
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get list partisipan", error);
}
}
if (_.isNull(data)) {
return <Collaboration_SkeletonListPrtisipanIsUser />;
}
return (
<>
<Stack mb={"lg"}>
<ComponentGlobal_CardStyles>
<Stack>
<Stack spacing={5}>
<Text c={"red"} fz={10}>
*
<Text px={"xs"} span inherit c={MainColor.white}>
Pilih user yang akan menjadi tim proyek anda
</Text>
</Text>
</Stack>
{_.isEmpty(data) ? (
<ComponentColab_IsEmptyData text="Tidak Ada Pertisipan" />
) : (
<Box>
<ScrollOnly
height="50vh"
renderLoading={() => (
<Center mt={"lg"}>
<Loader color={"yellow"} />
</Center>
)}
data={data}
setData={setData as any}
moreData={async () => {
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "list_partisipan",
page: `${activePage + 1}`,
});
setActivePage((val) => val + 1);
return respone.data;
}}
>
{(item) => (
<Checkbox.Group value={value} onChange={setValue}>
<Grid key={item} align="center">
<Grid.Col span={2}>
<Checkbox color={"yellow"} value={item.User?.id} />
</Grid.Col>
<Grid.Col span={"auto"}>
<ComponentColab_AuthorNameOnListPartisipan
isPembatas={true}
author={item.User}
deskripsi={item.deskripsi_diri}
/>
</Grid.Col>
</Grid>
</Checkbox.Group>
)}
</ScrollOnly>
</Box>
)}
</Stack>
</ComponentGlobal_CardStyles>
<ButtonAction value={value} />
</Stack>
</>
);
}
function ButtonAction({ value }: { value: string[] }) {
const params = useParams<{ id: string }>();
const router = useRouter(); const router = useRouter();
const [opened, { open, close }] = useDisclosure(false); const [opened, { open, close }] = useDisclosure(false);
const [hotMenu, setHotMenu] = useAtom(gs_colab_hot_menu); const [hotMenu, setHotMenu] = useAtom(gs_colab_hot_menu);
@@ -147,29 +195,35 @@ function ButtonAction({
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
async function onSave() { async function onSave() {
if (nameRoom === "") try {
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Nama Grup"); setLoading(true);
if (nameRoom === "")
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Nama Grup");
// await notifikasiToUser_CreateGroupCollaboration({ colabId: colabId }); // await notifikasiToUser_CreateGroupCollaboration({ colabId: colabId });
const res = await colab_funCreateRoomChat(nameRoom, value, colabId); const res = await colab_funCreateRoomChat(nameRoom, value, params.id);
if (res.status === 201) { if (res.status === 201) {
for (let a of value) { // for (let a of value) {
mqtt_client.publish( // mqtt_client.publish(
"USER", // "USER",
JSON.stringify({ // JSON.stringify({
userId: a, // userId: a,
count: 1, // count: 1,
}) // })
); // );
// }
ComponentGlobal_NotifikasiBerhasil("Berhasil Membuat Grup");
setHotMenu(4);
router.replace(RouterColab.grup_diskusi);
} else {
ComponentGlobal_NotifikasiGagal("Gagal Membuat Grup");
} }
} catch (error) {
setLoading(true); clientLogger.error("Error create room chat", error);
ComponentGlobal_NotifikasiBerhasil("Berhasil Membuat Grup"); } finally {
setHotMenu(4); setLoading(false);
router.push(RouterColab.grup_diskusi);
} else {
ComponentGlobal_NotifikasiGagal("Gagal Membuat Grup");
} }
} }
@@ -188,7 +242,7 @@ function ButtonAction({
transition: "0.5s", transition: "0.5s",
}} }}
> >
Buat Ruang Diskusi{" "} Buat Ruang Diskusi
</Button> </Button>
<Drawer <Drawer
@@ -220,12 +274,13 @@ function ButtonAction({
> >
<Stack> <Stack>
<Group position="apart"> <Group position="apart">
<Title order={6}>Nama Grup Diskusi</Title> <Title c={MainColor.white} order={6}>Nama Grup Diskusi</Title>
<ActionIcon onClick={close} variant="transparent"> <ActionIcon onClick={close} variant="transparent">
<IconX color="white" /> <IconX color={MainColor.white} />
</ActionIcon> </ActionIcon>
</Group> </Group>
<TextInput <TextInput
styles={{ input: { backgroundColor: MainColor.white } }}
placeholder="Masukan nama grup diskusi .." placeholder="Masukan nama grup diskusi .."
radius={"xl"} radius={"xl"}
onChange={(val) => { onChange={(val) => {

View File

@@ -6,22 +6,22 @@ import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_ta
import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate"; import UIGlobal_LayoutTamplate from "@/app_modules/_global/ui/ui_layout_tamplate";
import { ActionIcon } from "@mantine/core"; import { ActionIcon } from "@mantine/core";
import { IconDotsVertical, IconEdit } from "@tabler/icons-react"; import { IconDotsVertical, IconEdit } from "@tabler/icons-react";
import { useParams } from "next/navigation";
import React, { useState } from "react"; import React, { useState } from "react";
export default function LayoutColab_DetailProyekSaya({ export default function LayoutColab_DetailProyekSaya({
children, children,
colabId,
}: { }: {
children: React.ReactNode; children: React.ReactNode;
colabId: string;
}) { }) {
const params = useParams<{id: string}>()
const [openDrawer, setOpenDrawer] = useState(false); const [openDrawer, setOpenDrawer] = useState(false);
const listPage = [ const listPage = [
{ {
id: "1", id: "1",
name: "Edit Proyek", name: "Edit Proyek",
icon: <IconEdit />, icon: <IconEdit />,
path: RouterColab.edit + colabId, path: RouterColab.edit + params.id,
}, },
]; ];

View File

@@ -13,6 +13,7 @@ import {
MODEL_COLLABORATION, MODEL_COLLABORATION,
MODEL_COLLABORATION_MASTER, MODEL_COLLABORATION_MASTER,
} from "../model/interface"; } from "../model/interface";
import { clientLogger } from "@/util/clientLogger";
export default function Colab_Edit({ export default function Colab_Edit({
selectedData, selectedData,
@@ -30,8 +31,14 @@ export default function Colab_Edit({
maxLength={100} maxLength={100}
styles={{ styles={{
label: { label: {
color: "white", color: MainColor.white,
}, },
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
}
}} }}
label="Judul" label="Judul"
withAsterisk withAsterisk
@@ -49,8 +56,14 @@ export default function Colab_Edit({
maxLength={100} maxLength={100}
styles={{ styles={{
label: { label: {
color: "white", color: MainColor.white,
}, },
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
}
}} }}
label="Lokasi" label="Lokasi"
withAsterisk withAsterisk
@@ -67,8 +80,17 @@ export default function Colab_Edit({
<Select <Select
styles={{ styles={{
label: { label: {
color: "white", color: MainColor.white,
}, },
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
},
dropdown: {
backgroundColor: MainColor.white,
}
}} }}
placeholder="Pilih kategori industri" placeholder="Pilih kategori industri"
label="Pilih Industri" label="Pilih Industri"
@@ -113,8 +135,14 @@ export default function Colab_Edit({
<Textarea <Textarea
styles={{ styles={{
label: { label: {
color: "white", color: MainColor.white,
}, },
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
}
}} }}
label="Tujuan Proyek" label="Tujuan Proyek"
placeholder="Masukan tujuan proyek" placeholder="Masukan tujuan proyek"
@@ -138,7 +166,10 @@ export default function Colab_Edit({
<Textarea <Textarea
styles={{ styles={{
label: { label: {
color: "white", color: MainColor.white,
},
input: {
backgroundColor: MainColor.white,
}, },
}} }}
label="Keuntungan " label="Keuntungan "
@@ -181,12 +212,18 @@ function ButtonAction({ value }: { value: any }) {
// return ComponentGlobal_NotifikasiPeringatan("Minimal Ada 2 Partisipan"); // return ComponentGlobal_NotifikasiPeringatan("Minimal Ada 2 Partisipan");
await colab_funEditById(value as any).then((res) => { await colab_funEditById(value as any).then((res) => {
if (res.status === 200) { try {
setLoading(true); setLoading(true);
router.back(); if (res.status === 200) {
ComponentGlobal_NotifikasiBerhasil(res.message); router.back();
} else { ComponentGlobal_NotifikasiBerhasil(res.message);
ComponentGlobal_NotifikasiGagal(res.message); } else {
setLoading(false)
ComponentGlobal_NotifikasiGagal(res.message);
}
} catch (error) {
setLoading(false)
clientLogger.error("Error update proyek", error);
} }
}); });
} }

View File

@@ -2,17 +2,29 @@
import prisma from "@/app/lib/prisma"; import prisma from "@/app/lib/prisma";
import { RouterColab } from "@/app/lib/router_hipmi/router_colab"; import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { revalidatePath } from "next/cache"; import { revalidatePath } from "next/cache";
export default async function colab_funCreatePartisipan( export default async function colab_funCreatePartisipan({
colabId: string, id,
userId: string, deskripsi,
deskripsi: string }: {
) { id: string;
deskripsi: string;
}) {
const userLoginId = await funGetUserIdByToken();
if (userLoginId == null) {
return {
status: 500,
message: "Gagal mendapatkan data, user id tidak ada",
};
}
const create = await prisma.projectCollaboration_Partisipasi.create({ const create = await prisma.projectCollaboration_Partisipasi.create({
data: { data: {
projectCollaborationId: colabId, projectCollaborationId: id,
userId: userId, userId: userLoginId,
deskripsi_diri: deskripsi, deskripsi_diri: deskripsi,
}, },
select: { select: {
@@ -27,7 +39,7 @@ export default async function colab_funCreatePartisipan(
}); });
if (!create) return { status: 400, message: "Gagal menambahkan partisipan" }; if (!create) return { status: 400, message: "Gagal menambahkan partisipan" };
revalidatePath(RouterColab.main_detail + colabId); revalidatePath(RouterColab.main_detail + id);
return { return {
data: create, data: create,
status: 201, status: 201,

View File

@@ -26,5 +26,5 @@ export default async function colab_funCreateProyek(
if (!data) return { status: 400, message: "Gagal Membuat Proyek" }; if (!data) return { status: 400, message: "Gagal Membuat Proyek" };
revalidatePath(RouterColab.beranda); revalidatePath(RouterColab.beranda);
return { data, status: 201, message: "Berhasil Membuar Proyek" }; return { data, status: 201, message: "Berhasil Membuat Proyek" };
} }

View File

@@ -9,23 +9,41 @@ import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash"; import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader"; import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react"; import { useState } from "react";
import { apiGetAllCollaboration } from "../_lib/api_collaboration";
import { ComponentColab_ButtonUpdateBeranda } from "../component/button/button_update_beranda"; import { ComponentColab_ButtonUpdateBeranda } from "../component/button/button_update_beranda";
import { ComponentColab_CardBeranda } from "../component/card_view/card_beranda"; import { ComponentColab_CardBeranda } from "../component/card_view/card_beranda";
import colab_getListAllProyek from "../fun/get/get_list_all_proyek";
import { MODEL_COLLABORATION } from "../model/interface"; import { MODEL_COLLABORATION } from "../model/interface";
import { Collaboration_SkeletonBeranda } from "../component/skeleton_view";
import { clientLogger } from "@/util/clientLogger";
export default function Colab_Beranda({ export default function Colab_Beranda({
listData,
userLoginId, userLoginId,
}: { }: {
listData: MODEL_COLLABORATION[];
userLoginId: string; userLoginId: string;
}) { }) {
const [data, setData] = useState(listData); const [data, setData] = useState<MODEL_COLLABORATION[] | null>(null);
const [activePage, setActivePage] = useState(1); const [activePage, setActivePage] = useState(1);
const [isNewPost, setIsNewPost] = useState(false); const [isNewPost, setIsNewPost] = useState(false);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const respone = await apiGetAllCollaboration({
kategori: "beranda",
page: "1",
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get all collaboration", error);
}
}
useShallowEffect(() => { useShallowEffect(() => {
mqtt_client.subscribe("Colab_create"); mqtt_client.subscribe("Colab_create");
@@ -36,6 +54,10 @@ export default function Colab_Beranda({
}); });
}, []); }, []);
if (_.isNull(data)) {
return <Collaboration_SkeletonBeranda />;
}
return ( return (
<> <>
<Box> <Box>
@@ -62,15 +84,16 @@ export default function Colab_Beranda({
</Center> </Center>
)} )}
data={data} data={data}
setData={setData} setData={setData as any}
moreData={async () => { moreData={async () => {
const loadData = await colab_getListAllProyek({ const respone = await apiGetAllCollaboration({
page: activePage + 1, kategori: "beranda",
page: `${activePage + 1}`,
}); });
setActivePage((val) => val + 1); setActivePage((val) => val + 1);
return loadData; return respone.data;
}} }}
> >
{(item) => ( {(item) => (

View File

@@ -1,28 +1,51 @@
"use client"; "use client";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { import { Box, Center, Loader, Skeleton, Stack } from "@mantine/core";
Box,
Center,
Loader
} from "@mantine/core";
import _ from "lodash"; import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader"; import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react"; import { useState } from "react";
import { ComponentColab_CardGrup } from "../../component/card_view/crad_grup"; import { ComponentColab_CardGrup } from "../../component/card_view/crad_grup";
import colab_getListRoomChatByAuthorId from "../../fun/get/room_chat/get_list_room_by_author_id"; import colab_getListRoomChatByAuthorId from "../../fun/get/room_chat/get_list_room_by_author_id";
import { MODEL_COLLABORATION_ANGGOTA_ROOM_CHAT } from "../../model/interface";
import { clientLogger } from "@/util/clientLogger";
import { useShallowEffect } from "@mantine/hooks";
import { apiGetAllCollaboration } from "../../_lib/api_collaboration";
import { import {
MODEL_COLLABORATION_ANGGOTA_ROOM_CHAT Collaboration_SkeletonBeranda,
} from "../../model/interface"; Collaboration_SkeletonGrup,
} from "../../component/skeleton_view";
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
export default function Colab_GrupDiskus({ export default function Colab_GrupDiskus() {
listRoom, const [data, setData] = useState<
}: { MODEL_COLLABORATION_ANGGOTA_ROOM_CHAT[] | null
listRoom: MODEL_COLLABORATION_ANGGOTA_ROOM_CHAT[]; >(null);
}) {
const [data, setData] = useState(listRoom);
const [activePage, setActivePage] = useState(1); const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const respone = await apiGetAllCollaboration({
kategori: "grup",
page: `${activePage}`,
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get grup", error);
}
}
if (_.isNull(data)) {
return <Collaboration_SkeletonGrup />;
}
return ( return (
<> <>
<Box> <Box>
@@ -38,15 +61,16 @@ export default function Colab_GrupDiskus({
</Center> </Center>
)} )}
data={data} data={data}
setData={setData} setData={setData as any}
moreData={async () => { moreData={async () => {
const loadData = await colab_getListRoomChatByAuthorId({ const respone = await apiGetAllCollaboration({
page: activePage + 1, kategori: "grup",
page: `${activePage + 1}`,
}); });
setActivePage((val) => val + 1); setActivePage((val) => val + 1);
return loadData; return respone.data;
}} }}
> >
{(item) => <ComponentColab_CardGrup data={item} />} {(item) => <ComponentColab_CardGrup data={item} />}

View File

@@ -60,7 +60,7 @@ export default function LayoutColab_Main({
<ActionIcon <ActionIcon
// disabled={e.path === "" ? true : false} // disabled={e.path === "" ? true : false}
variant="transparent" variant="transparent"
c={hotMenu === e.id ? MainColor.yellow : "white"} c={hotMenu === e.id ? MainColor.yellow : MainColor.white}
onClick={() => { onClick={() => {
router.replace(e.path, { scroll: false }); router.replace(e.path, { scroll: false });
setHotMenu(e.id); setHotMenu(e.id);
@@ -69,7 +69,7 @@ export default function LayoutColab_Main({
{e.icon} {e.icon}
</ActionIcon> </ActionIcon>
<Text <Text
c={hotMenu === e.id ? MainColor.yellow : "white"} c={hotMenu === e.id ? MainColor.yellow : MainColor.white}
fz={"xs"} fz={"xs"}
lineClamp={1} lineClamp={1}
> >

View File

@@ -1,25 +1,17 @@
"use client"; "use client";
import {
AccentColor,
MainColor,
} from "@/app_modules/_global/color/color_pallet";
import { Stack, Tabs, Text } from "@mantine/core"; import { Stack, Tabs, Text } from "@mantine/core";
import { IconBrandOffice, IconUsersGroup, IconUser } from "@tabler/icons-react"; import { IconUser, IconUsersGroup } from "@tabler/icons-react";
import { useState } from "react";
import Colab_ProyekSaya from "./saya";
import Colab_PartisipasiProyek from "./partisipasi";
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { gs_colab_proyek } from "../../global_state"; import { gs_colab_proyek } from "../../global_state";
import { import Colab_PartisipasiProyek from "./partisipasi";
MODEL_COLLABORATION, import Colab_ProyekSaya from "./saya";
MODEL_COLLABORATION_PARTISIPASI,
} from "../../model/interface";
import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet";
export default function Colab_Proyek({ export default function Colab_Proyek() {
listPartisipasiUser,
listProyekSaya,
}: {
listPartisipasiUser: MODEL_COLLABORATION_PARTISIPASI[];
listProyekSaya: MODEL_COLLABORATION[];
}) {
const [activeTab, setActiveTab] = useAtom(gs_colab_proyek); const [activeTab, setActiveTab] = useAtom(gs_colab_proyek);
const listTabs = [ const listTabs = [
@@ -28,18 +20,14 @@ export default function Colab_Proyek({
icon: <IconUsersGroup />, icon: <IconUsersGroup />,
label: "Partisipasi Proyek", label: "Partisipasi Proyek",
value: "Partisipasi", value: "Partisipasi",
path: ( path: <Colab_PartisipasiProyek />,
<Colab_PartisipasiProyek
listPartisipasiUser={listPartisipasiUser as any}
/>
),
}, },
{ {
id: 2, id: 2,
icon: <IconUser />, icon: <IconUser />,
label: "Proyek Saya", label: "Proyek Saya",
value: "Saya", value: "Saya",
path: <Colab_ProyekSaya listProyekSaya={listProyekSaya as any} />, path: <Colab_ProyekSaya />,
}, },
]; ];
@@ -64,15 +52,15 @@ export default function Colab_Proyek({
key={e.id} key={e.id}
value={e.value} value={e.value}
fw={"bold"} fw={"bold"}
c={"black"}
style={{ style={{
transition: "0.5s", transition: "0.5s",
color: activeTab === e.value ? MainColor.darkblue : MainColor.black,
backgroundColor: backgroundColor:
activeTab === e.value ? MainColor.yellow : "white", activeTab === e.value ? MainColor.yellow : MainColor.white,
border: border:
activeTab === e.value activeTab === e.value
? `1px solid ${AccentColor.yellow}` ? `1px solid ${AccentColor.yellow}`
: `1px solid white`, : `1px solid ${MainColor.white}`,
}} }}
> >
<Stack align="center" justify="center" spacing={0}> <Stack align="center" justify="center" spacing={0}>

View File

@@ -2,28 +2,51 @@
import { RouterColab } from "@/app/lib/router_hipmi/router_colab"; import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader } from "@mantine/core"; import { Box, Center, Loader } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash"; import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader"; import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react"; import { useState } from "react";
import { apiGetAllCollaboration } from "../../_lib/api_collaboration";
import { ComponentColab_CardSemuaPartisipan } from "../../component/card_view/card_semua_partisipan"; import { ComponentColab_CardSemuaPartisipan } from "../../component/card_view/card_semua_partisipan";
import colab_getListPartisipasiProyekByAuthorId from "../../fun/get/pasrtisipan/get_list_partisipasi_proyek_by_author_id"; import { Collaboration_SkeletonBeranda } from "../../component/skeleton_view";
import { MODEL_COLLABORATION_PARTISIPASI } from "../../model/interface"; import { MODEL_COLLABORATION_PARTISIPASI } from "../../model/interface";
export default function Colab_PartisipasiProyek({ export default function Colab_PartisipasiProyek() {
listPartisipasiUser, const [data, setData] = useState<MODEL_COLLABORATION_PARTISIPASI[] | null>(
}: { null
listPartisipasiUser: MODEL_COLLABORATION_PARTISIPASI[]; );
}) {
const [data, setData] = useState(listPartisipasiUser);
const [activePage, setActivePage] = useState(1); const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const respone = await apiGetAllCollaboration({
kategori: "partisipasi",
page: `${activePage}`,
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get partisipasi", error);
}
}
if (_.isNull(data)) {
return <Collaboration_SkeletonBeranda />;
}
return ( return (
<> <>
{_.isEmpty(data) ? ( {_.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData /> <ComponentGlobal_IsEmptyData />
) : ( ) : (
// --- Main component --- //
<Box> <Box>
<ScrollOnly <ScrollOnly
height="73vh" height="73vh"
@@ -33,14 +56,15 @@ export default function Colab_PartisipasiProyek({
</Center> </Center>
)} )}
data={data} data={data}
setData={setData} setData={setData as any}
moreData={async () => { moreData={async () => {
const loadData = await colab_getListPartisipasiProyekByAuthorId({ const respone = await apiGetAllCollaboration({
page: activePage + 1, kategori: "partisipasi",
page: `${activePage + 1}`,
}); });
setActivePage((val) => val + 1); setActivePage((val) => val + 1);
return loadData; return respone.data;
}} }}
> >
{(item) => ( {(item) => (

View File

@@ -2,29 +2,51 @@
import { RouterColab } from "@/app/lib/router_hipmi/router_colab"; import { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data"; import ComponentGlobal_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { clientLogger } from "@/util/clientLogger";
import { Box, Center, Loader } from "@mantine/core"; import { Box, Center, Loader } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import _ from "lodash"; import _ from "lodash";
import { ScrollOnly } from "next-scroll-loader"; import { ScrollOnly } from "next-scroll-loader";
import { useState } from "react"; import { useState } from "react";
import { apiGetAllCollaboration } from "../../_lib/api_collaboration";
import { ComponentColab_CardProyekSaya } from "../../component/card_view/card_proyek_saya"; import { ComponentColab_CardProyekSaya } from "../../component/card_view/card_proyek_saya";
import colab_getListAllProyekSayaByAuthorId from "../../fun/get/pasrtisipan/get_list_proyek_saya_by_author_id"; import { Collaboration_SkeletonBeranda } from "../../component/skeleton_view";
import { MODEL_COLLABORATION } from "../../model/interface"; import { MODEL_COLLABORATION } from "../../model/interface";
export default function Colab_ProyekSaya({ export default function Colab_ProyekSaya() {
listProyekSaya, const [data, setData] = useState<MODEL_COLLABORATION[] | null>(null);
}: {
listProyekSaya: MODEL_COLLABORATION[];
}) {
const [data, setData] = useState(listProyekSaya);
const [activePage, setActivePage] = useState(1); const [activePage, setActivePage] = useState(1);
useShallowEffect(() => {
onLoadData();
}, []);
async function onLoadData() {
try {
const respone = await apiGetAllCollaboration({
kategori: "proyeksaya",
page: `${activePage}`,
});
if (respone) {
setData(respone.data);
}
} catch (error) {
clientLogger.error("Error get proyeksaya", error);
}
}
if (_.isNull(data)) {
return <Collaboration_SkeletonBeranda />;
}
return ( return (
<> <>
{_.isEmpty(data) ? ( {_.isEmpty(data) ? (
<ComponentGlobal_IsEmptyData /> <ComponentGlobal_IsEmptyData />
) : ( ) : (
// --- Main component --- // // --- Main component --- //
<Box > <Box>
<ScrollOnly <ScrollOnly
height="73vh" height="73vh"
renderLoading={() => ( renderLoading={() => (
@@ -33,14 +55,16 @@ export default function Colab_ProyekSaya({
</Center> </Center>
)} )}
data={data} data={data}
setData={setData} setData={setData as any}
moreData={async () => { moreData={async () => {
const loadData = await colab_getListAllProyekSayaByAuthorId({ const respone = await apiGetAllCollaboration({
page: activePage + 1, kategori: "proyeksaya",
page: `${activePage + 1}`,
}); });
setActivePage((val) => val + 1); setActivePage((val) => val + 1);
return loadData; return respone.data;
}} }}
> >
{(item) => ( {(item) => (

View File

@@ -13,6 +13,8 @@ import {
import { useAtom } from "jotai"; import { useAtom } from "jotai";
import { gs_donasi_tabs_posting } from "../../global_state"; import { gs_donasi_tabs_posting } from "../../global_state";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { AccentColor, MainColor } from "@/app_modules/_global/color";
import { clientLogger } from "@/util/clientLogger";
export function Donasi_ComponentButtonDeleteDonasiById({ export function Donasi_ComponentButtonDeleteDonasiById({
donasiId, donasiId,
@@ -24,6 +26,7 @@ export function Donasi_ComponentButtonDeleteDonasiById({
imageId: string; imageId: string;
}) { }) {
const router = useRouter(); const router = useRouter();
const [isLoading, setLoading] = useState(false);
const [openModal, setOpenModal] = useState(false); const [openModal, setOpenModal] = useState(false);
const [tabsPostingDonasi, setTabsPostingDonasi] = useAtom( const [tabsPostingDonasi, setTabsPostingDonasi] = useAtom(
gs_donasi_tabs_posting gs_donasi_tabs_posting
@@ -31,28 +34,35 @@ export function Donasi_ComponentButtonDeleteDonasiById({
async function onDelete() { async function onDelete() {
const del = await Donasi_funDeleteDonasiById(donasiId); const del = await Donasi_funDeleteDonasiById(donasiId);
if (del.status === 200) { try {
const deleteImageDonasi = await funGlobal_DeleteFileById({ setLoading(true);
fileId: imageId as any, if (del.status === 200) {
}); const deleteImageDonasi = await funGlobal_DeleteFileById({
fileId: imageId as any,
});
if (!deleteImageDonasi.success) { if (!deleteImageDonasi.success) {
ComponentGlobal_NotifikasiPeringatan("Gagal hapus gambar "); ComponentGlobal_NotifikasiPeringatan("Gagal hapus gambar ");
}
const deleteImageCerita = await funGlobal_DeleteFileById({
fileId: imageCeritaId as any,
});
if (!deleteImageCerita.success) {
ComponentGlobal_NotifikasiPeringatan("Gagal hapus gambar ");
}
router.replace(RouterDonasi.status_galang_dana({ id: "3" }));
setTabsPostingDonasi("Draft");
ComponentGlobal_NotifikasiBerhasil(del.message);
} else {
setLoading(false);
ComponentGlobal_NotifikasiGagal(del.message);
} }
} catch (error) {
const deleteImageCerita = await funGlobal_DeleteFileById({ setLoading(false);
fileId: imageCeritaId as any, clientLogger.error("Error delete donasi", error);
});
if (!deleteImageCerita.success) {
ComponentGlobal_NotifikasiPeringatan("Gagal hapus gambar ");
}
router.replace(RouterDonasi.status_galang_dana({ id: "3" }));
setTabsPostingDonasi("Draft");
ComponentGlobal_NotifikasiBerhasil(del.message);
} else {
ComponentGlobal_NotifikasiGagal(del.message);
} }
} }
@@ -60,7 +70,8 @@ export function Donasi_ComponentButtonDeleteDonasiById({
<> <>
<Button <Button
radius={"xl"} radius={"xl"}
color="red" style={{ backgroundColor: MainColor.red }}
c={AccentColor.white}
onClick={() => { onClick={() => {
setOpenModal(true); setOpenModal(true);
}} }}
@@ -73,12 +84,13 @@ export function Donasi_ComponentButtonDeleteDonasiById({
opened={openModal} opened={openModal}
close={() => setOpenModal(false)} close={() => setOpenModal(false)}
buttonKiri={ buttonKiri={
<Button radius={"xl"} onClick={() => setOpenModal(false)}> <Button style={{ backgroundColor: AccentColor.blue }}
c={AccentColor.white} radius={"xl"} onClick={() => setOpenModal(false)}>
Batal Batal
</Button> </Button>
} }
buttonKanan={ buttonKanan={
<Button radius={"xl"} color="red" onClick={() => onDelete()}> <Button c={AccentColor.white} loading={isLoading} loaderPosition="center" radius={"xl"} style={{ backgroundColor: MainColor.red}} onClick={() => onDelete()}>
Hapus Hapus
</Button> </Button>
} }

View File

@@ -1,5 +1,5 @@
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi"; import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { AccentColor } from "@/app_modules/_global/color/color_pallet"; import { AccentColor, MainColor } from "@/app_modules/_global/color/color_pallet";
import { ComponentGlobal_LoadImageCustom } from "@/app_modules/_global/component"; import { ComponentGlobal_LoadImageCustom } from "@/app_modules/_global/component";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal"; import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { Badge, Card, Grid, Group, Progress, Stack, Text } from "@mantine/core"; import { Badge, Card, Grid, Group, Progress, Stack, Text } from "@mantine/core";
@@ -36,7 +36,7 @@ export function ComponentDonasi_CardInvoiceNew({ data, }: { data: IDataAllDonasi
padding: "15px", padding: "15px",
cursor: "pointer", cursor: "pointer",
borderRadius: "10px", borderRadius: "10px",
color: "white", color: MainColor.white,
marginBottom: "15px", marginBottom: "15px",
}} }}
onClick={() => onCekInvoice()} onClick={() => onCekInvoice()}

View File

@@ -5,6 +5,7 @@ import { Grid, Progress, Stack, Text } from "@mantine/core";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import ComponentDonasi_TampilanHitungMundur from "../tampilan_hitung_mundur"; import ComponentDonasi_TampilanHitungMundur from "../tampilan_hitung_mundur";
import TampilanRupiahDonasi from "../tampilan_rupiah"; import TampilanRupiahDonasi from "../tampilan_rupiah";
import { MainColor } from "@/app_modules/_global/color";
export default function ComponentDonasi_CardPublishNew({ data }: { data: any; }) { export default function ComponentDonasi_CardPublishNew({ data }: { data: any; }) {
const router = useRouter(); const router = useRouter();
@@ -27,7 +28,7 @@ export default function ComponentDonasi_CardPublishNew({ data }: { data: any; })
<Grid.Col span={6}> <Grid.Col span={6}>
<Stack spacing={"xs"}> <Stack spacing={"xs"}>
<Stack spacing={0}> <Stack spacing={0}>
<Text fz={"sm"} fw={"bold"} lineClamp={2}> <Text c={MainColor.white} fz={"sm"} fw={"bold"} lineClamp={2}>
{data.title} {data.title}
</Text> </Text>
<ComponentDonasi_TampilanHitungMundur <ComponentDonasi_TampilanHitungMundur
@@ -38,8 +39,8 @@ export default function ComponentDonasi_CardPublishNew({ data }: { data: any; })
</Stack> </Stack>
<Progress value={+data.progres} color="yellow" /> <Progress value={+data.progres} color="yellow" />
<Stack spacing={0}> <Stack spacing={0}>
<Text fz={"sm"}>Terkumpul</Text> <Text c={MainColor.white} fz={"sm"}>Terkumpul</Text>
<Text fz={"sm"} fw={"bold"} c={"orange"} truncate> <Text c={MainColor.white} fz={"sm"} fw={"bold"} truncate>
<TampilanRupiahDonasi nominal={+data.terkumpul} /> <TampilanRupiahDonasi nominal={+data.terkumpul} />
</Text> </Text>
</Stack> </Stack>

View File

@@ -25,7 +25,7 @@ export default function ComponentDonasi_CeritaPenggalangMain({
<Stack <Stack
spacing={"xs"} spacing={"xs"}
style={{ style={{
color: "white", color: MainColor.white,
}} }}
> >
<Title order={4}>Cerita Penggalang Dana</Title> <Title order={4}>Cerita Penggalang Dana</Title>
@@ -35,7 +35,7 @@ export default function ComponentDonasi_CeritaPenggalangMain({
backgroundColor: AccentColor.darkblue, backgroundColor: AccentColor.darkblue,
border: `2px solid ${AccentColor.blue}`, border: `2px solid ${AccentColor.blue}`,
borderRadius: "10px", borderRadius: "10px",
color: "white", color: MainColor.white,
}} }}
> >
<Stack> <Stack>

View File

@@ -43,7 +43,7 @@ export default function ComponentDonasi_CeritaPenggalangMainNew() {
<Stack <Stack
spacing={"xs"} spacing={"xs"}
style={{ style={{
color: "white", color: MainColor.white,
}} }}
> >
<Title order={4}>Cerita Penggalang Dana</Title> <Title order={4}>Cerita Penggalang Dana</Title>
@@ -53,7 +53,7 @@ export default function ComponentDonasi_CeritaPenggalangMainNew() {
backgroundColor: AccentColor.darkblue, backgroundColor: AccentColor.darkblue,
border: `2px solid ${AccentColor.blue}`, border: `2px solid ${AccentColor.blue}`,
borderRadius: "10px", borderRadius: "10px",
color: "white", color: MainColor.white,
}} }}
> >
{ {

View File

@@ -2,7 +2,8 @@
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi"; import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { AccentColor, MainColor, } from "@/app_modules/_global/color/color_pallet"; import { AccentColor, MainColor, } from "@/app_modules/_global/color/color_pallet";
import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information"; import ComponentGlobal_BoxInformation from "@/app_modules/_global/component/box_information";
import { ActionIcon, Avatar, Group, Paper, Skeleton, Stack, Text, Title, } from "@mantine/core"; import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { ActionIcon, Avatar, Group, Paper, Stack, Text, Title } from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks"; import { useShallowEffect } from "@mantine/hooks";
import { IconCircleChevronRight } from "@tabler/icons-react"; import { IconCircleChevronRight } from "@tabler/icons-react";
import _ from "lodash"; import _ from "lodash";
@@ -40,7 +41,7 @@ export default function ComponentDonasi_InformasiPenggalangMainNew() {
<Stack <Stack
spacing={"xs"} spacing={"xs"}
style={{ style={{
color: "white", color: MainColor.white,
}} }}
> >
<Title order={4}>Informasi Penggalang Dana</Title> <Title order={4}>Informasi Penggalang Dana</Title>
@@ -50,11 +51,11 @@ export default function ComponentDonasi_InformasiPenggalangMainNew() {
backgroundColor: AccentColor.darkblue, backgroundColor: AccentColor.darkblue,
border: `2px solid ${AccentColor.blue}`, border: `2px solid ${AccentColor.blue}`,
borderRadius: "10px", borderRadius: "10px",
color: "white", color: MainColor.white,
}} }}
> >
{ {
loading ? <Skeleton height={100} radius="md" width={"100%"} /> loading ? <CustomSkeleton height={100} radius="md" width={"100%"} />
: :
<Stack> <Stack>
<Group position="apart"> <Group position="apart">

View File

@@ -1,13 +1,14 @@
import { Box, Skeleton } from "@mantine/core"; import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { Box } from "@mantine/core";
export default function SkeletonCeritaPenggalangDonasi() { export default function SkeletonCeritaPenggalangDonasi() {
return ( return (
<> <>
<Box mb={"md"}> <Box mb={"md"}>
<Skeleton height={10} mt={0} radius="xl" width={"50%"} /> <CustomSkeleton height={10} mt={0} radius="xl" width={"50%"} />
<Skeleton height={10} mt={10} radius="xl" /> <CustomSkeleton height={10} mt={10} radius="xl" />
<Skeleton height={10} mt={10} radius="xl" /> <CustomSkeleton height={10} mt={10} radius="xl" />
<Skeleton height={10} mt={10} radius="xl" /> <CustomSkeleton height={10} mt={10} radius="xl" />
</Box> </Box>
</> </>
); );

View File

@@ -1,19 +1,20 @@
import { Box, Skeleton } from "@mantine/core"; import CustomSkeleton from "@/app_modules/components/CustomSkeleton";
import { Box } from "@mantine/core";
export default function SkeletonDetailDanaDonasi() { export default function SkeletonDetailDanaDonasi() {
return ( return (
<> <>
<Box> <Box>
<Box mb={"md"}> <Box mb={"md"}>
<Skeleton height={150} radius="md" /> <CustomSkeleton height={150} radius="md" />
</Box> </Box>
<Box mb={"md"}> <Box mb={"md"}>
<Skeleton height={10} mt={10} radius="xl" width={"50%"} /> <CustomSkeleton height={10} mt={10} radius="xl" width={"50%"} />
<Skeleton height={10} mt={10} radius="xl" /> <CustomSkeleton height={10} mt={10} radius="xl" />
<Skeleton height={10} mt={10} radius="xl" /> <CustomSkeleton height={10} mt={10} radius="xl" />
</Box> </Box>
<Box> <Box>
<Skeleton height={50} radius="md" /> <CustomSkeleton height={50} radius="md" />
</Box> </Box>
</Box> </Box>
</> </>

Some files were not shown because too many files have changed in this diff Show More