feat(interests): desired-dimension form fields + size-desired column
Surfaces the recommender inputs added in Phase 2a (interests .desired_length_ft / desired_width_ft / desired_draft_ft) on the two interfaces reps actually use: - /interests list: new "Berth size desired" column rendered as a compact "60×18×6 ft" string. Cells with no dimensions show "-"; partial dimensions render "?" for the missing axis (recommender treats null as "no constraint"). - New/Edit Interest form: three optional length/width/draft inputs with explanatory subhead. Empty submissions collapse to undefined so the API doesn't see "" -> numeric coercion errors. - createInterestSchema gains the three optional desired-dim fields with a shared transform that coerces strings/numbers to a positive 2-decimal numeric string for the postgres `numeric` column. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,22 @@ import {
|
||||
|
||||
// ─── Create ──────────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Desired-dimension input. Strings/numbers are coerced to a positive
|
||||
* decimal (string-typed for postgres `numeric` column compatibility);
|
||||
* empty strings collapse to `undefined` so a blank form field doesn't
|
||||
* round-trip "" → numeric error on the API.
|
||||
*/
|
||||
const optionalDesiredDimSchema = z
|
||||
.union([z.string(), z.number()])
|
||||
.optional()
|
||||
.transform((v) => {
|
||||
if (v === undefined || v === null || v === '') return undefined;
|
||||
const n = typeof v === 'number' ? v : parseFloat(v);
|
||||
if (!Number.isFinite(n) || n <= 0) return undefined;
|
||||
return String(Math.round(n * 100) / 100);
|
||||
});
|
||||
|
||||
export const createInterestSchema = z.object({
|
||||
clientId: z.string().min(1),
|
||||
yachtId: z.string().optional(),
|
||||
@@ -21,6 +37,9 @@ export const createInterestSchema = z.object({
|
||||
tagIds: z.array(z.string()).optional().default([]),
|
||||
reminderEnabled: z.boolean().optional().default(false),
|
||||
reminderDays: z.number().int().min(1).optional(),
|
||||
desiredLengthFt: optionalDesiredDimSchema,
|
||||
desiredWidthFt: optionalDesiredDimSchema,
|
||||
desiredDraftFt: optionalDesiredDimSchema,
|
||||
});
|
||||
|
||||
// ─── Update ──────────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user