From 9f72e945572f332347757d6c86ef388c6b9efce1 Mon Sep 17 00:00:00 2001 From: nico Date: Wed, 17 Sep 2025 17:54:03 +0800 Subject: [PATCH] Fix Admin - User Menu Keamanan, Submenu Pencegahan Kriminalitas --- prisma/schema.prisma | 51 +-- .../keamanan/pencegahan-kriminalitas.ts | 143 +++------ .../keamanan/laporan-publik/[id]/page.tsx | 2 +- .../keamanan/laporan-publik/page.tsx | 4 +- .../[id]/edit/page.tsx | 301 +++++++++--------- .../pencegahan-kriminalitas/[id]/page.tsx | 211 +++++++----- .../pencegahan-kriminalitas/create/page.tsx | 225 +++++++------ .../keamanan/pencegahan-kriminalitas/page.tsx | 48 +-- .../pencegahan-kriminalitas/create.ts | 88 ++--- .../keamanan/pencegahan-kriminalitas/del.ts | 5 - .../pencegahan-kriminalitas/findFirst.ts | 60 ++++ .../pencegahan-kriminalitas/findMany.ts | 20 +- .../pencegahan-kriminalitas/findUnique.ts | 5 - .../keamanan/pencegahan-kriminalitas/index.ts | 44 +-- .../keamanan/pencegahan-kriminalitas/updt.ts | 183 +++++------ .../pencegahan-kriminalitas/[id]/page.tsx | 11 + .../keamanan/pencegahan-kriminalitas/page.tsx | 217 +++++++------ .../program-lainnya/page.tsx | 11 + 18 files changed, 782 insertions(+), 847 deletions(-) create mode 100644 src/app/api/[[...slugs]]/_lib/keamanan/pencegahan-kriminalitas/findFirst.ts create mode 100644 src/app/darmasaba/(pages)/keamanan/pencegahan-kriminalitas/[id]/page.tsx create mode 100644 src/app/darmasaba/(pages)/keamanan/pencegahan-kriminalitas/program-lainnya/page.tsx diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 67c9078d..97bdedff 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -1254,48 +1254,15 @@ model KontakDaruratToItem { // ========================================= 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[] + id String @id @default(cuid()) + judul String + deskripsi String + deskripsiSingkat String + linkVideo String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime @default(now()) + isActive Boolean @default(true) } // ========================================= LAPORAN PUBLIK ========================================= // diff --git a/src/app/admin/(dashboard)/_state/keamanan/pencegahan-kriminalitas.ts b/src/app/admin/(dashboard)/_state/keamanan/pencegahan-kriminalitas.ts index 46fbc669..8530d809 100644 --- a/src/app/admin/(dashboard)/_state/keamanan/pencegahan-kriminalitas.ts +++ b/src/app/admin/(dashboard)/_state/keamanan/pencegahan-kriminalitas.ts @@ -6,45 +6,17 @@ import { proxy } from "valtio"; import { z } from "zod"; const templateForm = z.object({ - pencegahanKriminalitas: z.object({ - programKeamanan: z.object({ - nama: z.string().min(1, "Nama minimal 1 karakter"), - deskripsi: z.string().min(1, "Deskripsi minimal 1 karakter"), - slug: z.string().min(1, "Slug minimal 1 karakter"), - }), - tipsKeamanan: z.object({ - judul: z.string().min(1, "Judul minimal 1 karakter"), - konten: z.string().min(1, "Konten minimal 1 karakter"), - slug: z.string().min(1, "Slug minimal 1 karakter"), - }), - videoKeamanan: z.object({ - judul: z.string().min(1, "Judul minimal 1 karakter"), - deskripsi: z.string().min(1, "Deskripsi minimal 1 karakter"), - videoUrl: z.string().min(1, "Video URL minimal 1 karakter"), - slug: z.string().min(1, "Slug minimal 1 karakter"), - }), - }), + judul: z.string().min(1, "Judul minimal 1 karakter"), + deskripsi: z.string().min(1, "Deskripsi minimal 1 karakter"), + deskripsiSingkat: z.string().min(1, "Deskripsi singkat minimal 1 karakter"), + linkVideo: z.string().min(1, "Link video minimal 1 karakter"), }); const defaultForm = { - pencegahanKriminalitas: { - programKeamanan: { - nama: "", - deskripsi: "", - slug: "", - }, - tipsKeamanan: { - judul: "", - konten: "", - slug: "", - }, - videoKeamanan: { - judul: "", - deskripsi: "", - videoUrl: "", - slug: "", - }, - }, + judul: "", + deskripsi: "", + deskripsiSingkat: "", + linkVideo: "", }; const pencegahanKriminalitasState = proxy({ @@ -65,7 +37,7 @@ const pencegahanKriminalitasState = proxy({ pencegahanKriminalitasState.create.loading = true; const res = await ApiFetch.api.keamanan.pencegahankriminalitas[ "create" - ].post(pencegahanKriminalitasState.create.form.pencegahanKriminalitas); + ].post(pencegahanKriminalitasState.create.form); if (res.status === 200) { pencegahanKriminalitasState.findMany.load(); return toast.success("success create"); @@ -82,11 +54,7 @@ const pencegahanKriminalitasState = proxy({ findMany: { data: null as | Prisma.PencegahanKriminalitasGetPayload<{ - include: { - programKeamanan: true; - tipsKeamanan: true; - videoKeamanan: true; - }; + omit: { isActive: true }; }>[] | null, page: 1, @@ -125,11 +93,7 @@ const pencegahanKriminalitasState = proxy({ }, findUnique: { data: null as Prisma.PencegahanKriminalitasGetPayload<{ - include: { - programKeamanan: true; - tipsKeamanan: true; - videoKeamanan: true; - }; + omit: { isActive: true }; }> | null, loading: false, async load(id: string) { @@ -148,6 +112,30 @@ const pencegahanKriminalitasState = proxy({ } }, }, + findFirst: { + data: null as Prisma.PencegahanKriminalitasGetPayload<{ + omit: { isActive: true }; + }> | null, + loading: false, + // findFirst.load() + async load() { + this.loading = true; + try { + const res = await ApiFetch.api.keamanan.pencegahankriminalitas["find-first"].get(); + + if (res.status === 200 && res.data?.success) { + this.data = res.data.data || null; + } else { + this.data = null; + } + } catch (err) { + console.error("Gagal fetch pencegahan kriminalitas terbaru:", err); + this.data = null; + } finally { + this.loading = false; + } + }, + }, delete: { loading: false, async byId(id: string) { @@ -213,24 +201,10 @@ const pencegahanKriminalitasState = proxy({ const data = result.data; pencegahanKriminalitasState.update.id = data.id; pencegahanKriminalitasState.update.form = { - pencegahanKriminalitas: { - programKeamanan: { - nama: data.programKeamanan.nama, - deskripsi: data.programKeamanan.deskripsi, - slug: data.programKeamanan.slug, - }, - tipsKeamanan: { - judul: data.tipsKeamanan.judul, - konten: data.tipsKeamanan.konten, - slug: data.tipsKeamanan.slug, - }, - videoKeamanan: { - judul: data.videoKeamanan.judul, - deskripsi: data.videoKeamanan.deskripsi, - videoUrl: data.videoKeamanan.videoUrl, - slug: data.videoKeamanan.slug, - }, - }, + judul: data.judul, + deskripsi: data.deskripsi, + deskripsiSingkat: data.deskripsiSingkat, + linkVideo: data.linkVideo, }; return data; } else { @@ -266,40 +240,11 @@ const pencegahanKriminalitasState = proxy({ "Content-Type": "application/json", }, body: JSON.stringify({ - pencegahanKriminalitas: { - programKeamanan: { - nama: pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.programKeamanan.nama, - deskripsi: - pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.programKeamanan.deskripsi, - slug: pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.programKeamanan.slug, - }, - tipsKeamanan: { - judul: - pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.tipsKeamanan.judul, - konten: - pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.tipsKeamanan.konten, - slug: pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.tipsKeamanan.slug, - }, - videoKeamanan: { - judul: - pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.videoKeamanan.judul, - deskripsi: - pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.videoKeamanan.deskripsi, - videoUrl: - pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.videoKeamanan.videoUrl, - slug: pencegahanKriminalitasState.update.form - .pencegahanKriminalitas.videoKeamanan.slug, - }, - }, + judul: pencegahanKriminalitasState.update.form.judul, + deskripsi: pencegahanKriminalitasState.update.form.deskripsi, + deskripsiSingkat: + pencegahanKriminalitasState.update.form.deskripsiSingkat, + linkVideo: pencegahanKriminalitasState.update.form.linkVideo, }), } ); diff --git a/src/app/admin/(dashboard)/keamanan/laporan-publik/[id]/page.tsx b/src/app/admin/(dashboard)/keamanan/laporan-publik/[id]/page.tsx index 2d25150d..396c59df 100644 --- a/src/app/admin/(dashboard)/keamanan/laporan-publik/[id]/page.tsx +++ b/src/app/admin/(dashboard)/keamanan/laporan-publik/[id]/page.tsx @@ -121,7 +121,7 @@ function DetailLaporanPublik() { Kronologi - {data.kronologi || '-'} + diff --git a/src/app/admin/(dashboard)/keamanan/laporan-publik/page.tsx b/src/app/admin/(dashboard)/keamanan/laporan-publik/page.tsx index b1723508..68b5d055 100644 --- a/src/app/admin/(dashboard)/keamanan/laporan-publik/page.tsx +++ b/src/app/admin/(dashboard)/keamanan/laporan-publik/page.tsx @@ -135,9 +135,7 @@ function ListLaporanPublik({ search }: { search: string }) { - - {item.kronologi} - + diff --git a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/[id]/edit/page.tsx b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/[id]/edit/page.tsx index d82f7a62..42ab7cc9 100644 --- a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/[id]/edit/page.tsx @@ -2,39 +2,35 @@ 'use client' import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import pencegahanKriminalitasState from '@/app/admin/(dashboard)/_state/keamanan/pencegahan-kriminalitas'; +import { convertYoutubeUrlToEmbed } from '@/app/admin/(dashboard)/desa/gallery/lib/youtube-utils'; import colors from '@/con/colors'; -import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { + Box, + Button, + Group, + Paper, + Stack, + TextInput, + Title, + Tooltip +} from '@mantine/core'; import { IconArrowBack } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; import { useProxy } from 'valtio/utils'; - function EditPencegahanKriminalitas() { const router = useRouter(); - const params = useParams() - const kriminalitasState = useProxy(pencegahanKriminalitasState) + const params = useParams(); + const kriminalitasState = useProxy(pencegahanKriminalitasState); + const [formData, setFormData] = useState({ - pencegahanKriminalitas: { - programKeamanan: { - nama: kriminalitasState.update.form.pencegahanKriminalitas.programKeamanan.nama, - deskripsi: kriminalitasState.update.form.pencegahanKriminalitas.programKeamanan.deskripsi, - slug: kriminalitasState.update.form.pencegahanKriminalitas.programKeamanan.slug, - }, - tipsKeamanan: { - judul: kriminalitasState.update.form.pencegahanKriminalitas.tipsKeamanan.judul, - konten: kriminalitasState.update.form.pencegahanKriminalitas.tipsKeamanan.konten, - slug: kriminalitasState.update.form.pencegahanKriminalitas.tipsKeamanan.slug, - }, - videoKeamanan: { - judul: kriminalitasState.update.form.pencegahanKriminalitas.videoKeamanan.judul, - deskripsi: kriminalitasState.update.form.pencegahanKriminalitas.videoKeamanan.deskripsi, - videoUrl: kriminalitasState.update.form.pencegahanKriminalitas.videoKeamanan.videoUrl, - slug: kriminalitasState.update.form.pencegahanKriminalitas.videoKeamanan.slug, - }, - }, - }) + judul: '', + deskripsi: '', + deskripsiSingkat: '', + linkVideo: '', + }); useEffect(() => { const loadKriminalitas = async () => { @@ -43,167 +39,154 @@ function EditPencegahanKriminalitas() { try { const data = await kriminalitasState.update.load(id); - if (data && data.pencegahanKriminalitas) { - const { programKeamanan, tipsKeamanan, videoKeamanan } = data.pencegahanKriminalitas; - + if (data) { setFormData({ - pencegahanKriminalitas: { - programKeamanan: { - nama: programKeamanan?.nama || "", - deskripsi: programKeamanan?.deskripsi || "", - slug: programKeamanan?.slug || "", - }, - tipsKeamanan: { - judul: tipsKeamanan?.judul || "", - konten: tipsKeamanan?.konten || "", - slug: tipsKeamanan?.slug || "", - }, - videoKeamanan: { - judul: videoKeamanan?.judul || "", - deskripsi: videoKeamanan?.deskripsi || "", - videoUrl: videoKeamanan?.videoUrl || "", - slug: videoKeamanan?.slug || "", - }, - }, + judul: data.judul || '', + deskripsi: data.deskripsi || '', + deskripsiSingkat: data.deskripsiSingkat || '', + linkVideo: data.linkVideo || '', }); } - } catch (error) { - console.error("Error loading pencegahan kriminalitas:", error); - toast.error("Gagal memuat data pencegahan kriminalitas"); + console.error('Error loading pencegahan kriminalitas:', error); + toast.error('Gagal memuat data pencegahan kriminalitas'); } - } + }; loadKriminalitas(); - }, [params.id]); + }, [params?.id]); + + const embedLink = convertYoutubeUrlToEmbed(formData.linkVideo); const handleSubmit = async () => { + const converted = convertYoutubeUrlToEmbed(formData.linkVideo); + if (!converted) { + toast.error('Link YouTube tidak valid. Pastikan formatnya benar.'); + return; + } + try { + // Update the form data first kriminalitasState.update.form = { ...kriminalitasState.update.form, - pencegahanKriminalitas: { - programKeamanan: { - nama: formData.pencegahanKriminalitas.programKeamanan.nama, - deskripsi: formData.pencegahanKriminalitas.programKeamanan.deskripsi, - slug: formData.pencegahanKriminalitas.programKeamanan.slug, - }, - tipsKeamanan: { - judul: formData.pencegahanKriminalitas.tipsKeamanan.judul, - konten: formData.pencegahanKriminalitas.tipsKeamanan.konten, - slug: formData.pencegahanKriminalitas.tipsKeamanan.slug, - }, - videoKeamanan: { - judul: formData.pencegahanKriminalitas.videoKeamanan.judul, - deskripsi: formData.pencegahanKriminalitas.videoKeamanan.deskripsi, - videoUrl: formData.pencegahanKriminalitas.videoKeamanan.videoUrl, - slug: formData.pencegahanKriminalitas.videoKeamanan.slug, - }, - }, - } - await kriminalitasState.update.update(); - toast.success("Pencegahan Kriminalitas berhasil diperbarui!"); - router.push("/admin/keamanan/pencegahan-kriminalitas"); - } catch (error) { - console.error("Error updating pencegahan kriminalitas:", error); - toast.error("Gagal memuat data pencegahan kriminalitas"); - } - } - return ( - - - - + judul: formData.judul, + deskripsi: formData.deskripsi, + deskripsiSingkat: formData.deskripsiSingkat, + linkVideo: formData.linkVideo, + }; - - - Edit Pencegahan Kriminalitas + // Set the ID and then call update + kriminalitasState.update.id = params?.id as string; + + await kriminalitasState.update.update(); + toast.success('Pencegahan Kriminalitas berhasil diperbarui!'); + router.push('/admin/keamanan/pencegahan-kriminalitas'); + } catch (error) { + console.error('Error updating pencegahan kriminalitas:', error); + toast.error('Terjadi kesalahan saat memperbarui data'); + } + }; + + return ( + + {/* Back button + Title */} + + + + + + Edit Pencegahan Kriminalitas + + + + {/* Form container */} + + { - formData.pencegahanKriminalitas.programKeamanan.nama = val.target.value; - }} - label={Judul Program Keamanan} - placeholder='Masukkan judul Program Keamanan' + label="Judul" + placeholder="Masukkan judul" + value={formData.judul} + onChange={(e) => setFormData({ ...formData, judul: e.target.value })} + required /> + { - formData.pencegahanKriminalitas.programKeamanan.slug = val.target.value; - }} - label={Slug Program Keamanan} - placeholder='Masukkan slug Program Keamanan' + label="Deskripsi Singkat" + placeholder="Masukkan deskripsi singkat" + value={formData.deskripsiSingkat} + onChange={(e) => + setFormData({ ...formData, deskripsiSingkat: e.target.value }) + } + required /> + - Deskripsi Program Keamanan + + Deskripsi Lengkap + { - formData.pencegahanKriminalitas.programKeamanan.deskripsi = val; - }} + value={formData.deskripsi} + onChange={(val) => + setFormData({ ...formData, deskripsi: val }) + } /> - { - formData.pencegahanKriminalitas.tipsKeamanan.judul = val.target.value; - }} - label={Judul Tips Keamanan} - placeholder='Masukkan judul Tips Keamanan' - /> - { - formData.pencegahanKriminalitas.tipsKeamanan.slug = val.target.value; - }} - label={Slug Tips Keamanan} - placeholder='Masukkan slug Tips Keamanan' - /> + - Deskripsi Tips Keamanan - { - formData.pencegahanKriminalitas.tipsKeamanan.konten = val; - }} + + setFormData({ ...formData, linkVideo: e.currentTarget.value }) + } + required /> + {embedLink && ( + + + + )} - { - formData.pencegahanKriminalitas.videoKeamanan.judul = val.target.value; - }} - label={Judul Video Keamanan} - placeholder='Masukkan judul Video Keamanan' - /> - { - formData.pencegahanKriminalitas.videoKeamanan.slug = val.target.value; - }} - label={Slug Video Keamanan} - placeholder='Masukkan slug Video Keamanan' - /> - - Deskripsi Tips Keamanan - { - formData.pencegahanKriminalitas.videoKeamanan.deskripsi = val; + + {/* Action button */} + + + > + Simpan + diff --git a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/[id]/page.tsx b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/[id]/page.tsx index 145bf121..72371193 100644 --- a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/[id]/page.tsx +++ b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/[id]/page.tsx @@ -1,113 +1,146 @@ 'use client' import colors from '@/con/colors'; -import { Box, Button, Flex, Paper, Skeleton, Stack, Text } from '@mantine/core'; -import { IconArrowBack, IconEdit, IconX } from '@tabler/icons-react'; -import { useRouter } from 'next/navigation'; +import { Box, Button, Flex, Paper, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; +import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; +import { useRouter, useParams } from 'next/navigation'; import { useState } from 'react'; import { useShallowEffect } from '@mantine/hooks'; -import { useParams } from 'next/navigation'; import { useProxy } from 'valtio/utils'; import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; import pencegahanKriminalitasState from '../../../_state/keamanan/pencegahan-kriminalitas'; function DetailPencegahanKriminalitas() { - const [modalHapus, setModalHapus] = useState(false) - const [selectedId, setSelectedId] = useState(null) + const [modalHapus, setModalHapus] = useState(false); + const [selectedId, setSelectedId] = useState(null); const router = useRouter(); - const params = useParams() - const kriminalitasState = useProxy(pencegahanKriminalitasState) + const params = useParams(); + const kriminalitasState = useProxy(pencegahanKriminalitasState); useShallowEffect(() => { - kriminalitasState.findUnique.load(params?.id as string) - }, []) + kriminalitasState.findUnique.load(params?.id as string); + }, []); const handleDelete = () => { if (selectedId) { - kriminalitasState.delete.byId(selectedId) - setModalHapus(false) - setSelectedId(null) - router.push("/admin/keamanan/pencegahan-kriminalitas") + kriminalitasState.delete.byId(selectedId); + setModalHapus(false); + setSelectedId(null); + router.push("/admin/keamanan/pencegahan-kriminalitas"); } - } + }; if (!kriminalitasState.findUnique.data) { return ( - + - ) + ); } + + const data = kriminalitasState.findUnique.data; + return ( - - - - - - - - Detail Pencegahan Kriminalitas - {kriminalitasState.findUnique.data ? ( - - - - Judul Program Keamanan - {kriminalitasState.findUnique.data?.programKeamanan.nama} - - - Slug - {kriminalitasState.findUnique.data?.programKeamanan.slug} - - - Deskripsi - - - - Judul Tips Keamanan - {kriminalitasState.findUnique.data?.tipsKeamanan.judul} - - - Slug Tips Keamanan - {kriminalitasState.findUnique.data?.tipsKeamanan.slug} - - - Deskripsi Tips Keamanan - - - - - - - - - ) : null} + + {/* Tombol Kembali */} + + + {/* Detail */} + + + + Detail Pencegahan Kriminalitas + + + + + + Judul + {data?.judul || '-'} + + + + Deskripsi Singkat + {data?.deskripsiSingkat ? ( + + ) : ( + Tidak ada deskripsi singkat + )} + + + + Deskripsi + {data?.deskripsi ? ( + + ) : ( + Tidak ada deskripsi + )} + + + + Video + {data?.linkVideo ? ( + + ) : ( + Tidak ada video + )} + + + {/* Tombol Aksi */} + + + + + + + + + + - {/* Modal Hapus */} + {/* Modal Konfirmasi Hapus */} setModalHapus(false)} @@ -116,6 +149,18 @@ function DetailPencegahanKriminalitas() { /> ); + + function convertToEmbedUrl(youtubeUrl: string): string { + try { + const url = new URL(youtubeUrl); + const videoId = url.searchParams.get("v"); + if (!videoId) return youtubeUrl; + return `https://www.youtube.com/embed/${videoId}`; + } catch (err) { + console.error("Error converting YouTube URL to embed:", err); + return youtubeUrl; + } + } } export default DetailPencegahanKriminalitas; diff --git a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/create/page.tsx b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/create/page.tsx index 72480025..69f06504 100644 --- a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/create/page.tsx +++ b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/create/page.tsx @@ -1,141 +1,158 @@ 'use client' + import colors from '@/con/colors'; -import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { + Box, + Button, + Group, + Paper, + Stack, + Text, + TextInput, + Title, + Tooltip, +} from '@mantine/core'; import { IconArrowBack } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useProxy } from 'valtio/utils'; import CreateEditor from '../../../_com/createEditor'; import pencegahanKriminalitasState from '../../../_state/keamanan/pencegahan-kriminalitas'; - +import { useState } from 'react'; +import { convertYoutubeUrlToEmbed } from '../../../desa/gallery/lib/youtube-utils'; +import { toast } from 'react-toastify'; function CreatePencegahanKriminalitas() { const router = useRouter(); - const kriminalitasState = useProxy(pencegahanKriminalitasState) + const kriminalitasState = useProxy(pencegahanKriminalitasState); + const [link, setLink] = useState(''); + const embedLink = convertYoutubeUrlToEmbed(link); const resetForm = () => { kriminalitasState.create.form = { - pencegahanKriminalitas: { - programKeamanan: { - nama: "", - deskripsi: "", - slug: "", - }, - tipsKeamanan: { - judul: "", - konten: "", - slug: "", - }, - videoKeamanan: { - judul: "", - deskripsi: "", - videoUrl: "", - slug: "", - }, - }, - } - } + judul: "", + deskripsi: "", + deskripsiSingkat: "", + linkVideo: "", + }; + setLink(''); + }; const handleSubmit = async () => { + if (!embedLink) { + toast.error('Link YouTube tidak valid. Pastikan formatnya benar.'); + return; + } + + kriminalitasState.create.form.linkVideo = embedLink; await kriminalitasState.create.create(); resetForm(); router.push('/admin/keamanan/pencegahan-kriminalitas'); - } - return ( - - - - + }; - - - Create Pencegahan Kriminalitas + return ( + + {/* Header Back Button + Title */} + + + + + + Tambah Pencegahan Kriminalitas + + + + {/* Card Form */} + + + {/* Judul */} { - kriminalitasState.create.form.pencegahanKriminalitas.programKeamanan.nama = val.target.value; + label="Judul Pencegahan Kriminalitas" + placeholder="Masukkan judul Pencegahan Kriminalitas" + value={kriminalitasState.create.form.judul} + onChange={(e) => { + kriminalitasState.create.form.judul = e.currentTarget.value; }} - label={Judul Program Keamanan} - placeholder='Masukkan judul Program Keamanan' + required /> + + {/* Deskripsi Singkat */} { - kriminalitasState.create.form.pencegahanKriminalitas.programKeamanan.slug = val.target.value; + label="Deskripsi Singkat" + placeholder="Masukkan deskripsi singkat" + value={kriminalitasState.create.form.deskripsiSingkat} + onChange={(e) => { + kriminalitasState.create.form.deskripsiSingkat = e.currentTarget.value; }} - label={Slug Program Keamanan} - placeholder='Masukkan slug Program Keamanan' + required /> + + {/* Deskripsi Panjang */} - Deskripsi Program Keamanan + + Deskripsi + { - kriminalitasState.create.form.pencegahanKriminalitas.programKeamanan.deskripsi = val; + kriminalitasState.create.form.deskripsi = val; }} /> + + {/* Link YouTube */} { - kriminalitasState.create.form.pencegahanKriminalitas.tipsKeamanan.judul = val.target.value; - }} - label={Judul Tips Keamanan} - placeholder='Masukkan judul Tips Keamanan' + label="Link Video YouTube" + placeholder="https://www.youtube.com/watch?v=abc123" + value={link} + onChange={(e) => setLink(e.currentTarget.value)} + required /> - { - kriminalitasState.create.form.pencegahanKriminalitas.tipsKeamanan.slug = val.target.value; - }} - label={Slug Tips Keamanan} - placeholder='Masukkan slug Tips Keamanan' - /> - - Deskripsi Tips Keamanan - { - kriminalitasState.create.form.pencegahanKriminalitas.tipsKeamanan.konten = val; + + {/* Preview Video */} + {embedLink && ( + + + + )} + + {/* Button Submit */} + + + > + Simpan + diff --git a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/page.tsx b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/page.tsx index 1e7e8524..45db4790 100644 --- a/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/page.tsx +++ b/src/app/admin/(dashboard)/keamanan/pencegahan-kriminalitas/page.tsx @@ -62,14 +62,6 @@ function ListPencegahanKriminalitas({ search }: { search: string }) { load(page, 10, search); }, [page, search]); - const filteredData = (data || []).filter(item => { - const keyword = search.toLowerCase(); - return ( - item.programKeamanan.nama.toLowerCase().includes(keyword) || - item.programKeamanan.slug.toLowerCase().includes(keyword) || - item.programKeamanan.deskripsi?.toLowerCase().includes(keyword) - ); - }); if (loading || !data) { return ( @@ -103,35 +95,43 @@ function ListPencegahanKriminalitas({ search }: { search: string }) { Nama Pencegahan - Slug Deskripsi + Deskripsi Singkat Aksi - {filteredData.length > 0 ? ( - filteredData.map((item) => ( + {data.length > 0 ? ( + data.map((item) => ( - {item.programKeamanan.nama} + {item.judul} - - {item.programKeamanan.slug} - + + + - + + + - - - - - - How to Keep Your Neighborhood Safe - - - Practical safety habits everyone can apply daily to reduce risks. - - - - - - - - Recognizing Criminal Activities - - - Key warning signs and behavior patterns you should stay aware of. - - - - - - - - - Ongoing Security Programs - - - {['Night Patrol', 'Neighborhood Watch', 'Emergency Preparedness'].map((program, i) => ( - - - - {program} - - - - - ))} - - - - - -