diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 041fac02..5a9168cd 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -633,25 +633,25 @@ model KategoriBerita {
// ========================================= POTENSI DESA ========================================= //
model PotensiDesa {
id String @id @default(cuid())
- name String
- deskripsi String
+ name String @unique @db.VarChar(255)
+ deskripsi String @db.Text
kategori KategoriPotensi? @relation(fields: [kategoriId], references: [id])
- kategoriId String?
+ kategoriId String @db.VarChar(36)
image FileStorage? @relation(fields: [imageId], references: [id])
imageId String?
content String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
- deletedAt DateTime @default(now())
+ deletedAt DateTime?
isActive Boolean @default(true)
}
model KategoriPotensi {
id String @id @default(cuid())
- nama String
+ nama String @unique @db.VarChar(100)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
- deletedAt DateTime @default(now())
+ deletedAt DateTime?
isActive Boolean @default(true)
PotensiDesa PotensiDesa[]
}
diff --git a/src/app/admin/(dashboard)/desa/potensi/list-potensi/[id]/page.tsx b/src/app/admin/(dashboard)/desa/potensi/list-potensi/[id]/page.tsx
index 3ae6dac8..35fe407a 100644
--- a/src/app/admin/(dashboard)/desa/potensi/list-potensi/[id]/page.tsx
+++ b/src/app/admin/(dashboard)/desa/potensi/list-potensi/[id]/page.tsx
@@ -8,6 +8,7 @@ import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
+import DOMPurify from 'dompurify';
export default function DetailPotensi() {
const router = useRouter();
@@ -77,7 +78,17 @@ export default function DetailPotensi() {
Deskripsi
-
+
@@ -102,7 +113,12 @@ export default function DetailPotensi() {
diff --git a/src/app/admin/(dashboard)/desa/potensi/list-potensi/page.tsx b/src/app/admin/(dashboard)/desa/potensi/list-potensi/page.tsx
index f2cb3d15..5ed853da 100644
--- a/src/app/admin/(dashboard)/desa/potensi/list-potensi/page.tsx
+++ b/src/app/admin/(dashboard)/desa/potensi/list-potensi/page.tsx
@@ -27,6 +27,7 @@ import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../../_com/header';
import potensiDesaState from '../../../_state/desa/potensi';
import { useDebouncedValue } from '@mantine/hooks';
+import DOMPurify from 'dompurify';
function Potensi() {
const [search, setSearch] = useState("");
@@ -137,7 +138,12 @@ function ListPotensi({ search }: { search: string }) {
fz="sm"
lh={1.5}
lineClamp={2}
- dangerouslySetInnerHTML={{ __html: item.deskripsi }}
+ dangerouslySetInnerHTML={{
+ __html: DOMPurify.sanitize(item.deskripsi, {
+ ALLOWED_TAGS: ['p', 'br', 'strong', 'em', 'u', 'ul', 'ol', 'li'],
+ ALLOWED_ATTR: []
+ })
+ }}
style={{ wordBreak: 'break-word' }}
/>
@@ -199,7 +205,12 @@ function ListPotensi({ search }: { search: string }) {
diff --git a/src/app/api/[[...slugs]]/_lib/desa/potensi/find-unique.ts b/src/app/api/[[...slugs]]/_lib/desa/potensi/find-unique.ts
index a17eda6a..dc431265 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/potensi/find-unique.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/potensi/find-unique.ts
@@ -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 });
}
-
+
}
\ No newline at end of file
diff --git a/src/app/api/[[...slugs]]/_lib/desa/potensi/kategori-potensi/del.ts b/src/app/api/[[...slugs]]/_lib/desa/potensi/kategori-potensi/del.ts
index d91cef98..356d73f0 100644
--- a/src/app/api/[[...slugs]]/_lib/desa/potensi/kategori-potensi/del.ts
+++ b/src/app/api/[[...slugs]]/_lib/desa/potensi/kategori-potensi/del.ts
@@ -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 });
+ }
}
\ No newline at end of file