diff --git a/prisma/schema.prisma b/prisma/schema.prisma index cce83ef8..5d8b95af 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -783,24 +783,22 @@ model Penghargaan { // ========================================= FASILITAS KESEHATAN ========================================= // model FasilitasKesehatan { - id String @id @default(cuid()) - name String - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) - informasiumum InformasiUmum @relation(fields: [informasiUmumId], references: [id]) - informasiUmumId String - layananunggulan LayananUnggulan @relation(fields: [layananUnggulanId], references: [id]) - layananUnggulanId String - dokterdantenagamedis DokterdanTenagaMedis @relation(fields: [dokterdanTenagaMedisId], references: [id]) - dokterdanTenagaMedisId String - fasilitaspendukung FasilitasPendukung @relation(fields: [fasilitasPendukungId], references: [id]) - fasilitasPendukungId String - prosedurpendaftaran ProsedurPendaftaran @relation(fields: [prosedurPendaftaranId], references: [id]) - prosedurPendaftaranId String - tarifdanlayanan TarifDanLayanan @relation(fields: [tarifDanLayananId], references: [id]) - tarifDanLayananId String + id String @id @default(cuid()) + name String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime @default(now()) + isActive Boolean @default(true) + informasiumum InformasiUmum @relation(fields: [informasiUmumId], references: [id]) + informasiUmumId String + layananunggulan LayananUnggulan @relation(fields: [layananUnggulanId], references: [id]) + layananUnggulanId String + dokterdantenagamedis DokterdanTenagaMedis[] @relation("Dokter") + fasilitaspendukung FasilitasPendukung @relation(fields: [fasilitasPendukungId], references: [id]) + fasilitasPendukungId String + prosedurpendaftaran ProsedurPendaftaran @relation(fields: [prosedurPendaftaranId], references: [id]) + prosedurPendaftaranId String + tarifdanlayanan TarifDanLayanan[] @relation("Tarif") } model InformasiUmum { @@ -826,15 +824,20 @@ model LayananUnggulan { } model DokterdanTenagaMedis { - id String @id @default(cuid()) - name String - specialist String - jadwal String - createdAt DateTime @default(now()) - updatedAt DateTime @updatedAt - deletedAt DateTime @default(now()) - isActive Boolean @default(true) - FasilitasKesehatan FasilitasKesehatan[] + id String @id @default(cuid()) + name String + specialist String + jadwal String + jadwalLibur String + jamBukaOperasional String + jamTutupOperasional String + jamBukaLibur String + jamTutupLibur String + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + deletedAt DateTime @default(now()) + isActive Boolean @default(true) + FasilitasKesehatan FasilitasKesehatan[] @relation("Dokter") } model FasilitasPendukung { @@ -865,7 +868,7 @@ model TarifDanLayanan { updatedAt DateTime @updatedAt deletedAt DateTime @default(now()) isActive Boolean @default(true) - FasilitasKesehatan FasilitasKesehatan[] + FasilitasKesehatan FasilitasKesehatan[] @relation("Tarif") } // ========================================= JADWAL KEGIATAN ========================================= // diff --git a/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan.ts b/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan.ts index 016f6b28..3aa3224e 100644 --- a/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan.ts +++ b/src/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan.ts @@ -9,29 +9,30 @@ import { z } from "zod"; // Validasi form const templateForm = z.object({ name: z.string().min(1, "Nama harus diisi"), + informasiUmum: z.object({ - fasilitas: z.string().min(1, "Fasilitas harus diisi"), - alamat: z.string().min(1, "Alamat harus diisi"), - jamOperasional: z.string().min(1, "Jam operasional harus diisi"), + fasilitas: z.string().min(1), + alamat: z.string().min(1), + jamOperasional: z.string().min(1), }), + layananUnggulan: z.object({ - content: z.string().min(1, "Layanan unggulan harus diisi"), - }), - dokterdanTenagaMedis: z.object({ - name: z.string().min(1, "Nama dokter harus diisi"), - specialist: z.string().min(1, "Spesialis harus diisi"), - jadwal: z.string().min(1, "Jadwal harus diisi"), + content: z.string().min(1), }), + + // NOW ARRAY OF STRING (ID) + dokterdanTenagaMedis: z.array(z.string()).min(1, "Minimal pilih 1 dokter"), + fasilitasPendukung: z.object({ - content: z.string().min(1, "Fasilitas pendukung harus diisi"), + content: z.string().min(1), }), + prosedurPendaftaran: z.object({ - content: z.string().min(1, "Prosedur pendaftaran harus diisi"), - }), - tarifDanLayanan: z.object({ - layanan: z.string().min(1, "Layanan harus diisi"), - tarif: z.string().min(1, "Tarif harus diisi"), + content: z.string().min(1), }), + + // NOW ARRAY OF STRING (ID) + tarifDanLayanan: z.array(z.string()).min(1, "Minimal pilih 1 tarif"), }); // Default form kosong @@ -45,21 +46,34 @@ const defaultForm = { layananUnggulan: { content: "", }, - dokterdanTenagaMedis: { - name: "", - specialist: "", - jadwal: "", - }, + + dokterdanTenagaMedis: [] as string[], // ← array kosong + tarifDanLayanan: [] as string[], // ← array kosong + fasilitasPendukung: { content: "", }, prosedurPendaftaran: { content: "", }, - tarifDanLayanan: { - layanan: "", - tarif: "", - }, +}; + +type DokterItem = { + id: string; + name: string; + specialist: string; + jadwal: string; + jadwalLibur: string; + jamBukaOperasional: string; + jamTutupOperasional: string; + jamBukaLibur: string; + jamTutupLibur: string; +}; + +type TarifItem = { + id: string; + layanan: string; + tarif: string; }; const fasilitasKesehatan = proxy({ @@ -186,33 +200,26 @@ const fasilitasKesehatan = proxy({ const result = await res.json(); const data = result.data; - - fasilitasKesehatan.edit.id = data.id; - fasilitasKesehatan.edit.form = { + this.id = data.id; + this.form = { name: data.name, informasiUmum: { fasilitas: data.informasiumum.fasilitas, alamat: data.informasiumum.alamat, jamOperasional: data.informasiumum.jamOperasional, }, - layananUnggulan: { - content: data.layananunggulan.content, - }, - dokterdanTenagaMedis: { - name: data.dokterdantenagamedis.name, - specialist: data.dokterdantenagamedis.specialist, - jadwal: data.dokterdantenagamedis.jadwal, - }, fasilitasPendukung: { content: data.fasilitaspendukung.content, }, prosedurPendaftaran: { content: data.prosedurpendaftaran.content, }, - tarifDanLayanan: { - layanan: data.tarifdanlayanan.layanan, - tarif: data.tarifdanlayanan.tarif, + // map relasi -> array of IDs + layananUnggulan: { + content: data.layananunggulan.content, }, + dokterdanTenagaMedis: data.dokterdantenagamedis?.map((v: DokterItem) => v.id) ?? [], + tarifDanLayanan: data.tarifdanlayanan?.map((v: TarifItem) => v.id) ?? [], }; }, async submit() { @@ -238,22 +245,15 @@ const fasilitasKesehatan = proxy({ layananUnggulan: { content: fasilitasKesehatan.edit.form.layananUnggulan.content, }, - dokterdanTenagaMedis: { - name: fasilitasKesehatan.edit.form.dokterdanTenagaMedis.name, - specialist: - fasilitasKesehatan.edit.form.dokterdanTenagaMedis.specialist, - jadwal: fasilitasKesehatan.edit.form.dokterdanTenagaMedis.jadwal, - }, + dokterdanTenagaMedis: + fasilitasKesehatan.edit.form.dokterdanTenagaMedis, fasilitasPendukung: { content: fasilitasKesehatan.edit.form.fasilitasPendukung.content, }, prosedurPendaftaran: { content: fasilitasKesehatan.edit.form.prosedurPendaftaran.content, }, - tarifDanLayanan: { - layanan: fasilitasKesehatan.edit.form.tarifDanLayanan.layanan, - tarif: fasilitasKesehatan.edit.form.tarifDanLayanan.tarif, - }, + tarifDanLayanan: fasilitasKesehatan.edit.form.tarifDanLayanan, }; const res = await fetch( @@ -320,12 +320,26 @@ const templateDokterForm = z.object({ name: z.string().min(1, "Nama tidak boleh kosong"), specialist: z.string().min(1, "Spesialis tidak boleh kosong"), jadwal: z.string().min(1, "Jadwal tidak boleh kosong"), + jadwalLibur: z.string().min(1, "Jadwal libur tidak boleh kosong"), + jamBukaOperasional: z + .string() + .min(1, "Jam buka operasional tidak boleh kosong"), + jamTutupOperasional: z + .string() + .min(1, "Jam tutup operasional tidak boleh kosong"), + jamBukaLibur: z.string().min(1, "Jam buka libur tidak boleh kosong"), + jamTutupLibur: z.string().min(1, "Jam tutup libur tidak boleh kosong"), }); const defaultDokterForm = { name: "", specialist: "", jadwal: "", + jadwalLibur: "", + jamBukaOperasional: "", + jamTutupOperasional: "", + jamBukaLibur: "", + jamTutupLibur: "", }; const dokter = proxy({ @@ -463,6 +477,11 @@ const dokter = proxy({ name: data.name, specialist: data.specialist, jadwal: data.jadwal, + jadwalLibur: data.jadwalLibur, + jamBukaOperasional: data.jamBukaOperasional, + jamTutupOperasional: data.jamTutupOperasional, + jamBukaLibur: data.jamBukaLibur, + jamTutupLibur: data.jamTutupLibur, }; return data; // Return the loaded data } else { @@ -487,6 +506,11 @@ const dokter = proxy({ name: this.form.name, specialist: this.form.specialist, jadwal: this.form.jadwal, + jadwalLibur: this.form.jadwalLibur, + jamBukaOperasional: this.form.jamBukaOperasional, + jamTutupOperasional: this.form.jamTutupOperasional, + jamBukaLibur: this.form.jamBukaLibur, + jamTutupLibur: this.form.jamTutupLibur, }; const cek = templateDokterForm.safeParse(formData); @@ -567,9 +591,255 @@ const dokter = proxy({ }, }); +const templateTarifForm = z.object({ + tarif: z.string().min(1, "Tarif tidak boleh kosong"), + layanan: z.string().min(1, "Layanan tidak boleh kosong"), +}); + +const defaultTarifForm = { + tarif: "", + layanan: "", +}; + +const tarif = proxy({ + create: { + form: defaultTarifForm, + loading: false, + async create() { + const cek = templateTarifForm.safeParse(tarif.create.form); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v) => `${v.path.join(".")}`) + .join("\n")}] required`; + toast.error(err); + return null; + } + try { + tarif.create.loading = true; + const res = await ApiFetch.api.kesehatan.tarifdanlayanan["create"].post( + tarif.create.form + ); + + if (res.status === 200) { + const id = res.data?.data; + if (id) { + toast.success("Sukses menambahkan"); + tarif.create.form = { ...defaultTarifForm }; + tarif.findMany.load(); + return id; + } + } + toast.error("failed create"); + return null; + } catch (error) { + console.log((error as Error).message); + return null; + } finally { + tarif.create.loading = false; + } + }, + }, + findMany: { + data: null as + | Prisma.TarifDanLayananGetPayload<{ + omit: { + isActive: true; + }; + }>[] + | null, + page: 1, + totalPages: 1, + loading: false, + search: "", + load: async (page = 1, limit = 10, search = "") => { + tarif.findMany.loading = true; // ✅ Akses langsung via nama path + tarif.findMany.page = page; + tarif.findMany.search = search; + + try { + const query: any = { page, limit }; + if (search) query.search = search; + + const res = await ApiFetch.api.kesehatan.tarifdanlayanan[ + "findMany" + ].get({ query }); + + if (res.status === 200 && res.data?.success) { + tarif.findMany.data = res.data.data ?? []; + tarif.findMany.totalPages = res.data.totalPages ?? 1; + } else { + tarif.findMany.data = []; + tarif.findMany.totalPages = 1; + } + } catch (err) { + console.error("Gagal fetch tarif dan layanan paginated:", err); + tarif.findMany.data = []; + tarif.findMany.totalPages = 1; + } finally { + tarif.findMany.loading = false; + } + }, + }, + findUnique: { + data: null as Prisma.TarifDanLayananGetPayload<{ + omit: { isActive: true }; + }> | null, + async load(id: string) { + try { + const res = await fetch(`/api/kesehatan/tarifdanlayanan/${id}`); + if (res.ok) { + const data = await res.json(); + tarif.findUnique.data = data.data ?? null; + } else { + console.error( + "Failed to fetch tarif dan layanan", + res.statusText + ); + tarif.findUnique.data = null; + } + } catch (error) { + console.error("Error fetching tarif dan layanan", error); + tarif.findUnique.data = null; + } + }, + }, + update: { + id: "", + form: { ...defaultTarifForm }, + loading: false, + async load(id: string) { + if (!id) { + toast.warn("ID tidak valid"); + return null; + } + + try { + const response = await fetch(`/api/kesehatan/tarifdanlayanan/${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 = { + tarif: data.tarif, + layanan: data.layanan + }; + return data; // Return the loaded data + } else { + throw new Error(result?.message || "Gagal memuat data"); + } + } catch (error) { + console.error("Error loading tarif dan layanan:", error); + toast.error( + error instanceof Error ? error.message : "Gagal memuat data" + ); + return null; + } + }, + async submit() { + const id = this.id; + if (!id) { + toast.warn("ID tidak valid"); + return null; + } + + const formData = { + tarif: this.form.tarif, + layanan: this.form.layanan + }; + + const cek = templateTarifForm.safeParse(formData); + if (!cek.success) { + const err = `[${cek.error.issues + .map((v: any) => `${v.path.join(".")}`) + .join("\n")}] required`; + toast.error(err); + return null; + } + + try { + this.loading = true; + const res = await fetch(`/api/kesehatan/tarifdanlayanan/${id}`, { + method: "PUT", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify(formData), + }); + + const result = await res.json(); + + if (!res.ok || !result?.success) { + throw new Error(result?.message || "Gagal update data"); + } + + toast.success("Berhasil update data!"); + await tarif.findMany.load(); + return result.data; + } catch (error) { + console.error("Update error:", error); + toast.error("Gagal update data tarif dan layanan"); + throw error; + } finally { + this.loading = false; + } + }, + }, + delete: { + loading: false, + async byId(id: string) { + if (!id) { + return toast.warn("ID tidak valid"); + } + try { + tarif.delete.loading = true; + + const response = await fetch( + `/api/kesehatan/tarifdanlayanan/del/${id}`, + { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + } + ); + + const result = await response.json(); + + if (response.ok && result?.success) { + toast.success( + result.message || "tarif dan layanan berhasil dihapus" + ); + await tarif.findMany.load(); // refresh list + } else { + toast.error( + result?.message || "Gagal menghapus tarif dan layanan" + ); + } + } catch (error) { + console.error("Gagal delete:", error); + toast.error("Terjadi kesalahan saat menghapus tarif dan layanan"); + } finally { + tarif.delete.loading = false; + } + }, + }, +}); + const fasilitasKesehatanState = proxy({ fasilitasKesehatan, dokter, + tarif }); export default fasilitasKesehatanState; diff --git a/src/app/admin/(dashboard)/desa/berita/kategori-berita/[id]/page.tsx b/src/app/admin/(dashboard)/desa/berita/kategori-berita/[id]/page.tsx index 2e86057b..4924f9e6 100644 --- a/src/app/admin/(dashboard)/desa/berita/kategori-berita/[id]/page.tsx +++ b/src/app/admin/(dashboard)/desa/berita/kategori-berita/[id]/page.tsx @@ -111,7 +111,7 @@ function EditKategoriBerita() { {/* Form Wrapper */} (); const [isSubmitting, setIsSubmitting] = useState(false); - const [formData, setFormData] = useState({ + const [formData, setFormData] = useState({ name: '', informasiUmum: { fasilitas: '', alamat: '', jamOperasional: '' }, layananUnggulan: { content: '' }, - dokterdanTenagaMedis: { name: '', specialist: '', jadwal: '' }, + dokterdanTenagaMedis: [], fasilitasPendukung: { content: '' }, prosedurPendaftaran: { content: '' }, - tarifDanLayanan: { layanan: '', tarif: '' }, + tarifDanLayanan: [], }); - const [originalData, setOriginalData] = useState({ - name: '', - informasiUmum: { fasilitas: '', alamat: '', jamOperasional: '' }, - layananUnggulan: { content: '' }, - dokterdanTenagaMedis: { name: '', specialist: '', jadwal: '' }, - fasilitasPendukung: { content: '' }, - prosedurPendaftaran: { content: '' }, - tarifDanLayanan: { layanan: '', tarif: '' }, - }); + // Load data fasilitas & daftar dokter/tarif + useShallowEffect(() => { + const loadAll = async () => { + const id = params?.id; + if (!id) return; - // Helper untuk update nested state - const updateForm = ( - key: K, - value: FasilitasKesehatanFormBase[K] - ) => setFormData(prev => ({ ...prev, [key]: value })); + // Load dokter & tarif (untuk opsi MultiSelect) + await Promise.all([ + dokterState.findMany.load(), + tarifState.findMany.load(), + ]); - const updateNested = < - K extends keyof FasilitasKesehatanFormBase, - N extends keyof FasilitasKesehatanFormBase[K] - >(key: K, nestedKey: N, value: FasilitasKesehatanFormBase[K][N]) => - setFormData(prev => ({ - ...prev, - [key]: { ...prev[key] as object, [nestedKey]: value }, - })); + // Load data fasilitas + await state.edit.load(id); + const loaded = state.edit.form; + if (loaded) { + setFormData({ + name: loaded.name, + informasiUmum: loaded.informasiUmum, + layananUnggulan: loaded.layananUnggulan, + dokterdanTenagaMedis: loaded.dokterdanTenagaMedis || [], + fasilitasPendukung: loaded.fasilitasPendukung, + prosedurPendaftaran: loaded.prosedurPendaftaran, + tarifDanLayanan: loaded.tarifDanLayanan || [], + }); + } + }; - const deepClone = (obj: any): any => { - try { - return JSON.parse(JSON.stringify(obj)); - } catch (error) { - console.warn('Gagal deep clone dengan JSON fallback:', error); - return obj; // fallback (berisiko shared reference) + loadAll(); + }, [params?.id]); + + const updateForm = ( + field: K, + value: EditFasilitasKesehatanForm[K] + ) => { + setFormData(prev => ({ ...prev, [field]: value })); + }; + + const handleReset = () => { + const loaded = state.edit.form; + if (loaded) { + setFormData({ + name: loaded.name, + informasiUmum: loaded.informasiUmum, + layananUnggulan: loaded.layananUnggulan, + dokterdanTenagaMedis: loaded.dokterdanTenagaMedis || [], + fasilitasPendukung: loaded.fasilitasPendukung, + prosedurPendaftaran: loaded.prosedurPendaftaran, + tarifDanLayanan: loaded.tarifDanLayanan || [], + }); + toast.info('Form dikembalikan ke data awal'); } }; - // Load data - useEffect(() => { - const load = async () => { - const id = params?.id as string; - if (!id) return; - - try { - await state.edit.load(id); - const loadedData = state.edit.form; - - if (!loadedData) { - toast.error('Data tidak ditemukan'); - return; - } - - // Gunakan JSON fallback untuk deep clone - const clonedData = deepClone(loadedData) as FasilitasKesehatanFormBase; - - setFormData(clonedData); - setOriginalData(clonedData); - } catch (err) { - console.error(err); - toast.error('Gagal memuat data fasilitas kesehatan'); - } - }; - - load(); - }, [params?.id]); - - const handleResetForm = () => { - setFormData({ - name: originalData.name, - informasiUmum: - { - fasilitas: originalData.informasiUmum.fasilitas, - alamat: originalData.informasiUmum.alamat, - jamOperasional: originalData.informasiUmum.jamOperasional - }, - layananUnggulan: { content: originalData.layananUnggulan.content }, - dokterdanTenagaMedis: { - name: originalData.dokterdanTenagaMedis.name, - specialist: originalData.dokterdanTenagaMedis.specialist, - jadwal: originalData.dokterdanTenagaMedis.jadwal - }, - fasilitasPendukung: { content: originalData.fasilitasPendukung.content }, - prosedurPendaftaran: { content: originalData.prosedurPendaftaran.content }, - tarifDanLayanan: { - layanan: originalData.tarifDanLayanan.layanan, - tarif: originalData.tarifDanLayanan.tarif - }, - }); - toast.info("Form dikembalikan ke data awal"); - }; - - // Submit - const handleSubmit = async () => { + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); try { setIsSubmitting(true); - state.edit.form = { ...state.edit.form, ...formData }; + + // Update state Valtio + state.edit.form = { ...formData }; + const success = await state.edit.submit(); if (success) { toast.success('Fasilitas kesehatan berhasil diperbarui!'); @@ -159,14 +124,14 @@ function EditFasilitasKesehatan() { } } catch (err) { console.error(err); - toast.error('Terjadi kesalahan saat memperbarui data fasilitas kesehatan'); + toast.error('Gagal memperbarui data'); } finally { setIsSubmitting(false); } }; return ( - + {/* Header */} - - {/* Tombol Simpan */} + + Edit Fasilitas Kesehatan + + + + {/* Form */} + + + handleChange("name", e.target.value)} + required + /> + + handleChange("jadwal", e.target.value)} + required + /> + + handleChange("jadwalLibur", e.target.value)} + required + /> + + handleChange("jamBukaOperasional", e.target.value)} + required + /> + + handleChange("jamTutupOperasional", e.target.value)} + required + /> + + handleChange("jamBukaLibur", e.target.value)} + required + /> + + handleChange("jamTutupLibur", e.target.value)} + required + /> + {/* Tombol Simpan */} + + {/* Tombol Batal */} + + + {/* Tombol Simpan */} + + + + + ); } -export default Page; +export default EditDokterTenagaMedis; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/page.tsx index 69da2f21..8add7c1c 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/[id]/page.tsx @@ -1,11 +1,165 @@ -import React from 'react'; +'use client' +import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; +import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; +import colors from '@/con/colors'; +import { + Box, + Button, + Group, + Paper, + Skeleton, + Stack, + Text +} from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; +import { IconArrowBack, IconEdit, IconTrash } from '@tabler/icons-react'; +import { useParams, useRouter } from 'next/navigation'; +import { useState } from 'react'; +import { useProxy } from 'valtio/utils'; + +function DetailDokterTenagaMedis() { + const params = useParams(); + const router = useRouter(); + const state = useProxy(fasilitasKesehatanState.dokter); + const [modalHapus, setModalHapus] = useState(false); + const [selectedId, setSelectedId] = useState(null); + + useShallowEffect(() => { + state.findUnique.load(params?.id as string); + }, []); + + const handleHapus = () => { + if (selectedId) { + state.delete.byId(selectedId); + setModalHapus(false); + setSelectedId(null); + router.push( + '/admin/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis' + ); + } + }; + + if (!state.findUnique.data) { + return ( + + + + ); + } + + const data = state.findUnique.data; -function Page() { return ( -
- Page -
+ + {/* Tombol Back */} + + + {/* Wrapper Detail */} + + + + Detail Dokter & Tenaga Medis + + + + + + Nama Dokter + {data.name || '-'} + + + + Specialist + {data.specialist || '-'} + + + + Jadwal + + + + + Jadwal Libur + + + + + Jam Buka Operasional + + + + + Jam Tutup Operasional + + + + + Jam Buka Libur + + + + + Jam Tutup Libur + + + + {/* Aksi */} + + + + + + + + + + + {/* Modal Konfirmasi Hapus */} + setModalHapus(false)} + onConfirm={handleHapus} + text="Apakah anda yakin ingin menghapus dokter & tenaga medis ini?" + /> + ); } -export default Page; +export default DetailDokterTenagaMedis; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/create/page.tsx index 3e33d305..ed4a1081 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/create/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/create/page.tsx @@ -1,71 +1,184 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client' -import CreateEditor from '@/app/admin/(dashboard)/_com/createEditor'; import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; 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 { ActionIcon, Box, Button, Group, Loader, Paper, Stack, TextInput, Title } from '@mantine/core'; +import { TimeInput } from '@mantine/dates'; +import { IconArrowBack, IconClock } from '@tabler/icons-react'; +import { useRouter } from 'next/navigation'; +import { useRef, useState } from 'react'; +import { toast } from 'react-toastify'; import { useProxy } from 'valtio/utils'; function CreateDokter() { - const params = useParams() const createState = useProxy(fasilitasKesehatanState.dokter) const router = useRouter(); + const [isSubmitting, setIsSubmitting] = useState(false); const resetForm = () => { createState.create.create.form = { name: "", specialist: "", jadwal: "", + jadwalLibur: "", + jamBukaOperasional: "", + jamTutupOperasional: "", + jamBukaLibur: "", + jamTutupLibur: "", }; }; + const refBuka = useRef(null); + const refTutup = useRef(null); + const refBukaLibur = useRef(null); + const refTutupLibur = useRef(null); + + const picker = (ref: any) => ( + ref.current?.showPicker()}> + + + ); + + const handleSubmit = async () => { - await createState.create.create.create(); - resetForm(); - router.push(`/admin/kesehatan/fasilitas-kesehatan/${params?.id}/dokter-tenaga-medis`) + try { + setIsSubmitting(true); + await createState.create.create.create(); + toast.success('Data berhasil disimpan'); + resetForm(); + router.push(`/admin/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis`) + } catch (error) { + console.error(error); + toast.error('Gagal menyimpan data'); + } finally { + setIsSubmitting(false); + } }; return ( - - - - + + Tambah Data Dokter & Tenaga Medis + + - - - Create Dokter + {/* Form */} + + Nama Dokter} - placeholder="masukkan nama dokter" + label={"Nama Dokter"} + placeholder="Masukkan nama dokter" value={createState.create.create.form.name} - onChange={(e) => { - createState.create.create.form.name = e.target.value; - }} + onChange={(e) => (createState.create.create.form.name = e.target.value)} + required /> - Specialist + + {/* Informasi Umum */} + Specialist} - placeholder="masukkan specialist" + label="Specialist" + placeholder="Masukkan specialist" value={createState.create.create.form.specialist} - onChange={(e) => { - createState.create.create.form.specialist = e.target.value; - }} + onChange={(e) => (createState.create.create.form.specialist = e.target.value)} + required /> - - Jadwal - { - createState.create.create.form.jadwal = htmlContent; + + (createState.create.create.form.jadwal = e.target.value)} + required + /> + + (createState.create.create.form.jadwalLibur = e.target.value)} + required + /> + + (createState.create.create.form.jamBukaOperasional = e.target.value)} + required + /> + + (createState.create.create.form.jamTutupOperasional = e.target.value)} + required + /> + + (createState.create.create.form.jamBukaLibur = e.target.value)} + required + /> + + (createState.create.create.form.jamTutupLibur = e.target.value)} + required + /> + + {/* Submit */} + + {/* Tombol Batal */} + + + {/* Tombol Simpan */} + + > + {isSubmitting ? : 'Simpan'} + + diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/page.tsx index 94a1ad90..87957722 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis/page.tsx @@ -1,13 +1,12 @@ 'use client' import colors from '@/con/colors'; -import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { Box, Button, Center, Group, Pagination, Paper, Skeleton, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; import { useShallowEffect } from '@mantine/hooks'; -import { IconArrowBack, IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; +import { IconArrowBack, IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useProxy } from 'valtio/utils'; import HeaderSearch from '@/app/admin/(dashboard)/_com/header'; -import JudulList from '@/app/admin/(dashboard)/_com/judulList'; import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; import { useState } from 'react'; @@ -18,7 +17,7 @@ function DokterTenagaMedis() { return ( - @@ -60,49 +59,101 @@ function ListDokterTenagaMedis({ search }: { search: string }) { } return ( - - - - - - - - Fasilitas Kesehatan - Alamat - Jam Operasional - Detail - - - - {filteredData.map((item) => ( + + {/* Judul + Tombol Tambah */} + + Daftar Dokter dan Tenaga Medis + + + + {/* Tabel */} + +
+ + + Nama Dokter + Spesialis + Jadwal + Aksi + + + + {filteredData.length > 0 ? ( + filteredData.map((item) => ( - {item.name} - {item.specialist} - + + + {item.name} + + - - ))} - -
-
-
+ )) + ) : ( + + +
+ + Tidak ada fasilitas kesehatan yang cocok + +
+
+
+ )} + + +
+ + {/* Pagination */}
load(newPage)} // ini penting! + onChange={(newPage) => { + load(newPage, 10, search); + window.scrollTo({ top: 0, behavior: 'smooth' }); + }} total={totalPages} mt="md" mb="md" + color="blue" + radius="md" />
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/page.tsx index be757981..5943590e 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/page.tsx @@ -1,9 +1,12 @@ 'use client' import colors from '@/con/colors'; import { + ActionIcon, Box, Button, Center, + Grid, + GridCol, Group, Pagination, Paper, @@ -16,30 +19,52 @@ import { TableThead, TableTr, Text, - Title + TextInput, + Title, + Tooltip } from '@mantine/core'; import { useShallowEffect } from '@mantine/hooks'; -import { IconDeviceImacCog, IconPlus, IconSearch } from '@tabler/icons-react'; +import { IconCoin, IconDeviceImacCog, IconPlus, IconReportMedical, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import { useProxy } from 'valtio/utils'; -import HeaderSearch from '../../../_com/header'; import fasilitasKesehatanState from '../../../_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; function FasilitasKesehatan() { const [search, setSearch] = useState(""); - + const router = useRouter() return ( - {/* Header Search */} - } - value={search} - onChange={(e) => setSearch(e.currentTarget.value)} - /> + + + Fasilitas Kesehatan + + + + + router.push('/admin/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/dokter-tenaga-medis')} size="lg" radius="xl" color="green.6"> + + + + + router.push('/admin/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan')} size="lg" radius="xl" color="blue.6"> + + + + + } + w="133%" + value={search} + onChange={(e) => setSearch(e.currentTarget.value)} + /> + + + + @@ -54,6 +79,7 @@ function ListFasilitasKesehatan({ search }: { search: string }) { const { data, page, totalPages, loading, load } = stateFasilitasKesehatan.findMany; useShallowEffect(() => { + load(page, 10, search); }, [page, search]); @@ -93,8 +119,8 @@ function ListFasilitasKesehatan({ search }: { search: string }) { Fasilitas Kesehatan - Dokter - Layanan + Jumlah Dokter + Jumlah Layanan Aksi @@ -111,13 +137,17 @@ function ListFasilitasKesehatan({ search }: { search: string }) { - {item.dokterdantenagamedis?.name || '-'} + {item.dokterdantenagamedis?.length + ? `${item.dokterdantenagamedis.length} dokter` + : '-'} - {item.tarifdanlayanan?.layanan || '-'} + {item.tarifdanlayanan?.length + ? `${item.tarifdanlayanan.length} layanan` + : '-'} @@ -141,7 +171,7 @@ function ListFasilitasKesehatan({ search }: { search: string }) {
- + Tidak ada fasilitas kesehatan yang cocok
diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/[id]/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/[id]/page.tsx new file mode 100644 index 00000000..7ff34a37 --- /dev/null +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/[id]/page.tsx @@ -0,0 +1,173 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' + +import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; +import colors from '@/con/colors'; +import { + Box, + Button, + Group, + Loader, + Paper, + Stack, + 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 EditTarifLayanan() { + const editState = useProxy(fasilitasKesehatanState.tarif); + const router = useRouter(); + const params = useParams(); + const [isSubmitting, setIsSubmitting] = useState(false); + + const [originalData, setOriginalData] = useState({ + tarif: '', + layanan: '' + }); + + const [formData, setFormData] = useState({ + tarif: '', + layanan: '' + }); + + useEffect(() => { + const loadTarifLayanan = async () => { + const id = params?.id as string; + if (!id) return; + + try { + const data = await editState.update.load(id); + if (data) { + setFormData({ + tarif: data.tarif || '', + layanan: data.layanan || '', + }); + setOriginalData({ + tarif: data.tarif || '', + layanan: data.layanan || '', + }); + } + } catch (error) { + console.error('Error loading tarif layanan:', error); + toast.error('Gagal memuat data tarif layanan'); + } + }; + + loadTarifLayanan(); + }, [params?.id]); + + const handleChange = (field: string, value: string) => { + setFormData((prev) => ({ ...prev, [field]: value })); + }; + + const handleResetForm = () => { + setFormData({ + tarif: originalData.tarif, + layanan: originalData.layanan, + }); + toast.info('Form dikembalikan ke data awal'); + }; + + const handleSubmit = async () => { + try { + setIsSubmitting(true); + // update global state hanya saat submit + editState.update.form = { + ...editState.update.form, + tarif: formData.tarif, + layanan: formData.layanan, + }; + + await editState.update.submit(); + toast.success('Tarif Layanan berhasil diperbarui!'); + router.push('/admin/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan'); + } catch (error) { + console.error('Error updating tarif layanan:', error); + toast.error('Terjadi kesalahan saat memperbarui tarif layanan'); + } finally { + setIsSubmitting(false); + } + }; + + return ( + + {/* Back Button + Title */} + + + + Edit Tarif Layanan + + + + {/* Form Wrapper */} + + + handleChange('layanan', e.target.value)} + required + /> + + handleChange('tarif', e.target.value)} + required + /> + + + + + {/* Tombol Simpan */} + + + + + + ); +} + +export default EditTarifLayanan; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/create/page.tsx new file mode 100644 index 00000000..60d23e1f --- /dev/null +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/create/page.tsx @@ -0,0 +1,119 @@ +'use client'; +import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; +import colors from '@/con/colors'; +import { + Box, + Button, + Group, + Loader, + Paper, + Stack, + TextInput, + Title +} from '@mantine/core'; +import { IconArrowBack } from '@tabler/icons-react'; +import { useRouter } from 'next/navigation'; +import { useState } from 'react'; +import { toast } from 'react-toastify'; +import { useProxy } from 'valtio/utils'; + +function CreateTarifLayanan() { + const createState = useProxy(fasilitasKesehatanState.tarif); + const router = useRouter(); + const [isSubmitting, setIsSubmitting] = useState(false); + + const resetForm = () => { + createState.create.form = { + tarif: '', + layanan: '', + }; + }; + + const handleSubmit = async () => { + setIsSubmitting(true); + try { + await createState.create.create(); + resetForm(); + router.push('/admin/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan'); + } catch (error) { + console.error('Error creating tarif layanan:', error); + toast.error('Gagal menambahkan tarif layanan'); + } finally { + setIsSubmitting(false); + } + }; + + return ( + + {/* Header dengan back button */} + + + + Tambah Tarif Layanan + + + + {/* Form utama */} + + + (createState.create.form.layanan = e.target.value)} + required + /> + (createState.create.form.tarif = e.target.value)} + required + /> + + + + + {/* Tombol Simpan */} + + + + + + ); +} + +export default CreateTarifLayanan; diff --git a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/page.tsx b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/page.tsx index eb82a5f9..844dc2c2 100644 --- a/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/data-kesehatan-warga/fasilitas_kesehatan/tarif-layanan/page.tsx @@ -1,13 +1,13 @@ 'use client' import colors from '@/con/colors'; -import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { Box, Button, Center, Group, Pagination, Paper, Skeleton, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; import { useShallowEffect } from '@mantine/hooks'; -import { IconArrowBack, IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; +import { IconArrowBack, IconEdit, IconPlus, IconSearch, IconTrash } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useProxy } from 'valtio/utils'; import HeaderSearch from '@/app/admin/(dashboard)/_com/header'; -import JudulList from '@/app/admin/(dashboard)/_com/judulList'; +import { ModalKonfirmasiHapus } from '@/app/admin/(dashboard)/_com/modalKonfirmasiHapus'; import fasilitasKesehatanState from '@/app/admin/(dashboard)/_state/kesehatan/data_kesehatan_warga/fasilitasKesehatan'; import { useState } from 'react'; @@ -18,12 +18,12 @@ function TarifLayanan() { return ( - } value={search} @@ -35,8 +35,11 @@ function TarifLayanan() { } function ListTarifLayanan({ search }: { search: string }) { - const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState.dokter) + const stateFasilitasKesehatan = useProxy(fasilitasKesehatanState.tarif); const router = useRouter(); + const [modalHapus, setModalHapus] = useState(false); + const [selectedId, setSelectedId] = useState(null); + const { data, loading, @@ -49,6 +52,15 @@ function ListTarifLayanan({ search }: { search: string }) { load(page, 10, search) }, [page, search]) + const handleDelete = () => { + if (selectedId) { + stateFasilitasKesehatan.delete.byId(selectedId); + setModalHapus(false); + setSelectedId(null); + load(page, 10, search); + } + }; + const filteredData = data || [] if (loading || !data) { @@ -60,51 +72,116 @@ function ListTarifLayanan({ search }: { search: string }) { } return ( - - - - - - - - Fasilitas Kesehatan - Alamat - Jam Operasional - Detail - - - - {filteredData.map((item) => ( + + {/* Judul + Tombol Tambah */} + + Daftar Tarif dan Layanan + + + + {/* Tabel */} + +
+ + + Layanan + Tarif + Edit + Hapus + + + + {filteredData.length > 0 ? ( + filteredData.map((item) => ( - {item.name} - {item.specialist} - + + {item.layanan || '-'} + - + + + - ))} - -
-
-
+ )) + ) : ( + + +
+ + Tidak ada fasilitas kesehatan yang cocok + +
+
+
+ )} + + +
+ + {/* Pagination */}
load(newPage)} // ini penting! + onChange={(newPage) => { + load(newPage, 10, search); + window.scrollTo({ top: 0, behavior: 'smooth' }); + }} total={totalPages} mt="md" mb="md" + color="blue" + radius="md" />
+ setModalHapus(false)} + onConfirm={handleDelete} + text="Apakah anda yakin ingin menghapus tarif layanan ini?" + />
) } diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/create.ts index 479a61cf..820771ce 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/create.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/create.ts @@ -1,18 +1,16 @@ import prisma from "@/lib/prisma"; import { Context } from "elysia"; -type FasilitasKesehatanInput = { - name: string; - informasiUmum: { fasilitas: string; alamat: string; jamOperasional: string }; - layananUnggulan: { content: string }; - dokterdanTenagaMedis: { name: string; specialist: string; jadwal: string }; - fasilitasPendukung: { content: string }; - prosedurPendaftaran: { content: string }; - tarifDanLayanan: { layanan: string; tarif: string }; -}; - const fasilitasKesehatanCreate = async (context: Context) => { - const body = await context.body as FasilitasKesehatanInput; + const body = (await context.body) as { + name: string; + informasiUmum: { fasilitas: string; alamat: string; jamOperasional: string }; + layananUnggulan: { content: string }; + dokterdanTenagaMedis: string[]; // ← ARRAY OF ID + fasilitasPendukung: { content: string }; + prosedurPendaftaran: { content: string }; + tarifDanLayanan: string[]; // ← ARRAY OF ID + }; const { name, @@ -24,25 +22,30 @@ const fasilitasKesehatanCreate = async (context: Context) => { tarifDanLayanan, } = body; - // Buat masing-masing relasi terlebih dahulu - const [createdInformasiUmum, createdLayananUnggulan, createdDokter, createdPendukung, createdProsedur, createdTarif] = await Promise.all([ - prisma.informasiUmum.create({ data: informasiUmum }), - prisma.layananUnggulan.create({ data: layananUnggulan }), - prisma.dokterdanTenagaMedis.create({ data: dokterdanTenagaMedis }), - prisma.fasilitasPendukung.create({ data: fasilitasPendukung }), - prisma.prosedurPendaftaran.create({ data: prosedurPendaftaran }), - prisma.tarifDanLayanan.create({ data: tarifDanLayanan }), - ]); + // CREATE SINGLE DATA + const [createdInformasi, createdUnggulan, createdPendukung, createdProsedur] = + await Promise.all([ + prisma.informasiUmum.create({ data: informasiUmum }), + prisma.layananUnggulan.create({ data: layananUnggulan }), + prisma.fasilitasPendukung.create({ data: fasilitasPendukung }), + prisma.prosedurPendaftaran.create({ data: prosedurPendaftaran }), + ]); + // ✅ CUKUP CONNECT KE ID YANG SUDAH ADA const fasilitas = await prisma.fasilitasKesehatan.create({ data: { name, - informasiUmumId: createdInformasiUmum.id, - layananUnggulanId: createdLayananUnggulan.id, - dokterdanTenagaMedisId: createdDokter.id, + informasiUmumId: createdInformasi.id, + layananUnggulanId: createdUnggulan.id, fasilitasPendukungId: createdPendukung.id, prosedurPendaftaranId: createdProsedur.id, - tarifDanLayananId: createdTarif.id, + + dokterdantenagamedis: { + connect: dokterdanTenagaMedis.map(id => ({ id })), // ← langsung dari input + }, + tarifdanlayanan: { + connect: tarifDanLayanan.map(id => ({ id })), // ← langsung dari input + }, }, include: { informasiumum: true, diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/del.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/del.ts index 349c46ce..4096558b 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/del.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/del.ts @@ -2,42 +2,14 @@ import prisma from "@/lib/prisma"; import { Context } from "elysia"; const fasilitasKesehatanDelete = async (context: Context) => { - const id = context.params?.id as string; + const id = context.params?.id as string; - if (!id) { - return { - status: 400, - message: "ID tidak ditemukan", - } - } + const data = await prisma.fasilitasKesehatan.findUnique({ where: { id } }); + if (!data) return { status: 404, message: "Data tidak ditemukan" }; - const fasilitasKesehatan = await prisma.fasilitasKesehatan.findUnique({ - where: { id }, - include: { - informasiumum: true, - layananunggulan: true, - dokterdantenagamedis: true, - fasilitaspendukung: true, - prosedurpendaftaran: true, - tarifdanlayanan: true, - } - }) + await prisma.fasilitasKesehatan.delete({ where: { id } }); - if (!fasilitasKesehatan) { - return { - status: 404, - message: "Fasilitas kesehatan tidak ditemukan", - } - } + return { success: true, message: "Berhasil dihapus" }; +}; - await prisma.fasilitasKesehatan.delete({ - where: { id }, - }) - - return { - status: 200, - success: true, - message: "Fasilitas kesehatan berhasil dihapus", - } -} -export default fasilitasKesehatanDelete \ No newline at end of file +export default fasilitasKesehatanDelete; diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/create.ts index 4852439d..19cf9c05 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/create.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/create.ts @@ -5,6 +5,11 @@ type FormCreate = { name: string; specialist: string; jadwal: string; + jadwalLibur: string; + jamBukaOperasional: string; + jamTutupOperasional: string; + jamBukaLibur: string; + jamTutupLibur: string; }; export default async function dokterTenagaMedisCreate(context: Context) { @@ -15,11 +20,21 @@ export default async function dokterTenagaMedisCreate(context: Context) { name: body.name, specialist: body.specialist, jadwal: body.jadwal, + jadwalLibur: body.jadwalLibur, + jamBukaOperasional: body.jamBukaOperasional, + jamTutupOperasional: body.jamTutupOperasional, + jamBukaLibur: body.jamBukaLibur, + jamTutupLibur: body.jamTutupLibur, }, select: { name: true, specialist: true, jadwal: true, + jadwalLibur: true, + jamBukaOperasional: true, + jamTutupOperasional: true, + jamBukaLibur: true, + jamTutupLibur: true, } }); diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/findMany.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/findMany.ts index 0e9ce6dd..ad250062 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/findMany.ts @@ -19,6 +19,7 @@ async function dokterTenagaMedisFindMany(context: Context) { { name: { contains: search, mode: 'insensitive' } }, { specialist: { contains: search, mode: 'insensitive' } }, { jadwal: { contains: search, mode: 'insensitive' } }, + { jadwalLibur: { contains: search, mode: 'insensitive' } }, ]; } diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/index.ts index b0c4760a..58817969 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/index.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/index.ts @@ -19,6 +19,11 @@ const DokterTenagaMedis = new Elysia({ name: t.String(), specialist: t.String(), jadwal: t.String(), + jadwalLibur: t.String(), + jamBukaOperasional: t.String(), + jamTutupOperasional: t.String(), + jamBukaLibur: t.String(), + jamTutupLibur: t.String(), }), }) .put("/:id", dokterTenagaMedisUpdate, { @@ -26,6 +31,11 @@ const DokterTenagaMedis = new Elysia({ name: t.String(), specialist: t.String(), jadwal: t.String(), + jadwalLibur: t.String(), + jamBukaOperasional: t.String(), + jamTutupOperasional: t.String(), + jamBukaLibur: t.String(), + jamTutupLibur: t.String(), }), }) .delete("/del/:id", dokterTenagaMedisDelete) diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/updt.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/updt.ts index 6db6b37d..68422677 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/updt.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis/updt.ts @@ -5,6 +5,11 @@ type FormUpdate = { name: string; specialist: string; jadwal: string; + jadwalLibur: string; + jamBukaOperasional: string; + jamTutupOperasional: string; + jamBukaLibur: string; + jamTutupLibur: string; } export default async function dokterTenagaMedisUpdate(context: Context) { @@ -18,6 +23,12 @@ export default async function dokterTenagaMedisUpdate(context: Context) { name: body.name, specialist: body.specialist, jadwal: body.jadwal, + jadwalLibur: body.jadwalLibur, + jamBukaOperasional: body.jamBukaOperasional, + jamTutupOperasional: body.jamTutupOperasional, + jamBukaLibur: body.jamBukaLibur, + jamTutupLibur: body.jamTutupLibur, + }, }); return { diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/index.ts index 1eb5badd..e49ce73c 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/index.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/index.ts @@ -1,6 +1,6 @@ import { Elysia, t } from "elysia"; import fasilitasKesehatanCreate from "./create"; -import findManyFasilitasKesehatan from "./findMany"; +import fasilitasKesehatanFindMany from "./findMany"; import findUniqueFasilitasKesehatan from "./findUnique"; import fasilitasKesehatanUpdate from "./updt"; import fasilitasKesehatanDelete from "./del"; @@ -9,42 +9,61 @@ const FasilitasKesehatan = new Elysia({ prefix: "fasilitas-kesehatan", tags: ["Kesehatan/Fasilitas Kesehatan"], }) + + // ========================== + // CREATE + // ========================== .post("/create", fasilitasKesehatanCreate, { body: t.Object({ name: t.String(), + informasiUmum: t.Object({ fasilitas: t.String(), alamat: t.String(), jamOperasional: t.String(), }), + layananUnggulan: t.Object({ content: t.String(), }), - dokterdanTenagaMedis: t.Object({ - name: t.String(), - specialist: t.String(), - jadwal: t.String(), - }), + + dokterdanTenagaMedis: t.Array(t.String()), // FIX karena create pakai array of string + fasilitasPendukung: t.Object({ content: t.String(), }), + prosedurPendaftaran: t.Object({ content: t.String(), }), - tarifDanLayanan: t.Object({ - layanan: t.String(), - tarif: t.String(), - }), + + tarifDanLayanan: t.Array(t.String()), // FIX karena create pakai array of string }), }) - .get("/find-many", findManyFasilitasKesehatan) + + // ========================== + // FIND MANY + // ========================== + .get("/find-many", fasilitasKesehatanFindMany) + + // ========================== + // DELETE + // ========================== .delete("/del/:id", fasilitasKesehatanDelete) + + // ========================== + // FIND UNIQUE + // ========================== .get("/:id", async (context) => { const response = await findUniqueFasilitasKesehatan( new Request(context.request) ); return response; }) + + // ========================== + // UPDATE + // ========================== .put( "/:id", async (context) => { @@ -54,29 +73,30 @@ const FasilitasKesehatan = new Elysia({ { body: t.Object({ name: t.String(), + informasiUmum: t.Object({ fasilitas: t.String(), alamat: t.String(), jamOperasional: t.String(), }), + layananUnggulan: t.Object({ content: t.String(), }), - dokterdanTenagaMedis: t.Object({ - name: t.String(), - specialist: t.String(), - jadwal: t.String(), - }), + + // FIX → harus array of string (ID dokter) + dokterdanTenagaMedis: t.Array(t.String()), + fasilitasPendukung: t.Object({ content: t.String(), }), + prosedurPendaftaran: t.Object({ content: t.String(), }), - tarifDanLayanan: t.Object({ - layanan: t.String(), - tarif: t.String(), - }), + + // FIX → harus array of string (ID tarif) + tarifDanLayanan: t.Array(t.String()), }), } ); diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/create.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/create.ts new file mode 100644 index 00000000..6df9c882 --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/create.ts @@ -0,0 +1,28 @@ +import prisma from "@/lib/prisma"; +import { Context } from "elysia"; + +type FormCreate = { + layanan: string; + tarif: string; +}; + +export default async function tarifLayananCreate(context: Context) { + const body = context.body as FormCreate; + + const created = await prisma.tarifDanLayanan.create({ + data: { + layanan: body.layanan, + tarif: body.tarif, + }, + select: { + layanan: true, + tarif: true, + } + }); + + return { + success: true, + message: "Sukses menambahkan dokter tenaga medis", + data: created, + }; +} \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/del.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/del.ts new file mode 100644 index 00000000..0b911c51 --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/del.ts @@ -0,0 +1,37 @@ +import prisma from "@/lib/prisma"; +import { Context } from "elysia"; + +export default async function tarifLayananDelete(context: Context) { + + const id = context.params?.id; + + if (!id) { + return { + success: false, + message: "ID tidak ditemukan", + }; + } + + const existing = await prisma.tarifDanLayanan.findUnique({ + where: { + id: id, + }, + }); + + if (!existing) { + return { + success: false, + message: "Data tidak ditemukan", + }; + } + + const deleted = await prisma.tarifDanLayanan.delete({ + where: { id }, + }); + + return { + success: true, + message: "Data berhasil dihapus", + data: deleted, + }; +} diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/findMany.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/findMany.ts new file mode 100644 index 00000000..d1ff935b --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/findMany.ts @@ -0,0 +1,54 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +// /api/berita/findManyPaginated.ts +import prisma from "@/lib/prisma"; +import { Context } from "elysia"; + +async function tarifLayananFindMany(context: Context) { + // Ambil parameter dari query + const page = Number(context.query.page) || 1; + const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ''; + const skip = (page - 1) * limit; + + // Buat where clause + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { layanan: { contains: search, mode: 'insensitive' } }, + { tarif: { contains: search, mode: 'insensitive' } }, + ]; + } + + try { + // Ambil data dan total count secara paralel + const [data, total] = await Promise.all([ + prisma.tarifDanLayanan.findMany({ + where, + skip, + take: limit, + orderBy: { layanan: 'asc' }, + }), + prisma.tarifDanLayanan.count({ where }), + ]); + + return { + success: true, + message: "Berhasil ambil data tarif layanan dengan pagination", + data, + page, + limit, + total, + totalPages: Math.ceil(total / limit), + }; + } catch (e) { + console.error("Error di findMany paginated:", e); + return { + success: false, + message: "Gagal mengambil data tarif layanan", + }; + } +} + +export default tarifLayananFindMany; \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/findUnique.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/findUnique.ts new file mode 100644 index 00000000..89d9c0f8 --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/findUnique.ts @@ -0,0 +1,47 @@ +import prisma from "@/lib/prisma"; + +export default async function tarifLayananFindUnique(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.tarifDanLayanan.findUnique({ + where: { id }, + }); + + if (!data) { + return Response.json({ + success: false, + message: "Data tidak ditemukan", + }, { status: 404 }); + } + + return Response.json({ + success: true, + message: "Berhasil mengambil data berdasarkan ID", + data, + }, { status: 200 }); + } catch (error) { + console.error("Error fetching data:", error); + return Response.json({ + success: false, + message: "Terjadi kesalahan saat mengambil data", + }, { status: 500 }); + } +} \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/index.ts new file mode 100644 index 00000000..bbd68317 --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/index.ts @@ -0,0 +1,30 @@ +import Elysia, { t } from "elysia"; +import tarifLayananCreate from "./create"; +import tarifLayananFindMany from "./findMany"; +import tarifLayananFindUnique from "./findUnique"; +import tarifLayananDelete from "./del"; +import tarifLayananUpdate from "./updt"; + +const TarifLayanan = new Elysia({ + prefix: "/tarifdanlayanan", + tags: ["Data Kesehatan/Fasilitas Kesehatan/Tarif Layanan"] +}) + .get("/:id", async (context) => { + const response = await tarifLayananFindUnique(new Request(context.request)); + return response; + }) + .get("/findMany", tarifLayananFindMany) + .post("/create", tarifLayananCreate, { + body: t.Object({ + tarif: t.String(), + layanan: t.String() + }), + }) + .put("/:id", tarifLayananUpdate, { + body: t.Object({ + tarif: t.String(), + layanan: t.String(), + }), + }) + .delete("/del/:id", tarifLayananDelete) +export default TarifLayanan \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/updt.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/updt.ts new file mode 100644 index 00000000..2638207d --- /dev/null +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan/updt.ts @@ -0,0 +1,32 @@ +import prisma from "@/lib/prisma"; +import { Context } from "elysia"; + +type FormUpdate = { + layanan: string; + tarif: string; +}; + +export default async function tarifLayananUpdate(context: Context) { + const body = (await context.body) as FormUpdate; + const id = context.params.id as string; + + try { + const result = await prisma.tarifDanLayanan.update({ + where: { id }, + data: { + layanan: body.layanan, + tarif: body.tarif, + }, + }); + return { + success: true, + message: "Berhasil mengupdate data tarif layanan", + data: result, + }; + } catch (error) { + console.error("Error updating data tarif layanan:", error); + throw new Error( + "Gagal mengupdate data tarif layanan: " + (error as Error).message + ); + } +} diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/updt.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/updt.ts index d0061150..db66ae74 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/updt.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/data_kesehatan_warga/fasilitas_kesehatan/updt.ts @@ -5,32 +5,26 @@ type FasilitasKesehatanInput = { name: string; informasiUmum: { fasilitas: string; alamat: string; jamOperasional: string }; layananUnggulan: { content: string }; - dokterdanTenagaMedis: { name: string; specialist: string; jadwal: string }; + dokterdanTenagaMedis: string[]; // ← ID saja fasilitasPendukung: { content: string }; prosedurPendaftaran: { content: string }; - tarifDanLayanan: { layanan: string; tarif: string }; + tarifDanLayanan: string[]; // ← ID saja }; const fasilitasKesehatanUpdate = async (context: Context) => { const id = context.params?.id as string; - const body = await context.body as FasilitasKesehatanInput; - - if (!id) { - return new Response( - JSON.stringify({ success: false, message: "ID is required" }), - { status: 400, headers: { "Content-Type": "application/json" } } - ); - } + const body = (await context.body) as FasilitasKesehatanInput; const existing = await prisma.fasilitasKesehatan.findUnique({ where: { id }, + include: { + dokterdantenagamedis: true, + tarifdanlayanan: true, + }, }); if (!existing) { - return new Response( - JSON.stringify({ success: false, message: "Data not found" }), - { status: 404, headers: { "Content-Type": "application/json" } } - ); + return { success: false, message: "Data tidak ditemukan" }; } const { @@ -43,38 +37,46 @@ const fasilitasKesehatanUpdate = async (context: Context) => { tarifDanLayanan, } = body; - // Update data masing-masing relasi + // update relasi 1-1 await Promise.all([ prisma.informasiUmum.update({ where: { id: existing.informasiUmumId }, data: informasiUmum, }), + prisma.layananUnggulan.update({ where: { id: existing.layananUnggulanId }, data: layananUnggulan, }), - prisma.dokterdanTenagaMedis.update({ - where: { id: existing.dokterdanTenagaMedisId }, - data: dokterdanTenagaMedis, - }), + prisma.fasilitasPendukung.update({ where: { id: existing.fasilitasPendukungId }, data: fasilitasPendukung, }), + prisma.prosedurPendaftaran.update({ where: { id: existing.prosedurPendaftaranId }, data: prosedurPendaftaran, }), - prisma.tarifDanLayanan.update({ - where: { id: existing.tarifDanLayananId }, - data: tarifDanLayanan, - }), ]); - // Update main record + // update m2m const updated = await prisma.fasilitasKesehatan.update({ where: { id }, - data: { name }, + + data: { + name, + + // reset dokter lama → ganti baru + dokterdantenagamedis: { + set: dokterdanTenagaMedis.map((id) => ({ id })), + }, + + tarifdanlayanan: { + set: tarifDanLayanan.map((id) => ({ id })), + }, + }, + include: { informasiumum: true, layananunggulan: true, @@ -87,7 +89,7 @@ const fasilitasKesehatanUpdate = async (context: Context) => { return { success: true, - message: "Fasilitas berhasil diupdate", + message: "Fasilitas diupdate", data: updated, }; }; diff --git a/src/app/api/[[...slugs]]/_lib/kesehatan/index.ts b/src/app/api/[[...slugs]]/_lib/kesehatan/index.ts index 8c38fcfb..19f978d7 100644 --- a/src/app/api/[[...slugs]]/_lib/kesehatan/index.ts +++ b/src/app/api/[[...slugs]]/_lib/kesehatan/index.ts @@ -20,6 +20,7 @@ import Kelahiran from "./data_kesehatan_warga/persentase_kelahiran_kematian/kela import Kematian from "./data_kesehatan_warga/persentase_kelahiran_kematian/kematian"; import DokterTenagaMedis from "./data_kesehatan_warga/fasilitas_kesehatan/dokter-tenaga-medis"; import PendaftaranJadwalKegiatan from "./data_kesehatan_warga/jadwal_kegiatan/pendaftaran"; +import TarifLayanan from "./data_kesehatan_warga/fasilitas_kesehatan/tarif-layanan"; const Kesehatan = new Elysia({ @@ -46,5 +47,6 @@ const Kesehatan = new Elysia({ .use(Kelahiran) .use(Kematian) .use(DokterTenagaMedis) +.use(TarifLayanan) .use(PendaftaranJadwalKegiatan) export default Kesehatan; diff --git a/src/app/api/[[...slugs]]/_lib/search/findMany.ts b/src/app/api/[[...slugs]]/_lib/search/findMany.ts index 5e6eab4e..7aae7328 100644 --- a/src/app/api/[[...slugs]]/_lib/search/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/search/findMany.ts @@ -557,25 +557,37 @@ export default async function searchFindMany(context: Context) { ], }, layananunggulan: { content: { contains: query, mode: "insensitive" } }, - dokterdantenagamedis: { - OR: [ - { name: { contains: query, mode: "insensitive" } }, - { specialist: { contains: query, mode: "insensitive" } }, - { jadwal: { contains: query, mode: "insensitive" } }, - ], - }, + fasilitaspendukung: { content: { contains: query, mode: "insensitive" }, }, prosedurpendaftaran: { content: { contains: query, mode: "insensitive" }, }, - tarifdanlayanan: { - OR: [ - { layanan: { contains: query, mode: "insensitive" } }, - { tarif: { contains: query, mode: "insensitive" } }, - ], - }, + }, + skip, + take: limitNum, + }); + return { data, nextPage: data.length < limitNum ? null : pageNum + 1 }; + } + + if (type === "doktertenagamedis") { + const data = await prisma.dokterdanTenagaMedis.findMany({ + where: { + name: { contains: query, mode: "insensitive" }, + specialist: { contains: query, mode: "insensitive" }, + }, + skip, + take: limitNum, + }); + return { data, nextPage: data.length < limitNum ? null : pageNum + 1 }; + } + + if (type === "tarifdanlayanan") { + const data = await prisma.tarifDanLayanan.findMany({ + where: { + layanan: { contains: query, mode: "insensitive" }, + tarif: { contains: query, mode: "insensitive" }, }, skip, take: limitNum, @@ -1567,6 +1579,8 @@ export default async function searchFindMany(context: Context) { jenisProgramYangDiselenggarakan, dataPerpustakaan, dataPendidikan, + dokterDanTenagaMedis, + tarifDanLayanan ] = await Promise.all([ prisma.pejabatDesa.findMany({ where: { name: { contains: query, mode: "insensitive" } }, @@ -1894,25 +1908,27 @@ export default async function searchFindMany(context: Context) { ], }, layananunggulan: { content: { contains: query, mode: "insensitive" } }, - dokterdantenagamedis: { - OR: [ - { name: { contains: query, mode: "insensitive" } }, - { specialist: { contains: query, mode: "insensitive" } }, - { jadwal: { contains: query, mode: "insensitive" } }, - ], - }, + fasilitaspendukung: { content: { contains: query, mode: "insensitive" }, }, prosedurpendaftaran: { content: { contains: query, mode: "insensitive" }, }, - tarifdanlayanan: { - OR: [ - { layanan: { contains: query, mode: "insensitive" } }, - { tarif: { contains: query, mode: "insensitive" } }, - ], - }, + }, + take: limitNum, + }), + prisma.dokterdanTenagaMedis.findMany({ + where: { + name: { contains: query, mode: "insensitive" }, + specialist: { contains: query, mode: "insensitive" }, + }, + take: limitNum, + }), + prisma.tarifDanLayanan.findMany({ + where: { + tarif: { contains: query, mode: "insensitive" }, + layanan: { contains: query, mode: "insensitive" }, }, take: limitNum, }), @@ -2316,7 +2332,7 @@ export default async function searchFindMany(context: Context) { { judul: { contains: query, mode: "insensitive" } }, { deskripsiSingkat: { contains: query, mode: "insensitive" } }, { deskripsiLengkap: { contains: query, mode: "insensitive" } }, - { lokasi: { contains: query, mode: "insensitive" } }, + { lokasi: { contains: query, mode: "insensitive" } }, { kategoriKegiatan: { nama: { contains: query, mode: "insensitive" }, @@ -2559,6 +2575,8 @@ export default async function searchFindMany(context: Context) { ...penghargaan.map((b) => ({ type: "penghargaan", ...b })), ...posyandu.map((b) => ({ type: "posyandu", ...b })), ...fasilitasKesehatan.map((b) => ({ type: "fasilitasKesehatan", ...b })), + ...dokterDanTenagaMedis.map((b) => ({ type: "dokterdanTenagaMedis", ...b })), + ...tarifDanLayanan.map((b) => ({ type: "tarifDanLayanan", ...b })), ...jadwalKegiatan.map((b) => ({ type: "jadwalKegiatan", ...b })), ...artikelKesehatan.map((b) => ({ type: "artikelKesehatan", ...b })), ...puskesmas.map((b) => ({ type: "puskesmas", ...b })), diff --git a/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/[id]/page.tsx b/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/[id]/page.tsx index 6aa24dfd..d8d02e6e 100644 --- a/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/[id]/page.tsx +++ b/src/app/darmasaba/(pages)/kesehatan/data-kesehatan-warga/fasilitas-kesehatan-page/[id]/page.tsx @@ -42,9 +42,7 @@ function Page() { const alamat = data?.informasiumum?.alamat || '-'; const jam = data?.informasiumum?.jamOperasional || '-'; const layananUnggulan = data?.layananunggulan?.content || ''; - const tenaga = data?.dokterdantenagamedis || null; const fasilitasPendukungHtml = data?.fasilitaspendukung?.content || ''; - const tarif = (data?.tarifdanlayanan as TarifDanLayanan) || null; const kontak = (data?.kontak as Kontak) || { telepon: '(0361) 123456', whatsapp: '6289647037426', @@ -211,7 +209,7 @@ function Page() { Dokter & Tenaga Medis - +
Nama @@ -220,12 +218,19 @@ function Page() { - {tenaga ? ( - - {tenaga?.name || '-'} - {tenaga?.specialist || '-'} - {tenaga?.jadwal || '-'} - + {Array.isArray(data?.dokterdantenagamedis) && data.dokterdantenagamedis.length > 0 ? ( + data.dokterdantenagamedis.map((dokter: any) => ( + + + + + {dokter.name || '-'} + + + {dokter.specialist || '-'} + {dokter.jadwal || '-'} + + )) ) : ( @@ -241,72 +246,74 @@ function Page() { - - - Fasilitas Pendukung - - {fasilitasPendukungHtml ? ( - - ) : ( - - - - Belum ada informasi fasilitas pendukung. - - - )} - - + + + Fasilitas Pendukung + + {fasilitasPendukungHtml ? ( + + ) : ( + + + + Belum ada informasi fasilitas pendukung. + + + )} + + - - - Layanan & Tarif - -
- - - Layanan - Tarif - - - - {tarif ? ( + + + Layanan & Tarif + +
+ - {tarif?.layanan || '-'} - {formatRupiah(tarif?.tarif)} + Layanan + Tarif - ) : ( - - - - - Tidak ada data tarif. - - - - )} - -
- {gratisBpjs && ( - - - Gratis dengan BPJS Kesehatan - - )} -
-
+ + + {Array.isArray(data?.tarifdanlayanan) && data.tarifdanlayanan.length > 0 ? ( + data.tarifdanlayanan.map((item: any) => ( + + {item.layanan || '-'} + {formatRupiah(item.tarif)} + + )) + ) : ( + + + + + Tidak ada data tarif. + + + + )} + + + {gratisBpjs && ( + + + Gratis dengan BPJS Kesehatan + + )} + + - + Prosedur Pendaftaran {prosedur ? ( - + ) : ( Belum ada prosedur pendaftaran )} diff --git a/src/app/darmasaba/_com/main-page/landing-page/SosmedView.tsx b/src/app/darmasaba/_com/main-page/landing-page/SosmedView.tsx index 3279e2ef..773b906f 100644 --- a/src/app/darmasaba/_com/main-page/landing-page/SosmedView.tsx +++ b/src/app/darmasaba/_com/main-page/landing-page/SosmedView.tsx @@ -50,7 +50,9 @@ function SosmedView({ loading="lazy" src={src} alt={item.name} - fit={item.image?.link ? "cover" : "contain"} + w={24} + h={24} + fit="contain" /> ); } diff --git a/src/app/darmasaba/_com/searchUrl.tsx b/src/app/darmasaba/_com/searchUrl.tsx index 6350b8dc..4ce896b9 100644 --- a/src/app/darmasaba/_com/searchUrl.tsx +++ b/src/app/darmasaba/_com/searchUrl.tsx @@ -1,4 +1,4 @@ -const getDetailUrl = (item: { type?: string; id: string | number; [key: string]: unknown }) => { +const getDetailUrl = (item: { type?: string; id: string | number;[key: string]: unknown }) => { const { type, id, kategori } = item; const map: Record string> = { programinovasi: (id) => `/darmasaba/program-inovasi/${id}`, @@ -30,6 +30,8 @@ const getDetailUrl = (item: { type?: string; id: string | number; [key: string]: penghargaan: () => '/darmasaba/desa/penghargaan', posyandu: (id) => `/darmasaba/kesehatan/posyandu/${id}`, fasilitasKesehatan: () => '/darmasaba/kesehatan/data-kesehatan-warga', + dokterDanTenagaMedis: () => '/darmasaba/kesehatan/data-kesehatan-warga', + tarifDanLayanan: () => '/darmasaba/kesehatan/data-kesehatan-warga', jadwalKegiatan: () => '/darmasaba/kesehatan/data-kesehatan-warga', artikelKesehatan: () => '/darmasaba/kesehatan/data-kesehatan-warga', puskesmas: () => '/darmasaba/kesehatan/puskesmas', @@ -82,7 +84,7 @@ const getDetailUrl = (item: { type?: string; id: string | number; [key: string]: jenisProgramYangDiselenggarakan: () => '/darmasaba/pendidikan/pendidikan-non-formal', dataPerpustakaan: () => '/darmasaba/pendidikan/perpustakaan-digital/semua', dataPendidikan: () => '/darmasaba/pendidikan/data-pendidikan', - + }; if (type && map[type]) return map[type](id, kategori as string | undefined);