Fix: Keep file input in DOM during print area editing
Changed PhotoPrintAreaField to use CSS display:none instead of conditional rendering to hide the file input when the print area editor is open. This prevents the file input element from being removed from the DOM, which was causing the selected file to be lost before form submission. The issue occurred when: 1. User selected an image file 2. Preview loaded and print area editor opened (showPrintAreaEditor = true) 3. React conditionally removed the file input from the DOM 4. Form submission lost the file data because the input no longer existed Now the file input stays in the DOM (just hidden), so the file data persists through form submission. Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 4.5
parent
f2aed12fb6
commit
487afb7a91
@@ -74,6 +74,7 @@ export async function createProduct(formData: FormData) {
|
|||||||
const sizesInput = String(formData.get('sizes') ?? '');
|
const sizesInput = String(formData.get('sizes') ?? '');
|
||||||
const imageFile = formData.get('image') as File | null;
|
const imageFile = formData.get('image') as File | null;
|
||||||
const imageBackFile = formData.get('imageBack') as File | null;
|
const imageBackFile = formData.get('imageBack') as File | null;
|
||||||
|
|
||||||
const photoRecolorable = String(formData.get('photoRecolorable') ?? '') === '1';
|
const photoRecolorable = String(formData.get('photoRecolorable') ?? '') === '1';
|
||||||
const showOnPersonalised = String(formData.get('showOnPersonalised') ?? '') === '1';
|
const showOnPersonalised = String(formData.get('showOnPersonalised') ?? '') === '1';
|
||||||
const showAsPlain = String(formData.get('showAsPlain') ?? '') === '1';
|
const showAsPlain = String(formData.get('showAsPlain') ?? '') === '1';
|
||||||
|
|||||||
@@ -110,51 +110,49 @@ export default function PhotoPrintAreaField({
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{!currentImageUrl || !showPrintAreaEditor ? (
|
<div style={{ display: showPrintAreaEditor && currentImageUrl ? 'none' : 'block' }}>
|
||||||
<>
|
<input
|
||||||
<input
|
ref={fileInputRef}
|
||||||
ref={fileInputRef}
|
id={fieldName}
|
||||||
id={fieldName}
|
name={fieldName}
|
||||||
name={fieldName}
|
type="file"
|
||||||
type="file"
|
accept="image/*"
|
||||||
accept="image/*"
|
onChange={handleFileChange}
|
||||||
onChange={handleFileChange}
|
className="w-full border border-line bg-paper px-3 py-2 text-sm"
|
||||||
className="w-full border border-line bg-paper px-3 py-2 text-sm"
|
/>
|
||||||
/>
|
{variant === 'front' ? (
|
||||||
{variant === 'front' ? (
|
<p className="mt-1 text-xs text-muted">
|
||||||
<p className="mt-1 text-xs text-muted">
|
Uploading a real photo replaces the illustration everywhere this product is shown. One
|
||||||
Uploading a real photo replaces the illustration everywhere this product is shown. One
|
tradeoff: the color swatches below can no longer recolor a photo the way they recolor the
|
||||||
tradeoff: the color swatches below can no longer recolor a photo the way they recolor the
|
illustration — they'll still be saved with each order, but the picture itself stays
|
||||||
illustration — they'll still be saved with each order, but the picture itself stays
|
fixed. Leave this blank to keep using the illustration (which does recolor live).
|
||||||
fixed. Leave this blank to keep using the illustration (which does recolor live).
|
</p>
|
||||||
</p>
|
) : (
|
||||||
) : (
|
<p className="mt-1 text-xs text-muted">
|
||||||
<p className="mt-1 text-xs text-muted">
|
If set, customers get a Front/Back toggle and can add a separate design to the back —
|
||||||
If set, customers get a Front/Back toggle and can add a separate design to the back —
|
drag a print-area box below just like the front.
|
||||||
drag a print-area box below just like the front.
|
</p>
|
||||||
</p>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{currentImageUrl && !showPrintAreaEditor && (
|
{currentImageUrl && !showPrintAreaEditor && (
|
||||||
<div className="mt-3 flex gap-2">
|
<div className="mt-3 flex gap-2">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => setShowPrintAreaEditor(true)}
|
onClick={() => setShowPrintAreaEditor(true)}
|
||||||
className="text-sm text-clay hover:text-clay-dark font-medium"
|
className="text-sm text-clay hover:text-clay-dark font-medium"
|
||||||
>
|
>
|
||||||
Modify print area →
|
Modify print area →
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={handleClearFile}
|
onClick={handleClearFile}
|
||||||
className="text-sm text-splash-pink hover:text-splash-pink-dark font-medium"
|
className="text-sm text-splash-pink hover:text-splash-pink-dark font-medium"
|
||||||
>
|
>
|
||||||
Remove
|
Remove
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</div>
|
||||||
) : null}
|
|
||||||
|
|
||||||
{currentImageUrl && showPrintAreaEditor && (
|
{currentImageUrl && showPrintAreaEditor && (
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
|
|||||||
Reference in New Issue
Block a user