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

161 lines
5.0 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;