NeoScan_Radiologist/app/modules/Dashboard/redux/aiDashboardSlice.ts

390 lines
11 KiB
TypeScript

/*
* File: aiDashboardSlice.ts
* Description: AI Analysis Dashboard state management slice
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import { dashboardAPI } from '../services/dashboardAPI';
import { logoutUser } from '../../Auth/redux/authActions';
// ============================================================================
// TYPES
// ============================================================================
/**
* AI Dashboard Statistics Interface
*
* Purpose: Defines the structure of AI dashboard statistics data
*/
export interface AIDashboardStats {
total_predictions: number;
total_patients: number;
total_feedbacks: number;
prediction_breakdown: Record<string, number>;
critical_findings: Record<string, number>;
midline_shift_stats: Record<string, number>;
hemorrhage_stats: Record<string, number>;
mass_lesion_stats: Record<string, number>;
edema_stats: Record<string, number>;
fracture_stats: Record<string, number>;
feedback_analysis: {
positive: number;
negative: number;
total: number;
};
hospital_distribution: Record<string, number>;
time_analysis: {
today: number;
this_week: number;
this_month: number;
this_year: number;
};
urgency_levels: {
critical: number;
urgent: number;
routine: number;
};
confidence_scores: {
high: number;
medium: number;
low: number;
};
feedback_rate_percentage: number;
predictions_with_feedback: number;
predictions_without_feedback: number;
average_feedback_per_prediction: string;
critical_case_percentage: number;
average_confidence_score: number;
}
/**
* AI Dashboard Summary Interface
*
* Purpose: Defines the structure of the AI dashboard summary data
*/
export interface AIDashboardSummary {
total_cases: number;
critical_cases: number;
routine_cases: number;
feedback_coverage: string;
critical_case_rate: string;
average_confidence: string;
}
/**
* Complete AI Dashboard Data Interface
*
* Purpose: Defines the complete structure of the AI dashboard API response
*/
export interface AIDashboardData {
success: boolean;
data: AIDashboardStats;
summary: AIDashboardSummary;
message: string;
}
/**
* AI Dashboard State Interface
*
* Purpose: Defines the state structure for AI dashboard
*/
export interface AIDashboardState {
// Dashboard data
dashboardData: AIDashboardData | null;
// Loading states
isLoading: boolean;
isRefreshing: boolean;
// Error handling
error: string | null;
// Filters and preferences
selectedTimeRange: 'today' | 'week' | 'month' | 'year';
selectedHospital: string | null;
selectedDepartment: string | null;
// Last updated timestamp
lastUpdated: string | null;
}
// ============================================================================
// ASYNC THUNKS
// ============================================================================
/**
* Fetch AI Dashboard Statistics Async Thunk
*
* Purpose: Fetch AI analysis dashboard statistics from API
*
* @param token - Authentication token
* @returns Promise with AI dashboard statistics data or error
*/
export const fetchAIDashboardStatistics = createAsyncThunk(
'aiDashboard/fetchStatistics',
async (token: string, { rejectWithValue, dispatch }) => {
try {
const response :any = await dashboardAPI.getDashboardStatistics(token);
// Check for 401 Unauthorized response
if (response.status === 401) {
// Dispatch logout action to clear authentication state
dispatch(logoutUser());
return rejectWithValue('Session expired. Please login again.');
}
if (response.ok && response.data ) {
return response.data as AIDashboardData;
} else {
return rejectWithValue(response.problem || 'Failed to fetch dashboard statistics');
}
} catch (error) {
return rejectWithValue('Network error occurred while fetching dashboard statistics');
}
}
);
/**
* Refresh AI Dashboard Statistics Async Thunk
*
* Purpose: Refresh AI dashboard statistics data
*
* @param token - Authentication token
* @returns Promise with refreshed AI dashboard statistics or error
*/
export const refreshAIDashboardStatistics = createAsyncThunk(
'aiDashboard/refreshStatistics',
async (token: string, { rejectWithValue, dispatch }) => {
try {
const response = await dashboardAPI.getDashboardStatistics(token);
// Check for 401 Unauthorized response
if (response.status === 401) {
// Dispatch logout action to clear authentication state
dispatch(logoutUser());
return rejectWithValue('Session expired. Please login again.');
}
if (response.ok && response.data) {
return response.data as AIDashboardData;
} else {
return rejectWithValue(response.problem || 'Failed to refresh dashboard statistics');
}
} catch (error) {
return rejectWithValue('Network error occurred while refreshing dashboard statistics');
}
}
);
/**
* Fetch Time-based Analysis Async Thunk
*
* Purpose: Fetch time-based analysis data for specific time range
*
* @param params - Parameters including token and time range
* @returns Promise with time-based analysis data or error
*/
export const fetchTimeBasedAnalysis = createAsyncThunk(
'aiDashboard/fetchTimeAnalysis',
async (params: { token: string; timeRange: 'today' | 'week' | 'month' | 'year' }, { rejectWithValue, dispatch }) => {
try {
const response = await dashboardAPI.getTimeBasedAnalysis(params.token, params.timeRange);
// Check for 401 Unauthorized response
if (response.status === 401) {
// Dispatch logout action to clear authentication state
dispatch(logoutUser());
return rejectWithValue('Session expired. Please login again.');
}
if (response.ok && response.data) {
return response.data as AIDashboardData;
} else {
return rejectWithValue(response.problem || 'Failed to fetch time-based analysis');
}
} catch (error) {
return rejectWithValue('Network error occurred while fetching time-based analysis');
}
}
);
// ============================================================================
// INITIAL STATE
// ============================================================================
/**
* Initial AI Dashboard State
*
* Purpose: Define the initial state for AI dashboard
*
* Features:
* - AI dashboard statistics data
* - Loading states for async operations
* - Error handling and messages
* - Filter preferences
* - Last updated tracking
*/
const initialState: AIDashboardState = {
// Dashboard data
dashboardData: null,
// Loading states
isLoading: false,
isRefreshing: false,
// Error handling
error: null,
// Filters and preferences
selectedTimeRange: 'today',
selectedHospital: null,
selectedDepartment: null,
// Last updated timestamp
lastUpdated: null,
};
// ============================================================================
// AI DASHBOARD SLICE
// ============================================================================
/**
* AI Dashboard Slice
*
* Purpose: Redux slice for AI dashboard state management
*
* Features:
* - AI dashboard statistics management
* - Time-based filtering
* - Hospital and department filtering
* - Error handling
* - Loading states
*/
const aiDashboardSlice = createSlice({
name: 'aiDashboard',
initialState,
reducers: {
/**
* Clear Error Action
*
* Purpose: Clear AI dashboard errors
*/
clearError: (state) => {
state.error = null;
},
/**
* Set Time Range Filter Action
*
* Purpose: Set time range filter for statistics
*/
setTimeRange: (state, action: PayloadAction<'today' | 'week' | 'month' | 'year'>) => {
state.selectedTimeRange = action.payload;
},
/**
* Set Hospital Filter Action
*
* Purpose: Set hospital filter for statistics
*/
setHospital: (state, action: PayloadAction<string | null>) => {
state.selectedHospital = action.payload;
},
/**
* Set Department Filter Action
*
* Purpose: Set department filter for statistics
*/
setDepartment: (state, action: PayloadAction<string | null>) => {
state.selectedDepartment = action.payload;
},
/**
* Update Dashboard Data Action
*
* Purpose: Update dashboard data manually
*/
updateDashboardData: (state, action: PayloadAction<Partial<AIDashboardData>>) => {
if (state.dashboardData) {
state.dashboardData = { ...state.dashboardData, ...action.payload };
state.lastUpdated = new Date().toLocaleDateString();
}
},
},
extraReducers: (builder) => {
// Fetch AI Dashboard Statistics
builder
.addCase(fetchAIDashboardStatistics.pending, (state) => {
state.isLoading = true;
state.error = null;
})
.addCase(fetchAIDashboardStatistics.fulfilled, (state, action) => {
state.isLoading = false;
state.dashboardData = action.payload;
state.lastUpdated = new Date().toLocaleDateString();
state.error = null;
})
.addCase(fetchAIDashboardStatistics.rejected, (state, action) => {
state.isLoading = false;
state.error = action.payload as string;
});
// Refresh AI Dashboard Statistics
builder
.addCase(refreshAIDashboardStatistics.pending, (state) => {
state.isRefreshing = true;
state.error = null;
})
.addCase(refreshAIDashboardStatistics.fulfilled, (state, action) => {
state.isRefreshing = false;
state.dashboardData = action.payload;
state.lastUpdated = new Date().toLocaleDateString();
state.error = null;
})
.addCase(refreshAIDashboardStatistics.rejected, (state, action) => {
state.isRefreshing = false;
state.error = action.payload as string;
});
// Fetch Time-based Analysis
builder
.addCase(fetchTimeBasedAnalysis.pending, (state) => {
state.isLoading = true;
state.error = null;
})
.addCase(fetchTimeBasedAnalysis.fulfilled, (state, action) => {
state.isLoading = false;
state.dashboardData = action.payload;
state.lastUpdated = new Date().toLocaleDateString();
state.error = null;
})
.addCase(fetchTimeBasedAnalysis.rejected, (state, action) => {
state.isLoading = false;
state.error = action.payload as string;
});
},
});
// ============================================================================
// EXPORTS
// ============================================================================
export const {
clearError,
setTimeRange,
setHospital,
setDepartment,
updateDashboardData,
} = aiDashboardSlice.actions;
export default aiDashboardSlice.reducer;
/*
* End of File: aiDashboardSlice.ts
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/