UNPKG

omnipay-savings-sdk

Version:

Omnipay Savings SDK

191 lines (190 loc) 10.9 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const react_native_1 = require("react-native"); const dayjs_1 = __importDefault(require("dayjs")); const react_query_1 = require("@tanstack/react-query"); const utils_1 = require("../../utils"); const Text_1 = require("../Text"); const transactionCard_1 = __importDefault(require("../Common/transactionCard")); const threePane_1 = __importDefault(require("../ToggleTab/threePane")); const actions_1 = require("../../services/actions"); const SDKConfigContext_1 = require("../../contexts/SDKConfigContext"); const TransactionsList = ({ savingsId, recordsPerPage = 10, limit, showScrollIndicator = false, contentContainerStyle, scrollEnabled = true, showTabs = true, useHistoryEndpoint = false, }) => { const { apiKey, primaryColor } = (0, SDKConfigContext_1.useSDKConfig)(); const [tabRoute, setTabRoute] = (0, react_1.useState)(0); // Convert tab route to transaction type for API const transactionType = (0, react_1.useMemo)(() => { if (tabRoute === 1) { return 'Credit'; } if (tabRoute === 2) { return 'Debit'; } return undefined; // undefined means 'All' - don't pass transactionType parameter }, [tabRoute]); // Query key should be different for history vs savings transactions const queryKey = useHistoryEndpoint ? ['savingsTransactionHistory', apiKey, transactionType] : ['savingsTransactions', savingsId, apiKey, transactionType]; // Query for transactions with infinite loading const { data: transactionsData, isLoading, isError, fetchNextPage, hasNextPage, isFetchingNextPage, isFetching, } = (0, react_query_1.useInfiniteQuery)({ queryKey, queryFn: async ({ pageParam }) => { try { const params = { recordsPerPage, nextPageToken: pageParam, }; // Only add transactionType if it's not 'All' if (transactionType) { params.transactionType = transactionType; } let result; if (useHistoryEndpoint) { // Use history endpoint - doesn't need savingsId result = await (0, actions_1.getSavingsTransactionHistory)(apiKey, params); console.log(result, 'result'); } else { // Use existing endpoint - needs savingsId if (!savingsId) { throw new Error('savingsId is required when not using history endpoint'); } params.savingsId = savingsId; result = await (0, actions_1.getSavingsTransactionsList)(apiKey, params); } // Ensure we always return a valid structure return { transactionsList: Array.isArray(result === null || result === void 0 ? void 0 : result.transactionsList) ? result.transactionsList : [], nextPageToken: (result === null || result === void 0 ? void 0 : result.nextPageToken) || undefined, }; } catch (error) { console.error('Error fetching transactions:', error); // Return empty structure on error return { transactionsList: [], nextPageToken: undefined, }; } }, getNextPageParam: (lastPage) => { if (!lastPage || typeof lastPage !== 'object') { return undefined; } return lastPage.nextPageToken || undefined; }, initialPageParam: undefined, retry: 2, enabled: useHistoryEndpoint || !!savingsId, // Add default data structure to prevent undefined errors initialData: { pages: [], pageParams: [], }, }); // Safely flatten all pages into a single transactions array const allTransactions = (0, react_1.useMemo)(() => { try { if (!(transactionsData === null || transactionsData === void 0 ? void 0 : transactionsData.pages) || !Array.isArray(transactionsData.pages)) { return []; } const flattened = transactionsData.pages .filter(page => page && typeof page === 'object') .flatMap(page => { if (!Array.isArray(page.transactionsList)) { return []; } return page.transactionsList.filter((transaction) => transaction && typeof transaction === 'object' && transaction.transactionId); }); return flattened; } catch (error) { console.error('Error processing transactions:', error); return []; } }, [transactionsData]); // Apply limit if specified (no need for transaction type filtering since it's done server-side) const filteredTransactions = (0, react_1.useMemo)(() => { if (!Array.isArray(allTransactions)) { return []; } // Apply limit if specified if (limit) { return allTransactions.slice(0, limit); } return allTransactions; }, [allTransactions, limit]); // Group transactions by day const getDayWiseTransactions = () => { if (!Array.isArray(filteredTransactions) || filteredTransactions.length === 0) { return []; } const transactionsWithDay = filteredTransactions .filter((el) => el && el.createdDate) .map(function (el) { const formattedDay = (0, utils_1.formatDate)(el.createdDate, 'MMM D, YYYY'); const todayDate = (0, utils_1.formatDate)(new Date(), 'MMM D, YYYY'); const dayDifference = (0, dayjs_1.default)(todayDate).diff(formattedDay, 'day'); return Object.assign(Object.assign({}, el), { dayName: dayDifference === 0 ? 'Today' : dayDifference === 1 ? 'Yesterday' : formattedDay }); }); const dayGroupTransactions = (0, utils_1.groupArray)(transactionsWithDay, 'dayName'); return Object.entries(dayGroupTransactions).map(([key, value]) => ({ title: key, data: value, })); }; const dayWiseTransactions = (0, react_1.useMemo)(() => getDayWiseTransactions(), [filteredTransactions]); // Render content area (loader, error, empty state, or transactions) const renderContent = () => { // Show loader for initial load or refetching if (isLoading || (isFetching && !isLoading)) { return ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingTop: (0, utils_1.ms)(50), } }, { children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: "small", color: primaryColor }) }))); } // Show error state if (isError) { return ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: { flex: 1, justifyContent: 'center', alignItems: 'center', paddingTop: (0, utils_1.ms)(50), } }, { children: (0, jsx_runtime_1.jsx)(Text_1.Text, { color: utils_1.Colors.neutral90, fontWeight: "400", fontFamily: 'Gordita-Regular', fontSize: 14, text: "Failed to load transactions" }) }))); } // Show empty state if (filteredTransactions.length === 0) { return ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: { alignItems: 'center', paddingTop: (0, utils_1.ms)(20) } }, { children: (0, jsx_runtime_1.jsx)(Text_1.Text, { color: utils_1.Colors.neutral90, fontWeight: "400", fontFamily: 'Gordita-Regular', fontSize: (0, utils_1.fontSz)(14), text: "No transactions found" }) }))); } // Show transactions list return ((0, jsx_runtime_1.jsx)(react_native_1.SectionList, { scrollEnabled: scrollEnabled, showsVerticalScrollIndicator: showScrollIndicator, sections: dayWiseTransactions, contentContainerStyle: contentContainerStyle, style: { marginTop: showTabs ? (0, utils_1.ms)(4) : 0 }, onEndReached: () => { if (hasNextPage && !isFetchingNextPage && !limit) { fetchNextPage(); } }, onEndReachedThreshold: 0.3, ListFooterComponent: isFetchingNextPage && !limit ? ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: { padding: (0, utils_1.ms)(20), alignItems: 'center' } }, { children: (0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: "small", color: primaryColor }) }))) : null, renderItem: ({ item, index }) => { return ((0, jsx_runtime_1.jsx)(transactionCard_1.default, { status: item === null || item === void 0 ? void 0 : item.transactionType, title: (item === null || item === void 0 ? void 0 : item.description) || (item === null || item === void 0 ? void 0 : item.narration), transactionType: item === null || item === void 0 ? void 0 : item.transactionType, amount: item === null || item === void 0 ? void 0 : item.amount, createdDate: item === null || item === void 0 ? void 0 : item.createdDate, showTransactionType: true, onPress: () => { } }, index)); }, renderSectionHeader: ({ section }) => ((0, jsx_runtime_1.jsx)(react_native_1.View, Object.assign({ style: { backgroundColor: utils_1.Colors.white, paddingTop: (0, utils_1.ms)(10), paddingBottom: (0, utils_1.ms)(5), } }, { children: (0, jsx_runtime_1.jsx)(Text_1.Text, { color: '#515A65', fontWeight: "500", fontFamily: 'Gordita-Medium', fontSize: (0, utils_1.fontSz)(12), lineHeight: (0, utils_1.fontSz)(18), text: section.title }) }))), keyExtractor: (item, index) => `${item.transactionId}-${index}` })); }; return ((0, jsx_runtime_1.jsxs)(react_native_1.View, Object.assign({ style: { flex: 1 } }, { children: [showTabs && ((0, jsx_runtime_1.jsx)(threePane_1.default, { selectedTab: (e) => { setTabRoute(e); }, currentTab: tabRoute, firstLabel: 'All', secondLabel: 'Credit', thirdLabel: 'Debit' })), renderContent()] }))); }; exports.default = TransactionsList;