// import { createSlice, PayloadAction } from '@reduxjs/toolkit'; // import { createAsyncThunk } from '@reduxjs/toolkit'; // import { toast } from 'react-toastify'; // import colors from '../../utlity/colorsArr'; // import api from '../../config/api'; // export enum recipientType { // SIGNER = "Signer", // INPERSONSIGNER = "InPersonSigner", // CC = "CC" // } // export interface Recipient { // id?: string; // firstName: string; // lastName: string; // routingOrder: number; // email: string; // hostName: string; // hostEmail: string; // type: recipientType; // color?: string; // } // export interface SelectedRecipientInt { // recipients: Recipient[], // signingOrder: boolean, // transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE // } // interface AddRecipientArgs { // recipientsData: Recipient[]; // accountId: string; // transactionId: string; // } // export enum TRANSACTION_TEMPLATE_TOGGLE { // TRANSACTIONS = "transactions", // TEMPLATES = "templates" // } // const initialState: SelectedRecipientInt = { // recipients: [], // signingOrder: false, // transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS // }; // export const addRecipientAsync = createAsyncThunk( // 'selectedRecipients/addRecipientAsync', // async ({ recipientsData, accountId, transactionId }, { rejectWithValue }) => { // console.log(recipientsData, accountId, transactionId, "recipientsData Line 46"); // try { // console.log(recipientsData, "recipientsData --- Line 48"); // const updateRecipientsData = recipientsData.filter((recipient, idx) => recipient.id !== null); // const createRecipientsData = recipientsData.filter((recipient, idx) => recipient.id == null); // console.log(updateRecipientsData, "updateRecipientsData Line 52"); // console.log(createRecipientsData, "createRecipientsData Line 53"); // const resUpdate = await api.put( // `/api/accounts/${accountId}/transactions/${transactionId}/recipients`, // updateRecipientsData // ); // const resCreate = await api.post( // `/api/accounts/${accountId}/transactions/${transactionId}/recipients`, // createRecipientsData // ); // if (createRecipientsData.length === 0) resCreate.data = []; // if (updateRecipientsData.length === 0) resUpdate.data = []; // console.log(resCreate, "resCreate"); // console.log(resUpdate, "resUpdate"); // return [...resCreate.data, ...resUpdate.data] as Recipient[]; // } catch (err: any) { // return rejectWithValue(err.response?.data || "Failed to add recipient"); // } // } // ); // interface RemoveRecipientAsyncInterfaceObj { // id?: string; // email?: string; // } // interface RemoveRecipientAsyncInterface { // recipientId: number | null; // accountId: string; // transactionId: string; // email: string; // } // export const removeRecipientAsync = createAsyncThunk( // 'selectedRecipients/removeRecipientAsync', // async (obj, { rejectWithValue }) => { // try { // if (obj.recipientId) { // const res = await api.delete(`/api/accounts/${obj.accountId}/transactions/${obj.transactionId}/recipients/${obj.recipientId}`); // console.log(res, "Line 77") // return obj.recipientId; // } // return obj.email // } catch (err: any) { // return rejectWithValue("Failed to remove recipient"); // } // } // ); // export const fetchRecipients = createAsyncThunk( // 'selectedRecipients/fetchRecipients', // async ({ accountId, transactionId }, { rejectWithValue }) => { // try { // const response = await api.get(`/api/accounts/${accountId}/transactions/${transactionId}/recipients`); // return response.data as Recipient[]; // } catch (err: any) { // return rejectWithValue(err.response?.data || "Failed to fetch recipients"); // } // } // ); // const selectedRecipientsSlice = createSlice({ // name: 'selectedRecipients', // initialState, // reducers: { // // Add a single recipient // addRecipient: (state, action: PayloadAction) => { // for (const recipient of state.recipients) { // if (recipient.email === action.payload.email) { // toast.dismiss(); // toast.error("Email already exists !", { // position: "bottom-right", // autoClose: 5000, // hideProgressBar: false, // closeOnClick: false, // pauseOnHover: true, // draggable: true, // progress: undefined, // theme: "light", // }); // return state; // } // } // // Adding Recipient on top if type is inPersonSigner // console.log("Getting Type ", action.payload.type) // if (action.payload.type === recipientType.INPERSONSIGNER) { // state.signingOrder = true // state.recipients = [action.payload, ...state.recipients] // } else { // state.recipients.push(action.payload); // } // }, // resetRecipients: (state) => { // state.recipients = []; // }, // toggleToTemplates: (state) => { // state.transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES; // }, // // Replace the entire selectedRecipients array // setSelectedRecipients: (state, action: PayloadAction) => { // for (const [index, recipient] of action.payload.entries()) { // if ((recipient.type === recipientType.INPERSONSIGNER && index > 0) && action.payload[index - 1].type !== recipientType.INPERSONSIGNER) { // return state; // } // } // state.recipients = action.payload; // }, // setSigningOrder: (state, action: PayloadAction) => { // for (const recipient of state.recipients) { // if (recipient.type === recipientType.INPERSONSIGNER) { // if (state.signingOrder) return state; // state.signingOrder = true; // return state // } // } // state.signingOrder = action.payload; // }, // // Remove Recipients // removeSelectedRecipient: (state, action: PayloadAction) => { // console.log("removeSelectedRecipient Called") // state.recipients = state.recipients.filter((recipient) => recipient.email !== action.payload.email); // }, // // Add Color in Recipient // addColorsToRecipient: (state) => { // // const colors = generateUniqueColors(state.recipients.length); // for (const [index, recipient] of state.recipients.entries()) { // console.log(state) // recipient.color = colors[index] // } // return state; // }, // updateRecipientOrder: (state, action: PayloadAction<{ id: string; routingOrder: number }>) => { // console.log("recipient order called Line 159") // const { id, routingOrder } = action.payload; // const recipient = state.recipients.find((r) => r.id === id || r.email === id); // if (recipient) { // recipient.routingOrder = routingOrder; // } // }, // updateRecipientIds: (state, action: PayloadAction) => { // console.log("updateRecipientIds", console.table(action.payload)); // for (const recObj of state.recipients) { // const email = recObj.email // for (const recObj2 of action.payload) { // recObj.id = recObj2.id; // } // } // }, // resetSelRecipient: (state) => { // state = initialState; // return state; // } // }, // extraReducers: (builder) => { // builder // // Fetch Recipient - START // .addCase(fetchRecipients.pending, (state) => { // }) // .addCase(fetchRecipients.fulfilled, (state, action: PayloadAction) => { // // console.log("Fetched recipients successfully:", action.payload); // // Assign colors to recipients // const assignedRecipients = action.payload.map((recipient, index) => ({ // ...recipient, // color: colors[index], // Cycle if more recipients than colors // })); // state.recipients = assignedRecipients; // }) // .addCase(fetchRecipients.rejected, (state, action) => { // console.error("Failed to fetch recipients:", action.payload); // toast.error("Failed to fetch recipients", { // position: "bottom-right", // autoClose: 5000, // hideProgressBar: false, // closeOnClick: false, // pauseOnHover: true, // draggable: true, // progress: undefined, // theme: "light", // }); // }) // // Fetch Recipient - END // // Add Recipient - START // .addCase(addRecipientAsync.pending, (state) => { // }) // .addCase(addRecipientAsync.fulfilled, (state, action: PayloadAction) => { // // Optionally avoid duplicates if needed // console.log("addRecipientAsync Called Line 258", action.payload); // // const newRecipients = action.payload.filter(newRec => { // // return !state.recipients.some(existing => existing existing.id === newRec.id); // // }); // // const newRecipients = action.payload.filter(newRec => { // // return !state.recipients.some(existing => "id" in existing && existing.id === newRec.id); // // }); // // // Add new recipients and assign colors // // const startIndex = state.recipients.length; // // newRecipients.forEach((rec, index) => { // // rec.color = colors[startIndex + index]; // // state.recipients.push(rec); // // }); // state.recipients = action.payload.map((recipient, index) => ({ // ...recipient, // color: colors[index % colors.length], // Cycle through colors // })); // }) // .addCase(addRecipientAsync.rejected, (state, action) => { // console.error("Failed to fetch recipients:", action.payload); // toast.error("Failed to fetch recipients", { // position: "bottom-right", // autoClose: 5000, // hideProgressBar: false, // closeOnClick: false, // pauseOnHover: true, // draggable: true, // progress: undefined, // theme: "light", // }); // }) // // Add Recipient - END // // Fetch Recipient - START // .addCase(removeRecipientAsync.pending, (state) => { // }) // .addCase(removeRecipientAsync.fulfilled, (state, action: PayloadAction) => { // state.recipients = state.recipients.filter( // (recipient) => recipient.id !== action.payload && recipient.email !== action.payload // ); // }) // .addCase(removeRecipientAsync.rejected, (state, action) => { // console.error("Failed to Delete recipients:", action.payload); // toast.error("Failed to Delete recipients", { // position: "bottom-right", // autoClose: 5000, // hideProgressBar: false, // closeOnClick: false, // pauseOnHover: true, // draggable: true, // progress: undefined, // theme: "light", // }); // }) // // Fetch Recipient - END // } // }); // export const { addRecipient, setSelectedRecipients, toggleToTemplates, removeSelectedRecipient, setSigningOrder, addColorsToRecipient, updateRecipientIds, resetSelRecipient, updateRecipientOrder, resetRecipients } = selectedRecipientsSlice.actions; // export default selectedRecipientsSlice.reducer; import { createSlice, PayloadAction, createAsyncThunk } from '@reduxjs/toolkit'; import { toast } from 'react-toastify'; import colors from '../../utlity/colorsArr'; import api from '../../config/api'; export enum recipientType { SIGNER = "Signer", INPERSONSIGNER = "InPersonSigner", CC = "CC" } export interface Recipient { id?: string; firstName: string; lastName: string; routingOrder: number; email: string; hostName: string; hostEmail: string; type: recipientType; color?: string; roleName:string } export interface SelectedRecipientInt { recipients: Recipient[], signingOrder: boolean, transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE } interface AddRecipientArgs { recipientsData: Recipient[]; accountId: string; transactionId: string; transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE; } interface RemoveRecipientAsyncInterface { recipientId: number | null; accountId: string; transactionId: string; email: string; transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE; } export enum TRANSACTION_TEMPLATE_TOGGLE { TRANSACTIONS = "transactions", TEMPLATES = "templates" } const initialState: SelectedRecipientInt = { recipients: [], signingOrder: false, transactionTemplateToggle: TRANSACTION_TEMPLATE_TOGGLE.TRANSACTIONS }; // 1. Add Recipient Async export const addRecipientAsync = createAsyncThunk< Recipient[], { recipientsData: Recipient[]; accountId: string; transactionId: string } >( 'selectedRecipients/addRecipientAsync', async ({ recipientsData, accountId, transactionId }, { rejectWithValue, getState }) => { try { const state = getState() as { selectedRecipients: SelectedRecipientInt }; const toggle = state.selectedRecipients.transactionTemplateToggle; const updateRecipientsData = recipientsData.filter(recipient => recipient.id !== null); const createRecipientsData = recipientsData.filter(recipient => recipient.id == null); const basePath = `/api/accounts/${accountId}/${toggle}/${transactionId}/recipients`; const resUpdate = updateRecipientsData.length ? await api.put(basePath, updateRecipientsData) : { data: [] }; const resCreate = createRecipientsData.length ? await api.post(basePath, createRecipientsData) : { data: [] }; return [...resCreate.data, ...resUpdate.data] as Recipient[]; } catch (err: any) { return rejectWithValue(err.response?.data || "Failed to add recipient"); } } ); // 2. Remove Recipient Async export const removeRecipientAsync = createAsyncThunk< string | number, { recipientId: number | null; accountId: string; transactionId: string; email: string } >( 'selectedRecipients/removeRecipientAsync', async ({ recipientId, accountId, transactionId, email }, { rejectWithValue, getState }) => { try { const state = getState() as { selectedRecipients: SelectedRecipientInt }; const toggle = state.selectedRecipients.transactionTemplateToggle; const basePath = `/api/accounts/${accountId}/${toggle}/${transactionId}/recipients`; if (recipientId) { await api.delete(`${basePath}/${recipientId}`); return recipientId; } return email; } catch (err: any) { return rejectWithValue("Failed to remove recipient"); } } ); // 3. Fetch Recipients Async export const fetchRecipients = createAsyncThunk< Recipient[], { accountId: string; transactionId: string } >( 'selectedRecipients/fetchRecipients', async ({ accountId, transactionId }, { rejectWithValue, getState }) => { try { const state = getState() as { selectedRecipients: SelectedRecipientInt }; const toggle = state.selectedRecipients.transactionTemplateToggle; const basePath = `/api/accounts/${accountId}/${toggle}/${transactionId}/recipients`; const response = await api.get(basePath); return response.data as Recipient[]; } catch (err: any) { return rejectWithValue(err.response?.data || "Failed to fetch recipients"); } } ); const selectedRecipientsSlice = createSlice({ name: 'selectedRecipients', initialState, reducers: { addRecipient: (state, action: PayloadAction) => { for (const recipient of state.recipients) { if (recipient.email === action.payload.email) { toast.dismiss(); toast.error("Email already exists !", { position: "bottom-right", autoClose: 5000, theme: "light", }); return state; } } if (action.payload.type === recipientType.INPERSONSIGNER) { state.signingOrder = true; state.recipients = [action.payload, ...state.recipients]; } else { state.recipients.push(action.payload); } }, resetRecipients: (state) => { state.recipients = []; }, toggleToTemplates: (state) => { state.transactionTemplateToggle = TRANSACTION_TEMPLATE_TOGGLE.TEMPLATES; }, setSelectedRecipients: (state, action: PayloadAction) => { for (const [index, recipient] of action.payload.entries()) { if ((recipient.type === recipientType.INPERSONSIGNER && index > 0) && action.payload[index - 1].type !== recipientType.INPERSONSIGNER) { return state; } } state.recipients = action.payload; }, setSigningOrder: (state, action: PayloadAction) => { for (const recipient of state.recipients) { if (recipient.type === recipientType.INPERSONSIGNER) { if (state.signingOrder) return state; state.signingOrder = true; return state; } } state.signingOrder = action.payload; }, removeSelectedRecipient: (state, action: PayloadAction) => { state.recipients = state.recipients.filter((recipient) => recipient.email !== action.payload.email); }, addColorsToRecipient: (state) => { for (const [index, recipient] of state.recipients.entries()) { recipient.color = colors[index]; } return state; }, updateRecipientOrder: (state, action: PayloadAction<{ id: string; routingOrder: number }>) => { const { id, routingOrder } = action.payload; const recipient = state.recipients.find((r) => r.id === id || r.email === id); if (recipient) { recipient.routingOrder = routingOrder; } }, updateRecipientIds: (state, action: PayloadAction) => { for (const recObj of state.recipients) { for (const recObj2 of action.payload) { recObj.id = recObj2.id; } } }, resetSelRecipient: () => initialState }, extraReducers: (builder) => { builder .addCase(fetchRecipients.pending, () => { }) .addCase(fetchRecipients.fulfilled, (state, action: PayloadAction) => { const assignedRecipients = action.payload.map((recipient, index) => ({ ...recipient, color: colors[index], })); state.recipients = assignedRecipients; }) .addCase(fetchRecipients.rejected, (state, action) => { console.error("Failed to fetch recipients:", action.payload); toast.error("Failed to fetch recipients", { position: "bottom-right", autoClose: 5000, theme: "light", }); }) .addCase(addRecipientAsync.pending, () => { }) .addCase(addRecipientAsync.fulfilled, (state, action: PayloadAction) => { state.recipients = action.payload.map((recipient, index) => ({ ...recipient, color: colors[index % colors.length], })); }) .addCase(addRecipientAsync.rejected, (state, action) => { console.error("Failed to add recipients:", action.payload); toast.error("Failed to add recipients", { position: "bottom-right", autoClose: 5000, theme: "light", }); }) .addCase(removeRecipientAsync.pending, () => { }) .addCase(removeRecipientAsync.fulfilled, (state, action: PayloadAction) => { state.recipients = state.recipients.filter( (recipient) => recipient.id !== action.payload && recipient.email !== action.payload ); }) .addCase(removeRecipientAsync.rejected, (state, action) => { console.error("Failed to delete recipient:", action.payload); toast.error("Failed to delete recipient", { position: "bottom-right", autoClose: 5000, theme: "light", }); }); } }); export const { addRecipient, setSelectedRecipients, toggleToTemplates, removeSelectedRecipient, setSigningOrder, addColorsToRecipient, updateRecipientIds, resetSelRecipient, updateRecipientOrder, resetRecipients } = selectedRecipientsSlice.actions; export default selectedRecipientsSlice.reducer;