UI & API Menu Landing Page

This commit is contained in:
2025-07-28 10:18:24 +08:00
parent a25cfe8b8a
commit 5601e59922
51 changed files with 3683 additions and 57 deletions

View File

@@ -0,0 +1,33 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const ageStatCreate = async (context: Context) => {
const body = (await context.body) as {
group: string;
count: number;
monthlyStatId: string;
};
try {
const created = await prisma.ageStat.create({
data: {
group: body.group,
count: body.count,
monthlyStatId: body.monthlyStatId,
},
});
return {
success: true,
message: "Age Stat berhasil dibuat",
data: created,
};
} catch (error) {
console.error("Gagal create age stat:", error);
return {
success: false,
message: "Gagal membuat data age stat",
};
}
};
export default ageStatCreate;

View File

@@ -0,0 +1,24 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const ageStatDelete = async (context: Context) => {
const { id } = context.params as { id: string };
try {
await prisma.ageStat.delete({
where: { id },
});
return {
success: true,
message: "Data age berhasil dihapus",
};
} catch (error) {
console.error("Gagal hapus Age Stat:", error);
return {
success: false,
message: "Gagal menghapus data age stat",
};
}
};
export default ageStatDelete;

View File

@@ -0,0 +1,26 @@
import prisma from "@/lib/prisma";
export const ageStatFindMany = async () => {
try {
const result = await prisma.ageStat.findMany({
include: {
MonthlyStat: true,
},
orderBy: {
id: "desc",
},
});
return {
success: true,
data: result,
};
} catch (error) {
console.error("Gagal ambil data Age Stat:", error);
return {
success: false,
message: "Gagal mengambil data age stat",
};
}
};
export default ageStatFindMany;

View File

@@ -0,0 +1,34 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const ageStatFindUnique = async (context: Context) => {
const { id } = context.params as { id: string };
try {
const result = await prisma.ageStat.findUnique({
where: { id },
include: {
MonthlyStat: true,
},
});
if (!result) {
return {
success: false,
message: "Data age tidak ditemukan",
};
}
return {
success: true,
data: result,
};
} catch (error) {
console.error("Gagal ambil data Age Stat:", error);
return {
success: false,
message: "Terjadi kesalahan saat mengambil data age stat",
};
}
};
export default ageStatFindUnique;

View File

@@ -0,0 +1,31 @@
import Elysia, { t } from "elysia";
import ageStatCreate from "./create";
import ageStatDelete from "./del";
import ageStatFindMany from "./findMany";
import ageStatFindUnique from "./findUnique";
import ageStatUpdate from "./updt";
const age = new Elysia({
prefix: "/age",
tags: ["Landing Page/Indeks Kepuasan Masyarakat/Age"],
})
.post("/create", ageStatCreate, {
body: t.Object({
monthlyStatId: t.String(),
group: t.String(),
count: t.Number(),
}),
})
.get("/findMany", ageStatFindMany)
.get("/:id", ageStatFindUnique)
.put("/:id", ageStatUpdate, {
body: t.Object({
group: t.String(),
count: t.Number(),
monthlyStatId: t.String(),
}),
})
.delete("/del/:id", ageStatDelete);
export default age;

View File

@@ -0,0 +1,35 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const ageStatUpdate = async (context: Context) => {
const { id } = context.params as { id: string };
const body = (await context.body) as {
group?: string;
count?: number;
monthlyStatId?: string;
};
try {
const updated = await prisma.ageStat.update({
where: { id },
data: {
group: body.group,
count: body.count,
monthlyStatId: body.monthlyStatId,
},
});
return {
success: true,
message: "Data age berhasil diperbarui",
data: updated,
};
} catch (error) {
console.error("Gagal update Age Stat:", error);
return {
success: false,
message: "Gagal memperbarui data age stat",
};
}
};
export default ageStatUpdate;

View File

