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 ( <>
0 ? fileList.length > 0 ? 'cropUploadFieldSmall' : 'cropUploadFieldSmallNoData' : '' } > {fileList.length < 1 && '+ Upload'}
Preview {isMobile && fileList?.length == 0 && hasCamera && <>
OR
{ const file = e.target.files?.[0]; if (!file) return; try { await handleUpload({ file, onSuccess: () => { setEditImageOpen(true); }, onError: () => { console.error("Upload failed"); } }); } catch (error) { console.error(error); } }} /> }
{!croppedImage && !cropImage && !shapedImage && (
Edit Image
)}
handleCropTool()} >
Crop Tool
handleShapeCrop()} >
Pen Tool
{cropImage && ( )} {croppedImage && cropImage && (

Cropped Image Preview

Cropped Image
)} {shapedImage && ( )}
} handleSubmit={ croppedImage == null && shapedData == null ? SetDefault : croppedImage != null ? handleSubmit : handleShapeSubmit } handleCancel={handleEditImageCancle} /> ); }; export default CropUpload;