/** * * @description Settings system state handler * * source : https://redux-toolkit.js.org/api/createslice */ import { createSlice , PayloadAction , createAsyncThunk } from '@reduxjs/toolkit' import axios from 'axios' import { fireAlert } from "./alert-slice"; const ACTION_NAME = "settings" type IinitialState = { value: SettingsState; } type SettingsState = { authRedirectPage: string; notAuthRedirectPage: string, appGeneralSettings: { appName : string | null, appNameEN : string | null, gymName : string | null, email : string | null, phone : string | null, address : string | null, showLogo : boolean | null, logo : string | null, currencySymbol : string | null }, isUpdatingGeneralSettings: boolean, isLoadingSettings: boolean, loadedFirstTime: boolean, } const initialState = { value: { authRedirectPage: '/dashboard', notAuthRedirectPage: '/login', appGeneralSettings: { appName : "انفنتي", appNameEN : "Infinity", gymName : null, email : null, phone : null, address : null, showLogo : true, logo : ` `, currencySymbol : null }, isUpdatingGeneralSettings: false, isLoadingSettings: false, loadedFirstTime: false, } } as IinitialState // thunks // load data ability const load = createAsyncThunk( 'settings/load', async (actionPayload : { page : number }, thunkAPI) => { try { let { data } = await axios.get(`/api/user/actions/${ACTION_NAME}?type=page&page=`+actionPayload.page) if(data.success) { return data } else { return { success : false } } }catch(err) { return { success : false } } } ) // update ability const update = createAsyncThunk( 'settings/update', async (actionPayload : { appName : string | null | undefined, appNameEN : string | null | undefined, gymName : string | null | undefined, email : string | null | undefined, phone : string | null | undefined, address : string | null | undefined, showLogo : boolean | null | undefined, logo : string | null | undefined, currencySymbol : string | null | undefined }, thunkAPI) => { try { let { data } = await axios.put(`/api/user/actions/${ACTION_NAME}`, { payload: actionPayload }) if(data.success) { thunkAPI.dispatch(fireAlert({ success: true, message: "actionDoneWithSuccess", })) return actionPayload } else { return { success : false } } }catch(err) { return { success : false } } } ) export const settings = createSlice({ name: "settings", initialState, reducers: { // reset settings to there default status setDefaultSettings: () => { return initialState }, // change the authRedirectPage state setAuthRedirectPage: (state , action: PayloadAction) => { state.value.authRedirectPage = action.payload.authRedirectPage }, // change the notAuthRedirectPage state setNotAuthRedirectPage: (state , action: PayloadAction) => { state.value.notAuthRedirectPage = action.payload.notAuthRedirectPage } }, extraReducers: (builder) => { // load ability builder.addCase(load.pending, (state : IinitialState , action) => { state.value.isLoadingSettings = true; }) builder.addCase(load.fulfilled, (state : IinitialState , action) => { if(action.payload.success) { // Safely merge incoming settings with existing settings // This ensures that if action.payload.data.settings is undefined or null, // the existing appGeneralSettings (from initialState) is preserved. state.value.appGeneralSettings = { ...state.value.appGeneralSettings, // Keep existing properties ...(action.payload.data?.settings || {}) // Merge incoming data, default to empty object if undefined }; state.value.isLoadingSettings = false; state.value.loadedFirstTime = true; } else { // If loading failed, ensure loading state is false but keep existing data state.value.isLoadingSettings = false; // You might want to reset loadedFirstTime to false here if the load was truly unsuccessful // state.value.loadedFirstTime = false; } }) // update ability builder.addCase(update.pending, (state : IinitialState , action) => { state.value.isUpdatingGeneralSettings = true; }) builder.addCase(update.fulfilled, (state : IinitialState , action) => { state.value.isUpdatingGeneralSettings = false; state.value.appGeneralSettings = action.payload; }) } }) // export the functions export const { setDefaultSettings , setAuthRedirectPage , setNotAuthRedirectPage } = settings.actions;// export extra reducers export { load , update } export default settings.reducer;