@@ -0,0 +1,40 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const genderStatCreate = async (context: Context) => {
const body = (await context.body) as {
laki: number;
perempuan: number;
monthlyStatId: string;
};
const total = body.laki + body.perempuan;
const percentLaki = total > 0 ? Number(((body.laki / total) * 100).toFixed(2)) : 0;
const percentPerempuan = total > 0 ? Number(((body.perempuan / total) * 100).toFixed(2)) : 0;
try {
const created = await prisma.genderStat.create({
data: {
laki: body.laki,
perempuan: body.perempuan,
total,
percentLaki: Number(percentLaki),
percentPerempuan: Number(percentPerempuan),
monthlyStatId: body.monthlyStatId,
},
});
return {
success: true,
message: "Gender Stat berhasil dibuat",
data: created,
};
} catch (error) {
console.error("Gagal create gender stat:", error);
return {
success: false,
message: "Gagal membuat data gender stat",
};
}
};
export default genderStatCreate;

View File

@@ -0,0 +1,24 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const genderStatDelete = async (context: Context) => {
const { id } = context.params as { id: string };
try {
await prisma.genderStat.delete({
where: { id },
});
return {
success: true,
message: "Data gender berhasil dihapus",
};
} catch (error) {
console.error("Gagal hapus Gender Stat:", error);
return {
success: false,
message: "Gagal menghapus data gender",
};
}
};
export default genderStatDelete;

View File

@@ -0,0 +1,26 @@
import prisma from "@/lib/prisma";
export const genderStatFindMany = async () => {
try {
const result = await prisma.genderStat.findMany({
include: {
MonthlyStat: true,
},
orderBy: {
id: "desc",
},
});
return {
success: true,
data: result,
};
} catch (error) {
console.error("Gagal ambil data Gender Stat:", error);
return {
success: false,
message: "Gagal mengambil data gender stat",
};
}
};
export default genderStatFindMany;

View File

@@ -0,0 +1,34 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const genderStatFindUnique = async (context: Context) => {
const { id } = context.params as { id: string };
try {
const result = await prisma.genderStat.findUnique({
where: { id },
include: {
MonthlyStat: true,
},
});
if (!result) {
return {
success: false,
message: "Data gender tidak ditemukan",
};
}
return {
success: true,
data: result,
};
} catch (error) {
console.error("Gagal ambil data Gender Stat:", error);
return {
success: false,
message: "Terjadi kesalahan saat mengambil data gender stat",
};
}
};
export default genderStatFindUnique;

View File

@@ -0,0 +1,37 @@
import Elysia, { t } from "elysia";
import genderStatCreate from "./create";
import genderStatDelete from "./del";
import genderStatFindMany from "./findMany";
import genderStatFindUnique from "./findUnique";
import genderStatUpdate from "./updt";
const gender = new Elysia({
prefix: "/gender",
tags: ["Landing Page/Indeks Kepuasan Masyarakat/Gender"],
})
.post("/create", genderStatCreate, {
body: t.Object({
monthlyStatId: t.String(),
laki: t.Number(),
perempuan: t.Number(),
total: t.Number(),
percentLaki: t.Number(),
percentPerempuan: t.Number(),
}),
})
.get("/findMany", genderStatFindMany)
.get("/:id", genderStatFindUnique)
.put("/:id", genderStatUpdate, {
body: t.Object({
laki: t.Number(),
perempuan: t.Number(),
monthlyStatId: t.String(),
total: t.Number(),
percentLaki: t.Number(),
percentPerempuan: t.Number(),
}),
})
.delete("/del/:id", genderStatDelete);
export default gender;

View File

@@ -0,0 +1,42 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const genderStatUpdate = async (context: Context) => {
const { id } = context.params as { id: string };
const body = (await context.body) as {
laki?: number;
perempuan?: number;
monthlyStatId?: string;
};
const total = (body.laki ?? 0) + (body.perempuan ?? 0);
const percentLaki = total > 0 ? Number(((body.laki ?? 0) / total) * 100).toFixed(2) : 0;
const percentPerempuan = total > 0 ? Number(((body.perempuan ?? 0) / total) * 100).toFixed(2) : 0;
try {
const updated = await prisma.genderStat.update({
where: { id },
data: {
laki: body.laki,
perempuan: body.perempuan,
total,
percentLaki: Number(percentLaki),
percentPerempuan: Number(percentPerempuan),
monthlyStatId: body.monthlyStatId,
},
});
return {
success: true,
message: "Data gender berhasil diperbarui",
data: updated,
};
} catch (error) {
console.error("Gagal update Gender Stat:", error);
return {
success: false,
message: "Gagal memperbarui data gender stat",
};
}
};
export default genderStatUpdate;

