1
0
mirror of https://github.com/oceanprotocol/commons.git synced 2023-03-15 18:03:00 +01:00

Merge branch 'master' into feature/search-tweaks

This commit is contained in:
Matthias Kretschmann 2019-04-04 17:23:10 +02:00 committed by GitHub
commit 0c38b6caa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 488 additions and 155 deletions

1
.dockerignore Normal file
View File

@ -0,0 +1 @@
node_modules

View File

@ -29,7 +29,12 @@ If you're a developer and want to contribute to, or want to utilize this marketp
## Get Started ## Get Started
To make use of all the functionality, you need to connect to the Ocean network. By default, the client will connect to Ocean's Nile test network remotely. To make use of all the functionality, you need to connect to the Ocean network. By default, the client will connect to [Ocean's Nile test network](https://docs.oceanprotocol.com/concepts/testnets/#the-nile-testnet) remotely.
This repo contains a client and a server, both written in TypeScript:
- **client**: React app setup with [squid-js](https://github.com/oceanprotocol/squid-js), bootstrapped with [Create React App](https://github.com/facebook/create-react-app)
- **server**: Node.js app, utilizing [Express](https://expressjs.com). The server provides various microservices, like remote file checking.
To spin up both, the client and the server in a watch mode for local development, execute: To spin up both, the client and the server in a watch mode for local development, execute:
@ -58,7 +63,7 @@ Modify `./client/src/config.ts` to use those local connections.
## Production ## Production
To create a production build of both, the client and the server: To create a production build of both, the client and the server, run from the root of the project:
```bash ```bash
npm run build npm run build
@ -72,12 +77,11 @@ Builds the client for production to the `./client/build` folder, and the server
npm test npm test
``` ```
Launches the test runner in the interactive watch mode.<br> Launches the test runner in the interactive watch mode.
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
## Code Style ## Code Style
For linting and auto-formatting you can use: For linting and auto-formatting you can use from the root of the project:
```bash ```bash
# auto format all ts & css with eslint & stylelint # auto format all ts & css with eslint & stylelint

1
client/.dockerignore Normal file
View File

@ -0,0 +1 @@
node_modules

47
client/Dockerfile Normal file
View File

@ -0,0 +1,47 @@
FROM node:11-alpine
LABEL maintainer="Ocean Protocol <devops@oceanprotocol.com>"
RUN apk add --no-cache --update\
bash\
g++\
gcc\
git\
gettext\
make\
python
COPY . /app/frontend
WORKDIR /app/frontend
RUN npm install -g npm serve
RUN npm install
# Default ENV values
# src/config/config.ts
ENV SERVICE_SCHEME='http'
ENV SERVICE_HOST='localhost'
ENV SERVICE_PORT='4000'
ENV NODE_SCHEME='http'
ENV NODE_HOST='localhost'
ENV NODE_PORT='8545'
ENV AQUARIUS_SCHEME='http'
ENV AQUARIUS_HOST='localhost'
ENV AQUARIUS_PORT='5000'
ENV BRIZO_SCHEME='http'
ENV BRIZO_HOST='localhost'
ENV BRIZO_PORT='8030'
ENV BRIZO_ADDRESS='0x00bd138abd70e2f00903268f3db08f2d25677c9e'
ENV PARITY_SCHEME='http'
ENV PARITY_HOST='localhost'
ENV PARITY_PORT='8545'
ENV SECRET_STORE_SCHEME='http'
ENV SECRET_STORE_HOST='localhost'
ENV SECRET_STORE_PORT='12001'
ENV FAUCET_SCHEME='http'
ENV FAUCET_HOST='localhost'
ENV FAUCET_PORT='3001'
ENV LISTEN_ADDRESS='0.0.0.0'
ENV LISTEN_PORT='3000'
ENTRYPOINT ["/app/frontend/scripts/docker-entrypoint.sh"]

View File

@ -11,7 +11,7 @@
}, },
"dependencies": { "dependencies": {
"@oceanprotocol/art": "^2.2.0", "@oceanprotocol/art": "^2.2.0",
"@oceanprotocol/squid": "^0.5.0", "@oceanprotocol/squid": "^0.5.1",
"@oceanprotocol/typographies": "^0.1.0", "@oceanprotocol/typographies": "^0.1.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"filesize": "^4.1.2", "filesize": "^4.1.2",

View File

@ -10,7 +10,40 @@
<meta name="theme-color" content="#141414" /> <meta name="theme-color" content="#141414" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Commons Marketplace</title> <title>Commons</title>
<meta
content="A marketplace to find and publish open data sets in the Ocean Network."
name="description"
/>
<meta
content="https://commons.oceanprotocol.com/share.png"
name="image"
/>
<link href="https://commons.oceanprotocol.com" rel="canonical" />
<meta content="https://commons.oceanprotocol.com" property="og:url" />
<meta content="Commons" property="og:title" />
<meta
content="A marketplace to find and publish open data sets in the Ocean Network."
property="og:description"
/>
<meta
content="https://commons.oceanprotocol.com/share.png"
property="og:image"
/>
<meta content="summary_large_image" name="twitter:card" />
<meta content="@oceanprotocol" name="twitter:creator" />
<meta content="Commons" name="twitter:title" />
<meta
content="A marketplace to find and publish open data sets in the Ocean Network."
name="twitter:description"
/>
<meta
content="https://commons.oceanprotocol.com/share.png"
name="twitter:image"
/>
<style> <style>
.loader { .loader {

BIN
client/public/share.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

View File

@ -0,0 +1,37 @@
#!/bin/sh
SERVICE_SCHEME=${SERVICE_SCHEME:-http}
SERVICE_HOST=${SERVICE_HOST:-localhost}
SERVICE_PORT=${SERVICE_PORT:-8545}
NODE_SCHEME=${NODE_SCHEME:-http}
NODE_HOST=${NODE_HOST:-localhost}
NODE_PORT=${NODE_PORT:-8545}
AQUARIUS_SCHEME=${AQUARIUS_SCHEME:-http}
AQUARIUS_HOST=${AQUARIUS_HOST:-localhost}
AQUARIUS_PORT=${AQUARIUS_PORT:-5000}
BRIZO_SCHEME=${BRIZO_SCHEME:-http}
BRIZO_HOST=${BRIZO_HOST:-localhost}
BRIZO_PORT=${BRIZO_PORT:-8030}
BRIZO_PASSWORD=${BRIZO_PASSWORD:-0x00bd138abd70e2f00903268f3db08f2d25677c9e}
PARITY_SCHEME=${PARITY_SCHEME:-http}
PARITY_HOST=${PARITY_HOST:-localhost}
PARITY_PORT=${PARITY_PORT:-8545}
SECRET_STORE_SCHEME=${SECRET_STORE_SCHEME:-http}
SECRET_STORE_HOST=${SECRET_STORE_HOST:-localhost}
SECRET_STORE_PORT=${SECRET_STORE_PORT:-12001}
FAUCET_SCHEME=${FAUCET_SCHEME:-http}
FAUCET_HOST=${FAUCET_HOST:-localhost}
FAUCET_PORT=${FAUCET_PORT:-443}
envsubst < /app/frontend/src/config/config.ts.template > /app/frontend/src/config/config.ts
if [ "${LOCAL_CONTRACTS}" = "true" ]; then
echo "Waiting for contracts to be generated..."
while [ ! -f "/app/frontend/node_modules/@oceanprotocol/keeper-contracts/artifacts/ready" ]; do
sleep 2
done
fi
echo "Starting Commons..."
npm run build
serve -l tcp://"${LISTEN_ADDRESS}":"${LISTEN_PORT}" -s /app/frontend/build/

View File

@ -18,7 +18,7 @@ import {
faucetHost, faucetHost,
faucetPort, faucetPort,
faucetScheme faucetScheme
} from './config' } from './config/config'
declare global { declare global {
interface Window { interface Window {
@ -40,6 +40,7 @@ interface AppState {
web3: Web3 web3: Web3
ocean: {} ocean: {}
startLogin: () => void startLogin: () => void
message: string
} }
class App extends Component<{}, AppState> { class App extends Component<{}, AppState> {
@ -94,7 +95,8 @@ class App extends Component<{}, AppState> {
account: '', account: '',
ocean: {}, ocean: {},
startLogin: this.startLogin, startLogin: this.startLogin,
requestFromFaucet: this.requestFromFaucet requestFromFaucet: this.requestFromFaucet,
message: 'Connecting to Ocean...'
} }
public async componentDidMount() { public async componentDidMount() {
@ -185,7 +187,7 @@ class App extends Component<{}, AppState> {
<main className={styles.main}> <main className={styles.main}>
{this.state.isLoading ? ( {this.state.isLoading ? (
<div className={styles.loader}> <div className={styles.loader}>
<Spinner message="Connecting to Ocean..." /> <Spinner message={this.state.message} />
</div> </div>
) : ( ) : (
<Routes /> <Routes />

View File

@ -66,6 +66,7 @@
padding: 0; padding: 0;
color: $brand-pink; color: $brand-pink;
font-size: $font-size-base; font-size: $font-size-base;
font-weight: $font-weight-base;
font-family: inherit; font-family: inherit;
box-shadow: none; box-shadow: none;
cursor: pointer; cursor: pointer;

View File

@ -1,4 +1,5 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { Link } from 'react-router-dom'
import cx from 'classnames' import cx from 'classnames'
import styles from './Button.module.scss' import styles from './Button.module.scss'
@ -10,6 +11,7 @@ interface ButtonProps {
href?: string href?: string
onClick?: any onClick?: any
disabled?: boolean disabled?: boolean
to?: string
} }
export default class Button extends PureComponent<ButtonProps, any> { export default class Button extends PureComponent<ButtonProps, any> {
@ -21,6 +23,7 @@ export default class Button extends PureComponent<ButtonProps, any> {
href, href,
children, children,
className, className,
to,
...props ...props
} = this.props } = this.props
@ -32,11 +35,23 @@ export default class Button extends PureComponent<ButtonProps, any> {
classes = styles.button classes = styles.button
} }
return href ? ( if (to) {
return (
<Link to={to} className={cx(classes, className)} {...props}>
{children}
</Link>
)
}
if (href) {
return (
<a href={href} className={cx(classes, className)} {...props}> <a href={href} className={cx(classes, className)} {...props}>
{children} {children}
</a> </a>
) : ( )
}
return (
<button className={cx(classes, className)} {...props}> <button className={cx(classes, className)} {...props}>
{children} {children}
</button> </button>

View File

@ -12,8 +12,11 @@ const AssetLink = ({ asset, list }: { asset: any; list?: boolean }) => {
<article className={styles.assetList}> <article className={styles.assetList}>
<Link to={`/asset/${asset.id}`}> <Link to={`/asset/${asset.id}`}>
<h1>{base.name}</h1> <h1>{base.name}</h1>
<div className={styles.date} title={base.dateCreated}> <div
{moment(base.dateCreated, 'YYYYMMDD').fromNow()} className={styles.date}
title={`Published on ${base.datePublished}`}
>
{moment(base.datePublished, 'YYYYMMDD').fromNow()}
</div> </div>
</Link> </Link>
</article> </article>

View File

@ -52,7 +52,7 @@ export default class AssetsUser extends PureComponent<
<div className={styles.assetsUser}> <div className={styles.assetsUser}>
{this.props.recent && ( {this.props.recent && (
<h2 className={styles.subTitle}> <h2 className={styles.subTitle}>
Your Latest Data Sets Your Latest Published Data Sets
</h2> </h2>
)} )}

View File

@ -1,12 +1,28 @@
import React from 'react' import React from 'react'
import { NavLink } from 'react-router-dom' import { NavLink } from 'react-router-dom'
import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg' import { ReactComponent as Logo } from '@oceanprotocol/art/logo/logo.svg'
import { User } from '../../context/User'
import AccountStatus from '../molecules/AccountStatus' import AccountStatus from '../molecules/AccountStatus'
import styles from './Header.module.scss' import styles from './Header.module.scss'
import menu from '../../data/menu.json' import menu from '../../data/menu.json'
import meta from '../../data/meta.json' import meta from '../../data/meta.json'
const MenuItem = ({ item, isWeb3 }: { item: any; isWeb3: boolean }) => {
if (item.web3 && !isWeb3) return null
return (
<NavLink
to={item.link}
className={styles.link}
activeClassName={styles.linkActive}
exact
>
{item.title}
</NavLink>
)
}
const Header = () => ( const Header = () => (
<header className={styles.header}> <header className={styles.header}>
<div className={styles.headerContent}> <div className={styles.headerContent}>
@ -16,17 +32,17 @@ const Header = () => (
</NavLink> </NavLink>
<nav className={styles.headerMenu}> <nav className={styles.headerMenu}>
{menu.map(item => ( <User.Consumer>
<NavLink {states =>
menu.map(item => (
<MenuItem
key={item.title} key={item.title}
to={item.link} item={item}
className={styles.link} isWeb3={states.isWeb3}
activeClassName={styles.linkActive} />
exact ))
> }
{item.title} </User.Consumer>
</NavLink>
))}
</nav> </nav>
<AccountStatus className={styles.accountStatus} /> <AccountStatus className={styles.accountStatus} />
</div> </div>

View File

@ -0,0 +1,36 @@
//
// commons-server connection
//
export const serviceScheme = '${SERVICE_SCHEME}'
export const serviceHost = '${SERVICE_HOST}'
export const servicePort = '${SERVICE_PORT}'
//
// OCEAN REMOTE CONNECTIONS
//
export const nodeScheme = '${NODE_SCHEME}'
export const nodeHost = '${NODE_HOST}'
export const nodePort = '${NODE_PORT}'
export const aquariusScheme = '${AQUARIUS_SCHEME}'
export const aquariusHost = '${AQUARIUS_HOST}'
export const aquariusPort = '${AQUARIUS_PORT}'
export const brizoScheme = '${BRIZO_SCHEME}'
export const brizoHost = '${BRIZO_HOST}'
export const brizoPort = '${BRIZO_ADDRESS}'
export const brizoAddress = '${BRIZO_ADDRESS}'
export const parityScheme = '${PARITY_SCHEME}'
export const parityHost = '${PARITY_HOST}'
export const parityPort = '${PARITY_PORT}'
export const secretStoreScheme = '${SECRET_STORE_SCHEME}'
export const secretStoreHost = '${SECRET_STORE_HOST}'
export const secretStorePort = '${SECRET_STORE_PORT}'
export const faucetScheme = '${FAUCET_SCHEME}'
export const faucetHost = '${FAUCET_HOST}'
export const faucetPort = '${FAUCET_PORT}'
export const verbose = true

View File

@ -1,22 +1,21 @@
[ [
{ {
"title": "Publish", "title": "Publish",
"link": "/publish" "link": "/publish",
"web3": true
}, },
{ {
"title": "History", "title": "History",
"link": "/history" "link": "/history",
"web3": true
}, },
{ {
"title": "Faucet", "title": "Faucet",
"link": "/faucet" "link": "/faucet",
"web3": true
}, },
{ {
"title": "About", "title": "About",
"link": "/about" "link": "/about"
},
{
"title": "Styleguide",
"link": "/styleguide"
} }
] ]

View File

@ -18,7 +18,7 @@ import {
secretStorePort, secretStorePort,
secretStoreScheme, secretStoreScheme,
verbose verbose
} from './config' } from './config/config'
export async function provideOcean() { export async function provideOcean() {
const nodeUri = `${nodeScheme}://${nodeHost}:${nodePort}` const nodeUri = `${nodeScheme}://${nodeHost}:${nodePort}`

View File

@ -10,6 +10,13 @@ interface AssetDetailsProps {
} }
export default class AssetDetails extends PureComponent<AssetDetailsProps> { export default class AssetDetails extends PureComponent<AssetDetailsProps> {
private datafilesLine = (files: any) => {
if (files.length === 1) {
return <span>{files.length} data file</span>
}
return <span>{files.length} data files</span>
}
public render() { public render() {
const { metadata, ddo } = this.props const { metadata, ddo } = this.props
const { base } = metadata const { base } = metadata
@ -43,9 +50,7 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
</Link> </Link>
)} )}
{base.files && ( {base.files && this.datafilesLine(base.files)}
<span>{base.files.length} data files</span>
)}
</div> </div>
</aside> </aside>
@ -79,9 +84,9 @@ export default class AssetDetails extends PureComponent<AssetDetailsProps> {
ddo={ddo} ddo={ddo}
/> />
<pre> {/* <pre>
<code>{JSON.stringify(metadata, null, 2)}</code> <code>{JSON.stringify(metadata, null, 2)}</code>
</pre> </pre> */}
</> </>
) )
} }

View File

@ -0,0 +1,60 @@
@import '../../styles/variables';
.buttonMain {
margin: auto;
margin-bottom: $spacer / 2;
display: block;
}
.error {
text-align: center;
color: $red;
font-size: $font-size-small;
}
.fileWrap {
margin-left: $spacer / 4;
margin-right: $spacer / 4;
margin-bottom: $spacer * $line-height;
flex: 1 1 100%;
@media (min-width: $break-point--small) {
flex-basis: calc(100% / 3 - #{$spacer} / 2);
}
}
.file {
display: inline-block;
background: $brand-grey;
padding: $spacer $spacer / 2;
margin-bottom: $spacer / 2;
text-align: left;
position: relative;
min-height: 100px;
&:before {
content: '';
position: absolute;
right: 0;
top: 0;
width: 0;
height: 0;
border-top: 1rem solid $body-background;
border-left: 1rem solid transparent;
}
li {
font-size: $font-size-small;
font-weight: $font-weight-bold;
color: $brand-white;
&:before {
display: none;
}
}
// move spinner a bit up
+ div {
margin-top: $spacer / 2;
}
}

View File

@ -0,0 +1,99 @@
import React, { PureComponent } from 'react'
import { Logger } from '@oceanprotocol/squid'
import filesize from 'filesize'
import { User } from '../../context/User'
import Button from '../../components/atoms/Button'
import Spinner from '../../components/atoms/Spinner'
import styles from './AssetFile.module.scss'
interface AssetFileProps {
file: any
ddo: any
}
interface AssetFileState {
isLoading: boolean
error: string
message: string
}
export default class AssetFile extends PureComponent<
AssetFileProps,
AssetFileState
> {
public state = {
isLoading: false,
error: '',
message: 'Decrypting file, please sign...'
}
private resetState = () => this.setState({ isLoading: true, error: '' })
private purchaseAsset = async (ddo: any, index: number) => {
this.resetState()
const { ocean } = this.context
const accounts = await ocean.accounts.list()
try {
const service = ddo.findServiceByType('Access')
const agreementId = await ocean.assets.order(
ddo.id,
service.serviceDefinitionId,
accounts[0]
)
const path = await ocean.assets.consume(
agreementId,
ddo.id,
service.serviceDefinitionId,
accounts[0],
'',
index
)
Logger.log('path', path)
this.setState({ isLoading: false })
} catch (error) {
Logger.log('error', error)
this.setState({ isLoading: false, error: error.message })
}
}
public render() {
const { ddo, file } = this.props
return (
<div className={styles.fileWrap}>
<ul key={file.index} className={styles.file}>
<li>
{file.contentType && file.contentType.split('/')[1]}
</li>
<li>
{file.contentLength && filesize(file.contentLength)}
</li>
{/* <li>{file.encoding}</li> */}
{/* <li>{file.compression}</li> */}
</ul>
{this.state.isLoading ? (
<Spinner message={this.state.message} />
) : (
<Button
primary
className={styles.buttonMain}
onClick={() => this.purchaseAsset(ddo, file.index)}
>
Get file
</Button>
)}
{this.state.error !== '' && (
<div className={styles.error}>{this.state.error}</div>
)}
</div>
)
}
}
AssetFile.contextType = User

View File

@ -1,36 +1,8 @@
@import '../../styles/variables'; @import '../../styles/variables';
.buttonMain {
margin: auto;
margin-bottom: $spacer / 2;
display: block;
}
.error {
text-align: center;
color: $red;
font-size: $font-size-small;
}
.files { .files {
text-align: center; text-align: center;
} display: flex;
flex-wrap: wrap;
.file { justify-content: center;
display: inline-block;
border: .1rem solid $brand-grey-light;
padding: $spacer $spacer / 2;
text-align: left;
margin-left: $spacer / 4;
margin-right: $spacer / 4;
li {
font-size: $font-size-small;
font-weight: $font-weight-bold;
color: $brand-grey-light;
&:before {
display: none;
}
}
} }

View File

@ -1,51 +1,11 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import { Logger } from '@oceanprotocol/squid' import AssetFile from './AssetFile'
import filesize from 'filesize'
import { User } from '../../context/User'
import Button from '../../components/atoms/Button'
import Spinner from '../../components/atoms/Spinner'
import styles from './AssetFilesDetails.module.scss' import styles from './AssetFilesDetails.module.scss'
interface AssetFilesDetailsProps { export default class AssetFilesDetails extends PureComponent<{
files: any[] files: any[]
ddo: any ddo: any
} }> {
export default class AssetFilesDetails extends PureComponent<
AssetFilesDetailsProps
> {
public state = { isLoading: false, error: null }
private purchaseAsset = async (ddo: any) => {
this.setState({ isLoading: true, error: null })
const { ocean } = this.context
const accounts = await ocean.accounts.list()
try {
const service = ddo.findServiceByType('Access')
const agreementId = await ocean.assets.order(
ddo.id,
service.serviceDefinitionId,
accounts[0]
)
const path = await ocean.assets.consume(
agreementId,
ddo.id,
service.serviceDefinitionId,
accounts[0],
''
)
Logger.log('path', path)
this.setState({ isLoading: false })
} catch (error) {
Logger.log('error', error)
this.setState({ isLoading: false, error: error.message })
}
}
public render() { public render() {
const { files, ddo } = this.props const { files, ddo } = this.props
@ -53,41 +13,12 @@ export default class AssetFilesDetails extends PureComponent<
<> <>
<div className={styles.files}> <div className={styles.files}>
{files.map(file => ( {files.map(file => (
<ul key={file.index} className={styles.file}> <AssetFile key={file.index} ddo={ddo} file={file} />
<li>
{file.contentType &&
file.contentType.split('/')[1]}
</li>
<li>
{file.contentLength &&
filesize(file.contentLength)}
</li>
{/* <li>{file.encoding}</li> */}
{/* <li>{file.compression}</li> */}
</ul>
))} ))}
</div> </div>
{this.state.isLoading ? (
<Spinner message="Decrypting files, please sign with your wallet..." />
) : (
<Button
primary
className={styles.buttonMain}
onClick={() => this.purchaseAsset(ddo)}
>
Get asset files
</Button>
)}
{this.state.error && (
<div className={styles.error}>{this.state.error}</div>
)}
</> </>
) : ( ) : (
<div>No files attached.</div> <div>No files attached.</div>
) )
} }
} }
AssetFilesDetails.contextType = User

View File

@ -6,7 +6,7 @@ import ItemForm from './ItemForm'
import Item from './Item' import Item from './Item'
import styles from './index.module.scss' import styles from './index.module.scss'
import { serviceHost, servicePort, serviceScheme } from '../../../config' import { serviceHost, servicePort, serviceScheme } from '../../../config/config'
interface File { interface File {
url: string url: string

View File

@ -3,3 +3,35 @@
.message { .message {
margin-bottom: $spacer; margin-bottom: $spacer;
} }
.success {
composes: message;
background: $green;
padding: $spacer / 1.5;
border-radius: $border-radius;
color: $brand-white;
font-weight: $font-weight-bold;
text-align: center;
&,
a,
button {
color: $brand-white;
}
a,
button {
transition: color .2s ease-out;
&:hover,
&:focus {
color: $brand-pink;
transform: none;
}
}
a {
display: inline-block;
margin-right: $spacer;
}
}

View File

@ -1,6 +1,7 @@
import React, { PureComponent } from 'react' import React, { PureComponent } from 'react'
import Web3message from '../../components/organisms/Web3message' import Web3message from '../../components/organisms/Web3message'
import Spinner from '../../components/atoms/Spinner' import Spinner from '../../components/atoms/Spinner'
import Button from '../../components/atoms/Button'
import styles from './StepRegisterContent.module.scss' import styles from './StepRegisterContent.module.scss'
interface StepRegisterContentProps { interface StepRegisterContentProps {
@ -26,11 +27,14 @@ export default class StepRegisterContent extends PureComponent<
) )
public publishedState = () => ( public publishedState = () => (
<div className={styles.message}> <div className={styles.success}>
Your asset is published! See it{' '} <p>Your asset is published!</p>
<a href={'/asset/' + this.props.state.publishedDid}>here</a>, submit <Button link to={'/asset/' + this.props.state.publishedDid}>
another asset by clicking{' '} See published asset
<a onClick={() => this.props.toStart()}>here</a> </Button>
<Button link onClick={() => this.props.toStart()}>
Publish another asset
</Button>
</div> </div>
) )
@ -38,7 +42,6 @@ export default class StepRegisterContent extends PureComponent<
return ( return (
<> <>
<Web3message /> <Web3message />
{this.props.state.isPublishing ? ( {this.props.state.isPublishing ? (
this.publishingState() this.publishingState()
) : this.props.state.publishingError ? ( ) : this.props.state.publishingError ? (

View File

@ -18,6 +18,8 @@ $yellow: #eac146;
$brand-gradient: linear-gradient(to right bottom, $brand-purple, $brand-pink); $brand-gradient: linear-gradient(to right bottom, $brand-purple, $brand-pink);
$body-background: darken($brand-white, 1%);
// Fonts // Fonts
$font-family-base: 'Sharp Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', $font-family-base: 'Sharp Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI',
Helvetica, Arial, sans-serif; Helvetica, Arial, sans-serif;

View File

@ -29,7 +29,7 @@ body {
font-family: $font-family-base; font-family: $font-family-base;
font-weight: $font-weight-base; font-weight: $font-weight-base;
line-height: $line-height; line-height: $line-height;
background: darken($brand-white, 1%); background: $body-background;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;

View File

@ -15,5 +15,5 @@
"noEmit": true, "noEmit": true,
"jsx": "preserve" "jsx": "preserve"
}, },
"include": ["src"] "include": ["src", "config/config.ts"]
} }

24
docker-compose.yml Normal file
View File

@ -0,0 +1,24 @@
version: '3.4'
services:
client:
build:
context: ./client
dockerfile: ./Dockerfile
ports:
- 3000:3000
depends_on:
- server
environment:
- SERVICE_SCHEME=http
- SERVICE_HOST=localhost
- SERVICE_PORT=4000
server:
build:
context: ./server
dockerfile: ./Dockerfile
ports:
- 4000:4000
command: npm run start

10
server/Dockerfile Normal file
View File

@ -0,0 +1,10 @@
FROM node:11-alpine
LABEL maintainer="Ocean Protocol <devops@oceanprotocol.com>"
WORKDIR /app/backend/
COPY . .
RUN npm install
RUN npm run build