submit responsiveness

This commit is contained in:
makearmy 2025-10-05 08:24:51 -04:00
parent 8654653589
commit d04613ffdc

View file

@ -93,7 +93,7 @@ type EditInitialValues = {
laser_soft?: any;
repeat_all?: number | null;
// may be present in existing data
// may exist on CO2 targets
lens_conf?: number | null;
lens_apt?: number | null;
lens_exp?: number | null;
@ -145,7 +145,7 @@ function normalizeForReset(iv: EditInitialValues) {
}
// ─────────────────────────────────────────────────────────────
// Directus field whitelists + mapper (prevents drift)
/** Directus field whitelists + mapper (prevents drift) */
// ─────────────────────────────────────────────────────────────
const DIRECTUS_FIELDS: Record<Target, readonly string[]> = {
settings_co2gal: [
@ -610,8 +610,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
focus: "",
laser_soft: "",
repeat_all: "", // on all targets
// extras
uploader: "",
// lens config (may be required on CO2 targets)
lens_conf: "",
lens_apt: "",
lens_exp: "",
@ -644,8 +643,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
focus: iv.focus ?? "",
laser_soft: iv.laser_soft ?? "",
repeat_all: iv.repeat_all ?? "",
uploader: (me?.username ?? me?.email ?? "") || "",
lens_conf: (iv as any).lens_conf ?? "",
lens_conf: (iv as any).lens_conf ?? "",
lens_apt: (iv as any).lens_apt ?? "",
lens_exp: (iv as any).lens_exp ?? "",
fill_settings: iv.fill_settings ?? [],
@ -654,7 +652,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isEdit, edit?.initialValues, reset, me?.username, me?.email]);
}, [isEdit, edit?.initialValues, reset]);
// After reset, force RHF values once (covers early case)
useEffect(() => {
@ -718,10 +716,13 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
async function onSubmit(values: any) {
setSubmitErr(null);
// In edit mode, allow keeping the existing photo (no new file) if one exists.
const hasExistingPhotoId =
!!(isEdit && typeof edit!.initialValues?.photo === "string" && edit!.initialValues.photo);
if (!photoFile && !hasExistingPhotoId && !isEdit) {
// Create vs Edit: photo is required unless an existing photo id is present or a new file is picked
const currentPhotoId =
isEdit && typeof edit!.initialValues?.photo === "string" && edit!.initialValues.photo
? (edit!.initialValues.photo as string)
: null;
const requirePhoto = !currentPhotoId && !photoFile;
if (requirePhoto) {
(document.querySelector('input[type="file"][data-role="photo"]') as HTMLInputElement | null)?.focus();
return;
}
@ -742,8 +743,10 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
laser_soft: values.laser_soft || null, // all targets
repeat_all: num(values.repeat_all), // all targets
// new/extra fields
uploader: (me?.username ?? me?.email ?? "") || "",
// uploader: set automatically from owner; include only if present on client
...(me?.username || me?.email ? { uploader: me?.username ?? me?.email! } : {}),
// lens config (required for CO2 targets per your list)
lens_conf: num(values.lens_conf),
lens_apt: num(values.lens_apt),
lens_exp: num(values.lens_exp),
@ -821,7 +824,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
try {
const form = new FormData();
form.set("payload", JSON.stringify(flatPayload)); // << prod-compatible key
form.set("payload", JSON.stringify(flatPayload)); // prod-compatible key
if (photoFile) form.set("photo", photoFile, photoFile.name || "photo");
if (screenFile) form.set("screen", screenFile, screenFile.name || "screen");
@ -872,9 +875,9 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
// Convenience strings for “Current:” (edit mode)
const currentPhotoId =
isEdit && typeof edit.initialValues?.photo === "string" ? (edit.initialValues.photo as string) : null;
isEdit && typeof edit?.initialValues?.photo === "string" ? (edit!.initialValues.photo as string) : null;
const currentScreenId =
isEdit && typeof edit.initialValues?.screen === "string" ? (edit.initialValues.screen as string) : null;
isEdit && typeof edit?.initialValues?.screen === "string" ? (edit!.initialValues.screen as string) : null;
return (
<div className="max-w-3xl mx-auto space-y-4">
@ -922,9 +925,6 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
<div className="border border-red-500 text-red-600 bg-red-50 rounded p-2 text-sm">{submitErr}</div>
) : null}
{/* hidden uploader so it's always sent */}
<input type="hidden" {...register("uploader", { required: true })} value={me?.username ?? me?.email ?? ""} />
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
{/* Title */}
<div className="grid md:grid-cols-2 gap-3">
@ -940,7 +940,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
<div className="grid md:grid-cols-2 gap-4">
<div>
<label className="block text-sm mb-1">
Result Photo {isEdit ? null : <span className="text-red-600">*</span>}
Result Photo {!currentPhotoId ? <span className="text-red-600">*</span> : null}
</label>
{currentPhotoId && (
@ -953,7 +953,8 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
type="file"
accept="image/*"
data-role="photo"
required={!isEdit && !currentPhotoId}
// Required when creating OR when editing without an existing photo id (until a new file is chosen)
required={!currentPhotoId && !photoFile}
onChange={(e) => onPick(e.target.files?.[0] ?? null, setPhotoFile, setPhotoPreview)}
/>
<p className="text-xs text-muted-foreground mt-1">
@ -1069,7 +1070,7 @@ export default function SettingsSubmit(props: CreateProps | EditProps) {
</p>
</div>
{/* Lens Configuration (target-specific requireds) */}
{/* Lens Configuration (required on CO2 targets per your list) */}
{(target === "settings_co2gan" || target === "settings_co2gal") && (
<fieldset className="border rounded p-3 space-y-2">
<legend className="font-semibold">Lens Configuration</legend>