API Admin Menu Keamanan Done

This commit is contained in:
2025-06-30 10:56:46 +08:00
parent 02462b2c19
commit ee10f339e9
26 changed files with 1270 additions and 21 deletions

View File

@@ -78,6 +78,10 @@ model FileStorage {
InfoWabahPenyakit InfoWabahPenyakit[] InfoWabahPenyakit InfoWabahPenyakit[]
KeamananLingkungan KeamananLingkungan[] KeamananLingkungan KeamananLingkungan[]
MenuTipsKeamanan MenuTipsKeamanan[]
Pelapor Pelapor[]
} }
//========================================= MENU PPID ========================================= // //========================================= MENU PPID ========================================= //
@@ -889,31 +893,138 @@ model KeamananLingkungan {
deletedAt DateTime @default(now()) deletedAt DateTime @default(now())
isActive Boolean @default(true) isActive Boolean @default(true)
} }
// ========================================= POLSEK TERDEKAT ========================================= // // ========================================= POLSEK TERDEKAT ========================================= //
model PolsekTerdekat { model PolsekTerdekat {
id String @id @default(uuid()) id String @id @default(uuid())
nama String nama String
jarakKeDesa String jarakKeDesa String
alamat String alamat String
nomorTelepon String nomorTelepon String
jamOperasional String jamOperasional String
embedMapUrl String embedMapUrl String
namaTempatMaps String namaTempatMaps String
alamatMaps String alamatMaps String
linkPetunjukArah String linkPetunjukArah String
layananPolsek LayananPolsek @relation(fields: [layananPolsekId], references: [id]) layananPolsek LayananPolsek @relation(fields: [layananPolsekId], references: [id])
layananPolsekId String layananPolsekId String
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
deletedAt DateTime @default(now()) deletedAt DateTime @default(now())
isActive Boolean @default(true) isActive Boolean @default(true)
} }
model LayananPolsek { model LayananPolsek {
id String @id @default(uuid()) id String @id @default(uuid())
nama String // contoh: "Pelayanan SKCK", "Laporan Kriminal" nama String // contoh: "Pelayanan SKCK", "Laporan Kriminal"
createdAt DateTime @default(now()) createdAt DateTime @default(now())
updatedAt DateTime @updatedAt updatedAt DateTime @updatedAt
deletedAt DateTime @default(now()) deletedAt DateTime @default(now())
isActive Boolean @default(true) isActive Boolean @default(true)
PolsekTerdekat PolsekTerdekat[] PolsekTerdekat PolsekTerdekat[]
} }
// ========================================= KONTAK DARURAT ========================================= //
model KontakDaruratKeamanan {
id String @id @default(cuid())
nama String // contoh: "Polisi", "Ambulans", "Pemadam Kebakaran"
kontak String // contoh: "081xxxxxxxxxx"
icon String? // opsional, untuk simpan nama icon-nya jika mau
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
}
// ========================================= PENCEGAHAN KRIMINALITAS ========================================= //
model PencegahanKriminalitas {
id String @id @default(cuid())
programKeamanan ProgramKeamanan @relation(fields: [programKeamananId], references: [id])
programKeamananId String
tipsKeamanan TipsKeamanan @relation(fields: [tipsKeamananId], references: [id])
tipsKeamananId String
videoKeamanan VideoKeamanan @relation(fields: [videoKeamananId], references: [id])
videoKeamananId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
}
model ProgramKeamanan {
id String @id @default(cuid())
nama String // contoh: "Ronda Malam"
deskripsi String? // jika mau tambahkan info detail
slug String @unique
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
PencegahanKriminalitas PencegahanKriminalitas[]
}
model TipsKeamanan {
id String @id @default(cuid())
judul String
konten String
slug String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
PencegahanKriminalitas PencegahanKriminalitas[]
}
model VideoKeamanan {
id String @id @default(cuid())
judul String
deskripsi String?
videoUrl String // link youtube atau embed url
slug String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
PencegahanKriminalitas PencegahanKriminalitas[]
}
// ========================================= LAPORAN PUBLIK ========================================= //
model LaporanPublik {
id String @id @default(cuid())
judul String
lokasi String
tanggalWaktu DateTime
status StatusLaporan
penanganan PenangananLaporanPublik[]
kronologi String? // Optional, bisa diisi detail kronologi
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model PenangananLaporanPublik {
id String @id @default(cuid())
laporanId String
deskripsi String
laporan LaporanPublik @relation(fields: [laporanId], references: [id], onDelete: Cascade)
}
enum StatusLaporan {
SELESAI
PROSES
GAGAL
}
model Pelapor {
id String @id @default(cuid())
nama String
alamat String
nomorTelepon String
image FileStorage @relation(fields: [imageId], references: [id])
imageId String
}
// ========================================= TIPS KEAMANAN ========================================= //
model MenuTipsKeamanan {
id String @id @default(cuid())
judul String
deskripsi String
image FileStorage? @relation(fields: [imageId], references: [id])
imageId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
}

View File

@@ -1,8 +1,16 @@
import Elysia from "elysia"; import Elysia from "elysia";
import KeamananLingkungan from "./keamanan-lingkungan"; import KeamananLingkungan from "./keamanan-lingkungan";
import PolsekTerdekat from "./polsek-terdekat"; import PolsekTerdekat from "./polsek-terdekat";
import KontakDarurat from "./kontak-darurat";
import PencegahanKriminalitas from "./pencegahan-kriminalitas";
import MenuTipsKeamanan from "./tips-keamanan";
import LaporanPublik from "./laporan-publik";
const Keamanan = new Elysia({ prefix: "/api/keamanan", tags: ["Keamanan"] }) const Keamanan = new Elysia({ prefix: "/api/keamanan", tags: ["Keamanan"] })
.use(KeamananLingkungan) .use(KeamananLingkungan)
.use(PolsekTerdekat) .use(PolsekTerdekat)
.use(KontakDarurat)
.use(PencegahanKriminalitas)
.use(MenuTipsKeamanan)
.use(LaporanPublik)
export default Keamanan; export default Keamanan;

View File

@@ -0,0 +1,29 @@
import prisma from "@/lib/prisma";
import { Prisma } from "@prisma/client";
import { Context } from "elysia";
type FormCreate = Prisma.KontakDaruratKeamananGetPayload<{
select: {
nama: true,
kontak: true,
icon: true,
}
}>
export default async function kontakDaruratKeamananCreate(context: Context){
const body = context.body as FormCreate
await prisma.kontakDaruratKeamanan.create({
data: {
nama: body.nama,
kontak: body.kontak,
icon: body.icon,
}
})
return {
success: true,
message: "Success create kontak darurat keamanan",
data: {
...body,
},
}
}

View File

@@ -0,0 +1,33 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
export default async function kontakDaruratKeamananDelete(context: Context){
const id = context.params?.id as string;
if (!id) {
return {
status: 400,
body: "ID tidak diberikan",
};
}
const kontakDaruratKeamanan = await prisma.kontakDaruratKeamanan.findUnique({
where: { id },
});
if (!kontakDaruratKeamanan) {
return {
status: 404,
body: "Kontak darurat keamanan tidak ditemukan",
};
}
await prisma.kontakDaruratKeamanan.delete({
where: { id },
});
return {
status: 200,
body: "Kontak darurat keamanan berhasil dihapus",
};
}

View File

@@ -0,0 +1,21 @@
import prisma from "@/lib/prisma";
export default async function kontakDaruratKeamananFindMany() {
try {
const data = await prisma.kontakDaruratKeamanan.findMany({
where: { isActive: true },
});
return {
success: true,
message: "Success fetch kontak darurat keamanan",
data,
};
} catch (e) {
console.error("Find many error:", e);
return {
success: false,
message: "Failed fetch kontak darurat keamanan",
};
}
}

View File

@@ -0,0 +1,46 @@
import prisma from "@/lib/prisma";
export default async function kontakDaruratKeamananFindUnique(request: Request){
const url = new URL(request.url);
const pathSegments = url.pathname.split('/');
const id = pathSegments[pathSegments.length - 1];
if(!id){
return Response.json({
success: false,
message: "ID tidak boleh kosong",
}, { status: 400 });
}
try {
if (typeof id !== 'string') {
return Response.json({
success: false,
message: "ID tidak valid",
}, { status: 400 });
}
const data = await prisma.kontakDaruratKeamanan.findUnique({
where: { id },
});
if (!data) {
return Response.json({
success: false,
message: "Kontak darurat keamanan tidak ditemukan",
}, { status: 404 });
}
return Response.json({
success: true,
message: "Success fetch kontak darurat keamanan by ID",
data,
}, { status: 200 });
} catch (error) {
console.error("Find by ID error:", error);
return Response.json({
success: false,
message: "Gagal mengambil kontak darurat keamanan: " + (error instanceof Error ? error.message : 'Unknown error'),
}, { status: 500 });
}
}

View File

@@ -0,0 +1,32 @@
import Elysia, { t } from "elysia";
import kontakDaruratKeamananFindMany from "./findMany";
import kontakDaruratKeamananFindUnique from "./findUnique";
import kontakDaruratKeamananCreate from "./create";
import kontakDaruratKeamananDelete from "./del";
const kontakDaruratKeamanan = new Elysia({ prefix: "/kontak-darurat", tags: ["Keamanan/Kontak Darurat"] })
.get("/find-many", kontakDaruratKeamananFindMany)
.get("/:id", async (context) => {
const response = await kontakDaruratKeamananFindUnique(new Request(context.request));
return response;
})
.post("/create", kontakDaruratKeamananCreate, {
body: t.Object({
nama: t.String(),
kontak: t.String(),
icon: t.String(),
}),
})
.delete("/del/:id", kontakDaruratKeamananDelete)
.put("/:id", async (context) => {
const response = await kontakDaruratKeamananCreate(context);
return response;
},
{
body: t.Object({
nama: t.String(),
kontak: t.String(),
icon: t.String(),
}),
})
export default kontakDaruratKeamanan;

View File

@@ -0,0 +1,61 @@
import prisma from "@/lib/prisma";
import { Prisma } from "@prisma/client";
import { Context } from "elysia";
type FormUpdate = Prisma.KontakDaruratKeamananGetPayload<{
select: {
nama: true;
kontak: true;
icon: true;
}
}>
export default async function kontakDaruratUpdate(context: Context){
try {
const id = context.params?.id;
const body = (await context.body) as Omit<FormUpdate, "id">;
const {nama, kontak, icon} = body;
if(!id){
return Response.json({
success: false,
message: "ID tidak diberikan",
}, { status: 400 });
}
const existing = await prisma.kontakDaruratKeamanan.findUnique({
where: { id },
});
if (!existing) {
return Response.json({
success: false,
message: "Kontak darurat keamanan tidak ditemukan",
}, { status: 404 });
}
const updated = await prisma.kontakDaruratKeamanan.update({
where: { id },
data: {
nama,
kontak,
icon,
},
});
return Response.json({
success: true,
message: "Success update kontak darurat keamanan",
data: updated,
}, { status: 200 });
} catch (error) {
console.error("Error updating kontak darurat keamanan:", error);
return Response.json({
success: false,
message: "Terjadi kesalahan saat mengupdate kontak darurat keamanan",
}, { status: 500 ,
headers: {
"Content-Type": "application/json",
},
});
}
}

View File

@@ -0,0 +1,40 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
type LaporanPublikInput = {
judul: string;
lokasi: string;
tanggalWaktu: string;
status: "SELESAI" | "PROSES" | "GAGAL";
penanganan: string[];
kronologi?: string;
};
const laporanPublikCreate = async (context: Context) => {
const { judul, lokasi, tanggalWaktu, status, penanganan, kronologi } =
(await context.body) as LaporanPublikInput;
const createdLaporanPublik = await prisma.laporanPublik.create({
data: {
judul,
lokasi,
tanggalWaktu: new Date(tanggalWaktu),
status,
penanganan: {
create: penanganan.map((item) => ({
deskripsi: item,
})),
},
kronologi,
},
include: {
penanganan: true,
}
})
return {
success: true,
data: createdLaporanPublik,
};
};
export default laporanPublikCreate;

View File

@@ -0,0 +1,38 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
const laporanPublikDelete = async (context: Context) => {
const id = context.params.id as string;
try {
// Cek dulu apakah data ada
const laporan = await prisma.laporanPublik.findUnique({
where: { id }
});
if (!laporan) {
return {
success: false,
message: "Laporan tidak ditemukan"
};
}
// Hapus data
await prisma.laporanPublik.delete({
where: { id }
});
return {
success: true,
message: "Laporan berhasil dihapus"
};
} catch (error) {
console.error("Gagal delete laporan:", error);
return {
success: false,
message: "Terjadi kesalahan saat menghapus laporan"
};
}
};
export default laporanPublikDelete;

View File

@@ -0,0 +1,20 @@
import prisma from "@/lib/prisma"
const laporanPublikFindMany = async () => {
const laporanPublik = await prisma.laporanPublik.findMany({
include: {
penanganan: true
},
orderBy: {
tanggalWaktu: 'desc'
}
})
return {
success: true,
data: laporanPublik,
}
}
export default laporanPublikFindMany;

View File

@@ -0,0 +1,26 @@
import { Context } from "elysia";
import prisma from "@/lib/prisma";
const laporanPublikFindUnique = async (context: Context) => {
const id = context.params.id as string;
const laporanPublik = await prisma.laporanPublik.findUnique({
where: {
id,
},
include: {
penanganan: true,
},
})
if (!laporanPublik) {
return {
success: false,
message: "Laporan publik tidak ditemukan",
}
}
return {
success: true,
data: laporanPublik,
}
}
export default laporanPublikFindUnique;

View File

@@ -0,0 +1,43 @@
import Elysia, { t } from "elysia";
import laporanPublikCreate from "./create";
import laporanPublikFindMany from "./findMany";
import laporanPublikFindUnique from "./findUnique";
import laporanPublikUpdate from "./updt";
import laporanPublikDelete from "./del";
const LaporanPublik = new Elysia({
prefix: "laporanpublik",
tags: ["Keamanan/Laporan Publik"],
})
.post("/create", laporanPublikCreate, {
body: t.Object({
judul: t.String(),
lokasi: t.String(),
tanggalWaktu: t.String(), // ISO string
status: t.Union([
t.Literal("SELESAI"),
t.Literal("PROSES"),
t.Literal("GAGAL"),
]),
penanganan: t.Array(t.String()), // 🛠️ ARRAY of strings
kronologi: t.Optional(t.String()),
}),
})
.get("/find-many", laporanPublikFindMany)
.get("/:id", laporanPublikFindUnique)
.put("/:id", laporanPublikUpdate, {
body: t.Object({
judul: t.String(),
lokasi: t.String(),
tanggalWaktu: t.String(), // ISO string
status: t.Union([
t.Literal("SELESAI"),
t.Literal("PROSES"),
t.Literal("GAGAL"),
]),
penanganan: t.Array(t.String()), // 🛠️ ARRAY of strings
kronologi: t.Optional(t.String()),
}),
})
.delete("/del/:id", laporanPublikDelete);
export default LaporanPublik;

View File

@@ -0,0 +1,50 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
type LaporanPublikUpdateInput = {
judul: string;
lokasi: string;
tanggalWaktu: string;
status: "SELESAI" | "PROSES" | "GAGAL";
penanganan: string[];
kronologi?: string;
};
const LaporanPublikUpdate = async (context: Context) => {
const id = context.params.id as string;
const { judul, lokasi, tanggalWaktu, status, penanganan, kronologi } =
(await context.body) as LaporanPublikUpdateInput;
await prisma.penangananLaporanPublik.deleteMany({
where: {
laporanId: id,
},
});
const updated = await prisma.laporanPublik.update({
where: {
id,
},
data: {
judul,
lokasi,
tanggalWaktu: new Date(tanggalWaktu),
status,
kronologi,
penanganan: {
create: penanganan.map((item) => ({
deskripsi: item,
})),
},
},
include: {
penanganan: true,
},
});
return {
success: true,
data: updated,
};
};
export default LaporanPublikUpdate;

View File

@@ -0,0 +1,81 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
type ProgramKeamananInput = {
nama: string;
deskripsi: string;
slug: string;
};
type TipsKeamanan = {
judul: string;
konten: string;
slug: string;
};
type VideoKeamanan = {
judul: string;
deskripsi: string;
videoUrl: string;
slug: string;
};
type createdPencegahanKriminalitas = {
programKeamanan: ProgramKeamananInput;
tipsKeamanan: TipsKeamanan;
videoKeamanan: VideoKeamanan;
};
const pencegahanKriminalitasCreate = async (context: Context) => {
const { programKeamanan, tipsKeamanan, videoKeamanan } =
(await context.body) as createdPencegahanKriminalitas;
const createdProgram = await prisma.programKeamanan.create({
data: {
nama: programKeamanan.nama,
deskripsi: programKeamanan.deskripsi,
slug: programKeamanan.slug,
},
});
const createdTips = await prisma.tipsKeamanan.create({
data: {
judul: tipsKeamanan.judul,
konten: tipsKeamanan.konten,
slug: tipsKeamanan.slug,
},
});
const createdVideo = await prisma.videoKeamanan.create({
data: {
judul: videoKeamanan.judul,
deskripsi: videoKeamanan.deskripsi,
videoUrl: videoKeamanan.videoUrl,
slug: videoKeamanan.slug,
},
});
const createdPencegahanKriminalitas =
await prisma.pencegahanKriminalitas.create({
data: {
programKeamananId: createdProgram.id,
tipsKeamananId: createdTips.id,
videoKeamananId: createdVideo.id,
},
include: {
programKeamanan: true,
tipsKeamanan: true,
videoKeamanan: true,
},
});
return Response.json(
{
success: true,
message: "Success create program keamanan",
data: createdPencegahanKriminalitas,
},
{ status: 200 }
);
};
export default pencegahanKriminalitasCreate;

View File

@@ -0,0 +1,39 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
const pencegahanKriminalitasDelete = async (context: Context) => {
const id = context.params?.id as string;
if (!id) {
return {
status: 400,
body: "ID tidak diberikan",
};
}
const pencegahanKriminalitas = await prisma.pencegahanKriminalitas.findUnique({
where: { id },
include: {
programKeamanan: true,
tipsKeamanan: true,
videoKeamanan: true,
}
});
if (!pencegahanKriminalitas) {
return {
status: 404,
body: "Pencegahan kriminalitas tidak ditemukan",
};
}
await prisma.pencegahanKriminalitas.delete({
where: { id },
});
return {
status: 200,
body: "Pencegahan kriminalitas berhasil dihapus",
};
};
export default pencegahanKriminalitasDelete;

View File

@@ -0,0 +1,27 @@
import prisma from "@/lib/prisma";
export default async function pencegahanKriminalitasFindMany() {
try {
const data = await prisma.pencegahanKriminalitas.findMany({
where: {
isActive: true,
},
include: {
programKeamanan: true,
tipsKeamanan: true,
videoKeamanan: true,
}
})
return {
success: true,
message: "Success fetch pencegahan kriminalitas",
data,
}
} catch (error) {
console.error("Find many error:", error);
return {
success: false,
message: "Failed fetch pencegahan kriminalitas",
}
}
}

View File

@@ -0,0 +1,51 @@
import prisma from "@/lib/prisma";
export default async function pencegahanKriminalitasFindUnique(request: Request) {
const url = new URL(request.url);
const pathSegments = url.pathname.split('/');
const id = pathSegments[pathSegments.length - 1];
if (!id) {
return Response.json({
success: false,
message: "ID tidak boleh kosong",
}, { status: 400 })
}
try {
if (typeof id !== 'string') {
return Response.json({
success: false,
message: "ID tidak valid",
}, { status: 400 })
}
const data = await prisma.pencegahanKriminalitas.findUnique({
where: {id},
include: {
programKeamanan: true,
tipsKeamanan: true,
videoKeamanan: true,
}
})
if (!data) {
return Response.json({
success: false,
message: "Data tidak ditemukan",
}, { status: 404 })
}
return Response.json({
success: true,
message: "Success fetch data",
data,
}, { status: 200 })
} catch (error) {
console.error("Find unique error:", error);
return Response.json({
success: false,
message: "Failed fetch data",
}, { status: 500 })
}
}

View File

@@ -0,0 +1,67 @@
import Elysia, { t } from "elysia";
import pencegahanKriminalitasCreate from "./create";
import pencegahanKriminalitasFindUnique from "./findUnique";
import pencegahanKriminalitasFindMany from "./findMany";
import pencegahanKriminalitasDelete from "./del";
import pencegahanKriminalitasUpdate from "./updt";
const PencegahanKriminalitas = new Elysia({
prefix: "pencegahankriminalitas",
tags: ["Keamanan/Pencegahan Kriminalitas"],
})
.post("/create", pencegahanKriminalitasCreate, {
body: t.Object({
programKeamanan: t.Object({
nama: t.String(),
deskripsi: t.String(),
slug: t.String(),
}),
tipsKeamanan: t.Object({
judul: t.String(),
konten: t.String(),
slug: t.String(),
}),
videoKeamanan: t.Object({
judul: t.String(),
deskripsi: t.String(),
videoUrl: t.String(),
slug: t.String(),
}),
}),
})
.get("/find-many", pencegahanKriminalitasFindMany)
.get("/:id", async (context) => {
const response = await pencegahanKriminalitasFindUnique(
new Request(context.request)
);
return response;
})
.delete("/del/:id", pencegahanKriminalitasDelete)
.put(
":/id",
async (context) => {
const response = await pencegahanKriminalitasUpdate(context);
return response;
},
{
body: t.Object({
programKeamanan: t.Object({
nama: t.String(),
deskripsi: t.String(),
slug: t.String(),
}),
tipsKeamanan: t.Object({
judul: t.String(),
konten: t.String(),
slug: t.String(),
}),
videoKeamanan: t.Object({
judul: t.String(),
deskripsi: t.String(),
videoUrl: t.String(),
slug: t.String(),
}),
}),
}
);
export default PencegahanKriminalitas;

View File

@@ -0,0 +1,112 @@
import prisma from "@/lib/prisma";
import { Prisma } from "@prisma/client";
import { Context } from "elysia";
type FormUpdate = Prisma.PencegahanKriminalitasGetPayload<{
select: {
id: true;
programKeamanan: true;
tipsKeamanan: true;
videoKeamanan: true;
}
}>
export default async function pencegahanKriminalitasUpdate(context: Context) {
try {
const id = context.params?.id as string;
const body = (await context.body) as Omit<FormUpdate, "id">;
const {programKeamanan, tipsKeamanan, videoKeamanan} = body;
if (!id) {
return new Response(JSON.stringify({
success: false,
message: "ID tidak diberikan",
}), {
status: 400,
headers: {
"Content-Type": "application/json",
},
});
}
const existing = await prisma.pencegahanKriminalitas.findUnique({
where: { id },
include: {
programKeamanan: true,
tipsKeamanan: true,
videoKeamanan: true,
}
});
if (!existing) {
return new Response(JSON.stringify({
success: false,
message: "Pencegahan kriminalitas tidak ditemukan",
}), {
status: 404,
headers: {
"Content-Type": "application/json",
},
});
}
await prisma.programKeamanan.update({
where: {id: existing.programKeamananId},
data: {
nama: programKeamanan.nama,
deskripsi: programKeamanan.deskripsi,
slug: programKeamanan.slug,
}
});
await prisma.tipsKeamanan.update({
where: {id: existing.tipsKeamananId},
data: {
judul: tipsKeamanan.judul,
konten: tipsKeamanan.konten,
slug: tipsKeamanan.slug,
}
});
await prisma.videoKeamanan.update({
where: {id: existing.videoKeamananId},
data: {
judul: videoKeamanan.judul,
deskripsi: videoKeamanan.deskripsi,
videoUrl: videoKeamanan.videoUrl,
slug: videoKeamanan.slug,
}
});
const updated = await prisma.pencegahanKriminalitas.update({
where: { id },
data: {
programKeamananId: programKeamanan.id,
tipsKeamananId: tipsKeamanan.id,
videoKeamananId: videoKeamanan.id,
}
});
return new Response(JSON.stringify({
success: true,
message: "Success update pencegahan kriminalitas",
data: updated,
}), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});
} catch (error) {
console.error("Update error:", error);
return new Response(JSON.stringify({
success: false,
message: "Failed update pencegahan kriminalitas",
}), {
status: 500,
headers: {
"Content-Type": "application/json",
},
});
}
}

