fix: enforce derived validation onblur in patch tests modal to block invalid submissions

This commit is contained in:
2026-05-29 18:24:03 +01:00
parent 20bd3e3310
commit 6625a3a699
@@ -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>