Skip to content

Commit

Permalink
add csv extract functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
zuies committed Sep 8, 2023
1 parent d4771d5 commit 9fba19b
Show file tree
Hide file tree
Showing 8 changed files with 274 additions and 24 deletions.
30 changes: 30 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"moment": "^2.29.4",
"moment-timezone": "^0.5.38",
"next": "13.0.2",
"papaparse": "^5.4.1",
"prettier": "^2.8.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand All @@ -65,6 +66,7 @@
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^14.0.0",
"@types/d3-force": "^3.0.4",
"@types/papaparse": "^5.3.8",
"autoprefixer": "^10.4.13",
"babel-jest": "^29.5.0",
"identity-obj-proxy": "^3.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import {
import CustomPagination from '../CustomPagination';
import CustomButton from '../../../../global/CustomButton';
import clsx from 'clsx';
import { FaFileCsv } from 'react-icons/fa';
import { Button } from '@mui/material';
import {
convertToCSV,
downloadCSVFile,
} from '../../../../../helpers/csvHelper';

const columns: Column[] = [
{ id: 'username', label: 'Name' },
Expand Down Expand Up @@ -109,15 +115,56 @@ export default function ActiveMemberBreakdown() {
toggleExpanded(!isExpanded);
};

const handleDownloadCSV = async () => {
if (!guild) {
return;
}

try {
const limit = fetchedData.totalResults;

const { results } = await getActiveMemberCompositionTable(
guild.guildId,
activityComposition,
roles,
username,
sortBy,
page,
limit
);

if (results && Array.isArray(results)) {
const csv = convertToCSV(results);
downloadCSVFile(csv, 'activeMemberComposition.csv');
} else {
console.error('Received data is not valid for CSV conversion.');
}
} catch (error) {
console.error('Error while fetching data and downloading CSV:', error);
}
};

return (
<>
<div className="relative overflow-x-scroll md:overflow-hidden mb-1 md:mb-1">
<h3
className="text-xl font-medium text-lite-black md:mb-4"
ref={tableTopRef}
>
Members breakdown
</h3>
<div className="flex justify-between items-center">
<h3
className="text-xl font-medium text-lite-black md:mb-4"
ref={tableTopRef}
>
Members breakdown
</h3>
<Button
startIcon={<FaFileCsv />}
size="small"
variant="contained"
className="bg-secondary text-white"
disableElevation
onClick={handleDownloadCSV}
>
Export CSV
</Button>
</div>
<div
className={clsx(
!isExpanded ? 'max-h-[17.8rem]' : 'max-h-max',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import {
import CustomPagination from '../CustomPagination';
import CustomButton from '../../../../global/CustomButton';
import clsx from 'clsx';
import { Button } from '@mui/material';
import { FaFileCsv } from 'react-icons/fa';
import {
convertToCSV,
downloadCSVFile,
} from '../../../../../helpers/csvHelper';

const columns: Column[] = [
{ id: 'username', label: 'Name' },
Expand Down Expand Up @@ -123,15 +129,56 @@ export default function DisengagedMembersCompositionBreakdown() {
toggleExpanded(!isExpanded);
};

const handleDownloadCSV = async () => {
if (!guild) {
return;
}

try {
const limit = fetchedData.totalResults;

const { results } = await getDisengagedMembersCompositionTable(
guild.guildId,
disengagedComposition,
roles,
username,
sortBy,
page,
limit
);

if (results && Array.isArray(results)) {
const csv = convertToCSV(results);
downloadCSVFile(csv, 'disengagedMemberComposition.csv');
} else {
console.error('Received data is not valid for CSV conversion.');
}
} catch (error) {
console.error('Error while fetching data and downloading CSV:', error);
}
};

return (
<>
<div className="relative overflow-x-scroll md:overflow-hidden mb-1 md:mb-1">
<h3
className="text-xl font-medium text-lite-black md:mb-4"
ref={tableTopRef}
>
Members breakdown
</h3>
<div className="flex justify-between items-center">
<h3
className="text-xl font-medium text-lite-black md:mb-4"
ref={tableTopRef}
>
Members breakdown
</h3>
<Button
startIcon={<FaFileCsv />}
size="small"
variant="contained"
className="bg-secondary text-white"
disableElevation
onClick={handleDownloadCSV}
>
Export CSV
</Button>
</div>
<div
className={clsx(
!isExpanded ? 'max-h-[17.8rem]' : 'max-h-max',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ import {
import CustomPagination from '../CustomPagination';
import CustomButton from '../../../../global/CustomButton';
import clsx from 'clsx';
import { Button } from '@mui/material';
import { FaFileCsv } from 'react-icons/fa';
import {
convertToCSV,
downloadCSVFile,
} from '../../../../../helpers/csvHelper';

const columns: Column[] = [
{ id: 'username', label: 'Name' },
Expand Down Expand Up @@ -111,15 +117,56 @@ export default function OnboardingMembersBreakdown() {
toggleExpanded(!isExpanded);
};

const handleDownloadCSV = async () => {
if (!guild) {
return;
}

try {
const limit = fetchedData.totalResults;

const { results } = await getOnboardingMemberCompositionTable(
guild.guildId,
onboardingComposition,
roles,
username,
sortBy,
page,
limit
);

if (results && Array.isArray(results)) {
const csv = convertToCSV(results);
downloadCSVFile(csv, 'onboardingMemberComposition.csv');
} else {
console.error('Received data is not valid for CSV conversion.');
}
} catch (error) {
console.error('Error while fetching data and downloading CSV:', error);
}
};

return (
<>
<div className="relative overflow-x-scroll md:overflow-hidden mb-1 md:mb-1">
<h3
className="text-xl font-medium text-lite-black md:mb-4"
ref={tableTopRef}
>
Members breakdown
</h3>
<div className="flex justify-between items-center">
<h3
className="text-xl font-medium text-lite-black md:mb-4"
ref={tableTopRef}
>
Members breakdown
</h3>
<Button
startIcon={<FaFileCsv />}
size="small"
variant="contained"
className="bg-secondary text-white"
disableElevation
onClick={handleDownloadCSV}
>
Export CSV
</Button>
</div>
<div
className={clsx(
!isExpanded ? 'max-h-[17.8rem]' : 'max-h-max',
Expand Down
62 changes: 62 additions & 0 deletions src/helpers/csvHelper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// csvHelper.ts

import Papa from 'papaparse';

interface DataObject {
[key: string]: any;
}

/**
* Convert given data to CSV format using Papaparse.
* @param {any[]} data The data to convert.
* @returns {string} The data in CSV format.
*/
function convertToCSV(data: any[]) {
const flattenedData = data.map((item) => {
let flattenedItem: { [key: string]: string | number } = {};

for (const key in item) {
if (item.hasOwnProperty(key)) {
// If the property is an array containing objects
if (
Array.isArray(item[key]) &&
item[key].length > 0 &&
typeof item[key][0] === 'object'
) {
flattenedItem[key] = item[key]
.map((subItem: any) =>
Object.entries(subItem)
.map(([subKey, subValue]) => `${subKey}: ${subValue}`)
.join(', ')
)
.join(' , ');
} else {
flattenedItem[key] = item[key];
}
}
}

return flattenedItem;
});

return Papa.unparse(flattenedData);
}

/**
* Download the given CSV data as a file.
* @param {string} csvData The CSV data to download.
* @param {string} filename The name for the downloaded file.
*/
function downloadCSVFile(csvData: string, filename = 'data.csv'): void {
const blob = new Blob([csvData], { type: 'text/csv' });
const url = URL.createObjectURL(blob);

const a = document.createElement('a');
a.href = url;
a.download = filename;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}

export { convertToCSV, downloadCSVFile };
Loading

0 comments on commit 9fba19b

Please sign in to comment.