diff --git a/package.json b/package.json index b9b8724f9..bcaa8799c 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "redux-thunk": "^3.1.0", "singularitynet-platform-contracts": "^1.0.4", "slick-carousel": "^1.8.1", - "snet-sdk-web": "^4.0.4", + "snet-sdk-web": "^4.1.2", "utf8": "^3.0.0", "validate.js": "^0.13.1", "web3": "^4.11.1" diff --git a/src/Redux/actionCreators/ServiceDetailsActions.js b/src/Redux/actionCreators/ServiceDetailsActions.js index 748950453..fd8cbb3d4 100644 --- a/src/Redux/actionCreators/ServiceDetailsActions.js +++ b/src/Redux/actionCreators/ServiceDetailsActions.js @@ -88,7 +88,8 @@ export const fetchMeteringData = async (dispatch) => { const { email, token } = await dispatch(fetchAuthenticatedUser()); const usageData = await meteringAPI(token, orgId, serviceId, groupId, email); - return dispatch(fetchMeteringDataSuccess(usageData)); + dispatch(fetchMeteringDataSuccess(usageData)); + return usageData; }; export const getIsTrainingAvailable = (detailsTraining, isLoggedIn) => { diff --git a/src/Redux/actionCreators/UserActions.js b/src/Redux/actionCreators/UserActions.js index 78adcd81c..41cbdd3f6 100644 --- a/src/Redux/actionCreators/UserActions.js +++ b/src/Redux/actionCreators/UserActions.js @@ -569,21 +569,25 @@ export const registerWallet = (address, type) => async (dispatch) => { }; export const updateMetamaskWallet = () => async (dispatch, getState) => { - const sdk = await dispatch(sdkActions.getSdk()); - const address = await sdk.account.getAddress(); + try { + const sdk = await dispatch(sdkActions.getSdk()); + const address = await sdk.account.getAddress(); - if (getState().userReducer.wallet?.address === address) { - return address; - } + if (getState().userReducer.wallet?.address === address) { + return address; + } - const availableUserWallets = await dispatch(fetchAvailableUserWallets()); - const addressAlreadyRegistered = availableUserWallets.some( - (wallet) => wallet.address.toLowerCase() === address.toLowerCase() - ); + const availableUserWallets = await dispatch(fetchAvailableUserWallets()); + const addressAlreadyRegistered = availableUserWallets.some( + (wallet) => wallet.address.toLowerCase() === address.toLowerCase() + ); - if (!addressAlreadyRegistered) { - await dispatch(registerWallet(address, walletTypes.METAMASK)); + if (!addressAlreadyRegistered) { + await dispatch(registerWallet(address, walletTypes.METAMASK)); + } + dispatch(updateWallet({ type: walletTypes.METAMASK, address })); + return address; + } catch (err) { + throw new Error("Can't update metamask wallet"); } - dispatch(updateWallet({ type: walletTypes.METAMASK, address })); - return address; }; diff --git a/src/components/AiMarketplace/MainSection/Filter/index.js b/src/components/AiMarketplace/MainSection/Filter/index.js index 2b647da17..4ff8d79ba 100644 --- a/src/components/AiMarketplace/MainSection/Filter/index.js +++ b/src/components/AiMarketplace/MainSection/Filter/index.js @@ -21,7 +21,7 @@ const Filter = ({ listView, total_count, handleSearchChange, toggleView, current useEffect(() => { return () => dispatch(serviceActions.resetFilter({ pagination })); - }, []); + }, [dispatch]); const handleSearch = (event) => { setSearchKeyword(event.currentTarget.value); diff --git a/src/components/FeedbackFormModal/styles.css b/src/components/FeedbackFormModal/styles.css index fc8e5541a..0f1c14440 100644 --- a/src/components/FeedbackFormModal/styles.css +++ b/src/components/FeedbackFormModal/styles.css @@ -81,7 +81,7 @@ } .cancel-button { - border-color: var(--button-background) !important; + border-color: var(--button-background) !important; } /* FORM LAUNCHER */ @@ -91,7 +91,7 @@ position: fixed; bottom: 50px; right: 30px; - z-index: var(--modal-layout-z-index); + z-index: 1; } .feedback-form-launcher { diff --git a/src/components/Login/Signup/styles.js b/src/components/Login/Signup/styles.js index 37bd9fc8e..2f32a36e6 100644 --- a/src/components/Login/Signup/styles.js +++ b/src/components/Login/Signup/styles.js @@ -121,7 +121,7 @@ export const useStyles = (theme) => ({ marginTop: 10, display: "flex", "& button": { - padding: " 13px 60px 11px", + padding: "15px 60px", marginTop: 10, "&:first-of-type": { marginRight: 10 }, }, diff --git a/src/components/Onboarding/Authentication/styles.js b/src/components/Onboarding/Authentication/styles.js index 8166785bd..b8c7b70dd 100644 --- a/src/components/Onboarding/Authentication/styles.js +++ b/src/components/Onboarding/Authentication/styles.js @@ -45,7 +45,7 @@ export const useStyles = (theme) => ({ buttonsContainer: { marginTop: 40, "& button": { - padding: " 13px 60px 11px", + padding: "15px 60px", }, }, infoText: { diff --git a/src/components/Onboarding/index.js b/src/components/Onboarding/index.js index 64c838a83..5b70eb9d4 100644 --- a/src/components/Onboarding/index.js +++ b/src/components/Onboarding/index.js @@ -20,25 +20,25 @@ const Onboarding = ({ classes }) => { const [activeSection, setActiveSection] = useState(0); const progressText = [{ label: "Authentication" }, { label: "Terms of service" }]; - const initialChecks = () => { - if (!isEmailVerified) { - return; - } - if (activeSection === 0) { - setActiveSection(1); - } - if (isTermsAccepted) { - if (location?.state && location?.state?.sourcePath) { - navigate(location.state.sourcePath); + useEffect(() => { + const initialChecks = () => { + if (!isEmailVerified) { return; } - navigate(`/${Routes.AI_MARKETPLACE}`); - } - }; + if (activeSection === 0) { + setActiveSection(1); + } + if (isTermsAccepted) { + if (location?.state && location?.state?.sourcePath) { + navigate(location.state.sourcePath); + return; + } + navigate(`/${Routes.AI_MARKETPLACE}`); + } + }; - useEffect(() => { initialChecks(); - }, []); + }, [navigate, isEmailVerified, isTermsAccepted, activeSection, location.state]); const handleNextSection = () => { setActiveSection(activeSection + 1); diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/CompletedActions/styles.js b/src/components/ServiceDetails/AboutService/ServiceDemo/CompletedActions/styles.js index e6faf37e7..dddd0d0b0 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/CompletedActions/styles.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/CompletedActions/styles.js @@ -5,7 +5,7 @@ export const useStyles = makeStyles((theme) => ({ marginTop: 10, textAlign: "center", "& button": { - padding: " 13px 60px 11px", + padding: "15px 60px", marginTop: 10, marginRight: "0 !important", }, diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ActiveSession/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ActiveSession/index.js index 310043e81..e5d6e8207 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ActiveSession/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ActiveSession/index.js @@ -1,7 +1,6 @@ import React, { useState } from "react"; import { withStyles } from "@mui/styles"; import Tooltip from "@mui/material/Tooltip"; -import CircularProgress from "@mui/material/CircularProgress"; import AlertBox from "../../../../../common/AlertBox"; import StyledButton from "../../../../../common/StyledButton"; @@ -14,20 +13,12 @@ import { currentServiceDetails } from "../../../../../../Redux/reducers/ServiceD import { isUndefined } from "lodash"; import { updateMetamaskWallet } from "../../../../../../Redux/actionCreators/UserActions"; -const ActiveSession = ({ - classes, - isFreecallLoading, - freeCallsRemaining, - handleComplete, - freeCallsAllowed, - isServiceAvailable, -}) => { +const ActiveSession = ({ classes, freeCallsRemaining, handleComplete, freeCallsAllowed, isServiceAvailable }) => { const dispatch = useDispatch(); const { detailsTraining } = useSelector((state) => state.serviceDetailsReducer); const { org_id, service_id } = useSelector((state) => currentServiceDetails(state)); const { modelsList } = useSelector((state) => state.serviceTrainingReducer); const isLoggedIn = useSelector((state) => state.userReducer.login.isLoggedIn); - const [showTooltip, setShowTooltip] = useState(false); const progressValue = () => (freeCallsRemaining / freeCallsAllowed) * 100; @@ -49,7 +40,7 @@ const ActiveSession = ({ await dispatch(getTrainingModels(org_id, service_id, address)); }; - const isActionsDisabled = !isServiceAvailable || isFreecallLoading; + const isActionsDisabled = !isServiceAvailable; return (
@@ -60,9 +51,7 @@ const ActiveSession = ({ />
Free API Calls - - {isFreecallLoading ? : freeCallsRemaining} - + {freeCallsRemaining}
{ if (!inputProps) { @@ -6,13 +6,15 @@ const CallPriceInput = ({ classes, disabled, inputProps }) => { } return ( -
+ {!inputProps?.noInput && ( - + )} - {Number(inputProps.totalPrice)} - {inputProps.unit} -
+
+ {String(inputProps.totalPrice)} + {inputProps.unit} +
+ ); }; diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ChannelSelectionBox/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ChannelSelectionBox/index.js index 1acbf10d5..5a64c2ab6 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ChannelSelectionBox/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ChannelSelectionBox/index.js @@ -28,13 +28,17 @@ const ChannelSelectionBox = ({ onClick={onClick} > -
+ -
-
+ +

{title}

-
+
({ borderStyle: "solid", borderColor: theme.palette.text.verticalTabLeftBorder, borderRadius: 4, - marginBottom: 20, backgroundColor: theme.palette.text.cardBackground, "&:hover": { borderColor: theme.palette.text.primary, @@ -24,9 +23,10 @@ export const useStyles = (theme) => ({ borderStyle: "solid", borderColor: theme.palette.text.primary, backgroundColor: theme.palette.text.cardBackground, + boxShadow: `0 0 5px ${theme.palette.text.primary}`, }, LeftSideSection: { - padding: "14px 0", + padding: "14px 10px", display: "flex", alignItems: "center", "@media(max-width:480px)": { maxWidth: "100%" }, @@ -38,7 +38,7 @@ export const useStyles = (theme) => ({ display: "flex", flexDirection: "column", gap: 7, - + maxWidth: "70%", "& h2": { color: theme.palette.text.darkShadedGray, fontSize: 22, @@ -51,13 +51,11 @@ export const useStyles = (theme) => ({ }, }, "& input": { - width: 24, padding: "7px", borderWidth: 1, borderStyle: "solid", borderColor: theme.palette.text.inputBoxBorder, borderRadius: 4, - marginRight: 10, backgroundColor: theme.palette.text.whiteColor, color: theme.palette.text.mediumShadeGray, fontSize: 16, @@ -66,7 +64,6 @@ export const useStyles = (theme) => ({ }, "& span": { color: theme.palette.text.lightShadedGray, - lineHeight: "17px", }, }, disabledInputDataContainer: { @@ -80,14 +77,14 @@ export const useStyles = (theme) => ({ color: theme.palette.text.disabledBtnBg, }, }, - value: { - fontSize: 18, - "@media(max-width:1023px)": { fontSize: 16 }, + priceContainer: { + fontSize: 16, + display: "flex", + gap: 5, + flexWrap: "wrap", }, - unit: { - marginLeft: 5, - display: "inline-block", - fontSize: 12, + value: { + overflow: "auto", }, selectionBoxDescription: { padding: "14px 8px", @@ -97,7 +94,6 @@ export const useStyles = (theme) => ({ display: "flex", alignItems: "center", "& p": { - paddingLeft: 22, margin: 0, color: theme.palette.text.mediumShadeGray, fontSize: 14, diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/MetamaskFlow/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/MetamaskFlow/index.js index a7b63ef73..1b4944f4b 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/MetamaskFlow/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/MetamaskFlow/index.js @@ -1,4 +1,4 @@ -import React, { Component } from "react"; +import React, { Component, Fragment } from "react"; import { connect } from "react-redux"; import Tooltip from "@mui/material/Tooltip"; import { withStyles } from "@mui/styles"; @@ -31,17 +31,10 @@ Click below to install and learn more about how to use Metamask and your AGIX cr const MIN_CALLS_NUMBER = 1; -const paymentInfoCardData = { - mpeBal: { - title: "Escrow Balance", - id: "mpeBal", - unit: "AGIX", - }, - channelBalance: { - title: "Channel Balance", - id: "channelBalance", - unit: "AGIX", - }, +const paymentInfoCardDatMpeBal = { + title: "Escrow Balance", + id: "mpeBal", + unit: "AGIX", }; class MetamaskFlow extends Component { @@ -99,7 +92,6 @@ class MetamaskFlow extends Component { startChannelSetupLoader(); const sdk = await getSdk(); const serviceClient = await sdk.createServiceClient(org_id, service_id); - // const serviceClient = new ServiceClient(sdk, org_id, service_id, sdk._mpeContract, {}, groupInfo); this.paymentChannelManagement = new PaymentChannelManagement(sdk, serviceClient); this.setState({ isStartServiceDisable: false }); } catch (error) { @@ -139,7 +131,7 @@ class MetamaskFlow extends Component { // }; getBalanceData = async () => { - const { updateMetamaskWallet, startChannelSetupLoader, stopLoader } = this.props; + const { updateMetamaskWallet, startChannelSetupLoader, stopLoader, setIsLastPaidCall } = this.props; this.setState({ alert: {} }); startChannelSetupLoader(); try { @@ -147,22 +139,29 @@ class MetamaskFlow extends Component { const mpeBal = await this.sdk.account.escrowBalance(); const channelBalance = this.paymentChannelManagement.availableBalance(); const channelBalanceInCogs = cogsToAgi(channelBalance); - console.log(channelBalanceInCogs); + if (channelBalanceInCogs === this.state.totalPrice) { + await this.handleSubmit(); + setIsLastPaidCall(true); + return; + } if (channelBalanceInCogs > this.state.totalPrice) { + setIsLastPaidCall(false); await this.handleSubmit(); + return; } // await this.updateChannelBalanceAPI(); this.handleDisabledPaytypes(channelBalance, mpeBal); this.setState({ mpeBal: cogsToAgi(mpeBal), channelBalance: channelBalanceInCogs, + selectedPayType: payTypes.MULTIPLE_CALLS, }); } catch (error) { - console.log("getBalanceData error"); this.setState({ alert: connectMMinfo }); + } finally { + stopLoader(); } - stopLoader(); }; handlePayTypeChange = (value) => { @@ -210,12 +209,12 @@ class MetamaskFlow extends Component { if (!this.isValidCallsNumber(noOfServiceCalls)) { return; } - const totalPrice = String(cogsToAgi(this.paymentChannelManagement.noOfCallsToCogs(noOfServiceCalls))); + const totalPrice = cogsToAgi(this.paymentChannelManagement.noOfCallsToCogs(noOfServiceCalls)); this.setState({ noOfServiceCalls, totalPrice }); }; handleSubmit = async () => { - const { startChannelSetupLoader, stopLoader, handleContinue } = this.props; + const { startChannelSetupLoader, stopLoader, handleContinue, setIsLastPaidCall } = this.props; startChannelSetupLoader(); this.setState({ alert: {} }); @@ -229,13 +228,19 @@ class MetamaskFlow extends Component { handleContinue(); } catch (e) { this.setState({ alert: { type: alertTypes.ERROR, message: e.message } }); + } finally { + stopLoader(); } - stopLoader(); return; } + if (selectedPayType === payTypes.SINGLE_CALL) { noOfServiceCalls = 1; } + if (noOfServiceCalls === 1) { + setIsLastPaidCall(true); + } + try { const mpeBal = await this.sdk.account.escrowBalance(); if (mpeBal < this.paymentChannelManagement.noOfCallsToCogs(noOfServiceCalls)) { @@ -310,7 +315,6 @@ class MetamaskFlow extends Component { const { showPurchaseDialog, channelBalance, - // channelBalanceFromBack, selectedPayType, disabledPayTypes, noOfServiceCalls, @@ -319,19 +323,10 @@ class MetamaskFlow extends Component { showTooltip, isStartServiceDisable, } = this.state; + if (isUndefined(channelBalance) || isNaN(channelBalance)) { - // const channelBalanceCard = paymentInfoCardData.channelBalance; return ( <> - {/* {this.sdk && ( - - )} */} - {/*
*/} - {/*
*/} ); } + return ( -
- +
- {Object.values(paymentInfoCardData).map((item) => ( - - ))} -
-
- Best Value - this.handlePayTypeChange(payTypes.MULTIPLE_CALLS)} - inputProps={{ - noOfServiceCalls, - onChange: this.handleNoOfCallsChange, - totalPrice, - unit: "AGIX", - }} - disabled={disabledPayTypes.includes(payTypes.MULTIPLE_CALLS)} + +
+
+ +
+
Best Value
+ this.handlePayTypeChange(payTypes.MULTIPLE_CALLS)} + inputProps={{ + noOfServiceCalls, + onChange: this.handleNoOfCallsChange, + totalPrice, + unit: "AGIX", + }} + disabled={disabledPayTypes.includes(payTypes.MULTIPLE_CALLS)} + /> +
+ +
+ + +
+ +
+
+
- -
- - -
- -
-
-
-
+ ); } } @@ -419,7 +419,6 @@ const mapStateToProps = (state) => ({ const mapDispatchToProps = (dispatch) => ({ startChannelSetupLoader: () => dispatch(loaderActions.startAppLoader(LoaderContent.SETUP_CHANNEL_FOR_SERV_EXEC)), updateMetamaskWallet: () => dispatch(userActions.updateMetamaskWallet()), - // stopWalletDetailsPolling: () => dispatch(userActions.stopWalletDetailsPolling), stopLoader: () => dispatch(loaderActions.stopAppLoader()), getSdk: () => dispatch(sdkActions.getSdk()), // updateChannelBalanceAPI: (orgId, serviceId, groupId, authorizedAmount, fullAmount, channelId, nonce) => diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/MetamaskFlow/style.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/MetamaskFlow/style.js index c80fb8252..c5fd5c6b2 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/MetamaskFlow/style.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/MetamaskFlow/style.js @@ -10,11 +10,16 @@ export const useStyles = (theme) => ({ width: "100%", display: "flex", flexDirection: "column", - gap: 20, + gap: 25, }, PurchaseFlowContainer: { "@media(max-width:1280px)": { padding: 0 }, }, + channelSelectionTitle: { + color: theme.palette.text.primary, + fontWeight: 600, + marginBottom: 10, + }, PurchaseFlowDescription: { margin: "33px 0 45px", color: theme.palette.text.alertBoxColor, @@ -23,10 +28,11 @@ export const useStyles = (theme) => ({ lineHeight: "21px", }, paymentInfoCard: { - marginBottom: 25, display: "flex", justifyContent: "space-between", - "@media(max-width:460px)": { flexDirection: "column", gap: 25 }, + flexWrap: "wrap", + gap: 25, + "@media(max-width:650px)": { justifyContent: "center" }, }, paymentChannelDropDownContainer: { display: "flex" }, infoIconContainer: { @@ -59,7 +65,6 @@ export const useStyles = (theme) => ({ }, walletIcon: { color: theme.palette.text.lightShadedGray }, buttonContainer: { - marginTop: 35, textAlign: "center", display: "flex", justifyContent: "space-evenly", @@ -67,12 +72,5 @@ export const useStyles = (theme) => ({ display: "inline-block", }, }, - channelSelectionTitle: { - marginBottom: 5, - display: "inline-block", - color: theme.palette.text.mediumShadeGray, - fontSize: 16, - fontWeight: 600, - }, tooltip: { fontSize: 14 }, }); diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/index.js index 6e62755a9..22d9d8414 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/index.js @@ -15,6 +15,7 @@ import WalletDetailsToggler from "./WalletDetailsToggler"; import { channelInfo } from "../../../../../../Redux/reducers/UserReducer"; import { anyPendingTxn, anyFailedTxn } from "../../../../../../Redux/reducers/PaymentReducer"; import { LoaderContent } from "../../../../../../utility/constants/LoaderContent"; +import { initPaypalSdk } from "../../../../../../utility/sdk"; const TransactionAlert = { PENDING: { type: alertTypes.WARNING, message: "Transaction Confirmed. Pending token allocation" }, @@ -40,21 +41,21 @@ class ExpiredSession extends Component { componentDidMount = () => { this.setState({ alert: this.transactionAlert() }); + this.props.setIsLastPaidCall(false); + if (process.env.REACT_APP_SANDBOX || this.props.wallet.type !== walletTypes.GENERAL) { + initPaypalSdk(this.props.wallet.address, channelInfo); + } }; handlePayTypeChange = (event) => { const { value } = event.target; const { updateWallet } = this.props; this.setState({ alert: {} }); - if (value === walletTypes.GENERAL) { - updateWallet({ type: value }); - return; - } updateWallet({ type: value }); }; render() { - const { classes, wallet, handleComplete, groupInfo, handlePurchaseError, isServiceAvailable, channelInfo } = + const { classes, wallet, handleComplete, handlePurchaseError, isServiceAvailable, channelInfo, setIsLastPaidCall } = this.props; const { alert } = this.state; const channelPaymentOptions = [ @@ -96,7 +97,7 @@ class ExpiredSession extends Component { generalWalletProps={{ handleContinue: handleComplete }} metamaskProps={{ handleContinue: handleComplete, - groupInfo, + setIsLastPaidCall, handlePurchaseError, isServiceAvailable, }} diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/styles.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/styles.js index 8702def36..4b213262c 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/styles.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/ExpiredSession/styles.js @@ -14,7 +14,6 @@ export const useStyles = (theme) => ({ fontFamily: theme.typography.primary.main, }, paymentInfoCard: { - marginBottom: 25, display: "flex", justifyContent: "space-between", }, diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PaymentInfoCard/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PaymentInfoCard/index.js index 03bf51e21..bf2c365bb 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PaymentInfoCard/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PaymentInfoCard/index.js @@ -1,6 +1,5 @@ import React from "react"; import { withStyles } from "@mui/styles"; -import InfoIcon from "@mui/icons-material/Info"; import { useStyles } from "./styles"; @@ -11,11 +10,10 @@ const PaymentInfoCard = ({ classes, title, value, unit, show = true }) => { return (
-
{title}
-

{Number(value)}

+

{String(value)}

{unit ? AGIX : ""}
diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PaymentInfoCard/styles.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PaymentInfoCard/styles.js index 102ea3aaf..292f897c8 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PaymentInfoCard/styles.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PaymentInfoCard/styles.js @@ -8,7 +8,7 @@ export const useStyles = (theme) => ({ verticalAlign: "middle", }, "& h5": { - margin: "0 0 0 7px", + margin: "0", display: "inline-block", color: theme.palette.text.lightShadedGray, fontSize: 16, @@ -18,9 +18,7 @@ export const useStyles = (theme) => ({ "@media(max-width:480px)": { textAlign: "left" }, }, TitleContainer: { - display: "flex", - alignItems: "center", - marginBottom: 5, + textAlign: "center", }, content: { "& h3": { diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PurchaseDialog/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PurchaseDialog/index.js index 7bf5803bc..dbcc475d5 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PurchaseDialog/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PurchaseDialog/index.js @@ -1,24 +1,16 @@ -import React, { useState } from "react"; +import React from "react"; import { withStyles } from "@mui/styles"; import Dialog from "@mui/material/Dialog"; import { useStyles } from "./styles"; -import MetamaskDetails from "../../../../../UserProfile/UserProfileAccount/MetamaskDetails/MetamaskDetails"; - -const DialogTitles = ["Deposit into Escrow", "Withdraw from Escrow"]; +import MetamaskDetails from "../../../../../UserProfile/UserProfileAccount/MetamaskDetails"; const PurchaseDialog = ({ classes, show, onClose }) => { - const [title, setTitle] = useState(DialogTitles[0]); - - const handleTitleChange = (activeTab) => { - setTitle(DialogTitles[activeTab]); - }; - return ( - {title} + Deposit into Escrow
- +
); diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PurchaseDialog/styles.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PurchaseDialog/styles.js index 22cea0d7b..158a81ace 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PurchaseDialog/styles.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/PurchaseDialog/styles.js @@ -56,5 +56,10 @@ export const useStyles = (theme) => ({ fontSize: 20, lineHeight: "25px", }, - escrowAccountDetails: { padding: "0 25px 25px" }, + escrowAccountDetails: { + padding: "25px", + display: "flex", + gap: 20, + flexDirection: "column", + }, }); diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/index.js index fe828d154..c6671ebf9 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/index.js @@ -1,24 +1,65 @@ -import React from "react"; +import React, { useEffect, useState } from "react"; import ActiveSession from "./ActiveSession"; import ExpiredSession from "./ExpiredSession"; +import { currentServiceDetails, groupInfo } from "../../../../../Redux/reducers/ServiceDetailsReducer"; +import { useDispatch, useSelector } from "react-redux"; +import { loaderActions, serviceDetailsActions } from "../../../../../Redux/actionCreators"; +import { LoaderContent } from "../../../../../utility/constants/LoaderContent"; +import CircularProgress from "@material-ui/core/CircularProgress"; +import "./styles.css"; -const Purchase = ({ - handleComplete, - freeCallsRemaining, - freeCallsAllowed, - isFreecallLoading, - wallet, - groupInfo, - handlePurchaseError, - isServiceAvailable, -}) => { - if (freeCallsRemaining < 1) { +const Purchase = ({ handleComplete, wallet, handlePurchaseError, isServiceAvailable, setIsLastPaidCall }) => { + const dispatch = useDispatch(); + const { org_id, service_id } = useSelector((state) => currentServiceDetails(state)); + const group_id = useSelector((state) => groupInfo(state).group_id); + const email = useSelector((state) => state.userReducer.email); + + const [isFreecallLoading, setIsFreecallLoading] = useState(false); + const [freeCalls, setFreeCalls] = useState({ freeCallsAllowed: 0, freeCallsRemaining: 0 }); + + useEffect(() => { + const fetchFreeCallsUsage = async () => { + dispatch(loaderActions.startAppLoader(LoaderContent.FREE_CALLS_GETTING)); + try { + setIsFreecallLoading(true); + const { free_calls_allowed, total_calls_made } = await dispatch( + serviceDetailsActions.fetchMeteringData({ + orgId: org_id, + serviceId: service_id, + groupId: group_id, + username: email, + }) + ); + setFreeCalls({ + freeCallsAllowed: free_calls_allowed, + freeCallsRemaining: free_calls_allowed - total_calls_made, + }); + } catch (error) { + console.error(error); + } finally { + setIsFreecallLoading(false); + dispatch(loaderActions.stopAppLoader()); + } + }; + + fetchFreeCallsUsage(); + }, [dispatch, org_id, service_id, group_id, email]); + + if (isFreecallLoading) { + return ( +
+ +
+ ); + } + + if (freeCalls.freeCallsRemaining < 1) { return ( @@ -26,9 +67,8 @@ const Purchase = ({ } return ( diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/styles.css b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/styles.css new file mode 100644 index 000000000..d6e30c489 --- /dev/null +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/Purchase/styles.css @@ -0,0 +1,3 @@ +.freecall-loader-container { + text-align: center; +} \ No newline at end of file diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/PurchaseToggler.js b/src/components/ServiceDetails/AboutService/ServiceDemo/PurchaseToggler.js index f090abfeb..5738e7dad 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/PurchaseToggler.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/PurchaseToggler.js @@ -2,11 +2,11 @@ import React from "react"; import ThirdPartyAIService from "./ThirdPartyAIService"; import Purchase from "./Purchase"; -const PurchaseToggler = ({ purchaseCompleted, purchaseProps, thirdPartyProps, groupInfo }) => { +const PurchaseToggler = ({ purchaseCompleted, purchaseProps, thirdPartyProps }) => { if (purchaseCompleted) { - return ; + return ; } - return ; + return ; }; export default PurchaseToggler; diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/ThirdPartyAIService.js b/src/components/ServiceDetails/AboutService/ServiceDemo/ThirdPartyAIService.js index 23563e396..27449aff4 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/ThirdPartyAIService.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/ThirdPartyAIService.js @@ -11,6 +11,7 @@ import ThirdPartyServiceErrorBoundary from "./ThirdPartyServiceErrorBoundary"; import { channelInfo } from "../../../../Redux/reducers/UserReducer"; import { isEmpty } from "lodash"; import { modelStatus } from "../../../../Redux/reducers/ServiceTrainingReducer"; +import { freeCalls, groupInfo } from "../../../../Redux/reducers/ServiceDetailsReducer"; class ThirdPartyAIService extends Component { state = { @@ -117,6 +118,8 @@ const mapStateToProps = (state) => ({ email: state.userReducer.email, wallet: state.userReducer.wallet, channelInfo: channelInfo(state), + groupInfo: groupInfo(state), + freeCallsRemaining: freeCalls(state).remaining, }); const mapDispatchToProps = (dispatch) => ({ diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/UserFeedback/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/UserFeedback/index.js index 699c1b4c1..f32f06732 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/UserFeedback/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/UserFeedback/index.js @@ -1,11 +1,4 @@ import React, { useState, useEffect, Fragment } from "react"; -import Modal from "@mui/material/Modal"; -import Card from "@mui/material/Card"; -import CardHeader from "@mui/material/CardHeader"; -import CloseIcon from "@mui/icons-material/Close"; -import IconButton from "@mui/material/IconButton"; -import CardContent from "@mui/material/CardContent"; -import CardActions from "@mui/material/CardActions"; import Snackbar from "@mui/material/Snackbar"; import StarRatingComponent from "react-star-rating-component"; import { connect } from "react-redux"; @@ -16,10 +9,11 @@ import { useStyles } from "./styles"; import StyledButton from "../../../../common/StyledButton"; import { serviceActions } from "../../../../../Redux/actionCreators"; import AlertBox from "../../../../common/AlertBox"; +import SNETDialog from "../../../../common/SNETDialog"; const UserFeedback = ({ open, handleClose, feedback, submitFeedback, orgId, serviceId, refetchFeedback }) => { const [comment, setComment] = useState(feedback.comment); - const [openSnackbar, setOpenSnackbar] = useState(feedback.comment); + const [openSnackbar, setOpenSnackbar] = useState(Boolean(feedback.comment)); const [count, setCount] = useState(feedback.comment.length); const [rating, setRating] = useState(feedback.rating); const [alert, setAlert] = useState({ type: "error", message: undefined }); @@ -73,49 +67,34 @@ const UserFeedback = ({ open, handleClose, feedback, submitFeedback, orgId, serv return ( - - - Write Your Own Review} - action={ - - - - } + +
+ - -
- - -
-
- - {count} / 500 Characters -
- -
- - - - - - + +
+
+ + {count} / 500 Characters +
+ + + +
Feedback updated successfully diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/UserFeedback/styles.js b/src/components/ServiceDetails/AboutService/ServiceDemo/UserFeedback/styles.js index a0998df6b..449c4577b 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/UserFeedback/styles.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/UserFeedback/styles.js @@ -45,7 +45,7 @@ export const useStyles = makeStyles((theme) => ({ marginTop: 10, textAlign: "center", "& button": { - padding: " 13px 60px 11px", + padding: "15px 60px", marginTop: 10, }, }, diff --git a/src/components/ServiceDetails/AboutService/ServiceDemo/index.js b/src/components/ServiceDetails/AboutService/ServiceDemo/index.js index be41f2ffd..d70037f15 100644 --- a/src/components/ServiceDetails/AboutService/ServiceDemo/index.js +++ b/src/components/ServiceDetails/AboutService/ServiceDemo/index.js @@ -3,10 +3,7 @@ import { withStyles } from "@mui/styles"; import { useDispatch, useSelector } from "react-redux"; import queryString from "query-string"; -import { freeCalls as getFreeCalls, groupInfo as getGroupInfo } from "../../../../Redux/reducers/ServiceDetailsReducer"; -import { channelInfo as getChannelInfo } from "../../../../Redux/reducers/UserReducer"; -import { anyPendingTxn as getAnyPendingTxn } from "../../../../Redux/reducers/PaymentReducer"; -import { serviceDetailsActions, loaderActions, userActions, paymentActions } from "../../../../Redux/actionCreators"; +import { loaderActions, userActions, paymentActions } from "../../../../Redux/actionCreators"; import { walletTypes } from "../../../../Redux/actionCreators/UserActions"; import ProgressBar from "../../../common/ProgressBar"; @@ -15,9 +12,8 @@ import PurchaseToggler from "./PurchaseToggler"; import { LoaderContent } from "../../../../utility/constants/LoaderContent"; import AlertBox, { alertTypes } from "../../../common/AlertBox"; import Routes from "../../../../utility/constants/Routes"; -import { initPaypalSdk } from "../../../../utility/sdk"; import { progressTabStatus } from "../../../common/ProgressBar"; -import { useLocation, useNavigate, useParams } from "react-router-dom"; +import { useLocation, useParams } from "react-router-dom"; const demoProgressStatus = { purchasing: 0, @@ -26,17 +22,10 @@ const demoProgressStatus = { }; const ServiceDemo = ({ classes, service }) => { - const navigate = useNavigate(); const dispatch = useDispatch(); const location = useLocation(); const { orderId, paymentId } = useParams(); - - const freeCalls = useSelector((state) => getFreeCalls(state)); - const groupInfo = useSelector((state) => getGroupInfo(state)); - const email = useSelector((state) => state.userReducer.email); const wallet = useSelector((state) => state.userReducer.wallet); - const channelInfo = useSelector((state) => getChannelInfo(state)); - const anyPendingTxn = useSelector((state) => getAnyPendingTxn(state)); const [progressText, setProgressText] = useState([ { label: "Purchase" }, @@ -46,55 +35,9 @@ const ServiceDemo = ({ classes, service }) => { const [purchaseCompleted, setPurchaseCompleted] = useState(false); const [isServiceExecutionComplete, setIsServiceExecutionComplete] = useState(false); const [alert, setAlert] = useState({}); - const [isFreecallLoading, setIsFreecallLoading] = useState(false); - - const fetchFreeCallsUsage = async () => { - try { - setIsFreecallLoading(true); - return await dispatch( - serviceDetailsActions.fetchMeteringData({ - orgId: service.org_id, - serviceId: service.service_id, - groupId: groupInfo.group_id, - username: email, - }) - ); - } catch (error) { - console.log(error); - } finally { - setIsFreecallLoading(false); - } - }; - - useEffect(() => { - if (process.env.REACT_APP_SANDBOX) { - return; - } - fetchFreeCallsUsage(); - - try { - dispatch(loaderActions.startAppLoader(LoaderContent.INIT_SERVICE_DEMO)); - checkForPaymentsInProgress(); - scrollToHash(); - dispatch(loaderActions.stopAppLoader()); - - if (window.location.href.indexOf("#demo") > -1) { - navigate(location.pathname); - } - } catch (error) { - dispatch(loaderActions.stopAppLoader()); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [dispatch, navigate]); - - useEffect(() => { - if (process.env.REACT_APP_SANDBOX || wallet.type !== walletTypes.GENERAL) { - return; - } - initPaypalSdk(wallet.address, channelInfo); - }, [channelInfo, wallet, anyPendingTxn]); + const [isLastPaidCall, setIsLastPaidCall] = useState(false); - const checkForPaymentsInProgress = async () => { + const checkForPaymentsInProgress = useCallback(async () => { const { paymentId: paypalPaymentId, PayerID } = queryString.parse(location); if (orderId && paymentId && paypalPaymentId && PayerID) { const { data } = await dispatch(paymentActions.fetchOrderDetails(orderId)); @@ -102,31 +45,36 @@ const ServiceDemo = ({ classes, service }) => { dispatch(paymentActions.updatePaypalInProgress(orderId, orderType, paymentId, paypalPaymentId, PayerID)); return dispatch(userActions.updateWallet({ type: walletTypes.GENERAL })); } - }; - - // const pollWalletDetails = async () => { - // const { - // service: { org_id: orgId }, - // groupInfo: { group_id: groupId }, - // } = this.props; - - // return await dispatch(userActions.startWalletDetailsPolling(orgId, groupId)); - // }; + }, [dispatch, orderId, paymentId, location]); - const scrollToHash = () => { + useEffect(() => { if (location.hash === Routes.hash.SERVICE_DEMO) { window.scroll({ top: 520, behavior: "smooth", }); } - }; + }, [location.hash]); + + useEffect(() => { + if (process.env.REACT_APP_SANDBOX) { + return; + } + + try { + dispatch(loaderActions.startAppLoader(LoaderContent.INIT_SERVICE_DEMO)); + checkForPaymentsInProgress(); + dispatch(loaderActions.stopAppLoader()); + } catch (error) { + dispatch(loaderActions.stopAppLoader()); + } + }, [dispatch, checkForPaymentsInProgress]); const computeActiveSection = useCallback(() => { const { purchasing, executingAIservice, displayingResponse } = demoProgressStatus; return purchaseCompleted ? (isServiceExecutionComplete ? displayingResponse : executingAIservice) : purchasing; - }, [purchaseCompleted, demoProgressStatus]); + }, [purchaseCompleted, isServiceExecutionComplete]); const serviceRequestStartHandler = () => { setAlert({}); @@ -151,7 +99,6 @@ const ServiceDemo = ({ classes, service }) => { setIsServiceExecutionComplete(false); setAlert({}); setProgressText(progressText.map((item) => ({ label: item.label }))); - fetchFreeCallsUsage(); }; const serviceRequestErrorHandler = (error) => { @@ -181,22 +128,25 @@ const ServiceDemo = ({ classes, service }) => { return (
+ {isLastPaidCall && ( + + )} ({ flexDirection: "column", gap: 30, }, + lastPaidCallInfo: { + margin: 0, + }, uploadImageContainer: { display: "flex", justifyContent: "space-evenly", diff --git a/src/components/ServiceDetails/DataPreset/index.js b/src/components/ServiceDetails/DataPreset/index.js index d5bf35fa3..305688da0 100644 --- a/src/components/ServiceDetails/DataPreset/index.js +++ b/src/components/ServiceDetails/DataPreset/index.js @@ -1,4 +1,4 @@ -import React, { useEffect } from "react"; +import React, { useCallback, useEffect } from "react"; import Card from "../../common/Card"; import DatasetUploader from "./DatasetUploader"; import MergeIcon from "@mui/icons-material/CallMerge"; @@ -33,34 +33,33 @@ const DataPreset = ({ classes }) => { const mergeDataset = useSelector((state) => state.datasetReducer.mergeDataset); const recentDatasets = useSelector((state) => state.datasetReducer.recentDatasets); - useEffect(() => { - !!mainDataset && !mainDataset?.additionalInfo && getStatistic(mainDataset, setMainDataset); - }, [mainDataset]); + const getStatistic = useCallback( + async (dataset, setDataset) => { + try { + dispatch(loaderActions.startAppLoader(LoaderContent.GET_DATASET_STATISTIC)); + const datasetKey = dataset?.datasetKey; + const { data } = await dispatch(getDatasetStatistic(datasetKey)); + const enrichedDataset = { ...dataset, additionalInfo: data }; + const actualDatasetIndexInRecent = recentDatasets.find((el) => el.datasetKey === datasetKey); + if (!actualDatasetIndexInRecent) { + await dispatch(addRecentDataset(enrichedDataset)); + } else { + await dispatch(updateRecentDataset(datasetKey, data)); + } + await dispatch(setDataset(enrichedDataset)); + } catch (error) { + console.error("getStatistic error", error); + dispatch(setDataset(null)); + } finally { + dispatch(loaderActions.stopAppLoader()); + } + }, + [dispatch, recentDatasets] + ); useEffect(() => { - !!mergeDataset && !mergeDataset?.additionalInfo && getStatistic(mergeDataset, setMergeDataset); - }, [mergeDataset]); - - const getStatistic = async (dataset, setDataset) => { - try { - dispatch(loaderActions.startAppLoader(LoaderContent.GET_DATASET_STATISTIC)); - const datasetKey = dataset?.datasetKey; - const { data } = await dispatch(getDatasetStatistic(datasetKey)); - const enrichedDataset = { ...dataset, additionalInfo: data }; - const actualDatasetIndexInRecent = recentDatasets.find((el) => el.datasetKey === datasetKey); - if (!actualDatasetIndexInRecent) { - await dispatch(addRecentDataset(enrichedDataset)); - } else { - await dispatch(updateRecentDataset(datasetKey, data)); - } - await dispatch(setDataset(enrichedDataset)); - } catch (error) { - console.error("getStatistic error", error); - dispatch(setDataset(null)); - } finally { - dispatch(loaderActions.stopAppLoader()); - } - }; + !!mainDataset && !mainDataset?.additionalInfo && getStatistic(mainDataset, setMainDataset); + }, [mainDataset, getStatistic]); const cleanMainDataset = () => { dispatch(setMainDataset(mergeDataset)); diff --git a/src/components/ServiceDetails/InstallAndRunService/index.js b/src/components/ServiceDetails/InstallAndRunService/index.js index 5301ba59c..d70128ad4 100644 --- a/src/components/ServiceDetails/InstallAndRunService/index.js +++ b/src/components/ServiceDetails/InstallAndRunService/index.js @@ -1,7 +1,6 @@ import React, { Component } from "react"; import Grid from "@mui/material/Grid"; import { withStyles } from "@mui/styles"; -import InfoIcon from "@mui/icons-material/Info"; import TextField from "@mui/material/TextField"; import Typography from "@mui/material/Typography"; import { connect } from "react-redux"; @@ -131,7 +130,6 @@ class InstallAndRunService extends Component {
- ({ paddingLeft: 20, paddingRight: 20, }, - infoIcon: { - paddingRight: 12, - color: theme.palette.text.lightGray, - fontSize: 20, - verticalAlign: "sub", - }, overViewContainer: { display: "flex", gap: 25, diff --git a/src/components/ServiceDetails/PaymentCanceled.js b/src/components/ServiceDetails/PaymentCanceled.js index 2391e6d86..7db44603a 100644 --- a/src/components/ServiceDetails/PaymentCanceled.js +++ b/src/components/ServiceDetails/PaymentCanceled.js @@ -14,7 +14,7 @@ const PaymentCanceled = () => { useEffect(() => { dispatch(paymentActions.cancelOrder(orderId)); navigate(`/${Routes.SERVICE_DETAILS}/org/${orgId}/service/${serviceId}`); - }, []); + }, [dispatch, navigate, orderId, serviceId, orgId]); return ; }; diff --git a/src/components/ServiceDetails/PricingDetails/index.js b/src/components/ServiceDetails/PricingDetails/index.js index e6b03f995..be128cd3d 100644 --- a/src/components/ServiceDetails/PricingDetails/index.js +++ b/src/components/ServiceDetails/PricingDetails/index.js @@ -7,8 +7,11 @@ import StyledButton from "../../common/StyledButton"; import { useStyles } from "./styles"; import Price from "./Price"; import { PricingStrategy } from "../../../utility/PricingStrategy"; +import { pricing as getPricing } from "../../../Redux/reducers/ServiceDetailsReducer"; +import { useSelector } from "react-redux"; -const PricingDetails = ({ classes, pricing, serviceAvailable, handleDemoClick }) => { +const PricingDetails = ({ classes, serviceAvailable, handleDemoClick }) => { + const pricing = useSelector((state) => getPricing(state)); const price_strategy = new PricingStrategy(pricing); const priceInAGI = typeof price_strategy === "undefined" ? undefined : price_strategy.getMaxPriceInAGI(); const price_model = typeof price_strategy === "undefined" ? undefined : price_strategy.getPriceModel(); diff --git a/src/components/ServiceDetails/TitleCard/index.js b/src/components/ServiceDetails/TitleCard/index.js index 7e190474a..6fdc24054 100644 --- a/src/components/ServiceDetails/TitleCard/index.js +++ b/src/components/ServiceDetails/TitleCard/index.js @@ -69,7 +69,7 @@ const TitleCard = ({

{display_name}

- +
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentInfoCard.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentInfoCard.js index 1c1ad5b7a..6758d2ff5 100644 --- a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentInfoCard.js +++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentInfoCard.js @@ -1,6 +1,5 @@ import React from "react"; import { withStyles } from "@mui/styles"; -import InfoIcon from "@mui/icons-material/Info"; import { useStyles } from "./styles"; @@ -11,7 +10,6 @@ const PaymentInfoCard = ({ classes, title, value, unit, show = true }) => { return (
-
{title}
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentMode.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentMode.js deleted file mode 100644 index a7897b61b..000000000 --- a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentMode.js +++ /dev/null @@ -1,143 +0,0 @@ -import React, { Component } from "react"; -import isEmpty from "lodash/isEmpty"; -import { connect } from "react-redux"; -import { withStyles } from "@mui/styles"; -import AccountBalanceWalletIcon from "@mui/icons-material/AccountBalanceWallet"; -import Typography from "@mui/material/Typography"; -import { walletTypes } from "../../../../../Redux/actionCreators/UserActions"; -import StyledDropdown from "../../../../common/StyledDropdown"; -import AlertBox, { alertTypes } from "../../../../common/AlertBox"; -import { channelInfo } from "../../../../../Redux/reducers/UserReducer"; -import PaymentInfoCard from "../../../AboutService/ServiceDemo/Purchase/PaymentInfoCard"; -import { loaderActions, userActions, sdkActions } from "../../../../../Redux/actionCreators"; -import { anyPendingTxn, anyFailedTxn } from "../../../../../Redux/reducers/PaymentReducer"; -import WalletDetailsToggler from "../../../AboutService/ServiceDemo/Purchase/ExpiredSession/WalletDetailsToggler"; -import { useStyles } from "./styles"; -import { groupInfo } from "../../../../../Redux/reducers/ServiceDetailsReducer"; - -const TransactionAlert = { - PENDING: { type: alertTypes.WARNING, message: "Transaction Confirmed. Pending token allocation" }, - FAILED: { type: alertTypes.ERROR, message: "Transaction Failed. See history for more details" }, -}; - -class PaymentMode extends Component { - state = { - alert: {}, - }; - - transactionAlert = () => { - const { anyPendingTxn, anyFailedTxn, wallet } = this.props; - if (wallet.type === walletTypes.GENERAL && anyPendingTxn) { - return TransactionAlert.PENDING; - } - if (wallet.type === walletTypes.GENERAL && anyFailedTxn) { - return TransactionAlert.FAILED; - } - return {}; - }; - - handlePayTypeChange = async (event) => { - const { value } = event.target; - const { updateWallet } = this.props; - this.setState({ alert: {} }); - if (value === walletTypes.METAMASK) { - try { - const sdk = await this.props.getSdk(); - const address = await sdk.account.getAddress(); - - if (!isEmpty(address)) { - // stopWalletDetailsPolling(); - updateWallet({ type: value, address }); - return; - } - this.setState({ - alert: { type: alertTypes.ERROR, message: `Unable to fetch Metamask address. Please try again` }, - }); - } catch (error) { - this.setState({ alert: { type: alertTypes.ERROR, message: `Something went wrong. Please try again` } }); - } - } - if (value === walletTypes.GENERAL) { - // stopWalletDetailsPolling(); - updateWallet({ type: value }); - return; - } - updateWallet({ type: value }); - }; - - handlePurchaseError = (error) => { - this.setState({ - alert: { type: alertTypes.ERROR, message: "Purchase could not be completed. Please try again" }, - }); - this.props.stopLoader(); - }; - - render() { - const { classes, wallet, groupInfo, service, channelInfo } = this.props; - - const channelPaymentOptions = [ - { value: walletTypes.GENERAL, label: "PayPal" }, - { value: walletTypes.METAMASK, label: "Metamask" }, - ]; - - return ( -
-

Please select a payment method to continue

-
-
-
- - Payment Channel - - - -
-
-
- -
- -
- - -
- ); - } -} - -const mapStateToProps = (state) => ({ - wallet: state.userReducer.wallet, - channelInfo: channelInfo(state), - anyPendingTxn: anyPendingTxn(state), - anyFailedTxn: anyFailedTxn(state), - groupInfo: groupInfo(state), -}); - -const mapDispatchToProps = (dispatch) => ({ - stopLoader: () => dispatch(loaderActions.stopAppLoader()), - updateWallet: (args) => dispatch(userActions.updateWallet(args)), - // stopWalletDetailsPolling: () => dispatch(userActions.stopWalletDetailsPolling), - getSdk: () => dispatch(sdkActions.getSdk()), -}); - -export default connect(mapStateToProps, mapDispatchToProps)(withStyles(useStyles)(PaymentMode)); diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/index.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/index.js deleted file mode 100644 index c4874fd6c..000000000 --- a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/index.js +++ /dev/null @@ -1,172 +0,0 @@ -// import React, { useState } from "react"; -// import { withStyles } from "@mui/styles"; -// import Grid from "@mui/material/Grid"; -// import Typography from "@mui/material/Typography"; -// import DoneIcon from "@mui/icons-material/Done"; -// import { useStyles } from "./styles"; -// import PaymentMode from "./PaymentMode"; -// import StyledButton from "../../../../common/StyledButton"; -// import AlertBox, { alertTypes } from "../../../../common/AlertBox"; -// import { callTypes, createServiceClient } from "../../../../../utility/sdk"; -// import { Calculator } from "../../../../../assets/thirdPartyServices/snet/example_service/example_service_pb_service"; -// import { channelInfo } from "../../../../../Redux/reducers/UserReducer"; -// import { currentServiceDetails, groupInfo } from "../../../../../Redux/reducers/ServiceDetailsReducer"; -// import { LoaderContent } from "../../../../../utility/constants/LoaderContent"; -// import { loaderActions } from "../../../../../Redux/actionCreators"; -// import { connect } from "react-redux"; - -// const Payment = ({ classes, handleNextClick }) => { -// const { currentModel } = useSelector((state) => state.serviceDetailsReducer.detailsTraining); -// const [autoSave] = useState(true); -// const [purchaseCompleted, setPurchaseCompleted] = useState(false); -// const [alert, setAlert] = useState({}); -// const addEllipsisAtEndOfString = (str) => `${str.substr(0, 40)}...`; - -// const AddressList = () => { -// if (currentModel?.address?.length) { -// return currentModel?.address.map((address) =>
  • {addEllipsisAtEndOfString(address)}
  • ); -// } -// return null; -// }; - -// const serviceRequestStartHandler = () => { -// setAlert({}); -// startLoader(); -// }; - -// const serviceRequestCompleteHandler = () => { -// stopLoader(); -// handleNextClick(); -// }; - -// const serviceRequestErrorHandler = (error) => { -// const alert = { type: alertTypes.ERROR }; -// if (error.response && error.response.data && error.response.data.error) { -// alert.message = error.response.data.error; -// } else { -// alert.message = error.message || error; -// } -// setAlert(alert); -// stopLoader(); -// }; - -// const onNextPress = async () => { -// const serviceClient = await createServiceClient( -// org_id, -// service_id, -// groupInfo, -// serviceRequestStartHandler, -// serviceRequestCompleteHandler, -// serviceRequestErrorHandler, -// callTypes, -// wallet, -// channelInfo -// ); -// const descriptor = currentModel.method.split(".")[1].split("/")[1]; -// const methodDescriptor = Calculator[descriptor]; -// const request = new methodDescriptor.requestType(); -// request.setLink(currentModel.dataLink); -// request.setAddress(wallet.address); -// request.setModelId(currentModel.modelId); -// request.setRequestId(""); -// const props = { -// request, -// onEnd: ({ message }) => { -// setTrainModelId(message.getModelId()); -// }, -// }; -// serviceClient.unary(methodDescriptor, props); -// }; - -// const handlePurchaseComplete = () => { -// setPurchaseCompleted(true); -// }; - -// return ( -//
    -//
    -// Review request -// -// -// Default Model: -// -// -// Yes -// -// -// -// -// Model name: -// -// -// {currentModel?.name || ""} -// -// -// -// -// Model description: -// -// -// {currentModel?.description || ""} -// -// -// -// -// Data files: -// -// -// {currentModel?.dataLink || ""} -// -// -// -// -// Ethereum address: -// -// -//
      -// -//
    -//
    -//
    -//
    -//
    -// Model Traning Fee -//

    This AI Model Traning requires a very small fee. Please select a payment method to continue

    -//
    -// agix tokens -// 0.002 -//
    -//
    -// {!purchaseCompleted ? ( -// -// ) : null} -//
    -// {autoSave ? ( -//
    -// -// Auto Saved -//
    -// ) : ( -// Auto Save -// )} -// -// -// -//
    -//
    -// ); -// }; - -// const mapStateToProps = (state) => ({ -// wallet: state.userReducer.wallet, -// channelInfo: channelInfo(state), -// groupInfo: groupInfo(state), -// serviceDetails: currentServiceDetails(state), -// }); - -// const mapDispatchToProps = (dispatch, ownProps) => ({ -// startLoader: () => dispatch(loaderActions.startAppLoader(LoaderContent.TRAIN_MODEL)), -// stopLoader: () => dispatch(loaderActions.stopAppLoader()), -// }); - -// export default connect(mapStateToProps, mapDispatchToProps)(withStyles(useStyles)(Payment)); diff --git a/src/components/ServiceDetails/index.js b/src/components/ServiceDetails/index.js index 250f1ce60..7db3d9a1e 100644 --- a/src/components/ServiceDetails/index.js +++ b/src/components/ServiceDetails/index.js @@ -22,7 +22,6 @@ import { getIsTrainingAvailable, } from "../../Redux/actionCreators/ServiceDetailsActions"; import { - pricing as getPricing, serviceDetails as getServiceDetails, groupInfo as getGroupInfo, } from "../../Redux/reducers/ServiceDetailsReducer"; @@ -52,7 +51,6 @@ const ServiceDetails = ({ classes }) => { const detailsTraining = useSelector((state) => state.serviceDetailsReducer.detailsTraining); const service = useSelector((state) => getServiceDetails(state, orgId, serviceId)); const groupInfo = useSelector((state) => getGroupInfo(state)); - const pricing = useSelector((state) => getPricing(state)); const loading = useSelector((state) => state.loaderReducer.app.loading); const [activeTab, setActiveTab] = useState(tabId ? tabId : 0); @@ -69,7 +67,7 @@ const ServiceDetails = ({ classes }) => { dispatch(fetchServiceDetails(orgId, serviceId)); } dispatch(fetchTrainingModel(orgId, serviceId)); - }, [dispatch]); + }, [dispatch, orgId, serviceId, service]); const handleTabChange = (activeTab) => { if (window.location.href.indexOf("#demo") > -1) { @@ -177,7 +175,7 @@ const ServiceDetails = ({ classes }) => { totalRating={service.service_rating ? service.service_rating.total_users_rated : 0} shortDescription={service.short_description} /> - +
    diff --git a/src/components/UserProfile/UserProfileAccount/MetamaskDetails/MetamaskDetails.js b/src/components/UserProfile/UserProfileAccount/MetamaskDetails/MetamaskDetails.js index 94b248686..1affd59b0 100644 --- a/src/components/UserProfile/UserProfileAccount/MetamaskDetails/MetamaskDetails.js +++ b/src/components/UserProfile/UserProfileAccount/MetamaskDetails/MetamaskDetails.js @@ -1,9 +1,8 @@ -import React, { useEffect, useState } from "react"; +import React, { useCallback, useEffect, useState } from "react"; import { useDispatch, useSelector } from "react-redux"; import { withStyles } from "@mui/styles"; import { useStyles } from "./styles"; -import InfoIcon from "@mui/icons-material/Info"; import { cogsToAgi } from "../../../../utility/PricingStrategy"; import { loaderActions, sdkActions } from "../../../../Redux/actionCreators"; import { LoaderContent } from "../../../../utility/constants/LoaderContent"; @@ -20,14 +19,7 @@ const MetamaskDetails = ({ classes }) => { const currentNetwork = Networks[process.env.REACT_APP_ETH_NETWORK]; - useEffect(() => { - const getAccountDetails = async () => { - await retrieveAccountDetails(); - }; - getAccountDetails(); - }, [wallet]); - - const retrieveAccountDetails = async () => { + const retrieveAccountDetails = useCallback(async () => { try { dispatch(loaderActions.startAppLoader(LoaderContent.FETCH_MM_ACC_DETAILS)); const sdk = await dispatch(sdkActions.getSdk()); @@ -37,39 +29,42 @@ const MetamaskDetails = ({ classes }) => { setEscrowBalance(cogsToAgi(escrowBalance)); setTokenBalance(cogsToAgi(tokenBalance)); } catch (error) { - console.log("error: ", error); + console.error("error: ", error); setAlert({ type: alertTypes.ERROR, message: `Unable to fetch account details` }); } finally { dispatch(loaderActions.stopAppLoader()); } - }; + }, [dispatch]); + + useEffect(() => { + const getAccountDetails = async () => { + await retrieveAccountDetails(); + }; + getAccountDetails(); + }, [wallet, retrieveAccountDetails]); return (
    - Current Network
    {currentNetwork} Network
    - Wallet ID
    {wallet.address}
    - Total Tokens
    {tokenBalance} AGIX
    - Escrow Balance
    {escrowBalance} AGIX diff --git a/src/components/UserProfile/UserProfileAccount/MetamaskDetails/styles.js b/src/components/UserProfile/UserProfileAccount/MetamaskDetails/styles.js index b6177fae0..eff0e2200 100644 --- a/src/components/UserProfile/UserProfileAccount/MetamaskDetails/styles.js +++ b/src/components/UserProfile/UserProfileAccount/MetamaskDetails/styles.js @@ -1,6 +1,5 @@ export const useStyles = (theme) => ({ accountDetails: { - marginTop: 32, boxSizing: "border-box", "& div": { display: "flex", diff --git a/src/components/UserProfile/UserProfileAccount/ProviderBalance/ChannelList/index.js b/src/components/UserProfile/UserProfileAccount/ProviderBalance/ChannelList/index.js index fea700d44..b8c3ab53b 100644 --- a/src/components/UserProfile/UserProfileAccount/ProviderBalance/ChannelList/index.js +++ b/src/components/UserProfile/UserProfileAccount/ProviderBalance/ChannelList/index.js @@ -21,18 +21,16 @@ const ChannelList = ({ classes, linkedProviders }) => { {linkedProviders.map((provider) => { - const { org_name, hero_image, groups } = provider; + const { org_name, org_id, hero_image, groups } = provider; const firstGroup = groups[0]; const firstChannel = firstGroup && firstGroup.channels[0]; const balance_in_cogs = firstChannel && firstChannel.balance_in_cogs; return ( - +
    -
    - {org_name} -
    + {org_name}
    diff --git a/src/components/UserProfile/UserProfileAccount/ProvidersLinkedCount/index.js b/src/components/UserProfile/UserProfileAccount/ProvidersLinkedCount/index.js index cb8bf362e..f06f747d9 100644 --- a/src/components/UserProfile/UserProfileAccount/ProvidersLinkedCount/index.js +++ b/src/components/UserProfile/UserProfileAccount/ProvidersLinkedCount/index.js @@ -1,6 +1,5 @@ import React from "react"; import { withStyles } from "@mui/styles"; -import InfoIcon from "@mui/icons-material/Info"; import Typography from "@mui/material/Typography"; import { useStyles } from "./styles"; @@ -9,7 +8,6 @@ const ProvidersLinkedCount = ({ classes, providerCount = 0 }) => { return (
    - Total providers linked
    {providerCount}
    diff --git a/src/components/UserProfile/UserProfileAccount/index.js b/src/components/UserProfile/UserProfileAccount/index.js index 50a021cb7..73695babe 100644 --- a/src/components/UserProfile/UserProfileAccount/index.js +++ b/src/components/UserProfile/UserProfileAccount/index.js @@ -60,7 +60,7 @@ const UserProfileAccount = ({ classes }) => { return window.ethereum; }; - const fetchWallets = async () => { + const fetchWallets = useCallback(async () => { try { const currentAddress = await getWeb3Address(); const wallets = await getWallets(currentAddress); @@ -70,17 +70,17 @@ const UserProfileAccount = ({ classes }) => { setCurrentAddress(""); setWallets([]); } - }; + }, [getWallets]); useEffect(() => { const ethereumProvider = getEthereumProvider(); ethereumProvider.addListener(ON_ACCOUNT_CHANGE, fetchWallets); return () => ethereumProvider.removeListener(ON_ACCOUNT_CHANGE, fetchWallets); - }, []); + }, [fetchWallets]); useEffect(() => { fetchWallets(); - }, [dispatch]); + }, [fetchWallets]); useEffect(() => { const getProviders = async () => { diff --git a/src/components/common/AlertBox/index.js b/src/components/common/AlertBox/index.js index ae79ffb3c..9c792af1d 100644 --- a/src/components/common/AlertBox/index.js +++ b/src/components/common/AlertBox/index.js @@ -20,10 +20,10 @@ const backgroundColor = { info: alertTypes.INFO, }; -const AlertBox = ({ classes, message, type = alertTypes.ERROR, link }) => { +const AlertBox = ({ classes, className, message, type = alertTypes.ERROR, link }) => { if (message) { return ( -

    +

    {message}

    ); diff --git a/src/components/common/RatingsCount/index.js b/src/components/common/RatingsCount/index.js index ef9c75edd..5f1149661 100644 --- a/src/components/common/RatingsCount/index.js +++ b/src/components/common/RatingsCount/index.js @@ -15,8 +15,8 @@ const RatingsCount = ({ ratingGiven, totalRating }) => { }; RatingsCount.propTypes = { - ratingGiven: PropTypes.number, - totalRating: PropTypes.number, + ratingGiven: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), + totalRating: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), }; export default RatingsCount; diff --git a/src/utility/constants/LoaderContent.js b/src/utility/constants/LoaderContent.js index 72972f632..c4b9fa93d 100644 --- a/src/utility/constants/LoaderContent.js +++ b/src/utility/constants/LoaderContent.js @@ -23,6 +23,10 @@ export const LoaderContent = { loaderHeader: "Forgot Password Submit", loaderText: "Resetting your password", }, + FREE_CALLS_GETTING: { + loaderHeader: "Fetching Free Calls", + loaderText: "Please wait while we fetch the free call details", + }, FETCH_SERVICE_DETAILS: { loaderHeader: "Fetching Service Details", loaderText: "Please wait while we fetch the service details", diff --git a/src/utility/sdk.js b/src/utility/sdk.js index 595659402..f385735eb 100644 --- a/src/utility/sdk.js +++ b/src/utility/sdk.js @@ -9,6 +9,7 @@ import { store } from "../"; import ProxyPaymentChannelManagementStrategy from "./ProxyPaymentChannelManagementStrategy"; import { isEmpty, isUndefined } from "lodash"; import Web3 from "web3"; +import { ethereumMethods } from "./snetSdk"; const DEFAULT_GAS_PRICE = 4700000; const DEFAULT_GAS_LIMIT = 210000; @@ -193,7 +194,6 @@ const clearSdk = () => { const addListenersForWeb3 = () => { window.ethereum.addListener(ON_ACCOUNT_CHANGE, async (accounts) => { - console.log("ON_ACCOUNT_CHANGE"); await getWeb3Address(); clearSdk(); const event = new CustomEvent("snetMMAccountChanged", { bubbles: true, details: accounts[0] }); @@ -208,7 +208,7 @@ const addListenersForWeb3 = () => { export const getWeb3Address = async () => { defineWeb3Provider(); - await window.ethereum.enable(); + await window.ethereum.request({ method: ethereumMethods.REQUEST_ACCOUNTS }); const isExpectedNetwork = await isUserAtExpectedEthereumNetwork(); if (!isExpectedNetwork) {