384 lines
9.8 KiB
TypeScript
384 lines
9.8 KiB
TypeScript
/*
|
|
* File: useAIPredictions.ts
|
|
* Description: Custom hook for AI Predictions functionality
|
|
* Design & Developed by Tech4Biz Solutions
|
|
* Copyright (c) Spurrin Innovations. All rights reserved.
|
|
*/
|
|
|
|
import { useCallback, useEffect, useMemo } from 'react';
|
|
import { useAppDispatch, useAppSelector } from '../../../store/hooks';
|
|
|
|
// Import Redux actions and selectors
|
|
import {
|
|
fetchAIPredictions,
|
|
setSearchQuery,
|
|
setUrgencyFilter,
|
|
setSeverityFilter,
|
|
setCategoryFilter,
|
|
clearAllFilters,
|
|
updateCaseReview,
|
|
} from '../redux';
|
|
|
|
import {
|
|
selectPaginatedCases,
|
|
selectIsLoading,
|
|
selectError,
|
|
selectSearchQuery,
|
|
selectUrgencyFilter,
|
|
selectSeverityFilter,
|
|
selectCategoryFilter,
|
|
selectCasesStatistics,
|
|
selectActiveFiltersCount,
|
|
selectCurrentPage,
|
|
selectTotalPages,
|
|
} from '../redux';
|
|
|
|
// Import auth selector
|
|
import { selectUser } from '../../Auth/redux/authSelectors';
|
|
|
|
// Import types
|
|
import type { AIPredictionState } from '../types';
|
|
|
|
// ============================================================================
|
|
// INTERFACES
|
|
// ============================================================================
|
|
|
|
interface UseAIPredictionsOptions {
|
|
autoLoad?: boolean;
|
|
refreshInterval?: number;
|
|
}
|
|
|
|
interface UseAIPredictionsReturn {
|
|
// Data
|
|
cases: ReturnType<typeof selectPaginatedCases>;
|
|
statistics: ReturnType<typeof selectCasesStatistics>;
|
|
|
|
// Loading states
|
|
isLoading: boolean;
|
|
error: string | null;
|
|
|
|
// Filters
|
|
searchQuery: string;
|
|
urgencyFilter: AIPredictionState['selectedUrgencyFilter'];
|
|
severityFilter: AIPredictionState['selectedSeverityFilter'];
|
|
categoryFilter: AIPredictionState['selectedCategoryFilter'];
|
|
activeFiltersCount: number;
|
|
|
|
// Pagination
|
|
currentPage: number;
|
|
totalPages: number;
|
|
|
|
// Actions
|
|
loadPredictions: () => Promise<void>;
|
|
refreshPredictions: () => Promise<void>;
|
|
setSearch: (query: string) => void;
|
|
setUrgency: (filter: AIPredictionState['selectedUrgencyFilter']) => void;
|
|
setSeverity: (filter: AIPredictionState['selectedSeverityFilter']) => void;
|
|
setCategory: (filter: AIPredictionState['selectedCategoryFilter']) => void;
|
|
clearFilters: () => void;
|
|
reviewCase: (caseId: string, reviewData?: Partial<{
|
|
review_status: 'pending' | 'reviewed' | 'confirmed' | 'disputed';
|
|
reviewed_by: string;
|
|
review_notes: string;
|
|
priority: 'critical' | 'high' | 'medium' | 'low';
|
|
}>) => Promise<void>;
|
|
|
|
// Computed properties
|
|
hasFilters: boolean;
|
|
isEmpty: boolean;
|
|
hasError: boolean;
|
|
}
|
|
|
|
// ============================================================================
|
|
// USE AI PREDICTIONS HOOK
|
|
// ============================================================================
|
|
|
|
/**
|
|
* useAIPredictions Hook
|
|
*
|
|
* Purpose: Custom hook for managing AI predictions state and actions
|
|
*
|
|
* Features:
|
|
* - Automatic data loading on mount
|
|
* - Search and filtering functionality
|
|
* - Case review management
|
|
* - Error handling
|
|
* - Loading states
|
|
* - Computed properties for UI state
|
|
* - Auto-refresh capability
|
|
* - Type-safe actions and selectors
|
|
*/
|
|
export const useAIPredictions = (options: UseAIPredictionsOptions = {}): UseAIPredictionsReturn => {
|
|
const {
|
|
autoLoad = true,
|
|
refreshInterval,
|
|
} = options;
|
|
|
|
// ============================================================================
|
|
// REDUX STATE
|
|
// ============================================================================
|
|
|
|
const dispatch = useAppDispatch();
|
|
|
|
// Auth state
|
|
const user = useAppSelector(selectUser);
|
|
|
|
// AI Predictions state
|
|
const cases = useAppSelector(selectPaginatedCases);
|
|
const statistics = useAppSelector(selectCasesStatistics);
|
|
const isLoading = useAppSelector(selectIsLoading);
|
|
const error = useAppSelector(selectError);
|
|
const searchQuery = useAppSelector(selectSearchQuery);
|
|
const urgencyFilter = useAppSelector(selectUrgencyFilter);
|
|
const severityFilter = useAppSelector(selectSeverityFilter);
|
|
const categoryFilter = useAppSelector(selectCategoryFilter);
|
|
const activeFiltersCount = useAppSelector(selectActiveFiltersCount);
|
|
const currentPage = useAppSelector(selectCurrentPage);
|
|
const totalPages = useAppSelector(selectTotalPages);
|
|
|
|
// ============================================================================
|
|
// MEMOIZED VALUES
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Has Filters
|
|
*
|
|
* Purpose: Check if any filters are active
|
|
*/
|
|
const hasFilters = useMemo(() => activeFiltersCount > 0, [activeFiltersCount]);
|
|
|
|
/**
|
|
* Is Empty
|
|
*
|
|
* Purpose: Check if the cases list is empty
|
|
*/
|
|
const isEmpty = useMemo(() => cases.length === 0, [cases.length]);
|
|
|
|
/**
|
|
* Has Error
|
|
*
|
|
* Purpose: Check if there's an error
|
|
*/
|
|
const hasError = useMemo(() => error !== null, [error]);
|
|
|
|
// ============================================================================
|
|
// ACTIONS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Load Predictions
|
|
*
|
|
* Purpose: Load AI predictions from API
|
|
*/
|
|
const loadPredictions = useCallback(async () => {
|
|
|
|
if (!user?.access_token) {
|
|
throw new Error('User not authenticated');
|
|
}
|
|
|
|
try {
|
|
const params = {
|
|
page: currentPage,
|
|
limit: 20,
|
|
...(urgencyFilter !== 'all' && { urgency: urgencyFilter }),
|
|
...(severityFilter !== 'all' && { severity: severityFilter }),
|
|
...(categoryFilter !== 'all' && { category: categoryFilter }),
|
|
...(searchQuery.trim() && { search: searchQuery.trim() }),
|
|
};
|
|
|
|
await dispatch(fetchAIPredictions({
|
|
token: user.access_token,
|
|
params,
|
|
})).unwrap();
|
|
} catch (error) {
|
|
console.error('Failed to load AI predictions:', error);
|
|
throw error;
|
|
}
|
|
}, [
|
|
dispatch,
|
|
user?.access_token,
|
|
currentPage,
|
|
urgencyFilter,
|
|
severityFilter,
|
|
categoryFilter,
|
|
searchQuery,
|
|
]);
|
|
|
|
/**
|
|
* Refresh Predictions
|
|
*
|
|
* Purpose: Refresh AI predictions data
|
|
*/
|
|
const refreshPredictions = useCallback(async () => {
|
|
await loadPredictions();
|
|
}, [loadPredictions]);
|
|
|
|
/**
|
|
* Set Search
|
|
*
|
|
* Purpose: Set search query
|
|
*/
|
|
const setSearch = useCallback((query: string) => {
|
|
dispatch(setSearchQuery(query));
|
|
}, [dispatch]);
|
|
|
|
/**
|
|
* Set Urgency Filter
|
|
*
|
|
* Purpose: Set urgency filter
|
|
*/
|
|
const setUrgency = useCallback((filter: AIPredictionState['selectedUrgencyFilter']) => {
|
|
dispatch(setUrgencyFilter(filter));
|
|
}, [dispatch]);
|
|
|
|
/**
|
|
* Set Severity Filter
|
|
*
|
|
* Purpose: Set severity filter
|
|
*/
|
|
const setSeverity = useCallback((filter: AIPredictionState['selectedSeverityFilter']) => {
|
|
dispatch(setSeverityFilter(filter));
|
|
}, [dispatch]);
|
|
|
|
/**
|
|
* Set Category Filter
|
|
*
|
|
* Purpose: Set category filter
|
|
*/
|
|
const setCategory = useCallback((filter: AIPredictionState['selectedCategoryFilter']) => {
|
|
dispatch(setCategoryFilter(filter));
|
|
}, [dispatch]);
|
|
|
|
/**
|
|
* Clear Filters
|
|
*
|
|
* Purpose: Clear all active filters
|
|
*/
|
|
const clearFilters = useCallback(() => {
|
|
dispatch(clearAllFilters());
|
|
}, [dispatch]);
|
|
|
|
/**
|
|
* Review Case
|
|
*
|
|
* Purpose: Update case review status
|
|
*/
|
|
const reviewCase = useCallback(async (
|
|
caseId: string,
|
|
reviewData: Partial<{
|
|
review_status: 'pending' | 'reviewed' | 'confirmed' | 'disputed';
|
|
reviewed_by: string;
|
|
review_notes: string;
|
|
priority: 'critical' | 'high' | 'medium' | 'low';
|
|
}> = {}
|
|
) => {
|
|
if (!user?.access_token) {
|
|
throw new Error('User not authenticated');
|
|
}
|
|
|
|
try {
|
|
const defaultReviewData = {
|
|
review_status: 'reviewed' as const,
|
|
reviewed_by: user.display_name || user.email || 'Current User',
|
|
...reviewData,
|
|
};
|
|
|
|
await dispatch(updateCaseReview({
|
|
caseId,
|
|
reviewData: defaultReviewData,
|
|
token: user.access_token,
|
|
})).unwrap();
|
|
} catch (error) {
|
|
console.error('Failed to review case:', error);
|
|
throw error;
|
|
}
|
|
}, [dispatch, user]);
|
|
|
|
// ============================================================================
|
|
// EFFECTS
|
|
// ============================================================================
|
|
|
|
/**
|
|
* Auto-load Effect
|
|
*
|
|
* Purpose: Automatically load predictions on mount if enabled
|
|
*/
|
|
useEffect(() => {
|
|
if (autoLoad && user?.access_token) {
|
|
loadPredictions().catch(console.error);
|
|
}
|
|
}, [autoLoad, user?.access_token, loadPredictions]);
|
|
|
|
/**
|
|
* Auto-refresh Effect
|
|
*
|
|
* Purpose: Set up auto-refresh interval if specified
|
|
*/
|
|
useEffect(() => {
|
|
if (!refreshInterval || !user?.access_token) return;
|
|
|
|
const interval = setInterval(() => {
|
|
loadPredictions().catch(console.error);
|
|
}, refreshInterval);
|
|
|
|
return () => clearInterval(interval);
|
|
}, [refreshInterval, user?.access_token, loadPredictions]);
|
|
|
|
/**
|
|
* Filter Change Effect
|
|
*
|
|
* Purpose: Reload data when filters change
|
|
*/
|
|
useEffect(() => {
|
|
if (user?.access_token) {
|
|
loadPredictions().catch(console.error);
|
|
}
|
|
}, [urgencyFilter, severityFilter, categoryFilter, searchQuery, currentPage]);
|
|
|
|
// ============================================================================
|
|
// RETURN
|
|
// ============================================================================
|
|
|
|
return {
|
|
// Data
|
|
cases,
|
|
statistics,
|
|
|
|
// Loading states
|
|
isLoading,
|
|
error,
|
|
|
|
// Filters
|
|
searchQuery,
|
|
urgencyFilter,
|
|
severityFilter,
|
|
categoryFilter,
|
|
activeFiltersCount,
|
|
|
|
// Pagination
|
|
currentPage,
|
|
totalPages,
|
|
|
|
// Actions
|
|
loadPredictions,
|
|
refreshPredictions,
|
|
setSearch,
|
|
setUrgency,
|
|
setSeverity,
|
|
setCategory,
|
|
clearFilters,
|
|
reviewCase,
|
|
|
|
// Computed properties
|
|
hasFilters,
|
|
isEmpty,
|
|
hasError,
|
|
};
|
|
};
|
|
|
|
/*
|
|
* End of File: useAIPredictions.ts
|
|
* Design & Developed by Tech4Biz Solutions
|
|
* Copyright (c) Spurrin Innovations. All rights reserved.
|
|
*/
|