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[]
KeamananLingkungan KeamananLingkungan[]
MenuTipsKeamanan MenuTipsKeamanan[]
Pelapor Pelapor[]
}
//========================================= MENU PPID ========================================= //
@@ -889,31 +893,138 @@ model KeamananLingkungan {
deletedAt DateTime @default(now())
isActive Boolean @default(true)
}
// ========================================= POLSEK TERDEKAT ========================================= //
model PolsekTerdekat {
id String @id @default(uuid())
nama String
jarakKeDesa String
alamat String
nomorTelepon String
jamOperasional String
embedMapUrl String
namaTempatMaps String
alamatMaps String
id String @id @default(uuid())
nama String
jarakKeDesa String
alamat String
nomorTelepon String
jamOperasional String
embedMapUrl String
namaTempatMaps String
alamatMaps String
linkPetunjukArah String
layananPolsek LayananPolsek @relation(fields: [layananPolsekId], references: [id])
layananPolsekId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
layananPolsek LayananPolsek @relation(fields: [layananPolsekId], references: [id])
layananPolsekId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
}
model LayananPolsek {
id String @id @default(uuid())
nama String // contoh: "Pelayanan SKCK", "Laporan Kriminal"
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
id String @id @default(uuid())
nama String // contoh: "Pelayanan SKCK", "Laporan Kriminal"
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
deletedAt DateTime @default(now())
isActive Boolean @default(true)
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 KeamananLingkungan from "./keamanan-lingkungan";
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"] })
.use(KeamananLingkungan)
.use(PolsekTerdekat)
.use(KontakDarurat)
.use(PencegahanKriminalitas)
.use(MenuTipsKeamanan)
.use(LaporanPublik)
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",
},
}
);
}
}