API & UI Kesehatan Sudah Sampai Di Penanganan Darurat
This commit is contained in:
@@ -0,0 +1,208 @@
|
||||
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 templateForm = z.object({
|
||||
name: z.string().min(3, "Judul minimal 3 karakter"),
|
||||
deskripsi: z.string().min(3, "Deskripsi minimal 3 karakter"),
|
||||
imageId: z.string().nonempty(),
|
||||
})
|
||||
|
||||
const defaultForm = {
|
||||
name: "",
|
||||
deskripsi: "",
|
||||
imageId: "",
|
||||
}
|
||||
|
||||
const penangananDarurat = proxy({
|
||||
findMany: {
|
||||
data: [] as Prisma.PenangananDaruratGetPayload<{
|
||||
include: {
|
||||
image: true;
|
||||
};
|
||||
}>[],
|
||||
async load() {
|
||||
const res = await ApiFetch.api.kesehatan.penanganandarurat[
|
||||
"find-many"
|
||||
].get();
|
||||
if (res.status === 200) {
|
||||
penangananDarurat.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
create:{
|
||||
form: {...defaultForm},
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateForm.safeParse(penangananDarurat.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
|
||||
try {
|
||||
penangananDarurat.create.loading = true;
|
||||
const res = await ApiFetch.api.kesehatan.penanganandarurat[
|
||||
"create"
|
||||
].post(penangananDarurat.create.form);
|
||||
if (res.status === 200) {
|
||||
penangananDarurat.findMany.load();
|
||||
return toast.success("Penanganan Darurat berhasil disimpan!");
|
||||
}
|
||||
|
||||
return toast.error("Gagal menyimpan penanganan darurat");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
penangananDarurat.create.loading = false;
|
||||
}
|
||||
},
|
||||
resetForm() {
|
||||
penangananDarurat.create.form = {...defaultForm};
|
||||
}
|
||||
},
|
||||
findUnique: {
|
||||
data: null as Prisma.PenangananDaruratGetPayload<{
|
||||
include: {
|
||||
image: true;
|
||||
};
|
||||
}> | null,
|
||||
async load(id: string) {
|
||||
try {
|
||||
const res = await fetch(`/api/kesehatan/penanganandarurat/${id}`);
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
penangananDarurat.findUnique.data = data.data ?? null;
|
||||
} else {
|
||||
console.error("Failed to fetch data", res.status, res.statusText);
|
||||
penangananDarurat.findUnique.data = null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching data:", error);
|
||||
penangananDarurat.findUnique.data = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
loading: false,
|
||||
async byId(id: string) {
|
||||
try {
|
||||
penangananDarurat.delete.loading = true;
|
||||
const response = await fetch(`/api/kesehatan/penanganandarurat/del/${id}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
|
||||
if (response.ok && result?.success) {
|
||||
toast.success(result.message || "Penanganan darurat berhasil dihapus");
|
||||
await penangananDarurat.findMany.load(); // refresh list
|
||||
} else {
|
||||
toast.error(result?.message || "Gagal menghapus penanganan darurat");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Gagal delete:", error);
|
||||
toast.error("Terjadi kesalahan saat menghapus penanganan darurat");
|
||||
} finally {
|
||||
penangananDarurat.delete.loading = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
edit: {
|
||||
id: "",
|
||||
form: { ...defaultForm },
|
||||
loading: false,
|
||||
|
||||
async load(id: string) {
|
||||
if (!id) {
|
||||
toast.warn("ID tidak valid");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/kesehatan/penanganandarurat/${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,
|
||||
deskripsi: data.deskripsi,
|
||||
imageId: data.imageId,
|
||||
};
|
||||
return data; // Return the loaded data
|
||||
} else {
|
||||
throw new Error(result?.message || "Gagal memuat data");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching penanganan darurat:", error);
|
||||
toast.error(error instanceof Error ? error.message : "Gagal memuat data");
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
async update() {
|
||||
const cek = templateForm.safeParse(penangananDarurat.edit.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
|
||||
try {
|
||||
penangananDarurat.edit.loading = true;
|
||||
const response = await fetch(`/api/kesehatan/penanganandarurat/${this.id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: this.form.name,
|
||||
deskripsi: this.form.deskripsi,
|
||||
imageId: this.form.imageId,
|
||||
}),
|
||||
});
|
||||
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(result.message || "Penanganan darurat berhasil diupdate");
|
||||
await penangananDarurat.findMany.load();
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(result.message || "Gagal update penanganan darurat");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Gagal update:", error);
|
||||
toast.error(error instanceof Error ? error.message : "Terjadi kesalahan saat mengupdate penanganan darurat");
|
||||
return false;
|
||||
} finally {
|
||||
penangananDarurat.edit.loading = false;
|
||||
}
|
||||
},
|
||||
reset() {
|
||||
penangananDarurat.edit.id = "";
|
||||
penangananDarurat.edit.form = { ...defaultForm };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default penangananDarurat
|
||||
@@ -0,0 +1,214 @@
|
||||
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 templateForm = z.object({
|
||||
name: z.string().min(3, "Judul minimal 3 karakter"),
|
||||
deskripsiSingkat: z.string().min(3, "Deskripsi singkat minimal 3 karakter"),
|
||||
deskripsi: z.string().min(3, "Deskripsi minimal 3 karakter"),
|
||||
imageId: z.string().nonempty(),
|
||||
});
|
||||
|
||||
const defaultForm = {
|
||||
name: "",
|
||||
deskripsiSingkat: "",
|
||||
deskripsi: "",
|
||||
imageId: "",
|
||||
};
|
||||
|
||||
const programKesehatan = proxy({
|
||||
findMany: {
|
||||
data: [] as Prisma.ProgramKesehatanGetPayload<{
|
||||
include: {
|
||||
image: true;
|
||||
};
|
||||
}>[],
|
||||
async load() {
|
||||
const res = await ApiFetch.api.kesehatan.programkesehatan[
|
||||
"find-many"
|
||||
].get();
|
||||
if (res.status === 200) {
|
||||
programKesehatan.findMany.data = res.data?.data ?? [];
|
||||
}
|
||||
},
|
||||
},
|
||||
create: {
|
||||
form: { ...defaultForm },
|
||||
loading: false,
|
||||
async create() {
|
||||
const cek = templateForm.safeParse(programKesehatan.create.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
|
||||
try {
|
||||
programKesehatan.create.loading = true;
|
||||
const res = await ApiFetch.api.kesehatan.programkesehatan[
|
||||
"create"
|
||||
].post(programKesehatan.create.form);
|
||||
if (res.status === 200) {
|
||||
programKesehatan.findMany.load();
|
||||
return toast.success("Program Kesehatan berhasil disimpan!");
|
||||
}
|
||||
|
||||
return toast.error("Gagal menyimpan program kesehatan");
|
||||
} catch (error) {
|
||||
console.log((error as Error).message);
|
||||
} finally {
|
||||
programKesehatan.create.loading = false;
|
||||
}
|
||||
},
|
||||
resetForm() {
|
||||
programKesehatan.create.form = { ...defaultForm };
|
||||
},
|
||||
},
|
||||
findUnique: {
|
||||
data: null as Prisma.ProgramKesehatanGetPayload<{
|
||||
include: {
|
||||
image: true;
|
||||
};
|
||||
}> | null,
|
||||
async load(id: string) {
|
||||
try {
|
||||
const res = await fetch(`/api/kesehatan/programkesehatan/${id}`);
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
programKesehatan.findUnique.data = data.data ?? null;
|
||||
} else {
|
||||
console.error("Failed to fetch program kesehatan:", res.statusText);
|
||||
programKesehatan.findUnique.data = null;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching program kesehatan:", error);
|
||||
programKesehatan.findUnique.data = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
delete: {
|
||||
loading: false,
|
||||
async byId(id: string) {
|
||||
if (!id) return toast.warn("ID tidak valid");
|
||||
|
||||
try {
|
||||
programKesehatan.delete.loading = true;
|
||||
|
||||
const response = await fetch(`/api/kesehatan/programkesehatan/del/${id}`, {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
});
|
||||
|
||||
const result = await response.json();
|
||||
if (response.ok && result?.success) {
|
||||
toast.success(result.message || "Program kesehatan berhasil dihapus");
|
||||
await programKesehatan.findMany.load(); // refresh list
|
||||
} else {
|
||||
toast.error(result?.message || "Gagal menghapus program kesehatan");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Gagal delete:", error);
|
||||
toast.error("Terjadi kesalahan saat menghapus program kesehatan");
|
||||
} finally {
|
||||
programKesehatan.delete.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
edit: {
|
||||
id: "",
|
||||
form: { ...defaultForm },
|
||||
loading: false,
|
||||
|
||||
async load(id: string) {
|
||||
if (!id) {
|
||||
toast.warn("ID tidak valid");
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`/api/kesehatan/programkesehatan/${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,
|
||||
deskripsiSingkat: data.deskripsiSingkat,
|
||||
deskripsi: data.deskripsi,
|
||||
imageId: data.imageId,
|
||||
};
|
||||
return data; // Return the loaded data
|
||||
} else {
|
||||
throw new Error(result?.message || "Gagal memuat data");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error fetching program kesehatan:", error);
|
||||
toast.error(error instanceof Error ? error.message : "Gagal memuat data");
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
async update() {
|
||||
const cek = templateForm.safeParse(programKesehatan.edit.form);
|
||||
if (!cek.success) {
|
||||
const err = `[${cek.error.issues
|
||||
.map((v) => `${v.path.join(".")}`)
|
||||
.join("\n")}] required`;
|
||||
return toast.error(err);
|
||||
}
|
||||
|
||||
try {
|
||||
programKesehatan.edit.loading = true;
|
||||
const response = await fetch(`/api/kesehatan/programkesehatan/${this.id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
name: this.form.name,
|
||||
deskripsiSingkat: this.form.deskripsiSingkat,
|
||||
deskripsi: this.form.deskripsi,
|
||||
imageId: this.form.imageId,
|
||||
}),
|
||||
});
|
||||
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(result.message || "Program kesehatan berhasil diupdate");
|
||||
await programKesehatan.findMany.load();
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(result.message || "Gagal update program kesehatan");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Gagal update:", error);
|
||||
toast.error(error instanceof Error ? error.message : "Terjadi kesalahan saat mengupdate program kesehatan");
|
||||
return false;
|
||||
} finally {
|
||||
programKesehatan.edit.loading = false;
|
||||
}
|
||||
},
|
||||
reset() {
|
||||
programKesehatan.edit.id = "";
|
||||
programKesehatan.edit.form = { ...defaultForm };
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
export default programKesehatan;
|
||||
@@ -0,0 +1,140 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
import penangananDarurat from '@/app/admin/(dashboard)/_state/kesehatan/penanganan-darurat/penangananDarurat';
|
||||
import colors from '@/con/colors';
|
||||
import ApiFetch from '@/lib/api-fetch';
|
||||
import { Box, Button, Center, FileInput, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack, IconImageInPicture } 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 EditPenangananDarurat() {
|
||||
const penangananDaruratState = useProxy(penangananDarurat)
|
||||
const router = useRouter();
|
||||
const params = useParams()
|
||||
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [formData, setFormData] = useState({
|
||||
name: penangananDaruratState.edit.form.name || '',
|
||||
deskripsi: penangananDaruratState.edit.form.deskripsi || '',
|
||||
imageId: penangananDaruratState.edit.form.imageId || '',
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const loadPenangananDarurat = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
|
||||
try {
|
||||
const data = await penangananDaruratState.edit.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
name: data.name || '',
|
||||
deskripsi: data.deskripsi || '',
|
||||
imageId: data.imageId || '',
|
||||
})
|
||||
|
||||
if (data?.image?.link) {
|
||||
setPreviewImage(data.image.link);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading penanganan darurat:', error);
|
||||
toast.error('Gagal memuat data penanganan darurat');
|
||||
}
|
||||
}
|
||||
|
||||
loadPenangananDarurat();
|
||||
}, [params?.id])
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
penangananDaruratState.edit.form = {
|
||||
...penangananDaruratState.edit.form,
|
||||
name: formData.name,
|
||||
deskripsi: formData.deskripsi,
|
||||
imageId: formData.imageId,
|
||||
}
|
||||
|
||||
if (file) {
|
||||
const res = await ApiFetch.api.fileStorage.create.post({ file, name: file.name });
|
||||
const uploaded = res.data?.data;
|
||||
|
||||
if (!uploaded?.id) {
|
||||
return toast.error("Gagal upload gambar");
|
||||
}
|
||||
|
||||
penangananDaruratState.edit.form.imageId = uploaded.id;
|
||||
}
|
||||
|
||||
await penangananDaruratState.edit.update();
|
||||
toast.success("Penanganan darurat berhasil diperbarui!");
|
||||
router.push("/admin/kesehatan/penanganan-darurat");
|
||||
} catch (error) {
|
||||
console.error("Error updating penanganan darurat:", error);
|
||||
toast.error("Gagal memuat data penanganan darurat");
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
<Stack gap={"xs"}>
|
||||
<Paper bg={colors['white-1']} p={"md"} w={{ base: '100%', md: '50%' }}>
|
||||
<Stack gap="xs">
|
||||
<Title order={3}>Edit Penanganan Darurat</Title>
|
||||
|
||||
<TextInput
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
label={<Text fz="sm" fw="bold">Judul</Text>}
|
||||
placeholder="masukkan judul"
|
||||
/>
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Deskripsi</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsi}
|
||||
onChange={(val) => setFormData({ ...formData, deskripsi: val })}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<FileInput
|
||||
label={<Text fz="sm" fw="bold">Upload Gambar</Text>}
|
||||
value={file}
|
||||
onChange={async (e) => {
|
||||
if (!e) return;
|
||||
setFile(e);
|
||||
const base64 = await e.arrayBuffer().then((buf) =>
|
||||
'data:image/png;base64,' + Buffer.from(buf).toString('base64')
|
||||
);
|
||||
setPreviewImage(base64);
|
||||
}}
|
||||
/>
|
||||
|
||||
{previewImage ? (
|
||||
<Image alt="" src={previewImage} w={200} h={200} />
|
||||
) : (
|
||||
<Center w={200} h={200} bg="gray">
|
||||
<IconImageInPicture />
|
||||
</Center>
|
||||
)}
|
||||
|
||||
<Button onClick={handleSubmit} bg={colors['blue-button']}>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack >
|
||||
</Box >
|
||||
);
|
||||
}
|
||||
|
||||
export default EditPenangananDarurat;
|
||||
@@ -0,0 +1,101 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Paper, Stack, Flex, Text, Image } from '@mantine/core';
|
||||
import { IconArrowBack, IconX, IconEdit } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React, { useState } from 'react';
|
||||
// import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
|
||||
import penangananDarurat from '../../../_state/kesehatan/penanganan-darurat/penangananDarurat';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useParams } from 'next/navigation';
|
||||
import { Skeleton } from '@mantine/core';
|
||||
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
|
||||
|
||||
function DetailPenangananDarurat() {
|
||||
const penangananDaruratState = useProxy(penangananDarurat)
|
||||
const [modalHapus, setModalHapus] = useState(false)
|
||||
const [selectedId, setSelectedId] = useState<string | null>(null)
|
||||
const router = useRouter();
|
||||
const params = useParams()
|
||||
|
||||
useShallowEffect(() => {
|
||||
penangananDaruratState.findUnique.load(params?.id as string)
|
||||
}, [])
|
||||
|
||||
const handleHapus = () => {
|
||||
if (selectedId) {
|
||||
penangananDaruratState.delete.byId(selectedId)
|
||||
setModalHapus(false)
|
||||
setSelectedId(null)
|
||||
router.push("/admin/kesehatan/penanganan-darurat")
|
||||
}
|
||||
}
|
||||
|
||||
if (!penangananDaruratState.findUnique.data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
<Paper w={{ base: "100%", md: "50%" }} bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Text fz={"xl"} fw={"bold"}>Detail Penanganan Darurat</Text>
|
||||
{penangananDaruratState.findUnique.data ? (
|
||||
<Paper bg={colors['BG-trans']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Nama Penanganan Darurat</Text>
|
||||
<Text fz={"lg"}>{penangananDaruratState.findUnique.data.name}</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Deskripsi</Text>
|
||||
<Text fz={"lg"} dangerouslySetInnerHTML={{ __html: penangananDaruratState.findUnique.data.deskripsi }} />
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Gambar</Text>
|
||||
<Image src={penangananDaruratState.findUnique.data.image?.link} alt="gambar" />
|
||||
</Box>
|
||||
<Box>
|
||||
<Flex gap={"xs"}>
|
||||
<Button color="red" onClick={() => {
|
||||
if (penangananDaruratState.findUnique.data) {
|
||||
setSelectedId(penangananDaruratState.findUnique.data.id)
|
||||
setModalHapus(true)
|
||||
}
|
||||
}}
|
||||
disabled={penangananDaruratState.delete.loading || !penangananDaruratState.findUnique.data}>
|
||||
<IconX size={20} />
|
||||
</Button>
|
||||
<Button onClick={() => router.push(`/admin/kesehatan/penanganan-darurat/${penangananDaruratState.findUnique.data?.id}/edit`)} color="green">
|
||||
<IconEdit size={20} />
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
) : null}
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
{/* Modal Hapus */}
|
||||
<ModalKonfirmasiHapus
|
||||
opened={modalHapus}
|
||||
onClose={() => setModalHapus(false)}
|
||||
onConfirm={handleHapus}
|
||||
text="Apakah anda yakin ingin menghapus penanganan darurat ini?"
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default DetailPenangananDarurat;
|
||||
@@ -1,14 +1,56 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import ApiFetch from '@/lib/api-fetch';
|
||||
import { Box, Button, Center, FileInput, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { KesehatanEditor } from '../../_com/kesehatanEditor';
|
||||
import { useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import CreateEditor from '../../../_com/createEditor';
|
||||
import penangananDarurat from '../../../_state/kesehatan/penanganan-darurat/penangananDarurat';
|
||||
|
||||
|
||||
function CreatePenangananDarurat() {
|
||||
const router = useRouter();
|
||||
const penangananDaruratState = useProxy(penangananDarurat)
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
|
||||
const resetForm = () => {
|
||||
penangananDaruratState.create.form = {
|
||||
name: "",
|
||||
deskripsi: "",
|
||||
imageId: "",
|
||||
};
|
||||
setPreviewImage(null);
|
||||
setFile(null);
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!file) {
|
||||
return toast.warn("Pilih file gambar terlebih dahulu");
|
||||
}
|
||||
|
||||
const res = await ApiFetch.api.fileStorage.create.post({
|
||||
file,
|
||||
name: file.name,
|
||||
});
|
||||
|
||||
const uploaded = res.data?.data;
|
||||
if (!uploaded?.id) {
|
||||
return toast.error("Gagal upload gambar");
|
||||
}
|
||||
|
||||
penangananDaruratState.create.form.imageId = uploaded.id;
|
||||
|
||||
await penangananDaruratState.create.create();
|
||||
|
||||
resetForm();
|
||||
router.push("/admin/kesehatan/penanganan-darurat")
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
@@ -20,54 +62,48 @@ function CreatePenangananDarurat() {
|
||||
<Title order={3}>Create Penanganan Darurat</Title>
|
||||
|
||||
<TextInput
|
||||
|
||||
value={penangananDaruratState.create.form.name}
|
||||
onChange={(val) => {
|
||||
penangananDaruratState.create.form.name = val.target.value;
|
||||
}}
|
||||
label={<Text fz="sm" fw="bold">Judul</Text>}
|
||||
placeholder="masukkan judul"
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
|
||||
label={<Text fz="sm" fw="bold">Deskripsi</Text>}
|
||||
placeholder="masukkan deskripsi"
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
|
||||
label={<Text fz="sm" fw="bold">Kategori</Text>}
|
||||
placeholder="masukkan kategori"
|
||||
/>
|
||||
|
||||
{/* <FileInput
|
||||
label={<Text fz="sm" fw="bold">Upload Gambar</Text>}
|
||||
value={file}
|
||||
onChange={async (e) => {
|
||||
if (!e) return;
|
||||
setFile(e);
|
||||
const base64 = await e.arrayBuffer().then((buf) =>
|
||||
'data:image/png;base64,' + Buffer.from(buf).toString('base64')
|
||||
);
|
||||
setPreviewImage(base64);
|
||||
}}
|
||||
/> */}
|
||||
|
||||
{/* {previewImage ? (
|
||||
<Image alt="" src={previewImage} w={200} h={200} />
|
||||
) : (
|
||||
<Center w={200} h={200} bg="gray">
|
||||
<IconImageInPicture />
|
||||
</Center>
|
||||
)} */}
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Konten</Text>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
<Text fz="sm" fw="bold">Deskripsi</Text>
|
||||
<CreateEditor
|
||||
value={penangananDaruratState.create.form.deskripsi}
|
||||
onChange={(val) => {
|
||||
penangananDaruratState.create.form.deskripsi = val;
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Button bg={colors['blue-button']}>
|
||||
Simpan Potensi
|
||||
</Button>
|
||||
<FileInput
|
||||
label={<Text fz="sm" fw="bold">Upload Gambar</Text>}
|
||||
value={file}
|
||||
onChange={async (e) => {
|
||||
if (!e) return;
|
||||
setFile(e);
|
||||
const base64 = await e.arrayBuffer().then((buf) =>
|
||||
'data:image/png;base64,' + Buffer.from(buf).toString('base64')
|
||||
);
|
||||
setPreviewImage(base64);
|
||||
}}
|
||||
/>
|
||||
|
||||
{previewImage ? (
|
||||
<Image alt="" src={previewImage} w={200} h={200} />
|
||||
) : (
|
||||
<Center w={200} h={200} bg="gray">
|
||||
<IconImageInPicture />
|
||||
</Center>
|
||||
)}
|
||||
|
||||
<Button onClick={handleSubmit} bg={colors['blue-button']}>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Paper, Stack, Flex, Text, Image } from '@mantine/core';
|
||||
import { IconArrowBack, IconX, IconEdit } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React from 'react';
|
||||
// import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
|
||||
|
||||
function DetailPenangananDarurat() {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
<Paper w={{ base: "100%", md: "50%" }} bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Text fz={"xl"} fw={"bold"}>Detail Penanganan Darurat</Text>
|
||||
|
||||
<Paper bg={colors['BG-trans']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Nama Penanganan Darurat</Text>
|
||||
<Text fz={"lg"}>Test Judul</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Deskripsi Penanganan Darurat</Text>
|
||||
<Text fz={"lg"}>Test Kategori</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Deskripsi</Text>
|
||||
<Text fz={"lg"}>Test Deskripsi</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Gambar</Text>
|
||||
<Image src={"/"} alt="gambar" />
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Konten</Text>
|
||||
<Text fz={"lg"} >Test Konten</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Flex gap={"xs"}>
|
||||
<Button color="red">
|
||||
<IconX size={20} />
|
||||
</Button>
|
||||
<Button onClick={() => router.push('/admin/kesehatan/penanganan-darurat/edit')} color="green">
|
||||
<IconEdit size={20} />
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
{/* Modal Hapus
|
||||
<ModalKonfirmasiHapus
|
||||
opened={modalHapus}
|
||||
onClose={() => setModalHapus(false)}
|
||||
onConfirm={handleHapus}
|
||||
text="Apakah anda yakin ingin menghapus penanganan darurat ini?"
|
||||
/> */}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default DetailPenangananDarurat;
|
||||
@@ -1,62 +0,0 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Stack, SimpleGrid, Paper, Title, TextInput, Text, Button, Image } from '@mantine/core';
|
||||
import { KesehatanEditor } from '../../_com/kesehatanEditor';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
|
||||
function EditPenangananDarurat() {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
<Stack gap={"xs"}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={"md"}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Edit Penanganan Darurat</Title>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"} fz={"sm"}>Nama Penanganan Darurat</Text>}
|
||||
placeholder='Masukkan nama Penanganan Darurat'
|
||||
/>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"} fz={"sm"}>Deskripsi Penanganan Darurat</Text>}
|
||||
placeholder='Masukkan deskripsi Penanganan Darurat'
|
||||
/>
|
||||
<Box>
|
||||
<Text fw={"bold"} fz={"sm"}>Deskripsi</Text>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
/>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fw={"bold"} fz={"sm"}>Gambar</Text>
|
||||
<Image src={"/"} alt="gambar" />
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={"md"}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={4}>Preview Data Penanganan Darurat</Title>
|
||||
<Text fw={"bold"} fz={"sm"}>Nama Penanganan Darurat</Text>
|
||||
<Text fw={"bold"} fz={"sm"}>No Telp Penanganan Darurat</Text>
|
||||
<Text fw={"bold"} fz={"sm"}>Deskripsi</Text>
|
||||
<Text fw={"bold"} fz={"sm"}>Pelayanan Posyandu</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditPenangananDarurat;
|
||||
@@ -1,10 +1,14 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Image, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||
import { Box, Button, Image, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||
import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
|
||||
import JudulList from '../../_com/judulList';
|
||||
import HeaderSearch from '../../_com/header';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import penangananDarurat from '../../_state/kesehatan/penanganan-darurat/penangananDarurat';
|
||||
|
||||
|
||||
function PenangananDarurat() {
|
||||
return (
|
||||
@@ -20,7 +24,21 @@ function PenangananDarurat() {
|
||||
}
|
||||
|
||||
function ListPenangananDarurat() {
|
||||
const penangananDaruratState = useProxy(penangananDarurat)
|
||||
const router = useRouter();
|
||||
|
||||
useShallowEffect(() => {
|
||||
penangananDaruratState.findMany.load()
|
||||
}, [])
|
||||
|
||||
if (!penangananDaruratState.findMany.data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
@@ -34,27 +52,31 @@ function ListPenangananDarurat() {
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh>Judul</TableTh>
|
||||
<TableTh>Kategori</TableTh>
|
||||
<TableTh>Deskripsi</TableTh>
|
||||
<TableTh>Image</TableTh>
|
||||
<TableTh>Detail</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
<TableTr>
|
||||
{penangananDaruratState.findMany.data?.map((item) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd>
|
||||
<Box w={100}>
|
||||
<Text truncate="end" fz={"sm"}>Test</Text>
|
||||
<Text truncate="end" fz={"sm"}>{item.name}</Text>
|
||||
</Box></TableTd>
|
||||
<TableTd>Test</TableTd>
|
||||
<TableTd>
|
||||
<Image w={100} src={"/"} alt="image" />
|
||||
<Text truncate="end" fz={"sm"} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Button onClick={() => router.push('/admin/kesehatan/penanganan-darurat/detail')}>
|
||||
<Image w={100} src={item.image?.link} alt="image" />
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Button onClick={() => router.push(`/admin/kesehatan/penanganan-darurat/${item.id}`)}>
|
||||
<IconDeviceImacCog size={25} />
|
||||
</Button>
|
||||
</TableTd>
|
||||
</TableTr>
|
||||
))}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Box>
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
import programKesehatan from '@/app/admin/(dashboard)/_state/kesehatan/program-kesehatan/programKesehatan';
|
||||
import colors from '@/con/colors';
|
||||
import ApiFetch from '@/lib/api-fetch';
|
||||
import { Box, Button, Center, FileInput, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack, IconImageInPicture } 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 EditProgramKesehatan() {
|
||||
const programKesehatanState = useProxy(programKesehatan)
|
||||
const router = useRouter();
|
||||
const params = useParams()
|
||||
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [formData, setFormData] = useState({
|
||||
name: programKesehatanState.edit.form.name || '',
|
||||
deskripsiSingkat: programKesehatanState.edit.form.deskripsiSingkat || '',
|
||||
deskripsi: programKesehatanState.edit.form.deskripsi || '',
|
||||
imageId: programKesehatanState.edit.form.imageId || '',
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const loadProgramKesehatan = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
|
||||
try {
|
||||
const data = await programKesehatanState.edit.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
name: data.name || '',
|
||||
deskripsiSingkat: data.deskripsiSingkat || '',
|
||||
deskripsi: data.deskripsi || '',
|
||||
imageId: data.imageId || '',
|
||||
});
|
||||
|
||||
if (data?.image?.link) {
|
||||
setPreviewImage(data.image.link);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading program kesehatan:", error);
|
||||
toast.error("Gagal memuat data program kesehatan");
|
||||
}
|
||||
};
|
||||
|
||||
loadProgramKesehatan();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
programKesehatanState.edit.form = {
|
||||
...programKesehatanState.edit.form,
|
||||
name: formData.name,
|
||||
deskripsiSingkat: formData.deskripsiSingkat,
|
||||
deskripsi: formData.deskripsi,
|
||||
imageId: formData.imageId,
|
||||
};
|
||||
|
||||
if (file) {
|
||||
const res = await ApiFetch.api.fileStorage.create.post({ file, name: file.name });
|
||||
const uploaded = res.data?.data;
|
||||
|
||||
if (!uploaded?.id) {
|
||||
return toast.error("Gagal upload gambar");
|
||||
}
|
||||
|
||||
programKesehatanState.edit.form.imageId = uploaded.id;
|
||||
}
|
||||
|
||||
await programKesehatanState.edit.update();
|
||||
toast.success("Program kesehatan berhasil diperbarui!");
|
||||
router.push("/admin/kesehatan/program-kesehatan");
|
||||
} catch (error) {
|
||||
console.error("Error updating program kesehatan:", error);
|
||||
toast.error("Gagal memuat data program kesehatan");
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
<Stack gap={"xs"}>
|
||||
<Paper bg={colors['white-1']} p="md" w={{ base: '100%', md: '50%' }}>
|
||||
<Stack gap="xs">
|
||||
<Title order={3}>Edit Program Kesehatan</Title>
|
||||
<TextInput
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
label={<Text fz="sm" fw="bold">Judul</Text>}
|
||||
placeholder="masukkan judul"
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
value={formData.deskripsiSingkat}
|
||||
onChange={(e) => setFormData({ ...formData, deskripsiSingkat: e.target.value })}
|
||||
label={<Text fz="sm" fw="bold">Deskripsi Singkat</Text>}
|
||||
placeholder="masukkan deskripsi"
|
||||
/>
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Deskripsi</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsi}
|
||||
onChange={(val) => setFormData({ ...formData, deskripsi: val })}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<FileInput
|
||||
label={<Text fz="sm" fw="bold">Upload Gambar</Text>}
|
||||
value={file}
|
||||
onChange={async (e) => {
|
||||
if (!e) return;
|
||||
setFile(e);
|
||||
const base64 = await e.arrayBuffer().then((buf) =>
|
||||
'data:image/png;base64,' + Buffer.from(buf).toString('base64')
|
||||
);
|
||||
setPreviewImage(base64);
|
||||
}}
|
||||
/>
|
||||
|
||||
{previewImage ? (
|
||||
<Image alt="" src={previewImage} w={200} h={200} />
|
||||
) : (
|
||||
<Center w={200} h={200} bg="gray">
|
||||
<IconImageInPicture />
|
||||
</Center>
|
||||
)}
|
||||
|
||||
<Button onClick={handleSubmit} bg={colors['blue-button']}>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Box >
|
||||
);
|
||||
}
|
||||
|
||||
export default EditProgramKesehatan;
|
||||
@@ -0,0 +1,103 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Paper, Stack, Flex, Text, Image, Skeleton } from '@mantine/core';
|
||||
import { IconArrowBack, IconX, IconEdit } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import React, { useState } from 'react';
|
||||
import programKesehatan from '../../../_state/kesehatan/program-kesehatan/programKesehatan';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
|
||||
|
||||
function DetailProgramKesehatan() {
|
||||
const programKesehatanState = useProxy(programKesehatan)
|
||||
const [modalHapus, setModalHapus] = useState(false)
|
||||
const [selectedId, setSelectedId] = useState<string | null>(null)
|
||||
const router = useRouter();
|
||||
const params = useParams()
|
||||
|
||||
useShallowEffect(() => {
|
||||
programKesehatanState.findUnique.load(params?.id as string)
|
||||
}, [])
|
||||
|
||||
const handleHapus = () => {
|
||||
if (selectedId) {
|
||||
programKesehatanState.delete.byId(selectedId)
|
||||
setModalHapus(false)
|
||||
setSelectedId(null)
|
||||
router.push("/admin/kesehatan/program-kesehatan")
|
||||
}
|
||||
}
|
||||
|
||||
if (!programKesehatanState.findUnique.data) {
|
||||
return (
|
||||
<Stack py={10}>
|
||||
<Skeleton h={400} />
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
<Paper w={{ base: "100%", md: "50%" }} bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Text fz={"xl"} fw={"bold"}>Detail Potensi</Text>
|
||||
{programKesehatanState.findUnique.data ? (
|
||||
<Paper bg={colors['BG-trans']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Judul</Text>
|
||||
<Text fz={"lg"}>{programKesehatanState.findUnique.data.name}</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Deskripsi Singkat</Text>
|
||||
<Text fz={"lg"}>{programKesehatanState.findUnique.data.deskripsiSingkat}</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Deskripsi</Text>
|
||||
<Text fz={"lg"} dangerouslySetInnerHTML={{ __html: programKesehatanState.findUnique.data.deskripsi }} />
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Gambar</Text>
|
||||
<Image src={programKesehatanState.findUnique.data.image?.link} alt="gambar" />
|
||||
</Box>
|
||||
<Box>
|
||||
<Flex gap={"xs"}>
|
||||
<Button color="red" onClick={() => {
|
||||
if (programKesehatanState.findUnique.data) {
|
||||
setSelectedId(programKesehatanState.findUnique.data.id)
|
||||
setModalHapus(true)
|
||||
}
|
||||
}}
|
||||
disabled={programKesehatanState.delete.loading || !programKesehatanState.findUnique.data}
|
||||
>
|
||||
<IconX size={20} />
|
||||
</Button>
|
||||
<Button onClick={() => router.push(`/admin/kesehatan/program-kesehatan/${programKesehatanState.findUnique.data?.id}/edit`)} color="green">
|
||||
<IconEdit size={20} />
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
) : null}
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
{/* Modal Hapus */}
|
||||
<ModalKonfirmasiHapus
|
||||
opened={modalHapus}
|
||||
onClose={() => setModalHapus(false)}
|
||||
onConfirm={handleHapus}
|
||||
text="Apakah anda yakin ingin menghapus program kesehatan ini?"
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default DetailProgramKesehatan;
|
||||
@@ -1,43 +1,101 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import ApiFetch from '@/lib/api-fetch';
|
||||
import { Box, Button, Center, FileInput, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { KesehatanEditor } from '../../_com/kesehatanEditor';
|
||||
import { useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import CreateEditor from '../../../_com/createEditor';
|
||||
import programKesehatan from '../../../_state/kesehatan/program-kesehatan/programKesehatan';
|
||||
|
||||
function CreateProgramKesehatan() {
|
||||
const router = useRouter();
|
||||
const programKesehatanState = useProxy(programKesehatan)
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
|
||||
const resetForm = () => {
|
||||
// Reset state di valtio
|
||||
programKesehatanState.create.form = {
|
||||
name: "",
|
||||
deskripsiSingkat: "",
|
||||
deskripsi: "",
|
||||
imageId: "",
|
||||
};
|
||||
|
||||
// Reset state lokal
|
||||
setPreviewImage(null);
|
||||
setFile(null);
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!file) {
|
||||
return toast.warn("Pilih file gambar terlebih dahulu");
|
||||
}
|
||||
|
||||
// Upload gambar dulu
|
||||
const res = await ApiFetch.api.fileStorage.create.post({
|
||||
file,
|
||||
name: file.name,
|
||||
});
|
||||
|
||||
const uploaded = res.data?.data;
|
||||
if (!uploaded?.id) {
|
||||
return toast.error("Gagal upload gambar");
|
||||
}
|
||||
|
||||
// Simpan ID gambar ke form
|
||||
programKesehatanState.create.form.imageId = uploaded.id;
|
||||
|
||||
// Submit data berita
|
||||
await programKesehatanState.create.create();
|
||||
|
||||
// Reset form setelah submit
|
||||
resetForm();
|
||||
router.push("/admin/kesehatan/program-kesehatan")
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
|
||||
<Paper bg={colors['white-1']} p="md" w={{ base: '100%', md: '50%' }}>
|
||||
<Stack gap="xs">
|
||||
<Title order={3}>Create Program Kesehatan</Title>
|
||||
|
||||
<TextInput
|
||||
|
||||
value={programKesehatanState.create.form.name}
|
||||
onChange={(val) => {
|
||||
programKesehatanState.create.form.name = val.target.value;
|
||||
}}
|
||||
label={<Text fz="sm" fw="bold">Judul</Text>}
|
||||
placeholder="masukkan judul"
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
|
||||
label={<Text fz="sm" fw="bold">Deskripsi</Text>}
|
||||
value={programKesehatanState.create.form.deskripsiSingkat}
|
||||
onChange={(val) => {
|
||||
programKesehatanState.create.form.deskripsiSingkat = val.target.value;
|
||||
}}
|
||||
label={<Text fz="sm" fw="bold">Deskripsi Singkat</Text>}
|
||||
placeholder="masukkan deskripsi"
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
|
||||
label={<Text fz="sm" fw="bold">Kategori</Text>}
|
||||
placeholder="masukkan kategori"
|
||||
/>
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Deskripsi</Text>
|
||||
<CreateEditor
|
||||
value={programKesehatanState.create.form.deskripsi}
|
||||
onChange={(val) => {
|
||||
programKesehatanState.create.form.deskripsi = val;
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* <FileInput
|
||||
<FileInput
|
||||
label={<Text fz="sm" fw="bold">Upload Gambar</Text>}
|
||||
value={file}
|
||||
onChange={async (e) => {
|
||||
@@ -48,25 +106,18 @@ function CreateProgramKesehatan() {
|
||||
);
|
||||
setPreviewImage(base64);
|
||||
}}
|
||||
/> */}
|
||||
/>
|
||||
|
||||
{/* {previewImage ? (
|
||||
{previewImage ? (
|
||||
<Image alt="" src={previewImage} w={200} h={200} />
|
||||
) : (
|
||||
<Center w={200} h={200} bg="gray">
|
||||
<IconImageInPicture />
|
||||
</Center>
|
||||
)} */}
|
||||
)}
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Konten</Text>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Button bg={colors['blue-button']}>
|
||||
Simpan Potensi
|
||||
<Button onClick={handleSubmit} bg={colors['blue-button']}>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Paper, Stack, Flex, Text, Image } from '@mantine/core';
|
||||
import { IconArrowBack, IconX, IconEdit } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import React from 'react';
|
||||
// import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
|
||||
|
||||
function DetailProgramKesehatan() {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
<Paper w={{ base: "100%", md: "50%" }} bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<Text fz={"xl"} fw={"bold"}>Detail Potensi</Text>
|
||||
|
||||
<Paper bg={colors['BG-trans']} p={'md'}>
|
||||
<Stack gap={"xs"}>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Judul</Text>
|
||||
<Text fz={"lg"}>Test Judul</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Kategori</Text>
|
||||
<Text fz={"lg"}>Test Kategori</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Deskripsi</Text>
|
||||
<Text fz={"lg"}>Test Deskripsi</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Gambar</Text>
|
||||
<Image src={"/"} alt="gambar" />
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fz={"lg"} fw={"bold"}>Konten</Text>
|
||||
<Text fz={"lg"} >Test Konten</Text>
|
||||
</Box>
|
||||
<Box>
|
||||
<Flex gap={"xs"}>
|
||||
<Button color="red">
|
||||
<IconX size={20} />
|
||||
</Button>
|
||||
<Button onClick={() => router.push('/admin/kesehatan/program-kesehatan/edit')} color="green">
|
||||
<IconEdit size={20} />
|
||||
</Button>
|
||||
</Flex>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
{/* Modal Hapus
|
||||
<ModalKonfirmasiHapus
|
||||
opened={modalHapus}
|
||||
onClose={() => setModalHapus(false)}
|
||||
onConfirm={handleHapus}
|
||||
text="Apakah anda yakin ingin menghapus potensi ini?"
|
||||
/> */}
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default DetailProgramKesehatan;
|
||||
@@ -1,64 +0,0 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Stack, SimpleGrid, Paper, Title, TextInput, Text, Button } from '@mantine/core';
|
||||
import { KesehatanEditor } from '../../_com/kesehatanEditor';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
|
||||
function EditProgramKesehatan() {
|
||||
const router = useRouter();
|
||||
return (
|
||||
<Box>
|
||||
<Box mb={10}>
|
||||
<Button variant="subtle" onClick={() => router.back()}>
|
||||
<IconArrowBack color={colors['blue-button']} size={25} />
|
||||
</Button>
|
||||
</Box>
|
||||
<Stack gap={"xs"}>
|
||||
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={"md"}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={3}>Edit Program Kesehatan</Title>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"} fz={"sm"}>Nama Program Kesehatan</Text>}
|
||||
placeholder='Masukkan nama Program Kesehatan'
|
||||
/>
|
||||
<TextInput
|
||||
label={<Text fw={"bold"} fz={"sm"}>No Telp Program Kesehatan</Text>}
|
||||
placeholder='Masukkan no telp Program Kesehatan'
|
||||
/>
|
||||
<Box>
|
||||
<Text fw={"bold"} fz={"sm"}>Deskripsi</Text>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
/>
|
||||
</Box>
|
||||
<Box>
|
||||
<Text fw={"bold"} fz={"sm"}>Pelayanan Posyandu</Text>
|
||||
<KesehatanEditor
|
||||
showSubmit={false}
|
||||
/>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Box>
|
||||
<Paper bg={colors['white-1']} p={"md"}>
|
||||
<Stack gap={"xs"}>
|
||||
<Title order={4}>Preview Data Program Kesehatan</Title>
|
||||
<Text fw={"bold"} fz={"sm"}>Nama Program Kesehatan</Text>
|
||||
<Text fw={"bold"} fz={"sm"}>No Telp Program Kesehatan</Text>
|
||||
<Text fw={"bold"} fz={"sm"}>Deskripsi</Text>
|
||||
<Text fw={"bold"} fz={"sm"}>Pelayanan Posyandu</Text>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
</SimpleGrid>
|
||||
</Stack>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
export default EditProgramKesehatan;
|
||||
@@ -1,10 +1,13 @@
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Image, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||
import { Box, Button, Image, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
|
||||
import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
|
||||
import JudulList from '../../_com/judulList';
|
||||
import HeaderSearch from '../../_com/header';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import programKesehatan from '../../_state/kesehatan/program-kesehatan/programKesehatan';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
|
||||
function ProgramKesehatan() {
|
||||
return (
|
||||
@@ -14,53 +17,70 @@ function ProgramKesehatan() {
|
||||
placeholder='pencarian'
|
||||
searchIcon={<IconSearch size={20} />}
|
||||
/>
|
||||
<ListProgramKesehatan/>
|
||||
<ListProgramKesehatan />
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
function ListProgramKesehatan() {
|
||||
const programKesehatanState = useProxy(programKesehatan)
|
||||
const router = useRouter()
|
||||
|
||||
useShallowEffect(() => {
|
||||
programKesehatanState.findMany.load()
|
||||
}, [])
|
||||
|
||||
if (!programKesehatanState.findMany.data) {
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Skeleton h={500} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<Box py={10}>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<JudulList
|
||||
title='List Program Kesehatan'
|
||||
href='/admin/kesehatan/program-kesehatan/create'
|
||||
/>
|
||||
<Box style={{ overflowX: "auto" }}>
|
||||
<Table striped withRowBorders withTableBorder style={{ minWidth: '700px' }}>
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh>Judul</TableTh>
|
||||
<TableTh>Kategori</TableTh>
|
||||
<TableTh>Image</TableTh>
|
||||
<TableTh>Detail</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
<TableTr>
|
||||
<TableTd>
|
||||
<Box w={100}>
|
||||
<Text truncate="end" fz={"sm"}>Test</Text>
|
||||
</Box></TableTd>
|
||||
<TableTd>Test</TableTd>
|
||||
<TableTd>
|
||||
<Image w={100} src={"/"} alt="image" />
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Button onClick={() => router.push('/admin/kesehatan/program-kesehatan/detail')}>
|
||||
<IconDeviceImacCog size={25} />
|
||||
</Button>
|
||||
</TableTd>
|
||||
</TableTr>
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
<Paper bg={colors['white-1']} p={'md'}>
|
||||
<Stack>
|
||||
<JudulList
|
||||
title='List Program Kesehatan'
|
||||
href='/admin/kesehatan/program-kesehatan/create'
|
||||
/>
|
||||
<Box style={{ overflowX: "auto" }}>
|
||||
<Table striped withRowBorders withTableBorder style={{ minWidth: '700px' }}>
|
||||
<TableThead>
|
||||
<TableTr>
|
||||
<TableTh w={250}>Judul</TableTh>
|
||||
<TableTh w={250}>Deskripsi Singkat</TableTh>
|
||||
<TableTh w={250}>Image</TableTh>
|
||||
<TableTh w={200}>Detail</TableTh>
|
||||
</TableTr>
|
||||
</TableThead>
|
||||
<TableTbody>
|
||||
{programKesehatanState.findMany.data?.map((item) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd>
|
||||
<Box w={100}>
|
||||
<Text truncate="end" fz={"sm"}>{item.name}</Text>
|
||||
</Box>
|
||||
</TableTd>
|
||||
<TableTd>{item.deskripsiSingkat}</TableTd>
|
||||
<TableTd>
|
||||
<Image w={100} src={item.image?.link} alt="image" />
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Button onClick={() => router.push(`/admin/kesehatan/program-kesehatan/${item.id}`)}>
|
||||
<IconDeviceImacCog size={25} />
|
||||
</Button>
|
||||
</TableTd>
|
||||
</TableTr>
|
||||
))}
|
||||
</TableTbody>
|
||||
</Table>
|
||||
</Box>
|
||||
</Stack>
|
||||
</Paper>
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -11,41 +11,26 @@ export const navBar = [
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_2",
|
||||
name: "Penghargaan",
|
||||
path: "/admin/landing-page/penghargaan"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_3",
|
||||
name: "Layanan",
|
||||
path: "/admin/landing-page/layanan"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_4",
|
||||
name: "Potensi",
|
||||
path: "/admin/landing-page/potensi"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_5",
|
||||
name: "Desa Anti Korupsi",
|
||||
path: "/admin/landing-page/desa-anti-korupsi"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_6",
|
||||
id: "Landing_Page_3",
|
||||
name: "Indeks Kepuasan Masyarakat",
|
||||
path: "/admin/landing-page/indeks-kepuasan-masyarakat"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_7",
|
||||
id: "Landing_Page_4",
|
||||
name: "SDGs Desa",
|
||||
path: "/admin/landing-page/sdgs-desa"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_8",
|
||||
id: "Landing_Page_5",
|
||||
name: "APBDes",
|
||||
path: "/admin/landing-page/apbdes"
|
||||
},
|
||||
{
|
||||
id: "Landing_Page_9",
|
||||
id: "Landing_Page_6",
|
||||
name: "Prestasi Desa",
|
||||
path: "/admin/landing-page/prestasi-desa"
|
||||
}
|
||||
|
||||
@@ -4,44 +4,51 @@ import { Context } from "elysia";
|
||||
import path from "path";
|
||||
|
||||
const penangananDaruratDelete = async (context: Context) => {
|
||||
const id = context.params?.id as string;
|
||||
|
||||
if (!id) {
|
||||
return {
|
||||
status: 400,
|
||||
body: "ID tidak diberikan",
|
||||
};
|
||||
}
|
||||
|
||||
const penangananDarurat = await prisma.penangananDarurat.findUnique({
|
||||
where: { id },
|
||||
include: { image: true },
|
||||
});
|
||||
if (!penangananDarurat) {
|
||||
return {
|
||||
status: 404,
|
||||
body: "Penanganan darurat tidak ditemukan",
|
||||
};
|
||||
}
|
||||
|
||||
// Hapus file gambar dari filesystem jika ada
|
||||
if (penangananDarurat.image) {
|
||||
try {
|
||||
const filePath = path.join(penangananDarurat.image.path, penangananDarurat.image.name);
|
||||
await fs.unlink(filePath);
|
||||
} catch (error) {
|
||||
console.error("Error deleting image file:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Hapus data dari database
|
||||
await prisma.penangananDarurat.delete({
|
||||
where: { id },
|
||||
});
|
||||
const id = context.params?.id as string;
|
||||
|
||||
if (!id) {
|
||||
return {
|
||||
status: 200,
|
||||
body: "Penanganan darurat berhasil dihapus",
|
||||
status: 400,
|
||||
body: "ID tidak diberikan",
|
||||
};
|
||||
}
|
||||
|
||||
const penangananDarurat = await prisma.penangananDarurat.findUnique({
|
||||
where: { id },
|
||||
include: { image: true },
|
||||
});
|
||||
if (!penangananDarurat) {
|
||||
return {
|
||||
status: 404,
|
||||
body: "Penanganan darurat tidak ditemukan",
|
||||
};
|
||||
}
|
||||
|
||||
// Hapus file gambar dari filesystem jika ada
|
||||
if (penangananDarurat.image) {
|
||||
try {
|
||||
const filePath = path.join(
|
||||
penangananDarurat.image.path,
|
||||
penangananDarurat.image.name
|
||||
);
|
||||
await fs.unlink(filePath);
|
||||
await prisma.fileStorage.delete({
|
||||
where: { id: penangananDarurat.image.id },
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Error deleting image file:", error);
|
||||
}
|
||||
}
|
||||
|
||||
// Hapus data dari database
|
||||
await prisma.penangananDarurat.delete({
|
||||
where: { id },
|
||||
});
|
||||
|
||||
return {
|
||||
status: 200,
|
||||
success: true,
|
||||
message: "Penanganan darurat dan file terkait berhasil dihapus",
|
||||
};
|
||||
};
|
||||
export default penangananDaruratDelete;
|
||||
export default penangananDaruratDelete;
|
||||
|
||||
@@ -6,7 +6,7 @@ import penangananDaruratFindUnique from "./findUnique";
|
||||
import penangananDaruratUpdate from "./updt";
|
||||
|
||||
const PenangananDarurat = new Elysia({
|
||||
prefix: "/penanganan-darurat",
|
||||
prefix: "/penanganandarurat",
|
||||
tags: ["Kesehatan/Penanganan Darurat"]
|
||||
})
|
||||
.post("/create", penangananDaruratCreate, {
|
||||
|
||||
Reference in New Issue
Block a user