diff --git a/src/app/api/home/search/route.ts b/src/app/api/home/search/route.ts index bf6a757..609630b 100644 --- a/src/app/api/home/search/route.ts +++ b/src/app/api/home/search/route.ts @@ -13,11 +13,26 @@ export async function GET(request: Request) { return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); } - let kondisi: any, kondisiProject: any + let kondisi: any, kondisiProject: any, kondisiDivision: any // klo perbekel/developer == semua grup if (userId.idUserRole == "supadmin" || userId.idUserRole == "developer") { kondisi = { + isActive: true, + idVillage: userId.idVillage, + Group: { + isActive: true, + }, + name: { + contains: (search == undefined || search == null) ? "" : search, + mode: "insensitive" + }, + NOT: { + idUserRole: "developer" + } + } + + kondisiDivision = { isActive: true, idVillage: userId.idVillage, Group: { @@ -42,6 +57,19 @@ export async function GET(request: Request) { } } else { kondisi = { + idVillage: userId.idVillage, + isActive: true, + idGroup: userId.idGroup, + name: { + contains: (search == undefined || search == null) ? "" : search, + mode: "insensitive" + }, + NOT: { + idUserRole: "developer" + } + } + + kondisiDivision = { idVillage: userId.idVillage, isActive: true, idGroup: userId.idGroup, @@ -84,12 +112,12 @@ export async function GET(request: Request) { const userOmit = user.map((v: any) => ({ ..._.omit(v, ["Position", "Group"]), - position: v.Position.name, + position: v.Position?.name, group: v.Group.name })) const divisions = await prisma.division.findMany({ - where: kondisi, + where: kondisiDivision, select: { id: true, name: true, @@ -133,6 +161,7 @@ export async function GET(request: Request) { return NextResponse.json({ success: true, data: allDataSearch }, { status: 200 }); } catch (error) { + console.error(error) return NextResponse.json({ success: false, message: 'Gagal mendapatkan data, coba lagi nanti (error: 500)' }, { status: 500 }); } } \ No newline at end of file diff --git a/src/app/api/mobile/banner/[id]/route.ts b/src/app/api/mobile/banner/[id]/route.ts new file mode 100644 index 0000000..31e2136 --- /dev/null +++ b/src/app/api/mobile/banner/[id]/route.ts @@ -0,0 +1,113 @@ +import { DIR, funDeleteFile, funUploadFile, prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import { NextResponse } from "next/server"; + + +// GET ONE BANNER +export async function GET(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const data = await prisma.bannerImage.findUnique({ + where: { + id: String(id) + } + }) + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan banner", data }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan banner, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// DELETE BANNER +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const upd = await prisma.bannerImage.update({ + where: { + id: String(id) + }, + data: { + isActive: false + } + }) + + + // create log user + const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus banner', table: 'bannerImage', data: id }) + + return NextResponse.json({ success: true, message: "Berhasil menghapus banner" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus banner, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// UPDATE BANNER +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const body = await request.formData() + const file = body.get("file") as File + const data = body.get("data") + const { title } = JSON.parse(data as string) + + + const upd = await prisma.bannerImage.update({ + where: { + id: String(id) + }, + data: { + title + }, + select: { + image: true + } + }) + + if (String(file) != "undefined" && String(file) != "null") { + const fExt = file.name.split(".").pop() + const fileName = id + '.' + fExt; + const newFile = new File([file], fileName, { type: file.type }); + await funDeleteFile({ fileId: String(upd.image) }) + const upload = await funUploadFile({ file: newFile, dirId: DIR.banner }) + await prisma.bannerImage.update({ + where: { + id: id + }, + data: { + image: upload.data.id + } + }) + } + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data banner', table: 'bannerImage', data: user.id }) + + return NextResponse.json({ success: true, message: "Berhasil mengupdate banner" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupdate banner, 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/banner/route.ts b/src/app/api/mobile/banner/route.ts new file mode 100644 index 0000000..66c5a96 --- /dev/null +++ b/src/app/api/mobile/banner/route.ts @@ -0,0 +1,84 @@ +import { DIR, funUploadFile, funViewDir, prisma } from "@/module/_global"; +import { funGetUserByCookies, funGetUserById } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import { NextResponse } from "next/server"; + + +// GET ALL BANNER +export async function GET(request: Request) { + try { + const { searchParams } = new URL(request.url) + const userMobile = searchParams.get("user") + + if (userMobile == "null" || userMobile == undefined || userMobile == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const user = await funGetUserById({ id: userMobile }) + + + const data = await prisma.bannerImage.findMany({ + where: { + isActive: true, + idVillage: user.idVillage + }, + orderBy: { + createdAt: 'desc' + } + }); + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan banner", data }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan data banner, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// CREATE BANNER +export async function POST(request: Request) { + try { + console.log('masuk') + const body = await request.formData() + const file = body.get("file") as File; + const data = body.get("data"); + + console.log(data) + + const { title, user } = JSON.parse(data as string) + + if (user == "null" || user == undefined || user == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const userLogin = await funGetUserById({ id: user }) + + + const fExt = file.name.split(".").pop() + const fName = file.name.replace("." + fExt, "") + const newFile = new File([file], file.name, { type: file.type }); + + const ini = funViewDir({ dirId: DIR.user }) + const upload = await funUploadFile({ file: newFile, dirId: DIR.banner }) + if (upload.success) { + const create = await prisma.bannerImage.create({ + data: { + title: title, + idVillage: userLogin.idVillage, + extension: String(fExt), + image: upload.data.id + } + }) + + // create log user + const log = await createLogUser({ act: 'CREATE', desc: 'User menambah data banner baru', table: 'bannerImage', data: String(userLogin.id) }) + + return Response.json({ success: true, message: 'Sukses menambah data banner' }, { status: 200 }); + } else { + return Response.json({ success: false, message: 'Gagal menambah data banner' }, { status: 200 }); + } + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menambahkan banner, 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/home/notification/route.ts b/src/app/api/mobile/home/notification/route.ts new file mode 100644 index 0000000..31e7116 --- /dev/null +++ b/src/app/api/mobile/home/notification/route.ts @@ -0,0 +1,125 @@ +import { prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import _ from "lodash"; +import moment from "moment"; +import "moment/locale/id"; +import { NextResponse } from "next/server"; + +// GET ALL NOTIFIKASI +export async function GET(request: Request) { + try { + const user = await funGetUserByCookies(); + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const { searchParams } = new URL(request.url); + const page = searchParams.get('page'); + const dataSkip = Number(page) * 10 - 10; + + const announcements = await prisma.notifications.findMany({ + skip: dataSkip, + take: 10, + where: { + isActive: true, + idUserTo: user.id + }, + orderBy: [ + { + isRead: 'asc' + }, + { + createdAt: 'desc' + } + ] + + }); + + const allData = announcements.map((v: any) => ({ + ..._.omit(v, ["createdAt"]), + createdAt: moment(v.createdAt).format("ll") + })) + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan notifikasi", data: allData, }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan notifikasi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + + +// UPDATE READ NOTIFIKASI +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 } = await request.json(); + const data = await prisma.notifications.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Gagal mendapatkan data, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const result = await prisma.notifications.update({ + where: { + id: id, + }, + data: { + isRead: true, + }, + }); + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User membaca notifikasi', table: 'notifications', data: id }) + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan notifikasi", }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan notifikasi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// UPDATE READ ALL NOTIFICATION +export async function POST(request: Request) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const upd = await prisma.notifications.updateMany({ + where: { + idUserTo: user.id, + isRead: false + }, + data: { + isRead: true + } + }) + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User menandai semua notifikasi', table: 'notifications', data: '' }) + + return NextResponse.json({ success: true, message: "Berhasil mengupdate notifikasi", }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupdate notifikasi, 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/home/route.ts b/src/app/api/mobile/home/route.ts new file mode 100644 index 0000000..3145082 --- /dev/null +++ b/src/app/api/mobile/home/route.ts @@ -0,0 +1,594 @@ +import { prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import _, { ceil } from "lodash"; +import moment from "moment"; +import "moment/locale/id"; +import { NextResponse } from "next/server"; + + +// HOME +export async function GET(request: Request) { + try { + let allData + const { searchParams } = new URL(request.url); + const kategori = searchParams.get("cat"); + const userMobile = searchParams.get("user") + + if (userMobile == "null" || userMobile == undefined || userMobile == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const user = await funGetUserById({ id: userMobile }) + + const roleUser = user.idUserRole + const idVillage = user.idVillage + const idGroup = user.idGroup + + + if (kategori == "kegiatan") { + let kondisi + + // klo perbekel/developer == semua grup + if (roleUser == "supadmin" || roleUser == "developer") { + kondisi = { + isActive: true, + idVillage: idVillage, + Group: { + isActive: true, + } + } + } else if (roleUser == "admin" || roleUser == "cosupadmin") { + kondisi = { + isActive: true, + idGroup: idGroup + } + } else { + kondisi = { + isActive: true, + idGroup: idGroup, + ProjectMember: { + some: { + idUser: user.id + } + } + } + } + + const data = await prisma.project.findMany({ + skip: 0, + take: 5, + where: kondisi, + select: { + id: true, + title: true, + desc: true, + status: true, + createdAt: true, + ProjectTask: { + where: { + isActive: true + }, + select: { + title: true, + status: true + } + } + }, + orderBy: { + createdAt: "desc" + } + }) + + allData = data.map((v: any) => ({ + ..._.omit(v, ["ProjectTask", "createdAt"]), + progress: ceil((v.ProjectTask.filter((i: any) => i.status == 1).length * 100) / v.ProjectTask.length), + createdAt: moment(v.createdAt).format("LL") + })) + + } else if (kategori == "division") { + let kondisi + + // klo perbekel/developer == semua grup + if (roleUser == "supadmin" || roleUser == "developer") { + kondisi = { + isActive: true, + idVillage: idVillage, + Group: { + isActive: true, + } + } + } else if (roleUser == "admin" || roleUser == "cosupadmin") { + kondisi = { + isActive: true, + idGroup: idGroup + } + } else { + kondisi = { + isActive: true, + idGroup: idGroup, + DivisionMember: { + some: { + idUser: user.id + } + } + } + } + + const data = await prisma.division.findMany({ + where: kondisi, + select: { + id: true, + name: true, + DivisionProject: { + where: { + isActive: true, + NOT: { + status: 3 + } + } + } + }, + }) + + const format = data.map((v: any) => ({ + ..._.omit(v, ["DivisionProject"]), + jumlah: v.DivisionProject.length, + })) + + allData = _.orderBy(format, 'jumlah', 'desc').slice(0, 5) + + } else if (kategori == "progress") { + let kondisi + + // klo perbekel/developer == semua grup + if (roleUser == "supadmin" || roleUser == "developer") { + kondisi = { + isActive: true, + Division: { + isActive: true, + idVillage: idVillage, + Group: { + isActive: true, + } + } + } + } else if (roleUser == "admin" || roleUser == "cosupadmin") { + kondisi = { + isActive: true, + Division: { + isActive: true, + idGroup: idGroup + } + } + } else { + kondisi = { + isActive: true, + Division: { + isActive: true, + DivisionMember: { + some: { + idUser: user.id + } + } + } + } + } + + const data = await prisma.divisionProject.groupBy({ + where: kondisi, + by: ["status"], + _count: true + }) + + const dataStatus = [{ name: 'Segera dikerjakan', status: 0, color: '#177AD5' }, { name: 'Dikerjakan', status: 1, color: '#fac858' }, { name: 'Selesai dikerjakan', status: 2, color: '#92cc76' }, { name: 'Dibatalkan', status: 3, color: '#ED6665' }] + const hasil: any[] = [] + let input + for (let index = 0; index < dataStatus.length; index++) { + const cek = data.some((i: any) => i.status == dataStatus[index].status) + if (cek) { + const find = ((Number(data.find((i: any) => i.status == dataStatus[index].status)?._count) * 100) / data.reduce((n, { _count }) => n + _count, 0)).toFixed(2) + const fix = find != "100.00" ? find.substr(-2, 2) == "00" ? find.substr(0, 2) : find : "100" + input = { + text: fix + '%', + value: fix, + color: dataStatus[index].color + } + } else { + input = { + text: '0%', + value: 0, + color: dataStatus[index].color + } + } + hasil.push(input) + } + + allData = hasil + + + } else if (kategori == "dokumen") { + let kondisi + + // klo perbekel/developer == semua grup + if (roleUser == "supadmin" || roleUser == "developer") { + kondisi = { + isActive: true, + category: 'FILE', + Division: { + isActive: true, + idVillage: idVillage, + Group: { + isActive: true, + } + } + } + } else if (roleUser == "admin" || roleUser == "cosupadmin") { + kondisi = { + isActive: true, + category: 'FILE', + Division: { + isActive: true, + idGroup: idGroup + } + } + } else { + kondisi = { + isActive: true, + category: 'FILE', + Division: { + isActive: true, + DivisionMember: { + some: { + idUser: user.id + } + } + } + } + } + + const data = await prisma.divisionDocumentFolderFile.findMany({ + where: kondisi, + }) + + const groupData = _.map(_.groupBy(data, "extension"), (v: any) => ({ + file: v[0].extension, + jumlah: v.length, + })) + + const image = ['jpg', 'jpeg', 'png', 'heic'] + + + let hasilImage = { + label: 'Gambar', + value: 0, + color: '#fac858' + } + + let hasilFile = { + label: 'Dokumen', + value: 0, + color: '#92cc76' + } + + groupData.map((v: any) => { + if (image.some((i: any) => i == v.file)) { + hasilImage = { + label: 'Gambar', + value: hasilImage.value + v.jumlah, + color: '#fac858' + } + } else { + hasilFile = { + label: 'Dokumen', + value: hasilFile.value + v.jumlah, + color: '#92cc76' + } + } + }) + + allData = [hasilImage, hasilFile] + + } else if (kategori == "event") { + let kondisi + + // klo perbekel/developer == semua grup + if (roleUser == "supadmin" || roleUser == "developer") { + kondisi = { + isActive: true, + dateStart: new Date(), + Division: { + isActive: true, + idVillage: idVillage, + Group: { + isActive: true, + } + }, + DivisionCalendar: { + isActive: true + }, + } + } else { + kondisi = { + isActive: true, + dateStart: new Date(), + Division: { + isActive: true, + idGroup: idGroup + }, + DivisionCalendar: { + isActive: true + }, + } + } + + + const data = await prisma.divisionCalendarReminder.findMany({ + skip: 0, + take: 5, + where: kondisi, + select: { + id: true, + idCalendar: true, + timeStart: true, + dateStart: true, + timeEnd: true, + dateEnd: true, + createdAt: true, + status: true, + idDivision: true, + DivisionCalendar: { + select: { + title: true, + desc: true, + User: { + select: { + name: true + } + } + } + } + }, + orderBy: [ + { + dateStart: 'asc' + }, + { + timeStart: 'asc' + }, + { + timeEnd: 'asc' + } + ] + }) + + allData = data.map((v: any) => ({ + ..._.omit(v, ["DivisionCalendar", "User"]), + user_name: v.DivisionCalendar.User.name, + title: v.DivisionCalendar.title, + timeStart: moment.utc(v.timeStart).format('HH:mm'), + timeEnd: moment.utc(v.timeEnd).format('HH:mm') + })) + + } else if (kategori == "discussion") { + let kondisi + + // klo perbekel/developer == semua grup + if (roleUser == "supadmin" || roleUser == "developer") { + kondisi = { + isActive: true, + status: 1, + Division: { + isActive: true, + idVillage: idVillage, + Group: { + isActive: true, + } + } + } + } else if (roleUser == "admin" || roleUser == "cosupadmin") { + kondisi = { + isActive: true, + status: 1, + Division: { + idGroup: idGroup, + isActive: true + } + } + } else { + kondisi = { + isActive: true, + status: 1, + Division: { + isActive: true, + DivisionMember: { + some: { + idUser: user.id + } + } + } + } + } + + const data = await prisma.divisionDisscussion.findMany({ + skip: 0, + take: 5, + where: kondisi, + select: { + id: true, + idDivision: true, + title: true, + desc: true, + createdAt: true, + User: { + select: { + name: true + } + } + }, + orderBy: { + createdAt: "desc" + } + }) + + allData = data.map((v: any) => ({ + ..._.omit(v, ["createdAt", "User"]), + date: moment(v.createdAt).format("ll"), + user: v.User.name + })) + } else if (kategori == "header") { + const total = await prisma.notifications.count({ + where: { + isActive: true, + isRead: false, + idUserTo: user.id + } + }) + + const desa = await prisma.village.findUnique({ + where: { + id: idVillage + } + }) + + allData = { + totalNotif: total, + village: desa?.name + } + } else if (kategori == "check-late-project") { + const supadmin = await prisma.user.findFirst({ + where: { + idUserRole: "supadmin", + idVillage: idVillage + } + }) + + const dataUmum = await prisma.projectTask.findMany({ + where: { + Project: { + idVillage: idVillage, + isActive: true, + status: { + not: { + in: [2, 3] + } + } + }, + notifikasi: false, + isActive: true, + status: 0, + dateEnd: { + lt: new Date() + } + }, + select: { + id: true, + title: true, + dateEnd: true, + Project: { + select: { + id: true, + }, + } + } + }) + + + for (let index = 0; index < dataUmum.length; index++) { + await prisma.projectTask.update({ + where: { + id: dataUmum[index].id + }, + data: { + notifikasi: true + } + }) + } + + const pertama = dataUmum.map((v: any) => ({ + ..._.omit(v, ["Project", "title", "id", "dateEnd"]), + idUserTo: String(supadmin?.id), + idUserFrom: String(user.id), + category: 'project', + idContent: v.Project.id, + title: `Tugas ${v.title} Telah Melewati Batas Waktu`, + desc: `Tugas dengan deadline ${moment(v.dateEnd).format('DD-MM-yyyy')} telah berakhir. Silakan segera melakukan tindakan yang diperlukan.` + })) + + const insertNotif = await prisma.notifications.createMany({ + data: pertama + }) + + const dataDivisi = await prisma.divisionProjectTask.findMany({ + where: { + Division: { + idVillage: idVillage, + isActive: true + }, + DivisionProject: { + isActive: true, + status: { + not: { + in: [2, 3] + } + } + }, + notifikasi: false, + isActive: true, + status: 0, + dateEnd: { + lt: new Date() + } + }, + select: { + id: true, + title: true, + dateEnd: true, + DivisionProject: { + select: { + id: true, + idDivision: true + }, + } + } + }) + + for (let index = 0; index < dataDivisi.length; index++) { + await prisma.divisionProjectTask.update({ + where: { + id: dataDivisi[index].id + }, + data: { + notifikasi: true + } + }) + } + + const kedua = dataDivisi.map((v: any) => ({ + ..._.omit(v, ["DivisionProject", "title", "id", "dateEnd"]), + idUserTo: String(supadmin?.id), + idUserFrom: String(user.id), + category: 'division/' + v.DivisionProject.idDivision + '/task', + idContent: v.DivisionProject.id, + title: `Tugas ${v.title} Telah Melewati Batas Waktu`, + desc: `Tugas dengan deadline ${moment(v.dateEnd).format('DD-MM-yyyy')} telah berakhir. Silakan segera melakukan tindakan yang diperlukan.` + })) + + const insertNotif2 = await prisma.notifications.createMany({ + data: kedua + }) + + + const merge = [...pertama, ...kedua] + + allData = merge + + } + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan data", data: allData }, { 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 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/home/search/route.ts b/src/app/api/mobile/home/search/route.ts new file mode 100644 index 0000000..5caacb6 --- /dev/null +++ b/src/app/api/mobile/home/search/route.ts @@ -0,0 +1,170 @@ +import { prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import _ from "lodash"; +import { NextResponse } from "next/server"; + +// SEARCH USER, DIVISION, PROJECT +export async function GET(request: Request) { + try { + const { searchParams } = new URL(request.url) + const search = searchParams.get("search") + const userMobile = searchParams.get("user") + + if (userMobile == "null" || userMobile == undefined || userMobile == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const userId = await funGetUserById({ id: userMobile }) + + let kondisi: any, kondisiProject: any, kondisiDivision: any + + // klo perbekel/developer == semua grup + if (userId.idUserRole == "supadmin" || userId.idUserRole == "developer") { + kondisi = { + isActive: true, + idVillage: userId.idVillage, + Group: { + isActive: true, + }, + name: { + contains: (search == undefined || search == null) ? "" : search, + mode: "insensitive" + }, + NOT: { + idUserRole: "developer" + } + } + + kondisiDivision = { + isActive: true, + idVillage: userId.idVillage, + Group: { + isActive: true, + }, + name: { + contains: (search == undefined || search == null) ? "" : search, + mode: "insensitive" + } + } + + kondisiProject = { + isActive: true, + idVillage: userId.idVillage, + Group: { + isActive: true, + }, + title: { + contains: (search == undefined || search == null) ? "" : search, + mode: "insensitive" + } + } + } else { + kondisi = { + idVillage: userId.idVillage, + isActive: true, + idGroup: userId.idGroup, + name: { + contains: (search == undefined || search == null) ? "" : search, + mode: "insensitive" + }, + NOT: { + idUserRole: "developer" + } + } + + kondisiDivision = { + idVillage: userId.idVillage, + isActive: true, + idGroup: userId.idGroup, + name: { + contains: (search == undefined || search == null) ? "" : search, + mode: "insensitive" + } + } + + kondisiProject = { + idVillage: userId.idVillage, + isActive: true, + idGroup: userId.idGroup, + title: { + contains: (search == undefined || search == null) ? "" : search, + mode: "insensitive" + } + } + } + + const user = await prisma.user.findMany({ + where: kondisi, + select: { + id: true, + name: true, + email: true, + img: true, + Position: { + select: { + name: true + } + }, + Group: { + select: { + name: true + } + } + } + }) + + const userOmit = user.map((v: any) => ({ + ..._.omit(v, ["Position", "Group"]), + position: v.Position?.name, + group: v.Group.name + })) + + const divisions = await prisma.division.findMany({ + where: kondisiDivision, + select: { + id: true, + name: true, + desc: true, + Group: { + select: { + name: true + } + } + } + }) + + const divisionOmit = divisions.map((v: any) => ({ + ..._.omit(v, ["Group"]), + group: v.Group.name + })) + + const projects = await prisma.project.findMany({ + where: kondisiProject, + select: { + id: true, + title: true, + Group: { + select: { + name: true + } + } + } + }) + + const projectOmit = projects.map((v: any) => ({ + ..._.omit(v, ["Group"]), + group: v.Group.name + })) + + const allDataSearch = { + user: userOmit, + division: divisionOmit, + project: projectOmit + } + return NextResponse.json({ success: true, data: allDataSearch }, { status: 200 }); + + } catch (error) { + console.error(error) + return NextResponse.json({ success: false, message: 'Gagal mendapatkan data, coba lagi nanti (error: 500)' }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/mobile/user/[id]/route.ts b/src/app/api/mobile/user/[id]/route.ts new file mode 100644 index 0000000..8ff8e71 --- /dev/null +++ b/src/app/api/mobile/user/[id]/route.ts @@ -0,0 +1,250 @@ +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"; +import sharp from "sharp"; + +// GET ONE MEMBER / USER +export async function GET(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params; + + const users = await prisma.user.findUnique({ + where: { + id: id, + }, + select: { + id: true, + nik: true, + name: true, + phone: true, + email: true, + gender: true, + img: true, + idGroup: true, + isActive: true, + idPosition: true, + UserRole: { + select: { + name: true, + id: true + } + }, + Position: { + select: { + name: true, + id: true + }, + }, + Group: { + select: { + name: true, + id: true + }, + }, + }, + }); + + const { ...userData } = users; + const group = users?.Group.name + const position = users?.Position?.name + const idUserRole = users?.UserRole.id + const phone = users?.phone.substr(2) + const role = users?.UserRole.name + + const result = { ...userData, group, position, idUserRole, phone, role }; + + const omitData = _.omit(result, ["Group", "Position", "UserRole"]); + + + + return NextResponse.json( + { + success: true, + message: "Berhasil mendapatkan anggota", + data: omitData, + }, + { status: 200 } + ); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan anggota, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// DELETE / ACTIVE & NON ACTIVE MEMBER / USER +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 { isActive } = (await request.json()); + const data = await prisma.user.count({ + where: { + id: id, + }, + }); + + if (data == 0) { + return NextResponse.json( + { + success: false, + message: "Gagal mendapatkan anggota, data tidak ditemukan", + }, + { status: 404 } + ); + } + + const result = await prisma.user.update({ + where: { + id: id, + }, + data: { + isActive: !isActive, + }, + select: { + id: true, + idGroup: true, + }, + }); + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate status anggota', table: 'user', data: id }) + + return NextResponse.json( + { + success: true, + message: "Berhasil mengupdate status anggota", + data: result, + }, + { status: 200 } + ); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupdate status anggota, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// UPDATE MEMBER +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 data = body.get("data") + const { + name, + email, + phone, + nik, + gender, + idGroup, + idPosition, + idUserRole + } = JSON.parse(data as string) + + const cekNIK = await prisma.user.count({ + where: { + nik: nik, + NOT: { + id: id + } + }, + }); + + const cekEmail = await prisma.user.count({ + where: { + email: email, + NOT: { + id: id + } + }, + }); + + const cekPhone = await prisma.user.count({ + where: { + phone: "62" + phone, + NOT: { + id: id + } + }, + }); + + if (cekNIK == 0 && cekEmail == 0 && cekPhone == 0) { + const updates = await prisma.user.update({ + where: { + id: id + }, + data: { + nik: nik, + name: name, + phone: "62" + phone, + email: email, + gender: gender, + idGroup: idGroup, + idPosition: idPosition, + idUserRole: idUserRole, + }, + select: { + img: true + } + }); + + if (String(file) != "undefined" && String(file) != "null") { + const fExt = file.name.split(".").pop() + const fileName = id + '.' + fExt; + + // Resize ukuran + const imageBuffer = await file.arrayBuffer(); + const resize = await sharp(imageBuffer).resize(300).toBuffer(); + + // Convert buffer ke Blob + const blob = new Blob([resize], { type: file.type }); + + // Convert Blob ke File + const resizedFile = new File([blob], fileName, { + type: file.type, + lastModified: new Date().getTime(), + }); + + // const newFile = new File([file], fileName, { type: file.type }); + + await funDeleteFile({ fileId: String(updates.img) }) + const upload = await funUploadFile({ file: resizedFile, dirId: DIR.user }) + await prisma.user.update({ + where: { + id: id + }, + data: { + img: upload.data.id + } + }) + } + + // create log user + const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data anggota', table: 'user', data: user.id }) + + return Response.json( + { success: true, message: "Sukses update anggota" }, + { status: 200 } + ); + } else { + return Response.json({ success: false, message: "Anggota sudah ada" }, { status: 400 }); + } + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mengupdate data anggota, 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/user/profile/route.ts b/src/app/api/mobile/user/profile/route.ts new file mode 100644 index 0000000..515a6c8 --- /dev/null +++ b/src/app/api/mobile/user/profile/route.ts @@ -0,0 +1,168 @@ +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"; +import sharp from "sharp"; + + +// GET PROFILE BY COOKIES +export async function GET(request: Request) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + const data = await prisma.user.findUnique({ + where: { + id: user.id + }, + select: { + id: true, + idUserRole: true, + name: true, + email: true, + phone: true, + nik: true, + gender: true, + idGroup: true, + idPosition: true, + img: true, + Group: { + select: { + name: true + } + }, + Position: { + select: { + name: true + } + }, + UserRole:{ + select:{ + name: true + } + } + } + }) + const { ...userData } = data; + const group = data?.Group.name + const position = data?.Position?.name + const phone = data?.phone.substr(2) + const role = data?.UserRole.name + + const omitData = _.omit(data, ["Group", "Position", "phone", "UserRole"]); + + const result = { ...userData, group, position, phone, role }; + + return NextResponse.json({ success: true, data: result }); + } catch (error) { + return NextResponse.json({ success: false, message: "Gagal mendapatkan data profile (error: 500)" }, { status: 500 }); + } + +} + +// UPDATE PROFILE BY COOKIES +export async function PUT(request: Request) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + const body = await request.formData() + const file = body.get("file") as File; + const data = body.get("data"); + + const { name, email, phone, nik, gender, idPosition } = JSON.parse(data as string) + + const cekNIK = await prisma.user.count({ + where: { + nik: nik, + NOT: { + id: user.id + } + }, + }); + + const cekEmail = await prisma.user.count({ + where: { + email: email, + NOT: { + id: user.id + } + }, + }); + + const cekPhone = await prisma.user.count({ + where: { + phone: "62" + phone, + NOT: { + id: user.id + } + }, + }); + + if (cekNIK > 0 || cekEmail > 0 || cekPhone > 0) { + return NextResponse.json({ success: false, message: "Gagal ubah profile, NIK/email/phone sudah terdaftar" }, { status: 401 }); + } + + const update = await prisma.user.update({ + where: { + id: user.id + }, + data: { + name: name, + email: email, + phone: "62" + phone, + nik: nik, + gender: gender, + idPosition: idPosition + }, + select: { + img: true + } + }) + + if (String(file) != "undefined" && String(file) != "null") { + const fExt = file.name.split(".").pop() + const fileName = user.id + '.' + fExt; + + // Resize ukuran + const imageBuffer = await file.arrayBuffer(); + const resize = await sharp(imageBuffer).resize(300).toBuffer(); + + // Convert buffer ke Blob + const blob = new Blob([resize], { type: file.type }); + + // Convert Blob ke File + const resizedFile = new File([blob], fileName, { + type: file.type, + lastModified: new Date().getTime(), + }); + + // const newFile = new File([file], fileName, { type: file.type }); + + await funDeleteFile({ fileId: String(update.img) }) + const upload = await funUploadFile({ file: resizedFile, dirId: DIR.user }) + if (upload.success) { + await prisma.user.update({ + where: { + id: user.id + }, + data: { + img: upload.data.id + } + }) + } + + } + + const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data profile', table: 'user', data: user.id }) + + return NextResponse.json({ success: true, message: "Berhasil ubah profile" }); + } catch (error) { + return NextResponse.json({ success: false, message: "Gagal mengubah profile (error: 500)" }, { status: 500 }); + } +} + diff --git a/src/app/api/mobile/user/route.ts b/src/app/api/mobile/user/route.ts new file mode 100644 index 0000000..fd9323f --- /dev/null +++ b/src/app/api/mobile/user/route.ts @@ -0,0 +1,245 @@ +import { DIR, funUploadFile, prisma } from "@/module/_global"; +import { funGetUserByCookies } from "@/module/auth"; +import { createLogUser } from "@/module/user"; +import _ from "lodash"; +import { NextResponse } from "next/server"; +import sharp from "sharp"; + +// GET ALL MEMBER / USER +export async function GET(request: Request) { + try { + let fixGroup + const { searchParams } = new URL(request.url); + const name = searchParams.get('search') + const idGroup = searchParams.get("group"); + const active = searchParams.get("active"); + const page = searchParams.get('page'); + const dataSkip = Number(page) * 10 - 10; + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + + if (idGroup == "null" || idGroup == undefined || idGroup == "") { + fixGroup = user.idGroup + } else { + fixGroup = idGroup + } + + const filter = await prisma.group.findUnique({ + where: { + id: fixGroup + }, + select: { + id: true, + name: true + } + }) + + + if (page != undefined) { + const users = await prisma.user.findMany({ + skip: dataSkip, + take: 10, + where: { + isActive: active == 'false' ? false : true, + idGroup: String(fixGroup), + name: { + contains: (name == undefined || name == null) ? "" : name, + mode: "insensitive", + }, + NOT: { + idUserRole: 'developer' + } + }, + select: { + id: true, + idUserRole: true, + isActive: true, + nik: true, + name: true, + phone: true, + email: true, + gender: true, + img: true, + Position: { + select: { + name: true, + }, + }, + Group: { + select: { + name: true, + }, + }, + }, + orderBy: { + name: 'asc' + } + }); + + const allData = users.map((v: any) => ({ + ..._.omit(v, ["Group", "Position"]), + group: v.Group.name, + position: v?.Position?.name + })) + + return NextResponse.json({ success: true, message: "Berhasil member", data: allData, filter }, { status: 200 }); + } else { + const users = await prisma.user.findMany({ + where: { + isActive: active == 'false' ? false : true, + idGroup: String(fixGroup), + name: { + contains: (name == undefined || name == null) ? "" : name, + mode: "insensitive", + }, + NOT: { + idUserRole: 'developer' + } + }, + select: { + id: true, + idUserRole: true, + isActive: true, + nik: true, + name: true, + phone: true, + email: true, + gender: true, + img: true, + Position: { + select: { + name: true, + }, + }, + Group: { + select: { + name: true, + }, + }, + }, + orderBy: { + name: 'asc' + } + }); + + const allData = users.map((v: any) => ({ + ..._.omit(v, ["Group", "Position"]), + group: v.Group.name, + position: v?.Position?.name + })) + + return NextResponse.json({ success: true, message: "Berhasil member", data: allData, filter }, { status: 200 }); + } + + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal mendapatkan anggota, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + + +// CREATE MEMBER / USER +export async function POST(request: Request) { + try { + const user = await funGetUserByCookies() + if (user.id == undefined) { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + } + const body = await request.formData() + const data = JSON.parse(body.get("data") as string) + const file = body.get("file") as File + const village = String(user.idVillage) + + let groupFix = data.idGroup + + if (groupFix == null || groupFix == undefined || groupFix == "") { + groupFix = user.idGroup + } + + const cekNIK = await prisma.user.count({ + where: { + nik: data.nik + }, + }); + + const cekEmail = await prisma.user.count({ + where: { + email: data.email + }, + }); + + const cekPhone = await prisma.user.count({ + where: { + phone: "62" + data.phone + }, + }); + + + if (cekNIK == 0 && cekEmail == 0 && cekPhone == 0) { + const users = await prisma.user.create({ + data: { + nik: data.nik, + name: data.name, + phone: "62" + data.phone, + email: data.email, + gender: data.gender, + idGroup: groupFix, + idVillage: village, + idPosition: data.idPosition, + idUserRole: data.idUserRole, + }, + select: { + id: true, + idGroup: true, + }, + }); + + if (String(file) != "undefined" && String(file) != "null") { + + const fExt = file.name.split(".").pop() + const fileName = user.id + '.' + fExt; + + // Resize ukuran + const imageBuffer = await file.arrayBuffer(); + const resize = await sharp(imageBuffer).resize(300).toBuffer(); + + // Convert buffer ke Blob + const blob = new Blob([resize], { type: file.type }); + + // Convert Blob ke File + const resizedFile = new File([blob], fileName, { + type: file.type, + lastModified: new Date().getTime(), + }); + + // const newFile = new File([file], fileName, { type: file.type }); + + const upload = await funUploadFile({ file: resizedFile, dirId: DIR.user }) + if (upload.success) { + await prisma.user.update({ + where: { + id: users.id + }, + data: { + img: upload.data.id + } + }) + } + } + + // create log user + const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data user baru', table: 'user', data: users.id }) + + return Response.json({ success: true, message: 'Sukses membuat user', data: users }, { status: 200 }); + } else { + return Response.json({ success: false, message: "User sudah ada" }, { status: 400 }); + } + + } catch (error) { + console.error(error); + return Response.json({ success: false, message: "Gagal membuat anggota, coba lagi nanti (error: 500)" }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/version-app/route.ts b/src/app/api/version-app/route.ts index 04e7db2..0d7576f 100644 --- a/src/app/api/version-app/route.ts +++ b/src/app/api/version-app/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export async function GET(request: Request) { try { - return NextResponse.json({ success: true, version: "1.4.1", tahap: "beta", update: "- user role developer; -pencarian minimal 3 karakter; -fitur baca semua notifikasi disable saat tidak ada notifikasi yg blm dibaca; -fix: route back diskusi general tambah member" }, { status: 200 }); + return NextResponse.json({ success: true, version: "1.4.2", tahap: "beta", update: "- user role developer; -pencarian minimal 3 karakter; -fitur baca semua notifikasi disable saat tidak ada notifikasi yg blm dibaca; -fix: route back diskusi general tambah member; -fix:api search error" }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); diff --git a/src/module/auth/api/funGetUserById.ts b/src/module/auth/api/funGetUserById.ts new file mode 100644 index 0000000..83704e6 --- /dev/null +++ b/src/module/auth/api/funGetUserById.ts @@ -0,0 +1,33 @@ +'use server' +import { prisma } from "@/module/_global"; + +export default async function funGetUserById({ id }: { id: string }) { + const user = await prisma.user.findUnique({ + where: { + id: id + }, + }); + + const village = await prisma.village.findUnique({ + where: { + id: user?.idVillage + } + }) + + const warna = await prisma.colorTheme.findUnique({ + where: { + id: String(village?.idTheme) + } + }) + + return { + id: user?.id, + idUserRole: user?.idUserRole, + name: user?.name, + idVillage: user?.idVillage, + idGroup: user?.idGroup, + idPosition: user?.idPosition, + theme: warna, + } + +} \ No newline at end of file diff --git a/src/module/auth/index.ts b/src/module/auth/index.ts index 228515f..1669193 100644 --- a/src/module/auth/index.ts +++ b/src/module/auth/index.ts @@ -1,13 +1,9 @@ import funDetectCookies from "./api/funDetectCookies"; import funGetUserByCookies from "./api/funGetUserByCookies"; +import funGetUserById from "./api/funGetUserById"; import funSetCookies from "./api/funSetCookies"; import ViewLogin from "./login/view/view_login"; import ViewVerification from "./varification/view/view_verification"; import { ViewWelcome } from "./welcome/view_welcome"; -export { ViewLogin } -export { ViewVerification } -export { ViewWelcome } -export { funSetCookies } -export { funDetectCookies } -export { funGetUserByCookies } \ No newline at end of file +export { funDetectCookies, funGetUserByCookies, funGetUserById, funSetCookies, ViewLogin, ViewVerification, ViewWelcome };