import React, { useState, useEffect, useCallback } from 'react';
import { Upload, Modal } from 'antd';
import { uploadImage } from '../../Features/upload/upload';
import { useDispatch } from 'react-redux';
import ImageCropper from '../../Components/Forms/Cropper2.jsx';
import ShapeCropper from './ShapeCropper.jsx';
import { PiCropBold } from 'react-icons/pi';
import { FiPenTool } from 'react-icons/fi';
import { DefaultModal } from '../../Components/Modal/DefaultModal.jsx';
import '../../Styles/Product/Product.scss';
import { Messages } from '../Notifications/Messages.jsx';
import { isMobile } from 'react-device-detect';
import Camera from '../MobileComponent/Camera.jsx';
import useHasCamera from '../../utils/useHasCamera.js';
const allowedTypes = [
'image/jpeg',
'image/png',
'image/webp',
'image/svg+xml',
'image/gif',
'image/avif',
];
const CropUpload = ({
updateImageUrl,
ImageLink,
onlineImage,
isProductList = {},
handleClose = () => { }
}) => {
const dispatch = useDispatch();
const hasCamera = useHasCamera();
const [messageType, setMessageType] = useState(null);
const [messageData, setMessageData] = useState(null);
const [fileList, setFileList] = useState([]);
const [previewVisible, setPreviewVisible] = useState(false);
const [previewImage, setPreviewImage] = useState('');
const [editImageOpen, setEditImageOpen] = useState(false);
const [croppedImage, setCroppedImage] = useState(null);
const [shapedImage, setShapedImage] = useState(false);
const [cropImage, setCropImage] = useState(false);
const [shapedData, setShapedData] = useState(null);
const [resizedImageUrl, setResizedImageUrl] = useState('');
useEffect(() => {
if (ImageLink != '' && ImageLink != null) {
updateImageUrl(ImageLink);
setFileList([
{
uid: `${Date.now()}-${Math.random()}`, // Ensures uniqueness
name: `image${Date.now()}-${Math.random()}.png`,
status: 'done',
url: ImageLink,
},
]);
} else {
updateImageUrl();
// setFileList([]);
// handleRemove()
}
}, [ImageLink]);
useEffect(() => {
if (ImageLink != '' && ImageLink != null) {
if (Object.keys(isProductList)?.length > 0) {
const { isProductListPutapi } = isProductList;
if (isProductListPutapi) {
setFileList([
{
uid: `${Date.now()}-${Math.random()}`, // Ensures uniqueness
name: `image${Date.now()}-${Math.random()}.png`,
status: 'done',
url: ImageLink,
},
]);
} else {
setFileList([]);
}
} else {
// setFileList([]);
}
} else {
// setFileList([]);
}
}, []);
useEffect(() => {
if (onlineImage !== '' && onlineImage != null && onlineImage != undefined) {
setEditImageOpen(true);
handleResizeImage(onlineImage);
} else {
setShapedImage(false);
setCropImage(false);
}
}, [onlineImage]);
useEffect(() => {
if (fileList.length > 0) {
const imageUrl = fileList?.[0]?.url;
if (imageUrl !== '' && imageUrl !== null && imageUrl !== undefined) {
handleResizeImage(imageUrl);
} else {
setShapedImage(false);
setCropImage(false);
}
}
}, [fileList]);
const handleResizeImage = async (imageUrl) => {
try {
const resizedImageUrl = await resizeImage(imageUrl, 300, 150);
setResizedImageUrl(resizedImageUrl);
} catch (error) {
console.error('Error resizing image:', error);
}
};
const SetDefault = async () => {
setEditImageOpen(false);
setCroppedImage(null);
setShapedData(null);
setShapedImage(false);
setCropImage(false);
updateImageUrl(
onlineImage !== '' && onlineImage != null
? onlineImage
: fileList?.[0]?.['url'] != '' && fileList?.[0]?.['url'] != null
? fileList?.[0]?.['url']
: ''
);
if (Object.keys(isProductList)?.length > 0) {
const { isProductListPutapi, record, imagePutFunction } = isProductList;
if (isProductListPutapi) {
imagePutFunction(
onlineImage !== '' && onlineImage != null
? onlineImage
: fileList?.[0]?.['url'] != '' && fileList?.[0]?.['url'] != null
? fileList?.[0]?.['url']
: '',
record
);
handleClose();
setMessageData("Image updated successfully");
setMessageType("success");
}
}
};
const handleEditImageCancle = () => {
setCroppedImage(null);
setShapedData(null);
setEditImageOpen(false);
updateImageUrl('');
setFileList([]);
setShapedImage(false);
setCropImage(false);
};
const handleSubmit = async () => {
const base64 = croppedImage;
const byteCharacters = atob(base64?.split(',')[1]);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: 'image/png' });
const file = new File([blob], 'cropped_image.png', { type: 'image/png' });
try {
await handleUpload({
file,
onSuccess: () => console.log('Upload successful'),
onError: () => console.error('Upload failed'),
});
setEditImageOpen(false);
await setCroppedImage(null);
setShapedImage(false);
setCropImage(false);
handleClose();
setMessageData("Image updated successfully");
setMessageType("success");
} catch (error) {
console.error('Error in handleUpload:', error);
}
};
const handleShapeSubmit = async () => {
const base64 = shapedData[0];
const byteCharacters = atob(base64?.split(',')[1]);
const byteNumbers = new Array(byteCharacters.length);
for (let i = 0; i < byteCharacters.length; i++) {
byteNumbers[i] = byteCharacters.charCodeAt(i);
}
const byteArray = new Uint8Array(byteNumbers);
const blob = new Blob([byteArray], { type: 'image/png' });
const file = new File([blob], 'cropped_image.png', { type: 'image/png' });
try {
await handleUpload({
file,
onSuccess: () => console.log('Upload successful'),
onError: () => console.error('Upload failed'),
});
setEditImageOpen(false);
await setShapedData(null);
setShapedImage(false);
setCropImage(false);
handleClose();
setMessageData("Image updated successfully");
setMessageType("success");
} catch (error) {
console.error('Error in handleUpload:', error);
}
};
const handleCancel = () => setPreviewVisible(false);
const onChange = async ({ fileList: newFileList }) => {
setFileList(newFileList);
if (Object.keys(isProductList)?.length > 0) {
const { isProductListPutapi } = isProductList;
if (isProductListPutapi && newFileList?.[0]?.originFileObj) {
const file = newFileList[0].originFileObj;
try {
const res = await dispatch(uploadImage(file)).unwrap();
if (res?.data?.status) {
updateImageUrl(res?.data?.image);
if (res?.data?.image) {
setFileList([
{
uid: `${Date.now()}-${Math.random()}`, // Ensures uniqueness
name: `image${Date.now()}-${Math.random()}.png`,
status: 'done',
url: res?.data?.image,
},
]);
}
}
} catch (error) {
console.error('Image upload failed:', error);
}
}
}
if (newFileList?.length > 0) {
setEditImageOpen(true);
}
};
const onPreview = async (file) => {
let src = file.url;
if (!src) {
src = await new Promise((resolve) => {
const reader = new FileReader();
reader.readAsDataURL(file.originFileObj);
reader.onload = () => resolve(reader.result);
});
}
setPreviewImage(src);
setPreviewVisible(true);
};
const handleCrop = (croppedData) => {
setCroppedImage(croppedData);
};
const handleShape = (shapedData) => {
setShapedData(shapedData);
};
const handleUpload = async ({ file, onSuccess, onError }) => {
try {
if (!file) {
console.error('File object is null or undefined.');
onError();
return;
}
const data = await dispatch(uploadImage(file)).unwrap();
if (data?.data?.status) {
if (Object.keys(isProductList)?.length > 0) {
const { isProductListPutapi, record, imagePutFunction } =
isProductList;
if (isProductListPutapi) {
imagePutFunction(data?.data?.image, record);
setFileList([{ url: data?.data?.image }]);
onSuccess(); // Trigger onSuccess to indicate a successful upload
setCroppedImage(null);
setShapedData(null);
} else {
updateImageUrl(data?.data?.image);
setFileList([{ url: data?.data?.image }]);
onSuccess(); // Trigger onSuccess to indicate a successful upload
setCroppedImage(null);
setShapedData(null);
}
} else {
updateImageUrl(data?.data?.image);
setFileList([{ url: data?.data?.image }]);
onSuccess(); // Trigger onSuccess to indicate a successful upload
setCroppedImage(null);
setShapedData(null);
}
} else {
console.error('API request was not successful:', data?.data?.error);
onError(); // Trigger onError to indicate a failed upload
}
} catch (error) {
console.error('Error calling API:', error);
onError(); // Trigger onError in case of an error
}
};
const handleRemove = () => {
if (Object.keys(isProductList)?.length > 0) {
const { isProductListPutapi, record, imagePutFunction } = isProductList;
if (isProductListPutapi) {
imagePutFunction('', record);
}
}
updateImageUrl('');
setEditImageOpen(false);
setShapedImage(false);
setCropImage(false);
};
const handleShapeCrop = () => {
setShapedImage(true);
setCropImage(false);
setCroppedImage(null);
};
const handleCropTool = () => {
setCropImage(true);
setShapedImage(false);
setShapedData(null);
};
function resizeImage(imageUrl, width, height) {
if (!imageUrl) {
// Handle the case where imageUrl is null or undefined
console.error('Image URL is null or undefined.');
return Promise.reject('Image URL is null or undefined.');
}
return new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = 'anonymous'; // Set crossOrigin to handle cross-origin images
img.onload = function () {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = width;
canvas.height = height;
ctx.drawImage(img, 0, 0, width, height);
const resizedImageUrl = canvas.toDataURL();
resolve(resizedImageUrl);
};
img.onerror = function (error) {
reject(error);
};
img.src = imageUrl;
});
}
const beforeUpload = (file) => {
const isAllowed = allowedTypes.includes(file.type);
if (!isAllowed) {
Modal.error({
title: 'Invalid File Type',
content:
'Only JPG, JPEG, PNG, WEBP, SVG, GIF, and AVIF files are allowed.',
});
}
return isAllowed || Upload.LIST_IGNORE; // prevents adding to fileList if invalid
};
const onComplete = useCallback(() => {
setMessageData(null);
setMessageType(null);
}, []);
return (
<>