View File

@@ -0,0 +1,20 @@
import Elysia from "elysia";
import gender from "./gender";
import monthlyStat from "./monthly-stat";
import survey from "./survey";
import response from "./response";
import age from "./age";
const IndeksKepuasanMasyarakat = new Elysia({
prefix: "/indekskepuasanmasyarakat",
tags: ["Landing Page/Profile/Indeks Kepuasan Masyarakat"],
})
.use(gender)
.use(monthlyStat)
.use(survey)
.use(response)
.use(age)
export default IndeksKepuasanMasyarakat

View File

@@ -0,0 +1,33 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const createMonthlyStat = async (context: Context) => {
const body = await context.body as {
month: string;
respondentsCount: number;
surveyId: string;
};
try {
const created = await prisma.monthlyStat.create({
data: {
month: body.month,
respondentsCount: body.respondentsCount,
surveyId: body.surveyId,
},
});
return {
success: true,
message: "Monthly stat berhasil dibuat",
data: created,
};
} catch (error) {
console.error("Gagal create monthly stat:", error);
return {
success: false,
message: "Gagal membuat monthly stat",
};
}
};
export default createMonthlyStat;

View File

@@ -0,0 +1,26 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const deleteMonthlyStat = async (context: Context) => {
const { id } = context.params as { id: string };
try {
await prisma.monthlyStat.delete({
where: { id },
});
return {
success: true,
message: "Data statistik bulanan berhasil dihapus",
};
} catch (error) {
console.error("Gagal hapus MonthlyStat:", error);
return {
success: false,
message: "Gagal menghapus data statistik bulanan",
};
}
};
export default deleteMonthlyStat;

View File

@@ -0,0 +1,26 @@
import prisma from "@/lib/prisma";
export const findManyMonthlyStat = async () => {
try {
const result = await prisma.monthlyStat.findMany({
include: {
survey: true,
},
orderBy: {
id: "desc",
},
});
return {
success: true,
data: result,
};
} catch (error) {
console.error("Gagal ambil data MonthlyStat:", error);
return {
success: false,
message: "Gagal mengambil data statistik bulanan",
};
}
};
export default findManyMonthlyStat;

View File

@@ -0,0 +1,35 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const findUniqueMonthlyStat = async (context: Context) => {
const { id } = context.params as { id: string };
try {
const result = await prisma.monthlyStat.findUnique({
where: { id },
include: {
survey: true,
},
});
if (!result) {
return {
success: false,
message: "Data tidak ditemukan",
};
}
return {
success: true,
data: result,
};
} catch (error) {
console.error("Gagal ambil data MonthlyStat:", error);
return {
success: false,
message: "Terjadi kesalahan saat mengambil data",
};
}
};
export default findUniqueMonthlyStat;

View File

@@ -0,0 +1,31 @@
import Elysia, { t } from "elysia";
import createMonthlyStat from "./create";
import deleteMonthlyStat from "./del";
import findManyMonthlyStat from "./findMany";
import findUniqueMonthlyStat from "./findUnique";
import updateMonthlyStat from "./updt";
const surveyResponse = new Elysia({
prefix: "/monthlystat",
tags: ["Landing Page/Indeks Kepuasan Masyarakat/Survey Response"],
})
.post("/create", createMonthlyStat, {
body: t.Object({
month: t.String(),
respondentsCount: t.Number(),
surveyId: t.String(),
}),
})
.get("/findMany", findManyMonthlyStat)
.get("/:id", findUniqueMonthlyStat)
.put("/:id", updateMonthlyStat, {
body: t.Object({
month: t.String(),
respondentsCount: t.Number(),
surveyId: t.String(),
}),
})
.delete("/del/:id", deleteMonthlyStat);
export default surveyResponse;

View File

@@ -0,0 +1,34 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const updateMonthlyStat = async (context: Context) => {
const { id } = context.params as { id: string };
const body = await context.body as {
month?: string;
respondentsCount?: number;
};
try {
const updated = await prisma.monthlyStat.update({
where: { id },
data: {
month: body.month,
respondentsCount: body.respondentsCount,
},
});
return {
success: true,
message: "Data MonthlyStat berhasil diupdate",
data: updated,
};
} catch (error) {
console.error("Gagal update MonthlyStat:", error);
return {
success: false,
message: "Gagal mengupdate data statistik bulanan",
};
}
};
export default updateMonthlyStat;