View File

@@ -0,0 +1,29 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
type MenuTipsKeamananInput = {
judul: string;
deskripsi: string;
imageId: string;
};
const menuTipsKeamananCreate = async (context: Context) => {
const { judul, deskripsi, imageId } = await context.body as MenuTipsKeamananInput;
const createdMenuTipsKeamanan = await prisma.menuTipsKeamanan.create({
data: {
judul,
deskripsi,
imageId,
},
include: {
image: true,
},
});
return {
success: true,
data: createdMenuTipsKeamanan,
};
};
export default menuTipsKeamananCreate;

View File

@@ -0,0 +1,53 @@
import prisma from "@/lib/prisma";
import { Context } from "elysia";
import path from "path";
import fs from "fs/promises";
const menuTipsKeamananDelete = async (context: Context) => {
const id = context.params?.id as string;
if (!id) {
return {
status: 400,
body: "ID tidak diberikan",
};
}
const tipsKeamanan = await prisma.menuTipsKeamanan.findUnique({
where: { id },
include: {
image: true,
},
});
if (!tipsKeamanan) {
return {
status: 404,
body: "Tips keamanan tidak ditemukan",
};
}
// Hapus file gambar dari filesystem jika ada
if (tipsKeamanan.image) {
try {
const filePath = path.join(tipsKeamanan.image.path, tipsKeamanan.image.name);
await fs.unlink(filePath);
await prisma.fileStorage.delete({
where: { id: tipsKeamanan.image.id },
});
} catch (err) {
console.error("Gagal hapus gambar lama:", err);
}
}
// Hapus tips keamanan dari database
const deleted = await prisma.menuTipsKeamanan.delete({
where: { id },
});
return {
status: 200,
body: deleted,
};
};
export default menuTipsKeamananDelete;

