From e20f5c11e43e1e617a354c3138f5678c887cf7f7 Mon Sep 17 00:00:00 2001 From: amal Date: Mon, 29 Sep 2025 17:23:44 +0800 Subject: [PATCH 01/32] upd : typo kata Deskripsi: - Silahkan menjadi silakan :: tanpa h No Issues --- src/app/api/announcement/route.ts | 6 +++--- src/app/api/discussion-general/route.ts | 4 ++-- src/app/api/discussion/route.ts | 8 ++++---- src/app/api/division/route.ts | 8 ++++---- src/app/api/mobile/announcement/route.ts | 8 ++++---- src/app/api/mobile/discussion-general/route.ts | 6 +++--- src/app/api/mobile/discussion/route.ts | 10 +++++----- src/app/api/mobile/division/route.ts | 10 +++++----- src/app/api/mobile/project/route.ts | 10 +++++----- src/app/api/mobile/task/route.ts | 10 +++++----- src/app/api/project/route.ts | 8 ++++---- src/app/api/task/route.ts | 8 ++++---- src/module/announcement/lib/api_announcement.ts | 8 ++++---- src/module/announcement/ui/create_announcement.tsx | 2 +- src/module/banner/ui/create_banner.tsx | 2 +- .../calender/ui/create_calender_division_caleder.tsx | 2 +- src/module/calender/ui/create_user_calender.tsx | 2 +- src/module/calender/ui/create_user_detail_calender.tsx | 2 +- src/module/calender/ui/update_division_calender.tsx | 4 ++-- src/module/calender/ui/update_list_users.tsx | 2 +- src/module/discussion_general/ui/add_member.tsx | 2 +- src/module/discussion_general/ui/choose_user.tsx | 2 +- src/module/discussion_general/ui/create_discussion.tsx | 2 +- src/module/division_new/ui/create_anggota_division.tsx | 2 +- src/module/division_new/ui/create_division.tsx | 4 ++-- src/module/division_new/ui/navbar_admin_division.tsx | 2 +- src/module/division_new/ui/navbar_create_users.tsx | 2 +- src/module/project/ui/add_file_detail_project.tsx | 2 +- src/module/project/ui/add_member_detail_project.tsx | 2 +- src/module/project/ui/create_project.tsx | 4 ++-- src/module/project/ui/create_users_project.tsx | 2 +- src/module/task/ui/add_file_detail_task.tsx | 2 +- src/module/task/ui/add_member_detail_task.tsx | 2 +- src/module/task/ui/create_task.tsx | 4 ++-- src/module/task/ui/create_users_project.tsx | 2 +- 35 files changed, 78 insertions(+), 78 deletions(-) diff --git a/src/app/api/announcement/route.ts b/src/app/api/announcement/route.ts index 63270d1..0c1cdda 100644 --- a/src/app/api/announcement/route.ts +++ b/src/app/api/announcement/route.ts @@ -184,7 +184,7 @@ export async function POST(request: Request) { category: 'announcement', idContent: data.id, title: 'Pengumuman Baru', - desc: 'Anda memiliki pengumuman baru. Silahkan periksa detailnya.' + desc: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' })) const dataPush = memberNotif.map((v: any) => ({ @@ -217,7 +217,7 @@ export async function POST(request: Request) { category: 'announcement', idContent: data.id, title: 'Pengumuman Baru', - desc: 'Anda memiliki pengumuman baru. Silahkan periksa detailnya.' + desc: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -229,7 +229,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: 'Anda memiliki pengumuman baru. Silahkan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/app/api/discussion-general/route.ts b/src/app/api/discussion-general/route.ts index 45ad8c2..ae383a6 100644 --- a/src/app/api/discussion-general/route.ts +++ b/src/app/api/discussion-general/route.ts @@ -147,7 +147,7 @@ export async function POST(request: Request) { category: 'discussion', idContent: data.id, title: 'Diskusi Umum Baru', - desc: 'Terdapat diskusi umum baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi umum baru. Silakan periksa detailnya.' })) if (userRoleLogin != "supadmin") { @@ -173,7 +173,7 @@ export async function POST(request: Request) { category: 'discussion', idContent: data.id, title: 'Diskusi Umum Baru', - desc: 'Terdapat diskusi umum baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi umum baru. Silakan periksa detailnya.' }) } diff --git a/src/app/api/discussion/route.ts b/src/app/api/discussion/route.ts index b3e4531..582163a 100644 --- a/src/app/api/discussion/route.ts +++ b/src/app/api/discussion/route.ts @@ -157,7 +157,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' })) const dataPush = memberDivision.map((v: any) => ({ @@ -189,7 +189,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -221,7 +221,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -232,7 +232,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat diskusi baru. Silahkan periksa detailnya.', title: 'Diskusi Baru' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat diskusi baru. Silakan periksa detailnya.', title: 'Diskusi Baru' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/app/api/division/route.ts b/src/app/api/division/route.ts index 51d2e5f..672467c 100644 --- a/src/app/api/division/route.ts +++ b/src/app/api/division/route.ts @@ -174,7 +174,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silahkan periksa detailnya.' + desc: 'Terdapat divisi baru. Silakan periksa detailnya.' })) const selectUser = await prisma.divisionMember.findMany({ @@ -225,7 +225,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silahkan periksa detailnya.' + desc: 'Terdapat divisi baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -262,7 +262,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silahkan periksa detailnya.' + desc: 'Terdapat divisi baru. Silakan periksa detailnya.' })) const omitPush = atasanGroup.map((v: any) => ({ @@ -279,7 +279,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: 'Terdapat divisi baru. Silahkan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: 'Terdapat divisi baru. Silakan periksa detailnya.' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/app/api/mobile/announcement/route.ts b/src/app/api/mobile/announcement/route.ts index 83b2c88..478ae4a 100644 --- a/src/app/api/mobile/announcement/route.ts +++ b/src/app/api/mobile/announcement/route.ts @@ -203,7 +203,7 @@ export async function POST(request: Request) { category: 'announcement', idContent: data.id, title: 'Pengumuman Baru', - desc: 'Anda memiliki pengumuman baru. Silahkan periksa detailnya.' + desc: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' })) @@ -244,7 +244,7 @@ export async function POST(request: Request) { category: 'announcement', idContent: data.id, title: 'Pengumuman Baru', - desc: 'Anda memiliki pengumuman baru. Silahkan periksa detailnya.' + desc: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -258,7 +258,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: 'Anda memiliki pengumuman baru. Silahkan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -267,7 +267,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Pengumuman Baru", - body: "Anda memiliki pengumuman baru. Silahkan periksa detailnya.", + body: "Anda memiliki pengumuman baru. Silakan periksa detailnya.", data: { id: data.id, category: "announcement", content: data.id } }) diff --git a/src/app/api/mobile/discussion-general/route.ts b/src/app/api/mobile/discussion-general/route.ts index 285ef8f..6fd308c 100644 --- a/src/app/api/mobile/discussion-general/route.ts +++ b/src/app/api/mobile/discussion-general/route.ts @@ -172,7 +172,7 @@ export async function POST(request: Request) { category: 'discussion', idContent: data.id, title: 'Diskusi Umum Baru', - desc: 'Terdapat diskusi umum baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi umum baru. Silakan periksa detailnya.' })) if (userRoleLogin != "supadmin") { @@ -205,7 +205,7 @@ export async function POST(request: Request) { category: 'discussion', idContent: data.id, title: 'Diskusi Umum Baru', - desc: 'Terdapat diskusi umum baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi umum baru. Silakan periksa detailnya.' }) } @@ -219,7 +219,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Diskusi Umum Baru", - body: "Anda memiliki diskusi umum baru. Silahkan periksa detailnya.", + body: "Anda memiliki diskusi umum baru. Silakan periksa detailnya.", data: { id: data.id, category: "discussion", content: data.id } }) diff --git a/src/app/api/mobile/discussion/route.ts b/src/app/api/mobile/discussion/route.ts index e32d27d..0553ab4 100644 --- a/src/app/api/mobile/discussion/route.ts +++ b/src/app/api/mobile/discussion/route.ts @@ -173,7 +173,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' })) const dataPush = memberDivision.map((v: any) => ({ @@ -212,7 +212,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -251,7 +251,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silahkan periksa detailnya.' + desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -264,7 +264,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat diskusi baru. Silahkan periksa detailnya.', title: 'Diskusi Baru' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat diskusi baru. Silakan periksa detailnya.', title: 'Diskusi Baru' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -274,7 +274,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Diskusi Baru", - body: "Anda memiliki diskusi baru. Silahkan periksa detailnya.", + body: "Anda memiliki diskusi baru. Silakan periksa detailnya.", data: { id: data.id, category: "division/" + idDivision + "/discussion", content: data.id } }) diff --git a/src/app/api/mobile/division/route.ts b/src/app/api/mobile/division/route.ts index 5803958..8f79bde 100644 --- a/src/app/api/mobile/division/route.ts +++ b/src/app/api/mobile/division/route.ts @@ -183,7 +183,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silahkan periksa detailnya.' + desc: 'Terdapat divisi baru. Silakan periksa detailnya.' })) const selectUser = await prisma.divisionMember.findMany({ @@ -252,7 +252,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silahkan periksa detailnya.' + desc: 'Terdapat divisi baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -299,7 +299,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silahkan periksa detailnya.' + desc: 'Terdapat divisi baru. Silakan periksa detailnya.' })) const omitPush = atasanGroup.map((v: any) => ({ @@ -317,7 +317,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: 'Terdapat divisi baru. Silahkan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: 'Terdapat divisi baru. Silakan periksa detailnya.' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -326,7 +326,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Divisi Baru", - body: "Anda memiliki divisi baru. Silahkan periksa detailnya.", + body: "Anda memiliki divisi baru. Silakan periksa detailnya.", data: { id: data.id, category: "division", content: data.id } }) diff --git a/src/app/api/mobile/project/route.ts b/src/app/api/mobile/project/route.ts index 0ed08bc..252b743 100644 --- a/src/app/api/mobile/project/route.ts +++ b/src/app/api/mobile/project/route.ts @@ -284,7 +284,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' })) const dataPush = memberNotif.map((v: any) => ({ @@ -323,7 +323,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -370,7 +370,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' })) const omitPush = atasanGroup.map((v: any) => ({ @@ -387,7 +387,7 @@ export async function POST(request: Request) { const dataNotifFilter = dataNotif.filter((item) => item.idUserTo != undefined && item.idUserTo != null && item.idUserTo != "" && item.idUserTo != userId) const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: 'Terdapat kegiatan baru. Silakan periksa detailnya.' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -396,7 +396,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Kegiatan Baru", - body: "Anda memiliki kegiatan baru. Silahkan periksa detailnya.", + body: "Anda memiliki kegiatan baru. Silakan periksa detailnya.", data: { id: data.id, category: "project", content: data.id } }) diff --git a/src/app/api/mobile/task/route.ts b/src/app/api/mobile/task/route.ts index e5cea77..7b8bde7 100644 --- a/src/app/api/mobile/task/route.ts +++ b/src/app/api/mobile/task/route.ts @@ -268,7 +268,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/task', idContent: data.id, title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + desc: 'Terdapat tugas baru. Silakan periksa detailnya.' })) const dataPush = memberDivision.map((v: any) => ({ @@ -307,7 +307,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/task', idContent: data.id, title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + desc: 'Terdapat tugas baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -346,7 +346,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/task', idContent: data.id, title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + desc: 'Terdapat tugas baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -358,7 +358,7 @@ export async function POST(request: Request) { const dataNotifFilter = dataNotif.filter((v: any) => v.idUserTo != undefined && v.idUserTo != null && v.idUserTo != "" && v.idUserTo != userId) const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat tugas baru. Silahkan periksa detailnya.', title: 'Tugas Baru' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat tugas baru. Silakan periksa detailnya.', title: 'Tugas Baru' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -367,7 +367,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Tugas Baru", - body: "Anda memiliki tugas baru. Silahkan periksa detailnya.", + body: "Anda memiliki tugas baru. Silakan periksa detailnya.", data: { id: data.id, category: 'division/' + idDivision + '/task', content: data.id } }) diff --git a/src/app/api/project/route.ts b/src/app/api/project/route.ts index d4e6652..598d11a 100644 --- a/src/app/api/project/route.ts +++ b/src/app/api/project/route.ts @@ -262,7 +262,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' })) const dataPush = memberNotif.map((v: any) => ({ @@ -294,7 +294,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -330,7 +330,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' + desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' })) const omitPush = atasanGroup.map((v: any) => ({ @@ -346,7 +346,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: 'Terdapat kegiatan baru. Silahkan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: 'Terdapat kegiatan baru. Silakan periksa detailnya.' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/app/api/task/route.ts b/src/app/api/task/route.ts index 976b941..ba2d4f3 100644 --- a/src/app/api/task/route.ts +++ b/src/app/api/task/route.ts @@ -254,7 +254,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/task', idContent: data.id, title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + desc: 'Terdapat tugas baru. Silakan periksa detailnya.' })) const dataPush = memberDivision.map((v: any) => ({ @@ -286,7 +286,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/task', idContent: data.id, title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + desc: 'Terdapat tugas baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -318,7 +318,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/task', idContent: data.id, title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silahkan periksa detailnya.' + desc: 'Terdapat tugas baru. Silakan periksa detailnya.' }) dataPush.push({ @@ -329,7 +329,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat tugas baru. Silahkan periksa detailnya.', title: 'Tugas Baru' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat tugas baru. Silakan periksa detailnya.', title: 'Tugas Baru' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/module/announcement/lib/api_announcement.ts b/src/module/announcement/lib/api_announcement.ts index 58e95f5..ef3f11b 100644 --- a/src/module/announcement/lib/api_announcement.ts +++ b/src/module/announcement/lib/api_announcement.ts @@ -12,10 +12,10 @@ export const funGetAnnouncementById = async (path: string) => { export const funCreateAnnouncement = async (data: IFormCreateAnnouncement) => { if (data.title == "" || data.desc == "") - return { success: false, message: 'Silahkan lengkapi form tambah pengumuman' } + return { success: false, message: 'Silakan lengkapi form tambah pengumuman' } if (data.groups.length == 0) - return { success: false, message: 'Silahkan pilih divisi penerima pengumuman' } + return { success: false, message: 'Silakan pilih divisi penerima pengumuman' } const response = await fetch("/api/announcement", { method: "POST", @@ -39,10 +39,10 @@ export const funDeleteAnnouncement = async (path: string) => { export const funEditAnnouncement = async (path: string, data: IFormCreateAnnouncement) => { if (data.title == "" || data.desc == "") - return { success: false, message: 'Silahkan lengkapi form edit pengumuman' } + return { success: false, message: 'Silakan lengkapi form edit pengumuman' } if (data.groups.length == 0) - return { success: false, message: 'Silahkan pilih divisi penerima pengumuman' } + return { success: false, message: 'Silakan pilih divisi penerima pengumuman' } const response = await fetch(`/api/announcement/${path}`, { method: "PUT", diff --git a/src/module/announcement/ui/create_announcement.tsx b/src/module/announcement/ui/create_announcement.tsx index 8163b82..3b48a36 100644 --- a/src/module/announcement/ui/create_announcement.tsx +++ b/src/module/announcement/ui/create_announcement.tsx @@ -102,7 +102,7 @@ export default function CreateAnnouncement() { return false if (memberValue.length == 0) - return toast.error("Error! silahkan pilih divisi") + return toast.error("Error! Silakan pilih divisi") setOpen(true) }, 500) diff --git a/src/module/banner/ui/create_banner.tsx b/src/module/banner/ui/create_banner.tsx index 0364387..db83e09 100644 --- a/src/module/banner/ui/create_banner.tsx +++ b/src/module/banner/ui/create_banner.tsx @@ -180,7 +180,7 @@ function CreateBanner() { {touched.image && !imgForm && ( - Silahkan Pilih Gambar + Silakan Pilih Gambar )} diff --git a/src/module/calender/ui/create_calender_division_caleder.tsx b/src/module/calender/ui/create_calender_division_caleder.tsx index f92c985..30e996b 100644 --- a/src/module/calender/ui/create_calender_division_caleder.tsx +++ b/src/module/calender/ui/create_calender_division_caleder.tsx @@ -135,7 +135,7 @@ export default function CreateCalenderDivisionCaleder() { return false if (memberValue.length == 0) - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") setModal(true) } diff --git a/src/module/calender/ui/create_user_calender.tsx b/src/module/calender/ui/create_user_calender.tsx index 32edcea..789b1f5 100644 --- a/src/module/calender/ui/create_user_calender.tsx +++ b/src/module/calender/ui/create_user_calender.tsx @@ -79,7 +79,7 @@ export default function CreateUserCalender({ onClose }: { onClose: (val: any) => function onSubmit() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } member.set(selectedFiles) onClose(true) diff --git a/src/module/calender/ui/create_user_detail_calender.tsx b/src/module/calender/ui/create_user_detail_calender.tsx index 1d57395..74e09f0 100644 --- a/src/module/calender/ui/create_user_detail_calender.tsx +++ b/src/module/calender/ui/create_user_detail_calender.tsx @@ -92,7 +92,7 @@ export default function CreateUserDetailCalender() { async function onSubmit() { try { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } setLoadingSubmit(true) const res = await funAddMemberCalender(String(isDataCalender?.idCalendar), selectedFiles) diff --git a/src/module/calender/ui/update_division_calender.tsx b/src/module/calender/ui/update_division_calender.tsx index 9a53bed..70de11d 100644 --- a/src/module/calender/ui/update_division_calender.tsx +++ b/src/module/calender/ui/update_division_calender.tsx @@ -43,7 +43,7 @@ export default function UpdateDivisionCalender() { } } catch (error) { console.error(error) - toast.error("Terjadi kesalahan! Silahkan coba kembali"); + toast.error("Terjadi kesalahan! Silakan coba kembali"); } finally { setLoading(false) } @@ -84,7 +84,7 @@ export default function UpdateDivisionCalender() { } } catch (error) { console.error(error) - toast.error("Terjadi kesalahan! Silahkan coba kembali"); + toast.error("Terjadi kesalahan! Silakan coba kembali"); } finally { setModal(false) setLoadingModal(false) diff --git a/src/module/calender/ui/update_list_users.tsx b/src/module/calender/ui/update_list_users.tsx index c59a38b..d7aeef4 100644 --- a/src/module/calender/ui/update_list_users.tsx +++ b/src/module/calender/ui/update_list_users.tsx @@ -82,7 +82,7 @@ export default function UpdateListUsers({ onClose }: { onClose: (val: any) => vo function onSubmit() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } member.set(selectedFiles) onClose(true) diff --git a/src/module/discussion_general/ui/add_member.tsx b/src/module/discussion_general/ui/add_member.tsx index 11a7b8a..da0d615 100644 --- a/src/module/discussion_general/ui/add_member.tsx +++ b/src/module/discussion_general/ui/add_member.tsx @@ -101,7 +101,7 @@ export default function AddMemberDiscussionGeneral() { function onCheck() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } setOpen(true) } diff --git a/src/module/discussion_general/ui/choose_user.tsx b/src/module/discussion_general/ui/choose_user.tsx index e8c7c41..f45a613 100644 --- a/src/module/discussion_general/ui/choose_user.tsx +++ b/src/module/discussion_general/ui/choose_user.tsx @@ -57,7 +57,7 @@ export default function ChooseUsersDiscussion({ grup, onClose }: { grup?: string function onSubmit() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } member.set(selectedFiles) onClose(true) diff --git a/src/module/discussion_general/ui/create_discussion.tsx b/src/module/discussion_general/ui/create_discussion.tsx index 87e3c3a..0ac648f 100644 --- a/src/module/discussion_general/ui/create_discussion.tsx +++ b/src/module/discussion_general/ui/create_discussion.tsx @@ -74,7 +74,7 @@ export default function FormCreateDiscussionGeneral() { return false if (memberValue.length <= 1) - return toast.error("Error! Silahkan pilih anggota lebih dari 1") + return toast.error("Error! Silakan pilih anggota lebih dari 1") setModal(true) } diff --git a/src/module/division_new/ui/create_anggota_division.tsx b/src/module/division_new/ui/create_anggota_division.tsx index 91ba45b..dbb74d7 100644 --- a/src/module/division_new/ui/create_anggota_division.tsx +++ b/src/module/division_new/ui/create_anggota_division.tsx @@ -99,7 +99,7 @@ export default function CreateAnggotaDivision() { function onCheck() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } setOpen(true) } diff --git a/src/module/division_new/ui/create_division.tsx b/src/module/division_new/ui/create_division.tsx index ec73fac..e02ec8f 100644 --- a/src/module/division_new/ui/create_division.tsx +++ b/src/module/division_new/ui/create_division.tsx @@ -51,9 +51,9 @@ export default function CreateDivision() { return false if (member.length == 0) - return toast.error("Error! Silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") // if (member.length <= 1) - // return toast.error("Error! Silahkan pilih anggota lebih dari 1") + // return toast.error("Error! Silakan pilih anggota lebih dari 1") setChooseAdmin(true) } diff --git a/src/module/division_new/ui/navbar_admin_division.tsx b/src/module/division_new/ui/navbar_admin_division.tsx index 09e8bc4..8b5c362 100644 --- a/src/module/division_new/ui/navbar_admin_division.tsx +++ b/src/module/division_new/ui/navbar_admin_division.tsx @@ -24,7 +24,7 @@ export default function NavbarAdminDivision({ data, onSuccess }: { data: any, on async function onSubmit() { if (value.length === 0) { - return toast.error("Error! Silahkan pilih admin divisi") + return toast.error("Error! Silakan pilih admin divisi") } try { diff --git a/src/module/division_new/ui/navbar_create_users.tsx b/src/module/division_new/ui/navbar_create_users.tsx index 83e61de..1571f20 100644 --- a/src/module/division_new/ui/navbar_create_users.tsx +++ b/src/module/division_new/ui/navbar_create_users.tsx @@ -53,7 +53,7 @@ export default function NavbarCreateUsers({ grup, onClose }: { grup?: string, on function onSubmit() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } member.set(selectedFiles) onClose(true) diff --git a/src/module/project/ui/add_file_detail_project.tsx b/src/module/project/ui/add_file_detail_project.tsx index f557e4b..9f447cf 100644 --- a/src/module/project/ui/add_file_detail_project.tsx +++ b/src/module/project/ui/add_file_detail_project.tsx @@ -171,7 +171,7 @@ export default function AddFileDetailProject() { if (fileForm.length > 0) { setOpenModal(true) } else { - toast.error("Silahkan pilih file yang akan diupload") + toast.error("Silakan pilih file yang akan diupload") } }}> Simpan diff --git a/src/module/project/ui/add_member_detail_project.tsx b/src/module/project/ui/add_member_detail_project.tsx index 0f50504..a448424 100644 --- a/src/module/project/ui/add_member_detail_project.tsx +++ b/src/module/project/ui/add_member_detail_project.tsx @@ -91,7 +91,7 @@ export default function AddMemberDetailProject() { function onVerifikasi() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } setOpenModal(true) diff --git a/src/module/project/ui/create_project.tsx b/src/module/project/ui/create_project.tsx index 069536a..0f68d9a 100644 --- a/src/module/project/ui/create_project.tsx +++ b/src/module/project/ui/create_project.tsx @@ -142,10 +142,10 @@ export default function CreateProject() { return false if (dataTask.length == 0) - return toast.error("Error! silahkan tambahkan tugas") + return toast.error("Error! Silakan tambahkan tugas") if (memberValue.length <= 1) - return toast.error("Error! Silahkan pilih anggota lebih dari 1") + return toast.error("Error! Silakan pilih anggota lebih dari 1") setModal(true) } diff --git a/src/module/project/ui/create_users_project.tsx b/src/module/project/ui/create_users_project.tsx index ced2c48..bd726db 100644 --- a/src/module/project/ui/create_users_project.tsx +++ b/src/module/project/ui/create_users_project.tsx @@ -57,7 +57,7 @@ export default function CreateUsersProject({ grup, onClose }: { grup?: string, o function onSubmit() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } member.set(selectedFiles) onClose(true) diff --git a/src/module/task/ui/add_file_detail_task.tsx b/src/module/task/ui/add_file_detail_task.tsx index f252803..dcdcb3a 100644 --- a/src/module/task/ui/add_file_detail_task.tsx +++ b/src/module/task/ui/add_file_detail_task.tsx @@ -171,7 +171,7 @@ export default function AddFileDetailTask() { if (fileForm.length > 0) { setOpenModal(true) } else { - toast.error("Silahkan pilih file yang akan diupload") + toast.error("Silakan pilih file yang akan diupload") } }}> Simpan diff --git a/src/module/task/ui/add_member_detail_task.tsx b/src/module/task/ui/add_member_detail_task.tsx index 8d7a859..b69575f 100644 --- a/src/module/task/ui/add_member_detail_task.tsx +++ b/src/module/task/ui/add_member_detail_task.tsx @@ -98,7 +98,7 @@ export default function AddMemberDetailTask() { function onVerifikasi() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } setOpenModal(true) diff --git a/src/module/task/ui/create_task.tsx b/src/module/task/ui/create_task.tsx index b8cc5f4..038a905 100644 --- a/src/module/task/ui/create_task.tsx +++ b/src/module/task/ui/create_task.tsx @@ -105,10 +105,10 @@ export default function CreateTask() { return false if (dataTask.length == 0) - return toast.error("Error! silahkan tambahkan tugas") + return toast.error("Error! Silakan tambahkan tugas") if (memberValue.length <= 1) - return toast.error("Error! silahkan pilih anggota lebih dari 1") + return toast.error("Error! Silakan pilih anggota lebih dari 1") setOpenModal(true) } diff --git a/src/module/task/ui/create_users_project.tsx b/src/module/task/ui/create_users_project.tsx index 93eb957..307dcd6 100644 --- a/src/module/task/ui/create_users_project.tsx +++ b/src/module/task/ui/create_users_project.tsx @@ -82,7 +82,7 @@ export default function CreateUsersProject({ onClose }: { onClose: (val: any) => function onSubmit() { if (selectedFiles.length == 0) { - return toast.error("Error! silahkan pilih anggota") + return toast.error("Error! Silakan pilih anggota") } member.set(selectedFiles) onClose(true) From 9a6a4d66df756164893196e5377c904716a72cfc Mon Sep 17 00:00:00 2001 From: amal Date: Tue, 30 Sep 2025 14:40:37 +0800 Subject: [PATCH 02/32] upd: notif insert Deskripsi: - mengganti kalimat notifikasi sesuai dengan content yg diinputkan - upd api version No Issues --- src/app/api/announcement/route.ts | 6 +++--- src/app/api/discussion-general/route.ts | 4 ++-- src/app/api/discussion/route.ts | 10 ++++++---- src/app/api/division/route.ts | 8 ++++---- src/app/api/mobile/announcement/route.ts | 8 ++++---- .../discussion-general/[id]/comment/route.ts | 4 +++- src/app/api/mobile/discussion-general/route.ts | 6 +++--- .../mobile/discussion/[id]/comment/route.ts | 4 +++- src/app/api/mobile/discussion/route.ts | 12 +++++++----- src/app/api/mobile/division/route.ts | 10 +++++----- src/app/api/mobile/project/route.ts | 10 +++++----- src/app/api/mobile/task/route.ts | 18 +++++++++--------- src/app/api/project/route.ts | 8 ++++---- src/app/api/task/route.ts | 17 ++++++++--------- src/app/api/version-app/route.ts | 2 +- 15 files changed, 67 insertions(+), 60 deletions(-) diff --git a/src/app/api/announcement/route.ts b/src/app/api/announcement/route.ts index 0c1cdda..0829e49 100644 --- a/src/app/api/announcement/route.ts +++ b/src/app/api/announcement/route.ts @@ -184,7 +184,7 @@ export async function POST(request: Request) { category: 'announcement', idContent: data.id, title: 'Pengumuman Baru', - desc: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' + desc: title })) const dataPush = memberNotif.map((v: any) => ({ @@ -217,7 +217,7 @@ export async function POST(request: Request) { category: 'announcement', idContent: data.id, title: 'Pengumuman Baru', - desc: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' + desc: title }) dataPush.push({ @@ -229,7 +229,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: title } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/app/api/discussion-general/route.ts b/src/app/api/discussion-general/route.ts index ae383a6..c3489e0 100644 --- a/src/app/api/discussion-general/route.ts +++ b/src/app/api/discussion-general/route.ts @@ -147,7 +147,7 @@ export async function POST(request: Request) { category: 'discussion', idContent: data.id, title: 'Diskusi Umum Baru', - desc: 'Terdapat diskusi umum baru. Silakan periksa detailnya.' + desc: title })) if (userRoleLogin != "supadmin") { @@ -173,7 +173,7 @@ export async function POST(request: Request) { category: 'discussion', idContent: data.id, title: 'Diskusi Umum Baru', - desc: 'Terdapat diskusi umum baru. Silakan periksa detailnya.' + desc: title }) } diff --git a/src/app/api/discussion/route.ts b/src/app/api/discussion/route.ts index 582163a..cc59f3d 100644 --- a/src/app/api/discussion/route.ts +++ b/src/app/api/discussion/route.ts @@ -146,6 +146,8 @@ export async function POST(request: Request) { } }) + const descNotif = desc.length > 300 ? desc.substring(0, 300) + '...' : desc + // mengirim notifikasi // datanotif untuk realtime notifikasi @@ -157,7 +159,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' + desc: descNotif })) const dataPush = memberDivision.map((v: any) => ({ @@ -189,7 +191,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' + desc: descNotif }) dataPush.push({ @@ -221,7 +223,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' + desc: descNotif }) dataPush.push({ @@ -232,7 +234,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat diskusi baru. Silakan periksa detailnya.', title: 'Diskusi Baru' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: descNotif, title: 'Diskusi Baru' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/app/api/division/route.ts b/src/app/api/division/route.ts index 672467c..bd6c9d5 100644 --- a/src/app/api/division/route.ts +++ b/src/app/api/division/route.ts @@ -174,7 +174,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silakan periksa detailnya.' + desc: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` })) const selectUser = await prisma.divisionMember.findMany({ @@ -225,7 +225,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silakan periksa detailnya.' + desc: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` }) dataPush.push({ @@ -262,7 +262,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silakan periksa detailnya.' + desc: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` })) const omitPush = atasanGroup.map((v: any) => ({ @@ -279,7 +279,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: 'Terdapat divisi baru. Silakan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/app/api/mobile/announcement/route.ts b/src/app/api/mobile/announcement/route.ts index 478ae4a..c5b0764 100644 --- a/src/app/api/mobile/announcement/route.ts +++ b/src/app/api/mobile/announcement/route.ts @@ -203,7 +203,7 @@ export async function POST(request: Request) { category: 'announcement', idContent: data.id, title: 'Pengumuman Baru', - desc: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' + desc: title })) @@ -244,7 +244,7 @@ export async function POST(request: Request) { category: 'announcement', idContent: data.id, title: 'Pengumuman Baru', - desc: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' + desc: title }) dataPush.push({ @@ -258,7 +258,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: 'Anda memiliki pengumuman baru. Silakan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: title } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -267,7 +267,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Pengumuman Baru", - body: "Anda memiliki pengumuman baru. Silakan periksa detailnya.", + body: title, data: { id: data.id, category: "announcement", content: data.id } }) diff --git a/src/app/api/mobile/discussion-general/[id]/comment/route.ts b/src/app/api/mobile/discussion-general/[id]/comment/route.ts index 0ce9d22..34f78a2 100644 --- a/src/app/api/mobile/discussion-general/[id]/comment/route.ts +++ b/src/app/api/mobile/discussion-general/[id]/comment/route.ts @@ -103,11 +103,13 @@ export async function POST(request: Request, context: { params: { id: string } } tokenDup.push(perbekel?.TokenDeviceUser.map((v: any) => v.token).flat()) } + const commentNotif = data.comment.length > 300 ? data.comment.substring(0, 300) + '...' : data.comment; + const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); await sendFCMNotificationMany({ token: tokenUnique, title: "Komentar Baru", - body: `${userSent?.name}: ${data.comment}`, + body: `${userSent?.name}: ${commentNotif}`, data: { id: data.id, category: "discussion-general", content: id } }) diff --git a/src/app/api/mobile/discussion-general/route.ts b/src/app/api/mobile/discussion-general/route.ts index 6fd308c..556a2c4 100644 --- a/src/app/api/mobile/discussion-general/route.ts +++ b/src/app/api/mobile/discussion-general/route.ts @@ -172,7 +172,7 @@ export async function POST(request: Request) { category: 'discussion', idContent: data.id, title: 'Diskusi Umum Baru', - desc: 'Terdapat diskusi umum baru. Silakan periksa detailnya.' + desc: title })) if (userRoleLogin != "supadmin") { @@ -205,7 +205,7 @@ export async function POST(request: Request) { category: 'discussion', idContent: data.id, title: 'Diskusi Umum Baru', - desc: 'Terdapat diskusi umum baru. Silakan periksa detailnya.' + desc: title }) } @@ -219,7 +219,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Diskusi Umum Baru", - body: "Anda memiliki diskusi umum baru. Silakan periksa detailnya.", + body: title, data: { id: data.id, category: "discussion", content: data.id } }) diff --git a/src/app/api/mobile/discussion/[id]/comment/route.ts b/src/app/api/mobile/discussion/[id]/comment/route.ts index 77ddd80..b205fcb 100644 --- a/src/app/api/mobile/discussion/[id]/comment/route.ts +++ b/src/app/api/mobile/discussion/[id]/comment/route.ts @@ -119,11 +119,13 @@ export async function POST(request: Request, context: { params: { id: string } } tokenDup.push(perbekel?.TokenDeviceUser.map((v: any) => v.token).flat()) } + const commentNotif = comment.length > 300 ? comment.substring(0, 300) + '...' : comment; + const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); await sendFCMNotificationMany({ token: tokenUnique, title: "Komentar Baru", - body: `${userSent?.name}: ${comment}`, + body: `${userSent?.name}: ${commentNotif}`, data: { id: data.id, category: `division/${dataDivision?.idDivision}/discussion`, content: id } }) diff --git a/src/app/api/mobile/discussion/route.ts b/src/app/api/mobile/discussion/route.ts index 0553ab4..38c2176 100644 --- a/src/app/api/mobile/discussion/route.ts +++ b/src/app/api/mobile/discussion/route.ts @@ -155,6 +155,8 @@ export async function POST(request: Request) { } }) + const deskripsiNotif = desc.length > 300 ? desc.substring(0, 300) + '...' : desc; + // mengirim notifikasi // dataFCM untuk push notifikasi mobile @@ -173,7 +175,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' + desc: deskripsiNotif })) const dataPush = memberDivision.map((v: any) => ({ @@ -212,7 +214,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' + desc: deskripsiNotif }) dataPush.push({ @@ -251,7 +253,7 @@ export async function POST(request: Request) { category: 'division/' + idDivision + '/discussion', idContent: data.id, title: 'Diskusi Baru', - desc: 'Terdapat diskusi baru. Silakan periksa detailnya.' + desc: deskripsiNotif }) dataPush.push({ @@ -264,7 +266,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat diskusi baru. Silakan periksa detailnya.', title: 'Diskusi Baru' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: deskripsiNotif, title: 'Diskusi Baru' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -274,7 +276,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Diskusi Baru", - body: "Anda memiliki diskusi baru. Silakan periksa detailnya.", + body: deskripsiNotif, data: { id: data.id, category: "division/" + idDivision + "/discussion", content: data.id } }) diff --git a/src/app/api/mobile/division/route.ts b/src/app/api/mobile/division/route.ts index 8f79bde..4a8638d 100644 --- a/src/app/api/mobile/division/route.ts +++ b/src/app/api/mobile/division/route.ts @@ -183,7 +183,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silakan periksa detailnya.' + desc: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` })) const selectUser = await prisma.divisionMember.findMany({ @@ -252,7 +252,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silakan periksa detailnya.' + desc: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` }) dataPush.push({ @@ -299,7 +299,7 @@ export async function POST(request: Request) { category: 'division', idContent: data.id, title: 'Divisi Baru', - desc: 'Terdapat divisi baru. Silakan periksa detailnya.' + desc: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` })) const omitPush = atasanGroup.map((v: any) => ({ @@ -317,7 +317,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: 'Terdapat divisi baru. Silakan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -326,7 +326,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Divisi Baru", - body: "Anda memiliki divisi baru. Silakan periksa detailnya.", + body: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.`, data: { id: data.id, category: "division", content: data.id } }) diff --git a/src/app/api/mobile/project/route.ts b/src/app/api/mobile/project/route.ts index 252b743..d0ed52f 100644 --- a/src/app/api/mobile/project/route.ts +++ b/src/app/api/mobile/project/route.ts @@ -284,7 +284,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' + desc: title })) const dataPush = memberNotif.map((v: any) => ({ @@ -323,7 +323,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' + desc: title }) dataPush.push({ @@ -370,7 +370,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' + desc: title })) const omitPush = atasanGroup.map((v: any) => ({ @@ -387,7 +387,7 @@ export async function POST(request: Request) { const dataNotifFilter = dataNotif.filter((item) => item.idUserTo != undefined && item.idUserTo != null && item.idUserTo != "" && item.idUserTo != userId) const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: 'Terdapat kegiatan baru. Silakan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: title } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -396,7 +396,7 @@ export async function POST(request: Request) { await sendFCMNotificationMany({ token: tokenUnique, title: "Kegiatan Baru", - body: "Anda memiliki kegiatan baru. Silakan periksa detailnya.", + body: title, data: { id: data.id, category: "project", content: data.id } }) diff --git a/src/app/api/mobile/task/route.ts b/src/app/api/mobile/task/route.ts index 7b8bde7..5d36a81 100644 --- a/src/app/api/mobile/task/route.ts +++ b/src/app/api/mobile/task/route.ts @@ -267,8 +267,8 @@ export async function POST(request: Request) { idUserFrom: String(userMobile.id), category: 'division/' + idDivision + '/task', idContent: data.id, - title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silakan periksa detailnya.' + title: 'Tugas Divisi Baru', + desc: title })) const dataPush = memberDivision.map((v: any) => ({ @@ -306,8 +306,8 @@ export async function POST(request: Request) { idUserFrom: userId, category: 'division/' + idDivision + '/task', idContent: data.id, - title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silakan periksa detailnya.' + title: 'Tugas Divisi Baru', + desc: title }) dataPush.push({ @@ -345,8 +345,8 @@ export async function POST(request: Request) { idUserFrom: userId, category: 'division/' + idDivision + '/task', idContent: data.id, - title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silakan periksa detailnya.' + title: 'Tugas Divisi Baru', + desc: title }) dataPush.push({ @@ -358,7 +358,7 @@ export async function POST(request: Request) { const dataNotifFilter = dataNotif.filter((v: any) => v.idUserTo != undefined && v.idUserTo != null && v.idUserTo != "" && v.idUserTo != userId) const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat tugas baru. Silakan periksa detailnya.', title: 'Tugas Baru' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: title, title: 'Tugas Divisi Baru' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotifFilter }) @@ -366,8 +366,8 @@ export async function POST(request: Request) { const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); await sendFCMNotificationMany({ token: tokenUnique, - title: "Tugas Baru", - body: "Anda memiliki tugas baru. Silakan periksa detailnya.", + title: "Tugas Divisi Baru", + body: title, data: { id: data.id, category: 'division/' + idDivision + '/task', content: data.id } }) diff --git a/src/app/api/project/route.ts b/src/app/api/project/route.ts index 598d11a..2f05c5a 100644 --- a/src/app/api/project/route.ts +++ b/src/app/api/project/route.ts @@ -262,7 +262,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' + desc: title })) const dataPush = memberNotif.map((v: any) => ({ @@ -294,7 +294,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' + desc: title }) dataPush.push({ @@ -330,7 +330,7 @@ export async function POST(request: Request) { category: 'project', idContent: data.id, title: 'Kegiatan Baru', - desc: 'Terdapat kegiatan baru. Silakan periksa detailnya.' + desc: title })) const omitPush = atasanGroup.map((v: any) => ({ @@ -346,7 +346,7 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: 'Terdapat kegiatan baru. Silakan periksa detailnya.' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: title } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) diff --git a/src/app/api/task/route.ts b/src/app/api/task/route.ts index ba2d4f3..ba4d224 100644 --- a/src/app/api/task/route.ts +++ b/src/app/api/task/route.ts @@ -253,8 +253,8 @@ export async function POST(request: Request) { idUserFrom: String(user.id), category: 'division/' + idDivision + '/task', idContent: data.id, - title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silakan periksa detailnya.' + title: 'Tugas Divisi Baru', + desc: title })) const dataPush = memberDivision.map((v: any) => ({ @@ -285,8 +285,8 @@ export async function POST(request: Request) { idUserFrom: userId, category: 'division/' + idDivision + '/task', idContent: data.id, - title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silakan periksa detailnya.' + title: 'Tugas Divisi Baru', + desc: title }) dataPush.push({ @@ -317,8 +317,8 @@ export async function POST(request: Request) { idUserFrom: userId, category: 'division/' + idDivision + '/task', idContent: data.id, - title: 'Tugas Baru', - desc: 'Terdapat tugas baru. Silakan periksa detailnya.' + title: 'Tugas Divisi Baru', + desc: title }) dataPush.push({ @@ -329,13 +329,12 @@ export async function POST(request: Request) { const pushNotif = dataPush.filter((item) => item.subscription != undefined) - const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: 'Terdapat tugas baru. Silakan periksa detailnya.', title: 'Tugas Baru' } }) + const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: title, title: 'Tugas Divisi Baru' } }) const insertNotif = await prisma.notifications.createMany({ data: dataNotif }) - - // create log user + // create log userc const log = await createLogUser({ act: 'CREATE', desc: 'User membuat tugas divisi baru', table: 'divisionProject', data: data.id }) diff --git a/src/app/api/version-app/route.ts b/src/app/api/version-app/route.ts index 33baf80..eca496f 100644 --- a/src/app/api/version-app/route.ts +++ b/src/app/api/version-app/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export async function GET(request: Request) { try { - return NextResponse.json({ success: true, version: "2.0.3", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); + return NextResponse.json({ success: true, version: "2.0.4", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); From 1f259a409b55bce4ff90d5fb91afe387b19b22bc Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 2 Oct 2025 17:39:10 +0800 Subject: [PATCH 03/32] upd: api mobile Deskripsi: - home > progress, kegiatan updated, divisi, dokumen, event, diskusi NO Issues --- src/app/api/mobile/home/route.ts | 244 +++++++++++++++++++++---------- 1 file changed, 166 insertions(+), 78 deletions(-) diff --git a/src/app/api/mobile/home/route.ts b/src/app/api/mobile/home/route.ts index 98dbddc..068d399 100644 --- a/src/app/api/mobile/home/route.ts +++ b/src/app/api/mobile/home/route.ts @@ -37,22 +37,28 @@ export async function GET(request: Request) { isActive: true, } } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { + } else { kondisi = { isActive: true, idGroup: idGroup } - } else { - kondisi = { - isActive: true, - idGroup: idGroup, - ProjectMember: { - some: { - idUser: user.id - } - } - } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // idGroup: idGroup + // } + // } else { + // kondisi = { + // isActive: true, + // idGroup: idGroup, + // ProjectMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } const data = await prisma.project.findMany({ skip: 0, @@ -97,24 +103,30 @@ export async function GET(request: Request) { isActive: true, } } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { + } else { kondisi = { isActive: true, idGroup: idGroup } - } else { - kondisi = { - isActive: true, - idGroup: idGroup, - DivisionMember: { - some: { - idUser: user.id - } - } - } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // idGroup: idGroup + // } + // } else { + // kondisi = { + // isActive: true, + // idGroup: idGroup, + // DivisionMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } + - const data = await prisma.division.findMany({ where: kondisi, select: { @@ -147,42 +159,63 @@ export async function GET(request: Request) { if (roleUser == "supadmin" || roleUser == "developer") { kondisi = { isActive: true, - Division: { + idVillage: idVillage, + Group: { isActive: true, - idVillage: idVillage, - Group: { - isActive: true, - } - } - } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { - kondisi = { - isActive: true, - Division: { - isActive: true, - idGroup: idGroup } } } else { kondisi = { isActive: true, - Division: { - isActive: true, - DivisionMember: { - some: { - idUser: user.id - } - } - } + idGroup: idGroup } } - const data = await prisma.divisionProject.groupBy({ + // if (roleUser == "supadmin" || roleUser == "developer") { + // kondisi = { + // isActive: true, + // Division: { + // isActive: true, + // idVillage: idVillage, + // Group: { + // isActive: true, + // } + // } + // } + // } else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // Division: { + // isActive: true, + // idGroup: idGroup + // } + // } + // } else { + // kondisi = { + // isActive: true, + // Division: { + // isActive: true, + // DivisionMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } + // } + + const data = await prisma.project.groupBy({ where: kondisi, by: ["status"], _count: true }) + // const data = await prisma.divisionProject.groupBy({ + // where: kondisi, + // by: ["status"], + // _count: true + // }) + const dataStatus = [{ name: 'Segera dikerjakan', status: 0, color: '#177AD5' }, { name: 'Dikerjakan', status: 1, color: '#fac858' }, { name: 'Selesai dikerjakan', status: 2, color: '#92cc76' }, { name: 'Dibatalkan', status: 3, color: '#ED6665' }] const hasil: any[] = [] let input @@ -225,7 +258,7 @@ export async function GET(request: Request) { } } } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { + } else { kondisi = { isActive: true, category: 'FILE', @@ -234,21 +267,32 @@ export async function GET(request: Request) { idGroup: idGroup } } - } else { - kondisi = { - isActive: true, - category: 'FILE', - Division: { - isActive: true, - DivisionMember: { - some: { - idUser: user.id - } - } - } - } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // category: 'FILE', + // Division: { + // isActive: true, + // idGroup: idGroup + // } + // } + // } else { + // kondisi = { + // isActive: true, + // category: 'FILE', + // Division: { + // isActive: true, + // DivisionMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } + // } + const data = await prisma.divisionDocumentFolderFile.findMany({ where: kondisi, }) @@ -373,22 +417,34 @@ export async function GET(request: Request) { })) } else if (kategori == "discussion") { - let kondisi + let kondisi, kondisiUmum // klo perbekel/developer == semua grup if (roleUser == "supadmin" || roleUser == "developer") { - kondisi = { + kondisiUmum = { isActive: true, status: 1, - Division: { + idVillage: idVillage + }, + + kondisi = { isActive: true, - idVillage: idVillage, - Group: { + status: 1, + Division: { isActive: true, + idVillage: idVillage, + Group: { + isActive: true, + } } } + } else { + kondisiUmum = { + isActive: true, + status: 1, + idGroup: idGroup, } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { + kondisi = { isActive: true, status: 1, @@ -397,20 +453,52 @@ export async function GET(request: Request) { isActive: true } } - } else { - kondisi = { - isActive: true, - status: 1, - Division: { - isActive: true, - DivisionMember: { - some: { - idUser: user.id - } - } - } - } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // status: 1, + // Division: { + // idGroup: idGroup, + // isActive: true + // } + // } + // } else { + // kondisi = { + // isActive: true, + // status: 1, + // Division: { + // isActive: true, + // DivisionMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } + // } + + + // TODO: + // const dataUmum = await prisma.discussion.findMany({ + // skip: 0, + // take: 5, + // where: kondisiUmum, + // select: { + // id: true, + // title: true, + // desc: true, + // createdAt: true, + // User: { + // select: { + // name: true + // } + // } + // }, + // orderBy: { + // createdAt: "desc" + // } + // }) const data = await prisma.divisionDisscussion.findMany({ skip: 0, From c2c52ed5fd0492e6aacfbd7716b4f47e0a56ab33 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Fri, 3 Oct 2025 16:53:31 +0800 Subject: [PATCH 04/32] upd: home api mobile --- src/app/api/mobile/home/route.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/app/api/mobile/home/route.ts b/src/app/api/mobile/home/route.ts index 068d399..d7778eb 100644 --- a/src/app/api/mobile/home/route.ts +++ b/src/app/api/mobile/home/route.ts @@ -425,19 +425,19 @@ export async function GET(request: Request) { isActive: true, status: 1, idVillage: idVillage - }, + } - kondisi = { + kondisi = { + isActive: true, + status: 1, + Division: { isActive: true, - status: 1, - Division: { + idVillage: idVillage, + Group: { isActive: true, - idVillage: idVillage, - Group: { - isActive: true, - } } } + } } else { kondisiUmum = { isActive: true, From b648735b06e951f5e25e2faa3c02ac29498c3e56 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Mon, 6 Oct 2025 17:08:07 +0800 Subject: [PATCH 05/32] fix:api mobile Deskripsi: - filter notif duplikat pada fitur pengumuman, diskusi umum, diskusi divisi, divisi, kegiatan dan tugas divisi NO Issues --- src/app/api/mobile/announcement/route.ts | 7 ++++++- src/app/api/mobile/discussion-general/route.ts | 6 +++++- src/app/api/mobile/discussion/route.ts | 6 +++++- src/app/api/mobile/division/route.ts | 6 +++++- src/app/api/mobile/project/route.ts | 6 +++++- src/app/api/mobile/task/route.ts | 6 +++++- 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/app/api/mobile/announcement/route.ts b/src/app/api/mobile/announcement/route.ts index c5b0764..822227d 100644 --- a/src/app/api/mobile/announcement/route.ts +++ b/src/app/api/mobile/announcement/route.ts @@ -255,15 +255,20 @@ export async function POST(request: Request) { const dataNotifFilter = dataNotif.filter((v: any) => v.idUserTo != undefined && v.idUserTo != null && v.idUserTo != "" && v.idUserTo != userId) + const dataNotifFilterUnique = dataNotifFilter + .filter((v: any, index: number, self: any[]) => + index === self.findIndex((t: any) => t.idUserTo == v.idUserTo) + ) const pushNotif = dataPush.filter((item) => item.subscription != undefined) const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Pengumuman Baru', body: title } }) const insertNotif = await prisma.notifications.createMany({ - data: dataNotifFilter + data: dataNotifFilterUnique }) const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); + await sendFCMNotificationMany({ token: tokenUnique, title: "Pengumuman Baru", diff --git a/src/app/api/mobile/discussion-general/route.ts b/src/app/api/mobile/discussion-general/route.ts index 556a2c4..bb46a00 100644 --- a/src/app/api/mobile/discussion-general/route.ts +++ b/src/app/api/mobile/discussion-general/route.ts @@ -210,9 +210,13 @@ export async function POST(request: Request) { } dataNotif.filter((v: any) => v.idUserTo != undefined && v.idUserTo != null && v.idUserTo != "" && v.idUserTo != userId) + const dataNotifUnique = dataNotif + .filter((v: any, index: number, self: any[]) => + index === self.findIndex((t: any) => t.idUserTo == v.idUserTo) + ) const insertNotif = await prisma.notifications.createMany({ - data: dataNotif + data: dataNotifUnique }) const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); diff --git a/src/app/api/mobile/discussion/route.ts b/src/app/api/mobile/discussion/route.ts index 38c2176..9dbdb43 100644 --- a/src/app/api/mobile/discussion/route.ts +++ b/src/app/api/mobile/discussion/route.ts @@ -263,12 +263,16 @@ export async function POST(request: Request) { } const dataNotifFilter = dataNotif.filter((v: any) => v.idUserTo != undefined && v.idUserTo != null && v.idUserTo != "" && v.idUserTo != userId) + const dataNotifFilterUnique = dataNotifFilter + .filter((v: any, index: number, self: any[]) => + index === self.findIndex((t: any) => t.idUserTo == v.idUserTo) + ) const pushNotif = dataPush.filter((item) => item.subscription != undefined) const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: deskripsiNotif, title: 'Diskusi Baru' } }) const insertNotif = await prisma.notifications.createMany({ - data: dataNotifFilter + data: dataNotifFilterUnique }) const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); diff --git a/src/app/api/mobile/division/route.ts b/src/app/api/mobile/division/route.ts index 4a8638d..48dfef7 100644 --- a/src/app/api/mobile/division/route.ts +++ b/src/app/api/mobile/division/route.ts @@ -314,12 +314,16 @@ export async function POST(request: Request) { } const dataNotifFilter = dataNotif.filter((v: any) => v.idUserTo != undefined && v.idUserTo != null && v.idUserTo != "" && v.idUserTo != userId) + const dataNotifFilterUnique = dataNotifFilter + .filter((v: any, index: number, self: any[]) => + index === self.findIndex((t: any) => t.idUserTo == v.idUserTo) + ) const pushNotif = dataPush.filter((item) => item.subscription != undefined) const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Divisi Baru', body: `Divisi ${sent.data.name} telah dibuat. Silakan periksa detailnya.` } }) const insertNotif = await prisma.notifications.createMany({ - data: dataNotifFilter + data: dataNotifFilterUnique }) const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); diff --git a/src/app/api/mobile/project/route.ts b/src/app/api/mobile/project/route.ts index d0ed52f..bffa5f0 100644 --- a/src/app/api/mobile/project/route.ts +++ b/src/app/api/mobile/project/route.ts @@ -385,11 +385,15 @@ export async function POST(request: Request) { } const dataNotifFilter = dataNotif.filter((item) => item.idUserTo != undefined && item.idUserTo != null && item.idUserTo != "" && item.idUserTo != userId) + const dataNotifFilterUnique = dataNotifFilter + .filter((v: any, index: number, self: any[]) => + index === self.findIndex((t: any) => t.idUserTo == v.idUserTo) + ) const pushNotif = dataPush.filter((item) => item.subscription != undefined) const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { title: 'Kegiatan Baru', body: title } }) const insertNotif = await prisma.notifications.createMany({ - data: dataNotifFilter + data: dataNotifFilterUnique }) const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); diff --git a/src/app/api/mobile/task/route.ts b/src/app/api/mobile/task/route.ts index 5d36a81..a83083b 100644 --- a/src/app/api/mobile/task/route.ts +++ b/src/app/api/mobile/task/route.ts @@ -356,11 +356,15 @@ export async function POST(request: Request) { } const dataNotifFilter = dataNotif.filter((v: any) => v.idUserTo != undefined && v.idUserTo != null && v.idUserTo != "" && v.idUserTo != userId) + const dataNotifFilterUnique = dataNotifFilter + .filter((v: any, index: number, self: any[]) => + index === self.findIndex((t: any) => t.idUserTo == v.idUserTo) + ) const pushNotif = dataPush.filter((item) => item.subscription != undefined) const sendWebPush = await funSendWebPush({ sub: pushNotif, message: { body: title, title: 'Tugas Divisi Baru' } }) const insertNotif = await prisma.notifications.createMany({ - data: dataNotifFilter + data: dataNotifFilterUnique }) const tokenUnique = [...new Set(tokenDup.flat())].filter((v: any) => v != undefined && v != null && v != ""); From d1a591a63a5a21f0bc4f608def82aa20ddc1a928 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 7 Oct 2025 12:01:19 +0800 Subject: [PATCH 06/32] upd: api mobile Deskripsi: - check nama divisi No Issues --- src/app/api/mobile/division/route.ts | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/src/app/api/mobile/division/route.ts b/src/app/api/mobile/division/route.ts index 48dfef7..9b6b538 100644 --- a/src/app/api/mobile/division/route.ts +++ b/src/app/api/mobile/division/route.ts @@ -342,4 +342,45 @@ export async function POST(request: Request) { console.error(error); return NextResponse.json({ success: false, message: "Gagal menambahkan divisi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); } +}; + + +// CEK DATA DIVISI (NAME DI DESA DAN GROUP YG SAMA) +export async function PUT(request: Request) { + try { + + const sent = (await request.json()) + const user = sent.user + const userMobile = await funGetUserById({ id: String(user) }) + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + let fixGroup + if (sent.data.idGroup == "null" || sent.data.idGroup == undefined || sent.data.idGroup == "") { + fixGroup = userMobile.idGroup + } else { + fixGroup = sent.data.idGroup + } + + const checkData = await prisma.division.count({ + where: { + name: { + equals: sent.data.name, + mode: "insensitive" + }, + idGroup: fixGroup, + idVillage: String(userMobile.idVillage) + } + }) + + if (checkData > 0) { + return NextResponse.json({ success: true, message: "Divisi dengan nama ini sudah ada", available: false }, { status: 200 }); + } + + return NextResponse.json({ success: true, message: "Berhasil cek data divisi", available: true }, { status: 200 }); + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menambahkan divisi, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } }; \ No newline at end of file From 150151e823265bc2d6a5225884b2bbc91105ed1e Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 7 Oct 2025 15:09:20 +0800 Subject: [PATCH 07/32] upd: order tugas Deskripsi: - order tugas pada tugas divisi dan kegiatan NO Issues' --- src/app/api/mobile/project/[id]/route.ts | 2 +- src/app/api/mobile/task/[id]/route.ts | 2 +- src/app/api/project/[id]/route.ts | 6 +++--- src/app/api/task/[id]/route.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/app/api/mobile/project/[id]/route.ts b/src/app/api/mobile/project/[id]/route.ts index 7c09849..9f0152a 100644 --- a/src/app/api/mobile/project/[id]/route.ts +++ b/src/app/api/mobile/project/[id]/route.ts @@ -71,7 +71,7 @@ export async function GET(request: Request, context: { params: { id: string } }) createdAt: true }, orderBy: { - createdAt: 'asc' + dateStart: 'asc' } }) diff --git a/src/app/api/mobile/task/[id]/route.ts b/src/app/api/mobile/task/[id]/route.ts index a7260f0..7f285c6 100644 --- a/src/app/api/mobile/task/[id]/route.ts +++ b/src/app/api/mobile/task/[id]/route.ts @@ -76,7 +76,7 @@ export async function GET(request: Request, context: { params: { id: string } }) dateEnd: true, }, orderBy: { - createdAt: 'asc' + dateStart: 'asc' } }) diff --git a/src/app/api/project/[id]/route.ts b/src/app/api/project/[id]/route.ts index df7e87f..f8cecad 100644 --- a/src/app/api/project/[id]/route.ts +++ b/src/app/api/project/[id]/route.ts @@ -68,7 +68,7 @@ export async function GET(request: Request, context: { params: { id: string } }) createdAt: true }, orderBy: { - createdAt: 'asc' + dateStart: 'asc' } }) @@ -78,8 +78,8 @@ export async function GET(request: Request, context: { params: { id: string } }) dateEnd: moment(v.dateEnd).format("DD-MM-YYYY"), createdAt: moment(v.createdAt).format("DD-MM-YYYY HH:mm"), })) - const dataFix = _.orderBy(formatData, 'createdAt', 'asc') - allData = dataFix + // const dataFix = _.orderBy(formatData, 'createdAt', 'asc') + allData = formatData } else if (kategori == "file") { const dataFile = await prisma.projectFile.findMany({ diff --git a/src/app/api/task/[id]/route.ts b/src/app/api/task/[id]/route.ts index 7ef6090..8f1652b 100644 --- a/src/app/api/task/[id]/route.ts +++ b/src/app/api/task/[id]/route.ts @@ -75,7 +75,7 @@ export async function GET(request: Request, context: { params: { id: string } }) dateEnd: true, }, orderBy: { - createdAt: 'asc' + dateStart: 'asc' } }) From bae91db60a7727ba318dd150e0a38cbcb3eecd15 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 7 Oct 2025 16:36:34 +0800 Subject: [PATCH 08/32] upd: penerima notifikasi Deskripsi: - pembuat data mendapat notifikasi saat user memberi komentar walaupun pembuat data bukan merupakan anggota dari diskusi umum maupun anggota divisi - diskusi umum dan diskusi divis No Issues --- .../discussion-general/[id]/comment/route.ts | 28 ++++++++++++++++++- .../mobile/discussion/[id]/comment/route.ts | 20 ++++++++++++- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/app/api/mobile/discussion-general/[id]/comment/route.ts b/src/app/api/mobile/discussion-general/[id]/comment/route.ts index 34f78a2..c748522 100644 --- a/src/app/api/mobile/discussion-general/[id]/comment/route.ts +++ b/src/app/api/mobile/discussion-general/[id]/comment/route.ts @@ -37,6 +37,29 @@ export async function POST(request: Request, context: { params: { id: string } } } }) + const dataDiscussion = await prisma.discussion.findUnique({ + where: { + id + }, + select: { + createdBy: true, + User: { + select: { + Subscribe: { + select: { + subscription: true + } + }, + TokenDeviceUser: { + select: { + token: true + } + } + } + } + } + }) + const member = await prisma.discussionMember.findMany({ where: { idDiscussion: id, @@ -70,7 +93,10 @@ export async function POST(request: Request, context: { params: { id: string } } } }) - const memberFilter = member.filter((v: any) => v.idUser != userMobile.id) + const memberFilter = [...member, { idUser: dataDiscussion?.createdBy, User: dataDiscussion?.User }].filter((v: any) => v.idUser != userMobile.id) + .filter((v: any, index: number, self: any[]) => + index === self.findIndex((t) => t.idUser === v.idUser) + ); const dataFCM = memberFilter.map((v: any) => ({ ..._.omit(v, ["idUser", "User", "Subscribe", "TokenDeviceUser"]), diff --git a/src/app/api/mobile/discussion/[id]/comment/route.ts b/src/app/api/mobile/discussion/[id]/comment/route.ts index b205fcb..34d86ec 100644 --- a/src/app/api/mobile/discussion/[id]/comment/route.ts +++ b/src/app/api/mobile/discussion/[id]/comment/route.ts @@ -50,6 +50,21 @@ export async function POST(request: Request, context: { params: { id: string } } }, select: { idDivision: true, + createdBy: true, + User: { + select: { + Subscribe: { + select: { + subscription: true + } + }, + TokenDeviceUser: { + select: { + token: true + } + } + } + } } }) @@ -86,7 +101,10 @@ export async function POST(request: Request, context: { params: { id: string } } } }) - const memberFilter = member.filter((v: any) => v.idUser != userMobile.id) + const memberFilter = [...member, { idUser: dataDivision?.createdBy, User: dataDivision?.User }].filter((v: any) => v.idUser != userMobile.id) + .filter((v: any, index: number, self: any[]) => + index === self.findIndex((t) => t.idUser === v.idUser) + ); const dataFCM = memberFilter.map((v: any) => ({ ..._.omit(v, ["idUser", "User", "Subscribe", "TokenDeviceUser"]), From b625150eb523185c5364b094e829bcbfca9a8b70 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 7 Oct 2025 17:09:36 +0800 Subject: [PATCH 09/32] upd: api home website Deskripsi: - update home api website jadi sama kyk mobile NO Issues --- src/app/api/home/route.ts | 194 +++++++++++++++++++++++--------------- 1 file changed, 120 insertions(+), 74 deletions(-) diff --git a/src/app/api/home/route.ts b/src/app/api/home/route.ts index 45f6514..7d7c85f 100644 --- a/src/app/api/home/route.ts +++ b/src/app/api/home/route.ts @@ -1,4 +1,3 @@ -import { DivisionProject } from './../../../../node_modules/.prisma/client/index.d'; import { prisma } from "@/module/_global"; import { funGetUserByCookies } from "@/module/auth"; import _, { ceil } from "lodash"; @@ -36,22 +35,28 @@ export async function GET(request: Request) { isActive: true, } } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { + } else { kondisi = { isActive: true, idGroup: idGroup } - } else { - kondisi = { - isActive: true, - idGroup: idGroup, - ProjectMember: { - some: { - idUser: user.id - } - } - } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // idGroup: idGroup + // } + // } else { + // kondisi = { + // isActive: true, + // idGroup: idGroup, + // ProjectMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } const data = await prisma.project.findMany({ skip: 0, @@ -96,22 +101,28 @@ export async function GET(request: Request) { isActive: true, } } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { + } else { kondisi = { isActive: true, idGroup: idGroup } - } else { - kondisi = { - isActive: true, - idGroup: idGroup, - DivisionMember: { - some: { - idUser: user.id - } - } - } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // idGroup: idGroup + // } + // } else { + // kondisi = { + // isActive: true, + // idGroup: idGroup, + // DivisionMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } const data = await prisma.division.findMany({ where: kondisi, @@ -134,7 +145,9 @@ export async function GET(request: Request) { jumlah: v.DivisionProject.length, })) - allData = _.orderBy(format, 'jumlah', 'desc').slice(0, 5) + const filter = format.filter((v: any) => v.jumlah > 0) + + allData = _.orderBy(filter, 'jumlah', 'desc').slice(0, 5) } else if (kategori == "progress") { let kondisi @@ -143,37 +156,50 @@ export async function GET(request: Request) { if (roleUser == "supadmin" || roleUser == "developer") { kondisi = { isActive: true, - Division: { + idVillage: idVillage, + Group: { isActive: true, - idVillage: idVillage, - Group: { - isActive: true, - } - } - } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { - kondisi = { - isActive: true, - Division: { - isActive: true, - idGroup: idGroup } } + // kondisi = { + // isActive: true, + // Division: { + // isActive: true, + // idVillage: idVillage, + // Group: { + // isActive: true, + // } + // } + // } } else { kondisi = { isActive: true, - Division: { - isActive: true, - DivisionMember: { - some: { - idUser: user.id - } - } - } + idGroup: idGroup } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // Division: { + // isActive: true, + // idGroup: idGroup + // } + // } + // } else { + // kondisi = { + // isActive: true, + // Division: { + // isActive: true, + // DivisionMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } + // } - const data = await prisma.divisionProject.groupBy({ + const data = await prisma.project.groupBy({ where: kondisi, by: ["status"], _count: true @@ -218,7 +244,7 @@ export async function GET(request: Request) { } } } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { + } else { kondisi = { isActive: true, category: 'FILE', @@ -227,20 +253,30 @@ export async function GET(request: Request) { idGroup: idGroup } } - } else { - kondisi = { - isActive: true, - category: 'FILE', - Division: { - isActive: true, - DivisionMember: { - some: { - idUser: user.id - } - } - } - } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // category: 'FILE', + // Division: { + // isActive: true, + // idGroup: idGroup + // } + // } + // } else { + // kondisi = { + // isActive: true, + // category: 'FILE', + // Division: { + // isActive: true, + // DivisionMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } + // } const data = await prisma.divisionDocumentFolderFile.findMany({ where: kondisi, @@ -377,7 +413,7 @@ export async function GET(request: Request) { } } } - } else if (roleUser == "admin" || roleUser == "cosupadmin") { + } else { kondisi = { isActive: true, status: 1, @@ -386,20 +422,30 @@ export async function GET(request: Request) { isActive: true } } - } else { - kondisi = { - isActive: true, - status: 1, - Division: { - isActive: true, - DivisionMember: { - some: { - idUser: user.id - } - } - } - } } + // else if (roleUser == "admin" || roleUser == "cosupadmin") { + // kondisi = { + // isActive: true, + // status: 1, + // Division: { + // idGroup: idGroup, + // isActive: true + // } + // } + // } else { + // kondisi = { + // isActive: true, + // status: 1, + // Division: { + // isActive: true, + // DivisionMember: { + // some: { + // idUser: user.id + // } + // } + // } + // } + // } const data = await prisma.divisionDisscussion.findMany({ skip: 0, From 22518189084a49c24ba7ee1817b01102d42e5c01 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 7 Oct 2025 17:11:18 +0800 Subject: [PATCH 10/32] upd: api version --- src/app/api/version-app/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/version-app/route.ts b/src/app/api/version-app/route.ts index eca496f..4f67b29 100644 --- a/src/app/api/version-app/route.ts +++ b/src/app/api/version-app/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export async function GET(request: Request) { try { - return NextResponse.json({ success: true, version: "2.0.4", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); + return NextResponse.json({ success: true, version: "2.0.6", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); From 66ba6dfa914d44ded5a5ea08102bf440dafaf8f2 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 8 Oct 2025 16:14:30 +0800 Subject: [PATCH 11/32] fix : api home Deskripsi: - update api home > kegiatan terupdate order by updatedate - api version app No Issues --- src/app/api/home/route.ts | 2 +- src/app/api/mobile/home/route.ts | 2 +- src/app/api/version-app/route.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/app/api/home/route.ts b/src/app/api/home/route.ts index 7d7c85f..83f7322 100644 --- a/src/app/api/home/route.ts +++ b/src/app/api/home/route.ts @@ -79,7 +79,7 @@ export async function GET(request: Request) { } }, orderBy: { - createdAt: "desc" + updatedAt: "desc" } }) diff --git a/src/app/api/mobile/home/route.ts b/src/app/api/mobile/home/route.ts index d7778eb..8ebe73f 100644 --- a/src/app/api/mobile/home/route.ts +++ b/src/app/api/mobile/home/route.ts @@ -81,7 +81,7 @@ export async function GET(request: Request) { } }, orderBy: { - createdAt: "desc" + updatedAt: "desc" } }) diff --git a/src/app/api/version-app/route.ts b/src/app/api/version-app/route.ts index 4f67b29..d7d65b4 100644 --- a/src/app/api/version-app/route.ts +++ b/src/app/api/version-app/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export async function GET(request: Request) { try { - return NextResponse.json({ success: true, version: "2.0.6", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); + return NextResponse.json({ success: true, version: "2.0.7", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); From 3d5149cbbacbf85e983ad3a6db17ce45a155b392 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Mon, 13 Oct 2025 17:19:20 +0800 Subject: [PATCH 12/32] upd: komentar diskusi - Deskripsi: - upd database - tampilan api mobile komentar diskusi umum dan diskusi divisi No Issues --- prisma/schema.prisma | 2 ++ src/app/api/mobile/discussion-general/[id]/route.ts | 5 ++++- src/app/api/mobile/discussion/[id]/route.ts | 7 ++++++- src/module/_global/fun/count_time.ts | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index dacd4ca..b187a9d 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -420,6 +420,7 @@ model DivisionDisscussionComment { isActive Boolean @default(true) User User @relation(fields: [createdBy], references: [id]) createdBy String + isEdited Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } @@ -615,6 +616,7 @@ model DiscussionComment { idUser String comment String @db.Text isActive Boolean @default(true) + isEdited Boolean @default(false) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } diff --git a/src/app/api/mobile/discussion-general/[id]/route.ts b/src/app/api/mobile/discussion-general/[id]/route.ts index 6b3a5dd..d538689 100644 --- a/src/app/api/mobile/discussion-general/[id]/route.ts +++ b/src/app/api/mobile/discussion-general/[id]/route.ts @@ -68,6 +68,8 @@ export async function GET(request: Request, context: { params: { id: string } }) id: true, comment: true, createdAt: true, + updatedAt: true, + isEdited: true, idUser: true, User: { select: { @@ -79,8 +81,9 @@ export async function GET(request: Request, context: { params: { id: string } }) }) dataFix = data.map((v: any) => ({ - ..._.omit(v, ["createdAt", "User",]), + ..._.omit(v, ["createdAt", "User", "updatedAt"]), createdAt: countTime(v.createdAt), + updatedAt: moment(v.updatedAt).format("ll"), username: v.User.name, img: v.User.img })) diff --git a/src/app/api/mobile/discussion/[id]/route.ts b/src/app/api/mobile/discussion/[id]/route.ts index 5b423cc..65930b1 100644 --- a/src/app/api/mobile/discussion/[id]/route.ts +++ b/src/app/api/mobile/discussion/[id]/route.ts @@ -44,6 +44,9 @@ export async function GET(request: Request, context: { params: { id: string } }) id: true, comment: true, createdAt: true, + updatedAt: true, + isEdited: true, + createdBy: true, User: { select: { name: true, @@ -54,10 +57,12 @@ export async function GET(request: Request, context: { params: { id: string } }) }) const omitMember = data.map((v: any) => ({ - ..._.omit(v, ["User", "createdAt"]), + ..._.omit(v, ["User", "createdBy", "createdAt", "updatedAt"]), + idUser: v.createdBy, username: v.User.name, img: v.User.img, createdAt: countTime(v.createdAt), + updatedAt: moment(v.updatedAt).format("ll") })) return NextResponse.json({ success: true, message: "Berhasil mendapatkan komentar", data: omitMember }, { status: 200 }); diff --git a/src/module/_global/fun/count_time.ts b/src/module/_global/fun/count_time.ts index 5a26efa..744950d 100644 --- a/src/module/_global/fun/count_time.ts +++ b/src/module/_global/fun/count_time.ts @@ -18,7 +18,7 @@ export function countTime(date: Date) { const seconds = totalSeconds; if (days > 0) { - return moment(date).format("ll") + return String(dateNow.getFullYear()) == moment(date).format("YYYY") ? moment(date).format("DD MMM") : moment(date).format("ll") } else if (hours > 0) { return `${hours} jam` } else if (minutes > 0) { From 878b3aa278af9a676ded9969b1881fc57019a41d Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 14 Oct 2025 15:00:39 +0800 Subject: [PATCH 13/32] upd: komentar diskusi - api mobile hapus komentar diskusi umum dan diskusi divisi - api mobile edit komentar diskusi dumum dan diskusi divisi No Issues --- .../discussion-general/[id]/comment/route.ts | 86 +++++++++++++++ .../api/mobile/discussion-general/route.ts | 3 + .../mobile/discussion/[id]/comment/route.ts | 101 +++++++++++++++++- src/app/api/mobile/discussion/[id]/route.ts | 3 +- src/app/api/mobile/discussion/route.ts | 3 + 5 files changed, 194 insertions(+), 2 deletions(-) diff --git a/src/app/api/mobile/discussion-general/[id]/comment/route.ts b/src/app/api/mobile/discussion-general/[id]/comment/route.ts index c748522..71b8dd2 100644 --- a/src/app/api/mobile/discussion-general/[id]/comment/route.ts +++ b/src/app/api/mobile/discussion-general/[id]/comment/route.ts @@ -147,4 +147,90 @@ export async function POST(request: Request, context: { params: { id: string } } console.error(error) return NextResponse.json({ success: false, message: "Gagal menambahkan komentar, coba lagi nanti (error: 500)" }) } +} + +// EDIT KOMENTAR +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params + const { desc, user } = (await request.json()); + const userMobile = await funGetUserById({ id: String(user) }) + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const cek = await prisma.discussionComment.count({ + where: { + id, + isActive: true + } + }) + + if (cek == 0) { + return NextResponse.json({ success: false, message: "Gagal mengedit komentar, data tidak ditemukan" }, { status: 200 }); + } + + + const data = await prisma.discussionComment.update({ + where: { + id + }, + data: { + comment: desc, + isEdited: true + } + }) + + // create log user + const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User mengedit komentar pada diskusi umum', table: 'discussionComment', data: id, user: userMobile.id }) + return NextResponse.json({ success: true, message: "Berhasil mengedit komentar" }, { status: 200 }); + + } catch (error) { + console.error(error) + return NextResponse.json({ success: false, message: "Gagal mengedit komentar, coba lagi nanti (error: 500)" }) + } +} + + +// HAPUS KOMENTAR +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params + const { user } = (await request.json()); + const userMobile = await funGetUserById({ id: String(user) }) + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const cek = await prisma.discussionComment.count({ + where: { + id, + isActive: true + } + }) + + if (cek == 0) { + return NextResponse.json({ success: false, message: "Gagal mengedit komentar, data tidak ditemukan" }, { status: 200 }); + } + + + const data = await prisma.discussionComment.update({ + where: { + id + }, + data: { + isActive: false + } + }) + + // create log user + const log = await createLogUserMobile({ act: 'DELETE', desc: 'User menghapus komentar pada diskusi umum', table: 'discussionComment', data: id, user: userMobile.id }) + return NextResponse.json({ success: true, message: "Berhasil mengedit komentar" }, { status: 200 }); + + } catch (error) { + console.error(error) + return NextResponse.json({ success: false, message: "Gagal mengedit komentar, coba lagi nanti (error: 500)" }) + } } \ No newline at end of file diff --git a/src/app/api/mobile/discussion-general/route.ts b/src/app/api/mobile/discussion-general/route.ts index bb46a00..b890761 100644 --- a/src/app/api/mobile/discussion-general/route.ts +++ b/src/app/api/mobile/discussion-general/route.ts @@ -75,6 +75,9 @@ export async function GET(request: Request) { DiscussionComment: { select: { id: true, + }, + where: { + isActive: true } } } diff --git a/src/app/api/mobile/discussion/[id]/comment/route.ts b/src/app/api/mobile/discussion/[id]/comment/route.ts index 34d86ec..57f7b2e 100644 --- a/src/app/api/mobile/discussion/[id]/comment/route.ts +++ b/src/app/api/mobile/discussion/[id]/comment/route.ts @@ -5,7 +5,7 @@ import _ from "lodash"; import { NextResponse } from "next/server"; import { sendFCMNotificationMany } from "../../../../../../../xsendMany"; -// CREATE COMENT BY ID KOMENTAR +// CREATE COMENT export async function POST(request: Request, context: { params: { id: string } }) { try { const { id } = context.params @@ -156,4 +156,103 @@ export async function POST(request: Request, context: { params: { id: string } } console.error(error); return NextResponse.json({ success: false, message: "Gagal menambah komentar, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); } +} + +// EDIT KOMENTAR +export async function PUT(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params + const { comment, user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "User tidak ditemukan" }, { status: 200 }); + } + + const cek = await prisma.divisionDisscussionComment.count({ + where: { + id, + isActive: true + } + }) + + if (cek == 0) { + return NextResponse.json( + { + success: false, + message: "Edit komentar gagal, data tidak ditemukan", + }, + { status: 200 } + ); + } + + const data = await prisma.divisionDisscussionComment.update({ + where: { + id: id + }, + data: { + comment: comment, + isEdited: true + } + }) + + // create log user + const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User mengedit komentar pada diskusi divisi', table: 'divisionDisscussionComment', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Berhasil mengedit komentar" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menambah komentar, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } +} + +// HAPUS KOMENTAR +export async function DELETE(request: Request, context: { params: { id: string } }) { + try { + const { id } = context.params + const { user } = (await request.json()); + + const userMobile = await funGetUserById({ id: String(user) }) + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "User tidak ditemukan" }, { status: 200 }); + } + + const cek = await prisma.divisionDisscussionComment.count({ + where: { + id, + isActive: true + } + }) + + if (cek == 0) { + return NextResponse.json( + { + success: false, + message: "Hapus komentar gagal, data tidak ditemukan", + }, + { status: 200 } + ); + } + + const data = await prisma.divisionDisscussionComment.update({ + where: { + id: id + }, + data: { + isActive: false + } + }) + + // create log user + const log = await createLogUserMobile({ act: 'DELETE', desc: 'User menghapus komentar pada diskusi divisi', table: 'divisionDisscussionComment', data: id, user: userMobile.id }) + + return NextResponse.json({ success: true, message: "Berhasil menghapus komentar" }, { status: 200 }); + + } catch (error) { + console.error(error); + return NextResponse.json({ success: false, message: "Gagal menghapus komentar, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); + } } \ No newline at end of file diff --git a/src/app/api/mobile/discussion/[id]/route.ts b/src/app/api/mobile/discussion/[id]/route.ts index 65930b1..14d676d 100644 --- a/src/app/api/mobile/discussion/[id]/route.ts +++ b/src/app/api/mobile/discussion/[id]/route.ts @@ -38,7 +38,8 @@ export async function GET(request: Request, context: { params: { id: string } }) if (cat == "comment") { const data = await prisma.divisionDisscussionComment.findMany({ where: { - idDisscussion: id + idDisscussion: id, + isActive: true }, select: { id: true, diff --git a/src/app/api/mobile/discussion/route.ts b/src/app/api/mobile/discussion/route.ts index 9dbdb43..3003002 100644 --- a/src/app/api/mobile/discussion/route.ts +++ b/src/app/api/mobile/discussion/route.ts @@ -67,6 +67,9 @@ export async function GET(request: Request) { DivisionDisscussionComment: { select: { id: true, + }, + where: { + isActive: true } } } From bd1758ce3255ec85e516b12821a595875059e5d8 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 14 Oct 2025 15:13:51 +0800 Subject: [PATCH 14/32] upd: api diskusi komentar deskripsi: - api komentar pada website diskusi umum dan diskusi divisi NO Issues --- src/app/api/discussion-general/route.ts | 3 +++ src/app/api/discussion/[id]/route.ts | 3 +++ src/app/api/discussion/route.ts | 3 +++ 3 files changed, 9 insertions(+) diff --git a/src/app/api/discussion-general/route.ts b/src/app/api/discussion-general/route.ts index c3489e0..f2858e3 100644 --- a/src/app/api/discussion-general/route.ts +++ b/src/app/api/discussion-general/route.ts @@ -74,6 +74,9 @@ export async function GET(request: Request) { DiscussionComment: { select: { id: true, + }, + where:{ + isActive:true } } } diff --git a/src/app/api/discussion/[id]/route.ts b/src/app/api/discussion/[id]/route.ts index cf7fd56..1f140bc 100644 --- a/src/app/api/discussion/[id]/route.ts +++ b/src/app/api/discussion/[id]/route.ts @@ -60,6 +60,9 @@ export async function GET(request: Request, context: { params: { id: string } }) img: true } } + }, + where: { + isActive:true } }, } diff --git a/src/app/api/discussion/route.ts b/src/app/api/discussion/route.ts index cc59f3d..dd174f3 100644 --- a/src/app/api/discussion/route.ts +++ b/src/app/api/discussion/route.ts @@ -64,6 +64,9 @@ export async function GET(request: Request) { DivisionDisscussionComment: { select: { id: true, + }, + where:{ + isActive:true } } } From 18023807cd1b4d27a03de1dd5060d8120bf2e8bc Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 14 Oct 2025 15:14:08 +0800 Subject: [PATCH 15/32] upd: api version app --- src/app/api/version-app/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/version-app/route.ts b/src/app/api/version-app/route.ts index d7d65b4..ed8f69f 100644 --- a/src/app/api/version-app/route.ts +++ b/src/app/api/version-app/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export async function GET(request: Request) { try { - return NextResponse.json({ success: true, version: "2.0.7", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); + return NextResponse.json({ success: true, version: "2.0.8", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); From 4a4be31921f3da8a42f469bcf64f170f62587018 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 15 Oct 2025 14:51:58 +0800 Subject: [PATCH 16/32] upd: api website dan mobile Deskripsi: - update order komentar pada mobile dan website pada fitur diskusi umum dan diskusi divisi No Issues --- src/app/api/discussion-general/[id]/route.ts | 5 ++++- src/app/api/discussion/[id]/route.ts | 3 +++ src/app/api/mobile/discussion-general/[id]/route.ts | 3 +++ src/app/api/mobile/discussion/[id]/route.ts | 3 +++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/app/api/discussion-general/[id]/route.ts b/src/app/api/discussion-general/[id]/route.ts index 7e27184..a600a87 100644 --- a/src/app/api/discussion-general/[id]/route.ts +++ b/src/app/api/discussion-general/[id]/route.ts @@ -3,8 +3,8 @@ import { funGetUserByCookies } from "@/module/auth"; import { createLogUser } from "@/module/user"; import _ from "lodash"; import moment from "moment"; -import { NextResponse } from "next/server"; import "moment/locale/id"; +import { NextResponse } from "next/server"; // GET ONE DETAIL DISKUSI UMUM @@ -75,6 +75,9 @@ export async function GET(request: Request, context: { params: { id: string } }) img: true } } + }, + orderBy: { + createdAt: "asc" } }) diff --git a/src/app/api/discussion/[id]/route.ts b/src/app/api/discussion/[id]/route.ts index 1f140bc..47cfbaf 100644 --- a/src/app/api/discussion/[id]/route.ts +++ b/src/app/api/discussion/[id]/route.ts @@ -63,6 +63,9 @@ export async function GET(request: Request, context: { params: { id: string } }) }, where: { isActive:true + }, + orderBy: { + createdAt: "asc" } }, } diff --git a/src/app/api/mobile/discussion-general/[id]/route.ts b/src/app/api/mobile/discussion-general/[id]/route.ts index d538689..fb2ea1b 100644 --- a/src/app/api/mobile/discussion-general/[id]/route.ts +++ b/src/app/api/mobile/discussion-general/[id]/route.ts @@ -77,6 +77,9 @@ export async function GET(request: Request, context: { params: { id: string } }) img: true } } + }, + orderBy: { + createdAt: "asc" } }) diff --git a/src/app/api/mobile/discussion/[id]/route.ts b/src/app/api/mobile/discussion/[id]/route.ts index 14d676d..b131309 100644 --- a/src/app/api/mobile/discussion/[id]/route.ts +++ b/src/app/api/mobile/discussion/[id]/route.ts @@ -54,6 +54,9 @@ export async function GET(request: Request, context: { params: { id: string } }) img: true } } + }, + orderBy: { + createdAt: "asc" } }) From 10b9037fda5b34d2b94c33efe23b3378dd841e69 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 15 Oct 2025 14:52:17 +0800 Subject: [PATCH 17/32] upd: api version --- src/app/api/version-app/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/version-app/route.ts b/src/app/api/version-app/route.ts index ed8f69f..ba17ddf 100644 --- a/src/app/api/version-app/route.ts +++ b/src/app/api/version-app/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export async function GET(request: Request) { try { - return NextResponse.json({ success: true, version: "2.0.8", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); + return NextResponse.json({ success: true, version: "2.0.9", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); From ed2c9495c3ea481622e8e5bf2502de20c2575a42 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 16 Oct 2025 14:53:23 +0800 Subject: [PATCH 18/32] upd: api mobile status saat error --- src/app/api/mobile/announcement/[id]/route.ts | 5 +++-- src/app/api/mobile/banner/route.ts | 2 +- src/app/api/mobile/discussion-general/[id]/route.ts | 4 ++-- src/app/api/mobile/discussion-general/route.ts | 2 +- src/app/api/mobile/discussion/[id]/route.ts | 4 ++-- src/app/api/mobile/discussion/route.ts | 4 ++-- src/app/api/mobile/group/[id]/route.ts | 12 ++++++------ src/app/api/mobile/group/route.ts | 4 ++-- src/app/api/mobile/home/search/route.ts | 2 +- src/app/api/mobile/position/[id]/route.ts | 8 ++++---- src/app/api/mobile/position/route.ts | 8 ++++---- src/app/api/mobile/user/[id]/route.ts | 8 ++++---- src/app/api/mobile/user/profile/route.ts | 2 +- src/app/api/version-app/route.ts | 2 +- 14 files changed, 34 insertions(+), 33 deletions(-) diff --git a/src/app/api/mobile/announcement/[id]/route.ts b/src/app/api/mobile/announcement/[id]/route.ts index 9c7710b..0ca038a 100644 --- a/src/app/api/mobile/announcement/[id]/route.ts +++ b/src/app/api/mobile/announcement/[id]/route.ts @@ -20,6 +20,7 @@ export async function GET(request: Request, context: { params: { id: string } }) const data = await prisma.announcement.count({ where: { id: id, + isActive: true, }, }); @@ -29,7 +30,7 @@ export async function GET(request: Request, context: { params: { id: string } }) success: false, message: "Gagal mendapatkan pengumuman, data tidak ditemukan", }, - { status: 404 } + { status: 200 } ); } @@ -173,7 +174,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) success: false, message: "Edit pengumuman gagal, data tidak ditemukan", }, - { status: 404 } + { status: 200 } ); } diff --git a/src/app/api/mobile/banner/route.ts b/src/app/api/mobile/banner/route.ts index 160d4b6..5350995 100644 --- a/src/app/api/mobile/banner/route.ts +++ b/src/app/api/mobile/banner/route.ts @@ -11,7 +11,7 @@ export async function GET(request: Request) { const userMobile = searchParams.get("user") if (userMobile == "null" || userMobile == undefined || userMobile == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const user = await funGetUserById({ id: userMobile }) diff --git a/src/app/api/mobile/discussion-general/[id]/route.ts b/src/app/api/mobile/discussion-general/[id]/route.ts index fb2ea1b..19b4656 100644 --- a/src/app/api/mobile/discussion-general/[id]/route.ts +++ b/src/app/api/mobile/discussion-general/[id]/route.ts @@ -19,7 +19,7 @@ export async function GET(request: Request, context: { params: { id: string } }) const user = await funGetUserById({ id: String(userMobile) }) if (user.id == "null" || user.id == undefined || user.id == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const cek = await prisma.discussion.count({ @@ -29,7 +29,7 @@ export async function GET(request: Request, context: { params: { id: string } }) }) if (cek == 0) { - return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, data tidak ditemukan" }, { status: 404 }); + return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, data tidak ditemukan" }, { status: 200 }); } if (kategori == "detail") { diff --git a/src/app/api/mobile/discussion-general/route.ts b/src/app/api/mobile/discussion-general/route.ts index b890761..875d76d 100644 --- a/src/app/api/mobile/discussion-general/route.ts +++ b/src/app/api/mobile/discussion-general/route.ts @@ -15,7 +15,7 @@ export async function GET(request: Request) { const { searchParams } = new URL(request.url); const user = searchParams.get("user") if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const userMobile = await funGetUserById({ id: user }) diff --git a/src/app/api/mobile/discussion/[id]/route.ts b/src/app/api/mobile/discussion/[id]/route.ts index b131309..33de9f9 100644 --- a/src/app/api/mobile/discussion/[id]/route.ts +++ b/src/app/api/mobile/discussion/[id]/route.ts @@ -31,7 +31,7 @@ export async function GET(request: Request, context: { params: { id: string } }) success: false, message: "Gagal mendapatkan diskusi, data tidak ditemukan", }, - { status: 404 } + { status: 200 } ); } @@ -137,7 +137,7 @@ export async function DELETE(request: Request, context: { params: { id: string } }); if (data == 0) { - return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, data tidak ditemukan" }, { status: 404 }); + return NextResponse.json({ success: false, message: "Gagal mendapatkan diskusi, data tidak ditemukan" }, { status: 200 }); } const result = await prisma.divisionDisscussion.update({ diff --git a/src/app/api/mobile/discussion/route.ts b/src/app/api/mobile/discussion/route.ts index 3003002..663b00b 100644 --- a/src/app/api/mobile/discussion/route.ts +++ b/src/app/api/mobile/discussion/route.ts @@ -35,7 +35,7 @@ export async function GET(request: Request) { }) if (cekDivision == 0) { - return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 }); + return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 200 }); } const data = await prisma.divisionDisscussion.findMany({ @@ -121,7 +121,7 @@ export async function POST(request: Request) { }) if (cekDivision == 0) { - return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 404 }); + return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan" }, { status: 200 }); } const data = await prisma.divisionDisscussion.create({ diff --git a/src/app/api/mobile/group/[id]/route.ts b/src/app/api/mobile/group/[id]/route.ts index 106a238..4a418bc 100644 --- a/src/app/api/mobile/group/[id]/route.ts +++ b/src/app/api/mobile/group/[id]/route.ts @@ -12,7 +12,7 @@ export async function GET(request: Request, context: { params: { id: string } }) const userMobile = searchParams.get("user") if (userMobile == "null" || userMobile == undefined || userMobile == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const { id } = context.params; @@ -28,7 +28,7 @@ export async function GET(request: Request, context: { params: { id: string } }) success: false, message: "Gagal mendapatkan grup, data tidak ditemukan", }, - { status: 404 } + { status: 200 } ); } @@ -52,7 +52,7 @@ export async function DELETE(request: Request, context: { params: { id: string } const { isActive, user } = (await request.json()); if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const userLogin = await funGetUserById({ id: user }) @@ -68,7 +68,7 @@ export async function DELETE(request: Request, context: { params: { id: string } success: false, message: "Edit grup gagal, data tidak ditemukan", }, - { status: 404 } + { status: 200 } ); } @@ -98,7 +98,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) const { name, user } = (await request.json()); if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const data = await prisma.group.count({ @@ -113,7 +113,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) success: false, message: "Edit grup gagal, data tidak ditemukan", }, - { status: 404 } + { status: 200 } ); } diff --git a/src/app/api/mobile/group/route.ts b/src/app/api/mobile/group/route.ts index 95944b2..b0266f1 100644 --- a/src/app/api/mobile/group/route.ts +++ b/src/app/api/mobile/group/route.ts @@ -11,7 +11,7 @@ export async function GET(request: Request) { const userMobile = searchParams.get("user") if (userMobile == "null" || userMobile == undefined || userMobile == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const user = await funGetUserById({ id: userMobile }) @@ -51,7 +51,7 @@ export async function POST(request: Request) { const { name, user } = (await request.json()); if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const userMobile = await funGetUserById({ id: user }) diff --git a/src/app/api/mobile/home/search/route.ts b/src/app/api/mobile/home/search/route.ts index 5caacb6..83c5ef7 100644 --- a/src/app/api/mobile/home/search/route.ts +++ b/src/app/api/mobile/home/search/route.ts @@ -11,7 +11,7 @@ export async function GET(request: Request) { const userMobile = searchParams.get("user") if (userMobile == "null" || userMobile == undefined || userMobile == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const userId = await funGetUserById({ id: userMobile }) diff --git a/src/app/api/mobile/position/[id]/route.ts b/src/app/api/mobile/position/[id]/route.ts index 7655611..a51cdc2 100644 --- a/src/app/api/mobile/position/[id]/route.ts +++ b/src/app/api/mobile/position/[id]/route.ts @@ -11,7 +11,7 @@ export async function GET(request: Request, context: { params: { id: string } }) const { id } = context.params; if (userMobile == "null" || userMobile == undefined || userMobile == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const data = await prisma.position.findUnique({ @@ -30,7 +30,7 @@ export async function GET(request: Request, context: { params: { id: string } }) success: false, message: "Gagal mendapatkan jabatan, data tidak ditemukan", }, - { status: 404 } + { status: 200 } ); } @@ -55,7 +55,7 @@ export async function DELETE(request: Request, context: { params: { id: string } const { isActive, user } = (await request.json()); if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const data = await prisma.position.count({ @@ -104,7 +104,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) const { name, idGroup, user } = await request.json(); if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const cek = await prisma.position.count({ diff --git a/src/app/api/mobile/position/route.ts b/src/app/api/mobile/position/route.ts index eeec356..3d52fdd 100644 --- a/src/app/api/mobile/position/route.ts +++ b/src/app/api/mobile/position/route.ts @@ -16,7 +16,7 @@ export async function GET(request: Request) { const userMobile = searchParams.get("user") if (userMobile == "null" || userMobile == undefined || userMobile == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const user = await funGetUserById({ id: userMobile }) @@ -35,7 +35,7 @@ export async function GET(request: Request) { }) if (cek == 0) { - return NextResponse.json({ success: false, message: "Gagal mendapatkan jabatan, data tidak ditemukan", }, { status: 404 }); + return NextResponse.json({ success: false, message: "Gagal mendapatkan jabatan, data tidak ditemukan", }, { status: 200 }); } const filter = await prisma.group.findUnique({ @@ -93,7 +93,7 @@ export async function POST(request: Request) { const { name, idGroup, user } = await request.json(); if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const userMobile = await funGetUserById({ id: user }) @@ -131,7 +131,7 @@ export async function POST(request: Request) { } else { return NextResponse.json( { success: false, message: "Jabatan sudah ada" }, - { status: 400 } + { status: 200 } ); } diff --git a/src/app/api/mobile/user/[id]/route.ts b/src/app/api/mobile/user/[id]/route.ts index 0fffb77..bcaf08a 100644 --- a/src/app/api/mobile/user/[id]/route.ts +++ b/src/app/api/mobile/user/[id]/route.ts @@ -87,7 +87,7 @@ export async function DELETE(request: Request, context: { params: { id: string } const { isActive, user } = (await request.json()); if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const data = await prisma.user.count({ @@ -102,7 +102,7 @@ export async function DELETE(request: Request, context: { params: { id: string } success: false, message: "Gagal mendapatkan anggota, data tidak ditemukan", }, - { status: 404 } + { status: 200 } ); } @@ -158,7 +158,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) } = JSON.parse(data as string) if (user == "null" || user == undefined || user == "") { - return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 401 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const cekNIK = await prisma.user.count({ @@ -247,7 +247,7 @@ export async function PUT(request: Request, context: { params: { id: string } }) { status: 200 } ); } else { - return Response.json({ success: false, message: "Anggota sudah ada" }, { status: 400 }); + return Response.json({ success: false, message: "Anggota sudah ada" }, { status: 200 }); } } catch (error) { console.error(error); diff --git a/src/app/api/mobile/user/profile/route.ts b/src/app/api/mobile/user/profile/route.ts index 8db6104..5996e02 100644 --- a/src/app/api/mobile/user/profile/route.ts +++ b/src/app/api/mobile/user/profile/route.ts @@ -11,7 +11,7 @@ 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 }); + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } const data = await prisma.user.findUnique({ where: { diff --git a/src/app/api/version-app/route.ts b/src/app/api/version-app/route.ts index ba17ddf..4fccbfa 100644 --- a/src/app/api/version-app/route.ts +++ b/src/app/api/version-app/route.ts @@ -2,7 +2,7 @@ import { NextResponse } from "next/server"; export async function GET(request: Request) { try { - return NextResponse.json({ success: true, version: "2.0.9", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); + return NextResponse.json({ success: true, version: "2.1.0", tahap: "beta", update: "-api mobile; -login tanpa otp (mobile app); -tambah laporan pada project dan tugas divisi; -tambah upload link pada project dan tugas divisi; -tambah detail tanggal dan jam pada project dan tugas divisi; -api jenna ai; -privacy policy" }, { status: 200 }); } catch (error) { console.error(error); return NextResponse.json({ success: false, version: "Gagal mendapatkan version, coba lagi nanti (error: 500)", reason: (error as Error).message, }, { status: 500 }); From 3ab2566a8973629ab63c710252bb0be7dd73520c Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Mon, 27 Oct 2025 10:32:54 +0800 Subject: [PATCH 19/32] update --- src/app/api/mobile/discussion-general/[id]/route.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/api/mobile/discussion-general/[id]/route.ts b/src/app/api/mobile/discussion-general/[id]/route.ts index 19b4656..a1b536f 100644 --- a/src/app/api/mobile/discussion-general/[id]/route.ts +++ b/src/app/api/mobile/discussion-general/[id]/route.ts @@ -8,7 +8,7 @@ import { NextResponse } from "next/server"; // GET ONE DETAIL DISKUSI UMUM -export async function GET(request: Request, context: { params: { id: string } }) { +export async function GET(request : Request, context: { params: { id: string } }) { try { let dataFix const { id } = context.params From 9f3acf306e24d7ea8f6b6039142316d4a0d63eaa Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 14 Jan 2026 15:02:43 +0800 Subject: [PATCH 20/32] req: pengumuman Deskripsi: - struktur db pengumuman - api tambah pengumuman - api detail pengumuman - api update pengumuman No Issues --- prisma/schema.prisma | 21 +++++-- src/app/api/mobile/announcement/[id]/route.ts | 59 ++++++++++++++++++- src/app/api/mobile/announcement/route.ts | 32 +++++++++- src/module/_global/bin/val_global.ts | 7 ++- 4 files changed, 107 insertions(+), 12 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index b187a9d..7324a97 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -168,16 +168,29 @@ model Announcement { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt AnnouncementMember AnnouncementMember[] + AnnouncementFile AnnouncementFile[] } 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 AnnouncementFile { 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 + name String + extension String + idStorage String? isActive Boolean @default(true) createdAt DateTime @default(now()) updatedAt DateTime @updatedAt diff --git a/src/app/api/mobile/announcement/[id]/route.ts b/src/app/api/mobile/announcement/[id]/route.ts index 0ca038a..868c65a 100644 --- a/src/app/api/mobile/announcement/[id]/route.ts +++ b/src/app/api/mobile/announcement/[id]/route.ts @@ -1,4 +1,4 @@ -import { prisma } from "@/module/_global"; +import { DIR, funUploadFile, prisma } from "@/module/_global"; import { funGetUserById } from "@/module/auth"; import { createLogUserMobile } from "@/module/user"; import _ from "lodash"; @@ -76,13 +76,26 @@ export async function GET(request: Request, context: { params: { id: string } }) // const fixMember = Object.groupBy(formatMember, ({ group }) => group); const fixMember = _.groupBy(formatMember, ({ group }) => group); + const file = await prisma.announcementFile.findMany({ + where: { + idAnnouncement: id + }, + select: { + id: true, + idStorage: true, + name: true, + extension: true + } + }) + return NextResponse.json( { success: true, message: "Berhasil mendapatkan pengumuman", data: announcement, - member: fixMember + member: fixMember, + file: file }, { status: 200 } ); @@ -154,7 +167,12 @@ export async function DELETE(request: Request, context: { params: { id: string } // EDIT PENGUMUMAN export async function PUT(request: Request, context: { params: { id: string } }) { try { - const { title, desc, groups, user } = (await request.json()); + const body = await request.formData() + const dataBody = body.get("data") + const cekFile = body.has("file0") + + // const { title, desc, groups, user } = (await request.json()); + const { title, desc, groups, user, oldFile } = JSON.parse(dataBody as string) const { id } = context.params; const userMobile = await funGetUserById({ id: String(user) }) @@ -214,6 +232,41 @@ export async function PUT(request: Request, context: { params: { id: string } }) data: memberDivision, }); + if (oldFile.length > 0) { + for (let index = 0; index < oldFile.length; index++) { + const element = oldFile[index]; + if (element.delete) { + await prisma.announcementFile.delete({ + where: { + id: element.id + } + }) + } + } + } + + if (cekFile) { + body.delete("data") + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = decodeURIComponent(file.name.replace("." + fExt, "")) + const upload = await funUploadFile({ file: file, dirId: DIR.announcement }) + if (upload.success) { + await prisma.announcementFile.create({ + data: { + idStorage: upload.data.id, + idAnnouncement: id, + name: fName, + extension: String(fExt) + } + }) + } + } + } + } + // create log user const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User mengupdate data pengumuman', table: 'announcement', data: id, user: userMobile.id }) diff --git a/src/app/api/mobile/announcement/route.ts b/src/app/api/mobile/announcement/route.ts index 822227d..abd8ea9 100644 --- a/src/app/api/mobile/announcement/route.ts +++ b/src/app/api/mobile/announcement/route.ts @@ -1,4 +1,4 @@ -import { funSendWebPush, prisma } from "@/module/_global"; +import { DIR, funSendWebPush, funUploadFile, prisma } from "@/module/_global"; import { funGetUserById } from "@/module/auth"; import { createLogUserMobile } from '@/module/user'; import _ from "lodash"; @@ -113,7 +113,12 @@ export async function GET(request: Request) { // CREATE PENGUMUMAN export async function POST(request: Request) { try { - const { title, desc, groups, user } = (await request.json()); + const body = await request.formData() + const dataBody = body.get("data") + const cekFile = body.has("file0") + + // const { title, desc, groups, user } = (await request.json()); + const { title, desc, groups, user } = JSON.parse(dataBody as string) const userMobile = await funGetUserById({ id: String(user) }) if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { @@ -152,6 +157,29 @@ export async function POST(request: Request) { } } + + if (cekFile) { + body.delete("data") + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = decodeURIComponent(file.name.replace("." + fExt, "")) + const upload = await funUploadFile({ file: file, dirId: DIR.announcement }) + if (upload.success) { + await prisma.announcementFile.create({ + data: { + idStorage: upload.data.id, + idAnnouncement: data.id, + name: fName, + extension: String(fExt) + } + }) + } + } + } + } + const announcementMember = await prisma.announcementMember.createMany({ data: memberDivision, }); diff --git a/src/module/_global/bin/val_global.ts b/src/module/_global/bin/val_global.ts index 906b7d7..74844c1 100644 --- a/src/module/_global/bin/val_global.ts +++ b/src/module/_global/bin/val_global.ts @@ -1,6 +1,6 @@ -import { hookstate } from "@hookstate/core" -import { IGlobalTema } from './type_global'; +import { hookstate } from "@hookstate/core"; import { RefObject } from "react"; +import { IGlobalTema } from './type_global'; export const pwd_key_config = "fchgvjknlmdfnbvghhujlaknsdvjbhknlkmsdbdyu567t8y9u30r4587638y9uipkoeghjvuyi89ipkoefmnrjbhtiu4or9ipkoemnjfbhjiuoijdklnjhbviufojkejnshbiuojijknehgruyu" export const globalRole = hookstate('') @@ -11,7 +11,8 @@ export const DIR = { document: "cm0xhbkf50009acbbtw03qo4l", village: "cm0xhb91o0007acbbkx8rk8hj", user: "cm0x8dbwn0005bp5tgmfcthzw", - banner: "cm1sxex19004938bjvyaq8vta" + banner: "cm1sxex19004938bjvyaq8vta", + announcement: "cmkdfkze4005hkhjgunsroi4t" } export const keyWibu = 'padahariminggukuturutayahkekotanaikdelmanistimewakududukdimuka' From 968202e34b2a07a72b983b36fcded27365e3d15b Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 15 Jan 2026 17:34:51 +0800 Subject: [PATCH 21/32] upd: api diskusi umum Deskripsi: - tambah file pada data diskusi umum - detail file pada get one diskusi umum No Issues --- prisma/schema.prisma | 33 +++++++--- .../mobile/discussion-general/[id]/route.ts | 61 +++++++++++++++++-- .../api/mobile/discussion-general/route.ts | 38 ++++++++++-- src/module/_global/bin/val_global.ts | 3 +- 4 files changed, 116 insertions(+), 19 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 7324a97..f46fcb0 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -172,16 +172,16 @@ model Announcement { } 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 + 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 AnnouncementFile { @@ -608,6 +608,7 @@ model Discussion { updatedAt DateTime @updatedAt DiscussionMember DiscussionMember[] DiscussionComment DiscussionComment[] + DiscussionFile DiscussionFile[] } model DiscussionMember { @@ -633,3 +634,15 @@ model DiscussionComment { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } + +model DiscussionFile { + id String @id @default(cuid()) + Discussion Discussion @relation(fields: [idDiscussion], references: [id]) + idDiscussion String + name String + extension String + idStorage String? + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} diff --git a/src/app/api/mobile/discussion-general/[id]/route.ts b/src/app/api/mobile/discussion-general/[id]/route.ts index a1b536f..8df834b 100644 --- a/src/app/api/mobile/discussion-general/[id]/route.ts +++ b/src/app/api/mobile/discussion-general/[id]/route.ts @@ -1,4 +1,4 @@ -import { countTime, prisma } from "@/module/_global"; +import { countTime, DIR, funUploadFile, prisma } from "@/module/_global"; import { funGetUserById } from "@/module/auth"; import { createLogUserMobile } from "@/module/user"; import _ from "lodash"; @@ -8,7 +8,7 @@ import { NextResponse } from "next/server"; // GET ONE DETAIL DISKUSI UMUM -export async function GET(request : Request, context: { params: { id: string } }) { +export async function GET(request: Request, context: { params: { id: string } }) { try { let dataFix const { id } = context.params @@ -127,8 +127,21 @@ export async function GET(request : Request, context: { params: { id: string } } } else { dataFix = false } - } + } else if (kategori == "file") { + const data = await prisma.discussionFile.findMany({ + where: { + idDiscussion: id + }, + select: { + id: true, + idStorage: true, + name: true, + extension: true + } + }) + dataFix = data + } return NextResponse.json({ success: true, message: "Berhasil mendapatkan diskusi", data: dataFix }, { status: 200 }); @@ -247,7 +260,12 @@ export async function DELETE(request: Request, context: { params: { id: string } export async function PUT(request: Request, context: { params: { id: string } }) { try { const { id } = context.params - const { title, desc, user } = (await request.json()); + const body = await request.formData() + const dataBody = body.get("data") + const cekFile = body.has("file0") + + // const { title, desc, user } = (await request.json()); + const { title, desc, user, oldFile } = JSON.parse(dataBody as string) const userMobile = await funGetUserById({ id: String(user) }) @@ -275,6 +293,41 @@ export async function PUT(request: Request, context: { params: { id: string } }) } }); + if (oldFile.length > 0) { + for (let index = 0; index < oldFile.length; index++) { + const element = oldFile[index]; + if (element.delete) { + await prisma.discussionFile.delete({ + where: { + id: element.id + } + }) + } + } + } + + if (cekFile) { + body.delete("data") + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = decodeURIComponent(file.name.replace("." + fExt, "")) + const upload = await funUploadFile({ file: file, dirId: DIR.discussion }) + if (upload.success) { + await prisma.discussionFile.create({ + data: { + idStorage: upload.data.id, + idDiscussion: id, + name: fName, + extension: String(fExt) + } + }) + } + } + } + } + // create log user const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User mengupdate data diskusi umum', table: 'discussion', data: id, user: userMobile.id }) return NextResponse.json({ success: true, message: "Berhasil mengedit diskusi umum" }, { status: 200 }); diff --git a/src/app/api/mobile/discussion-general/route.ts b/src/app/api/mobile/discussion-general/route.ts index 875d76d..ac5c351 100644 --- a/src/app/api/mobile/discussion-general/route.ts +++ b/src/app/api/mobile/discussion-general/route.ts @@ -1,4 +1,4 @@ -import { prisma } from "@/module/_global"; +import { DIR, funUploadFile, prisma } from "@/module/_global"; import { funGetUserById } from "@/module/auth"; import { createLogUserMobile } from "@/module/user"; import _ from "lodash"; @@ -112,13 +112,20 @@ export async function GET(request: Request) { // CREATE DISCUSSION GENERALE export async function POST(request: Request) { try { - const { idGroup, user, title, desc, member } = await request.json(); - if (user == "null" || user == undefined || user == "") { + const body = await request.formData() + const dataBody = body.get("data") + const cekFile = body.has("file0") + + // const { idGroup, user, title, desc, member } = await request.json(); + const { idGroup, user, title, desc, member } = JSON.parse(dataBody as string) + + const userMobile = await funGetUserById({ id: user }) + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } - const userMobile = await funGetUserById({ id: user }) const userId = user const userRoleLogin = userMobile.idUserRole @@ -145,6 +152,29 @@ export async function POST(request: Request) { data: dataMember }) + + if (cekFile) { + body.delete("data") + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = decodeURIComponent(file.name.replace("." + fExt, "")) + const upload = await funUploadFile({ file: file, dirId: DIR.discussion }) + if (upload.success) { + await prisma.discussionFile.create({ + data: { + idStorage: upload.data.id, + idDiscussion: data.id, + name: fName, + extension: String(fExt) + } + }) + } + } + } + } + const memberNotifMobile = await prisma.discussionMember.findMany({ where: { idDiscussion: data.id diff --git a/src/module/_global/bin/val_global.ts b/src/module/_global/bin/val_global.ts index 74844c1..40fae51 100644 --- a/src/module/_global/bin/val_global.ts +++ b/src/module/_global/bin/val_global.ts @@ -12,7 +12,8 @@ export const DIR = { village: "cm0xhb91o0007acbbkx8rk8hj", user: "cm0x8dbwn0005bp5tgmfcthzw", banner: "cm1sxex19004938bjvyaq8vta", - announcement: "cmkdfkze4005hkhjgunsroi4t" + announcement: "cmkdfkze4005hkhjgunsroi4t", + discussion: "cmkf5h7ic006jkhjgyrkog7ut" } export const keyWibu = 'padahariminggukuturutayahkekotanaikdelmanistimewakududukdimuka' From e5b95a828d0cbdafeb85b6d5663dbde551e685f6 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Mon, 19 Jan 2026 10:21:56 +0800 Subject: [PATCH 22/32] upd: diskusi divisi deskripsi: - schema db - api tambah detail dan update diskusi divisi NO Issues' --- prisma/schema.prisma | 12 +++++++ src/app/api/mobile/discussion/[id]/route.ts | 15 +++++++++ src/app/api/mobile/discussion/route.ts | 35 +++++++++++++++++++-- src/module/_global/bin/val_global.ts | 3 +- 4 files changed, 62 insertions(+), 3 deletions(-) diff --git a/prisma/schema.prisma b/prisma/schema.prisma index f46fcb0..c2f5c11 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -423,6 +423,7 @@ model DivisionDisscussion { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt DivisionDisscussionComment DivisionDisscussionComment[] + DivisionDiscussionFile DivisionDiscussionFile[] } model DivisionDisscussionComment { @@ -437,6 +438,17 @@ model DivisionDisscussionComment { createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } +model DivisionDiscussionFile { + id String @id @default(cuid()) + DivisionDisscussion DivisionDisscussion @relation(fields: [idDiscussion], references: [id]) + idDiscussion String + name String + extension String + idStorage String? + isActive Boolean @default(true) + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt +} model DivisionDocumentFolderFile { id String @id @default(cuid()) diff --git a/src/app/api/mobile/discussion/[id]/route.ts b/src/app/api/mobile/discussion/[id]/route.ts index 33de9f9..07d9633 100644 --- a/src/app/api/mobile/discussion/[id]/route.ts +++ b/src/app/api/mobile/discussion/[id]/route.ts @@ -70,6 +70,21 @@ export async function GET(request: Request, context: { params: { id: string } }) })) return NextResponse.json({ success: true, message: "Berhasil mendapatkan komentar", data: omitMember }, { status: 200 }); + } else if (cat == "file") { + const data = await prisma.divisionDiscussionFile.findMany({ + where: { + idDiscussion: id, + isActive: true + }, + select: { + id: true, + idStorage: true, + name: true, + extension: true + } + }) + + return NextResponse.json({ success: true, message: "Berhasil mendapatkan file", data: data }, { status: 200 }); } else { const data = await prisma.divisionDisscussion.findUnique({ where: { diff --git a/src/app/api/mobile/discussion/route.ts b/src/app/api/mobile/discussion/route.ts index 663b00b..f8d8d27 100644 --- a/src/app/api/mobile/discussion/route.ts +++ b/src/app/api/mobile/discussion/route.ts @@ -1,4 +1,5 @@ -import { funSendWebPush, prisma } from "@/module/_global"; +import { DivisionDiscussionFile } from './../../../../../node_modules/.prisma/client/index.d'; +import { DIR, funSendWebPush, funUploadFile, prisma } from "@/module/_global"; import { funGetUserById } from "@/module/auth"; import { createLogUserMobile } from "@/module/user"; import _ from "lodash"; @@ -102,7 +103,14 @@ export async function GET(request: Request) { // CREATE DISCUSSION export async function POST(request: Request) { try { - const { idDivision, desc, user } = (await request.json()); + const body = await request.formData() + const dataBody = body.get("data") + const cekFile = body.has("file0") + + // const { idDivision, desc, user } = (await request.json()); + const { idDivision, desc, user } = JSON.parse(String(dataBody)); + + const userMobile = await funGetUserById({ id: String(user) }) if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { @@ -135,6 +143,29 @@ export async function POST(request: Request) { } }); + + if (cekFile) { + body.delete("data") + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = decodeURIComponent(file.name.replace("." + fExt, "")) + const upload = await funUploadFile({ file: file, dirId: DIR.discussionDivision }) + if (upload.success) { + await prisma.divisionDiscussionFile.create({ + data: { + idStorage: upload.data.id, + idDiscussion: data.id, + name: fName, + extension: String(fExt) + } + }) + } + } + } + } + const memberDivision = await prisma.divisionMember.findMany({ where: { idDivision: idDivision diff --git a/src/module/_global/bin/val_global.ts b/src/module/_global/bin/val_global.ts index 40fae51..9cde0ca 100644 --- a/src/module/_global/bin/val_global.ts +++ b/src/module/_global/bin/val_global.ts @@ -13,7 +13,8 @@ export const DIR = { user: "cm0x8dbwn0005bp5tgmfcthzw", banner: "cm1sxex19004938bjvyaq8vta", announcement: "cmkdfkze4005hkhjgunsroi4t", - discussion: "cmkf5h7ic006jkhjgyrkog7ut" + discussion: "cmkf5h7ic006jkhjgyrkog7ut", + discussionDivision: "cmkdfktfm005fkhjggjvnqly5" } export const keyWibu = 'padahariminggukuturutayahkekotanaikdelmanistimewakududukdimuka' From 9e11208a13584e7d6a638d8f462ce41cdc29d9cc Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Mon, 19 Jan 2026 15:08:33 +0800 Subject: [PATCH 23/32] upd: api diskusi divisi Deskripsi: - api tambah diskusi divisi - api edit diskusi divisi - api detail diskusi divisi NO Issues --- src/app/api/mobile/discussion/[id]/route.ts | 45 ++++++++++++++++++++- src/app/api/mobile/discussion/route.ts | 1 - 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/app/api/mobile/discussion/[id]/route.ts b/src/app/api/mobile/discussion/[id]/route.ts index 07d9633..ecfe8e2 100644 --- a/src/app/api/mobile/discussion/[id]/route.ts +++ b/src/app/api/mobile/discussion/[id]/route.ts @@ -1,4 +1,4 @@ -import { countTime, prisma } from "@/module/_global"; +import { countTime, DIR, funUploadFile, prisma } from "@/module/_global"; import { funGetUserById } from "@/module/auth"; import { createLogUserMobile } from "@/module/user"; import _ from "lodash"; @@ -227,7 +227,13 @@ export async function PUT(request: Request, context: { params: { id: string } }) export async function POST(request: Request, context: { params: { id: string } }) { try { const { id } = context.params - const { title, desc, user } = (await request.json()) + const body = await request.formData() + const dataBody = body.get("data") + const cekFile = body.has("file0") + + // const { title, desc, user } = (await request.json()) + const { title, desc, user, oldFile } = JSON.parse(dataBody as string) + const userMobile = await funGetUserById({ id: String(user) }) @@ -254,6 +260,41 @@ export async function POST(request: Request, context: { params: { id: string } } } }); + if (oldFile.length > 0) { + for (let index = 0; index < oldFile.length; index++) { + const element = oldFile[index]; + if (element.delete) { + await prisma.divisionDiscussionFile.delete({ + where: { + id: element.id + } + }) + } + } + } + + if (cekFile) { + body.delete("data") + for (var pair of body.entries()) { + if (String(pair[0]).substring(0, 4) == "file") { + const file = body.get(pair[0]) as File + const fExt = file.name.split(".").pop() + const fName = decodeURIComponent(file.name.replace("." + fExt, "")) + const upload = await funUploadFile({ file: file, dirId: DIR.discussionDivision }) + if (upload.success) { + await prisma.divisionDiscussionFile.create({ + data: { + idStorage: upload.data.id, + idDiscussion: id, + name: fName, + extension: String(fExt) + } + }) + } + } + } + } + // create log user const log = await createLogUserMobile({ act: 'UPDATE', desc: 'User mengupdate data diskusi', table: 'divisionDisscussion', data: id, user: userMobile.id }) return NextResponse.json({ success: true, message: "Berhasil mengedit diskusi" }, { status: 200 }); diff --git a/src/app/api/mobile/discussion/route.ts b/src/app/api/mobile/discussion/route.ts index f8d8d27..4f2d157 100644 --- a/src/app/api/mobile/discussion/route.ts +++ b/src/app/api/mobile/discussion/route.ts @@ -1,4 +1,3 @@ -import { DivisionDiscussionFile } from './../../../../../node_modules/.prisma/client/index.d'; import { DIR, funSendWebPush, funUploadFile, prisma } from "@/module/_global"; import { funGetUserById } from "@/module/auth"; import { createLogUserMobile } from "@/module/user"; From 183d40580db7a3eb7317ffae35601c6a7ef3d55e Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 22 Jan 2026 11:41:42 +0800 Subject: [PATCH 24/32] upd: seeder Deskripsi: - hapus data seeder lukman NO Issues --- src/module/seeder/data/admin.json | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/module/seeder/data/admin.json b/src/module/seeder/data/admin.json index a783b25..337f78c 100644 --- a/src/module/seeder/data/admin.json +++ b/src/module/seeder/data/admin.json @@ -8,15 +8,7 @@ "gender": "F" }, { - "id": "devLukman", - "idAdminRole": "dev", - "name": "Lukman", - "phone": "6287701790942", - "email": "lukman@bip.com", - "gender": "M" - }, - { - "id": "devLukman", + "id": "devMalik", "idAdminRole": "dev", "name": "Malik", "phone": "6289697338821", From bf9ef48a7057e60b9efb97161f2f5a83c5e73cd5 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Mon, 2 Feb 2026 10:14:39 +0800 Subject: [PATCH 25/32] revisi: api filter tahun Deskripsi: - api filter tahun project dan tugas divisi No Issues --- .../api/mobile/division/[id]/detail/route.ts | 10 ++++- src/app/api/mobile/project/route.ts | 14 ++++++- src/app/api/mobile/project/tahun/route.ts | 41 +++++++++++++++++++ src/app/api/mobile/task/route.ts | 13 ++++++ src/app/api/mobile/task/tahun/route.ts | 41 +++++++++++++++++++ 5 files changed, 117 insertions(+), 2 deletions(-) create mode 100644 src/app/api/mobile/project/tahun/route.ts create mode 100644 src/app/api/mobile/task/tahun/route.ts diff --git a/src/app/api/mobile/division/[id]/detail/route.ts b/src/app/api/mobile/division/[id]/detail/route.ts index 1d74a28..7470e2f 100644 --- a/src/app/api/mobile/division/[id]/detail/route.ts +++ b/src/app/api/mobile/division/[id]/detail/route.ts @@ -33,13 +33,21 @@ export async function GET(request: Request, context: { params: { id: string } }) } if (kategori == "jumlah") { + const tahunFilter = new Date().getFullYear().toString(); + const startTahun = new Date(`${tahunFilter}-01-01T00:00:00.000Z`); + const endTahun = new Date(`${parseInt(tahunFilter) + 1}-01-01T00:00:00.000Z`); + const tugas = await prisma.divisionProject.count({ where: { idDivision: String(id), status: { lte: 1 }, - isActive: true + isActive: true, + createdAt: { + gte: startTahun, + lt: endTahun + } } }) diff --git a/src/app/api/mobile/project/route.ts b/src/app/api/mobile/project/route.ts index bffa5f0..f480eb0 100644 --- a/src/app/api/mobile/project/route.ts +++ b/src/app/api/mobile/project/route.ts @@ -15,6 +15,7 @@ export async function GET(request: Request) { const name = searchParams.get('search'); const status = searchParams.get('status'); const idGroup = searchParams.get("group"); + const tahun = searchParams.get("year"); const page = searchParams.get('page'); const kategori = searchParams.get('cat'); const user = searchParams.get('user'); @@ -30,6 +31,9 @@ export async function GET(request: Request) { const roleUser = userMobile.idUserRole const villageId = userMobile.idVillage const userId = userMobile.id + const tahunFilter = tahun ? tahun : new Date().getFullYear().toString(); + const startTahun = new Date(`${tahunFilter}-01-01T00:00:00.000Z`); + const endTahun = new Date(`${parseInt(tahunFilter) + 1}-01-01T00:00:00.000Z`); if (idGroup == "null" || idGroup == undefined || idGroup == "" || idGroup == "undefined") { grup = userMobile.idGroup @@ -58,7 +62,11 @@ export async function GET(request: Request) { contains: (name == undefined || name == "null") ? "" : name, mode: "insensitive" }, - status: (status == "0" || status == "1" || status == "2" || status == "3") ? Number(status) : 0 + status: (status == "0" || status == "1" || status == "2" || status == "3") ? Number(status) : 0, + createdAt: { + gte: startTahun, + lt: endTahun + } } @@ -78,6 +86,10 @@ export async function GET(request: Request) { some: { idUser: String(userId) } + }, + createdAt: { + gte: startTahun, + lt: endTahun } } } diff --git a/src/app/api/mobile/project/tahun/route.ts b/src/app/api/mobile/project/tahun/route.ts new file mode 100644 index 0000000..192757f --- /dev/null +++ b/src/app/api/mobile/project/tahun/route.ts @@ -0,0 +1,41 @@ +import { prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const user = searchParams.get('user'); + const userMobile = await funGetUserById({ id: String(user) }) + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const villageId = userMobile.idVillage + const currentYear = new Date().getFullYear(); + + const data = await prisma.project.findMany({ + where: { + isActive: true, + idVillage: villageId, + }, + select: { + createdAt: true, + }, + }) + + const dataYear = data.map((item: any) => item.createdAt.getFullYear()) + // Hapus duplikat pakai Set + const uniqueYears = [...new Set(dataYear)]; + + // Tambahkan tahun sekarang kalau belum ada + if (!uniqueYears.includes(currentYear)) { + uniqueYears.push(currentYear); + } + + // (opsional) urutkan dari terbaru ke lama + uniqueYears.sort((a, b) => b - a); + + return NextResponse.json({ success: true, message: "Success", data: uniqueYears }, { status: 200 }); +} + diff --git a/src/app/api/mobile/task/route.ts b/src/app/api/mobile/task/route.ts index a83083b..0533f40 100644 --- a/src/app/api/mobile/task/route.ts +++ b/src/app/api/mobile/task/route.ts @@ -16,6 +16,11 @@ export async function GET(request: Request) { const page = searchParams.get('page'); const user = searchParams.get('user'); const dataSkip = Number(page) * 10 - 10; + const tahun = searchParams.get("year"); + + const tahunFilter = tahun ? tahun : new Date().getFullYear().toString(); + const startTahun = new Date(`${tahunFilter}-01-01T00:00:00.000Z`); + const endTahun = new Date(`${parseInt(tahunFilter) + 1}-01-01T00:00:00.000Z`); const userMobile = await funGetUserById({ id: String(user) }) if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { @@ -43,6 +48,10 @@ export async function GET(request: Request) { title: { contains: (name == undefined || name == "null") ? "" : name, mode: "insensitive" + }, + createdAt: { + gte: startTahun, + lt: endTahun } }, select: { @@ -87,6 +96,10 @@ export async function GET(request: Request) { title: { contains: (name == undefined || name == "null") ? "" : name, mode: "insensitive" + }, + createdAt: { + gte: startTahun, + lt: endTahun } } }) diff --git a/src/app/api/mobile/task/tahun/route.ts b/src/app/api/mobile/task/tahun/route.ts new file mode 100644 index 0000000..3df17b4 --- /dev/null +++ b/src/app/api/mobile/task/tahun/route.ts @@ -0,0 +1,41 @@ +import { prisma } from "@/module/_global"; +import { funGetUserById } from "@/module/auth"; +import { NextResponse } from "next/server"; + +export async function GET(request: Request) { + const { searchParams } = new URL(request.url); + const user = searchParams.get('user'); + const divisi = searchParams.get('division'); + const userMobile = await funGetUserById({ id: String(user) }) + const currentYear = new Date().getFullYear(); + + if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { + return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); + } + + const data = await prisma.divisionProject.findMany({ + where: { + isActive: true, + idDivision: String(divisi), + }, + select: { + createdAt: true, + }, + }) + + const dataYear = data.map((item: any) => item.createdAt.getFullYear()) + // Hapus duplikat pakai Set + const uniqueYears = [...new Set(dataYear)]; + + // Tambahkan tahun sekarang kalau belum ada + if (!uniqueYears.includes(currentYear)) { + uniqueYears.push(currentYear); + } + + // (opsional) urutkan dari terbaru ke lama + uniqueYears.sort((a, b) => b - a); + + + return NextResponse.json({ success: true, message: "Success", data: uniqueYears }, { status: 200 }); + +} \ No newline at end of file From 3b5849268099ca7aa16ab87cb9fa7c6c6451e108 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Mon, 2 Feb 2026 17:21:38 +0800 Subject: [PATCH 26/32] upd: api project Deskripsi: - api project tahun - api get project - qwen NoIssues --- QWEN.md | 204 ++++++++++++++++++++++ src/app/api/mobile/project/route.ts | 15 +- src/app/api/mobile/project/tahun/route.ts | 7 +- 3 files changed, 220 insertions(+), 6 deletions(-) create mode 100644 QWEN.md diff --git a/QWEN.md b/QWEN.md new file mode 100644 index 0000000..574a841 --- /dev/null +++ b/QWEN.md @@ -0,0 +1,204 @@ +# Sistem Desa Mandiri - Project Documentation + +## Project Overview + +Sistem Desa Mandiri is a comprehensive web application built with Next.js to assist with village-level administration and information management. The application provides various features to support village activities, including announcements, discussions, project management, and population administration. + +### Key Features +- **User Management**: Manage member data and access rights +- **Announcements**: Distribute important information to all village residents +- **Discussions**: Forum for discussions among villagers or village officials +- **Project & Task Management**: Track progress of ongoing village projects and tasks +- **Documentation**: Centralized location for storing and managing important documents +- **Push Notifications**: Send real-time notifications to user devices + +### Technology Stack +- **Framework**: Next.js 14 +- **UI Framework**: Mantine +- **Database ORM**: Prisma +- **Styling**: Tailwind CSS, CSS Modules +- **State Management**: Hookstate +- **Push Notifications**: Web Push +- **Authentication**: Custom cookie-based authentication system +- **Icons**: Tabler Icons React +- **Rich Text Editor**: TipTap +- **Charts**: Recharts, ECharts +- **Date Handling**: Day.js, Moment.js +- **File Upload**: Multer +- **Server Framework**: Elysia.js + +## Project Structure + +``` +sistem-desa-mandiri/ +├── src/ +│ ├── app/ # Next.js app router pages +│ │ ├── (application)/ # Main application routes +│ │ ├── (auth)/ # Authentication routes +│ │ ├── api/ # API routes +│ │ └── ... # Other route groups +│ ├── module/ # Feature modules organized by domain +│ │ ├── _global/ # Global components and utilities +│ │ ├── announcement/ # Announcement feature +│ │ ├── auth/ # Authentication feature +│ │ ├── discussion/ # Discussion forum +│ │ ├── document/ # Document management +│ │ ├── project/ # Project management +│ │ ├── user/ # User management +│ │ └── ... # Other feature modules +│ ├── lib/ # Utility functions and libraries +│ ├── types/ # TypeScript type definitions +├── public/ # Static assets +├── .env.test # Environment variables template +├── next.config.mjs # Next.js configuration +├── package.json # Dependencies and scripts +├── README.md # Project documentation +├── tailwind.config.ts # Tailwind CSS configuration +└── tsconfig.json # TypeScript configuration +``` + +### Module Organization +The application follows a modular architecture where each feature is contained in its own module directory under `/src/module/`. Each module typically contains: +- `api/` - API functions and server actions +- `ui/` - User interface components +- `hooks/` - Custom React hooks +- `types/` - Type definitions specific to the module +- `utils/` - Utility functions + +## Building and Running + +### Prerequisites +- Node.js (version 20.x or higher) +- Bun (recommended) or other package managers like npm/yarn/pnpm +- Database (PostgreSQL, MySQL, or SQLite) + +### Installation Steps +1. Clone the repository: +```bash +git clone https://github.com/username/sistem-desa-mandiri.git +cd sistem-desa-mandiri +``` + +2. Install dependencies: +```bash +bun install +``` + +3. Setup environment variables: +```bash +cp .env.test .env +``` +Edit the `.env` file and fill in the required variables, especially `DATABASE_URL`. + +4. Run Prisma migrations: +```bash +npx prisma migrate dev +``` + +5. Seed the database (optional): +```bash +npx prisma db seed +``` + +6. Run the development server: +```bash +bun run dev +``` +The application will run at https://localhost:3000 + +### Available Scripts +- `dev`: Runs the development server with HTTPS +- `build`: Creates a production build of the application +- `start`: Runs the production server +- `lint`: Runs the linter to check code quality +- `prisma:seed`: Runs the database seeding script + +## Development Conventions + +### Coding Standards +- Follow Next.js conventions for file-based routing +- Use TypeScript for type safety +- Maintain consistent component structure within modules +- Use Mantine components for UI elements +- Follow accessibility best practices + +### Naming Conventions +- Components: PascalCase (e.g., `UserProfile.tsx`) +- Functions: camelCase (e.g., `getUserData`) +- Constants: UPPER_SNAKE_CASE (e.g., `MAX_FILE_SIZE`) +- Modules: lowercase with hyphens if needed (e.g., `discussion-general`) + +### State Management +- Use Hookstate for global state management +- Use React hooks for component-local state +- Store persistent data in cookies or localStorage as appropriate + +### API Design +- Organize API routes by feature in the `/src/app/api/` directory +- Use RESTful conventions where possible +- Implement proper error handling and validation +- Secure endpoints with appropriate authentication checks + +### Testing +- Unit tests should be co-located with the code they test +- Integration tests should be in the `/tests/` directory +- Follow the testing pyramid: many unit tests, fewer integration tests, minimal end-to-end tests + +## Key Dependencies + +### Core Dependencies +- `next`: React framework for production applications +- `react`, `react-dom`: UI library +- `@mantine/core`: Component library with accessible components +- `@prisma/client`: Database toolkit +- `web-push`: Web Push protocol implementation +- `elysia`: Fast, lightweight web framework +- `@hookstate/core`: State management solution + +### UI Dependencies +- `@mantine/carousel`: Carousel component +- `@mantine/charts`: Chart components +- `@mantine/form`: Form management +- `@mantine/notifications`: Notification system +- `@mantine/tiptap`: Rich text editor components +- `@tabler/icons-react`: Icon library +- `@tiptap/react`: Rich text editor +- `recharts`: Charting library +- `echarts-for-react`: Alternative charting library + +### Utilities +- `dayjs`: Date manipulation library +- `lodash`: Utility functions +- `crypto-js`: Cryptographic algorithms +- `iron-session`: Session management +- `jose`: JavaScript Object Signing and Encryption +- `multer`: File upload middleware +- `firebase-admin`: Firebase admin SDK + +## Architecture Patterns + +### Modular Design +The application follows a modular design where each feature is encapsulated in its own module directory. This promotes separation of concerns and makes the codebase easier to maintain and scale. + +### API Layer +API routes are organized by feature in the `/src/app/api/` directory. Each feature has its own subdirectory containing related API endpoints. This makes it easy to locate and maintain API functionality. + +### Component Organization +Components are organized within their respective module directories. Common components that are shared across multiple modules are placed in the `_global` module. + +### Data Flow +- Client-side state is managed using React hooks and Hookstate +- Server-side data fetching is done through Next.js API routes +- Database interactions are handled through Prisma ORM +- Authentication is implemented using cookies and server actions + +## Deployment + +The application is designed to be deployed as a Next.js application. It can be deployed to platforms like Vercel, Netlify, or any hosting service that supports Node.js applications. + +For production deployment: +1. Run `bun run build` to create an optimized production build +2. Run `bun start` to start the production server +3. Configure environment variables for the production environment +4. Set up SSL certificates for secure connections +5. Configure database connection for production environment \ No newline at end of file diff --git a/src/app/api/mobile/project/route.ts b/src/app/api/mobile/project/route.ts index f480eb0..332ff51 100644 --- a/src/app/api/mobile/project/route.ts +++ b/src/app/api/mobile/project/route.ts @@ -26,14 +26,11 @@ export async function GET(request: Request) { return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); } - let grup + let grup, tahunFilter = String(tahun) const dataSkip = Number(page) * 10 - 10; const roleUser = userMobile.idUserRole const villageId = userMobile.idVillage const userId = userMobile.id - const tahunFilter = tahun ? tahun : new Date().getFullYear().toString(); - const startTahun = new Date(`${tahunFilter}-01-01T00:00:00.000Z`); - const endTahun = new Date(`${parseInt(tahunFilter) + 1}-01-01T00:00:00.000Z`); if (idGroup == "null" || idGroup == undefined || idGroup == "" || idGroup == "undefined") { grup = userMobile.idGroup @@ -41,6 +38,14 @@ export async function GET(request: Request) { grup = idGroup } + if (tahun == "null" || tahun == undefined || tahun == "" || tahun == "undefined") { + tahunFilter = new Date().getFullYear().toString(); + } + + const startTahun = new Date(`${tahunFilter}-01-01T00:00:00.000Z`); + const endTahun = new Date(`${parseInt(tahunFilter) + 1}-01-01T00:00:00.000Z`); + + const cek = await prisma.group.count({ where: { id: grup, @@ -151,7 +156,7 @@ export async function GET(request: Request) { }) - return NextResponse.json({ success: true, message: "Berhasil mendapatkan kegiatan", data: omitData, filter, total: totalData }, { status: 200 }); + return NextResponse.json({ success: true, message: "Berhasil mendapatkan kegiatan", data: omitData, filter, tahun: tahunFilter, total: totalData }, { status: 200 }); } catch (error) { console.error(error); diff --git a/src/app/api/mobile/project/tahun/route.ts b/src/app/api/mobile/project/tahun/route.ts index 192757f..ed4c4d7 100644 --- a/src/app/api/mobile/project/tahun/route.ts +++ b/src/app/api/mobile/project/tahun/route.ts @@ -36,6 +36,11 @@ export async function GET(request: Request) { // (opsional) urutkan dari terbaru ke lama uniqueYears.sort((a, b) => b - a); - return NextResponse.json({ success: true, message: "Success", data: uniqueYears }, { status: 200 }); + const formattedData = uniqueYears.map(year => ({ + id: String(year), + name: String(year) + })); + + return NextResponse.json({ success: true, message: "Success", data: formattedData }, { status: 200 }); } From f5e36f5ac75976d27b47957a5e9dd52d772d9c47 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Tue, 3 Feb 2026 12:24:23 +0800 Subject: [PATCH 27/32] upd: api tahun Deskripsi: - update api mobile filter tahun pada fitur divisi tugas No Issues --- src/app/api/mobile/task/route.ts | 15 ++++++++++----- src/app/api/mobile/task/tahun/route.ts | 8 +++++++- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/app/api/mobile/task/route.ts b/src/app/api/mobile/task/route.ts index 0533f40..784be12 100644 --- a/src/app/api/mobile/task/route.ts +++ b/src/app/api/mobile/task/route.ts @@ -18,10 +18,6 @@ export async function GET(request: Request) { const dataSkip = Number(page) * 10 - 10; const tahun = searchParams.get("year"); - const tahunFilter = tahun ? tahun : new Date().getFullYear().toString(); - const startTahun = new Date(`${tahunFilter}-01-01T00:00:00.000Z`); - const endTahun = new Date(`${parseInt(tahunFilter) + 1}-01-01T00:00:00.000Z`); - const userMobile = await funGetUserById({ id: String(user) }) if (userMobile.id == "null" || userMobile.id == undefined || userMobile.id == "") { return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 }); @@ -38,6 +34,15 @@ export async function GET(request: Request) { return NextResponse.json({ success: false, message: "Gagal mendapatkan divisi, data tidak ditemukan", }, { status: 200 }); } + let tahunFilter = String(tahun) + if (tahunFilter == "null" || tahunFilter == undefined || tahunFilter == "" || tahunFilter == "undefined") { + tahunFilter = new Date().getFullYear().toString(); + } + + + const startTahun = new Date(`${tahunFilter}-01-01T00:00:00.000Z`); + const endTahun = new Date(`${parseInt(tahunFilter) + 1}-01-01T00:00:00.000Z`); + const data = await prisma.divisionProject.findMany({ skip: dataSkip, take: 10, @@ -104,7 +109,7 @@ export async function GET(request: Request) { } }) - return NextResponse.json({ success: true, message: "Berhasil mendapatkan divisi", data: formatData, total: totalData }, { status: 200 }); + return NextResponse.json({ success: true, message: "Berhasil mendapatkan divisi", data: formatData, tahun: tahunFilter, total: totalData }, { status: 200 }); } catch (error) { console.error(error); diff --git a/src/app/api/mobile/task/tahun/route.ts b/src/app/api/mobile/task/tahun/route.ts index 3df17b4..7743729 100644 --- a/src/app/api/mobile/task/tahun/route.ts +++ b/src/app/api/mobile/task/tahun/route.ts @@ -35,7 +35,13 @@ export async function GET(request: Request) { // (opsional) urutkan dari terbaru ke lama uniqueYears.sort((a, b) => b - a); + const formattedData = uniqueYears.map(year => ({ + id: String(year), + name: String(year) + })); - return NextResponse.json({ success: true, message: "Success", data: uniqueYears }, { status: 200 }); + + + return NextResponse.json({ success: true, message: "Success", data: formattedData }, { status: 200 }); } \ No newline at end of file From 44b400cfb819b875b78341dad9ee5955e122820d Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 4 Feb 2026 13:56:22 +0800 Subject: [PATCH 28/32] upd: panduan penggunaan by QWEN --- PANDUAN PENGGUNAAN.md | 255 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 255 insertions(+) create mode 100644 PANDUAN PENGGUNAAN.md diff --git a/PANDUAN PENGGUNAAN.md b/PANDUAN PENGGUNAAN.md new file mode 100644 index 0000000..3d191d5 --- /dev/null +++ b/PANDUAN PENGGUNAAN.md @@ -0,0 +1,255 @@ +# Panduan Penggunaan Sistem Desa Mandiri + +## Daftar Isi +1. [Gambaran Umum](#gambaran-umum) +2. [Peran Pengguna dan Hak Akses](#peran-pengguna-dan-hak-akses) +3. [Fitur-Fitur Utama dan Aksesnya](#fitur-fitur-utama-dan-aksesnya) +4. [Cara Menggunakan Aplikasi](#cara-menggunakan-aplikasi) +5. [Tips dan Trik](#tips-dan-trik) + +## Gambaran Umum + +Sistem Desa Mandiri adalah aplikasi web yang dirancang untuk membantu pengelolaan administrasi dan informasi di tingkat desa. Aplikasi ini dibangun dengan teknologi Next.js dan menyediakan berbagai fitur untuk mendukung kegiatan desa, mulai dari pengumuman, diskusi, manajemen proyek, hingga administrasi kependudukan. + +## Peran Pengguna dan Hak Akses + +Aplikasi ini memiliki beberapa peran pengguna dengan hak akses berbeda: + +### 1. Super Admin +- **Hak Akses**: Memiliki akses penuh ke semua fitur aplikasi +- **Fungsi**: Mengelola seluruh sistem, termasuk pembuatan akun admin, pengaturan desa, dan manajemen sistem secara keseluruhan +- **Dapat Mengakses**: Semua fitur dalam aplikasi + +### 2. Admin Desa +- **Hak Akses**: Memiliki akses ke fitur-fitur yang berkaitan dengan desa tertentu +- **Fungsi**: Mengelola data dan informasi dalam lingkup desa tertentu +- **Dapat Mengakses**: Semua fitur terkait desa yang dikelola, termasuk pengumuman, proyek, divisi, dan pengguna + +### 3. Ketua Divisi +- **Hak Akses**: Memiliki akses administratif dalam divisi tertentu +- **Fungsi**: Mengelola anggota, proyek, dan kegiatan dalam divisi +- **Dapat Mengakses**: Fitur-fitur terkait divisi yang dipimpin, termasuk manajemen anggota, proyek, diskusi, dan dokumentasi + +### 4. Anggota Divisi +- **Hak Akses**: Dapat mengakses dan berpartisipasi dalam kegiatan divisi +- **Fungsi**: Menjalankan tugas dan berkontribusi dalam kegiatan divisi +- **Dapat Mengakses**: Kegiatan dan informasi dalam divisi yang diikuti + +### 5. Warga/Perangkat Desa +- **Hak Akses**: Akses dasar ke fitur-fitur umum +- **Fungsi**: Melihat informasi, berpartisipasi dalam diskusi umum +- **Dapat Mengakses**: Pengumuman, diskusi umum, kalender kegiatan umum + +## Fitur-Fitur Utama dan Aksesnya + +### 1. Manajemen Pengguna +- **Deskripsi**: Fitur untuk mendaftarkan dan mengelola data anggota desa serta mengatur hak akses berdasarkan peran +- **Dapat Diakses Oleh**: Super Admin, Admin Desa +- **Fungsi**: + - Registrasi pengguna baru + - Pengelolaan data pengguna + - Penetapan peran pengguna + - Pengelolaan grup dan posisi dalam desa + +### 2. Pengumuman +- **Deskripsi**: Fitur untuk membuat dan menyebarkan pengumuman penting kepada warga +- **Dapat Diakses Oleh**: Super Admin, Admin Desa, Ketua Divisi (untuk divisi masing-masing) +- **Fungsi**: + - Membuat pengumuman baru + - Menargetkan pengumuman ke grup atau divisi tertentu + - Melampirkan file dalam pengumuman + - Mengedit atau menghapus pengumuman + +### 3. Diskusi Umum +- **Deskripsi**: Forum diskusi umum untuk seluruh warga desa +- **Dapat Diakses Oleh**: Seluruh pengguna terdaftar +- **Fungsi**: + - Membuat topik diskusi baru + - Memberikan komentar dalam diskusi + - Melihat riwayat diskusi + - Melampirkan file dalam diskusi + +### 4. Diskusi Divisi +- **Deskripsi**: Forum diskusi internal dalam divisi-divisi dalam desa +- **Dapat Diakses Oleh**: Anggota divisi yang bersangkutan +- **Fungsi**: + - Membuat topik diskusi internal divisi + - Memberikan komentar dalam diskusi divisi + - Menambahkan anggota ke dalam diskusi + - Melampirkan dokumen terkait diskusi + +### 5. Manajemen Proyek +- **Deskripsi**: Fitur untuk membuat dan mengelola proyek-proyek desa +- **Dapat Diakses Oleh**: Super Admin, Admin Desa, Ketua Divisi +- **Fungsi**: + - Membuat proyek baru + - Menetapkan anggota tim proyek + - Melacak kemajuan proyek dan tugas-tugasnya + - Melampirkan dokumen dan tautan terkait proyek + - Menambahkan laporan kemajuan proyek + - Menyelesaikan atau membatalkan proyek + +### 6. Manajemen Tugas +- **Deskripsi**: Fitur untuk mengelola tugas-tugas dalam proyek atau divisi +- **Dapat Diakses Oleh**: Super Admin, Admin Desa, Ketua Divisi, Leader Proyek +- **Fungsi**: + - Membuat tugas baru + - Menetapkan anggota yang bertugas + - Melacak kemajuan tugas + - Menambahkan detail waktu pelaksanaan + - Melampirkan dokumen terkait tugas + +### 7. Divisi +- **Deskripsi**: Fitur untuk membuat dan mengelola divisi-divisi dalam desa +- **Dapat Diakses Oleh**: Super Admin, Admin Desa +- **Fungsi**: + - Membuat divisi baru + - Mengelola anggota dalam divisi + - Menetapkan admin dan leader divisi + - Mengelola proyek yang dikelola oleh divisi + - Mengelola diskusi internal divisi + - Mengelola dokumentasi divisi + - Mengelola kalender kegiatan divisi + +### 8. Dokumentasi +- **Deskripsi**: Fitur untuk penyimpanan dokumen terpusat dalam divisi +- **Dapat Diakses Oleh**: Admin Divisi, Anggota Divisi (tergantung izin) +- **Fungsi**: + - Upload dokumen ke dalam folder + - Membuat struktur folder + - Berbagi dokumen antar divisi + - Cut dan paste dokumen antar folder + - Melihat riwayat dokumen + +### 9. Kalender +- **Deskripsi**: Fitur untuk mengelola jadwal kegiatan desa dan divisi +- **Dapat Diakses Oleh**: Super Admin, Admin Desa, Ketua Divisi +- **Fungsi**: + - Membuat jadwal kegiatan baru + - Mengatur pengingat kegiatan + - Menetapkan peserta kegiatan + - Mengelola kegiatan berulang + - Melihat riwayat kegiatan + +### 10. Tema Warna +- **Deskripsi**: Fitur untuk mengelola tampilan warna aplikasi berdasarkan desa +- **Dapat Diakses Oleh**: Super Admin, Admin Desa +- **Fungsi**: + - Mengatur warna utama aplikasi + - Mengatur warna latar belakang + - Mengatur warna elemen-elemen tampilan + +### 11. Banner +- **Deskripsi**: Fitur untuk mengelola banner tampilan utama aplikasi +- **Dapat Diakses Oleh**: Super Admin, Admin Desa +- **Fungsi**: + - Upload banner baru + - Mengatur tampilan banner + - Menghapus banner lama + +### 12. Notifikasi +- **Deskripsi**: Fitur untuk mengelola dan menerima notifikasi dalam aplikasi +- **Dapat Diakses Oleh**: Seluruh pengguna +- **Fungsi**: + - Menerima notifikasi real-time + - Melihat riwayat notifikasi + - Mengelola pengaturan notifikasi + +## Cara Menggunakan Aplikasi + +### 1. Login ke Sistem +- Buka browser dan kunjungi alamat aplikasi +- Masukkan NIK dan password yang telah didaftarkan +- Klik tombol "Login" +- Sistem akan mengarahkan ke dashboard sesuai dengan peran pengguna + +### 2. Dashboard +- Setelah login, Anda akan diarahkan ke halaman dashboard +- Dashboard menampilkan ringkasan aktivitas dan informasi penting sesuai dengan hak akses Anda +- Gunakan menu navigasi di sisi kiri untuk mengakses fitur-fitur lain + +### 3. Melihat dan Membuat Pengumuman +- **Melihat Pengumuman**: + - Klik menu "Pengumuman" di sidebar + - Pilih pengumuman yang ingin dibaca + - Anda juga dapat mengunduh file terlampir jika ada + +- **Membuat Pengumuman (Untuk Pengguna Berwenang)**: + - Klik menu "Pengumuman" di sidebar + - Klik tombol "Buat Pengumuman Baru" + - Isi judul, deskripsi, dan pilih grup/divisi yang akan menerima + - Lampirkan file jika diperlukan + - Klik "Simpan" untuk menerbitkan pengumuman + +### 4. Bergabung dalam Diskusi +- **Diskusi Umum**: + - Klik menu "Diskusi Umum" di sidebar + - Pilih forum diskusi yang tersedia + - Klik pada topik diskusi untuk membacanya + - Tulis komentar Anda dan klik "Kirim" + +- **Diskusi Divisi**: + - Klik menu "Divisi" di sidebar + - Pilih divisi yang Anda ikuti + - Klik pada tab "Diskusi" + - Ikuti proses diskusi seperti pada diskusi umum + +### 5. Mengelola Proyek +- Klik menu "Proyek" di sidebar +- Untuk membuat proyek baru, klik "Tambah Proyek" +- Isi informasi proyek seperti judul, deskripsi, tanggal mulai, dll. +- Tambahkan anggota tim proyek +- Buat tugas-tugas dalam proyek dan tetapkan ke anggota +- Pantau kemajuan proyek secara real-time + +### 6. Mengelola Divisi +- Klik menu "Divisi" di sidebar +- Untuk membuat divisi baru, klik "Tambah Divisi" +- Isi informasi divisi seperti nama, deskripsi, dll. +- Tambahkan anggota ke dalam divisi + - Sebagai ketua divisi, Anda dapat menambahkan anggota + - Tetapkan admin dan leader divisi +- Kelola proyek, diskusi, dan dokumentasi dalam divisi + +### 7. Mengelola Dokumen +- Klik menu "Divisi" di sidebar +- Pilih divisi yang Anda kelola atau ikuti +- Klik pada tab "Dokumen" +- Buat folder untuk mengorganisir dokumen +- Upload dokumen dengan klik tombol "Upload" +- Bagikan dokumen dengan divisi lain jika diperlukan + +### 8. Menggunakan Kalender +- Klik menu "Divisi" di sidebar +- Pilih divisi yang Anda kelola atau ikuti +- Klik pada tab "Kalender" +- Lihat jadwal kegiatan yang telah direncanakan +- Klik "Tambah Kegiatan" untuk membuat jadwal baru +- Atur tanggal, waktu, dan pengingat untuk kegiatan + +### 9. Mengelola Profil +- Klik foto profil Anda di pojok kanan atas +- Pilih "Profil" untuk melihat atau mengedit informasi pribadi +- Ganti foto profil, password, atau informasi kontak + +## Tips dan Trik + +1. **Gunakan Fitur Pencarian**: Gunakan fitur pencarian untuk menemukan pengumuman, diskusi, atau dokumen secara cepat. + +2. **Atur Notifikasi**: Sesuaikan pengaturan notifikasi agar hanya menerima informasi yang relevan dengan peran Anda. + +3. **Gunakan Filter**: Gunakan filter untuk menampilkan data yang spesifik sesuai kebutuhan (misalnya proyek aktif, pengumuman terbaru, dll.). + +4. **Organisasi Dokumen**: Buat folder yang terstruktur untuk mengorganisasi dokumen agar mudah dicari kembali. + +5. **Update Informasi**: Pastikan informasi pribadi Anda selalu diperbarui agar komunikasi berjalan efektif. + +6. **Gunakan Mobile Version**: Aplikasi ini responsif dan dapat digunakan di perangkat mobile untuk kemudahan akses. + +7. **Ikuti Aturan Diskusi**: Hormati sesama pengguna saat berdiskusi dan gunakan bahasa yang sopan. + +8. **Gunakan Kalender**: Manfaatkan fitur kalender untuk tidak ketinggalan kegiatan penting di desa. + +9. **Laporan Masalah**: Jika menemui masalah teknis, laporkan segera kepada admin untuk ditindaklanjuti. + +10. **Pelajari Fitur Lainnya**: Luangkan waktu untuk menjelajahi semua fitur yang tersedia agar dapat memanfaatkan aplikasi secara maksimal. \ No newline at end of file From 352469ce32c267fb4a516e9a32480293bc0e2792 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Wed, 4 Feb 2026 17:31:18 +0800 Subject: [PATCH 29/32] upd: seeder Deskripsi: - tambah data dummy desa untuk testing dan presentasi No Issues --- prisma/seed.ts | 123 ++- src/module/seeder/complete_village_seeder.ts | 922 ++++++++++++++++++ src/module/seeder/data/desa.json | 5 + src/module/seeder/data/discussion.json | 20 + src/module/seeder/data/discussion_member.json | 27 + src/module/seeder/data/group.json | 20 + src/module/seeder/data/position.json | 20 + src/module/seeder/data/project.json | 11 + src/module/seeder/data/project_member.json | 14 + src/module/seeder/data/project_task.json | 29 + src/module/seeder/data/user.json | 48 + src/module/seeder/index.ts | 14 +- 12 files changed, 1248 insertions(+), 5 deletions(-) create mode 100644 src/module/seeder/complete_village_seeder.ts create mode 100644 src/module/seeder/data/discussion.json create mode 100644 src/module/seeder/data/discussion_member.json create mode 100644 src/module/seeder/data/project.json create mode 100644 src/module/seeder/data/project_member.json create mode 100644 src/module/seeder/data/project_task.json diff --git a/prisma/seed.ts b/prisma/seed.ts index b55d1ae..fe5a0db 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,7 +1,11 @@ -import { seederAdmin, seederAdminRole, seederDesa, seederGroup, seederPosition, seederTheme, seederUser, seederUserRole } from '@/module/seeder'; +import { seederAdmin, seederAdminRole, seederDesa, seederDiscussion, seederDiscussionMember, seederGroup, seederPosition, seederProject, seederProjectMember, seederProjectTask, seederTheme, seederUser, seederUserRole } from '@/module/seeder'; import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient() +// DATA YG DI SEEDER MERUPAKAN DATA REAL(DARMASABA) & DATA DUMMY (MANDALA) +// DATA JSON GABUNGAN (REAL & DUMMY) ADALAH adminRole, admin, theme, desa, group, position, user, userRole, user +// Selain table yg disebutkan merupakan data dummy + async function main() { // ADMIN ROLE for (let data of seederAdminRole) { @@ -176,6 +180,123 @@ async function main() { }) } + + // DISCUSSION + for (let data of seederDiscussion) { + await prisma.discussion.upsert({ + where: { + id: data.id + }, + update: { + idVillage: data.idVillage, + idGroup: data.idGroup, + title: data.title, + desc: data.desc, + status: data.status, + createdBy: data.createdBy + }, + create: { + id: data.id, + idVillage: data.idVillage, + idGroup: data.idGroup, + title: data.title, + desc: data.desc, + status: data.status, + createdBy: data.createdBy + }, + }) + } + + + // DISSCUSSION MEMBER + for (let data of seederDiscussionMember) { + await prisma.discussionMember.upsert({ + where: { + id: data.id + }, + update: { + idDiscussion: data.idDiscussion, + idUser: data.idUser + }, + create: { + id: data.id, + idDiscussion: data.idDiscussion, + idUser: data.idUser + }, + }) + } + + // PROJECT + for (let data of seederProject) { + await prisma.project.upsert({ + where: { + id: data.id + }, + update: { + idVillage: data.idVillage, + idGroup: data.idGroup, + title: data.title, + desc: data.desc, + status: data.status, + createdBy: data.createdBy + }, + create: { + id: data.id, + idVillage: data.idVillage, + idGroup: data.idGroup, + title: data.title, + desc: data.desc, + status: data.status, + createdBy: data.createdBy + }, + }) + } + + // PROJECT MEMBER + for (let data of seederProjectMember) { + await prisma.projectMember.upsert({ + where: { + id: data.id + }, + update: { + idProject: data.idProject, + idUser: data.idUser, + isLeader: data.isLeader + }, + create: { + id: data.id, + idProject: data.idProject, + idUser: data.idUser, + isLeader: data.isLeader + }, + }) + } + + // PROJECT TASK + for (let data of seederProjectTask) { + await prisma.projectTask.upsert({ + where: { + id: data.id + }, + update: { + idProject: data.idProject, + title: data.title, + desc: data.desc, + status: data.status, + dateStart: new Date(data.dateStart), + dateEnd: new Date(data.dateEnd) + }, + create: { + id: data.id, + idProject: data.idProject, + title: data.title, + desc: data.desc, + status: data.status, + dateStart: new Date(data.dateStart), + dateEnd: new Date(data.dateEnd) + }, + }) + } } main().then(async () => { diff --git a/src/module/seeder/complete_village_seeder.ts b/src/module/seeder/complete_village_seeder.ts new file mode 100644 index 0000000..9335e5f --- /dev/null +++ b/src/module/seeder/complete_village_seeder.ts @@ -0,0 +1,922 @@ +import { prisma } from "@/module/_global"; +import { + seederAdmin, + seederAdminRole, + seederDesa, + seederGroup, + seederPosition, + seederTheme, + seederUser, + seederUserRole +} from '@/module/seeder'; + +async function seedCompleteVillageData() { + console.log("Starting complete village data seeding process..."); + + // Define comprehensive dummy data variables outside transaction scope + // GROUP - Comprehensive dummy data + const seederGroupComprehensive = [ + { + "id": "group_rt01", + "idVillage": "desaDummy", + "name": "Dinas" + }, + { + "id": "group_rt02", + "idVillage": "desaDummy", + "name": "Adat" + }, + { + "id": "group_karang_taruna", + "idVillage": "desaDummy", + "name": "Karang Taruna" + }, + { + "id": "group_bumdes", + "idVillage": "desaDummy", + "name": "PKK" + } + ]; + + // POSITION - Comprehensive dummy data + const seederPositionComprehensive = [ + { + "id": "pos_ketua_rt01", + "idGroup": "group_rt01", + "name": "Perbekel" + }, + { + "id": "pos_sekretaris_rt01", + "idGroup": "group_rt01", + "name": "Sekretaris" + }, + { + "id": "pos_bendahara_rt01", + "idGroup": "group_rt01", + "name": "Bendahara" + }, + { + "id": "pos_staff_rt01", + "idGroup": "group_rt01", + "name": "Staff" + }, + { + "id": "pos_staff_rt02", + "idGroup": "group_rt02", + "name": "Staff" + }, + { + "id": "pos_ketua_karang_taruna", + "idGroup": "group_karang_taruna", + "name": "Ketua Karang Taruna" + }, + { + "id": "pos_ketua_bumdes", + "idGroup": "group_bumdes", + "name": "Ketua PKK" + } + ]; + + // USER - Comprehensive dummy data + const seederUserComprehensive = [ + { + "id": "user_kades", + "idUserRole": "supadmin", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_ketua_rt01", + "nik": "3201010101010001", + "name": "Kepala Desa", + "phone": "081234567890", + "email": "kades@desamandiri.test", + "gender": "M" + }, + { + "id": "user_sekdes", + "idUserRole": "admin", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_sekretaris_rt01", + "nik": "3201010101010002", + "name": "Sekretaris Desa", + "phone": "081234567891", + "email": "sekdes@desamandiri.test", + "gender": "M" + }, + { + "id": "user_ketua_bumdes", + "idUserRole": "admin", + "idVillage": "desaDummy", + "idGroup": "group_bumdes", + "idPosition": "pos_ketua_bumdes", + "nik": "3201010101010003", + "name": "Ketua BUMDES", + "phone": "081234567892", + "email": "ketuabumdes@desamandiri.test", + "gender": "M" + }, + { + "id": "user_ketua_karang_taruna", + "idUserRole": "user", + "idVillage": "desaDummy", + "idGroup": "group_karang_taruna", + "idPosition": "pos_ketua_karang_taruna", + "nik": "3201010101010004", + "name": "Ketua Karang Taruna", + "phone": "081234567893", + "email": "ketuakt@desamandiri.test", + "gender": "M" + }, + { + "id": "user_warga1", + "idUserRole": "user", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_staff_rt01", + "nik": "3201010101010005", + "name": "Warga Satu", + "phone": "081234567894", + "email": "wargasatu@desamandiri.test", + "gender": "F" + }, + { + "id": "user_warga2", + "idUserRole": "user", + "idVillage": "desaDummy", + "idGroup": "group_rt02", + "idPosition": "pos_staff_rt02", + "nik": "3201010101010006", + "name": "Warga Dua", + "phone": "081234567895", + "email": "wargadua@desamandiri.test", + "gender": "M" + } + ]; + + // ANNOUNCEMENTS - Comprehensive dummy data + const seederAnnouncementComprehensive = [ + { + "id": "ann_pembangunan_jalan", + "idVillage": "desaDummy", + "title": "Pembangunan Jalan Desa Tahap 2", + "desc": "Pada bulan ini akan dilakukan pembangunan jalan desa tahap 2 yang mencakup wilayah RT 01 dan RT 02. Mohon kerjasama warga untuk menyesuaikan aktivitas selama masa pembangunan.", + "createdBy": "user_kades" + }, + { + "id": "ann_posyandu", + "idVillage": "desaDummy", + "title": "Posyandu Bulanan", + "desc": "Posyandu bulan akan diselenggarakan pada tanggal 21 setiap bulannya di Balai Desa. Warga diharapkan aktif membawa balita untuk pemeriksaan kesehatan.", + "createdBy": "user_sekdes" + }, + { + "id": "ann_rapat_warga", + "idVillage": "desaDummy", + "title": "Rapat Warga Bulanan", + "desc": "Rapat warga bulanan akan diselenggarakan pada hari Sabtu, 25 Februari 2026 pukul 09.00 WIB di Balai Desa. Hadirilah tepat waktu.", + "createdBy": "user_kades" + } + ]; + + // ANNOUNCEMENT MEMBERS - Comprehensive dummy data + const seederAnnouncementMemberComprehensive = [ + { + "id": "ann_mem_pembangunan_jalan_rt01", + "idAnnouncement": "ann_pembangunan_jalan", + "idGroup": "group_rt01", + "idDivision": null + }, + { + "id": "ann_mem_pembangunan_jalan_rt02", + "idAnnouncement": "ann_pembangunan_jalan", + "idGroup": "group_rt02", + "idDivision": null + }, + { + "id": "ann_mem_posyandu_all", + "idAnnouncement": "ann_posyandu", + "idGroup": null, + "idDivision": null + }, + { + "id": "ann_mem_rapat_warga_all", + "idAnnouncement": "ann_rapat_warga", + "idGroup": null, + "idDivision": null + } + ]; + + // DIVISIONS - Comprehensive dummy data + const seederDivisionComprehensive = [ + { + "id": "div_bumdes", + "idVillage": "desaDummy", + "idGroup": "group_bumdes", + "name": "BUMDES Desa Mandiri", + "desc": "Badan Usaha Milik Desa yang bertujuan untuk meningkatkan kesejahteraan masyarakat desa melalui berbagai usaha produktif.", + "createdBy": "user_ketua_bumdes" + }, + { + "id": "div_karang_taruna", + "idVillage": "desaDummy", + "idGroup": "group_karang_taruna", + "name": "Karang Taruna Desa Mandiri", + "desc": "Organisasi pemuda desa yang berfokus pada pengembangan potensi pemuda dan kegiatan sosial kemasyarakatan.", + "createdBy": "user_ketua_karang_taruna" + }, + { + "id": "div_linmas", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "name": "Linmas Desa Mandiri", + "desc": "Perlindungan Masyarakat yang bertugas menjaga ketertiban dan keamanan di wilayah desa.", + "createdBy": "user_kades" + } + ]; + + // DIVISION MEMBERS - Comprehensive dummy data + const seederDivisionMemberComprehensive = [ + { + "id": "div_mem_bumdes_ketua", + "idDivision": "div_bumdes", + "idUser": "user_ketua_bumdes", + "isAdmin": true, + "isLeader": true + }, + { + "id": "div_mem_bumdes_anggota1", + "idDivision": "div_bumdes", + "idUser": "user_warga1", + "isAdmin": false, + "isLeader": false + }, + { + "id": "div_mem_karang_taruna_ketua", + "idDivision": "div_karang_taruna", + "idUser": "user_ketua_karang_taruna", + "isAdmin": true, + "isLeader": true + }, + { + "id": "div_mem_karang_taruna_anggota1", + "idDivision": "div_karang_taruna", + "idUser": "user_warga2", + "isAdmin": false, + "isLeader": false + }, + { + "id": "div_mem_linmas_kades", + "idDivision": "div_linmas", + "idUser": "user_kades", + "isAdmin": true, + "isLeader": true + } + ]; + + // PROJECTS - Comprehensive dummy data + const seederProjectComprehensive = [ + { + "id": "proj_pembangunan_jalan", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "title": "Pembangunan Jalan Desa Tahap 2", + "desc": "Pembangunan jalan desa tahap 2 yang mencakup wilayah RT 01 dan RT 02", + "status": 1, + "createdBy": "user_kades" + }, + { + "id": "proj_penghijauan", + "idVillage": "desaDummy", + "idGroup": "group_karang_taruna", + "title": "Program Penghijauan Desa", + "desc": "Penanaman pohon di sepanjang jalan desa dan area publik", + "status": 0, + "createdBy": "user_ketua_karang_taruna" + }, + { + "id": "proj_pembukuan_bumdes", + "idVillage": "desaDummy", + "idGroup": "group_bumdes", + "title": "Sistem Pembukuan Digital BUMDES", + "desc": "Pembuatan sistem pembukuan digital untuk BUMDES Desa Mandiri", + "status": 0, + "createdBy": "user_ketua_bumdes" + } + ]; + + // PROJECT MEMBERS - Comprehensive dummy data + const seederProjectMemberComprehensive = [ + { + "id": "proj_mem_pembangunan_jalan_kades", + "idProject": "proj_pembangunan_jalan", + "idUser": "user_kades", + "isLeader": true + }, + { + "id": "proj_mem_pembangunan_jalan_sekdes", + "idProject": "proj_pembangunan_jalan", + "idUser": "user_sekdes", + "isLeader": false + }, + { + "id": "proj_mem_penghijauan_ketua_kt", + "idProject": "proj_penghijauan", + "idUser": "user_ketua_karang_taruna", + "isLeader": true + }, + { + "id": "proj_mem_penghijauan_warga1", + "idProject": "proj_penghijauan", + "idUser": "user_warga1", + "isLeader": false + }, + { + "id": "proj_mem_pembukuan_bumdes_ketua", + "idProject": "proj_pembukuan_bumdes", + "idUser": "user_ketua_bumdes", + "isLeader": true + } + ]; + + // PROJECT TASKS - Comprehensive dummy data + const seederProjectTaskComprehensive = [ + { + "id": "task_survey_lokasi", + "idProject": "proj_pembangunan_jalan", + "title": "Survey Lokasi", + "desc": "Melakukan survey lokasi untuk menentukan titik pembangunan jalan", + "status": 1, + "dateStart": "2026-01-15T00:00:00.000Z", + "dateEnd": "2026-01-20T00:00:00.000Z" + }, + { + "id": "task_pengadaan_material", + "idProject": "proj_pembangunan_jalan", + "title": "Pengadaan Material", + "desc": "Mengadakan material pembangunan seperti pasir, batu, dan semen", + "status": 0, + "dateStart": "2026-02-01T00:00:00.000Z", + "dateEnd": "2026-02-10T00:00:00.000Z" + }, + { + "id": "task_pelaksanaan_pembangunan", + "idProject": "proj_pembangunan_jalan", + "title": "Pelaksanaan Pembangunan", + "desc": "Melaksanakan pembangunan jalan sesuai dengan desain yang telah ditentukan", + "status": 0, + "dateStart": "2026-02-15T00:00:00.000Z", + "dateEnd": "2026-03-15T00:00:00.000Z" + }, + { + "id": "task_penanaman_pohon", + "idProject": "proj_penghijauan", + "title": "Penanaman Pohon", + "desc": "Menanam pohon di sepanjang jalan desa dan area publik", + "status": 0, + "dateStart": "2026-03-01T00:00:00.000Z", + "dateEnd": "2026-03-15T00:00:00.000Z" + } + ]; + + // DISCUSSIONS - Comprehensive dummy data + const seederDiscussionComprehensive = [ + { + "id": "disc_kegiatan_desa", + "idVillage": "desaDummy", + "idGroup": null, + "title": "Pembahasan Kegiatan Desa Mendatang", + "desc": "Diskusi untuk merencanakan kegiatan desa yang akan datang dan menyerap aspirasi warga", + "status": 1, + "createdBy": "user_kades" + }, + { + "id": "disc_pengelolaan_sampah", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "title": "Pengelolaan Sampah di RT 01", + "desc": "Diskusi internal RT 01 mengenai pengelolaan sampah rumah tangga dan lingkungan", + "status": 1, + "createdBy": "user_kades" + }, + { + "id": "disc_program_karang_taruna", + "idVillage": "desaDummy", + "idGroup": "group_karang_taruna", + "title": "Program Kerja Karang Taruna", + "desc": "Merancang program kerja Karang Taruna untuk tahun ini", + "status": 1, + "createdBy": "user_ketua_karang_taruna" + } + ]; + + // DISCUSSION MEMBERS - Comprehensive dummy data + const seederDiscussionMemberComprehensive = [ + { + "id": "disc_mem_kegiatan_desa_kades", + "idDiscussion": "disc_kegiatan_desa", + "idUser": "user_kades" + }, + { + "id": "disc_mem_kegiatan_desa_sekdes", + "idDiscussion": "disc_kegiatan_desa", + "idUser": "user_sekdes" + }, + { + "id": "disc_mem_kegiatan_desa_warga1", + "idDiscussion": "disc_kegiatan_desa", + "idUser": "user_warga1" + }, + { + "id": "disc_mem_pengelolaan_sampah_kades", + "idDiscussion": "disc_pengelolaan_sampah", + "idUser": "user_kades" + }, + { + "id": "disc_mem_pengelolaan_sampah_warga1", + "idDiscussion": "disc_pengelolaan_sampah", + "idUser": "user_warga1" + }, + { + "id": "disc_mem_program_kt_ketua", + "idDiscussion": "disc_program_karang_taruna", + "idUser": "user_ketua_karang_taruna" + }, + { + "id": "disc_mem_program_kt_warga2", + "idDiscussion": "disc_program_karang_taruna", + "idUser": "user_warga2" + } + ]; + + try { + // Start transaction to ensure data consistency + await prisma.$transaction(async (tx) => { + + // ADMIN ROLE + for (let data of seederAdminRole) { + await tx.adminRole.upsert({ + where: { + id: data.id + }, + update: { + name: data.name + }, + create: { + id: data.id, + name: data.name, + }, + }) + } + + // ADMIN + for (let data of seederAdmin) { + await tx.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 tx.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 - Original data + for (let data of seederDesa) { + await tx.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 - Original data + for (let data of seederGroup) { + await tx.group.upsert({ + where: { + id: data.id + }, + update: { + name: data.name, + idVillage: data.idVillage + }, + create: { + id: data.id, + name: data.name, + idVillage: data.idVillage + } + }) + } + + for (let data of seederGroupComprehensive) { + await tx.group.upsert({ + where: { + id: data.id + }, + update: { + name: data.name, + idVillage: data.idVillage + }, + create: { + id: data.id, + name: data.name, + idVillage: data.idVillage + } + }) + } + + // POSITION - Original data + for (let data of seederPosition) { + await tx.position.upsert({ + where: { + id: data.id + }, + update: { + name: data.name, + idGroup: data.idGroup + }, + create: { + id: data.id, + name: data.name, + idGroup: data.idGroup + } + }) + } + + for (let data of seederPositionComprehensive) { + await tx.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 tx.userRole.upsert({ + where: { + id: data.id + }, + update: { + name: data.name + }, + create: { + id: data.id, + name: data.name, + desc: data.desc + }, + }) + } + + // USER - Original data + for (let data of seederUser) { + await tx.user.upsert({ + where: { + id: data.id + }, + update: { + 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, + phone: data.phone, + email: data.email, + gender: data.gender + }, + }) + } + + for (let data of seederUserComprehensive) { + await tx.user.upsert({ + where: { + id: data.id + }, + update: { + 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, + phone: data.phone, + email: data.email, + gender: data.gender + }, + }) + } + + for (let data of seederAnnouncementComprehensive) { + await tx.announcement.upsert({ + where: { + id: data.id + }, + update: { + title: data.title, + desc: data.desc, + createdBy: data.createdBy + }, + create: { + id: data.id, + idVillage: data.idVillage, + title: data.title, + desc: data.desc, + createdBy: data.createdBy, + isActive: true + } + }) + } + + for (let data of seederAnnouncementMemberComprehensive) { + await tx.announcementMember.upsert({ + where: { + id: data.id + }, + update: { + idAnnouncement: data.idAnnouncement, + idGroup: data.idGroup!, + idDivision: data.idDivision! + }, + create: { + id: data.id, + idAnnouncement: data.idAnnouncement, + idGroup: data.idGroup!, + idDivision: data.idDivision!, + isActive: true + } + }) + } + + for (let data of seederDivisionComprehensive) { + await tx.division.upsert({ + where: { + id: data.id + }, + update: { + name: data.name, + desc: data.desc, + createdBy: data.createdBy + }, + create: { + id: data.id, + idVillage: data.idVillage, + idGroup: data.idGroup, + name: data.name, + desc: data.desc, + createdBy: data.createdBy, + isActive: true + } + }) + } + + for (let data of seederDivisionMemberComprehensive) { + await tx.divisionMember.upsert({ + where: { + id: data.id + }, + update: { + idUser: data.idUser, + isAdmin: data.isAdmin, + isLeader: data.isLeader + }, + create: { + id: data.id, + idDivision: data.idDivision, + idUser: data.idUser, + isAdmin: data.isAdmin, + isLeader: data.isLeader, + isActive: true + } + }) + } + + for (let data of seederProjectComprehensive) { + await tx.project.upsert({ + where: { + id: data.id + }, + update: { + title: data.title, + desc: data.desc, + status: data.status, + createdBy: data.createdBy + }, + create: { + id: data.id, + idVillage: data.idVillage, + idGroup: data.idGroup, + title: data.title, + desc: data.desc, + status: data.status, + createdBy: data.createdBy, + isActive: true + } + }) + } + + for (let data of seederProjectMemberComprehensive) { + await tx.projectMember.upsert({ + where: { + id: data.id + }, + update: { + idUser: data.idUser, + isLeader: data.isLeader + }, + create: { + id: data.id, + idProject: data.idProject, + idUser: data.idUser, + isLeader: data.isLeader, + isActive: true + } + }) + } + + for (let data of seederProjectTaskComprehensive) { + await tx.projectTask.upsert({ + where: { + id: data.id + }, + update: { + title: data.title, + desc: data.desc, + status: data.status, + dateStart: new Date(data.dateStart), + dateEnd: new Date(data.dateEnd) + }, + create: { + id: data.id, + idProject: data.idProject, + title: data.title, + desc: data.desc, + status: data.status, + dateStart: new Date(data.dateStart), + dateEnd: new Date(data.dateEnd), + isActive: true + } + }) + } + + for (let data of seederDiscussionComprehensive) { + await tx.discussion.upsert({ + where: { + id: data.id + }, + update: { + title: data.title, + desc: data.desc, + status: data.status, + createdBy: data.createdBy + }, + create: { + id: data.id, + idVillage: data.idVillage, + idGroup: data.idGroup!, + title: data.title, + desc: data.desc, + status: data.status, + createdBy: data.createdBy, + isActive: true + } + }) + } + + for (let data of seederDiscussionMemberComprehensive) { + await tx.discussionMember.upsert({ + where: { + id: data.id + }, + update: { + idUser: data.idUser + }, + create: { + id: data.id, + idDiscussion: data.idDiscussion, + idUser: data.idUser, + isActive: true + } + }) + } + }); + + console.log("\n✅ Complete village data seeding completed successfully!"); + console.log(`📊 Total admin roles processed: ${seederAdminRole.length}`); + console.log(`📊 Total admins processed: ${seederAdmin.length}`); + console.log(`📊 Total themes processed: ${seederTheme.length}`); + console.log(`📊 Total villages processed: ${seederDesa.length}`); + console.log(`📊 Total groups processed: ${[...seederGroup, ...seederGroupComprehensive].length}`); + console.log(`📊 Total positions processed: ${[...seederPosition, ...seederPositionComprehensive].length}`); + console.log(`📊 Total user roles processed: ${seederUserRole.length}`); + console.log(`📊 Total users processed: ${[...seederUser, ...seederUserComprehensive].length}`); + console.log(`📊 Total announcements processed: ${seederAnnouncementComprehensive.length}`); + console.log(`📊 Total announcement members processed: ${seederAnnouncementMemberComprehensive.length}`); + console.log(`📊 Total divisions processed: ${seederDivisionComprehensive.length}`); + console.log(`📊 Total division members processed: ${seederDivisionMemberComprehensive.length}`); + console.log(`📊 Total projects processed: ${seederProjectComprehensive.length}`); + console.log(`📊 Total project members processed: ${seederProjectMemberComprehensive.length}`); + console.log(`📊 Total project tasks processed: ${seederProjectTaskComprehensive.length}`); + console.log(`📊 Total discussions processed: ${seederDiscussionComprehensive.length}`); + console.log(`📊 Total discussion members processed: ${seederDiscussionMemberComprehensive.length}`); + } catch (error) { + console.error("\n❌ Error during seeding:", error); + throw new Error("Seeding process failed"); + } finally { + await prisma.$disconnect(); + } +} + +// Execute seeding if called directly from command line +if (require.main === module) { + seedCompleteVillageData() + .catch((e) => { + console.error(e); + process.exit(1); + }); +} + +export default seedCompleteVillageData; \ No newline at end of file diff --git a/src/module/seeder/data/desa.json b/src/module/seeder/data/desa.json index 421ae11..707874e 100644 --- a/src/module/seeder/data/desa.json +++ b/src/module/seeder/data/desa.json @@ -3,5 +3,10 @@ "id": "desa1", "name": "Darmasaba", "desc": "-" + }, + { + "id": "desaDummy", + "name": "Mandala", + "desc": "Desa Dummy untuk testing" } ] \ No newline at end of file diff --git a/src/module/seeder/data/discussion.json b/src/module/seeder/data/discussion.json new file mode 100644 index 0000000..d1eeeca --- /dev/null +++ b/src/module/seeder/data/discussion.json @@ -0,0 +1,20 @@ +[ + { + "id": "disc_kegiatan_desa", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "title": "Pembahasan Kegiatan Desa Mendatang", + "desc": "Diskusi untuk merencanakan kegiatan desa yang akan datang dan menyerap aspirasi warga", + "status": 1, + "createdBy": "user_kades" + }, + { + "id": "disc_pengelolaan_sampah", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "title": "Pengelolaan Sampah di RT 01", + "desc": "Diskusi internal RT 01 mengenai pengelolaan sampah rumah tangga dan lingkungan", + "status": 1, + "createdBy": "user_kades" + } +] \ No newline at end of file diff --git a/src/module/seeder/data/discussion_member.json b/src/module/seeder/data/discussion_member.json new file mode 100644 index 0000000..b75c966 --- /dev/null +++ b/src/module/seeder/data/discussion_member.json @@ -0,0 +1,27 @@ +[ + { + "id": "disc_mem_kegiatan_desa_kades", + "idDiscussion": "disc_kegiatan_desa", + "idUser": "user_sekdes" + }, + { + "id": "disc_mem_kegiatan_desa_sekdes", + "idDiscussion": "disc_kegiatan_desa", + "idUser": "user_warga1" + }, + { + "id": "disc_mem_kegiatan_desa_warga1", + "idDiscussion": "disc_kegiatan_desa", + "idUser": "user_warga2" + }, + { + "id": "disc_mem_pengelolaan_sampah_kades", + "idDiscussion": "disc_pengelolaan_sampah", + "idUser": "user_warga1" + }, + { + "id": "disc_mem_pengelolaan_sampah_warga1", + "idDiscussion": "disc_pengelolaan_sampah", + "idUser": "user_warga2" + } +] \ No newline at end of file diff --git a/src/module/seeder/data/group.json b/src/module/seeder/data/group.json index a333b68..90f3d78 100644 --- a/src/module/seeder/data/group.json +++ b/src/module/seeder/data/group.json @@ -3,5 +3,25 @@ "id": "group1", "idVillage": "desa1", "name": "Dinas" + }, + { + "id": "group_rt01", + "idVillage": "desaDummy", + "name": "Dinas" + }, + { + "id": "group_rt02", + "idVillage": "desaDummy", + "name": "Adat" + }, + { + "id": "group_karang_taruna", + "idVillage": "desaDummy", + "name": "Karang Taruna" + }, + { + "id": "group_bumdes", + "idVillage": "desaDummy", + "name": "PKK" } ] \ No newline at end of file diff --git a/src/module/seeder/data/position.json b/src/module/seeder/data/position.json index f820921..55c76b8 100644 --- a/src/module/seeder/data/position.json +++ b/src/module/seeder/data/position.json @@ -3,5 +3,25 @@ "id": "position1", "idGroup": "group1", "name": "Perbekel" + }, + { + "id": "pos_ketua_rt01", + "idGroup": "group_rt01", + "name": "Perbekel" + }, + { + "id": "pos_sekretaris_rt01", + "idGroup": "group_rt01", + "name": "Sekretaris" + }, + { + "id": "pos_bendahara_rt01", + "idGroup": "group_rt01", + "name": "Bendahara" + }, + { + "id": "pos_staff_rt01", + "idGroup": "group_rt01", + "name": "Staff" } ] \ No newline at end of file diff --git a/src/module/seeder/data/project.json b/src/module/seeder/data/project.json new file mode 100644 index 0000000..802fe58 --- /dev/null +++ b/src/module/seeder/data/project.json @@ -0,0 +1,11 @@ +[ + { + "id": "proj_pembangunan_jalan", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "title": "Pembangunan Jalan Desa Tahap 2", + "desc": "Pembangunan jalan desa tahap 2 yang mencakup wilayah RT 01 dan RT 02", + "status": 1, + "createdBy": "user_kades" + } +] \ No newline at end of file diff --git a/src/module/seeder/data/project_member.json b/src/module/seeder/data/project_member.json new file mode 100644 index 0000000..b4ef908 --- /dev/null +++ b/src/module/seeder/data/project_member.json @@ -0,0 +1,14 @@ +[ + { + "id": "proj_mem_pembangunan_jalan_kades", + "idProject": "proj_pembangunan_jalan", + "idUser": "user_warga1", + "isLeader": true + }, + { + "id": "proj_mem_pembangunan_jalan_sekdes", + "idProject": "proj_pembangunan_jalan", + "idUser": "user_warga2", + "isLeader": false + } +] \ No newline at end of file diff --git a/src/module/seeder/data/project_task.json b/src/module/seeder/data/project_task.json new file mode 100644 index 0000000..bd6c408 --- /dev/null +++ b/src/module/seeder/data/project_task.json @@ -0,0 +1,29 @@ +[ + { + "id": "task_survey_lokasi", + "idProject": "proj_pembangunan_jalan", + "title": "Survey Lokasi", + "desc": "Melakukan survey lokasi untuk menentukan titik pembangunan jalan", + "status": 1, + "dateStart": "2026-01-15T00:00:00.000Z", + "dateEnd": "2026-01-20T00:00:00.000Z" + }, + { + "id": "task_pengadaan_material", + "idProject": "proj_pembangunan_jalan", + "title": "Pengadaan Material", + "desc": "Mengadakan material pembangunan seperti pasir, batu, dan semen", + "status": 0, + "dateStart": "2026-02-01T00:00:00.000Z", + "dateEnd": "2026-02-10T00:00:00.000Z" + }, + { + "id": "task_pelaksanaan_pembangunan", + "idProject": "proj_pembangunan_jalan", + "title": "Pelaksanaan Pembangunan", + "desc": "Melaksanakan pembangunan jalan sesuai dengan desain yang telah ditentukan", + "status": 0, + "dateStart": "2026-02-15T00:00:00.000Z", + "dateEnd": "2026-03-15T00:00:00.000Z" + } +] \ No newline at end of file diff --git a/src/module/seeder/data/user.json b/src/module/seeder/data/user.json index 15c2589..2a5e29f 100644 --- a/src/module/seeder/data/user.json +++ b/src/module/seeder/data/user.json @@ -10,5 +10,53 @@ "phone": "628980185458", "email": "amalia_dev@bip.com", "gender": "F" + }, + { + "id": "user_kades", + "idUserRole": "supadmin", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_ketua_rt01", + "nik": "3201010101010001", + "name": "Kepala Desa", + "phone": "081234567890", + "email": "kades@desamandiri.test", + "gender": "M" + }, + { + "id": "user_sekdes", + "idUserRole": "admin", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_sekretaris_rt01", + "nik": "3201010101010002", + "name": "Sekretaris Desa", + "phone": "081234567891", + "email": "sekdes@desamandiri.test", + "gender": "M" + }, + { + "id": "user_warga1", + "idUserRole": "user", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_staff_rt01", + "nik": "3201010101010005", + "name": "Warga Satu", + "phone": "081234567894", + "email": "wargasatu@desamandiri.test", + "gender": "F" + }, + { + "id": "user_warga2", + "idUserRole": "user", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_staff_rt01", + "nik": "3201010101010006", + "name": "Warga Dua", + "phone": "081234567895", + "email": "wargadua@desamandiri.test", + "gender": "M" } ] \ No newline at end of file diff --git a/src/module/seeder/index.ts b/src/module/seeder/index.ts index 401ebb1..0aad346 100644 --- a/src/module/seeder/index.ts +++ b/src/module/seeder/index.ts @@ -1,10 +1,16 @@ -import seederAdminRole from "./data/admin_role.json"; import seederAdmin from "./data/admin.json"; -import seederUserRole from "./data/user_role.json"; -import seederUser from "./data/user.json"; +import seederAdminRole from "./data/admin_role.json"; import seederDesa from "./data/desa.json"; +import seederDiscussion from "./data/discussion.json"; +import seederDiscussionMember from "./data/discussion_member.json"; import seederGroup from "./data/group.json"; import seederPosition from "./data/position.json"; +import seederProject from "./data/project.json"; +import seederProjectMember from "./data/project_member.json"; +import seederProjectTask from "./data/project_task.json"; import seederTheme from "./data/theme.json"; +import seederUser from "./data/user.json"; +import seederUserRole from "./data/user_role.json"; + +export { seederAdmin, seederAdminRole, seederDesa, seederDiscussion, seederDiscussionMember, seederGroup, seederPosition, seederProject, seederProjectMember, seederProjectTask, seederTheme, seederUser, seederUserRole }; -export { seederAdminRole, seederAdmin, seederDesa, seederGroup, seederPosition, seederUserRole, seederUser, seederTheme } \ No newline at end of file From 474ced6a3890898a3111dfac4536cd3ee58b81ce Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 5 Feb 2026 14:04:49 +0800 Subject: [PATCH 30/32] upd: update seeder data desa dummy Deskripsi: - untuk presentasi - untuk testing No Issues --- prisma/seed.ts | 94 ++++++++++++++++++- src/module/seeder/data/announcement.json | 16 ++++ .../seeder/data/announcement_member.json | 20 ++++ src/module/seeder/data/division.json | 18 ++++ src/module/seeder/data/division_member.json | 30 ++++++ src/module/seeder/data/user.json | 48 +++++++--- src/module/seeder/index.ts | 6 +- 7 files changed, 216 insertions(+), 16 deletions(-) create mode 100644 src/module/seeder/data/announcement.json create mode 100644 src/module/seeder/data/announcement_member.json create mode 100644 src/module/seeder/data/division.json create mode 100644 src/module/seeder/data/division_member.json diff --git a/prisma/seed.ts b/prisma/seed.ts index fe5a0db..2931f9c 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,10 +1,10 @@ -import { seederAdmin, seederAdminRole, seederDesa, seederDiscussion, seederDiscussionMember, seederGroup, seederPosition, seederProject, seederProjectMember, seederProjectTask, seederTheme, seederUser, seederUserRole } from '@/module/seeder'; +import { seederAdmin, seederAdminRole, seederAnnouncement, seederAnnouncementMember, seederDesa, seederDiscussion, seederDiscussionMember, seederDivision, seederDivisionMember, seederGroup, seederPosition, seederProject, seederProjectMember, seederProjectTask, seederTheme, seederUser, seederUserRole } from '@/module/seeder'; import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient() // DATA YG DI SEEDER MERUPAKAN DATA REAL(DARMASABA) & DATA DUMMY (MANDALA) // DATA JSON GABUNGAN (REAL & DUMMY) ADALAH adminRole, admin, theme, desa, group, position, user, userRole, user -// Selain table yg disebutkan merupakan data dummy +// Selain table yg disebutkan, data lainnya merupakan data dummy async function main() { // ADMIN ROLE @@ -148,7 +148,7 @@ async function main() { }) } - // USER + // USER for (let data of seederUser) { await prisma.user.upsert({ where: { @@ -297,6 +297,94 @@ async function main() { }, }) } + + // DIVISION + for (let data of seederDivision) { + await prisma.division.upsert({ + where: { + id: data.id + }, + update: { + name: data.name, + desc: data.desc, + createdBy: data.createdBy + }, + create: { + id: data.id, + idVillage: data.idVillage, + idGroup: data.idGroup, + name: data.name, + desc: data.desc, + createdBy: data.createdBy, + isActive: true + } + }) + } + + // DIVISION MEMBER + for (let data of seederDivisionMember) { + await prisma.divisionMember.upsert({ + where: { + id: data.id + }, + update: { + idUser: data.idUser, + isAdmin: data.isAdmin, + isLeader: data.isLeader + }, + create: { + id: data.id, + idDivision: data.idDivision, + idUser: data.idUser, + isAdmin: data.isAdmin, + isLeader: data.isLeader, + isActive: true + } + }) + } + + // ANNOUNCEMENT + for (let data of seederAnnouncement) { + await prisma.announcement.upsert({ + where: { + id: data.id + }, + update: { + title: data.title, + desc: data.desc, + createdBy: data.createdBy + }, + create: { + id: data.id, + idVillage: data.idVillage, + title: data.title, + desc: data.desc, + createdBy: data.createdBy, + isActive: true + } + }) + } + + // ANNOUNCEMENT MEMBER + for (let data of seederAnnouncementMember) { + await prisma.announcementMember.upsert({ + where: { + id: data.id + }, + update: { + idAnnouncement: data.idAnnouncement, + idGroup: data.idGroup, + idDivision: data.idDivision + }, + create: { + id: data.id, + idAnnouncement: data.idAnnouncement, + idGroup: data.idGroup, + idDivision: data.idDivision, + isActive: true + } + }) + } } main().then(async () => { diff --git a/src/module/seeder/data/announcement.json b/src/module/seeder/data/announcement.json new file mode 100644 index 0000000..9daaba6 --- /dev/null +++ b/src/module/seeder/data/announcement.json @@ -0,0 +1,16 @@ +[ + { + "id": "ann_pembangunan_jalan", + "idVillage": "desaDummy", + "title": "Pembangunan Jalan Desa Tahap 2", + "desc": "Pada bulan ini akan dilakukan pembangunan jalan desa tahap 2 yang mencakup wilayah RT 01 dan RT 02. Mohon kerjasama warga untuk menyesuaikan aktivitas selama masa pembangunan.", + "createdBy": "user_kades" + }, + { + "id": "ann_rapat_warga", + "idVillage": "desaDummy", + "title": "Rapat Bulanan", + "desc": "Rapat bulanan akan diselenggarakan pada hari Sabtu, 25 Februari 2026 pukul 09.00 WIB di Balai Desa. Hadirilah tepat waktu.", + "createdBy": "user_kades" + } +] \ No newline at end of file diff --git a/src/module/seeder/data/announcement_member.json b/src/module/seeder/data/announcement_member.json new file mode 100644 index 0000000..d0e1964 --- /dev/null +++ b/src/module/seeder/data/announcement_member.json @@ -0,0 +1,20 @@ +[ + { + "id": "ann_mem_pembangunan_jalan_rt01", + "idAnnouncement": "ann_pembangunan_jalan", + "idGroup": "group_rt01", + "idDivision": "div_pelayanan" + }, + { + "id": "ann_mem_pembangunan_jalan_rt02", + "idAnnouncement": "ann_pembangunan_jalan", + "idGroup": "group_rt01", + "idDivision": "div_umum" + }, + { + "id": "ann_mem_rapat_warga_all", + "idAnnouncement": "ann_rapat_warga", + "idGroup": "group_rt01", + "idDivision": "div_umum" + } +] \ No newline at end of file diff --git a/src/module/seeder/data/division.json b/src/module/seeder/data/division.json new file mode 100644 index 0000000..b43fe30 --- /dev/null +++ b/src/module/seeder/data/division.json @@ -0,0 +1,18 @@ +[ + { + "id": "div_pelayanan", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "name": "Seksi Pelayanan", + "desc": "Bertanggung jawab atas pelayanan administrasi umum, perizinan, dan kebutuhan dokumen masyarakat desa.", + "createdBy": "user_kades" + }, + { + "id": "div_umum", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "name": "Urusan Tata Usaha dan Umum", + "desc": "Menangani administrasi perkantoran, arsip desa, inventaris aset, dan operasional kantor desa.", + "createdBy": "user_kades" + } +] \ No newline at end of file diff --git a/src/module/seeder/data/division_member.json b/src/module/seeder/data/division_member.json new file mode 100644 index 0000000..b56b999 --- /dev/null +++ b/src/module/seeder/data/division_member.json @@ -0,0 +1,30 @@ +[ + { + "id": "div_mem_linmas_warga1", + "idDivision": "div_linmas", + "idUser": "user_warga1", + "isAdmin": false, + "isLeader": false + }, + { + "id": "div_mem_linmas_warga2", + "idDivision": "div_linmas", + "idUser": "user_warga2", + "isAdmin": false, + "isLeader": false + }, + { + "id": "div_mem_umum_warga3", + "idDivision": "div_umum", + "idUser": "user_warga3", + "isAdmin": false, + "isLeader": false + }, + { + "id": "div_mem_umum_warga4", + "idDivision": "div_umum", + "idUser": "user_warga4", + "isAdmin": false, + "isLeader": false + } +] \ No newline at end of file diff --git a/src/module/seeder/data/user.json b/src/module/seeder/data/user.json index 2a5e29f..5b41cec 100644 --- a/src/module/seeder/data/user.json +++ b/src/module/seeder/data/user.json @@ -16,12 +16,12 @@ "idUserRole": "supadmin", "idVillage": "desaDummy", "idGroup": "group_rt01", - "idPosition": "pos_ketua_rt01", + "idPosition": "pos_keØtua_rt01", "nik": "3201010101010001", - "name": "Kepala Desa", + "name": "Juli Ningrum", "phone": "081234567890", - "email": "kades@desamandiri.test", - "gender": "M" + "email": "juli@gmail.com", + "gender": "F" }, { "id": "user_sekdes", @@ -30,10 +30,10 @@ "idGroup": "group_rt01", "idPosition": "pos_sekretaris_rt01", "nik": "3201010101010002", - "name": "Sekretaris Desa", + "name": "Salwa Kusmawati", "phone": "081234567891", - "email": "sekdes@desamandiri.test", - "gender": "M" + "email": "salwa@gmail.com", + "gender": "F" }, { "id": "user_warga1", @@ -42,10 +42,10 @@ "idGroup": "group_rt01", "idPosition": "pos_staff_rt01", "nik": "3201010101010005", - "name": "Warga Satu", + "name": "Bakidin Wibowo", "phone": "081234567894", - "email": "wargasatu@desamandiri.test", - "gender": "F" + "email": "bakidin@gmail.com", + "gender": "M" }, { "id": "user_warga2", @@ -54,9 +54,33 @@ "idGroup": "group_rt01", "idPosition": "pos_staff_rt01", "nik": "3201010101010006", - "name": "Warga Dua", + "name": "Jais Kurniawan", "phone": "081234567895", - "email": "wargadua@desamandiri.test", + "email": "jais@gmail.com", + "gender": "M" + }, + { + "id": "user_warga3", + "idUserRole": "user", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_staff_rt01", + "nik": "3201010101010007", + "name": "Safira Oktaviani S.I.Kom", + "phone": "081234567894", + "email": "safira@gmail.com", + "gender": "F" + }, + { + "id": "user_warga4", + "idUserRole": "user", + "idVillage": "desaDummy", + "idGroup": "group_rt01", + "idPosition": "pos_staff_rt01", + "nik": "3201010101010008", + "name": "Agus Setiawan", + "phone": "081234567895", + "email": "agus@gmail.com", "gender": "M" } ] \ No newline at end of file diff --git a/src/module/seeder/index.ts b/src/module/seeder/index.ts index 0aad346..4256eaa 100644 --- a/src/module/seeder/index.ts +++ b/src/module/seeder/index.ts @@ -1,8 +1,12 @@ import seederAdmin from "./data/admin.json"; import seederAdminRole from "./data/admin_role.json"; +import seederAnnouncement from "./data/announcement.json"; +import seederAnnouncementMember from "./data/announcement_member.json"; import seederDesa from "./data/desa.json"; import seederDiscussion from "./data/discussion.json"; import seederDiscussionMember from "./data/discussion_member.json"; +import seederDivision from "./data/division.json"; +import seederDivisionMember from "./data/division_member.json"; import seederGroup from "./data/group.json"; import seederPosition from "./data/position.json"; import seederProject from "./data/project.json"; @@ -12,5 +16,5 @@ import seederTheme from "./data/theme.json"; import seederUser from "./data/user.json"; import seederUserRole from "./data/user_role.json"; -export { seederAdmin, seederAdminRole, seederDesa, seederDiscussion, seederDiscussionMember, seederGroup, seederPosition, seederProject, seederProjectMember, seederProjectTask, seederTheme, seederUser, seederUserRole }; +export { seederAdmin, seederAdminRole, seederAnnouncement, seederAnnouncementMember, seederDesa, seederDiscussion, seederDiscussionMember, seederDivision, seederDivisionMember, seederGroup, seederPosition, seederProject, seederProjectMember, seederProjectTask, seederTheme, seederUser, seederUserRole }; From 854921935a33ad7c349a64fffb62ba3a39556463 Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 5 Feb 2026 16:25:07 +0800 Subject: [PATCH 31/32] data dummy seeder --- src/module/seeder/data/division_member.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/module/seeder/data/division_member.json b/src/module/seeder/data/division_member.json index b56b999..81b11b2 100644 --- a/src/module/seeder/data/division_member.json +++ b/src/module/seeder/data/division_member.json @@ -1,14 +1,14 @@ [ { "id": "div_mem_linmas_warga1", - "idDivision": "div_linmas", + "idDivision": "div_pelayanan", "idUser": "user_warga1", "isAdmin": false, "isLeader": false }, { "id": "div_mem_linmas_warga2", - "idDivision": "div_linmas", + "idDivision": "div_pelayanan", "idUser": "user_warga2", "isAdmin": false, "isLeader": false From 30611802f41ede56588136addd05d4703a6ef0ba Mon Sep 17 00:00:00 2001 From: amaliadwiy Date: Thu, 5 Feb 2026 17:26:03 +0800 Subject: [PATCH 32/32] upd: seeder data dummy --- src/module/seeder/data/admin.json | 2 +- src/module/seeder/data/user.json | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/module/seeder/data/admin.json b/src/module/seeder/data/admin.json index 337f78c..b3ac3ca 100644 --- a/src/module/seeder/data/admin.json +++ b/src/module/seeder/data/admin.json @@ -8,7 +8,7 @@ "gender": "F" }, { - "id": "devMalik", + "id": "devLukman", "idAdminRole": "dev", "name": "Malik", "phone": "6289697338821", diff --git a/src/module/seeder/data/user.json b/src/module/seeder/data/user.json index 5b41cec..310b4b1 100644 --- a/src/module/seeder/data/user.json +++ b/src/module/seeder/data/user.json @@ -16,7 +16,7 @@ "idUserRole": "supadmin", "idVillage": "desaDummy", "idGroup": "group_rt01", - "idPosition": "pos_keØtua_rt01", + "idPosition": "pos_ketua_rt01", "nik": "3201010101010001", "name": "Juli Ningrum", "phone": "081234567890", @@ -43,7 +43,7 @@ "idPosition": "pos_staff_rt01", "nik": "3201010101010005", "name": "Bakidin Wibowo", - "phone": "081234567894", + "phone": "6", "email": "bakidin@gmail.com", "gender": "M" }, @@ -67,7 +67,7 @@ "idPosition": "pos_staff_rt01", "nik": "3201010101010007", "name": "Safira Oktaviani S.I.Kom", - "phone": "081234567894", + "phone": "081234567896", "email": "safira@gmail.com", "gender": "F" }, @@ -79,7 +79,7 @@ "idPosition": "pos_staff_rt01", "nik": "3201010101010008", "name": "Agus Setiawan", - "phone": "081234567895", + "phone": "081234567897", "email": "agus@gmail.com", "gender": "M" }