From 21c2a5cf7d7d8f812877956bc715f39f9b834482 Mon Sep 17 00:00:00 2001 From: Kartik Sharma Date: Mon, 24 Nov 2025 15:27:33 +0530 Subject: [PATCH 1/4] Adding ImageGallery Chips. --- src/components/gallary/GalleryFilterChips.jsx | 59 +++++++++++++++++++ src/components/gallary/GalleryFilterPanel.jsx | 41 +++++++++++-- .../gallary/ImageGalleryListView.jsx | 55 ++++++++++------- src/pages/Gallary/ImageGallaryPage.jsx | 36 +++++++++-- 4 files changed, 160 insertions(+), 31 deletions(-) create mode 100644 src/components/gallary/GalleryFilterChips.jsx diff --git a/src/components/gallary/GalleryFilterChips.jsx b/src/components/gallary/GalleryFilterChips.jsx new file mode 100644 index 00000000..8c09328d --- /dev/null +++ b/src/components/gallary/GalleryFilterChips.jsx @@ -0,0 +1,59 @@ +import React, { useMemo } from "react"; + +const GalleryFilterChips = ({ filter, filterData, removeFilterChip, clearFilter }) => { + const data = filterData?.data || filterData || {}; + + const filterChips = useMemo(() => { + const chips = []; + + const addGroup = (ids, list, label, key) => { + if (!ids?.length) return; + const items = ids.map((id) => ({ + id, + name: list?.find((i) => i.id === id)?.name || id, + })); + chips.push({ key, label, items }); + }; + + addGroup(filter.buildingIds, data.buildings, "Building", "buildingIds"); + addGroup(filter.floorIds, data.floors, "Floor", "floorIds"); + addGroup(filter.workAreaIds, data.workAreas, "Work Area", "workAreaIds"); + addGroup(filter.activityIds, data.activities, "Activity", "activityIds"); + addGroup(filter.workCategoryIds, data.workCategories, "Work Category", "workCategoryIds"); + addGroup(filter.uploadedByIds, data.uploadedBy, "Uploaded By", "uploadedByIds"); + addGroup(filter.serviceIds, data.services, "Service", "serviceIds"); + + return chips; + }, [filter, filterData]); + + if (!filterChips.length) return null; + return ( +
+ {filterChips.map((chipGroup) => ( +
+ {chipGroup.label}: + {chipGroup.items.map((item) => ( + + {item.name} +
+ ))} +
+ ); +}; + +export default GalleryFilterChips; diff --git a/src/components/gallary/GalleryFilterPanel.jsx b/src/components/gallary/GalleryFilterPanel.jsx index 6518eb74..e7a89172 100644 --- a/src/components/gallary/GalleryFilterPanel.jsx +++ b/src/components/gallary/GalleryFilterPanel.jsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from "react"; +import React, { forwardRef, useEffect, useImperativeHandle, useMemo, useState } from "react"; import { useImageGalleryFilter } from "../../hooks/useImageGallery"; import { useSelectedProject } from "../../slices/apiDataManager"; import { FormProvider, useForm } from "react-hook-form"; @@ -10,19 +10,52 @@ import SelectMultiple from "../common/SelectMultiple"; import { localToUtc } from "../../utils/appUtils"; import { useLocation } from "react-router-dom"; -const GalleryFilterPanel = ({ onApply }) => { +const GalleryFilterPanel = forwardRef(({ onApply, setFilterdata, clearFilter }, ref) => { const selectedProject = useSelectedProject(); const [resetKey, setResetKey] = useState(0); const { data, isLoading, isError, error } = useImageGalleryFilter(selectedProject); + + const dynamicDefaultFilter = useMemo(() => { + return { + ...defaultGalleryFilterValue, + buildingIds: defaultGalleryFilterValue.buildingIds || [], + floorIds: defaultGalleryFilterValue.floorIds || [], + workAreaIds: defaultGalleryFilterValue.workAreaIds || [], + activityIds: defaultGalleryFilterValue.activityIds || [], + workCategoryIds: defaultGalleryFilterValue.workCategoryIds || [], + startDate: defaultGalleryFilterValue.startDate, + endDate: defaultGalleryFilterValue.endDate, + uploadedByIds: defaultGalleryFilterValue.uploadedByIds || [], + serviceIds: defaultGalleryFilterValue.serviceIds || [], + }; + }, [selectedProject]); + + useImperativeHandle(ref, () => ({ + resetFieldValue: (name, value) => { + // Reset specific field + if (value !== undefined) { + setValue(name, value); + } else { + reset({ ...methods.getValues(), [name]: defaultFilter[name] }); + } + }, + getValues: methods.getValues, // optional, to read current filter state + })); + + useEffect(() => { + if (data && setFilterdata) { + setFilterdata(data); + } + }, [data, setFilterdata]); const closePanel = () => { document.querySelector(".offcanvas.show .btn-close")?.click(); }; const methods = useForm({ resolver: zodResolver(gallerySchema), - defaultValues: defaultGalleryFilterValue, + defaultValues: dynamicDefaultFilter, }); const { @@ -144,6 +177,6 @@ const GalleryFilterPanel = ({ onApply }) => { ); -}; +}); export default GalleryFilterPanel; diff --git a/src/components/gallary/ImageGalleryListView.jsx b/src/components/gallary/ImageGalleryListView.jsx index af5cfbc2..08dce746 100644 --- a/src/components/gallary/ImageGalleryListView.jsx +++ b/src/components/gallary/ImageGalleryListView.jsx @@ -8,7 +8,8 @@ import { ITEMS_PER_PAGE } from "../../utils/constants"; import Pagination from "../common/Pagination"; import { formatUTCToLocalTime } from "../../utils/dateUtils"; import { SpinnerLoader } from "../common/Loader"; -const ImageGalleryListView = ({filter}) => { +import GalleryFilterChips from "./GalleryFilterChips"; +const ImageGalleryListView = ({ filter, filterData, removeFilterChip, clearFilter }) => { const [hoveredImage, setHoveredImage] = useState(null); const selectedProject = useSelectedProject(); const [currentPage, setCurrentPage] = useState(1); @@ -27,40 +28,50 @@ const ImageGalleryListView = ({filter}) => { } }; - if (!data?.data?.length && !isLoading) { - return ( -
- - {selectedProject - ? "No images match the selected filters." - : "Please Select Project!"} - -
- ); -} + if (!data?.data?.length && !isLoading) { + return ( +
+ + {selectedProject + ? "No images match the selected filters." + : "Please Select Project!"} + +
+ ); + } - if (isLoading) { + if (isLoading) { return (
); - } + } + + + return (
+
+ +
{data?.data?.map((batch) => { - if (!batch.documents?.length) return null; + if (!batch.documents?.length) return null; const doc = batch.documents[0]; - const userName = `${doc.uploadedBy?.firstName || ""} ${ - doc.uploadedBy?.lastName || "" - }`.trim(); + const userName = `${doc.uploadedBy?.firstName || ""} ${doc.uploadedBy?.lastName || "" + }`.trim(); const date = formatUTCToLocalTime(doc.uploadedAt); // const hasArrows = batch.documents.length > scrollThreshold; @@ -112,7 +123,7 @@ const ImageGalleryListView = ({filter}) => { )} */}
(imageGroupRefs.current[batch.batchId] = el)} + // ref={(el) => (imageGroupRefs.current[batch.batchId] = el)} > {batch.documents.map((d, i) => { const hoverDate = moment().format("DD MMMM, YYYY"); diff --git a/src/pages/Gallary/ImageGallaryPage.jsx b/src/pages/Gallary/ImageGallaryPage.jsx index 501bd84c..d87b2fce 100644 --- a/src/pages/Gallary/ImageGallaryPage.jsx +++ b/src/pages/Gallary/ImageGallaryPage.jsx @@ -23,6 +23,7 @@ import GlobalModel from "../../components/common/GlobalModel"; import ViewGallery from "../../components/gallary/ViewGallery"; import { useFab } from "../../Context/FabContext"; import GalleryFilterPanel from "../../components/gallary/GalleryFilterPanel"; +import { defaultGalleryFilterValue } from "../../components/gallary/GallerySchema"; const GalleryContext = createContext(); @@ -36,12 +37,12 @@ export const useGalleryContext = () => { }; const ImageGalleryPage = () => { - const [filter, setFilter] = useState(); + const [filter, setFilter] = useState(defaultGalleryFilterValue); const selectedProjectId = useSelectedProject(); const { projectNames } = useProjectName(); - + const [filterData, setFilterdata] = useState(null); + const updatedRef = useRef(); const [openGallery, setOpenGallery] = useState({ isOpen: false, data: null }); - const { data: assignedServices = [], isLoading } = useProjectAssignedServices(selectedProjectId); @@ -55,13 +56,18 @@ const ImageGalleryPage = () => { setOpenGallery, }; + const clearFilter = () => setFilter(defaultGalleryFilterValue); const { setOffcanvasContent, setShowTrigger } = useFab(); useEffect(() => { setShowTrigger(true); setOffcanvasContent( "Gallery Filter", - + ); return () => { @@ -70,6 +76,22 @@ const ImageGalleryPage = () => { }; }, []); + const handleRemoveChip = (key, id) => { + setFilter((prev) => { + const updated = { ...prev }; + + if (Array.isArray(updated[key])) { + updated[key] = updated[key].filter((v) => v !== id); + setTimeout(() => updatedRef.current?.resetFieldValue(key, updated[key]), 0); + } else { + updated[key] = null; + setTimeout(() => updatedRef.current?.resetFieldValue(key, null), 0); + } + + return updated; + }); + }; + return (
@@ -105,7 +127,11 @@ const ImageGalleryPage = () => {
)} */} - +
{openGallery?.isOpen && ( From 4a66dad07adc30064acc805ae5a98ce95a494490 Mon Sep 17 00:00:00 2001 From: Kartik Sharma Date: Wed, 3 Dec 2025 11:17:06 +0530 Subject: [PATCH 2/4] UI updation in Organization. --- src/components/Organization/AssignOrg.jsx | 36 +++++++++---------- src/components/Organization/ManagOrg.jsx | 2 +- .../Organization/OrgPickerFromSPId.jsx | 14 ++++---- .../Organization/OrganizationsList.jsx | 1 + .../Organization/ViewOrganization.jsx | 28 +++++++-------- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/src/components/Organization/AssignOrg.jsx b/src/components/Organization/AssignOrg.jsx index d0886a62..b35402ed 100644 --- a/src/components/Organization/AssignOrg.jsx +++ b/src/components/Organization/AssignOrg.jsx @@ -96,11 +96,11 @@ const AssignOrg = ({ setStep }) => {
logo

{orgData.name}

+ src="/public/assets/img/orgLogo.png" + alt="logo" + width={40} + height={40} + />

{orgData.name}

-
Organization Info
+
Organization Info
{/* Contact Info */} -
+
{orgData.contactPerson}
-
+
{orgData.contactNumber}
-
+
-
{orgData.email}
+
{orgData.email}
-
+
{orgData.sprid}
-
+
{orgData.address}
diff --git a/src/components/Organization/ManagOrg.jsx b/src/components/Organization/ManagOrg.jsx index e73c34e1..d994b8b5 100644 --- a/src/components/Organization/ManagOrg.jsx +++ b/src/components/Organization/ManagOrg.jsx @@ -189,7 +189,7 @@ const ManagOrg = () => { )}
-
+