SME-Web/src/store/slices/documentSlice.ts

337 lines
10 KiB
TypeScript

// import { createSlice, createAsyncThunk, PayloadAction } from "@reduxjs/toolkit";
// // import { v4 as uuidv4 } from "uuid";
// import { hideLoader, showLoader } from "./loaderSlice";
// // import { showModal } from "./modalSlice";
// // import { updateSelectedDocuments } from "./selectedDocsSlice";
// import api from "../../config/api";
// import { Bounce, toast } from "react-toastify";
// // import { createAxiosInstance } from "../../config/axiosInstance";
// // const axiosInstance = createAxiosInstance();
// export interface Document {
// id: string;
// name: string;
// extension: string;
// original?: boolean;
// corrupted?: boolean;
// isCompleted: boolean;
// status: string;
// }
// export interface DocumentState {
// documents: Document[];
// loading: boolean;
// error: string | null;
// }
// const initialState: DocumentState = {
// documents: [],
// loading: false,
// error: null,
// };
// interface uploadArgs {
// formData: FormData;
// accountId: string;
// transactionId: string;
// }
// // Fetch documents from API
// export const fetchDocuments = createAsyncThunk<Document[], { accountId: string, transactionId: string }>(
// "documents/fetchDocuments",
// async ({ accountId, transactionId }, { rejectWithValue }) => {
// try {
// const response = await api.get(`/api/accounts/${accountId}/transactions/${transactionId}/documents?include_images=true`);
// return response.data as Document[];
// } catch (error: any) {
// // if(error.status === 401) {}
// return rejectWithValue(error.response?.data || "Failed to fetch documents");
// }
// }
// );
// // Upload multiple documents using FormData (Key: "document")
// export const uploadDocuments = createAsyncThunk<Document[], uploadArgs>(
// "documents/uploadDocuments",
// async ({ formData, accountId, transactionId }, { dispatch, rejectWithValue }) => {
// try {
// dispatch(showLoader("Uploading documents..."));
// console.log("Form Data", formData.getAll("document"))
// const response = await api.post(`/api/accounts/${accountId}/transactions/${transactionId}/documents`, formData, {
// headers: {
// "Content-Type": "multipart/form-data"
// },
// });
// console.log("Form Uploaded Response DocumentSlice Line 185", response.data)
// dispatch(hideLoader());
// return [response.data];
// } catch (error: any) {
// dispatch(hideLoader());
// toast.error("Error Uploading Document", {
// position: "bottom-right",
// autoClose: 3000,
// hideProgressBar: false,
// closeOnClick: false,
// pauseOnHover: false,
// draggable: false,
// progress: undefined,
// theme: "light",
// transition: Bounce,
// });
// console.log("Failed Uploading Documents")
// throw new Error("Failed Uploading Documents")
// // Mock data in case of failure
// // const failedDocuments = formData.getAll("document").map((file: any) => ({
// // id: uuidv4(),
// // name: file.name,
// // extension: file.name.split(".").pop() || "unknown",
// // original: Math.random() < 0.5,
// // corrupted: Math.random() < 0.5,
// // }));
// // dispatch(updateSelectedDocuments({ documents: failedDocuments }));
// // return failedDocuments; // Instead of rejecting, return mock data
// }
// }
// );
// const documentSlice = createSlice({
// name: "documents",
// initialState,
// reducers: {
// setDocuments: (state, action: PayloadAction<Document[]>) => {
// state.documents = action.payload;
// },
// setDocProgComplete: (state, action: PayloadAction<string>) => {
// const docIndex = state.documents.findIndex(doc => doc.id === action.payload);
// if (docIndex !== -1) {
// state.documents[docIndex].isCompleted = true;
// }
// },
// resetDocuments: (state) => {
// state.documents = [];
// },
// deleteDocument: (state, action: PayloadAction<string>) => {
// state.documents = state.documents.filter(doc => doc.id !== action.payload);
// },
// },
// extraReducers: (builder) => {
// builder
// // Fetch documents
// .addCase(fetchDocuments.pending, (state) => {
// state.loading = true;
// state.error = null;
// })
// .addCase(fetchDocuments.fulfilled, (state, action: PayloadAction<Document[]>) => {
// state.loading = false;
// state.documents = action.payload;
// })
// .addCase(fetchDocuments.rejected, (state, action) => {
// state.loading = false;
// state.error = action.payload as string;
// })
// // Upload multiple documents
// .addCase(uploadDocuments.pending, (state) => {
// state.loading = true;
// state.error = null;
// })
// .addCase(uploadDocuments.fulfilled, (state, action: PayloadAction<Document[]>) => {
// state.loading = false;
// state.documents = [...action.payload, ...state.documents];
// })
// .addCase(uploadDocuments.rejected, (state, action) => {
// state.loading = false;
// state.error = action.payload as string;
// });
// },
// });
// export const { resetDocuments, setDocuments, setDocProgComplete, deleteDocument } = documentSlice.actions;
// export default documentSlice.reducer;
import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import { toast, Bounce } from 'react-toastify';
import api from '../../config/api';
import { hideLoader, showLoader } from './loaderSlice';
// import { showLoader, hideLoader } from '../loader/loaderSlice';
// -----------------------
// Document Type
// -----------------------
export interface Document {
id?: string;
name: string;
url: string;
type: string;
pageCount?: number;
[key: string]: any;
}
// -----------------------
// Initial State
// -----------------------
interface DocumentState {
documents: Document[];
loading: boolean;
error: string | null;
}
const initialState: DocumentState = {
documents: [],
loading: false,
error: null,
};
// -----------------------
// Thunk: Fetch Documents
// -----------------------
export const fetchDocuments = createAsyncThunk<
Document[],
{ accountId: string; transactionId: string }
>(
'documents/fetchDocuments',
async ({ accountId, transactionId }, { rejectWithValue, getState }) => {
try {
const state = getState() as {
selectedRecipients: { transactionTemplateToggle: string };
};
const toggle = state.selectedRecipients.transactionTemplateToggle;
const response = await api.get(
`/api/accounts/${accountId}/${toggle}/${transactionId}/documents?include_images=true`
);
return response.data as Document[];
} catch (error: any) {
return rejectWithValue(error.response?.data || 'Failed to fetch documents');
}
}
);
// -----------------------
// Thunk: Upload Documents
// -----------------------
const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
export const uploadDocuments = createAsyncThunk<
Document[],
{ formData: FormData; accountId: string; transactionId: string }
>(
'documents/uploadDocuments',
async ({ formData, accountId, transactionId }, { dispatch, rejectWithValue, getState }) => {
try {
dispatch(showLoader('Uploading documents...'));
const state = getState() as {
selectedRecipients: { transactionTemplateToggle: string };
};
const toggle = state.selectedRecipients.transactionTemplateToggle;
console.log(`/api/accounts/${accountId}/${toggle}/${transactionId}/documents`)
const response = await api.post(
`/api/accounts/${accountId}/${toggle}/${transactionId}/documents`,
formData,
{
headers: {
'Content-Type': 'multipart/form-data',
},
}
);
console.log("// await sleep(5000);", response.data)
// await sleep(5000);
dispatch(hideLoader());
return [response.data];
} catch (error: any) {
dispatch(hideLoader());
toast.error('Error Uploading Document', {
position: 'bottom-right',
autoClose: 3000,
theme: 'light',
transition: Bounce,
});
return rejectWithValue('Failed Uploading Documents');
}
}
);
// -----------------------
// Slice
// -----------------------
const documentsSlice = createSlice({
name: 'documents',
initialState,
reducers: {
setDocuments: (state, action: PayloadAction<Document[]>) => {
state.documents = action.payload;
},
setDocProgComplete: (state, action: PayloadAction<string>) => {
const docIndex = state.documents.findIndex(doc => doc.id === action.payload);
if (docIndex !== -1) {
state.documents[docIndex].isCompleted = true;
}
},
resetDocuments: (state) => {
state.documents = [];
},
deleteDocument: (state, action: PayloadAction<string>) => {
state.documents = state.documents.filter(doc => doc.id !== action.payload);
},
},
extraReducers: (builder) => {
builder
// fetchDocuments
.addCase(fetchDocuments.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(fetchDocuments.fulfilled, (state, action: PayloadAction<Document[]>) => {
state.loading = false;
state.documents = action.payload;
})
.addCase(fetchDocuments.rejected, (state, action) => {
state.loading = false;
state.error = action.payload as string;
toast.error('Failed to fetch documents', {
position: 'bottom-right',
autoClose: 3000,
theme: 'light',
transition: Bounce,
});
})
// uploadDocuments
.addCase(uploadDocuments.pending, (state) => {
state.loading = true;
state.error = null;
})
.addCase(uploadDocuments.fulfilled, (state, action: PayloadAction<Document[]>) => {
state.loading = false;
state.documents.push(...action.payload);
})
.addCase(uploadDocuments.rejected, (state, action) => {
state.loading = false;
state.error = action.payload as string;
});
},
});
// -----------------------
// Exports
// -----------------------
export const { deleteDocument, resetDocuments, setDocuments, setDocProgComplete } = documentsSlice.actions;
export default documentsSlice.reducer;