diff --git a/src/pages/ClosedRequests/ClosedRequests.tsx b/src/pages/ClosedRequests/ClosedRequests.tsx index cbf29a2..f88bc7d 100644 --- a/src/pages/ClosedRequests/ClosedRequests.tsx +++ b/src/pages/ClosedRequests/ClosedRequests.tsx @@ -27,6 +27,7 @@ export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) { searchTerm: filters.searchTerm, statusFilter: filters.statusFilter, priorityFilter: filters.priorityFilter, + templateTypeFilter: filters.templateTypeFilter, sortBy: filters.sortBy, sortOrder: filters.sortOrder, }); @@ -39,9 +40,10 @@ export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) { search: filters.searchTerm || undefined, status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined, priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined, - sortBy: filters.sortBy, - sortOrder: filters.sortOrder, - }); + templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, + sortBy: filters.sortBy, + sortOrder: filters.sortOrder, + }); hasInitialFetchRun.current = true; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); // Only on mount @@ -55,6 +57,7 @@ export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) { prev.searchTerm !== filters.searchTerm || prev.statusFilter !== filters.statusFilter || prev.priorityFilter !== filters.priorityFilter || + prev.templateTypeFilter !== filters.templateTypeFilter || prev.sortBy !== filters.sortBy || prev.sortOrder !== filters.sortOrder; @@ -67,15 +70,17 @@ export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) { search: filters.searchTerm || undefined, status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined, priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined, + templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, sortBy: filters.sortBy, sortOrder: filters.sortOrder, - }); + }); // Update previous values prevFiltersRef.current = { searchTerm: filters.searchTerm, statusFilter: filters.statusFilter, priorityFilter: filters.priorityFilter, + templateTypeFilter: filters.templateTypeFilter, sortBy: filters.sortBy, sortOrder: filters.sortOrder, }; @@ -83,7 +88,7 @@ export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) { return () => clearTimeout(timeoutId); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [filters.searchTerm, filters.statusFilter, filters.priorityFilter, filters.sortBy, filters.sortOrder]); + }, [filters.searchTerm, filters.statusFilter, filters.priorityFilter, filters.templateTypeFilter, filters.sortBy, filters.sortOrder]); // Page change handler const handlePageChange = useCallback( @@ -94,6 +99,7 @@ export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) { search: filters.searchTerm || undefined, status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined, priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined, + templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, sortBy: filters.sortBy, sortOrder: filters.sortOrder, }); @@ -108,6 +114,7 @@ export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) { search: filters.searchTerm || undefined, status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined, priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined, + templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, sortBy: filters.sortBy, sortOrder: filters.sortOrder, }); @@ -128,12 +135,14 @@ export function ClosedRequests({ onViewRequest }: ClosedRequestsProps) { searchTerm={filters.searchTerm} priorityFilter={filters.priorityFilter} statusFilter={filters.statusFilter} + templateTypeFilter={filters.templateTypeFilter} sortBy={filters.sortBy} sortOrder={filters.sortOrder} activeFiltersCount={filters.activeFiltersCount} onSearchChange={filters.setSearchTerm} onPriorityChange={filters.setPriorityFilter} onStatusChange={filters.setStatusFilter} + onTemplateTypeChange={filters.setTemplateTypeFilter} onSortByChange={filters.setSortBy} onSortOrderChange={() => filters.setSortOrder(filters.sortOrder === 'asc' ? 'desc' : 'asc')} onClearFilters={filters.clearFilters} diff --git a/src/pages/ClosedRequests/components/ClosedRequestCard.tsx b/src/pages/ClosedRequests/components/ClosedRequestCard.tsx index 5043391..6d271e3 100644 --- a/src/pages/ClosedRequests/components/ClosedRequestCard.tsx +++ b/src/pages/ClosedRequests/components/ClosedRequestCard.tsx @@ -71,7 +71,7 @@ export function ClosedRequestCard({ request, onViewRequest }: ClosedRequestCardP let templateColor = 'bg-purple-100 !text-purple-600 border-purple-200'; if (templateTypeUpper === 'DEALER CLAIM') { - templateLabel = 'Claim Management'; + templateLabel = 'Dealer Claim'; templateColor = 'bg-blue-100 !text-blue-700 border-blue-200'; } else if (templateTypeUpper === 'TEMPLATE') { templateLabel = 'Template'; diff --git a/src/pages/ClosedRequests/components/ClosedRequestsFilters.tsx b/src/pages/ClosedRequests/components/ClosedRequestsFilters.tsx index 9fe3198..f6ae88a 100644 --- a/src/pages/ClosedRequests/components/ClosedRequestsFilters.tsx +++ b/src/pages/ClosedRequests/components/ClosedRequestsFilters.tsx @@ -12,12 +12,14 @@ interface ClosedRequestsFiltersProps { searchTerm: string; priorityFilter: string; statusFilter: string; + templateTypeFilter: string; sortBy: 'created' | 'due' | 'priority'; sortOrder: 'asc' | 'desc'; activeFiltersCount: number; onSearchChange: (value: string) => void; onPriorityChange: (value: string) => void; onStatusChange: (value: string) => void; + onTemplateTypeChange: (value: string) => void; onSortByChange: (value: 'created' | 'due' | 'priority') => void; onSortOrderChange: () => void; onClearFilters: () => void; @@ -27,12 +29,14 @@ export function ClosedRequestsFilters({ searchTerm, priorityFilter, statusFilter, + templateTypeFilter, sortBy, sortOrder, activeFiltersCount, onSearchChange, onPriorityChange, onStatusChange, + onTemplateTypeChange, onSortByChange, onSortOrderChange, onClearFilters, @@ -71,7 +75,7 @@ export function ClosedRequestsFilters({ -
+
+ +
+ +
diff --git a/src/pages/MyRequests/components/RequestCard.tsx b/src/pages/MyRequests/components/RequestCard.tsx index 03757be..d880ad1 100644 --- a/src/pages/MyRequests/components/RequestCard.tsx +++ b/src/pages/MyRequests/components/RequestCard.tsx @@ -107,7 +107,7 @@ export function RequestCard({ request, index, onViewRequest }: RequestCardProps) let templateColor = 'bg-purple-100 !text-purple-600 border-purple-200'; if (templateTypeUpper === 'DEALER CLAIM') { - templateLabel = 'Claim Management'; + templateLabel = 'Dealer Claim'; templateColor = 'bg-blue-100 !text-blue-700 border-blue-200'; } else if (templateTypeUpper === 'TEMPLATE') { templateLabel = 'Template'; diff --git a/src/pages/MyRequests/hooks/useMyRequests.ts b/src/pages/MyRequests/hooks/useMyRequests.ts index 0ab2ad9..98c6106 100644 --- a/src/pages/MyRequests/hooks/useMyRequests.ts +++ b/src/pages/MyRequests/hooks/useMyRequests.ts @@ -13,6 +13,7 @@ interface UseMyRequestsOptions { search?: string; status?: string; priority?: string; + templateType?: string; }; } @@ -28,7 +29,7 @@ export function useMyRequests({ itemsPerPage = 10 }: UseMyRequestsOptions = {}) }); const fetchMyRequests = useCallback( - async (page: number = 1, filters?: { search?: string; status?: string; priority?: string }) => { + async (page: number = 1, filters?: { search?: string; status?: string; priority?: string; templateType?: string }) => { try { if (page === 1) { setLoading(true); @@ -41,6 +42,7 @@ export function useMyRequests({ itemsPerPage = 10 }: UseMyRequestsOptions = {}) search: filters?.search, status: filters?.status, priority: filters?.priority, + templateType: filters?.templateType, }); // Extract data - workflowApi now returns { data: [], pagination: {} } diff --git a/src/pages/MyRequests/hooks/useMyRequestsFilters.ts b/src/pages/MyRequests/hooks/useMyRequestsFilters.ts index e66d09b..bc99254 100644 --- a/src/pages/MyRequests/hooks/useMyRequestsFilters.ts +++ b/src/pages/MyRequests/hooks/useMyRequestsFilters.ts @@ -9,6 +9,7 @@ import { setSearchTerm as setSearchTermAction, setStatusFilter as setStatusFilterAction, setPriorityFilter as setPriorityFilterAction, + setTemplateTypeFilter as setTemplateTypeFilterAction, setCurrentPage as setCurrentPageAction, clearFilters as clearFiltersAction, } from '../redux/myRequestsSlice'; @@ -24,12 +25,13 @@ export function useMyRequestsFilters({ onFiltersChange, debounceMs = 500 }: UseM const isInitialMount = useRef(true); // Get filters from Redux - const { searchTerm, statusFilter, priorityFilter, currentPage } = useAppSelector((state) => state.myRequests); + const { searchTerm, statusFilter, priorityFilter, templateTypeFilter, currentPage } = useAppSelector((state) => state.myRequests); // Create setters that dispatch Redux actions const setSearchTerm = useCallback((value: string) => dispatch(setSearchTermAction(value)), [dispatch]); const setStatusFilter = useCallback((value: string) => dispatch(setStatusFilterAction(value)), [dispatch]); const setPriorityFilter = useCallback((value: string) => dispatch(setPriorityFilterAction(value)), [dispatch]); + const setTemplateTypeFilter = useCallback((value: string) => dispatch(setTemplateTypeFilterAction(value)), [dispatch]); const setCurrentPage = useCallback((value: number) => dispatch(setCurrentPageAction(value)), [dispatch]); const getFilters = useCallback((): MyRequestsFilters => { @@ -37,8 +39,9 @@ export function useMyRequestsFilters({ onFiltersChange, debounceMs = 500 }: UseM search: searchTerm, status: statusFilter, priority: priorityFilter, + templateType: templateTypeFilter, }; - }, [searchTerm, statusFilter, priorityFilter]); + }, [searchTerm, statusFilter, priorityFilter, templateTypeFilter]); // Debounced filter change handler useEffect(() => { @@ -65,7 +68,7 @@ export function useMyRequestsFilters({ onFiltersChange, debounceMs = 500 }: UseM clearTimeout(debounceTimeoutRef.current); } }; - }, [searchTerm, statusFilter, priorityFilter, onFiltersChange, getFilters, debounceMs]); + }, [searchTerm, statusFilter, priorityFilter, templateTypeFilter, onFiltersChange, getFilters, debounceMs]); const resetFilters = useCallback(() => { dispatch(clearFiltersAction()); @@ -75,10 +78,12 @@ export function useMyRequestsFilters({ onFiltersChange, debounceMs = 500 }: UseM searchTerm, statusFilter, priorityFilter, + templateTypeFilter, currentPage, setSearchTerm, setStatusFilter, setPriorityFilter, + setTemplateTypeFilter, setCurrentPage, getFilters, resetFilters, diff --git a/src/pages/MyRequests/redux/myRequestsSlice.ts b/src/pages/MyRequests/redux/myRequestsSlice.ts index a88dffe..54b4385 100644 --- a/src/pages/MyRequests/redux/myRequestsSlice.ts +++ b/src/pages/MyRequests/redux/myRequestsSlice.ts @@ -4,6 +4,7 @@ export interface MyRequestsFiltersState { searchTerm: string; statusFilter: string; priorityFilter: string; + templateTypeFilter: string; currentPage: number; } @@ -11,6 +12,7 @@ const initialState: MyRequestsFiltersState = { searchTerm: '', statusFilter: 'all', priorityFilter: 'all', + templateTypeFilter: 'all', currentPage: 1, }; @@ -28,6 +30,10 @@ const myRequestsSlice = createSlice({ state.priorityFilter = action.payload; state.currentPage = 1; // Reset to page 1 when filter changes }, + setTemplateTypeFilter: (state, action: PayloadAction) => { + state.templateTypeFilter = action.payload; + state.currentPage = 1; // Reset to page 1 when filter changes + }, setCurrentPage: (state, action: PayloadAction) => { state.currentPage = action.payload; }, @@ -35,6 +41,7 @@ const myRequestsSlice = createSlice({ state.searchTerm = ''; state.statusFilter = 'all'; state.priorityFilter = 'all'; + state.templateTypeFilter = 'all'; state.currentPage = 1; }, }, @@ -44,6 +51,7 @@ export const { setSearchTerm, setStatusFilter, setPriorityFilter, + setTemplateTypeFilter, setCurrentPage, clearFilters, } = myRequestsSlice.actions; diff --git a/src/pages/MyRequests/types/myRequests.types.ts b/src/pages/MyRequests/types/myRequests.types.ts index 9e9f06a..8dc2397 100644 --- a/src/pages/MyRequests/types/myRequests.types.ts +++ b/src/pages/MyRequests/types/myRequests.types.ts @@ -40,6 +40,7 @@ export interface MyRequestsFilters { search: string; status: string; priority: string; + templateType?: string; } export interface PaginationState { diff --git a/src/pages/OpenRequests/OpenRequests.tsx b/src/pages/OpenRequests/OpenRequests.tsx index 043aca7..430bc81 100644 --- a/src/pages/OpenRequests/OpenRequests.tsx +++ b/src/pages/OpenRequests/OpenRequests.tsx @@ -122,7 +122,7 @@ export function OpenRequests({ onViewRequest }: OpenRequestsProps) { // - An initiator (for approved requests awaiting closure) // This applies to ALL users including regular users, MANAGEMENT, and ADMIN roles // For organization-wide view, users should use the "All Requests" screen (/requests) - const fetchRequests = useCallback(async (page: number = 1, filterParams?: { search?: string; status?: string; priority?: string; sortBy?: string; sortOrder?: string }) => { + const fetchRequests = useCallback(async (page: number = 1, filterParams?: { search?: string; status?: string; priority?: string; templateType?: string; sortBy?: string; sortOrder?: string }) => { try { if (page === 1) { setLoading(true); @@ -138,6 +138,7 @@ export function OpenRequests({ onViewRequest }: OpenRequestsProps) { search: filterParams?.search, status: filterParams?.status, priority: filterParams?.priority, + templateType: filterParams?.templateType, sortBy: filterParams?.sortBy, sortOrder: filterParams?.sortOrder }); @@ -197,6 +198,7 @@ export function OpenRequests({ onViewRequest }: OpenRequestsProps) { search: filters.searchTerm || undefined, status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined, priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined, + templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, sortBy: filters.sortBy, sortOrder: filters.sortOrder }); @@ -209,6 +211,7 @@ export function OpenRequests({ onViewRequest }: OpenRequestsProps) { search: filters.searchTerm || undefined, status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined, priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined, + templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, sortBy: filters.sortBy, sortOrder: filters.sortOrder }); @@ -244,6 +247,7 @@ export function OpenRequests({ onViewRequest }: OpenRequestsProps) { search: filters.searchTerm || undefined, status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined, priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined, + templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, sortBy: filters.sortBy, sortOrder: filters.sortOrder, }); @@ -263,6 +267,7 @@ export function OpenRequests({ onViewRequest }: OpenRequestsProps) { search: filters.searchTerm || undefined, status: filters.statusFilter !== 'all' ? filters.statusFilter : undefined, priority: filters.priorityFilter !== 'all' ? filters.priorityFilter : undefined, + templateType: filters.templateTypeFilter !== 'all' ? filters.templateTypeFilter : undefined, sortBy: filters.sortBy, sortOrder: filters.sortOrder, }); @@ -270,7 +275,7 @@ export function OpenRequests({ onViewRequest }: OpenRequestsProps) { return () => clearTimeout(timeoutId); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [filters.searchTerm, filters.statusFilter, filters.priorityFilter, filters.sortBy, filters.sortOrder]); + }, [filters.searchTerm, filters.statusFilter, filters.priorityFilter, filters.templateTypeFilter, filters.sortBy, filters.sortOrder]); // Backend handles both filtering and sorting - use items directly // No client-side sorting needed anymore @@ -345,7 +350,7 @@ export function OpenRequests({ onViewRequest }: OpenRequestsProps) { {/* Primary filters */} -
+
+ +
+ + + +