fix inputan edit menu: desa, ekonomi, inovasi, keamanan, kesehatan, landing-page, & lingkungan
This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
"use client";
|
||||
|
||||
import {
|
||||
@@ -40,12 +39,12 @@ function EditKeamananLingkungan() {
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [formData, setFormData] = useState({
|
||||
name: keamananState.edit.form.name || "",
|
||||
deskripsi: keamananState.edit.form.deskripsi || "",
|
||||
imageId: keamananState.edit.form.imageId || "",
|
||||
name: "",
|
||||
deskripsi: "",
|
||||
imageId: "",
|
||||
});
|
||||
|
||||
// Load data by id
|
||||
// Load data sekali pas mount
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
const id = params?.id as string;
|
||||
@@ -71,16 +70,16 @@ function EditKeamananLingkungan() {
|
||||
};
|
||||
|
||||
loadData();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [params?.id]);
|
||||
|
||||
const handleChange = (field: string, value: string) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
keamananState.edit.form = {
|
||||
...keamananState.edit.form,
|
||||
name: formData.name,
|
||||
deskripsi: formData.deskripsi,
|
||||
imageId: formData.imageId,
|
||||
};
|
||||
let imageId = formData.imageId;
|
||||
|
||||
if (file) {
|
||||
const res = await ApiFetch.api.fileStorage.create.post({
|
||||
@@ -93,9 +92,17 @@ function EditKeamananLingkungan() {
|
||||
return toast.error("Gagal upload gambar");
|
||||
}
|
||||
|
||||
keamananState.edit.form.imageId = uploaded.id;
|
||||
imageId = uploaded.id;
|
||||
}
|
||||
|
||||
// update global state hanya sekali pas submit
|
||||
keamananState.edit.form = {
|
||||
...keamananState.edit.form,
|
||||
name: formData.name,
|
||||
deskripsi: formData.deskripsi,
|
||||
imageId,
|
||||
};
|
||||
|
||||
await keamananState.edit.update();
|
||||
toast.success("Keamanan Lingkungan berhasil diperbarui!");
|
||||
router.push("/admin/keamanan/keamanan-lingkungan-pecalang-patwal");
|
||||
@@ -186,7 +193,7 @@ function EditKeamananLingkungan() {
|
||||
</Dropzone>
|
||||
|
||||
{previewImage ? (
|
||||
<Image alt="" src={previewImage} w={200} h={200} loading="lazy"/>
|
||||
<Image alt="" src={previewImage} w={200} h={200} loading="lazy" />
|
||||
) : (
|
||||
<Center w={200} h={200} bg={"gray"}>
|
||||
<IconImageInPicture />
|
||||
@@ -194,10 +201,8 @@ function EditKeamananLingkungan() {
|
||||
)}
|
||||
|
||||
<TextInput
|
||||
defaultValue={formData.name}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, name: e.target.value })
|
||||
}
|
||||
value={formData.name}
|
||||
onChange={(e) => handleChange("name", e.target.value)}
|
||||
label="Judul Keamanan Lingkungan"
|
||||
placeholder="Masukkan judul"
|
||||
required
|
||||
@@ -209,10 +214,7 @@ function EditKeamananLingkungan() {
|
||||
</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsi}
|
||||
onChange={(htmlContent) => {
|
||||
setFormData((prev) => ({ ...prev, deskripsi: htmlContent }));
|
||||
keamananState.edit.form.deskripsi = htmlContent;
|
||||
}}
|
||||
onChange={(htmlContent) => handleChange("deskripsi", htmlContent)}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
@@ -27,11 +27,12 @@ function EditKontakItem() {
|
||||
const params = useParams();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: kontakState.update.form.nama || '',
|
||||
nomorTelepon: kontakState.update.form.nomorTelepon || '',
|
||||
icon: kontakState.update.form.icon || '',
|
||||
name: '',
|
||||
nomorTelepon: '',
|
||||
icon: '',
|
||||
});
|
||||
|
||||
// Load data sekali dari global state
|
||||
useEffect(() => {
|
||||
const loadKontakDarurat = async () => {
|
||||
const id = params?.id as string;
|
||||
@@ -55,14 +56,23 @@ function EditKontakItem() {
|
||||
loadKontakDarurat();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleChange = (field: keyof typeof formData, value: string) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
// Update global state sekali pas submit
|
||||
kontakState.update.form = {
|
||||
...kontakState.update.form,
|
||||
nama: formData.name,
|
||||
nomorTelepon: formData.nomorTelepon,
|
||||
icon: formData.icon,
|
||||
};
|
||||
|
||||
await kontakState.update.update();
|
||||
toast.success('Kontak Darurat berhasil diperbarui!');
|
||||
router.push('/admin/keamanan/kontak-darurat/kontak-darurat-item');
|
||||
@@ -99,16 +109,16 @@ function EditKontakItem() {
|
||||
<TextInput
|
||||
label="Nama Kontak"
|
||||
placeholder="Masukkan nama kontak"
|
||||
defaultValue={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
value={formData.name}
|
||||
onChange={(e) => handleChange('name', e.target.value)}
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Nomor Telepon"
|
||||
placeholder="Masukkan nomor telepon"
|
||||
defaultValue={formData.nomorTelepon}
|
||||
onChange={(e) => setFormData({ ...formData, nomorTelepon: e.target.value })}
|
||||
value={formData.nomorTelepon}
|
||||
onChange={(e) => handleChange('nomorTelepon', e.target.value)}
|
||||
required
|
||||
/>
|
||||
|
||||
@@ -118,10 +128,7 @@ function EditKontakItem() {
|
||||
</Text>
|
||||
<SelectIconProgramEdit
|
||||
value={formData.icon as IconKey}
|
||||
onChange={(value) => {
|
||||
setFormData((prev) => ({ ...prev, icon: value }));
|
||||
kontakState.update.form.icon = value;
|
||||
}}
|
||||
onChange={(value) => handleChange('icon', value)}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
@@ -15,40 +15,40 @@ import {
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
Tooltip
|
||||
Tooltip,
|
||||
} from "@mantine/core";
|
||||
import {
|
||||
IconArrowBack
|
||||
} from "@tabler/icons-react";
|
||||
import { IconArrowBack } from "@tabler/icons-react";
|
||||
import { useParams, useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
import { useProxy } from "valtio/utils";
|
||||
|
||||
function EditKontakDaruratKeamanan() {
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const router = useRouter();
|
||||
const kontakState = useProxy(kontakDarurat.kontakDaruratKeamananState);
|
||||
const params = useParams();
|
||||
const kontakState = useProxy(kontakDarurat.kontakDaruratKeamananState);
|
||||
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const [formData, setFormData] = useState({
|
||||
name: kontakState.update.form.nama || "",
|
||||
icon: kontakState.update.form.icon || "",
|
||||
kategoriId: kontakState.update.form.kategoriId || [],
|
||||
name: "",
|
||||
icon: "" as IconKey | "",
|
||||
kategoriId: [] as string[],
|
||||
});
|
||||
|
||||
// Load data
|
||||
// Load data dari backend
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await kontakDarurat.kontakDaruratItem.findMany.load();
|
||||
|
||||
const id = params?.id as string;
|
||||
if (id) {
|
||||
const data = await kontakState.update.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
name: data.nama || "",
|
||||
icon: data.icon || "",
|
||||
icon: (data.icon as IconKey) || "",
|
||||
kategoriId: data.kategoriId || [],
|
||||
});
|
||||
}
|
||||
@@ -63,6 +63,7 @@ function EditKontakDaruratKeamanan() {
|
||||
|
||||
loadData();
|
||||
}, [params?.id]);
|
||||
|
||||
// Handle submit
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
@@ -72,6 +73,7 @@ function EditKontakDaruratKeamanan() {
|
||||
icon: formData.icon,
|
||||
kategoriId: formData.kategoriId,
|
||||
};
|
||||
|
||||
await kontakState.update.update();
|
||||
toast.success("Kontak Darurat berhasil diperbarui!");
|
||||
router.push("/admin/keamanan/kontak-darurat");
|
||||
@@ -110,43 +112,54 @@ function EditKontakDaruratKeamanan() {
|
||||
style={{ border: "1px solid #e0e0e0" }}
|
||||
>
|
||||
<Stack gap="md">
|
||||
{/* Nama kategori */}
|
||||
{/* Nama Kontak */}
|
||||
<TextInput
|
||||
defaultValue={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
value={formData.name}
|
||||
onChange={(e) =>
|
||||
setFormData((prev) => ({ ...prev, name: e.target.value }))
|
||||
}
|
||||
label="Nama Kontak Darurat"
|
||||
placeholder="Masukkan nama kontak darurat"
|
||||
required
|
||||
/>
|
||||
|
||||
{/* MultiSelect */}
|
||||
<MultiSelect
|
||||
value={formData.kategoriId}
|
||||
onChange={(val) => setFormData({ ...formData, kategoriId: val })}
|
||||
onChange={(val) =>
|
||||
setFormData((prev) => ({ ...prev, kategoriId: val }))
|
||||
}
|
||||
label={<Text fw={"bold"} fz={"sm"}>Kontak Item</Text>}
|
||||
placeholder={isLoading ? "Memuat data..." : "Pilih kontak item"}
|
||||
data={
|
||||
Array.isArray(kontakDarurat.kontakDaruratItem.findMany.data)
|
||||
? kontakDarurat.kontakDaruratItem.findMany.data.map((v) => ({
|
||||
value: v.id,
|
||||
label: v.nama
|
||||
}))
|
||||
value: v.id,
|
||||
label: v.nama,
|
||||
}))
|
||||
: []
|
||||
}
|
||||
clearable
|
||||
searchable
|
||||
required
|
||||
error={!formData.kategoriId.length ? "Pilih minimal satu kategori" : undefined}
|
||||
error={
|
||||
!formData.kategoriId.length
|
||||
? "Pilih minimal satu kategori"
|
||||
: undefined
|
||||
}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
|
||||
{/* Icon Select */}
|
||||
<Box>
|
||||
<Text fz={"sm"} fw={"bold"}>Ikon Program Kreatif Desa</Text>
|
||||
<Text fz={"sm"} fw={"bold"}>
|
||||
Ikon Program Kreatif Desa
|
||||
</Text>
|
||||
<SelectIconProgramEdit
|
||||
value={formData.icon as IconKey}
|
||||
onChange={(value) => {
|
||||
setFormData((prev) => ({ ...prev, icon: value }));
|
||||
kontakState.update.form.icon = value;
|
||||
}}
|
||||
onChange={(value) =>
|
||||
setFormData((prev) => ({ ...prev, icon: value }))
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
import laporanPublikState from '@/app/admin/(dashboard)/_state/keamanan/laporan-publik';
|
||||
@@ -30,13 +28,20 @@ function EditLaporanPublik() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
judul: stateLaporan.edit.form.judul || '',
|
||||
lokasi: stateLaporan.edit.form.lokasi || '',
|
||||
tanggalWaktu: stateLaporan.edit.form.tanggalWaktu || '',
|
||||
status: stateLaporan.edit.form.status || '',
|
||||
penanganan: stateLaporan.edit.form.penanganan || '',
|
||||
kronologi: stateLaporan.edit.form.kronologi || '',
|
||||
const [formData, setFormData] = useState<{
|
||||
judul: string;
|
||||
lokasi: string;
|
||||
tanggalWaktu: string;
|
||||
status: Status;
|
||||
penanganan: string;
|
||||
kronologi: string;
|
||||
}>({
|
||||
judul: '',
|
||||
lokasi: '',
|
||||
tanggalWaktu: '',
|
||||
status: 'Proses', // Default status
|
||||
penanganan: '',
|
||||
kronologi: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -52,7 +57,7 @@ function EditLaporanPublik() {
|
||||
lokasi: data.lokasi || '',
|
||||
tanggalWaktu: data.tanggalWaktu || '',
|
||||
status: data.status || '',
|
||||
penanganan: data.penanganan?.map((p: any) => p.deskripsi)[0] || '',
|
||||
penanganan: data.penanganan?.[0]?.deskripsi || '',
|
||||
kronologi: data.kronologi || '',
|
||||
});
|
||||
}
|
||||
@@ -63,18 +68,17 @@ function EditLaporanPublik() {
|
||||
};
|
||||
|
||||
loadLaporanPublik();
|
||||
}, [params?.id]);
|
||||
}, [params?.id, stateLaporan.edit]);
|
||||
|
||||
const handleChange = (field: string, value: string | Status) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
stateLaporan.edit.form = {
|
||||
...stateLaporan.edit.form,
|
||||
judul: formData.judul,
|
||||
lokasi: formData.lokasi,
|
||||
tanggalWaktu: formData.tanggalWaktu,
|
||||
status: formData.status,
|
||||
penanganan: formData.penanganan,
|
||||
kronologi: formData.kronologi,
|
||||
...formData,
|
||||
};
|
||||
|
||||
await stateLaporan.edit.update();
|
||||
@@ -111,16 +115,16 @@ function EditLaporanPublik() {
|
||||
>
|
||||
<Stack gap="md">
|
||||
<TextInput
|
||||
defaultValue={formData.judul}
|
||||
onChange={(e) => setFormData({ ...formData, judul: e.target.value })}
|
||||
value={formData.judul}
|
||||
onChange={(e) => handleChange('judul', e.target.value)}
|
||||
label={<Text fw="bold" fz="sm">Judul Laporan Publik</Text>}
|
||||
placeholder="Masukkan judul laporan publik"
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
defaultValue={formData.lokasi}
|
||||
onChange={(e) => setFormData({ ...formData, lokasi: e.target.value })}
|
||||
value={formData.lokasi}
|
||||
onChange={(e) => handleChange('lokasi', e.target.value)}
|
||||
label={<Text fw="bold" fz="sm">Lokasi Laporan Publik</Text>}
|
||||
placeholder="Masukkan lokasi laporan publik"
|
||||
required
|
||||
@@ -129,15 +133,20 @@ function EditLaporanPublik() {
|
||||
<DateTimePicker
|
||||
label="Tanggal & Waktu Laporan Publik"
|
||||
value={formData.tanggalWaktu ? new Date(formData.tanggalWaktu) : null}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, tanggalWaktu: val ? val.toString() : '' })
|
||||
}
|
||||
onChange={(value: string | null) => {
|
||||
if (value) {
|
||||
const date = new Date(value);
|
||||
handleChange('tanggalWaktu', date.toISOString());
|
||||
} else {
|
||||
handleChange('tanggalWaktu', '');
|
||||
}
|
||||
}}
|
||||
required
|
||||
/>
|
||||
|
||||
<Select
|
||||
value={formData.status}
|
||||
onChange={(e) => setFormData({ ...formData, status: e as Status })}
|
||||
onChange={(val) => handleChange('status', val as Status)}
|
||||
label={<Text fw="bold" fz="sm">Status Laporan Publik</Text>}
|
||||
placeholder="Pilih status laporan publik"
|
||||
data={[
|
||||
@@ -152,10 +161,7 @@ function EditLaporanPublik() {
|
||||
<Text fw="bold" fz="sm" mb={6}>Kronologi Laporan Publik</Text>
|
||||
<EditEditor
|
||||
value={formData.kronologi}
|
||||
onChange={(htmlContent) => {
|
||||
setFormData((prev) => ({ ...prev, kronologi: htmlContent }));
|
||||
stateLaporan.edit.form.kronologi = htmlContent;
|
||||
}}
|
||||
onChange={(htmlContent) => handleChange('kronologi', htmlContent)}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
@@ -163,10 +169,7 @@ function EditLaporanPublik() {
|
||||
<Text fw="bold" fz="sm" mb={6}>Penanganan Laporan Publik</Text>
|
||||
<EditEditor
|
||||
value={formData.penanganan}
|
||||
onChange={(htmlContent) => {
|
||||
setFormData((prev) => ({ ...prev, penanganan: htmlContent }));
|
||||
stateLaporan.edit.form.penanganan = htmlContent;
|
||||
}}
|
||||
onChange={(htmlContent) => handleChange('penanganan', htmlContent)}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
Stack,
|
||||
TextInput,
|
||||
Title,
|
||||
Tooltip
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
@@ -32,6 +32,7 @@ function EditPencegahanKriminalitas() {
|
||||
linkVideo: '',
|
||||
});
|
||||
|
||||
// load data hanya sekali pas id berubah
|
||||
useEffect(() => {
|
||||
const loadKriminalitas = async () => {
|
||||
const id = params?.id as string;
|
||||
@@ -41,10 +42,10 @@ function EditPencegahanKriminalitas() {
|
||||
const data = await kriminalitasState.update.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
judul: data.judul || '',
|
||||
deskripsi: data.deskripsi || '',
|
||||
deskripsiSingkat: data.deskripsiSingkat || '',
|
||||
linkVideo: data.linkVideo || '',
|
||||
judul: data.judul ?? '',
|
||||
deskripsi: data.deskripsi ?? '',
|
||||
deskripsiSingkat: data.deskripsiSingkat ?? '',
|
||||
linkVideo: data.linkVideo ?? '',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -58,6 +59,12 @@ function EditPencegahanKriminalitas() {
|
||||
|
||||
const embedLink = convertYoutubeUrlToEmbed(formData.linkVideo);
|
||||
|
||||
const handleChange =
|
||||
(field: keyof typeof formData) =>
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: e.target.value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const converted = convertYoutubeUrlToEmbed(formData.linkVideo);
|
||||
if (!converted) {
|
||||
@@ -66,16 +73,13 @@ function EditPencegahanKriminalitas() {
|
||||
}
|
||||
|
||||
try {
|
||||
// Update the form data first
|
||||
// update global state saat submit
|
||||
kriminalitasState.update.form = {
|
||||
...kriminalitasState.update.form,
|
||||
judul: formData.judul,
|
||||
deskripsi: formData.deskripsi,
|
||||
deskripsiSingkat: formData.deskripsiSingkat,
|
||||
linkVideo: formData.linkVideo,
|
||||
};
|
||||
|
||||
// Set the ID and then call update
|
||||
kriminalitasState.update.id = params?.id as string;
|
||||
|
||||
await kriminalitasState.update.update();
|
||||
@@ -119,18 +123,16 @@ function EditPencegahanKriminalitas() {
|
||||
<TextInput
|
||||
label="Judul"
|
||||
placeholder="Masukkan judul"
|
||||
defaultValue={formData.judul}
|
||||
onChange={(e) => setFormData({ ...formData, judul: e.target.value })}
|
||||
value={formData.judul}
|
||||
onChange={handleChange('judul')}
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Deskripsi Singkat"
|
||||
placeholder="Masukkan deskripsi singkat"
|
||||
defaultValue={formData.deskripsiSingkat}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, deskripsiSingkat: e.target.value })
|
||||
}
|
||||
value={formData.deskripsiSingkat}
|
||||
onChange={handleChange('deskripsiSingkat')}
|
||||
required
|
||||
/>
|
||||
|
||||
@@ -141,7 +143,7 @@ function EditPencegahanKriminalitas() {
|
||||
<EditEditor
|
||||
value={formData.deskripsi}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, deskripsi: val })
|
||||
setFormData((prev) => ({ ...prev, deskripsi: val }))
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
@@ -150,10 +152,8 @@ function EditPencegahanKriminalitas() {
|
||||
<TextInput
|
||||
label="Link Video YouTube"
|
||||
placeholder="https://www.youtube.com/watch?v=abc123"
|
||||
defaultValue={formData.linkVideo}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, linkVideo: e.currentTarget.value })
|
||||
}
|
||||
value={formData.linkVideo}
|
||||
onChange={handleChange('linkVideo')}
|
||||
required
|
||||
/>
|
||||
{embedLink && (
|
||||
|
||||
@@ -52,50 +52,36 @@ function EditPolsekTerdekat() {
|
||||
layananPolsekId: "",
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const loadPolsekTerdekat = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
|
||||
try {
|
||||
const data = await polsekState.edit.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
nama: data.nama || "",
|
||||
jarakKeDesa: data.jarakKeDesa || "",
|
||||
alamat: data.alamat || "",
|
||||
nomorTelepon: data.nomorTelepon || "",
|
||||
jamOperasional: data.jamOperasional || "",
|
||||
embedMapUrl: data.embedMapUrl || "",
|
||||
namaTempatMaps: data.namaTempatMaps || "",
|
||||
alamatMaps: data.alamatMaps || "",
|
||||
linkPetunjukArah: data.linkPetunjukArah || "",
|
||||
layananPolsekId: data.layananPolsekId || "",
|
||||
});
|
||||
// load data untuk form edit
|
||||
useEffect(() => {
|
||||
const loadPolsekTerdekat = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
|
||||
try {
|
||||
const data = await polsekState.edit.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
nama: data.nama || "",
|
||||
jarakKeDesa: data.jarakKeDesa || "",
|
||||
alamat: data.alamat || "",
|
||||
nomorTelepon: data.nomorTelepon || "",
|
||||
jamOperasional: data.jamOperasional || "",
|
||||
embedMapUrl: data.embedMapUrl || "",
|
||||
namaTempatMaps: data.namaTempatMaps || "",
|
||||
alamatMaps: data.alamatMaps || "",
|
||||
linkPetunjukArah: data.linkPetunjukArah || "",
|
||||
layananPolsekId: data.layananPolsekId || "",
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading polsek terdekat:", error);
|
||||
toast.error("Gagal memuat data polsek terdekat");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading polsek terdekat:", error);
|
||||
toast.error("Gagal memuat data polsek terdekat");
|
||||
}
|
||||
};
|
||||
|
||||
loadPolsekTerdekat();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
polsekState.edit.form = {
|
||||
...polsekState.edit.form,
|
||||
...formData,
|
||||
};
|
||||
await polsekState.edit.update();
|
||||
toast.success("Polsek terdekat berhasil diperbarui!");
|
||||
router.push("/admin/keamanan/polsek-terdekat");
|
||||
} catch (error) {
|
||||
console.error("Error updating polsek terdekat:", error);
|
||||
toast.error("Gagal memperbarui data polsek terdekat");
|
||||
}
|
||||
};
|
||||
|
||||
loadPolsekTerdekat();
|
||||
}, [params?.id]);
|
||||
|
||||
const fetchLayanan = async () => {
|
||||
try {
|
||||
@@ -198,6 +184,22 @@ function EditPolsekTerdekat() {
|
||||
fetchLayanan();
|
||||
}, []);
|
||||
|
||||
const handleChange = (field: string, value: string) => {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
polsekState.edit.form = { ...formData }; // update global state hanya di sini
|
||||
await polsekState.edit.update();
|
||||
toast.success("Polsek terdekat berhasil diperbarui!");
|
||||
router.push("/admin/keamanan/polsek-terdekat");
|
||||
} catch (error) {
|
||||
console.error("Error updating polsek terdekat:", error);
|
||||
toast.error("Gagal memperbarui data polsek terdekat");
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box px={{ base: "sm", md: "lg" }} py="md">
|
||||
{/* Modal Tambah */}
|
||||
@@ -273,88 +275,59 @@ function EditPolsekTerdekat() {
|
||||
<Stack gap="md">
|
||||
{/* Input fields */}
|
||||
<TextInput
|
||||
defaultValue={formData.nama}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, nama: val.target.value })
|
||||
}
|
||||
value={formData.nama}
|
||||
onChange={(e) => handleChange("nama", e.currentTarget.value)}
|
||||
label="Nama Polsek Terdekat"
|
||||
placeholder="Masukkan nama Polsek Terdekat"
|
||||
required
|
||||
/>
|
||||
<TextInput
|
||||
defaultValue={formData.jarakKeDesa}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, jarakKeDesa: val.target.value })
|
||||
}
|
||||
value={formData.jarakKeDesa}
|
||||
onChange={(e) => handleChange("jarakKeDesa", e.currentTarget.value)}
|
||||
label="Jarak Polsek Terdekat"
|
||||
placeholder="Masukkan jarak Polsek Terdekat"
|
||||
/>
|
||||
<TextInput
|
||||
defaultValue={formData.alamat}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, alamat: val.target.value })
|
||||
}
|
||||
value={formData.alamat}
|
||||
onChange={(e) => handleChange("alamat", e.currentTarget.value)}
|
||||
label="Alamat Polsek Terdekat"
|
||||
placeholder="Masukkan alamat Polsek Terdekat"
|
||||
/>
|
||||
<TextInput
|
||||
defaultValue={formData.nomorTelepon}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, nomorTelepon: val.target.value })
|
||||
}
|
||||
value={formData.nomorTelepon}
|
||||
onChange={(e) => handleChange("nomorTelepon", e.currentTarget.value)}
|
||||
label="Nomor Telepon"
|
||||
placeholder="Masukkan nomor telepon Polsek Terdekat"
|
||||
/>
|
||||
<TextInput
|
||||
defaultValue={formData.jamOperasional}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, jamOperasional: val.target.value })
|
||||
}
|
||||
value={formData.jamOperasional}
|
||||
onChange={(e) => handleChange("jamOperasional", e.currentTarget.value)}
|
||||
label="Jam Operasional"
|
||||
placeholder="Masukkan jam operasional Polsek Terdekat"
|
||||
/>
|
||||
<TextInput
|
||||
defaultValue={formData.embedMapUrl}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, embedMapUrl: val.target.value })
|
||||
}
|
||||
value={formData.embedMapUrl}
|
||||
onChange={(e) => handleChange("embedMapUrl", e.currentTarget.value)}
|
||||
label="Embed Map URL"
|
||||
placeholder="Masukkan embed map url"
|
||||
/>
|
||||
<TextInput
|
||||
defaultValue={formData.namaTempatMaps}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, namaTempatMaps: val.target.value })
|
||||
}
|
||||
value={formData.namaTempatMaps}
|
||||
onChange={(e) => handleChange("namaTempatMaps", e.currentTarget.value)}
|
||||
label="Nama Tempat Maps"
|
||||
placeholder="Masukkan nama tempat di maps"
|
||||
/>
|
||||
<TextInput
|
||||
defaultValue={formData.alamatMaps}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, alamatMaps: val.target.value })
|
||||
}
|
||||
value={formData.alamatMaps}
|
||||
onChange={(e) => handleChange("alamatMaps", e.currentTarget.value)}
|
||||
label="Alamat Maps"
|
||||
placeholder="Masukkan alamat di maps"
|
||||
/>
|
||||
<TextInput
|
||||
defaultValue={formData.linkPetunjukArah}
|
||||
onChange={(val) =>
|
||||
setFormData({ ...formData, linkPetunjukArah: val.target.value })
|
||||
}
|
||||
value={formData.linkPetunjukArah}
|
||||
onChange={(e) => handleChange("linkPetunjukArah", e.currentTarget.value)}
|
||||
label="Link Petunjuk Arah"
|
||||
placeholder="Masukkan link petunjuk arah"
|
||||
/>
|
||||
|
||||
{/* Dropdown Layanan */}
|
||||
<Select
|
||||
label="Layanan Polsek"
|
||||
placeholder="Pilih layanan polsek"
|
||||
data={layananOptions}
|
||||
value={polsekState.create.form.layananPolsekId}
|
||||
onChange={(val) => {
|
||||
polsekState.create.form.layananPolsekId = val || "";
|
||||
}}
|
||||
value={formData.layananPolsekId}
|
||||
onChange={(val) => handleChange("layananPolsekId", val || "")}
|
||||
/>
|
||||
<Button
|
||||
variant="light"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
"use client";
|
||||
|
||||
import {
|
||||
@@ -39,9 +38,9 @@ function EditTipsKeamanan() {
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [formData, setFormData] = useState({
|
||||
judul: keamananState.update.form.judul || "",
|
||||
deskripsi: keamananState.update.form.deskripsi || "",
|
||||
imageId: keamananState.update.form.imageId || "",
|
||||
judul: "",
|
||||
deskripsi: "",
|
||||
imageId: "",
|
||||
});
|
||||
|
||||
// Load data saat pertama kali
|
||||
@@ -70,14 +69,12 @@ function EditTipsKeamanan() {
|
||||
};
|
||||
|
||||
loadData();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [params?.id]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
keamananState.update.form = {
|
||||
...keamananState.update.form,
|
||||
...formData,
|
||||
};
|
||||
let imageId = formData.imageId;
|
||||
|
||||
if (file) {
|
||||
const res = await ApiFetch.api.fileStorage.create.post({
|
||||
@@ -87,10 +84,14 @@ function EditTipsKeamanan() {
|
||||
const uploaded = res.data?.data;
|
||||
|
||||
if (!uploaded?.id) return toast.error("Gagal upload gambar");
|
||||
|
||||
keamananState.update.form.imageId = uploaded.id;
|
||||
imageId = uploaded.id;
|
||||
}
|
||||
|
||||
keamananState.update.form = {
|
||||
...formData,
|
||||
imageId,
|
||||
};
|
||||
|
||||
await keamananState.update.update();
|
||||
toast.success("Tips Keamanan berhasil diperbarui!");
|
||||
router.push("/admin/keamanan/tips-keamanan");
|
||||
@@ -105,7 +106,12 @@ function EditTipsKeamanan() {
|
||||
{/* Header */}
|
||||
<Group mb="md">
|
||||
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
|
||||
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
|
||||
<Button
|
||||
variant="subtle"
|
||||
onClick={() => router.back()}
|
||||
p="xs"
|
||||
radius="md"
|
||||
>
|
||||
<IconArrowBack color={colors["blue-button"]} size={24} />
|
||||
</Button>
|
||||
</Tooltip>
|
||||
@@ -137,7 +143,9 @@ function EditTipsKeamanan() {
|
||||
setPreviewImage(URL.createObjectURL(selectedFile));
|
||||
}
|
||||
}}
|
||||
onReject={() => toast.error("File tidak valid, gunakan format gambar")}
|
||||
onReject={() =>
|
||||
toast.error("File tidak valid, gunakan format gambar")
|
||||
}
|
||||
maxSize={5 * 1024 ** 2}
|
||||
accept={{ "image/*": [] }}
|
||||
radius="md"
|
||||
@@ -145,7 +153,11 @@ function EditTipsKeamanan() {
|
||||
>
|
||||
<Group justify="center" gap="xl" mih={180}>
|
||||
<Dropzone.Accept>
|
||||
<IconUpload size={48} color={colors["blue-button"]} stroke={1.5} />
|
||||
<IconUpload
|
||||
size={48}
|
||||
color={colors["blue-button"]}
|
||||
stroke={1.5}
|
||||
/>
|
||||
</Dropzone.Accept>
|
||||
<Dropzone.Reject>
|
||||
<IconX size={48} color="red" stroke={1.5} />
|
||||
@@ -199,8 +211,10 @@ function EditTipsKeamanan() {
|
||||
<TextInput
|
||||
label="Nama Tips Keamanan"
|
||||
placeholder="Masukkan nama tips keamanan"
|
||||
defaultValue={formData.judul}
|
||||
onChange={(e) => setFormData({ ...formData, judul: e.target.value })}
|
||||
value={formData.judul}
|
||||
onChange={(e) =>
|
||||
setFormData((prev) => ({ ...prev, judul: e.target.value }))
|
||||
}
|
||||
required
|
||||
/>
|
||||
|
||||
@@ -211,10 +225,9 @@ function EditTipsKeamanan() {
|
||||
</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsi}
|
||||
onChange={(htmlContent) => {
|
||||
setFormData((prev) => ({ ...prev, deskripsi: htmlContent }));
|
||||
keamananState.update.form.deskripsi = htmlContent;
|
||||
}}
|
||||
onChange={(htmlContent) =>
|
||||
setFormData((prev) => ({ ...prev, deskripsi: htmlContent }))
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user