Skip to content

Commit

Permalink
Merge pull request #528 from culturecreates/feature/issue-411
Browse files Browse the repository at this point in the history
Feature/issue 411
  • Loading branch information
AbhishekPAnil authored Aug 17, 2023
2 parents 97a1843 + f7a7a73 commit 1035e97
Show file tree
Hide file tree
Showing 13 changed files with 31,726 additions and 4,959 deletions.
35,975 changes: 31,084 additions & 4,891 deletions package-lock.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"rc-year-calendar": "^1.0.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-easy-crop": "^5.0.0",
"react-i18next": "^12.0.0",
"react-places-autocomplete": "^7.3.0",
"react-quill": "^2.0.0",
Expand Down
193 changes: 193 additions & 0 deletions src/components/ImageCrop/ImageCrop.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import React, { useState, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import './imageCrop.css';
import { Row, Col, Space, Radio, Button } from 'antd';
import { MinusOutlined, PlusOutlined } from '@ant-design/icons';
import Cropper from 'react-easy-crop';
import CustomModal from '../Modal/Common/CustomModal';
import PrimaryButton from '../Button/Primary/Primary';
import TextButton from '../Button/Text/Text';
import getCroppedImg from '../../utils/getCroppedImg';
import { ratioChecker } from '../../utils/ratioChecker';

function ImageCrop(props) {
const { image, open, setOpen, largeAspectRatio, thumbnailAspectRatio, form, cropValues, setCropValues, setImage } =
props;
const { t } = useTranslation();

let ASPECT_RATIO_TYPE = {
large: {
value: largeAspectRatio ? ratioChecker(largeAspectRatio) : 16 / 9,
type: 'LARGE',
},
thumbnail: {
value: thumbnailAspectRatio ? ratioChecker(thumbnailAspectRatio) : 3 / 2,
type: 'THUMBNAIL',
},
};
const [crop, onCropChange] = useState(cropValues?.large);
const [zoom, onZoomChange] = useState(1);
const [aspectRatio, setAspectRatio] = useState(ASPECT_RATIO_TYPE.large.value);
const [aspectRatioType, setAspectRatioType] = useState(ASPECT_RATIO_TYPE.large.type);

const onCropAreaChange = (croppedArea, croppedAreaPixel) => {
switch (aspectRatioType) {
case ASPECT_RATIO_TYPE.large.type:
setCropValues({
...cropValues,
large: {
x: croppedAreaPixel?.x,
y: croppedAreaPixel?.y,
height: croppedAreaPixel?.height,
width: croppedAreaPixel?.width,
},
});
break;
case ASPECT_RATIO_TYPE.thumbnail.type:
setCropValues({
...cropValues,
thumbnail: {
x: croppedAreaPixel?.x,
y: croppedAreaPixel?.y,
height: croppedAreaPixel?.height,
width: croppedAreaPixel?.width,
},
});
break;
default:
break;
}
};

const aspectRatioControl = (type) => {
switch (type) {
case ASPECT_RATIO_TYPE.large.type:
setAspectRatioType(ASPECT_RATIO_TYPE.large.type);
setAspectRatio(ASPECT_RATIO_TYPE.large.value);
break;
case ASPECT_RATIO_TYPE.thumbnail.type:
setAspectRatioType(ASPECT_RATIO_TYPE.thumbnail.type);
setAspectRatio(ASPECT_RATIO_TYPE.thumbnail.value);
break;
default:
break;
}
};

const saveCropHandler = () => {
form.setFieldsValue({
imageCrop: cropValues,
});
setOpen(false);
showCroppedImage();
};

const showCroppedImage = useCallback(async () => {
try {
const croppedImage = await getCroppedImg(image, cropValues?.large, null);
setImage(croppedImage);
} catch (e) {
console.error(e);
}
}, [cropValues?.large]);

return (
<CustomModal
width={500}
centered
open={open}
bodyStyle={{
height: '600px',
}}
onCancel={() => setOpen(false)}
title={
<span className="quick-select-modal-title">
{t('dashboard.events.addEditEvent.otherInformation.image.crop.title')}
</span>
}
footer={[
<TextButton
key="cancel"
size="large"
label={t('dashboard.events.addEditEvent.otherInformation.image.crop.cancel')}
onClick={() => setOpen(false)}
/>,
<PrimaryButton
key="add-dates"
label={t('dashboard.events.addEditEvent.otherInformation.image.crop.save')}
onClick={() => saveCropHandler()}
/>,
]}>
<div className="image-crop-wrapper">
<Row gutter={[0, 18]}>
<Col span={24}>
<span className="quick-select-modal-sub-heading">
{t('dashboard.events.addEditEvent.otherInformation.image.crop.subHeading')}
</span>
</Col>
<Col span={24}>
<span className="quick-select-modal-sub-heading" style={{ fontWeight: 700, color: '#222732' }}>
{t('dashboard.events.addEditEvent.otherInformation.image.crop.savedFrameSize')}
</span>
</Col>
<Col span={24}>
<Radio.Group
defaultValue={ASPECT_RATIO_TYPE.large.type}
onChange={(event) => aspectRatioControl(event.target.value)}
style={{ color: '#222732' }}>
<Space direction="vertical">
<Radio value={ASPECT_RATIO_TYPE.large.type}>
{largeAspectRatio} {t('dashboard.events.addEditEvent.otherInformation.image.crop.ratio')}
</Radio>
<Radio value={ASPECT_RATIO_TYPE.thumbnail.type}>
{thumbnailAspectRatio} {t('dashboard.events.addEditEvent.otherInformation.image.crop.ratio')}
</Radio>
</Space>
</Radio.Group>
</Col>
<Col span={24}>
<div className="controls">
<Button type="text" icon={<MinusOutlined color=" #646d7b" />} onClick={() => onZoomChange(zoom - 0.1)} />
<input
type="range"
value={zoom}
min={1}
max={3}
step={0.1}
aria-labelledby="Zoom"
onChange={(e) => {
onZoomChange(e.target.value);
}}
className="zoom-range"
/>
<Button
type="text"
icon={<PlusOutlined style={{ color: '#646d7b' }} />}
onClick={() => onZoomChange(zoom + 0.1)}
/>
</div>
</Col>
<Col span={24}>
<div className="crop-container">
<Cropper
classes={{
containerClassName: 'crop-area-container',
}}
showGrid={false}
image={image}
crop={crop}
zoom={zoom}
aspect={aspectRatio}
onCropChange={onCropChange}
onZoomChange={onZoomChange}
onCropAreaChange={onCropAreaChange}
/>
</div>
</Col>
</Row>
</div>
</CustomModal>
);
}

export default ImageCrop;
61 changes: 61 additions & 0 deletions src/components/ImageCrop/imageCrop.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
.image-crop-wrapper .controls {
height: 40px;
display: flex;
align-items: center;
gap: 8px;
}

.image-crop-wrapper .quick-select-modal-sub-heading {
font-weight: 400;
font-size: 16px;
color: #646d7b;
}

.image-crop-wrapper .slider {
padding: 22px 0px;
}

.image-crop-wrapper .zoom-range {
-webkit-appearance: none;
-moz-appearance: none;
height: 2px;
border-top: 2px solid #1b3de6;
border-bottom: 2px solid #1b3de6;
background: #1b3de6;
width: 100%;
}

.image-crop-wrapper .crop-area-container {
height: 350px;
}

.image-crop-wrapper .zoom-range::-moz-range-thumb {
-webkit-appearance: none;
-moz-appearance: none;
border: 1px solid #3f51b5;
background: white;
border-radius: 50%;
width: 12px;
height: 12px;
transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}

.image-crop-wrapper .zoom-range::-webkit-slider-thumb {
-webkit-appearance: none;
-moz-appearance: none;
border: 1px solid #3f51b5;
background: white;
border-radius: 50%;
width: 12px;
height: 12px;
transition: box-shadow 150ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
}

.image-crop-wrapper .controls:hover input[type='range']::-webkit-slider-thumb {
box-shadow: 0px 0px 0px 8px rgba(63, 81, 181, 0.16);
border-radius: 50%;
}

.image-crop-wrapper .controls:hover input[type='range']::-moz-range-thumb {
box-shadow: 0px 0px 0px 8px rgba(63, 81, 181, 0.16);
}
1 change: 1 addition & 0 deletions src/components/ImageCrop/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './ImageCrop';
Loading

0 comments on commit 1035e97

Please sign in to comment.