394 lines
11 KiB
TypeScript
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.
|
|
*/
|