Merge pull request 'Adding ImageGallery Chips.' (#517) from Image_Gallery_FilterChips into Purchase_Invoice_Management
Reviewed-on: #517 merged
This commit is contained in:
commit
8dfc8e4336
@ -96,11 +96,11 @@ const AssignOrg = ({ setStep }) => {
|
|||||||
<div className="d-flex justify-content-between align-items-center text-start mb-1">
|
<div className="d-flex justify-content-between align-items-center text-start mb-1">
|
||||||
<div className="d-flex flex-row gap-2 align-items-center text-wrap">
|
<div className="d-flex flex-row gap-2 align-items-center text-wrap">
|
||||||
<img
|
<img
|
||||||
src="/public/assets/img/orgLogo.png"
|
src="/public/assets/img/orgLogo.png"
|
||||||
alt="logo"
|
alt="logo"
|
||||||
width={40}
|
width={40}
|
||||||
height={40}
|
height={40}
|
||||||
/> <p className="fw-semibold fs-6 m-0">{orgData.name}</p>
|
/> <p className="fw-semibold fs-5 mt-2 m-0">{orgData.name}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-end">
|
<div className="text-end">
|
||||||
<button
|
<button
|
||||||
@ -113,60 +113,60 @@ const AssignOrg = ({ setStep }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex text-secondary mb-2"> <i className="bx bx-sm bx-info-circle me-1" /> Organization Info</div>
|
<div className="d-flex text-secondary mb-3"> <i className="bx bx-sm bx-info-circle me-2" /> Organization Info</div>
|
||||||
{/* Contact Info */}
|
{/* Contact Info */}
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-4">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
style={{ minWidth: "130px" }}
|
style={{ minWidth: "130px" }}
|
||||||
>
|
>
|
||||||
<i className="bx bx-sm bx-user me-1" /> Contact Person :
|
<i className="bx bx-sm bx-user me-1" /> Contact Person :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{orgData.contactPerson}</div>
|
<div className="text-muted">{orgData.contactPerson}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-4">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
style={{ minWidth: "130px" }}
|
style={{ minWidth: "130px" }}
|
||||||
>
|
>
|
||||||
<i className='bx bx-sm me-1 bx-phone'></i> Contact Number :
|
<i className='bx bx-sm me-1 bx-phone'></i> Contact Number :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{orgData.contactNumber}</div>
|
<div className="text-muted">{orgData.contactNumber}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-4">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
style={{ minWidth: "130px" }}
|
style={{ minWidth: "130px" }}
|
||||||
>
|
>
|
||||||
<i className='bx bx-sm me-1 bx-envelope'></i> Email Address :
|
<i className='bx bx-sm me-1 bx-envelope'></i> Email Address :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{orgData.email}</div>
|
<div className="text-muted text-wrap">{orgData.email}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 mb-3">
|
<div className="col-12 mb-4">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
style={{ maxWidth: "130px" }}
|
style={{ maxWidth: "130px" }}
|
||||||
>
|
>
|
||||||
<i className="bx bx-sm me-1 bx-barcode"></i>
|
<i className="bx bx-sm me-2 bx-barcode"></i>
|
||||||
Service Provider Id (SPRID) :
|
Service Provider Id (SPRID) :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{orgData.sprid}</div>
|
<div className="text-muted">{orgData.sprid}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 mb-3">
|
<div className="col-12 mb-4">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-1 mb-0 fw-semibold"
|
className="form-label me-1 mb-0 fw-semibold"
|
||||||
style={{ minWidth: "130px" }}
|
style={{ minWidth: "130px" }}
|
||||||
>
|
>
|
||||||
<i className='bx bx-sm me-1 bx-map'></i> Address :
|
<i className='bx bx-sm me-1 bx-map'></i> Address :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted text-start">{orgData.address}</div>
|
<div className="text-muted text-start">{orgData.address}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -189,7 +189,7 @@ const ManagOrg = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="d-flex justify-content-between gap-2 my-2">
|
<div className="d-flex justify-content-between gap-2 my-5">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="btn btn-sm btn-outline-secondary"
|
className="btn btn-sm btn-outline-secondary"
|
||||||
|
|||||||
@ -45,7 +45,7 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="d-block mt-4">
|
<div className="d-block mt-4">
|
||||||
<form onSubmit={handleSubmit(onSubmit)}>
|
<form onSubmit={handleSubmit(onSubmit)}>
|
||||||
<div className="row align-items-center g-2">
|
<div className="row align-items-center g-2 mb-3">
|
||||||
{/* Input Section */}
|
{/* Input Section */}
|
||||||
<div className="col-12 col-md-8 d-block d-md-flex align-items-center gap-2 m-0 text-start">
|
<div className="col-12 col-md-8 d-block d-md-flex align-items-center gap-2 m-0 text-start">
|
||||||
<Label className="text-nowrap mb-1 mb-md-0" required>
|
<Label className="text-nowrap mb-1 mb-md-0" required>
|
||||||
@ -88,7 +88,7 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
|
|||||||
<div className="py-2 text-tiny text-center">
|
<div className="py-2 text-tiny text-center">
|
||||||
<div className="d-flex flex-column gap-2 border-0 bg-none">
|
<div className="d-flex flex-column gap-2 border-0 bg-none">
|
||||||
{data.data.map((org) => (
|
{data.data.map((org) => (
|
||||||
<div className="d-flex flex-row gap-2 text-start text-black ">
|
<div className="d-flex flex-row gap-2 text-start text-black mt-3">
|
||||||
<div className="mt-1">
|
<div className="mt-1">
|
||||||
<img
|
<img
|
||||||
src="/public/assets/img/orgLogo.png"
|
src="/public/assets/img/orgLogo.png"
|
||||||
@ -97,19 +97,19 @@ const OrgPickerFromSPId = ({ title, placeholder }) => {
|
|||||||
height={50}
|
height={50}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex flex-column p-0 m-0 cursor-pointer">
|
<div className="d-flex flex-column p-0 m-0 cursor-pointer mb-3">
|
||||||
<span className="fs-6 fw-semibold">{org.name}</span>
|
<span className="fs-6 fw-semibold mb-2">{org.name}</span>
|
||||||
<div className="d-flex gap-2">
|
<div className="d-flex gap-2">
|
||||||
<small
|
<small
|
||||||
className=" fw-semibold text-uppercase"
|
className=" fw-semibold text-uppercase mb-2"
|
||||||
style={{ letterSpacing: "1px" }}
|
style={{ letterSpacing: "1px" }}
|
||||||
>
|
>
|
||||||
SPRID :{" "}
|
SPRID :{" "}
|
||||||
</small>
|
</small>
|
||||||
<small className="fs-6">{org.sprid}</small>
|
<small className="fs-6">{org.sprid}</small>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex flex-row gap-2">
|
<div className="d-flex flex-row gap-2 mb-4">
|
||||||
<small className="text-small fw-semibold">Address:</small>
|
<small className="text-small fw-semibold ">Address:</small>
|
||||||
<div className="d-flex text-wrap">{org.address}</div>
|
<div className="d-flex text-wrap">{org.address}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="m-0 p-0">
|
<div className="m-0 p-0">
|
||||||
|
|||||||
@ -122,6 +122,7 @@ const OrganizationsList = ({searchText}) => {
|
|||||||
{organizationsColumns.map((col) => (
|
{organizationsColumns.map((col) => (
|
||||||
<td
|
<td
|
||||||
key={col.key}
|
key={col.key}
|
||||||
|
style={{ height: "50px" }}
|
||||||
className={`d-table-cell ${col.align ?? ""}`}
|
className={`d-table-cell ${col.align ?? ""}`}
|
||||||
>
|
>
|
||||||
{col.customRender
|
{col.customRender
|
||||||
|
|||||||
@ -9,7 +9,7 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
return (
|
return (
|
||||||
<div className="row text-black text-black text-start ">
|
<div className="row text-black text-black text-start ">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="col-12 mb-3">
|
<div className="col-12 mb-5">
|
||||||
<div className="d-flex justify-content-between align-items-center text-start mb-1">
|
<div className="d-flex justify-content-between align-items-center text-start mb-1">
|
||||||
<div className="d-flex flex-row gap-2 align-items-center text-wrap">
|
<div className="d-flex flex-row gap-2 align-items-center text-wrap">
|
||||||
<img
|
<img
|
||||||
@ -18,7 +18,7 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
width={40}
|
width={40}
|
||||||
height={40}
|
height={40}
|
||||||
/>{" "}
|
/>{" "}
|
||||||
<p className="fw-semibold fs-6 m-0">{data?.name}</p>
|
<p className="fw-semibold fs-5 mt-2 m-0">{data?.name}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="text-end">
|
<div className="text-end">
|
||||||
<span
|
<span
|
||||||
@ -30,12 +30,12 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex text-secondary mb-2">
|
<div className="d-flex text-secondary mb-5">
|
||||||
{" "}
|
{" "}
|
||||||
<i className="bx bx-sm bx-info-circle me-1" /> Organization Info
|
<i className="bx bx-sm bx-info-circle me-1" /> Organization Info
|
||||||
</div>
|
</div>
|
||||||
{/* Contact Info */}
|
{/* Contact Info */}
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-5">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
@ -46,7 +46,7 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
<div className="text-muted">{data?.contactPerson}</div>
|
<div className="text-muted">{data?.contactPerson}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-6 mb-3">
|
<div className="col-md-12 mb-5">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
@ -57,7 +57,7 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
<div className="text-muted">{data?.contactNumber}</div>
|
<div className="text-muted">{data?.contactNumber}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-md-12 mb-3">
|
<div className="col-md-12 mb-5">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
@ -68,32 +68,32 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
<div className="text-muted">{data?.email}</div>
|
<div className="text-muted">{data?.email}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-6 mb-3">
|
<div className="col-12 mb-5">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
style={{ maxWidth: "130px" }}
|
style={{ maxWidth: "130px" }}
|
||||||
>
|
>
|
||||||
<i className="bx bx-sm me-1 bx-barcode"></i>
|
<i className="bx bx-sm me-2 bx-barcode"></i>
|
||||||
Service Provider Id (SPRID) :
|
Service Provider Id (SPRID) :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{data?.sprid}</div>
|
<div className="text-muted">{data?.sprid}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-6 mb-3">
|
<div className="col-12 mb-5">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-2 mb-0 fw-semibold"
|
className="form-label me-2 mb-0 fw-semibold"
|
||||||
style={{ maxWidth: "130px" }}
|
style={{ maxWidth: "130px" }}
|
||||||
>
|
>
|
||||||
<i className="bx bx-sm me-1 bx-group"></i>
|
<i className="bx bx-sm me-2 bx-group"></i>
|
||||||
Employees :
|
Employees :
|
||||||
</label>
|
</label>
|
||||||
<div className="text-muted">{data?.activeEmployeeCount}</div>
|
<div className="text-muted">{data?.activeEmployeeCount}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 mb-3">
|
<div className="col-12 mb-5">
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<label
|
<label
|
||||||
className="form-label me-1 mb-0 fw-semibold"
|
className="form-label me-1 mb-0 fw-semibold"
|
||||||
@ -104,7 +104,7 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
<div className="text-muted text-start">{data?.address}</div>
|
<div className="text-muted text-start">{data?.address}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-12 mb-3">
|
<div className="col-12 mb-5">
|
||||||
<div
|
<div
|
||||||
className="d-flex justify-content-between align-items-center text-secondary mb-2 cursor-pointer"
|
className="d-flex justify-content-between align-items-center text-secondary mb-2 cursor-pointer"
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
@ -162,7 +162,7 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Services Section */}
|
{/* Services Section */}
|
||||||
<div className="col-12 mb-3">
|
<div className="col-12 mb-5">
|
||||||
<div
|
<div
|
||||||
className="d-flex justify-content-between align-items-center text-secondary mb-2 cursor-pointer"
|
className="d-flex justify-content-between align-items-center text-secondary mb-2 cursor-pointer"
|
||||||
data-bs-toggle="collapse"
|
data-bs-toggle="collapse"
|
||||||
@ -180,7 +180,7 @@ const VieworgDataanization = ({ orgId }) => {
|
|||||||
{data?.services && data.services.length > 0 ? (
|
{data?.services && data.services.length > 0 ? (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{data.services.map((service) => (
|
{data.services.map((service) => (
|
||||||
<div key={service.id} className="col-md-12 mb-3">
|
<div key={service.id} className="col-md-12 mb-5">
|
||||||
<div className="card h-100 shadow-sm border-0">
|
<div className="card h-100 shadow-sm border-0">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<h6 className="fw-semibold mb-1">
|
<h6 className="fw-semibold mb-1">
|
||||||
|
|||||||
59
src/components/gallary/GalleryFilterChips.jsx
Normal file
59
src/components/gallary/GalleryFilterChips.jsx
Normal file
@ -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 (
|
||||||
|
<div className="d-flex flex-wrap align-items-center gap-2">
|
||||||
|
{filterChips.map((chipGroup) => (
|
||||||
|
<div key={chipGroup.key} className="d-flex align-items-center flex-wrap">
|
||||||
|
<span className="fw-semibold me-2">{chipGroup.label}:</span>
|
||||||
|
{chipGroup.items.map((item) => (
|
||||||
|
<span
|
||||||
|
key={item.id}
|
||||||
|
className="d-flex align-items-center bg-light rounded px-2 py-1 me-1"
|
||||||
|
>
|
||||||
|
<span>{item.name}</span>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className="btn-close btn-close-white btn-sm ms-2"
|
||||||
|
style={{
|
||||||
|
filter: "invert(1) grayscale(1)",
|
||||||
|
opacity: 0.7,
|
||||||
|
fontSize: "0.6rem",
|
||||||
|
}}
|
||||||
|
onClick={() => removeFilterChip(chipGroup.key, item.id)}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default GalleryFilterChips;
|
||||||
@ -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 { useImageGalleryFilter } from "../../hooks/useImageGallery";
|
||||||
import { useSelectedProject } from "../../slices/apiDataManager";
|
import { useSelectedProject } from "../../slices/apiDataManager";
|
||||||
import { FormProvider, useForm } from "react-hook-form";
|
import { FormProvider, useForm } from "react-hook-form";
|
||||||
@ -10,19 +10,52 @@ import SelectMultiple from "../common/SelectMultiple";
|
|||||||
import { localToUtc } from "../../utils/appUtils";
|
import { localToUtc } from "../../utils/appUtils";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
|
|
||||||
const GalleryFilterPanel = ({ onApply }) => {
|
const GalleryFilterPanel = forwardRef(({ onApply, setFilterdata, clearFilter }, ref) => {
|
||||||
const selectedProject = useSelectedProject();
|
const selectedProject = useSelectedProject();
|
||||||
const [resetKey, setResetKey] = useState(0);
|
const [resetKey, setResetKey] = useState(0);
|
||||||
|
|
||||||
const { data, isLoading, isError, error } =
|
const { data, isLoading, isError, error } =
|
||||||
useImageGalleryFilter(selectedProject);
|
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 = () => {
|
const closePanel = () => {
|
||||||
document.querySelector(".offcanvas.show .btn-close")?.click();
|
document.querySelector(".offcanvas.show .btn-close")?.click();
|
||||||
};
|
};
|
||||||
const methods = useForm({
|
const methods = useForm({
|
||||||
resolver: zodResolver(gallerySchema),
|
resolver: zodResolver(gallerySchema),
|
||||||
defaultValues: defaultGalleryFilterValue,
|
defaultValues: dynamicDefaultFilter,
|
||||||
});
|
});
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@ -144,6 +177,6 @@ const GalleryFilterPanel = ({ onApply }) => {
|
|||||||
</FormProvider>
|
</FormProvider>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
});
|
||||||
|
|
||||||
export default GalleryFilterPanel;
|
export default GalleryFilterPanel;
|
||||||
|
|||||||
@ -8,7 +8,8 @@ import { ITEMS_PER_PAGE } from "../../utils/constants";
|
|||||||
import Pagination from "../common/Pagination";
|
import Pagination from "../common/Pagination";
|
||||||
import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
import { formatUTCToLocalTime } from "../../utils/dateUtils";
|
||||||
import { SpinnerLoader } from "../common/Loader";
|
import { SpinnerLoader } from "../common/Loader";
|
||||||
const ImageGalleryListView = ({filter}) => {
|
import GalleryFilterChips from "./GalleryFilterChips";
|
||||||
|
const ImageGalleryListView = ({ filter, filterData, removeFilterChip, clearFilter }) => {
|
||||||
const [hoveredImage, setHoveredImage] = useState(null);
|
const [hoveredImage, setHoveredImage] = useState(null);
|
||||||
const selectedProject = useSelectedProject();
|
const selectedProject = useSelectedProject();
|
||||||
const [currentPage, setCurrentPage] = useState(1);
|
const [currentPage, setCurrentPage] = useState(1);
|
||||||
@ -27,40 +28,50 @@ const ImageGalleryListView = ({filter}) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!data?.data?.length && !isLoading) {
|
if (!data?.data?.length && !isLoading) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className="d-flex justify-content-center align-items-center text-muted"
|
className="d-flex justify-content-center align-items-center text-muted"
|
||||||
style={{ minHeight: "50vh" }}
|
style={{ minHeight: "50vh" }}
|
||||||
>
|
>
|
||||||
<span style={{ fontSize: "0.9rem" }}>
|
<span style={{ fontSize: "0.9rem" }}>
|
||||||
{selectedProject
|
{selectedProject
|
||||||
? "No images match the selected filters."
|
? "No images match the selected filters."
|
||||||
: "Please Select Project!"}
|
: "Please Select Project!"}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
<div className="page-min-h d-flex justify-content-center align-items-center">
|
<div className="page-min-h d-flex justify-content-center align-items-center">
|
||||||
<SpinnerLoader />
|
<SpinnerLoader />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="main-content">
|
<div className="main-content">
|
||||||
|
<div className="col-12 mb-2 mt-2 px-4">
|
||||||
|
<GalleryFilterChips
|
||||||
|
filter={filter}
|
||||||
|
filterData={filterData}
|
||||||
|
removeFilterChip={removeFilterChip}
|
||||||
|
clearFilter={clearFilter}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className="activity-section">
|
<div className="activity-section">
|
||||||
{data?.data?.map((batch) => {
|
{data?.data?.map((batch) => {
|
||||||
if (!batch.documents?.length) return null;
|
if (!batch.documents?.length) return null;
|
||||||
|
|
||||||
const doc = batch.documents[0];
|
const doc = batch.documents[0];
|
||||||
const userName = `${doc.uploadedBy?.firstName || ""} ${
|
const userName = `${doc.uploadedBy?.firstName || ""} ${doc.uploadedBy?.lastName || ""
|
||||||
doc.uploadedBy?.lastName || ""
|
}`.trim();
|
||||||
}`.trim();
|
|
||||||
const date = formatUTCToLocalTime(doc.uploadedAt);
|
const date = formatUTCToLocalTime(doc.uploadedAt);
|
||||||
// const hasArrows = batch.documents.length > scrollThreshold;
|
// const hasArrows = batch.documents.length > scrollThreshold;
|
||||||
|
|
||||||
@ -112,7 +123,7 @@ const ImageGalleryListView = ({filter}) => {
|
|||||||
)} */}
|
)} */}
|
||||||
<div
|
<div
|
||||||
className="image-group-horizontal"
|
className="image-group-horizontal"
|
||||||
// ref={(el) => (imageGroupRefs.current[batch.batchId] = el)}
|
// ref={(el) => (imageGroupRefs.current[batch.batchId] = el)}
|
||||||
>
|
>
|
||||||
{batch.documents.map((d, i) => {
|
{batch.documents.map((d, i) => {
|
||||||
const hoverDate = moment().format("DD MMMM, YYYY");
|
const hoverDate = moment().format("DD MMMM, YYYY");
|
||||||
|
|||||||
@ -47,6 +47,7 @@ export const useImageGalleryFilter = (project)=>{
|
|||||||
const response = await ImageGalleryRepository.getImageGalleryFilter(project);
|
const response = await ImageGalleryRepository.getImageGalleryFilter(project);
|
||||||
return response.data;
|
return response.data;
|
||||||
},
|
},
|
||||||
|
enabled:!!project
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,6 +23,7 @@ import GlobalModel from "../../components/common/GlobalModel";
|
|||||||
import ViewGallery from "../../components/gallary/ViewGallery";
|
import ViewGallery from "../../components/gallary/ViewGallery";
|
||||||
import { useFab } from "../../Context/FabContext";
|
import { useFab } from "../../Context/FabContext";
|
||||||
import GalleryFilterPanel from "../../components/gallary/GalleryFilterPanel";
|
import GalleryFilterPanel from "../../components/gallary/GalleryFilterPanel";
|
||||||
|
import { defaultGalleryFilterValue } from "../../components/gallary/GallerySchema";
|
||||||
|
|
||||||
const GalleryContext = createContext();
|
const GalleryContext = createContext();
|
||||||
|
|
||||||
@ -36,12 +37,12 @@ export const useGalleryContext = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const ImageGalleryPage = () => {
|
const ImageGalleryPage = () => {
|
||||||
const [filter, setFilter] = useState();
|
const [filter, setFilter] = useState(defaultGalleryFilterValue);
|
||||||
const selectedProjectId = useSelectedProject();
|
const selectedProjectId = useSelectedProject();
|
||||||
const { projectNames } = useProjectName();
|
const { projectNames } = useProjectName();
|
||||||
|
const [filterData, setFilterdata] = useState(null);
|
||||||
|
const updatedRef = useRef();
|
||||||
const [openGallery, setOpenGallery] = useState({ isOpen: false, data: null });
|
const [openGallery, setOpenGallery] = useState({ isOpen: false, data: null });
|
||||||
|
|
||||||
const { data: assignedServices = [], isLoading } =
|
const { data: assignedServices = [], isLoading } =
|
||||||
useProjectAssignedServices(selectedProjectId);
|
useProjectAssignedServices(selectedProjectId);
|
||||||
|
|
||||||
@ -55,13 +56,18 @@ const ImageGalleryPage = () => {
|
|||||||
setOpenGallery,
|
setOpenGallery,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const clearFilter = () => setFilter(defaultGalleryFilterValue);
|
||||||
const { setOffcanvasContent, setShowTrigger } = useFab();
|
const { setOffcanvasContent, setShowTrigger } = useFab();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setShowTrigger(true);
|
setShowTrigger(true);
|
||||||
setOffcanvasContent(
|
setOffcanvasContent(
|
||||||
"Gallery Filter",
|
"Gallery Filter",
|
||||||
<GalleryFilterPanel onApply={setFilter} />
|
<GalleryFilterPanel
|
||||||
|
onApply={setFilter}
|
||||||
|
ref={updatedRef}
|
||||||
|
clearFilter={clearFilter}
|
||||||
|
setFilterdata={setFilterdata} />
|
||||||
);
|
);
|
||||||
|
|
||||||
return () => {
|
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 (
|
return (
|
||||||
<GalleryContext.Provider value={contextMessager}>
|
<GalleryContext.Provider value={contextMessager}>
|
||||||
<div className="container-fluid">
|
<div className="container-fluid">
|
||||||
@ -78,34 +100,11 @@ const ImageGalleryPage = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<div className="card page-min-h p-2">
|
<div className="card page-min-h p-2">
|
||||||
{/* {selectedProjectId && (
|
<ImageGalleryListView
|
||||||
<div className="d-flex flex-row w-20 pb-2">
|
filter={filter}
|
||||||
{!isLoading && assignedServices?.length === 0 ? (
|
filterData={filterData}
|
||||||
<span className="badge bg-label-secondary">
|
removeFilterChip={handleRemoveChip}
|
||||||
Not service assiged yet
|
clearFilter={clearFilter} />
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<select className="form-select form-select-sm">
|
|
||||||
<option>Select Service</option>
|
|
||||||
{isLoading ? (
|
|
||||||
<option>Loading...</option>
|
|
||||||
) : assignedServices.length === 1 ? (
|
|
||||||
<span className="badge bg-label-secondary">
|
|
||||||
{assignedServices[0].name}
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
assignedServices?.map((service) => (
|
|
||||||
<option key={service.id} value={service?.id}>
|
|
||||||
{service?.name}
|
|
||||||
</option>
|
|
||||||
))
|
|
||||||
)}
|
|
||||||
</select>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)} */}
|
|
||||||
|
|
||||||
<ImageGalleryListView filter={filter} />
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{openGallery?.isOpen && (
|
{openGallery?.isOpen && (
|
||||||
|
|||||||
@ -140,13 +140,13 @@ const CollectionPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="col-12 col-sm-8 d-block d-sm-flex justify-content-end ga-2 align-items-center gap-2">
|
<div className="col-12 col-sm-8 d-block d-sm-flex justify-content-end ga-2 align-items-center gap-2">
|
||||||
<input
|
<input
|
||||||
type="search"
|
type="search"
|
||||||
value={searchText}
|
value={searchText}
|
||||||
onChange={(e) => setSearchText(e.target.value)}
|
onChange={(e) => setSearchText(e.target.value)}
|
||||||
placeholder="Search Collection"
|
placeholder="Search Collection"
|
||||||
className="form-control form-control-sm mt-2 mt-sm-0"
|
className="form-control form-control-sm w-25 mt-2 mt-sm-0"
|
||||||
/>
|
/>
|
||||||
<div className="d-flex justify-content-between justify-content-sm-between mt-2 mt-sm-0">
|
<div className="d-flex justify-content-between justify-content-sm-between mt-2 mt-sm-0">
|
||||||
<FormProvider {...methods} className="me-3">
|
<FormProvider {...methods} className="me-3">
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user