View File

@@ -0,0 +1,33 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const responseStatCreate = async (context: Context) => {
const body = (await context.body) as {
label: string;
count: number;
monthlyStatId: string;
};
try {
const created = await prisma.responseStat.create({
data: {
label: body.label,
count: body.count,
monthlyStatId: body.monthlyStatId,
},
});
return {
success: true,
message: "Response Stat berhasil dibuat",
data: created,
};
} catch (error) {
console.error("Gagal create response stat:", error);
return {
success: false,
message: "Gagal membuat data response stat",
};
}
};
export default responseStatCreate;

View File

@@ -0,0 +1,24 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const responseStatDelete = async (context: Context) => {
const { id } = context.params as { id: string };
try {
await prisma.responseStat.delete({
where: { id },
});
return {
success: true,
message: "Data response berhasil dihapus",
};
} catch (error) {
console.error("Gagal hapus Response Stat:", error);
return {
success: false,
message: "Gagal menghapus data response stat",
};
}
};
export default responseStatDelete;

View File

@@ -0,0 +1,26 @@
import prisma from "@/lib/prisma";
export const responseStatFindMany = async () => {
try {
const result = await prisma.responseStat.findMany({
include: {
MonthlyStat: true,
},
orderBy: {
id: "desc",
},
});
return {
success: true,
data: result,
};
} catch (error) {
console.error("Gagal ambil data Response Stat:", error);
return {
success: false,
message: "Gagal mengambil data response stat",
};
}
};
export default responseStatFindMany;

View File

@@ -0,0 +1,34 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const responseStatFindUnique = async (context: Context) => {
const { id } = context.params as { id: string };
try {
const result = await prisma.responseStat.findUnique({
where: { id },
include: {
MonthlyStat: true,
},
});
if (!result) {
return {
success: false,
message: "Data response tidak ditemukan",
};
}
return {
success: true,
data: result,
};
} catch (error) {
console.error("Gagal ambil data Response Stat:", error);
return {
success: false,
message: "Terjadi kesalahan saat mengambil data response stat",
};
}
};
export default responseStatFindUnique;

View File

@@ -0,0 +1,31 @@
import Elysia, { t } from "elysia";
import responseStatCreate from "./create";
import responseStatDelete from "./del";
import responseStatFindMany from "./findMany";
import responseStatFindUnique from "./findUnique";
import responseStatUpdate from "./updt";
const response = new Elysia({
prefix: "/response",
tags: ["Landing Page/Indeks Kepuasan Masyarakat/Response"],
})
.post("/create", responseStatCreate, {
body: t.Object({
monthlyStatId: t.String(),
label: t.String(),
count: t.Number(),
}),
})
.get("/findMany", responseStatFindMany)
.get("/:id", responseStatFindUnique)
.put("/:id", responseStatUpdate, {
body: t.Object({
label: t.String(),
count: t.Number(),
monthlyStatId: t.String(),
}),
})
.delete("/del/:id", responseStatDelete);
export default response;

View File

@@ -0,0 +1,35 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const responseStatUpdate = async (context: Context) => {
const { id } = context.params as { id: string };
const body = (await context.body) as {
label?: string;
count?: number;
monthlyStatId?: string;
};
try {
const updated = await prisma.responseStat.update({
where: { id },
data: {
label: body.label,
count: body.count,
monthlyStatId: body.monthlyStatId,
},
});
return {
success: true,
message: "Data response berhasil diperbarui",
data: updated,
};
} catch (error) {
console.error("Gagal update Response Stat:", error);
return {
success: false,
message: "Gagal memperbarui data response stat",
};
}
};
export default responseStatUpdate;

View File

@@ -0,0 +1,42 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
const surveyCreate = async (context: Context) => {
const body = await context.body as {
title: string;
totalRespondents: number;
averageScore: number;
};
// Validasi
if (!body.title || !body.totalRespondents || body.averageScore === undefined) {
return {
success: false,
message: "Field title, tahun, dan skor wajib diisi",
};
}
try {
const created = await prisma.survey.create({
data: {
title: body.title,
totalRespondents: body.totalRespondents,
averageScore: body.averageScore,
},
});
return {
success: true,
message: "Survey berhasil dibuat",
data: created,
};
} catch (error) {
console.error("Gagal create survey :", error);
return {
success: false,
message: "Terjadi kesalahan saat membuat survey ",
};
}
};
export default surveyCreate;

