ikoncomponents 1.2.0 → 1.2.2
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/ikoncomponents/activity-sheet/index.d.ts +11 -0
- package/dist/ikoncomponents/activity-sheet/index.js +23 -0
- package/dist/ikoncomponents/big-calendar/big-calender-event/index.d.ts +5 -0
- package/dist/ikoncomponents/big-calendar/big-calender-event/index.js +16 -0
- package/dist/ikoncomponents/big-calendar/big-calender-toolbar/index.d.ts +2 -0
- package/dist/ikoncomponents/big-calendar/big-calender-toolbar/index.js +39 -0
- package/dist/ikoncomponents/big-calendar/index.d.ts +4 -0
- package/dist/ikoncomponents/big-calendar/index.js +35 -0
- package/dist/ikoncomponents/big-calendar/type.d.ts +31 -0
- package/dist/ikoncomponents/big-calendar/type.js +1 -0
- package/dist/ikoncomponents/form-fields/combobox-input-value/index.js +1 -0
- package/dist/ikoncomponents/image-cropper-upload/components/newCropper.d.ts +15 -0
- package/dist/ikoncomponents/image-cropper-upload/components/newCropper.js +85 -0
- package/dist/ikoncomponents/image-cropper-upload/components/newImageUploadForm.d.ts +7 -0
- package/dist/ikoncomponents/image-cropper-upload/components/newImageUploadForm.js +145 -0
- package/dist/ikoncomponents/image-cropper-upload/cropper-form/index.d.ts +6 -0
- package/dist/ikoncomponents/image-cropper-upload/cropper-form/index.js +92 -0
- package/dist/ikoncomponents/image-cropper-upload/cropper-form-with-modal/index.d.ts +6 -0
- package/dist/ikoncomponents/image-cropper-upload/cropper-form-with-modal/index.js +14 -0
- package/dist/ikoncomponents/image-cropper-upload/image-cropper/index.d.ts +14 -0
- package/dist/ikoncomponents/image-cropper-upload/image-cropper/index.js +87 -0
- package/dist/ikoncomponents/image-cropper-upload/index.d.ts +27 -0
- package/dist/ikoncomponents/image-cropper-upload/index.js +49 -0
- package/dist/ikoncomponents/image-cropper-upload/utils/index.d.ts +16 -0
- package/dist/ikoncomponents/image-cropper-upload/utils/index.js +73 -0
- package/dist/ikoncomponents/main-layout/main-sidebar.d.ts +5 -9
- package/dist/ikoncomponents/main-layout/main-sidebar.js +2 -2
- package/dist/ikoncomponents/provider-wrapper/index.d.ts +5 -0
- package/dist/ikoncomponents/provider-wrapper/index.js +10 -0
- package/dist/ikoncomponents/resource-spreadsheet/index.d.ts +21 -21
- package/dist/ikoncomponents/resource-spreadsheet/index.js +36 -36
- package/dist/index.d.ts +15 -0
- package/dist/index.js +9 -0
- package/dist/styles.css +95 -0
- package/dist/utils/actions/account/index.d.ts +5 -0
- package/dist/utils/actions/account/index.js +28 -0
- package/dist/utils/actions/account/type.d.ts +4 -0
- package/dist/utils/actions/account/type.js +1 -0
- package/dist/utils/actions/auth/index.d.ts +7 -0
- package/dist/utils/actions/auth/index.js +58 -0
- package/dist/utils/actions/common/utils.d.ts +5 -0
- package/dist/utils/actions/common/utils.js +25 -0
- package/dist/utils/actions/software/index.d.ts +11 -0
- package/dist/utils/actions/software/index.js +75 -0
- package/dist/utils/api/accountService/index.d.ts +23 -0
- package/dist/utils/api/accountService/index.js +64 -0
- package/dist/utils/api/accountService/type.d.ts +4 -0
- package/dist/utils/api/accountService/type.js +1 -0
- package/dist/utils/api/file-upload/index.d.ts +5 -0
- package/dist/utils/api/file-upload/index.js +80 -0
- package/dist/utils/api/file-upload/type.d.ts +6 -0
- package/dist/utils/api/file-upload/type.js +1 -0
- package/dist/utils/api/ikonBaseApi.d.ts +12 -0
- package/dist/utils/api/ikonBaseApi.js +104 -0
- package/dist/utils/api/loginService/index.d.ts +12 -0
- package/dist/utils/api/loginService/index.js +72 -0
- package/dist/utils/api/loginService/type.d.ts +31 -0
- package/dist/utils/api/loginService/type.js +1 -0
- package/dist/utils/api/softwareService/index.d.ts +64 -0
- package/dist/utils/api/softwareService/index.js +212 -0
- package/dist/utils/api/softwareService/type.d.ts +54 -0
- package/dist/utils/api/softwareService/type.js +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export type ActivityLogProps = {
|
|
2
|
+
id: string;
|
|
3
|
+
activity: string;
|
|
4
|
+
updatedBy: string;
|
|
5
|
+
updatedOn: string;
|
|
6
|
+
source: string;
|
|
7
|
+
parentId: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function ActivitySheet({ activityLogs }: {
|
|
10
|
+
activityLogs?: ActivityLogProps[];
|
|
11
|
+
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { AlignJustify } from "lucide-react";
|
|
4
|
+
import { Tabs } from "../tabs";
|
|
5
|
+
import { NoDataComponent } from "../no-data";
|
|
6
|
+
import { UploadTab } from "../upload-tab";
|
|
7
|
+
import { SheetComponent } from "../sheet";
|
|
8
|
+
export function ActivitySheet({ activityLogs = [] }) {
|
|
9
|
+
const tabArray = [
|
|
10
|
+
{
|
|
11
|
+
tabName: "Activity",
|
|
12
|
+
tabId: "tab-activity",
|
|
13
|
+
default: true,
|
|
14
|
+
tabContent: _jsx("div", { className: "overflow-auto flex flex-col gap-2 h-full", children: activityLogs.length > 0 ? (activityLogs.map((log) => (_jsxs("div", { className: "border-b text-sm pb-2", children: [_jsx("p", { className: "font-medium pb-1", children: log.activity }), _jsxs("p", { className: "text-gray-500 pb-1", children: ["Updated On:", " ", _jsx("span", { className: "text-gray-700", children: new Date(log.updatedOn).toLocaleString() })] }), _jsxs("p", { className: "text-gray-500 pb-1", children: ["Updated By: ", _jsx("span", { className: "text-gray-700", children: log.updatedBy })] })] }, log.id)))) : (_jsx(NoDataComponent, { text: "No Activity Logs Available" })) })
|
|
15
|
+
}, {
|
|
16
|
+
tabName: "File Upload",
|
|
17
|
+
tabId: "tab-upload",
|
|
18
|
+
default: false,
|
|
19
|
+
tabContent: _jsx(UploadTab, {})
|
|
20
|
+
}
|
|
21
|
+
];
|
|
22
|
+
return (_jsx(SheetComponent, { buttonText: "", buttonIcon: _jsx(AlignJustify, {}), sheetTitle: "", sheetContent: _jsx(Tabs, { tabArray: tabArray, tabListClass: '' }), closeButton: true }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Eye, SquarePen } from "lucide-react";
|
|
3
|
+
import { TooltipComponent as Tooltip } from "../../tooltip";
|
|
4
|
+
// Custom event component
|
|
5
|
+
export default function BigCalenderEvent({ event, extraParamsEvent }) {
|
|
6
|
+
return (_jsxs("div", { className: "custom-event flex flex-row justify-between", children: [_jsx("span", { className: "truncate", children: event.title }), _jsxs("span", { className: "flex flex-row gap-1", children: [((extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.isEditableAll) || event.isEditable) &&
|
|
7
|
+
_jsx(Tooltip, { tooltipContent: "Edit", children: _jsx("button", { className: "event-edit-button", onClick: (e) => {
|
|
8
|
+
var _a;
|
|
9
|
+
e.stopPropagation(); // Prevent triggering other event handlers
|
|
10
|
+
(_a = extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.onEditEventClick) === null || _a === void 0 ? void 0 : _a.call(extraParamsEvent, event);
|
|
11
|
+
}, children: _jsx(SquarePen, { size: 16 }) }) }), _jsx(Tooltip, { tooltipContent: "View", children: _jsx("button", { className: "event-view-button", onClick: (e) => {
|
|
12
|
+
var _a;
|
|
13
|
+
e.stopPropagation(); // Prevent triggering other event handlers
|
|
14
|
+
(_a = extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.onViewEventClick) === null || _a === void 0 ? void 0 : _a.call(extraParamsEvent, event);
|
|
15
|
+
}, children: _jsx(Eye, { size: 16 }) }) })] })] }));
|
|
16
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { Views } from "react-big-calendar";
|
|
3
|
+
import { Fragment, useState } from "react";
|
|
4
|
+
import { ChevronLeft, ChevronRight } from "lucide-react";
|
|
5
|
+
import { ToggleGroup, ToggleGroupItem } from "../../../shadcn/toggle-group";
|
|
6
|
+
// Custom toolbar component
|
|
7
|
+
export default function BigCalenderToolbar({ onNavigate, onView, label, extraTools, view }) {
|
|
8
|
+
const [calViewsValue, setValue] = useState(view === Views.DAY ? "DAY" : view === Views.WEEK ? "WEEK" : "MONTH");
|
|
9
|
+
return (_jsx(_Fragment, { children: _jsxs("div", { className: "flex flex-col md:flex-row justify-between items-start md:items-center mb-3", children: [_jsxs(ToggleGroup, { type: "single", variant: 'outline', onValueChange: (value) => {
|
|
10
|
+
switch (value) {
|
|
11
|
+
case "PREV":
|
|
12
|
+
onNavigate("PREV");
|
|
13
|
+
break;
|
|
14
|
+
case "NEXT":
|
|
15
|
+
onNavigate("NEXT");
|
|
16
|
+
break;
|
|
17
|
+
case "TODAY":
|
|
18
|
+
onNavigate("TODAY");
|
|
19
|
+
break;
|
|
20
|
+
default:
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}, children: [_jsx(ToggleGroupItem, { className: "rounded-e-none", value: "PREV", children: _jsx(ChevronLeft, { size: 16 }) }), _jsx(ToggleGroupItem, { className: 'rounded-none border-x-0', value: "NEXT", children: _jsx(ChevronRight, { size: 16 }) }), _jsx(ToggleGroupItem, { className: 'rounded-s-none', value: "TODAY", children: "Today" })] }), _jsx("span", { className: "rbc-toolbar-label", children: label }), _jsxs("div", { className: "flex flex-row gap-2", children: [extraTools === null || extraTools === void 0 ? void 0 : extraTools.map((tool, index) => _jsx(Fragment, { children: tool }, index)), _jsxs(ToggleGroup, { type: "single", variant: 'outline', value: calViewsValue, onValueChange: (value) => {
|
|
24
|
+
setValue(value);
|
|
25
|
+
switch (value) {
|
|
26
|
+
case "DAY":
|
|
27
|
+
onView(Views.DAY);
|
|
28
|
+
break;
|
|
29
|
+
case "WEEK":
|
|
30
|
+
onView(Views.WEEK);
|
|
31
|
+
break;
|
|
32
|
+
case "MONTH":
|
|
33
|
+
onView(Views.MONTH);
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
}, children: [_jsx(ToggleGroupItem, { className: "rounded-e-none", value: "DAY", children: "Day" }), _jsx(ToggleGroupItem, { className: 'rounded-none border-x-0', value: "WEEK", children: "Week" }), _jsx(ToggleGroupItem, { className: 'rounded-s-none', value: "MONTH", children: "Month" })] })] })] }) }));
|
|
39
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { format, getDay, parse, startOfWeek } from "date-fns";
|
|
4
|
+
import { Calendar, dateFnsLocalizer, Views } from "react-big-calendar";
|
|
5
|
+
import "react-big-calendar/lib/css/react-big-calendar.css";
|
|
6
|
+
import { useState } from "react";
|
|
7
|
+
import "./index.css";
|
|
8
|
+
import BigCalenderToolbar from "./big-calender-toolbar";
|
|
9
|
+
import BigCalenderEvent from "./big-calender-event";
|
|
10
|
+
// Localization settings
|
|
11
|
+
const locales = {
|
|
12
|
+
"en-US": require("date-fns/locale/en-US"),
|
|
13
|
+
};
|
|
14
|
+
const localizer = dateFnsLocalizer({
|
|
15
|
+
format,
|
|
16
|
+
parse,
|
|
17
|
+
startOfWeek,
|
|
18
|
+
getDay,
|
|
19
|
+
locales,
|
|
20
|
+
});
|
|
21
|
+
export function BigCalendar({ events, extraParamsEvent, extraTools }) {
|
|
22
|
+
const [view, setView] = useState((extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.defaultView) === "day" ? Views.DAY :
|
|
23
|
+
(extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.defaultView) === "week" ? Views.WEEK :
|
|
24
|
+
(extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.defaultView) === "month" ? Views.MONTH :
|
|
25
|
+
(extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.defaultView) === "work week" ? Views.WORK_WEEK :
|
|
26
|
+
(extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.defaultView) === "agenda" ? Views.AGENDA : Views.MONTH);
|
|
27
|
+
const [date, setDate] = useState(new Date());
|
|
28
|
+
return (_jsx(Calendar, { localizer: localizer, events: events || [], startAccessor: "start", endAccessor: "end", views: [Views.DAY, Views.WEEK, Views.MONTH], view: view, onView: (view) => setView(view), date: date, onNavigate: (date) => setDate(date), components: {
|
|
29
|
+
event: (props) => _jsx(BigCalenderEvent, { event: props.event, extraParamsEvent: extraParamsEvent }),
|
|
30
|
+
toolbar: (props) => _jsx(BigCalenderToolbar, Object.assign({}, props, { extraTools: extraTools, view: view })),
|
|
31
|
+
}, style: {
|
|
32
|
+
height: (extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.height) || "100%",
|
|
33
|
+
margin: (extraParamsEvent === null || extraParamsEvent === void 0 ? void 0 : extraParamsEvent.margin) || "0px",
|
|
34
|
+
} }));
|
|
35
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
export interface BigCalendarProps {
|
|
3
|
+
events: BigCalendarEventProps[];
|
|
4
|
+
extraParamsEvent?: ExtraParamsEvent;
|
|
5
|
+
extraTools?: ReactNode[];
|
|
6
|
+
onDateClick?: (date: Date) => void;
|
|
7
|
+
}
|
|
8
|
+
export interface ExtraParamsEvent {
|
|
9
|
+
defaultView?: string;
|
|
10
|
+
isEditableAll?: boolean;
|
|
11
|
+
isViewable?: boolean;
|
|
12
|
+
onEditEventClick?: (event: BigCalendarEventProps) => void;
|
|
13
|
+
onViewEventClick?: (event: BigCalendarEventProps) => void;
|
|
14
|
+
height?: string;
|
|
15
|
+
margin?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface BigCalendarEventProps extends Event {
|
|
18
|
+
title?: string;
|
|
19
|
+
isEditable?: boolean;
|
|
20
|
+
isViewable?: boolean;
|
|
21
|
+
start: Date;
|
|
22
|
+
end: Date;
|
|
23
|
+
onEventClick?: (event: any) => void;
|
|
24
|
+
}
|
|
25
|
+
export interface BigCalenderToolbarProps {
|
|
26
|
+
onNavigate: (view: any) => void;
|
|
27
|
+
onView: (view: any) => void;
|
|
28
|
+
label: string;
|
|
29
|
+
extraTools?: ReactNode[];
|
|
30
|
+
view: "month" | "week" | "work_week" | "day" | "agenda";
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import "cropperjs/dist/cropper.css";
|
|
3
|
+
export interface CropperImgProps {
|
|
4
|
+
imageSrc: string | undefined;
|
|
5
|
+
onCroppedImage: (imageUrl: string) => void;
|
|
6
|
+
aspectRatio: number;
|
|
7
|
+
rotationAngle: number;
|
|
8
|
+
zoomLevel: number;
|
|
9
|
+
moveDirection: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
currentState: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const NewCropperImg: React.FC<CropperImgProps>;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useRef } from "react";
|
|
3
|
+
import Cropper from "react-cropper";
|
|
4
|
+
import "cropperjs/dist/cropper.css";
|
|
5
|
+
export const NewCropperImg = ({ imageSrc, onCroppedImage, aspectRatio, rotationAngle, zoomLevel, moveDirection, currentState }) => {
|
|
6
|
+
const cropperRef = useRef(null);
|
|
7
|
+
const onCrop = () => {
|
|
8
|
+
var _a;
|
|
9
|
+
const cropper = (_a = cropperRef.current) === null || _a === void 0 ? void 0 : _a.cropper;
|
|
10
|
+
if (cropper) {
|
|
11
|
+
cropper.setDragMode('move');
|
|
12
|
+
const croppedCanvas = cropper.getCroppedCanvas();
|
|
13
|
+
const croppedImageUrl = croppedCanvas.toDataURL(); // Data URL for preview
|
|
14
|
+
onCroppedImage(croppedImageUrl);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
console.log("Cropper instance is not available.");
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
var _a;
|
|
22
|
+
// Rotate the image whenever the rotation angle changes
|
|
23
|
+
const cropper = (_a = cropperRef.current) === null || _a === void 0 ? void 0 : _a.cropper;
|
|
24
|
+
if (cropper) {
|
|
25
|
+
cropper.rotate(rotationAngle); // Apply the rotation to the image
|
|
26
|
+
}
|
|
27
|
+
}, [rotationAngle]); // Effect will run whenever rotationAngle changes
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
var _a;
|
|
30
|
+
// Zoom the image whenever the zoom level changes
|
|
31
|
+
const cropper = (_a = cropperRef.current) === null || _a === void 0 ? void 0 : _a.cropper;
|
|
32
|
+
if (cropper) {
|
|
33
|
+
const cropBoxData = cropper.getCropBoxData();
|
|
34
|
+
if (cropBoxData.width) {
|
|
35
|
+
console.log('Inside cropper scale');
|
|
36
|
+
cropper.scale(zoomLevel); // Apply the zoom level
|
|
37
|
+
}
|
|
38
|
+
// Apply zoom directly without using getZoom method
|
|
39
|
+
}
|
|
40
|
+
}, [zoomLevel]); // Effect will run whenever zoomLevel changes
|
|
41
|
+
// Move the image based on the moveDirection prop
|
|
42
|
+
useEffect(() => {
|
|
43
|
+
var _a;
|
|
44
|
+
const cropper = (_a = cropperRef.current) === null || _a === void 0 ? void 0 : _a.cropper;
|
|
45
|
+
if (cropper) {
|
|
46
|
+
// Make sure moveDirection is available before calling move
|
|
47
|
+
const cropBoxData = cropper.getCropBoxData();
|
|
48
|
+
if (cropBoxData.width) {
|
|
49
|
+
const { x, y } = moveDirection;
|
|
50
|
+
if (typeof x === "number" && typeof y === "number") {
|
|
51
|
+
cropper.move(x, y); // Move the image
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}, [moveDirection]); // This effect runs whenever moveDirection changes
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
var _a;
|
|
58
|
+
const cropper = (_a = cropperRef.current) === null || _a === void 0 ? void 0 : _a.cropper;
|
|
59
|
+
if (cropper) {
|
|
60
|
+
cropper.setAspectRatio(aspectRatio); // Dynamically set the aspect ratio
|
|
61
|
+
if (aspectRatio === 1) {
|
|
62
|
+
// Get the displayed (canvas) dimensions of the image
|
|
63
|
+
const canvasData = cropper.getCanvasData();
|
|
64
|
+
const canvasWidth = canvasData.width; // Displayed width of the image
|
|
65
|
+
const canvasHeight = canvasData.height; // Displayed height of the image
|
|
66
|
+
const canvasLeft = canvasData.left; // Left offset of the image within the container
|
|
67
|
+
const canvasTop = canvasData.top; // Top offset of the image within the container
|
|
68
|
+
// Define the desired crop box dimensions
|
|
69
|
+
const cropBoxWidth = 200; // Desired crop box width
|
|
70
|
+
const cropBoxHeight = 100; // Desired crop box height
|
|
71
|
+
// Calculate the center position for the crop box
|
|
72
|
+
const left = canvasLeft + (canvasWidth - cropBoxWidth) / 2;
|
|
73
|
+
const top = canvasTop + (canvasHeight - cropBoxHeight) / 2;
|
|
74
|
+
// Set the crop box data
|
|
75
|
+
cropper.setCropBoxData({
|
|
76
|
+
left: left,
|
|
77
|
+
top: top,
|
|
78
|
+
width: cropBoxWidth,
|
|
79
|
+
height: cropBoxHeight,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}, [aspectRatio]); // Trigger this effect whenever aspectRatio changes
|
|
84
|
+
return (_jsx(Cropper, { src: imageSrc, style: { height: "100%", width: "100%", objectFit: "contain" }, guides: true, crop: onCrop, ref: cropperRef, dragMode: 'move', movable: true, zoomable: true, scalable: true, cropBoxMovable: true, cropBoxResizable: false }));
|
|
85
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
export interface ImageFormProps {
|
|
3
|
+
open: boolean;
|
|
4
|
+
setOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
|
5
|
+
onImageSubmit: (data: string | null) => void;
|
|
6
|
+
}
|
|
7
|
+
export declare const NewImageForm: React.NamedExoticComponent<ImageFormProps>;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, memo } from "react";
|
|
3
|
+
import { ZoomIn, ZoomOut, RotateCw, RotateCcw, ArrowUp, ArrowDown, ArrowLeft, ArrowRight, ImageIcon, FileImage, Square, Upload, } from "lucide-react";
|
|
4
|
+
import { Label } from "../../../shadcn/label";
|
|
5
|
+
import { Input } from "../../../shadcn/input";
|
|
6
|
+
import { Button } from "../../../shadcn/button";
|
|
7
|
+
import { NewCropperImg } from "./newCropper";
|
|
8
|
+
import Image from "next/image";
|
|
9
|
+
const NewImageFormComponent = ({ open, setOpen, onImageSubmit, }) => {
|
|
10
|
+
const [imageSrc, setImageSrc] = useState(null);
|
|
11
|
+
const [croppedImage, setCroppedImage] = useState(null);
|
|
12
|
+
const [prevImages, setPrevImages] = useState({
|
|
13
|
+
first: null,
|
|
14
|
+
second: null,
|
|
15
|
+
third: null,
|
|
16
|
+
});
|
|
17
|
+
const [aspectRatio, setAspectRatio] = useState(4 / 3);
|
|
18
|
+
const [activeState, setActiveState] = useState("first");
|
|
19
|
+
const [rotationAngle, setRotationAngle] = useState(0);
|
|
20
|
+
const [scale, setScale] = useState(1);
|
|
21
|
+
const [moveDirection, setMoveDirection] = useState({
|
|
22
|
+
x: 0,
|
|
23
|
+
y: 0,
|
|
24
|
+
});
|
|
25
|
+
const [fileName, setFileName] = useState("");
|
|
26
|
+
const handleImageSubmit = () => {
|
|
27
|
+
console.log("Image Submit Button is pressed");
|
|
28
|
+
console.log(prevImages);
|
|
29
|
+
onImageSubmit(prevImages.third);
|
|
30
|
+
setOpen(false);
|
|
31
|
+
};
|
|
32
|
+
const rotateImage = (angle) => {
|
|
33
|
+
setRotationAngle((prevAngle) => prevAngle + angle);
|
|
34
|
+
};
|
|
35
|
+
const handleMoveUp = () => {
|
|
36
|
+
setMoveDirection({ x: 0, y: -5 });
|
|
37
|
+
};
|
|
38
|
+
const handleMoveDown = () => {
|
|
39
|
+
setMoveDirection({ x: 0, y: 5 });
|
|
40
|
+
};
|
|
41
|
+
const handleMoveLeft = () => {
|
|
42
|
+
setMoveDirection({ x: -5, y: 0 });
|
|
43
|
+
};
|
|
44
|
+
const handleMoveRight = () => {
|
|
45
|
+
setMoveDirection({ x: 5, y: 0 });
|
|
46
|
+
};
|
|
47
|
+
// Handle zoom in
|
|
48
|
+
const zoomIn = () => {
|
|
49
|
+
setScale((prevScale) => {
|
|
50
|
+
const newScale = prevScale + 0.2;
|
|
51
|
+
if (newScale <= 2) {
|
|
52
|
+
// Ensure scale does not exceed the max value
|
|
53
|
+
return newScale;
|
|
54
|
+
}
|
|
55
|
+
return prevScale;
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
// Handle zoom out
|
|
59
|
+
const zoomOut = () => {
|
|
60
|
+
setScale((prevScale) => {
|
|
61
|
+
const newScale = prevScale - 0.2;
|
|
62
|
+
if (newScale >= 0.2) {
|
|
63
|
+
// Ensure scale does not go below the min value
|
|
64
|
+
return newScale;
|
|
65
|
+
}
|
|
66
|
+
return prevScale;
|
|
67
|
+
});
|
|
68
|
+
};
|
|
69
|
+
const handleAspectRatioChange = (ratio, stateName) => {
|
|
70
|
+
setAspectRatio(ratio);
|
|
71
|
+
setActiveState(stateName);
|
|
72
|
+
};
|
|
73
|
+
const handleFileChange = (file) => {
|
|
74
|
+
if (file.type.startsWith("image/")) {
|
|
75
|
+
const reader = new FileReader();
|
|
76
|
+
reader.onloadend = () => {
|
|
77
|
+
setImageSrc(reader.result);
|
|
78
|
+
setFileName((prev) => prev || file.name);
|
|
79
|
+
};
|
|
80
|
+
reader.readAsDataURL(file);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
alert("Please drop a valid image file.");
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const handleDrop = (event) => {
|
|
87
|
+
event.preventDefault();
|
|
88
|
+
handleFileChange(event.dataTransfer.files[0]);
|
|
89
|
+
};
|
|
90
|
+
const getImagePreview = (state) => {
|
|
91
|
+
const imgSource = croppedImage && activeState === state ? croppedImage : prevImages[state];
|
|
92
|
+
// const imgSource = prevImages[state];
|
|
93
|
+
return imgSource ? (_jsx("div", { className: `
|
|
94
|
+
${state === "first"
|
|
95
|
+
? "relative w-3/5 h-[200px] bg-slate-400"
|
|
96
|
+
: state === "second"
|
|
97
|
+
? "relative w-1/2 h-[220px] bg-slate-400"
|
|
98
|
+
: "relative w-1/3 h-[120px] bg-slate-400"}`, children: _jsx(Image, { src: imgSource || "", alt: `Preview ${state}`, layout: "fill", objectFit: "70vh" }) })) : (_jsx("div", { className: `
|
|
99
|
+
${state === "first"
|
|
100
|
+
? "relative w-3/5 h-[200px] bg-slate-400"
|
|
101
|
+
: state === "second"
|
|
102
|
+
? "relative w-1/2 h-[220px] bg-slate-400"
|
|
103
|
+
: "relative w-1/3 h-[120px] bg-slate-400"}` }));
|
|
104
|
+
};
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (croppedImage) {
|
|
107
|
+
if (prevImages.first === null ||
|
|
108
|
+
prevImages.second === null ||
|
|
109
|
+
prevImages.third === null) {
|
|
110
|
+
setPrevImages({
|
|
111
|
+
first: croppedImage,
|
|
112
|
+
second: croppedImage,
|
|
113
|
+
third: croppedImage,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
setPrevImages((prev) => (Object.assign(Object.assign({}, prev), { [activeState]: croppedImage })));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}, [croppedImage]);
|
|
121
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex flex-row gap-2", children: [_jsxs("div", { className: "flex-1", children: [_jsx(Label, { htmlFor: "imageName", children: "Image Name" }), _jsx(Input, { id: "imageName", placeholder: "Enter image name", value: fileName, onChange: (e) => setFileName(e.target.value) })] }), _jsxs("div", { className: "self-end", children: [_jsx(Button, { variant: "outline", onClick: () => { var _a; return (_a = document.getElementById("inputImage1")) === null || _a === void 0 ? void 0 : _a.click(); }, children: _jsx(Upload, {}) }), _jsx(Input, { id: "inputImage1", type: "file", accept: "image/png, image/jpeg", className: "hidden", onChange: (e) => {
|
|
122
|
+
var _a;
|
|
123
|
+
const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
124
|
+
if (file && file.type.startsWith("image/")) {
|
|
125
|
+
const reader = new FileReader();
|
|
126
|
+
reader.onloadend = () => {
|
|
127
|
+
setImageSrc(reader.result);
|
|
128
|
+
setFileName((prevFileName) => prevFileName || file.name);
|
|
129
|
+
};
|
|
130
|
+
reader.readAsDataURL(file);
|
|
131
|
+
setPrevImages({
|
|
132
|
+
first: null,
|
|
133
|
+
second: null,
|
|
134
|
+
third: null,
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
} })] }), _jsxs("div", { className: "flex-1", children: [_jsx(Label, { htmlFor: "imageDesc", children: "Image Description" }), _jsx(Input, { id: "imageDesc", placeholder: "Describe your image" })] })] }), _jsxs("div", { className: "flex flex-row gap-2", children: [_jsx("div", { className: "w-3/5 flex justify-center items-center border-2 border-dashed border-gray-400 bg-gray-100", style: { height: "70vh" }, onDrop: handleDrop, onDragOver: (e) => e.preventDefault(), children: imageSrc ? (_jsx(NewCropperImg, { imageSrc: imageSrc, onCroppedImage: setCroppedImage, aspectRatio: aspectRatio, rotationAngle: rotationAngle, zoomLevel: scale, moveDirection: moveDirection, currentState: activeState })) : (_jsxs("div", { className: "text-center", children: [_jsx(Label, { htmlFor: "inputImage", children: "Drag and drop an image here" }), _jsxs("div", { className: "mt-4", children: [_jsx(Button, { variant: "outline", onClick: () => { var _a; return (_a = document.getElementById("inputImage")) === null || _a === void 0 ? void 0 : _a.click(); }, children: "Upload Image" }), _jsx(Input, { id: "inputImage", type: "file", accept: "image/png, image/jpeg", className: "hidden", onChange: (e) => {
|
|
138
|
+
var _a;
|
|
139
|
+
const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
140
|
+
if (file) {
|
|
141
|
+
handleFileChange(file);
|
|
142
|
+
}
|
|
143
|
+
} })] })] })) }), _jsxs("div", { className: "w-2/5 flex flex-col gap-2", children: [_jsx("h3", { children: "Landscape" }), getImagePreview("first"), _jsx("h3", { children: "Potrait" }), getImagePreview("second"), _jsx("h3", { children: "Icon" }), getImagePreview("third")] })] }), _jsxs("div", { className: "flex flex-row gap-1", children: [_jsxs("div", { className: "w-3/5 flex flex-row justify-between", children: [_jsxs("div", { children: [_jsx(Button, { variant: "outline", onClick: () => handleAspectRatioChange(4 / 3, "first"), children: _jsx(ImageIcon, {}) }), _jsx(Button, { variant: "outline", onClick: () => handleAspectRatioChange(3 / 4, "second"), children: _jsx(FileImage, {}) }), _jsx(Button, { variant: "outline", onClick: () => handleAspectRatioChange(1 / 1, "third"), children: _jsx(Square, {}) })] }), _jsxs("div", { children: [_jsx(Button, { onClick: () => rotateImage(90), variant: "outline", children: _jsx(RotateCw, {}) }), _jsx(Button, { onClick: () => rotateImage(-90), variant: "outline", children: _jsx(RotateCcw, {}) })] }), _jsxs("div", { children: [_jsx(Button, { onClick: () => zoomIn(), variant: "outline", children: _jsx(ZoomIn, {}) }), _jsx(Button, { onClick: () => zoomOut(), variant: "outline", children: _jsx(ZoomOut, {}) })] }), _jsxs("div", { children: [_jsx(Button, { onClick: handleMoveUp, variant: "outline", children: _jsx(ArrowUp, {}) }), _jsx(Button, { onClick: handleMoveDown, variant: "outline", children: _jsx(ArrowDown, {}) }), _jsx(Button, { onClick: handleMoveLeft, variant: "outline", children: _jsx(ArrowLeft, {}) }), _jsx(Button, { onClick: handleMoveRight, variant: "outline", children: _jsx(ArrowRight, {}) })] })] }), _jsx("div", { className: "w-2/5 flex flex-row-reverse", children: _jsx(Button, { onClick: handleImageSubmit, children: "Save" }) })] })] }));
|
|
144
|
+
};
|
|
145
|
+
export const NewImageForm = memo(NewImageFormComponent);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
onNewFileUpload?: (...args: any) => void;
|
|
3
|
+
}
|
|
4
|
+
declare function CropperFormComponent({ onNewFileUpload }: Props): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export declare const CropperForm: import("react").MemoExoticComponent<typeof CropperFormComponent>;
|
|
6
|
+
export {};
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Input } from '../../../shadcn/input';
|
|
3
|
+
import { Label } from '../../../shadcn/label';
|
|
4
|
+
import { ToggleGroup, ToggleGroupItem } from '../../../shadcn/toggle-group';
|
|
5
|
+
import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, FileImage, ImageIcon, RotateCcw, RotateCw, Square, ZoomIn, ZoomOut } from 'lucide-react';
|
|
6
|
+
import { memo, useEffect, useState } from 'react';
|
|
7
|
+
import { ImageCropper } from '../image-cropper';
|
|
8
|
+
import Image from 'next/image';
|
|
9
|
+
import { AspectRatio } from '../../../shadcn/aspect-ratio';
|
|
10
|
+
import { TextButton } from '../../buttons';
|
|
11
|
+
import { toast } from 'sonner';
|
|
12
|
+
import { FileInput } from '../../file-input';
|
|
13
|
+
import { useImageCropper } from '..';
|
|
14
|
+
const stateWiseAspectRatio = {
|
|
15
|
+
landscape: 4 / 3,
|
|
16
|
+
potrait: 3 / 4,
|
|
17
|
+
icon: 1 / 1
|
|
18
|
+
};
|
|
19
|
+
function CropperFormComponent({ onNewFileUpload }) {
|
|
20
|
+
const { originalImage, setOriginalImage, aspectRatioWiseImages, setAspectRatioWiseImages } = useImageCropper();
|
|
21
|
+
const [croppedImage, setCroppedImage] = useState(null);
|
|
22
|
+
const [activeState, setActiveState] = useState();
|
|
23
|
+
const [rotationAngle, setRotationAngle] = useState(0);
|
|
24
|
+
const [scale, setScale] = useState(1);
|
|
25
|
+
const [moveDirection, setMoveDirection] = useState({
|
|
26
|
+
x: 0,
|
|
27
|
+
y: 0,
|
|
28
|
+
});
|
|
29
|
+
const [imageSrc, setImageSrc] = useState(null);
|
|
30
|
+
const handleDrop = (event) => {
|
|
31
|
+
event.preventDefault();
|
|
32
|
+
handleFileChange(event.dataTransfer.files[0]);
|
|
33
|
+
};
|
|
34
|
+
const handleFileChange = (file) => {
|
|
35
|
+
var _a;
|
|
36
|
+
if (typeof file === "string") {
|
|
37
|
+
setImageSrc(file);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if ((_a = file === null || file === void 0 ? void 0 : file.type) === null || _a === void 0 ? void 0 : _a.startsWith("image/")) {
|
|
41
|
+
onNewFileUpload === null || onNewFileUpload === void 0 ? void 0 : onNewFileUpload();
|
|
42
|
+
const reader = new FileReader();
|
|
43
|
+
reader.onloadend = () => {
|
|
44
|
+
setImageSrc(reader.result);
|
|
45
|
+
setActiveState(undefined);
|
|
46
|
+
};
|
|
47
|
+
reader.readAsDataURL(file);
|
|
48
|
+
setOriginalImage(Object.assign(Object.assign({}, originalImage), { image: file, name: file.name }));
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
toast.error("Please select a valid image file.");
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (originalImage.image) {
|
|
57
|
+
handleFileChange(originalImage.image);
|
|
58
|
+
}
|
|
59
|
+
}, [originalImage.image]);
|
|
60
|
+
const getImagePreview = (state) => {
|
|
61
|
+
const imgSource = croppedImage && activeState === state ? croppedImage : aspectRatioWiseImages[state];
|
|
62
|
+
return (_jsxs(_Fragment, { children: [_jsx("h3", { className: 'mb-3', children: state }), _jsx(AspectRatio, { ratio: stateWiseAspectRatio[state], className: 'bg-muted', children: imgSource &&
|
|
63
|
+
_jsx(Image, { src: imgSource || "", alt: `Preview ${state}`, fill: true }) })] }));
|
|
64
|
+
};
|
|
65
|
+
useEffect(() => {
|
|
66
|
+
if (croppedImage) {
|
|
67
|
+
if (activeState) {
|
|
68
|
+
setAspectRatioWiseImages(Object.assign(Object.assign({}, aspectRatioWiseImages), { [activeState]: croppedImage }));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
setAspectRatioWiseImages({
|
|
72
|
+
landscape: croppedImage,
|
|
73
|
+
potrait: croppedImage,
|
|
74
|
+
icon: croppedImage
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}, [croppedImage]);
|
|
79
|
+
return (_jsx(_Fragment, { children: _jsxs("div", { className: 'flex flex-col gap-3 h-full overflow-auto', children: [_jsxs("div", { className: 'flex flex-col lg:flex-row gap-3 justify-between', children: [_jsxs("div", { className: 'w-full flex flex-col gap-4', children: [_jsx(Label, { htmlFor: "imageName", children: "Image Name" }), _jsx(FileInput, { id: "inputImage", accept: "image/*", fileNamePlaceholder: "Enter image name", fileName: (originalImage === null || originalImage === void 0 ? void 0 : originalImage.name) || "", onChange: (e) => {
|
|
80
|
+
var _a;
|
|
81
|
+
const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
|
|
82
|
+
if (file) {
|
|
83
|
+
handleFileChange(file);
|
|
84
|
+
}
|
|
85
|
+
}, onFileNameChange: (e) => {
|
|
86
|
+
setOriginalImage(Object.assign(Object.assign({}, originalImage), { name: e.target.value }));
|
|
87
|
+
} })] }), _jsxs("div", { className: 'w-full flex flex-col gap-4', children: [_jsx(Label, { htmlFor: "imageDescription", children: "Image Description" }), _jsx(Input, { id: "imageDescription", placeholder: "Enter image Description", value: (originalImage === null || originalImage === void 0 ? void 0 : originalImage.description) || "", onChange: (e) => setOriginalImage(Object.assign(Object.assign({}, originalImage), { description: e.target.value })) })] })] }), _jsxs("div", { className: 'flex flex-col lg:flex-row gap-3', children: [_jsxs("div", { className: 'flex-grow flex flex-col gap-3', children: [_jsxs("div", { children: [_jsx("h3", { className: 'mb-3', children: "Original Image" }), _jsx(AspectRatio, { ratio: 4 / 3, className: 'flex justify-center items-center bg-muted text-muted-foreground', onDrop: handleDrop, onDragOver: (e) => e.preventDefault(), children: imageSrc ?
|
|
88
|
+
_jsx(ImageCropper, { src: imageSrc, onCroppedImage: setCroppedImage, aspectRatio: stateWiseAspectRatio[activeState || "icon"], rotationAngle: rotationAngle, zoomLevel: scale, moveDirection: moveDirection })
|
|
89
|
+
:
|
|
90
|
+
_jsxs("div", { className: "text-center", children: [_jsx(Label, { htmlFor: "inputImage", children: "Drag and drop an image here" }), _jsx("div", { className: "mt-3", children: _jsx(TextButton, { variant: "outline", onClick: () => { var _a; return (_a = document.getElementById("inputImage")) === null || _a === void 0 ? void 0 : _a.click(); }, children: "Browse Image" }) })] }) })] }), _jsxs("div", { className: "flex flex-col lg:flex-row gap-3 justify-between", children: [_jsx("div", { children: _jsxs(ToggleGroup, { type: "single", variant: 'outline', value: activeState, onValueChange: (value) => setActiveState(value), children: [_jsx(ToggleGroupItem, { className: "rounded-e-none", value: "landscape", children: _jsx(ImageIcon, {}) }), _jsx(ToggleGroupItem, { className: "rounded-none border-x-0", value: "potrait", children: _jsx(FileImage, {}) }), _jsx(ToggleGroupItem, { className: 'rounded-s-none', value: "icon", children: _jsx(Square, {}) })] }) }), _jsxs("div", { className: 'flex flex-col lg:flex-row gap-3 justify-between', children: [_jsxs(ToggleGroup, { type: "single", variant: 'outline', value: "", onValueChange: (value) => setRotationAngle(parseInt(value)), children: [_jsx(ToggleGroupItem, { className: "rounded-e-none", value: "90", children: _jsx(RotateCw, {}) }), _jsx(ToggleGroupItem, { className: 'rounded-s-none border-s-0', value: "-90", children: _jsx(RotateCcw, {}) })] }), _jsxs(ToggleGroup, { type: "single", variant: 'outline', value: '', children: [_jsx(ToggleGroupItem, { className: "rounded-e-none", value: "up", onClick: () => setMoveDirection({ x: 0, y: -5 }), children: _jsx(ArrowUp, {}) }), _jsx(ToggleGroupItem, { className: "rounded-none border-x-0", value: "down", onClick: () => setMoveDirection({ x: 0, y: 5 }), children: _jsx(ArrowDown, {}) }), _jsx(ToggleGroupItem, { className: 'rounded-none border-e-0', value: "left", onClick: () => setMoveDirection({ x: -5, y: 0 }), children: _jsx(ArrowLeft, {}) }), _jsx(ToggleGroupItem, { className: 'rounded-s-none', value: "right", onClick: () => setMoveDirection({ x: 5, y: 0 }), children: _jsx(ArrowRight, {}) })] }), _jsxs(ToggleGroup, { type: "single", variant: 'outline', value: "", onValueChange: (value) => setScale(pre => pre + parseFloat(value)), children: [_jsx(ToggleGroupItem, { className: "rounded-e-none", value: "0.1", children: _jsx(ZoomIn, {}) }), _jsx(ToggleGroupItem, { className: 'rounded-s-none border-s-0', value: "-0.1", children: _jsx(ZoomOut, {}) })] })] })] })] }), _jsxs("div", { className: "flex flex-row lg:flex-col gap-3 w-full lg:w-48", children: [_jsx("div", { className: 'w-5/5', children: getImagePreview("landscape") }), _jsx("div", { className: 'w-4/5', children: getImagePreview("potrait") }), _jsx("div", { className: 'w-3/5', children: getImagePreview("icon") })] })] })] }) }));
|
|
91
|
+
}
|
|
92
|
+
export const CropperForm = memo(CropperFormComponent);
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AspectRatioWiseImagesProps, OriginalImageProps } from '..';
|
|
2
|
+
export declare function CropperFormWithModal({ open, onOpenChange, onCropperChange }: Readonly<{
|
|
3
|
+
open: boolean;
|
|
4
|
+
onOpenChange: (open: boolean) => void;
|
|
5
|
+
onCropperChange: (originalImage: OriginalImageProps, aspectRatioWiseImages: AspectRatioWiseImagesProps) => void;
|
|
6
|
+
}>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from '../../../shadcn/dialog';
|
|
3
|
+
import { CropperForm } from '../cropper-form';
|
|
4
|
+
import { TextButton } from '../../buttons';
|
|
5
|
+
import { useImageCropper } from '..';
|
|
6
|
+
export function CropperFormWithModal({ open, onOpenChange, onCropperChange }) {
|
|
7
|
+
const { originalImage, aspectRatioWiseImages } = useImageCropper();
|
|
8
|
+
return (_jsx(Dialog, { modal: true, open: open, onOpenChange: (isOpen) => {
|
|
9
|
+
onOpenChange(isOpen);
|
|
10
|
+
}, children: _jsxs(DialogContent, { className: "max-w-full lg:max-w-5xl max-h-full overflow-auto", children: [_jsx(DialogHeader, { children: _jsx(DialogTitle, { children: "Image to upload" }) }), _jsx(CropperForm, {}), _jsx(DialogFooter, { children: _jsx(TextButton, { onClick: () => {
|
|
11
|
+
onCropperChange(originalImage, aspectRatioWiseImages);
|
|
12
|
+
onOpenChange(false);
|
|
13
|
+
}, children: "Save Changes" }) })] }) }));
|
|
14
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import "cropperjs/dist/cropper.css";
|
|
3
|
+
export interface CropperImgProps {
|
|
4
|
+
src: string | undefined;
|
|
5
|
+
onCroppedImage: (imageUrl: string) => void;
|
|
6
|
+
aspectRatio: number;
|
|
7
|
+
rotationAngle: number;
|
|
8
|
+
zoomLevel: number;
|
|
9
|
+
moveDirection: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export declare const ImageCropper: React.NamedExoticComponent<CropperImgProps>;
|