Fix: Handle image removal in product editor
- Add support for removeImage/removeImageBack flags in updateProduct action - When Remove button is clicked, client sets isRemoved=true to hide UI - Server action checks removeImage/removeImageBack form fields and sets imageUrl/imageUrlBack to null - Also reset printArea to default when image is removed - Tested: Remove button now successfully clears images and persists changes to database
This commit is contained in:
@@ -268,9 +268,12 @@ export async function updateProduct(formData: FormData) {
|
||||
weightGrams,
|
||||
};
|
||||
|
||||
// Only touch the front photo/print area if a new photo was actually uploaded —
|
||||
// otherwise leave whatever's already there alone.
|
||||
if (imageFile && imageFile.size > 0) {
|
||||
// Handle front photo: new upload, removal, or keep existing
|
||||
const removeImage = String(formData.get('removeImage') ?? '') === '1';
|
||||
if (removeImage) {
|
||||
data.imageUrl = null;
|
||||
data.printArea = JSON.stringify(DEFAULT_PRINT_AREAS[mockup] ?? DEFAULT_PRINT_AREAS.tshirt);
|
||||
} else if (imageFile && imageFile.size > 0) {
|
||||
data.imageUrl = await fileToDataUrl(imageFile);
|
||||
|
||||
const hasCustomPrintArea = String(formData.get('hasCustomPrintArea') ?? '') === '1';
|
||||
@@ -286,7 +289,12 @@ export async function updateProduct(formData: FormData) {
|
||||
);
|
||||
}
|
||||
|
||||
if (imageBackFile && imageBackFile.size > 0) {
|
||||
// Handle back photo: new upload, removal, or keep existing
|
||||
const removeImageBack = String(formData.get('removeImageBack') ?? '') === '1';
|
||||
if (removeImageBack) {
|
||||
data.imageUrlBack = null;
|
||||
data.printAreaBack = null;
|
||||
} else if (imageBackFile && imageBackFile.size > 0) {
|
||||
data.imageUrlBack = await fileToDataUrl(imageBackFile);
|
||||
|
||||
const hasCustomPrintAreaBack = String(formData.get('hasCustomPrintAreaBack') ?? '') === '1';
|
||||
|
||||
@@ -17,6 +17,7 @@ export default function PhotoPrintAreaField({
|
||||
const [previewUrl, setPreviewUrl] = useState<string | null>(null);
|
||||
const [box, setBox] = useState<Box>(DEFAULT_BOX);
|
||||
const [showPrintAreaEditor, setShowPrintAreaEditor] = useState(false);
|
||||
const [isRemoved, setIsRemoved] = useState(false);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const dragState = useRef<{
|
||||
@@ -28,22 +29,26 @@ export default function PhotoPrintAreaField({
|
||||
|
||||
const fieldName = variant === 'front' ? 'image' : 'imageBack';
|
||||
const suffix = variant === 'front' ? '' : 'Back';
|
||||
const removeFieldName = variant === 'front' ? 'removeImage' : 'removeImageBack';
|
||||
|
||||
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) {
|
||||
setPreviewUrl(null);
|
||||
setShowPrintAreaEditor(false);
|
||||
setIsRemoved(false);
|
||||
return;
|
||||
}
|
||||
setPreviewUrl(URL.createObjectURL(file));
|
||||
setBox(DEFAULT_BOX);
|
||||
setShowPrintAreaEditor(true);
|
||||
setIsRemoved(false);
|
||||
};
|
||||
|
||||
const handleClearFile = () => {
|
||||
setPreviewUrl(null);
|
||||
setShowPrintAreaEditor(false);
|
||||
setIsRemoved(true);
|
||||
if (fileInputRef.current) {
|
||||
fileInputRef.current.value = '';
|
||||
}
|
||||
@@ -53,7 +58,7 @@ export default function PhotoPrintAreaField({
|
||||
setShowPrintAreaEditor(false);
|
||||
};
|
||||
|
||||
const currentImageUrl = previewUrl || existingImageUrl;
|
||||
const currentImageUrl = previewUrl || (isRemoved ? null : existingImageUrl);
|
||||
|
||||
const onBoxMouseDown = (e: React.MouseEvent) => {
|
||||
e.preventDefault();
|
||||
@@ -192,6 +197,7 @@ export default function PhotoPrintAreaField({
|
||||
</div>
|
||||
)}
|
||||
|
||||
<input type="hidden" name={removeFieldName} value={isRemoved ? '1' : ''} />
|
||||
<input type="hidden" name={`hasCustomPrintArea${suffix}`} value={currentImageUrl ? '1' : ''} />
|
||||
<input type="hidden" name={`printX${suffix}`} value={box.xPct / 100} />
|
||||
<input type="hidden" name={`printY${suffix}`} value={box.yPct / 100} />
|
||||
|
||||
Reference in New Issue
Block a user