NeoScan_Radiologist/app/modules/Settings/redux/settingsSlice.ts
2025-08-05 18:01:36 +05:30

394 lines
11 KiB
TypeScript

/*
* File: settingsSlice.ts
* Description: Settings state management slice
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import { UserProfile, UserPreferences, SettingsState } from '../../../shared/types';
// ============================================================================
// ASYNC THUNKS
// ============================================================================
/**
* Fetch User Profile Async Thunk
*
* Purpose: Fetch user profile from API
*
* @returns Promise with user profile data or error
*/
export const fetchUserProfile = createAsyncThunk(
'settings/fetchUserProfile',
async (_, { rejectWithValue }) => {
try {
// TODO: Replace with actual API call
await new Promise(resolve => setTimeout(resolve, 1000));
// Mock user profile data
const mockProfile: UserProfile = {
id: '1',
email: 'john.smith@hospital.com',
firstName: 'Dr. John',
lastName: 'Smith',
role: 'ATTENDING_PHYSICIAN',
department: 'Emergency Medicine',
credentials: ['MD', 'FACEP'],
specialties: ['Emergency Medicine', 'Trauma'],
profilePicture: null,
phoneNumber: '+1-555-0123',
yearsOfExperience: 15,
isActive: true,
lastLogin: new Date().toISOString(),
permissions: ['READ_PATIENTS', 'WRITE_PATIENTS', 'VIEW_ALERTS'],
};
return mockProfile;
} catch (error) {
return rejectWithValue('Failed to fetch user profile.');
}
}
);
/**
* Update User Profile Async Thunk
*
* Purpose: Update user profile information
*
* @param profileData - Updated profile data
* @returns Promise with updated profile or error
*/
export const updateUserProfile = createAsyncThunk(
'settings/updateUserProfile',
async (profileData: Partial<UserProfile> & { id: string }, { rejectWithValue }) => {
try {
// TODO: Replace with actual API call
await new Promise(resolve => setTimeout(resolve, 800));
return profileData;
} catch (error) {
return rejectWithValue('Failed to update user profile.');
}
}
);
/**
* Fetch User Preferences Async Thunk
*
* Purpose: Fetch user preferences from API
*
* @returns Promise with user preferences data or error
*/
export const fetchUserPreferences = createAsyncThunk(
'settings/fetchUserPreferences',
async (_, { rejectWithValue }) => {
try {
// TODO: Replace with actual API call
await new Promise(resolve => setTimeout(resolve, 500));
// Mock user preferences data
const mockPreferences: UserPreferences = {
notifications: {
criticalAlerts: true,
patientUpdates: true,
shiftChanges: false,
systemMaintenance: false,
soundEnabled: true,
vibrationEnabled: true,
},
clinical: {
autoRefreshInterval: 30,
showVitalSigns: true,
showAllergies: true,
showMedications: true,
defaultView: 'list',
},
privacy: {
biometricEnabled: true,
sessionTimeout: 30,
dataRetention: 90,
auditLogging: true,
},
accessibility: {
fontSize: 'medium',
highContrast: false,
screenReader: false,
reducedMotion: false,
},
};
return mockPreferences;
} catch (error) {
return rejectWithValue('Failed to fetch user preferences.');
}
}
);
/**
* Update User Preferences Async Thunk
*
* Purpose: Update user preferences
*
* @param preferences - Updated preferences data
* @returns Promise with updated preferences or error
*/
export const updateUserPreferences = createAsyncThunk(
'settings/updateUserPreferences',
async (preferences: Partial<UserPreferences>, { rejectWithValue }) => {
try {
// TODO: Replace with actual API call
await new Promise(resolve => setTimeout(resolve, 600));
return preferences;
} catch (error) {
return rejectWithValue('Failed to update user preferences.');
}
}
);
// ============================================================================
// INITIAL STATE
// ============================================================================
/**
* Initial Settings State
*
* Purpose: Define the initial state for settings
*
* Features:
* - User profile management
* - User preferences management
* - Loading states for async operations
* - Error handling and messages
* - Settings validation
*/
const initialState: SettingsState = {
// User profile
userProfile: null,
// User preferences
userPreferences: null,
// Loading states
isLoading: false,
isUpdatingProfile: false,
isUpdatingPreferences: false,
// Error handling
error: null,
// Settings validation
isProfileValid: true,
isPreferencesValid: true,
// Last updated timestamps
profileLastUpdated: null,
preferencesLastUpdated: null,
};
// ============================================================================
// SETTINGS SLICE
// ============================================================================
/**
* Settings Slice
*
* Purpose: Redux slice for settings state management
*
* Features:
* - User profile management
* - User preferences management
* - Settings validation
* - Error handling
* - Loading states
*/
const settingsSlice = createSlice({
name: 'settings',
initialState,
reducers: {
/**
* Clear Error Action
*
* Purpose: Clear settings errors
*/
clearError: (state) => {
state.error = null;
},
/**
* Set Profile Validation Action
*
* Purpose: Set profile validation status
*/
setProfileValidation: (state, action: PayloadAction<boolean>) => {
state.isProfileValid = action.payload;
},
/**
* Set Preferences Validation Action
*
* Purpose: Set preferences validation status
*/
setPreferencesValidation: (state, action: PayloadAction<boolean>) => {
state.isPreferencesValid = action.payload;
},
/**
* Update Profile Field Action
*
* Purpose: Update a specific profile field
*/
updateProfileField: (state, action: PayloadAction<{ field: keyof UserProfile; value: any }>) => {
if (state.userProfile) {
(state.userProfile as any)[action.payload.field] = action.payload.value;
state.profileLastUpdated = new Date();
}
},
/**
* Update Preference Field Action
*
* Purpose: Update a specific preference field
*/
updatePreferenceField: (state, action: PayloadAction<{ path: string; value: any }>) => {
if (state.userPreferences) {
const path = action.payload.path.split('.');
let current: any = state.userPreferences;
for (let i = 0; i < path.length - 1; i++) {
current = current[path[i]];
}
current[path[path.length - 1]] = action.payload.value;
state.preferencesLastUpdated = new Date();
}
},
/**
* Reset Profile Action
*
* Purpose: Reset profile to last saved state
*/
resetProfile: (state) => {
// TODO: Implement reset logic
state.isProfileValid = true;
},
/**
* Reset Preferences Action
*
* Purpose: Reset preferences to last saved state
*/
resetPreferences: (state) => {
// TODO: Implement reset logic
state.isPreferencesValid = true;
},
/**
* Clear Settings Cache Action
*
* Purpose: Clear settings data cache
*/
clearSettingsCache: (state) => {
state.userProfile = null;
state.userPreferences = null;
state.profileLastUpdated = null;
state.preferencesLastUpdated = null;
},
},
extraReducers: (builder) => {
// Fetch User Profile
builder
.addCase(fetchUserProfile.pending, (state) => {
state.isLoading = true;
state.error = null;
})
.addCase(fetchUserProfile.fulfilled, (state, action) => {
state.isLoading = false;
state.userProfile = action.payload;
state.profileLastUpdated = new Date();
state.error = null;
})
.addCase(fetchUserProfile.rejected, (state, action) => {
state.isLoading = false;
state.error = action.payload as string;
});
// Update User Profile
builder
.addCase(updateUserProfile.pending, (state) => {
state.isUpdatingProfile = true;
state.error = null;
})
.addCase(updateUserProfile.fulfilled, (state, action) => {
state.isUpdatingProfile = false;
if (state.userProfile) {
state.userProfile = { ...state.userProfile, ...action.payload };
state.profileLastUpdated = new Date();
}
state.error = null;
})
.addCase(updateUserProfile.rejected, (state, action) => {
state.isUpdatingProfile = false;
state.error = action.payload as string;
});
// Fetch User Preferences
builder
.addCase(fetchUserPreferences.pending, (state) => {
state.isLoading = true;
state.error = null;
})
.addCase(fetchUserPreferences.fulfilled, (state, action) => {
state.isLoading = false;
state.userPreferences = action.payload;
state.preferencesLastUpdated = new Date();
state.error = null;
})
.addCase(fetchUserPreferences.rejected, (state, action) => {
state.isLoading = false;
state.error = action.payload as string;
});
// Update User Preferences
builder
.addCase(updateUserPreferences.pending, (state) => {
state.isUpdatingPreferences = true;
state.error = null;
})
.addCase(updateUserPreferences.fulfilled, (state, action) => {
state.isUpdatingPreferences = false;
if (state.userPreferences) {
state.userPreferences = { ...state.userPreferences, ...action.payload };
state.preferencesLastUpdated = new Date();
}
state.error = null;
})
.addCase(updateUserPreferences.rejected, (state, action) => {
state.isUpdatingPreferences = false;
state.error = action.payload as string;
});
},
});
// ============================================================================
// EXPORTS
// ============================================================================
export const {
clearError,
setProfileValidation,
setPreferencesValidation,
updateProfileField,
updatePreferenceField,
resetProfile,
resetPreferences,
clearSettingsCache,
} = settingsSlice.actions;
export default settingsSlice.reducer;
/*
* End of File: settingsSlice.ts
* Design & Developed by Tech4Biz Solutions
* Copyright (c) Spurrin Innovations. All rights reserved.
*/