diff --git a/src/app/admin/(dashboard)/_state/desa/pengumuman.ts b/src/app/admin/(dashboard)/_state/desa/pengumuman.ts index 3c9ae6ae..ccb3e16c 100644 --- a/src/app/admin/(dashboard)/_state/desa/pengumuman.ts +++ b/src/app/admin/(dashboard)/_state/desa/pengumuman.ts @@ -1,10 +1,222 @@ -/* eslint-disable @typescript-eslint/no-explicit-any */ import ApiFetch from "@/lib/api-fetch"; import { Prisma } from "@prisma/client"; import { toast } from "react-toastify"; import { proxy } from "valtio"; import { z } from "zod"; +const templateKategoriPengumuman = z.object({ + name: z.string().min(1, "Nama harus diisi"), +}); + +const defaultKategoriPengumuman = { + name: "", +}; + +const category = proxy({ + create: { + form: { ...defaultKategoriPengumuman }, + loading: false, + async create() { + const cek = templateKategoriPengumuman.safeParse(category.create.form); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v) => `${v.path.join(".")}`) + .join("\n")}] required`; + return toast.error(err); + } + + try { + category.create.loading = true; + const res = await ApiFetch.api.desa.kategoripengumuman["create"].post( + category.create.form + ); + if (res.status === 200) { + category.findMany.load(); + return toast.success("Data Kategori Pengumuman Berhasil Dibuat"); + } + console.log(res); + return toast.error("failed create"); + } catch (error) { + console.log(error); + return toast.error("failed create"); + } finally { + category.create.loading = false; + } + }, + }, + findMany: { + data: [] as Prisma.CategoryPengumumanGetPayload<{ + omit: { + isActive: true; + }; + }>[], + loading: false, + async load() { + const res = await ApiFetch.api.desa.kategoripengumuman["findMany"].get(); + if (res.status === 200) { + category.findMany.data = res.data?.data ?? []; + } + }, + }, + findUnique: { + data: null as Prisma.CategoryPengumumanGetPayload<{ + omit: { + isActive: true; + }; + }> | null, + loading: false, + async load(id: string) { + try { + const res = await fetch(`/api/desa/kategoripengumuman/${id}`); + if (res.ok) { + const data = await res.json(); + category.findUnique.data = data.data ?? null; + } else { + console.error("Failed to fetch data", res.status, res.statusText); + category.findUnique.data = null; + } + } catch (error) { + console.error("Error fetching data:", error); + category.findUnique.data = null; + } + }, + }, + delete: { + loading: false, + async delete(id: string) { + if (!id) return toast.warn("ID tidak valid"); + + try { + category.delete.loading = true; + + const response = await fetch(`/api/desa/kategoripengumuman/del/${id}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + }); + + const result = await response.json(); + + if (response.ok && result?.success) { + toast.success( + result.message || "Data Kategori Pengumuman berhasil dihapus" + ); + await category.findMany.load(); // refresh list + } else { + toast.error( + result?.message || "Gagal menghapus Data Kategori Pengumuman" + ); + } + } catch (error) { + console.error("Gagal delete:", error); + toast.error("Terjadi kesalahan saat menghapus Data Kategori Pengumuman"); + } finally { + category.delete.loading = false; + } + }, + }, + update: { + id: "", + form: { ...defaultKategoriPengumuman }, + loading: false, + async load(id: string) { + if (!id) { + toast.warn("ID tidak valid"); + return null; + } + + try { + const response = await fetch(`/api/desa/kategoripengumuman/${id}`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, + }); + if (!response.ok) { + throw new Error(`HTTP error! status: ${response.status}`); + } + + const result = await response.json(); + + if (result?.success) { + const data = result.data; + this.id = data.id; + this.form = { + name: data.name, + }; + return data; // Return the loaded data + } else { + throw new Error(result?.message || "Gagal memuat data"); + } + } catch (error) { + console.error("Error loading kategori berita:", error); + toast.error( + error instanceof Error ? error.message : "Gagal memuat data" + ); + return null; + } + }, + async update() { + const cek = templateKategoriPengumuman.safeParse(category.update.form); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v) => `${v.path.join(".")}`) + .join("\n")}] required`; + toast.error(err); + return false; + } + + try { + category.update.loading = true; + + const response = await fetch(`/api/desa/kategoripengumuman/${this.id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + name: this.form.name, + }), + }); + + if (!response.ok) { + const errorData = await response.json().catch(() => ({})); + throw new Error( + errorData.message || `HTTP error! status: ${response.status}` + ); + } + + const result = await response.json(); + + if (result.success) { + toast.success("Berhasil update data kategori pengumuman"); + await category.findMany.load(); // refresh list + return true; + } else { + throw new Error( + result.message || "Gagal update data kategori pengumuman" + ); + } + } catch (error) { + console.error("Error updating data kategori pengumuman:", error); + toast.error( + error instanceof Error + ? error.message + : "Terjadi kesalahan saat update data kategori pengumuman" + ); + return false; + } finally { + category.update.loading = false; + } + }, + reset() { + category.update.id = ""; + category.update.form = { ...defaultKategoriPengumuman }; + }, + }, +}); + const templateFormPengumuman = z.object({ judul: z.string().min(3, "Judul minimal 3 karakter"), deskripsi: z.string().min(3, "Deskripsi minimal 3 karakter"), @@ -12,22 +224,6 @@ const templateFormPengumuman = z.object({ categoryPengumumanId: z.string().nonempty(), }); -const category = proxy({ - findMany: { - data: null as - | null - | Prisma.CategoryPengumumanGetPayload<{ omit: { isActive: true } }>[], - async load() { - const res = await ApiFetch.api.desa.pengumuman.category[ - "find-many" - ].get(); - if (res.status === 200) { - category.findMany.data = (res.data?.data as any) ?? []; - } - }, - }, -}); - type PengumumanForm = Prisma.PengumumanGetPayload<{ select: { judul: true; diff --git a/src/app/admin/(dashboard)/desa/pengumuman/_com/layoutTabs.tsx b/src/app/admin/(dashboard)/desa/pengumuman/_com/layoutTabs.tsx new file mode 100644 index 00000000..d65f89a5 --- /dev/null +++ b/src/app/admin/(dashboard)/desa/pengumuman/_com/layoutTabs.tsx @@ -0,0 +1,62 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' +import colors from '@/con/colors'; +import { Stack, Tabs, TabsList, TabsPanel, TabsTab, Title } from '@mantine/core'; +import { usePathname, useRouter } from 'next/navigation'; +import React, { useEffect, useState } from 'react'; + +function LayoutTabsLayanan({ children }: { children: React.ReactNode }) { + const router = useRouter() + const pathname = usePathname() + const tabs = [ + { + label: "List Pengumuman", + value: "listpengumuman", + href: "/admin/desa/pengumuman/list-pengumuman" + }, + { + label: "Kategori Pengumuman", + value: "kategoripengumuman", + href: "/admin/desa/pengumuman/kategori-pengumuman" + }, + ]; + const curentTab = tabs.find(tab => tab.href === pathname) + const [activeTab, setActiveTab] = useState(curentTab?.value || tabs[0].value); + + const handleTabChange = (value: string | null) => { + const tab = tabs.find(t => t.value === value) + if (tab) { + router.push(tab.href) + } + setActiveTab(value) + } + + useEffect(() => { + const match = tabs.find(tab => tab.href === pathname) + if (match) { + setActiveTab(match.value) + } + }, [pathname]) + + return ( + + Pengumuman + + + {tabs.map((e, i) => ( + {e.label} + ))} + + {tabs.map((e, i) => ( + + {/* Konten dummy, bisa diganti tergantung routing */} + <> + + ))} + + {children} + + ); +} + +export default LayoutTabsLayanan; \ No newline at end of file diff --git a/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/[id]/page.tsx b/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/[id]/page.tsx new file mode 100644 index 00000000..8c4c06bf --- /dev/null +++ b/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/[id]/page.tsx @@ -0,0 +1,80 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' +import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman'; +import colors from '@/con/colors'; +import { Box, Button, Paper, Stack, Text, TextInput, Title } 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 EditKategoriPengumuman() { + const editState = useProxy(stateDesaPengumuman.category) + const router = useRouter(); + const params = useParams(); + const [formData, setFormData] = useState({ + name: editState.update.form.name || '', + }); + + useEffect(() => { + const loadKategori = async () => { + const id = params?.id as string; + if (!id) return; + + try { + const data = await editState.update.load(id); // akses langsung, bukan dari proxy + if (data) { + setFormData({ + name: data.name || '', + }); + } + } catch (error) { + console.error("Error loading kategori Pengumuman:", error); + toast.error("Gagal memuat data kategori Pengumuman"); + } + }; + + loadKategori(); + }, [params?.id]); + + const handleSubmit = async () => { + try { + editState.update.form = { + ...editState.update.form, + name: formData.name, + }; + await editState.update.update(); + toast.success('Kategori Pengumuman berhasil diperbarui!'); + router.push('/admin/desa/pengumuman/kategori-pengumuman'); + } catch (error) { + console.error('Error updating kategori Pengumuman:', error); + toast.error('Terjadi kesalahan saat memperbarui kategori Pengumuman'); + } + }; + + return ( + + + + + + + Edit Kategori Pengumuman + setFormData({ ...formData, name: e.target.value })} + label={Nama Kategori Pengumuman} + placeholder="masukkan nama kategori Pengumuman" + /> + + + + + + ); +} + +export default EditKategoriPengumuman; diff --git a/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/create/page.tsx b/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/create/page.tsx new file mode 100644 index 00000000..d238e152 --- /dev/null +++ b/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/create/page.tsx @@ -0,0 +1,55 @@ +'use client' +import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman'; +import colors from '@/con/colors'; +import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { IconArrowBack } from '@tabler/icons-react'; +import { useRouter } from 'next/navigation'; +import { useProxy } from 'valtio/utils'; + + + +function CreateKategoriPengumuman() { + const createState = useProxy(stateDesaPengumuman.category) + const router = useRouter(); + + const resetForm = () => { + createState.create.form = { + name: "", + }; + }; + + const handleSubmit = async () => { + await createState.create.create(); + resetForm(); + router.push("/admin/desa/pengumuman/kategori-pengumuman") + }; + + return ( + + + + + + + + Create Kategori Pengumuman + Nama Kategori Pengumuman} + placeholder='Masukkan nama kategori Pengumuman' + value={createState.create.form.name} + onChange={(val) => { + createState.create.form.name = val.target.value; + }} + /> + + + + + + + ); +} + +export default CreateKategoriPengumuman; diff --git a/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/page.tsx b/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/page.tsx new file mode 100644 index 00000000..7ed4b149 --- /dev/null +++ b/src/app/admin/(dashboard)/desa/pengumuman/kategori-pengumuman/page.tsx @@ -0,0 +1,128 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' +import colors from '@/con/colors'; +import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { IconEdit, IconSearch, IconTrash } from '@tabler/icons-react'; +import { useRouter } from 'next/navigation'; +import { useEffect, useState } from 'react'; +import { useProxy } from 'valtio/utils'; +import HeaderSearch from '../../../_com/header'; +import JudulList from '../../../_com/judulList'; +import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; +import stateDesaPengumuman from '../../../_state/desa/pengumuman'; + + + +function KategoriPengumuman() { + const [search, setSearch] = useState(''); + return ( + + } + value={search} + onChange={(e) => setSearch(e.currentTarget.value)} + /> + + + ); +} + +function ListKategoriPengumuman({ search }: { search: string }) { + const listDataState = useProxy(stateDesaPengumuman.category) + const router = useRouter(); + const [modalHapus, setModalHapus] = useState(false) + const [selectedId, setSelectedId] = useState(null) + + useEffect(() => { + listDataState.findMany.load() + }, []) + + const handleDelete = () => { + if (selectedId) { + listDataState.delete.delete(selectedId) + setModalHapus(false) + setSelectedId(null) + + listDataState.findMany.load() + } + } + + const filteredData = (listDataState.findMany.data || []).filter(item => { + const keyword = search.toLowerCase(); + return ( + item.name.toLowerCase().includes(keyword) + ); + }); + + if (!listDataState.findMany.data) { + return ( + + + + ) + } + return ( + + + + + + + + + No + Nama + Edit + Hapus + + + + {filteredData.map((item, index) => ( + + + + {index + 1} + + + {item.name} + + + + + + + + ))} + +
+
+
+
+ + {/* Modal Konfirmasi Hapus */} + setModalHapus(false)} + onConfirm={handleDelete} + text='Apakah anda yakin ingin menghapus kategori Pengumuman ini?' + /> +
+ ) +} + +export default KategoriPengumuman; diff --git a/src/app/admin/(dashboard)/desa/pengumuman/layout.tsx b/src/app/admin/(dashboard)/desa/pengumuman/layout.tsx new file mode 100644 index 00000000..4a4acdbd --- /dev/null +++ b/src/app/admin/(dashboard)/desa/pengumuman/layout.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import LayoutTabs from './_com/layoutTabs'; + +function Layout({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ); +} + +export default Layout; diff --git a/src/app/admin/(dashboard)/desa/pengumuman/[id]/edit/page.tsx b/src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/[id]/edit/page.tsx similarity index 100% rename from src/app/admin/(dashboard)/desa/pengumuman/[id]/edit/page.tsx rename to src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/[id]/edit/page.tsx diff --git a/src/app/admin/(dashboard)/desa/pengumuman/[id]/page.tsx b/src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/[id]/page.tsx similarity index 100% rename from src/app/admin/(dashboard)/desa/pengumuman/[id]/page.tsx rename to src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/[id]/page.tsx diff --git a/src/app/admin/(dashboard)/desa/pengumuman/create/page.tsx b/src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/create/page.tsx similarity index 95% rename from src/app/admin/(dashboard)/desa/pengumuman/create/page.tsx rename to src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/create/page.tsx index 3355f8de..b68df236 100644 --- a/src/app/admin/(dashboard)/desa/pengumuman/create/page.tsx +++ b/src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/create/page.tsx @@ -1,4 +1,6 @@ 'use client' +import CreateEditor from '@/app/admin/(dashboard)/_com/createEditor'; +import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman'; import colors from '@/con/colors'; import { Box, Button, Group, Paper, Select, Stack, Text, TextInput, Title } from '@mantine/core'; import { useShallowEffect } from '@mantine/hooks'; @@ -6,8 +8,7 @@ import { Prisma } from '@prisma/client'; import { IconArrowBack } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useProxy } from 'valtio/utils'; -import CreateEditor from '../../../_com/createEditor'; -import stateDesaPengumuman from '../../../_state/desa/pengumuman'; + function CreatePengumuman() { const pengumumanState = useProxy(stateDesaPengumuman) diff --git a/src/app/admin/(dashboard)/desa/pengumuman/page.tsx b/src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/page.tsx similarity index 92% rename from src/app/admin/(dashboard)/desa/pengumuman/page.tsx rename to src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/page.tsx index dd2dde97..97328475 100644 --- a/src/app/admin/(dashboard)/desa/pengumuman/page.tsx +++ b/src/app/admin/(dashboard)/desa/pengumuman/list-pengumuman/page.tsx @@ -5,10 +5,10 @@ import { useShallowEffect } from '@mantine/hooks'; import { IconCircleDashedPlus, IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useProxy } from 'valtio/utils'; -import HeaderSearch from '../../_com/header'; -import stateDesaPengumuman from '../../_state/desa/pengumuman'; -import { ModalKonfirmasiHapus } from '../../_com/modalKonfirmasiHapus'; import { useState } from 'react'; +import HeaderSearch from '../../../_com/header'; +import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus'; +import stateDesaPengumuman from '../../../_state/desa/pengumuman'; function Pengumuman() { @@ -16,7 +16,7 @@ function Pengumuman() { return ( } value={search} @@ -113,7 +113,7 @@ function ListPengumuman({ search }: { search: string }) { opened={modalHapus} onClose={() => setModalHapus(false)} onConfirm={handleHapus} - text='Apakah anda yakin ingin menghapus berita ini?' + text='Apakah anda yakin ingin menghapus pengumuman ini?' /> ) diff --git a/src/app/admin/_com/list_PageAdmin.tsx b/src/app/admin/_com/list_PageAdmin.tsx index 5926b590..cfc1fca4 100644 --- a/src/app/admin/_com/list_PageAdmin.tsx +++ b/src/app/admin/_com/list_PageAdmin.tsx @@ -108,7 +108,7 @@ export const navBar = [ { id: "Desa_4", name: "Pengumuman", - path: "/admin/desa/pengumuman" + path: "/admin/desa/pengumuman/list-pengumuman" }, { id: "Desa_5", diff --git a/src/app/api/[[...slugs]]/_lib/desa/index.ts b/src/app/api/[[...slugs]]/_lib/desa/index.ts index 28e94577..6c4ce431 100644 --- a/src/app/api/[[...slugs]]/_lib/desa/index.ts +++ b/src/app/api/[[...slugs]]/_lib/desa/index.ts @@ -9,6 +9,7 @@ import LayananDesa from "./layanan"; import Penghargaan from "./penghargaan"; import KategoriPotensi from "./potensi/kategori-potensi"; import KategoriBerita from "./berita/kategori-berita"; +import KategoriPengumuman from "./pengumuman/kategori-pengumuman"; const Desa = new Elysia({ prefix: "/api/desa", tags: ["Desa"] }) @@ -22,5 +23,6 @@ const Desa = new Elysia({ prefix: "/api/desa", tags: ["Desa"] }) .use(Penghargaan) .use(KategoriPotensi) .use(KategoriBerita) + .use(KategoriPengumuman) export default Desa; diff --git a/src/app/api/[[...slugs]]/_lib/desa/pengumuman/index.ts b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/index.ts index 3bcb683e..b03ac6e6 100644 --- a/src/app/api/[[...slugs]]/_lib/desa/pengumuman/index.ts +++ b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/index.ts @@ -1,16 +1,13 @@ -import Elysia from "elysia"; +import Elysia, { t } from "elysia"; import { pengumumanCreate } from "./create"; -import pengumumanFindMany from "./find-many"; -import { t } from "elysia"; -import pengumumanCategoryFindMany from "./category"; import pengumumanDelete from "./del"; import pengumumanFindById from "./find-by-id"; -import pengumumanUpdate from "./updt"; +import pengumumanFindMany from "./find-many"; import pengumumanFindFirst from "./findFirst"; import pengumumanFindRecent from "./findRecent"; +import pengumumanUpdate from "./updt"; const Pengumuman = new Elysia({ prefix: "/pengumuman", tags: ["Desa/Pengumuman"] }) - .get("/category/find-many", pengumumanCategoryFindMany) .get("/find-many", pengumumanFindMany) .get("/:id", pengumumanFindById) .delete("/delete/:id", pengumumanDelete) diff --git a/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/create.ts b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/create.ts new file mode 100644 index 00000000..759e8890 --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/create.ts @@ -0,0 +1,26 @@ +import prisma from "@/lib/prisma"; +import { Context } from "elysia"; + +type FormCreate = { + name: string; +} + +export default async function kategoriPengumumanCreate(context: Context) { + const body = (await context.body) as FormCreate; + + try { + const result = await prisma.categoryPengumuman.create({ + data: { + name: body.name, + }, + }); + return { + success: true, + message: "Berhasil membuat kategori pengumuman", + data: result, + }; + } catch (error) { + console.error("Error creating kategori pengumuman:", error); + throw new Error("Gagal membuat kategori pengumuman: " + (error as Error).message); + } +} \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/del.ts b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/del.ts new file mode 100644 index 00000000..3fde4347 --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/del.ts @@ -0,0 +1,16 @@ +import prisma from "@/lib/prisma"; +import { Context } from "elysia"; + +export default async function kategoriPengumumanDelete(context: Context) { + const id = context.params.id as string; + + await prisma.categoryPengumuman.delete({ + where: { id }, + }); + + return { + status: 200, + success: true, + message: "Success delete kategori pengumuman", + }; +} \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/findMany.ts b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/findMany.ts new file mode 100644 index 00000000..2646b2ee --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/findMany.ts @@ -0,0 +1,8 @@ +import prisma from "@/lib/prisma"; + +async function kategoriPengumumanFindMany() { + const data = await prisma.categoryPengumuman.findMany(); + return { data }; +} + +export default kategoriPengumumanFindMany diff --git a/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/findUnique.ts b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/findUnique.ts new file mode 100644 index 00000000..7c3ad8fe --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/findUnique.ts @@ -0,0 +1,46 @@ +import prisma from "@/lib/prisma"; + +export default async function kategoriPengumumanFindUnique(request: Request) { + const url = new URL(request.url); + const pathSegments = url.pathname.split('/'); + const id = pathSegments[pathSegments.length - 1]; + + if (!id) { + return { + success: false, + message: "ID is required", + } + } + + try { + if (typeof id !== 'string') { + return { + success: false, + message: "ID is required", + } + } + + const data = await prisma.categoryPengumuman.findUnique({ + where: { id }, + }); + + if (!data) { + return { + success: false, + message: "Data not found", + } + } + + return { + success: true, + message: "Success get kategori pengumuman", + data, + } + } catch (error) { + console.error("Find by ID error:", error); + return { + success: false, + message: "Gagal mengambil data: " + (error instanceof Error ? error.message : 'Unknown error'), + } + } +} \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/index.ts b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/index.ts new file mode 100644 index 00000000..92819f4d --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/index.ts @@ -0,0 +1,33 @@ +import Elysia, { t } from "elysia"; +import kategoriPengumumanCreate from "./create"; +import kategoriPengumumanDelete from "./del"; +import kategoriPengumumanFindMany from "./findMany"; +import kategoriPengumumanFindUnique from "./findUnique"; +import kategoriPengumumanUpdate from "./updt"; + +const KategoriPengumuman = new Elysia({ + prefix: "/kategoripengumuman", + tags: ["Desa / Pengumuman / Kategori Pengumuman"], +}) + + .post("/create", kategoriPengumumanCreate, { + body: t.Object({ + name: t.String(), + }), + }) + + .get("/findMany", kategoriPengumumanFindMany) + .get("/:id", async (context) => { + const response = await kategoriPengumumanFindUnique( + new Request(context.request) + ); + return response; + }) + .put("/:id", kategoriPengumumanUpdate, { + body: t.Object({ + name: t.String(), + }), + }) + .delete("/del/:id", kategoriPengumumanDelete); + +export default KategoriPengumuman; \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/updt.ts b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/updt.ts new file mode 100644 index 00000000..1f3be759 --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/desa/pengumuman/kategori-pengumuman/updt.ts @@ -0,0 +1,28 @@ +import prisma from "@/lib/prisma"; +import { Context } from "elysia"; + +type FormUpdate = { + name: string; +} + +export default async function kategoriPengumumanUpdate(context: Context) { + const body = (await context.body) as FormUpdate; + const id = context.params.id as string; + + try { + const result = await prisma.categoryPengumuman.update({ + where: { id }, + data: { + name: body.name, + }, + }); + return { + success: true, + message: "Berhasil mengupdate kategori pengumuman", + data: result, + }; + } catch (error) { + console.error("Error updating kategori pengumuman:", error); + throw new Error("Gagal mengupdate kategori pengumuman: " + (error as Error).message); + } +} \ No newline at end of file diff --git a/src/app/darmasaba/(pages)/desa/potensi/page.tsx b/src/app/darmasaba/(pages)/desa/potensi/page.tsx index 37d2a4e4..ccd973e3 100644 --- a/src/app/darmasaba/(pages)/desa/potensi/page.tsx +++ b/src/app/darmasaba/(pages)/desa/potensi/page.tsx @@ -60,7 +60,7 @@ function Page() { {data?.filter(item => item.kategori?.nama.toLowerCase() === 'wisata' ).length || 0} - Destinasi Wisata + Wisata diff --git a/src/app/darmasaba/(tambahan)/penghargaan/[id]/page.tsx b/src/app/darmasaba/(tambahan)/penghargaan/[id]/page.tsx index 8f84518e..cb5cd9ff 100644 --- a/src/app/darmasaba/(tambahan)/penghargaan/[id]/page.tsx +++ b/src/app/darmasaba/(tambahan)/penghargaan/[id]/page.tsx @@ -68,7 +68,7 @@ function Page() {