fix: enforce derived validation onblur in patch tests modal to block invalid submissions
This commit is contained in:
@@ -45,15 +45,35 @@ import { Button } from '$lib/components/ui/button';
|
||||
expiry: ''
|
||||
});
|
||||
|
||||
function validateForm(): boolean {
|
||||
formErrors = {
|
||||
name: !formData.name.trim() ? 'Name is required' : '',
|
||||
notice_duration: (formData.notice_duration_hours < 0 || isNaN(formData.notice_duration_hours)) ? 'Must be a positive number' : '',
|
||||
expiry: (formData.expiry_months < 1 || isNaN(formData.expiry_months)) ? 'Must be at least 1 month' : ''
|
||||
};
|
||||
return Object.values(formErrors).every(err => err === '');
|
||||
function validateNameField() {
|
||||
formErrors.name = !formData.name.trim() ? 'Name is required' : '';
|
||||
}
|
||||
|
||||
function validateNoticeDurationField() {
|
||||
formErrors.notice_duration = (formData.notice_duration_hours < 0 || isNaN(formData.notice_duration_hours)) ? 'Must be a positive number' : '';
|
||||
}
|
||||
|
||||
function validateExpiryField() {
|
||||
formErrors.expiry = (formData.expiry_months < 1 || isNaN(formData.expiry_months)) ? 'Must be at least 1 month' : '';
|
||||
}
|
||||
|
||||
function validateAllFields() {
|
||||
validateNameField();
|
||||
validateNoticeDurationField();
|
||||
validateExpiryField();
|
||||
}
|
||||
|
||||
let isFormValid = $derived(
|
||||
formData.name.trim() !== '' &&
|
||||
!formErrors.name &&
|
||||
!formErrors.notice_duration &&
|
||||
!formErrors.expiry &&
|
||||
formData.notice_duration_hours >= 0 &&
|
||||
!isNaN(formData.notice_duration_hours) &&
|
||||
formData.expiry_months >= 1 &&
|
||||
!isNaN(formData.expiry_months)
|
||||
);
|
||||
|
||||
async function fetchData() {
|
||||
loading = true;
|
||||
try {
|
||||
@@ -94,6 +114,11 @@ import { Button } from '$lib/components/ui/button';
|
||||
expiry_months: 6,
|
||||
service_ids: []
|
||||
};
|
||||
formErrors = {
|
||||
name: '',
|
||||
notice_duration: '',
|
||||
expiry: ''
|
||||
};
|
||||
isEditing = false;
|
||||
}
|
||||
|
||||
@@ -111,6 +136,11 @@ import { Button } from '$lib/components/ui/button';
|
||||
expiry_months: pt.expiry_months,
|
||||
service_ids: pt.service_ids || []
|
||||
};
|
||||
formErrors = {
|
||||
name: '',
|
||||
notice_duration: '',
|
||||
expiry: ''
|
||||
};
|
||||
isEditing = true;
|
||||
showModal = true;
|
||||
}
|
||||
@@ -124,8 +154,9 @@ import { Button } from '$lib/components/ui/button';
|
||||
}
|
||||
|
||||
async function savePatchTest() {
|
||||
if (!formData.name.trim()) {
|
||||
toast.error('Patch test name is required');
|
||||
validateAllFields();
|
||||
if (!isFormValid) {
|
||||
toast.error('Please fix validation errors before submitting');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -346,6 +377,7 @@ import { Button } from '$lib/components/ui/button';
|
||||
type="text"
|
||||
placeholder="e.g. Standard Glue Patch Test"
|
||||
bind:value={formData.name}
|
||||
onblur={validateNameField}
|
||||
class="w-full {formErrors.name ? 'border-red-500' : ''}"
|
||||
/>
|
||||
{#if formErrors.name}
|
||||
@@ -373,6 +405,7 @@ import { Button } from '$lib/components/ui/button';
|
||||
inputmode="numeric"
|
||||
min="0"
|
||||
bind:value={formData.notice_duration_hours}
|
||||
onblur={validateNoticeDurationField}
|
||||
class="w-full {formErrors.notice_duration ? 'border-red-500' : ''}"
|
||||
/>
|
||||
{#if formErrors.notice_duration}
|
||||
@@ -389,6 +422,7 @@ import { Button } from '$lib/components/ui/button';
|
||||
inputmode="numeric"
|
||||
min="1"
|
||||
bind:value={formData.expiry_months}
|
||||
onblur={validateExpiryField}
|
||||
class="w-full {formErrors.expiry ? 'border-red-500' : ''}"
|
||||
/>
|
||||
{#if formErrors.expiry}
|
||||
@@ -424,10 +458,8 @@ import { Button } from '$lib/components/ui/button';
|
||||
Cancel
|
||||
</Button>
|
||||
<Button
|
||||
onclick={() => {
|
||||
if (validateForm()) savePatchTest();
|
||||
}}
|
||||
disabled={isSubmitting}
|
||||
onclick={savePatchTest}
|
||||
disabled={isSubmitting || !isFormValid}
|
||||
>
|
||||
{isSubmitting ? 'Saving...' : 'Save'}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user