import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit' import axios from 'axios' import {fulfilledNotify, rejectNotify, resetNotify} from "../../helpers/notifyStateHandler"; interface MainState { documents: any loading: boolean count: number refetch: boolean; rolesWidgets: any[]; notify: { showNotification: boolean textNotification: string typeNotification: string } } const initialState: MainState = { documents: [], loading: false, count: 0, refetch: false, rolesWidgets: [], notify: { showNotification: false, textNotification: '', typeNotification: 'warn', }, } export const fetch = createAsyncThunk('documents/fetch', async (data: any) => { const { id, query } = data const result = await axios.get( `documents${ query || (id ? `/${id}` : '') }` ) return id ? result.data : {rows: result.data.rows, count: result.data.count}; }) export const deleteItemsByIds = createAsyncThunk( 'documents/deleteByIds', async (data: any, { rejectWithValue }) => { try { await axios.post('documents/deleteByIds', { data }); } catch (error) { if (!error.response) { throw error; } return rejectWithValue(error.response.data); } }, ); export const deleteItem = createAsyncThunk('documents/deleteDocuments', async (id: string, { rejectWithValue }) => { try { await axios.delete(`documents/${id}`) } catch (error) { if (!error.response) { throw error; } return rejectWithValue(error.response.data); } }) export const create = createAsyncThunk('documents/createDocuments', async (payload: any, { rejectWithValue }) => { try { let result; if (payload instanceof FormData) { // FormData upload result = await axios.post('documents', payload); } else { // JSON fallback result = await axios.post('documents', { data: payload }); } return result.data; } catch (error) { if (!error.response) { throw error; } return rejectWithValue(error.response.data); } }); export const uploadCsv = createAsyncThunk( 'documents/uploadCsv', async (file: File, { rejectWithValue }) => { try { const data = new FormData(); data.append('file', file); data.append('filename', file.name); const result = await axios.post('documents/bulk-import', data, { headers: { 'Content-Type': 'multipart/form-data', }, }); return result.data; } catch (error) { if (!error.response) { throw error; } return rejectWithValue(error.response.data); } }, ); export const update = createAsyncThunk('documents/updateDocuments', async (payload: any, { rejectWithValue }) => { try { let result; const { id, data } = payload; if (data instanceof FormData) { // Multipart upload result = await axios.put(`documents/${id}`, data); } else { // JSON fallback result = await axios.put(`documents/${id}`, { id, data }); } return result.data; } catch (error) { if (!error.response) { throw error; } return rejectWithValue(error.response.data); } }); export const documentsSlice = createSlice({ name: 'documents', initialState, reducers: { setRefetch: (state, action: PayloadAction) => { state.refetch = action.payload; }, }, extraReducers: (builder) => { builder.addCase(fetch.pending, (state) => { state.loading = true resetNotify(state); }) builder.addCase(fetch.rejected, (state, action) => { state.loading = false rejectNotify(state, action); }) builder.addCase(fetch.fulfilled, (state, action) => { if (action.payload.rows && action.payload.count >= 0) { state.documents = action.payload.rows; state.count = action.payload.count; } else { state.documents = action.payload; } state.loading = false }) builder.addCase(deleteItemsByIds.pending, (state) => { state.loading = true; resetNotify(state); }); builder.addCase(deleteItemsByIds.fulfilled, (state) => { state.loading = false; fulfilledNotify(state, 'Documents has been deleted'); }); builder.addCase(deleteItemsByIds.rejected, (state, action) => { state.loading = false; rejectNotify(state, action); }); builder.addCase(deleteItem.pending, (state) => { state.loading = true resetNotify(state); }) builder.addCase(deleteItem.fulfilled, (state) => { state.loading = false fulfilledNotify(state, `${'Documents'.slice(0, -1)} has been deleted`); }) builder.addCase(deleteItem.rejected, (state, action) => { state.loading = false rejectNotify(state, action); }) builder.addCase(create.pending, (state) => { state.loading = true resetNotify(state); }) builder.addCase(create.rejected, (state, action) => { state.loading = false rejectNotify(state, action); }) builder.addCase(create.fulfilled, (state) => { state.loading = false fulfilledNotify(state, `${'Documents'.slice(0, -1)} has been created`); }) builder.addCase(update.pending, (state) => { state.loading = true resetNotify(state); }) builder.addCase(update.fulfilled, (state) => { state.loading = false fulfilledNotify(state, `${'Documents'.slice(0, -1)} has been updated`); }) builder.addCase(update.rejected, (state, action) => { state.loading = false rejectNotify(state, action); }) builder.addCase(uploadCsv.pending, (state) => { state.loading = true; resetNotify(state); }) builder.addCase(uploadCsv.fulfilled, (state) => { state.loading = false; fulfilledNotify(state, 'Documents has been uploaded'); }) builder.addCase(uploadCsv.rejected, (state, action) => { state.loading = false; rejectNotify(state, action); }) }, }) // Action creators are generated for each case reducer function export const { setRefetch } = documentsSlice.actions export default documentsSlice.reducer