Merge pull request 'fix/admin/menu-desa/berita' (#69) from fix/admin/menu-desa/berita into staggingweb

Reviewed-on: #69
This commit is contained in:
2026-02-25 16:27:35 +08:00
254 changed files with 8153 additions and 685 deletions

View File

@@ -2,15 +2,50 @@ import prisma from "@/lib/prisma";
import { Context } from "elysia";
export default async function kategoriBeritaDelete(context: Context) {
const id = context.params.id as string;
try {
const id = context.params?.id as string;
await prisma.kategoriBerita.delete({
where: { id },
});
if (!id) {
return Response.json({
success: false,
message: "ID tidak boleh kosong",
}, { status: 400 });
}
return {
status: 200,
success: true,
message: "Sukses Menghapus kategori berita",
};
// ✅ Cek apakah kategori masih digunakan oleh berita
const beritaCount = await prisma.berita.count({
where: {
kategoriBeritaId: id,
isActive: true,
deletedAt: null,
},
});
if (beritaCount > 0) {
return Response.json({
success: false,
message: `Kategori tidak dapat dihapus karena masih digunakan oleh ${beritaCount} berita`,
}, { status: 400 });
}
// ✅ Soft delete (bukan hard delete)
await prisma.kategoriBerita.update({
where: { id },
data: {
deletedAt: new Date(),
isActive: false,
},
});
return {
success: true,
message: "Kategori berita berhasil dihapus",
};
} catch (error) {
console.error("Delete kategori error:", error);
return Response.json({
success: false,
message: "Gagal menghapus kategori: " + (error instanceof Error ? error.message : 'Unknown error'),
}, { status: 500 });
}
}

View File

@@ -21,8 +21,13 @@ export default async function findUnique(
}, { status: 400 });
}
const data = await prisma.potensiDesa.findUnique({
where: { id },
// ✅ Filter by isActive and deletedAt
const data = await prisma.potensiDesa.findFirst({
where: {
id,
isActive: true,
deletedAt: null,
},
include: {
image: true,
kategori: true
@@ -48,5 +53,5 @@ export default async function findUnique(
message: "Gagal mengambil potensi desa: " + (error instanceof Error ? error.message : 'Unknown error'),
}, { status: 500 });
}
}

View File

@@ -2,15 +2,50 @@ import prisma from "@/lib/prisma";
import { Context } from "elysia";
export default async function kategoriPotensiDelete(context: Context) {
const id = context.params.id as string;
try {
const id = context.params?.id as string;
await prisma.kategoriPotensi.delete({
where: { id },
});
if (!id) {
return Response.json({
success: false,
message: "ID tidak boleh kosong",
}, { status: 400 });
}
return {
status: 200,
success: true,
message: "Sukses Menghapus kategori potensi",
};
// ✅ Cek apakah kategori masih digunakan oleh potensi desa
const existingPotensi = await prisma.potensiDesa.findFirst({
where: {
kategoriId: id,
isActive: true,
deletedAt: null,
},
});
if (existingPotensi) {
return Response.json({
success: false,
message: "Kategori masih digunakan oleh potensi desa. Tidak dapat dihapus.",
}, { status: 400 });
}
// Soft delete
await prisma.kategoriPotensi.update({
where: { id },
data: {
deletedAt: new Date(),
isActive: false,
},
});
return {
success: true,
message: "Kategori potensi berhasil dihapus",
};
} catch (error) {
console.error("Delete kategori error:", error);
return Response.json({
success: false,
message: "Gagal menghapus kategori: " + (error instanceof Error ? error.message : 'Unknown error'),
}, { status: 500 });
}
}

View File

@@ -0,0 +1,40 @@
import prisma from "@/lib/prisma";
import { requireAuth } from "@/lib/api-auth";
export default async function sejarahDesaFindFirst(request: Request) {
// ✅ Authentication check
const headers = new Headers(request.url);
const authResult = await requireAuth({ headers });
if (!authResult.authenticated) {
return authResult.response;
}
try {
// Get the first active record
const data = await prisma.sejarahDesa.findFirst({
where: {
isActive: true,
deletedAt: null
},
orderBy: { createdAt: 'asc' } // Get the oldest one first
});
if (!data) {
return Response.json({
success: false,
message: "Data tidak ditemukan",
}, {status: 404})
}
return Response.json({
success: true,
data,
}, {status: 200})
} catch (error) {
console.error("Gagal mengambil data sejarah desa:", error)
return Response.json({
success: false,
message: "Terjadi kesalahan saat mengambil data",
}, {status: 500})
}
}

View File

@@ -1,11 +1,16 @@
import Elysia, { t } from "elysia";
import sejarahDesaFindById from "./find-by-id";
import sejarahDesaUpdate from "./update";
import sejarahDesaFindFirst from "./find-first";
const SejarahDesa = new Elysia({
prefix: "/sejarah",
tags: ["Desa/Profile"],
})
.get("/first", async (context) => {
const response = await sejarahDesaFindFirst(new Request(context.request));
return response;
})
.get("/:id", async (context) => {
const response = await sejarahDesaFindById(new Request(context.request));
return response;

View File

@@ -1,7 +1,14 @@
import prisma from "@/lib/prisma";
import { requireAuth } from "@/lib/api-auth";
import { Context } from "elysia";
export default async function sejarahDesaUpdate(context: Context) {
// ✅ Authentication check
const authResult = await requireAuth(context);
if (!authResult.authenticated) {
return authResult.response;
}
try {
const id = context.params?.id as string;
const body = await context.body as {

View File

@@ -35,35 +35,35 @@ export async function POST(req: Request) {
// ✅ PERBAIKAN: Gunakan format pesan yang lebih sederhana
// Hapus karakter khusus yang bisa bikin masalah
const waMessage = `Website Desa Darmasaba\nKode verifikasi Anda ${codeOtp}`;
// const waMessage = `Website Desa Darmasaba\nKode verifikasi Anda ${codeOtp}`;
// // ✅ OPSI 1: Tanpa encoding (coba dulu ini)
// const waUrl = `https://wa.wibudev.com/code?nom=${nomor}&text=${waMessage}`;
// ✅ OPSI 2: Dengan encoding (kalau opsi 1 gagal)
const waUrl = `https://wa.wibudev.com/code?nom=${nomor}&text=${encodeURIComponent(waMessage)}`;
// const waUrl = `https://wa.wibudev.com/code?nom=${nomor}&text=${encodeURIComponent(waMessage)}`;
// ✅ OPSI 3: Encoding manual untuk URL-safe (alternatif terakhir)
// const encodedMessage = waMessage.replace(/\n/g, '%0A').replace(/ /g, '%20');
// const waUrl = `https://wa.wibudev.com/code?nom=${nomor}&text=${encodedMessage}`;
console.log("🔍 Debug WA URL:", waUrl); // Untuk debugging
// console.log("🔍 Debug WA URL:", waUrl); // Untuk debugging
const res = await fetch(waUrl);
const sendWa = await res.json();
// const res = await fetch(waUrl);
// const sendWa = await res.json();
console.log("📱 WA Response:", sendWa); // Debug response
// console.log("📱 WA Response:", sendWa); // Debug response
if (sendWa.status !== "success") {
return NextResponse.json(
{
success: false,
message: "Gagal mengirim OTP via WhatsApp",
debug: sendWa // Tampilkan error detail
},
{ status: 400 }
);
}
// if (sendWa.status !== "success") {
// return NextResponse.json(
// {
// success: false,
// message: "Gagal mengirim OTP via WhatsApp",
// debug: sendWa // Tampilkan error detail
// },
// { status: 400 }
// );
// }
const createOtpId = await prisma.kodeOtp.create({
data: { nomor, otp: otpNumber, isActive: true },