Skip to content

Commit

Permalink
#38 add csv import feature
Browse files Browse the repository at this point in the history
  • Loading branch information
zamrokk committed Sep 14, 2023
1 parent eab9eb7 commit 83cc3d7
Show file tree
Hide file tree
Showing 7 changed files with 209 additions and 16 deletions.
14 changes: 14 additions & 0 deletions app/node_modules/.package-lock.json

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

16 changes: 16 additions & 0 deletions app/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 app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"jwt-decode": "^3.1.2",
"moment": "^2.29.4",
"moment-duration-format": "^2.3.2",
"papaparse": "^5.4.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "^5.3.4",
Expand All @@ -55,6 +56,7 @@
"@types/autosuggest-highlight": "^3.2.0",
"@types/moment-duration-format": "^2.2.3",
"@types/node": "^20.5.7",
"@types/papaparse": "^5.3.8",
"@types/react": "^18.2.21",
"@types/react-dom": "^18.0.10",
"@vitejs/plugin-legacy": "^4.0.2",
Expand Down
49 changes: 49 additions & 0 deletions app/public/csv.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
26 changes: 16 additions & 10 deletions app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,22 @@ const App: React.FC = () => {
console.warn(
"Access token expired, try to fetch from refresh token.."
);
await refreshToken(userAddress!, localStorage);
const userProfile = await getUserProfile(
userAddress!,
localStorage
);
if (userProfile) setUserProfile(userProfile);
setUserProfiles(
await loadUserProfiles(Tezos, userAddress!, localStorage)
);
break;
try {
await refreshToken(userAddress!, localStorage);
const userProfile = await getUserProfile(
userAddress!,
localStorage
);
if (userProfile) setUserProfile(userProfile);
setUserProfiles(
await loadUserProfiles(Tezos, userAddress!, localStorage)
);
break;
} catch (error) {
console.warn("Cannot refresh token, disconnect", error);
disconnectWallet();
break;
}
}
}
} else {
Expand Down
55 changes: 55 additions & 0 deletions app/src/components/CreatePermissionedSimplePoll.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import Papa from "papaparse";

import {
IonAvatar,
IonButton,
Expand Down Expand Up @@ -480,6 +482,59 @@ const CreatePermissionedSimplePoll: React.FC = () => {
) : (
""
)}

<IonButton>
<IonIcon icon="/csv.svg" />
<label htmlFor="csvInput"> &nbsp; Import CSV</label>
<input
id="csvInput"
type="file"
hidden
name="data"
accept=".csv"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
const data = e.target.files
? e.target.files[0]
: null;

if (!data) {
presentAlert(
"Enter a valid CSV file, only first column with Tezos addresses, no header"
);
} else {
let newBakerDelegators: string[] = [];
Papa.parse(data, {
header: false,

step: (row) => {
const address = (row.data as Array<string>)[0];
if (!validateAddress(address)) {
presentAlert(
"Enter a valid Tezos address (" +
address +
") on the first column of the CSV file, no header please"
);
}
newBakerDelegators.push(address);
},
complete: () => {
setContract({
...contract,
registeredVoters: [
...new Set([
...contract.registeredVoters,
...newBakerDelegators,
]),
],
} as PermissionedSimplePollVotingContract);
},
});
}

e.preventDefault();
}}
/>
</IonButton>
</IonRow>
</IonCardSubtitle>
</IonCardHeader>
Expand Down
63 changes: 57 additions & 6 deletions app/src/components/Settings.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
import { Share } from "@capacitor/share";
import {
TezosTemplate3WalletType,
Storage as TezosTemplateVotingContract,
} from "../tezosTemplate3.types";

import {
IonAvatar,
IonButton,
Expand Down Expand Up @@ -40,6 +35,7 @@ import {
shareSocialOutline,
trashBinOutline,
} from "ionicons/icons";
import Papa from "papaparse";
import React, { useEffect, useRef, useState } from "react";
import { RouteComponentProps, useHistory } from "react-router-dom";
import { PAGES, UserContext, UserContextType } from "../App";
Expand All @@ -56,6 +52,10 @@ import {
Storage as PermissionedSimplePollVotingContract,
PermissionedSimplePollWalletType,
} from "../permissionedSimplePoll.types";
import {
TezosTemplate3WalletType,
Storage as TezosTemplateVotingContract,
} from "../tezosTemplate3.types";

import { Capacitor } from "@capacitor/core";
import {
Expand Down Expand Up @@ -198,7 +198,7 @@ export const Settings: React.FC<SettingsProps> = ({ match }) => {
} else {
presentAlert({
header: "Warning",
message: "All delegators already added",
message: "All voters already added",
});
setLoading(false);
}
Expand Down Expand Up @@ -731,6 +731,57 @@ export const Settings: React.FC<SettingsProps> = ({ match }) => {
) : (
""
)}

<IonButton>
<IonIcon icon="/csv.svg" />
<label htmlFor="csvInput"> &nbsp; Import CSV</label>
<input
id="csvInput"
type="file"
hidden
name="data"
accept=".csv"
onChange={(
e: React.ChangeEvent<HTMLInputElement>
) => {
const data = e.target.files
? e.target.files[0]
: null;

if (!data) {
presentAlert(
"Enter a valid CSV file, only first column with Tezos addresses, no header"
);
} else {
let newBakerDelegators: string[] = [];
Papa.parse(data, {
header: false,

step: (row) => {
const address = (
row.data as Array<string>
)[0];
if (!validateAddress(address)) {
presentAlert(
"Enter a valid Tezos address (" +
address +
") on the first column of the CSV file, no header please"
);
}
newBakerDelegators.push(address);
},
complete: () => {
handleAddDelegatorVoters(
newBakerDelegators
);
},
});
}

e.preventDefault();
}}
/>
</IonButton>
</IonRow>
</IonCardSubtitle>
</IonCardHeader>
Expand Down

0 comments on commit 83cc3d7

Please sign in to comment.