Skip to content

Commit

Permalink
Refactored CSV export to reuse utils functions across ActivityExportO…
Browse files Browse the repository at this point in the history
…ptions and ActivityToCsv
  • Loading branch information
shubhamkmr04 committed Feb 10, 2025
1 parent d9f9be2 commit 25dd28a
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 217 deletions.
83 changes: 83 additions & 0 deletions utils/ActivityCsvUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import RNFS from 'react-native-fs';
import { Platform } from 'react-native';

// Keys for CSV export.
export const CSV_KEYS = {
invoice: [
{ label: 'Amount Paid (sat)', value: 'getAmount' },
{ label: 'Payment Request', value: 'getPaymentRequest' },
{ label: 'Payment Hash', value: 'getRHash' },
{ label: 'Memo', value: 'getMemo' },
{ label: 'Note', value: 'getNote' },
{ label: 'Creation Date', value: 'getCreationDate' },
{ label: 'Expiry', value: 'formattedTimeUntilExpiry' }
],
payment: [
{ label: 'Destination', value: 'getDestination' },
{ label: 'Payment Request', value: 'getPaymentRequest' },
{ label: 'Payment Hash', value: 'paymentHash' },
{ label: 'Amount Paid (sat)', value: 'getAmount' },
{ label: 'Memo', value: 'getMemo' },
{ label: 'Note', value: 'getNote' },
{ label: 'Creation Date', value: 'getDate' }
],
transaction: [
{ label: 'Transaction Hash', value: 'tx' },
{ label: 'Amount (sat)', value: 'getAmount' },
{ label: 'Total Fees (sat)', value: 'getFee' },
{ label: 'Note', value: 'getNote' },
{ label: 'Timestamp', value: 'getDate' }
]
};

// Generates a formatted timestamp string for file naming.
export const getFormattedDateTime = (): string => {
const now = new Date();
const year = now.getFullYear();
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const day = now.getDate().toString().padStart(2, '0');
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');
return `${year}${month}${day}_${hours}${minutes}${seconds}`;
};

// Converts activity data into a CSV string.
export const convertActivityToCsv = async (
data: Array<any>,
keysToInclude: Array<{ label: string; value: string }>
): Promise<string> => {
if (!data || data.length === 0) return '';

try {
const header = keysToInclude.map((field) => field.label).join(',');
const rows = data
.map((item) =>
keysToInclude
.map((field) => `"${item[field.value] || ''}"`)
.join(',')
)
.join('\n');

return `${header}\n${rows}`;
} catch (err) {
console.error(err);
return '';
}
};

//Saves CSV file to the device.
export const saveCsvFile = async (fileName: string, csvData: string) => {
try {
const filePath =
Platform.OS === 'android'
? `${RNFS.DownloadDirectoryPath}/${fileName}`
: `${RNFS.DocumentDirectoryPath}/${fileName}`;

console.log(`Saving file to: ${filePath}`);
await RNFS.writeFile(filePath, csvData, 'utf8');
} catch (err) {
console.error('Failed to save CSV file:', err);
throw err;
}
};
141 changes: 31 additions & 110 deletions views/Activity/ActivityToCsv.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import React, { useState } from 'react';
import { StyleSheet, View, Platform, Alert, Modal } from 'react-native';
import RNFS from 'react-native-fs';
import Button from '../../components/Button';
import TextInput from '../../components/TextInput';
import { localeString } from '../../utils/LocaleUtils';
import { themeColor } from '../../utils/ThemeUtils';
import { StyleSheet, View, Alert, Modal } from 'react-native';

import Invoice from '../../models/Invoice';
import Payment from '../../models/Payment';
import Transaction from '../../models/Transaction';

import Button from '../../components/Button';
import TextInput from '../../components/TextInput';
import LoadingIndicator from '../../components/LoadingIndicator';

import { localeString } from '../../utils/LocaleUtils';
import { themeColor } from '../../utils/ThemeUtils';
import {
getFormattedDateTime,
convertActivityToCsv,
saveCsvFile,
CSV_KEYS
} from '../../utils/ActivityCsvUtils';

