Fix QC Kak Inno Admin, Fix QC Keano UI User, Fix QC Pak jun tabel apbdes
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
Loader,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
@@ -50,6 +51,7 @@ export default function EditDataLingkunganDesa() {
|
||||
const stateDataLingkunganDesa = useProxy(dataLingkunganDesaState);
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const [formData, setFormData] = useState<FormDataLingkunganDesa>({
|
||||
name: '',
|
||||
@@ -58,6 +60,13 @@ export default function EditDataLingkunganDesa() {
|
||||
icon: '',
|
||||
});
|
||||
|
||||
const [originalData, setOriginalData] = useState<FormDataLingkunganDesa>({
|
||||
name: '',
|
||||
deskripsi: '',
|
||||
jumlah: '',
|
||||
icon: '',
|
||||
});
|
||||
|
||||
// Load data saat komponen mount
|
||||
useEffect(() => {
|
||||
const loadData = async () => {
|
||||
@@ -74,6 +83,12 @@ export default function EditDataLingkunganDesa() {
|
||||
jumlah: data.jumlah,
|
||||
icon: data.icon,
|
||||
});
|
||||
setOriginalData({
|
||||
name: data.name,
|
||||
deskripsi: data.deskripsi,
|
||||
jumlah: data.jumlah,
|
||||
icon: data.icon,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading data lingkungan desa:', error);
|
||||
@@ -84,8 +99,19 @@ export default function EditDataLingkunganDesa() {
|
||||
loadData();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
name: originalData.name,
|
||||
deskripsi: originalData.deskripsi,
|
||||
jumlah: originalData.jumlah,
|
||||
icon: originalData.icon,
|
||||
});
|
||||
toast.info('Form dikembalikan ke data awal');
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
// Update global state hanya saat submit
|
||||
stateDataLingkunganDesa.update.form = {
|
||||
...formData,
|
||||
@@ -100,6 +126,8 @@ export default function EditDataLingkunganDesa() {
|
||||
} catch (error) {
|
||||
console.error('Error updating data lingkungan desa:', error);
|
||||
toast.error('Terjadi kesalahan saat memperbarui data lingkungan desa');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -168,6 +196,17 @@ export default function EditDataLingkunganDesa() {
|
||||
</Box>
|
||||
|
||||
<Group justify="flex-end">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -178,7 +217,7 @@ export default function EditDataLingkunganDesa() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
Loader,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
@@ -16,10 +17,13 @@ import { useProxy } from 'valtio/utils';
|
||||
import CreateEditor from '../../../_com/createEditor';
|
||||
import SelectIconProgram from '../../../_com/selectIcon';
|
||||
import dataLingkunganDesaState from '../../../_state/lingkungan/data-lingkungan-desa';
|
||||
import { useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
function CreateDataLingkunganDesa() {
|
||||
const stateCreate = useProxy(dataLingkunganDesaState);
|
||||
const router = useRouter();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const resetForm = () => {
|
||||
stateCreate.create.form = {
|
||||
@@ -31,9 +35,17 @@ function CreateDataLingkunganDesa() {
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await stateCreate.create.create();
|
||||
resetForm();
|
||||
router.push('/admin/lingkungan/data-lingkungan-desa');
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
await stateCreate.create.create();
|
||||
resetForm();
|
||||
router.push('/admin/lingkungan/data-lingkungan-desa');
|
||||
} catch (error) {
|
||||
console.error("Error creating data lingkungan desa:", error);
|
||||
toast.error("Terjadi kesalahan saat menambahkan data lingkungan desa");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -66,7 +78,7 @@ function CreateDataLingkunganDesa() {
|
||||
<TextInput
|
||||
label={<Text fw="bold" fz="sm">Nama Data Lingkungan Desa</Text>}
|
||||
placeholder="Masukkan nama data lingkungan desa"
|
||||
defaultValue={stateCreate.create.form.name || ''}
|
||||
value={stateCreate.create.form.name || ''}
|
||||
onChange={(val) => (stateCreate.create.form.name = val.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -83,7 +95,7 @@ function CreateDataLingkunganDesa() {
|
||||
<TextInput
|
||||
label={<Text fw="bold" fz="sm">Jumlah Data Lingkungan Desa</Text>}
|
||||
placeholder="Masukkan jumlah data lingkungan desa"
|
||||
defaultValue={stateCreate.create.form.jumlah || ''}
|
||||
value={stateCreate.create.form.jumlah || ''}
|
||||
onChange={(e) => (stateCreate.create.form.jumlah = e.currentTarget.value)}
|
||||
required
|
||||
/>
|
||||
@@ -102,6 +114,17 @@ function CreateDataLingkunganDesa() {
|
||||
|
||||
{/* Submit Button */}
|
||||
<Group justify="right" mt="sm">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={resetForm}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -112,7 +135,7 @@ function CreateDataLingkunganDesa() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
import stateEdukasiLingkungan from '@/app/admin/(dashboard)/_state/lingkungan/edukasi-lingkungan';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
const EdukasiLingkunganTextEditor = dynamic(
|
||||
@@ -24,12 +25,19 @@ export default function EditContohKegiatanDesaDarmasaba() {
|
||||
stateEdukasiLingkungan.stateContohEdukasiLingkungan
|
||||
);
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// state lokal untuk form
|
||||
const [formData, setFormData] = useState({
|
||||
judul: '',
|
||||
deskripsi: '',
|
||||
});
|
||||
|
||||
const [originalData, setOriginalData] = useState({
|
||||
judul: '',
|
||||
deskripsi: '',
|
||||
});
|
||||
|
||||
// load data awal
|
||||
useShallowEffect(() => {
|
||||
if (!contohEdukasiState.findById.data) {
|
||||
@@ -44,6 +52,10 @@ export default function EditContohKegiatanDesaDarmasaba() {
|
||||
judul: contohEdukasiState.findById.data.judul ?? '',
|
||||
deskripsi: contohEdukasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
setOriginalData({
|
||||
judul: contohEdukasiState.findById.data.judul ?? '',
|
||||
deskripsi: contohEdukasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
}
|
||||
}, [contohEdukasiState.findById.data]);
|
||||
|
||||
@@ -52,19 +64,35 @@ export default function EditContohKegiatanDesaDarmasaba() {
|
||||
setFormData((prev) => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
judul: originalData.judul,
|
||||
deskripsi: originalData.deskripsi,
|
||||
});
|
||||
toast.info("Form dikembalikan ke data awal");
|
||||
};
|
||||
|
||||
// submit update
|
||||
const handleSubmit = () => {
|
||||
if (contohEdukasiState.findById.data) {
|
||||
const updatedData = {
|
||||
...contohEdukasiState.findById.data,
|
||||
judul: formData.judul,
|
||||
deskripsi: formData.deskripsi,
|
||||
};
|
||||
contohEdukasiState.update.save(updatedData);
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (contohEdukasiState.findById.data) {
|
||||
const updatedData = {
|
||||
...contohEdukasiState.findById.data,
|
||||
judul: formData.judul,
|
||||
deskripsi: formData.deskripsi,
|
||||
};
|
||||
contohEdukasiState.update.save(updatedData);
|
||||
}
|
||||
router.push(
|
||||
'/admin/lingkungan/edukasi-lingkungan/contoh-kegiatan-desa-darmasaba'
|
||||
);
|
||||
} catch (error) {
|
||||
console.error("Error updating contoh kegiatan desa darmasaba:", error);
|
||||
toast.error("Terjadi kesalahan saat memperbarui contoh kegiatan desa darmasaba");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
router.push(
|
||||
'/admin/lingkungan/edukasi-lingkungan/contoh-kegiatan-desa-darmasaba'
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -111,7 +139,19 @@ export default function EditContohKegiatanDesaDarmasaba() {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Group justify="right">
|
||||
{/* Tombol Batal */}
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -121,9 +161,8 @@ export default function EditContohKegiatanDesaDarmasaba() {
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
loading={contohEdukasiState.update.loading}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
'use client'
|
||||
import stateEdukasiLingkungan from '@/app/admin/(dashboard)/_state/lingkungan/edukasi-lingkungan';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
const EdukasiLingkunganTextEditor = dynamic(
|
||||
@@ -17,9 +18,14 @@ const EdukasiLingkunganTextEditor = dynamic(
|
||||
export default function EditMateriEdukasiYangDiberikan() {
|
||||
const router = useRouter();
|
||||
const materiEdukasiState = useProxy(stateEdukasiLingkungan.stateMateriEdukasiLingkungan);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// State lokal gabungan untuk form
|
||||
const [formData, setFormData] = useState({ judul: '', content: '' });
|
||||
const [originalData, setOriginalData] = useState({
|
||||
judul: '',
|
||||
content: '',
|
||||
});
|
||||
|
||||
// Initialize data kalau belum ada
|
||||
useShallowEffect(() => {
|
||||
@@ -35,6 +41,10 @@ export default function EditMateriEdukasiYangDiberikan() {
|
||||
judul: materiEdukasiState.findById.data.judul ?? '',
|
||||
content: materiEdukasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
setOriginalData({
|
||||
judul: materiEdukasiState.findById.data.judul ?? '',
|
||||
content: materiEdukasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
}
|
||||
}, [materiEdukasiState.findById.data]);
|
||||
|
||||
@@ -42,17 +52,32 @@ export default function EditMateriEdukasiYangDiberikan() {
|
||||
const handleChange = (field: 'judul' | 'content', value: string) => {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
judul: originalData.judul,
|
||||
content: originalData.content,
|
||||
});
|
||||
toast.info("Form dikembalikan ke data awal");
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
if (materiEdukasiState.findById.data) {
|
||||
const updatedData = {
|
||||
...materiEdukasiState.findById.data,
|
||||
judul: formData.judul,
|
||||
deskripsi: formData.content,
|
||||
};
|
||||
materiEdukasiState.update.save(updatedData);
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (materiEdukasiState.findById.data) {
|
||||
const updatedData = {
|
||||
...materiEdukasiState.findById.data,
|
||||
judul: formData.judul,
|
||||
deskripsi: formData.content,
|
||||
};
|
||||
materiEdukasiState.update.save(updatedData);
|
||||
}
|
||||
router.push('/admin/lingkungan/edukasi-lingkungan/materi-edukasi-yang-diberikan');
|
||||
} catch (error) {
|
||||
console.error("Error updating materi edukasi yang diberikan:", error);
|
||||
toast.error("Terjadi kesalahan saat memperbarui materi edukasi yang diberikan");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
router.push('/admin/lingkungan/edukasi-lingkungan/materi-edukasi-yang-diberikan');
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -97,7 +122,19 @@ export default function EditMateriEdukasiYangDiberikan() {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Group justify="right">
|
||||
{/* Tombol Batal */}
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={submit}
|
||||
radius="md"
|
||||
@@ -107,9 +144,8 @@ export default function EditMateriEdukasiYangDiberikan() {
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
loading={materiEdukasiState.update.loading}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
import stateEdukasiLingkungan from '@/app/admin/(dashboard)/_state/lingkungan/edukasi-lingkungan';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
const EdukasiLingkunganTextEditor = dynamic(
|
||||
@@ -18,9 +19,14 @@ const EdukasiLingkunganTextEditor = dynamic(
|
||||
export default function EditTujuanEdukasiLingkungan() {
|
||||
const router = useRouter();
|
||||
const tujuanEdukasiState = useProxy(stateEdukasiLingkungan.stateTujuanEdukasi);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// State lokal untuk form, gak tergantung global state
|
||||
const [formData, setFormData] = useState({ judul: '', deskripsi: '' });
|
||||
const [originalData, setOriginalData] = useState({
|
||||
judul: '',
|
||||
deskripsi: '',
|
||||
});
|
||||
|
||||
// Initialize global state
|
||||
useShallowEffect(() => {
|
||||
@@ -36,25 +42,45 @@ export default function EditTujuanEdukasiLingkungan() {
|
||||
judul: tujuanEdukasiState.findById.data.judul ?? '',
|
||||
deskripsi: tujuanEdukasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
setOriginalData({
|
||||
judul: tujuanEdukasiState.findById.data.judul ?? '',
|
||||
deskripsi: tujuanEdukasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
}
|
||||
}, [tujuanEdukasiState.findById.data]);
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
judul: originalData.judul,
|
||||
deskripsi: originalData.deskripsi,
|
||||
});
|
||||
toast.info("Form dikembalikan ke data awal");
|
||||
};
|
||||
|
||||
// Handler input
|
||||
const handleChange = (field: 'judul' | 'deskripsi', value: string) => {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
if (tujuanEdukasiState.findById.data) {
|
||||
// Update global state hanya saat submit
|
||||
const updatedData = {
|
||||
...tujuanEdukasiState.findById.data,
|
||||
judul: formData.judul,
|
||||
deskripsi: formData.deskripsi,
|
||||
};
|
||||
tujuanEdukasiState.update.save(updatedData);
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (tujuanEdukasiState.findById.data) {
|
||||
// Update global state hanya saat submit
|
||||
const updatedData = {
|
||||
...tujuanEdukasiState.findById.data,
|
||||
judul: formData.judul,
|
||||
deskripsi: formData.deskripsi,
|
||||
};
|
||||
tujuanEdukasiState.update.save(updatedData);
|
||||
}
|
||||
router.push('/admin/lingkungan/edukasi-lingkungan/tujuan-edukasi-lingkungan');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error('Gagal memuat data tujuan edukasi lingkungan');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
router.push('/admin/lingkungan/edukasi-lingkungan/tujuan-edukasi-lingkungan');
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -104,7 +130,19 @@ export default function EditTujuanEdukasiLingkungan() {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Group justify="right">
|
||||
{/* Tombol Batal */}
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={submit}
|
||||
radius="md"
|
||||
@@ -114,9 +152,8 @@ export default function EditTujuanEdukasiLingkungan() {
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
loading={tujuanEdukasiState.update.loading}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import gotongRoyongState from '@/app/admin/(dashboard)/_state/lingkungan/gotong-royong';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
@@ -15,8 +15,10 @@ function EditKategoriKegiatan() {
|
||||
const params = useParams();
|
||||
const id = params?.id as string;
|
||||
const stateKategori = useProxy(gotongRoyongState.kategoriKegiatan);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const [formData, setFormData] = useState({ nama: '' });
|
||||
const [originalData, setOriginalData] = useState({ nama: '' });
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
// Load data once
|
||||
@@ -29,6 +31,7 @@ function EditKategoriKegiatan() {
|
||||
if (data) {
|
||||
stateKategori.edit.id = id;
|
||||
setFormData({ nama: data.nama || '' });
|
||||
setOriginalData({ nama: data.nama || '' });
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Error loading kategori kegiatan:', err);
|
||||
@@ -53,6 +56,7 @@ function EditKategoriKegiatan() {
|
||||
}
|
||||
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
stateKategori.edit.form = { nama: trimmedNama };
|
||||
if (!stateKategori.edit.id) stateKategori.edit.id = id;
|
||||
|
||||
@@ -64,9 +68,18 @@ function EditKategoriKegiatan() {
|
||||
} catch (err) {
|
||||
console.error('Error updating kategori kegiatan:', err);
|
||||
toast.error('Gagal memperbarui kategori kegiatan');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
nama: originalData.nama,
|
||||
});
|
||||
toast.info('Form dikembalikan ke data awal');
|
||||
};
|
||||
|
||||
if (loading) return <Text>Loading...</Text>;
|
||||
|
||||
return (
|
||||
@@ -98,6 +111,17 @@ function EditKategoriKegiatan() {
|
||||
/>
|
||||
|
||||
<Group justify="right">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -108,7 +132,7 @@ function EditKategoriKegiatan() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect } from 'react';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
import gotongRoyongState from '../../../../_state/lingkungan/gotong-royong';
|
||||
import { toast } from 'react-toastify';
|
||||
|
||||
function CreateKategoriKegiatan() {
|
||||
const router = useRouter();
|
||||
const stateKategori = useProxy(gotongRoyongState.kategoriKegiatan)
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
stateKategori.findMany.load();
|
||||
@@ -23,9 +25,17 @@ function CreateKategoriKegiatan() {
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await stateKategori.create.create();
|
||||
resetForm();
|
||||
router.push("/admin/lingkungan/gotong-royong/kategori-kegiatan")
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
await stateKategori.create.create();
|
||||
resetForm();
|
||||
router.push("/admin/lingkungan/gotong-royong/kategori-kegiatan")
|
||||
} catch (error) {
|
||||
console.error('Error creating kategori kegiatan:', error);
|
||||
toast.error('Terjadi kesalahan saat menambahkan kategori kegiatan');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -51,7 +61,7 @@ function CreateKategoriKegiatan() {
|
||||
>
|
||||
<Stack gap="md">
|
||||
<TextInput
|
||||
defaultValue={stateKategori.create.form.nama}
|
||||
value={stateKategori.create.form.nama}
|
||||
onChange={(val) => (stateKategori.create.form.nama = val.target.value)}
|
||||
label={<Text fw="bold" fz="sm">Nama Kategori Kegiatan</Text>}
|
||||
placeholder="Masukkan nama kategori kegiatan"
|
||||
@@ -59,6 +69,17 @@ function CreateKategoriKegiatan() {
|
||||
/>
|
||||
|
||||
<Group justify="right">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={resetForm}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -69,7 +90,7 @@ function CreateKategoriKegiatan() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -5,10 +5,12 @@ import gotongRoyongState from '@/app/admin/(dashboard)/_state/lingkungan/gotong-
|
||||
import colors from '@/con/colors';
|
||||
import ApiFetch from '@/lib/api-fetch';
|
||||
import {
|
||||
ActionIcon,
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
Image,
|
||||
Loader,
|
||||
Paper,
|
||||
Select,
|
||||
Stack,
|
||||
@@ -38,6 +40,7 @@ export default function EditKegiatanDesa() {
|
||||
const kegiatanDesaState = useProxy(gotongRoyongState.kegiatanDesa);
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const [formData, setFormData] = useState<FormKegiatanDesa>({
|
||||
judul: '',
|
||||
@@ -49,6 +52,18 @@ export default function EditKegiatanDesa() {
|
||||
imageId: '',
|
||||
kategoriKegiatanId: '',
|
||||
});
|
||||
const [originalData, setOriginalData] = useState({
|
||||
judul: '',
|
||||
deskripsiSingkat: '',
|
||||
deskripsiLengkap: '',
|
||||
tanggal: '',
|
||||
lokasi: '',
|
||||
partisipan: 0,
|
||||
imageId: '',
|
||||
imageUrl: '',
|
||||
kategoriKegiatanId: '',
|
||||
});
|
||||
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
|
||||
@@ -77,10 +92,18 @@ export default function EditKegiatanDesa() {
|
||||
imageId: data.imageId || '',
|
||||
kategoriKegiatanId: data.kategoriKegiatanId || '',
|
||||
});
|
||||
if (data.imageId) {
|
||||
// Optional: bisa fetch URL image dari backend
|
||||
setPreviewImage(`/api/file/${data.imageId}`);
|
||||
}
|
||||
setOriginalData({
|
||||
judul: data.judul || '',
|
||||
deskripsiSingkat: data.deskripsiSingkat || '',
|
||||
deskripsiLengkap: data.deskripsiLengkap || '',
|
||||
tanggal: data.tanggal || '',
|
||||
lokasi: data.lokasi || '',
|
||||
partisipan: data.partisipan || 0,
|
||||
imageId: data.imageId || '',
|
||||
kategoriKegiatanId: data.kategoriKegiatanId || '',
|
||||
imageUrl: data.image?.link || "",
|
||||
});
|
||||
setPreviewImage(data.image?.link || null);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
@@ -90,8 +113,24 @@ export default function EditKegiatanDesa() {
|
||||
loadData();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
judul: originalData.judul,
|
||||
deskripsiSingkat: originalData.deskripsiSingkat,
|
||||
deskripsiLengkap: originalData.deskripsiLengkap,
|
||||
tanggal: originalData.tanggal,
|
||||
lokasi: originalData.lokasi,
|
||||
partisipan: originalData.partisipan,
|
||||
imageId: originalData.imageId,
|
||||
kategoriKegiatanId: originalData.kategoriKegiatanId,
|
||||
});
|
||||
setPreviewImage(originalData.imageUrl || null);
|
||||
setFile(null);
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
let imageId = formData.imageId;
|
||||
if (file) {
|
||||
const res = await ApiFetch.api.fileStorage.create.post({ file, name: file.name });
|
||||
@@ -117,6 +156,8 @@ export default function EditKegiatanDesa() {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error('Terjadi kesalahan saat memperbarui kegiatan desa');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -203,7 +244,7 @@ export default function EditKegiatanDesa() {
|
||||
}}
|
||||
onReject={() => toast.error('File tidak valid.')}
|
||||
maxSize={5 * 1024 ** 2}
|
||||
accept={{ 'image/*': [] }}
|
||||
accept={{ 'image/*': ['.jpeg', '.jpg', '.png', '.webp'] }}
|
||||
radius="md"
|
||||
p="xl"
|
||||
>
|
||||
@@ -219,13 +260,13 @@ export default function EditKegiatanDesa() {
|
||||
</Dropzone.Idle>
|
||||
<Stack gap="xs" align="center">
|
||||
<Text size="md" fw={500}>Drag gambar atau klik untuk pilih file</Text>
|
||||
<Text size="sm" c="dimmed">Maksimal 5MB, format gambar wajib</Text>
|
||||
<Text size="sm" c="dimmed">Maksimal 5MB, format gambar .png, .jpg, .jpeg, webp</Text>
|
||||
</Stack>
|
||||
</Group>
|
||||
</Dropzone>
|
||||
|
||||
{previewImage && (
|
||||
<Box mt="sm" style={{ display: 'flex', justifyContent: 'center' }}>
|
||||
<Box pos={"relative"} mt="sm" style={{ display: 'flex', justifyContent: 'center' }}>
|
||||
<Image
|
||||
src={previewImage}
|
||||
alt="Preview"
|
||||
@@ -233,11 +274,40 @@ export default function EditKegiatanDesa() {
|
||||
style={{ maxHeight: 220, objectFit: 'contain', border: `1px solid ${colors['blue-button']}` }}
|
||||
loading="lazy"
|
||||
/>
|
||||
<ActionIcon
|
||||
variant="filled"
|
||||
color="red"
|
||||
radius="xl"
|
||||
size="sm"
|
||||
pos="absolute"
|
||||
top={5}
|
||||
right={5}
|
||||
onClick={() => {
|
||||
setPreviewImage(null);
|
||||
setFile(null);
|
||||
}}
|
||||
style={{
|
||||
boxShadow: '0 2px 6px rgba(0,0,0,0.15)',
|
||||
}}
|
||||
>
|
||||
<IconX size={14} />
|
||||
</ActionIcon>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
|
||||
<Group justify="right">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -248,7 +318,7 @@ export default function EditKegiatanDesa() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -5,10 +5,12 @@ import gotongRoyongState from '@/app/admin/(dashboard)/_state/lingkungan/gotong-
|
||||
import colors from '@/con/colors';
|
||||
import ApiFetch from '@/lib/api-fetch';
|
||||
import {
|
||||
ActionIcon,
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
Image,
|
||||
Loader,
|
||||
Paper,
|
||||
Select,
|
||||
Stack,
|
||||
@@ -34,6 +36,8 @@ function CreateKegiatanDesa() {
|
||||
gotongRoyongState.kategoriKegiatan.findMany.load();
|
||||
}, []);
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const resetForm = () => {
|
||||
stateKegiatanDesa.create.form = {
|
||||
judul: '',
|
||||
@@ -50,27 +54,35 @@ function CreateKegiatanDesa() {
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!file) {
|
||||
return toast.warn('Silakan pilih file gambar terlebih dahulu');
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (!file) {
|
||||
return toast.warn('Silakan 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 mengunggah gambar, silakan coba lagi');
|
||||
}
|
||||
|
||||
stateKegiatanDesa.create.form.imageId = uploaded.id;
|
||||
|
||||
await stateKegiatanDesa.create.create();
|
||||
|
||||
resetForm();
|
||||
router.push('/admin/lingkungan/gotong-royong/kegiatan-desa');
|
||||
} catch (error) {
|
||||
console.error('Error creating kegiatan desa:', error);
|
||||
toast.error('Gagal membuat kegiatan desa');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
|
||||
const res = await ApiFetch.api.fileStorage.create.post({
|
||||
file,
|
||||
name: file.name,
|
||||
});
|
||||
|
||||
const uploaded = res.data?.data;
|
||||
|
||||
if (!uploaded?.id) {
|
||||
return toast.error('Gagal mengunggah gambar, silakan coba lagi');
|
||||
}
|
||||
|
||||
stateKegiatanDesa.create.form.imageId = uploaded.id;
|
||||
|
||||
await stateKegiatanDesa.create.create();
|
||||
|
||||
resetForm();
|
||||
router.push('/admin/lingkungan/gotong-royong/kegiatan-desa');
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -115,7 +127,7 @@ function CreateKegiatanDesa() {
|
||||
}}
|
||||
onReject={() => toast.error('File tidak valid, gunakan format gambar')}
|
||||
maxSize={5 * 1024 ** 2}
|
||||
accept={{ 'image/*': [] }}
|
||||
accept={{ 'image/*': ['.jpeg', '.jpg', '.png', '.webp'] }}
|
||||
radius="md"
|
||||
p="xl"
|
||||
>
|
||||
@@ -136,7 +148,7 @@ function CreateKegiatanDesa() {
|
||||
</Dropzone>
|
||||
|
||||
{previewImage && (
|
||||
<Box mt="sm" style={{ textAlign: 'center' }}>
|
||||
<Box pos={"relative"} mt="sm" style={{ textAlign: 'center' }}>
|
||||
<Image
|
||||
src={previewImage}
|
||||
alt="Preview Gambar"
|
||||
@@ -144,6 +156,24 @@ function CreateKegiatanDesa() {
|
||||
style={{ maxHeight: 200, objectFit: 'contain', border: '1px solid #ddd' }}
|
||||
loading="lazy"
|
||||
/>
|
||||
<ActionIcon
|
||||
variant="filled"
|
||||
color="red"
|
||||
radius="xl"
|
||||
size="sm"
|
||||
pos="absolute"
|
||||
top={5}
|
||||
right={5}
|
||||
onClick={() => {
|
||||
setPreviewImage(null);
|
||||
setFile(null);
|
||||
}}
|
||||
style={{
|
||||
boxShadow: '0 2px 6px rgba(0,0,0,0.15)',
|
||||
}}
|
||||
>
|
||||
<IconX size={14} />
|
||||
</ActionIcon>
|
||||
</Box>
|
||||
)}
|
||||
</Box>
|
||||
@@ -152,7 +182,7 @@ function CreateKegiatanDesa() {
|
||||
<TextInput
|
||||
label="Judul Kegiatan"
|
||||
placeholder="Masukkan judul kegiatan"
|
||||
defaultValue={stateKegiatanDesa.create.form.judul}
|
||||
value={stateKegiatanDesa.create.form.judul}
|
||||
onChange={(e) => (stateKegiatanDesa.create.form.judul = e.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -168,7 +198,7 @@ function CreateKegiatanDesa() {
|
||||
<TextInput
|
||||
type="number"
|
||||
min={0}
|
||||
defaultValue={stateKegiatanDesa.create.form.partisipan}
|
||||
value={stateKegiatanDesa.create.form.partisipan}
|
||||
onChange={(e) => {
|
||||
const value = Number(e.target.value);
|
||||
if (value >= 0) {
|
||||
@@ -183,7 +213,7 @@ function CreateKegiatanDesa() {
|
||||
label="Tanggal"
|
||||
type="date"
|
||||
placeholder="Contoh: 2022-01-01"
|
||||
defaultValue={
|
||||
value={
|
||||
stateKegiatanDesa.create.form.tanggal
|
||||
? stateKegiatanDesa.create.form.tanggal.toISOString().split('T')[0]
|
||||
: ''
|
||||
@@ -197,7 +227,7 @@ function CreateKegiatanDesa() {
|
||||
<TextInput
|
||||
label="Lokasi"
|
||||
placeholder="Masukkan lokasi kegiatan"
|
||||
defaultValue={stateKegiatanDesa.create.form.lokasi}
|
||||
value={stateKegiatanDesa.create.form.lokasi}
|
||||
onChange={(e) => (stateKegiatanDesa.create.form.lokasi = e.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -228,6 +258,17 @@ function CreateKegiatanDesa() {
|
||||
|
||||
{/* Submit */}
|
||||
<Group justify="right">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={resetForm}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -238,7 +279,7 @@ function CreateKegiatanDesa() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
'use client'
|
||||
import stateKonservasiAdatBali from '@/app/admin/(dashboard)/_state/lingkungan/konservasi-adat-bali';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
const KonservasiAdatBaliTextEditor = dynamic(
|
||||
@@ -17,9 +18,14 @@ const KonservasiAdatBaliTextEditor = dynamic(
|
||||
function EditBentukKonservasiBerdasarkanAdat() {
|
||||
const router = useRouter();
|
||||
const bentukKonservasiState = useProxy(stateKonservasiAdatBali.stateBentukKonservasiBerdasarkanAdat);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// Gabung semua field form jadi satu object
|
||||
const [formData, setFormData] = useState({ judul: '', deskripsi: '' });
|
||||
const [originalData, setOriginalData] = useState({
|
||||
judul: '',
|
||||
deskripsi: '',
|
||||
});
|
||||
|
||||
// Initialize data dari global state
|
||||
useShallowEffect(() => {
|
||||
@@ -34,6 +40,10 @@ function EditBentukKonservasiBerdasarkanAdat() {
|
||||
judul: bentukKonservasiState.findById.data.judul ?? '',
|
||||
deskripsi: bentukKonservasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
setOriginalData({
|
||||
judul: bentukKonservasiState.findById.data.judul ?? '',
|
||||
deskripsi: bentukKonservasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
}
|
||||
}, [bentukKonservasiState.findById.data]);
|
||||
|
||||
@@ -41,13 +51,29 @@ function EditBentukKonservasiBerdasarkanAdat() {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
if (bentukKonservasiState.findById.data) {
|
||||
// Update global state cuma pas submit
|
||||
const updatedData = { ...bentukKonservasiState.findById.data, ...formData };
|
||||
bentukKonservasiState.update.save(updatedData);
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
judul: originalData.judul,
|
||||
deskripsi: originalData.deskripsi,
|
||||
});
|
||||
toast.info("Form dikembalikan ke data awal");
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (bentukKonservasiState.findById.data) {
|
||||
// Update global state cuma pas submit
|
||||
const updatedData = { ...bentukKonservasiState.findById.data, ...formData };
|
||||
bentukKonservasiState.update.save(updatedData);
|
||||
}
|
||||
router.push('/admin/lingkungan/konservasi-adat-bali/bentuk-konservasi-berdasarkan-adat');
|
||||
} catch (error) {
|
||||
console.error("Error updating bentuk konservasi berdasarkan adat:", error);
|
||||
toast.error("Terjadi kesalahan saat memperbarui bentuk konservasi berdasarkan adat");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
router.push('/admin/lingkungan/konservasi-adat-bali/bentuk-konservasi-berdasarkan-adat');
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -94,9 +120,21 @@ function EditBentukKonservasiBerdasarkanAdat() {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Group justify="right">
|
||||
{/* Tombol Batal */}
|
||||
<Button
|
||||
onClick={submit}
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
style={{
|
||||
@@ -104,9 +142,8 @@ function EditBentukKonservasiBerdasarkanAdat() {
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
loading={bentukKonservasiState.update.loading}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
|
||||
import stateKonservasiAdatBali from '@/app/admin/(dashboard)/_state/lingkungan/konservasi-adat-bali';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
const KonservasiAdatBaliTextEditor = dynamic(
|
||||
@@ -21,9 +22,14 @@ const KonservasiAdatBaliTextEditor = dynamic(
|
||||
function EditFilosofiTriHitaKarana() {
|
||||
const router = useRouter();
|
||||
const filosofiTriHitaState = useProxy(stateKonservasiAdatBali.stateFilosofiTriHita);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// Local state form
|
||||
const [formData, setFormData] = useState({ judul: '', content: '' });
|
||||
const [originalData, setOriginalData] = useState({
|
||||
judul: '',
|
||||
content: '',
|
||||
});
|
||||
|
||||
// Load data dari global state kalau belum ada
|
||||
useShallowEffect(() => {
|
||||
@@ -39,6 +45,10 @@ function EditFilosofiTriHitaKarana() {
|
||||
judul: filosofiTriHitaState.findById.data.judul ?? '',
|
||||
content: filosofiTriHitaState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
setOriginalData({
|
||||
judul: filosofiTriHitaState.findById.data.judul ?? '',
|
||||
content: filosofiTriHitaState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
}
|
||||
}, [filosofiTriHitaState.findById.data]);
|
||||
|
||||
@@ -46,13 +56,29 @@ function EditFilosofiTriHitaKarana() {
|
||||
setFormData((prev) => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
judul: originalData.judul,
|
||||
content: originalData.content,
|
||||
});
|
||||
toast.info("Form dikembalikan ke data awal");
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
if (filosofiTriHitaState.findById.data) {
|
||||
filosofiTriHitaState.findById.data.judul = formData.judul;
|
||||
filosofiTriHitaState.findById.data.deskripsi = formData.content;
|
||||
filosofiTriHitaState.update.save(filosofiTriHitaState.findById.data);
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (filosofiTriHitaState.findById.data) {
|
||||
filosofiTriHitaState.findById.data.judul = formData.judul;
|
||||
filosofiTriHitaState.findById.data.deskripsi = formData.content;
|
||||
filosofiTriHitaState.update.save(filosofiTriHitaState.findById.data);
|
||||
}
|
||||
router.push('/admin/lingkungan/konservasi-adat-bali/filosofi-tri-hita-karana');
|
||||
} catch (error) {
|
||||
console.error("Error updating filosofi tri hita karana:", error);
|
||||
toast.error("Terjadi kesalahan saat memperbarui filosofi tri hita karana");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
router.push('/admin/lingkungan/konservasi-adat-bali/filosofi-tri-hita-karana');
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -99,7 +125,19 @@ function EditFilosofiTriHitaKarana() {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Group justify="right">
|
||||
{/* Tombol Batal */}
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -109,9 +147,8 @@ function EditFilosofiTriHitaKarana() {
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
loading={filosofiTriHitaState.update.loading}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
'use client'
|
||||
import stateKonservasiAdatBali from '@/app/admin/(dashboard)/_state/lingkungan/konservasi-adat-bali';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, Title } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
const KonservasiAdatBaliTextEditor = dynamic(
|
||||
@@ -17,9 +18,11 @@ const KonservasiAdatBaliTextEditor = dynamic(
|
||||
function EditNilaiKonservasiAdat() {
|
||||
const router = useRouter();
|
||||
const nilaiKonservasiState = useProxy(stateKonservasiAdatBali.stateNilaiKonservasiAdat);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// state lokal untuk form
|
||||
const [formData, setFormData] = useState({ judul: '', deskripsi: '' });
|
||||
const [originalData, setOriginalData] = useState({ judul: '', deskripsi: '' });
|
||||
|
||||
// load data awal
|
||||
useShallowEffect(() => {
|
||||
@@ -35,6 +38,10 @@ function EditNilaiKonservasiAdat() {
|
||||
judul: nilaiKonservasiState.findById.data.judul ?? '',
|
||||
deskripsi: nilaiKonservasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
setOriginalData({
|
||||
judul: nilaiKonservasiState.findById.data.judul ?? '',
|
||||
deskripsi: nilaiKonservasiState.findById.data.deskripsi ?? '',
|
||||
});
|
||||
}
|
||||
}, [nilaiKonservasiState.findById.data]);
|
||||
|
||||
@@ -42,14 +49,30 @@ function EditNilaiKonservasiAdat() {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const submit = () => {
|
||||
if (nilaiKonservasiState.findById.data) {
|
||||
// update global state saat submit
|
||||
nilaiKonservasiState.findById.data.judul = formData.judul;
|
||||
nilaiKonservasiState.findById.data.deskripsi = formData.deskripsi;
|
||||
nilaiKonservasiState.update.save(nilaiKonservasiState.findById.data);
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
judul: originalData.judul,
|
||||
deskripsi: originalData.deskripsi,
|
||||
});
|
||||
toast.info("Form dikembalikan ke data awal");
|
||||
};
|
||||
|
||||
const handleSubmit = () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (nilaiKonservasiState.findById.data) {
|
||||
// update global state saat submit
|
||||
nilaiKonservasiState.findById.data.judul = formData.judul;
|
||||
nilaiKonservasiState.findById.data.deskripsi = formData.deskripsi;
|
||||
nilaiKonservasiState.update.save(nilaiKonservasiState.findById.data);
|
||||
}
|
||||
router.push('/admin/lingkungan/konservasi-adat-bali/nilai-konservasi-adat');
|
||||
} catch (error) {
|
||||
console.error("Error updating nilai konservasi adat:", error);
|
||||
toast.error("Terjadi kesalahan saat memperbarui nilai konservasi adat");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
router.push('/admin/lingkungan/konservasi-adat-bali/nilai-konservasi-adat');
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -96,9 +119,21 @@ function EditNilaiKonservasiAdat() {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Group justify="right">
|
||||
{/* Tombol Batal */}
|
||||
<Button
|
||||
onClick={submit}
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
style={{
|
||||
@@ -106,9 +141,8 @@ function EditNilaiKonservasiAdat() {
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
loading={nilaiKonservasiState.update.loading}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
import pengelolaanSampahState from '@/app/admin/(dashboard)/_state/lingkungan/pengelolaan-sampah';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
@@ -18,7 +18,7 @@ function EditKeteranganBankSampahTerdekat() {
|
||||
const router = useRouter();
|
||||
const params = useParams();
|
||||
const [markerPosition, setMarkerPosition] = useState<{ lat: number; lng: number } | null>(null);
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
const [formData, setFormData] = useState({
|
||||
name: '',
|
||||
alamat: '',
|
||||
@@ -27,6 +27,14 @@ function EditKeteranganBankSampahTerdekat() {
|
||||
lng: 0,
|
||||
});
|
||||
|
||||
const [originalData, setOriginalData] = useState({
|
||||
name: '',
|
||||
alamat: '',
|
||||
namaTempatMaps: '',
|
||||
lat: 0,
|
||||
lng: 0,
|
||||
});
|
||||
|
||||
// Load data ketika component mount
|
||||
useEffect(() => {
|
||||
const loadKeterangan = async () => {
|
||||
@@ -46,6 +54,15 @@ function EditKeteranganBankSampahTerdekat() {
|
||||
lat: data.lat,
|
||||
lng: data.lng,
|
||||
});
|
||||
|
||||
// simpan juga versi original
|
||||
setOriginalData({
|
||||
name: data.name,
|
||||
alamat: data.alamat,
|
||||
namaTempatMaps: data.namaTempatMaps,
|
||||
lat: data.lat,
|
||||
lng: data.lng,
|
||||
});
|
||||
setMarkerPosition({ lat: data.lat, lng: data.lng });
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -61,8 +78,21 @@ function EditKeteranganBankSampahTerdekat() {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
name: originalData.name,
|
||||
alamat: originalData.alamat,
|
||||
namaTempatMaps: originalData.namaTempatMaps,
|
||||
lat: originalData.lat,
|
||||
lng: originalData.lng,
|
||||
});
|
||||
setMarkerPosition({ lat: originalData.lat, lng: originalData.lng });
|
||||
toast.info('Form dikembalikan ke data awal');
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (!formData.name.trim()) return toast.error('Nama bank sampah harus diisi');
|
||||
if (!formData.alamat.trim()) return toast.error('Alamat harus diisi');
|
||||
if (!formData.namaTempatMaps.trim()) return toast.error('Nama tempat di Maps harus diisi');
|
||||
@@ -84,6 +114,8 @@ function EditKeteranganBankSampahTerdekat() {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error(error instanceof Error ? error.message : 'Gagal memperbarui data bank sampah');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -150,6 +182,17 @@ function EditKeteranganBankSampahTerdekat() {
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -160,7 +203,7 @@ function EditKeteranganBankSampahTerdekat() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import pengelolaanSampahState from '@/app/admin/(dashboard)/_state/lingkungan/pengelolaan-sampah';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import dynamic from 'next/dynamic';
|
||||
import { useRouter } from 'next/navigation';
|
||||
@@ -17,6 +17,7 @@ function CreateKeteranganBankSampahTerdekat() {
|
||||
const router = useRouter();
|
||||
|
||||
const [markerPosition, setMarkerPosition] = useState<{ lat: number; lng: number } | null>(null);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const resetForm = () => {
|
||||
keteranganState.create.form = {
|
||||
@@ -30,6 +31,7 @@ function CreateKeteranganBankSampahTerdekat() {
|
||||
}
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
if (!keteranganState.create.form.name) {
|
||||
return toast.error('Nama bank sampah harus diisi');
|
||||
}
|
||||
@@ -48,6 +50,8 @@ function CreateKeteranganBankSampahTerdekat() {
|
||||
} catch (error) {
|
||||
console.error('Error creating bank sampah:', error);
|
||||
toast.error('Gagal menambahkan data bank sampah');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +78,7 @@ function CreateKeteranganBankSampahTerdekat() {
|
||||
<TextInput
|
||||
label="Nama Bank Sampah"
|
||||
placeholder="Masukkan nama bank sampah"
|
||||
defaultValue={keteranganState.create.form.name}
|
||||
value={keteranganState.create.form.name}
|
||||
onChange={(e) => (keteranganState.create.form.name = e.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -82,7 +86,7 @@ function CreateKeteranganBankSampahTerdekat() {
|
||||
<TextInput
|
||||
label="Alamat"
|
||||
placeholder="Masukkan alamat lengkap"
|
||||
defaultValue={keteranganState.create.form.alamat}
|
||||
value={keteranganState.create.form.alamat}
|
||||
onChange={(e) => (keteranganState.create.form.alamat = e.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -90,7 +94,7 @@ function CreateKeteranganBankSampahTerdekat() {
|
||||
<TextInput
|
||||
label="Nama Tempat di Maps"
|
||||
placeholder="Masukkan nama tempat yang terdaftar di Google Maps"
|
||||
defaultValue={keteranganState.create.form.namaTempatMaps}
|
||||
value={keteranganState.create.form.namaTempatMaps}
|
||||
onChange={(e) => (keteranganState.create.form.namaTempatMaps = e.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -116,6 +120,17 @@ function CreateKeteranganBankSampahTerdekat() {
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={resetForm}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -126,7 +141,7 @@ function CreateKeteranganBankSampahTerdekat() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import SelectIconProgramEdit from '@/app/admin/(dashboard)/_com/selectIconEdit';
|
||||
import pengelolaanSampahState from '@/app/admin/(dashboard)/_state/lingkungan/pengelolaan-sampah';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
import { useEffect, useState } from 'react';
|
||||
@@ -21,6 +21,7 @@ function EditProgramKreatifDesa() {
|
||||
const stateSampah = useProxy(pengelolaanSampahState.pengelolaanSampah)
|
||||
const params = useParams()
|
||||
const router = useRouter();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// State lokal untuk form controlled
|
||||
const [formData, setFormData] = useState<FormProgramKreatif>({
|
||||
@@ -28,6 +29,11 @@ function EditProgramKreatifDesa() {
|
||||
icon: '',
|
||||
});
|
||||
|
||||
const [originalData, setOriginalData] = useState<FormProgramKreatif>({
|
||||
name: '',
|
||||
icon: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const loadProgramKreatif = async () => {
|
||||
const id = params?.id as string;
|
||||
@@ -41,6 +47,10 @@ function EditProgramKreatifDesa() {
|
||||
name: data.name,
|
||||
icon: data.icon,
|
||||
});
|
||||
setOriginalData({
|
||||
name: data.name,
|
||||
icon: data.icon,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error loading pengelolaan sampah:", error);
|
||||
@@ -51,8 +61,17 @@ function EditProgramKreatifDesa() {
|
||||
loadProgramKreatif();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
name: originalData.name,
|
||||
icon: originalData.icon,
|
||||
});
|
||||
toast.info("Form dikembalikan ke data awal");
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
// Update global state HANYA saat submit
|
||||
stateSampah.update.form = {
|
||||
name: formData.name.trim(),
|
||||
@@ -65,6 +84,8 @@ function EditProgramKreatifDesa() {
|
||||
} catch (error) {
|
||||
console.error("Error updating pengelolaan sampah:", error);
|
||||
toast.error(error instanceof Error ? error.message : "Gagal memperbarui data pengelolaan sampah");
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -107,6 +128,17 @@ function EditProgramKreatifDesa() {
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -117,7 +149,7 @@ function EditProgramKreatifDesa() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -2,17 +2,16 @@
|
||||
import SelectIconProgram from '@/app/admin/(dashboard)/_com/selectIcon';
|
||||
import pengelolaanSampahState from '@/app/admin/(dashboard)/_state/lingkungan/pengelolaan-sampah';
|
||||
import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { Box, Button, Group, Loader, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
|
||||
import { IconArrowBack } from '@tabler/icons-react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import { useState } from 'react';
|
||||
import { useProxy } from 'valtio/utils';
|
||||
|
||||
|
||||
|
||||
|
||||
function CreatePengelolaanSampahBankSampah() {
|
||||
const stateCreate = useProxy(pengelolaanSampahState.pengelolaanSampah);
|
||||
const router = useRouter();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const resetForm = () => {
|
||||
stateCreate.create.form = {
|
||||
@@ -23,11 +22,14 @@ function CreatePengelolaanSampahBankSampah() {
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
await stateCreate.create.create();
|
||||
resetForm();
|
||||
router.push("/admin/lingkungan/pengelolaan-sampah-bank-sampah/list-pengelolaan-sampah-bank-sampah");
|
||||
} catch (error) {
|
||||
console.error('Error creating pengelolaan sampah:', error);
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -59,7 +61,7 @@ function CreatePengelolaanSampahBankSampah() {
|
||||
<TextInput
|
||||
label="Nama Pengelolaan Sampah"
|
||||
placeholder="Masukkan nama pengelolaan sampah"
|
||||
defaultValue={stateCreate.create.form.name || ''}
|
||||
value={stateCreate.create.form.name || ''}
|
||||
onChange={(e) => (stateCreate.create.form.name = e.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -74,6 +76,17 @@ function CreatePengelolaanSampahBankSampah() {
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="md">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={resetForm}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -84,7 +97,7 @@ function CreatePengelolaanSampahBankSampah() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
Loader,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
@@ -47,6 +48,7 @@ function EditProgramPenghijauan() {
|
||||
const stateProgramPenghijauan = useProxy(programPenghijauanState);
|
||||
const params = useParams();
|
||||
const router = useRouter();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const [formData, setFormData] = useState<FormProgramPenghijauan>({
|
||||
name: '',
|
||||
@@ -55,6 +57,13 @@ function EditProgramPenghijauan() {
|
||||
icon: '',
|
||||
});
|
||||
|
||||
const [originalData, setOriginalData] = useState<FormProgramPenghijauan>({
|
||||
name: '',
|
||||
judul: '',
|
||||
deskripsi: '',
|
||||
icon: '',
|
||||
});
|
||||
|
||||
// Load data program penghijauan
|
||||
useEffect(() => {
|
||||
const loadProgram = async () => {
|
||||
@@ -71,6 +80,12 @@ function EditProgramPenghijauan() {
|
||||
deskripsi: data.deskripsi,
|
||||
icon: data.icon,
|
||||
});
|
||||
setOriginalData({
|
||||
name: data.name,
|
||||
judul: data.judul,
|
||||
deskripsi: data.deskripsi,
|
||||
icon: data.icon,
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error loading program penghijauan:', error);
|
||||
@@ -81,9 +96,20 @@ function EditProgramPenghijauan() {
|
||||
loadProgram();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleResetForm = () => {
|
||||
setFormData({
|
||||
name: originalData.name,
|
||||
judul: originalData.judul,
|
||||
deskripsi: originalData.deskripsi,
|
||||
icon: originalData.icon,
|
||||
});
|
||||
toast.info('Form dikembalikan ke data awal');
|
||||
};
|
||||
|
||||
// Hanya update global state saat submit
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
stateProgramPenghijauan.update.form = {
|
||||
name: formData.name.trim(),
|
||||
judul: formData.judul.trim(),
|
||||
@@ -97,6 +123,8 @@ function EditProgramPenghijauan() {
|
||||
} catch (error) {
|
||||
console.error('Error updating program penghijauan:', error);
|
||||
toast.error('Gagal memperbarui program penghijauan');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -173,6 +201,17 @@ function EditProgramPenghijauan() {
|
||||
|
||||
{/* Tombol simpan */}
|
||||
<Group justify="flex-end">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={handleResetForm}
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -183,7 +222,7 @@ function EditProgramPenghijauan() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
@@ -4,9 +4,13 @@ import colors from '@/con/colors';
|
||||
import { Box, Button, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||
import { useShallowEffect } from '@mantine/hooks';
|
||||
import {
|
||||
IconArrowBack, IconChartLine, IconChristmasTreeFilled, IconClipboard,
|
||||
IconEdit, IconHomeEco, IconLeaf, IconRecycle, IconScale,
|
||||
IconShieldFilled, IconTent, IconTrash, IconTrendingUp,
|
||||
IconAlertTriangle,
|
||||
IconAmbulance,
|
||||
IconArrowBack, IconBuilding, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboard,
|
||||
IconDroplet,
|
||||
IconEdit, IconFiretruck, IconHome, IconHomeEco, IconHospital, IconLeaf, IconRecycle, IconScale,
|
||||
IconSchool,
|
||||
IconShieldFilled, IconShoppingCart, IconTent, IconTrash, IconTree, IconTrendingUp,
|
||||
IconTrophy, IconTruck
|
||||
} from '@tabler/icons-react';
|
||||
import { useParams, useRouter } from 'next/navigation';
|
||||
@@ -24,18 +28,31 @@ function DetailProgramPenghijauan() {
|
||||
|
||||
const iconMap: Record<string, React.FC<any>> = {
|
||||
ekowisata: IconLeaf,
|
||||
kompetisi: IconTrophy,
|
||||
wisata: IconTent,
|
||||
ekonomi: IconChartLine,
|
||||
sampah: IconRecycle,
|
||||
truck: IconTruck,
|
||||
scale: IconScale,
|
||||
clipboard: IconClipboard,
|
||||
trash: IconTrash,
|
||||
lingkunganSehat: IconHomeEco,
|
||||
sumberOksigen: IconChristmasTreeFilled,
|
||||
ekonomiBerkelanjutan: IconTrendingUp,
|
||||
mencegahBencana: IconShieldFilled,
|
||||
kompetisi: IconTrophy,
|
||||
wisata: IconTent,
|
||||
ekonomi: IconChartLine,
|
||||
sampah: IconRecycle,
|
||||
truck: IconTruck,
|
||||
scale: IconScale,
|
||||
clipboard: IconClipboard,
|
||||
trash: IconTrash,
|
||||
lingkunganSehat: IconHomeEco,
|
||||
sumberOksigen: IconChristmasTreeFilled,
|
||||
ekonomiBerkelanjutan: IconTrendingUp,
|
||||
mencegahBencana: IconShieldFilled,
|
||||
rumah: IconHome,
|
||||
pohon: IconTree,
|
||||
air: IconDroplet,
|
||||
bantuan: IconCash,
|
||||
pelatihan: IconSchool,
|
||||
subsidi: IconShoppingCart,
|
||||
layananKesehatan: IconHospital,
|
||||
polisi: IconShieldFilled,
|
||||
ambulans: IconAmbulance,
|
||||
pemadam: IconFiretruck,
|
||||
rumahSakit: IconHospital,
|
||||
bangunan: IconBuilding,
|
||||
darurat: IconAlertTriangle
|
||||
};
|
||||
|
||||
useShallowEffect(() => {
|
||||
@@ -96,7 +113,7 @@ function DetailProgramPenghijauan() {
|
||||
|
||||
<Box>
|
||||
<Text fz="lg" fw="bold">Ikon Program</Text>
|
||||
{iconMap[data?.icon] ? (
|
||||
{iconMap[data?.icon] ? (
|
||||
<Box title={data?.icon}>
|
||||
{React.createElement(iconMap[data.icon], { size: 28, color: colors['blue-button'] })}
|
||||
</Box>
|
||||
|
||||
@@ -4,6 +4,7 @@ import {
|
||||
Box,
|
||||
Button,
|
||||
Group,
|
||||
Loader,
|
||||
Paper,
|
||||
Stack,
|
||||
Text,
|
||||
@@ -16,10 +17,13 @@ import { useProxy } from 'valtio/utils';
|
||||
import CreateEditor from '../../../_com/createEditor';
|
||||
import SelectIconProgram from '../../../_com/selectIcon';
|
||||
import programPenghijauanState from '../../../_state/lingkungan/program-penghijauan';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useState } from 'react';
|
||||
|
||||
function CreateProgramPenghijauan() {
|
||||
const stateCreate = useProxy(programPenghijauanState);
|
||||
const router = useRouter();
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const resetForm = () => {
|
||||
stateCreate.create.form = {
|
||||
@@ -31,9 +35,17 @@ function CreateProgramPenghijauan() {
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await stateCreate.create.create();
|
||||
resetForm();
|
||||
router.push('/admin/lingkungan/program-penghijauan');
|
||||
try {
|
||||
setIsSubmitting(true);
|
||||
await stateCreate.create.create();
|
||||
resetForm();
|
||||
router.push('/admin/lingkungan/program-penghijauan');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
toast.error(error instanceof Error ? error.message : 'Gagal menambahkan program penghijauan');
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -66,7 +78,7 @@ function CreateProgramPenghijauan() {
|
||||
<TextInput
|
||||
label={<Text fz="sm" fw="bold">Nama Program Penghijauan</Text>}
|
||||
placeholder="Masukkan nama program penghijauan"
|
||||
defaultValue={stateCreate.create.form.name || ''}
|
||||
value={stateCreate.create.form.name || ''}
|
||||
onChange={(e) => (stateCreate.create.form.name = e.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -83,7 +95,7 @@ function CreateProgramPenghijauan() {
|
||||
<TextInput
|
||||
label={<Text fz="sm" fw="bold">Judul Deskripsi Program Penghijauan</Text>}
|
||||
placeholder="Masukkan judul deskripsi program penghijauan"
|
||||
defaultValue={stateCreate.create.form.judul || ''}
|
||||
value={stateCreate.create.form.judul || ''}
|
||||
onChange={(e) => (stateCreate.create.form.judul = e.target.value)}
|
||||
required
|
||||
/>
|
||||
@@ -101,6 +113,17 @@ function CreateProgramPenghijauan() {
|
||||
</Box>
|
||||
|
||||
<Group justify="right" mt="sm">
|
||||
<Button
|
||||
variant="outline"
|
||||
color="gray"
|
||||
radius="md"
|
||||
size="md"
|
||||
onClick={resetForm}
|
||||
>
|
||||
Reset
|
||||
</Button>
|
||||
|
||||
{/* Tombol Simpan */}
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
@@ -111,7 +134,7 @@ function CreateProgramPenghijauan() {
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
>
|
||||
Simpan
|
||||
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
|
||||
</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
|
||||
Reference in New Issue
Block a user