From d9f9be2630dd327d6ff3b9dbe132130a1cdb1340 Mon Sep 17 00:00:00 2001 From: Shubham Kumar Date: Mon, 10 Feb 2025 18:33:38 +0530 Subject: [PATCH] Added date filter modal and the option to download complete data --- locales/en.json | 4 + views/ActivityExportOptions.tsx | 288 ++++++++++++++++++++++++++++++-- 2 files changed, 277 insertions(+), 15 deletions(-) diff --git a/locales/en.json b/locales/en.json index fe2d78512..6d7ed5321 100644 --- a/locales/en.json +++ b/locales/en.json @@ -1004,6 +1004,10 @@ "views.activityExport.exportPayments": "Export Payments", "views.activityExport.exportInvoices": "Export Invoices", "views.activityExport.exportTransactions": "Export Transactions", + "views.activityExport.fromDate": "From Date (Start Date)", + "views.activityExport.toDate": "To Date (End Date)", + "views.activityExport.dateRange": "Select Date Range:", + "views.activityExport.downloadCompleteData": "Download Complete Data", "views.Routing.RoutingEvent.sourceChannel": "Source Channel", "views.Routing.RoutingEvent.destinationChannel": "Destination Channel", "views.Olympians.title": "Olympians", diff --git a/views/ActivityExportOptions.tsx b/views/ActivityExportOptions.tsx index d9da1532d..22292b75b 100644 --- a/views/ActivityExportOptions.tsx +++ b/views/ActivityExportOptions.tsx @@ -1,18 +1,21 @@ import * as React from 'react'; import { View, - Text, TouchableOpacity, StyleSheet, Alert, Platform, - ScrollView + ScrollView, + Modal } from 'react-native'; import RNFS from 'react-native-fs'; import Icon from 'react-native-vector-icons/Feather'; import { inject, observer } from 'mobx-react'; import Header from '../components/Header'; +import Button from '../components/Button'; +import TextInput from '../components/TextInput'; +import Text from '../components/Text'; import LoadingIndicator from '../components/LoadingIndicator'; import { localeString } from '../utils/LocaleUtils'; @@ -24,6 +27,8 @@ import SettingsStore from '../stores/SettingsStore'; import Invoice from '../models/Invoice'; import Payment from '../models/Payment'; import Transaction from '../models/Transaction'; +import DatePicker from 'react-native-date-picker'; +import { CheckBox } from 'react-native-elements'; interface ActivityExportOptionsProps { navigation: any; @@ -35,6 +40,12 @@ interface ActivityExportOptionsState { isCsvLoading: boolean; isActivityFetching: boolean; filteredActivity: any; + isModalVisible: boolean; + customFileName: string; + fromDate: any; + toDate: any; + exportType: any; + downloadCompleteData: boolean; } @inject('ActivityStore', 'SettingsStore') @@ -48,7 +59,13 @@ export default class ActivityExportOptions extends React.Component< this.state = { isCsvLoading: false, isActivityFetching: true, - filteredActivity: [] + filteredActivity: [], + isModalVisible: false, + customFileName: '', + fromDate: null, + toDate: null, + exportType: '', + downloadCompleteData: false }; } @@ -113,6 +130,21 @@ export default class ActivityExportOptions extends React.Component< } }; + filterDataByDate = (data: any) => { + const { fromDate, toDate, downloadCompleteData } = this.state; + if (!fromDate && !toDate) return data; + + if (downloadCompleteData) return data; + + return data.filter((item: any) => { + const itemDate = new Date(item.getDate); + if (isNaN(itemDate.getTime())) return false; + if (fromDate && itemDate < fromDate) return false; + if (toDate && itemDate > toDate) return false; + return true; + }); + }; + downloadCsv = async (type: 'invoice' | 'payment' | 'transaction') => { this.setState({ isCsvLoading: true }, async () => { await new Promise((resolve) => setTimeout(resolve, 0)); @@ -189,6 +221,8 @@ export default class ActivityExportOptions extends React.Component< break; } + filteredData = this.filterDataByDate(filteredData); + if (!filteredData || filteredData.length === 0) { console.log('No valid data found for', type); this.setState({ isCsvLoading: false }); @@ -215,7 +249,9 @@ export default class ActivityExportOptions extends React.Component< try { const dateTime = this.getFormattedDateTime(); - const baseFileName = `zeus_${dateTime}_${type}.csv`; + const baseFileName = this.state.customFileName + ? `${this.state.customFileName}.csv` + : `zeus_${dateTime}_${type}.csv`; const filePath = Platform.OS === 'android' ? `${RNFS.DownloadDirectoryPath}/${baseFileName}` @@ -223,8 +259,12 @@ export default class ActivityExportOptions extends React.Component< console.log('Saving file to:', filePath); + this.setState({ isModalVisible: false }); + await RNFS.writeFile(filePath, csvData, 'utf8'); + this.closeAndClearInput(); + Alert.alert( localeString('general.success'), localeString('views.ActivityToCsv.csvDownloaded') @@ -241,8 +281,219 @@ export default class ActivityExportOptions extends React.Component< }); }; + closeAndClearInput = () => { + this.setState({ + isModalVisible: false, + customFileName: '', + fromDate: new Date(), + toDate: new Date(), + downloadCompleteData: false + }); + }; + + openModal = (type: 'invoice' | 'transaction' | 'payment') => + this.setState({ isModalVisible: true, exportType: type }); + + renderModal = () => { + const { + isModalVisible, + isCsvLoading, + customFileName, + fromDate, + toDate, + downloadCompleteData + } = this.state; + return ( + + + + {isCsvLoading ? ( + + ) : ( + <> + + {localeString( + 'views.activityExport.dateRange' + )} + + + + + this.setState({ + downloadCompleteData: + !downloadCompleteData, + fromDate: + !downloadCompleteData + ? null + : fromDate, + toDate: !downloadCompleteData + ? null + : toDate + }) + } + containerStyle={{ + backgroundColor: 'transparent', + borderWidth: 0 + }} + textStyle={{ + color: themeColor('text') + }} + checkedColor="green" + /> + + {!downloadCompleteData && ( + <> + + {localeString( + 'views.activityExport.fromDate' + )} + + { + this.setState({ + fromDate: date + }); + if ( + toDate && + date > toDate + ) { + this.setState({ + toDate: date + }); + } + }} + style={{ + height: 100, + marginTop: 10, + marginBottom: 20, + alignSelf: 'center' + }} + maximumDate={new Date()} + textColor={themeColor('text')} + /> + + {localeString( + 'views.activityExport.toDate' + )} + + { + if ( + fromDate && + date < fromDate + ) { + Alert.alert( + 'Invalid Date' + ); + } else { + this.setState({ + toDate: date + }); + } + }} + style={{ + height: 100, + marginTop: 10, + marginBottom: 20, + alignSelf: 'center' + }} + maximumDate={new Date()} + textColor={themeColor('text')} + /> + + )} + + + + this.setState({ + customFileName: text + }) + } + style={{ marginHorizontal: 12 }} + /> + +