Lin / frontend /src /store /reducers /linkedinAccountsSlice.js
Zelyanoth's picture
fff
25f22bf
raw
history blame
9.71 kB
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
import linkedinAuthService from '../../services/linkedinAuthService';
// Initial state
const initialState = {
linkedinAccounts: [],
loading: false,
error: null,
oauthLoading: false,
oauthError: null,
deletingAccount: null,
deletingError: null,
settingPrimary: null,
settingPrimaryError: null
};
// Async thunks
export const fetchLinkedInAccounts = createAsyncThunk(
'linkedinAccounts/fetchLinkedInAccounts',
async (_, { rejectWithValue }) => {
try {
const response = await linkedinAuthService.getLinkedInAccounts();
console.log('πŸ” [DEBUG] Async thunk - Service response:', response);
console.log('πŸ” [DEBUG] Async thunk - Service response type:', typeof response);
console.log('πŸ” [DEBUG] Async thunk - Service response is array:', Array.isArray(response));
// Return the response directly, not response.data
return response;
} catch (error) {
console.error('πŸ” [DEBUG] Async thunk - Error:', error);
return rejectWithValue(error.message);
}
}
);
export const initiateLinkedInAuth = createAsyncThunk(
'linkedinAccounts/initiateLinkedInAuth',
async (_, { rejectWithValue }) => {
try {
const response = await linkedinAuthService.initiateAuth();
console.log('πŸ” [DEBUG] Initiate auth - Service response:', response);
return response;
} catch (error) {
console.error('πŸ” [DEBUG] Initiate auth - Error:', error);
return rejectWithValue(error.message);
}
}
);
export const handleLinkedInCallback = createAsyncThunk(
'linkedinAccounts/handleLinkedInCallback',
async ({ code, state }, { rejectWithValue }) => {
try {
const response = await linkedinAuthService.handleCallback(code, state);
console.log('πŸ” [DEBUG] Handle callback - Service response:', response);
return response;
} catch (error) {
console.error('πŸ” [DEBUG] Handle callback - Error:', error);
return rejectWithValue(error.message);
}
}
);
export const deleteLinkedInAccount = createAsyncThunk(
'linkedinAccounts/deleteLinkedInAccount',
async (accountId, { rejectWithValue }) => {
try {
const response = await linkedinAuthService.deleteLinkedInAccount(accountId);
console.log('πŸ” [DEBUG] Delete account - Service response:', response);
return { accountId, ...response };
} catch (error) {
console.error('πŸ” [DEBUG] Delete account - Error:', error);
return rejectWithValue(error.message);
}
}
);
export const setPrimaryLinkedInAccount = createAsyncThunk(
'linkedinAccounts/setPrimaryLinkedInAccount',
async (accountId, { rejectWithValue }) => {
try {
const response = await linkedinAuthService.setPrimaryAccount(accountId);
console.log('πŸ” [DEBUG] Set primary - Service response:', response);
return { accountId, ...response };
} catch (error) {
console.error('πŸ” [DEBUG] Set primary - Error:', error);
return rejectWithValue(error.message);
}
}
);
// LinkedIn accounts slice
const linkedinAccountsSlice = createSlice({
name: 'linkedinAccounts',
initialState,
reducers: {
clearLinkedInError: (state) => {
state.error = null;
state.oauthError = null;
state.deletingError = null;
state.settingPrimaryError = null;
},
resetOAuthState: (state) => {
state.oauthLoading = false;
state.oauthError = null;
},
resetDeleteState: (state) => {
state.deletingAccount = null;
state.deletingError = null;
},
resetPrimaryState: (state) => {
state.settingPrimary = null;
state.settingPrimaryError = null;
}
},
extraReducers: (builder) => {
// Fetch LinkedIn accounts
builder
.addCase(fetchLinkedInAccounts.pending, (state) => {
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.pending - State:', state);
state.loading = true;
state.error = null;
})
.addCase(fetchLinkedInAccounts.fulfilled, (state, action) => {
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Action:', action);
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Action payload:', action.payload);
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Action payload type:', typeof action.payload);
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Action payload is array:', Array.isArray(action.payload));
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - State before update:', state);
state.loading = false;
// Handle different response formats robustly
if (!action.payload) {
console.warn('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Empty payload');
state.linkedinAccounts = [];
return;
}
// If service returns error object, handle it
if (action.payload.success === false) {
console.error('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Service error:', action.payload.message);
state.error = action.payload.message;
state.linkedinAccounts = [];
return;
}
// If service returns object with accounts property (expected format)
if (action.payload.accounts && Array.isArray(action.payload.accounts)) {
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Using accounts property format');
state.linkedinAccounts = action.payload.accounts;
return;
}
// If service returns array directly (fallback)
if (Array.isArray(action.payload)) {
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Using direct array format');
state.linkedinAccounts = action.payload;
return;
}
// Fallback to empty array
console.warn('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - Unexpected payload format, using empty array');
state.linkedinAccounts = [];
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.fulfilled - State after update:', state);
})
.addCase(fetchLinkedInAccounts.rejected, (state, action) => {
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.rejected - Action:', action);
console.log('πŸ” [DEBUG] fetchLinkedInAccounts.rejected - Error:', action.payload);
state.loading = false;
state.error = action.payload;
})
// Initiate LinkedIn auth
.addCase(initiateLinkedInAuth.pending, (state) => {
state.oauthLoading = true;
state.oauthError = null;
})
.addCase(initiateLinkedInAuth.fulfilled, (state, action) => {
state.oauthLoading = false;
if (action.payload.success) {
// Redirect to LinkedIn authorization URL
window.location.href = action.payload.authorization_url;
} else {
state.oauthError = action.payload.message;
}
})
.addCase(initiateLinkedInAuth.rejected, (state, action) => {
state.oauthLoading = false;
state.oauthError = action.payload;
})
// Handle LinkedIn callback
.addCase(handleLinkedInCallback.pending, (state) => {
state.oauthLoading = true;
state.oauthError = null;
})
.addCase(handleLinkedInCallback.fulfilled, (state, action) => {
state.oauthLoading = false;
if (action.payload.success) {
// Refresh accounts list
state.linkedinAccounts = [...state.linkedinAccounts];
state.oauthError = null;
} else {
state.oauthError = action.payload.message;
}
})
.addCase(handleLinkedInCallback.rejected, (state, action) => {
state.oauthLoading = false;
state.oauthError = action.payload;
})
// Delete LinkedIn account
.addCase(deleteLinkedInAccount.pending, (state, action) => {
state.deletingAccount = action.meta.arg;
state.deletingError = null;
})
.addCase(deleteLinkedInAccount.fulfilled, (state, action) => {
state.deletingAccount = null;
if (action.payload.success) {
// Remove account from list
state.linkedinAccounts = state.linkedinAccounts.filter(
account => account.id !== action.payload.accountId
);
} else {
state.deletingError = action.payload.message;
}
})
.addCase(deleteLinkedInAccount.rejected, (state, action) => {
state.deletingAccount = null;
state.deletingError = action.payload;
})
// Set primary LinkedIn account
.addCase(setPrimaryLinkedInAccount.pending, (state, action) => {
state.settingPrimary = action.meta.arg;
state.settingPrimaryError = null;
})
.addCase(setPrimaryLinkedInAccount.fulfilled, (state, action) => {
state.settingPrimary = null;
if (action.payload.success) {
// Update primary account in list
state.linkedinAccounts = state.linkedinAccounts.map(account => ({
...account,
is_primary: account.id === action.payload.accountId
}));
} else {
state.settingPrimaryError = action.payload.message;
}
})
.addCase(setPrimaryLinkedInAccount.rejected, (state, action) => {
state.settingPrimary = null;
state.settingPrimaryError = action.payload;
});
}
});
export const {
clearLinkedInError,
resetOAuthState,
resetDeleteState,
resetPrimaryState
} = linkedinAccountsSlice.actions;
export default linkedinAccountsSlice.reducer;