px-react-ui-components 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +3 -0
- package/README.md +126 -0
- package/dist/components/MyAlert/MyAlert.css +113 -0
- package/dist/components/MyAlert/MyAlert.js +109 -0
- package/dist/components/MyContainer/MyContainer.js +59 -0
- package/dist/components/MyContainer/MyContainer.module.css +110 -0
- package/dist/components/MyContainer/MyContainerBody.js +9 -0
- package/dist/components/MyContainer/MyContainerFooter.js +9 -0
- package/dist/components/MyContainer/MyContainerRight.js +10 -0
- package/dist/components/MyEditor/MyEditor.js +292 -0
- package/dist/components/MyEditor/MyEditor.scss +277 -0
- package/dist/components/MyFileUpload/MyFileUpload.js +288 -0
- package/dist/components/MyFileUpload/MyFileUpload.module.css +86 -0
- package/dist/components/MyImageCropper/MyImageCropper.js +95 -0
- package/dist/components/MyInput/MyInput.js +768 -0
- package/dist/components/MyInput/MyInput.module.css +420 -0
- package/dist/components/MyMaps/YandexMaps.js +162 -0
- package/dist/components/MyMenu/MenuItem.js +55 -0
- package/dist/components/MyMenu/MyMenu.module.css +102 -0
- package/dist/components/MyModal/MyModal.css +83 -0
- package/dist/components/MyModal/MyModal.js +71 -0
- package/dist/components/MyModal/MyModalBody.js +9 -0
- package/dist/components/MyModal/MyModalFooter.js +9 -0
- package/dist/components/MyNotFound/MyNotFound.css +22 -0
- package/dist/components/MyNotFound/MyNotFound.js +20 -0
- package/dist/components/MyScrollableCard/MyScrollableCard.js +74 -0
- package/dist/components/MyTable/MyTable.js +310 -0
- package/dist/components/MyTable/MyTable.module.css +350 -0
- package/dist/components/MyTable/MyTableBody.js +9 -0
- package/dist/components/MyTable/MyTableHead.js +9 -0
- package/dist/components/MyTabs/MyTabPane.js +17 -0
- package/dist/components/MyTabs/MyTabs.css +105 -0
- package/dist/components/MyTabs/MyTabs.js +66 -0
- package/dist/components/MyWaiting/MyWaiting.css +28 -0
- package/dist/components/MyWaiting/MyWaiting.js +27 -0
- package/dist/components/MyZoomImage/MyZoomImage.css +0 -0
- package/dist/components/MyZoomImage/MyZoomImage.js +108 -0
- package/dist/index.js +15 -0
- package/package.json +44 -0
- package/src/components/MyAlert/MyAlert.css +113 -0
- package/src/components/MyAlert/MyAlert.jsx +96 -0
- package/src/components/MyContainer/MyContainer.jsx +90 -0
- package/src/components/MyContainer/MyContainer.module.css +110 -0
- package/src/components/MyContainer/MyContainerBody.jsx +8 -0
- package/src/components/MyContainer/MyContainerFooter.jsx +8 -0
- package/src/components/MyContainer/MyContainerRight.jsx +11 -0
- package/src/components/MyEditor/MyEditor.jsx +252 -0
- package/src/components/MyEditor/MyEditor.scss +277 -0
- package/src/components/MyFileUpload/MyFileUpload.jsx +373 -0
- package/src/components/MyFileUpload/MyFileUpload.module.css +86 -0
- package/src/components/MyImageCropper/MyImageCropper.jsx +108 -0
- package/src/components/MyInput/MyInput.jsx +896 -0
- package/src/components/MyInput/MyInput.module.css +420 -0
- package/src/components/MyMaps/YandexMaps.jsx +186 -0
- package/src/components/MyMenu/MenuItem.jsx +62 -0
- package/src/components/MyMenu/MyMenu.module.css +102 -0
- package/src/components/MyModal/MyModal.css +83 -0
- package/src/components/MyModal/MyModal.jsx +78 -0
- package/src/components/MyModal/MyModalBody.jsx +8 -0
- package/src/components/MyModal/MyModalFooter.jsx +8 -0
- package/src/components/MyNotFound/MyNotFound.css +22 -0
- package/src/components/MyNotFound/MyNotFound.jsx +11 -0
- package/src/components/MyScrollableCard/MyScrollableCard.jsx +86 -0
- package/src/components/MyTable/MyTable.jsx +458 -0
- package/src/components/MyTable/MyTable.module.css +350 -0
- package/src/components/MyTable/MyTableBody.jsx +8 -0
- package/src/components/MyTable/MyTableHead.jsx +10 -0
- package/src/components/MyTabs/MyTabPane.jsx +9 -0
- package/src/components/MyTabs/MyTabs.css +105 -0
- package/src/components/MyTabs/MyTabs.jsx +63 -0
- package/src/components/MyWaiting/MyWaiting.css +28 -0
- package/src/components/MyWaiting/MyWaiting.jsx +27 -0
- package/src/components/MyZoomImage/MyZoomImage.css +0 -0
- package/src/components/MyZoomImage/MyZoomImage.jsx +139 -0
- package/src/index.js +15 -0
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import React, { useEffect, useState, useRef } from "react";
|
|
2
|
+
import { PiCamera, PiFileArrowUpLight } from "react-icons/pi";
|
|
3
|
+
import Resizer from "react-image-file-resizer";
|
|
4
|
+
import Camera, { FACING_MODES, IMAGE_TYPES } from "react-html5-camera-photo";
|
|
5
|
+
import "react-html5-camera-photo/build/css/index.css";
|
|
6
|
+
import { useTranslation } from "../../context/TranslationContext";
|
|
7
|
+
import MyWaiting from "../MyWaiting/MyWaiting";
|
|
8
|
+
import { MyAlert, MyAlertType } from "../MyAlert/MyAlert";
|
|
9
|
+
import styles from "./MyFileUpload.module.css";
|
|
10
|
+
import MyModal from "../MyModal/MyModal";
|
|
11
|
+
export const AcceptType = {
|
|
12
|
+
ALL: "all",
|
|
13
|
+
FILE: "file",
|
|
14
|
+
IMAGE: "image",
|
|
15
|
+
MEDIA: "media",
|
|
16
|
+
PDF: "pdf",
|
|
17
|
+
IMAGEPDF: "imagepdf"
|
|
18
|
+
};
|
|
19
|
+
Object.freeze(MyAlertType);
|
|
20
|
+
export default function MyFileUpload({
|
|
21
|
+
multiple = false,
|
|
22
|
+
accept = AcceptType.ALL,
|
|
23
|
+
className = null,
|
|
24
|
+
camera = true,
|
|
25
|
+
maxSizeMB = 50,
|
|
26
|
+
onData
|
|
27
|
+
}) {
|
|
28
|
+
const {
|
|
29
|
+
t
|
|
30
|
+
} = useTranslation();
|
|
31
|
+
const [loading, setLoading] = useState(false);
|
|
32
|
+
const [accepttypes, setAccepttypes] = useState(AcceptType.ALL);
|
|
33
|
+
const [acceptlabel, setAcceptlabel] = useState(AcceptType.ALL);
|
|
34
|
+
const [cameraopen, setCameraopen] = useState(false);
|
|
35
|
+
const [cameraopened, setCameraopened] = useState(false);
|
|
36
|
+
const [devices, setDevices] = useState([]);
|
|
37
|
+
const [selectedDeviceId, setSelectedDeviceId] = useState("");
|
|
38
|
+
const fileInputRef = useRef(null);
|
|
39
|
+
let type_files = ".pdf,.rar,.zip,.doc,.docx,.xls,.xlsx,.ppt,.pptx,msword,msexcel,vnd.ms-excel,vnd.openxmlformats-officedocument.spreadsheetml.sheet,vnd.openxmlformats-officedocument.wordprocessingml.document";
|
|
40
|
+
let type_image = ".jpg,.jpeg,.png";
|
|
41
|
+
let type_media = ".mp3,.mp4,.avi,.wav";
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
switch (accept) {
|
|
44
|
+
case AcceptType.ALL:
|
|
45
|
+
setAccepttypes(type_files + "," + type_image + "," + type_media);
|
|
46
|
+
setAcceptlabel("PNG, JPG, PDF, RAR, ZIP, MP3, MP4, AVI, WAV veya Word-Excel Dosyaları");
|
|
47
|
+
break;
|
|
48
|
+
case AcceptType.IMAGE:
|
|
49
|
+
setAccepttypes(type_image);
|
|
50
|
+
setAcceptlabel(t("PNG veya JPG Dosyaları"));
|
|
51
|
+
break;
|
|
52
|
+
case AcceptType.MEDIA:
|
|
53
|
+
setAccepttypes(type_media);
|
|
54
|
+
setAcceptlabel(t("MP3, MP4, AVI veya WAV Dosyaları"));
|
|
55
|
+
break;
|
|
56
|
+
case AcceptType.FILE:
|
|
57
|
+
setAccepttypes(type_files + "," + type_image);
|
|
58
|
+
setAcceptlabel(t("PDF, RAR, ZIP, PNG, JPG veya Word-Excel Dosyaları"));
|
|
59
|
+
break;
|
|
60
|
+
case AcceptType.PDF:
|
|
61
|
+
setAccepttypes(".pdf");
|
|
62
|
+
setAcceptlabel(t("PDF Dosyaları"));
|
|
63
|
+
break;
|
|
64
|
+
case AcceptType.IMAGEPDF:
|
|
65
|
+
setAccepttypes(type_image + ",.pdf");
|
|
66
|
+
setAcceptlabel(t("PNG, JPG veya PDF Dosyaları"));
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
navigator.mediaDevices.enumerateDevices().then(deviceInfos => {
|
|
70
|
+
const videoDevices = deviceInfos.filter(device => device.kind === "videoinput");
|
|
71
|
+
setDevices(videoDevices);
|
|
72
|
+
if (videoDevices.length > 0) {
|
|
73
|
+
setSelectedDeviceId(videoDevices[0].deviceId); // İlk kamerayı varsayılan olarak seç
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
}, []);
|
|
77
|
+
const responseData = (resdata, _error) => {
|
|
78
|
+
if (_error.length > 0) {
|
|
79
|
+
let message = _error.map((e, i) => {
|
|
80
|
+
return i + 1 + ".) <b><i>" + e.filename + "</i></b><br/>---- " + e.message + "<br/>";
|
|
81
|
+
});
|
|
82
|
+
MyAlert(t("Aşağıdaki dosyalar eklenemedi!") + "<br/><br/><div style='display: block;font-size:13px;width: 100%;text-align: left;'>" + message + "</div>", MyAlertType.WARNING);
|
|
83
|
+
}
|
|
84
|
+
if (onData && (Array.isArray(resdata) && resdata.length > 0 || !Array.isArray(resdata) && resdata)) onData(resdata);
|
|
85
|
+
setLoading(false);
|
|
86
|
+
};
|
|
87
|
+
const getBase64 = (files, callback = null) => {
|
|
88
|
+
let response_files = [];
|
|
89
|
+
let _error = [];
|
|
90
|
+
let fileReaderCalc = 0;
|
|
91
|
+
setLoading(true);
|
|
92
|
+
for (let i = 0; i < files.length; i++) {
|
|
93
|
+
const file = files[i];
|
|
94
|
+
let filesize = parseInt(file.size) / 1024 / 1024; //MB
|
|
95
|
+
|
|
96
|
+
let file_ext = file.type.split("/");
|
|
97
|
+
file_ext = file_ext[file_ext.length - 1];
|
|
98
|
+
if (filesize > maxSizeMB || accepttypes.indexOf(file_ext) == -1) {
|
|
99
|
+
if (filesize > maxSizeMB) {
|
|
100
|
+
_error.push({
|
|
101
|
+
filename: file.name,
|
|
102
|
+
message: t("Boyutu Max. Dosya Boyutundan büyük olamaz!") + ` <b>${maxSizeMB}MB</b>`
|
|
103
|
+
});
|
|
104
|
+
} else {
|
|
105
|
+
_error.push({
|
|
106
|
+
filename: file.name,
|
|
107
|
+
message: t("Dosya türü desteklenmiyor!") + ` <b>${file_ext}</b>`
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (files.length == i + 1 && response_files.length == 0) {
|
|
111
|
+
responseData(response_files, _error);
|
|
112
|
+
if (callback) {
|
|
113
|
+
callback();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
let extension_type = type_image.indexOf(file_ext) > -1 ? "image" : "file";
|
|
119
|
+
if (extension_type == "file") {
|
|
120
|
+
const reader = new FileReader();
|
|
121
|
+
reader.onload = function () {
|
|
122
|
+
let fileitem = {
|
|
123
|
+
base64: reader.result,
|
|
124
|
+
extension: file_ext,
|
|
125
|
+
extension_type: type_image.indexOf(file_ext) > -1 ? "image" : "file",
|
|
126
|
+
file: file
|
|
127
|
+
};
|
|
128
|
+
if (!multiple) {
|
|
129
|
+
response_files = fileitem;
|
|
130
|
+
} else {
|
|
131
|
+
response_files.push(fileitem);
|
|
132
|
+
}
|
|
133
|
+
fileReaderCalc++;
|
|
134
|
+
if (files.length == fileReaderCalc) {
|
|
135
|
+
responseData(response_files, _error);
|
|
136
|
+
if (callback) {
|
|
137
|
+
callback();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
reader.readAsDataURL(file);
|
|
142
|
+
} else {
|
|
143
|
+
let reader_param = {
|
|
144
|
+
file: file,
|
|
145
|
+
index: i,
|
|
146
|
+
ext: file_ext,
|
|
147
|
+
type_image: type_image
|
|
148
|
+
};
|
|
149
|
+
Resizer.imageFileResizer(file, 2600, 2600, "JPEG", 100, 0, uri => {
|
|
150
|
+
fileReaderCalc++;
|
|
151
|
+
let fileitem = {
|
|
152
|
+
base64: uri,
|
|
153
|
+
extension: reader_param.ext,
|
|
154
|
+
extension_type: reader_param.type_image.indexOf(reader_param.ext) > -1 ? "image" : "file",
|
|
155
|
+
file: reader_param.file
|
|
156
|
+
};
|
|
157
|
+
if (!multiple) {
|
|
158
|
+
response_files = fileitem;
|
|
159
|
+
} else {
|
|
160
|
+
response_files.push(fileitem);
|
|
161
|
+
}
|
|
162
|
+
if (files.length == fileReaderCalc) {
|
|
163
|
+
responseData(response_files, _error);
|
|
164
|
+
if (callback) {
|
|
165
|
+
callback();
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}, "base64");
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// responseData(response_files, _error);
|
|
173
|
+
};
|
|
174
|
+
useEffect(() => {
|
|
175
|
+
if (!cameraopen) {
|
|
176
|
+
setCameraopened(false);
|
|
177
|
+
}
|
|
178
|
+
}, [cameraopen]);
|
|
179
|
+
const handleFileInputChange = e => {
|
|
180
|
+
getBase64(e.target.files, () => {
|
|
181
|
+
if (fileInputRef.current) {
|
|
182
|
+
fileInputRef.current.value = '';
|
|
183
|
+
fileInputRef.current.files = null;
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
};
|
|
187
|
+
const handleDeviceChange = event => {
|
|
188
|
+
setSelectedDeviceId(event.target.value);
|
|
189
|
+
};
|
|
190
|
+
const handleTakePhoto = dataUri => {
|
|
191
|
+
let fileitem = {
|
|
192
|
+
base64: dataUri,
|
|
193
|
+
extension: "jpg",
|
|
194
|
+
extension_type: "image",
|
|
195
|
+
file: ""
|
|
196
|
+
};
|
|
197
|
+
responseData([fileitem], []);
|
|
198
|
+
setCameraopened(false);
|
|
199
|
+
setCameraopen(false);
|
|
200
|
+
};
|
|
201
|
+
const handleCameraError = () => {
|
|
202
|
+
// setCameraopened(false);
|
|
203
|
+
// setCameraopen(false);
|
|
204
|
+
};
|
|
205
|
+
const handleCameraStart = stream => {
|
|
206
|
+
setCameraopened(true);
|
|
207
|
+
};
|
|
208
|
+
const handleCameraStop = () => {
|
|
209
|
+
// setCameraopened(false);
|
|
210
|
+
};
|
|
211
|
+
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(MyWaiting, {
|
|
212
|
+
show: loading,
|
|
213
|
+
message: ""
|
|
214
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
215
|
+
className: className
|
|
216
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
217
|
+
className: styles.myFileUploadContainer
|
|
218
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
219
|
+
className: styles.myFileUploadContainerItem
|
|
220
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
221
|
+
className: styles.myFileUploadContainerItemIcon
|
|
222
|
+
}, /*#__PURE__*/React.createElement(PiFileArrowUpLight, {
|
|
223
|
+
className: styles.Icon
|
|
224
|
+
}), /*#__PURE__*/React.createElement("h2", {
|
|
225
|
+
className: styles.myFileUploadContainerItemIconText
|
|
226
|
+
}, acceptlabel, /*#__PURE__*/React.createElement("br", null), " ", t("En fazla"), " ", maxSizeMB, " MB")), /*#__PURE__*/React.createElement("div", {
|
|
227
|
+
className: styles.myFileUploadContainerItemFile
|
|
228
|
+
}, /*#__PURE__*/React.createElement("input", {
|
|
229
|
+
type: "file",
|
|
230
|
+
hidden: true,
|
|
231
|
+
ref: fileInputRef,
|
|
232
|
+
onChange: handleFileInputChange,
|
|
233
|
+
multiple: multiple,
|
|
234
|
+
accept: accepttypes
|
|
235
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
236
|
+
className: styles.myFileUploadButton,
|
|
237
|
+
onClick: () => fileInputRef.current.click()
|
|
238
|
+
}, t("Dosya Seç")))), camera && /*#__PURE__*/React.createElement("div", {
|
|
239
|
+
className: styles.myFileUploadContainerItem
|
|
240
|
+
}, /*#__PURE__*/React.createElement("div", {
|
|
241
|
+
className: styles.myFileUploadContainerItemIcon
|
|
242
|
+
}, /*#__PURE__*/React.createElement(PiCamera, {
|
|
243
|
+
className: styles.Icon
|
|
244
|
+
}), /*#__PURE__*/React.createElement("div", {
|
|
245
|
+
className: styles.myFileUploadContainerItemIconText
|
|
246
|
+
}, /*#__PURE__*/React.createElement("span", null, t("Kameradan fotoğraf çekebilirsin.")))), /*#__PURE__*/React.createElement("div", {
|
|
247
|
+
className: styles.myFileUploadContainerItemFile
|
|
248
|
+
}, /*#__PURE__*/React.createElement("button", {
|
|
249
|
+
type: "button",
|
|
250
|
+
className: styles.myFileUploadButton,
|
|
251
|
+
onClick: () => setCameraopen(true)
|
|
252
|
+
}, t("Fotoğraf Çek")))))), /*#__PURE__*/React.createElement(MyModal, {
|
|
253
|
+
show: cameraopen,
|
|
254
|
+
onClose: () => setCameraopen(false),
|
|
255
|
+
title: t("Fotoğraf Çek"),
|
|
256
|
+
closeOnEsc: false,
|
|
257
|
+
closeOnBackdropClick: false
|
|
258
|
+
}, /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Camera, {
|
|
259
|
+
videoConstraints: {
|
|
260
|
+
deviceId: selectedDeviceId ? {
|
|
261
|
+
exact: selectedDeviceId
|
|
262
|
+
} : undefined
|
|
263
|
+
},
|
|
264
|
+
onTakePhoto: dataUri => {
|
|
265
|
+
console.log(dataUri);
|
|
266
|
+
handleTakePhoto(dataUri);
|
|
267
|
+
},
|
|
268
|
+
onCameraError: handleCameraError,
|
|
269
|
+
onCameraStart: stream => {
|
|
270
|
+
handleCameraStart(stream);
|
|
271
|
+
},
|
|
272
|
+
onCameraStop: () => {
|
|
273
|
+
handleCameraStop();
|
|
274
|
+
},
|
|
275
|
+
idealFacingMode: FACING_MODES.ENVIRONMENT,
|
|
276
|
+
idealResolution: {
|
|
277
|
+
width: 1024,
|
|
278
|
+
height: 1024
|
|
279
|
+
},
|
|
280
|
+
imageType: IMAGE_TYPES.JPG,
|
|
281
|
+
isMaxResolution: true,
|
|
282
|
+
isImageMirror: false,
|
|
283
|
+
isSilentMode: false,
|
|
284
|
+
isDisplayStartCameraError: true,
|
|
285
|
+
isFullscreen: false,
|
|
286
|
+
sizeFactor: 1
|
|
287
|
+
}))));
|
|
288
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
.myFileUploadContainer {
|
|
2
|
+
display: flex;
|
|
3
|
+
width: 100%;
|
|
4
|
+
flex-direction: row;
|
|
5
|
+
gap: 5px;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.myFileUploadContainer .myFileUploadContainerItem {
|
|
9
|
+
width: 100%;
|
|
10
|
+
padding: 5px;
|
|
11
|
+
background-color: #f0f0f0;
|
|
12
|
+
border-radius: 5px;
|
|
13
|
+
border: 1px dashed #ccc;
|
|
14
|
+
display: flex;
|
|
15
|
+
flex-direction: row;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
align-items: center;
|
|
18
|
+
gap: 3px;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.myFileUploadContainer
|
|
22
|
+
.myFileUploadContainerItem
|
|
23
|
+
.myFileUploadContainerItemIcon {
|
|
24
|
+
display: flex;
|
|
25
|
+
width: 100%;
|
|
26
|
+
|
|
27
|
+
flex-direction: row;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
align-items: center;
|
|
30
|
+
gap: 1px;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.myFileUploadContainer
|
|
34
|
+
.myFileUploadContainerItem
|
|
35
|
+
.myFileUploadContainerItemIcon
|
|
36
|
+
.Icon {
|
|
37
|
+
font-size: 35px;
|
|
38
|
+
color: #17305b;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.myFileUploadContainer
|
|
42
|
+
.myFileUploadContainerItem
|
|
43
|
+
.myFileUploadContainerItemIcon
|
|
44
|
+
.myFileUploadContainerItemIconText {
|
|
45
|
+
width: 100%;
|
|
46
|
+
|
|
47
|
+
text-align: center;
|
|
48
|
+
font-weight: normal;
|
|
49
|
+
color: #636363;
|
|
50
|
+
font-size: 12px;
|
|
51
|
+
line-height: 1.3;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.myFileUploadContainer
|
|
55
|
+
.myFileUploadContainerItem
|
|
56
|
+
.myFileUploadContainerItemFile {
|
|
57
|
+
display: flex;
|
|
58
|
+
flex-direction: row;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
align-items: center;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.myFileUploadContainer
|
|
64
|
+
.myFileUploadContainerItem
|
|
65
|
+
.myFileUploadContainerItemFile
|
|
66
|
+
.myFileUploadButton {
|
|
67
|
+
display: flex;
|
|
68
|
+
width: 200px;
|
|
69
|
+
height: 35px;
|
|
70
|
+
flex-direction: column;
|
|
71
|
+
align-items: center;
|
|
72
|
+
justify-content: center;
|
|
73
|
+
gap: 10px;
|
|
74
|
+
flex-shrink: 0;
|
|
75
|
+
background-color: #334f7f;
|
|
76
|
+
color: #fff;
|
|
77
|
+
border-radius: 15px;
|
|
78
|
+
cursor: pointer;
|
|
79
|
+
font-size: 13px;
|
|
80
|
+
}
|
|
81
|
+
.myFileUploadContainer
|
|
82
|
+
.myFileUploadContainerItem
|
|
83
|
+
.myFileUploadContainerItemFile
|
|
84
|
+
.myFileUploadButton:hover {
|
|
85
|
+
background-color: #2a436a;
|
|
86
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import ReactCrop from "react-image-crop";
|
|
3
|
+
import "react-image-crop/dist/ReactCrop.css";
|
|
4
|
+
import MyImageZoom from "../MyZoomImage/MyZoomImage";
|
|
5
|
+
const MyImageCropper = ({
|
|
6
|
+
image,
|
|
7
|
+
style = null,
|
|
8
|
+
onChange = null
|
|
9
|
+
}) => {
|
|
10
|
+
const [crop, setCrop] = useState({
|
|
11
|
+
x: 0,
|
|
12
|
+
y: 0,
|
|
13
|
+
width: 0,
|
|
14
|
+
height: 0,
|
|
15
|
+
aspect: 1
|
|
16
|
+
});
|
|
17
|
+
// const [croppedImageUrl, setCroppedImageUrl] = useState(null);
|
|
18
|
+
const [imageRef, setImageRef] = useState(null);
|
|
19
|
+
const [zoom, setZoom] = useState({
|
|
20
|
+
scale: 1,
|
|
21
|
+
positionX: 0,
|
|
22
|
+
positionY: 0
|
|
23
|
+
}); // Zoom seviyesini saklamak için state
|
|
24
|
+
const [scaleFactor, setScaleFactor] = useState(1.5);
|
|
25
|
+
|
|
26
|
+
// Görüntü yüklendiğinde çağrılır
|
|
27
|
+
const handleImageLoad = e => {
|
|
28
|
+
setImageRef(e.currentTarget); // HTMLImageElement olarak kaydediyoruz
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// Zoom değiştiğinde çağrılır
|
|
32
|
+
const handleZoomChange = newZoom => {
|
|
33
|
+
setZoom(newZoom);
|
|
34
|
+
setScaleFactor(newZoom.scale * 3);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
// Kırpma tamamlandığında çağrılır
|
|
38
|
+
const onCropComplete = newCrop => {
|
|
39
|
+
if (imageRef && newCrop.width && newCrop.height) {
|
|
40
|
+
// Zoom oranını kullanarak yeni koordinatlar hesapla
|
|
41
|
+
const adjustedCrop = {
|
|
42
|
+
...newCrop,
|
|
43
|
+
x: (newCrop.x - zoom.positionX) / zoom.scale,
|
|
44
|
+
y: (newCrop.y - zoom.positionY) / zoom.scale,
|
|
45
|
+
width: newCrop.width / zoom.scale,
|
|
46
|
+
height: newCrop.height / zoom.scale
|
|
47
|
+
};
|
|
48
|
+
generateCroppedImage(imageRef, adjustedCrop);
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
// Kırpılmış görseli base64 formatında almak için
|
|
53
|
+
const generateCroppedImage = (image, crop) => {
|
|
54
|
+
if (!crop || !crop.width || !crop.height || crop.width === 0) {
|
|
55
|
+
console.warn("Geçersiz kırpma ölçüleri");
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const canvas = document.createElement("canvas");
|
|
59
|
+
const scaleX = image.naturalWidth / image.width;
|
|
60
|
+
const scaleY = image.naturalHeight / image.height;
|
|
61
|
+
|
|
62
|
+
// Kesim boyutlarını scaleFactor ile çarp
|
|
63
|
+
const outputWidth = crop.width * scaleFactor;
|
|
64
|
+
const outputHeight = crop.height * scaleFactor;
|
|
65
|
+
canvas.width = outputWidth;
|
|
66
|
+
canvas.height = outputHeight;
|
|
67
|
+
const ctx = canvas.getContext("2d");
|
|
68
|
+
ctx.drawImage(image, crop.x * scaleX, crop.y * scaleY, crop.width * scaleX, crop.height * scaleY, 0, 0, outputWidth, outputHeight // Büyütülmüş boyutlar
|
|
69
|
+
);
|
|
70
|
+
const base64Image = canvas.toDataURL("image/jpeg");
|
|
71
|
+
// setCroppedImageUrl(base64Image);
|
|
72
|
+
|
|
73
|
+
if (onChange) {
|
|
74
|
+
onChange({
|
|
75
|
+
value: base64Image
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
80
|
+
style: style
|
|
81
|
+
}, image && /*#__PURE__*/React.createElement(ReactCrop, {
|
|
82
|
+
crop: crop,
|
|
83
|
+
onComplete: onCropComplete,
|
|
84
|
+
onChange: newCrop => setCrop(newCrop),
|
|
85
|
+
style: style
|
|
86
|
+
}, /*#__PURE__*/React.createElement(MyImageZoom, {
|
|
87
|
+
onZoomChange: handleZoomChange
|
|
88
|
+
}, /*#__PURE__*/React.createElement("img", {
|
|
89
|
+
src: image,
|
|
90
|
+
alt: "Crop preview",
|
|
91
|
+
onLoad: handleImageLoad,
|
|
92
|
+
className: "rounded-e-md"
|
|
93
|
+
}))));
|
|
94
|
+
};
|
|
95
|
+
export default MyImageCropper;
|