Allow medications with only a generic name (no commercial name required) (#311)
* Initial plan * feat: allow generic name only for medications (frontend changes) - Add getMedDisplayName() helper for consistent name display - Update validation to require either commercial or generic name - Update all display locations to use display name fallback - Add i18n keys for nameOrGenericRequired in en.json and de.json - Remove required attribute from commercial name field - Update FIELD_LIMITS.name.min from 1 to 0 Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com> * feat: allow generic name only for medications (backend changes) - Update Zod schema to allow empty name with cross-field refinement - Update reminder scheduler to use name || genericName for display - Update planner routes to match medications by display name - Update existing tests to match new validation behavior Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com> * fix: update placeholder text and fix FIELD_LIMITS test - Remove "(optional)" from generic name placeholder in en/de - Update types.test.ts to expect FIELD_LIMITS.name.min = 0 Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: DanielVolz <3275994+DanielVolz@users.noreply.github.com>
This commit is contained in:
@@ -115,9 +115,6 @@ export function useMedicationForm(): UseMedicationFormReturn {
|
||||
// Skip validation for takenBy array (individual items validated on add)
|
||||
if (field === "takenBy") return undefined;
|
||||
const strValue = typeof value === "string" ? value : "";
|
||||
if (field === "name" && (!strValue || strValue.trim().length === 0)) {
|
||||
return t("common.validation.required");
|
||||
}
|
||||
if ("max" in limits && strValue.length > limits.max) {
|
||||
return t("common.validation.maxLength", { max: limits.max, current: strValue.length });
|
||||
}
|
||||
@@ -150,8 +147,16 @@ export function useMedicationForm(): UseMedicationFormReturn {
|
||||
const error = validateField(f, form[f]);
|
||||
if (error) errors[f] = error;
|
||||
});
|
||||
// Cross-field validation: at least one of name or genericName is required
|
||||
const hasName = form.name && form.name.trim().length > 0;
|
||||
const hasGenericName = form.genericName && form.genericName.trim().length > 0;
|
||||
if (!hasName && !hasGenericName) {
|
||||
const msg = t("common.validation.nameOrGenericRequired");
|
||||
errors.name = errors.name || msg;
|
||||
errors.genericName = errors.genericName || msg;
|
||||
}
|
||||
setFieldErrors(errors);
|
||||
}, [form.name, form.genericName, form.notes, validateField, form]);
|
||||
}, [form.name, form.genericName, form.notes, validateField, form, t]);
|
||||
|
||||
const setBlisterValue = useCallback((idx: number, field: keyof FormBlister, value: string) => {
|
||||
setForm((prev) => {
|
||||
|
||||
Reference in New Issue
Block a user