QC User & Admin Responsive : Menu Kesehatan - Ekonomi
This commit is contained in:
@@ -581,33 +581,24 @@ const pelayananPerizinanBerusaha = proxy({
|
||||
findById: {
|
||||
data: null as pelayananPerizinanBerusahaForm | null,
|
||||
loading: false,
|
||||
initialize() {
|
||||
pelayananPerizinanBerusaha.findById.data = {
|
||||
id: "",
|
||||
name: "",
|
||||
deskripsi: "",
|
||||
link: "",
|
||||
} as pelayananPerizinanBerusahaForm;
|
||||
},
|
||||
async load(id: string) {
|
||||
try {
|
||||
pelayananPerizinanBerusaha.findById.loading = true;
|
||||
const res = await fetch(
|
||||
`/api/desa/layanan/pelayananperizinanberusaha/${id}`
|
||||
);
|
||||
if (res.ok) {
|
||||
const data = await res.json();
|
||||
pelayananPerizinanBerusaha.findById.data = data.data ?? null;
|
||||
} else {
|
||||
console.error(
|
||||
"Failed to fetch pelayanan perizinan berusaha:",
|
||||
res.statusText
|
||||
);
|
||||
pelayananPerizinanBerusaha.findById.data = null;
|
||||
this.loading = true;
|
||||
const response = await fetch(`/api/desa/layanan/pelayananperizinanberusaha/${id}`);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
const result = await response.json();
|
||||
if (result?.success) {
|
||||
this.data = result.data; // Make sure this matches your API response structure
|
||||
}
|
||||
return result?.data || null;
|
||||
} catch (error) {
|
||||
console.error("Error fetching pelayanan perizinan berusaha:", error);
|
||||
pelayananPerizinanBerusaha.findById.data = null;
|
||||
console.error('Error loading data:', error);
|
||||
toast.error('Gagal memuat data');
|
||||
return null;
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
@@ -12,6 +12,7 @@ const templatePasarDesaForm = z.object({
|
||||
imageId: z.string().min(1, "Gambar wajib dipilih"),
|
||||
rating: z.number().min(1, "Rating minimal 1"),
|
||||
kategoriId: z.array(z.string()).min(1, "Minimal pilih satu kategori"),
|
||||
kontak: z.string().min(1, "Kontak wajib diisi"),
|
||||
});
|
||||
|
||||
const defaultPasarDesaForm = {
|
||||
@@ -21,6 +22,7 @@ const defaultPasarDesaForm = {
|
||||
imageId: "",
|
||||
rating: 0,
|
||||
kategoriId: [] as string[],
|
||||
kontak: "",
|
||||
};
|
||||
|
||||
const pasarDesa = proxy({
|
||||
@@ -188,6 +190,7 @@ const pasarDesa = proxy({
|
||||
imageId: data.imageId,
|
||||
rating: data.rating,
|
||||
kategoriId: data.kategoriId,
|
||||
kontak: data.kontak,
|
||||
};
|
||||
return data;
|
||||
} else {
|
||||
@@ -225,6 +228,7 @@ const pasarDesa = proxy({
|
||||
imageId: this.form.imageId,
|
||||
rating: this.form.rating,
|
||||
kategoriId: this.form.kategoriId,
|
||||
kontak: this.form.kontak,
|
||||
}),
|
||||
});
|
||||
if (!response.ok) {
|
||||
@@ -336,6 +340,40 @@ const kategoriProduk = proxy({
|
||||
}
|
||||
},
|
||||
},
|
||||
// ✅ Versi findManyAll (ambil semua tanpa pagination)
|
||||
findManyAll: {
|
||||
data: null as
|
||||
| Prisma.KategoriProdukGetPayload<{
|
||||
omit: { isActive: true };
|
||||
}>[]
|
||||
| null,
|
||||
loading: false,
|
||||
search: "",
|
||||
load: async (search = "") => {
|
||||
kategoriProduk.findManyAll.loading = true;
|
||||
kategoriProduk.findManyAll.search = search;
|
||||
|
||||
try {
|
||||
const query: any = {};
|
||||
if (search) query.search = search;
|
||||
|
||||
const res = await ApiFetch.api.ekonomi.kategoriproduk["find-many-all"].get({
|
||||
query,
|
||||
});
|
||||
|
||||
if (res.status === 200 && res.data?.success) {
|
||||
kategoriProduk.findManyAll.data = res.data.data ?? [];
|
||||
} else {
|
||||
kategoriProduk.findManyAll.data = [];
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Gagal fetch kategori produk (all):", err);
|
||||
kategoriProduk.findManyAll.data = [];
|
||||
} finally {
|
||||
kategoriProduk.findManyAll.loading = false;
|
||||
}
|
||||
},
|
||||
},
|
||||
findUnique: {
|
||||
data: null as Prisma.KategoriProdukGetPayload<{
|
||||
omit: { isActive: true };
|
||||
|
||||
@@ -9,12 +9,14 @@ 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(),
|
||||
whatsapp: z.string().min(10, "Whatsapp minimal 10 karakter"),
|
||||
});
|
||||
|
||||
const defaultForm = {
|
||||
name: "",
|
||||
deskripsi: "",
|
||||
imageId: "",
|
||||
whatsapp: "",
|
||||
};
|
||||
|
||||
const kontakDarurat = proxy({
|
||||
@@ -171,6 +173,7 @@ const kontakDarurat = proxy({
|
||||
name: data.name,
|
||||
deskripsi: data.deskripsi,
|
||||
imageId: data.imageId,
|
||||
whatsapp: data.whatsapp,
|
||||
};
|
||||
return data; // Return the loaded data
|
||||
} else {
|
||||
@@ -207,6 +210,7 @@ const kontakDarurat = proxy({
|
||||
name: this.form.name,
|
||||
deskripsi: this.form.deskripsi,
|
||||
imageId: this.form.imageId,
|
||||
whatsapp: this.form.whatsapp,
|
||||
}),
|
||||
}
|
||||
);
|
||||
|
||||
@@ -59,7 +59,7 @@ function PelayananPendudukNonPermanent() {
|
||||
radius="md"
|
||||
onClick={() =>
|
||||
router.push(
|
||||
'/admin/desa/layanan/pelayanan_penduduk_non_permanent/edit'
|
||||
`/admin/desa/layanan/pelayanan_penduduk_non_permanent/${data.id}`
|
||||
)
|
||||
}
|
||||
>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
import stateLayananDesa from '@/app/admin/(dashboard)/_state/desa/layananDesa';
|
||||
import colors from '@/con/colors';
|
||||
@@ -8,6 +9,7 @@ import {
|
||||
Button,
|
||||
Group,
|
||||
Paper,
|
||||
Skeleton,
|
||||
Stack,
|
||||
TextInput,
|
||||
Title,
|
||||
@@ -21,66 +23,82 @@ import { useProxy } from 'valtio/utils';
|
||||
|
||||
function EditPelayananPerizinanBerusaha() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const statePerizinanBerusaha = useProxy(
|
||||
stateLayananDesa.pelayananPerizinanBerusaha
|
||||
);
|
||||
const params = useParams<{ id: string }>();
|
||||
const id = params?.id; // ini langsung string
|
||||
const state = useProxy(stateLayananDesa.pelayananPerizinanBerusaha);
|
||||
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [formData, setFormData] = useState({
|
||||
id: '',
|
||||
name: '',
|
||||
deskripsi: '',
|
||||
link: '',
|
||||
});
|
||||
|
||||
// load data pertama kali
|
||||
// Load data detail
|
||||
useEffect(() => {
|
||||
const loadPelayananPerizinan = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
if (!id) {
|
||||
toast.error("ID tidak valid");
|
||||
return;
|
||||
}
|
||||
|
||||
const loadData = async () => {
|
||||
try {
|
||||
const data = await statePerizinanBerusaha.update.load(id);
|
||||
setLoading(true);
|
||||
const data = await state.findById.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
name: data.name || '',
|
||||
deskripsi: data.deskripsi || '',
|
||||
link: data.link || '',
|
||||
id: data.id,
|
||||
name: data.name || "",
|
||||
deskripsi: data.deskripsi || "",
|
||||
link: data.link || "",
|
||||
});
|
||||
} else {
|
||||
toast.error("Data tidak ditemukan");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading pelayanan perizinan berusaha:', error);
|
||||
toast.error('Gagal memuat data pelayanan perizinan berusaha');
|
||||
console.error("Error loading data:", error);
|
||||
toast.error("Gagal memuat data");
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
loadPelayananPerizinan();
|
||||
}, [params?.id]);
|
||||
|
||||
loadData();
|
||||
}, [id]);
|
||||
|
||||
|
||||
const handleChange =
|
||||
(field: keyof typeof formData) =>
|
||||
(value: string) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
};
|
||||
(value: string) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const { name, deskripsi, link } = formData;
|
||||
if (statePerizinanBerusaha.findById.data) {
|
||||
const updatedData = {
|
||||
...statePerizinanBerusaha.findById.data,
|
||||
name,
|
||||
deskripsi,
|
||||
link,
|
||||
};
|
||||
await statePerizinanBerusaha.update.update(updatedData);
|
||||
try {
|
||||
await state.update.update(formData);
|
||||
router.push('/admin/desa/layanan/pelayanan_perizinan_berusaha');
|
||||
} catch (error) {
|
||||
console.error('Error updating pelayanan perizinan berusaha:', error);
|
||||
toast.error('Terjadi kesalahan saat update data');
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Stack align="center" justify="center" py="xl">
|
||||
<Skeleton height={800} radius="md" />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Stack gap="xs">
|
||||
{/* Header Section */}
|
||||
{/* Header */}
|
||||
<Group mb="md">
|
||||
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
|
||||
<Button
|
||||
@@ -97,7 +115,7 @@ function EditPelayananPerizinanBerusaha() {
|
||||
</Title>
|
||||
</Group>
|
||||
|
||||
{/* Form Section */}
|
||||
{/* Form */}
|
||||
<Paper
|
||||
w={{ base: '100%', md: '50%' }}
|
||||
bg={colors['white-1']}
|
||||
@@ -109,7 +127,6 @@ function EditPelayananPerizinanBerusaha() {
|
||||
<Stack gap="xs">
|
||||
<Title order={3}>Edit Pelayanan Perizinan Berusaha</Title>
|
||||
|
||||
{/* Nama Field */}
|
||||
<TextInput
|
||||
label="Judul"
|
||||
placeholder="Masukkan judul"
|
||||
@@ -118,7 +135,6 @@ function EditPelayananPerizinanBerusaha() {
|
||||
required
|
||||
/>
|
||||
|
||||
{/* Link Field */}
|
||||
<TextInput
|
||||
label="Link"
|
||||
placeholder="Masukkan link terkait"
|
||||
@@ -126,7 +142,6 @@ function EditPelayananPerizinanBerusaha() {
|
||||
onChange={(e) => handleChange('link')(e.target.value)}
|
||||
/>
|
||||
|
||||
{/* Deskripsi Field */}
|
||||
<Box>
|
||||
<Title order={6}>Deskripsi</Title>
|
||||
<EditEditor
|
||||
@@ -135,23 +150,20 @@ function EditPelayananPerizinanBerusaha() {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* Action Buttons */}
|
||||
<Group>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
loading={statePerizinanBerusaha.update.loading}
|
||||
loading={state.update.loading}
|
||||
disabled={!formData.name}
|
||||
>
|
||||
{statePerizinanBerusaha.update.loading
|
||||
? 'Menyimpan...'
|
||||
: 'Simpan Perubahan'}
|
||||
{state.update.loading ? 'Menyimpan...' : 'Simpan Perubahan'}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="outline"
|
||||
onClick={() => router.back()}
|
||||
disabled={statePerizinanBerusaha.update.loading}
|
||||
disabled={state.update.loading}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
@@ -1,3 +1,4 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import {
|
||||
@@ -19,35 +20,58 @@ import {
|
||||
Tooltip,
|
||||
} from '@mantine/core';
|
||||
import { IconEdit } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import stateLayananDesa from '../../../_state/desa/layananDesa';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
function PerizinanBerusaha() {
|
||||
const router = useRouter();
|
||||
const pelayananPerizinanBerusaha = useProxy(
|
||||
stateLayananDesa.pelayananPerizinanBerusaha
|
||||
);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
const [active, setActive] = useState(1);
|
||||
const nextStep = () =>
|
||||
setActive((current) => (current < 6 ? current + 1 : current));
|
||||
const prevStep = () =>
|
||||
setActive((current) => (current > 0 ? current - 1 : current));
|
||||
|
||||
useShallowEffect(() => {
|
||||
pelayananPerizinanBerusaha.findById.load('1');
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
// You should get the ID from your router query or params
|
||||
const id = '1'; // Replace with actual ID or get from URL params
|
||||
await pelayananPerizinanBerusaha.findById.load(id);
|
||||
} catch (err) {
|
||||
setError('Gagal memuat data');
|
||||
console.error('Error:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
if (!pelayananPerizinanBerusaha.findById.data) {
|
||||
if (loading) {
|
||||
return (
|
||||
<Stack align="center" justify="center" py="xl">
|
||||
<Skeleton radius="md" height={800} />
|
||||
<Skeleton height={800} radius="md" />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
if (error || !pelayananPerizinanBerusaha.findById.data) {
|
||||
return (
|
||||
<Center h={200}>
|
||||
<Text>{error || 'Data tidak ditemukan'}</Text>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
const data = pelayananPerizinanBerusaha.findById.data;
|
||||
|
||||
return (
|
||||
@@ -69,7 +93,7 @@ function PerizinanBerusaha() {
|
||||
radius="md"
|
||||
onClick={() =>
|
||||
router.push(
|
||||
'/admin/desa/layanan/pelayanan_perizinan_berusaha/edit'
|
||||
`/admin/desa/layanan/pelayanan_perizinan_berusaha/${data.id}`
|
||||
)
|
||||
}
|
||||
>
|
||||
@@ -183,3 +207,4 @@ function PerizinanBerusaha() {
|
||||
}
|
||||
|
||||
export default PerizinanBerusaha;
|
||||
|
||||
|
||||
@@ -44,39 +44,37 @@ function EditSuratKeterangan() {
|
||||
const [previewImage2, setPreviewImage2] = useState<string | null>(null);
|
||||
|
||||
// load data awal
|
||||
useEffect(() => {
|
||||
const loadSurat = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
useEffect(() => {
|
||||
const loadSurat = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
|
||||
try {
|
||||
const data = await stateSurat.edit.load(id);
|
||||
if (!data) return;
|
||||
|
||||
try {
|
||||
const data = await stateSurat.edit.load(id);
|
||||
if (data) {
|
||||
// merge style -> isi hanya field kosong
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
name: prev.name || data.name || '',
|
||||
deskripsi: prev.deskripsi || data.deskripsi || '',
|
||||
imageId: prev.imageId || data.imageId || '',
|
||||
image2Id: prev.image2Id || data.image2Id || '',
|
||||
...{
|
||||
name: prev.name || data.name || "",
|
||||
deskripsi: prev.deskripsi || data.deskripsi || "",
|
||||
imageId: prev.imageId || data.imageId || "",
|
||||
image2Id: prev.image2Id || data.image2Id || "",
|
||||
},
|
||||
}));
|
||||
|
||||
if (data.image?.link && !previewImage) {
|
||||
setPreviewImage(data.image.link);
|
||||
}
|
||||
if (data.image2?.link && !previewImage2) {
|
||||
setPreviewImage2(data.image2.link);
|
||||
}
|
||||
if (data.image?.link && !previewImage) setPreviewImage(data.image.link);
|
||||
if (data.image2?.link && !previewImage2) setPreviewImage2(data.image2.link);
|
||||
} catch (error) {
|
||||
console.error("Error loading surat:", error);
|
||||
toast.error("Gagal memuat data surat");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading surat:", error);
|
||||
toast.error("Gagal memuat data surat");
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
loadSurat();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [params?.id]);
|
||||
|
||||
loadSurat();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [params?.id]);
|
||||
|
||||
|
||||
// handler untuk submit
|
||||
|
||||
@@ -8,17 +8,15 @@ import {
|
||||
Group,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
Tooltip,
|
||||
Tooltip
|
||||
} from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useEffect, useState, useCallback } from 'react';
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import EditEditor from '@/app/admin/(dashboard)/_com/editEditor';
|
||||
|
||||
function EditPelayananTelunjukSakti() {
|
||||
const stateTelunjukDesa = useProxy(stateLayananDesa.pelayananTelunjukSaktiDesa);
|
||||
@@ -111,21 +109,19 @@ function EditPelayananTelunjukSakti() {
|
||||
required
|
||||
/>
|
||||
|
||||
{/* Deskripsi pakai editor */}
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold" mb={6}>
|
||||
Deskripsi
|
||||
</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsi}
|
||||
onChange={(htmlContent) => handleChange('deskripsi', htmlContent)}
|
||||
/>
|
||||
</Box>
|
||||
{/* Deskripsi */}
|
||||
<TextInput
|
||||
value={formData.deskripsi}
|
||||
onChange={(e) => handleChange('deskripsi', e.target.value)}
|
||||
label="Judul Link"
|
||||
placeholder="Masukkan judul link"
|
||||
required
|
||||
/>
|
||||
|
||||
{/* Link */}
|
||||
<TextInput
|
||||
label="Link"
|
||||
placeholder="Masukkan link terkait"
|
||||
placeholder="Masukkan alamat link"
|
||||
value={formData.link}
|
||||
onChange={(e) => handleChange('link', e.target.value)}
|
||||
/>
|
||||
|
||||
@@ -82,8 +82,8 @@ function CreatePelayananTelunjukDesa() {
|
||||
onChange={(val) => {
|
||||
stateTelunjukDesa.create.form.deskripsi = val.target.value;
|
||||
}}
|
||||
label="Deskripsi"
|
||||
placeholder="Masukkan deskripsi pelayanan"
|
||||
label="Judul Link"
|
||||
placeholder="Masukkan judul link"
|
||||
required
|
||||
/>
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ type FormData = {
|
||||
imageId: string;
|
||||
rating: number;
|
||||
kategoriId: string[];
|
||||
kontak: string;
|
||||
};
|
||||
|
||||
function EditPasarDesa() {
|
||||
@@ -47,6 +48,7 @@ function EditPasarDesa() {
|
||||
imageId: '',
|
||||
rating: 0,
|
||||
kategoriId: [],
|
||||
kontak: '',
|
||||
});
|
||||
|
||||
// load data awal
|
||||
@@ -67,6 +69,7 @@ function EditPasarDesa() {
|
||||
imageId: data.imageId || '',
|
||||
rating: data.rating || 0,
|
||||
kategoriId: data.KategoriToPasar?.map((k: any) => k.kategoriId) || [],
|
||||
kontak: data.kontak || '',
|
||||
});
|
||||
if (data.image?.link) setPreviewImage(data.image.link);
|
||||
}
|
||||
@@ -228,6 +231,14 @@ function EditPasarDesa() {
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Kontak"
|
||||
placeholder="Masukkan kontak"
|
||||
value={formData.kontak}
|
||||
onChange={(e) => handleChange('kontak', e.target.value)}
|
||||
required
|
||||
/>
|
||||
|
||||
<MultiSelect
|
||||
label="Kategori Produk"
|
||||
placeholder="Pilih kategori produk"
|
||||
|
||||
@@ -85,6 +85,11 @@ function DetailPasarDesa() {
|
||||
<Text fz="md" c="dimmed">{data.alamatUsaha || '-'}</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="lg" fw="bold">Kontak</Text>
|
||||
<Text fz="md" c="dimmed">{data.kontak || '-'}</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="lg" fw="bold">Gambar</Text>
|
||||
{data.image?.link ? (
|
||||
|
||||
@@ -41,6 +41,7 @@ export default function CreatePasarDesa() {
|
||||
imageId: '',
|
||||
rating: 0,
|
||||
kategoriId: [],
|
||||
kontak: '',
|
||||
};
|
||||
setPreviewImage(null);
|
||||
setFile(null);
|
||||
@@ -184,6 +185,15 @@ export default function CreatePasarDesa() {
|
||||
onChange={(e) => (statePasar.pasarDesa.create.form.alamatUsaha = e.target.value)}
|
||||
/>
|
||||
|
||||
{/* Kontak */}
|
||||
<TextInput
|
||||
label="Kontak"
|
||||
type="number"
|
||||
placeholder="Masukkan kontak"
|
||||
defaultValue={statePasar.pasarDesa.create.form.kontak}
|
||||
onChange={(e) => (statePasar.pasarDesa.create.form.kontak = e.target.value)}
|
||||
/>
|
||||
|
||||
{/* Kategori Produk */}
|
||||
<MultiSelect
|
||||
label="Kategori Produk"
|
||||
|
||||
@@ -29,10 +29,11 @@ function EditKontakDaruratKeamanan() {
|
||||
const kontakState = useProxy(kontakDarurat.kontakDaruratKeamananState);
|
||||
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
// Remove the dependency on data in the initial state
|
||||
const [formData, setFormData] = useState({
|
||||
name: "",
|
||||
icon: "" as IconKey | "",
|
||||
kategoriId: [] as string[],
|
||||
kategoriId: [] as string[], // Initialize as empty array
|
||||
});
|
||||
|
||||
// Load data dari backend
|
||||
@@ -41,7 +42,7 @@ function EditKontakDaruratKeamanan() {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await kontakDarurat.kontakDaruratItem.findMany.load();
|
||||
|
||||
|
||||
const id = params?.id as string;
|
||||
if (id) {
|
||||
const data = await kontakState.update.load(id);
|
||||
@@ -49,7 +50,7 @@ function EditKontakDaruratKeamanan() {
|
||||
setFormData({
|
||||
name: data.nama || "",
|
||||
icon: (data.icon as IconKey) || "",
|
||||
kategoriId: data.kategoriId || [],
|
||||
kategoriId: Array.isArray(data.kategoriId) ? data.kategoriId : [],
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -134,9 +135,9 @@ function EditKontakDaruratKeamanan() {
|
||||
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
|
||||
|
||||
@@ -48,27 +48,29 @@ function EditLaporanPublik() {
|
||||
const loadLaporanPublik = async () => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
|
||||
|
||||
try {
|
||||
const data = await stateLaporan.edit.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
judul: data.judul || '',
|
||||
lokasi: data.lokasi || '',
|
||||
tanggalWaktu: data.tanggalWaktu || '',
|
||||
status: data.status || '',
|
||||
penanganan: data.penanganan?.[0]?.deskripsi || '',
|
||||
kronologi: data.kronologi || '',
|
||||
});
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
judul: data.judul ?? prev.judul,
|
||||
lokasi: data.lokasi ?? prev.lokasi,
|
||||
tanggalWaktu: data.tanggalWaktu ?? prev.tanggalWaktu,
|
||||
status: (data.status as Status) ?? prev.status,
|
||||
penanganan: data.penanganan?.[0]?.deskripsi ?? prev.penanganan,
|
||||
kronologi: data.kronologi ?? prev.kronologi,
|
||||
}));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading laporan publik:', error);
|
||||
console.error("Error loading laporan publik:", error);
|
||||
toast.error("Gagal mengambil data laporan publik");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
loadLaporanPublik();
|
||||
}, [params?.id, stateLaporan.edit]);
|
||||
|
||||
|
||||
const handleChange = (field: string, value: string | Status) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: value }));
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
Group,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
Tooltip,
|
||||
@@ -61,9 +62,9 @@ function EditPencegahanKriminalitas() {
|
||||
|
||||
const handleChange =
|
||||
(field: keyof typeof formData) =>
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: e.target.value }));
|
||||
};
|
||||
(e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setFormData((prev) => ({ ...prev, [field]: e.target.value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
const converted = convertYoutubeUrlToEmbed(formData.linkVideo);
|
||||
@@ -128,13 +129,17 @@ function EditPencegahanKriminalitas() {
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Deskripsi Singkat"
|
||||
placeholder="Masukkan deskripsi singkat"
|
||||
value={formData.deskripsiSingkat}
|
||||
onChange={handleChange('deskripsiSingkat')}
|
||||
required
|
||||
/>
|
||||
<Box>
|
||||
<Text fw="bold" fz="sm" mb={6}>
|
||||
Deskripsi
|
||||
</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsiSingkat}
|
||||
onChange={(val) =>
|
||||
setFormData((prev) => ({ ...prev, deskripsiSingkat: val }))
|
||||
}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Title order={6} fw="bold" fz="sm" mb={6}>
|
||||
|
||||
@@ -90,15 +90,17 @@ function CreatePencegahanKriminalitas() {
|
||||
/>
|
||||
|
||||
{/* Deskripsi Singkat */}
|
||||
<TextInput
|
||||
label="Deskripsi Singkat"
|
||||
placeholder="Masukkan deskripsi singkat"
|
||||
defaultValue={kriminalitasState.create.form.deskripsiSingkat}
|
||||
onChange={(e) => {
|
||||
kriminalitasState.create.form.deskripsiSingkat = e.currentTarget.value;
|
||||
}}
|
||||
required
|
||||
/>
|
||||
<Box>
|
||||
<Text fw="bold" fz="sm" mb={6}>
|
||||
Deskripsi Singkat
|
||||
</Text>
|
||||
<CreateEditor
|
||||
value={kriminalitasState.create.form.deskripsiSingkat}
|
||||
onChange={(val) => {
|
||||
kriminalitasState.create.form.deskripsiSingkat = val;
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* Deskripsi Panjang */}
|
||||
<Box>
|
||||
|
||||
@@ -105,9 +105,11 @@ function ListPencegahanKriminalitas({ search }: { search: string }) {
|
||||
data.map((item) => (
|
||||
<TableTr key={item.id}>
|
||||
<TableTd>
|
||||
<Text fw={500} truncate="end" lineClamp={1}>
|
||||
<Box w={200}>
|
||||
<Text fw={500} truncate="end" lineClamp={1}>
|
||||
{item.judul}
|
||||
</Text>
|
||||
</Box>
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Box w={200}>
|
||||
|
||||
@@ -127,7 +127,9 @@ function ListFasilitasKesehatan({ search }: { search: string }) {
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
<Box w={150}>
|
||||
{item.tarifdanlayanan?.layanan || '-'}
|
||||
<Text truncate="end" lineClamp={1}>
|
||||
{item.tarifdanlayanan?.layanan || '-'}
|
||||
</Text>
|
||||
</Box>
|
||||
</TableTd>
|
||||
<TableTd>
|
||||
|
||||
@@ -140,15 +140,15 @@ function EditInfoWabahPenyakit() {
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
value={formData.deskripsiSingkat}
|
||||
onChange={(e: ChangeEvent<HTMLInputElement>) =>
|
||||
updateField('deskripsiSingkat', e.target.value)
|
||||
}
|
||||
label="Deskripsi Singkat"
|
||||
placeholder="Masukkan deskripsi singkat"
|
||||
required
|
||||
/>
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">
|
||||
Deskripsi Singkat
|
||||
</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsiSingkat}
|
||||
onChange={(val) => updateField('deskripsiSingkat', val)}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">
|
||||
|
||||
@@ -84,7 +84,7 @@ function DetailInfoWabahPenyakit() {
|
||||
|
||||
<Box>
|
||||
<Text fz="lg" fw="bold">Deskripsi Singkat</Text>
|
||||
<Text fz="md" c="dimmed" style={{ wordBreak: "break-word", whiteSpace: "normal" }}>{data.deskripsiSingkat || '-'}</Text>
|
||||
<Text fz="md" c="dimmed" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: data.deskripsiSingkat }} />
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
|
||||
@@ -100,15 +100,15 @@ function CreateInfoWabahPenyakit() {
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
defaultValue={infoWabahPenyakitState.create.form.deskripsiSingkat}
|
||||
onChange={(val) => {
|
||||
infoWabahPenyakitState.create.form.deskripsiSingkat = val.target.value;
|
||||
}}
|
||||
label={<Text fz="sm" fw="bold">Deskripsi Singkat</Text>}
|
||||
placeholder="Masukkan deskripsi singkat"
|
||||
required
|
||||
/>
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Deskripsi Singkat</Text>
|
||||
<CreateEditor
|
||||
value={infoWabahPenyakitState.create.form.deskripsiSingkat}
|
||||
onChange={(val) => {
|
||||
infoWabahPenyakitState.create.form.deskripsiSingkat = val;
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Deskripsi</Text>
|
||||
|
||||
@@ -33,6 +33,7 @@ function EditKontakDarurat() {
|
||||
name: '',
|
||||
deskripsi: '',
|
||||
imageId: '',
|
||||
whatsapp: '',
|
||||
});
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@@ -49,6 +50,7 @@ function EditKontakDarurat() {
|
||||
name: data.name || '',
|
||||
deskripsi: data.deskripsi || '',
|
||||
imageId: data.imageId || '',
|
||||
whatsapp: data.whatsapp || '',
|
||||
});
|
||||
if (data?.image?.link) setPreviewImage(data.image.link);
|
||||
}
|
||||
@@ -124,6 +126,14 @@ function EditKontakDarurat() {
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
value={formData.whatsapp}
|
||||
onChange={(e) => setFormData(prev => ({ ...prev, whatsapp: e.target.value }))}
|
||||
label="Whatsapp"
|
||||
placeholder="Masukkan whatsapp"
|
||||
required
|
||||
/>
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Deskripsi</Text>
|
||||
<EditEditor
|
||||
|
||||
@@ -72,6 +72,11 @@ function DetailKontakDarurat() {
|
||||
<Text fz="md" c="dimmed">{data.name || '-'}</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="lg" fw="bold">Whatsapp</Text>
|
||||
<Text fz="md" c="dimmed">{data.whatsapp || '-'}</Text>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="lg" fw="bold">Deskripsi</Text>
|
||||
<Text
|
||||
|
||||
@@ -38,6 +38,7 @@ function CreateKontakDarurat() {
|
||||
name: '',
|
||||
deskripsi: '',
|
||||
imageId: '',
|
||||
whatsapp: '',
|
||||
};
|
||||
setPreviewImage(null);
|
||||
setFile(null);
|
||||
@@ -105,6 +106,17 @@ function CreateKontakDarurat() {
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
type='number'
|
||||
defaultValue={kontakDaruratState.create.form.whatsapp}
|
||||
onChange={(val) => {
|
||||
kontakDaruratState.create.form.whatsapp = val.target.value;
|
||||
}}
|
||||
label={<Text fz="sm" fw="bold">Whatsapp</Text>}
|
||||
placeholder="Masukkan whatsapp"
|
||||
required
|
||||
/>
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold">Deskripsi</Text>
|
||||
<CreateEditor
|
||||
|
||||
@@ -117,7 +117,6 @@ function EditProgramKesehatan() {
|
||||
<Stack gap="md">
|
||||
{[
|
||||
{ label: 'Judul', key: 'name', placeholder: 'Masukkan judul' },
|
||||
{ label: 'Deskripsi Singkat', key: 'deskripsiSingkat', placeholder: 'Masukkan deskripsi singkat' },
|
||||
].map((field) => (
|
||||
<TextInput
|
||||
key={field.key}
|
||||
@@ -129,6 +128,16 @@ function EditProgramKesehatan() {
|
||||
/>
|
||||
))}
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold" mb={6}>
|
||||
Deskripsi Singkat
|
||||
</Text>
|
||||
<EditEditor
|
||||
value={formData.deskripsiSingkat}
|
||||
onChange={(val) => handleChange('deskripsiSingkat', val)}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fz="sm" fw="bold" mb={6}>
|
||||
Deskripsi
|
||||
|
||||
@@ -73,7 +73,7 @@ function DetailProgramKesehatan() {
|
||||
|
||||
<Box>
|
||||
<Text fz="lg" fw="bold">Deskripsi Singkat</Text>
|
||||
<Text fz="md" c="dimmed" style={{ wordBreak: "break-word", whiteSpace: "normal" }}>{data?.deskripsiSingkat || '-'}</Text>
|
||||
<Text fz="md" c="dimmed" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: data?.deskripsiSingkat || '-' }} />
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
|
||||
@@ -101,15 +101,17 @@ function CreateProgramKesehatan() {
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
defaultValue={programKesehatanState.create.form.deskripsiSingkat}
|
||||
onChange={(val) => {
|
||||
programKesehatanState.create.form.deskripsiSingkat = val.target.value;
|
||||
}}
|
||||
label="Deskripsi Singkat"
|
||||
placeholder="Masukkan deskripsi singkat"
|
||||
required
|
||||
/>
|
||||
<Box>
|
||||
<Title order={6} mb={6}>
|
||||
Deskripsi Singkat
|
||||
</Title>
|
||||
<CreateEditor
|
||||
value={programKesehatanState.create.form.deskripsiSingkat}
|
||||
onChange={(val) => {
|
||||
programKesehatanState.create.form.deskripsiSingkat = val;
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Title order={6} mb={6}>
|
||||
|
||||
Reference in New Issue
Block a user