Merge pull request #228 from bipproduction/lukman/13-september-2024

Lukman/13 september 2024
This commit is contained in:
Amalia
2024-09-13 13:54:53 +08:00
committed by GitHub
442 changed files with 34895 additions and 3245 deletions

7
.env
View File

@@ -1,7 +0,0 @@
# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
DATABASE_URL="postgresql://bip:Production_123d@localhost:5433/sistem_desa_mandiri?schema=public"

4
.gitignore vendored
View File

@@ -37,3 +37,7 @@ yarn-error.log*
# typescript
*.tsbuildinfo
next-env.d.ts
# folder foto kandidat
/public/image/
/public/file/

262
api.http Normal file
View File

@@ -0,0 +1,262 @@
###
POST http://localhost:3000/api/auth/login/ HTTP/1.1
Content-Type: application/json
{
"phone": "6287701790942"
}
// GROUP
###
GET http://localhost:3000/api/group/get?path=get-all-group&villageId=121212&active=true HTTP/1.1
###
POST http://localhost:3000/api/group/post?path=create-group HTTP/1.1
Content-Type: application/json
{
"name": "LPD 3",
"idVillage": "121212"
}
###
POST http://localhost:3000/api/group/post?path=update-group HTTP/1.1
Content-Type: application/json
{
"id": "1",
"name": "LPD2",
"idVillage": "121212"
}
###
POST http://localhost:3000/api/group/post?path=delete-group HTTP/1.1
Content-Type: application/json
{
"id": "1",
"idVillage": "121212"
}
###
GET http://localhost:3000/api/group/get?path=get-one-group&groupId=3 HTTP/1.1
// VILLAGE
###
GET http://localhost:3000/api/village/get?path=get-all-village HTTP/1.1
###
GET http://localhost:3000/api/village/get?path=get-one-village HTTP/1.1
###
POST http://localhost:3000/api/village/post?path=create-village HTTP/1.1
Content-Type: application/json
{
"name": "nama satu satu ",
"desc": "description data"
}
###
POST http://localhost:3000/api/village/post?path=update-village HTTP/1.1
Content-Type: application/json
{
"id": "11",
"name": "nama satu new",
"desc": "description data new"
}
###
POST http://localhost:3000/api/village/post?path=delete-village HTTP/1.1
Content-Type: application/json
{
"id": "11"
}
// POSITION
###
GET http://localhost:3000/api/position/get?path=get-all-position&groupID=2 HTTP/1.1
###
GET http://localhost:3000/api/position/get?path=get-one-position&positionId=clz24bff70001w01in64dd9ea HTTP/1.1
###
POST http://localhost:3000/api/position/post?path=create-position HTTP/1.1
Content-Type: application/json
{
"name": "Anggota",
"idGroup": "1"
}
###
POST http://localhost:3000/api/position/post?path=update-position HTTP/1.1
Content-Type: application/json
{
"id": "1",
"name": "Wakil Sekertaris",
"idGroup": "2"
}
###
POST http://localhost:3000/api/position/post?path=delete-position HTTP/1.1
Content-Type: application/json
{
"id": "1"
}
// USERS
###
GET http://localhost:3000/api/user/get?path=get-all-users&active=true HTTP/1.1
###
GET http://localhost:3000/api/user/get?path=get-one-users&userID=devAmalia HTTP/1.1
###
POST http://localhost:3000/api/user/post?path=create-users HTTP/1.1
Content-Type: application/json
{
"idUserRole": "user",
"idVillage": "121212",
"idGroup": "2",
"idPosition": "clz24bff70001w01in64dd9ea",
"nik": "53239236727329",
"name": "coba user",
"email": "cobauser@gmail.com",
"phone": "07319031009",
"gender": "M"
}
###
POST http://localhost:3000/api/user/post?path=update-users HTTP/1.1
Content-Type: application/json
{
"id": "clz6dq88e0001b3mlyl4vjaf8",
"idUserRole": "user",
"idVillage": "121212",
"idGroup": "2",
"idPosition": "clz24bff70001w01in64dd9ea",
"nik": "53239236727329",
"name": "coba user edit",
"email": "cobauser@gmail.com",
"phone": "07319031009",
"gender": "M"
}
###
POST http://localhost:3000/api/user/post?path=delete-users HTTP/1.1
Content-Type: application/json
{
"id": "clz6dq88e0001b3mlyl4vjaf8"
}
// Announcement
###
POST http://localhost:3000/api/announcement/post?path=create-announcement HTTP/1.1
Content-Type: application/json
{
"title": "cobaannouncement1 dsdsd",
"desc": "coba announcement sdsdsd",
"idVillage": "desa1",
"createBy": "superAdminLukman",
"groups": [
{
"idGroup": "group1",
"idDivision": "1"
},
]
}
###
GET http://localhost:3000/api/announcement/get?path=get-all-announcement HTTP/1.1
###
GET http://localhost:3000/api/announcement/get?path=get-user-announcement HTTP/1.1
###
GET http://localhost:3000/api/announcement/get?path=get-all-announcement&divisionI=1 HTTP/1.1
###
GET http://localhost:3000/api/announcement/get?path=get-one-announcement&announcementId=1 HTTP/1.1
###
POST http://localhost:3000/api/announcement/post?path=update-announcement HTTP/1.1
Content-Type: application/json
{
"id": "clz6kqzvt000eb3mle1nyz6fd",
"title": "cobaannouncement coba coba",
"desc": "coba announcement coba coba",
"idVillage": "121212",
"createBy": "clz6dq88e0001b3mlyl4vjaf8",
"groups": [
{
"idGroup": "1",
"idDivision": "1"
},
{
"idGroup": "1",
"idDivision": "2"
}
]
}
###
POST http://localhost:3000/api/announcement/post?path=delete-announcement HTTP/1.1
Content-Type: application/json
{
"id": "clz6naf9s000ib3mlf5aujk92"
}
###
POST http://localhost:3000/api/announcement HTTP/1.1
Content-Type: application/json
{
"title": "test",
"desc": "test",
"groups":
[
{
"idAnnouncement": "1",
"idGroup": "group1",
"idDivision": "1",
"isActive": true
},
{
"idAnnouncement": "1",
"idGroup": "group1",
"idDivision": "clzknx2xy0001bt0wygcwjfph",
"isActive": true
}
]
}
###
DELETE http://localhost:3000/api/discussion/clzs6b7kb0001aw16g5clh5vw HTTP/1.1
Content-Type: application/json
{
"status":1
}

View File

@@ -1,4 +1,8 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};
const nextConfig = {
devIndicators: {
buildActivityPosition: 'bottom-right',
},
};
export default nextConfig;

View File

