feat: implement form validation for empty fields across multiple admin pages
- Added validation to disable submit buttons when required fields are empty - Implemented consistent validation patterns across various admin pages - Applied validation to create and edit forms for berita, gallery, layanan, penghargaan, pengumuman, potensi, profil-desa, and ppid sections - Used helper functions to check for empty HTML content in editor fields - Ensured submit buttons are disabled until all required fields are filled Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
@@ -28,6 +28,15 @@ function EditDaftarInformasiPublik() {
|
||||
tanggal: '',
|
||||
});
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
formData.jenisInformasi?.trim() !== '' &&
|
||||
formData.deskripsi?.trim() !== '' &&
|
||||
formData.tanggal?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
const formatDateForInput = (dateString: string) => {
|
||||
if (!dateString) return '';
|
||||
const date = new Date(dateString);
|
||||
@@ -128,10 +137,13 @@ function EditDaftarInformasiPublik() {
|
||||
<Group justify="right" mt="md">
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
disabled={!isFormValid()}
|
||||
radius="md"
|
||||
size="md"
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid()
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -11,6 +11,15 @@ export default function CreateDaftarInformasi() {
|
||||
const daftarInformasi = useProxy(daftarInformasiPublik);
|
||||
const router = useRouter();
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
daftarInformasi.create.form.jenisInformasi?.trim() !== '' &&
|
||||
daftarInformasi.create.form.deskripsi?.trim() !== '' &&
|
||||
daftarInformasi.create.form.tanggal?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
daftarInformasi.create.form = {
|
||||
jenisInformasi: "",
|
||||
@@ -106,10 +115,13 @@ export default function CreateDaftarInformasi() {
|
||||
<Button
|
||||
onClick={handleSubmit}
|
||||
loading={daftarInformasi.create.loading}
|
||||
disabled={!isFormValid() || daftarInformasi.create.loading}
|
||||
radius="md"
|
||||
size="md"
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || daftarInformasi.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)',
|
||||
}}
|
||||
|
||||
@@ -27,6 +27,21 @@ function EditDasarHukum() {
|
||||
content: '',
|
||||
});
|
||||
|
||||
// Helper function to check if rich text content is empty
|
||||
const isRichTextEmpty = (content: string) => {
|
||||
// Remove HTML tags and check if the resulting text is empty
|
||||
const plainText = content.replace(/<[^>]*>/g, '').trim();
|
||||
return plainText === '' || content.trim() === '<p></p>' || content.trim() === '<p><br></p>';
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
!isRichTextEmpty(formData.judul) &&
|
||||
!isRichTextEmpty(formData.content)
|
||||
);
|
||||
};
|
||||
|
||||
// Load data awal sekali
|
||||
useShallowEffect(() => {
|
||||
if (!dasarHukumState.findById.data) {
|
||||
@@ -137,8 +152,11 @@ function EditDasarHukum() {
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={!isFormValid() || isSubmitting}
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || isSubmitting
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -57,6 +57,17 @@ function EditResponden() {
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
formData.name?.trim() !== '' &&
|
||||
formData.tanggal?.trim() !== '' &&
|
||||
formData.jenisKelaminId?.trim() !== '' &&
|
||||
formData.ratingId?.trim() !== '' &&
|
||||
formData.kelompokUmurId?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
// 🔹 Load data pilihan select
|
||||
const loadSelectOptions = useCallback(() => {
|
||||
indeksKepuasanState.jenisKelaminResponden.findMany.load();
|
||||
@@ -231,8 +242,11 @@ function EditResponden() {
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={!isFormValid() || isSubmitting}
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || isSubmitting
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -16,6 +16,17 @@ function RespondenCreate() {
|
||||
const [donutData, setDonutData] = useState<any[]>([]);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
stategrafikBerdasarkanResponden.create.form.name?.trim() !== '' &&
|
||||
stategrafikBerdasarkanResponden.create.form.tanggal?.trim() !== '' &&
|
||||
stategrafikBerdasarkanResponden.create.form.jenisKelaminId?.trim() !== '' &&
|
||||
stategrafikBerdasarkanResponden.create.form.ratingId?.trim() !== '' &&
|
||||
stategrafikBerdasarkanResponden.create.form.kelompokUmurId?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
stategrafikBerdasarkanResponden.create.form = {
|
||||
...stategrafikBerdasarkanResponden.create.form,
|
||||
@@ -151,8 +162,11 @@ function RespondenCreate() {
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={!isFormValid() || isSubmitting}
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || isSubmitting
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -56,6 +56,12 @@ export default function EditPegawaiPPID() {
|
||||
const [previewImage, setPreviewImage] = useState<string | null>(null);
|
||||
const [file, setFile] = useState<File | null>(null);
|
||||
|
||||
// Helper function to validate email format
|
||||
const isValidEmail = (email: string) => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
// Format date for <input type="date">
|
||||
const formatDateForInput = (dateString: string) => {
|
||||
if (!dateString) return '';
|
||||
@@ -63,6 +69,20 @@ export default function EditPegawaiPPID() {
|
||||
return date.toISOString().split('T')[0];
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
formData.namaLengkap?.trim() !== '' &&
|
||||
formData.gelarAkademik?.trim() !== '' &&
|
||||
formData.posisiId !== '' &&
|
||||
formData.tanggalMasuk !== '' &&
|
||||
formData.email !== '' &&
|
||||
isValidEmail(formData.email) &&
|
||||
formData.telepon !== '' &&
|
||||
formData.alamat !== ''
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const loadPegawai = async () => {
|
||||
try {
|
||||
@@ -347,8 +367,11 @@ export default function EditPegawaiPPID() {
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={!isFormValid() || isSubmitting}
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || isSubmitting
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -24,6 +24,27 @@ function CreatePegawaiPPID() {
|
||||
resetForm();
|
||||
}, []);
|
||||
|
||||
// Helper function to validate email format
|
||||
const isValidEmail = (email: string) => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
stateOrganisasi.create.form.namaLengkap?.trim() !== '' &&
|
||||
stateOrganisasi.create.form.gelarAkademik?.trim() !== '' &&
|
||||
stateOrganisasi.create.form.posisiId !== '' &&
|
||||
stateOrganisasi.create.form.tanggalMasuk !== '' &&
|
||||
stateOrganisasi.create.form.email !== '' &&
|
||||
isValidEmail(stateOrganisasi.create.form.email) &&
|
||||
stateOrganisasi.create.form.telepon !== '' &&
|
||||
stateOrganisasi.create.form.alamat !== '' &&
|
||||
file !== null
|
||||
);
|
||||
};
|
||||
|
||||
const resetForm = () => {
|
||||
stateOrganisasi.create.form = {
|
||||
namaLengkap: "",
|
||||
@@ -78,7 +99,7 @@ function CreatePegawaiPPID() {
|
||||
};
|
||||
|
||||
return (
|
||||
<Box px={{ base: 0, md: 'lg' }} py="xs">
|
||||
<Box px={{ base: 0, md: 'lg' }} py="xs">
|
||||
<Group mb="md">
|
||||
<Button variant="subtle" onClick={() => router.back()} p="xs" radius="md">
|
||||
<IconArrowBack color={colors['blue-button']} size={24} />
|
||||
@@ -99,15 +120,16 @@ function CreatePegawaiPPID() {
|
||||
<Stack gap="md">
|
||||
<Box>
|
||||
<TextInput
|
||||
required
|
||||
label="Nama Lengkap"
|
||||
placeholder="Masukkan nama lengkap"
|
||||
value={stateOrganisasi.create.form.namaLengkap}
|
||||
onChange={(e) => (stateOrganisasi.create.form.namaLengkap = e.currentTarget.value)}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
<Box>
|
||||
<TextInput
|
||||
required
|
||||
label="Gelar Akademik"
|
||||
placeholder="Contoh: S.Kom"
|
||||
value={stateOrganisasi.create.form.gelarAkademik}
|
||||
@@ -191,6 +213,7 @@ function CreatePegawaiPPID() {
|
||||
</Box>
|
||||
<Box>
|
||||
<TextInput
|
||||
required
|
||||
label="Tanggal Masuk"
|
||||
type="date"
|
||||
placeholder="Contoh: 2022-01-01"
|
||||
@@ -201,6 +224,7 @@ function CreatePegawaiPPID() {
|
||||
|
||||
<Box>
|
||||
<TextInput
|
||||
required
|
||||
label="Email"
|
||||
type="email"
|
||||
placeholder="Contoh: email@example.com"
|
||||
@@ -211,6 +235,7 @@ function CreatePegawaiPPID() {
|
||||
|
||||
<Box>
|
||||
<TextInput
|
||||
required
|
||||
type='number'
|
||||
label="Nomor Telepon"
|
||||
placeholder="Contoh: 08123456789"
|
||||
@@ -221,6 +246,7 @@ function CreatePegawaiPPID() {
|
||||
|
||||
<Box>
|
||||
<TextInput
|
||||
required
|
||||
label="Alamat"
|
||||
placeholder="Contoh: Jl. Contoh No. 1"
|
||||
value={stateOrganisasi.create.form.alamat}
|
||||
@@ -229,35 +255,8 @@ function CreatePegawaiPPID() {
|
||||
</Box>
|
||||
|
||||
<Box>
|
||||
<Text fw="bold" fz="sm" mb={6}>
|
||||
Posisi
|
||||
</Text>
|
||||
<Select
|
||||
label="Kategori"
|
||||
placeholder="Pilih kategori"
|
||||
data={stateStrukturPPID.posisiOrganisasi.findManyAll.data?.map((item) => ({
|
||||
label: item.nama,
|
||||
value: item.id,
|
||||
})) || []}
|
||||
value={stateOrganisasi.create.form.posisiId || null}
|
||||
onChange={(val: string | null) => {
|
||||
if (val) {
|
||||
const selected = stateStrukturPPID.posisiOrganisasi.findManyAll.data?.find(
|
||||
(item) => item.id === val
|
||||
);
|
||||
if (selected) {
|
||||
stateOrganisasi.create.form.posisiId = selected.id;
|
||||
}
|
||||
} else {
|
||||
stateOrganisasi.create.form.posisiId = '';
|
||||
}
|
||||
}}
|
||||
searchable
|
||||
clearable
|
||||
nothingFoundMessage="Tidak ditemukan"
|
||||
required
|
||||
/>
|
||||
{/* <Select
|
||||
label="Posisi"
|
||||
placeholder="Pilih posisi"
|
||||
data={stateStrukturPPID.posisiOrganisasi.findManyAll.data?.map(p => ({
|
||||
value: p.id,
|
||||
@@ -269,10 +268,10 @@ function CreatePegawaiPPID() {
|
||||
}}
|
||||
searchable
|
||||
clearable
|
||||
/> */}
|
||||
required
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
{/* ======= Tombol Aksi ======= */}
|
||||
<Group justify="right">
|
||||
{/* Tombol Batal */}
|
||||
@@ -291,8 +290,11 @@ function CreatePegawaiPPID() {
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={!isFormValid() || isSubmitting}
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || isSubmitting
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -26,6 +26,15 @@ function EditPosisiOrganisasiPPID() {
|
||||
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
formData.nama?.trim() !== '' &&
|
||||
formData.hierarki?.toString().trim() !== '' &&
|
||||
formData.deskripsi?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
const [originalData, setOriginalData] = useState({
|
||||
nama: "",
|
||||
deskripsi: "",
|
||||
@@ -174,8 +183,11 @@ function EditPosisiOrganisasiPPID() {
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={!isFormValid() || isSubmitting}
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || isSubmitting
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -15,6 +15,15 @@ function CreatePosisiOrganisasiPPID() {
|
||||
const stateOrganisasi = useProxy(stateStrukturPPID.posisiOrganisasi);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
stateOrganisasi.create.form.nama?.trim() !== '' &&
|
||||
stateOrganisasi.create.form.hierarki?.toString().trim() !== '' &&
|
||||
stateOrganisasi.create.form.deskripsi?.trim() !== ''
|
||||
);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
stateOrganisasi.findMany.load();
|
||||
}, []);
|
||||
@@ -115,8 +124,11 @@ function CreatePosisiOrganisasiPPID() {
|
||||
onClick={handleSubmit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={!isFormValid() || isSubmitting}
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || isSubmitting
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
@@ -20,6 +20,21 @@ function VisiMisiPPIDEdit() {
|
||||
const [originalData, setOriginalData] = useState({ visi: '', misi: '' });
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
// Helper function to check if rich text content is empty
|
||||
const isRichTextEmpty = (content: string) => {
|
||||
// Remove HTML tags and check if the resulting text is empty
|
||||
const plainText = content.replace(/<[^>]*>/g, '').trim();
|
||||
return plainText === '' || content.trim() === '<p></p>' || content.trim() === '<p><br></p>';
|
||||
};
|
||||
|
||||
// Check if form is valid
|
||||
const isFormValid = () => {
|
||||
return (
|
||||
!isRichTextEmpty(formData.visi) &&
|
||||
!isRichTextEmpty(formData.misi)
|
||||
);
|
||||
};
|
||||
|
||||
// Initialize global data ke state lokal saat pertama load
|
||||
useShallowEffect(() => {
|
||||
if (!visiMisi.findById.data) {
|
||||
@@ -116,8 +131,11 @@ function VisiMisiPPIDEdit() {
|
||||
onClick={submit}
|
||||
radius="md"
|
||||
size="md"
|
||||
disabled={!isFormValid() || isSubmitting}
|
||||
style={{
|
||||
background: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
background: !isFormValid() || isSubmitting
|
||||
? `linear-gradient(135deg, #cccccc, #eeeeee)`
|
||||
: `linear-gradient(135deg, ${colors['blue-button']}, #4facfe)`,
|
||||
color: '#fff',
|
||||
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user