View File

@@ -0,0 +1,24 @@
import prisma from "@/lib/prisma";
export default async function menuTipsKeamananFindMany() {
try {
const data = await prisma.menuTipsKeamanan.findMany({
where: { isActive: true },
include: {
image: true,
},
});
return {
success: true,
message: "Success fetch menu tips keamanan",
data,
};
} catch (e) {
console.error("Find many error:", e);
return {
success: false,
message: "Failed fetch menu tips keamanan",
};
}
}

View File

@@ -0,0 +1,49 @@
import prisma from "@/lib/prisma";
export default async function menuTipsKeamananFindUnique(request: Request) {
const url = new URL(request.url);
const pathSegments = url.pathname.split('/');
const id = pathSegments[pathSegments.length - 1];
if (!id){
return Response.json({
success: false,
message: "ID tidak boleh kosong",
}, { status: 400 });
}
try {
if (typeof id !== 'string') {
return Response.json({
success: false,
message: "ID harus string",
}, { status: 400 });
}
const data = await prisma.menuTipsKeamanan.findUnique({
where: { id },
include: {
image: true,
},
});
if (!data) {
return Response.json({
success: false,
message: "Menu tips keamanan tidak ditemukan",
}, { status: 404 });
}
return Response.json({
success: true,
message: "Success fetch menu tips keamanan by ID",
data,
}, { status: 200 });
} catch (error) {
console.error("Find by ID error:", error);
return Response.json({
success: false,
message: "Gagal mengambil menu tips keamanan: " + (error instanceof Error ? error.message : 'Unknown error'),
}, { status: 500 });
}
}

