Adding Card inside Image Gallery.

This commit is contained in:
Kartik Sharma 2025-09-20 14:52:32 +05:30
parent eaccf0fca2
commit 32bcaf2602

View File

@ -22,14 +22,12 @@ const ImageGalleryPage = () => {
const { openModal } = useModal();
const { setOffcanvasContent, setShowTrigger } = useFab();
// Auto-select first project if none selected
useEffect(() => {
if (!selectedProjectId && projectNames?.length) {
dispatch(setProjectId(projectNames[0].id));
}
}, [selectedProjectId, projectNames, dispatch]);
// --- Filters state ---
const [appliedFilters, setAppliedFilters] = useState({
buildingIds: [],
floorIds: [],
@ -41,18 +39,11 @@ const ImageGalleryPage = () => {
endDate: null,
});
const {
data,
fetchNextPage,
hasNextPage,
isLoading,
isFetchingNextPage,
refetch,
} = useImageGallery(selectedProjectId, appliedFilters);
const { data, fetchNextPage, hasNextPage, isLoading, isFetchingNextPage, refetch } =
useImageGallery(selectedProjectId, appliedFilters);
const images = data?.pages.flatMap((page) => page.data) || [];
// --- Utility: store mappings independent of images ---
const [labelMaps, setLabelMaps] = useState({
buildings: new Map(),
floors: new Map(),
@ -92,31 +83,21 @@ const ImageGalleryPage = () => {
});
}, [images]);
// --- Apply filters ---
const handleApplyFilters = useCallback((values) => setAppliedFilters(values), []);
// --- Remove single filter ---
const handleRemoveFilter = (filterKey, valueId) => {
setAppliedFilters((prev) => {
const updated = { ...prev };
if (Array.isArray(updated[filterKey])) {
updated[filterKey] = updated[filterKey].filter((id) => id !== valueId);
}
else if (filterKey === "startDate" || filterKey === "endDate") {
updated[filterKey] = null;
}
else if (filterKey === "dateRange") {
} else if (filterKey === "startDate" || filterKey === "endDate" || filterKey === "dateRange") {
updated.startDate = null;
updated.endDate = null;
}
return updated;
});
};
// --- Chips ---
const appliedFiltersChips = useMemo(() => {
const chips = [];
const { buildings, floors, activities, workAreas, workCategories, uploadedByUsers } = labelMaps;
@ -139,6 +120,7 @@ const ImageGalleryPage = () => {
appliedFilters.workCategoryIds?.forEach((id) =>
chips.push({ label: "Work Category", value: workCategories.get(id) || id, key: "workCategoryIds", id })
);
if (appliedFilters.startDate || appliedFilters.endDate) {
const start = appliedFilters.startDate ? moment(appliedFilters.startDate).format("DD MMM, YYYY") : "";
const end = appliedFilters.endDate ? moment(appliedFilters.endDate).format("DD MMM, YYYY") : "";
@ -147,10 +129,8 @@ const ImageGalleryPage = () => {
return chips;
}, [appliedFilters, labelMaps]);
// --- Refetch on filter change ---
useEffect(() => { refetch(); }, [appliedFilters, refetch]);
// --- Filter Panel ---
const filterPanelElement = useMemo(
() => (
<ImageGalleryFilters
@ -168,7 +148,6 @@ const ImageGalleryPage = () => {
[labelMaps, appliedFilters, handleApplyFilters]
);
// --- Fab Offcanvas ---
useEffect(() => {
setShowTrigger(true);
setOffcanvasContent("Gallery Filters", filterPanelElement);
@ -178,14 +157,12 @@ const ImageGalleryPage = () => {
};
}, [filterPanelElement, setOffcanvasContent, setShowTrigger]);
// --- EventBus ---
useEffect(() => {
const handler = (data) => { if (data.projectId === selectedProjectId) refetch(); };
eventBus.on("image_gallery", handler);
return () => eventBus.off("image_gallery", handler);
}, [selectedProjectId, refetch]);
// --- Infinite scroll ---
useEffect(() => {
if (!loaderRef.current) return;
const observer = new IntersectionObserver(
@ -199,77 +176,49 @@ const ImageGalleryPage = () => {
}, [hasNextPage, isFetchingNextPage, isLoading, fetchNextPage]);
return (
<div className="gallery-container container-fluid">
<div className="container my-3">
<Breadcrumb data={[{ label: "Home", link: "/" }, { label: "Gallery" }]} />
{appliedFiltersChips.length > 0 && (
<div className="mb-3 text-start d-flex flex-wrap align-items-center gap-2">
<strong className="me-2 fs-6 ms-1">Filters:</strong>
{/* Card wrapper */}
<div className="card shadow-sm">
<div className="card-body">
{/* Group chips by label */}
{["Building", "Floor", "Work Area", "Activity", "Uploaded By", "Work Category"].map((label) => {
const chipsForLabel = appliedFiltersChips.filter((chip) => chip.label === label);
if (chipsForLabel.length === 0) return null;
return (
<span key={label} className="d-flex align-items-center px-2 py-1 rounded" style={{ background: "transparent" }}>
<strong className="me-1">{label} :</strong>
{chipsForLabel.map((chip, idx) => (
<span
key={chip.id}
className="d-flex align-items-center bg-label-secondary px-2 py-1 rounded me-1"
>
{chip.value}
<button
type="button"
className="btn-close btn-close-white btn-sm ms-1"
aria-label="Remove"
onClick={() => handleRemoveFilter(chip.key, chip.id)}
/>
</span>
))}
</span>
);
})}
{/* Date Range */}
{appliedFiltersChips.some((chip) => chip.label === "Date Range") && (
<span className="d-flex align-items-center px-2 py-1 rounded bg-label-secondary">
<strong className="me-1">Date Range :</strong>
{appliedFiltersChips
.filter((chip) => chip.label === "Date Range")
.map((chip, idx) => (
<span key={idx} className="d-flex align-items-center me-1">
{chip.value}
<button
type="button"
className="btn-close btn-close-white btn-sm ms-1"
aria-label="Remove"
onClick={() => handleRemoveFilter(chip.key, chip.id)}
/>
</span>
))}
</span>
{/* Filter Chips */}
{appliedFiltersChips.length > 0 && (
<div className="mb-3 d-flex flex-wrap align-items-center gap-2">
<strong className="me-2 fs-6">Filters:</strong>
{appliedFiltersChips.map((chip, idx) => (
<span key={idx} className="d-flex align-items-center bg-label-secondary px-2 py-1 rounded me-1">
{chip.label} : {chip.value}
<button
type="button"
className="btn-close btn-close-white btn-sm ms-1"
aria-label="Remove"
onClick={() => handleRemoveFilter(chip.key, chip.id)}
/>
</span>
))}
</div>
)}
{/* Gallery */}
{isLoading ? (
<ImageGallerySkeleton count={4} />
) : (
<ImageGalleryListView
images={images}
isLoading={isLoading}
isFetchingNextPage={isFetchingNextPage}
hasNextPage={hasNextPage}
loaderRef={loaderRef}
openModal={openModal}
formatUTCToLocalTime={formatUTCToLocalTime}
moment={moment}
/>
)}
</div>
)}
{isLoading ? (
<ImageGallerySkeleton count={4} />
) : (
<ImageGalleryListView
images={images}
isLoading={isLoading}
isFetchingNextPage={isFetchingNextPage}
hasNextPage={hasNextPage}
loaderRef={loaderRef}
openModal={openModal}
formatUTCToLocalTime={formatUTCToLocalTime}
moment={moment}
/>
)}
</div>
</div>
);
};