feat: add form validation for inovasi, lingkungan, and pendidikan modules
- Added isFormValid() and isHtmlEmpty() helper functions for form validation - Disabled submit buttons when required fields are empty across multiple admin and public pages - Applied consistent validation pattern for creating and editing records - Commented out WhatsApp OTP sending in login route for debugging/testing - Fixed path in NavbarMainMenu tooltip action
This commit is contained in:
@@ -12,6 +12,25 @@ function Page() {
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const ideInovatif = useProxy(ajukanIdeInovatifState);
|
||||
|
||||
// Helper function to check if HTML content is empty
|
||||
const isHtmlEmpty = (html: string) => {
|
||||
// Remove all HTML tags and check if there's any text content
|
||||
const textContent = html.replace(/<[^>]*>/g, '').trim();
|
||||
return textContent === '';
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
ideInovatif.create.form.name?.trim() !== '' &&
|
||||
ideInovatif.create.form.alamat?.trim() !== '' &&
|
||||
ideInovatif.create.form.namaIde?.trim() !== '' &&
|
||||
!isHtmlEmpty(ideInovatif.create.form.deskripsi) &&
|
||||
ideInovatif.create.form.masalah?.trim() !== '' &&
|
||||
ideInovatif.create.form.benefit?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
ideInovatif.create.form = {
|
||||
name: "",
|
||||
@@ -168,7 +187,11 @@ function Page() {
|
||||
ideInovatif.create.form.benefit = val.target.value;
|
||||
}}
|
||||
/>
|
||||
<Button bg={colors['blue-button']} onClick={handleSubmit}>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
disabled={!isFormValid()}
|
||||
>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
@@ -24,6 +24,16 @@ function AdministrasiOnline() {
|
||||
const [opened, { open, close }] = useDisclosure(false);
|
||||
const state = useProxy(layananonlineDesa);
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
state.administrasiOnline.create.form.name?.trim() !== '' &&
|
||||
state.administrasiOnline.create.form.alamat?.trim() !== '' &&
|
||||
state.administrasiOnline.create.form.nomorTelepon?.trim() !== '' &&
|
||||
state.administrasiOnline.create.form.jenisLayananId?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// ✅ Panggil load data jenis layanan dari backend
|
||||
if (!state.jenisLayanan.findMany.data) {
|
||||
@@ -104,7 +114,11 @@ function AdministrasiOnline() {
|
||||
}
|
||||
/>
|
||||
|
||||
<Button bg={colors['blue-button']} onClick={handleSubmit}>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
disabled={!isFormValid()}
|
||||
>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
@@ -19,6 +19,28 @@ function PengaduanMasyarakat() {
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
|
||||
// Helper function to check if HTML content is empty
|
||||
const isHtmlEmpty = (html: string) => {
|
||||
// Remove all HTML tags and check if there's any text content
|
||||
const textContent = html.replace(/<[^>]*>/g, '').trim();
|
||||
return textContent === '';
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
state.pengaduanMasyarakat.create.form.name?.trim() !== '' &&
|
||||
state.pengaduanMasyarakat.create.form.email?.trim() !== '' &&
|
||||
state.pengaduanMasyarakat.create.form.nomorTelepon?.trim() !== '' &&
|
||||
state.pengaduanMasyarakat.create.form.nik?.trim() !== '' &&
|
||||
state.pengaduanMasyarakat.create.form.judulPengaduan?.trim() !== '' &&
|
||||
state.pengaduanMasyarakat.create.form.lokasiKejadian?.trim() !== '' &&
|
||||
!isHtmlEmpty(state.pengaduanMasyarakat.create.form.deskripsiPengaduan) &&
|
||||
state.pengaduanMasyarakat.create.form.jenisPengaduanId?.trim() !== '' &&
|
||||
file !== null
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
// ✅ Panggil load data jenis layanan dari backend
|
||||
if (!state.jenisPengaduan.findMany.data) {
|
||||
@@ -207,7 +229,11 @@ function PengaduanMasyarakat() {
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
<Button bg={colors['blue-button']} onClick={handleSubmit}>
|
||||
<Button
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
disabled={!isFormValid()}
|
||||
>
|
||||
Simpan
|
||||
</Button>
|
||||
</Stack>
|
||||
|
||||
@@ -37,6 +37,24 @@ function Page() {
|
||||
};
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
beasiswaDesa.create.form.namaLengkap?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.nis?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.kelas?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.jenisKelamin?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.alamatDomisili?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.tempatLahir?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.tanggalLahir?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.namaOrtu?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.nik?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.pekerjaanOrtu?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.penghasilan?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.noHp?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
const { data, page, totalPages, loading, load } = ungggulanDesa.findMany;
|
||||
|
||||
useShallowEffect(() => {
|
||||
@@ -238,7 +256,7 @@ function Page() {
|
||||
onChange={(val) => { beasiswaDesa.create.form.noHp = val.target.value }} />
|
||||
<Group justify="flex-end" mt="md">
|
||||
<Button variant="default" radius="xl" onClick={close}>Batal</Button>
|
||||
<Button radius="xl" bg={colors['blue-button']} onClick={handleSubmit}>Kirim</Button>
|
||||
<Button radius="xl" bg={colors['blue-button']} onClick={handleSubmit} disabled={!isFormValid()}>Kirim</Button>
|
||||
</Group>
|
||||
</Stack>
|
||||
</Paper>
|
||||
|
||||
@@ -46,6 +46,24 @@ export default function BeasiswaPage() {
|
||||
};
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
beasiswaDesa.create.form.namaLengkap?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.nis?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.kelas?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.jenisKelamin?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.alamatDomisili?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.tempatLahir?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.tanggalLahir?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.namaOrtu?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.nik?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.pekerjaanOrtu?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.penghasilan?.trim() !== '' &&
|
||||
beasiswaDesa.create.form.noHp?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
await beasiswaDesa.create.create();
|
||||
resetForm();
|
||||
@@ -391,6 +409,7 @@ export default function BeasiswaPage() {
|
||||
radius="xl"
|
||||
bg={colors['blue-button']}
|
||||
onClick={handleSubmit}
|
||||
disabled={!isFormValid()}
|
||||
style={{ fontSize: '0.9375rem', fontWeight: 600, lineHeight: 1.4 }}
|
||||
>
|
||||
Kirim
|
||||
|
||||
@@ -42,6 +42,24 @@ export default function ModalPeminjaman({
|
||||
|
||||
const BATAS_HARI_PINJAM = 4;
|
||||
|
||||
// Helper function to check if HTML content is empty
|
||||
const isHtmlEmpty = (html: string) => {
|
||||
// Remove all HTML tags and check if there's any text content
|
||||
const textContent = html.replace(/<[^>]*>/g, '').trim();
|
||||
return textContent === '';
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
snap.create.form.nama?.trim() !== '' &&
|
||||
snap.create.form.noTelp?.trim() !== '' &&
|
||||
snap.create.form.alamat?.trim() !== '' &&
|
||||
snap.create.form.tanggalPinjam?.trim() !== '' &&
|
||||
!isHtmlEmpty(snap.create.form.catatan)
|
||||
);
|
||||
};
|
||||
|
||||
// Reset form setiap modal dibuka
|
||||
useEffect(() => {
|
||||
if (opened && buku) {
|
||||
@@ -222,13 +240,13 @@ export default function ModalPeminjaman({
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
loading={snap.create.loading}
|
||||
disabled={
|
||||
!snap.create.form.nama || !snap.create.form.tanggalPinjam
|
||||
}
|
||||
disabled={!isFormValid() || snap.create.loading}
|
||||
rightSection={<IconArrowRight size={16} />}
|
||||
radius="xl"
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || snap.create.loading
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -13,7 +13,7 @@ import { NavbarSubMenu } from "./NavbarSubMenu"
|
||||
import { authStore } from "@/store/authStore";
|
||||
|
||||
// contoh state auth (dummy aja dulu, bisa diganti sesuai sistem auth kamu)
|
||||
const isAdmin = authStore.user?.roleId === 0 || authStore.user?.roleId === 1 || authStore.user?.roleId === 2 || authStore.user?.roleId === 3 || authStore.user?.roleId === 4;
|
||||
const isAdmin = authStore.user?.roleId === 0 || authStore.user?.roleId === 1 || authStore.user?.roleId === 2 || authStore.user?.roleId === 3 || authStore.user?.roleId === 4;
|
||||
|
||||
export function NavbarMainMenu({ listNavbar }: { listNavbar: MenuItem[] }) {
|
||||
const { item, isSearch } = useSnapshot(stateNav)
|
||||
@@ -46,11 +46,11 @@ export function NavbarMainMenu({ listNavbar }: { listNavbar: MenuItem[] }) {
|
||||
</Tooltip>
|
||||
|
||||
{listNavbar.map((item, k) => (
|
||||
<MenuItemCom
|
||||
key={k}
|
||||
item={item}
|
||||
isActive={item.href && pathname.startsWith(item.href) ||
|
||||
(item.children?.some(child => child.href && pathname.startsWith(child.href)))}
|
||||
<MenuItemCom
|
||||
key={k}
|
||||
item={item}
|
||||
isActive={item.href && pathname.startsWith(item.href) ||
|
||||
(item.children?.some(child => child.href && pathname.startsWith(child.href)))}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -73,7 +73,7 @@ export function NavbarMainMenu({ listNavbar }: { listNavbar: MenuItem[] }) {
|
||||
<Tooltip label="Kembali ke Admin" position="bottom" withArrow>
|
||||
<ActionIcon
|
||||
onClick={() => {
|
||||
next.push("/admin/landing-page/profil/program-inovasi")
|
||||
next.push("/admin/landing-page/profile/program-inovasi")
|
||||
}}
|
||||
color={colors["blue-button"]}
|
||||
radius="xl"
|
||||
|
||||
Reference in New Issue
Block a user