View File

@@ -0,0 +1,41 @@
import Elysia, { t } from "elysia";
import menuTipsKeamananFindMany from "./findMany";
import menuTipsKeamananFindUnique from "./findUnique";
import menuTipsKeamananCreate from "./create";
import menuTipsKeamananDelete from "./del";
import menuTipsKeamananUpdate from "./updt";
const MenuTipsKeamanan = new Elysia({
prefix: "/menutipskeamanan",
tags: ["Keamanan/Tips Keamanan"],
})
.get("/find-many", menuTipsKeamananFindMany)
.get("/:id", async (context) => {
const response = await menuTipsKeamananFindUnique(
new Request(context.request)
);
return response;
})
.post("/create", menuTipsKeamananCreate, {
body: t.Object({
name: t.String(),
deskripsi: t.String(),
imageId: t.String(),
}),
})
.delete("/del/:id", menuTipsKeamananDelete)
.put(
"/:id",
async (context) => {
const response = await menuTipsKeamananUpdate(context);
return response;
},
{
body: t.Object({
name: t.String(),
deskripsi: t.String(),
imageId: t.String(),
}),
}
);
export default MenuTipsKeamanan;

View File

@@ -0,0 +1,118 @@
import prisma from "@/lib/prisma";
import { Prisma } from "@prisma/client";
import path from "path";
import fs from "fs/promises";
import { Context } from "elysia";
type MenuTipsKeamananUpdate = Prisma.MenuTipsKeamananGetPayload<{
select: {
id: true;
judul: true;
deskripsi: true;
imageId: true;
};
}>;
export default async function menuTipsKeamananUpdate(context: Context) {
try {
const id = context.params?.id as string;
const body = (await context.body) as MenuTipsKeamananUpdate;
const { judul, deskripsi, imageId } = body;
if (!id) {
return new Response(
JSON.stringify({
success: false,
message: "ID tidak boleh kosong",
}),
{
status: 400,
headers: {
"Content-Type": "application/json",
},
}
);
}
const existing = await prisma.menuTipsKeamanan.findUnique({
where: { id },
include: {
image: true,
},
});
if (!existing) {
return new Response(
JSON.stringify({
success: false,
message: "Menu tips keamanan tidak ditemukan",
}),
{
status: 404,
headers: {
"Content-Type": "application/json",
},
}
);
}
if (existing.imageId && existing.imageId !== imageId) {
const oldImage = existing.image;
if (oldImage) {
try {
const filePath = path.join(oldImage.path, oldImage.name);
await fs.unlink(filePath);
await prisma.fileStorage.delete({
where: { id: oldImage.id },
});
} catch (err) {
console.error("Gagal hapus gambar lama:", err);
}
}
}
const updated = await prisma.menuTipsKeamanan.update({
where: { id },
data: {
judul,
deskripsi,
imageId,
},
include: {
image: true,
},
});
return new Response(
JSON.stringify({
success: true,
message: "Success update menu tips keamanan",
data: updated,
}),
{
status: 200,
headers: {
"Content-Type": "application/json",
},
}
);
} catch (error) {
console.error("Update error:", error);
return new Response(
JSON.stringify({
success: false,
message:
"Gagal update menu tips keamanan: " +
(error instanceof Error ? error.message : "Unknown error"),
}),
{
status: 500,
headers: {
"Content-Type": "application/json",
},
}
);
}
}