From 502c98fd6d8df60d68efab1f2e440faeebbea8ed Mon Sep 17 00:00:00 2001 From: amel Date: Thu, 8 May 2025 17:26:40 +0800 Subject: [PATCH] upd: api moblie Deskripsi: - update api mobile load project - update get user by id No Issues --- .../api/mobile/project/[id]/lainnya/route.ts | 48 +++ .../api/mobile/project/[id]/member/route.ts | 191 ++++++++++ src/app/api/mobile/project/[id]/route.ts | 285 ++++++++++++++ .../api/mobile/project/detail/[id]/route.ts | 247 ++++++++++++ src/app/api/mobile/project/file/[id]/route.ts | 199 ++++++++++ src/app/api/mobile/project/route.ts | 354 ++++++++++++++++++ src/module/auth/api/funGetUserById.ts | 14 +- 7 files changed, 1337 insertions(+), 1 deletion(-) create mode 100644 src/app/api/mobile/project/[id]/lainnya/route.ts create mode 100644 src/app/api/mobile/project/[id]/member/route.ts create mode 100644 src/app/api/mobile/project/[id]/route.ts create mode 100644 src/app/api/mobile/project/detail/[id]/route.ts create mode 100644 src/app/api/mobile/project/file/[id]/route.ts create mode 100644 src/app/api/mobile/project/route.ts diff --git a/src/app/api/mobile/project/[id]/lainnya/route.ts b/src/app/api/mobile/project/[id]/lainnya/route.ts new file mode 100644 index 0000000..bf3f042 --- /dev/null +++ b/src/app/api/mobile/project/[id]/lainnya/route.ts @@ -0,0 +1,48 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import { NextResponse } from "next/server"; + + +// HAPUS PROJECT YG TELAH DIBATALKAN +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params + const data = await prisma.project.count({ + where: { + id: id, + } + }) + + if (data == 0) { + return NextResponse.json( + { + success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const dataDelete = await prisma.project.update({ + where: { + id + }, + data: { + isActive: false + } + }) + + // create log user + const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus data kegiatan', table: 'project', data: String(id) }) + return NextResponse.json({ success: true, message: "Kegiatan berhasil dihapus", user: user.id }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/project/[id]/member/route.ts b/src/app/api/mobile/project/[id]/member/route.ts new file mode 100644 index 0000000..0af5250 --- /dev/null +++ b/src/app/api/mobile/project/[id]/member/route.ts @@ -0,0 +1,191 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + + +// ADD MEMBER PROJECT +export async function POST(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params + const { member } = (await request.json()) + + const data = await prisma.project.count({ + where: { + id: id + } + }) + + if (data == 0) { + return NextResponse.json( + { + success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", + }, + { status: 404 } + ); + } + + if (member.length > 0) { + const dataMember = member.map((v: any) => ({ + ..._.omit(v, ["idUser", "name", "img"]), + idProject: id, + idUser: v.idUser + })) + + const insertMember = await prisma.projectMember.createMany({ + data: dataMember + }) + } + + // create log user + const log = await createLogUser({ act: 'CREATE', desc: 'User menambah anggota kegiatan', table: 'project', data: String(id) }) + return NextResponse.json({ success: true, message: "Berhasil menambahkan anggota kegiatan" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menambah anggota kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +// MENGELUARKAN ANGGOTA +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params + const { idUser } = (await request.json()); + + const data = await prisma.project.count({ + where: { + id: id, + }, + }); + + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Gagal, data tugas tidak ditemukan", + }, + { status: 404 } + ); + } + + const deleteMember = await prisma.projectMember.deleteMany({ + where: { + idProject: id, + idUser: idUser + } + }) + + // create log user + const log = await createLogUser({ act: 'DELETE', desc: 'User mengeluarkan anggota kegiatan', table: 'project', data: String(id) }) + + return NextResponse.json({ success: true, message: "Berhasil mengeluarkan anggota kegiatan" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengeluarkan anggota kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +//GET MEMBER ALL USER ID GROUP +export async function GET(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params + const groupId = user.idGroup + const userId = user.id + const { searchParams } = new URL(request.url); + const name = searchParams.get('search'); + + const data = await prisma.project.findUnique({ + where: { + id: String(id), + isActive: true + } + }) + + if (data == null) { + return NextResponse.json( + { + success: false, + message: "Gagal, data tugas tidak ditemukan", + }, + { status: 404 } + ); + } + + const member = await prisma.user.findMany({ + where: { + idGroup: String(groupId), + // id: { + // not: String(userId) + // }, + // OR: [ + // { idUserRole: 'coadmin', }, + // { idUserRole: 'user', } + // ], + isActive: true, + name: { + contains: (name == undefined || name == "null") ? "" : name, + mode: 'insensitive' + } + + }, + select: { + id: true, + idUserRole: true, + name: true, + email: true, + img: true, + UserRole: { + select: { + name: true + } + } + }, + orderBy: { + name: 'asc' + } + }) + + const omitData = member.map((v: any) => ({ + ..._.omit(v, ["UserRole"]), + userRole: v.UserRole.name + })) + + const fixMember = omitData.map((v: any) => ({ + idUser: v.id, + name: v.name, + email: v.email, + img: v.img, + idUserRole: v.idUserRole + })) + + const dataFix = { + project: data, + member: fixMember + } + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan kegiatan", data: dataFix, }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/project/[id]/route.ts b/src/app/api/mobile/project/[id]/route.ts new file mode 100644 index 0000000..19bc836 --- /dev/null +++ b/src/app/api/mobile/project/[id]/route.ts @@ -0,0 +1,285 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import _ from "lodash"; +import moment from "moment"; +import { NextResponse } from "next/server"; + + +// GET DETAIL PROJECT / GET ONE PROJECT +export async function GET(request: Request, context: { params: { id: string } }) { + try { + let allData + const { id } = context.params; + const user = await funGetUserByCookies() + const { searchParams } = new URL(request.url); + const kategori = searchParams.get("cat"); + + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const data = await prisma.project.findUnique({ + where: { + id: String(id), + isActive: true + } + }); + + if (!data) { + return NextResponse.json({ success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", }, { status: 404 }); + } + + + if (kategori == "data") { + allData = data + } else if (kategori == "progress") { + const dataProgress = await prisma.projectTask.findMany({ + where: { + isActive: true, + idProject: String(id) + }, + orderBy: { + updatedAt: 'desc' + } + }) + + const semua = dataProgress.length + const selesai = _.filter(dataProgress, { status: 1 }).length + const progress = Math.ceil((selesai / semua) * 100) + + allData = { + progress: (_.isNaN(progress)) ? 0 : progress, + lastUpdate: moment(dataProgress[0]?.updatedAt).format("DD MMMM YYYY"), + } + } else if (kategori == "task") { + const dataProgress = await prisma.projectTask.findMany({ + where: { + isActive: true, + idProject: String(id) + }, + select: { + id: true, + title: true, + desc: true, + status: true, + dateStart: true, + dateEnd: true, + createdAt: true + }, + orderBy: { + createdAt: 'asc' + } + }) + + const formatData = dataProgress.map((v: any) => ({ + ..._.omit(v, ["dateStart", "dateEnd", "createdAt"]), + dateStart: moment(v.dateStart).format("DD-MM-YYYY"), + dateEnd: moment(v.dateEnd).format("DD-MM-YYYY"), + createdAt: moment(v.createdAt).format("DD-MM-YYYY HH:mm"), + })) + const dataFix = _.orderBy(formatData, 'createdAt', 'asc') + allData = dataFix + + } else if (kategori == "file") { + const dataFile = await prisma.projectFile.findMany({ + where: { + isActive: true, + idProject: String(id) + }, + orderBy: { + createdAt: 'asc' + }, + select: { + id: true, + name: true, + extension: true, + idStorage: true + } + }) + + allData = dataFile + } else if (kategori == "member") { + + const dataMember = await prisma.projectMember.findMany({ + where: { + isActive: true, + idProject: String(id) + }, + select: { + id: true, + idUser: true, + User: { + select: { + name: true, + email: true, + img: true, + Position: { + select: { + name: true + } + } + } + }, + } + }) + + const fix = dataMember.map((v: any) => ({ + ..._.omit(v, ["User"]), + name: v.User.name, + email: v.User.email, + img: v.User.img, + position: v.User.Position.name + })) + + allData = fix + } + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan kegiatan", data: allData, }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +//CREATE NEW DETAIL TASK PROJECT +export async function POST(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params + const { name, dateStart, dateEnd, } = await request.json() + + const data = await prisma.project.count({ + where: { + id: String(id) + } + }) + + if (data == 0) { + return NextResponse.json( + { + success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const dataCreate = await prisma.projectTask.create({ + data: { + title: name, + idProject: id, + dateStart: new Date(dateStart), + dateEnd: new Date(dateEnd), + }, + select: { + id: true + } + }) + + // create log user + const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data tahapan kegiatan', table: 'projectTask', data: String(dataCreate.id) }) + + return NextResponse.json({ success: true, message: "Detail tahapan kegiatan berhasil ditambahkan", data: dataCreate, }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal tambah tahapan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// PEMBATALAN TASK PROJECT +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params + const { reason } = await request.json() + const data = await prisma.project.count({ + where: { + id: id + } + }) + + if (data == 0) { + return NextResponse.json( + { + success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const dataCreate = await prisma.project.update({ + where: { + id + }, + data: { + status: 3, + reason: reason + } + }) + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User membatalkan data kegiatan', table: 'project', data: String(id) }) + return NextResponse.json({ success: true, message: "Kegiatan berhasil dibatalkan" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal membatalkan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +// EDIT PROJECT +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params + const { name } = await request.json() + + const data = await prisma.project.count({ + where: { + id: id + } + }) + + if (data == 0) { + return NextResponse.json( + { + success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const dataCreate = await prisma.project.update({ + where: { + id + }, + data: { + title: name + } + }) + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data kegiatan', table: 'project', data: String(id) }) + + return NextResponse.json({ success: true, message: "Kegiatan berhasil diupdate" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupdate kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/project/detail/[id]/route.ts b/src/app/api/mobile/project/detail/[id]/route.ts new file mode 100644 index 0000000..abd5571 --- /dev/null +++ b/src/app/api/mobile/project/detail/[id]/route.ts @@ -0,0 +1,247 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import { NextResponse } from "next/server"; + + +// HAPUS DETAIL PROJECT +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + const { id } = context.params; + const { idProject } = (await request.json()); + + const data = await prisma.projectTask.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Hapus tahapan kegiatan gagal, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const update = await prisma.projectTask.update({ + where: { + id: id, + }, + data: { + isActive: false, + }, + }); + + const dataTask = await prisma.projectTask.findMany({ + where: { + isActive: true, + idProject: idProject, + } + }) + + const semua = dataTask.length + const selesai = dataTask.filter((item) => item.status == 1).length + const prosess = Math.ceil((selesai / semua) * 100) + let statusProject = 1 + + if (prosess == 100) { + statusProject = 2 + } else if (prosess == 0) { + statusProject = 0 + } + + + const updProject = await prisma.project.update({ + where: { + id: idProject + }, + data: { + status: statusProject + } + }) + + // create log user + const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus tahapan kegiatan', table: 'projectTask', data: String(id) }) + + + return NextResponse.json( + { + success: true, + message: "Tahapan kegiatan berhasil dihapus", + data, + }, + { status: 200 } + ); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus tahapan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// EDIT STATUS DETAIL PROJECT +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params; + const { status, idProject } = (await request.json()); + + const data = await prisma.projectTask.count({ + where: { + id + } + }) + + if (data == 0) { + return NextResponse.json( + { + success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const dataCreate = await prisma.projectTask.update({ + where: { + id + }, + data: { + status: status + } + }) + + + // const cek progress + const dataTask = await prisma.projectTask.findMany({ + where: { + isActive: true, + idProject: idProject, + } + }) + + const semua = dataTask.length + const selesai = dataTask.filter((item) => item.status == 1).length + const prosess = Math.ceil((selesai / semua) * 100) + let statusProject = 1 + + if (prosess == 100) { + statusProject = 2 + } else if (prosess == 0) { + statusProject = 0 + } + + + const update = await prisma.project.update({ + where: { + id: idProject + }, + data: { + status: statusProject + } + }) + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate status tahapan kegiatan', table: 'projectTask', data: String(id) }) + + return NextResponse.json({ success: true, message: "Status tahapan kegiatan berhasil diupdate", data }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupdate status tahapan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// GET ONE DETAIL PROJECT +export async function GET(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params; + const data = await prisma.projectTask.findUnique({ + where: { + id: String(id), + isActive: true + } + }) + + if (!data) { + return NextResponse.json( + { + success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", + }, + { status: 404 } + ); + } + + return NextResponse.json({ success: true, message: "Detail kegiatan berhasil ditemukan", data }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// EDIT DETAIL PROJECT +export async function POST(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { id } = context.params; + const { title, dateStart, dateEnd } = (await request.json()); + + + + const dataTask = await prisma.projectTask.count({ + where: { + id + } + }) + + if (dataTask == 0) { + return NextResponse.json( + { + success: false, message: "Gagal mendapatkan kegiatan, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const data = await prisma.projectTask.update({ + where: { + id + }, + data: { + title, + dateStart: new Date(dateStart), + dateEnd: new Date(dateEnd), + } + }) + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate tahapan kegiatan', table: 'projectTask', data: String(id) }) + + return NextResponse.json({ success: true, message: "Detail tahapan kegiatan berhasil diupdate", data }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupdate detail tahapan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/project/file/[id]/route.ts b/src/app/api/mobile/project/file/[id]/route.ts new file mode 100644 index 0000000..30f3965 --- /dev/null +++ b/src/app/api/mobile/project/file/[id]/route.ts @@ -0,0 +1,199 @@ +import { DIR, funDeleteFile, funUploadFile, prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +// HAPUS FILE PROJECT BUKAN PAKE ISACTIVE +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + const { id } = context.params; + const data = await prisma.projectFile.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Hapus file gagal, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const dataRelasi = await prisma.projectFile.findUnique({ + where: { + id: id, + } + }) + + const delStorage = await funDeleteFile({ fileId: String(dataRelasi?.idStorage) }) + + const deleteRelasi = await prisma.projectFile.delete({ + where: { + id: id, + }, + }); + + // create log user + const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus file kegiatan', table: 'project', data: String(dataRelasi?.idProject) }) + + + return NextResponse.json( + { + success: true, + message: "File berhasil dihapus", + data, + }, + { status: 200 } + ); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus file, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// CEK FILE PROJECT APAKAH PERNAH DIUPLOAD PADA PROJECT YG SAMA +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + + const { id } = context.params; + const body = await request.formData() + const file = body.get("file") as File + const fileName = file.name + + const dataCek = await prisma.project.count({ + where: { + id: id, + }, + }); + + if (dataCek == 0) { + return NextResponse.json( + { + success: false, + message: "Upload file gagal, data kegiatan tidak ditemukan", + }, + { status: 404 } + ); + } + + const dataTaskFile = await prisma.projectFile.findMany({ + where: { + idProject: id, + isActive: true + }, + select: { + id: true, + name: true, + extension: true + } + }) + + const dataOmit = dataTaskFile.map((v: any) => ({ + ..._.omit(v, [""]), + file: v.name + '.' + v.extension, + })) + + const cek = dataOmit.some((i: any) => i.file == fileName) + + + if (cek) { + return NextResponse.json({ success: false, message: "File sudah pernah diupload" }, { status: 400 }); + } else { + return NextResponse.json({ success: true, message: "Cek berhasil" }, { status: 200 }); + } + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Upload file gagal, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// TAMBAH FILE PROJECT +export async function POST(request: Request, context: { params: { id: string } }) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + + const { id } = context.params; + const body = await request.formData() + const cekFile = body.has("file0") + + const dataCek = await prisma.project.count({ + where: { + id: id, + }, + }); + + if (dataCek == 0) { + return NextResponse.json( + { + success: false, + message: "Tambah file kegiatan gagal, data tugas tidak ditemukan", + }, + { status: 404 } + ); + } + + const dataProject = await prisma.project.findUnique({ + where: { + id: id, + }, + }); + + + + if (cekFile) { + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = file.name.replace("." + fExt, "") + + const upload = await funUploadFile({ file: file, dirId: DIR.project }) + if (upload.success) { + const insertToTable = await prisma.projectFile.create({ + data: { + idStorage: upload.data.id, + idProject: id, + name: fName, + extension: String(fExt), + + }, + select: { + id: true + } + }) + } + } + } + } + + // create log user + const log = await createLogUser({ act: 'CREATE', desc: 'User menambah file kegiatan', table: 'project', data: String(id) }) + return NextResponse.json({ success: true, message: "Berhasil mengupload file kegiatan" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupload file, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/project/route.ts b/src/app/api/mobile/project/route.ts new file mode 100644 index 0000000..faa8ef8 --- /dev/null +++ b/src/app/api/mobile/project/route.ts @@ -0,0 +1,354 @@ +import { DIR, funSendWebPush, funUploadFile, prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import { createLogUserMobile } from "@/module/user"; +import _, { ceil } from "lodash"; +import moment from "moment"; +import "moment/locale/id"; +import { NextResponse } from "next/server"; + + +// GET ALL DATA PROJECT +export async function GET(request: Request) { + try { + const { searchParams } = new URL(request.url); + const name = searchParams.get('search'); + const status = searchParams.get('status'); + const idGroup = searchParams.get("group"); + const page = searchParams.get('page'); + const kategori = searchParams.get('cat'); + const user = searchParams.get('user'); + + const userMobile = await funGetUserById({ id: String(user) }) + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + let grup + const dataSkip = Number(page) * 10 - 10; + const roleUser = userMobile.idUserRole + const villageId = userMobile.idVillage + const userId = userMobile.id + + if (idGroup == "null" || idGroup == undefined || idGroup == "" || idGroup == "undefined") { + grup = userMobile.idGroup + } else { + grup = idGroup + } + + const cek = await prisma.group.count({ + where: { + id: grup, + isActive: true + } + }) + + if (cek == 0) { + return NextResponse.json({ success: false, message: "Gagal mendapatkan data kegiatan, data tidak ditemukan", }, { status: 200 }); + } + + + // JIKA (ROLE BUKAN USER DAN COADMIN) ATAU SEMUA ROLE DG KATEGORI == SEMUA + let kondisi: any = { + isActive: true, + idVillage: String(villageId), + idGroup: grup, + title: { + contains: (name == undefined || name == "null") ? "" : name, + mode: "insensitive" + }, + status: (status == "0" || status == "1" || status == "2" || status == "3") ? Number(status) : 0 + } + + + // JIKA ROLE = USER ATAU COADMIN DAN KATEGORI != SEMUA (KEGIATAN SAYA) + if (roleUser != "supadmin" && roleUser != "developer" && roleUser != "cosupadmin" && roleUser != "admin") { + if (kategori != "semua") { + kondisi = { + isActive: true, + idVillage: String(villageId), + idGroup: grup, + title: { + contains: (name == undefined || name == "null") ? "" : name, + mode: "insensitive" + }, + status: (status == "0" || status == "1" || status == "2" || status == "3") ? Number(status) : 0, + ProjectMember: { + some: { + idUser: String(userId) + } + } + } + } + } + + + const data = await prisma.project.findMany({ + // skip: dataSkip, + // take: 10, + where: kondisi, + select: { + id: true, + title: true, + desc: true, + status: true, + createdAt: true, + ProjectMember: { + where: { + isActive: true + }, + select: { + idUser: true + } + }, + ProjectTask: { + where: { + isActive: true + }, + select: { + title: true, + status: true + } + } + }, + orderBy: { + createdAt: 'desc' + } + }) + + const omitData = data.map((v: any) => ({ + ..._.omit(v, ["ProjectMember", "ProjectTask", "createdAt"]), + progress: ceil((v.ProjectTask.filter((i: any) => i.status == 1).length * 100) / v.ProjectTask.length), + member: v.ProjectMember.length, + createdAt: moment(v.createdAt).format("LL") + })) + + const totalData = await prisma.project.count({ + where: kondisi + }) + + const filter = await prisma.group.findUnique({ + where: { + id: grup + }, + select: { + id: true, + name: true + } + }) + + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan kegiatan", data: omitData, filter, total: totalData }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +// CREATE PROJECT +export async function POST(request: Request) { + try { + + const body = await request.formData() + const dataBody = body.get("data") + const cekFile = body.has("file0") + + const { idGroup, title, task, member, user } = JSON.parse(dataBody as string) + + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + + const userId = userMobile.id + const userRoleLogin = userMobile.idUserRole + + const data = await prisma.project.create({ + data: { + idVillage: String(userMobile.idVillage), + idGroup: String(idGroup), + title, + createdBy: String(userId) + }, + select: { + id: true + } + }) + + if (task.length > 0) { + const dataProject = task.map((v: any) => ({ + ..._.omit(v, ["dateStart", "dateEnd", "name"]), + idProject: data.id, + title: v.title, + dateStart: new Date(v.dateStart), + dateEnd: new Date(v.dateEnd), + })) + + const insertTask = await prisma.projectTask.createMany({ + data: dataProject + }) + } + + if (member.length > 0) { + const dataMember = member.map((v: any) => ({ + ..._.omit(v, ["idUser", "name", "img"]), + idProject: data.id, + idUser: v.idUser, + })) + + const insertMember = await prisma.projectMember.createMany({ + data: dataMember + }) + } + + if (cekFile) { + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = file.name.replace("." + fExt, "") + const upload = await funUploadFile({ file: file, dirId: DIR.project }) + if (upload.success) { + await prisma.projectFile.create({ + data: { + idStorage: upload.data.id, + idProject: data.id, + name: fName, + extension: String(fExt) + } + }) + } + } + } + } + + const memberNotif = await prisma.projectMember.findMany({ + where: { + idProject: data.id + }, + select: { + idUser: true, + User: { + select: { + Subscribe: { + select: { + subscription: true + } + } + } + } + } + }) + + + // mengirim notifikasi + // datanotif untuk realtime notifikasi + // datapush untuk web push notifikasi ketika aplikasi tidak aktif + const dataNotif = memberNotif.map((v: any) => ({ + ..._.omit(v, ["idUser", "User", "Subscribe"]), + idUserTo: v.idUser, + idUserFrom: userId, + category: 'project', + idContent: data.id, + title: 'Kegiatan Baru', + desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + })) + + const dataPush = memberNotif.map((v: any) => ({ + ..._.omit(v, ["idUser", "User", "Subscribe"]), + idUser: v.idUser, + subscription: v.User.Subscribe?.subscription, + })) + + if (userRoleLogin != "supadmin") { + const perbekel = await prisma.user.findFirst({ + where: { + isActive: true, + idUserRole: "supadmin", + idVillage: userMobile.idVillage + }, + select: { + id: true, + Subscribe: { + select: { + subscription: true + } + } + } + }) + + dataNotif.push({ + idUserTo: perbekel?.id, + idUserFrom: userId, + category: 'project', + idContent: data.id, + title: 'Kegiatan Baru', + desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + }) + + dataPush.push({ + idUser: perbekel?.id, + subscription: perbekel?.Subscribe?.subscription + }) + } else { + const atasanGroup = await prisma.user.findMany({ + where: { + isActive: true, + idGroup: idGroup, + AND: { + OR: [ + { idUserRole: 'cosupadmin' }, + { idUserRole: 'admin' }, + ] + } + }, + select: { + id: true, + Subscribe: { + select: { + subscription: true + } + } + } + }) + + const omitData = atasanGroup.map((v: any) => ({ + ..._.omit(v, ["id", "Subscribe"]), + idUserTo: v.id, + idUserFrom: userId, + category: 'project', + idContent: data.id, + title: 'Kegiatan Baru', + desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + })) + + const omitPush = atasanGroup.map((v: any) => ({ + ..._.omit(v, ["id", "Subscribe"]), + idUser: v.id, + subscription: v.Subscribe?.subscription, + })) + + dataNotif.push(...omitData) + dataPush.push(...omitPush) + + } + + const pushNotif = dataPush.filter((item) => item.subscription != undefined) + + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' } }) + const insertNotif = await prisma.notifications.createMany({ + data: dataNotif + }) + + + // create log user + const log = await createLogUserMobile({ act: 'CREATE', desc: 'User membuat data kegiatan', table: 'project', data: data.id, user: userMobile.id }) + return NextResponse.json({ success: true, message: "Berhasil membuat kegiatan"}, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal membuat kegiatan, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/module/auth/api/funGetUserById.ts b/src/module/auth/api/funGetUserById.ts index 83704e6..6a6e252 100644 --- a/src/module/auth/api/funGetUserById.ts +++ b/src/module/auth/api/funGetUserById.ts @@ -8,9 +8,21 @@ export default async function funGetUserById({ id }: { id: string }) { }, }); + if (!user) { + return { + id: undefined, + idUserRole: undefined, + name: undefined, + idVillage: undefined, + idGroup: undefined, + idPosition: undefined, + theme: undefined, + } + } + const village = await prisma.village.findUnique({ where: { - id: user?.idVillage + id: user.idVillage } })