From d550a15e9088ca7d03306b172a5cb580eb395dcf Mon Sep 17 00:00:00 2001
From: jakogri
Date: Tue, 4 Jun 2024 05:15:30 +0300
Subject: [PATCH] =?UTF-8?q?16.05.2024=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?=
=?UTF-8?q?=D0=B8=D0=BB=20=D0=BF=D1=80=D0=BE=D0=B3=D1=80=D0=B0=D0=BC=D0=BC?=
=?UTF-8?q?=D1=83=20=D0=B2=20=D1=81=D0=BE=D0=BE=D1=82=D0=B2=D0=B5=D1=82?=
=?UTF-8?q?=D1=81=D1=82=D0=B2=D0=B8=D0=B8=20=D1=81=20=D1=82=D0=B5=D0=BC,?=
=?UTF-8?q?=20=D1=87=D1=82=D0=BE=20=D0=B1=D0=BE=D0=BB=D1=8C=D1=88=D0=B5=20?=
=?UTF-8?q?=D0=BD=D0=B5=D1=82=20=D0=B7=D0=B0=D0=B4=E2=80=A6=20(#177)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 16.05.2024 изменил программу в соответствии с тем, что больше нет задеплоиных компаний, а только кошельки компаний.
* 17.05.2024 исправил модуль CampaignPage. Теперь программа после отсылки донатов выходит в основной список.
* 24.05.2024 внёс исправление в функцию handleLoadOneCampaign. Убрал из условий отбора компании поле deleted.
* 27.05.2024 Внёс изменения во внешний вид.Добавил внизу строчку пробела. Исправил ошибку с неправильным показом количества всего собранных компанией донатов, как в общем списке так и в форме показа отдельной компании.
* 28.05.2024 изменил файл package.json, чтобы можно было запускать и под Windows, и под Linux.
---
package.json | 4 +
server/server.js | 4 +
server/serverLib.js | 143 +++++++--
src/components/App.js | 2 -
src/components/CampaignList.js | 9 +-
src/components/CampaignPage.js | 249 +++++++---------
src/components/CreateCampaign.js | 305 +++++++++----------
src/components/EditCampaign.js | 489 ++++++++++++++-----------------
src/components/TRC20.js | 3 +
src/components/TextEditor.js | 5 +
src/components/UserCampaigns.js | 3 -
src/lang/translationEN.json | 11 +-
src/lang/translationRU.json | 11 +-
src/util/Utilities.js | 14 +-
14 files changed, 630 insertions(+), 622 deletions(-)
create mode 100644 src/components/TRC20.js
diff --git a/package.json b/package.json
index 4ca4dd4..9558709 100644
--- a/package.json
+++ b/package.json
@@ -74,11 +74,15 @@
"typescript": "^3.9.9"
},
"scripts": {
+ "start-react-windows": "set NODE_OPTIONS=--openssl-legacy-provider && react-scripts start",
"start-react": "export NODE_OPTIONS=--openssl-legacy-provider && react-scripts start",
+ "start-windows": "set NODE_OPTIONS=--openssl-legacy-provider && cd server && node server.js",
"start": "export NODE_OPTIONS=--openssl-legacy-provider && cd server && node server.js",
"postinstall": "npm config set legacy-peer-deps true && cd server && npm --loglevel=error install",
"install-all": "npm config set legacy-peer-deps true && npm --loglevel=error install && cd server && npm --loglevel=error install",
+ "build-windows": "set NODE_OPTIONS=--openssl-legacy-provider && react-scripts build && mv build/index.html build/_index.html",
"build": "export NODE_OPTIONS=--openssl-legacy-provider && react-scripts build && mv build/index.html build/_index.html",
+ "test-windows": "set NODE_OPTIONS=--openssl-legacy-provider && react-scripts test",
"test": "export NODE_OPTIONS=--openssl-legacy-provider && react-scripts test",
"eject": "react-scripts eject"
},
diff --git a/server/server.js b/server/server.js
index ee96d6d..729328e 100644
--- a/server/server.js
+++ b/server/server.js
@@ -195,6 +195,10 @@ APP.post('/api/donate/adddanate', async (req, res) => {
}
});
+APP.post('/api/campaign/updateWallet', async (req, res) => {
+ const DB = CLIENT.db(DBNAME);
+ serverLib.handleUpdateCampaignWallet(req, res, Sentry, DB);
+});
APP.post('/api/campaign/update', (req, res) => {
if(serverLib.authenticated(req, res, Sentry)) {
diff --git a/server/serverLib.js b/server/serverLib.js
index ee4a80d..96f23b1 100644
--- a/server/serverLib.js
+++ b/server/serverLib.js
@@ -29,6 +29,7 @@ class ServerLib {
this.emailCode.set(req.body.mydata.to_email, randCode);
return(text);
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendStatus(500);
}
@@ -62,6 +63,7 @@ class ServerLib {
await myCollection.insertOne(ITEM);
res.send('success');
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendStatus(500);
}
@@ -74,6 +76,7 @@ class ServerLib {
await myCollection.updateOne({'_id': req.body.mydata.to_email}, {$set: {password:password}});
res.send('success');
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendStatus(500);
}
@@ -142,6 +145,7 @@ class ServerLib {
res.send('success');
}).catch(console.error);
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendStatus(500);
}
@@ -152,19 +156,22 @@ class ServerLib {
campaignID: req.body.mydata.campaignID.toLowerCase(),
donatorID: req.body.mydata.donatorID.toLowerCase(),
raisedAmount: req.body.mydata.raisedAmount,
+ tipAmount: req.body.mydata.tipAmount,
transactionHash: req.body.mydata.transactionHash,
chainId: req.body.mydata.chainId,
coinAddress: req.body.mydata.coinAddress,
+ blockChainOrt: req.body.mydata.blockChainOrt,
donateDate: Date.now(),
deleted: false,
checked: false
}
-
try {
const myCollection = await DB.collection('donations');
await myCollection.insertOne(ITEM);
+ await this.handleUpdateCampaignWallet(req, res, Sentry, DB);
res.send('success');
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendStatus(500);
}
@@ -195,15 +202,15 @@ class ServerLib {
raisedAmount: 0,
creationDate: Date.now(),
lastDonationTime: 0,
- coins: req.body.mydata.coins,
- addresses: req.body.mydata.addresses,
- accounts: req.body.mydata.accounts,
active: false,
email: req.body.mydata.email,
countryCode: req.body.mydata.countryCode,
number: req.body.mydata.number,
telegram: req.body.mydata.telegram,
website: req.body.mydata.website,
+ payout_address: req.body.mydata.payout_address,
+ payout_chain: req.body.mydata.payout_chain,
+ complete:req.body.mydata.complete,
new: true
}
try {
@@ -211,6 +218,7 @@ class ServerLib {
await myCollection.insertOne(ITEM);
return true
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
return false;
}
@@ -234,6 +242,7 @@ class ServerLib {
await myCollection.updateOne({'_id': req.body.mydata.address}, {$set: req.body.mydata.dataToUpdate});
res.send('success');
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendStatus(500);
}
@@ -252,6 +261,7 @@ class ServerLib {
await myCollection.updateOne({'_id': req.body.id}, {$set: {deleted:true}});
res.send('success');
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendStatus(500);
}
@@ -260,16 +270,23 @@ class ServerLib {
async handleLoadFinishedCampaigns(req, res, Sentry, DB) {
try{
-
let pipeline = [
- { $match: {successful: true, deleted:{ $exists : false}}},
- {$sort: {raisedAmount: -1, raisedOnCoinbase: -1, _id: 1}},
- { $skip : req.body.startRec},
- { $limit:req.body.compaignsCount}
+ {$lookup: {from :"campaign_wallet", localField: "_id", foreignField: "campaign_id", as : "wallet"}},
+ {$match: {successful: true,
+ $or:[{deleted:{ $exists : false}}, {deleted:false}],"wallet":{ $ne : []},"active":true, complete:true}},
+ {$set: {wallet: {$arrayElemAt: ["$wallet.addres_base58",0]},donate_count:{$arrayElemAt: ["$wallet.donate_count",0]}}},
+ {$sort: {donate_count: -1, raisedOnCoinbase: -1, _id: 1}},
+ {$skip : req.body.startRec},
+ { $limit:req.body.compaignsCount}
];
+ let pipeline1 = [
+ { $lookup: {from :"campaign_wallet", localField: "_id", foreignField: "campaign_id", as : "wallet"}},
+ { $match: {successful:true,
+ $or:[{deleted:{ $exists : false}}, {deleted:false}],"wallet":{ $ne : []},"active":true, complete:true}}
+ ];
let curArr = await DB.collection('campaigns').aggregate(pipeline).toArray();
- let arCount = await DB.collection('campaigns').count({successful: true, deleted:{ $exists : false }});
- let result = {curArr:curArr, arCount:arCount};
+ let curArr1 = await DB.collection('campaigns').aggregate(pipeline1).toArray();
+ let result = {curArr:curArr, arCount:curArr1.length};
res.send(result);
} catch (err) {
console.log(err);
@@ -281,16 +298,25 @@ class ServerLib {
async handleLoadAllCampaigns(req, res, Sentry, DB) {
try{
let pipeline = [
- { $match: {active: true, deleted:{ $exists : false}}},
- {$sort: {lastDonationTime: -1, raisedAmount: -1, raisedOnCoinbase: -1, _id: 1}},
+ {$lookup: {from :"campaign_wallet", localField: "_id", foreignField: "campaign_id", as : "wallet"}},
+ {$match: {$or:[{successful:false },{successful:{$exists : false}}],
+ $or:[{deleted:{ $exists : false}}, {deleted:false}],"wallet":{ $ne : []},"active":true, complete:true}},
+ {$set: {wallet: {$arrayElemAt: ["$wallet.addres_base58",0]},donate_count:{$sum:{$arrayElemAt: ["$wallet.donate_count",0]}}}},
+ {$sort: {donate_count: -1, raisedOnCoinbase: -1, _id: 1}},
{ $skip : req.body.startRec},
{ $limit: req.body.compaignsCount}
];
+ let pipeline1 = [
+ { $lookup: {from :"campaign_wallet", localField: "_id", foreignField: "campaign_id", as : "wallet"}},
+ { $match: {$or:[{successful:false },{successful:{$exists : false}}],
+ $or:[{deleted:{ $exists : false}}, {deleted:false}],"wallet":{ $ne : []},"active":true, complete:true}}
+ ];
let curArr = await DB.collection('campaigns').aggregate(pipeline).toArray();
- let arCount = await DB.collection('campaigns').count({active: true, deleted:{ $exists : false }});
- let result = {curArr:curArr, arCount:arCount};
+ let curArr1 = await DB.collection('campaigns').aggregate(pipeline1).toArray();
+ let result = {curArr:curArr, arCount:curArr1.length};
res.send(result);
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendStatus(500);
}
@@ -310,6 +336,7 @@ class ServerLib {
res.send(result);
}
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.send("error");
}
@@ -324,6 +351,7 @@ class ServerLib {
let result = await DB.collection('donations').aggregate(pipeline).toArray();
res.send(result);
} catch (err) {
+ console.log(err);
Sentry.captureException(new Error(err));
res.sendn("error");
}
@@ -335,7 +363,11 @@ class ServerLib {
let result = await myCollection.findOne({"key" : req.body.KEY, "deleted":{ $exists : false }});
if (result) res.send(result._id)
else res.send(req.body.KEY);
- } catch (err) {Sentry.captureException(new Error(err));}
+ } catch (err) {
+ console.log(err);
+ Sentry.captureException(new Error(err));
+ res.sendStatus(500);
+ }
}
async handlecheckKey(req, res, Sentry, DB) {
@@ -344,7 +376,11 @@ class ServerLib {
let result = await myCollection.findOne({"key" : req.body.KEY, "deleted":{ $exists : false }});
if (result) res.send(true)
else res.send(false);
- } catch (err) {Sentry.captureException(new Error(err));}
+ } catch (err) {
+ console.log(err);
+ Sentry.captureException(new Error(err));
+ res.sendStatus(500);
+ }
}
async handleGetCoinsList(req, res, Sentry, DB) {
@@ -353,7 +389,11 @@ class ServerLib {
let coins = await myCollection.find();//aggregate([{$group:{ _id : "$chain", coins:{$push: "$coin"}}}]);
const result = await coins.toArray();
res.send(result);
- } catch (err) {Sentry.captureException(new Error(err));}
+ } catch (err) {
+ console.log(err);
+ Sentry.captureException(new Error(err));
+ res.sendStatus(500);
+ }
}
async handleGetTipForHeo(req, res, Sentry, DB) {
@@ -365,6 +405,7 @@ class ServerLib {
} catch (err) {
console.log(err);
Sentry.captureException(new Error(err));
+ res.sendStatus(500);
}
}
@@ -374,15 +415,54 @@ class ServerLib {
let chains = await myCollection.distinct("chain");
const result = await chains.toArray();
res.send(result._id);
- } catch (err) {Sentry.captureException(new Error(err));}
+ } catch (err) {
+ console.log(err);
+ Sentry.captureException(new Error(err));
+ res.sendStatus(500);
+ }
+ }
+
+ async handleUpdateCampaignWallet(req, res, Sentry, DB) {
+ try {
+ const myCollection = await DB.collection('campaign_wallet');
+ await myCollection.updateOne({'campaign_id': req.body.mydata.campaignID, 'wallet_ort': req.body.mydata.blockChainOrt},
+ {$inc: {"donate_count":req.body.mydata.raisedAmount, "heo_donate":req.body.mydata.tipAmount}});
+ return true;
+ } catch (err) {
+ console.log(err);
+ Sentry.captureException(new Error(err));
+ res.sendStatus(500);
+ }
}
async handleLoadOneCampaign(req, res, Sentry, DB) {
try {
const myCollection = await DB.collection('campaigns');
- let result = await myCollection.findOne({"_id" : req.body.ID, "deleted":{ $exists : false }});
+ const walletColection = await DB.collection('campaign_wallet');
+ let result = await myCollection.findOne({"_id" : req.body.ID });
+ let donate = await DB.collection('donations').find({campaignID: req.body.ID}).toArray();
+ let campaign_wallets = await walletColection.find({"campaign_id" : req.body.ID}).
+ project({_id:0,wallet_ort:1,addres_base58:1,addres_hex:1,coin_name:1}).toArray();
+ for(let i=0; i
-
diff --git a/src/components/CampaignList.js b/src/components/CampaignList.js
index 9106818..e271300 100644
--- a/src/components/CampaignList.js
+++ b/src/components/CampaignList.js
@@ -148,11 +148,11 @@ class CampaignList extends Component {
campaigns.forEach( campaign => {
const found = donates.find(element => element._id === campaign._id);
let totalQuantity = found ? found.totalQuantity : 0;
- let raisedAmount = campaign.raisedAmount ? parseFloat(campaign.raisedAmount) : 0;
+ let raisedAmount = campaign.raisedAmount? parseFloat(campaign.raisedAmount) : 0;
let fiatDonations = campaign.fiatDonations ? parseFloat(campaign.fiatDonations) : 0;
let raisedOnCoinbase = campaign.raisedOnCoinbase ? parseFloat(campaign.raisedOnCoinbase) : 0;
if(raisedAmount || fiatDonations || raisedOnCoinbase || totalQuantity) {
- campaign["raisedAmount"] = Math.round((raisedAmount + fiatDonations + raisedOnCoinbase + totalQuantity) * 100)/100;
+ campaign.donate_count = Math.round((raisedAmount + fiatDonations + raisedOnCoinbase + totalQuantity) * 100)/100;
}
//dedupe coin names for "accepting" section
let dedupedCoinNames = [];
@@ -203,8 +203,8 @@ class CampaignList extends Component {
{`${DescriptionPreview(item.description, i18n.language)}...`}
- ${item.raisedAmount}{i18n.t('raised')}${item.maxAmount} {i18n.t('goal')}
-
+ ${item.donate_count}{i18n.t('raised')}${item.maxAmount} {i18n.t('goal')}
+
@@ -262,6 +262,7 @@ class CampaignList extends Component {
}
+
);
diff --git a/src/components/CampaignPage.js b/src/components/CampaignPage.js
index 8f45a58..ac064f6 100644
--- a/src/components/CampaignPage.js
+++ b/src/components/CampaignPage.js
@@ -7,6 +7,7 @@ import ReactTextCollapse from 'react-text-collapse';
import ReactPlayer from 'react-player';
import { Link } from "react-router-dom";
import { Trans } from 'react-i18next';
+import tron_abi from './TRC20';
import {
i18nString,
initWeb3,
@@ -21,7 +22,6 @@ import { Editor, EditorState, convertFromRaw, CompositeDecorator } from "draft-j
import '../css/campaignPage.css';
import '../css/modal.css';
import ReactGA from "react-ga4";
-import web3 from 'web3';
import bnbIcon from '../images/binance-coin-bnb-logo.png';
import busdIcon from '../images/binance-usd-busd-logo.png';
import usdcIcon from '../images/usd-coin-usdc-logo.png';
@@ -40,7 +40,8 @@ const IMG_MAP = {"BUSD": busdIcon,
"USDC": usdcIcon,
"USDT": usdtLogo,
"ETH": ethIcon,
- "cUSD": cusdIcon};
+ "cUSD": cusdIcon,
+};
const PAYMENT_ERROR_MESSAGES = {
declined: "cardPaymentDeclined",
@@ -83,6 +84,9 @@ class CampaignPage extends Component {
modalButtonMessage: "",
modalButtonVariant: "",
chainId:"",
+ campaign_wallets:[],
+ chain_addres:"",
+ token_addres:"",
chains:[],
chains_coins:[],
coins:[],
@@ -92,30 +96,34 @@ class CampaignPage extends Component {
fiatPaymentEnabled: false,
fiatPaymentProvider: '',
recurringFiatPayments: false,
- cur_chain: -1
+ cur_chain: -1,
+ tipForHeo: 0
};
this.handleGetCCInfo = this.handleGetCCInfo.bind(this);
this.handleCCInfoCancel = this.handleCCInfoCancel.bind(this);
-
+ this.blockChainOrt = "";
}
+
async handleGetCCInfo(info) {
- await this.setState({ccinfo : info});
+ this.setState({ccinfo : info});
this.handleDonateFiat();
-
}
+
handleCCInfoCancel() {
this.setState({showCCinfoModal : false});
}
handleDonationAmount = (e) => {
let donationAmount = parseInt(e.target.value);
- let tipAmount = parseInt(this.state.tipAmount);
+ let tipAmount = Math.max(1, parseInt(parseInt(donationAmount)/100 * this.state.tipForHeo));;
this.setState({tipAmount: tipAmount, donationAmount: donationAmount, totalAmount: (donationAmount + tipAmount)});
};
+
handleTipAmount = (e) => {
let tipAmount = parseInt(e.target.value);
this.setState({tipAmount: tipAmount, totalAmount: (tipAmount + parseInt(this.state.donationAmount))});
};
+
handleRecurringAmount = (e) => {
this.setState({recurringAmount: e.target.value});
};
@@ -129,7 +137,7 @@ class CampaignPage extends Component {
}
this.setState({cur_chain: -1});
return(-1);
- }
+ };
async getCampaign(address) {
var campaign = {};
@@ -153,37 +161,6 @@ class CampaignPage extends Component {
return campaign;
}
- updateRaisedAmount = async () => {
- var modalMessage;
- let data = {campaignID: this.state.campaignId};
- var donateAmount;
- await axios.post('/api/campaign/getalldonations', {mydata: data}, {headers: {"Content-Type": "application/json"}})
- .then(res => {
- donateAmount = (res.data === 0 || res.data.length === 0) ? 0 : parseFloat(res.data[0].totalQuantity);
- }).catch(err => {
- if (err.response) {
- modalMessage = 'technicalDifficulties'}
- else if(err.request) {
- modalMessage = 'checkYourConnection'
- }
- console.log(err);
- this.setState({
- showError: true,
- modalMessage: modalMessage,
- })
- })
- if(!donateAmount) {
- donateAmount = 0;
- }
- let baseAmount = this.state.campaign.raisedAmount ? parseFloat(this.state.campaign.raisedAmount) : 0;
- let fiatDonations = this.state.campaign.fiatDonations ? parseFloat(this.state.campaign.fiatDonations) : 0;
- let raisedOnCoinbase = this.state.campaign.raisedOnCoinbase ? parseFloat(this.state.campaign.raisedOnCoinbase) : 0;
- if(baseAmount || fiatDonations || raisedOnCoinbase || donateAmount) {
- let raisedAmount = Math.round((baseAmount + fiatDonations + raisedOnCoinbase + donateAmount) * 100)/100;
- this.setState({raisedAmount : raisedAmount});
- }
- }
-
handleDonateCoinbaseCommerce = async () => {
let data = {
amount: this.state.totalAmount,
@@ -206,7 +183,7 @@ class CampaignPage extends Component {
window.open(resp.data.redirectUrl, '_self');
} else {
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalMessage: "failedConnectCoinbaseCommerce",
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: false
@@ -215,7 +192,7 @@ class CampaignPage extends Component {
} catch (err) {
console.log(err);
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalMessage: err.response.data,
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: false
@@ -239,7 +216,7 @@ class CampaignPage extends Component {
try {
this.setState({
showCCWarningModal:false,
- showModal: true, modalTitle: 'processingWait',
+ showModal: true, modalTitle: 'processingWait', goHome: false,
modalMessage: "plzWait",
errorIcon: 'HourglassSplit', modalButtonVariant: "gold", waitToClose: true
});
@@ -249,7 +226,7 @@ class CampaignPage extends Component {
window.open(resp.data.redirectUrl, '_self');
} else if(resp.data.paymentStatus === "success") {
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouFiatDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false, tryAgainCC: false, ccinfo: {}
@@ -257,7 +234,7 @@ class CampaignPage extends Component {
} else {
this.setState({
showModal: true, modalTitle: 'failed', modalMessage: PAYMENT_ERROR_MESSAGES[resp.data.paymentStatus],
- errorIcon: 'XCircle', modalButtonMessage: 'tryAgain',
+ errorIcon: 'XCircle', modalButtonMessage: 'tryAgain', goHome: false,
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: false
});
this.setState(prevState => ({
@@ -270,7 +247,7 @@ class CampaignPage extends Component {
} catch (err) {
if (err.response.status === 503) {
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalMessage: err.response.data,
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: false
@@ -279,7 +256,7 @@ class CampaignPage extends Component {
}
console.log(err.response)
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'tryAgain',
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: (this.state.fiatPaymentProvider !== 'stripe')
});
@@ -300,7 +277,7 @@ class CampaignPage extends Component {
}
try {
this.setState({
- showCCWarningModal:false,
+ showCCWarningModal:false, goHome: false,
showModal: true, modalTitle: 'processingWait',
modalMessage: "plzWait",
errorIcon: 'HourglassSplit', modalButtonVariant: "gold", waitToClose: true
@@ -311,7 +288,7 @@ class CampaignPage extends Component {
window.open(resp.data.redirectUrl, '_self');
} else if(resp.data.paymentStatus === "success") {
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouFiatDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false, tryAgainCC: false, ccinfo: {}
@@ -319,7 +296,7 @@ class CampaignPage extends Component {
} else {
this.setState({
showModal: true, modalTitle: 'failed', modalMessage: PAYMENT_ERROR_MESSAGES[resp.data.paymentStatus],
- errorIcon: 'XCircle', modalButtonMessage: 'tryAgain',
+ errorIcon: 'XCircle', modalButtonMessage: 'tryAgain', goHome: false,
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: false
});
this.setState(prevState => ({
@@ -332,7 +309,7 @@ class CampaignPage extends Component {
} catch (err) {
if (err.response.status === 503) {
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalMessage: err.response.data,
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: false
@@ -341,7 +318,7 @@ class CampaignPage extends Component {
}
console.log(err.response)
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'tryAgain',
})
}
@@ -351,35 +328,29 @@ class CampaignPage extends Component {
this.setState({showCoinbaseModal: true});
}
- saveDonateToDb = async (value, decimals, transactionHash, chainId, coinAddress) => {
+ saveDonateToDb = async (transactionHash, chainId, coinAddress) => {
let accounts = this.state.accounts;
- if (window.blockChainOrt === "ethereum"){
- if(decimals === 18) {
- value = parseFloat(web3.utils.fromWei(value));
- } else {
- value = parseFloat(value/Math.pow(10, decimals));
- }
- }
- else if (window.blockChainOrt === "tron"){
- value = parseFloat(window.tronWeb.fromSun(value));
- }
let donateData
- if (window.blockChainOrt === "ethereum"){
+ if (this.blockChainOrt === "ethereum"){
donateData = {
campaignID : this.state.campaignId,
donatorID: accounts[0],
- raisedAmount: value,
+ raisedAmount: this.state.donationAmount,
+ tipAmount: this.state.tipAmount,
transactionHash: transactionHash,
chainId: chainId,
+ blockChainOrt: "Ethereum",
coinAddress: coinAddress
};
- } else if (window.blockChainOrt === "tron"){
+ } else if (this.blockChainOrt === "tron"){
donateData = {
campaignID : this.state.campaignId,
donatorID: window.tronAdapter.address,
- raisedAmount: value,
+ raisedAmount: this.state.donationAmount,
+ tipAmount: this.state.tipAmount,
transactionHash: transactionHash,
chainId: chainId,
+ blockChainOrt: "Tron",
coinAddress: coinAddress
};
}
@@ -391,44 +362,38 @@ class CampaignPage extends Component {
modalButtonMessage: 'returnHome',
modalButtonVariant: "#588157", waitToClose: false
});
- await this.updateRaisedAmount();
+ this.setState({raisedAmount: this.state.raisedAmount + this.state.donationAmount});
}
-
- handleDonateClick = async(chain_name, coin_address, blockChainOrt) =>{
- if(blockChainOrt === "ethereum"){
- window.blockChainOrt = "ethereum";
- if (this.state.campaign.new === false) await this.handleDonateOld(chain_name, coin_address);
- else await this.handleDonateNew(chain_name, coin_address);
+
+ handleDonateClick = async(wallet_ort, addres_base58, addres_hex, coin_addres, chain_name) =>{
+ if(wallet_ort === "Ethereum"){
+ this.blockChainOrt = "ethereum";
+ //if (this.state.campaign.new === false) await this.handleDonateOld(chain_name, addres_hex);
+ await this.handleDonateNew(chain_name, addres_hex);
}
- else if(blockChainOrt === "tron"){
- window.blockChainOrt = "tron";
- await this.handleDonateTron(chain_name, coin_address);
+ else if(wallet_ort === "Tron"){
+ this.blockChainOrt = "tron";
+ await this.handleDonateTron(chain_name, addres_base58, coin_addres);
}
}
- handleDonateTron = async (chainId, coinAddress) =>{
+ handleDonateTron = async (chainId, addres_base58, coinAddress) =>{
try{
await clearTronProvider();
await initTronadapter();
- await initTron(chainId, this);
- let TRC20Coin = (await import("../remote/"+ chainId + "/TRC20")).default;
- let HEOCampaign = (await import("../remote/"+ chainId + "/HEOCampaign")).default;
- let campaignAddress = this.state.campaign.addresses[chainId];
- let campaignInstance = await window.tronWeb.contract(HEOCampaign, window.tronWeb.address.fromHex(campaignAddress));
- var toDonate = window.tronWeb.toSun(this.state.donationAmount);
- var coinInstance = await window.tronWeb.contract(TRC20Coin, window.tronWeb.address.fromHex(coinAddress));
- var decimals = coinInstance.methods.decimals().call();
+ await initTron(chainId);
+ var toDonate = window.tronWeb.toSun(this.state.totalAmount);
+ var coinInstance = await window.tronWeb.contract(tron_abi, coinAddress);
ReactGA.event({
category: "donation",
action: "donate_button_click",
- value: parseInt(this.state.donationAmount), // optional, must be a number
+ value: parseInt(this.state.totalAmount), // optional, must be a number
nonInteraction: false
});
//check if donating to oneself
- let beneficiaryAdres = await campaignInstance.methods.beneficiary().call();
- if(window.tronWeb.address.toHex(window.tronAdapter.address).toLowerCase() === beneficiaryAdres.toLowerCase()) {
+ if(window.tronAdapter.address.toLowerCase() === addres_base58.toLowerCase()) {
this.setState({
- showModal: true, modalTitle: 'notAllowed',
+ showModal: true, modalTitle: 'notAllowed', goHome: false,
modalMessage: 'donateToYourSelf',
errorIcon: 'ExclamationTriangle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false
@@ -439,13 +404,13 @@ class CampaignPage extends Component {
nonInteraction: false
});
console.log("Tronadapter address" + window.tronAdapter.address);
- console.log("Beneficiary" + beneficiaryAdres);
return;
}
- let result = await coinInstance.methods.transfer(campaignAddress, toDonate)
+ let result = await coinInstance.methods.transfer(addres_base58, toDonate)
.send({from:window.tronAdapter.address,callValue:0,feeLimit:15000000000,shouldPollResponse:false});
+
this.setState({showModal:true,
- modalTitle: 'processingWait',
+ modalTitle: 'processingWait', goHome: false,
modalMessage: 'waitingForNetwork', errorIcon:'HourglassSplit',
modalButtonVariant: "gold", waitToClose: true});
let txnObject;
@@ -459,15 +424,16 @@ class CampaignPage extends Component {
}while(m !== 2);
if (txnObject.receipt.result === "SUCCESS"){
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false
});
- this.saveDonateToDb(toDonate,decimals, txnObject.txID, chainId, coinAddress);
+ this.saveDonateToDb(txnObject.id, chainId, coinAddress);
+
}else {
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false,
modalMessage: 'blockChainTransactionFailed'
@@ -481,7 +447,7 @@ class CampaignPage extends Component {
}
} catch (err) {
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false,
modalMessage: 'blockChainTransactionFailed'
@@ -525,7 +491,7 @@ class CampaignPage extends Component {
//check if donating to oneself
if(accounts[0].toLowerCase() === this.state.campaign.beneficiaryId.toLowerCase()) {
this.setState({
- showModal: true, modalTitle: 'notAllowed',
+ showModal: true, modalTitle: 'notAllowed', goHome: false,
modalMessage: 'donateToYourSelf',
errorIcon: 'ExclamationTriangle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false
@@ -568,7 +534,7 @@ class CampaignPage extends Component {
} catch (err) {
this.setState({
showModal: true, modalTitle: 'failed', modalMessage: 'blockChainTransactionFailed',
- errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
+ errorIcon: 'XCircle', modalButtonMessage: 'closeBtn', goHome: false,
modalButtonVariant: '#E63C36', waitToClose: false
});
console.log(err);
@@ -580,9 +546,8 @@ class CampaignPage extends Component {
).once('transactionHash', function(transactionHash) {
that.setState({modalMessage: "waitingForNetwork"})
});
- await this.updateRaisedAmount(accounts, campaignInstance, web3, 18);
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false
@@ -590,7 +555,7 @@ class CampaignPage extends Component {
} catch (err) {
this.setState({
showModal: true, modalTitle: 'failed', modalMessage: 'blockChainTransactionFailed',
- errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
+ errorIcon: 'XCircle', modalButtonMessage: 'closeBtn', goHome: false,
modalButtonVariant: '#E63C36', waitToClose: false
});
console.log("donateNative transaction failed");
@@ -602,7 +567,7 @@ class CampaignPage extends Component {
ERC20Coin = (await import("../remote/"+ chainId + "/ERC20")).default;
var coinInstance = new web3.eth.Contract(ERC20Coin, coinAddress);
this.setState({
- showModal: true, modalTitle: 'processingWait',
+ showModal: true, modalTitle: 'processingWait', goHome: false,
modalMessage: "approveSpend",
errorIcon: 'HourglassSplit', modalButtonVariant: "#E63C36", waitToClose: false,
modalButtonMessage: 'abortBtn',
@@ -648,7 +613,7 @@ class CampaignPage extends Component {
);
}).on('error', function(error) {
that.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false,
modalMessage: 'blockChainTransactionFailed'
@@ -702,7 +667,7 @@ class CampaignPage extends Component {
if(result.code) {
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false,
modalMessage: 'blockChainTransactionFailed'
@@ -716,9 +681,8 @@ class CampaignPage extends Component {
clearWeb3Provider(this);
return;
}
- await this.updateRaisedAmount(accounts, campaignInstance, web3, decimals);
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false
@@ -822,7 +786,7 @@ class CampaignPage extends Component {
{from:accounts[0], value:(""+toDonate)}
).once('transactionHash', function(transactionHash) {
that.setState({modalMessage: "waitingForNetwork"});
- that.saveDonateToDb(toDonate, 0, transactionHash, chainId, coinAddress);
+ that.saveDonateToDb(transactionHash, chainId, coinAddress);
web3.eth.getTransaction(transactionHash).then(
function(txnObject) {
if(txnObject) {
@@ -843,24 +807,16 @@ class CampaignPage extends Component {
});
console.log(err);
}
- } else {
+ } else {
try {
await campaignInstance.methods.donateNative().send(
{from:accounts[0], value:(""+toDonate)}
).once('transactionHash', function(transactionHash) {
that.setState({modalMessage: "waitingForNetwork"});
- let decimals = 0;
- coinInstance.methods.decimals().call({from:accounts[0]}, function(err, result) {
- if(err) {
- console.log(`Failed to fetch decimals from ${coinAddress} `);
- console.log(err);
- }
- else decimals = result;
- });
- that.saveDonateToDb(toDonate, decimals, transactionHash, chainId, coinAddress);
+ that.saveDonateToDb(transactionHash, chainId, coinAddress);
});
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false
@@ -868,7 +824,7 @@ class CampaignPage extends Component {
} catch (err) {
this.setState({
showModal: true, modalTitle: 'failed', modalMessage: 'blockChainTransactionFailed',
- errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
+ errorIcon: 'XCircle', modalButtonMessage: 'closeBtn', goHome: false,
modalButtonVariant: '#E63C36', waitToClose: false
});
console.log("donateNative transaction failed");
@@ -880,7 +836,7 @@ class CampaignPage extends Component {
ERC20Coin = (await import("../remote/"+ chainId + "/ERC20")).default;
this.setState({
- showModal: true, modalTitle: 'processingWait',
+ showModal: true, modalTitle: 'processingWait', goHome: false,
modalMessage: "approveSpend",
errorIcon: 'HourglassSplit', modalButtonVariant: "#E63C36", waitToClose: false,
modalButtonMessage: 'abortBtn',
@@ -914,7 +870,7 @@ class CampaignPage extends Component {
{from:accounts[0]}
).once('transactionHash', function(transactionHash) {
console.log(`Got donation trnasaction hash ${transactionHash}`);
- that.saveDonateToDb(toDonate,decimals, transactionHash, chainId, coinAddress);
+ that.saveDonateToDb(transactionHash, chainId, coinAddress);
ReactGA.event({
category: "donation",
action: "donation_hash",
@@ -939,7 +895,7 @@ class CampaignPage extends Component {
nonInteraction: false
});
that.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false,
modalMessage: 'blockChainTransactionFailed'
@@ -966,11 +922,11 @@ class CampaignPage extends Component {
).once('transactionHash', function(transactionHash) {
console.log(`transaction hash for donateERC20 ${transactionHash}`);
that.setState({modalMessage: "waitingForNetwork"});
- that.saveDonateToDb(toDonate,decimals, transactionHash, chainId, coinAddress);
+ that.saveDonateToDb(transactionHash, chainId, coinAddress);
});
if(result.code) {
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false,
modalMessage: 'blockChainTransactionFailed'
@@ -985,7 +941,7 @@ class CampaignPage extends Component {
return;
}
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false
@@ -995,7 +951,7 @@ class CampaignPage extends Component {
}
} catch (err) {
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false,
modalMessage: 'blockChainTransactionFailed'
@@ -1013,7 +969,7 @@ class CampaignPage extends Component {
} catch (err) {
console.log(err);
this.setState({
- showModal: true, modalTitle: 'failed',
+ showModal: true, modalTitle: 'failed', goHome: false,
errorIcon: 'XCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#E63C36', waitToClose: false,
modalMessage: 'blockChainConnectFailed'
@@ -1061,6 +1017,7 @@ class CampaignPage extends Component {
label: this.state.modalTitle, // optional, must be a number
nonInteraction: false
});
+ if(this.state.goHome) this.props.history.push('/');
}
}>
@@ -1173,10 +1130,14 @@ class CampaignPage extends Component {
}
}
}>USD }
-
- {this.state.chains_coins.map((item, i) =>
- this.handleDonateClick(item.chain, item.coin.address, item.blockChainOrt)}>{item.coin.name} ({item.chain_name })
+ {this.state.campaign_wallets.map((item, i) =>
+
+ this.handleDonateClick(item.wallet_ort, item.addres_base58, item.addres_hex,item.coin_addres,item.chainId)}>
+ {item.coin_name}
+
)}
+
+ Coinbase commerce
{
this.handleDonateCoinbaseCommerce();
@@ -1263,20 +1224,25 @@ class CampaignPage extends Component {
modalMessage: modalMessage
})
})
-
let campaign = await this.getCampaign(campaignId);
if(!campaign) {
this.props.history.push("/404");
return;
}
- let tipForHeo = 10;
+ this.state.campaign_wallets = campaign.campaign_wallets;
let result = await axios.post('/api/gettipforheo', {headers: {"Content-Type": "application/json"}});
if(result) {
- tipForHeo = Number(result.data);
+ this.state.tipForHeo = Number(result.data);
}
this.state.donationAmount = campaign.defaultDonationAmount ? campaign.defaultDonationAmount : 20;
- this.state.tipAmount = Math.max(1, parseInt(parseInt(this.state.donationAmount)/100 * tipForHeo));
+ this.state.tipAmount = Math.max(1, parseInt(parseInt(this.state.donationAmount)/100 * this.state.tipForHeo));
this.state.totalAmount = parseInt(campaign.defaultDonationAmount) + this.state.tipAmount;
+ let totalQuantity = campaign.totalQuantity? parseFloat(campaign.totalQuantity) : 0;
+ let raisedAmount = campaign.raisedAmount? parseFloat(campaign.raisedAmount) : 0;
+ let fiatDonations = campaign.fiatDonations ? parseFloat(campaign.fiatDonations) : 0;
+ let raisedOnCoinbase = campaign.raisedOnCoinbase ? parseFloat(campaign.raisedOnCoinbase) : 0;
+ raisedAmount = Math.round((raisedAmount + fiatDonations + raisedOnCoinbase + totalQuantity) * 100)/100;
+ this.state.raisedAmount = raisedAmount;
campaign.percentRaised = 100 * (this.state.raisedAmount)/campaign.maxAmount;
var contentState = {};
var lng
@@ -1308,7 +1274,6 @@ class CampaignPage extends Component {
chains.push(configChains[ch]);
}
}
-
let globals = config.get("GLOBALS");
globals.forEach(element => {
if(element._id === 'FIATPAYMENT') {
@@ -1349,6 +1314,7 @@ class CampaignPage extends Component {
dedupedCoinNames.push(coinName);
}
}
+
await axios.post('/api/getcoinslist')
.then(res => {
let chains_coins = [];
@@ -1384,7 +1350,6 @@ class CampaignPage extends Component {
campaign : campaign,
coins: dedupedCoinNames
});
- await this.updateRaisedAmount();
ReactGA.send({ hitType: "pageview", page: this.props.location.pathname });
const params = new Proxy(new URLSearchParams(window.location.search), {
get: (searchParams, prop) => searchParams.get(prop),
@@ -1393,7 +1358,7 @@ class CampaignPage extends Component {
if(params.fp) {
if(params.fp === 's') {
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouFiatDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false, tryAgainCC: false, ccinfo: {}
@@ -1401,7 +1366,7 @@ class CampaignPage extends Component {
} else if(params.fp === 'f') {
this.setState({
showModal: true, modalTitle: 'failed', modalMessage: 'failed3ds',
- errorIcon: 'XCircle', modalButtonMessage: 'tryAgain',
+ errorIcon: 'XCircle', modalButtonMessage: 'tryAgain', goHome: false,
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: true,
donationAmount: params.am
});
@@ -1409,13 +1374,13 @@ class CampaignPage extends Component {
if(params.state ==='declined' || params.state==='cancelled') {
this.setState({
showModal: true, modalTitle: 'failed', modalMessage: 'cardPaymentDeclined',
- errorIcon: 'XCircle', modalButtonMessage: 'tryAgain',
+ errorIcon: 'XCircle', modalButtonMessage: 'tryAgain', goHome: false,
modalButtonVariant: '#E63C36', waitToClose: false, tryAgainCC: false,
donationAmount: params.am, ccinfo: {}
});
} else {
this.setState({
- showModal: true, modalTitle: 'complete',
+ showModal: true, modalTitle: 'complete', goHome: true,
modalMessage: 'thankYouFiatDonation',
errorIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
modalButtonVariant: '#588157', waitToClose: false, tryAgainCC: false, ccinfo: {}
@@ -1462,10 +1427,6 @@ function findLinkEntities(contentBlock, callback, contentState) {
function checkDonationTransaction(txnObject, decimals, chainId, that) {
if(txnObject.blockNumber) {
console.log(`Donation transaction successful in block ${txnObject.blockNumber}`);
-
- if(decimals > 0) {
- that.updateRaisedAmount();
- }
that.setState({
showModal: true, modalTitle: 'complete',
modalMessage: 'thankYouDonation',
diff --git a/src/components/CreateCampaign.js b/src/components/CreateCampaign.js
index addd10c..c83977d 100644
--- a/src/components/CreateCampaign.js
+++ b/src/components/CreateCampaign.js
@@ -8,7 +8,7 @@ import uuid from 'react-uuid';
import axios from 'axios';
import { Trans } from 'react-i18next';
import i18n from '../util/i18n';
-import {checkEmail,isValidUrl,blockchains} from '../util/Utilities';
+import {checkEmail,isValidUrl} from '../util/Utilities';
import {getEditorStateEn, getEditorStateRu, TextEditorEn, TextEditorRu, setEditorStateEn, setEditorStateRu} from '../components/TextEditor';
import { ChevronLeft, CheckCircle, ExclamationTriangle, HourglassSplit, XCircle } from 'react-bootstrap-icons';
import '../css/createCampaign.css';
@@ -69,10 +69,19 @@ class CreateCampaign extends React.Component {
countryCode:"",
number:"",
website:"",
+ badWebsite:false,
+ badKey:false,
+ badEmail:false,
+ noCountryCode:false,
+ notValidAddr:false,
+ noCoverImage:false,
+ longDescRequired:false,
+ longDescEnIncludRu:false,
telegram:"",
- blockchain:"",
+ blockchain:"Tron",
wallet:""
}
+ this.mistake = false;
};
onSubmit = (e) => {
@@ -102,15 +111,12 @@ class CreateCampaign extends React.Component {
help_value += e.target.value[i];
}
let key = help_value.toLowerCase().replaceAll(" ", "-");
- this.setState({key: key});
+ if((key !== "")&&(this.state.key === "")) this.setState({key: key});
}
- }
- else if(e.target.name === 'fiatPayments')
- this.setState({fiatPayments: e.target.checked});
- else if(e.target.name === 'countryCode'){
- this.setState({ countryCode: e.target.value });
- }
- else if(e.target.name === 'campaignURL'){
+ }
+ else if(e.target.name === 'fiatPayments') this.setState({fiatPayments: e.target.checked});
+ else if(e.target.name === 'countryCode') this.setState({ countryCode: e.target.value });
+ else if(e.target.name === 'campaignURL'){
help_value = '';
for(i = 0; i < e.target.value.length; i++){
if ((/^[-A-Za-z0-9]*$/.test(e.target.value[i]) === true)||(e.target.value[i] === ' '))
@@ -118,8 +124,8 @@ class CreateCampaign extends React.Component {
}
let key = help_value.toLowerCase().replaceAll(" ", "-");
this.setState({key: key});
- }
- else if(e.target.name === 'number'){
+ }
+ else if(e.target.name === 'number'){
help_value = '';
for(let i = 0; i < e.target.value.length; i++){
if ((/^[-0-9]*$/.test(e.target.value[i]) === true)||(e.target.value[i] === ' '))
@@ -127,8 +133,8 @@ class CreateCampaign extends React.Component {
}
e.target.value = help_value;
this.setState({ [e.target.name]: e.target.value });
- }
- else if(e.target.name === 'wallet'){
+ }
+ else if(e.target.name === 'wallet'){
help_value = '';
for(i = 0; i < e.target.value.length; i++){
if (/^[A-Za-z0-9]*$/.test(e.target.value[i]) === true)
@@ -148,60 +154,24 @@ class CreateCampaign extends React.Component {
this.setState({qrCodeImageFile:e.target.files[0], qrCodeImageURL: URL.createObjectURL(e.target.files[0])});
};
- async handleClick (event) {
+ async handleClick () {
let imgID = uuid();
let qrImgID = uuid();
let result;
+ this.mistake = false;
try {
- if(!this.state.orgEn) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'orgRequiredEn', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if(!this.state.cn) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'cnRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if(this.state.website){
+ if(this.state.orgEn.trim() === "") this.mistake = true;
+ if(this.state.cn.trim() === "") this.mistake = true;
+ if(this.state.website.trim() !== ""){
result = await isValidUrl(this.state.website);
if(!result){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'badWebsite', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
+ this.setState({badWebsite:true});
+ this.mistake = true;
}
}
- if(!this.state.titleEn) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'titleRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if(!this.state.descriptionEn) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'shortDescRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if(!this.state.key) {
+ if(this.state.titleEn.trim() === "") this.mistake = true;
+ if(this.state.descriptionEn.trim() === "") this.mistake = true;
+ if(this.state.key.trim() === ""){
this.setState(
{showModal:true, modalTitle: 'requiredFieldsTitle',
modalMessage: 'campaignURLRequired', modalIcon: 'ExclamationTriangle',
@@ -210,7 +180,7 @@ class CreateCampaign extends React.Component {
});
return false;
}
- if(this.state.key){
+ if(this.state.key.trim() !== ""){
let data = {KEY : this.state.key};
let res = await axios.post('/api/campaign/checkKey', data,
{headers: {"Content-Type": "application/json"}});
@@ -222,104 +192,55 @@ class CreateCampaign extends React.Component {
modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
});
- return false;
+ return false;
}
}
- if(!this.state.email) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'emailRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- result = await checkEmail(this.state.email);
- if(!result) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'emailFaulty', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if ((this.state.number)&&(this.state.countryCode.trim()==="")){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'countryCodeRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if (!this.state.blockchain){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'selectBlockchain', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
+ if(this.state.email.trim() === "")this.mistake = true;
+ if(this.state.email.trim() !== "" ){
+ result = await checkEmail(this.state.email);
+ if(!result){
+ this.setState({badEmail:true});
+ this.mistake = true;
+ }
}
- if (!this.state.wallet){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'enterWallet', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
+ if ((this.state.number.trim() !== "")&&(this.state.countryCode.trim()==="")){
+ this.setState({noCountryCode:true});
+ this.mistake = true;
}
- if (this.state.blockchain === "Ethereum"){
+ if (this.state.wallet.trim() === "") this.mistake = true;
+ if ((this.state.blockchain === "Ethereum")&&(this.state.wallet.trim() !== "")){
if((this.state.wallet.substring(0,2) !== "0x")||(this.state.wallet.length !== 42))
{
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'notValidAddr', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
+ this.setState({notValidAddr:true});
+ this.mistake = true;
}
}
- if (this.state.blockchain === "Tron"){
+ if ((this.state.blockchain === "Tron")&&(this.state.wallet.trim() !== "")){
if((this.state.wallet.substring(0,1) !== "T")||(this.state.wallet.length !== 34))
{
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'notValidAddr', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
+ this.setState({notValidAddr:true});
+ this.mistake = true;
}
}
let n = 0;
let EditorStateEn = await getEditorStateEn();
+ if(!EditorStateEn){
+ this.setState({longDescRequired:true});
+ this.mistake = true;
+ }
if (EditorStateEn){
for (let i = 0; i < EditorStateEn.blocks.length; i++){
n = n + EditorStateEn.blocks[i].text.length;
}
if (n < 3) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'longDescRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
+ this.setState({longDescRequired:true});
+ this.mistake = true;
}
for (let i = 0; i < EditorStateEn.blocks.length; i++){
for(let j = 0; j < getEditorStateEn().blocks[i].text.length; j++){
if (/^[А-Яа-я]*$/.test(getEditorStateEn().blocks[i].text[j]) === true){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'longDescEnIncludRu', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
+ this.setState({longDescEnIncludRu:true});
+ this.mistake = true;
}
}
}
@@ -327,31 +248,32 @@ class CreateCampaign extends React.Component {
let qrImgUrl = '';
let imgUrl = await this.uploadImageS3('main', imgID);
if (imgUrl) this.setState({imgUrl:imgUrl});
+ else{
+ this.setState({noCoverImage:true});
+ this.mistake = true;
+ }
if(this.state.qrCodeImageURL) {
qrImgUrl = await this.uploadImageS3('qrCode', qrImgID);
- if(qrImgUrl) this.setState({imgUrl:imgUrl});
- }
- if(imgUrl) {
- let campaignData = {mainImageURL:imgUrl,
- qrCodeImageURL:qrImgUrl}
- await this.addCampaignToDb(campaignData);
+ if(qrImgUrl) this.setState({qrImgUrl:qrImgUrl});
}
+ if(this.mistake === true) this.setState({showModalМistakes:true})
+ else await this.addCampaignToDb();
} catch(error) {
console.log(error);
}
}
- async addCampaignToDb(campaignData) {
+ async addCampaignToDb() {
try {
+ let campaignData = {};
+ campaignData.qrCodeImageUR = this.state.qrImgUrl;
+ campaignData.mainImageURL = this.state.imgUrl;
campaignData.key = this.state.key;
campaignData.id = uuid();
campaignData.title = {};
campaignData.title["default"] = this.state.titleEn;
campaignData.title["en"] = this.state.titleEn;
campaignData.title["ru"] = this.state.titleRu;
- campaignData.addresses = {};
- campaignData.accounts = {};
- campaignData.coins = {};
campaignData.description = {};
campaignData.description["default"] = this.state.descriptionEn;
campaignData.description["en"] = this.state.descriptionEn;
@@ -384,11 +306,14 @@ class CreateCampaign extends React.Component {
campaignData.website = this.state.website;
campaignData.payout_chain = this.state.blockchain;
campaignData.payout_address = this.state.wallet;
+ if(this.mistake === true) campaignData.complete = false;
+ else campaignData.complete = true;
let res = await axios.post('/api/campaign/add', {mydata : campaignData},
{headers: {"Content-Type": "application/json"}});
if (res.data === 'success'){
+ if(this.mistake === true) {
this.setState({showModal:true, goHome: true,
- modalMessage: 'campaignwWillBePublished',
+ modalMessage: 'campaignSavedWithErrors',
modalTitle: 'success',
modalIcon: 'CheckCircle',
modalButtonMessage: 'ok',
@@ -396,6 +321,18 @@ class CreateCampaign extends React.Component {
campaignID: campaignData.id,
campaignData:campaignData
});
+ }
+ else {
+ this.setState({showModal:true, goHome: true,
+ modalMessage: 'campaignSaved',
+ modalTitle: 'success',
+ modalIcon: 'CheckCircle',
+ modalButtonMessage: 'ok',
+ modalButtonVariant: "#588157", waitToClose: false, isInDB: true,
+ campaignID: campaignData.id,
+ campaignData:campaignData
+ });
+ }
}
else{
this.setState({showModal: true, goHome: false,
@@ -425,12 +362,7 @@ class CreateCampaign extends React.Component {
modalButtonVariant: "gold", waitToClose: true
});
if(type === 'main' && (!this.state.mainImageFile || !this.state.mainImageFile.type)) {
- this.setState(
- {showModal:true, modalTitle: 'coverImageRequiredTitle',
- modalMessage: 'coverImageRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
+ this.setState({noCoverImage:true, showModal:false});
return false;
}
let fileType;
@@ -456,12 +388,7 @@ class CreateCampaign extends React.Component {
this.setState({showModal:false});
return (res.data);
} else {
- console.log('error uploading image: res.data is empty');
- this.setState({showModal: true, goHome: false,
- modalTitle: 'imageUploadFailed',
- modalMessage: 'technicalDifficulties',
- modalIcon: 'XCircle', modalButtonMessage: 'closeBtn',
- modalButtonVariant: "#E63C36", waitToClose: false});
+ this.setState({noCoverImage:true, showModal:false});
return false;
}
} catch(err) {
@@ -493,6 +420,55 @@ class CreateCampaign extends React.Component {
render() {
return (
+
{}} className='myModal' centered>
+
+
+
+
+
+
+
+
+
+ {(this.state.orgEn === "")&&
}
+ {(this.state.cn === "")&&
}
+ {(this.state.badWebsite === true)&&
}
+ {(this.state.titleEn === "")&&
}
+ {(this.state.descriptionEn === "")&&
}
+ {(this.state.email === "")&&
}
+ {(this.state.badEmail === true)&&
}
+ {(this.state.noCountryCode === true)&&
}
+ {(this.state.wallet === "")&&
}
+ {(this.state.notValidAddr === true)&&
}
+ {(this.state.longDescRequired === true)&&
}
+ {(this.state.longDescEnIncludRu === true)&&
}
+ {(this.state.noCoverImage=== true)&&
}
+
+
+
+
+
+
+
+
+
+
+
+
{}} className='myModal' centered>
@@ -753,13 +729,9 @@ class CreateCampaign extends React.Component {
-
-
-
- {blockchains.map((data) =>
-
- )}
-
+
+
+
diff --git a/src/components/EditCampaign.js b/src/components/EditCampaign.js
index 02c2dfa..cc06d5a 100644
--- a/src/components/EditCampaign.js
+++ b/src/components/EditCampaign.js
@@ -1,17 +1,18 @@
import React from 'react';
import countries from '../countries';
-import {Container, Form, Col, Button, DropdownButton, Dropdown, Image, Modal, Row} from 'react-bootstrap';
+import {Container, Form, Col, Button, Image, Modal, Row} from 'react-bootstrap';
import ReactPlayer from 'react-player';
import {getCountryCodeForRegionCode} from 'awesome-phonenumber';
import config from "react-global-configuration";
import axios from 'axios';
import { Trans } from 'react-i18next';
+import uuid from 'react-uuid';
import i18n from '../util/i18n';
import { ChevronLeft, CheckCircle, ExclamationTriangle, HourglassSplit, XCircle } from 'react-bootstrap-icons';
import { Link } from 'react-router-dom';
import { getEditorStateEn, getEditorStateRu, TextEditorEn, TextEditorRu, setEditorStateEn, setEditorStateRu, editorStateHasChangedRu,
editorStateHasChangedEn } from '../components/TextEditor';
-import { initWeb3, checkAuth, initWeb3Modal, initTronadapter, checkAuthTron, initTron, checkEmail, isValidUrl,blockchains} from '../util/Utilities';
+import { initWeb3Modal, initTronadapter, checkEmail, isValidUrl, countWordsString} from '../util/Utilities';
import '../css/createCampaign.css';
import '../css/modal.css';
import ReactGA from "react-ga4";
@@ -65,11 +66,14 @@ class EditCampaign extends React.Component {
key: "",
chainId:"",
tronChainId:"",
- isInTron:false,
- isInEtherium:false,
- resultEtherium : true,
- resultTron: true,
- active:false,
+ badWebsite:false,
+ badKey:false,
+ badEmail:false,
+ noCountryCode:false,
+ notValidAddr:false,
+ noCoverImage:false,
+ longDescRequired:false,
+ longDescEnIncludRu:false,
email:"",
countryCode:"",
number:"",
@@ -131,219 +135,107 @@ class EditCampaign extends React.Component {
}
handleClick = async () => {
+ let imgID;
+ if(this.state.imgID === "") imgID = this.state.imgID
+ else imgID = uuid();
let result;
- if (this.state.maxAmount_old !== this.state.maxAmount){
- if ((window.ethereum)&&(this.state.isInEtherium)){
- await initWeb3Modal(this.state.chainId, this);
- await initWeb3(this.state.chainId, this);
- // is the user logged in?
- if(!this.state.isLoggedIn) {
- await checkAuth(this.state.chainId, this);
+ this.mistake = false;
+ try{
+ if(this.state.orgEn.trim() === "") this.mistake = true;
+ if(this.state.cn.trim() === "") this.mistake = true;
+ if(this.state.website.trim() !== ""){
+ result = await isValidUrl(this.state.website);
+ if(!result){
+ this.setState({badWebsite:true});
+ this.mistake = true;
+ }
+ }
+ if(this.state.titleEn.trim() === "") this.mistake = true;
+ if(this.state.descriptionEn.trim() === "") this.mistake = true;
+ if(this.state.email.trim() === "")this.mistake = true;
+ if(this.state.email.trim() !== "" ){
+ result = await checkEmail(this.state.email);
+ if(!result){
+ this.setState({badEmail:true});
+ this.mistake = true;
+ }
}
- }
- if ((window.tron)&&(this.state.isInTron)){
- await initTronadapter();
- await initTron(this.state.tronChainId, this);
- // is the user logged in?
- if(!this.state.isLoggedInTron) {
- await checkAuthTron(this.state.tronChainId, this);
+ if ((this.state.number.trim() !== "")&&(this.state.countryCode.trim()==="")){
+ this.setState({noCountryCode:true});
+ this.mistake = true;
}
- }
- }
-
- this.setState({resultEtherium : true, resultTron: true});
- //check if this campaign belongs to this user
- if(editorStateHasChangedEn()|| editorStateHasChangedRu()) {
- this.state.updateMeta = true;
- }
- if(!this.state.orgEn) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'orgRequiredEn', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if(!this.state.cn) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'cnRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if(this.state.website){
- result = await isValidUrl(this.state.website);
- if(!result){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'badWebsite', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
+ if (this.state.wallet.trim() === "") this.mistake = true;
+ if ((this.state.blockchain === "Ethereum")&&(this.state.wallet.trim() !== "")){
+ if((this.state.wallet.substring(0,2) !== "0x")||(this.state.wallet.length !== 42))
+ {
+ this.setState({notValidAddr:true});
+ this.mistake = true;
+ }
}
- }
- if(!this.state.titleEn) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'titleRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if(!this.state.email) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'emailRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- result = await checkEmail(this.state.email);
- if(!result) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'emailFaulty', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if ((this.state.number)&&(this.state.countryCode.trim()==="")){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'countryCodeRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if(!this.state.descriptionEn) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'shortDescRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if (!this.state.blockchain){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'selectBlockchain', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if (!this.state.wallet){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'enterWallet', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- if (this.state.blockchain === "Ethereum"){
- if((this.state.wallet.substring(0,2) !== "0x")||(this.state.wallet.length !== 42))
- {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'notValidAddr', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- }
- if (this.state.blockchain === "Tron"){
- if((this.state.wallet.substring(0,1) !== "T")||(this.state.wallet.length !== 34))
- {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'notValidAddr', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- }
- let n = 0;
- let EditorStateEn = await getEditorStateEn();
- if (EditorStateEn){
- for (let i = 0; i < EditorStateEn.blocks.length; i++){
- n = n + EditorStateEn.blocks[i].text.length;
- }
- if (n < 3) {
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'longDescRequired', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- for (let i = 0; i < EditorStateEn.blocks.length; i++){
- for(let j = 0; j < EditorStateEn.blocks[i].text.length; j++){
- if (/^[А-Яа-я]*$/.test(EditorStateEn.blocks[i].text[j]) === true){
- this.setState(
- {showModal:true, modalTitle: 'requiredFieldsTitle',
- modalMessage: 'longDescEnIncludRu', modalIcon: 'ExclamationTriangle',
- waitToClose: false,
- modalButtonMessage: 'closeBtn', modalButtonVariant: '#E63C36'
- });
- return false;
- }
- }
- }
- }
-
- this.setState({showModal:true, modalTitle: 'processingWait',
- modalMessage: 'waitingForNetwork',
- modalIcon:'HourglassSplit',
- modalButtonVariant: "gold", waitToClose: true});
- var newImgUrl = this.state.mainImageURL;
- if(this.state.updateImage) {
- newImgUrl = await this.uploadImageS3('main');
- if(!newImgUrl) {
- this.setState({showModal:true,
- modalTitle: 'imageUploadFailed',
- modalMessage: 'technicalDifficulties',
- modalIcon:'XCircle', modalButtonMessage: 'returnHome',
- modalButtonVariant: "#E63C36", waitToClose: false});
- return;
+ if ((this.state.blockchain === "Tron")&&(this.state.wallet.trim() !== "")){
+ if((this.state.wallet.substring(0,1) !== "T")||(this.state.wallet.length !== 34))
+ {
+ this.setState({notValidAddr:true});
+ this.mistake = true;
+ }
}
- }
- //updating existing HEOCampaign
- if(this.state.updateMeta){
- if(!(await this.updateCampaign())) {
- this.setState({showModal : true,
- modalTitle: 'updatingAmountFailed',
- modalMessage: this.state.currentError,
- modalIcon:'XCircle', modalButtonMessage: 'closeBtn',
- modalButtonVariant: "#E63C36", waitToClose: false});
- return;
+ let n = 0;
+ let EditorStateEn = await getEditorStateEn();
+ if(!EditorStateEn){
+ this.setState({longDescRequired:true});
+ this.mistake = true;
+ }
+ if (EditorStateEn){
+ for (let i = 0; i < EditorStateEn.blocks.length; i++){
+ n = n + countWordsString(EditorStateEn.blocks[i].text);
+ }
+ if (n < 3) {
+ this.setState({longDescRequired:true});
+ this.mistake = true;
+ }
+ for (let i = 0; i < EditorStateEn.blocks.length; i++){
+ for(let j = 0; j < getEditorStateEn().blocks[i].text.length; j++){
+ if (/^[А-Яа-я]*$/.test(getEditorStateEn().blocks[i].text[j]) === true){
+ this.setState({longDescEnIncludRu:true});
+ this.mistake = true;
+ }
+ }
+ }
+ }
+ var newImgUrl = this.state.mainImageURL;
+ if(this.state.updateImage) {
+ newImgUrl = await this.uploadImageS3('main', imgID);
+ if(!newImgUrl) {
+ this.setState({noCoverImage:true});
+ this.mistake = true;
+ }
+ else this.setState({mainImageURL: newImgUrl});
+ }
+ else if(this.state.mainImageURL === "") {
+ this.setState({noCoverImage:true});
+ this.mistake = true;
+
}
+
+ if(this.mistake === true) this.setState({showModalМistakes:true})
+ else{
+ result = await this.updateCampaign();
+ if (result === false)
+ this.setState({showModal : true,
+ modalTitle: 'failed',
+ modalMessage: 'errorWritingCampaignToDB',
+ modalIcon:'XCircle', modalButtonMessage: 'closeBtn',
+ modalButtonVariant: "#E63C36", waitToClose: false});
+ else this.setState({
+ showModal: true, modalTitle: 'complete', goHome: true,
+ modalMessage: 'updateSuccessfull',
+ modalIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
+ modalButtonVariant: '#588157', waitToClose: false
+ });
+ }
+ } catch(error) {
+ console.log(error);
}
- result = await this.updateCampaign();
- if (result === false)
- this.setState({showModal : true,
- modalTitle: 'failed',
- modalMessage: 'errorWritingCampaignToDB',
- modalIcon:'XCircle', modalButtonMessage: 'closeBtn',
- modalButtonVariant: "#E63C36", waitToClose: false});
- else this.setState({
- showModal: true, modalTitle: 'complete', goHome: true,
- modalMessage: 'updateSuccessfull',
- modalIcon: 'CheckCircle', modalButtonMessage: 'closeBtn',
- modalButtonVariant: '#588157', waitToClose: false
- });
}
async updateCampaign() {
@@ -386,15 +278,11 @@ class EditCampaign extends React.Component {
data.org["en"] = this.state.orgEn;
data.org["default"] = this.state.orgEn;
data.org["ru"] = this.state.orgRu;
- data.addresses = this.state.addresses;
- data.accounts = this.state.line_accounts;
data.payout_chain = this.state.blockchain;
data.payout_address = this.state.wallet;
- console.log(`Updating title to`);
- console.log(data.title);
- console.log(`Updating org to`);
- console.log(data.org);
- let dataForDB = {address: this.state.campaignId, dataToUpdate: data};
+ if(this.mistake === true) data.complete = false;
+ else data.complete = true;
+ let dataForDB = {address: this.state.campaignId, dataToUpdate: data};
try {
let res = await axios.post('/api/campaign/update', {mydata : dataForDB},
{headers: {"Content-Type": "application/json"}});
@@ -417,34 +305,63 @@ class EditCampaign extends React.Component {
}
}
- async uploadImageS3(type) {
- this.setState({showModal:true, modalTitle: 'processingWait',
- modalMessage: 'uploadingImageWait', modalIcon:'HourglassSplit',
- modalButtonVariant: "gold", waitToClose: true});
- let imgID = this.state.imgID;
+ async uploadImageS3 (type, imgID) {
+ this.setState(
+ {showModal:true, modalTitle: 'processingWait',
+ modalMessage: 'uploadingImageWait', modalIcon: 'HourglassSplit',
+ modalButtonVariant: "gold", waitToClose: true
+ });
+ if(type === 'main' && (!this.state.mainImageFile || !this.state.mainImageFile.type)) {
+ this.setState({noCoverImage:true, showModal:false});
+ return false;
+ }
+ let fileType;
const formData = new FormData();
if(type === 'main') {
- this.setState({ imageFileName : imgID,});
- let fileType = this.state.mainImageFile.type.split("/")[1];
+ fileType = this.state.mainImageFile.type.split("/")[1];
formData.append(
"myFile",
this.state.mainImageFile,
`${imgID}.${fileType}`,
);
+ } else if(type === 'qrCode') {
+ fileType = this.state.qrCodeImageFile.type.split("/")[1];
+ formData.append(
+ "myFile",
+ this.state.qrCodeImageFile,
+ `${imgID}.${fileType}`,
+ );
}
try {
let res = await axios.post('/api/uploadimage', formData);
- if(type === 'main') {
- this.setState({showModal: false, mainImageURL: res.data});
+ if((res)&&(res.data)) {
+ this.setState({showModal:false});
+ return (res.data);
+ } else {
+ this.setState({noCoverImage:true, showModal:false});
+ return false;
}
- return res.data;
- } catch (err) {
- if(err.response) {
- this.setState({currentError : 'technicalDifficulties'});
+ } catch(err) {
+ if (err.response) {
+ console.log('response error in uploading main image- ' + err.response.status);
+ this.setState({showModal: true, goHome: false,
+ modalTitle: 'imageUploadFailed',
+ modalMessage: 'technicalDifficulties',
+ modalIcon: 'XCircle', modalButtonMessage: 'returnHome',
+ modalButtonVariant: "#E63C36", waitToClose: false});
} else if (err.request) {
- this.setState({currentError : 'checkYourConnection'});
+ console.log('No response in uploading main image' + err.message);
+ this.setState({showModal: true, goHome: false,
+ modalTitle: 'imageUploadFailed',
+ modalMessage: 'checkYourConnection',
+ modalIcon: 'XCircle', modalButtonMessage: 'returnHome',
+ modalButtonVariant: "#E63C36", waitToClose: false});
} else {
- this.setState({currentError : ''});
+ console.log('error uploading image ' + err.message);
+ this.setState({showModal: true, goHome: false,
+ modalTitle: 'imageUploadFailed',
+ modalIcon: 'XCircle', modalButtonMessage: 'returnHome',
+ modalButtonVariant: "#E63C36", waitToClose: false});
}
return false;
}
@@ -453,6 +370,66 @@ class EditCampaign extends React.Component {
render() {
return (
+
{}} className='myModal' centered>
+
+
+
+
+
+
+
+
+
+ {(this.state.orgEn === "")&&
}
+ {(this.state.cn === "")&&
}
+ {(this.state.badWebsite === true)&&
}
+ {(this.state.titleEn === "")&&
}
+ {(this.state.descriptionEn === "")&&
}
+ {(this.state.email === "")&&
}
+ {(this.state.badEmail === true)&&
}
+ {(this.state.noCountryCode === true)&&
}
+ {(this.state.wallet === "")&&
}
+ {(this.state.notValidAddr === true)&&
}
+ {(this.state.longDescRequired === true)&&
}
+ {(this.state.longDescEnIncludRu === true)&&
}
+ {(this.state.noCoverImage=== true)&&
}
+
+
+
+
+
+
+
+
+
+
+
+
{}} className='myModal' centered>
{this.state.modalIcon === 'CheckCircle' && }
@@ -681,12 +658,8 @@ class EditCampaign extends React.Component {
-
-
- {blockchains.map((data) =>
-
- )}
-
+
-
-
- {this.state.addresses[this.state.chainId] &&
-
- }
-
-
- {this.state.addresses[this.state.tronChainId] &&
-
- }
-
-
-
-
-
-
- {(((!this.state.addresses[this.state.tronChainId])||(!this.state.addresses[this.state.chainId]))&&(window.ethereum||window.tron)&&(this.state.active)) &&
-
- {(!this.state.addresses[this.state.chainId] && window.ethereum)&& {
- await this.saveToEtherium(true);
- }} >Etherium}
- {(!this.state.addresses[this.state.tronChainId] && window.tron)&& {
- await this.savetoTron(true);
- }}>Tron}
- }
-
+
+
@@ -871,10 +818,6 @@ class EditCampaign extends React.Component {
this.setState({website : dbCampaignObj.website});
if (dbCampaignObj.telegram)
this.setState({telegram : dbCampaignObj.telegram});
- console.log(`Set title to`);
- console.log(this.state.ogTitle);
- console.log(`Set org to`);
- console.log(this.state.ogOrg);
}
}
diff --git a/src/components/TRC20.js b/src/components/TRC20.js
new file mode 100644
index 0000000..14494cf
--- /dev/null
+++ b/src/components/TRC20.js
@@ -0,0 +1,3 @@
+const abi = [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_upgradedAddress","type":"address"}],"name":"deprecate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_value","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"deprecated","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_evilUser","type":"address"}],"name":"addBlackList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_from","type":"address"},{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"upgradedAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maximumFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"_totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_maker","type":"address"}],"name":"getBlackListStatus","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"_value","type":"uint256"}],"name":"calcFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_to","type":"address"},{"name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"who","type":"address"}],"name":"oldBalanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newBasisPoints","type":"uint256"},{"name":"newMaxFee","type":"uint256"}],"name":"setParams","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"issue","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_spender","type":"address"},{"name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount","type":"uint256"}],"name":"redeem","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"_owner","type":"address"},{"name":"_spender","type":"address"}],"name":"allowance","outputs":[{"name":"remaining","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"basisPointsRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"isBlackListed","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_clearedUser","type":"address"}],"name":"removeBlackList","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_UINT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"_blackListedUser","type":"address"}],"name":"destroyBlackFunds","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[{"name":"_initialSupply","type":"uint256"},{"name":"_name","type":"string"},{"name":"_symbol","type":"string"},{"name":"_decimals","type":"uint8"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_blackListedUser","type":"address"},{"indexed":false,"name":"_balance","type":"uint256"}],"name":"DestroyedBlackFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Issue","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"amount","type":"uint256"}],"name":"Redeem","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"newAddress","type":"address"}],"name":"Deprecate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_user","type":"address"}],"name":"AddedBlackList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"_user","type":"address"}],"name":"RemovedBlackList","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"feeBasisPoints","type":"uint256"},{"indexed":false,"name":"maxFee","type":"uint256"}],"name":"Params","type":"event"},{"anonymous":false,"inputs":[],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"previousOwner","type":"address"},{"indexed":true,"name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"}];
+
+export default abi;
diff --git a/src/components/TextEditor.js b/src/components/TextEditor.js
index 0a0d93b..b82f3aa 100644
--- a/src/components/TextEditor.js
+++ b/src/components/TextEditor.js
@@ -423,6 +423,7 @@ class TextEditorEn extends TextEditor{
componentDidMount() {
if(STOREDSTATEEN.length) {
this.setState({editorState : EditorState.createWithContent(STOREDSTATEEN, this.createDecorator())});
+
} else {
this.setState({editorState : EditorState.createEmpty(this.createDecorator())});
}
@@ -504,6 +505,8 @@ class TextEditorRu extends TextEditor{
componentDidMount() {
if(STOREDSTATERU.length) {
this.setState({editorState : EditorState.createWithContent(STOREDSTATERU, this.createDecorator())});
+ DESCRIPTIONRAWRU = convertToRaw(this.state.editorState.getCurrentContent());
+ STATEHASCHANGEDRU = true;
} else {
this.setState({editorState : EditorState.createEmpty(this.createDecorator())});
}
@@ -568,6 +571,7 @@ class TextEditorRu extends TextEditor{
function setEditorState(storedState, hasContent) {
if(hasContent) {
+
const contentState = convertFromRaw(storedState);
STOREDSTATE = contentState;
} else {
@@ -577,6 +581,7 @@ class TextEditorRu extends TextEditor{
function setEditorStateEn(storedState, hasContent) {
if(hasContent) {
+ DESCRIPTIONRAWEN = storedState;
const contentState = convertFromRaw(storedState);
STOREDSTATEEN = contentState;
} else {
diff --git a/src/components/UserCampaigns.js b/src/components/UserCampaigns.js
index 4a783ed..895bda0 100644
--- a/src/components/UserCampaigns.js
+++ b/src/components/UserCampaigns.js
@@ -349,9 +349,6 @@ class UserCampaigns extends Component {
- {item.new &&
-
- }
diff --git a/src/lang/translationEN.json b/src/lang/translationEN.json
index cf0affb..5ce952d 100644
--- a/src/lang/translationEN.json
+++ b/src/lang/translationEN.json
@@ -62,7 +62,7 @@
"campaignDescription": "Campaign description",
"createCampaignBtn": "CREATE CAMPAIGN",
"noUserCampaigns": "You did not create any campaigns yet. Click <1>here1> to create your first campaign",
- "saveCampaignBtn" : "SAVE CAMPAIGN",
+ "saveCampaignBtn" : "Save campaign",
"complete" : "Complete!",
"updateSuccessfull" : "Updated Campaign information successfully",
"closeBtn" : "Close",
@@ -241,6 +241,13 @@
"campaignURL":"Campaign URL",
"campaignURLPlaceHolder":"Symbols which will appear in campaign’s address after https://app.heo.finance/campaign/",
"campaignURLBad":"This campaign URL already exists in the database, enter another",
- "countryCodeRequired": "Please select the country code for the tefon number"
+ "countryCodeRequired": "Please select the country code for the tefon number",
+ "notValidAddr":"Not valid wallet address",
+ "blockchain":"Blockchain",
+ "wallet": "Wallet address",
+ "payout":"Payout address",
+ "enterWallet":"Please enter wallet address",
+ "campaignSaved":"Campaign saved to database",
+ "campaignSavedWithErrors":"Campaign saved in database with errors"
}
diff --git a/src/lang/translationRU.json b/src/lang/translationRU.json
index c831ad2..bd15132 100644
--- a/src/lang/translationRU.json
+++ b/src/lang/translationRU.json
@@ -58,7 +58,7 @@
"campaignDescription": "Описание кампании",
"createCampaignBtn": "СОЗДАТЬ КАМПАНИЮ",
"noUserCampaigns": "Вы ещё не запустили кампании. Нажмите <1>сюда1> чтобы создать первую кампанию",
- "saveCampaignBtn" : "СОХРАНИТЬ",
+ "saveCampaignBtn" : "Сохранить кампанию",
"complete" : "Успешно!",
"updateSuccessfull" : "Информация о кампании успешно обновлена",
"closeBtn" : "Закрыть",
@@ -237,5 +237,12 @@
"campaignURL":"URL кампании",
"campaignURLPlaceHolder":"Символы, которые появятся в адресе кампании после https://app.heo.finance/campaign/",
"campaignURLBad":"Такой URL кампании уже есть в базе данных, введите другой",
- "countryCodeRequired": "Пожалуйста, выберите код страны для телефонного номера"
+ "countryCodeRequired": "Пожалуйста, выберите код страны для телефонного номера",
+ "notValidAddr":"Недопустимый адрес кошелька",
+ "blockchain":"Блокчейн",
+ "wallet": "Адрес кошелька",
+ "payout":"Адрес для выплат",
+ "enterWallet":"Пожалуйста, введите адрес кошелька",
+ "campaignSaved":"Кампания сохранена в базе данных",
+ "campaignSavedWithErrors":"Кампания сохранена в базе данных с ошибками"
}
diff --git a/src/util/Utilities.js b/src/util/Utilities.js
index 8604201..6a84376 100644
--- a/src/util/Utilities.js
+++ b/src/util/Utilities.js
@@ -163,7 +163,7 @@ const getTronWeb = async () => {
return tronWeb;
}
-const initTron = async (chainId, that) => {
+const initTron = async (chainId) => {
if(!window.tronWeb)
{
window.tronWeb = await getTronWeb();
@@ -415,11 +415,21 @@ const encryptCardData = async(keyData, cardData) => {
return btoa(encrypted);
}
+function countWordsString(string){
+ var counter = 0;
+ string=string.replace(/[\s]+/gim, ' ');
+ string.replace(/(\s+)/g, function (a) {
+ counter++;
+ });
+ return counter;
+}
+
const blockchains = [
{value:"Ethereum"},
{value:"Tron"}
];
export {DescriptionPreview, i18nString, GetLanguage, LogIn, initWeb3, checkAuth, initWeb3Modal, clearWeb3Provider,clearTronProvider,
- getPCIPublicKey, encryptCardData, LogInTron, initTronadapter, checkAuthTron, initTron, getTronWeb, checkEmail, isValidUrl,blockchains};
+ getPCIPublicKey, encryptCardData, LogInTron, initTronadapter, checkAuthTron, initTron, getTronWeb, checkEmail, isValidUrl,blockchains,
+ countWordsString};
export default Utilities;