diff --git a/src/components/ServiceDetails/AboutService/index.js b/src/components/ServiceDetails/AboutService/index.js
index f90dc4b63..2de424edd 100644
--- a/src/components/ServiceDetails/AboutService/index.js
+++ b/src/components/ServiceDetails/AboutService/index.js
@@ -1,8 +1,7 @@
-import React from "react";
+import React, { useEffect, useState } from "react";
import Grid from "@material-ui/core/Grid";
import { withStyles } from "@material-ui/styles";
import { connect } from "react-redux";
-
import { useStyles } from "./styles";
import DemoToggler from "./DemoToggler";
import ServiceOverview from "./ServiceOverview";
@@ -10,6 +9,10 @@ import CreatorDetails from "../CreatorDetails";
import ProjectDetails from "../ProjectDetails";
import MediaGallery from "../MediaGallery";
import PromoBox from "./PromoBox";
+import ExistingModel from "../ExistingModel";
+import { alertTypes } from "../../common/AlertBox";
+import { LoaderContent } from "../../../utility/constants/LoaderContent";
+import { loaderActions, userActions } from "../../../Redux/actionCreators";
const AboutService = ({
classes,
@@ -20,10 +23,18 @@ const AboutService = ({
demoExampleRef,
scrollToView,
demoComponentRequired,
+ haveANewModel
}) => {
+ const RenderExistingModel = () => {
+ if (process.env.REACT_APP_TRAINING_ENABLE === "true") {
+ return
;
+ }
+ return null;
+ };
+
return (
-
+
+
-
+
({
isLoggedIn: state.userReducer.login.isLoggedIn,
+ wallet: state.userReducer.wallet,
+});
+
+const mapDispatchToProps = dispatch => ({
+ startMMconnectLoader: () => dispatch(loaderActions.startAppLoader(LoaderContent.CONNECT_METAMASK)),
+ updateWallet: ({ type, address }) => dispatch(userActions.updateWallet({ type, address })),
+ registerWallet: (address, type) => dispatch(userActions.registerWallet(address, type)),
+ fetchAvailableUserWallets: () => dispatch(userActions.fetchAvailableUserWallets()),
+ stopLoader: () => dispatch(loaderActions.stopAppLoader),
});
-export default connect(mapStateToProps)(withStyles(useStyles)(AboutService));
+export default connect(mapStateToProps, mapDispatchToProps)(withStyles(useStyles)(AboutService));
diff --git a/src/components/ServiceDetails/AboutService/styles.js b/src/components/ServiceDetails/AboutService/styles.js
index 1046d2490..3cd16bc53 100644
--- a/src/components/ServiceDetails/AboutService/styles.js
+++ b/src/components/ServiceDetails/AboutService/styles.js
@@ -14,25 +14,14 @@ export const useStyles = theme => ({
fontSize: 20,
fontWeight: 400,
},
- "@media(max-width:768px)": {
- padding: " 20px 10px 0",
- position: "relative",
- flexDirection: "column",
- },
},
leftSideSection: {
paddingRight: 25,
- "@media(max-width:768px)": {
+ "@media(max-width:960px)": {
maxWidth: "100%",
paddingRight: 0,
},
},
- rightSideSection: {
- "@media(max-width:768px)": {
- maxWidth: "100%",
- marginTop: 25,
- },
- },
overViewContainer: {
boxShadow: "0 1px 1px 0 rgba(0,0,0,0.07), 0 2px 1px -1px rgba(0,0,0,0.07), 0 1px 3px 0 rgba(0,0,0,0.1)",
backgroundColor: theme.palette.text.white,
@@ -294,4 +283,13 @@ export const useStyles = theme => ({
"@media(max-width:768px)": { display: "block" },
},
showOnNrmalResolution: { "@media(max-width:768px)": { display: "none" } },
+ connectMatamaskContainer: {
+ textAlign: "center",
+ "& button": {
+ marginTop: 20,
+ marginBottom: 36,
+ marginRight: "0 !important",
+ paddingBottomg: 15,
+ },
+ },
});
diff --git a/src/components/ServiceDetails/ConnectMetamask/index.js b/src/components/ServiceDetails/ConnectMetamask/index.js
new file mode 100644
index 000000000..c8fcd8474
--- /dev/null
+++ b/src/components/ServiceDetails/ConnectMetamask/index.js
@@ -0,0 +1,18 @@
+import React from "react";
+import { withStyles } from "@material-ui/styles";
+import StyledButton from "../../common/StyledButton";
+import MetamaskImg from "../../../assets/images/Metamask.png";
+import { useStyles } from "./styles";
+
+const ConnectMetamask = ({ classes, handleConnectMM }) => {
+ return (
+
+
+
Metamask
+
Connect to your Metamask Wallet
+
+
+ );
+};
+
+export default withStyles(useStyles)(ConnectMetamask);
diff --git a/src/components/ServiceDetails/ConnectMetamask/styles.js b/src/components/ServiceDetails/ConnectMetamask/styles.js
new file mode 100644
index 000000000..d3c3a5220
--- /dev/null
+++ b/src/components/ServiceDetails/ConnectMetamask/styles.js
@@ -0,0 +1,25 @@
+export const useStyles = theme => ({
+ connectMMContainer: {
+ width: '100%',
+ padding: '80px 0',
+ margin: '0 auto',
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ textAlign: 'center',
+ '& > span': {
+ marginTop: 24,
+ color: theme.palette.text.primary,
+ fontSize: 18,
+ lineHeight: '23px'
+ },
+ '& p': {
+ margin: '9px 0',
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: '24px'
+ }
+ }
+ });
+
\ No newline at end of file
diff --git a/src/components/ServiceDetails/ExistingModel/ModelDetails/index.js b/src/components/ServiceDetails/ExistingModel/ModelDetails/index.js
new file mode 100644
index 000000000..b63390dc1
--- /dev/null
+++ b/src/components/ServiceDetails/ExistingModel/ModelDetails/index.js
@@ -0,0 +1,97 @@
+import React from "react";
+import { withStyles } from "@material-ui/styles";
+
+import { useStyles } from "./styles";
+import Button from "@material-ui/core/Button";
+import EditIcon from "@material-ui/icons/Edit";
+import DeleteIcon from "@material-ui/icons/Delete";
+import NearMeOutlinedIcon from "@material-ui/icons/NearMeOutlined";
+import Box from "@material-ui/core/Box";
+import Typography from "@material-ui/core/Typography";
+import Modal from "@material-ui/core/Modal";
+import StyledButton from "../../../common/StyledButton";
+
+const ModelDetails = ({ classes, title, id, description, status, accessTo, lastUpdate }) => {
+ const [open, setOpen] = React.useState(false);
+ const handleOpenModal = () => setOpen(true);
+ const handleCloseModal = () => setOpen(false);
+ const handleDeleteModel = () => {
+ setOpen(false);
+ }
+ return (
+ <>
+
+
+
{title}
+
+ Model id: {id}
+
+
+
{description}
+
+
+
+ Status: {status}
+
+
+ Access:
+ {/* { */}
+ {/* accessTo === 'limited' ? */}
+ <>
+ limited(4)
+
+ 90986239898
+ 90986239898
+ 90986239898
+ 90986239898
+
+ >
+ {/* :
{accessTo} */}
+ {/* } */}
+
+
+
Last update: {lastUpdate}
+
+
+
+
+
+ Update
+
+
+
+ Test
+
+
+
+
+ Delete
+
+
+
+
+
+
+ Are you sure you want to delete this ?{" "}
+
+
+ Are you sure you want ot delete ”Region Recognition” model? This action cannot be undone and you model will
+ be unable to recover.
+
+
+
+
+
+
+
+ >
+ );
+};
+
+export default withStyles(useStyles)(ModelDetails);
diff --git a/src/components/ServiceDetails/ExistingModel/ModelDetails/styles.js b/src/components/ServiceDetails/ExistingModel/ModelDetails/styles.js
new file mode 100644
index 000000000..65fa1229f
--- /dev/null
+++ b/src/components/ServiceDetails/ExistingModel/ModelDetails/styles.js
@@ -0,0 +1,166 @@
+const modelStatus = {
+ IN_PROGRESS: "IN_PROGRESS",
+ PUBLISHED: "PUBLISHED",
+};
+export const useStyles = theme => ({
+ modelDetailsContainer: {
+ padding: "21px 21px 16px 22px",
+ border: "1px solid #ECECEC",
+ borderRadius: 4,
+ margin: '17px 23px 24px',
+ backgroundColor: theme.palette.text.gray1,
+ "& p": {
+ padding: "8px 0 16px",
+ margin: 0,
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "18px",
+ },
+ '&:last-of-type': { marginBottom: 0 }
+ },
+ titleIdContainer: {
+ display: "flex",
+ justifyContent: "space-between",
+ alignItems: "center",
+ "& h3": {
+ margin: 0,
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 18,
+ lineHeight: "23px",
+ },
+ "& p": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 14,
+ fontWeight: 400,
+ lineHeight: "18px",
+ "& span": {
+ color: theme.palette.text.mediumShadeGray,
+ },
+ },
+ },
+ statusAccessLastUpdateContainer: {
+ display: "flex",
+ justifyContent: "space-between",
+ alignItems: "center",
+ "& > div": {
+ width: "60%",
+ display: "flex",
+ alignItems: "center",
+ "& p": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 12,
+ fontWeight: "bold",
+ lineHeight: "15px",
+ "& span": { color: theme.palette.text.mediumShadeGray },
+ [`& span[data-status-type="${modelStatus.IN_PROGRESS}"]`]: { color: "#2CB7CF" },
+ [`& span[data-status-type="${modelStatus.PUBLISHED}"]`]: { color: "#0B8E1C" },
+ "&:first-of-type": { paddingRight: "5%" },
+ },
+ },
+ "& > p": {
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 12,
+ lineHeight: "15px",
+ },
+ "@media(max-width: 520px)": {
+ flexDirection: "column",
+ alignItems: "flex-start",
+ },
+ },
+ actionButtons: {
+ paddingTop: 16,
+ borderTop: "1px solid #ececec",
+ display: "flex",
+ justifyContent: "space-between",
+ alignItems: "center",
+ "& svg": {
+ paddingRight: 4,
+ fontSize: 18,
+ },
+ "& span": {
+ fontSize: 14,
+ letterSpacing: 1.3,
+ lineHeight: "18px",
+ textTransform: "capitalize",
+ },
+ },
+ updateBtn: { color: theme.palette.text.darkShadedGray },
+ testBtn: { color: theme.palette.text.primary },
+ deleteBtn: { color: theme.palette.text.redBtnText },
+ deleteModalContent: {
+ width: 580,
+ padding: "30px 22px 24px",
+ borderRadius: 4,
+ position: "absolute",
+ top: "50%",
+ left: "50%",
+ boxShadow: "0 0 2px 0 rgba(0,0,0,0.15), 0 1px 2px 0 rgba(0,0,0,0.15)",
+ backgroundColor: theme.palette.text.white,
+ transform: "translate(-50%, -50%)",
+ "& h2": {
+ color: theme.palette.text.darkShadedGray,
+ fontFamily: "Muli",
+ fontSize: 20,
+ fontWeight: 600,
+ lineHeight: "25px",
+ },
+ "& p": {
+ margin: "8px 0 24px",
+ color: theme.palette.text.mediumShadeGray,
+ fontFamily: "Muli",
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "24px",
+ },
+ "@media(max-width: 600px)": { width: "100%" },
+ },
+ deleteModalActions: {
+ textAlign: "right",
+ "& button": {
+ textTransform: "initial",
+ letterSpacing: 1.3,
+ fontWeight: 400,
+ "&:last-of-type": {
+ backgroundColor: theme.palette.text.redBtnText,
+ "&:hover": { backgroundColor: theme.palette.text.redBtnBg },
+ },
+ },
+ },
+ accessValue: {
+ position: "relative",
+ "& span": {
+ "&:hover": {
+ "& + ul": { display: "block" },
+ },
+ },
+ "& ul": {
+ margin: "7px 0 0",
+ padding: "5px 12px 10px 11px",
+ display: "none",
+ position: "absolute",
+ left: "50%",
+ transform: "translateX(-10%)",
+ zIndex: 1,
+ background: "#333",
+ color: theme.palette.text.white,
+ fontWeight: 400,
+ listStyle: "none",
+ "& li": {
+ paddingBottom: 5,
+ "&:last-of-type": { paddingBottom: 0 },
+ },
+ "&::after": {
+ content: '" "',
+ position: "absolute",
+ left: "50%",
+ top: -7,
+ transform: "translateX(-50%)",
+ borderTop: "none",
+ borderRight: "7px solid transparent",
+ borderLeft: "7px solid transparent",
+ borderBottom: "7px solid #333",
+ },
+ },
+ },
+});
diff --git a/src/components/ServiceDetails/ExistingModel/index.js b/src/components/ServiceDetails/ExistingModel/index.js
new file mode 100644
index 000000000..029976b03
--- /dev/null
+++ b/src/components/ServiceDetails/ExistingModel/index.js
@@ -0,0 +1,97 @@
+import React, { useEffect, useState } from "react";
+import { connect } from "react-redux";
+import Web3 from "web3";
+import { withStyles } from "@material-ui/styles";
+import ModelDetails from "./ModelDetails";
+import StyledButton from "../../common/StyledButton";
+import { useStyles } from "./styles";
+import ConnectMetamask from "../ConnectMetamask";
+import { initSdk } from "../../../utility/sdk";
+import { walletTypes } from "../../../Redux/actionCreators/UserActions";
+import { alertTypes } from "../../common/AlertBox";
+import { loaderActions, userActions } from "../../../Redux/actionCreators";
+import { LoaderContent } from "../../../utility/constants/LoaderContent";
+
+const web3 = new Web3(process.env.REACT_APP_WEB3_PROVIDER, null, {});
+
+const ExistingModel = ({ classes, showReqNewModelBtn, startMMconnectLoader, fetchAvailableUserWallets, stopLoader, registerWallet, updateWallet, wallet,training,haveANewModel }) => {
+ const [metamaskConnected, setMetamaskConnected] = useState(false);
+ const [alert, setAlert] = useState({});
+ useEffect(() => {
+ if (wallet.address) {
+ setMetamaskConnected(true);
+ generateSignature(wallet.address);
+ }
+ }, [wallet]);
+
+ const generateSignature = async address => {
+ const currentBlockNumber = await web3.eth.getBlockNumber();
+ const sha3Message = await web3.utils.soliditySha3(
+ { type: "string", value: "Signature for existing models" },
+ { type: "string", value: address },
+ { type: "uint64", value: currentBlockNumber }
+ );
+ const { signature } = await web3.eth.accounts.sign(sha3Message, address);
+ console.log({ signature });
+ };
+
+ const handleConnectMM = async () => {
+ try {
+ startMMconnectLoader();
+ const sdk = await initSdk();
+ const address = await sdk.account.getAddress();
+ const availableUserWallets = await fetchAvailableUserWallets();
+ const addressAlreadyRegistered = availableUserWallets.some(wallet => wallet.address.toLowerCase() === address);
+
+ if (!addressAlreadyRegistered) {
+ await registerWallet(address, walletTypes.METAMASK);
+ }
+ updateWallet({ type: walletTypes.METAMASK, address });
+ setMetamaskConnected(true)
+ } catch (error) {
+ setAlert({ type: alertTypes.ERROR, message: error.message });
+ }
+ stopLoader();
+ };
+
+ return (
+
+
Existing Model
+ {
+ metamaskConnected ? (
+ <>
+
+ {showReqNewModelBtn && (haveANewModel === true) ?
+
+
+
+ : null }
+ >
+ ) : (
+
+ )
+ }
+
+ );
+};
+
+const mapStateToProps = state => ({
+ wallet: state.userReducer.wallet,
+});
+
+const mapDispatchToProps = dispatch => ({
+ startMMconnectLoader: () => dispatch(loaderActions.startAppLoader(LoaderContent.CONNECT_METAMASK)),
+ fetchAvailableUserWallets: () => dispatch(userActions.fetchAvailableUserWallets()),
+ registerWallet: (address, type) => dispatch(userActions.registerWallet(address, type)),
+ updateWallet: ({ type, address }) => dispatch(userActions.updateWallet({ type, address })),
+ stopLoader: () => dispatch(loaderActions.stopAppLoader),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(withStyles(useStyles)(ExistingModel));
diff --git a/src/components/ServiceDetails/ExistingModel/styles.js b/src/components/ServiceDetails/ExistingModel/styles.js
new file mode 100644
index 000000000..d55a1a496
--- /dev/null
+++ b/src/components/ServiceDetails/ExistingModel/styles.js
@@ -0,0 +1,48 @@
+export const useStyles = theme => ({
+ existingModelContainer: {
+ paddingBottom: 24,
+ borderRadius: 4,
+ margin: '25px 0 0',
+ boxShadow: "0 1px 1px 0 rgba(0,0,0,0.07), 0 2px 1px -1px rgba(0,0,0,0.07), 0 1px 3px 0 rgba(0,0,0,0.1)",
+ backgroundColor: theme.palette.text.white,
+ "& h2": {
+ padding: "11px 22px",
+ borderBottomWidth: 1,
+ borderBottomStyle: "solid",
+ borderBottomColor: theme.palette.text.gray1,
+ margin: 0,
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 20,
+ fontWeight: 400,
+ },
+ "@media(max-width:768px)": {
+ padding: "17px 22px",
+ flexDirection: "column",
+ },
+ },
+ btnContainer: {
+ textAlign: 'center',
+ },
+ connectMMContainer: {
+ width: '100%',
+ padding: '80px 0',
+ margin: '0 auto',
+ display: 'flex',
+ flexDirection: 'column',
+ alignItems: 'center',
+ textAlign: 'center',
+ '& > span': {
+ marginTop: 24,
+ color: theme.palette.text.primary,
+ fontSize: 18,
+ lineHeight: '23px'
+ },
+ '& p': {
+ margin: '9px 0',
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: '24px'
+ }
+ }
+});
diff --git a/src/components/ServiceDetails/InstallAndRunService/styles.js b/src/components/ServiceDetails/InstallAndRunService/styles.js
index 29da687ff..1bde2b59d 100644
--- a/src/components/ServiceDetails/InstallAndRunService/styles.js
+++ b/src/components/ServiceDetails/InstallAndRunService/styles.js
@@ -72,6 +72,7 @@ export const useStyles = theme => ({
borderRadius: 4,
boxShadow: "0 1px 1px 0 rgba(0,0,0,0.07), 0 2px 1px -1px rgba(0,0,0,0.07), 0 1px 3px 0 rgba(0,0,0,0.1)",
backgroundColor: theme.palette.text.white,
+ "@media(max-width:960px)": { marginRight: 0 }
},
integrationContent: {
minHeight: 500,
diff --git a/src/components/ServiceDetails/ProjectDetails/styles.js b/src/components/ServiceDetails/ProjectDetails/styles.js
index ce77e8cb6..19a420437 100644
--- a/src/components/ServiceDetails/ProjectDetails/styles.js
+++ b/src/components/ServiceDetails/ProjectDetails/styles.js
@@ -4,6 +4,16 @@ export const useStyles = theme => ({
padding: "0 14px 25px 0",
borderRadius: 4,
backgroundColor: theme.palette.text.white,
+ "& h2": {
+ padding: "12px 22px",
+ borderBottomWidth: 1,
+ borderBottomStyle: "solid",
+ borderBottomColor: theme.palette.text.gray1,
+ margin: 0,
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 20,
+ fontWeight: 400,
+ },
"& h3": { marginBottom: 15 },
"& > div": {
paddingLeft: 30,
@@ -35,6 +45,7 @@ export const useStyles = theme => ({
},
"&:last-of-type": { marginBottom: 0 },
},
+ "@media(max-width:960px)": { marginTop: 25 }
},
projectDetailsHeadings: { width: "35%" },
projectDetailsValue: {
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/CreateModelContainer.js b/src/components/ServiceDetails/TrainingModels/CreateModel/CreateModelContainer.js
new file mode 100644
index 000000000..d7addbbb9
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/CreateModelContainer.js
@@ -0,0 +1,17 @@
+import React, { Fragment } from "react";
+
+import ProgressBar from "../../../common/ProgressBar";
+
+const CreateModelContainer = ({ item, active, activeSection, progressText }) => {
+ if (!active) {
+ return null;
+ }
+ return (
+
+
+ {item.component}
+
+ );
+};
+
+export default CreateModelContainer;
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/UploadFromLink.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/UploadFromLink.js
new file mode 100644
index 000000000..f69055868
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/UploadFromLink.js
@@ -0,0 +1,45 @@
+import React, { Fragment } from "react";
+import { withStyles, styled } from "@material-ui/styles";
+import InputBase from "@material-ui/core/InputBase";
+import SubdirectoryArrowLeftIcon from "@material-ui/icons/SubdirectoryArrowLeft";
+import { useStyles } from "./styles";
+
+const Search = styled("div")(({ theme }) => ({
+ padding: "9px 17px 9px 14px",
+ border: "1px solid #C4C4C4",
+ borderRadius: 4,
+ display: "flex",
+ justifyContent: "space-between",
+ alignItems: 'center',
+ backgroundColor: theme.palette.text.white,
+ // [theme.breakpoints.up("sm")]: {
+ // marginLeft: theme.spacing(1),
+ // width: "auto",
+ // },
+}));
+
+const SearchIconWrapper = styled("div")(({ theme }) => ({
+ color: theme.palette.text.primary,
+}));
+
+const StyledInputBase = styled(InputBase)(({ theme }) => ({
+ width: "100%",
+ color: "#666",
+ fontSize: 14,
+}));
+
+const UploadFromLink = ({ classes }) => {
+ return (
+
+
+
+
+
+
+
+
Link should only include sample data file, other files will be rejected automatically.
+
+ );
+};
+
+export default withStyles(useStyles)(UploadFromLink);
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/index.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/index.js
new file mode 100644
index 000000000..95bbdc6e6
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/index.js
@@ -0,0 +1,10 @@
+import React from "react";
+import { withStyles } from "@material-ui/styles";
+import UploadFromLink from "./UploadFromLink";
+import { useStyles } from "./styles";
+
+const Data = () => {
+ return ;
+};
+
+export default withStyles(useStyles)(Data);
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/styles.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/styles.js
new file mode 100644
index 000000000..1924f6adb
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/Upload/styles.js
@@ -0,0 +1,76 @@
+export const useStyles = theme => ({
+ appBar: {
+ marginTop: 24,
+ backgroundColor: theme.palette.text.white,
+ boxShadow: "none",
+ },
+ tabsContainer: {
+ "& .MuiTab-textColorPrimary.Mui-selected": { color: theme.palette.text.primary },
+ "& .MuiTabs-indicator": { backgroundColor: theme.palette.text.primary },
+ },
+ tab: {
+ padding: 0,
+ letterSpacing: 0.54,
+ textTransform: "capitalize",
+ },
+ uploadFromLinkContainer: {
+ padding: "60px 64px",
+ border: "1px dashed #D6D6D6",
+ borderRadius: 4,
+ margin: "16px 0 40px",
+ backgroundColor: "#F5F5F5",
+ "& p": {
+ margin: "8px 0 0",
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 12,
+ fontWeight: 300,
+ lineHeight: "24px",
+ },
+ },
+ uploadFromSystemContainer: {
+ boxSizing: 'border-box',
+ width: "100%",
+ padding: "60px 64px 24px",
+ border: "1px dashed #D6D6D6",
+ borderRadius: 4,
+ marginTop: 16,
+ backgroundColor: "#F5F5F5",
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center",
+ "& > svg": {
+ color: theme.palette.text.primary,
+ fontSize: 42,
+ },
+ "& span": {
+ margin: "16px 0",
+ display: "block",
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ "& a": {
+ color: theme.palette.text.primary,
+ textDecoration: "none",
+ },
+ },
+ "& p": {
+ margin: 0,
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 12,
+ fontWeight: 300,
+ lineHeight: "24px",
+ },
+ "& div": {
+ width: 474,
+ padding: '8px 15px',
+ marginTop: 24,
+ display: "flex",
+ justifyContent: "space-between",
+ alignItems: 'center',
+ backgroundColor: theme.palette.text.white,
+ '& svg': {
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 16,
+ }
+ },
+ },
+});
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Data/index.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/index.js
new file mode 100644
index 000000000..79136990a
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/index.js
@@ -0,0 +1,34 @@
+import React, { Fragment } from "react";
+import { withStyles } from "@material-ui/styles";
+import Upload from "./Upload";
+import StyledButton from "../../../../common/StyledButton";
+import fileDownload from "../../../../../assets/images/fileDownload.svg";
+import { useStyles } from "./styles";
+
+const Data = ({ classes, handleNextClick }) => {
+ return (
+
+
+
Creating your dataset
+
+ This AI requires a certain type of data set for Model trainng. Download sample data from following and submit.
+
+
+
+
filename.zip
+
+
+
+
+ Upload your dataset
+
+
+
+
+
+
+
+ );
+};
+
+export default withStyles(useStyles)(Data);
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Data/styles.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/styles.js
new file mode 100644
index 000000000..c6225146f
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Data/styles.js
@@ -0,0 +1,53 @@
+export const useStyles = theme => ({
+ modelDataContaienr: { padding: "60px 33px 24px 24px" },
+ createDatasetContainer: {
+ "& > span": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 14,
+ lineHeight: "18px",
+ },
+ "& p": {
+ margin: "8px 0 40px",
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "24px",
+ },
+ "& div": {
+ width: 180,
+ paddingTop: 30,
+ borderRadius: 4,
+ margin: "0 auto",
+ backgroundColor: theme.palette.text.white,
+ boxShadow: "0 0 2px 0 rgba(0,0,0,0.15), 0 1px 2px 0 rgba(0,0,0,0.15)",
+ textAlign: "center",
+ "& > span": {
+ margin: '13px 0 16px',
+ display: 'block',
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 12,
+ fontWeight: 300,
+ lineHeight: "15px",
+ },
+ '& button': {
+ width: '100%',
+ padding: '11px 18px',
+ borderRadius: 0,
+ '& span': { textTransform: 'capitalize' }
+ }
+ },
+ },
+ uploadDatasetContainer: {
+ marginTop: 40,
+ '& > span': {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 14,
+ fontWeight: 'bold',
+ lineHeight: '18px',
+ }
+ },
+ btnContainer: {
+ marginTop: 40,
+ textAlign: 'center'
+ }
+});
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Finish/index.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Finish/index.js
new file mode 100644
index 000000000..3b724a39d
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Finish/index.js
@@ -0,0 +1,30 @@
+import React from "react";
+import { Link } from "react-router-dom";
+
+import { withStyles } from "@material-ui/styles";
+import CheckCircleIcon from "@material-ui/icons/CheckCircle";
+
+import { userProfileRoutes } from "../../../../UserProfile";
+import { useStyles } from "./styles";
+import StyledButton from "../../../../common/StyledButton";
+
+const Payment = ({ classes }) => {
+ return (
+
+
+
Training Request Submitted
+
Your model request has been submitted and will be processed soon.
+
+ Model Request Reference ID: 231212
+
+
+
+
+
+
+
+
+ );
+};
+
+export default withStyles(useStyles)(Payment);
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Finish/styles.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Finish/styles.js
new file mode 100644
index 000000000..68294a799
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Finish/styles.js
@@ -0,0 +1,49 @@
+export const useStyles = theme => ({
+ finishContaienr: {
+ margin: "68px 0 40px",
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center",
+ "& svg": {
+ marginBottom: 24,
+ fontSize: 80,
+ color: "#05C38C",
+ },
+ "& > span": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 20,
+ lineHeight: "25px",
+ },
+ "& p": {
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "24px",
+ "&:first-of-type": {
+ width: "33%",
+ margin: "6px 0 32px",
+ textAlign: "center",
+ },
+ "& span": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 14,
+ fontWeight: 800,
+ lineHeight: "24px",
+ },
+ },
+ },
+ btnContainer: {
+ marginTop: 32,
+ '& a': { textDecoration: 'none' },
+ "& button": {
+ "&:first-of-type": {
+ marginRight: 16,
+ '@media(max-width: 480px)': { marginBottom: 20 }
+ },
+ },
+ '@media(max-width: 480px)': {
+ display: 'flex',
+ flexDirection: 'column'
+ }
+ },
+});
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/ModelInfo/index.js b/src/components/ServiceDetails/TrainingModels/CreateModel/ModelInfo/index.js
new file mode 100644
index 000000000..8f355c52c
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/ModelInfo/index.js
@@ -0,0 +1,95 @@
+import React from "react";
+
+import FormControlLabel from "@material-ui/core/FormControlLabel";
+import Switch from "@material-ui/core/Switch";
+import { withStyles } from "@material-ui/styles";
+import DeleteOutlineIcon from "@material-ui/icons/DeleteOutline";
+import AddIcon from "@material-ui/icons/Add";
+
+import StyledDropdown from "../../../../common/StyledDropdown";
+import StyledTextField from "../../../../common/StyledTextField";
+import StyledButton from "../../../../common/StyledButton";
+import { useStyles } from "./styles";
+
+const ModelInfo = ({ classes, handleNextClick }) => {
+ const [enableAccessModel, setEnableAccessModel] = React.useState(false);
+ const [counter, setCounter] = React.useState(0);
+
+ const onAccessModelSwitchChange = () => {
+ setEnableAccessModel(!enableAccessModel);
+ };
+
+ const addInput = () => {
+ setCounter(counter + 1);
+ };
+
+ const handleDeleteEthAdd = (index) => {
+ console.log('delete')
+ }
+
+ return (
+
+
+
+
+ Please select a method to train as a first step.
+
+
+
+
+ The model name can't be more then 63 characters. It can only contain alphanumeric characters, with no spaces
+ or special characters.
+
+
+
+
+
+
+
+
+ }
+ />
+ Add a list ofaddress that can access this model.
+ {enableAccessModel ? (
+
+
Etherum addresses
+
+
+
+
+ {Array.from(Array(counter)).map((c, index) => {
+ return (
+
+
+
+
+ );
+ })}
+
+
+
Add another address
+
+
+ ) : null}
+
+
+
+
+
+ );
+};
+
+export default withStyles(useStyles)(ModelInfo);
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/ModelInfo/styles.js b/src/components/ServiceDetails/TrainingModels/CreateModel/ModelInfo/styles.js
new file mode 100644
index 000000000..a22a5b95b
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/ModelInfo/styles.js
@@ -0,0 +1,135 @@
+export const useStyles = theme => ({
+ modelInfoContaienr: {
+ padding: "61px 24px 24px",
+ },
+ switchToggle: {
+ width: 45,
+ height: 20,
+ padding: 0,
+ borderRadius: 25,
+ margin: 0,
+ '& > span': { padding: 0 },
+ '& + span': {
+ paddingLeft: 8,
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 14,
+ lineHeight: "18px",
+ },
+ "& .MuiSwitch-colorPrimary.Mui-checked": { color: theme.palette.text.white },
+ "& .MuiSwitch-colorPrimary.Mui-checked + .MuiSwitch-track": {
+ backgroundColor: theme.palette.text.primary,
+ opacity: 1,
+ },
+ "& .MuiSwitch-thumb": {
+ boxShadow: "none",
+ width: 16,
+ height: 16,
+ margin: 2,
+ },
+ },
+ trainingBasicDetails: {
+ marginTop: 27,
+ "& > div": {
+ display: "flex",
+ flexDirection: "column",
+ "& span": {
+ margin: "8px 0 24px",
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "24px",
+ },
+ },
+ },
+ methodDropBox: {
+ "& .MuiFormControl-root": {
+ width: 512,
+ '@media(max-width: 570px)': { width: '100%' }
+ },
+ "& .MuiFormLabel-root": {
+ padding: "0 15px 0 5px",
+ top: 7,
+ color: theme.palette.text.darkShadedGray,
+ backgroundColor: theme.palette.text.white,
+ },
+ "& .MuiSelect-root": {
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ lineHeight: "18px",
+ },
+ },
+ modelNameContainer: {
+ "& > div": {
+ width: 512,
+ margin: 0,
+ "& .MuiFormLabel-root": { color: theme.palette.text.darkShadedGray },
+ "& fieldset": { borderColor: "#c4c4c4" },
+ "& input": { color: theme.palette.text.darkShadedGray },
+ '@media(max-width: 570px)': { width: '100%' },
+ },
+ },
+ modelDescriptionContainer: {
+ "& > div": {
+ width: 512,
+ '@media(max-width: 570px)': { width: '100%' }
+ },
+ },
+ accessModelContainer: {
+ marginTop: 24,
+ display: "flex",
+ flexDirection: "column",
+ "& > span": {
+ marginLeft: 53,
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "24px",
+ },
+ },
+ ethAddresses: {
+ marginTop: 30,
+ display: "flex",
+ flexDirection: "column",
+ "& > span": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 14,
+ lineHeight: "18px",
+ },
+ },
+ ethAddTextBox: {
+ display: "flex",
+ alignItems: "center",
+ "& > div": {
+ width: 512,
+ margin: "12px 0 16px",
+ "& input": {
+ padding: "15.7px 14px",
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ '&::placeholder': {
+ color: theme.palette.text.mediumShadeGray,
+ opacity: 1
+ }
+ },
+ '@media(max-width: 570px)': { width: '100%' }
+ },
+ "& svg": {
+ marginLeft: 24,
+ color: theme.palette.text.redBtnText,
+ fontSize: 20,
+ },
+ },
+ addTextBox: {
+ marginTop: 24,
+ display: 'flex',
+ alignItems: 'center',
+ color: theme.palette.text.primary,
+ cursor: 'pointer',
+ '& svg': { fontSize: 20 },
+ '& span': { fontSize: 14 }
+ },
+ btnContainer: {
+ marginTop: 24,
+ textAlign: 'center'
+ }
+});
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentInfoCard.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentInfoCard.js
new file mode 100644
index 000000000..cf88c2487
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentInfoCard.js
@@ -0,0 +1,29 @@
+import React from "react";
+import { withStyles } from "@material-ui/styles";
+import InfoIcon from "@material-ui/icons/Info";
+
+import { useStyles } from "./styles";
+
+const PaymentInfoCard = ({ classes, title, value, unit, show }) => {
+ if (!show) {
+ return null;
+ }
+ return (
+
+
+
+
{title}
+
+
+
{value}
+ {unit ? AGIX : ""}
+
+
+ );
+};
+
+PaymentInfoCard.defaultProps = {
+ show: true,
+};
+
+export default withStyles(useStyles)(PaymentInfoCard);
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentMode.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentMode.js
new file mode 100644
index 000000000..449d12857
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/PaymentMode.js
@@ -0,0 +1,133 @@
+import React, { Component } from "react";
+import isEmpty from "lodash/isEmpty";
+import { connect } from "react-redux";
+
+import { withStyles } from "@material-ui/styles";
+import AccountBalanceWalletIcon from "@material-ui/icons/AccountBalanceWallet";
+import InfoIcon from "@material-ui/icons/Info";
+import Typography from "@material-ui/core/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 { initSdk } from "../../../../../utility/sdk";
+import { userActions } from "../../../../../Redux/actionCreators";
+import { anyPendingTxn, anyFailedTxn } from "../../../../../Redux/reducers/PaymentReducer";
+import WalletDetailsToggler from "../../../AboutService/ServiceDemo/Purchase/ExpiredSession/WalletDetailsToggler";
+import { useStyles } from "./styles";
+
+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 {
+
+ 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, stopWalletDetailsPolling } = this.props;
+ this.setState({ alert: {} });
+ if (value === walletTypes.METAMASK) {
+ try {
+ const selectedEthAddress = window.ethereum && window.ethereum.selectedAddress;
+ const sdk = await initSdk(selectedEthAddress);
+ 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 });
+ };
+ render() {
+ const { classes, wallet, handleComplete, groupInfo, handlePurchaseError, isServiceAvailable } = this.props;
+
+ const channelPaymentOptions = [
+ { value: walletTypes.GENERAL, label: "General Account Wallet" },
+ { 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),
+});
+
+const mapDispatchToProps = dispatch => ({
+ updateWallet: args => dispatch(userActions.updateWallet(args)),
+ registerWallet: (address, type) => dispatch(userActions.registerWallet(address, type)),
+ stopWalletDetailsPolling: () => dispatch(userActions.stopWalletDetailsPolling),
+});
+
+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
new file mode 100644
index 000000000..96cbc33b7
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/index.js
@@ -0,0 +1,117 @@
+import React from "react";
+import { withStyles } from "@material-ui/styles";
+import Grid from "@material-ui/core/Grid";
+import Typography from "@material-ui/core/Typography";
+import EditOutlinedIcon from "@material-ui/icons/EditOutlined";
+
+import { useStyles } from "./styles";
+import PaymentMode from "./PaymentMode";
+import StyledButton from "../../../../common/StyledButton";
+
+const Payment = ({ classes, handleNextClick }) => {
+
+ const addEllipsisAtEndOfString = str => `${str.substr(0, 40)}...`;
+
+ return (
+
+
+
Review request
+
+
+ Default Model:
+
+
+ Yes
+
+
+
+
+ Model name:
+
+
+
+ Animal detection
+
+
+
+
+
+
+ Model description:
+
+
+
+ Helping wildlife researchers in studying the wild animal species collectively and making strategies to
+ protect them. Artificial intelligence tracks wildlife patterns and predicts the extinction of endangered
+ animal species.
+
+
+
+
+
+
+ Data set name:
+
+
+
+ Butterflies & Caterpillers
+
+
+
+
+
+
+ Data files:
+
+
+
+
+ https://www.littlebigfiles.com/file234565432123454321.zip
+
+
+
+
+
+
+
+ Access for this model:
+
+
+
+ Public(5)
+
+
+
+
+
+
+ Cardano ID:
+
+
+
+ {addEllipsisAtEndOfString("456iorkjahfjouo23eyu3o2u01982409un9u092")}
+ {addEllipsisAtEndOfString("456iorkjahfjouo23eyu3o2u01982409un9u092")}
+ {addEllipsisAtEndOfString("456iorkjahfjouo23eyu3o2u01982409un9u092")}
+ {addEllipsisAtEndOfString("456iorkjahfjouo23eyu3o2u01982409un9u092")}
+ {addEllipsisAtEndOfString("456iorkjahfjouo23eyu3o2u01982409un9u092")}
+
+
+
+
+
+
Model Traning Fee
+
This AI Model Traning requires a very small fee. Please select a payment method to continue
+
+ agix tokens
+ 0.002
+
+
+
+
+
+
+
+ );
+};
+
+export default withStyles(useStyles)(Payment);
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/styles.js b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/styles.js
new file mode 100644
index 000000000..60d72e119
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/Payment/styles.js
@@ -0,0 +1,149 @@
+export const useStyles = theme => ({
+ paymentContaienr: {
+ padding: "60px 24px 32px",
+ },
+ reviewReqContainer: {
+ "& > span": { fontWeight: "bold" },
+ "& span": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 14,
+ lineHeight: "18px",
+ },
+ "& > div": {
+ marginTop: 16,
+ display: "flex",
+ alignItems: "flex-start",
+ "& p": {
+ display: "flex",
+ color: theme.palette.text.mediumShadeGray,
+ fontFamily: "Muli",
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "24px",
+ "& svg": {
+ marginLeft: 16,
+ color: theme.palette.text.darkShadedGray,
+ },
+ },
+ "& a": {
+ color: theme.palette.text.primary,
+ fontWeight: 400,
+ textDecoration: "none",
+ },
+ "& ul": {
+ margin: 0,
+ padding: 0,
+ listStyle: "none",
+ "& li": {
+ paddingBottom: 8,
+ color: theme.palette.text.mediumShadeGray,
+ fontFamily: "Muli",
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "24px",
+ "&:lastof-type": { paddingBottom: 0 },
+ },
+ },
+ },
+ },
+ modelTrainFeeContainer: {
+ marginTop: 50,
+ "& > span": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 14,
+ fontWeight: "bold",
+ lineHeight: "18px",
+ },
+ "& > p": {
+ margin: "16px 0",
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "24px",
+ },
+ },
+ tokenCount: {
+ width: 166,
+ padding: "24px 0",
+ border: "1px solid #DAF0FF",
+ borderRadius: 4,
+ backgroundColor: "#E7F5FF",
+ display: "flex",
+ flexDirection: "column",
+ alignItems: "center",
+ "& span": {
+ "&:first-of-type": {
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "18px",
+ textTransform: "capitalize",
+ },
+ "&:last-of-type": {
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 20,
+ fontWeight: "bold",
+ lineHeight: "25px",
+ },
+ },
+ },
+ paymentMode: {
+ marginTop: 24,
+ "& p": {
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ lineHeight: "18px",
+ },
+ },
+ paymentChannelAndDetails: {
+ marginTop: 35,
+ display: "flex",
+ "& > p": {
+ width: "100%",
+ margin: "0 0 0 40px",
+ "@media(max-width:1280px)": { margin: "25px 0 0 0" },
+ },
+ "@media(max-width:767px)": { flexDirection: "column" },
+ "@media(max-width:1280px)": { flexWrap: "wrap" },
+ },
+ paymentChannelDropDownContainer: {
+ display: "flex",
+ marginRight: 40,
+ "& fieldset": { display: "none" },
+ "@media(max-width:940px)": { marginBottom: 30 },
+ },
+ infoIconContainer: {
+ marginRight: 10,
+ alignSelf: "center",
+ color: theme.palette.text.lightShadedGray,
+ fontSize: 18,
+ },
+ paymentChannelDropDown: {
+ width: 278,
+ padding: "0 10px",
+ borderWidth: 1,
+ borderStyle: "solid",
+ borderColor: "rgba(25,25,25,0.32)",
+ borderRadius: 4,
+ display: "flex",
+ alignItems: "center",
+ position: "relative",
+ "& .MuiFormControl-root": { width: "90%" },
+ "& .MuiSelect-outlined": { padding: "15px 14px" },
+ "& .MuiSelect-icon": { color: theme.palette.text.darkShadedGray },
+ "@media(min-width: 768px) and (max-width: 960px)": { width: 178 },
+ },
+ dropDownTitle: {
+ padding: "0 5px",
+ position: "absolute",
+ top: -11,
+ left: 10,
+ backgroundColor: theme.palette.text.white,
+ color: theme.palette.text.dialogTitle,
+ fontSize: 12,
+ letterSpacing: 0.4,
+ },
+ walletIcon: { color: theme.palette.text.lightShadedGray },
+ btnContainer: { textAlign: 'center' }
+});
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/index.js b/src/components/ServiceDetails/TrainingModels/CreateModel/index.js
new file mode 100644
index 000000000..a85d084b2
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/index.js
@@ -0,0 +1,58 @@
+import React from "react";
+import { withStyles } from "@material-ui/styles";
+
+import { useStyles } from "./styles";
+import CreateModelContainer from "./CreateModelContainer";
+import ModelInfo from "./ModelInfo";
+import Data from './Data';
+import Payment from "./Payment";
+import Finish from './Finish';
+
+const CreateModel = ({ classes }) => {
+ const [activeSection, setActiveSection] = React.useState(1);
+
+ const handleNextClick = () => {
+ console.log('before', activeSection)
+ setActiveSection(activeSection + 1);
+ console.log('after', activeSection)
+ };
+
+ const createModelTabs = [
+ {
+ key: "modelInfo",
+ component: ,
+ },
+ {
+ key: "data",
+ component: ,
+ },
+ {
+ key: "payment",
+ component:
+ },
+ {
+ key: "finish",
+ component:
+ },
+ ];
+
+ const progressText = [{ label: "Model Info" }, { label: "Data" }, { label: "Payment" }, { label: "Finish" }];
+
+ return (
+
+
New Model Request
+ {createModelTabs.map((item, index) => (
+
+ ))}
+
+ );
+};
+
+export default withStyles(useStyles)(CreateModel);
diff --git a/src/components/ServiceDetails/TrainingModels/CreateModel/styles.js b/src/components/ServiceDetails/TrainingModels/CreateModel/styles.js
new file mode 100644
index 000000000..787ca2532
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/CreateModel/styles.js
@@ -0,0 +1,42 @@
+export const useStyles = theme => ({
+ createModelContainer: {
+ boxShadow: "0 1px 1px 0 rgba(0,0,0,0.07), 0 2px 1px -1px rgba(0,0,0,0.07), 0 1px 3px 0 rgba(0,0,0,0.1)",
+ backgroundColor: theme.palette.text.white,
+ borderRadius: 4,
+ paddingBottom: 20,
+ "& h2": {
+ padding: "11px 22px",
+ borderBottomWidth: 1,
+ borderBottomStyle: "solid",
+ borderBottomColor: theme.palette.text.gray1,
+ margin: 0,
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 20,
+ fontWeight: 400,
+ },
+ '& > div': {
+ '&:first-of-type': {
+ '& ul': {
+ justifyContent: 'center',
+ '@media(max-width: 570px)': {
+ width: '30%',
+ margin: '0 auto',
+ flexDirection: 'column',
+ alignItems: 'flex-start',
+ '& li': {
+ '@media(max-width: 570px)': { marginBottom: 10 },
+ '&::before': {
+ '@media(max-width: 570px)': { display: 'none' }
+ }
+ }
+ }
+ },
+ '& li::before': {
+ width: 50,
+ margin: '0 10px'
+ },
+ '@media(max-width: 1015px)': { width: '100%' }
+ }
+ }
+ },
+});
diff --git a/src/components/ServiceDetails/TrainingModels/index.js b/src/components/ServiceDetails/TrainingModels/index.js
new file mode 100644
index 000000000..c46bc4dcd
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/index.js
@@ -0,0 +1,63 @@
+import React, { useState } from "react";
+import Grid from "@material-ui/core/Grid";
+import { withStyles } from "@material-ui/styles";
+import StyledButton from "../../common/StyledButton";
+
+import { useStyles } from "./styles";
+import ExistingModel from "../ExistingModel";
+import ProjectDetails from "../ProjectDetails";
+import InfoOutlinedIcon from "@material-ui/icons/InfoOutlined";
+import CreateModel from "./CreateModel";
+
+const TrainingModels = ({ classes, service, haveANewModel }) => {
+ const [showCreateModel, setShowCreateModel] = useState(false);
+ const [MMconnected, setMMConnected] = useState(true);
+
+ const handleRequestModel = () => {
+ setShowCreateModel(true);
+ };
+
+ if (!MMconnected) {
+ return (
+
+
+
+ );
+ }
+
+ return (
+
+
+ {showCreateModel ? (
+
+ ) : (
+ <>
+
+
Request a new model
+
+
+
+ The first step in requesting a custom model is to create a project. A project is where you can create
+ and manage models. The models you create in this project inherit the name of the project.
+
+
+ {/* {haveANewModel ?
: null} */}
+
+
+
+ >
+ )}
+
+
+
+
+
+ );
+};
+
+export default withStyles(useStyles)(TrainingModels);
diff --git a/src/components/ServiceDetails/TrainingModels/styles.js b/src/components/ServiceDetails/TrainingModels/styles.js
new file mode 100644
index 000000000..e81605db4
--- /dev/null
+++ b/src/components/ServiceDetails/TrainingModels/styles.js
@@ -0,0 +1,47 @@
+export const useStyles = theme => ({
+ trainingModelContainer: {
+ paddingTop: 11,
+ marginBottom: 25,
+ borderTopWidth: 1,
+ borderTopStyle: "solid",
+ borderTopColor: theme.palette.text.verticalTabLeftBorder,
+ },
+ leftSideSection: {
+ paddingRight: 25,
+ "@media(max-width:960px)": { paddingRight: 0 }
+ },
+ requestModelContainer: {
+ boxShadow: "0 1px 1px 0 rgba(0,0,0,0.07), 0 2px 1px -1px rgba(0,0,0,0.07), 0 1px 3px 0 rgba(0,0,0,0.1)",
+ backgroundColor: theme.palette.text.white,
+ borderRadius: 4,
+ paddingBottom: 20,
+ "& h2": {
+ padding: "11px 22px",
+ borderBottomWidth: 1,
+ borderBottomStyle: "solid",
+ borderBottomColor: theme.palette.text.gray1,
+ margin: 0,
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 20,
+ fontWeight: 400,
+ },
+ "& div": {
+ padding: '22px 22px 24px',
+ display: 'flex',
+ "& svg": {
+ padding: '3px 8px 0 0',
+ color: theme.palette.text.primary,
+ fontSize: 16,
+ },
+ "& p": {
+ margin: 0,
+ color: theme.palette.text.mediumShadeGray,
+ fontSize: 14,
+ fontWeight: 300,
+ letterSpacing: "0.25px",
+ lineHeight: "20px",
+ },
+ },
+ "& button": { marginLeft: 22 }
+ }
+});
diff --git a/src/components/ServiceDetails/index.js b/src/components/ServiceDetails/index.js
index 4fb434c7d..968078811 100644
--- a/src/components/ServiceDetails/index.js
+++ b/src/components/ServiceDetails/index.js
@@ -18,7 +18,8 @@ import ErrorBox from "../common/ErrorBox";
import SeoMetadata from "../common/SeoMetadata";
import Routes from "../../utility/constants/Routes";
import CardImg from "../../assets/images/SnetDefaultServiceImage.png";
-
+import TrainingModels from "./TrainingModels";
+import { fetchTrainingModel } from "../../Redux/actionCreators/ServiceDetailsActions";
export const HERO_IMG = "hero_image";
class ServiceDetails extends Component {
@@ -42,6 +43,17 @@ class ServiceDetails extends Component {
if (isEmpty(this.props.service)) {
this.fetchServiceDetails();
}
+ this.fetchTrainingModel();
+ }
+
+ fetchTrainingModel = async () => {
+ const {
+ fetchTrainingModel,
+ match: {
+ params: { orgId, serviceId },
+ },
+ } = this.props;
+ await fetchTrainingModel(orgId, serviceId);
}
fetchServiceDetails = async () => {
@@ -89,12 +101,13 @@ class ServiceDetails extends Component {
};
render() {
- const { classes, service, pricing, loading, error, history, groupInfo, match } = this.props;
+ const { classes, service, pricing, loading, error, history, groupInfo, match, training } = this.props;
const { offlineNotication } = this.state;
const {
params: { orgId, serviceId },
} = match;
-
+ let haveTrainingModel = (Object.keys(training).length === 0 ? false : true);
+ let haveANewModel = (((training !== undefined) && ((training.training_methods === undefined)||((training.training_methods).length === 0)))? false : true);
if (isEmpty(service) || error) {
if (loading) {
return null;
@@ -119,6 +132,9 @@ class ServiceDetails extends Component {
demoExampleRef={this.demoExampleRef}
scrollToView={this.scrollToView}
demoComponentRequired={!!service.demo_component_required}
+ haveTrainingModel={haveTrainingModel}
+ training={training}
+ haveANewModel={haveANewModel}
/>
),
},
@@ -129,6 +145,14 @@ class ServiceDetails extends Component {
},
];
+ if (process.env.REACT_APP_TRAINING_ENABLE === 'true') {
+ tabs.push({
+ name: "Models",
+ activeIndex: 2,
+ component: ,
+ });
+ }
+
const seoURL = `${process.env.REACT_APP_BASE_URL}/servicedetails/org/${orgId}/service/${serviceId}`;
return (
@@ -184,11 +208,13 @@ const mapStateToProps = (state, ownProps) => {
groupInfo: groupInfo(state),
pricing: pricing(state),
loading: state.loaderReducer.app.loading,
+ training: state.serviceDetailsReducer.detailsTraining,
};
};
const mapDispatchToProps = dispatch => ({
fetchServiceDetails: (orgId, serviceId) => dispatch(serviceDetailsActions.fetchServiceDetails(orgId, serviceId)),
+ fetchTrainingModel: (orgId, serviceId) => dispatch(fetchTrainingModel(orgId, serviceId)),
});
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(useStyles)(ServiceDetails));
diff --git a/src/components/UserProfile/UserProfileModels/RejectedRequestModel.js b/src/components/UserProfile/UserProfileModels/RejectedRequestModel.js
new file mode 100644
index 000000000..9619f7dd3
--- /dev/null
+++ b/src/components/UserProfile/UserProfileModels/RejectedRequestModel.js
@@ -0,0 +1,54 @@
+import React from "react";
+import { withStyles } from "@material-ui/styles";
+import Grid from "@material-ui/core/Grid";
+import Typography from "@material-ui/core/Typography";
+
+import { useStyles } from "./styles";
+
+const RejectedRequestModel = ({ classes }) => {
+ return (
+
+
+
+ name
+
+
+ service
+
+
+ submission date
+
+
+ fee
+
+
+ status
+
+
+
+
+ name:
+ Region Recognation
+
+
+ service:
+ Deoldify photos
+
+
+ submission date:
+ 15 June 2022 - 9:14 AM
+
+
+ fee:
+ 0.5 AZIX
+
+
+ status:
+ Ready for use
+
+
+
+ );
+};
+
+export default withStyles(useStyles)(RejectedRequestModel);
diff --git a/src/components/UserProfile/UserProfileModels/RequestedModel.js b/src/components/UserProfile/UserProfileModels/RequestedModel.js
new file mode 100644
index 000000000..d6e196527
--- /dev/null
+++ b/src/components/UserProfile/UserProfileModels/RequestedModel.js
@@ -0,0 +1,54 @@
+import React from "react";
+import { withStyles } from "@material-ui/styles";
+import Grid from "@material-ui/core/Grid";
+import Typography from "@material-ui/core/Typography";
+
+import { useStyles } from "./styles";
+
+const RequestedModel = ({ classes }) => {
+ return (
+
+
+
+ name
+
+
+ service
+
+
+ submission date
+
+
+ fee
+
+
+ status
+
+
+
+
+ name:
+ Region Recognation
+
+
+ service:
+ Deoldify photos
+
+
+ submission date:
+ 15 June 2022 - 9:14 AM
+
+
+ fee:
+ 0.5 AZIX
+
+
+ status:
+ Ready for use
+
+
+
+ );
+};
+
+export default withStyles(useStyles)(RequestedModel);
diff --git a/src/components/UserProfile/UserProfileModels/index.js b/src/components/UserProfile/UserProfileModels/index.js
new file mode 100644
index 000000000..96f9e666c
--- /dev/null
+++ b/src/components/UserProfile/UserProfileModels/index.js
@@ -0,0 +1,45 @@
+import React, { Component } from "react";
+import { withStyles } from "@material-ui/styles";
+import Grid from "@material-ui/core/Grid";
+import AppBar from "@material-ui/core/AppBar";
+import Tabs from "@material-ui/core/Tabs";
+import Tab from "@material-ui/core/Tab";
+
+import { useStyles } from "./styles";
+import RequestedModel from "./RequestedModel";
+import RejectedRequestModel from "./RejectedRequestModel";
+
+const UserProfileModels = ({ classes }) => {
+ const [ activeTab, setActiveTab ] = React.useState(0);
+
+ const onTabChange = activeTab => {
+ setActiveTab(activeTab );
+ };
+
+ const tabs = [
+ { name: "Requests", activeIndex: 0, component: },
+ { name: "Rejected Requests", activeIndex: 1, component: },
+ ];
+
+ const activeComponent = tabs.filter(el => el.activeIndex === activeTab)[0].component;
+
+ return (
+
+
+ Model Training
+
+
+
+ {tabs.map(value => (
+ onTabChange(value.activeIndex)} />
+ ))}
+
+
+ {activeComponent}
+
+
+
+ );
+}
+
+export default withStyles(useStyles)(UserProfileModels );
diff --git a/src/components/UserProfile/UserProfileModels/styles.js b/src/components/UserProfile/UserProfileModels/styles.js
new file mode 100644
index 000000000..75a88b26f
--- /dev/null
+++ b/src/components/UserProfile/UserProfileModels/styles.js
@@ -0,0 +1,83 @@
+export const useStyles = theme => ({
+ userProfileModelMainContainer: {
+ margin: "29px 0 85px",
+ backgroundColor: theme.palette.text.white,
+ boxShadow: "0 1px 1px 0 rgba(0,0,0,0.07), 0 2px 1px -1px rgba(0,0,0,0.07), 0 1px 3px 0 rgba(0,0,0,0.1)",
+ "& h3": {
+ padding: "11px 22px",
+ borderBottomWidth: 1,
+ borderBottomStyle: "solid",
+ borderBottomColor: theme.palette.text.gray1,
+ margin: 0,
+ color: theme.palette.text.darkShadedGray,
+ fontSize: 20,
+ fontWeight: 400,
+ },
+ },
+ userProfileModelContainer: { "@media(max-width: 1280px)": { overflow: "auto" } },
+ tabsHeader: {
+ padding: "7px 26px 0",
+ borderBottomWidth: 1,
+ borderBottomStyle: "solid",
+ borderBottomColor: "#e2e2e2",
+ backgroundColor: "transparent",
+ color: theme.palette.text.lightShadedGray,
+ boxShadow: "none",
+ "& button": {
+ minWidth: "auto",
+ padding: 0,
+ marginRight: 40,
+ fontSize: 20,
+ textTransform: "none",
+ color: theme.palette.text.lightShadedGray,
+ fontFamily: theme.typography.primary.main,
+ },
+ "& .Mui-selected": { color: theme.palette.text.primary },
+ "& .MuiTabs-indicator": { backgroundColor: theme.palette.text.primary },
+ },
+ requestedModelsHeaders: {
+ padding: "20px 22px",
+ borderBottomWidth: 1,
+ borderBottomStyle: "solid",
+ borderBottomColor: "#f6f6f7",
+ backgroundColor: "#f5f5f5",
+ display: "flex",
+ "& p": {
+ color: theme.palette.text.mediumShadeGray,
+ fontFamily: theme.typography.primary.main,
+ fontSize: 14,
+ lineHeight: "18px",
+ textTransform: "uppercase",
+ },
+ '@media(max-width: 960px)': { display: 'none' }
+ },
+ requestedModelsDataContainer: {
+ padding: "24px 0",
+ margin: "0 22px",
+ borderBottomWidth: 2,
+ borderBottomStyle: "solid",
+ borderBottomColor: "#e2e2e2",
+ display: "flex",
+ '& div': {
+ display: 'flex',
+ alignItems: 'center'
+ },
+ "& span": {
+ width: '150px',
+ display: "none",
+ color: theme.palette.text.mediumShadeGray,
+ fontFamily: theme.typography.primary.main,
+ fontSize: 14,
+ lineHeight: "18px",
+ textTransform: "uppercase",
+ '@media(max-width: 960px)': { display: 'block' }
+ },
+ "& p": {
+ color: theme.palette.text.mediumShadeGray,
+ fontFamily: theme.typography.primary.main,
+ fontSize: 14,
+ lineHeight: "24px",
+ },
+ "&:last-of-type": { border: "none" },
+ },
+});
diff --git a/src/components/UserProfile/UserProfileTransactionHistory/styles.js b/src/components/UserProfile/UserProfileTransactionHistory/styles.js
index 240b4b2ef..f8c55ae96 100644
--- a/src/components/UserProfile/UserProfileTransactionHistory/styles.js
+++ b/src/components/UserProfile/UserProfileTransactionHistory/styles.js
@@ -11,6 +11,7 @@ export const useStyles = theme => ({
margin: 0,
color: theme.palette.text.darkShadedGray,
fontSize: 20,
+ fontWeight: 400,
"@media(max-width:1280px)": {
boxSizing: "border-box",
width: 1280,
@@ -20,7 +21,7 @@ export const useStyles = theme => ({
transactionHistoryContainer: { "@media(max-width: 1280px)": { overflow: "auto" } },
transactionHistoryContent: { "@media(max-width:1280px)": { width: 1280 } },
tabsHeader: {
- padding: "7px 26px 0",
+ padding: "7px 22px 0",
borderBottomWidth: 1,
borderBottomStyle: "solid",
borderBottomColor: "#e2e2e2",
diff --git a/src/components/UserProfile/index.js b/src/components/UserProfile/index.js
index 084d023a9..37cf92531 100644
--- a/src/components/UserProfile/index.js
+++ b/src/components/UserProfile/index.js
@@ -10,6 +10,7 @@ import UserProfileSettings from "./UserProfileSettings";
import UserProfileHeader from "./UserProfileHeader";
import UserProfileAccount from "./UserProfileAccount";
import UserProfileTransactionHistory from "./UserProfileTransactionHistory";
+import UserProfileModels from "./UserProfileModels";
import { useStyles } from "./styles";
import Routes from "../../utility/constants/Routes";
@@ -17,13 +18,14 @@ export const userProfileRoutes = {
ACCOUNT: { path: `/${Routes.USER_PROFILE}/account`, component: () => },
SETTINGS: { path: `/${Routes.USER_PROFILE}/settings`, component: () => },
TRANSACTIONS: { path: `/${Routes.USER_PROFILE}/transactions`, component: () => },
+ MODELS: { path: `/${Routes.USER_PROFILE}/models`, component: () => }
};
const activeIndexEnum = {
[`${userProfileRoutes.ACCOUNT.path}`]: 0,
[`${userProfileRoutes.SETTINGS.path}`]: 1,
[`${userProfileRoutes.TRANSACTIONS.path}`]: 2,
-};
+ [`${userProfileRoutes.MODELS.path}`]: 3,};
const tabs = [
{ name: "Account", activeIndex: 0, path: userProfileRoutes.ACCOUNT.path },
@@ -31,6 +33,14 @@ const tabs = [
{ name: "Transactions", activeIndex: 2, path: userProfileRoutes.TRANSACTIONS.path },
];
+if (process.env.REACT_APP_TRAINING_ENABLE === 'true') {
+ tabs.push({
+ name: "Models",
+ activeIndex: 3,
+ path: userProfileRoutes.MODELS.path
+ });
+};
+
const UserProfile = ({ classes, nickname, history, location, email }) => {
const onTabChange = (activeTab, activePath) => {
history.push(activePath);
@@ -57,6 +67,7 @@ const UserProfile = ({ classes, nickname, history, location, email }) => {
+
diff --git a/src/components/common/StyledButton/styles.js b/src/components/common/StyledButton/styles.js
index 6133e7446..0c0dc5aea 100644
--- a/src/components/common/StyledButton/styles.js
+++ b/src/components/common/StyledButton/styles.js
@@ -2,10 +2,11 @@ import { makeStyles } from "@material-ui/styles";
export const useStyles = makeStyles(theme => ({
styledButton: {
+ minWidth: 170,
borderWidth: 1,
borderStyle: "solid",
borderColor: "transparent",
- padding: "7px 28px",
+ padding: "11px 28px",
color: theme.palette.text.white,
textTransform: "uppercase",
fontFamily: theme.typography.primary.main,
diff --git a/src/utility/constants/UserPopupMenu.js b/src/utility/constants/UserPopupMenu.js
index 99c5fa467..fdcb651ab 100644
--- a/src/utility/constants/UserPopupMenu.js
+++ b/src/utility/constants/UserPopupMenu.js
@@ -4,6 +4,8 @@ import { signOut } from "../../Redux/actionCreators/UserActions";
import SettingIcon from "@material-ui/icons/Settings";
import ExitToAppIcon from "@material-ui/icons/ExitToApp";
import AccountCircleIcon from "@material-ui/icons/AccountCircle";
+// import TransactionIcon from "../../assets/images/transaction_icon.svg";
+// import ModelsIcon from "../../assets/images/models_icon.svg";
export const UserMenuList = [
{
@@ -20,9 +22,17 @@ export const UserMenuList = [
menuIcon: SettingIcon,
menuTitle: "Transactions",
menuLink: `${Routes.USER_PROFILE}/transactions`,
- },
+ }
];
+if (process.env.REACT_APP_TRAINING_ENABLE === "true") {
+ UserMenuList.push({
+ menuIcon: SettingIcon,
+ menuTitle: "Models",
+ menuLink: `${Routes.USER_PROFILE}/models`,
+ });
+}
+
export const UserMenuActionList = [
{
menuIcon: ExitToAppIcon,