feat: tambah endpoint kalender umum village
- GET /mobile/village-calendar: ambil acara divisi dan kegiatan se-village per tanggal - GET /mobile/village-calendar/indicator: dot indikator per bulan, task di-expand per hari dalam range dateStart-dateEnd
This commit is contained in:
83
src/app/api/mobile/village-calendar/indicator/route.ts
Normal file
83
src/app/api/mobile/village-calendar/indicator/route.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { prisma } from "@/module/_global";
|
||||
import { funGetUserById } from "@/module/auth";
|
||||
import _ from "lodash";
|
||||
import moment from "moment";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
// GET indicator dot per bulan (tanggal mana saja yang ada event)
|
||||
export async function GET(request: Request) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const user = searchParams.get("user");
|
||||
const date = searchParams.get("date");
|
||||
|
||||
const userMobile = await funGetUserById({ id: String(user) });
|
||||
if (!userMobile.id || userMobile.id === "null") {
|
||||
return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 });
|
||||
}
|
||||
|
||||
const idVillage = userMobile.idVillage;
|
||||
const awalDate = moment(date).format("YYYY-MM") + "-01";
|
||||
const akhirDate = moment(awalDate).add(1, "M").format("YYYY-MM-DD");
|
||||
|
||||
// Tanggal dengan event kalender divisi
|
||||
const calendarDates = await prisma.divisionCalendarReminder.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
dateStart: {
|
||||
gte: new Date(awalDate),
|
||||
lt: new Date(akhirDate),
|
||||
},
|
||||
Division: {
|
||||
idVillage,
|
||||
isActive: true,
|
||||
},
|
||||
DivisionCalendar: {
|
||||
isActive: true,
|
||||
},
|
||||
},
|
||||
select: { dateStart: true },
|
||||
});
|
||||
|
||||
// Tanggal dengan task project se-village (ambil semua task yang overlap dengan bulan ini)
|
||||
const taskDates = await prisma.projectTask.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
dateStart: { lt: new Date(akhirDate) },
|
||||
dateEnd: { gte: new Date(awalDate) },
|
||||
Project: {
|
||||
isActive: true,
|
||||
idVillage: String(idVillage),
|
||||
},
|
||||
},
|
||||
select: { dateStart: true, dateEnd: true },
|
||||
});
|
||||
|
||||
// Expand setiap task menjadi array tanggal per hari dalam range bulan
|
||||
const taskExpandedDates: string[] = [];
|
||||
for (const task of taskDates) {
|
||||
let cur = moment(task.dateStart);
|
||||
const end = moment(task.dateEnd);
|
||||
const monthStart = moment(awalDate);
|
||||
const monthEnd = moment(akhirDate);
|
||||
while (cur.isSameOrBefore(end)) {
|
||||
if (cur.isSameOrAfter(monthStart) && cur.isBefore(monthEnd)) {
|
||||
taskExpandedDates.push(cur.format("YYYY-MM-DD"));
|
||||
}
|
||||
cur.add(1, 'day');
|
||||
}
|
||||
}
|
||||
|
||||
const calendarResult = _.uniq(calendarDates.map((v) => moment(v.dateStart).format("YYYY-MM-DD"))).sort();
|
||||
const taskResult = _.uniq(taskExpandedDates).sort();
|
||||
|
||||
return NextResponse.json({
|
||||
success: true,
|
||||
message: "Berhasil mendapatkan indicator kalender",
|
||||
data: { calendar: calendarResult, task: taskResult }
|
||||
}, { status: 200 });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return NextResponse.json({ success: false, message: "Gagal mendapatkan indicator kalender (error: 500)" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
122
src/app/api/mobile/village-calendar/route.ts
Normal file
122
src/app/api/mobile/village-calendar/route.ts
Normal file
@@ -0,0 +1,122 @@
|
||||
import { prisma } from "@/module/_global";
|
||||
import { funGetUserById } from "@/module/auth";
|
||||
import _ from "lodash";
|
||||
import moment from "moment";
|
||||
import "moment/locale/id";
|
||||
import { NextResponse } from "next/server";
|
||||
|
||||
// GET events per tanggal (DivisionCalendarReminder + ProjectTask)
|
||||
export async function GET(request: Request) {
|
||||
try {
|
||||
const { searchParams } = new URL(request.url);
|
||||
const user = searchParams.get("user");
|
||||
const date = searchParams.get("date");
|
||||
|
||||
const userMobile = await funGetUserById({ id: String(user) });
|
||||
if (!userMobile.id || userMobile.id === "null") {
|
||||
return NextResponse.json({ success: false, message: "Anda harus login untuk mengakses ini" }, { status: 200 });
|
||||
}
|
||||
|
||||
const targetDate = new Date(String(date));
|
||||
const idVillage = userMobile.idVillage;
|
||||
|
||||
// Ambil semua event kalender divisi se-village pada tanggal tersebut
|
||||
const calendarData = await prisma.divisionCalendarReminder.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
dateStart: targetDate,
|
||||
Division: {
|
||||
idVillage,
|
||||
isActive: true,
|
||||
},
|
||||
DivisionCalendar: {
|
||||
isActive: true,
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
idCalendar: true,
|
||||
dateStart: true,
|
||||
dateEnd: true,
|
||||
timeStart: true,
|
||||
timeEnd: true,
|
||||
Division: {
|
||||
select: {
|
||||
id: true,
|
||||
name: true,
|
||||
},
|
||||
},
|
||||
DivisionCalendar: {
|
||||
select: {
|
||||
title: true,
|
||||
desc: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: [{ timeStart: "asc" }, { timeEnd: "asc" }],
|
||||
});
|
||||
|
||||
// Ambil semua task project se-village yang mencakup tanggal tersebut (dateStart <= target <= dateEnd)
|
||||
const taskData = await prisma.projectTask.findMany({
|
||||
where: {
|
||||
isActive: true,
|
||||
dateStart: { lte: targetDate },
|
||||
dateEnd: { gte: targetDate },
|
||||
Project: {
|
||||
isActive: true,
|
||||
idVillage: String(idVillage),
|
||||
},
|
||||
},
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
desc: true,
|
||||
dateStart: true,
|
||||
dateEnd: true,
|
||||
Project: {
|
||||
select: {
|
||||
id: true,
|
||||
title: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
orderBy: { dateStart: "asc" },
|
||||
});
|
||||
|
||||
const calendarResult = calendarData.map((v) => ({
|
||||
id: v.id,
|
||||
type: "calendar",
|
||||
title: v.DivisionCalendar.title,
|
||||
desc: v.DivisionCalendar.desc,
|
||||
dateStart: moment(v.dateStart).format("YYYY-MM-DD"),
|
||||
dateEnd: v.dateEnd ? moment(v.dateEnd).format("YYYY-MM-DD") : null,
|
||||
timeStart: moment.utc(v.timeStart).format("HH:mm"),
|
||||
timeEnd: moment.utc(v.timeEnd).format("HH:mm"),
|
||||
divisionName: v.Division.name,
|
||||
projectName: null,
|
||||
idDivision: v.Division.id,
|
||||
idRef: v.Division.id,
|
||||
}));
|
||||
|
||||
const taskResult = taskData.map((v) => ({
|
||||
id: v.id,
|
||||
type: "task",
|
||||
title: v.title,
|
||||
desc: v.desc ?? "",
|
||||
dateStart: moment(v.dateStart).format("YYYY-MM-DD"),
|
||||
dateEnd: moment(v.dateEnd).format("YYYY-MM-DD"),
|
||||
timeStart: null,
|
||||
timeEnd: null,
|
||||
divisionName: null,
|
||||
projectName: v.Project.title,
|
||||
idRef: v.Project.id,
|
||||
}));
|
||||
|
||||
const data = [...calendarResult, ...taskResult];
|
||||
|
||||
return NextResponse.json({ success: true, message: "Berhasil mendapatkan kalender umum", data }, { status: 200 });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return NextResponse.json({ success: false, message: "Gagal mendapatkan kalender umum (error: 500)" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user