View File

@@ -0,0 +1,24 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const surveyDelete = async (context: Context) => {
const { id } = context.params as { id: string };
try {
await prisma.survey.delete({
where: { id },
});
return {
success: true,
message: "Survey berhasil dihapus",
};
} catch (error) {
console.error("Gagal hapus survey:", error);
return {
success: false,
message: "Gagal menghapus survey",
};
}
};
export default surveyDelete;

View File

@@ -0,0 +1,28 @@
import prisma from "@/lib/prisma";
export const surveyFindMany = async () => {
try {
const surveys = await prisma.survey.findMany({
include: {
monthlyStats: true,
},
orderBy: {
createdAt: "desc",
},
});
return {
success: true,
data: surveys,
};
} catch (error) {
console.error("Gagal ambil data survey:", error);
return {
success: false,
message: "Terjadi kesalahan saat mengambil data survey",
};
}
};
export default surveyFindMany;

View File

@@ -0,0 +1,34 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
export const surveyFindUnique = async (context: Context) => {
const { id } = context.params as { id: string };
try {
const survey = await prisma.survey.findUnique({
where: { id },
include: {
monthlyStats: true,
},
});
if (!survey) {
return {
success: false,
message: "Survey tidak ditemukan",
};
}
return {
success: true,
data: survey,
};
} catch (error) {
console.error("Gagal ambil data survey:", error);
return {
success: false,
message: "Terjadi kesalahan saat mengambil data survey",
};
}
};
export default surveyFindUnique;

View File

@@ -0,0 +1,30 @@
import Elysia, { t } from "elysia";
import surveyCreate from "./create";
import surveyUpdate from "./updt";
import surveyFindMany from "./findMany";
import surveyFindUnique from "./findUnique";
import surveyDelete from "./del";
const survey = new Elysia({
prefix: "/survey",
tags: ["Landing Page/Indeks Kepuasan Masyarakat/Survey "],
})
.post("/create", surveyCreate, {
body: t.Object({
title: t.String(),
totalRespondents: t.Number(),
averageScore: t.Number(),
}),
})
.get("/findMany", surveyFindMany)
.get("/:id", surveyFindUnique)
.put("/:id", surveyUpdate, {
body: t.Object({
title: t.String(),
totalRespondents: t.Number(),
averageScore: t.Number(),
}),
})
.delete("/del/:id", surveyDelete);
export default survey;

View File

@@ -0,0 +1,49 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
type FormUpdateSurvey = {
title?: string;
tahun?: number;
totalRespondents?: number;
averageScore?: number;
};
const surveyUpdate = async (context: Context) => {
const id = context.params?.id as string;
const body = await context.body as FormUpdateSurvey;
if (!id) {
return {
success: false,
message: "ID survey wajib diisi",
};
}
try {
const updated = await prisma.survey.update({
where: { id },
data: {
title: body.title,
totalRespondents: body.totalRespondents,
averageScore: body.averageScore,
},
include: {
monthlyStats: true,
},
});
return {
success: true,
message: "Berhasil update survey ",
data: updated,
};
} catch (error) {
console.error("Gagal update survey :", error);
return {
success: false,
message: "Gagal update survey ",
};
}
};
export default surveyUpdate;

View File

@@ -8,6 +8,7 @@ import SDGSDesa from "./sdgs-desa";
import APBDes from "./apbdes";
import PrestasiDesa from "./prestasi-desa";
import KategoriPrestasi from "./prestasi-desa/kategori-prestasi";
import IndeksKepuasanMasyarakat from "./indeks-kepuasan-masyarakat";
const LandingPage = new Elysia({
prefix: "/api/landingpage",
@@ -23,5 +24,6 @@ const LandingPage = new Elysia({
.use(APBDes)
.use(PrestasiDesa)
.use(KategoriPrestasi)
.use(IndeksKepuasanMasyarakat)
export default LandingPage