From a1a8dd44474225a7815ddabbebc3b70a7b0b1387 Mon Sep 17 00:00:00 2001 From: "pramod.mahajan" Date: Wed, 26 Nov 2025 18:37:05 +0530 Subject: [PATCH] added zoom in and size bar collaspeing --- src/components/Expenses/Filelist.jsx | 2 +- src/components/Expenses/PreviewDocument.jsx | 197 ++++++++++++++------ src/components/Expenses/ViewExpense.jsx | 2 +- src/pages/Expense/ExpensePage.jsx | 8 +- 4 files changed, 149 insertions(+), 60 deletions(-) diff --git a/src/components/Expenses/Filelist.jsx b/src/components/Expenses/Filelist.jsx index 35a4a986..e9a09b2b 100644 --- a/src/components/Expenses/Filelist.jsx +++ b/src/components/Expenses/Filelist.jsx @@ -72,7 +72,7 @@ export const FilelistView = ({ files, viewFile }) => { e.preventDefault(); viewFile({ IsOpen: true, - Image: file.preSignedUrl, + Image: files, }); }} > diff --git a/src/components/Expenses/PreviewDocument.jsx b/src/components/Expenses/PreviewDocument.jsx index 2f0e796b..142ee65c 100644 --- a/src/components/Expenses/PreviewDocument.jsx +++ b/src/components/Expenses/PreviewDocument.jsx @@ -1,80 +1,169 @@ -import { useState } from "react"; +import { useState, useRef, useEffect } from "react"; +const PreviewDocument = ({ files = [] }) => { + const images = Array.isArray(files) ? files : [files]; -const PreviewDocument = ({ imageUrl }) => { + const [index, setIndex] = useState(0); const [loading, setLoading] = useState(true); const [rotation, setRotation] = useState(0); const [scale, setScale] = useState(1); + const [position, setPosition] = useState({ x: 0, y: 0 }); + const [dragging, setDragging] = useState(false); + + const startPos = useRef({ x: 0, y: 0 }); + + const MIN_ZOOM = 0.4; + const MAX_ZOOM = 3; + + const currentImage = images[index]; + + // Reset on image change + useEffect(() => { + setRotation(0); + setScale(1); + setPosition({ x: 0, y: 0 }); + setLoading(true); + }, [index]); + + const zoomIn = () => setScale((prev) => Math.min(prev + 0.2, MAX_ZOOM)); + const zoomOut = () => setScale((prev) => Math.max(prev - 0.2, MIN_ZOOM)); - const zoomIn = () => setScale((prev) => Math.min(prev + 0.2, 3)); - const zoomOut = () => setScale((prev) => Math.max(prev - 0.2, 0.4)); const resetAll = () => { setRotation(0); setScale(1); + setPosition({ x: 0, y: 0 }); }; + const nextImage = () => { + if (index < images.length - 1) setIndex((i) => i + 1); + }; + + const prevImage = () => { + if (index > 0) setIndex((i) => i - 1); + }; + + const handleWheel = (e) => { + e.preventDefault(); + + if (e.ctrlKey) { + const delta = e.deltaY > 0 ? -0.1 : 0.1; + setScale((prev) => { + let next = prev + delta; + if (next < MIN_ZOOM) next = MIN_ZOOM; + if (next > MAX_ZOOM) next = MAX_ZOOM; + return next; + }); + } else { + if (e.deltaY > 0) nextImage(); + else prevImage(); + } + }; + + const handleMouseDown = (e) => { + setDragging(true); + startPos.current = { + x: e.clientX - position.x, + y: e.clientY - position.y, + }; + }; + + const handleMouseMove = (e) => { + if (!dragging) return; + + setPosition({ + x: e.clientX - startPos.current.x, + y: e.clientY - startPos.current.y, + }); + }; + + const handleMouseUp = () => setDragging(false); + + const handleDoubleClick = () => resetAll(); + return ( <> -
- setRotation((prev) => prev + 90)} - > - - - - + {/* Top Controls */} +
+ {/* Left */} +
+ setRotation((prev) => prev + 90)} + title="Rotate" + /> + + + +
- {loading && ( -
- Loading... -
- )} + {loading &&
Loading...
} -
- Full View setLoading(false)} - /> + Preview setLoading(false)} + /> +
+ +
+
+ Scroll = change image | Double click = reset
- -
- +
+ + + {index + 1} / {images.length} + +
); }; - - export default PreviewDocument; diff --git a/src/components/Expenses/ViewExpense.jsx b/src/components/Expenses/ViewExpense.jsx index 8c032fc0..93304240 100644 --- a/src/components/Expenses/ViewExpense.jsx +++ b/src/components/Expenses/ViewExpense.jsx @@ -393,7 +393,7 @@ const tdsPercentage = Number(watch("tdsPercentage")) || 0; if (isImage) { setDocumentView({ IsOpen: true, - Image: doc.preSignedUrl, + Images: data?.documents, }); } }} diff --git a/src/pages/Expense/ExpensePage.jsx b/src/pages/Expense/ExpensePage.jsx index e7ac3638..d7b2b594 100644 --- a/src/pages/Expense/ExpensePage.jsx +++ b/src/pages/Expense/ExpensePage.jsx @@ -62,7 +62,7 @@ const ExpensePage = () => { const [ViewDocument, setDocumentView] = useState({ IsOpen: false, - Image: null, + Images: null, }); const IsCreatedAble = useHasUserPermission(CREATE_EXEPENSE); @@ -208,10 +208,10 @@ const ExpensePage = () => { setDocumentView({ IsOpen: false, Image: null })} + key={ViewDocument.Images ?? "doc"} + closeModal={() => setDocumentView({ IsOpen: false, Images: null })} > - + )}