Android_Retail/src/Components/PedalOCR/CropperArea.jsx

223 lines
6.4 KiB
React
Raw Normal View History

2026-01-27 18:27:29 +05:30
import React, { useState, useRef, useEffect } from "react";
import ReactCrop from "react-image-crop";
import "react-image-crop/dist/ReactCrop.css";
import { FiX, FiScissors } from "react-icons/fi";
const ResizableCropper = ({ imageSrc, onCropComplete, onCancel, onNext, currentIndex, total }) => {
const [crop, setCrop] = useState({ unit: "%", width: 80, height: 100, aspect: 4 / 5 });
const [completedCrop, setCompletedCrop] = useState(null);
const [screenSize, setScreenSize] = useState('desktop');
const imgRef = useRef(null);
useEffect(() => {
const updateScreenSize = () => {
const width = window.innerWidth;
if (width <= 480) setScreenSize('mobile');
else if (width <= 768) setScreenSize('tablet');
else if (width <= 1024) setScreenSize('laptop');
else setScreenSize('desktop');
};
updateScreenSize();
window.addEventListener('resize', updateScreenSize);
return () => window.removeEventListener('resize', updateScreenSize);
}, []);
// Convert crop to base64 image
const getCroppedImage = () => {
if (!imgRef.current || !completedCrop?.width || !completedCrop?.height) return null;
const canvas = document.createElement("canvas");
const scaleX = imgRef.current.naturalWidth / imgRef.current.width;
const scaleY = imgRef.current.naturalHeight / imgRef.current.height;
canvas.width = completedCrop.width * scaleX;
canvas.height = completedCrop.height * scaleY;
const ctx = canvas.getContext("2d");
ctx.drawImage(
imgRef.current,
completedCrop.x * scaleX,
completedCrop.y * scaleY,
completedCrop.width * scaleX,
completedCrop.height * scaleY,
0,
0,
completedCrop.width * scaleX,
completedCrop.height * scaleY
);
return canvas.toDataURL("image/jpeg");
};
const handleNext = () => {
const cropped = getCroppedImage();
if (cropped) onCropComplete(cropped);
if (onNext) onNext();
};
const getResponsiveStyles = () => {
switch (screenSize) {
case 'mobile':
return {
containerPadding: "12px",
imagePadding: 8,
maxHeight: "250px",
buttonPadding: "14px 20px",
fontSize: 13,
iconSize: 16,
gap: 8,
direction: 'row',
borderRadius: 8
};
case 'tablet':
return {
containerPadding: "16px",
imagePadding: 12,
maxHeight: "320px",
buttonPadding: "12px 18px",
fontSize: 13,
iconSize: 16,
gap: 10,
direction: 'row',
borderRadius: 10
};
case 'laptop':
return {
containerPadding: "18px",
imagePadding: 14,
maxHeight: "380px",
buttonPadding: "12px 20px",
fontSize: 14,
iconSize: 16,
gap: 12,
direction: 'row',
borderRadius: 12
};
default:
return {
containerPadding: "20px",
imagePadding: 16,
maxHeight: "400px",
buttonPadding: "12px 20px",
fontSize: 14,
iconSize: 16,
gap: 12,
direction: 'row',
borderRadius: 12
};
}
};
const styles = getResponsiveStyles();
const buttonStyle = {
padding: styles.buttonPadding,
border: "none",
borderRadius: 8,
cursor: "pointer",
fontSize: styles.fontSize,
fontWeight: 500,
transition: "all 0.3s ease",
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
display: "flex",
alignItems: "center",
gap: 6,
width: screenSize === 'mobile' ? '100%' : 'auto',
justifyContent: 'center',
minHeight: screenSize === 'mobile' ? '48px' : 'auto'
};
return (
<div style={{
textAlign: "center",
marginTop: screenSize === 'mobile' ? 12 : 20,
padding: styles.containerPadding,
backgroundColor: "#f8f9fa",
borderRadius: styles.borderRadius,
margin: screenSize === 'mobile' ? '12px 8px' : '20px auto',
maxWidth: screenSize === 'mobile' ? '100%' : '500px'
}}>
{/* {screenSize !== 'mobile' && (
<div style={{ marginBottom: 16 }}>
<h3 style={{ margin: 0, color: "#333", fontSize: screenSize === 'tablet' ? 16 : 18 }}>
Crop Image {currentIndex + 1} of {total}
</h3>
</div>
)} */}
<div style={{
backgroundColor: "#fff",
padding: styles.imagePadding,
borderRadius: 8,
boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
overflow: 'hidden'
}}>
{screenSize === 'mobile' && (
<div style={{ marginBottom: 8, fontSize: 12, color: "#666" }}>
Image {currentIndex + 1} of {total}
</div>
)}
<ReactCrop
crop={crop}
onChange={(newCrop) => setCrop(newCrop)}
onComplete={(newCrop) => setCompletedCrop(newCrop)}
keepSelection={true}
>
<img
ref={imgRef}
src={imageSrc}
alt="Preview"
style={{
maxWidth: "100%",
maxHeight: styles.maxHeight,
borderRadius: 4,
touchAction: 'none'
}}
/>
</ReactCrop>
</div>
<div style={{
marginTop: screenSize === 'mobile' ? 16 : 20,
display: "flex",
flexDirection: styles.direction,
justifyContent: "center",
gap: styles.gap,
padding: screenSize === 'mobile' ? '0 4px' : '0'
}}>
<button
onClick={onCancel}
style={{
...buttonStyle,
backgroundColor: "#6c757d",
color: "#fff",
fontFamily: "Poppins"
}}
onMouseOver={(e) => e.target.style.backgroundColor = "#5a6268"}
onMouseOut={(e) => e.target.style.backgroundColor = "#6c757d"}
>
<FiX size={styles.iconSize} />
{screenSize === 'mobile' ? 'Cancel' : 'Cancel All'}
</button>
<button
onClick={handleNext}
style={{
...buttonStyle,
backgroundColor: "#1890ff",
color: "#fff",
fontFamily: "Poppins"
}}
onMouseOver={(e) => e.target.style.backgroundColor = "#096dd9"}
onMouseOut={(e) => e.target.style.backgroundColor = "#1890ff"}
>
<FiScissors size={styles.iconSize} />
{screenSize === 'mobile' ? 'Crop' : 'Crop '}
</button>
</div>
</div>
);
};
export default ResizableCropper;