From c99416c7f84c42f3eb06f578b99c063a1c9b5bb7 Mon Sep 17 00:00:00 2001 From: nico Date: Thu, 14 Aug 2025 10:24:03 +0800 Subject: [PATCH] Fix FileInput dengan Dropzone --- .../berita/list-berita/[id]/edit/page.tsx | 89 +++++-- .../desa/berita/list-berita/create/page.tsx | 80 ++++-- .../desa/penghargaan/[id]/edit/page.tsx | 81 ++++-- .../desa/penghargaan/create/page.tsx | 84 +++++-- .../profile/profile-perbekel/[id]/page.tsx | 95 +++++--- .../ekonomi/jumlah-pengangguran/page.tsx | 4 +- .../[id]/edit/page.tsx | 77 ++++-- .../create/page.tsx | 81 ++++-- .../[id]/edit/page.tsx | 77 ++++-- .../info-teknologi-tepat-guna/create/page.tsx | 81 ++++-- .../info-wabah-penyakit/[id]/edit/page.tsx | 133 ++++++---- .../info-wabah-penyakit/create/page.tsx | 77 ++++-- .../kontak-darurat/[id]/edit/page.tsx | 118 +++++---- .../kesehatan/kontak-darurat/create/page.tsx | 230 ++++++++++-------- .../penanganan-darurat/[id]/edit/page.tsx | 78 ++++-- .../penanganan-darurat/create/page.tsx | 83 +++++-- .../kesehatan/posyandu/[id]/edit/page.tsx | 80 ++++-- .../kesehatan/posyandu/create/page.tsx | 80 ++++-- .../program-kesehatan/[id]/edit/page.tsx | 132 ++++++---- .../program-kesehatan/create/page.tsx | 78 ++++-- .../kesehatan/puskesmas/[id]/edit/page.tsx | 99 +++++--- .../kesehatan/puskesmas/create/page.tsx | 81 ++++-- .../indeks-kepuasan-masyarakat/page.tsx | 4 + .../ppid/profile-ppid/[id]/page.tsx | 93 ++++--- .../posisi-organisasi/[id]/page.tsx | 15 +- .../posisi-organisasi/create/page.tsx | 17 +- 26 files changed, 1451 insertions(+), 696 deletions(-) diff --git a/src/app/admin/(dashboard)/desa/berita/list-berita/[id]/edit/page.tsx b/src/app/admin/(dashboard)/desa/berita/list-berita/[id]/edit/page.tsx index 1e99645c..00a92075 100644 --- a/src/app/admin/(dashboard)/desa/berita/list-berita/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/desa/berita/list-berita/[id]/edit/page.tsx @@ -1,28 +1,28 @@ /* eslint-disable react-hooks/exhaustive-deps */ "use client"; +import EditEditor from "@/app/admin/(dashboard)/_com/editEditor"; +import stateDashboardBerita from "@/app/admin/(dashboard)/_state/desa/berita"; +import colors from "@/con/colors"; +import ApiFetch from "@/lib/api-fetch"; import { Box, Button, - Center, + Group, Image, Paper, Select, Stack, Text, TextInput, - Title, + Title } from "@mantine/core"; -import { IconArrowBack, IconImageInPicture } from "@tabler/icons-react"; +import { Dropzone } from "@mantine/dropzone"; +import { IconArrowBack, IconPhoto, IconUpload, IconX } 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"; -import EditEditor from "@/app/admin/(dashboard)/_com/editEditor"; -import colors from "@/con/colors"; -import ApiFetch from "@/lib/api-fetch"; -import { FileInput } from "@mantine/core"; -import stateDashboardBerita from "@/app/admin/(dashboard)/_state/desa/berita"; function EditBerita() { @@ -130,27 +130,62 @@ function EditBerita() { placeholder="masukkan deskripsi" /> - Upload Gambar Baru (Opsional)} - 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); - }} - /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - {previewImage ? ( - - ) : ( -
- -
- )} +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
+
Konten - Upload Gambar} - 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 ? ( - - ) : ( -
- -
- )} + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
+
Konten Juara} placeholder="masukkan juara" /> - Upload Gambar Baru (Opsional)} - 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); - }} - /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - {previewImage ? ( - - ) : ( -
- -
- )} +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
+
Deskripsi diff --git a/src/app/admin/(dashboard)/desa/penghargaan/create/page.tsx b/src/app/admin/(dashboard)/desa/penghargaan/create/page.tsx index 838aa368..9083e826 100644 --- a/src/app/admin/(dashboard)/desa/penghargaan/create/page.tsx +++ b/src/app/admin/(dashboard)/desa/penghargaan/create/page.tsx @@ -1,14 +1,15 @@ 'use client' import colors from '@/con/colors'; -import { Box, Button, Center, FileInput, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; -import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react'; +import ApiFetch from '@/lib/api-fetch'; +import { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import { toast } from 'react-toastify'; import { useProxy } from 'valtio/utils'; -import penghargaanState from '../../../_state/desa/penghargaan'; -import ApiFetch from '@/lib/api-fetch'; import CreateEditor from '../../../_com/createEditor'; +import penghargaanState from '../../../_state/desa/penghargaan'; function CreatePenghargaan() { @@ -85,25 +86,62 @@ function CreatePenghargaan() { }} /> - Upload Gambar Konten} - 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 ? ( - - ) : ( -
- -
- )} + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
+
diff --git a/src/app/admin/(dashboard)/desa/profile/profile-perbekel/[id]/page.tsx b/src/app/admin/(dashboard)/desa/profile/profile-perbekel/[id]/page.tsx index 2768b0ae..ed9f0e62 100644 --- a/src/app/admin/(dashboard)/desa/profile/profile-perbekel/[id]/page.tsx +++ b/src/app/admin/(dashboard)/desa/profile/profile-perbekel/[id]/page.tsx @@ -4,8 +4,9 @@ import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import stateProfileDesa from '@/app/admin/(dashboard)/_state/desa/profile'; import colors from '@/con/colors'; import ApiFetch from '@/lib/api-fetch'; -import { Box, Button, Center, FileInput, Group, Image, Paper, Stack, Text, Title } from '@mantine/core'; -import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react'; +import { Box, Button, Center, Group, Image, Paper, Stack, Text, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -44,21 +45,7 @@ function ProfilePerbekel() { perbekelState.findUnique.reset(); // opsional: reset juga data lama }; }, [params?.id, router]); - - const handleFileChange = (newFile: File | null) => { - if (!newFile) { - setFile(null); - return; - } - - setFile(newFile); - - const reader = new FileReader(); - reader.onload = (event) => { - setPreviewImage(event.target?.result as string); - }; - reader.readAsDataURL(newFile); - }; + const handleSubmit = async () => { if (isSubmitting || !perbekelState.edit.form.biodata.trim()) { @@ -128,27 +115,61 @@ function ProfilePerbekel() { value={perbekelState.edit.form.biodata} onChange={(val) => perbekelState.edit.form.biodata = val} /> - {/* File Upload */} - Upload Gambar Baru (Opsional)} - value={file} - onChange={handleFileChange} - accept="image/*" - /> - - {/* Preview Gambar */} - Preview Gambar - {previewImage ? ( - Profile preview - ) : ( -
- - - Tidak ada gambar - -
- )} + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
diff --git a/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran/page.tsx b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran/page.tsx index 7da97e31..67f59594 100644 --- a/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran/page.tsx +++ b/src/app/admin/(dashboard)/ekonomi/jumlah-pengangguran/page.tsx @@ -116,14 +116,14 @@ function ListDetailDataPengangguran() { {!mounted && !chartData ? ( - Data Kelahiran & Kematian + Data Pengangguran Terdidik dan Tidak Terdidik Belum ada data untuk ditampilkan dalam grafik ) : ( - Data Kelahiran & Kematian + Data Pengangguran Terdidik dan Tidak Terdidik {mounted && chartData.length > 0 && ( Judul} placeholder="masukkan judul" /> - Upload Gambar Baru (Opsional)} - 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); - }} - /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - {previewImage ? ( - - ) : ( -
- -
- )} +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} +
+
Deskripsi - Upload Gambar Konten} - 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 ? ( - - ) : ( -
- -
- )} + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} +
+
diff --git a/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/[id]/edit/page.tsx b/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/[id]/edit/page.tsx index 842cab36..41d5fb65 100644 --- a/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/inovasi/info-teknologi-tepat-guna/[id]/edit/page.tsx @@ -4,8 +4,9 @@ import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import infoTeknoState from '@/app/admin/(dashboard)/_state/inovasi/info-tekno'; 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -94,27 +95,61 @@ function EditInfoTeknologiTepatGuna() { label={Judul} placeholder="masukkan judul" /> - Upload Gambar Baru (Opsional)} - 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); - }} - /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - {previewImage ? ( - - ) : ( -
- -
- )} +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} +
+
Deskripsi - Upload Gambar Konten} - 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 ? ( - - ) : ( -
- -
- )} + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} +
+
diff --git a/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/[id]/edit/page.tsx index a69c05fc..327f47a9 100644 --- a/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/[id]/edit/page.tsx @@ -4,8 +4,9 @@ import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import infoWabahPenyakit from '@/app/admin/(dashboard)/_state/kesehatan/info-wabah-penyakit/infoWabahPenyakit'; 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -91,57 +92,91 @@ function EditInfoWabahPenyakit() {
- - - Edit Info Wabah Penyakit - setFormData({ ...formData, name: e.target.value })} - label={Judul} - placeholder="masukkan judul" - /> - - setFormData({ ...formData, deskripsiSingkat: e.target.value })} - label={Deskripsi Singkat} - placeholder="masukkan deskripsi" - /> - - - Deskripsi - setFormData({ ...formData, deskripsi: val })} + + + Edit Info Wabah Penyakit + setFormData({ ...formData, name: e.target.value })} + label={Judul} + placeholder="masukkan judul" /> - - Upload Gambar} - 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); - }} - /> + setFormData({ ...formData, deskripsiSingkat: e.target.value })} + label={Deskripsi Singkat} + placeholder="masukkan deskripsi" + /> - {previewImage ? ( - - ) : ( -
- -
- )} + + Deskripsi + setFormData({ ...formData, deskripsi: val })} + /> + + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - -
-
+
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+ + + + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
+
+ + +
); diff --git a/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/create/page.tsx index 4fb3f039..4fbc8104 100644 --- a/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/create/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/info-wabah-penyakit/create/page.tsx @@ -1,14 +1,15 @@ 'use client' 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import { toast } from 'react-toastify'; import { useProxy } from 'valtio/utils'; import CreateEditor from '../../../_com/createEditor'; import infoWabahPenyakit from '../../../_state/kesehatan/info-wabah-penyakit/infoWabahPenyakit'; +import { Dropzone } from '@mantine/dropzone'; function CreateInfoWabahPenyakit() { const router = useRouter(); @@ -94,28 +95,62 @@ function CreateInfoWabahPenyakit() { }} /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - Upload Gambar} - 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); - }} - /> +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
- {previewImage ? ( - - ) : ( -
- -
- )} + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} +
+
diff --git a/src/app/admin/(dashboard)/kesehatan/kontak-darurat/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/[id]/edit/page.tsx index dea08402..d2927838 100644 --- a/src/app/admin/(dashboard)/kesehatan/kontak-darurat/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/[id]/edit/page.tsx @@ -4,8 +4,9 @@ import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import kontakDarurat from '@/app/admin/(dashboard)/_state/kesehatan/kontak-darurat/kontakDarurat'; 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -89,49 +90,82 @@ function EditKontakDarurat() { - - - Edit Kontak Darurat - setFormData({ ...formData, name: e.target.value })} - label={Judul} - placeholder="masukkan judul" - /> - - Deskripsi - setFormData({ ...formData, deskripsi: val })} + + + Edit Kontak Darurat + setFormData({ ...formData, name: e.target.value })} + label={Judul} + placeholder="masukkan judul" /> - + + Deskripsi + setFormData({ ...formData, deskripsi: val })} + /> + + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - Upload Gambar} - 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); - }} - /> +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
- {previewImage ? ( - - ) : ( -
- -
- )} - - -
-
+ {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + + + +
+ ); diff --git a/src/app/admin/(dashboard)/kesehatan/kontak-darurat/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/create/page.tsx index ac55207c..e318dee1 100644 --- a/src/app/admin/(dashboard)/kesehatan/kontak-darurat/create/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/kontak-darurat/create/page.tsx @@ -1,113 +1,147 @@ 'use client' import colors from '@/con/colors'; -import { Box, Button, Center, FileInput, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; -import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react'; +import ApiFetch from '@/lib/api-fetch'; +import { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; -import { useProxy } from 'valtio/utils'; -import kontakDarurat from '../../../_state/kesehatan/kontak-darurat/kontakDarurat'; import { useState } from 'react'; import { toast } from 'react-toastify'; -import ApiFetch from '@/lib/api-fetch'; +import { useProxy } from 'valtio/utils'; import CreateEditor from '../../../_com/createEditor'; +import kontakDarurat from '../../../_state/kesehatan/kontak-darurat/kontakDarurat'; +import { Dropzone } from '@mantine/dropzone'; function CreateKontakDarurat() { - const router = useRouter(); - const kontakDaruratState = useProxy(kontakDarurat) - const [previewImage, setPreviewImage] = useState(null); - const [file, setFile] = useState(null); - - const resetForm = () => { - kontakDaruratState.create.form = { - name: "", - deskripsi: "", - imageId: "", - }; - setPreviewImage(null); - setFile(null); + const router = useRouter(); + const kontakDaruratState = useProxy(kontakDarurat) + const [previewImage, setPreviewImage] = useState(null); + const [file, setFile] = useState(null); + + const resetForm = () => { + kontakDaruratState.create.form = { + name: "", + deskripsi: "", + imageId: "", }; - - 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"); - } - - kontakDaruratState.create.form.imageId = uploaded.id; - - await kontakDaruratState.create.create(); - - resetForm(); - router.push("/admin/kesehatan/kontak-darurat") + setPreviewImage(null); + setFile(null); + }; + + const handleSubmit = async () => { + if (!file) { + return toast.warn("Pilih file gambar terlebih dahulu"); } - return ( - - - - - - - - Create Kontak Darurat - - { - kontakDaruratState.create.form.name = val.target.value; - }} - label={Judul} - placeholder="masukkan judul" - /> - - - Deskripsi - { - kontakDaruratState.create.form.deskripsi = val; - }} - /> - - - Upload Gambar} - 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 ? ( - - ) : ( -
- -
- )} - - -
-
+ + 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"); + } + + kontakDaruratState.create.form.imageId = uploaded.id; + + await kontakDaruratState.create.create(); + + resetForm(); + router.push("/admin/kesehatan/kontak-darurat") + } + return ( + + + - ); + + + + Create Kontak Darurat + + { + kontakDaruratState.create.form.name = val.target.value; + }} + label={Judul} + placeholder="masukkan judul" + /> + + + Deskripsi + { + kontakDaruratState.create.form.deskripsi = val; + }} + /> + + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} +
+
+ +
+
+
+ ); } export default CreateKontakDarurat; diff --git a/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/[id]/edit/page.tsx index 3f1c5019..911fdaf2 100644 --- a/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/[id]/edit/page.tsx @@ -4,8 +4,9 @@ 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -105,28 +106,61 @@ function EditPenangananDarurat() { onChange={(val) => setFormData({ ...formData, deskripsi: val })} />
+ + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - Upload Gambar} - 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 ? ( - - ) : ( -
- -
- )} +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} +
+
diff --git a/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/create/page.tsx index 2c972d9b..a712dba6 100644 --- a/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/create/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/penanganan-darurat/create/page.tsx @@ -1,8 +1,9 @@ 'use client' 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import { toast } from 'react-toastify'; @@ -79,31 +80,65 @@ function CreatePenangananDarurat() { }} /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - Upload Gambar} - 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); - }} - /> +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
- {previewImage ? ( - - ) : ( -
- -
- )} + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} - +
+
+ diff --git a/src/app/admin/(dashboard)/kesehatan/posyandu/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/posyandu/[id]/edit/page.tsx index 192f363a..66133acf 100644 --- a/src/app/admin/(dashboard)/kesehatan/posyandu/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/posyandu/[id]/edit/page.tsx @@ -4,8 +4,9 @@ import EditEditor from '@/app/admin/(dashboard)/_com/editEditor'; import posyandustate from '@/app/admin/(dashboard)/_state/kesehatan/posyandu/posyandu'; import colors from '@/con/colors'; import ApiFetch from '@/lib/api-fetch'; -import { Box, Button, Center, FileInput, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; -import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react'; +import { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -94,25 +95,62 @@ function EditPosyandu() { Edit Posyandu - {previewImage ? ( - - ) : ( -
- -
- )} - Upload Gambar} - 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); - }} - /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
+
setFormData({ ...formData, name: e.target.value })} diff --git a/src/app/admin/(dashboard)/kesehatan/posyandu/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/posyandu/create/page.tsx index f0c09ea7..6784da6b 100644 --- a/src/app/admin/(dashboard)/kesehatan/posyandu/create/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/posyandu/create/page.tsx @@ -1,8 +1,9 @@ 'use client' import colors from '@/con/colors'; import ApiFetch from '@/lib/api-fetch'; -import { Box, Button, Center, FileInput, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; -import { IconArrowBack, IconImageInPicture } from '@tabler/icons-react'; +import { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useState } from 'react'; import { toast } from 'react-toastify'; @@ -65,25 +66,62 @@ function CreatePosyandu() { Create Posyandu - {previewImage ? ( - - ) : ( -
- -
- )} - Upload Gambar} - 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); - }} - /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
+
Nama Posyandu} placeholder='Masukkan nama posyandu' diff --git a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/[id]/edit/page.tsx index 4f4e527e..bf8a9fcb 100644 --- a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/[id]/edit/page.tsx @@ -4,8 +4,9 @@ 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -91,57 +92,90 @@ function EditProgramKesehatan() { - - - Edit Program Kesehatan - setFormData({ ...formData, name: e.target.value })} - label={Judul} - placeholder="masukkan judul" - /> - - setFormData({ ...formData, deskripsiSingkat: e.target.value })} - label={Deskripsi Singkat} - placeholder="masukkan deskripsi" - /> - - - Deskripsi - setFormData({ ...formData, deskripsi: val })} + + + Edit Program Kesehatan + setFormData({ ...formData, name: e.target.value })} + label={Judul} + placeholder="masukkan judul" /> - - Upload Gambar} - 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); - }} - /> + setFormData({ ...formData, deskripsiSingkat: e.target.value })} + label={Deskripsi Singkat} + placeholder="masukkan deskripsi" + /> - {previewImage ? ( - - ) : ( -
- -
- )} + + Deskripsi + setFormData({ ...formData, deskripsi: val })} + /> + + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - -
-
+
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+ + + + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + + + +
+
); diff --git a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/create/page.tsx b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/create/page.tsx index 1bd5f486..449ff9e2 100644 --- a/src/app/admin/(dashboard)/kesehatan/program-kesehatan/create/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/program-kesehatan/create/page.tsx @@ -1,14 +1,15 @@ 'use client' 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; 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'; +import { Dropzone } from '@mantine/dropzone'; function CreateProgramKesehatan() { const router = useRouter(); @@ -94,28 +95,61 @@ function CreateProgramKesehatan() { }} /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - Upload Gambar} - 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 ? ( - - ) : ( -
- -
- )} +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} +
+
diff --git a/src/app/admin/(dashboard)/kesehatan/puskesmas/[id]/edit/page.tsx b/src/app/admin/(dashboard)/kesehatan/puskesmas/[id]/edit/page.tsx index 2d84f27a..1168e26d 100644 --- a/src/app/admin/(dashboard)/kesehatan/puskesmas/[id]/edit/page.tsx +++ b/src/app/admin/(dashboard)/kesehatan/puskesmas/[id]/edit/page.tsx @@ -4,8 +4,9 @@ import puskesmasState from '@/app/admin/(dashboard)/_state/kesehatan/puskesmas/puskesmas'; 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 { Box, Button, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Dropzone } from '@mantine/dropzone'; +import { IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { ChangeEvent, useEffect, useState } from 'react'; import { toast } from 'react-toastify'; @@ -141,22 +142,6 @@ function EditPuskesmas() { } }; - const handleFileChange = (selectedFile: File | null) => { - if (selectedFile) { - setFile(selectedFile); - const reader = new FileReader(); - reader.onload = (e) => { - if (e.target?.result) { - setPreviewImage(e.target.result as string); - } - }; - reader.readAsDataURL(selectedFile); - } else { - setFile(null); - setPreviewImage(null); - } - }; - const handleInputChange = (e: ChangeEvent) => { const { name, value } = e.target; setFormData(prev => ({ @@ -186,7 +171,7 @@ function EditPuskesmas() { Edit Puskesmas - + Nama Puskesmas} placeholder="masukkan nama puskesmas" @@ -252,26 +237,66 @@ function EditPuskesmas() { onChange={(e) => handleNestedChange('kontak', 'kontakUGD', e.target.value)} /> - } - value={file} - onChange={handleFileChange} - /> + + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + - {previewImage ? ( - Preview - ) : ( -
- -
- )} +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
- diff --git a/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/indeks-kepuasan-masyarakat/page.tsx b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/indeks-kepuasan-masyarakat/page.tsx index 1f466e3c..6bb6d463 100644 --- a/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/indeks-kepuasan-masyarakat/page.tsx +++ b/src/app/admin/(dashboard)/ppid/ikm-desa-darmasaba/indeks-kepuasan-masyarakat/page.tsx @@ -36,6 +36,10 @@ function Page() { const [barChartData, setBarChartData] = useState>([]); useShallowEffect(() => { + if (!data && !loading) { + state.findMany.load(); + return; + } if (data) { // Hitung total berdasarkan jenis kelamin const totalLaki = data.filter((item: any) => item.jenisKelamin?.name?.toLowerCase() === 'laki-laki').length; diff --git a/src/app/admin/(dashboard)/ppid/profile-ppid/[id]/page.tsx b/src/app/admin/(dashboard)/ppid/profile-ppid/[id]/page.tsx index 72956a86..b32c2162 100644 --- a/src/app/admin/(dashboard)/ppid/profile-ppid/[id]/page.tsx +++ b/src/app/admin/(dashboard)/ppid/profile-ppid/[id]/page.tsx @@ -1,13 +1,14 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ 'use client' import colors from '@/con/colors'; -import { Alert, Box, Button, Center, FileInput, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; +import { Alert, Box, Button, Center, Group, Image, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; import { useEffect, useState } from 'react'; import { useProxy } from 'valtio/utils'; import stateProfilePPID from '../../../_state/ppid/profile_ppid/profile_PPID'; import ApiFetch from '@/lib/api-fetch'; -import { IconAlertCircle, IconArrowBack, IconImageInPicture } from '@tabler/icons-react'; +import { Dropzone } from '@mantine/dropzone'; +import { IconAlertCircle, IconArrowBack, IconPhoto, IconUpload, IconX } from '@tabler/icons-react'; import { useParams, useRouter } from 'next/navigation'; import { toast } from 'react-toastify'; import Biodata from './biodata/biodataForm'; @@ -58,21 +59,6 @@ function EditProfilePPID() { stateProfilePPID.editForm.updateField(field as any, value); }; - const handleFileChange = (newFile: File | null) => { - if (!newFile) { - setFile(null); - return; - } - - setFile(newFile); - - const reader = new FileReader(); - reader.onload = (event) => { - setPreviewImage(event.target?.result as string); - }; - reader.readAsDataURL(newFile); - }; - const handleSubmit = async () => { if (isSubmitting || !stateProfilePPID.editForm.form.name.trim()) { toast.error("Nama wajib diisi"); @@ -183,26 +169,61 @@ function EditProfilePPID() { /> {/* File Upload */} - Upload Gambar Baru (Opsional)} - value={file} - onChange={handleFileChange} - accept="image/*" - /> - - {/* Preview Gambar */} - Preview Gambar - {previewImage ? ( - Profile preview - ) : ( -
- - - Tidak ada gambar - -
- )} + Gambar + + { + const selectedFile = files[0]; // Ambil file pertama + if (selectedFile) { + setFile(selectedFile); + setPreviewImage(URL.createObjectURL(selectedFile)); // Buat preview + } + }} + onReject={() => toast.error('File tidak valid.')} + maxSize={5 * 1024 ** 2} // Maks 5MB + accept={{ 'image/*': [] }} + > + + + + + + + + + + + +
+ + Drag gambar ke sini atau klik untuk pilih file + + + Maksimal 5MB dan harus format gambar + +
+
+
+ + {/* Tampilkan preview kalau ada */} + {previewImage && ( + + Preview + + )} + +
{/* Rich Components */} diff --git a/src/app/admin/(dashboard)/ppid/struktur-ppid/posisi-organisasi/[id]/page.tsx b/src/app/admin/(dashboard)/ppid/struktur-ppid/posisi-organisasi/[id]/page.tsx index 21a7c79e..617aa57e 100644 --- a/src/app/admin/(dashboard)/ppid/struktur-ppid/posisi-organisasi/[id]/page.tsx +++ b/src/app/admin/(dashboard)/ppid/struktur-ppid/posisi-organisasi/[id]/page.tsx @@ -93,12 +93,15 @@ function EditPosisiOrganisasiPPID() { label={Nama Posisi Organisasi} placeholder='Masukkan nama posisi organisasi' /> - { - setFormData({ ...formData, deskripsi: htmlContent }); - }} - /> + + Deskripsi + { + setFormData({ ...formData, deskripsi: htmlContent }); + }} + /> + setFormData({ ...formData, hierarki: parseInt(e.target.value) })} diff --git a/src/app/admin/(dashboard)/ppid/struktur-ppid/posisi-organisasi/create/page.tsx b/src/app/admin/(dashboard)/ppid/struktur-ppid/posisi-organisasi/create/page.tsx index 88b535f4..39a47477 100644 --- a/src/app/admin/(dashboard)/ppid/struktur-ppid/posisi-organisasi/create/page.tsx +++ b/src/app/admin/(dashboard)/ppid/struktur-ppid/posisi-organisasi/create/page.tsx @@ -3,7 +3,7 @@ import CreateEditor from '@/app/admin/(dashboard)/_com/createEditor'; import stateStrukturPPID from '@/app/admin/(dashboard)/_state/ppid/struktur_ppid/struktur_PPID'; import colors from '@/con/colors'; -import { Box, Button, Paper, Stack, TextInput, Title } from '@mantine/core'; +import { Box, Button, Paper, Stack, Text, TextInput, Title } from '@mantine/core'; import { IconArrowBack } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; import { useEffect } from 'react'; @@ -46,12 +46,15 @@ function CreatePosisiOrganisasiPPID() { value={stateOrganisasi.create.form.nama} onChange={(e) => (stateOrganisasi.create.form.nama = e.currentTarget.value)} /> - { - stateOrganisasi.create.form.deskripsi = htmlContent; - }} - /> + + Deskripsi + { + stateOrganisasi.create.form.deskripsi = htmlContent; + }} + /> +