@@ -9,20 +9,21 @@
"lint": "next lint"
},
"prisma": {
"seed": "tsx prisma/seed.ts"
"seed": "npx tsx prisma/seed.ts"
},
"dependencies": {
"@hookstate/core": "^4.0.1",
"@hookstate/localstored": "^4.0.2",
"@mantine/carousel": "^7.11.1",
"@mantine/charts": "^7.11.0",
"@mantine/code-highlight": "^7.11.0",
"@mantine/core": "^7.11.0",
"@mantine/dates": "^7.11.0",
"@mantine/dropzone": "^7.11.0",
"@mantine/dates": "^7.11.1",
"@mantine/dropzone": "^7.12.1",
"@mantine/form": "^7.11.0",
"@mantine/hooks": "^7.11.0",
"@mantine/modals": "^7.11.0",
"@mantine/notifications": "^7.11.0",
"@mantine/notifications": "^7.12.2",
"@mantine/nprogress": "^7.11.0",
"@mantine/spotlight": "^7.11.0",
"@mantine/tiptap": "^7.11.0",
@@ -33,15 +34,25 @@
"@tiptap/starter-kit": "^2.4.0",
"@types/lodash": "^4.17.6",
"dayjs": "^1.11.11",
"echarts": "^5.5.1",
"echarts-for-react": "^3.0.2",
"embla-carousel-autoplay": "^7.1.0",
"embla-carousel-react": "^7.1.0",
"iron-session": "^8.0.2",
"lodash": "^4.17.21",
"moment": "^2.30.1",
"next": "14.2.4",
"pdfjs-dist": "^4.6.82",
"prettier": "^3.3.2",
"react": "^18",
"react-dom": "^18",
"react-hot-toast": "^2.4.1",
"react-icons": "^5.2.1",
"recharts": "2"
"react-simple-toasts": "^5.10.0",
"readdirp": "^3.6.0",
"recharts": "2",
"rrule": "^2.8.1",
"yargs": "^17.7.2"
},
"devDependencies": {
"@types/node": "^20.14.9",

View File

@@ -13,6 +13,28 @@ datasource db {
url = env("DATABASE_URL")
}
model AdminRole {
id String @id @default(cuid())
name String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Admin Admin[]
}
model Admin {
id String @id @default(cuid())
AdminRole AdminRole @relation(fields: [idAdminRole], references: [id])
idAdminRole String
name String
phone String @unique
email String? @unique
gender String @default("M") //M= Male, F= Female
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model UserRole {
id String @id @default(cuid())
name String
@@ -24,32 +46,34 @@ model UserRole {
}
model Village {
id String @id @default(cuid())
name String
desc String @db.Text
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Group Group[]
User User[]
Annoucement Annoucement[]
Project Project[]
Division Division[]
id String @id @default(cuid())
idTheme String?
name String
desc String @db.Text
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Group Group[]
User User[]
Announcement Announcement[]
Project Project[]
Division Division[]
ColorTheme ColorTheme[]
}
model Group {
id String @id @default(cuid())
Village Village @relation(fields: [idVillage], references: [id])
idVillage String
name String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Position Position[]
User User[]
Project Project[]
Division Division[]
AnnoucementMember AnnoucementMember[]
id String @id @default(cuid())
Village Village @relation(fields: [idVillage], references: [id])
idVillage String
name String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Position Position[]
User User[]
Project Project[]
Division Division[]
AnnouncementMember AnnouncementMember[]
}
model Position {
@@ -67,21 +91,23 @@ model User {
id String @id @default(cuid())
UserRole UserRole @relation(fields: [idUserRole], references: [id])
idUserRole String
Village Village? @relation(fields: [idVillage], references: [id])
idVillage String?
Group Group? @relation(fields: [idGroup], references: [id])
idGroup String?
Position Position? @relation(fields: [idPosition], references: [id])
idPosition String?
Village Village @relation(fields: [idVillage], references: [id])
idVillage String
Group Group @relation(fields: [idGroup], references: [id])
idGroup String
Position Position @relation(fields: [idPosition], references: [id])
idPosition String
nik String @unique
name String
phone String @unique
email String? @unique
gender String @default("M") //M= Male, F= Female
img String?
isFirstLogin Boolean @default(true)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
Annoucement Annoucement[]
Announcement Announcement[]
Project Project[]
ProjectMember ProjectMember[]
ProjectComment ProjectComment[]
@@ -94,6 +120,7 @@ model User {
DivisionDisscussionComment DivisionDisscussionComment[]
DivisionDocumentFolderFile DivisionDocumentFolderFile[]
DivisionCalendar DivisionCalendar[]
DivisionCalendarMember DivisionCalendarMember[]
}
model UserLog {
@@ -109,31 +136,31 @@ model UserLog {
updatedAt DateTime @updatedAt
}
model Annoucement {
id String @id @default(cuid())
Village Village @relation(fields: [idVillage], references: [id])
idVillage String
title String
desc String @db.Text
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
AnnoucementMember AnnoucementMember[]
model Announcement {
id String @id @default(cuid())
Village Village @relation(fields: [idVillage], references: [id])
idVillage String
title String
desc String @db.Text
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
AnnouncementMember AnnouncementMember[]
}
model AnnoucementMember {
id String @id @default(cuid())
Annoucement Annoucement @relation(fields: [idAnnoucement], references: [id])
idAnnoucement String
Group Group @relation(fields: [idGroup], references: [id])
idGroup String
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
model AnnouncementMember {
id String @id @default(cuid())
Announcement Announcement @relation(fields: [idAnnouncement], references: [id])
idAnnouncement String
Group Group @relation(fields: [idGroup], references: [id])
idGroup String
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Project {
@@ -142,8 +169,10 @@ model Project {
idVillage String
Group Group @relation(fields: [idGroup], references: [id])
idGroup String
name String
desc String @db.Text
title String
status Int @default(0) // 0 = pending, 1 = ongoing, 2 = done, 3 = cancelled
desc String? @db.Text
reason String? @db.Text
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
@@ -152,6 +181,7 @@ model Project {
ProjectMember ProjectMember[]
ProjectFile ProjectFile[]
ProjectComment ProjectComment[]
ProjectTask ProjectTask[]
}
model ProjectMember {
@@ -172,6 +202,21 @@ model ProjectFile {
idProject String
name String
extension String
idStorage String?
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ProjectTask {
id String @id @default(cuid())
Project Project @relation(fields: [idProject], references: [id])
idProject String
title String
desc String?
status Int @default(0) // 0 = todo, 1 = done
dateStart DateTime @db.Date
dateEnd DateTime @db.Date
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -203,7 +248,7 @@ model Division {
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
DivisionMember DivisionMember[]
AnnoucementMember AnnoucementMember[]
AnnouncementMember AnnouncementMember[]
DivisionProject DivisionProject[]
DivisionProjectTask DivisionProjectTask[]
DivisionProjectMember DivisionProjectMember[]
@@ -213,6 +258,7 @@ model Division {
DivisionDocumentShare DivisionDocumentShare[]
DivisionCalendar DivisionCalendar[]
DivisionCalendarReminder DivisionCalendarReminder[]
ContainerFileDivision ContainerFileDivision[]
}
model DivisionMember {
@@ -229,85 +275,98 @@ model DivisionMember {
}
model DivisionProject {
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
title String
desc String @db.Text
status Int @default(0)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
title String
desc String? @db.Text
reason String? @db.Text
status Int @default(0) // 0 = pending, 1 = ongoing, 2 = done, 3 = cancelled
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
DivisionProjectTask DivisionProjectTask[]
DivisionProjectMember DivisionProjectMember[]
DivisionProjectFile DivisionProjectFile[]
}
model DivisionProjectTask {
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
title String
desc String @db.Text
status Int @default(0)
dateStart DateTime @db.Date
dateEnd DateTime @db.Date
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
DivisionProject DivisionProject @relation(fields: [idProject], references: [id])
idProject String
title String
desc String? @db.Text
status Int @default(0) // 0 = todo, 1 = done
dateStart DateTime @db.Date
dateEnd DateTime @db.Date
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model DivisionProjectMember {
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
User User @relation(fields: [idUser], references: [id])
idUser String
isLeader Boolean @default(false)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
DivisionProject DivisionProject @relation(fields: [idProject], references: [id])
idProject String
User User @relation(fields: [idUser], references: [id])
idUser String
isLeader Boolean @default(false)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model DivisionProjectFile {
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
name String
extension String
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
DivisionProject DivisionProject @relation(fields: [idProject], references: [id])
idProject String
ContainerFileDivision ContainerFileDivision @relation(fields: [idFile], references: [id])
idFile String
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model DivisionDisscussion {
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
title String
desc String @db.Text
status Int @default(1) // 1 = open, 2 = close
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
title String?
desc String @db.Text
status Int @default(1) // 1 = open, 2 = close
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
DivisionDisscussionComment DivisionDisscussionComment[]
}
model DivisionDisscussionComment {
id String @id @default(cuid())
idDisscussion String
comment String @db.Text
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
id String @id @default(cuid())
DivisionDisscussion DivisionDisscussion @relation(fields: [idDisscussion], references: [id])
idDisscussion String
comment String @db.Text
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model DivisionDocumentFolderFile {
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
idStorage String?
category String @default("FOLDER") // FOLDER OR FILE
name String
extension String
@@ -337,16 +396,21 @@ model DivisionCalendar {
idDivision String
title String
desc String @db.Text
linkMeet String? @db.Text
dateStart DateTime @db.Date
dateEnd DateTime @db.Date
repeatEventTyper String
reminderInterval String
dateEnd DateTime? @db.Date
timeStart DateTime @db.Time()
timeEnd DateTime @db.Time()
repeatEventTyper String // once = Acara 1 Kali, weekdays = hari Kerja (senin - jumat), daily=setiap hari , weekly = setiap minggu, monthly = setiap bulan, yearly = setiap tahun
repeatValue Int @default(1)
reminderInterval String?
status Int @default(0)
isActive Boolean @default(true)
User User @relation(fields: [createdBy], references: [id])
createdBy String
createdAt DateTime @default(now())
DivisionCalendarReminder DivisionCalendarReminder[]
DivisionCalendarMember DivisionCalendarMember[]
}
model DivisionCalendarReminder {
@@ -356,9 +420,61 @@ model DivisionCalendarReminder {
DivisionCalendar DivisionCalendar @relation(fields: [idCalendar], references: [id])
idCalendar String
dateStart DateTime @db.Date
dateEnd DateTime @db.Date
dateEnd DateTime? @db.Date
timeStart DateTime @db.Time()
timeEnd DateTime @db.Time()
status Int @default(0)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model DivisionCalendarMember {
id String @id @default(cuid())
DivisionCalendar DivisionCalendar @relation(fields: [idCalendar], references: [id])
idCalendar String
User User @relation(fields: [idUser], references: [id])
idUser String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ContainerImage {
id String @id @default(cuid())
category String
idCategory String
extension String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model ContainerFileDivision {
id String @id @default(cuid())
Division Division @relation(fields: [idDivision], references: [id])
idDivision String
idStorage String?
name String
extension String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
DivisionProjectFile DivisionProjectFile[]
}
model ColorTheme {
id String @id @default(cuid())
Village Village? @relation(fields: [idVillage], references: [id])
idVillage String?
name String
utama String
bgUtama String
bgIcon String
bgFiturHome String
bgFiturDivision String
bgTotalKegiatan String
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}

View File

@@ -1,8 +1,132 @@
import { seederUser, seederUserRole } from '@/module/seeder';
import { seederAdmin, seederAdminRole, seederDesa, seederGroup, seederPosition, seederTheme, seederUser, seederUserRole } from '@/module/seeder';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient()
async function main() {
// ADMIN ROLE
for (let data of seederAdminRole) {
await prisma.adminRole.upsert({
where: {
id: data.id
},
update: {
name: data.name
},
create: {
id: data.id,
name: data.name,
},
})
}
// ADMIN
for (let data of seederAdmin) {
await prisma.admin.upsert({
where: {
id: data.id
},
update: {
name: data.name,
idAdminRole: data.idAdminRole,
phone: data.phone,
email: data.email,
gender: data.gender
},
create: {
id: data.id,
idAdminRole: data.idAdminRole,
phone: data.phone,
email: data.email,
gender: data.gender,
name: data.name
},
})
}
// THEME
for (let data of seederTheme) {
await prisma.colorTheme.upsert({
where: {
id: data.id
},
update: {
name: data.name,
utama: data.utama,
bgUtama: data.bgUtama,
bgIcon: data.bgIcon,
bgFiturHome: data.bgFiturHome,
bgFiturDivision: data.bgFiturDivisi,
bgTotalKegiatan: data.bgTotalKegiatan
},
create: {
id: data.id,
name: data.name,
utama: data.utama,
bgUtama: data.bgUtama,
bgIcon: data.bgIcon,
bgFiturHome: data.bgFiturHome,
bgFiturDivision: data.bgFiturDivisi,
bgTotalKegiatan: data.bgTotalKegiatan
}
})
}
// DESA
for (let data of seederDesa) {
await prisma.village.upsert({
where: {
id: data.id
},
update: {
name: data.name,
desc: data.desc,
idTheme: "theme1"
},
create: {
id: data.id,
name: data.name,
desc: data.desc,
idTheme: "theme1"
}
})
}
// GROUP
for (let data of seederGroup) {
await prisma.group.upsert({
where: {
id: data.id
},
update: {
name: data.name,
idVillage: data.idVillage
},
create: {
id: data.id,
name: data.name,
idVillage: data.idVillage
}
})
}
// POSITION
for (let data of seederPosition) {
await prisma.position.upsert({
where: {
id: data.id
},
update: {
name: data.name,
idGroup: data.idGroup
},
create: {
id: data.id,
name: data.name,
idGroup: data.idGroup
}
})
}
// USER ROLE
for (let data of seederUserRole) {
await prisma.userRole.upsert({
@@ -27,10 +151,21 @@ async function main() {
id: data.id
},
update: {
name: data.name
idVillage: data.idVillage,
idGroup: data.idGroup,
idPosition: data.idPosition,
idUserRole: data.idUserRole,
nik: data.nik,
name: data.name,
// phone: data.phone,
email: data.email,
gender: data.gender
},
create: {
id: data.id,
idVillage: data.idVillage,
idGroup: data.idGroup,
idPosition: data.idPosition,
idUserRole: data.idUserRole,
nik: data.nik,
name: data.name,
@@ -40,6 +175,7 @@ async function main() {
},
})
}
}
main().then(async () => {

View File

@@ -1,8 +1,12 @@
import { ViewDetailAnnouncement } from "@/module/announcement";
import { DetailAnnouncement, NavbarDetailAnnouncement } from "@/module/announcement";
import { Box } from "@mantine/core";
function Page({ params }: { params: { id: string } }) {
return (
<ViewDetailAnnouncement data={params.id} />
<Box>
<NavbarDetailAnnouncement />
<DetailAnnouncement id={params.id} />
</Box>
)
}

View File

@@ -0,0 +1,11 @@
import CreateUsersAnnouncement from '@/module/announcement/ui/create_users_announcement';
import React from 'react';
function Page() {
return (
// <CreateUsersAnnouncement />
<></>
);
}
export default Page;

View File

@@ -1,8 +1,9 @@
import { ViewCreateAnnouncement } from "@/module/announcement";
import { CreateAnnouncement } from "@/module/announcement";
function Page() {
return (
<ViewCreateAnnouncement />
<CreateAnnouncement />
)
}

View File

@@ -1,8 +1,11 @@
import { ViewEditAnnouncement } from "@/module/announcement";
import { EditAnnouncement } from "@/module/announcement";
import { Box } from "@mantine/core";
function Page({ params }: { params: { id: any } }) {
return (
<ViewEditAnnouncement data={params.id} />
<Box>
<EditAnnouncement />
</Box>
)
}

View File

@@ -1,8 +1,15 @@
import { ViewListAnnouncement } from "@/module/announcement";
import { ViewFilter } from "@/module/_global";
import { ListAnnouncement, NavbarAnnouncement } from "@/module/announcement";
import { Box } from "@mantine/core";
function Page() {
function Page({ searchParams }: { searchParams: { page: string } }) {
if (searchParams.page == 'filter')
return <ViewFilter linkFilter="announcement" />
return (
<ViewListAnnouncement/>
<Box>
<NavbarAnnouncement />
<ListAnnouncement />
</Box>
)
}

View File

@@ -0,0 +1,10 @@
import { CreatePaletteColor } from '@/module/color_palette';
import React from 'react';
function Page() {
return (
<CreatePaletteColor />
);
}
export default Page;

View File

@@ -0,0 +1,10 @@
import { ListColorPalette } from '@/module/color_palette';
import React from 'react';
function Page() {
return (
<ListColorPalette />
);
}
export default Page;

View File

@@ -0,0 +1,10 @@
import { EditPaletteColor } from '@/module/color_palette';
import React from 'react';
function Page() {
return (
<EditPaletteColor />
);
}
export default Page;

View File

@@ -1,10 +0,0 @@
import { ViewDetailFeature } from '@/module/home';
import React from 'react';
function Page() {
return (
<ViewDetailFeature/>
);
}
export default Page;

View File

@@ -0,0 +1,10 @@
import { CreateUserDetailCalender } from '@/module/calender';
import React from 'react';
function Page() {
return (
<CreateUserDetailCalender/>
);
}
export default Page;

View File

@@ -0,0 +1,12 @@
import { DetailEventDivision } from '@/module/calender';
import React from 'react';
function Page() {
return (
<>
<DetailEventDivision />
</>
);
}
export default Page;

View File

@@ -0,0 +1,11 @@
import { CreateCalenderDivisionCaleder } from '@/module/calender';
import React from 'react';
function Page({ searchParams }: { searchParams: any }) {
return (
<CreateCalenderDivisionCaleder />
);
}
export default Page;

View File

@@ -0,0 +1,10 @@
import { HistoryDivisionCalender } from '@/module/calender';
import React from 'react';
function Page() {
return (
<HistoryDivisionCalender />
);
}
export default Page;

View File

@@ -0,0 +1,10 @@
import { NavbarDivisionCalender } from '@/module/calender';
import React from 'react';
function Page() {
return (
<NavbarDivisionCalender />
);
}
export default Page;

View File

@@ -0,0 +1,10 @@
import { UpdateDivisionCalender } from '@/module/calender';
import React from 'react';
function Page({ searchParams }: { searchParams: any }) {
return (
<UpdateDivisionCalender/>
);
}
export default Page;

View File

@@ -0,0 +1,10 @@
import { DetailDiscussion } from "@/module/discussion"
function Page({ params}: { params: { detail: string, id: string } }) {
return (
<DetailDiscussion id={params.detail} idDivision={params.id} />
)
}
export default Page

View File

@@ -0,0 +1,13 @@
import { LayoutNavbarNew } from "@/module/_global";
import { FormCreateDiscussion } from "@/module/discussion";
function Page({ params }: { params: { id: string } }) {
return (
<>
<LayoutNavbarNew back="" title="Tambah Diskusi" menu={<></>} />
<FormCreateDiscussion id={params.id} />
</>
)
}
export default Page;

View File

@@ -0,0 +1,13 @@
import { ListDiscussion, NavbarListDiscussion } from '@/module/discussion';
import React from 'react';
function Page({ params }: { params: { id: string } }) {
return (
<div>
<NavbarListDiscussion />
<ListDiscussion id={params.id} />
</div>
);
}
export default Page;

View File

@@ -0,0 +1,15 @@
import { LayoutNavbarNew } from "@/module/_global";
import { FormEditDiscussion } from "@/module/discussion";
import { Box } from "@mantine/core";
function Page() {
return (
<Box>
<LayoutNavbarNew back="" title="Edit Diskusi" menu={<></>} />
<FormEditDiscussion />
</Box>
)
}
export default Page;

View File

@@ -0,0 +1,13 @@
import { NavbarDocumentDivision } from '@/module/document';
import { Box } from '@mantine/core';
import React from 'react';
function Page({ searchParams }: { searchParams: any }) {
return (
<Box>
<NavbarDocumentDivision />
</Box>
);
}
export default Page;

View File

@@ -0,0 +1,7 @@
import { AddFileDetailTask } from "@/module/task";
export default function Page() {
return (
<AddFileDetailTask />
)
}

View File

@@ -0,0 +1,9 @@
import { AddMemberDetailTask } from "@/module/task"
function Page() {
return (
<AddMemberDetailTask />
)
}
export default Page

View File

@@ -0,0 +1,9 @@
import { AddDetailTask } from "@/module/task"
function Page() {
return (
<AddDetailTask />
)
}
export default Page

View File

@@ -0,0 +1,9 @@
import { CancelTask } from "@/module/task"
function Page() {
return (
<CancelTask />
)
}
export default Page

View File

@@ -0,0 +1,9 @@
import { EditTask } from "@/module/task"
function Page() {
return (
<EditTask />
)
}
export default Page

View File

@@ -0,0 +1,18 @@
import { NavbarDetailDivisionTask, ProgressDetailTask, ListTugasDetailTask, ListFileDetailTask, ListAnggotaDetailTask } from "@/module/task"
import { Box } from "@mantine/core"
function Page() {
return (
<Box>
<NavbarDetailDivisionTask />
<Box p={20}>
<ProgressDetailTask />
<ListTugasDetailTask />
<ListFileDetailTask />
<ListAnggotaDetailTask />
</Box>
</Box>
)
}
export default Page

View File

@@ -0,0 +1,11 @@
import { CreateTask, FileSave } from "@/module/task";
function Page({ searchParams }: { searchParams: any }) {
// if (searchParams.page == "file-save")
// return <FileSave kategori="task" />
return <CreateTask />
}
export default Page

View File

@@ -0,0 +1,9 @@
import { EditDetailTask } from "@/module/task"
function Page() {
return (
<EditDetailTask />
)
}
export default Page

View File

@@ -0,0 +1,13 @@
import { NavbarDivisionTask, TabsDivisionTask } from '@/module/task';
import React from 'react';
function Page() {
return (
<div>
<NavbarDivisionTask />
<TabsDivisionTask />
</div>
);
}
export default Page;

View File

@@ -0,0 +1,12 @@
import { WrapLayoutDivision } from "@/module/division_new";
import _ from "lodash"
export default async function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<WrapLayoutDivision>
{children}
</WrapLayoutDivision>
</>
);
}

View File

@@ -0,0 +1,22 @@
import { NavbarDetailDivision, CarouselDivision, FeatureDetailDivision, ListTaskOnDetailDivision, ListDocumentOnDetailDivision, ListDiscussionOnDetailDivision } from '@/module/division_new';
import { Box, Stack } from '@mantine/core';
import React from 'react';
function Page({ params }: { params: { id: string } }) {
return (
<Box>
<NavbarDetailDivision />
<Box p={20}>
<Stack>
<CarouselDivision />
<FeatureDetailDivision/>
<ListTaskOnDetailDivision />
<ListDocumentOnDetailDivision />
<ListDiscussionOnDetailDivision />
</Stack>
</Box>
</Box>
);
}
export default Page;

View File

@@ -0,0 +1,12 @@
import { CreateAnggotaDivision } from "@/module/division_new";
import { Box } from "@mantine/core";
function Page({ params }: { params: { id: string } }) {
return (
<Box>
<CreateAnggotaDivision />
</Box>
)
}
export default Page;

View File

@@ -1,9 +1,9 @@
import { ViewNotification } from '@/module/notification';
import { CreateDivision } from '@/module/division_new';
import React from 'react';
function Page() {
return (
<ViewNotification />
<CreateDivision/>
);
}

View File

@@ -0,0 +1,12 @@
import { EditDivision } from "@/module/division_new"
import { Box } from "@mantine/core"
function Page({ params }: { params: { id: string } }) {
return (
<Box>
<EditDivision />
</Box>
)
}
export default Page

View File

@@ -0,0 +1,12 @@
import { InformationDivision } from "@/module/division_new";
import { Box } from "@mantine/core";
function Page({ params }: { params: { id: string } }) {
return (
<Box>
<InformationDivision />
</Box>
)
}
export default Page;

View File

@@ -0,0 +1,15 @@
import { ViewFilter } from '@/module/_global';
import { CreateReport, ListDivision } from '@/module/division_new';
import React from 'react';
function Page({ searchParams }: { searchParams: { page: string } }) {
if (searchParams.page == "filter")
return <ViewFilter linkFilter='division'/>
if (searchParams.page == "report")
return <CreateReport />
return (
<ListDivision/>
);
}
export default Page;

View File

@@ -0,0 +1,9 @@
import { ReportDivisionId } from "@/module/division_new"
function Page() {
return (
<ReportDivisionId />
)
}
export default Page

View File

@@ -1,9 +1,13 @@
import { ViewGroup } from '@/module/group';
import { NavbarGroup, TabListGroup } from '@/module/group';
import { Box } from '@mantine/core';
import React from 'react';
function Page() {
function Page({ searchParams }: { searchParams: { active: string } }) {
return (
<ViewGroup />
<Box>
<NavbarGroup />
<TabListGroup />
</Box>
);
}

View File

@@ -1,9 +1,13 @@
import LayoutNavbarHome from '@/module/_global/layout/layout_navbar_home';
import { ViewHome } from '@/module/home';
import { Flex, Group, Text } from '@mantine/core';
import { ViewDetailFeature, ViewHome, ViewNotification, ViewSearch } from '@/module/home';
import React from 'react';
function Page() {
function Page({ searchParams }: { searchParams: { cat: string } }) {
if (searchParams.cat == "notification")
return <ViewNotification />
if (searchParams.cat == "search")
return <ViewSearch />
if (searchParams.cat == "fitur")
return <ViewDetailFeature />
return (
<>
<ViewHome />

View File

@@ -0,0 +1,18 @@
import { WrapLayout } from "@/module/_global"
import { funDetectCookies, funGetUserByCookies } from "@/module/auth"
import _ from "lodash"
import { redirect } from "next/navigation"
export default async function Layout({ children }: { children: React.ReactNode }) {
const cookies = await funDetectCookies()
if (!cookies) return redirect('/')
const user = await funGetUserByCookies()
return (
<>
<WrapLayout role={user.idUserRole}>
{children}
</WrapLayout>
</>
);
}

View File

@@ -1,10 +1,12 @@
import { ViewDetailMember } from "@/module/user/member";
import { NavbarDetailMember } from "@/module/user/member";
import { Box } from "@mantine/core";
function Page({ params }: { params: { id: string } }) {
return (
<ViewDetailMember data={params.id} />
)
return (
<Box>
<NavbarDetailMember id={params.id} />
</Box>
);
}
export default Page;

View File

@@ -1,9 +1,14 @@
import { ViewCreateMember } from "@/module/user/member";
import { LayoutNavbarNew } from "@/module/_global";
import { CreateMember } from "@/module/user/member";
import { Box } from "@mantine/core";
function Page() {
return (
<ViewCreateMember />
);
return (
<Box>
<LayoutNavbarNew back="" title="Tambah Anggota" menu={<></>} />
<CreateMember />
</Box>
);
}
export default Page;
export default Page;

View File

@@ -1,9 +1,14 @@
import { ViewEditMember } from "@/module/user/member";
import { LayoutNavbarNew } from "@/module/_global";
import { EditMember } from "@/module/user/member";
import { Box } from "@mantine/core";
function Page() {
return (
<ViewEditMember />
)
function Page({ params }: { params: { id: string } }) {
return (
<Box>
<LayoutNavbarNew back="" title="Edit Anggota" menu={<></>} />
<EditMember id={params.id} />
</Box>
);
}
export default Page;
export default Page;

View File

@@ -1,9 +1,16 @@
import { ViewListMember } from "@/module/user/member";
import { ViewFilter } from "@/module/_global";
import { ListMember, NavbarListMember } from "@/module/user/member";
import { Box } from "@mantine/core";
function Page() {
return (
<ViewListMember />
)
function Page({ searchParams }: { searchParams: { page: string } }) {
if (searchParams.page == "filter") return <ViewFilter linkFilter="member" />;
return (
<Box>
<NavbarListMember />
<ListMember />
</Box>
);
}
export default Page;
export default Page;

View File

@@ -1,9 +1,17 @@
import { ViewListPosition } from '@/module/position';
import { ViewFilter } from '@/module/_global';
import { NavbarListPosition, TabListPosition } from '@/module/position';
import { Box } from '@mantine/core';
import React from 'react';
function Page() {
function Page({ searchParams }: { searchParams: { page: string } }) {
if (searchParams.page == "filter")
return <ViewFilter linkFilter='position' />
return (
<ViewListPosition />
<Box>
<NavbarListPosition />
<TabListPosition />
</Box>
);
}

View File

@@ -1,8 +1,8 @@
import { ViewEditProfile } from "@/module/user"
import { EditProfile } from "@/module/user"
function Page() {
return (
<ViewEditProfile />
<EditProfile />
)
}

View File

@@ -1,8 +1,8 @@
import { ViewProfile } from "@/module/user";
import { Profile } from "@/module/user";
function Page() {
return (
<ViewProfile />
<Profile />
)
}

View File

@@ -0,0 +1,9 @@
import { AddFileDetailProject } from "@/module/project";
export default function Page() {
return (
<>
<AddFileDetailProject />
</>
)
}

View File

@@ -0,0 +1,10 @@
import { AddMemberDetailProject } from '@/module/project';
import React from 'react';
function Page() {
return (
<AddMemberDetailProject/>
);
}
export default Page;

View File

@@ -0,0 +1,10 @@
import { AddDetailTaskProject } from '@/module/project';
import React from 'react';
function Page() {
return (
<AddDetailTaskProject />
);
}
export default Page;

View File

@@ -1,9 +1,9 @@
import { ViewSearch } from '@/module/search';
import { CancelProject } from '@/module/project';
import React from 'react';
function Page() {
return (
<ViewSearch/>
<CancelProject />
);
}

View File

@@ -0,0 +1,10 @@
import { EditTaskProject } from '@/module/project';
import React from 'react';
function Page() {
return (
<EditTaskProject />
);
}
export default Page;

View File

@@ -0,0 +1,19 @@
import { ListAnggotaDetailProject, ListFileDetailProject, ListTugasDetailProject, NavbarDetailProject, ProgressDetailProject, ViewDetailProject } from '@/module/project';
import { Box } from '@mantine/core';
import React from 'react';
function Page() {
return (
<Box>
<NavbarDetailProject />
<Box p={20}>
<ProgressDetailProject />
<ListTugasDetailProject />
<ListFileDetailProject />
<ListAnggotaDetailProject />
</Box>
</Box>
);
}
export default Page;

View File

@@ -0,0 +1,12 @@
import { CreateProject, ViewFileSave } from "@/module/project";
import React from "react";
function Page({ searchParams }: { searchParams: any }) {
// if (searchParams.page == "file-save")
// return <ViewFileSave kategori="project" />
return <CreateProject />;
}
export default Page;

View File

@@ -1,9 +1,12 @@
import { ViewProject } from '@/module/project';
import { ViewFilter } from '@/module/_global';
import { TabProject, ViewProject } from '@/module/project';
import React from 'react';
function Page() {
function Page({ searchParams }: { searchParams: { page: string } }) {
if (searchParams.page == 'filter')
return <ViewFilter linkFilter='project' />
return (
<ViewProject />
<TabProject />
);
}

View File

@@ -0,0 +1,11 @@
import { EditDetailTaskProject } from "@/module/project";
import React from "react";
function Page() {
return (
<EditDetailTaskProject/>
)
}
export default Page;

View File

@@ -1,6 +1,7 @@
import { ViewVerification } from "@/module/auth";
import { IVerification } from "@/types";
import React from "react";
export default function Verification() {
return <ViewVerification />;
export default function Page() {
return <ViewVerification phone={""} otp={0} user={''} />;
}

View File

@@ -0,0 +1,223 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import _ from "lodash";
import { NextResponse } from "next/server";
// GET ONE PENGUMUMAN, UNTUK TAMPIL DETAIL PENGUMUMAN
export async function GET(request: Request, context: { params: { id: string } }) {
try {
const { id } = context.params;
const { searchParams } = new URL(request.url);
const kategori = searchParams.get('category');
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.announcement.count({
where: {
id: id,
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan pengumuman, data tidak ditemukan",
},
{ status: 404 }
);
}
const announcement = await prisma.announcement.findUnique({
where: {
id: id,
},
select: {
id: true,
title: true,
desc: true,
},
});
const announcementMember = await prisma.announcementMember.findMany({
where: {
idAnnouncement: id,
},
select: {
idGroup: true,
idDivision: true,
Group: {
select: {
name: true,
},
},
Division: {
select: {
name: true,
},
},
},
});
const formatMember = announcementMember.map((v: any) => ({
..._.omit(v, ["Group", "Division"]),
idGroup: v.idGroup,
idDivision: v.idDivision,
group: v.Group.name,
division: v.Division.name
}))
const fixMember = Object.groupBy(formatMember, ({ group }) => group);
return NextResponse.json(
{
success: true,
message: "Berhasil mendapatkan pengumuman",
data: announcement,
member: fixMember
},
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan pengumuman, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// HAPUS PENGUMUMAN
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.announcement.count({
where: {
id: id,
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Hapus pengumuman gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const update = await prisma.announcement.update({
where: {
id: id,
},
data: {
isActive: false,
},
});
// create log user
const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus data pengumuman', table: 'announcement', data: id })
return NextResponse.json(
{
success: true,
message: "Pengumuman berhasil dihapus",
data,
},
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan pengumuman, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// EDIT PENGUMUMAN
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 { title, desc, groups } = (await request.json());
const { id } = context.params;
const data = await prisma.announcement.count({
where: {
id: id,
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Edit pengumuman gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const update = await prisma.announcement.update({
where: {
id: id
},
data: {
title,
desc,
},
});
// hapus semua member divisi pengumuman
const hapus = await prisma.announcementMember.deleteMany({
where: {
idAnnouncement: id
}
})
let memberDivision = []
for (var i = 0, l = groups.length; i < l; i++) {
var obj = groups[i].Division;
for (let index = 0; index < obj.length; index++) {
const element = obj[index];
const fix = {
idAnnouncement: id,
idGroup: groups[i].id,
idDivision: element.id
}
memberDivision.push(fix)
}
}
const announcementMember = await prisma.announcementMember.createMany({
data: memberDivision,
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data pengumuman', table: 'announcement', data: id })
return NextResponse.json({ success: true, message: "Berhasil mengupdate pengumuman" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengeupdate pengumuman, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,156 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _ from "lodash";
import moment from "moment";
import "moment/locale/id";
import { NextResponse } from "next/server";
import { createLogUser } from '@/module/user';
export const dynamic = 'force-dynamic'
// GET ALL PENGUMUMAN
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 villageId = user.idVillage
const roleUser = user.idUserRole
const groupId = user.idGroup
const { searchParams } = new URL(request.url);
const name = searchParams.get('search');
let kondisi: any = {
idVillage: String(villageId),
isActive: true,
title: {
contains: (name == undefined || name == null) ? "" : name,
mode: "insensitive"
}
}
if (roleUser != "supadmin") {
if (roleUser == "cosupadmin" || roleUser == "admin") {
kondisi = {
idVillage: String(villageId),
isActive: true,
title: {
contains: (name == undefined || name == null) ? "" : name,
mode: "insensitive"
},
AnnouncementMember: {
some: {
idGroup: String(groupId)
}
}
}
} else {
kondisi = {
idVillage: String(villageId),
isActive: true,
title: {
contains: (name == undefined || name == null) ? "" : name,
mode: "insensitive"
},
AnnouncementMember: {
some: {
idGroup: String(groupId),
Division: {
DivisionMember: {
some: {
idUser: String(user.id)
}
}
}
}
}
}
}
}
const announcements = await prisma.announcement.findMany({
where: kondisi,
select: {
id: true,
title: true,
desc: true,
createdAt: true,
},
orderBy: {
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 pengumuman", data: allData, }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan pengumuman, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// CREATE PENGUMUMAN
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 { title, desc, groups } = (await request.json());
const villaId = user.idVillage
const userId = user.id
const data = await prisma.announcement.create({
data: {
title,
desc,
idVillage: String(villaId),
createdBy: String(userId),
},
select: {
id: true,
}
});
let memberDivision = []
for (var i = 0, l = groups.length; i < l; i++) {
var obj = groups[i].Division;
for (let index = 0; index < obj.length; index++) {
const element = obj[index];
const fix = {
idAnnouncement: data.id,
idGroup: groups[i].id,
idDivision: element.id
}
memberDivision.push(fix)
}
}
const announcementMember = await prisma.announcementMember.createMany({
data: memberDivision,
});
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data pengumuman baru', table: 'announcement', data: data.id })
return NextResponse.json({ success: true, message: "Berhasil membuat pengumuman" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal membuat pengumuman, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,18 @@
import { prisma, pwd_key_config } from "@/module/_global";
import { unsealData } from "iron-session";
import { cookies } from "next/headers";
export async function GET() {
const sessionCookie = cookies().get("sessionCookieSDM");
const userId = await unsealData(sessionCookie!.value, {
password: pwd_key_config,
});
const user = await prisma.user.findUnique({
where: {
id: String(userId),
},
});
return Response.json(user);
}

View File

@@ -0,0 +1,31 @@
import { prisma } from "@/module/_global";
import { ILogin } from "@/types";
import { NextRequest } from "next/server";
export async function POST(req: NextRequest) {
try {
const { phone }: ILogin = await req.json();
const user = await prisma.user.findUnique({
where: { phone, isActive: true },
select: { id: true, phone: true },
});
if (!user) {
return Response.json({
success: false,
message: "Nomor telepon tidak terdaftar",
});
}
return Response.json({
success: true,
message: "Sukses",
phone: user.phone,
id: user.id,
});
} catch (error) {
console.error(error);
return Response.json({ message: "Internal Server Error", success: false });
}
}

View File

@@ -0,0 +1,10 @@
import { createLogUser } from "@/module/user";
import { cookies } from "next/headers";
export async function DELETE() {
const log = await createLogUser({ act: 'LOGOUT', desc: 'User keluar dari program', table: 'user', data: '' })
cookies().delete('sessionCookieSDM')
return Response.json({ success: true })
}

View File

@@ -0,0 +1,176 @@
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 ONE DATA KALENDER BY ID KALENDER
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 cek = await prisma.divisionCalendar.count({
where: {
id: id
}
})
if (cek == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan calender, data tidak ditemukan",
},
{ status: 404 }
);
}
const data = await prisma.divisionCalendar.findUnique({
where: {
id: id
},
select: {
id: true,
title: true,
desc: true,
timeStart: true,
dateStart: true,
timeEnd: true,
createdAt: true,
linkMeet: true,
repeatValue: true,
repeatEventTyper: true,
}
});
const { ...dataCalender } = data
const timeStart = moment.utc(dataCalender?.timeStart).format("HH:mm")
const timeEnd = moment.utc(dataCalender?.timeEnd).format("HH:mm")
const result = { ...dataCalender, timeStart, timeEnd }
return NextResponse.json({ success: true, message: "Berhasil mendapatkan calender", data: result }, { status: 200 });
} catch (error) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan calender, data tidak ditemukan",
},
{ status: 404 }
);
}
}
// TAMBAH MEMBER KALENDER
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 cek = await prisma.divisionCalendar.count({
where: {
id: id
}
})
if (cek == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal menambahkan anggota, data tidak ditemukan",
},
{ status: 404 }
);
}
if (member.length > 0) {
const dataMember = member.map((v: any) => ({
..._.omit(v, ["idUser", "name", "img"]),
idCalendar: id,
idUser: v.idUser,
}))
const insertMember = await prisma.divisionCalendarMember.createMany({
data: dataMember
})
}
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User menambah anggota kalender', table: 'divisionCalendar', data: String(id) })
return NextResponse.json({ success: true, message: "Berhasil menambahkan anggota", }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menambah anggota, coba lagi nanti", 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.divisionCalendar.count({
where: {
id: id,
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal mengeluarkan anggota, data tidak ditemukan",
},
{ status: 404 }
);
}
const del = await prisma.divisionCalendarMember.deleteMany({
where: {
idUser: idUser,
idCalendar: id
}
})
// create log user
const log = await createLogUser({ act: 'DELETE', desc: 'User mengeluarkan anggota acara kalender', table: 'divisionCalendar', data: String(id) })
return NextResponse.json(
{
success: true,
message: "Berhasil mengeluarkan anggota",
},
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengeluarkan anggota, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,271 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import _, { remove } from "lodash";
import moment from "moment";
import { NextResponse } from "next/server";
import { Frequency, RRule } from 'rrule';
// GET ONE CALENDER BY ID KALENDER REMINDER
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 cek = await prisma.divisionCalendarReminder.count({
where: {
id: id
}
})
if (cek == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan acara, data tidak ditemukan",
},
{ status: 404 }
);
}
const data: any = await prisma.divisionCalendarReminder.findUnique({
where: {
id: id
},
select: {
id: true,
timeStart: true,
dateStart: true,
timeEnd: true,
createdAt: true,
DivisionCalendar: {
select: {
id: true,
title: true,
desc: true,
linkMeet: true,
repeatEventTyper: true,
repeatValue: true,
}
}
}
});
const { DivisionCalendar, ...dataCalender } = data
const timeStart = moment.utc(dataCalender?.timeStart).format("HH:mm")
const timeEnd = moment.utc(dataCalender?.timeEnd).format("HH:mm")
const idCalendar = data?.DivisionCalendar.id
const title = data?.DivisionCalendar?.title
const desc = data?.DivisionCalendar?.desc
const linkMeet = data?.DivisionCalendar?.linkMeet
const repeatEventTyper = data?.DivisionCalendar?.repeatEventTyper
const repeatValue = data?.DivisionCalendar?.repeatValue
const result = { ...dataCalender, timeStart, timeEnd, idCalendar, title, desc, linkMeet, repeatEventTyper, repeatValue }
const member = await prisma.divisionCalendarMember.findMany({
where: {
idCalendar: data?.DivisionCalendar.id
},
select: {
id: true,
idUser: true,
User: {
select: {
id: true,
name: true,
email: true,
img: true
}
}
}
})
const fixMember = member.map((v: any) => ({
..._.omit(v, ["User"]),
name: v.User.name,
email: v.User.email,
img: v.User.img
}))
const dataFix = {
calender: result,
member: fixMember,
total: fixMember.length
}
return NextResponse.json({ success: true, message: "Berhasil mendapatkan calender", data: dataFix }, { status: 200 });
} catch (error) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan calender, data tidak ditemukan",
},
{ status: 404 }
);
}
}
// DELETE CALENDER BY ID
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 cek = await prisma.divisionCalendar.count({
where: {
id: id
}
})
if (cek == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal menghapus acara kalender, data tidak ditemukan",
},
{ status: 404 }
);
}
const data = await prisma.divisionCalendar.update({
where: {
id: id
},
data: {
isActive: false
}
});
// create log user
const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus data acara kalender', table: 'divisionCalendar', data: id })
return NextResponse.json({ success: true, message: "Berhasil menghapus acara kalender", data }, { status: 200 });
} catch (error) {
return NextResponse.json(
{
success: false,
message: "Gagal menghapus calender, coba lagi nanti",
},
{ status: 500 }
);
}
}
// EDIT CALENDER BY IDKALENDER
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 userId = user.id
const { title, desc, timeStart, dateStart, timeEnd, linkMeet, repeatEventTyper, repeatValue } = await request.json()
const cek = await prisma.divisionCalendar.count({
where: {
id: id
}
})
if (cek == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal mengedit acara, data tidak ditemukan",
},
{ status: 404 }
);
}
const y = new Date('1970-01-01 ' + timeStart)
const x = new Date('1970-01-01 ' + timeEnd)
const timeStartFix = new Date(y.getTime() - (y.getTimezoneOffset() * 60000)).toISOString()
const timeEndFix = new Date(x.getTime() - (x.getTimezoneOffset() * 60000)).toISOString()
const statusCalender = 0
const data = await prisma.divisionCalendar.update({
where: {
id: id
},
data: {
title: title,
desc: desc,
createdBy: String(userId),
timeStart: timeStartFix,
dateStart: new Date(dateStart),
timeEnd: timeEndFix,
linkMeet: linkMeet,
repeatEventTyper: repeatEventTyper,
status: statusCalender,
repeatValue: Number(repeatValue)
},
select: {
idDivision: true
}
});
const freq: Frequency = repeatEventTyper === "yearly" ? RRule.YEARLY :
repeatEventTyper === "monthly" ? RRule.MONTHLY :
repeatEventTyper === "weekly" ? RRule.WEEKLY :
repeatEventTyper === "daily" ? RRule.DAILY :
repeatEventTyper === "hourly" ? RRule.HOURLY :
repeatEventTyper === "minutely" ? RRule.MINUTELY :
RRule.SECONDLY;
const rule = new RRule({
freq,
interval: 1,
dtstart: new Date(dateStart),
count: repeatValue
});
const hasil = rule.all().map(recurrenceDate => ({
idDivision: data.idDivision,
idCalendar: id,
dateStart: recurrenceDate,
timeStart: timeStartFix,
timeEnd: timeEndFix,
dateEnd: recurrenceDate
}));
const deleteReminder = await prisma.divisionCalendarReminder.deleteMany({
where: {
idCalendar: id
}
})
const insertReminder = await prisma.divisionCalendarReminder.createMany({
data: hasil
})
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data acara kalender', table: 'divisionCalendar', data: id })
return NextResponse.json({ success: true, message: "Berhasil mengedit acara" }, { status: 200 });
} catch (error) {
return NextResponse.json(
{
success: false,
message: "Gagal mengedit acara, coba lagi nanti",
},
{ status: 500 }
);
}
}

View File

@@ -0,0 +1,102 @@
import moment from "moment";
import { NextResponse } from "next/server";
import "moment/locale/id";
import { funGetUserByCookies } from "@/module/auth";
import { prisma } from "@/module/_global";
import _ from "lodash";
// GET HSITORY
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 idDivision = searchParams.get("division");
const name = searchParams.get('search');
if (idDivision != "null" && idDivision != null && idDivision != undefined) {
const cekDivision = await prisma.division.count({
where: {
id: idDivision,
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
const data = await prisma.divisionCalendarReminder.findMany({
where: {
isActive: true,
idDivision: idDivision,
DivisionCalendar: {
title: {
contains: (name == undefined || name == "null") ? "" : name,
mode: "insensitive"
},
isActive: true
}
},
select: {
id: true,
timeStart: true,
dateStart: true,
timeEnd: true,
DivisionCalendar: {
select: {
title: true,
}
}
},
orderBy: [
{
dateStart: 'asc'
},
{
timeStart: 'asc'
},
{
timeEnd: 'asc'
}
]
});
const allOmit = data.map((v: any) => ({
..._.omit(v, ["DivisionCalendar"]),
title: v.DivisionCalendar.title
}))
// groupBy untuk dateStart
const groupByDateStart = _.groupBy(allOmit, 'dateStart');
const result = Object.keys(groupByDateStart).map(key => {
const obj = groupByDateStart[key];
const data = obj.map((v: any) => ({
id: v.id,
title: v.title,
timeEnd: moment.utc(v.timeEnd).format('HH:mm'),
timeStart: moment.utc(v.timeStart).format('HH:mm')
}))
return {
dateStart: key,
data: data
}
})
return NextResponse.json({ success: true, message: "Berhasil mendapatkan riwayat acara kalender", data: result }, { status: 200 });
} else {
return NextResponse.json({ success: false, message: "Gagal mendapatkan riwayat acara kalender, coba lagi nanti" }, { status: 404 });
}
} catch (error) {
console.error(error)
return NextResponse.json({ success: false, message: "Gagal mendapatkan riwayat acara kalender, coba lagi nanti" }, { status: 404 });
}
}

View File

@@ -0,0 +1,67 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _ from "lodash";
import moment from "moment";
import { NextResponse } from "next/server";
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 idDivision = searchParams.get("division");
const date = searchParams.get("date");
const awalDate = moment(date).format('YYYY-MM') + '-01'
const akhirDate = moment(awalDate).add(1, 'M').format('YYYY-MM-DD')
const cekDivision = await prisma.division.count({
where: {
id: String(idDivision),
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
const data = await prisma.divisionCalendarReminder.findMany({
where: {
isActive: true,
idDivision: String(idDivision),
dateStart: {
gte: new Date(awalDate),
lte: new Date(akhirDate),
},
DivisionCalendar: {
isActive: true
}
}
})
const dataGroup = _.map(_.groupBy(data, "dateStart"), (v: any) => ({
dateContent: v[0].dateStart
}))
const result = dataGroup.map(a => moment(a.dateContent).format('YYYY-MM-DD'));
return NextResponse.json({ success: true, message: "Berhasil mendapatkan list acara", data: result }, { status: 200 });
} catch (error) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan list acara" }, { status: 401 });
}
}

View File

@@ -0,0 +1,196 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _ from "lodash";
import moment from "moment";
import { NextResponse } from "next/server";
import "moment/locale/id";
import { createLogUser } from '@/module/user';
import { Frequency, RRule } from 'rrule';
//GET ALL CALENDER
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 idDivision = searchParams.get("division");
const isDate = searchParams.get("date")
if (idDivision != "null" && idDivision != null && idDivision != undefined) {
const cekDivision = await prisma.division.count({
where: {
id: idDivision,
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
const data = await prisma.divisionCalendarReminder.findMany({
where: {
isActive: true,
idDivision: idDivision,
dateStart: new Date(String(isDate)),
DivisionCalendar: {
isActive: true
}
},
select: {
id: true,
idCalendar: true,
timeStart: true,
dateStart: true,
timeEnd: true,
dateEnd: true,
createdAt: true,
status: true,
DivisionCalendar: {
select: {
title: true,
desc: true,
User: {
select: {
name: true
}
}
}
}
},
orderBy: [
{
dateStart: 'asc'
},
{
timeStart: 'asc'
},
{
timeEnd: 'asc'
}
]
});
const allOmit = data.map((v: any) => ({
..._.omit(v, ["DivisionCalendar", "User"]),
title: v.DivisionCalendar.title,
desc: v.DivisionCalendar.desc,
user_name: v.DivisionCalendar.User.name,
timeStart: moment.utc(v.timeStart).format('HH:mm'),
timeEnd: moment.utc(v.timeEnd).format('HH:mm')
}))
return NextResponse.json({ success: true, message: "Berhasil mendapatkan calender", data: allOmit }, { status: 200 });
} else {
return NextResponse.json({ success: false, message: "Gagal mendapatkan calender, data tidak ditemukan" }, { status: 404 });
}
} catch (error) {
console.error(error)
return NextResponse.json({ success: false, message: "Gagal mendapatkan calender, data tidak ditemukan" }, { status: 404 });
}
}
//CREATE CALENDER
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 { idDivision, title, desc, timeStart, timeEnd, dateStart, dateEnd, repeatEventTyper, member, linkMeet, repeatValue } = (await request.json());
const userId = user.id
const cekDivision = await prisma.division.count({
where: {
id: idDivision,
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
const y = new Date('1970-01-01 ' + timeStart)
const x = new Date('1970-01-01 ' + timeEnd)
const timeStartFix = new Date(y.getTime() - (y.getTimezoneOffset() * 60000)).toISOString()
const timeEndFix = new Date(x.getTime() - (x.getTimezoneOffset() * 60000)).toISOString()
const data = await prisma.divisionCalendar.create({
data: {
idDivision,
createdBy: String(userId),
title,
dateStart: new Date(dateStart),
timeStart: timeStartFix,
timeEnd: timeEndFix,
linkMeet,
repeatEventTyper,
desc,
repeatValue: Number(repeatValue)
},
select: {
id: true,
}
});
const freq: Frequency = repeatEventTyper === "yearly" ? RRule.YEARLY :
repeatEventTyper === "monthly" ? RRule.MONTHLY :
repeatEventTyper === "weekly" ? RRule.WEEKLY :
repeatEventTyper === "daily" ? RRule.DAILY :
repeatEventTyper === "hourly" ? RRule.HOURLY :
repeatEventTyper === "minutely" ? RRule.MINUTELY :
RRule.SECONDLY;
const rule = new RRule({
freq,
interval: 1,
dtstart: new Date(dateStart),
count: repeatValue
});
const hasil = rule.all().map(recurrenceDate => ({
idDivision: idDivision,
idCalendar: data.id,
dateStart: recurrenceDate,
timeStart: timeStartFix,
timeEnd: timeEndFix,
dateEnd: recurrenceDate
}));
const insertReminder = await prisma.divisionCalendarReminder.createMany({
data: hasil
})
const omitMember = member.map((v: any) => ({
..._.omit(v, ["name", "idUser", "img"]),
idCalendar: data.id,
idUser: v.idUser
}))
const insertMember = await prisma.divisionCalendarMember.createMany({
data: omitMember
});
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data acara kalender', table: 'divisionCalendar', data: data.id })
return NextResponse.json({ success: true, message: "Berhasil membuat acara kalender" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal membuat acara kalender, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,53 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import { NextResponse } from "next/server";
// CREATE COMENT BY ID KOMENTAR
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 { comment } = (await request.json());
const cek = await prisma.divisionDisscussion.count({
where: {
id: id
}
})
if (cek == 0) {
return NextResponse.json(
{
success: false,
message: "Tambah komentar gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const data = await prisma.divisionDisscussionComment.create({
data: {
comment: comment,
idDisscussion: id,
createdBy: user.id
},
select: {
id: true
}
})
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User menambah komentar pada diskusi', table: 'divisionDisscussionComment', data: data.id })
return NextResponse.json({ success: true, message: "Berhasil menambah komentar", data: data, }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menambah komentar, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,223 @@
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 ONE DISCUSSION BY ID
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 cek = await prisma.divisionDisscussion.count({
where: {
id: id
}
})
if (cek == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan diskusi, data tidak ditemukan",
},
{ status: 404 }
);
}
const data = await prisma.divisionDisscussion.findUnique({
where: {
id: id
},
select: {
id: true,
title: true,
desc: true,
status: true,
createdAt: true,
createdBy: true,
User: {
select: {
name: true,
img: true
}
},
DivisionDisscussionComment: {
select: {
id: true,
comment: true,
createdAt: true,
User: {
select: {
name: true,
img: true
}
}
}
},
}
});
const { ...userMember } = data
const username = data?.User.name
const user_img = data?.User.img
const createdAt = moment(data?.createdAt).format("ll")
const isCreator = data?.createdBy == user.id
const result = { ...userMember, username, createdAt, user_img, isCreator }
const omitData = _.omit(result, ["User"])
const comments = omitData.DivisionDisscussionComment.map((comment: any) => {
return { ...comment, username: comment.User.name, img: comment.User.img };
});
omitData.DivisionDisscussionComment = comments;
const response = {
...omitData,
totalComments: comments.length,
};
return NextResponse.json({ success: true, message: "Berhasil mendapatkan diskusi", data: response }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// OPEN OR CLOSE DISCUSSION
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 { status } = (await request.json());
let newStatus;
if (status === 1) {
newStatus = 2;
} else if (status === 2) {
newStatus = 1;
} else {
return NextResponse.json({ success: false, message: "Invalid status" }, { status: 400 });
}
const data = await prisma.divisionDisscussion.count({
where: {
id: id
},
});
if (data == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, data tidak ditemukan" }, { status: 404 });
}
const result = await prisma.divisionDisscussion.update({
where: {
id: id
},
data: {
status: newStatus
}
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate status diskusi', table: 'divisionDisscussion', data: id })
return NextResponse.json({ success: true, message: "Berhasil mengedit diskusi" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengedit diskusi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// DELETE DISCUSSION
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 cek = await prisma.divisionDisscussion.count({
where: {
id: id
},
});
if (cek == 0) {
return NextResponse.json({ success: false, message: "Gagal menghapus diskusi, data tidak ditemukan" }, { status: 404 });
}
const data = await prisma.divisionDisscussion.update({
where: {
id: id
},
data: {
isActive: false
}
});
// create log user
const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus data diskusi', table: 'divisionDisscussion', data: id })
return NextResponse.json({ success: true, message: "Berhasil menghapus diskusi" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menghapus diskusi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// EDIT DISCUSSION
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, desc } = (await request.json());
const data = await prisma.divisionDisscussion.count({
where: {
id: id
},
});
if (data == 0) {
return NextResponse.json({ success: false, message: "Gagal mengedit diskusi, data tidak ditemukan" }, { status: 404 });
}
const update = await prisma.divisionDisscussion.update({
where: {
id: id
},
data: {
desc: desc
}
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data diskusi', table: 'divisionDisscussion', data: id })
return NextResponse.json({ success: true, message: "Berhasil mengedit diskusi" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengedit diskusi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,133 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _ from "lodash";
import moment from "moment";
import { NextResponse } from "next/server";
import "moment/locale/id";
import { createLogUser } from "@/module/user";
// GET ALL DISCUSSION DIVISION ACTIVE = TRUE
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 idDivision = searchParams.get("division");
const name = searchParams.get('search');
if (idDivision != "null" && idDivision != null && idDivision != undefined) {
const cekDivision = await prisma.division.count({
where: {
id: idDivision,
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
const data = await prisma.divisionDisscussion.findMany({
where: {
isActive: true,
idDivision: idDivision,
User: {
name: {
contains: (name == undefined || name == "null") ? "" : name,
mode: "insensitive"
}
}
},
orderBy: {
createdAt: 'desc'
},
select: {
id: true,
title: true,
desc: true,
status: true,
createdAt: true,
User: {
select: {
name: true,
img: true
}
},
DivisionDisscussionComment: {
select: {
id: true,
}
}
}
});
const fixData = data.map((v: any) => ({
..._.omit(v, ["User", "DivisionDisscussionComment", "createdAt"]),
user_name: v.User.name,
img: v.User.img,
total_komentar: v.DivisionDisscussionComment.length,
createdAt: moment(v.createdAt).format("ll")
}))
return NextResponse.json({ success: true, message: "Berhasil mendapatkan diskusi", data: fixData, }, { status: 200 });
} else {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// CREATE DISCUSSION
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 { idDivision, desc } = (await request.json());
const cekDivision = await prisma.division.count({
where: {
id: idDivision,
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
const data = await prisma.divisionDisscussion.create({
data: {
idDivision,
desc,
createdBy: user.id
},
select: {
id: true
}
});
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data diskusi', table: 'divisionDisscussion', data: data.id })
return NextResponse.json({ success: true, message: "Berhasil menambahkan diskusi", data, }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menambahkan diskusi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};

View File

@@ -0,0 +1,321 @@
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 ONE DATA DIVISI :: UNTUK TAMPIL DETAIL DIVISI (FITUR DIVISI) PADA HALAMAN DETAIL
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.division.findUnique({
where: {
id: String(id),
isActive: true
}
});
if (!data) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan", }, { status: 404 });
}
if (kategori == "jumlah") {
const tugas = await prisma.divisionProject.count({
where: {
idDivision: String(id),
status: {
lte: 1
},
isActive: true
}
})
const dokumen = await prisma.divisionDocumentFolderFile.count({
where: {
idDivision: String(id),
isActive: true,
category: "FILE"
}
})
const diskusi = await prisma.divisionDisscussion.count({
where: {
idDivision: String(id),
isActive: true,
status: 1
}
})
const kalender = await prisma.divisionCalendarReminder.count({
where: {
idDivision: String(id),
isActive: true,
dateStart: {
lte: new Date()
},
DivisionCalendar: {
isActive: true
}
}
})
allData = {
tugas: tugas,
dokumen: dokumen,
diskusi: diskusi,
kalender: kalender
}
} else if (kategori == "today-task") {
const tugas = await prisma.divisionProjectTask.findMany({
skip: 0,
take: 5,
where: {
idDivision: String(id),
status: 0,
isActive: true,
dateStart: new Date()
},
select: {
id: true,
title: true,
dateStart: true,
dateEnd: true,
}
})
allData = tugas.map((v: any) => ({
..._.omit(v, ["dateStart", "dateEnd"]),
dateStart: moment(v.dateStart).format("LL"),
dateEnd: moment(v.dateEnd).format("LL")
}))
} else if (kategori == "new-file") {
allData = await prisma.divisionDocumentFolderFile.findMany({
skip: 0,
take: 5,
where: {
idDivision: String(id),
isActive: true,
category: "FILE"
},
select: {
id: true,
name: true,
extension: true,
},
orderBy: {
createdAt: "desc"
}
})
} else if (kategori == "new-discussion") {
const diskusi = await prisma.divisionDisscussion.findMany({
skip: 0,
take: 5,
where: {
idDivision: String(id),
isActive: true,
status: 1
},
select: {
id: true,
title: true,
desc: true,
createdAt: true,
User: {
select: {
name: true
}
}
},
orderBy: {
createdAt: "desc"
}
})
allData = diskusi.map((v: any) => ({
..._.omit(v, ["createdAt", "User"]),
date: moment(v.dateStart).format("ll"),
user: v.User.name
}))
}
return NextResponse.json({ success: true, message: "Berhasil mendapatkan divisi", data: allData }, { status: 200 });
}
catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// MENGELUARKAN ANGGOTA DARI DIVISI
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 idDivision = context.params.id;
const { id } = (await request.json());
const data = await prisma.division.count({
where: {
id: idDivision,
isActive: true
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Hapus anggota divisi gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const update = await prisma.divisionMember.delete({
where: {
id: id,
},
});
// create log user
const log = await createLogUser({ act: 'DELETE', desc: 'User mengeluarkan anggota divisi', table: 'division', data: idDivision })
return NextResponse.json(
{
success: true,
message: "Anggota divisi berhasil dihapus",
},
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengeluarkan anggota divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// MENGGANTI STATUS ADMIN DIVISI
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 idDivision = context.params.id;
const { id, isAdmin } = (await request.json());
const data = await prisma.division.count({
where: {
id: idDivision,
isActive: true
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Perubahan status admin gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const update = await prisma.divisionMember.update({
where: {
id: id,
},
data: {
isAdmin: !isAdmin
}
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate status anggota divisi', table: 'division', data: idDivision })
return NextResponse.json(
{
success: true,
message: "Status admin berhasil diupdate",
},
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengubah status admin divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// TAMBAH ANGGOTA DIVISI
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 member = await request.json();
const idDivision = context.params.id;
const data = await prisma.division.count({
where: {
id: idDivision,
isActive: true
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Tambah anggota divisi gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const dataMember = member.map((v: any) => ({
..._.omit(v, ["name", "img"]),
idUser: v.idUser,
idDivision: idDivision,
}))
const insertMember = await prisma.divisionMember.createMany({
data: dataMember
})
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User menambah anggota divisi', table: 'division', data: idDivision })
return NextResponse.json({ success: true, message: "Berhasil menambahkan anggota divisi" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menambahkan anggota divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};

View File

@@ -0,0 +1,70 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _ from "lodash";
import { NextResponse } from "next/server";
// GET MEMBER BY ID
export async function GET(request: Request, context: { params: { id: string } }) {
try {
const { id } = context.params;
const { searchParams } = new URL(request.url);
const user = await funGetUserByCookies()
const name = searchParams.get('search')
if (user.id == undefined) {
return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
}
const data = await prisma.division.findUnique({
where: {
id: String(id),
isActive: true,
}
});
if (!data) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan", }, { status: 404 });
}
const member = await prisma.divisionMember.findMany({
where: {
idDivision: String(id),
isActive: true,
User: {
name: {
contains: (name == undefined || name == null) ? "" : name,
mode: "insensitive",
}
}
},
select: {
id: true,
isAdmin: true,
isLeader: true,
idUser: true,
User: {
select: {
name: true,
img: true
}
}
},
orderBy: {
isAdmin: 'desc',
}
})
const fixMember = member.map((v: any) => ({
..._.omit(v, ["User"]),
name: v.User.name,
img: v.User.img
}))
return NextResponse.json({ success: true, data: fixMember })
} catch (error) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan member, data tidak ditemukan", }, { status: 404 });
}
}

View File

@@ -0,0 +1,122 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import _ from "lodash";
import { NextResponse } from "next/server";
// GET ONE DATA DIVISI :: UNTUK TAMPIL DATA DI HALAMAN EDIT DAN INFO
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.division.findUnique({
where: {
id: String(id),
isActive: true
}
});
if (!data) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan", }, { status: 404 });
}
const member = await prisma.divisionMember.findMany({
where: {
idDivision: String(id),
isActive: true,
},
select: {
id: true,
isAdmin: true,
isLeader: true,
idUser: true,
User: {
select: {
name: true,
img: true
}
}
},
orderBy: {
isAdmin: 'desc',
}
})
const fixMember = member.map((v: any) => ({
..._.omit(v, ["User"]),
name: v.User.name,
img: v.User.img
}))
const dataFix = {
division: data,
member: fixMember
}
return NextResponse.json({ success: true, message: "Berhasil mendapatkan divisi", data: dataFix, }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// EDIT DATA DIVISI
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, desc } = (await request.json());
const data = await prisma.division.count({
where: {
id: id,
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Edit divisi gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const update = await prisma.division.update({
where: {
id: id,
},
data: {
name: name,
desc: desc
},
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data divisi', table: 'division', data: id })
return NextResponse.json(
{
success: true,
message: "Divisi berhasil diedit",
},
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengedit divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,50 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _ from "lodash";
import { NextResponse } from "next/server";
// GET LIST DIVISI BY ID DIVISI (CONTOH : UNTUK SHARE DOKUMEN)
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 idDivision = searchParams.get("division");
const name = searchParams.get('search');
const dataDivision = await prisma.division.findUnique({
where: {
id: String(idDivision),
isActive: true
}
})
if (!dataDivision) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan", }, { status: 404 });
}
const data = await prisma.division.findMany({
where: {
isActive: true,
idGroup: dataDivision.idGroup,
name: {
contains: (name == undefined || name == "null") ? "" : name,
mode: "insensitive"
}
},
select: {
id: true,
name: true,
}
});
return NextResponse.json({ success: true, message: "Berhasil mendapatkan divisi", data }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,198 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _, { ceil } from "lodash";
import moment from "moment";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
try {
const user = await funGetUserByCookies()
const { searchParams } = new URL(request.url)
const group = searchParams.get("group")
const division = searchParams.get("division")
const date = searchParams.get("date")
if (user.id == undefined) {
return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 })
}
// CHART PROGRESS
let kondisiProgress
if (division == "undefined") {
kondisiProgress = {
isActive: true,
updatedAt: {
lte: new Date(String(date))
},
Division: {
idGroup: String(group)
}
}
} else {
kondisiProgress = {
isActive: true,
idDivision: String(division),
updatedAt: {
lte: new Date(String(date))
},
}
}
const data = await prisma.divisionProject.groupBy({
where: kondisiProgress,
by: ["status"],
_count: true
})
const dataStatus = [{ name: 'Segera dikerjakan', status: 0 }, { name: 'Dikerjakan', status: 1 }, { name: 'Selesai dikerjakan', status: 2 }, { name: 'Dibatalkan', status: 3 }]
const hasilProgres: 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)
input = {
name: dataStatus[index].name,
value: find
}
} else {
input = {
name: dataStatus[index].name,
value: 0
}
}
hasilProgres.push(input)
}
// CHART DOKUMEN
let kondisi
if (division == "undefined") {
kondisi = {
isActive: true,
category: 'FILE',
Division: {
idGroup: String(group)
},
createdAt: {
lte: new Date(String(date))
},
}
} else {
kondisi = {
isActive: true,
category: 'FILE',
idDivision: String(division),
createdAt: {
lte: new Date(String(date))
},
}
}
const dataDokumen = await prisma.divisionDocumentFolderFile.findMany({
where: kondisi,
})
const groupData = _.map(_.groupBy(dataDokumen, "extension"), (v: any) => ({
file: v[0].extension,
jumlah: v.length,
}))
const image = ['jpg', 'jpeg', 'png', 'heic']
let hasilImage = {
name: 'Gambar',
value: 0
}
let hasilFile = {
name: 'Dokumen',
value: 0
}
groupData.map((v: any) => {
if (image.some((i: any) => i == v.file)) {
hasilImage = {
name: 'Gambar',
value: hasilImage.value + v.jumlah
}
} else {
hasilFile = {
name: 'Dokumen',
value: hasilFile.value + v.jumlah
}
}
})
const hasilDokumen = [hasilImage, hasilFile]
// CHART EVENT
let kondisiEvent
if (division == "undefined") {
kondisiEvent = {
isActive: true,
Division: {
idGroup: String(group)
},
dateStart: new Date(String(date))
}
} else {
kondisiEvent = {
isActive: true,
idDivision: String(division),
dateStart: new Date(String(date))
}
}
const dataEvent = await prisma.divisionCalendar.findMany({
where: kondisiEvent,
select: {
id: true,
idDivision: true,
title: true,
desc: true,
status: true,
timeStart: true,
dateStart: true,
timeEnd: true,
dateEnd: true,
createdAt: true,
User: {
select: {
name: true
}
}
},
orderBy: {
createdAt: 'desc'
}
})
const hasilEvent = dataEvent.map((v: any) => ({
..._.omit(v, ["User"]),
user_name: v.User.name,
timeStart: moment.utc(v.timeStart).format('HH:mm'),
timeEnd: moment.utc(v.timeEnd).format('HH:mm')
}))
const allData = {
progress: hasilProgres,
dokumen: hasilDokumen,
event: hasilEvent
}
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", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,152 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import _ from "lodash";
import { revalidatePath, revalidateTag } from "next/cache";
import { NextResponse } from "next/server";
// GET ALL DATA DIVISI == LIST DATA DIVISI
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 });
}
let grup
const villaId = user.idVillage
const roleUser = user.idUserRole
const { searchParams } = new URL(request.url);
const idGroup = searchParams.get("group");
const name = searchParams.get('search');
if (idGroup == "null" || idGroup == undefined) {
grup = user.idGroup
} else {
grup = idGroup
}
let kondisi: any = {
isActive: true,
idVillage: String(villaId),
idGroup: grup,
name: {
contains: (name == undefined || name == "null") ? "" : name,
mode: "insensitive"
}
}
if (roleUser != "supadmin" && roleUser != "cosupadmin" && roleUser != "admin") {
kondisi = {
isActive: true,
idVillage: String(villaId),
idGroup: grup,
name: {
contains: (name == undefined || name == "null") ? "" : name,
mode: "insensitive"
},
DivisionMember: {
some: {
isActive: true,
idUser: String(user.id)
}
}
}
}
const data = await prisma.division.findMany({
where: kondisi,
select: {
id: true,
name: true,
desc: true,
DivisionMember: {
where: {
isActive: true
},
select: {
idUser: true
}
}
}
});
const allData = data.map((v: any) => ({
..._.omit(v, ["DivisionMember"]),
jumlah_member: v.DivisionMember.length
}))
const filter = await prisma.group.findUnique({
where: {
id: grup
},
select: {
id: true,
name: true
}
})
return NextResponse.json({ success: true, message: "Berhasil mendapatkan divisi", data: allData, filter }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// CREATE DATA DIVISI
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 sent = (await request.json());
const villaId = user.idVillage
const data = await prisma.division.create({
data: {
name: sent.data.name,
idVillage: String(user.idVillage),
idGroup: sent.data.idGroup,
desc: sent.data.desc,
createdBy: String(user.id)
},
select: {
id: true
}
})
const dataMember = sent.member.map((v: any) => ({
..._.omit(v, ["idUser", "name", "img"]),
idUser: v.idUser,
idDivision: data.id,
isAdmin: sent.admin.some((i: any) => i == v.idUser)
}))
const insertMember = await prisma.divisionMember.createMany({
data: dataMember
})
revalidatePath('/api/divisi/', "page")
revalidatePath('/divisi', 'page')
revalidateTag('divisi')
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data divisi', table: 'division', data: data.id })
return NextResponse.json({ success: true, message: "Berhasil menambahkan divisi", data, }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menambahkan divisi, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};

View File

@@ -0,0 +1,202 @@
import { DIR, funCopyFile, prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import _ from "lodash";
import { NextResponse } from "next/server";
// MOVE ITEM
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 { path, dataItem } = (await request.json());
if (path != "home") {
const cekPath = await prisma.divisionDocumentFolderFile.count({
where: {
isActive: true,
id: path
}
})
if (cekPath == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan path, data tidak ditemukan" }, { status: 404 });
}
}
for (let i = 0; i < dataItem.length; i++) {
let status = false
let numb = 1
let name = dataItem[i].name
do {
const cekName = await prisma.divisionDocumentFolderFile.count({
where: {
path: path,
isActive: true,
extension: dataItem[i].extension,
name
}
})
if (cekName > 0) {
name = dataItem[i].name + " (" + numb + ")"
numb++
status = false
} else {
status = true
}
} while (status == false);
const id = dataItem[i].id;
const update = await prisma.divisionDocumentFolderFile.update({
where: {
id
},
data: {
path,
name
}
})
}
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User memindahkan file atau folder', table: 'divisionDocumentFolderFile', data: '' })
return NextResponse.json({ success: true, message: "Berhasil memindahkan item" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal memindahkan item, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};
// COPY ITEM
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 { idDivision, path, dataItem } = (await request.json());
if (path != "home") {
const cekPath = await prisma.divisionDocumentFolderFile.count({
where: {
isActive: true,
id: path
}
})
if (cekPath == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan path, data tidak ditemukan" }, { status: 404 });
}
}
for (let i = 0; i < dataItem.length; i++) {
let name = dataItem[i].name;
const category = dataItem[i].category;
const extension = dataItem[i].extension;
const idStorage = dataItem[i].idStorage;
const copyOnStorage = await funCopyFile({ fileId: idStorage, dirId: DIR.document })
if (copyOnStorage.success) {
let status = false
let numb = 1
do {
const cekName = await prisma.divisionDocumentFolderFile.count({
where: {
path: path,
isActive: true,
extension,
name
}
})
if (cekName > 0) {
name = dataItem[i].name + " (" + numb + ")"
numb++
status = false
} else {
status = true
}
} while (status == false);
const create = await prisma.divisionDocumentFolderFile.create({
data: {
name,
path,
idDivision,
category,
extension,
idStorage: copyOnStorage.data.id,
createdBy: user.id
},
select: {
id: true
}
})
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User menyalin file', table: 'divisionDocumentFolderFile', data: create.id })
}
}
return NextResponse.json({ success: true, message: "Berhasil salin item" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal salin item, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};
// SHARE ITEM
export async function DELETE(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 { dataDivision, dataItem } = (await request.json());
for (let i = 0; i < dataItem.length; i++) {
const del = await prisma.divisionDocumentShare.deleteMany({
where: {
idDocument: dataItem[i].id
}
})
const omitData = dataDivision.map((v: any) => ({
..._.omit(v, ["name", "id"]),
idDivision: v.id,
idDocument: dataItem[i].id
}))
const insert = await prisma.divisionDocumentShare.createMany({
data: omitData
})
}
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User membagikan item', table: 'divisionDocumentShare', data: '' })
return NextResponse.json({ success: true, message: "Berhasil membagikan item" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal membagikan item, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};

View File

@@ -0,0 +1,394 @@
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 ALL DOCUMENT
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 idDivision = searchParams.get("division");
const path = searchParams.get("path");
const category = searchParams.get("category");
const cekDivision = await prisma.division.count({
where: {
id: String(idDivision),
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
let statusAkses = false
let aksesPath = String(path)
if (path != "home" && path != "null" && path != "undefined" && path != "") {
const cekPath = await prisma.divisionDocumentFolderFile.count({
where: {
isActive: true,
id: String(path),
idDivision: String(idDivision)
}
})
const cekSharePath = await prisma.divisionDocumentShare.count({
where: {
isActive: true,
idDivision: String(idDivision),
idDocument: String(path)
}
})
if (cekPath == 0 && cekSharePath == 0) {
do {
const dataPath = await prisma.divisionDocumentFolderFile.findUnique({
where: {
id: String(aksesPath)
}
})
if (dataPath) {
const cekShare = await prisma.divisionDocumentShare.count({
where: {
isActive: true,
idDivision: String(idDivision),
idDocument: String(aksesPath)
}
})
if (cekShare == 0) {
statusAkses = false
aksesPath = dataPath.path
} else {
statusAkses = true
}
} else {
aksesPath = "home"
}
} while (aksesPath != "home" && statusAkses == false);
if (statusAkses == false) {
return NextResponse.json({ success: false, message: "Data tidak ditemukan / tidak memilik hak akses" }, { status: 404 });
}
}
}
let kondisi: any = {
isActive: true,
idDivision: String(idDivision),
path: (path == "undefined" || path == "null" || path == "" || path == null) ? "home" : path
}
let formatDataShare: any[] = [];
if (category == "folder") {
kondisi = {
isActive: true,
idDivision: String(idDivision),
path: (path == "undefined" || path == "null" || path == "" || path == null) ? "home" : path,
category: "FOLDER"
}
} else {
if (path == "home" || path == "null" || path == "undefined") {
const dataShare = await prisma.divisionDocumentShare.findMany({
where: {
isActive: true,
idDivision: String(idDivision),
},
select: {
DivisionDocumentFolderFile: {
select: {
id: true,
category: true,
name: true,
extension: true,
path: true,
User: {
select: {
name: true
}
},
createdAt: true,
updatedAt: true
}
}
}
})
formatDataShare = dataShare.map((v: any) => ({
..._.omit(v, ["DivisionDocumentFolderFile"]),
idStorage: '',
id: v.DivisionDocumentFolderFile.id,
category: v.DivisionDocumentFolderFile.category,
name: v.DivisionDocumentFolderFile.name,
extension: v.DivisionDocumentFolderFile.extension,
path: v.DivisionDocumentFolderFile.path,
createdBy: v.DivisionDocumentFolderFile.User.name,
createdAt: moment(v.DivisionDocumentFolderFile.createdAt).format("DD-MM-YYYY HH:mm"),
updatedAt: moment(v.DivisionDocumentFolderFile.updatedAt).format("DD-MM-YYYY HH:mm"),
share: true
}))
} else {
kondisi = {
isActive: true,
path: (path == "undefined" || path == "null" || path == null) ? "home" : path
}
}
}
const data = await prisma.divisionDocumentFolderFile.findMany({
where: kondisi,
select: {
id: true,
category: true,
name: true,
extension: true,
idStorage: true,
path: true,
User: {
select: {
name: true
}
},
createdAt: true,
updatedAt: true
},
orderBy: {
name: 'asc'
}
})
const allData = data.map((v: any) => ({
..._.omit(v, ["User", "createdAt", "updatedAt"]),
createdBy: v.User.name,
createdAt: moment(v.createdAt).format("DD-MM-YYYY HH:mm"),
updatedAt: moment(v.updatedAt).format("DD-MM-YYYY HH:mm"),
share: false
}))
if (formatDataShare.length > 0) {
allData.push(...formatDataShare)
}
const formatData = _.orderBy(allData, ['category', 'name'], ['desc', 'asc']);
let pathNow = path
let jalur = []
if (path != "home" && path != "null" && path != "undefined" && path != "") {
do {
const dataPath = await prisma.divisionDocumentFolderFile.findUnique({
where: {
id: String(pathNow)
}
})
if (dataPath && (dataPath.idDivision == idDivision || path == pathNow || pathNow == aksesPath)) {
const fix = {
id: String(pathNow),
name: dataPath.name,
}
jalur.push(fix)
pathNow = dataPath.path
} else {
pathNow = "home"
}
} while (pathNow != "home");
}
jalur.push({ id: 'home', name: 'home' })
jalur = [...jalur].reverse()
return NextResponse.json({ success: true, message: "Berhasil mendapatkan item", data: formatData, jalur }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan item, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// CREATE FOLDER
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 { name, path, idDivision } = (await request.json());
const cekDivision = await prisma.division.count({
where: {
id: String(idDivision),
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
if (path != "home") {
const cekPath = await prisma.divisionDocumentFolderFile.count({
where: {
isActive: true,
id: path
}
})
if (cekPath == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan path, data tidak ditemukan" }, { status: 404 });
}
}
const nameFile = await prisma.divisionDocumentFolderFile.count({
where: {
name,
idDivision,
path,
extension: "folder",
category: "FOLDER",
isActive: true
}
})
if (nameFile > 0) {
return NextResponse.json({ success: false, message: "Gagal membuat folder baru, folder sudah ada" }, { status: 400 });
}
const data = await prisma.divisionDocumentFolderFile.create({
data: {
name,
path,
idDivision,
category: "FOLDER",
extension: "folder",
createdBy: user.id,
},
select: {
id: true
}
});
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User membuat folder baru', table: 'divisionDocumentFolderFile', data: data.id })
return NextResponse.json({ success: true, message: "Berhasil membuat folder baru" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal membuat folder, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};
// RENAME ITEM
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 { name, id, path, idDivision, extension } = (await request.json());
const cekFile = await prisma.divisionDocumentFolderFile.count({
where: {
id: id,
isActive: true
}
})
if (cekFile == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan item, data tidak ditemukan" }, { status: 404 });
}
const nameFile = await prisma.divisionDocumentFolderFile.count({
where: {
name,
idDivision,
path,
extension,
isActive: true,
NOT: {
id: id
},
}
})
if (nameFile > 0) {
return NextResponse.json({ success: false, message: "Gagal mengubah nama item, item sudah ada" }, { status: 400 });
}
const update = await prisma.divisionDocumentFolderFile.update({
where: {
id: id
},
data: {
name,
}
})
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengubah nama file atau folder', table: 'divisionDocumentFolderFile', data: id })
return NextResponse.json({ success: true, message: "Berhasil mengubah nama item" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengubah nama item, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};
// DELETE ITEM
export async function DELETE(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 request.json()
for (let i = 0; i < data.length; i++) {
const id = data[i].id;
const cekFile = await prisma.divisionDocumentFolderFile.update({
where: {
id: id
},
data: {
isActive: false
}
})
}
// create log user
const log = await createLogUser({ act: 'DELETE', desc: 'User menghapus file atau folder', table: 'divisionDocumentFolderFile', data: '' })
return NextResponse.json({ success: true, message: "Berhasil menghapus item" }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menghapus item, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};

View File

@@ -0,0 +1,100 @@
import { DIR, funUploadFile, prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _ from "lodash";
import { NextResponse } from "next/server";
import fs from "fs";
import path from "path";
import { createLogUser } from "@/module/user";
// UPLOAD FILE
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 dataBody = body.get("data")
const file = body.get("file") as File
const fileName = file.name
const { idPath, idDivision } = JSON.parse(dataBody as string)
const cekDivision = await prisma.division.count({
where: {
id: String(idDivision),
isActive: true
}
})
if (cekDivision == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 });
}
if (idPath != "home") {
const cekPath = await prisma.divisionDocumentFolderFile.count({
where: {
isActive: true,
id: idPath
}
})
if (cekPath == 0) {
return NextResponse.json({ success: false, message: "Gagal mendapatkan path, data tidak ditemukan" }, { status: 404 });
}
}
const nameFile = await prisma.divisionDocumentFolderFile.findMany({
where: {
idDivision,
path: idPath,
category: "FILE",
isActive: true
}
})
const dataOmit = nameFile.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: "Terdapat file dengan nama yang sama" }, { status: 400 });
}
const fExt = file.name.split(".").pop()
const fName = file.name.replace("." + fExt, "")
const upload = await funUploadFile({ file: file, dirId: DIR.document })
if (upload.success) {
const dataInsert = await prisma.divisionDocumentFolderFile.create({
data: {
name: fName,
path: idPath,
idDivision,
category: "FILE",
extension: String(fExt),
createdBy: user.id,
idStorage: upload.data.id
},
select: {
id: true
}
});
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User mengupload file baru', table: 'divisionDocumentFolderFile', data: dataInsert.id })
return NextResponse.json({ success: true, message: "Berhasil upload file" }, { status: 200 });
} else {
return NextResponse.json({ success: false, message: "Gagal upload file, coba lagi nanti" }, { status: 400 });
}
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal upload file, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};

View File

@@ -0,0 +1,23 @@
import { NextRequest, NextResponse } from "next/server"
import fs from 'fs'
export async function GET(request: Request) {
let fl;
try {
const { searchParams } = new URL(request.url);
const kategori = searchParams.get('cat');
const file = searchParams.get('file');
const jenis = searchParams.get('jenis');
fl = fs.readFileSync(`./public/${jenis}/${kategori}/${file}`)
} catch (err: any) {
throw err;
}
return new NextResponse(fl, {
headers: {
"Content-Type": "image/png"
}
})
}

View File

@@ -0,0 +1,133 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import { NextResponse } from "next/server";
export const dynamic = 'force-dynamic'
export const revalidate = true
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.group.findUnique({
where: {
id: id,
},
});
if (!data) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan grup, data tidak ditemukan",
},
{ status: 404 }
);
}
return NextResponse.json(
{
success: true,
message: "Berhasil mendapatkan grup",
data,
},
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan grup, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
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.group.count({
where: {
id: id,
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Edit grup gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const update = await prisma.group.update({
where: {
id: id,
},
data: {
isActive: !isActive,
},
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengedit status data grup', table: 'group', data: id })
return NextResponse.json( { success: true, message: "Grup berhasil diedit", data, }, { status: 200 } );
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengedit grup, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
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.group.count({
where: {
id: id,
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Edit grup gagal, data tidak ditemukan",
},
{ status: 404 }
);
}
const update = await prisma.group.update({
where: {
id: id,
},
data: {
name: name,
},
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengedit data grup', table: 'group', data: id })
return NextResponse.json( { success: true, message: "Grup berhasil diedit", data, }, { status: 200 } );
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengedit grup, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,49 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { NextResponse } from "next/server";
export const dynamic = 'force-dynamic'
export const revalidate = true
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 role = user.idUserRole
const villaId = user.idVillage
const group = user.idGroup
let kondisi: any = {
isActive: true,
idVillage: String(villaId)
}
if (role != "supadmin") {
kondisi = {
isActive: true,
idVillage: String(villaId),
id: String(group)
}
}
const data = await prisma.group.findMany({
where: kondisi,
select: {
id: true,
name: true,
Division: {
select: {
id: true,
name: true
}
}
}
});
return NextResponse.json({ success: true, message: "Berhasil mendapatkan grup", data, }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan grup, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,79 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import { revalidatePath, revalidateTag } from "next/cache";
import { NextResponse } from "next/server";
export const dynamic = 'force-dynamic'
export const revalidate = true
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 villaId = user.idVillage
const { searchParams } = new URL(request.url);
const isActive = searchParams.get("active");
const name = searchParams.get('search');
const data = await prisma.group.findMany({
where: {
isActive: isActive == 'false' ? false : true,
idVillage: String(villaId),
name: {
contains: (name == undefined || name == null) ? "" : name,
mode: "insensitive"
}
},
select: {
id: true,
name: true,
isActive: true
}
});
return NextResponse.json({ success: true, message: "Berhasil mendapatkan grup", data, }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan grup, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
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 { name } = (await request.json());
const villaId = user.idVillage
const data = await prisma.group.create({
data: {
name,
idVillage: String(villaId)
},
select: {
id: true
}
});
revalidatePath('/api/group?active=true', "page")
revalidatePath('/api/group?active=false', 'page')
revalidatePath('/group?active=true', 'page')
revalidateTag('group')
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data grup', table: 'group', data: data.id })
return NextResponse.json({ success: true, message: "Berhasil menambahkan grup", data, }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menambahkan grup, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
};

370
src/app/api/home/route.ts Normal file
View File

@@ -0,0 +1,370 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } 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 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 roleUser = user.idUserRole
const idVillage = user.idVillage
const idGroup = user.idGroup
if (kategori == "kegiatan") {
let kondisi
// klo perbekel == semua grup
if (roleUser == "supadmin") {
kondisi = {
isActive: true,
idVillage: idVillage,
Group: {
isActive: true,
}
}
} else {
kondisi = {
isActive: true,
idGroup: idGroup
}
}
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 == semua grup
if (roleUser == "supadmin") {
kondisi = {
isActive: true,
idVillage: idVillage,
Group: {
isActive: true,
}
}
} else {
kondisi = {
isActive: true,
idGroup: idGroup
}
}
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 == semua grup
if (roleUser == "supadmin") {
kondisi = {
isActive: true,
Division: {
idVillage: idVillage,
Group: {
isActive: true,
}
}
}
} else {
kondisi = {
isActive: true,
Division: {
idGroup: idGroup
}
}
}
const data = await prisma.divisionProject.groupBy({
where: kondisi,
by: ["status"],
_count: true
})
const dataStatus = [{ name: 'Segera dikerjakan', status: 0 }, { name: 'Dikerjakan', status: 1 }, { name: 'Selesai dikerjakan', status: 2 }, { name: 'Dibatalkan', status: 3 }]
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)
input = {
name: dataStatus[index].name,
value: find
}
} else {
input = {
name: dataStatus[index].name,
value: 0
}
}
hasil.push(input)
}
allData = hasil
} else if (kategori == "dokumen") {
let kondisi
// klo perbekel == semua grup
if (roleUser == "supadmin") {
kondisi = {
isActive: true,
category: 'FILE',
Division: {
idVillage: idVillage,
Group: {
isActive: true,
}
}
}
} else {
kondisi = {
isActive: true,
category: 'FILE',
Division: {
idGroup: idGroup
}
}
}
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 = {
name: 'Gambar',
value: 0
}
let hasilFile = {
name: 'Dokumen',
value: 0
}
groupData.map((v: any) => {
if (image.some((i: any) => i == v.file)) {
hasilImage = {
name: 'Gambar',
value: hasilImage.value + v.jumlah
}
} else {
hasilFile = {
name: 'Dokumen',
value: hasilFile.value + v.jumlah
}
}
})
allData = [hasilImage, hasilFile]
} else if (kategori == "event") {
let kondisi
// klo perbekel == semua grup
if (roleUser == "supadmin") {
kondisi = {
isActive: true,
dateStart: new Date(),
Division: {
idVillage: idVillage,
Group: {
isActive: true,
}
},
DivisionCalendar: {
isActive: true
},
}
} else {
kondisi = {
isActive: true,
dateStart: new Date(),
Division: {
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,
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 == semua grup
if (roleUser == "supadmin") {
kondisi = {
isActive: true,
status: 1,
Division: {
idVillage: idVillage,
Group: {
isActive: true,
}
}
}
} else {
kondisi = {
isActive: true,
status: 1,
Division: {
idGroup: idGroup
}
}
}
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.dateStart).format("ll"),
user: v.User.name
}))
}
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 99", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,141 @@
// SEARCH USER, DIVISION, PROJECT
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import _ from "lodash";
import { NextResponse } from "next/server";
export async function GET(request: Request) {
try {
const { searchParams } = new URL(request.url)
const search = searchParams.get("search")
const userId = await funGetUserByCookies()
if (userId.id == undefined) {
return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 });
}
let kondisi: any, kondisiProject: any
// klo perbekel == semua grup
if (userId.idUserRole == "supadmin") {
kondisi = {
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"
}
}
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: kondisi,
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) {
return NextResponse.json({ success: false, message: error }, { status: 500 });
}
}

View File

@@ -0,0 +1,141 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import { revalidatePath } from "next/cache";
import { NextResponse } from "next/server";
// GET ONE JABATAN
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.position.findUnique({
where: {
id: id,
},
select: {
id: true,
name: true,
idGroup: true,
},
});
if (!data) {
return NextResponse.json(
{
success: false,
message: "Gagal mendapatkan jabatan, data tidak ditemukan",
},
{ status: 404 }
);
}
return NextResponse.json(
{
success: true,
message: "Berhasil mendapatkan jabatan",
data,
},
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan jabatan, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// DELETE / ACTIVE & NON ACTIVE POSITION
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.position.count({
where: {
id: id,
},
});
if (data == 0) {
return NextResponse.json(
{
success: false,
message: "Gagal mengubah status jabatan, data tidak ditemukan",
},
{ status: 404 }
);
}
const update = await prisma.position.update({
where: {
id: id,
},
data: {
isActive: !isActive,
},
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate status data jabatan', table: 'position', data: id })
return NextResponse.json(
{ success: true, message: "Berhasil mengubah status jabatan" },
{ status: 200 }
);
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengubah status jabatan, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// UPDATE POSITION
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 data = await request.json();
const cek = await prisma.position.count({
where: {
name: data.name,
idGroup: data.idGroup,
NOT: {
id: id
}
},
});
if (cek == 0) {
const positions = await prisma.position.update({
where: {
id: id,
},
data: {
name: data.name,
// idGroup: data.idGroup,
},
});
// create log user
const log = await createLogUser({ act: 'UPDATE', desc: 'User mengupdate data jabatan', table: 'position', data: id })
return NextResponse.json({ success: true, message: "Berhasil mengedit jabatan", }, { status: 200 });
} else {
return NextResponse.json(
{ success: false, message: "Jabatan sudah ada" },
{ status: 400 }
);
}
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mengedit jabatan, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

View File

@@ -0,0 +1,139 @@
import { prisma } from "@/module/_global";
import { funGetUserByCookies } from "@/module/auth";
import { createLogUser } from "@/module/user";
import _ from "lodash";
import { revalidatePath, revalidateTag } from "next/cache";
import { NextResponse } from "next/server";
// GET ALL POSITION
export async function GET(request: Request) {
try {
let grup
const { searchParams } = new URL(request.url);
const idGroup = searchParams.get("group");
const active = searchParams.get('active');
const name = searchParams.get('search')
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) {
grup = user.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 jabatan, data tidak ditemukan", }, { status: 404 });
}
const filter = await prisma.group.findUnique({
where: {
id: grup
},
select: {
id: true,
name: true
}
})
const positions = await prisma.position.findMany({
where: {
idGroup: grup,
isActive: active == 'false' ? false : true,
name: {
contains: (name == undefined || name == null) ? "" : name,
mode: "insensitive"
}
},
select: {
id: true,
name: true,
isActive: true,
Group: {
select: {
name: true
}
}
},
});
const allData = positions.map((v: any) => ({
..._.omit(v, ["Group"]),
group: v.Group.name
}))
return NextResponse.json({ success: true, message: "Berhasil mendapatkan jabatan", data: allData, filter }, { status: 200 });
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal mendapatkan jabatan, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}
// CREATE POSITION
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 { name, idGroup } = await request.json();
let groupFix = idGroup
if (groupFix == null || groupFix == undefined || groupFix == "") {
groupFix = user.idGroup
}
const cek = await prisma.position.count({
where: {
name: name,
idGroup: groupFix,
},
});
if (cek == 0) {
const positions = await prisma.position.create({
data: {
name: name,
idGroup: groupFix,
},
select: {
id: true,
name: true,
},
});
revalidatePath('/api/position?active=true', "page")
revalidatePath('/api/position?active=false', 'page')
revalidatePath('/position?active=true', 'page')
revalidateTag('position')
// create log user
const log = await createLogUser({ act: 'CREATE', desc: 'User membuat data jabatan baru', table: 'position', data: positions.id })
return NextResponse.json({ success: true, message: "Berhasil menambahkan jabatan", positions, }, { status: 200 });
} else {
return NextResponse.json(
{ success: false, message: "Jabatan sudah ada" },
{ status: 400 }
);
}
} catch (error) {
console.error(error);
return NextResponse.json({ success: false, message: "Gagal menambahkan jabatan, coba lagi nanti", reason: (error as Error).message, }, { status: 500 });
}
}

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