From 518928e4399852c9f3a0f5139155692fa279f95f Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Sat, 30 Aug 2025 17:31:36 +0530 Subject: [PATCH] adedd fillter sidepanel and handle filter object on api level --- .../Documents/DocumentFilterPanel.jsx | 186 +++++++++++++++++- src/components/Documents/DocumentSchema.js | 27 ++- src/components/Documents/DocumentSkeleton.jsx | 4 +- src/components/Documents/Documents.jsx | 50 ++++- src/components/Documents/DocumentsList.jsx | 61 ++++-- .../{NewDocument.jsx => ManageDocument.jsx} | 4 +- .../Expenses/ExpenseFilterPanel.jsx | 2 +- src/hooks/useDocument.js | 40 +++- src/repositories/DocumentRepository.jsx | 4 +- 9 files changed, 333 insertions(+), 45 deletions(-) rename src/components/Documents/{NewDocument.jsx => ManageDocument.jsx} (99%) diff --git a/src/components/Documents/DocumentFilterPanel.jsx b/src/components/Documents/DocumentFilterPanel.jsx index 0fa039fa..02cb1cff 100644 --- a/src/components/Documents/DocumentFilterPanel.jsx +++ b/src/components/Documents/DocumentFilterPanel.jsx @@ -1,9 +1,183 @@ -import React from 'react' +import React, { useState } from "react"; +import { useDocumentFilterEntities } from "../../hooks/useDocument"; +import { FormProvider, useForm } from "react-hook-form"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { + DocumentFilterDefaultValues, + DocumentFilterSchema, +} from "./DocumentSchema"; +import { DateRangePicker1 } from "../common/DateRangePicker"; +import SelectMultiple from "../common/SelectMultiple"; +import moment from "moment"; + +const DocumentFilterPanel = ({ entityTypeId, onApply }) => { + const [resetKey, setResetKey] = useState(0); + + const { data, isError, isLoading, error } = + useDocumentFilterEntities(entityTypeId); + + const methods = useForm({ + resolver: zodResolver(DocumentFilterSchema), + defaultValues: DocumentFilterDefaultValues, + }); + + const { handleSubmit, reset, setValue, watch } = methods; + + // Watch values from form + const isUploadedAt = watch("isUploadedAt"); + const isVerified = watch("isVerified"); + + // Close the offcanvas (bootstrap specific) + const closePanel = () => { + document.querySelector(".offcanvas.show .btn-close")?.click(); + }; + + const onSubmit = (values) => { + onApply({ + ...values, + startDate: values.startDate + ? moment.utc(values.startDate, "DD-MM-YYYY").toISOString() + : null, + endDate: values.endDate + ? moment.utc(values.endDate, "DD-MM-YYYY").toISOString() + : null, + }); + closePanel(); + }; + + const onClear = () => { + reset(DocumentFilterDefaultValues); + setResetKey((prev) => prev + 1); + onApply(DocumentFilterDefaultValues); + closePanel(); + }; + + if (isLoading) return
Loading...
; + if (isError) return
Error: {error?.message || "Something went wrong!"}
; + + const { uploadedBy = [], documentCategory = [], documentType = [], documentTag = [] } = + data?.data || {}; -const DocumentFilterPanel = () => { return ( -

filter

- ) -} + +
+ {/* Date Range Section */} +
+
+ +
+ + +
+
-export default DocumentFilterPanel \ No newline at end of file + +
+ + {/* Dropdown Filters */} +
+ + + + +
+ + {/* Status Filter */} +
+ +
+ + + +
+
+ + {/* Footer Buttons */} +
+ + +
+
+
+ ); +}; + +export default DocumentFilterPanel; diff --git a/src/components/Documents/DocumentSchema.js b/src/components/Documents/DocumentSchema.js index bb20e8b0..adb82152 100644 --- a/src/components/Documents/DocumentSchema.js +++ b/src/components/Documents/DocumentSchema.js @@ -71,9 +71,7 @@ export const DocumentPayloadSchema = (docConfig = {}) => { (val) => val !== null, { message: "Attachment is required" } ), - tags: z.array(TagSchema).optional().default([]), - }); }; @@ -95,3 +93,28 @@ export const defaultDocumentValues = { }, tags: [], }; + + +//--------------------Filter------------------------- + +export const DocumentFilterSchema = z.object({ + uploadedByIds: z.array(z.string()).default([]), + documentCategoryIds: z.array(z.string()).default([]), + documentTypeIds: z.array(z.string()).default([]), + documentTagIds: z.array(z.string()).default([]), + isUploadedAt: z.boolean().default(true), + isVerified: z.boolean().nullable().optional(), + startDate: z.string().nullable().optional(), + endDate: z.string().nullable().optional(), +}); +export const DocumentFilterDefaultValues = { + uploadedByIds: [], + documentCategoryIds: [], + documentTypeIds: [], + documentTagIds: [], + isUploadedAt: true, + isVerified: null, + startDate: null, + endDate: null, +}; + diff --git a/src/components/Documents/DocumentSkeleton.jsx b/src/components/Documents/DocumentSkeleton.jsx index af75fd01..94198326 100644 --- a/src/components/Documents/DocumentSkeleton.jsx +++ b/src/components/Documents/DocumentSkeleton.jsx @@ -19,7 +19,7 @@ const SkeletonCell = ({ export const DocumentTableSkeleton = ({ rows = 5 }) => { return ( -
+ @@ -65,6 +65,6 @@ export const DocumentTableSkeleton = ({ rows = 5 }) => { ))}
-
+ ); }; diff --git a/src/components/Documents/Documents.jsx b/src/components/Documents/Documents.jsx index cb1cd96c..5099cc1d 100644 --- a/src/components/Documents/Documents.jsx +++ b/src/components/Documents/Documents.jsx @@ -1,29 +1,53 @@ import React, { useEffect, useState } from "react"; import GlobalModel from "../common/GlobalModel"; -import NewDocument from "./NewDocument"; +import NewDocument from "./ManageDocument"; import { DOCUMENTS_ENTITIES } from "../../utils/constants"; import { useParams } from "react-router-dom"; import DocumentsList from "./DocumentsList"; import DocumentFilterPanel from "./DocumentFilterPanel"; import { useFab } from "../../Context/FabContext"; +import { useForm } from "react-hook-form"; +import { + DocumentFilterDefaultValues, + DocumentFilterSchema, +} from "./DocumentSchema"; +import { zodResolver } from "@hookform/resolvers/zod"; +import ManageDocument from "./ManageDocument"; const Documents = ({ Document_Entity, Entity }) => { const [searchText, setSearchText] = useState(""); + const [filters, setFilter] = useState(); const [isRefetching, setIsRefetching] = useState(false); const [refetchFn, setRefetchFn] = useState(null); const { employeeId } = useParams(); const [isUpload, setUpload] = useState(false); const { setOffcanvasContent, setShowTrigger } = useFab(); + const methods = useForm({ + resolver: zodResolver(DocumentFilterSchema), + defaultValues: DocumentFilterDefaultValues, + }); + + const { reset } = methods; + + const clearFilter = () => { + setFilter(DocumentFilterDefaultValues); + reset(); + }; + useEffect(() => { setShowTrigger(true); - setOffcanvasContent("Document Filters", ); + setOffcanvasContent( + "Document Filters", + + ); return () => { setShowTrigger(false); setOffcanvasContent("", null); }; }, []); + return (
@@ -41,12 +65,21 @@ const Documents = ({ Document_Entity, Entity }) => { {/* Actions */}
- refetchFn && refetchFn()}> + { + setSearchText(""); + setFilter(DocumentFilterDefaultValues); + refetchFn && refetchFn(); + }} + > Refresh - +