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.
## [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.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",
"version": "1.2.36",
"version": "1.2.39",
"private": true,
"prisma": {
"seed": "npx tsx prisma/seed.ts --yes"
@@ -87,6 +87,7 @@
"react-quill": "^2.0.0",
"react-responsive-carousel": "^3.2.23",
"react-toastify": "^9.1.3",
"sharp": "^0.33.5",
"socket.io-client": "^4.7.2",
"tailwindcss": "3.3.3",
"ts-node": "^10.9.2",

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

View File

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

View File

@@ -1,5 +1,6 @@
import { sessionCreate } from "@/app/auth/_lib/session_create";
import prisma from "@/app/lib/prisma";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export async function POST(req: Request) {
@@ -23,7 +24,7 @@ export async function POST(req: Request) {
data: {
username: data.username,
nomor: data.nomor,
active: true,
active: false,
},
});
@@ -38,7 +39,15 @@ export async function POST(req: Request) {
{ status: 200 }
);
} 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 prisma from "@/app/lib/prisma";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
export async function POST(req: Request) {
@@ -42,7 +43,15 @@ export async function POST(req: Request) {
{ status: 200 }
);
} 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(

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);
const data = await res.json();
if (res.ok) {
backendLogger.info(
`Success delete ${keyOfDirectory}`
);
backendLogger.info(`Success delete ${keyOfDirectory}`);
return NextResponse.json({ success: true });
} else {
const errorText = await res.json();

View File

@@ -1,8 +1,13 @@
import { funGetDirectoryNameByValue } from "@/app_modules/_global/fun/get";
import backendLogger from "@/util/backendLogger";
import { NextResponse } from "next/server";
import sharp from "sharp";
export async function POST(request: Request) {
let fixFormData;
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 keyOfDirectory = await funGetDirectoryNameByValue({
@@ -11,9 +16,33 @@ export async function POST(request: Request) {
if (request.method === "POST") {
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", {
method: "POST",
body: formData,
body: fixFormData,
headers: {
Authorization: `Bearer ${process.env.WS_APIKEY}`,
},

View File

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

View File

@@ -14,7 +14,8 @@ export async function GET(request: Request) {
const kategori = searchParams.get("cat")
const status = searchParams.get("status")
const page = searchParams.get("page")
const dataSkip = Number(page) * 5 - 5;
const dataTake = 10
const dataSkip = Number(page) * dataTake - dataTake;
if (kategori == "bursa") {
const data = await prisma.investasi.findMany({
@@ -61,7 +62,7 @@ export async function GET(request: Request) {
// cek data yang lewat
// klo ada, update status
const dataAwal = await prisma.investasi.findMany({
take: 5,
take: dataTake,
skip: dataSkip,
orderBy: [
{
@@ -100,28 +101,28 @@ export async function GET(request: Request) {
}
const data = await prisma.investasi.findMany({
take: 5,
skip: dataSkip,
orderBy: {
updatedAt: "desc",
},
where: {
authorId: userLoginId,
masterStatusInvestasiId: status,
},
select: {
id: true,
title: true,
targetDana: true,
imageId: true,
countDown: true,
updatedAt: true,
MasterPencarianInvestor: {
select: {
name: true
}
}
}
take: dataTake,
skip: dataSkip,
orderBy: {
updatedAt: "desc",
},
where: {
authorId: userLoginId,
masterStatusInvestasiId: status,
},
select: {
id: true,
title: true,
targetDana: true,
imageId: true,
countDown: true,
updatedAt: true,
MasterPencarianInvestor: {
select: {
name: true,
},
},
},
});
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 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";
// GET ONE DATA PORTOFOLIO BY ID PORTOFOLIO
export async function GET(request: Request, context: { params: { id: string } }) {
try {
let dataFix
const { id } = context.params;
const { searchParams } = new URL(request.url);
const kategori = searchParams.get('cat');
export async function GET(
request: Request,
context: { params: { id: string } }
) {
try {
let dataFix;
const { id } = context.params;
const { searchParams } = new URL(request.url);
const kategori = searchParams.get("cat");
if (kategori == "bisnis") {
const data = await prisma.portofolio.findUnique({
where: {
id: id,
},
if (kategori == "bisnis") {
const data = await prisma.portofolio.findUnique({
where: {
id: id,
},
select: {
id_Portofolio: true,
namaBisnis: true,
alamatKantor: true,
tlpn: true,
deskripsi: true,
logoId: true,
MasterBidangBisnis: {
select: {
id_Portofolio: 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,
name: true,
},
},
Profile: {
select: {
logoId: 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,
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,
},
select: {
logoId: true,
BusinessMaps: {
select: {
Portofolio_MediaSosial: {
select: {
facebook: true,
twitter: true,
instagram: true,
tiktok: true,
youtube: true
}
}
}
});
id: true,
namePin: true,
latitude: true,
longitude: true,
imageId: true,
pinId: true,
},
},
},
});
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
}
}
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,
},
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) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan data, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 });
}
return NextResponse.json(
{ success: true, message: "Berhasil mendapatkan data", data: dataFix },
{ 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
export async function DELETE(request: Request, context: { params: { id: string } }) {
try {
const { id } = context.params
export async function DELETE(
request: Request,
context: { params: { id: string } }
) {
try {
const { id } = context.params;
const data = await prisma.portofolio.findUnique({
where: {
id: id
}
})
const data = await prisma.portofolio.findUnique({
where: {
id: id,
},
include: {
BusinessMaps: {
select: {
pinId: true,
imageId: true,
},
},
},
});
const findLogo = await prisma.images.findFirst({
where: {
id: String(data?.logoId),
},
select: {
id: true,
url: true,
},
});
try {
const id = data?.logoId;
const deleteLogo = await fetch(
`https://wibu-storage.wibudev.com/api/files/${id}/delete`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.WS_APIKEY}`,
},
}
);
if (findLogo) {
fs.unlinkSync(`./public/portofolio/logo/${findLogo.url}`)
const deleteLogo = await prisma.images.delete({
where: {
id: String(findLogo?.id),
},
});
if (deleteLogo.ok) {
backendLogger.info(`Success delete logo`);
}
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({
where: {
portofolioId: id,
},
});
const imageId = data?.BusinessMaps?.imageId;
const deleteImage = await fetch(
`https://wibu-storage.wibudev.com/api/files/${imageId}/delete`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${process.env.WS_APIKEY}`,
},
}
);
const deleteMap = await prisma.businessMaps.delete({
where: {
portofolioId: id
}
})
if (deleteImage.ok) {
backendLogger.info(`Success delete image`);
}
}
} catch (error) {
backendLogger.error("Error delete logo", error);
}
const deletePortofolio = await prisma.portofolio.delete({
where: {
id: id,
},
});
const deletePortoMedsos = await prisma.portofolio_MediaSosial.delete({
where: {
portofolioId: id,
},
});
return NextResponse.json({ success: true, message: "Berhasil menghapus data" }, { status: 200 });
const deleteMap = await prisma.businessMaps.delete({
where: {
portofolioId: id,
},
});
} 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 });
}
}
const deletePortofolio = await prisma.portofolio.delete({
where: {
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 _ 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)) {
@@ -18,5 +19,7 @@ export async function GET() {
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";
export async function GET(req: Request) {
const auth = req.headers.get("Authorization");
const token = auth?.split(" ")[1];
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_AnggotaRoomChat",
]);
let listMsg = await colab_getMessageByRoomId({ roomId: roomId, page: 1 });
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_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 (
<>
<Colab_DetailInfoGrup dataRoom={dataRoom as any} />
<Colab_DetailInfoGrup />
</>
);
}

View File

@@ -1,24 +1,13 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
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 } }) {
let colabId = params.id;
export default async function Page() {
const userLoginId = await funGetUserIdByToken();
const dataColab = await colab_getOneCollaborationById(colabId);
const listPartisipan = await colab_getListPartisipanByColabId(colabId);
const cekPartisipan = await colab_funCekPartisipasiById(colabId);
return (
<>
<Colab_MainDetail
dataColab={dataColab as any}
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 }) {
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_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 (
<>
<Colab_DetailPartisipasiProyek
dataColab={dataColab as any}
listPartisipan={listPartisipan as any}
/>
<Colab_DetailPartisipasiProyek />
</>
);
}

View File

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

View File

@@ -1,19 +1,9 @@
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 (
<>
{/* <pre>{JSON.stringify(listPartisipan, null,2)}</pre> */}
<Colab_DetailProyekSaya
dataColab={dataColab as any}
listPartisipan={listPartisipan as any}
/>
<Colab_DetailProyekSaya />
</>
);
}

View File

@@ -1,14 +1,12 @@
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
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() {
const listData = await colab_getListAllProyek({ page: 1 });
const userLoginId = await funGetUserIdByToken();
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";
export default async function Page() {
const listRoom = await colab_getListRoomChatByAuthorId({page: 1});
// const listRoom = await colab_getListRoomChatByAuthorId({page: 1});
return (
<>
<Colab_GrupDiskus listRoom={listRoom as any} />
<Colab_GrupDiskus />
</>
);
}

View File

@@ -1,17 +1,12 @@
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() {
const listPartisipasiProyek = await colab_getListPartisipasiProyekByAuthorId({page: 1})
const listProyekSaya = await colab_getListAllProyekSayaByAuthorId({page: 1})
// const listPartisipasiProyek = await colab_getListPartisipasiProyekByAuthorId({page: 1})
// const listProyekSaya = await colab_getListAllProyekSayaByAuthorId({page: 1})
return (
<>
<Colab_Proyek
listPartisipasiUser={listPartisipasiProyek as any}
listProyekSaya={listProyekSaya as any}
/>
<Colab_Proyek />
</>
);
}

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 } }) {
const donasiId = params.id
const dataDonasi = await Donasi_getOneById(donasiId);
return (
<>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,13 +1,9 @@
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 (
<>
<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";
export default async function Page({ params }: { params: { id: string } }) {
const voteId = params.id;
const userLoginId = await funGetUserIdByToken();
return (
<>

View File

@@ -1,19 +1,9 @@
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 (
<>
<Vote_DetailSemuaRiwayat
dataVote={dataVote as any}
listKontributor={listKontributor as any}
/>
<Vote_DetailSemuaRiwayat />
</>
);
}

View File

@@ -19,27 +19,30 @@ export type ITypeStatusNotifikasi =
| "Menunggu"
| "Gagal";
/**
* @param kategoriApp | "JOB", "VOTING", "EVENT", "DONASI", "INVESTASI", "COLLABORATION", "FORUM"
* @type string
*/
export type IRealtimeData = {
status?: ITypeStatusNotifikasi;
appId: string;
appId?: string;
userId: string;
pesan: string;
title: string;
kategoriApp:
pesan?: string;
title?: string;
kategoriApp?:
| "JOB"
| "VOTING"
| "EVENT"
| "DONASI"
| "INVESTASI"
| "COLLABORATION"
| "FORUM";
| "FORUM"
| "ACCESS"; // Untuk trigger akses user
};
// Access User
export const gs_access_user = atom<boolean>(false);
export const gs_realtimeData = atom<IRealtimeData | null>(null);
export const gs_admin_ntf = atom<number>(0);
export const gs_user_ntf = atom<number>(0);
@@ -63,4 +66,4 @@ export const gs_donasiTriggerBeranda = atom<boolean>(false);
// investasi
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 = {
profile_foto: "cm0x93rgo000jbp5tj8baoaus",
profile_background: "cm0x93ze8000lbp5t1a8uc9wl",
profile_foto: "cm5ni43ub001pxpug0qw4p11e",
profile_background: "cm5ni4hnq001l12p9gpagxgtv",
portofolio_logo: "cm0yjl6ug000310njwmk6j0tx",
map_pin: "cm0yjq8up000710njv5klra32",
map_image: "cm0yjqnxl000910njplqho07w",

View File

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

View File

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

View File

@@ -5,7 +5,8 @@ import {
UIGlobal_LayoutHeaderTamplate,
UIGlobal_LayoutTamplate,
} 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() {
return (
@@ -13,8 +14,44 @@ export default function Voting_ComponentSkeletonViewPuh() {
<UIGlobal_LayoutTamplate
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>
<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"}>
<Grid align="center" gutter={"md"}>
<Grid.Col span={"content"}>
@@ -23,12 +60,35 @@ export default function Voting_ComponentSkeletonViewPuh() {
<Grid.Col span={3}>
<Skeleton height={20} w={150} />
</Grid.Col>
<Grid.Col span={3} offset={3}>
<Skeleton height={20} w={150} />
</Grid>
<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>
<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>
</ComponentGlobal_CardStyles>
</ComponentGlobal_CardStyles> */}
{/* <ComponentGlobal_CardStyles>
<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";
import { clientLogger } from "@/util/clientLogger";
import { Button, FileButton } from "@mantine/core";
import { IconCamera } from "@tabler/icons-react";
import { useState } from "react";
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({
onSetFile,
@@ -15,22 +13,27 @@ export function ComponentGlobal_ButtonUploadFileImage({
onSetFile: File | any;
onSetImage: any | null;
}) {
const [isLoading, setIsLoading] = useState(false);
return (
<FileButton
onChange={async (files: any | null) => {
try {
setIsLoading(true);
const buffer = URL.createObjectURL(
new Blob([new Uint8Array(await files.arrayBuffer())])
);
if (files.size > MAX_SIZE) {
ComponentGlobal_NotifikasiPeringatan(PemberitahuanMaksimalFile);
return;
} else {
onSetFile(files);
onSetImage(buffer);
}
// if (files.size > MAX_SIZE) {
// ComponentGlobal_NotifikasiPeringatan(PemberitahuanMaksimalFile);
// return;
// } else {
// }
onSetFile(files);
onSetImage(buffer);
setIsLoading(false);
} catch (error) {
setIsLoading(false);
clientLogger.error("Upload error:", error);
}
}}
@@ -39,6 +42,8 @@ export function ComponentGlobal_ButtonUploadFileImage({
{(props) => (
<Button
{...props}
loading={isLoading}
loaderPosition="center"
radius={"xl"}
leftIcon={<IconCamera />}
bg={MainColor.yellow}

View File

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

View File

@@ -47,7 +47,7 @@ export function ComponentGlobal_AvatarAndUsername({
onClick={() => onCheckProfile()}
>
{visible ? (
<Avatar radius={"xl"} size={40}>
<Avatar radius={"xl"} size={40}>
<ComponentGlobal_Loader />
</Avatar>
) : (
@@ -63,7 +63,7 @@ export function ComponentGlobal_AvatarAndUsername({
<Text
c={MainColor.white}
fw={"bold"}
fz={fontSize ? fontSize : "sm"}
fz={fontSize ? fontSize : "md"}
lineClamp={1}
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 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({
children,
backgroundColor,
@@ -30,7 +44,7 @@ export function ComponentGlobal_CardStyles({
paddingInline: "16px",
paddingBlock: "16px",
borderRadius: "10px",
color: color ? color : "white",
color: color ? color : MainColor.white,
height: height ? height : "auto",
marginBottom: marginBottom ? marginBottom : "15px",
}}

View File

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

View File

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

View File

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

View File

@@ -22,29 +22,7 @@ export async function funGlobal_DeleteFileById({
return { success: false, message: data.message };
}
} catch (error) {
console.error("Upload error:", error);
clientLogger.error("Upload error:", error);
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";
import { jwtVerify } from "jose";
import { cookies } from "next/headers";
import { decrypt } from "../../../../app/auth/_lib/decrypt";
@@ -16,21 +15,3 @@ export async function funGetUserIdByToken() {
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 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/jpeg",
"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}`,
borderLeft: `1px solid ${AccentColor.blue}`,
borderRadius: "20px 20px 0px 0px",
color: "white",
color: MainColor.white,
paddingBottom: "5%",
},
}}
@@ -86,7 +86,7 @@ export default function UIGlobal_Drawer({
>
<ActionIcon
variant="transparent"
c="white"
c={MainColor.white}
>
{/* PAKE LOADING */}
{/* {isLoading && e?.id === pageId ? (

View File

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

View File

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

View File

@@ -1,11 +1,14 @@
"use server";
import prisma from "@/app/lib/prisma";
import backendLogger from "@/util/backendLogger";
import { revalidatePath } from "next/cache";
import { headers } from "next/headers";
export default async function adminUserAccess_funEditAccess(
userId: string,
value: boolean
value: boolean,
nomor?: string
) {
const updt = await prisma.user.update({
where: {
@@ -16,6 +19,31 @@ export default async function adminUserAccess_funEditAccess(
},
});
const headersList = headers();
const host = headersList.get("host");
const protocol = headersList.get("x-forwarded-proto") || "http";
const path = headersList.get("x-invoke-path");
const baseUrl = `${protocol}://${host}`;
// const fullUrl = `${protocol}://${host}${path}`;
if (value === true) {
const message = `Hallo rekan HIPMI, Anda telah diberikan akses ke HIPMI Apps. Silakan mulai jelajahi fitur-fitur yang tersedia melalui link berikut: ${baseUrl}`;
const encodedMessage = encodeURIComponent(message);
const res = await fetch(
`https://wa.wibudev.com/code?nom=${nomor}&text=${encodedMessage}
`
);
if (!res.ok) {
backendLogger.error("Error send message", res);
}
const result = await res.json();
backendLogger.info("Success send message", result);
}
if (!updt) return { status: 400, message: "Update gagal" };
revalidatePath("/dev/admin/user-access");
return { status: 200, message: "Update berhasil" };

View File

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

View File

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

View File

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

View File

@@ -25,6 +25,7 @@ import { useEffect, useState } from "react";
import { ComponentGlobal_NotifikasiGagal } from "@/app_modules/_global/notif_global";
import { auth_funDeleteAktivasiKodeOtpByNomor } from "../fun/fun_edit_aktivasi_kode_otp_by_id";
import Validasi_SkeletonView from "./skeleton";
import { clientLogger } from "@/util/clientLogger";
export default function Validasi() {
const router = useRouter();
@@ -86,9 +87,6 @@ export default function Validasi() {
body: JSON.stringify({
nomor: data.nomor,
}),
headers: {
"Content-Type": "application/json",
},
});
const result = await res.json();
@@ -99,6 +97,7 @@ export default function Validasi() {
await auth_funDeleteAktivasiKodeOtpByNomor({
nomor: data.nomor,
});
router.push(RouterHome.main_home, { scroll: false });
return;
}
@@ -109,25 +108,33 @@ export default function Validasi() {
await auth_funDeleteAktivasiKodeOtpByNomor({
nomor: data.nomor,
});
router.push(RouterAdminDashboard.splash_admin, { scroll: false });
return;
}
if (res.status === 404) {
setLoading(false);
router.push("/register", { scroll: false });
ComponentGlobal_NotifikasiBerhasil(result.message);
return;
}
if (res.status === 400) {
setLoading(false);
ComponentGlobal_NotifikasiPeringatan(result.message);
return;
}
if (res.status == 500) {
setLoading(false);
ComponentGlobal_NotifikasiGagal(result.message);
return;
}
} catch (error) {
console.error(error);
} finally {
setLoading(false);
}
clientLogger.error("Error validasi:", error);
}
}
async function onBack() {
@@ -207,14 +214,13 @@ export default function Validasi() {
</Text>
</Stack>
<Center>
<PinInput
<PinInput
size="xl"
type={"number"}
ref={focusTrapRef}
spacing={"md"}
mt={"md"}
styles={{ input: { backgroundColor: MainColor.white } }}
mt={"md"}
styles={{ input: { backgroundColor: MainColor.white } }}
onChange={(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"}>
<Grid>
<Grid.Col span={2}>
<Text fw={"bold"} fz={"xs"}>
<Text fw={"bold"} >
Industri
</Text>
</Grid.Col>
<Grid.Col span={1}>
<Text fz={"xs"}>:</Text>
<Text >:</Text>
</Grid.Col>
<Grid.Col span={"auto"}>
<Text fz={"xs"} lineClamp={1}>
<Text lineClamp={1}>
{data?.ProjectCollaborationMaster_Industri.name
? data?.ProjectCollaborationMaster_Industri?.name
: "Industri"}
@@ -58,25 +58,25 @@ export default function ComponentColab_CardSectionData({
<Grid>
<Grid.Col span={2}>
<Text fw={"bold"} fz={"xs"}>
<Text fw={"bold"} >
Lokasi
</Text>
</Grid.Col>
<Grid.Col span={1}>
<Text fz={"xs"}>:</Text>
<Text >:</Text>
</Grid.Col>
<Grid.Col span={"auto"}>
<Text fz={"xs"} lineClamp={1}>
<Text lineClamp={1}>
{data?.lokasi ? data?.lokasi : "Lokasi dari proyek"}
</Text>
</Grid.Col>
</Grid>
<Stack spacing={5}>
<Text fw={"bold"} fz={"xs"}>
<Text fw={"bold"} >
Tujuan proyek
</Text>
<Text lineClamp={3} fz={"xs"}>
<Text lineClamp={2} >
{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"}

View File

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

View File

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

View File

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

View File

@@ -4,9 +4,14 @@ import {
AccentColor,
MainColor,
} 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_IsEmptyData from "@/app_modules/_global/component/is_empty_data";
import { ComponentGlobal_NotifikasiBerhasil } from "@/app_modules/_global/notif_global/notifikasi_berhasil";
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 {
ActionIcon,
Box,
@@ -14,83 +19,219 @@ import {
Center,
Drawer,
Group,
Paper,
ScrollArea,
Loader,
Stack,
Text,
Textarea,
Title,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
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 { apiGetOneCollaborationById } from "../../_lib/api_collaboration";
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 { Collaboration_SkeletonListPrtisipanIsUser } from "../skeleton_view";
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({
listPartisipan,
userLoginId,
authorId,
colabId,
cekPartisipan,
}: {
listPartisipan?: MODEL_COLLABORATION_PARTISIPASI[];
userLoginId?: string;
authorId?: string;
colabId?: string;
cekPartisipan?: boolean;
}) {
const [apply, setApply] = useState(false);
const [data, setData] = useState(listPartisipan);
const params = useParams<{ id: string }>();
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 [deskripsi, setDeskripsi] = useState("");
const [isLoading, setIsLoading] = useState(false);
async function onJoin() {
const res = await colab_funCreatePartisipan(
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 !",
};
useShallowEffect(() => {
onLoadDataPartisipan();
}, []);
const createNotifikasi = await notifikasiToUser_funCreate({
data: dataNotif as any,
async function onLoadDataPartisipan() {
try {
const respone = await apiGetOneCollaborationById({
id: params.id,
kategori: "list_partisipan",
page: `${activePage}`,
});
if (createNotifikasi.status === 201) {
mqtt_client.publish(
"USER",
JSON.stringify({
userId: dataNotif.userId,
count: 1,
})
);
if (respone) {
setData(respone.data);
}
const resList = await colab_getListPartisipanByColabId(colabId as any);
setApply(true);
close();
setData(resList as any);
ComponentGlobal_NotifikasiBerhasil(res.message);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
} catch (error) {
clientLogger.error("Error get list partisipan", error);
}
}
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 (
<>
<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
opened={opened}
onClose={close}
@@ -113,21 +254,29 @@ export default function ComponentColab_DetailListPartisipasiUser({
borderRight: `1px solid ${AccentColor.blue}`,
borderLeft: `1px solid ${AccentColor.blue}`,
borderRadius: "20px 20px 0px 0px",
color: "white",
color: MainColor.white,
paddingBottom: "5%",
},
}}
>
<Stack spacing={"xs"}>
<Group position="right">
<ActionIcon onClick={close} variant="transparent">
<IconX color="white" />
<IconX color={MainColor.white} />
</ActionIcon>
</Group>
<Textarea
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.."
minRows={4}
onChange={(val) => {
@@ -143,6 +292,8 @@ export default function ComponentColab_DetailListPartisipasiUser({
maxInput={300}
/>
<Button
loaderPosition="center"
loading={isLoading}
disabled={!deskripsi}
radius={"xl"}
color="yellow"
@@ -157,63 +308,6 @@ export default function ComponentColab_DetailListPartisipasiUser({
</Group>
</Stack>
</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 { Group, Stack, Text } from "@mantine/core";
import { useRouter } from "next/navigation";
import moment from "moment";
import "moment/locale/id";
export default function ComponentColab_AuthorNameOnHeader({
tglPublish,
@@ -19,10 +21,8 @@ export default function ComponentColab_AuthorNameOnHeader({
component={
<Group position="right">
{tglPublish ? (
<Text fz={"xs"}>
{new Intl.DateTimeFormat("id-ID", {
dateStyle: "medium",
}).format(tglPublish)}
<Text lineClamp={1}>
{moment(tglPublish).locale("id").format("ll")}
</Text>
) : (
""
@@ -65,7 +65,7 @@ export default function ComponentColab_AuthorNameOnHeader({
<Grid.Col span={"content"}>
<Stack justify="center" h={"100%"}>
{tglPublish ? (
<Text fz={"xs"}>
<Text >
{new Intl.DateTimeFormat("id-ID", {
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 (
<>
<Stack px={"xl"} spacing={"lg"}>
<Stack px={"xl"} spacing={"md"}>
<Stack spacing={"xs"}>
<Skeleton height={10} width={50} />
<Skeleton height={40} />
<CustomSkeleton height={15} width={50} />
<CustomSkeleton height={40} />
</Stack>
<Stack spacing={"xs"}>
<Skeleton height={10} width={50} />
<Skeleton height={40} />
<CustomSkeleton height={15} width={50} />
<CustomSkeleton height={40} />
</Stack>
<Stack spacing={"xs"}>
<Skeleton height={10} width={50} />
<Skeleton height={130} />
<CustomSkeleton height={15} width={50} />
<CustomSkeleton height={40} />
</Stack>
<Stack spacing={"xs"}>
<Skeleton height={10} width={50} />
<Skeleton height={130} />
<CustomSkeleton height={15} width={50} />
<CustomSkeleton height={130} />
</Stack>
<Stack spacing={"xs"}>
<CustomSkeleton height={15} width={50} />
<CustomSkeleton height={130} />
</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>
</>
);

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_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { ComponentGlobal_NotifikasiPeringatan } from "@/app_modules/_global/notif_global/notifikasi_peringatan";
import { clientLogger } from "@/util/clientLogger";
import mqtt_client from "@/util/mqtt_client";
import {
Button,
Center,
Select,
Stack,
TextInput,
Textarea,
Loader,
Textarea
} from "@mantine/core";
import { useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation";
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 { 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() {
const [value, setValue] = useState({
@@ -55,7 +51,7 @@ export default function Colab_Create() {
}
}
if (listIndustri == null) {
return (
<>
@@ -70,9 +66,9 @@ export default function Colab_Create() {
<TextInput
maxLength={100}
styles={{
label: {
color: "white",
},
label: { color: MainColor.white },
input: { backgroundColor: MainColor.white },
required: { color: MainColor.red },
}}
label="Judul"
withAsterisk
@@ -87,9 +83,9 @@ export default function Colab_Create() {
<TextInput
styles={{
label: {
color: "white",
},
label: { color: MainColor.white },
input: { backgroundColor: MainColor.white },
required: { color: MainColor.red },
}}
maxLength={100}
label="Lokasi"
@@ -103,11 +99,12 @@ export default function Colab_Create() {
}}
/>
{/* <Select
<Select
styles={{
label: {
color: "white",
},
label: { color: MainColor.white },
input: { backgroundColor: MainColor.white },
required: { color: MainColor.red },
dropdown: { backgroundColor: MainColor.white },
}}
placeholder="Pilih kategori industri"
label="Pilih Industri"
@@ -122,32 +119,14 @@ export default function Colab_Create() {
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}>
<Textarea
styles={{
label: {
color: "white",
},
label: { color: MainColor.white },
input: { backgroundColor: MainColor.white },
required: { color: MainColor.red },
}}
maxLength={500}
label="Tujuan Proyek"
@@ -170,9 +149,8 @@ export default function Colab_Create() {
<Stack spacing={5}>
<Textarea
styles={{
label: {
color: "white",
},
label: { color: MainColor.white },
input: { backgroundColor: MainColor.white },
}}
maxLength={500}
label="Keuntungan "
@@ -207,7 +185,6 @@ function ButtonAction({ value }: { value: any }) {
JSON.stringify({ isNewPost: true, count: 1 })
);
console.log(value.jumlah_partisipan);
if (value.title === "")
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Data");
if (value.lokasi === "")
@@ -218,26 +195,33 @@ function ButtonAction({ value }: { value: any }) {
return ComponentGlobal_NotifikasiPeringatan("Pilih Industri");
const res = await colab_funCreateProyek(value);
if (res.status === 201) {
setLoading(true);
router.back();
ComponentGlobal_NotifikasiBerhasil(res.message);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
try {
setLoading(true)
if (res.status === 201) {
setLoading(true);
router.back();
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 (
<>
<Button
disabled={
!value.title ||
!value.lokasi ||
!value.purpose ||
!value.benefit ||
value.projectCollaborationMaster_IndustriId === 0
!value.lokasi ||
!value.purpose ||
!value.benefit ||
value.projectCollaborationMaster_IndustriId === 0
? true
: false
}

View File

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

View File

@@ -1,56 +1,90 @@
"use client";
import { AccentColor } from "@/app_modules/_global/color/color_pallet";
import { ComponentGlobal_AvatarAndUsername, ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
import {
ComponentGlobal_AvatarAndUsername,
ComponentGlobal_CardStyles,
} from "@/app_modules/_global/component";
import UIGlobal_LayoutHeaderTamplate from "@/app_modules/_global/ui/ui_header_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 { 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({
dataRoom,
}: {
dataRoom: MODEL_COLLABORATION_ROOM_CHAT;
}) {
export default function Colab_DetailInfoGrup() {
return (
<>
<UIGlobal_LayoutTamplate
header={<UIGlobal_LayoutHeaderTamplate title="Info Grup" />}
>
<InfoGroup dataRoom={dataRoom} />
<InfoGroup />
</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 (
<>
<ComponentGlobal_CardStyles>
<Stack>
<ComponentColab_DetailData data={dataRoom.ProjectCollaboration} />
<Paper
style={{
border: `2px solid ${AccentColor.softblue}`,
backgroundColor: AccentColor.blue,
color: "white",
borderRadius: "10px",
padding: "15px",
}}
>
<Stack>
<Title order={6}>Anggota Grup</Title>
{dataRoom.ProjectCollaboration_AnggotaRoomChat.map((e, i) => (
<Box key={i}>
<ComponentGlobal_AvatarAndUsername profile={e.User.Profile as any}/>
</Box>
))}
</Stack>
</Paper>
</Stack>
</ComponentGlobal_CardStyles>
<Stack>
<ComponentGlobal_CardStyles marginBottom={"0px"}>
<ComponentColab_DetailData data={data?.ProjectCollaboration} />
</ComponentGlobal_CardStyles>
<ComponentGlobal_CardStyles>
<Stack>
<Title order={6}>Anggota Grup</Title>
{data?.ProjectCollaboration_AnggotaRoomChat.map((e, i) => (
<Box mb={"sm"} key={i}>
<ComponentGlobal_AvatarAndUsername
profile={e.User.Profile as any}
/>
</Box>
))}
</Stack>
</ComponentGlobal_CardStyles>
</Stack>
</>
);
}

View File

@@ -1,42 +1,68 @@
"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 { 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_DetailListPartisipasiUser from "../../component/detail/list_partisipasi_user";
import ComponentColab_AuthorNameOnHeader from "../../component/header_author_name";
import { Collaboration_SkeletonDetail } from "../../component/skeleton_view";
import { MODEL_COLLABORATION } from "../../model/interface";
import { ComponentGlobal_CardStyles } from "@/app_modules/_global/component";
export default function Colab_MainDetail({
dataColab,
userLoginId,
listPartisipan,
cekPartisipan,
}: {
dataColab?: MODEL_COLLABORATION;
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 (
<>
<ComponentGlobal_CardStyles>
<Stack>
<ComponentColab_AuthorNameOnHeader
tglPublish={new Date()}
profile={dataColab?.Author?.Profile as any}
/>
<ComponentColab_DetailData data={dataColab} />
<ComponentColab_DetailListPartisipasiUser
listPartisipan={listPartisipan}
userLoginId={userLoginId}
authorId={dataColab?.Author.id}
colabId={dataColab?.id}
cekPartisipan={cekPartisipan}
/>
</Stack>
</ComponentGlobal_CardStyles>
<Stack>
{_.isNull(data) ? (
<Collaboration_SkeletonDetail />
) : (
<ComponentGlobal_CardStyles>
<Stack>
<ComponentColab_AuthorNameOnHeader
tglPublish={data.createdAt}
profile={data?.Author?.Profile as any}
/>
<ComponentColab_DetailData data={data as any} />
</Stack>
</ComponentGlobal_CardStyles>
)}
<ComponentColab_DetailListPartisipasiUser
userLoginId={userLoginId}
authorId={data?.Author.id}
/>
</Stack>
</>
);
}

View File

@@ -1,36 +1,60 @@
"use client";
import { AccentColor } from "@/app_modules/_global/color/color_pallet";
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_DetailListPartisipasiUser from "@/app_modules/colab/component/detail/list_partisipasi_user";
import ComponentColab_AuthorNameOnHeader from "@/app_modules/colab/component/header_author_name";
import {
MODEL_COLLABORATION,
MODEL_COLLABORATION_PARTISIPASI,
} from "@/app_modules/colab/model/interface";
import { Stack, Text } from "@mantine/core";
import { Collaboration_SkeletonDetail } from "@/app_modules/colab/component/skeleton_view";
import { MODEL_COLLABORATION } from "@/app_modules/colab/model/interface";
import { clientLogger } from "@/util/clientLogger";
import { Stack } 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 (
<>
<ComponentGlobal_CardStyles>
{_.isNull(data) ? (
<Collaboration_SkeletonDetail />
) : (
<Stack>
<ComponentColab_AuthorNameOnHeader
profile={dataColab.Author.Profile}
/>
<ComponentColab_DetailData data={dataColab} />
<ComponentColab_DetailListPartisipasiUser
listPartisipan={listPartisipan}
/>
<ComponentGlobal_CardStyles>
<Stack>
<ComponentColab_AuthorNameOnHeader
profile={data.Author.Profile}
/>
<ComponentColab_DetailData data={data} />
</Stack>
</ComponentGlobal_CardStyles>
<ComponentColab_DetailListPartisipasiUser />
</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_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
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_AuthorNameOnListPartisipan from "@/app_modules/colab/component/detail/header_author_list_partisipan";
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 { gs_colab_hot_menu } from "@/app_modules/colab/global_state";
import {
MODEL_COLLABORATION,
MODEL_COLLABORATION_PARTISIPASI,
} from "@/app_modules/colab/model/interface";
import mqtt_client from "@/util/mqtt_client";
import { clientLogger } from "@/util/clientLogger";
import {
ActionIcon,
Box,
Button,
Center,
Checkbox,
Drawer,
Grid,
Group,
Paper,
ScrollArea,
Loader,
Stack,
Text,
TextInput,
Title,
} from "@mantine/core";
import { useDisclosure } from "@mantine/hooks";
import { useDisclosure, useShallowEffect } from "@mantine/hooks";
import { IconX } from "@tabler/icons-react";
import { useAtom } from "jotai";
import _ from "lodash";
import { useRouter } from "next/navigation";
import { ScrollOnly } from "next-scroll-loader";
import { useParams, useRouter } from "next/navigation";
import { useState } from "react";
export default function Colab_DetailProyekSaya({
dataColab,
listPartisipan,
}: {
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>
</>
);
}
export default function Colab_DetailProyekSaya() {
const params = useParams<{ id: string }>();
const [data, setData] = useState<MODEL_COLLABORATION | null>(null);
function CheckBoxPartisipan({
listPartisipan,
colabId,
}: {
listPartisipan: MODEL_COLLABORATION_PARTISIPASI[];
colabId: string;
}) {
const [value, setValue] = useState<string[]>([]);
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 (
<>
<Stack>
{/* <pre>{JSON.stringify(listPartisipan,null,2)}</pre> */}
<Paper
style={{
border: `2px solid ${AccentColor.softblue}`,
backgroundColor: AccentColor.blue,
color: "white",
borderRadius: "10px",
marginBottom: "20px",
padding: "15px",
}}
>
{/* {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} />
{_.isNull(data) ? (
<Collaboration_SkeletonDetail />
) : (
<ComponentGlobal_CardStyles marginBottom={"15px"}>
<ComponentColab_DetailData data={data} />
</ComponentGlobal_CardStyles>
)}
<CheckBoxPartisipan />
</Stack>
</>
);
}
function ButtonAction({
value,
colabId,
}: {
value: string[];
colabId: string;
}) {
function CheckBoxPartisipan() {
const params = useParams<{ id: string }>();
const [value, setValue] = useState<string[]>([]);
const [data, setData] = useState<MODEL_COLLABORATION_PARTISIPASI[] | null>(
null
);
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 [opened, { open, close }] = useDisclosure(false);
const [hotMenu, setHotMenu] = useAtom(gs_colab_hot_menu);
@@ -147,29 +195,35 @@ function ButtonAction({
const [loading, setLoading] = useState(false);
async function onSave() {
if (nameRoom === "")
return ComponentGlobal_NotifikasiPeringatan("Lengkapi Nama Grup");
try {
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);
if (res.status === 201) {
for (let a of value) {
mqtt_client.publish(
"USER",
JSON.stringify({
userId: a,
count: 1,
})
);
const res = await colab_funCreateRoomChat(nameRoom, value, params.id);
if (res.status === 201) {
// for (let a of value) {
// mqtt_client.publish(
// "USER",
// JSON.stringify({
// userId: a,
// count: 1,
// })
// );
// }
ComponentGlobal_NotifikasiBerhasil("Berhasil Membuat Grup");
setHotMenu(4);
router.replace(RouterColab.grup_diskusi);
} else {
ComponentGlobal_NotifikasiGagal("Gagal Membuat Grup");
}
setLoading(true);
ComponentGlobal_NotifikasiBerhasil("Berhasil Membuat Grup");
setHotMenu(4);
router.push(RouterColab.grup_diskusi);
} else {
ComponentGlobal_NotifikasiGagal("Gagal Membuat Grup");
} catch (error) {
clientLogger.error("Error create room chat", error);
} finally {
setLoading(false);
}
}
@@ -188,7 +242,7 @@ function ButtonAction({
transition: "0.5s",
}}
>
Buat Ruang Diskusi{" "}
Buat Ruang Diskusi
</Button>
<Drawer
@@ -220,12 +274,13 @@ function ButtonAction({
>
<Stack>
<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">
<IconX color="white" />
<IconX color={MainColor.white} />
</ActionIcon>
</Group>
<TextInput
styles={{ input: { backgroundColor: MainColor.white } }}
placeholder="Masukan nama grup diskusi .."
radius={"xl"}
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 { ActionIcon } from "@mantine/core";
import { IconDotsVertical, IconEdit } from "@tabler/icons-react";
import { useParams } from "next/navigation";
import React, { useState } from "react";
export default function LayoutColab_DetailProyekSaya({
children,
colabId,
}: {
children: React.ReactNode;
colabId: string;
}) {
const params = useParams<{id: string}>()
const [openDrawer, setOpenDrawer] = useState(false);
const listPage = [
{
id: "1",
name: "Edit Proyek",
icon: <IconEdit />,
path: RouterColab.edit + colabId,
path: RouterColab.edit + params.id,
},
];

View File

@@ -13,6 +13,7 @@ import {
MODEL_COLLABORATION,
MODEL_COLLABORATION_MASTER,
} from "../model/interface";
import { clientLogger } from "@/util/clientLogger";
export default function Colab_Edit({
selectedData,
@@ -30,8 +31,14 @@ export default function Colab_Edit({
maxLength={100}
styles={{
label: {
color: "white",
color: MainColor.white,
},
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
}
}}
label="Judul"
withAsterisk
@@ -49,8 +56,14 @@ export default function Colab_Edit({
maxLength={100}
styles={{
label: {
color: "white",
color: MainColor.white,
},
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
}
}}
label="Lokasi"
withAsterisk
@@ -67,8 +80,17 @@ export default function Colab_Edit({
<Select
styles={{
label: {
color: "white",
color: MainColor.white,
},
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
},
dropdown: {
backgroundColor: MainColor.white,
}
}}
placeholder="Pilih kategori industri"
label="Pilih Industri"
@@ -113,8 +135,14 @@ export default function Colab_Edit({
<Textarea
styles={{
label: {
color: "white",
color: MainColor.white,
},
input: {
backgroundColor: MainColor.white,
},
required: {
color: MainColor.red,
}
}}
label="Tujuan Proyek"
placeholder="Masukan tujuan proyek"
@@ -138,7 +166,10 @@ export default function Colab_Edit({
<Textarea
styles={{
label: {
color: "white",
color: MainColor.white,
},
input: {
backgroundColor: MainColor.white,
},
}}
label="Keuntungan "
@@ -181,12 +212,18 @@ function ButtonAction({ value }: { value: any }) {
// return ComponentGlobal_NotifikasiPeringatan("Minimal Ada 2 Partisipan");
await colab_funEditById(value as any).then((res) => {
if (res.status === 200) {
try {
setLoading(true);
router.back();
ComponentGlobal_NotifikasiBerhasil(res.message);
} else {
ComponentGlobal_NotifikasiGagal(res.message);
if (res.status === 200) {
router.back();
ComponentGlobal_NotifikasiBerhasil(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 { RouterColab } from "@/app/lib/router_hipmi/router_colab";
import { funGetUserIdByToken } from "@/app_modules/_global/fun/get";
import { revalidatePath } from "next/cache";
export default async function colab_funCreatePartisipan(
colabId: string,
userId: string,
deskripsi: string
) {
export default async function colab_funCreatePartisipan({
id,
deskripsi,
}: {
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({
data: {
projectCollaborationId: colabId,
userId: userId,
projectCollaborationId: id,
userId: userLoginId,
deskripsi_diri: deskripsi,
},
select: {
@@ -27,7 +39,7 @@ export default async function colab_funCreatePartisipan(
});
if (!create) return { status: 400, message: "Gagal menambahkan partisipan" };
revalidatePath(RouterColab.main_detail + colabId);
revalidatePath(RouterColab.main_detail + id);
return {
data: create,
status: 201,

View File

@@ -26,5 +26,5 @@ export default async function colab_funCreateProyek(
if (!data) return { status: 400, message: "Gagal Membuat Proyek" };
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 { ScrollOnly } from "next-scroll-loader";
import { useState } from "react";
import { apiGetAllCollaboration } from "../_lib/api_collaboration";
import { ComponentColab_ButtonUpdateBeranda } from "../component/button/button_update_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 { Collaboration_SkeletonBeranda } from "../component/skeleton_view";
import { clientLogger } from "@/util/clientLogger";
export default function Colab_Beranda({
listData,
userLoginId,
}: {
listData: MODEL_COLLABORATION[];
userLoginId: string;
}) {
const [data, setData] = useState(listData);
const [data, setData] = useState<MODEL_COLLABORATION[] | null>(null);
const [activePage, setActivePage] = useState(1);
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(() => {
mqtt_client.subscribe("Colab_create");
@@ -36,6 +54,10 @@ export default function Colab_Beranda({
});
}, []);
if (_.isNull(data)) {
return <Collaboration_SkeletonBeranda />;
}
return (
<>
<Box>
@@ -62,15 +84,16 @@ export default function Colab_Beranda({
</Center>
)}
data={data}
setData={setData}
setData={setData as any}
moreData={async () => {
const loadData = await colab_getListAllProyek({
page: activePage + 1,
const respone = await apiGetAllCollaboration({
kategori: "beranda",
page: `${activePage + 1}`,
});
setActivePage((val) => val + 1);
return loadData;
return respone.data;
}}
>
{(item) => (

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,5 @@
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_NotifikasiGagal } from "@/app_modules/_global/notif_global/notifikasi_gagal";
import { Badge, Card, Grid, Group, Progress, Stack, Text } from "@mantine/core";
@@ -36,7 +36,7 @@ export function ComponentDonasi_CardInvoiceNew({ data, }: { data: IDataAllDonasi
padding: "15px",
cursor: "pointer",
borderRadius: "10px",
color: "white",
color: MainColor.white,
marginBottom: "15px",
}}
onClick={() => onCekInvoice()}

View File

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

View File

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

View File

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

View File

@@ -2,7 +2,8 @@
import { RouterDonasi } from "@/app/lib/router_hipmi/router_donasi";
import { AccentColor, MainColor, } from "@/app_modules/_global/color/color_pallet";
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 { IconCircleChevronRight } from "@tabler/icons-react";
import _ from "lodash";
@@ -40,7 +41,7 @@ export default function ComponentDonasi_InformasiPenggalangMainNew() {
<Stack
spacing={"xs"}
style={{
color: "white",
color: MainColor.white,
}}
>
<Title order={4}>Informasi Penggalang Dana</Title>
@@ -50,11 +51,11 @@ export default function ComponentDonasi_InformasiPenggalangMainNew() {
backgroundColor: AccentColor.darkblue,
border: `2px solid ${AccentColor.blue}`,
borderRadius: "10px",
color: "white",
color: MainColor.white,
}}
>
{
loading ? <Skeleton height={100} radius="md" width={"100%"} />
loading ? <CustomSkeleton height={100} radius="md" width={"100%"} />
:
<Stack>
<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() {
return (
<>
<Box mb={"md"}>
<Skeleton height={10} mt={0} radius="xl" width={"50%"} />
<Skeleton height={10} mt={10} radius="xl" />
<Skeleton height={10} mt={10} radius="xl" />
<Skeleton height={10} mt={10} radius="xl" />
<CustomSkeleton height={10} mt={0} radius="xl" width={"50%"} />
<CustomSkeleton height={10} mt={10} radius="xl" />
<CustomSkeleton height={10} mt={10} radius="xl" />
<CustomSkeleton height={10} mt={10} radius="xl" />
</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() {
return (
<>
<Box>
<Box mb={"md"}>
<Skeleton height={150} radius="md" />
<CustomSkeleton height={150} radius="md" />
</Box>
<Box mb={"md"}>
<Skeleton height={10} mt={10} radius="xl" width={"50%"} />
<Skeleton height={10} mt={10} radius="xl" />
<Skeleton height={10} mt={10} radius="xl" />
<CustomSkeleton height={10} mt={10} radius="xl" width={"50%"} />
<CustomSkeleton height={10} mt={10} radius="xl" />
<CustomSkeleton height={10} mt={10} radius="xl" />
</Box>
<Box>
<Skeleton height={50} radius="md" />
<CustomSkeleton height={50} radius="md" />
</Box>
</Box>
</>

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