added pagination for the leads tasks and deals accounts
This commit is contained in:
parent
e91bbbbd1d
commit
e53b229c03
@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useMemo } from 'react';
|
import React, { useState, useEffect, useMemo, useCallback } from 'react';
|
||||||
import {
|
import {
|
||||||
View,
|
View,
|
||||||
Text,
|
Text,
|
||||||
@ -8,6 +8,7 @@ import {
|
|||||||
RefreshControl,
|
RefreshControl,
|
||||||
FlatList,
|
FlatList,
|
||||||
Alert,
|
Alert,
|
||||||
|
ActivityIndicator,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { useSelector, useDispatch } from 'react-redux';
|
import { useSelector, useDispatch } from 'react-redux';
|
||||||
import type { AppDispatch } from '@/store/store';
|
import type { AppDispatch } from '@/store/store';
|
||||||
@ -26,9 +27,26 @@ import {
|
|||||||
selectPurchaseOrders,
|
selectPurchaseOrders,
|
||||||
selectInvoices,
|
selectInvoices,
|
||||||
selectCrmLoading,
|
selectCrmLoading,
|
||||||
selectCrmErrors
|
selectCrmErrors,
|
||||||
|
selectLeadsPagination,
|
||||||
|
selectTasksPagination,
|
||||||
|
selectContactsPagination,
|
||||||
|
selectDealsPagination,
|
||||||
|
selectSalesOrdersPagination,
|
||||||
|
selectPurchaseOrdersPagination,
|
||||||
|
selectInvoicesPagination
|
||||||
} from '../store/selectors';
|
} from '../store/selectors';
|
||||||
import { fetchAllCrmData } from '../store/crmSlice';
|
import {
|
||||||
|
fetchAllCrmData,
|
||||||
|
fetchLeads,
|
||||||
|
fetchTasks,
|
||||||
|
fetchContacts,
|
||||||
|
fetchDeals,
|
||||||
|
resetLeadsPagination,
|
||||||
|
resetTasksPagination,
|
||||||
|
resetContactsPagination,
|
||||||
|
resetDealsPagination
|
||||||
|
} from '../store/crmSlice';
|
||||||
import type { RootState } from '@/store/store';
|
import type { RootState } from '@/store/store';
|
||||||
|
|
||||||
const ZohoCrmDataScreen: React.FC = () => {
|
const ZohoCrmDataScreen: React.FC = () => {
|
||||||
@ -48,6 +66,15 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
const loading = useSelector(selectCrmLoading);
|
const loading = useSelector(selectCrmLoading);
|
||||||
const errors = useSelector(selectCrmErrors);
|
const errors = useSelector(selectCrmErrors);
|
||||||
|
|
||||||
|
// Pagination selectors
|
||||||
|
const leadsPagination = useSelector(selectLeadsPagination);
|
||||||
|
const tasksPagination = useSelector(selectTasksPagination);
|
||||||
|
const contactsPagination = useSelector(selectContactsPagination);
|
||||||
|
const dealsPagination = useSelector(selectDealsPagination);
|
||||||
|
const salesOrdersPagination = useSelector(selectSalesOrdersPagination);
|
||||||
|
const purchaseOrdersPagination = useSelector(selectPurchaseOrdersPagination);
|
||||||
|
const invoicesPagination = useSelector(selectInvoicesPagination);
|
||||||
|
|
||||||
// Create CRM data object from Redux state
|
// Create CRM data object from Redux state
|
||||||
const crmData: CrmData = useMemo(() => ({
|
const crmData: CrmData = useMemo(() => ({
|
||||||
leads: leads || [],
|
leads: leads || [],
|
||||||
@ -60,7 +87,7 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
}), [leads, tasks, contacts, deals, salesOrders, purchaseOrders, invoices]);
|
}), [leads, tasks, contacts, deals, salesOrders, purchaseOrders, invoices]);
|
||||||
|
|
||||||
// Fetch CRM data using Redux
|
// Fetch CRM data using Redux
|
||||||
const fetchCrmData = async (showRefresh = false) => {
|
const fetchCrmData = useCallback(async (showRefresh = false) => {
|
||||||
try {
|
try {
|
||||||
if (showRefresh) {
|
if (showRefresh) {
|
||||||
setRefreshing(true);
|
setRefreshing(true);
|
||||||
@ -78,23 +105,87 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
} finally {
|
} finally {
|
||||||
setRefreshing(false);
|
setRefreshing(false);
|
||||||
}
|
}
|
||||||
};
|
}, [dispatch]);
|
||||||
|
|
||||||
|
// Load more data for infinite scrolling
|
||||||
|
const loadMoreData = useCallback(async (dataType: string) => {
|
||||||
|
try {
|
||||||
|
let pagination;
|
||||||
|
let fetchAction;
|
||||||
|
let resetAction;
|
||||||
|
|
||||||
|
switch (dataType) {
|
||||||
|
case 'leads':
|
||||||
|
pagination = leadsPagination;
|
||||||
|
fetchAction = fetchLeads;
|
||||||
|
resetAction = resetLeadsPagination;
|
||||||
|
break;
|
||||||
|
case 'tasks':
|
||||||
|
pagination = tasksPagination;
|
||||||
|
fetchAction = fetchTasks;
|
||||||
|
resetAction = resetTasksPagination;
|
||||||
|
break;
|
||||||
|
case 'contacts':
|
||||||
|
pagination = contactsPagination;
|
||||||
|
fetchAction = fetchContacts;
|
||||||
|
resetAction = resetContactsPagination;
|
||||||
|
break;
|
||||||
|
case 'deals':
|
||||||
|
pagination = dealsPagination;
|
||||||
|
fetchAction = fetchDeals;
|
||||||
|
resetAction = resetDealsPagination;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return; // Only leads, tasks, contacts, and deals support infinite scrolling for now
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if there are more records and not currently loading
|
||||||
|
if (!pagination.moreRecords || loading[dataType as keyof typeof loading]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch next page
|
||||||
|
await (dispatch(fetchAction({
|
||||||
|
page: pagination.page + 1,
|
||||||
|
limit: 20,
|
||||||
|
append: true
|
||||||
|
}) as any)).unwrap();
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
showError(`Failed to load more ${dataType}`);
|
||||||
|
}
|
||||||
|
}, [dispatch, leadsPagination, tasksPagination, contactsPagination, dealsPagination, loading]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetchCrmData();
|
fetchCrmData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleRefresh = () => {
|
const handleRefresh = useCallback(() => {
|
||||||
fetchCrmData(true);
|
fetchCrmData(true);
|
||||||
};
|
}, [fetchCrmData]);
|
||||||
|
|
||||||
const handleRetry = () => {
|
const handleRetry = useCallback(() => {
|
||||||
fetchCrmData();
|
fetchCrmData();
|
||||||
};
|
}, [fetchCrmData]);
|
||||||
|
|
||||||
const handleCardPress = (item: any, type: string) => {
|
const handleCardPress = useCallback((item: any, type: string) => {
|
||||||
showInfo(`Viewing ${type}: ${item.name || item.subject || `${item.firstName} ${item.lastName}`}`);
|
showInfo(`Viewing ${type}: ${item.name || item.subject || `${item.firstName} ${item.lastName}`}`);
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
|
// Render loading footer for infinite scroll
|
||||||
|
const renderFooter = useCallback((dataType: string) => {
|
||||||
|
const isLoadingMore = loading[dataType as keyof typeof loading];
|
||||||
|
if (!isLoadingMore) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.footerLoader}>
|
||||||
|
<ActivityIndicator size="small" color={colors.primary} />
|
||||||
|
<Text style={[styles.footerText, { color: colors.textLight }]}>
|
||||||
|
Loading more...
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}, [loading, colors]);
|
||||||
|
|
||||||
// Get current loading state and error
|
// Get current loading state and error
|
||||||
const isLoading = loading.leads || loading.tasks || loading.contacts || loading.deals ||
|
const isLoading = loading.leads || loading.tasks || loading.contacts || loading.deals ||
|
||||||
@ -123,7 +214,7 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const renderTabContent = () => {
|
const renderTabContent = useCallback(() => {
|
||||||
const commonFlatListProps = {
|
const commonFlatListProps = {
|
||||||
numColumns: 1,
|
numColumns: 1,
|
||||||
showsVerticalScrollIndicator: false,
|
showsVerticalScrollIndicator: false,
|
||||||
@ -144,7 +235,10 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
onPress={() => handleCardPress(item, 'Lead')}
|
onPress={() => handleCardPress(item, 'Lead')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => `lead-${item.id}`}
|
||||||
|
onEndReached={() => loadMoreData('leads')}
|
||||||
|
onEndReachedThreshold={0.1}
|
||||||
|
ListFooterComponent={() => renderFooter('leads')}
|
||||||
{...commonFlatListProps}
|
{...commonFlatListProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -158,7 +252,10 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
onPress={() => handleCardPress(item, 'Task')}
|
onPress={() => handleCardPress(item, 'Task')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => `task-${item.id}`}
|
||||||
|
onEndReached={() => loadMoreData('tasks')}
|
||||||
|
onEndReachedThreshold={0.1}
|
||||||
|
ListFooterComponent={() => renderFooter('tasks')}
|
||||||
{...commonFlatListProps}
|
{...commonFlatListProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -172,7 +269,10 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
onPress={() => handleCardPress(item, 'Contact')}
|
onPress={() => handleCardPress(item, 'Contact')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => `contact-${item.id}`}
|
||||||
|
onEndReached={() => loadMoreData('contacts')}
|
||||||
|
onEndReachedThreshold={0.1}
|
||||||
|
ListFooterComponent={() => renderFooter('contacts')}
|
||||||
{...commonFlatListProps}
|
{...commonFlatListProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -186,7 +286,10 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
onPress={() => handleCardPress(item, 'Deal')}
|
onPress={() => handleCardPress(item, 'Deal')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => `deal-${item.id}`}
|
||||||
|
onEndReached={() => loadMoreData('deals')}
|
||||||
|
onEndReachedThreshold={0.1}
|
||||||
|
ListFooterComponent={() => renderFooter('deals')}
|
||||||
{...commonFlatListProps}
|
{...commonFlatListProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -200,7 +303,7 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
onPress={() => handleCardPress(item, 'Sales Order')}
|
onPress={() => handleCardPress(item, 'Sales Order')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => `sales-order-${item.id}`}
|
||||||
{...commonFlatListProps}
|
{...commonFlatListProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -214,7 +317,7 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
onPress={() => handleCardPress(item, 'Purchase Order')}
|
onPress={() => handleCardPress(item, 'Purchase Order')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => `purchase-order-${item.id}`}
|
||||||
{...commonFlatListProps}
|
{...commonFlatListProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -228,14 +331,14 @@ const ZohoCrmDataScreen: React.FC = () => {
|
|||||||
onPress={() => handleCardPress(item, 'Invoice')}
|
onPress={() => handleCardPress(item, 'Invoice')}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item) => item.id}
|
keyExtractor={(item) => `invoice-${item.id}`}
|
||||||
{...commonFlatListProps}
|
{...commonFlatListProps}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
}, [selectedTab, crmData, handleCardPress, loadMoreData, renderFooter, refreshing, handleRefresh]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, { backgroundColor: colors.background }]}>
|
<View style={[styles.container, { backgroundColor: colors.background }]}>
|
||||||
@ -366,6 +469,16 @@ const styles = StyleSheet.create({
|
|||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
paddingBottom: 20,
|
paddingBottom: 20,
|
||||||
},
|
},
|
||||||
|
footerLoader: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingVertical: 16,
|
||||||
|
},
|
||||||
|
footerText: {
|
||||||
|
marginLeft: 8,
|
||||||
|
fontSize: 14,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default ZohoCrmDataScreen;
|
export default ZohoCrmDataScreen;
|
||||||
|
|||||||
@ -25,8 +25,8 @@ export const crmAPI = {
|
|||||||
provider: 'zoho',
|
provider: 'zoho',
|
||||||
service: 'crm',
|
service: 'crm',
|
||||||
resource,
|
resource,
|
||||||
page: 1,
|
page: params?.page || 1,
|
||||||
limit: 20,
|
limit: params?.limit || 20,
|
||||||
...params
|
...params
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -47,13 +47,34 @@ export const crmAPI = {
|
|||||||
crmAPI.getCrmData<CrmDeal>('deals', params),
|
crmAPI.getCrmData<CrmDeal>('deals', params),
|
||||||
|
|
||||||
// New API endpoints for sales orders, purchase orders, and invoices
|
// New API endpoints for sales orders, purchase orders, and invoices
|
||||||
getSalesOrders: (params?: CrmSearchParams) =>
|
getSalesOrders: (params?: CrmSearchParams) => {
|
||||||
http.get<CrmApiResponse<CrmPaginatedResponse<any>>>(`/api/v1/integrations/zoho/crm/sales-orders?provider=zoho`, params),
|
const queryParams = {
|
||||||
|
provider: 'zoho',
|
||||||
|
page: params?.page || 1,
|
||||||
|
limit: params?.limit || 20,
|
||||||
|
...params
|
||||||
|
};
|
||||||
|
return http.get<CrmApiResponse<CrmPaginatedResponse<any>>>(`/api/v1/integrations/zoho/crm/sales-orders`, queryParams);
|
||||||
|
},
|
||||||
|
|
||||||
getPurchaseOrders: (params?: CrmSearchParams) =>
|
getPurchaseOrders: (params?: CrmSearchParams) => {
|
||||||
http.get<CrmApiResponse<CrmPaginatedResponse<any>>>(`/api/v1/integrations/zoho/crm/purchase-orders?provider=zoho`, params),
|
const queryParams = {
|
||||||
|
provider: 'zoho',
|
||||||
|
page: params?.page || 1,
|
||||||
|
limit: params?.limit || 20,
|
||||||
|
...params
|
||||||
|
};
|
||||||
|
return http.get<CrmApiResponse<CrmPaginatedResponse<any>>>(`/api/v1/integrations/zoho/crm/purchase-orders`, queryParams);
|
||||||
|
},
|
||||||
|
|
||||||
getInvoices: (params?: CrmSearchParams) =>
|
getInvoices: (params?: CrmSearchParams) => {
|
||||||
http.get<CrmApiResponse<CrmPaginatedResponse<any>>>(`/api/v1/integrations/zoho/crm/invoices?provider=zoho`, params),
|
const queryParams = {
|
||||||
|
provider: 'zoho',
|
||||||
|
page: params?.page || 1,
|
||||||
|
limit: params?.limit || 20,
|
||||||
|
...params
|
||||||
|
};
|
||||||
|
return http.get<CrmApiResponse<CrmPaginatedResponse<any>>>(`/api/v1/integrations/zoho/crm/invoices`, queryParams);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -127,36 +127,48 @@ const initialState: CrmState = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// Async thunks
|
// Async thunks for infinite scrolling
|
||||||
export const fetchLeads = createAsyncThunk(
|
export const fetchLeads = createAsyncThunk(
|
||||||
'crm/fetchLeads',
|
'crm/fetchLeads',
|
||||||
async (params?: CrmSearchParams) => {
|
async (params?: CrmSearchParams & { append?: boolean }) => {
|
||||||
const response = await crmAPI.getLeads(params);
|
const response = await crmAPI.getLeads(params);
|
||||||
return response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } };
|
return {
|
||||||
|
data: response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } },
|
||||||
|
append: params?.append || false
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchTasks = createAsyncThunk(
|
export const fetchTasks = createAsyncThunk(
|
||||||
'crm/fetchTasks',
|
'crm/fetchTasks',
|
||||||
async (params?: CrmSearchParams) => {
|
async (params?: CrmSearchParams & { append?: boolean }) => {
|
||||||
const response = await crmAPI.getTasks(params);
|
const response = await crmAPI.getTasks(params);
|
||||||
return response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } };
|
return {
|
||||||
|
data: response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } },
|
||||||
|
append: params?.append || false
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchContacts = createAsyncThunk(
|
export const fetchContacts = createAsyncThunk(
|
||||||
'crm/fetchContacts',
|
'crm/fetchContacts',
|
||||||
async (params?: CrmSearchParams) => {
|
async (params?: CrmSearchParams & { append?: boolean }) => {
|
||||||
const response = await crmAPI.getContacts(params);
|
const response = await crmAPI.getContacts(params);
|
||||||
return response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } };
|
return {
|
||||||
|
data: response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } },
|
||||||
|
append: params?.append || false
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchDeals = createAsyncThunk(
|
export const fetchDeals = createAsyncThunk(
|
||||||
'crm/fetchDeals',
|
'crm/fetchDeals',
|
||||||
async (params?: CrmSearchParams) => {
|
async (params?: CrmSearchParams & { append?: boolean }) => {
|
||||||
const response = await crmAPI.getDeals(params);
|
const response = await crmAPI.getDeals(params);
|
||||||
return response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } };
|
return {
|
||||||
|
data: response.data?.data || { data: [], info: { count: 0, moreRecords: false, page: 1 } },
|
||||||
|
append: params?.append || false
|
||||||
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -266,6 +278,23 @@ const crmSlice = createSlice({
|
|||||||
setInvoicesPage: (state, action: PayloadAction<number>) => {
|
setInvoicesPage: (state, action: PayloadAction<number>) => {
|
||||||
state.pagination.invoices.page = action.payload;
|
state.pagination.invoices.page = action.payload;
|
||||||
},
|
},
|
||||||
|
// Reset pagination for specific data types
|
||||||
|
resetLeadsPagination: (state) => {
|
||||||
|
state.pagination.leads = { page: 1, count: 0, moreRecords: false };
|
||||||
|
state.leads = [];
|
||||||
|
},
|
||||||
|
resetTasksPagination: (state) => {
|
||||||
|
state.pagination.tasks = { page: 1, count: 0, moreRecords: false };
|
||||||
|
state.tasks = [];
|
||||||
|
},
|
||||||
|
resetContactsPagination: (state) => {
|
||||||
|
state.pagination.contacts = { page: 1, count: 0, moreRecords: false };
|
||||||
|
state.contacts = [];
|
||||||
|
},
|
||||||
|
resetDealsPagination: (state) => {
|
||||||
|
state.pagination.deals = { page: 1, count: 0, moreRecords: false };
|
||||||
|
state.deals = [];
|
||||||
|
},
|
||||||
},
|
},
|
||||||
extraReducers: (builder) => {
|
extraReducers: (builder) => {
|
||||||
// Fetch leads
|
// Fetch leads
|
||||||
@ -276,8 +305,17 @@ const crmSlice = createSlice({
|
|||||||
})
|
})
|
||||||
.addCase(fetchLeads.fulfilled, (state, action) => {
|
.addCase(fetchLeads.fulfilled, (state, action) => {
|
||||||
state.loading.leads = false;
|
state.loading.leads = false;
|
||||||
state.leads = action.payload.data || [];
|
const { data, append } = action.payload;
|
||||||
state.pagination.leads = action.payload.info || { page: 1, count: 0, moreRecords: false };
|
|
||||||
|
if (append) {
|
||||||
|
// Append new data to existing data for infinite scrolling
|
||||||
|
state.leads = [...state.leads, ...(data.data || [])];
|
||||||
|
} else {
|
||||||
|
// Replace data for initial load or refresh
|
||||||
|
state.leads = data.data || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
state.pagination.leads = data.info || { page: 1, count: 0, moreRecords: false };
|
||||||
state.lastUpdated.leads = new Date().toISOString();
|
state.lastUpdated.leads = new Date().toISOString();
|
||||||
})
|
})
|
||||||
.addCase(fetchLeads.rejected, (state, action) => {
|
.addCase(fetchLeads.rejected, (state, action) => {
|
||||||
@ -292,8 +330,17 @@ const crmSlice = createSlice({
|
|||||||
})
|
})
|
||||||
.addCase(fetchTasks.fulfilled, (state, action) => {
|
.addCase(fetchTasks.fulfilled, (state, action) => {
|
||||||
state.loading.tasks = false;
|
state.loading.tasks = false;
|
||||||
state.tasks = action.payload.data || [];
|
const { data, append } = action.payload;
|
||||||
state.pagination.tasks = action.payload.info || { page: 1, count: 0, moreRecords: false };
|
|
||||||
|
if (append) {
|
||||||
|
// Append new data to existing data for infinite scrolling
|
||||||
|
state.tasks = [...state.tasks, ...(data.data || [])];
|
||||||
|
} else {
|
||||||
|
// Replace data for initial load or refresh
|
||||||
|
state.tasks = data.data || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
state.pagination.tasks = data.info || { page: 1, count: 0, moreRecords: false };
|
||||||
state.lastUpdated.tasks = new Date().toISOString();
|
state.lastUpdated.tasks = new Date().toISOString();
|
||||||
})
|
})
|
||||||
.addCase(fetchTasks.rejected, (state, action) => {
|
.addCase(fetchTasks.rejected, (state, action) => {
|
||||||
@ -308,8 +355,17 @@ const crmSlice = createSlice({
|
|||||||
})
|
})
|
||||||
.addCase(fetchContacts.fulfilled, (state, action) => {
|
.addCase(fetchContacts.fulfilled, (state, action) => {
|
||||||
state.loading.contacts = false;
|
state.loading.contacts = false;
|
||||||
state.contacts = action.payload.data || [];
|
const { data, append } = action.payload;
|
||||||
state.pagination.contacts = action.payload.info || { page: 1, count: 0, moreRecords: false };
|
|
||||||
|
if (append) {
|
||||||
|
// Append new data to existing data for infinite scrolling
|
||||||
|
state.contacts = [...state.contacts, ...(data.data || [])];
|
||||||
|
} else {
|
||||||
|
// Replace data for initial load or refresh
|
||||||
|
state.contacts = data.data || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
state.pagination.contacts = data.info || { page: 1, count: 0, moreRecords: false };
|
||||||
state.lastUpdated.contacts = new Date().toISOString();
|
state.lastUpdated.contacts = new Date().toISOString();
|
||||||
})
|
})
|
||||||
.addCase(fetchContacts.rejected, (state, action) => {
|
.addCase(fetchContacts.rejected, (state, action) => {
|
||||||
@ -324,8 +380,17 @@ const crmSlice = createSlice({
|
|||||||
})
|
})
|
||||||
.addCase(fetchDeals.fulfilled, (state, action) => {
|
.addCase(fetchDeals.fulfilled, (state, action) => {
|
||||||
state.loading.deals = false;
|
state.loading.deals = false;
|
||||||
state.deals = action.payload.data || [];
|
const { data, append } = action.payload;
|
||||||
state.pagination.deals = action.payload.info || { page: 1, count: 0, moreRecords: false };
|
|
||||||
|
if (append) {
|
||||||
|
// Append new data to existing data for infinite scrolling
|
||||||
|
state.deals = [...state.deals, ...(data.data || [])];
|
||||||
|
} else {
|
||||||
|
// Replace data for initial load or refresh
|
||||||
|
state.deals = data.data || [];
|
||||||
|
}
|
||||||
|
|
||||||
|
state.pagination.deals = data.info || { page: 1, count: 0, moreRecords: false };
|
||||||
state.lastUpdated.deals = new Date().toISOString();
|
state.lastUpdated.deals = new Date().toISOString();
|
||||||
})
|
})
|
||||||
.addCase(fetchDeals.rejected, (state, action) => {
|
.addCase(fetchDeals.rejected, (state, action) => {
|
||||||
@ -465,6 +530,10 @@ export const {
|
|||||||
setSalesOrdersPage,
|
setSalesOrdersPage,
|
||||||
setPurchaseOrdersPage,
|
setPurchaseOrdersPage,
|
||||||
setInvoicesPage,
|
setInvoicesPage,
|
||||||
|
resetLeadsPagination,
|
||||||
|
resetTasksPagination,
|
||||||
|
resetContactsPagination,
|
||||||
|
resetDealsPagination,
|
||||||
} = crmSlice.actions;
|
} = crmSlice.actions;
|
||||||
|
|
||||||
export default crmSlice.reducer;
|
export default crmSlice.reducer;
|
||||||
|
|||||||
@ -17,6 +17,15 @@ export const selectCrmLoading = (state: RootState) => state.crm.loading;
|
|||||||
export const selectCrmErrors = (state: RootState) => state.crm.errors;
|
export const selectCrmErrors = (state: RootState) => state.crm.errors;
|
||||||
export const selectCrmPagination = (state: RootState) => state.crm.pagination;
|
export const selectCrmPagination = (state: RootState) => state.crm.pagination;
|
||||||
|
|
||||||
|
// Pagination selectors for infinite scrolling
|
||||||
|
export const selectLeadsPagination = (state: RootState) => state.crm.pagination.leads;
|
||||||
|
export const selectTasksPagination = (state: RootState) => state.crm.pagination.tasks;
|
||||||
|
export const selectContactsPagination = (state: RootState) => state.crm.pagination.contacts;
|
||||||
|
export const selectDealsPagination = (state: RootState) => state.crm.pagination.deals;
|
||||||
|
export const selectSalesOrdersPagination = (state: RootState) => state.crm.pagination.salesOrders;
|
||||||
|
export const selectPurchaseOrdersPagination = (state: RootState) => state.crm.pagination.purchaseOrders;
|
||||||
|
export const selectInvoicesPagination = (state: RootState) => state.crm.pagination.invoices;
|
||||||
|
|
||||||
// Loading selectors
|
// Loading selectors
|
||||||
export const selectLeadsLoading = (state: RootState) => state.crm.loading.leads;
|
export const selectLeadsLoading = (state: RootState) => state.crm.loading.leads;
|
||||||
export const selectTasksLoading = (state: RootState) => state.crm.loading.tasks;
|
export const selectTasksLoading = (state: RootState) => state.crm.loading.tasks;
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { clearSelectedService } from '@/modules/integrations/store/integrationsS
|
|||||||
let pendingRequest: any = null;
|
let pendingRequest: any = null;
|
||||||
|
|
||||||
const http = create({
|
const http = create({
|
||||||
baseURL: 'http://192.168.1.17:4000',
|
baseURL: 'http://10.175.59.235:4000',
|
||||||
// baseURL: 'http://160.187.167.216',
|
// baseURL: 'http://160.187.167.216',
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user