interface ActivityProps {
filteredActivity: Array<Invoice | Payment | Transaction>;
isVisible: boolean;
Expand All @@ -29,87 +37,22 @@ const ActivityToCsv: React.FC<ActivityProps> = ({
closeModal();
};

const getFormattedDateTime = () => {
const now = new Date();
const year = now.getFullYear();
const month = (now.getMonth() + 1).toString().padStart(2, '0');
const day = now.getDate().toString().padStart(2, '0');
const hours = now.getHours().toString().padStart(2, '0');
const minutes = now.getMinutes().toString().padStart(2, '0');
const seconds = now.getSeconds().toString().padStart(2, '0');

return `${year}${month}${day}_${hours}${minutes}${seconds}`;
};

const convertActivityToCsv = async (
data: Array<Invoice | Payment | Transaction>,
keysToInclude: Array<any>
) => {
if (!data || data.length === 0) {
return '';
}

try {
const header = keysToInclude.map((field) => field.label).join(',');
const rows = data
?.map((item: any) =>
keysToInclude
.map((field) => `"${item[field.value]}"` || '')
.join(',')
)
.join('\n');

return `${header}\n${rows}`;
} catch (err) {
console.error(err);
return '';
}
};

const downloadCsv = async () => {
setIsLoading(true);
setTimeout(async () => {
const invoiceKeys = [
{ label: 'Amount Paid (sat)', value: 'getAmount' },
{ label: 'Payment Request', value: 'getPaymentRequest' },
{ label: 'Payment Hash', value: 'getRHash' },
{ label: 'Memo', value: 'getMemo' },
{ label: 'Note', value: 'getNote' },
{ label: 'Creation Date', value: 'getCreationDate' },
{ label: 'Expiry', value: 'formattedTimeUntilExpiry' }
];

const paymentKeys = [
{ label: 'Destination', value: 'getDestination' },
{ label: 'Payment Request', value: 'getPaymentRequest' },
{ label: 'Payment Hash', value: 'paymentHash' },
{ label: 'Amount Paid (sat)', value: 'getAmount' },
{ label: 'Memo', value: 'getMemo' },
{ label: 'Note', value: 'getNote' },
{ label: 'Creation Date', value: 'getDate' }
];

const transactionKeys = [
{ label: 'Transaction Hash', value: 'tx' },
{ label: 'Amount (sat)', value: 'getAmount' },
{ label: 'Total Fees (sat)', value: 'getFee' },
{ label: 'Note', value: 'getNote' },
{ label: 'Timestamp', value: 'getDate' }
];

const invoiceCsv = await convertActivityToCsv(
filteredActivity.filter((item: any) => item instanceof Invoice),
invoiceKeys
CSV_KEYS.invoice
);
const paymentCsv = await convertActivityToCsv(
filteredActivity.filter((item: any) => item instanceof Payment),
paymentKeys
CSV_KEYS.payment
);
const transactionCsv = await convertActivityToCsv(
filteredActivity.filter(
(item: any) => item instanceof Transaction
),
transactionKeys
CSV_KEYS.transaction
);

if (!invoiceCsv && !paymentCsv && !transactionCsv) {
Expand All @@ -120,43 +63,21 @@ const ActivityToCsv: React.FC<ActivityProps> = ({
try {
const dateTime = getFormattedDateTime();
const baseFileName = customFileName || `zeus_${dateTime}`;
const invoiceFileName = `${baseFileName}_ln_invoices.csv`;
const paymentFileName = `${baseFileName}_ln_payments.csv`;
const transactionFileName = `${baseFileName}_onchain.csv`;

const invoiceFilePath =
Platform.OS === 'android'
? `${RNFS.DownloadDirectoryPath}/${invoiceFileName}`
: `${RNFS.DocumentDirectoryPath}/${invoiceFileName}`;

const paymentFilePath =
Platform.OS === 'android'
? `${RNFS.DownloadDirectoryPath}/${paymentFileName}`
: `${RNFS.DocumentDirectoryPath}/${paymentFileName}`;

const transactionFilePath =
Platform.OS === 'android'
? `${RNFS.DownloadDirectoryPath}/${transactionFileName}`
: `${RNFS.DocumentDirectoryPath}/${transactionFileName}`;

if (invoiceCsv) {
console.log('invoiceFilePath', invoiceFilePath);
await RNFS.writeFile(invoiceFilePath, invoiceCsv, 'utf8');
}

if (paymentCsv) {
console.log('paymentFilePath', paymentFilePath);
await RNFS.writeFile(paymentFilePath, paymentCsv, 'utf8');
}

if (transactionCsv) {
console.log('transactionFilePath', transactionFilePath);
await RNFS.writeFile(
transactionFilePath,
transactionCsv,
'utf8'
if (invoiceCsv)
await saveCsvFile(
`${baseFileName}_ln_invoices.csv`,
invoiceCsv
);
if (paymentCsv)
await saveCsvFile(
`${baseFileName}_ln_payments.csv`,
paymentCsv
);
if (transactionCsv)
await saveCsvFile(
`${baseFileName}_onchain.csv`,
transactionCsv
);
}

Alert.alert(
localeString('general.success'),
Expand Down
Loading

0 comments on commit 25dd28a

Please sign in to comment.