@parameshdev/react-psh-image-editor-modal 1.0.1

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/dist/index.js ADDED
@@ -0,0 +1,1226 @@
1
+ 'use strict';
2
+
3
+ var React = require('react');
4
+
5
+ function _arrayLikeToArray(r, a) {
6
+ (null == a || a > r.length) && (a = r.length);
7
+ for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
8
+ return n;
9
+ }
10
+ function _arrayWithHoles(r) {
11
+ if (Array.isArray(r)) return r;
12
+ }
13
+ function _arrayWithoutHoles(r) {
14
+ if (Array.isArray(r)) return _arrayLikeToArray(r);
15
+ }
16
+ function asyncGeneratorStep(n, t, e, r, o, a, c) {
17
+ try {
18
+ var i = n[a](c),
19
+ u = i.value;
20
+ } catch (n) {
21
+ return void e(n);
22
+ }
23
+ i.done ? t(u) : Promise.resolve(u).then(r, o);
24
+ }
25
+ function _asyncToGenerator(n) {
26
+ return function () {
27
+ var t = this,
28
+ e = arguments;
29
+ return new Promise(function (r, o) {
30
+ var a = n.apply(t, e);
31
+ function _next(n) {
32
+ asyncGeneratorStep(a, r, o, _next, _throw, "next", n);
33
+ }
34
+ function _throw(n) {
35
+ asyncGeneratorStep(a, r, o, _next, _throw, "throw", n);
36
+ }
37
+ _next(void 0);
38
+ });
39
+ };
40
+ }
41
+ function _defineProperty(e, r, t) {
42
+ return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
43
+ value: t,
44
+ enumerable: true,
45
+ configurable: true,
46
+ writable: true
47
+ }) : e[r] = t, e;
48
+ }
49
+ function _iterableToArray(r) {
50
+ if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r);
51
+ }
52
+ function _iterableToArrayLimit(r, l) {
53
+ var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
54
+ if (null != t) {
55
+ var e,
56
+ n,
57
+ i,
58
+ u,
59
+ a = [],
60
+ f = true,
61
+ o = false;
62
+ try {
63
+ if (i = (t = t.call(r)).next, 0 === l) ; else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0);
64
+ } catch (r) {
65
+ o = true, n = r;
66
+ } finally {
67
+ try {
68
+ if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return;
69
+ } finally {
70
+ if (o) throw n;
71
+ }
72
+ }
73
+ return a;
74
+ }
75
+ }
76
+ function _nonIterableRest() {
77
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
78
+ }
79
+ function _nonIterableSpread() {
80
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
81
+ }
82
+ function ownKeys(e, r) {
83
+ var t = Object.keys(e);
84
+ if (Object.getOwnPropertySymbols) {
85
+ var o = Object.getOwnPropertySymbols(e);
86
+ r && (o = o.filter(function (r) {
87
+ return Object.getOwnPropertyDescriptor(e, r).enumerable;
88
+ })), t.push.apply(t, o);
89
+ }
90
+ return t;
91
+ }
92
+ function _objectSpread2(e) {
93
+ for (var r = 1; r < arguments.length; r++) {
94
+ var t = null != arguments[r] ? arguments[r] : {};
95
+ r % 2 ? ownKeys(Object(t), true).forEach(function (r) {
96
+ _defineProperty(e, r, t[r]);
97
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) {
98
+ Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r));
99
+ });
100
+ }
101
+ return e;
102
+ }
103
+ function _regenerator() {
104
+ /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */
105
+ var e,
106
+ t,
107
+ r = "function" == typeof Symbol ? Symbol : {},
108
+ n = r.iterator || "@@iterator",
109
+ o = r.toStringTag || "@@toStringTag";
110
+ function i(r, n, o, i) {
111
+ var c = n && n.prototype instanceof Generator ? n : Generator,
112
+ u = Object.create(c.prototype);
113
+ return _regeneratorDefine(u, "_invoke", function (r, n, o) {
114
+ var i,
115
+ c,
116
+ u,
117
+ f = 0,
118
+ p = o || [],
119
+ y = false,
120
+ G = {
121
+ p: 0,
122
+ n: 0,
123
+ v: e,
124
+ a: d,
125
+ f: d.bind(e, 4),
126
+ d: function (t, r) {
127
+ return i = t, c = 0, u = e, G.n = r, a;
128
+ }
129
+ };
130
+ function d(r, n) {
131
+ for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) {
132
+ var o,
133
+ i = p[t],
134
+ d = G.p,
135
+ l = i[2];
136
+ r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0));
137
+ }
138
+ if (o || r > 1) return a;
139
+ throw y = true, n;
140
+ }
141
+ return function (o, p, l) {
142
+ if (f > 1) throw TypeError("Generator is already running");
143
+ for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) {
144
+ i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u);
145
+ try {
146
+ if (f = 2, i) {
147
+ if (c || (o = "next"), t = i[o]) {
148
+ if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object");
149
+ if (!t.done) return t;
150
+ u = t.value, c < 2 && (c = 0);
151
+ } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1);
152
+ i = e;
153
+ } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break;
154
+ } catch (t) {
155
+ i = e, c = 1, u = t;
156
+ } finally {
157
+ f = 1;
158
+ }
159
+ }
160
+ return {
161
+ value: t,
162
+ done: y
163
+ };
164
+ };
165
+ }(r, o, i), true), u;
166
+ }
167
+ var a = {};
168
+ function Generator() {}
169
+ function GeneratorFunction() {}
170
+ function GeneratorFunctionPrototype() {}
171
+ t = Object.getPrototypeOf;
172
+ var c = [][n] ? t(t([][n]())) : (_regeneratorDefine(t = {}, n, function () {
173
+ return this;
174
+ }), t),
175
+ u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c);
176
+ function f(e) {
177
+ return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e;
178
+ }
179
+ return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine(u), _regeneratorDefine(u, o, "Generator"), _regeneratorDefine(u, n, function () {
180
+ return this;
181
+ }), _regeneratorDefine(u, "toString", function () {
182
+ return "[object Generator]";
183
+ }), (_regenerator = function () {
184
+ return {
185
+ w: i,
186
+ m: f
187
+ };
188
+ })();
189
+ }
190
+ function _regeneratorDefine(e, r, n, t) {
191
+ var i = Object.defineProperty;
192
+ try {
193
+ i({}, "", {});
194
+ } catch (e) {
195
+ i = 0;
196
+ }
197
+ _regeneratorDefine = function (e, r, n, t) {
198
+ function o(r, n) {
199
+ _regeneratorDefine(e, r, function (e) {
200
+ return this._invoke(r, n, e);
201
+ });
202
+ }
203
+ r ? i ? i(e, r, {
204
+ value: n,
205
+ enumerable: !t,
206
+ configurable: !t,
207
+ writable: !t
208
+ }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2));
209
+ }, _regeneratorDefine(e, r, n, t);
210
+ }
211
+ function _slicedToArray(r, e) {
212
+ return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest();
213
+ }
214
+ function _toConsumableArray(r) {
215
+ return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread();
216
+ }
217
+ function _toPrimitive(t, r) {
218
+ if ("object" != typeof t || !t) return t;
219
+ var e = t[Symbol.toPrimitive];
220
+ if (void 0 !== e) {
221
+ var i = e.call(t, r);
222
+ if ("object" != typeof i) return i;
223
+ throw new TypeError("@@toPrimitive must return a primitive value.");
224
+ }
225
+ return ("string" === r ? String : Number)(t);
226
+ }
227
+ function _toPropertyKey(t) {
228
+ var i = _toPrimitive(t, "string");
229
+ return "symbol" == typeof i ? i : i + "";
230
+ }
231
+ function _unsupportedIterableToArray(r, a) {
232
+ if (r) {
233
+ if ("string" == typeof r) return _arrayLikeToArray(r, a);
234
+ var t = {}.toString.call(r).slice(8, -1);
235
+ return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0;
236
+ }
237
+ }
238
+
239
+ var UploadButton = function UploadButton(_ref) {
240
+ var onUpload = _ref.onUpload,
241
+ name = _ref.name;
242
+ var fileInputRef = React.useRef(null);
243
+ var handleFileChange = /*#__PURE__*/function () {
244
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(e) {
245
+ var file, validTypes;
246
+ return _regenerator().w(function (_context) {
247
+ while (1) switch (_context.n) {
248
+ case 0:
249
+ file = e.target.files[0];
250
+ if (file) {
251
+ _context.n = 1;
252
+ break;
253
+ }
254
+ return _context.a(2);
255
+ case 1:
256
+ validTypes = ['image/png', 'image/jpg', 'image/jpeg', 'image/webp'];
257
+ if (validTypes.includes(file.type)) {
258
+ _context.n = 2;
259
+ break;
260
+ }
261
+ alert('Please upload a valid image file (.png, .jpg, .jpeg, .webp)');
262
+ return _context.a(2);
263
+ case 2:
264
+ onUpload(file);
265
+ case 3:
266
+ return _context.a(2);
267
+ }
268
+ }, _callee);
269
+ }));
270
+ return function handleFileChange(_x) {
271
+ return _ref2.apply(this, arguments);
272
+ };
273
+ }();
274
+ return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", {
275
+ ref: fileInputRef,
276
+ type: "file",
277
+ accept: ".png,.jpg,.jpeg,.webp",
278
+ onChange: handleFileChange,
279
+ className: "hidden"
280
+ }), /*#__PURE__*/React.createElement("button", {
281
+ onClick: function onClick() {
282
+ var _fileInputRef$current;
283
+ return (_fileInputRef$current = fileInputRef.current) === null || _fileInputRef$current === void 0 ? void 0 : _fileInputRef$current.click();
284
+ },
285
+ className: "px-6 py-3 text-lg font-semibold text-white bg-gradient-to-r from-purple-500 to-purple-700 rounded-lg shadow-lg hover:scale-105 transition-transform duration-200"
286
+ }, "".concat(name)));
287
+ };
288
+
289
+ var platformSizes = {
290
+ instagram: {
291
+ width: 1080,
292
+ height: 1080,
293
+ label: 'Instagram Post',
294
+ ratio: '1:1'
295
+ },
296
+ 'instagram-story': {
297
+ width: 1080,
298
+ height: 1920,
299
+ label: 'Instagram Story',
300
+ ratio: '9:16'
301
+ },
302
+ facebook: {
303
+ width: 1200,
304
+ height: 630,
305
+ label: 'Facebook Post',
306
+ ratio: '1.91:1'
307
+ },
308
+ linkedin: {
309
+ width: 1200,
310
+ height: 627,
311
+ label: 'LinkedIn Post',
312
+ ratio: '1.91:1'
313
+ },
314
+ youtube: {
315
+ width: 1280,
316
+ height: 720,
317
+ label: 'YouTube Thumbnail',
318
+ ratio: '16:9'
319
+ },
320
+ twitter: {
321
+ width: 1200,
322
+ height: 675,
323
+ label: 'Twitter Post',
324
+ ratio: '16:9'
325
+ },
326
+ custom: {
327
+ width: 800,
328
+ height: 800,
329
+ label: 'Custom Size',
330
+ ratio: 'Custom'
331
+ }
332
+ };
333
+
334
+ var SizeSelectorModal = function SizeSelectorModal(_ref) {
335
+ var onSelect = _ref.onSelect,
336
+ onCancel = _ref.onCancel;
337
+ return /*#__PURE__*/React.createElement("div", {
338
+ className: "fixed inset-0 bg-gradient-to-br from-gray-900 via-purple-900 to-gray-900 z-50 flex items-center justify-center p-5"
339
+ }, /*#__PURE__*/React.createElement("button", {
340
+ onClick: onCancel,
341
+ className: "fixed top-6 left-6 w-10 h-10 flex items-center justify-center bg-white bg-opacity-10 hover:bg-opacity-20 rounded-full transition-all"
342
+ }, /*#__PURE__*/React.createElement("svg", {
343
+ className: "w-6 h-6 text-white",
344
+ fill: "none",
345
+ stroke: "currentColor",
346
+ viewBox: "0 0 24 24"
347
+ }, /*#__PURE__*/React.createElement("path", {
348
+ strokeLinecap: "round",
349
+ strokeLinejoin: "round",
350
+ strokeWidth: 2,
351
+ d: "M15 19l-7-7 7-7"
352
+ }))), /*#__PURE__*/React.createElement("div", {
353
+ className: "w-full max-w-4xl bg-gray-800 bg-opacity-50 backdrop-blur-md rounded-2xl shadow-2xl p-8"
354
+ }, /*#__PURE__*/React.createElement("h2", {
355
+ className: "text-white text-3xl font-bold mb-8 text-center"
356
+ }, "Select Platform Size"), /*#__PURE__*/React.createElement("div", {
357
+ className: "grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4"
358
+ }, Object.entries(platformSizes).map(function (_ref2) {
359
+ var _ref3 = _slicedToArray(_ref2, 2),
360
+ key = _ref3[0],
361
+ _ref3$ = _ref3[1],
362
+ width = _ref3$.width,
363
+ height = _ref3$.height,
364
+ label = _ref3$.label,
365
+ ratio = _ref3$.ratio;
366
+ return /*#__PURE__*/React.createElement("div", {
367
+ key: key,
368
+ onClick: function onClick() {
369
+ return onSelect(key);
370
+ },
371
+ className: "p-6 bg-gradient-to-br from-purple-600 to-purple-800 border-2 border-purple-500 border-opacity-30 rounded-xl cursor-pointer text-center text-white transition-all hover:scale-105 hover:shadow-xl hover:border-opacity-100"
372
+ }, /*#__PURE__*/React.createElement("h3", {
373
+ className: "text-xl font-semibold mb-2"
374
+ }, label), /*#__PURE__*/React.createElement("p", {
375
+ className: "text-sm opacity-90"
376
+ }, width, " \xD7 ", height), /*#__PURE__*/React.createElement("p", {
377
+ className: "text-xs opacity-70 mt-1"
378
+ }, ratio));
379
+ }))));
380
+ };
381
+
382
+ // // utils/imageHelpers.js
383
+ // export const getCroppedImg = (imageSrc, pixelCrop) => {
384
+ // return new Promise((resolve, reject) => {
385
+ // const image = new Image();
386
+ // image.src = imageSrc;
387
+ // image.onload = () => {
388
+ // const canvas = document.createElement("canvas");
389
+ // canvas.width = pixelCrop.width;
390
+ // canvas.height = pixelCrop.height;
391
+ // const ctx = canvas.getContext("2d");
392
+
393
+ // ctx.drawImage(
394
+ // image,
395
+ // pixelCrop.x,
396
+ // pixelCrop.y,
397
+ // pixelCrop.width,
398
+ // pixelCrop.height,
399
+ // 0,
400
+ // 0,
401
+ // pixelCrop.width,
402
+ // pixelCrop.height
403
+ // );
404
+
405
+ // canvas.toBlob((blob) => {
406
+ // const file = new File([blob], "cropped_image.png", { type: "image/png" });
407
+ // resolve(URL.createObjectURL(file));
408
+ // }, "image/png");
409
+ // };
410
+ // image.onerror = reject;
411
+ // });
412
+ // };
413
+
414
+ // export const resizeImage = (imageSrc, width, height, format = "png") => {
415
+ // return new Promise((resolve, reject) => {
416
+ // const image = new Image();
417
+ // image.src = imageSrc;
418
+ // image.onload = () => {
419
+ // const canvas = document.createElement("canvas");
420
+ // canvas.width = width;
421
+ // canvas.height = height;
422
+ // const ctx = canvas.getContext("2d");
423
+ // ctx.drawImage(image, 0, 0, width, height);
424
+
425
+ // canvas.toBlob(
426
+ // (blob) => {
427
+ // const file = new File([blob], `resized_image.${format}`, { type: `image/${format}` });
428
+ // resolve(URL.createObjectURL(file));
429
+ // },
430
+ // `image/${format}`,
431
+ // 1
432
+ // );
433
+ // };
434
+ // image.onerror = reject;
435
+ // });
436
+ // };
437
+
438
+ // export const renderImageToCanvas = (canvas, image, settings) => {
439
+ // const ctx = canvas.getContext('2d');
440
+ // const { zoom, brightness, contrast, saturation, crop, dimensions } = settings;
441
+
442
+ // canvas.width = dimensions.width;
443
+ // canvas.height = dimensions.height;
444
+
445
+ // ctx.clearRect(0, 0, canvas.width, canvas.height);
446
+ // ctx.filter = `brightness(${brightness}%) contrast(${contrast}%) saturate(${saturation}%)`;
447
+
448
+ // // Calculate crop area
449
+ // const sx = (image.width * crop.x) / 100;
450
+ // const sy = (image.height * crop.y) / 100;
451
+ // const sWidth = (image.width * crop.width) / 100;
452
+ // const sHeight = (image.height * crop.height) / 100;
453
+
454
+ // // Calculate zoom positioning
455
+ // const scaledWidth = canvas.width * zoom;
456
+ // const scaledHeight = canvas.height * zoom;
457
+ // const offsetX = (canvas.width - scaledWidth) / 2;
458
+ // const offsetY = (canvas.height - scaledHeight) / 2;
459
+
460
+ // ctx.drawImage(image, sx, sy, sWidth, sHeight, offsetX, offsetY, scaledWidth, scaledHeight);
461
+ // };
462
+
463
+ // export const loadImageFromFile = (file) => {
464
+ // return new Promise((resolve, reject) => {
465
+ // const reader = new FileReader();
466
+ // reader.onload = (event) => {
467
+ // const img = new Image();
468
+ // img.onload = () => resolve({ img, dataUrl: event.target.result });
469
+ // img.onerror = reject;
470
+ // img.src = event.target.result;
471
+ // };
472
+ // reader.onerror = reject;
473
+ // reader.readAsDataURL(file);
474
+ // });
475
+ // };
476
+
477
+ var renderImageToCanvas = function renderImageToCanvas(canvas, image, settings) {
478
+ var ctx = canvas.getContext('2d');
479
+ settings.zoom;
480
+ var brightness = settings.brightness,
481
+ contrast = settings.contrast,
482
+ saturation = settings.saturation,
483
+ crop = settings.crop,
484
+ dimensions = settings.dimensions;
485
+ canvas.width = dimensions.width;
486
+ canvas.height = dimensions.height;
487
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
488
+
489
+ // Apply filters
490
+ ctx.filter = "brightness(".concat(brightness, "%) contrast(").concat(contrast, "%) saturate(").concat(saturation, "%)");
491
+
492
+ // Calculate the source crop area (what part of the original image to use)
493
+ var sx = image.width * crop.x / 100;
494
+ var sy = image.height * crop.y / 100;
495
+ var sWidth = image.width * crop.width / 100;
496
+ var sHeight = image.height * crop.height / 100;
497
+
498
+ // Draw the cropped portion to fill the entire canvas
499
+ ctx.drawImage(image, sx, sy, sWidth, sHeight,
500
+ // Source: cropped area from original image
501
+ 0, 0, canvas.width, canvas.height // Destination: fill entire canvas
502
+ );
503
+ };
504
+ var loadImageFromFile = function loadImageFromFile(file) {
505
+ return new Promise(function (resolve, reject) {
506
+ var reader = new FileReader();
507
+ reader.onload = function (event) {
508
+ var img = new Image();
509
+ img.onload = function () {
510
+ return resolve({
511
+ img: img,
512
+ dataUrl: event.target.result
513
+ });
514
+ };
515
+ img.onerror = reject;
516
+ img.src = event.target.result;
517
+ };
518
+ reader.onerror = reject;
519
+ reader.readAsDataURL(file);
520
+ });
521
+ };
522
+
523
+ var CanvasEditor = function CanvasEditor(_ref) {
524
+ var image = _ref.image,
525
+ settings = _ref.settings,
526
+ onCropChange = _ref.onCropChange;
527
+ var canvasRef = React.useRef(null);
528
+ var containerRef = React.useRef(null);
529
+ var dragStartRef = React.useRef({
530
+ x: 0,
531
+ y: 0
532
+ });
533
+ var cropStartRef = React.useRef(null);
534
+ var _useState = React.useState(false),
535
+ _useState2 = _slicedToArray(_useState, 2),
536
+ isDragging = _useState2[0],
537
+ setIsDragging = _useState2[1];
538
+ var _useState3 = React.useState(null),
539
+ _useState4 = _slicedToArray(_useState3, 2),
540
+ dragHandle = _useState4[0],
541
+ setDragHandle = _useState4[1];
542
+ var _useState5 = React.useState({
543
+ x: 10,
544
+ y: 10,
545
+ width: 80,
546
+ height: 80
547
+ }),
548
+ _useState6 = _slicedToArray(_useState5, 2),
549
+ cropBox = _useState6[0],
550
+ setCropBox = _useState6[1];
551
+ var _useState7 = React.useState({
552
+ width: 0,
553
+ height: 0
554
+ }),
555
+ _useState8 = _slicedToArray(_useState7, 2);
556
+ _useState8[0];
557
+ var setCanvasSize = _useState8[1];
558
+ React.useEffect(function () {
559
+ if (image && canvasRef.current) {
560
+ renderImageToCanvas(canvasRef.current, image, settings);
561
+ // Update canvas size for overlay positioning
562
+ var rect = canvasRef.current.getBoundingClientRect();
563
+ setCanvasSize({
564
+ width: rect.width,
565
+ height: rect.height
566
+ });
567
+ }
568
+ }, [image, settings]);
569
+ React.useEffect(function () {
570
+ setCropBox({
571
+ x: settings.crop.x,
572
+ y: settings.crop.y,
573
+ width: settings.crop.width,
574
+ height: settings.crop.height
575
+ });
576
+ }, [settings.crop]);
577
+
578
+ // const handleMouseDown = (e, handle) => {
579
+ // e.preventDefault();
580
+ // e.stopPropagation();
581
+ // setIsDragging(true);
582
+ // setDragHandle(handle);
583
+ // };
584
+ var handleMouseDown = function handleMouseDown(e, handle) {
585
+ e.preventDefault();
586
+ e.stopPropagation();
587
+ var rect = canvasRef.current.getBoundingClientRect();
588
+ dragStartRef.current = {
589
+ x: (e.clientX - rect.left) / rect.width * 100,
590
+ y: (e.clientY - rect.top) / rect.height * 100
591
+ };
592
+ cropStartRef.current = _objectSpread2({}, cropBox);
593
+ setIsDragging(true);
594
+ setDragHandle(handle);
595
+ };
596
+ var handleMouseMove = function handleMouseMove(e) {
597
+ if (!isDragging || !canvasRef.current) return;
598
+ var rect = canvasRef.current.getBoundingClientRect();
599
+ var mouseX = (e.clientX - rect.left) / rect.width * 100;
600
+ var mouseY = (e.clientY - rect.top) / rect.height * 100;
601
+ var dx = mouseX - dragStartRef.current.x;
602
+ var dy = mouseY - dragStartRef.current.y;
603
+ var newCrop = _objectSpread2({}, cropStartRef.current);
604
+ if (dragHandle === 'move') {
605
+ newCrop.x = Math.min(100 - newCrop.width, Math.max(0, cropStartRef.current.x + dx));
606
+ newCrop.y = Math.min(100 - newCrop.height, Math.max(0, cropStartRef.current.y + dy));
607
+ }
608
+ if (dragHandle === 'nw') {
609
+ newCrop.x = Math.max(0, cropStartRef.current.x + dx);
610
+ newCrop.y = Math.max(0, cropStartRef.current.y + dy);
611
+ newCrop.width = cropStartRef.current.width - dx;
612
+ newCrop.height = cropStartRef.current.height - dy;
613
+ }
614
+ if (dragHandle === 'ne') {
615
+ newCrop.y = Math.max(0, cropStartRef.current.y + dy);
616
+ newCrop.width = cropStartRef.current.width + dx;
617
+ newCrop.height = cropStartRef.current.height - dy;
618
+ }
619
+ if (dragHandle === 'sw') {
620
+ newCrop.x = Math.max(0, cropStartRef.current.x + dx);
621
+ newCrop.width = cropStartRef.current.width - dx;
622
+ newCrop.height = cropStartRef.current.height + dy;
623
+ }
624
+ if (dragHandle === 'se') {
625
+ newCrop.width = cropStartRef.current.width + dx;
626
+ newCrop.height = cropStartRef.current.height + dy;
627
+ }
628
+
629
+ // ✅ Minimum size + bounds
630
+ if (newCrop.width >= 10 && newCrop.height >= 10 && newCrop.x + newCrop.width <= 100 && newCrop.y + newCrop.height <= 100) {
631
+ setCropBox(newCrop);
632
+ onCropChange(newCrop);
633
+ }
634
+ };
635
+ var handleMouseUp = function handleMouseUp() {
636
+ setIsDragging(false);
637
+ setDragHandle(null);
638
+ };
639
+ React.useEffect(function () {
640
+ if (isDragging) {
641
+ window.addEventListener('mousemove', handleMouseMove);
642
+ window.addEventListener('mouseup', handleMouseUp);
643
+ return function () {
644
+ window.removeEventListener('mousemove', handleMouseMove);
645
+ window.removeEventListener('mouseup', handleMouseUp);
646
+ };
647
+ }
648
+ }, [isDragging]);
649
+ return /*#__PURE__*/React.createElement("div", {
650
+ className: "relative w-full h-full flex items-center justify-center"
651
+ }, /*#__PURE__*/React.createElement("div", {
652
+ ref: containerRef,
653
+ className: "relative inline-block"
654
+ }, /*#__PURE__*/React.createElement("canvas", {
655
+ ref: canvasRef,
656
+ className: "max-w-full max-h-full rounded-lg shadow-2xl block relative",
657
+ style: {
658
+ position: 'relative',
659
+ zIndex: 1
660
+ }
661
+ }), /*#__PURE__*/React.createElement("div", {
662
+ className: "absolute border-2 border-purple-400 cursor-move",
663
+ style: {
664
+ left: "".concat(cropBox.x, "%"),
665
+ top: "".concat(cropBox.y, "%"),
666
+ width: "".concat(cropBox.width, "%"),
667
+ height: "".concat(cropBox.height, "%"),
668
+ boxShadow: '0 0 0 9999px rgba(0,0,0,0.6)',
669
+ zIndex: 10
670
+ },
671
+ onMouseDown: function onMouseDown(e) {
672
+ return handleMouseDown(e, 'move');
673
+ }
674
+ }, /*#__PURE__*/React.createElement("div", {
675
+ className: "absolute w-6 h-6 bg-white border-3 border-purple-500 rounded-full cursor-nw-resize shadow-lg",
676
+ style: {
677
+ left: '-12px',
678
+ top: '-12px',
679
+ zIndex: 100
680
+ },
681
+ onMouseDown: function onMouseDown(e) {
682
+ return handleMouseDown(e, 'nw');
683
+ }
684
+ }), /*#__PURE__*/React.createElement("div", {
685
+ className: "absolute w-6 h-6 bg-white border-3 border-purple-500 rounded-full cursor-ne-resize shadow-lg",
686
+ style: {
687
+ right: '-12px',
688
+ top: '-12px',
689
+ zIndex: 100
690
+ },
691
+ onMouseDown: function onMouseDown(e) {
692
+ return handleMouseDown(e, 'ne');
693
+ }
694
+ }), /*#__PURE__*/React.createElement("div", {
695
+ className: "absolute w-6 h-6 bg-white border-3 border-purple-500 rounded-full cursor-sw-resize shadow-lg",
696
+ style: {
697
+ left: '-12px',
698
+ bottom: '-12px',
699
+ zIndex: 100
700
+ },
701
+ onMouseDown: function onMouseDown(e) {
702
+ return handleMouseDown(e, 'sw');
703
+ }
704
+ }), /*#__PURE__*/React.createElement("div", {
705
+ className: "absolute w-6 h-6 bg-white border-3 border-purple-500 rounded-full cursor-se-resize shadow-lg",
706
+ style: {
707
+ right: '-12px',
708
+ bottom: '-12px',
709
+ zIndex: 100
710
+ },
711
+ onMouseDown: function onMouseDown(e) {
712
+ return handleMouseDown(e, 'se');
713
+ }
714
+ }), /*#__PURE__*/React.createElement("div", {
715
+ className: "absolute inset-0 grid grid-cols-3 grid-rows-3 pointer-events-none"
716
+ }, _toConsumableArray(Array(9)).map(function (_, i) {
717
+ return /*#__PURE__*/React.createElement("div", {
718
+ key: i,
719
+ className: "border border-white border-opacity-40"
720
+ });
721
+ })))));
722
+ };
723
+
724
+ var RightToolbar = function RightToolbar(_ref) {
725
+ var settings = _ref.settings,
726
+ onSettingsChange = _ref.onSettingsChange,
727
+ imageData = _ref.imageData;
728
+ var zoom = settings.zoom,
729
+ brightness = settings.brightness,
730
+ contrast = settings.contrast,
731
+ saturation = settings.saturation,
732
+ crop = settings.crop,
733
+ dimensions = settings.dimensions;
734
+ var _useState = React.useState('no-change'),
735
+ _useState2 = _slicedToArray(_useState, 2),
736
+ resizeMode = _useState2[0],
737
+ setResizeMode = _useState2[1];
738
+ var _useState3 = React.useState(''),
739
+ _useState4 = _slicedToArray(_useState3, 2),
740
+ customWidth = _useState4[0],
741
+ setCustomWidth = _useState4[1];
742
+ var _useState5 = React.useState(''),
743
+ _useState6 = _slicedToArray(_useState5, 2),
744
+ customHeight = _useState6[0],
745
+ setCustomHeight = _useState6[1];
746
+ var handleChange = function handleChange(key, value) {
747
+ onSettingsChange(_objectSpread2(_objectSpread2({}, settings), {}, _defineProperty({}, key, value)));
748
+ };
749
+ var handleCropChange = function handleCropChange(key, value) {
750
+ onSettingsChange(_objectSpread2(_objectSpread2({}, settings), {}, {
751
+ crop: _objectSpread2(_objectSpread2({}, crop), {}, _defineProperty({}, key, value))
752
+ }));
753
+ };
754
+ var handleResizeChange = function handleResizeChange(mode) {
755
+ setResizeMode(mode);
756
+ var newDimensions = _objectSpread2({}, dimensions);
757
+ if (mode === 'no-change') {
758
+ newDimensions = imageData ? {
759
+ width: imageData.width,
760
+ height: imageData.height
761
+ } : dimensions;
762
+ } else if (mode === '25-smaller') {
763
+ newDimensions = {
764
+ width: Math.round(dimensions.width * 0.75),
765
+ height: Math.round(dimensions.height * 0.75)
766
+ };
767
+ } else if (mode === '50-smaller') {
768
+ newDimensions = {
769
+ width: Math.round(dimensions.width * 0.5),
770
+ height: Math.round(dimensions.height * 0.5)
771
+ };
772
+ } else if (mode === '75-smaller') {
773
+ newDimensions = {
774
+ width: Math.round(dimensions.width * 0.25),
775
+ height: Math.round(dimensions.height * 0.25)
776
+ };
777
+ } else if (mode === 'fit-800') {
778
+ var maxDim = 800;
779
+ var ratio = Math.min(maxDim / dimensions.width, maxDim / dimensions.height);
780
+ newDimensions = {
781
+ width: Math.round(dimensions.width * ratio),
782
+ height: Math.round(dimensions.height * ratio)
783
+ };
784
+ }
785
+ onSettingsChange(_objectSpread2(_objectSpread2({}, settings), {}, {
786
+ dimensions: newDimensions
787
+ }));
788
+ };
789
+ var handleCustomResize = function handleCustomResize() {
790
+ var width = parseInt(customWidth) || dimensions.width;
791
+ var height = parseInt(customHeight) || dimensions.height;
792
+ onSettingsChange(_objectSpread2(_objectSpread2({}, settings), {}, {
793
+ dimensions: {
794
+ width: width,
795
+ height: height
796
+ }
797
+ }));
798
+ };
799
+ var SliderControl = function SliderControl(_ref2) {
800
+ var label = _ref2.label,
801
+ value = _ref2.value,
802
+ _onChange = _ref2.onChange,
803
+ _ref2$min = _ref2.min,
804
+ min = _ref2$min === void 0 ? 0 : _ref2$min,
805
+ _ref2$max = _ref2.max,
806
+ max = _ref2$max === void 0 ? 200 : _ref2$max,
807
+ _ref2$step = _ref2.step,
808
+ step = _ref2$step === void 0 ? 1 : _ref2$step,
809
+ _ref2$unit = _ref2.unit,
810
+ unit = _ref2$unit === void 0 ? '%' : _ref2$unit;
811
+ return /*#__PURE__*/React.createElement("div", {
812
+ className: "mb-5"
813
+ }, /*#__PURE__*/React.createElement("label", {
814
+ className: "block text-sm font-semibold mb-2 text-white"
815
+ }, label, ": ", /*#__PURE__*/React.createElement("span", {
816
+ className: "text-purple-300 font-bold"
817
+ }, value, unit)), /*#__PURE__*/React.createElement("input", {
818
+ type: "range",
819
+ min: min,
820
+ max: max,
821
+ step: step,
822
+ value: value,
823
+ onChange: function onChange(e) {
824
+ return _onChange(parseFloat(e.target.value));
825
+ },
826
+ className: "w-full h-2 bg-gray-600 rounded-lg appearance-none cursor-pointer accent-purple-500"
827
+ }));
828
+ };
829
+ var originalDimensions = imageData ? {
830
+ width: imageData.width,
831
+ height: imageData.height
832
+ } : dimensions;
833
+ var croppedWidth = Math.round(originalDimensions.width * crop.width / 100);
834
+ var croppedHeight = Math.round(originalDimensions.height * crop.height / 100);
835
+ return /*#__PURE__*/React.createElement("div", {
836
+ className: "flex-1 overflow-y-auto p-6 bg-slate-800"
837
+ }, /*#__PURE__*/React.createElement("h3", {
838
+ className: "text-white text-xl font-bold mb-6 pb-3 border-b border-gray-600"
839
+ }, "Edit Controls"), /*#__PURE__*/React.createElement("div", {
840
+ className: "mb-6 pb-6 border-b border-gray-600"
841
+ }, /*#__PURE__*/React.createElement("h4", {
842
+ className: "text-white text-base font-bold mb-3"
843
+ }, "Resize Image"), /*#__PURE__*/React.createElement("label", {
844
+ className: "block text-sm font-semibold mb-2 text-white"
845
+ }, "Select new size:"), /*#__PURE__*/React.createElement("select", {
846
+ value: resizeMode,
847
+ onChange: function onChange(e) {
848
+ return handleResizeChange(e.target.value);
849
+ },
850
+ className: "w-full p-2.5 bg-gray-700 text-white rounded-lg border-2 border-gray-600 focus:border-purple-400 focus:ring-2 focus:ring-purple-400 focus:outline-none mb-3 text-sm font-medium"
851
+ }, /*#__PURE__*/React.createElement("option", {
852
+ value: "no-change"
853
+ }, "No change"), /*#__PURE__*/React.createElement("option", {
854
+ value: "25-smaller"
855
+ }, "25% smaller"), /*#__PURE__*/React.createElement("option", {
856
+ value: "50-smaller"
857
+ }, "50% smaller"), /*#__PURE__*/React.createElement("option", {
858
+ value: "75-smaller"
859
+ }, "75% smaller"), /*#__PURE__*/React.createElement("option", {
860
+ value: "fit-800"
861
+ }, "Fit to screen: 800 resolution"), /*#__PURE__*/React.createElement("option", {
862
+ value: "custom"
863
+ }, "Custom Size...")), resizeMode === 'custom' && /*#__PURE__*/React.createElement("div", {
864
+ className: "space-y-2"
865
+ }, /*#__PURE__*/React.createElement("div", {
866
+ className: "flex gap-2"
867
+ }, /*#__PURE__*/React.createElement("input", {
868
+ type: "number",
869
+ placeholder: "Width",
870
+ value: customWidth,
871
+ onChange: function onChange(e) {
872
+ return setCustomWidth(e.target.value);
873
+ },
874
+ className: "flex-1 p-2 bg-gray-700 text-white text-sm rounded-lg border-2 border-gray-600 focus:border-purple-400 focus:ring-2 focus:ring-purple-400 focus:outline-none font-medium"
875
+ }), /*#__PURE__*/React.createElement("span", {
876
+ className: "text-white self-center text-sm font-bold"
877
+ }, "\xD7"), /*#__PURE__*/React.createElement("input", {
878
+ type: "number",
879
+ placeholder: "Height",
880
+ value: customHeight,
881
+ onChange: function onChange(e) {
882
+ return setCustomHeight(e.target.value);
883
+ },
884
+ className: "flex-1 p-2 bg-gray-700 text-white text-sm rounded-lg border-2 border-gray-600 focus:border-purple-400 focus:ring-2 focus:ring-purple-400 focus:outline-none font-medium"
885
+ })), /*#__PURE__*/React.createElement("button", {
886
+ onClick: handleCustomResize,
887
+ className: "w-full px-4 py-2 bg-purple-600 text-white text-sm font-bold rounded-lg hover:bg-purple-700 transition-colors"
888
+ }, "Apply Custom Size")), /*#__PURE__*/React.createElement("div", {
889
+ className: "mt-3 text-xs bg-slate-900 rounded-lg p-3 border border-gray-700"
890
+ }, /*#__PURE__*/React.createElement("div", {
891
+ className: "grid grid-cols-3 gap-2"
892
+ }, /*#__PURE__*/React.createElement("div", {
893
+ className: "font-bold text-white"
894
+ }, "Your Image"), /*#__PURE__*/React.createElement("div", {
895
+ className: "text-center font-bold text-white"
896
+ }, "Width(px)"), /*#__PURE__*/React.createElement("div", {
897
+ className: "text-center font-bold text-white"
898
+ }, "Height(px)"), /*#__PURE__*/React.createElement("div", {
899
+ className: "text-gray-300 font-semibold"
900
+ }, "Original"), /*#__PURE__*/React.createElement("div", {
901
+ className: "text-center text-white font-semibold"
902
+ }, originalDimensions.width), /*#__PURE__*/React.createElement("div", {
903
+ className: "text-center text-white font-semibold"
904
+ }, originalDimensions.height), /*#__PURE__*/React.createElement("div", {
905
+ className: "text-gray-300 font-semibold"
906
+ }, "Cropped"), /*#__PURE__*/React.createElement("div", {
907
+ className: "text-center text-white font-semibold"
908
+ }, croppedWidth), /*#__PURE__*/React.createElement("div", {
909
+ className: "text-center text-white font-semibold"
910
+ }, croppedHeight), /*#__PURE__*/React.createElement("div", {
911
+ className: "text-green-400 font-bold"
912
+ }, "Final"), /*#__PURE__*/React.createElement("div", {
913
+ className: "text-center text-green-400 font-bold"
914
+ }, dimensions.width), /*#__PURE__*/React.createElement("div", {
915
+ className: "text-center text-green-400 font-bold"
916
+ }, dimensions.height)))), /*#__PURE__*/React.createElement(SliderControl, {
917
+ label: "Zoom",
918
+ value: zoom,
919
+ onChange: function onChange(val) {
920
+ return handleChange('zoom', val);
921
+ },
922
+ min: 0.5,
923
+ max: 3,
924
+ step: 0.1,
925
+ unit: "x"
926
+ }), /*#__PURE__*/React.createElement(SliderControl, {
927
+ label: "Brightness",
928
+ value: brightness,
929
+ onChange: function onChange(val) {
930
+ return handleChange('brightness', val);
931
+ }
932
+ }), /*#__PURE__*/React.createElement(SliderControl, {
933
+ label: "Contrast",
934
+ value: contrast,
935
+ onChange: function onChange(val) {
936
+ return handleChange('contrast', val);
937
+ }
938
+ }), /*#__PURE__*/React.createElement(SliderControl, {
939
+ label: "Saturation",
940
+ value: saturation,
941
+ onChange: function onChange(val) {
942
+ return handleChange('saturation', val);
943
+ }
944
+ }), /*#__PURE__*/React.createElement("div", {
945
+ className: "border-t border-gray-600 pt-4 mt-4"
946
+ }, /*#__PURE__*/React.createElement("h4", {
947
+ className: "text-white text-base font-bold mb-4"
948
+ }, "Crop Position"), /*#__PURE__*/React.createElement(SliderControl, {
949
+ label: "Crop X",
950
+ value: crop.x,
951
+ onChange: function onChange(val) {
952
+ return handleCropChange('x', val);
953
+ },
954
+ max: 50
955
+ }), /*#__PURE__*/React.createElement(SliderControl, {
956
+ label: "Crop Y",
957
+ value: crop.y,
958
+ onChange: function onChange(val) {
959
+ return handleCropChange('y', val);
960
+ },
961
+ max: 50
962
+ })));
963
+ };
964
+
965
+ var BottomActions = function BottomActions(_ref) {
966
+ var onSubmit = _ref.onSubmit,
967
+ onDownload = _ref.onDownload;
968
+ return /*#__PURE__*/React.createElement("div", {
969
+ className: "flex justify-end gap-3"
970
+ }, /*#__PURE__*/React.createElement("button", {
971
+ onClick: onDownload,
972
+ className: "px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 transition-all shadow-lg hover:shadow-xl"
973
+ }, "\u2B07 Download"), /*#__PURE__*/React.createElement("button", {
974
+ onClick: onSubmit,
975
+ className: "px-4 py-2 bg-green-600 text-white text-sm font-medium rounded-lg hover:bg-green-700 transition-all shadow-lg hover:shadow-xl"
976
+ }, "\u2713 Submit"));
977
+ };
978
+
979
+ // export const canvasToBlob = (canvas, format = 'image/png', quality = 1) => {
980
+ // return new Promise((resolve) => {
981
+ // canvas.toBlob((blob) => {
982
+ // const file = new File([blob], `psh-edited-${Date.now()}.png`, { type: format });
983
+ // resolve(file);
984
+ // }, format, quality);
985
+ // });
986
+ // };
987
+
988
+ // export const downloadFromCanvas = (canvas, filename = `psh-image-${Date.now()}.png`) => {
989
+ // const link = document.createElement('a');
990
+ // link.download = filename;
991
+ // link.href = canvas.toDataURL('image/png');
992
+ // link.click();
993
+ // };
994
+
995
+ var canvasToBlob = function canvasToBlob(canvas) {
996
+ var format = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'image/png';
997
+ var quality = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;
998
+ return new Promise(function (resolve) {
999
+ canvas.toBlob(function (blob) {
1000
+ var file = new File([blob], "psh-edited-".concat(Date.now(), ".png"), {
1001
+ type: format
1002
+ });
1003
+ resolve(file);
1004
+ }, format, quality);
1005
+ });
1006
+ };
1007
+ var downloadFromCanvas = function downloadFromCanvas(canvas) {
1008
+ var filename = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "psh-image-".concat(Date.now(), ".png");
1009
+ var link = document.createElement('a');
1010
+ link.download = filename;
1011
+ link.href = canvas.toDataURL('image/png');
1012
+ link.click();
1013
+ };
1014
+
1015
+ var ImageEditorModal = function ImageEditorModal(_ref) {
1016
+ var image = _ref.image,
1017
+ settings = _ref.settings,
1018
+ onSettingsChange = _ref.onSettingsChange,
1019
+ onSubmit = _ref.onSubmit,
1020
+ onCancel = _ref.onCancel,
1021
+ onBackToSizeSelector = _ref.onBackToSizeSelector;
1022
+ React.useRef(null);
1023
+ var handleCropChange = function handleCropChange(newCrop) {
1024
+ onSettingsChange(_objectSpread2(_objectSpread2({}, settings), {}, {
1025
+ crop: newCrop
1026
+ }));
1027
+ };
1028
+ var handleSubmit = /*#__PURE__*/function () {
1029
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
1030
+ var canvas, file;
1031
+ return _regenerator().w(function (_context) {
1032
+ while (1) switch (_context.n) {
1033
+ case 0:
1034
+ canvas = document.querySelector('canvas');
1035
+ if (!canvas) {
1036
+ _context.n = 2;
1037
+ break;
1038
+ }
1039
+ _context.n = 1;
1040
+ return canvasToBlob(canvas);
1041
+ case 1:
1042
+ file = _context.v;
1043
+ onSubmit(file);
1044
+ case 2:
1045
+ return _context.a(2);
1046
+ }
1047
+ }, _callee);
1048
+ }));
1049
+ return function handleSubmit() {
1050
+ return _ref2.apply(this, arguments);
1051
+ };
1052
+ }();
1053
+ var handleDownload = function handleDownload() {
1054
+ var canvas = document.querySelector('canvas');
1055
+ if (canvas) {
1056
+ downloadFromCanvas(canvas);
1057
+ }
1058
+ };
1059
+ return /*#__PURE__*/React.createElement("div", {
1060
+ className: "fixed inset-0 bg-gradient-to-br from-slate-900 via-purple-900 to-slate-900 z-50 flex items-center justify-center p-5"
1061
+ }, /*#__PURE__*/React.createElement("button", {
1062
+ onClick: onBackToSizeSelector,
1063
+ className: "fixed top-6 left-6 w-10 h-10 flex items-center justify-center bg-white bg-opacity-10 hover:bg-opacity-20 rounded-full transition-all z-10"
1064
+ }, /*#__PURE__*/React.createElement("svg", {
1065
+ className: "w-6 h-6 text-white",
1066
+ fill: "none",
1067
+ stroke: "currentColor",
1068
+ viewBox: "0 0 24 24"
1069
+ }, /*#__PURE__*/React.createElement("path", {
1070
+ strokeLinecap: "round",
1071
+ strokeLinejoin: "round",
1072
+ strokeWidth: 2,
1073
+ d: "M15 19l-7-7 7-7"
1074
+ }))), /*#__PURE__*/React.createElement("div", {
1075
+ className: "w-full max-w-6xl h-[90vh] bg-slate-800 bg-opacity-60 backdrop-blur-lg rounded-2xl shadow-2xl overflow-hidden flex"
1076
+ }, /*#__PURE__*/React.createElement("div", {
1077
+ className: "flex-1 flex items-center justify-center p-8 bg-gradient-to-br from-gray-900 to-gray-800"
1078
+ }, /*#__PURE__*/React.createElement(CanvasEditor, {
1079
+ image: image,
1080
+ settings: settings,
1081
+ onCropChange: handleCropChange
1082
+ })), /*#__PURE__*/React.createElement("div", {
1083
+ className: "w-80 flex z-10 flex-col bg-slate-800 border-l border-gray-700 shadow-2xl"
1084
+ }, /*#__PURE__*/React.createElement(RightToolbar, {
1085
+ settings: settings,
1086
+ onSettingsChange: onSettingsChange,
1087
+ imageData: image
1088
+ }), /*#__PURE__*/React.createElement("div", {
1089
+ className: "p-4 bg-slate-900 border-t border-gray-700"
1090
+ }, /*#__PURE__*/React.createElement(BottomActions, {
1091
+ onSubmit: handleSubmit,
1092
+ onDownload: handleDownload,
1093
+ onCancel: onCancel
1094
+ })))));
1095
+ };
1096
+
1097
+ var PSHImageEditor = function PSHImageEditor(_ref) {
1098
+ var onSubmit = _ref.onSubmit,
1099
+ name = _ref.name;
1100
+ _ref.width;
1101
+ _ref.height;
1102
+ var _useState = React.useState(null),
1103
+ _useState2 = _slicedToArray(_useState, 2);
1104
+ _useState2[0];
1105
+ var setUploadedFile = _useState2[1];
1106
+ var _useState3 = React.useState(null),
1107
+ _useState4 = _slicedToArray(_useState3, 2),
1108
+ imageData = _useState4[0],
1109
+ setImageData = _useState4[1];
1110
+ var _useState5 = React.useState(false),
1111
+ _useState6 = _slicedToArray(_useState5, 2),
1112
+ showSizeSelector = _useState6[0],
1113
+ setShowSizeSelector = _useState6[1];
1114
+ var _useState7 = React.useState(false),
1115
+ _useState8 = _slicedToArray(_useState7, 2),
1116
+ showEditor = _useState8[0],
1117
+ setShowEditor = _useState8[1];
1118
+ var _useState9 = React.useState({
1119
+ zoom: 1,
1120
+ brightness: 100,
1121
+ contrast: 100,
1122
+ saturation: 100,
1123
+ crop: {
1124
+ x: 0,
1125
+ y: 0,
1126
+ width: 100,
1127
+ height: 100
1128
+ },
1129
+ dimensions: {
1130
+ width: 800,
1131
+ height: 800
1132
+ }
1133
+ }),
1134
+ _useState0 = _slicedToArray(_useState9, 2),
1135
+ settings = _useState0[0],
1136
+ setSettings = _useState0[1];
1137
+ var handleUpload = /*#__PURE__*/function () {
1138
+ var _ref2 = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(file) {
1139
+ var _yield$loadImageFromF, img, _t;
1140
+ return _regenerator().w(function (_context) {
1141
+ while (1) switch (_context.p = _context.n) {
1142
+ case 0:
1143
+ _context.p = 0;
1144
+ _context.n = 1;
1145
+ return loadImageFromFile(file);
1146
+ case 1:
1147
+ _yield$loadImageFromF = _context.v;
1148
+ img = _yield$loadImageFromF.img;
1149
+ _yield$loadImageFromF.dataUrl;
1150
+ setUploadedFile(file);
1151
+ setImageData(img);
1152
+ setShowSizeSelector(true);
1153
+ _context.n = 3;
1154
+ break;
1155
+ case 2:
1156
+ _context.p = 2;
1157
+ _t = _context.v;
1158
+ console.error('Error loading image:', _t);
1159
+ alert('Failed to load image. Please try again.');
1160
+ case 3:
1161
+ return _context.a(2);
1162
+ }
1163
+ }, _callee, null, [[0, 2]]);
1164
+ }));
1165
+ return function handleUpload(_x) {
1166
+ return _ref2.apply(this, arguments);
1167
+ };
1168
+ }();
1169
+ var handleSizeSelect = function handleSizeSelect(platformKey) {
1170
+ var size = platformSizes[platformKey];
1171
+ setSettings(_objectSpread2(_objectSpread2({}, settings), {}, {
1172
+ dimensions: {
1173
+ width: size.width,
1174
+ height: size.height
1175
+ }
1176
+ }));
1177
+ setShowSizeSelector(false);
1178
+ setShowEditor(true);
1179
+ };
1180
+ var handleBackToSizeSelector = function handleBackToSizeSelector() {
1181
+ setShowEditor(false);
1182
+ setShowSizeSelector(true);
1183
+ };
1184
+ var handleEditorSubmit = function handleEditorSubmit(file) {
1185
+ onSubmit(file);
1186
+ resetEditor();
1187
+ };
1188
+ var resetEditor = function resetEditor() {
1189
+ setUploadedFile(null);
1190
+ setImageData(null);
1191
+ setShowSizeSelector(false);
1192
+ setShowEditor(false);
1193
+ setSettings({
1194
+ zoom: 1,
1195
+ brightness: 100,
1196
+ contrast: 100,
1197
+ saturation: 100,
1198
+ crop: {
1199
+ x: 0,
1200
+ y: 0,
1201
+ width: 100,
1202
+ height: 100
1203
+ },
1204
+ dimensions: {
1205
+ width: 800,
1206
+ height: 800
1207
+ }
1208
+ });
1209
+ };
1210
+ return /*#__PURE__*/React.createElement(React.Fragment, null, !showSizeSelector && !showEditor && /*#__PURE__*/React.createElement(UploadButton, {
1211
+ onUpload: handleUpload,
1212
+ name: name
1213
+ }), showSizeSelector && /*#__PURE__*/React.createElement(SizeSelectorModal, {
1214
+ onSelect: handleSizeSelect,
1215
+ onCancel: resetEditor
1216
+ }), showEditor && imageData && /*#__PURE__*/React.createElement(ImageEditorModal, {
1217
+ image: imageData,
1218
+ settings: settings,
1219
+ onSettingsChange: setSettings,
1220
+ onSubmit: handleEditorSubmit,
1221
+ onCancel: resetEditor,
1222
+ onBackToSizeSelector: handleBackToSizeSelector
1223
+ }));
1224
+ };
1225
+
1226
+ module.exports = PSHImageEditor;