refactor for Gatsby, update all the things
@ -1,6 +1,7 @@
|
|||||||
{
|
{
|
||||||
|
"parser": "babel-eslint",
|
||||||
"extends": ["eslint:recommended", "prettier"],
|
"extends": ["eslint:recommended", "prettier"],
|
||||||
"env": { "es6": true, "browser": true, "node": true },
|
"env": { "es6": true, "browser": true, "node": true, "jest": true },
|
||||||
"settings": {
|
"settings": {
|
||||||
"react": {
|
"react": {
|
||||||
"version": "detect"
|
"version": "detect"
|
||||||
|
2
.github/CODEOWNERS
vendored
@ -1 +1 @@
|
|||||||
* @maxieprotocol @kremalicious @pfmescher @unjapones
|
* @mihaisc @kremalicious
|
4
.gitignore
vendored
@ -4,8 +4,10 @@ out
|
|||||||
.next
|
.next
|
||||||
.idea
|
.idea
|
||||||
.env
|
.env
|
||||||
.env.build
|
|
||||||
coverage
|
coverage
|
||||||
|
dist
|
||||||
|
public
|
||||||
|
.cache
|
||||||
storybook-static
|
storybook-static
|
||||||
public/storybook
|
public/storybook
|
||||||
.artifacts
|
.artifacts
|
@ -1,7 +1,3 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
stories: [
|
stories: ['../src/**/*.stories.tsx', '../tests/**/*.stories.tsx']
|
||||||
'../src/components/**/*.stories.tsx',
|
|
||||||
'../src/styles/**/*.stories.tsx'
|
|
||||||
],
|
|
||||||
addons: []
|
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,11 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { addDecorator } from '@storybook/react'
|
import { addDecorator } from '@storybook/react'
|
||||||
import WebFont from 'webfontloader'
|
|
||||||
|
|
||||||
WebFont.load({
|
|
||||||
google: {
|
|
||||||
families: ['Montserrat:400,400i,600']
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Import global css with custom properties once for all stories.
|
// Import global css with custom properties once for all stories.
|
||||||
// Needed because in Next.js we impoprt that file only once too,
|
import '../src/global/styles.css'
|
||||||
// in src/_app.tsx which does not get loaded by Storybook
|
|
||||||
import '../src/styles/global.css'
|
|
||||||
|
|
||||||
// Wrapper for all stories previews
|
// Wrapper for all stories previews
|
||||||
addDecorator(storyFn => (
|
addDecorator((storyFn) => (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
minHeight: '100vh',
|
minHeight: '100vh',
|
||||||
@ -25,3 +16,19 @@ addDecorator(storyFn => (
|
|||||||
{storyFn()}
|
{storyFn()}
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|
||||||
|
// Gatsby's Link overrides:
|
||||||
|
// Gatsby defines a global called ___loader to prevent its method calls from creating console errors you override it here
|
||||||
|
global.___loader = {
|
||||||
|
enqueue: () => {},
|
||||||
|
hovering: () => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gatsby internal mocking to prevent unnecessary errors in storybook testing environment
|
||||||
|
global.__PATH_PREFIX__ = ''
|
||||||
|
global.__BASE_PATH__ = ''
|
||||||
|
|
||||||
|
// This is to utilized to override the window.___navigate method Gatsby defines and uses to report what path a Link would be taking us to if it wasn't inside a storybook
|
||||||
|
window.___navigate = (pathname) => {
|
||||||
|
action('NavigateTo:')(pathname)
|
||||||
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
// https://www.gatsbyjs.org/docs/visual-testing-with-storybook/
|
||||||
|
|
||||||
// Make CSS modules work
|
// Make CSS modules work
|
||||||
// https://github.com/storybookjs/storybook/issues/4306#issuecomment-517951264
|
// https://github.com/storybookjs/storybook/issues/4306#issuecomment-517951264
|
||||||
const setCssModulesRule = rule => {
|
const setCssModulesRule = (rule) => {
|
||||||
const nextRule = rule
|
const nextRule = rule
|
||||||
const cssLoader = rule.use[1]
|
const cssLoader = rule.use[1]
|
||||||
|
|
||||||
@ -15,8 +17,8 @@ const setCssModulesRule = rule => {
|
|||||||
return nextRule
|
return nextRule
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = async ({ config, mode }) => {
|
module.exports = ({ config }) => {
|
||||||
const cssRules = config.module.rules.map(rule => {
|
const cssRules = config.module.rules.map((rule) => {
|
||||||
const isCssRule = rule.test.toString().indexOf('css') !== -1
|
const isCssRule = rule.test.toString().indexOf('css') !== -1
|
||||||
let nextRule = rule
|
let nextRule = rule
|
||||||
|
|
||||||
@ -28,28 +30,46 @@ module.exports = async ({ config, mode }) => {
|
|||||||
|
|
||||||
config.module.rules = cssRules
|
config.module.rules = cssRules
|
||||||
|
|
||||||
|
// Transpile Gatsby module because Gatsby includes un-transpiled ES6 code.
|
||||||
|
config.module.rules[0].exclude = [/node_modules\/(?!(gatsby)\/)/]
|
||||||
|
// use installed babel-loader which is v8.0-beta (which is meant to work with @babel/core@7)
|
||||||
|
config.module.rules[0].use[0].loader = require.resolve('babel-loader')
|
||||||
|
|
||||||
|
// use @babel/preset-react for JSX and env (instead of staged presets)
|
||||||
|
config.module.rules[0].use[0].options.presets = [
|
||||||
|
require.resolve('@babel/preset-react'),
|
||||||
|
require.resolve('@babel/preset-env')
|
||||||
|
]
|
||||||
|
config.module.rules[0].use[0].options.plugins = [
|
||||||
|
// use @babel/plugin-proposal-class-properties for class arrow functions
|
||||||
|
require.resolve('@babel/plugin-proposal-class-properties'),
|
||||||
|
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
|
||||||
|
require.resolve('babel-plugin-remove-graphql-queries')
|
||||||
|
]
|
||||||
|
// Prefer Gatsby ES6 entrypoint (module) over commonjs (main) entrypoint
|
||||||
|
config.resolve.mainFields = ['browser', 'module', 'main']
|
||||||
|
|
||||||
|
// Handle TypeScript
|
||||||
config.module.rules.push({
|
config.module.rules.push({
|
||||||
test: /\.(ts|tsx)$/,
|
test: /\.(ts|tsx)$/,
|
||||||
loader: require.resolve('babel-loader'),
|
loader: require.resolve('babel-loader'),
|
||||||
options: {
|
options: {
|
||||||
presets: [['react-app', { flow: false, typescript: true }]]
|
presets: [['react-app', { flow: false, typescript: true }]],
|
||||||
|
plugins: [
|
||||||
|
require.resolve('@babel/plugin-proposal-class-properties'),
|
||||||
|
// use babel-plugin-remove-graphql-queries to remove static queries from components when rendering in storybook
|
||||||
|
require.resolve('babel-plugin-remove-graphql-queries')
|
||||||
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
config.resolve.extensions.push('.ts', '.tsx')
|
config.resolve.extensions.push('.ts', '.tsx')
|
||||||
|
|
||||||
config.node = {
|
|
||||||
fs: 'empty'
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handle SVGs
|
// Handle SVGs
|
||||||
// Don't use Storybook's default SVG Configuration
|
// Don't use Storybook's default SVG Configuration
|
||||||
config.module.rules = config.module.rules.map(rule => {
|
config.module.rules = config.module.rules.map((rule) => {
|
||||||
if (rule.test.toString().includes('svg')) {
|
if (rule.test.toString().includes('svg')) {
|
||||||
const test = rule.test
|
const test = rule.test.toString().replace('svg|', '').replace(/\//g, '')
|
||||||
.toString()
|
|
||||||
.replace('svg|', '')
|
|
||||||
.replace(/\//g, '')
|
|
||||||
return { ...rule, test: new RegExp(test) }
|
return { ...rule, test: new RegExp(test) }
|
||||||
} else {
|
} else {
|
||||||
return rule
|
return rule
|
||||||
@ -59,7 +79,19 @@ module.exports = async ({ config, mode }) => {
|
|||||||
// Use SVG Configuration for SVGR yourself
|
// Use SVG Configuration for SVGR yourself
|
||||||
config.module.rules.push({
|
config.module.rules.push({
|
||||||
test: /\.svg$/,
|
test: /\.svg$/,
|
||||||
use: ['@svgr/webpack']
|
use: [
|
||||||
|
{
|
||||||
|
loader: '@svgr/webpack',
|
||||||
|
options: {
|
||||||
|
svgoConfig: {
|
||||||
|
plugins: {
|
||||||
|
removeViewBox: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'url-loader'
|
||||||
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
return config
|
return config
|
||||||
|
@ -4,8 +4,6 @@ node_js: node
|
|||||||
|
|
||||||
cache:
|
cache:
|
||||||
npm: true
|
npm: true
|
||||||
directories:
|
|
||||||
- .next/cache
|
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
||||||
|
79
README.md
@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
<h1 align="center">Ocean Marketplace</h1>
|
<h1 align="center">Ocean Marketplace</h1>
|
||||||
|
|
||||||
>
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.com/oceanprotocol/market.svg?branch=master)](https://travis-ci.com/oceanprotocol/market)
|
[![Build Status](https://travis-ci.com/oceanprotocol/market.svg?branch=master)](https://travis-ci.com/oceanprotocol/market)
|
||||||
[![Now deployment](https://flat.badgen.net/badge/now/auto-deployment/21c4dd?icon=now)](https://zeit.co/oceanprotocol/market)
|
[![Now deployment](https://flat.badgen.net/badge/now/auto-deployment/21c4dd?icon=now)](https://zeit.co/oceanprotocol/market)
|
||||||
[![Maintainability](https://api.codeclimate.com/v1/badges/d114f94f75e6efd2ee71/maintainability)](https://codeclimate.com/repos/5e3933869a31771fd800011c/maintainability)
|
[![Maintainability](https://api.codeclimate.com/v1/badges/d114f94f75e6efd2ee71/maintainability)](https://codeclimate.com/repos/5e3933869a31771fd800011c/maintainability)
|
||||||
@ -15,6 +13,7 @@
|
|||||||
- [🤓 Resources](#-resources)
|
- [🤓 Resources](#-resources)
|
||||||
- [🏄 Get Started](#-get-started)
|
- [🏄 Get Started](#-get-started)
|
||||||
- [Local Spree components with Barge](#local-spree-components-with-barge)
|
- [Local Spree components with Barge](#local-spree-components-with-barge)
|
||||||
|
- [API](#api)
|
||||||
- [🦑 Environment variables](#-environment-variables)
|
- [🦑 Environment variables](#-environment-variables)
|
||||||
- [🎨 Storybook](#-storybook)
|
- [🎨 Storybook](#-storybook)
|
||||||
- [✨ Code Style](#-code-style)
|
- [✨ Code Style](#-code-style)
|
||||||
@ -27,30 +26,25 @@
|
|||||||
|
|
||||||
## 🤓 Resources
|
## 🤓 Resources
|
||||||
|
|
||||||
- [UI Design: Figma Mock Up](https://www.figma.com/file/K38ZsQjzndyp2YFJCLxIN7/dexFreight-Marketplace)
|
|
||||||
- [Planning: ZenHub Board](https://app.zenhub.com/workspaces/dexfreight-marketplace-5e2f201751116794cf4f2e75/board?repos=236508929)
|
|
||||||
|
|
||||||
## 🏄 Get Started
|
## 🏄 Get Started
|
||||||
|
|
||||||
The app is a React app built with [Next.js](https://nextjs.org) + TypeScript + CSS modules and will connect to Ocean components in Pacific by default.
|
The app is a React app built with [Gatsby.js](https://www.gatsbyjs.org) + TypeScript + CSS modules and will connect to Ocean components in Pacific by default.
|
||||||
|
|
||||||
To start local development:
|
To start local development:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git clone git@github.com:oceanprotocol/dexfreight.git
|
git clone git@github.com:oceanprotocol/market.git
|
||||||
cd dexfreight
|
cd market
|
||||||
|
|
||||||
npm install
|
npm install
|
||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
This will launch the app under [localhost:3000](http://localhost:3000).
|
This will start the development server under
|
||||||
|
`http://localhost:8000`.
|
||||||
|
|
||||||
Depending on your configuration, you might have to increase the amount of `inotify` watchers:
|
To explore the generated GraphQL data structure fire up the accompanying GraphiQL IDE under
|
||||||
|
`http://localhost:8000/__graphql`.
|
||||||
```
|
|
||||||
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
|
||||||
```
|
|
||||||
|
|
||||||
### Local Spree components with Barge
|
### Local Spree components with Barge
|
||||||
|
|
||||||
@ -72,33 +66,30 @@ This will take some time on first start, and at the end you need to copy the gen
|
|||||||
|
|
||||||
The script will wait for all contracts to be generated in the `keeper-contracts` Docker container, then will copy the artifacts in place into `node_modules/@oceanprotocol/keeper-contracts/artifacts/`.
|
The script will wait for all contracts to be generated in the `keeper-contracts` Docker container, then will copy the artifacts in place into `node_modules/@oceanprotocol/keeper-contracts/artifacts/`.
|
||||||
|
|
||||||
Finally, set environment variables to use those local connections in `.env` & `.env.build` in the app:
|
Finally, set environment variables to use those local connections in `.env` in the app:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# modify env variables, Spree is enabled by default when using those files
|
# modify env variables, Spree is enabled by default when using those files
|
||||||
cp .env.example .env && cp .env.example .env.build
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
Files under `/api` are isolated and not part of Gatsby.
|
||||||
|
|
||||||
|
- [API Documentation](api/)
|
||||||
|
|
||||||
## 🦑 Environment variables
|
## 🦑 Environment variables
|
||||||
|
|
||||||
The `./src/config/ocean.ts` file is setup to prioritize environment variables for setting each Ocean component endpoint. By setting environment variables, you can easily switch between Ocean networks the app connects to, without directly modifying `./src/config/ocean.ts`.
|
The `./src/config/ocean.ts` file is setup to prioritize environment variables for setting each Ocean component endpoint. By setting environment variables, you can easily switch between Ocean networks the app connects to, without directly modifying `./src/config/ocean.ts`.
|
||||||
|
|
||||||
For local development, you can use a `.env` & `.env.build` file:
|
For local development, you can use a `.env` file:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# modify env variables, Spree is enabled by default when using those files
|
# modify env variables, Spree is enabled by default when using those files
|
||||||
cp .env.example .env && cp .env.example .env.build
|
cp .env.example .env
|
||||||
```
|
```
|
||||||
|
|
||||||
For a Now deployment, all environment variables defining the Ocean component endpoints need to be added with `now secrets` to `oceanprotocol` org based on the `@` variable names defined in `now.json`, e.g.:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
now switch
|
|
||||||
now secrets add aquarius_uri https://aquarius.pacific.dexfreight.dev-ocean.com
|
|
||||||
```
|
|
||||||
|
|
||||||
Adding the env vars like that will provide them during both, build & run time.
|
|
||||||
|
|
||||||
## 🎨 Storybook
|
## 🎨 Storybook
|
||||||
|
|
||||||
[Storybook](https://storybook.js.org) is set up for this project and is used for UI development of components. Stories are created inside `src/components/` alongside each component in the form of `ComponentName.stories.tsx`.
|
[Storybook](https://storybook.js.org) is set up for this project and is used for UI development of components. Stories are created inside `src/components/` alongside each component in the form of `ComponentName.stories.tsx`.
|
||||||
@ -130,9 +121,7 @@ npm run format
|
|||||||
Test suite for unit tests is setup with [Jest](https://jestjs.io) as a test runner and:
|
Test suite for unit tests is setup with [Jest](https://jestjs.io) as a test runner and:
|
||||||
|
|
||||||
- [react-testing-library](https://github.com/kentcdodds/react-testing-library) for all React components
|
- [react-testing-library](https://github.com/kentcdodds/react-testing-library) for all React components
|
||||||
- [node-mocks-http](https://github.com/howardabrams/node-mocks-http) for all `src/pages/api/` routes
|
- [node-mocks-http](https://github.com/howardabrams/node-mocks-http) for all `api/` routes
|
||||||
|
|
||||||
> Note: fully testing Next.js API routes should be part of integration tests. There are [various problems](https://spectrum.chat/next-js/general/api-routes-unit-testing~aa868f97-3a7d-45fe-97e5-3f0408f0022d) with fully testing them so a proper unit test suite for them should be setup.
|
|
||||||
|
|
||||||
To run all linting and unit tests:
|
To run all linting and unit tests:
|
||||||
|
|
||||||
@ -164,7 +153,7 @@ npm run serve
|
|||||||
|
|
||||||
## ⬆️ Deployment
|
## ⬆️ Deployment
|
||||||
|
|
||||||
Every branch or Pull Request is automatically deployed by [Now](https://zeit.co/now) with their GitHub integration. A link to a deployment will appear under each Pull Request.
|
Every branch or Pull Request is automatically deployed by [Vercel](https://vercel.com) with their GitHub integration. A link to a deployment will appear under each Pull Request.
|
||||||
|
|
||||||
The latest deployment of the `master` branch is automatically aliased to `xxx`.
|
The latest deployment of the `master` branch is automatically aliased to `xxx`.
|
||||||
|
|
||||||
@ -174,47 +163,47 @@ If needed, app can be deployed manually. Make sure to switch to Ocean Protocol o
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# first run
|
# first run
|
||||||
now login
|
vercel login
|
||||||
now switch
|
vercel switch
|
||||||
|
|
||||||
# deploy
|
# deploy
|
||||||
now
|
vercel
|
||||||
# switch alias to new deployment
|
# switch alias to new deployment
|
||||||
now alias
|
vercel alias
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🏗 Ocean Protocol Infrastructure
|
## 🏗 Ocean Protocol Infrastructure
|
||||||
|
|
||||||
The following Aquarius & Brizo instances specifically for dexFreight marketplace are deployed in Ocean Protocol's AWS K8:
|
The following Aquarius & Brizo instances specifically for marketplace are deployed in Ocean Protocol's AWS K8:
|
||||||
|
|
||||||
**Nile (Staging)**
|
**Nile (Staging)**
|
||||||
|
|
||||||
- K8 namespace: `dexfreight-nile`
|
- K8 namespace: `market-nile`
|
||||||
- `aquarius.nile.dexfreight.dev-ocean.com`
|
- `aquarius.nile.market.dev-ocean.com`
|
||||||
- `brizo.nile.dexfreight.dev-ocean.com`
|
- `brizo.nile.market.dev-ocean.com`
|
||||||
|
|
||||||
Edit command with `kubectl`, e.g.:
|
Edit command with `kubectl`, e.g.:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl edit deployment -n dexfreight-nile aquarius
|
kubectl edit deployment -n market-nile aquarius
|
||||||
```
|
```
|
||||||
|
|
||||||
**Pacific (Production)**
|
**Pacific (Production)**
|
||||||
|
|
||||||
- K8 namespace: `dexfreight-pacific`
|
- K8 namespace: `market-pacific`
|
||||||
- `aquarius.pacific.dexfreight.dev-ocean.com`
|
- `aquarius.pacific.market.dev-ocean.com`
|
||||||
- `brizo.pacific.dexfreight.dev-ocean.com`
|
- `brizo.pacific.market.dev-ocean.com`
|
||||||
|
|
||||||
Edit command with `kubectl`, e.g.:
|
Edit command with `kubectl`, e.g.:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
kubectl edit deployment -n dexfreight-pacific aquarius
|
kubectl edit deployment -n market-pacific aquarius
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🏛 License
|
## 🏛 License
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Copyright 2019 Ocean Protocol Foundation Ltd.
|
Copyright 2020 Ocean Protocol Foundation Ltd.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
46
gatsby-config.js
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
require('dotenv').config()
|
||||||
|
|
||||||
|
const siteConfig = require('./site.config.js')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
siteMetadata: {
|
||||||
|
...siteConfig
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-source-filesystem',
|
||||||
|
options: {
|
||||||
|
name: 'content',
|
||||||
|
path: `${__dirname}/content`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-source-filesystem',
|
||||||
|
options: {
|
||||||
|
name: 'images',
|
||||||
|
path: `${__dirname}/src/images`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-source-filesystem',
|
||||||
|
options: {
|
||||||
|
name: 'art',
|
||||||
|
path: `${__dirname}/node_modules/@oceanprotocol/art/`
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'gatsby-transformer-json',
|
||||||
|
'gatsby-transformer-remark',
|
||||||
|
{
|
||||||
|
resolve: 'gatsby-plugin-svgr',
|
||||||
|
options: {
|
||||||
|
icon: false,
|
||||||
|
svgoConfig: {
|
||||||
|
plugins: [{ removeViewBox: false }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'gatsby-plugin-react-helmet',
|
||||||
|
'gatsby-plugin-remove-trailing-slashes',
|
||||||
|
'gatsby-plugin-webpack-size'
|
||||||
|
]
|
||||||
|
}
|
@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"jsx": "react",
|
|
||||||
"allowJs": true,
|
|
||||||
"resolveJsonModule": true,
|
|
||||||
"allowSyntheticDefaultImports": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"noImplicitAny": true,
|
|
||||||
"sourceMap": true,
|
|
||||||
"target": "es5"
|
|
||||||
}
|
|
||||||
}
|
|
2
next-env.d.ts
vendored
@ -1,2 +0,0 @@
|
|||||||
/// <reference types="next" />
|
|
||||||
/// <reference types="next/types/global" />
|
|
109
next.config.js
@ -1,109 +0,0 @@
|
|||||||
const webpack = require('webpack')
|
|
||||||
require('dotenv').config()
|
|
||||||
|
|
||||||
// Returns environment variables as an object
|
|
||||||
const env = Object.keys(process.env).reduce((acc, curr) => {
|
|
||||||
acc[`process.env.${curr}`] = JSON.stringify(process.env[curr])
|
|
||||||
return acc
|
|
||||||
}, {})
|
|
||||||
|
|
||||||
const withSvgr = (nextConfig = {}) => ({
|
|
||||||
webpack(config, options) {
|
|
||||||
config.module.rules.push({
|
|
||||||
test: /\.svg$/,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: '@svgr/webpack',
|
|
||||||
options: {
|
|
||||||
icon: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
|
|
||||||
if (typeof nextConfig.webpack === 'function') {
|
|
||||||
return nextConfig.webpack(config, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
|
||||||
const withFsFix = (nextConfig = {}) => ({
|
|
||||||
webpack(config, options) {
|
|
||||||
// Fixes npm packages that depend on `fs` module
|
|
||||||
// https://github.com/zeit/next.js/issues/7755#issuecomment-508633125
|
|
||||||
// or https://github.com/zeit/next.js/issues/7755
|
|
||||||
if (!options.isServer) {
|
|
||||||
config.node = {
|
|
||||||
fs: 'empty'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof nextConfig.webpack === 'function') {
|
|
||||||
return nextConfig.webpack(config, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const withGlobalConstants = (nextConfig = {}) => ({
|
|
||||||
webpack(config, options) {
|
|
||||||
// Allows to create global constants which can be configured at compile
|
|
||||||
// time (in this case they are the environment variables)
|
|
||||||
config.plugins.push(new webpack.DefinePlugin(env))
|
|
||||||
|
|
||||||
if (typeof nextConfig.webpack === 'function') {
|
|
||||||
return nextConfig.webpack(config, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const withBundleAnalyzer = require('@next/bundle-analyzer')({
|
|
||||||
enabled: process.env.ANALYZE === 'true'
|
|
||||||
})
|
|
||||||
|
|
||||||
const withMarkdown = (nextConfig = {}) => ({
|
|
||||||
webpack(config, options) {
|
|
||||||
config.module.rules.push({
|
|
||||||
test: /\.md$/,
|
|
||||||
loader: 'raw-loader'
|
|
||||||
})
|
|
||||||
|
|
||||||
if (typeof nextConfig.webpack === 'function') {
|
|
||||||
return nextConfig.webpack(config, options)
|
|
||||||
}
|
|
||||||
|
|
||||||
return config
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
module.exports = withBundleAnalyzer(
|
|
||||||
withSvgr(
|
|
||||||
withFsFix(
|
|
||||||
withMarkdown(
|
|
||||||
withGlobalConstants({
|
|
||||||
exportPathMap: (defaultPathMap, { dev }) => {
|
|
||||||
// In dev environment return defaultPathMas as it is
|
|
||||||
if (dev) {
|
|
||||||
return defaultPathMap
|
|
||||||
}
|
|
||||||
|
|
||||||
// pages we know about beforehand
|
|
||||||
const paths = {
|
|
||||||
'/': { page: '/' },
|
|
||||||
'/publish': { page: '/publish' },
|
|
||||||
'/explore': { page: '/explore' }
|
|
||||||
}
|
|
||||||
|
|
||||||
return paths
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
26605
package-lock.json
generated
97
package.json
@ -1,19 +1,20 @@
|
|||||||
{
|
{
|
||||||
"name": "market",
|
"name": "@oceanprotocol/market",
|
||||||
"description": "Data marketplace for ocean.",
|
"description": "Data marketplace for ocean.",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
"homepage": "https://oceanprotocol.com",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "next dev",
|
"start": "gatsby develop --host 0.0.0.0",
|
||||||
"export": "next export",
|
"build": "gatsby build",
|
||||||
"build": "npm run storybook:build && next build",
|
"serve": "serve -s public/",
|
||||||
"serve": "next start",
|
|
||||||
"jest": "NODE_ENV=test jest -c tests/unit/jest.config.js",
|
"jest": "NODE_ENV=test jest -c tests/unit/jest.config.js",
|
||||||
"test": "npm run lint && npm run jest",
|
"test": "npm run lint && npm run jest",
|
||||||
"test:watch": "npm run lint && npm run jest -- --watch",
|
"test:watch": "npm run lint && npm run jest -- --watch",
|
||||||
"lint": "eslint --ignore-path .gitignore --ext .js --ext .ts --ext .tsx .",
|
"lint": "eslint --ignore-path .gitignore --ext .js --ext .ts --ext .tsx .",
|
||||||
"format": "prettier --ignore-path .gitignore **/**/*.{css,yml,js,jsx,ts,tsx,json} --write",
|
"format": "prettier --ignore-path .gitignore './**/*.{css,yml,js,ts,tsx,json}' --write",
|
||||||
"analyze": "ANALYZE=true next build",
|
"type-check": "tsc --noEmit",
|
||||||
|
"analyze": "npm run build && source-map-explorer 'public/*.js'",
|
||||||
"storybook": "start-storybook -p 4000 -c .storybook",
|
"storybook": "start-storybook -p 4000 -c .storybook",
|
||||||
"storybook:build": "build-storybook -c .storybook -o public/storybook"
|
"storybook:build": "build-storybook -c .storybook -o public/storybook"
|
||||||
},
|
},
|
||||||
@ -23,70 +24,70 @@
|
|||||||
"@oceanprotocol/squid": "^2.2.0",
|
"@oceanprotocol/squid": "^2.2.0",
|
||||||
"@oceanprotocol/typographies": "^0.1.0",
|
"@oceanprotocol/typographies": "^0.1.0",
|
||||||
"@sindresorhus/slugify": "^1.0.0",
|
"@sindresorhus/slugify": "^1.0.0",
|
||||||
"@tippyjs/react": "^4.0.2",
|
"@tippyjs/react": "^4.0.5",
|
||||||
"@types/classnames": "^2.2.10",
|
"@types/classnames": "^2.2.10",
|
||||||
"axios": "^0.19.2",
|
"axios": "^0.19.2",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"date-fns": "^2.11.0",
|
"date-fns": "^2.14.0",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"filesize": "^6.1.0",
|
"filesize": "^6.1.0",
|
||||||
"is-url-superb": "^3.0.0",
|
"gatsby": "^2.23.12",
|
||||||
"next": "^9.3.2",
|
"gatsby-plugin-react-helmet": "^3.3.6",
|
||||||
"next-seo": "^4.4.0",
|
"gatsby-plugin-remove-trailing-slashes": "^2.3.7",
|
||||||
"next-svgr": "^0.0.2",
|
"gatsby-plugin-svgr": "^2.0.2",
|
||||||
"nprogress": "^0.2.0",
|
"gatsby-plugin-webpack-size": "^1.0.0",
|
||||||
|
"gatsby-source-filesystem": "^2.3.14",
|
||||||
|
"gatsby-source-graphql": "^2.5.7",
|
||||||
|
"gatsby-transformer-json": "^2.4.7",
|
||||||
|
"gatsby-transformer-remark": "^2.8.20",
|
||||||
|
"is-url-superb": "^4.0.0",
|
||||||
"numeral": "^2.0.6",
|
"numeral": "^2.0.6",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-data-table-component": "^6.9.2",
|
"react-data-table-component": "^6.9.3",
|
||||||
"react-datepicker": "^2.14.0",
|
"react-datepicker": "^3.0.0",
|
||||||
"react-dom": "^16.13.1",
|
"react-dom": "^16.13.1",
|
||||||
"react-dotdotdot": "^1.3.1",
|
"react-dotdotdot": "^1.3.1",
|
||||||
"react-dropzone": "^11.0.1",
|
"react-dropzone": "^11.0.1",
|
||||||
"react-jsonschema-form": "^1.8.1",
|
"react-jsonschema-form": "^1.8.1",
|
||||||
"react-markdown": "^4.3.1",
|
"react-markdown": "^4.3.1",
|
||||||
"react-paginate": "^6.3.2",
|
"react-paginate": "^6.3.2",
|
||||||
"react-rating": "^2.0.4",
|
"react-rating": "^2.0.5",
|
||||||
"react-responsive-modal": "^5.0.2",
|
"react-responsive-modal": "^5.0.2",
|
||||||
"react-toastify": "^5.5.0",
|
"react-toastify": "^6.0.6",
|
||||||
"shortid": "^2.2.15",
|
"shortid": "^2.2.15",
|
||||||
"slugify": "^1.4.0",
|
"slugify": "^1.4.4",
|
||||||
"use-debounce": "^3.4.0",
|
"use-debounce": "^3.4.2",
|
||||||
"web3connect": "^1.0.0-beta.33"
|
"web3connect": "^1.0.0-beta.33"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.8.7",
|
"@babel/core": "^7.10.3",
|
||||||
"@next/bundle-analyzer": "^9.3.0",
|
"@storybook/addon-storyshots": "^5.3.19",
|
||||||
"@storybook/addon-storyshots": "^5.3.17",
|
"@storybook/react": "^5.3.19",
|
||||||
"@storybook/react": "^5.3.17",
|
"@testing-library/jest-dom": "^5.11.0",
|
||||||
"@testing-library/jest-dom": "^5.1.1",
|
"@testing-library/react": "^10.4.3",
|
||||||
"@testing-library/react": "^10.0.1",
|
"@testing-library/react-hooks": "^3.3.0",
|
||||||
"@testing-library/react-hooks": "^3.2.1",
|
"@types/jest": "^26.0.3",
|
||||||
"@types/jest": "^25.1.4",
|
"@types/node": "^14.0.14",
|
||||||
"@types/node": "^13.9.1",
|
"@types/numeral": "^0.0.28",
|
||||||
"@types/nprogress": "^0.2.0",
|
"@types/react": "^16.9.41",
|
||||||
"@types/numeral": "0.0.26",
|
"@types/react-datepicker": "^3.0.2",
|
||||||
"@types/react": "^16.9.23",
|
"@types/react-jsonschema-form": "^1.7.3",
|
||||||
"@types/react-datepicker": "^2.11.0",
|
|
||||||
"@types/react-jsonschema-form": "^1.7.0",
|
|
||||||
"@types/react-paginate": "^6.2.1",
|
"@types/react-paginate": "^6.2.1",
|
||||||
"@types/shortid": "0.0.29",
|
"@types/shortid": "0.0.29",
|
||||||
"@typescript-eslint/eslint-plugin": "^2.23.0",
|
"@typescript-eslint/eslint-plugin": "^3.5.0",
|
||||||
"@typescript-eslint/parser": "^2.23.0",
|
"@typescript-eslint/parser": "^3.5.0",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.1.0",
|
||||||
"babel-preset-react-app": "^9.1.1",
|
"babel-preset-react-app": "^9.1.2",
|
||||||
"eslint": "^6.8.0",
|
"eslint": "^7.3.1",
|
||||||
"eslint-config-oceanprotocol": "^1.5.0",
|
"eslint-config-oceanprotocol": "^1.5.0",
|
||||||
"eslint-config-prettier": "^6.10.0",
|
"eslint-config-prettier": "^6.11.0",
|
||||||
"eslint-plugin-prettier": "^3.1.2",
|
"eslint-plugin-prettier": "^3.1.4",
|
||||||
"eslint-plugin-react": "^7.19.0",
|
"eslint-plugin-react": "^7.20.2",
|
||||||
"identity-obj-proxy": "^3.0.0",
|
"identity-obj-proxy": "^3.0.0",
|
||||||
"jest": "^25.1.0",
|
"jest": "^26.1.0",
|
||||||
"node-mocks-http": "^1.8.1",
|
"node-mocks-http": "^1.8.1",
|
||||||
"prettier": "^1.19.1",
|
"prettier": "^2.0.5",
|
||||||
"react-test-renderer": "^16.12.0",
|
"typescript": "^3.9.5"
|
||||||
"ts-jest": "^25.2.1",
|
|
||||||
"typescript": "^3.8.3",
|
|
||||||
"webfontloader": "^1.6.28"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -1,23 +1,9 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
title: 'Ocean Market',
|
siteTitle: 'Ocean Market',
|
||||||
description: `A marketplace to find and publish open data sets in the Ocean Network.`,
|
siteTagline: `A marketplace to find and publish open data sets in the Ocean Network.`,
|
||||||
url: 'https://market.oceanprotocol.now.sh/',
|
siteUrl: 'https://market.oceanprotocol.now.sh/',
|
||||||
copyright:
|
copyright:
|
||||||
'All Rights Reserved. Powered by [Ocean Protocol](https://oceanprotocol.com)',
|
'All Rights Reserved. Powered by [Ocean Protocol](https://oceanprotocol.com)',
|
||||||
refundPolicy: [
|
|
||||||
'Data can be challenged within 2 days after purchase.',
|
|
||||||
'The marketplace decides if you are eligible for refund.'
|
|
||||||
],
|
|
||||||
assetTerms: [
|
|
||||||
{
|
|
||||||
name: 'Personal Identifiable Information',
|
|
||||||
value: 'This offer contains no personal data'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Regions where data can be used',
|
|
||||||
value: 'Worldwide'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
menu: [
|
menu: [
|
||||||
{
|
{
|
||||||
name: 'Explore',
|
name: 'Explore',
|
||||||
|
@ -14,7 +14,7 @@ export default function Dropzone({
|
|||||||
multiple?: boolean
|
multiple?: boolean
|
||||||
error?: string
|
error?: string
|
||||||
}) {
|
}) {
|
||||||
const onDrop = useCallback(acceptedFiles => handleOnDrop(acceptedFiles), [
|
const onDrop = useCallback((acceptedFiles) => handleOnDrop(acceptedFiles), [
|
||||||
handleOnDrop
|
handleOnDrop
|
||||||
])
|
])
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ export default function DateRangeWidget(props: WidgetProps) {
|
|||||||
<input
|
<input
|
||||||
id="range"
|
id="range"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
onChange={ev => setRange(ev.target.checked)}
|
onChange={(ev) => setRange(ev.target.checked)}
|
||||||
checked={range}
|
checked={range}
|
||||||
/>
|
/>
|
||||||
<label className={styles.label} htmlFor="range">
|
<label className={styles.label} htmlFor="range">
|
||||||
|
@ -32,9 +32,9 @@ export default function TermsWidget(props: WidgetProps) {
|
|||||||
checked={typeof value === 'undefined' ? false : value}
|
checked={typeof value === 'undefined' ? false : value}
|
||||||
disabled={disabled || readonly}
|
disabled={disabled || readonly}
|
||||||
autoFocus={autofocus}
|
autoFocus={autofocus}
|
||||||
onChange={event => onChange(event.target.checked)}
|
onChange={(event) => onChange(event.target.checked)}
|
||||||
onBlur={onBlur && (event => onBlur(id, event.target.checked))}
|
onBlur={onBlur && ((event) => onBlur(id, event.target.checked))}
|
||||||
onFocus={onFocus && (event => onFocus(id, event.target.checked))}
|
onFocus={onFocus && ((event) => onFocus(id, event.target.checked))}
|
||||||
/>
|
/>
|
||||||
<span>{label}</span>
|
<span>{label}</span>
|
||||||
</label>
|
</label>
|
||||||
|
@ -44,7 +44,7 @@ const Tags: React.FC<TagsProps> = ({
|
|||||||
return (
|
return (
|
||||||
<div className={classes}>
|
<div className={classes}>
|
||||||
{tags &&
|
{tags &&
|
||||||
tags.map(tag => (
|
tags.map((tag) => (
|
||||||
<Tag tag={tag} noLinks={noLinks} key={shortid.generate()} />
|
<Tag tag={tag} noLinks={noLinks} key={shortid.generate()} />
|
||||||
))}
|
))}
|
||||||
{shouldShowMore && (
|
{shouldShowMore && (
|
||||||
|
@ -13,7 +13,7 @@ export const FieldTemplate = ({
|
|||||||
rawErrors,
|
rawErrors,
|
||||||
children
|
children
|
||||||
}: FieldTemplateProps) => {
|
}: FieldTemplateProps) => {
|
||||||
const noLabel = id !== noLabelFields.filter(f => id === f)[0]
|
const noLabel = id !== noLabelFields.filter((f) => id === f)[0]
|
||||||
return (
|
return (
|
||||||
<section
|
<section
|
||||||
key={id}
|
key={id}
|
||||||
|
@ -39,8 +39,8 @@ export default function Pagination({
|
|||||||
// adapt based on media query match
|
// adapt based on media query match
|
||||||
marginPagesDisplayed={smallViewport ? 0 : 1}
|
marginPagesDisplayed={smallViewport ? 0 : 1}
|
||||||
pageRangeDisplayed={smallViewport ? 3 : 6}
|
pageRangeDisplayed={smallViewport ? 3 : 6}
|
||||||
onPageChange={data => onPageChange(data.selected)}
|
onPageChange={(data) => onPageChange(data.selected)}
|
||||||
hrefBuilder={pageIndex => hrefBuilder(pageIndex)}
|
hrefBuilder={(pageIndex) => hrefBuilder(pageIndex)}
|
||||||
disableInitialCallback
|
disableInitialCallback
|
||||||
previousLabel="←"
|
previousLabel="←"
|
||||||
nextLabel="→"
|
nextLabel="→"
|
||||||
|
@ -51,7 +51,7 @@ export default function SearchBar({
|
|||||||
className={large ? `${styles.input} ${styles.large}` : styles.input}
|
className={large ? `${styles.input} ${styles.large}` : styles.input}
|
||||||
placeholder={placeholder || 'What are you looking for?'}
|
placeholder={placeholder || 'What are you looking for?'}
|
||||||
value={value}
|
value={value}
|
||||||
onChange={e => handleChange(e)}
|
onChange={(e) => handleChange(e)}
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
<Button onClick={(e: FormEvent<HTMLButtonElement>) => startSearch(e)}>
|
<Button onClick={(e: FormEvent<HTMLButtonElement>) => startSearch(e)}>
|
||||||
|
@ -42,13 +42,13 @@ export const SearchPriceFilter = () => {
|
|||||||
<PriceInput
|
<PriceInput
|
||||||
label="minPrice"
|
label="minPrice"
|
||||||
value={min}
|
value={min}
|
||||||
onChange={ev => setMin(ev.target.value)}
|
onChange={(ev) => setMin(ev.target.value)}
|
||||||
text="Min price"
|
text="Min price"
|
||||||
/>
|
/>
|
||||||
<PriceInput
|
<PriceInput
|
||||||
label="maxPrice"
|
label="maxPrice"
|
||||||
value={max}
|
value={max}
|
||||||
onChange={ev => setMax(ev.target.value)}
|
onChange={(ev) => setMax(ev.target.value)}
|
||||||
text="Max price"
|
text="Max price"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,7 +5,7 @@ import asset from '../../../tests/unit/__fixtures__/ddo'
|
|||||||
|
|
||||||
const queryResult = {
|
const queryResult = {
|
||||||
results: [asset, asset, asset, asset, asset, asset].map(
|
results: [asset, asset, asset, asset, asset, asset].map(
|
||||||
asset => new DDO(asset)
|
(asset) => new DDO(asset)
|
||||||
),
|
),
|
||||||
page: 1,
|
page: 1,
|
||||||
totalPages: 100,
|
totalPages: 100,
|
||||||
|
@ -40,7 +40,7 @@ const AssetList: React.FC<AssetListProps> = ({ queryResult }) => {
|
|||||||
<>
|
<>
|
||||||
<div className={styles.assetList}>
|
<div className={styles.assetList}>
|
||||||
{queryResult.results &&
|
{queryResult.results &&
|
||||||
queryResult.results.map(ddo => (
|
queryResult.results.map((ddo) => (
|
||||||
<AssetTeaser ddo={ddo} key={shortid.generate()} />
|
<AssetTeaser ddo={ddo} key={shortid.generate()} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
@ -74,7 +74,7 @@ export default function Compute({
|
|||||||
const comType = event.target.value
|
const comType = event.target.value
|
||||||
setComputeType(comType)
|
setComputeType(comType)
|
||||||
|
|
||||||
const selectedComputeOption = computeOptions.find(x => x.name === comType)
|
const selectedComputeOption = computeOptions.find((x) => x.name === comType)
|
||||||
if (selectedComputeOption !== undefined)
|
if (selectedComputeOption !== undefined)
|
||||||
setComputeContainer(selectedComputeOption.value)
|
setComputeContainer(selectedComputeOption.value)
|
||||||
}
|
}
|
||||||
@ -109,7 +109,7 @@ export default function Compute({
|
|||||||
label="Select image to run the algorithm"
|
label="Select image to run the algorithm"
|
||||||
placeholder=""
|
placeholder=""
|
||||||
value={computeType}
|
value={computeType}
|
||||||
options={computeOptions.map(x => x.name)}
|
options={computeOptions.map((x) => x.name)}
|
||||||
onChange={handleSelectChange}
|
onChange={handleSelectChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -57,7 +57,7 @@ export default function ConsumedList() {
|
|||||||
|
|
||||||
if (!consumedItems) return
|
if (!consumedItems) return
|
||||||
|
|
||||||
const data = consumedItems.map(ddo => {
|
const data = consumedItems.map((ddo) => {
|
||||||
const { attributes } = findServiceByType(ddo, 'metadata')
|
const { attributes } = findServiceByType(ddo, 'metadata')
|
||||||
const { name, price, datePublished } = attributes.main as MetaDataMain
|
const { name, price, datePublished } = attributes.main as MetaDataMain
|
||||||
return {
|
return {
|
||||||
|
@ -96,7 +96,7 @@ export default function JobsList() {
|
|||||||
try {
|
try {
|
||||||
const computeItems = await getComputeItems()
|
const computeItems = await getComputeItems()
|
||||||
if (!computeItems) return
|
if (!computeItems) return
|
||||||
const data = computeItems.map(item => {
|
const data = computeItems.map((item) => {
|
||||||
const { attributes } = findServiceByType(item.ddo, 'metadata')
|
const { attributes } = findServiceByType(item.ddo, 'metadata')
|
||||||
const { name, price } = attributes.main as MetaDataMain
|
const { name, price } = attributes.main as MetaDataMain
|
||||||
return {
|
return {
|
||||||
|
@ -73,7 +73,7 @@ export default function PublishedList() {
|
|||||||
count: publishedItems.totalPages
|
count: publishedItems.totalPages
|
||||||
})
|
})
|
||||||
|
|
||||||
const data = publishedItems.results.map(ddo => {
|
const data = publishedItems.results.map((ddo) => {
|
||||||
const { attributes } = findServiceByType(ddo, 'metadata')
|
const { attributes } = findServiceByType(ddo, 'metadata')
|
||||||
const { name, price, datePublished } = attributes.main as MetaDataMain
|
const { name, price, datePublished } = attributes.main as MetaDataMain
|
||||||
return {
|
return {
|
||||||
|
@ -46,7 +46,7 @@ const HomePage = () => {
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div className={styles.actions}>
|
<div className={styles.actions}>
|
||||||
{actions.map(action => (
|
{actions.map((action) => (
|
||||||
<Link key={shortid.generate()} href={action.link}>
|
<Link key={shortid.generate()} href={action.link}>
|
||||||
<a
|
<a
|
||||||
className={action.comingSoon ? styles.comingSoon : styles.action}
|
className={action.comingSoon ? styles.comingSoon : styles.action}
|
||||||
|
@ -38,7 +38,7 @@ const TransactionsPage: React.FC = () => {
|
|||||||
<Layout title={title} description={description}>
|
<Layout title={title} description={description}>
|
||||||
<article className={styles.grid}>
|
<article className={styles.grid}>
|
||||||
<div>
|
<div>
|
||||||
{sections.map(section => {
|
{sections.map((section) => {
|
||||||
const { title, component } = section
|
const { title, component } = section
|
||||||
return <Section key={title} title={title} component={component} />
|
return <Section key={title} title={title} component={component} />
|
||||||
})}
|
})}
|
||||||
|
@ -25,7 +25,7 @@ export default function MetaSecondary({
|
|||||||
title="Sample Data"
|
title="Sample Data"
|
||||||
content={
|
content={
|
||||||
<ul>
|
<ul>
|
||||||
{links?.map(link => (
|
{links?.map((link) => (
|
||||||
<ListItem key={shortid.generate()}>
|
<ListItem key={shortid.generate()}>
|
||||||
<a href={link.url}>{link.name}</a>
|
<a href={link.url}>{link.name}</a>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
@ -51,7 +51,7 @@ export default function MetaSecondary({
|
|||||||
title="Refund Policy"
|
title="Refund Policy"
|
||||||
content={
|
content={
|
||||||
<ul>
|
<ul>
|
||||||
{refundPolicy.map(item => (
|
{refundPolicy.map((item) => (
|
||||||
<ListItem key={shortid.generate()}>{item}</ListItem>
|
<ListItem key={shortid.generate()}>{item}</ListItem>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
@ -59,7 +59,7 @@ export default function MetaSecondary({
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{assetTerms.map(item => (
|
{assetTerms.map((item) => (
|
||||||
<MetaItem
|
<MetaItem
|
||||||
key={shortid.generate()}
|
key={shortid.generate()}
|
||||||
title={item.name}
|
title={item.name}
|
||||||
|
@ -34,7 +34,7 @@ export default function useCategoriesQueryParam(allCategories: string[]) {
|
|||||||
// Update url and the state with the selected categories
|
// Update url and the state with the selected categories
|
||||||
const toggleCategory = (category: string) => {
|
const toggleCategory = (category: string) => {
|
||||||
const newSelectedCategories = selectedCategories.includes(category)
|
const newSelectedCategories = selectedCategories.includes(category)
|
||||||
? selectedCategories.filter(c => c !== category)
|
? selectedCategories.filter((c) => c !== category)
|
||||||
: [...selectedCategories, category]
|
: [...selectedCategories, category]
|
||||||
setSelectedCategories(newSelectedCategories)
|
setSelectedCategories(newSelectedCategories)
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ const Explore: NextPage<{ queryResult: string }> = ({ queryResult }) => (
|
|||||||
<ExplorePage queryResult={JSON.parse(queryResult)} />
|
<ExplorePage queryResult={JSON.parse(queryResult)} />
|
||||||
)
|
)
|
||||||
|
|
||||||
export const getServerSideProps: GetServerSideProps = async context => {
|
export const getServerSideProps: GetServerSideProps = async (context) => {
|
||||||
const searchQuery = {
|
const searchQuery = {
|
||||||
offset: 15,
|
offset: 15,
|
||||||
page: Number(context.query.page) || 1,
|
page: Number(context.query.page) || 1,
|
||||||
|
@ -36,7 +36,7 @@ export function getSearchQuery(
|
|||||||
} as SearchQuery
|
} as SearchQuery
|
||||||
}
|
}
|
||||||
|
|
||||||
Search.getInitialProps = async context => {
|
Search.getInitialProps = async (context) => {
|
||||||
const { text, tag, page, offset, minPrice, maxPrice } = context.query
|
const { text, tag, page, offset, minPrice, maxPrice } = context.query
|
||||||
|
|
||||||
const minPriceParsed = priceQueryParamToWei(
|
const minPriceParsed = priceQueryParamToWei(
|
||||||
|
Before Width: | Height: | Size: 6.5 KiB After Width: | Height: | Size: 6.5 KiB |
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
29
tests/unit/__mocks__/gatsby.js
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/* eslint-disable no-unused-vars */
|
||||||
|
|
||||||
|
const React = require('react')
|
||||||
|
const gatsby = jest.requireActual('gatsby')
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
...gatsby,
|
||||||
|
graphql: jest.fn(),
|
||||||
|
Link: jest.fn().mockImplementation(
|
||||||
|
// these props are invalid for an `a` tag
|
||||||
|
({
|
||||||
|
activeClassName,
|
||||||
|
activeStyle,
|
||||||
|
getProps,
|
||||||
|
innerRef,
|
||||||
|
partiallyActive,
|
||||||
|
ref,
|
||||||
|
replace,
|
||||||
|
to,
|
||||||
|
...rest
|
||||||
|
}) =>
|
||||||
|
React.createElement('a', {
|
||||||
|
...rest,
|
||||||
|
href: to
|
||||||
|
})
|
||||||
|
),
|
||||||
|
StaticQuery: jest.fn(),
|
||||||
|
useStaticQuery: jest.fn()
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
export default Object.defineProperty(window, 'matchMedia', {
|
export default Object.defineProperty(window, 'matchMedia', {
|
||||||
writable: true,
|
writable: true,
|
||||||
value: jest.fn().mockImplementation(query => ({
|
value: jest.fn().mockImplementation((query) => ({
|
||||||
matches: false,
|
matches: false,
|
||||||
media: query,
|
media: query,
|
||||||
onchange: null,
|
onchange: null,
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
const Router = require('next/router')
|
|
||||||
|
|
||||||
Router.router = {
|
|
||||||
push: () => null,
|
|
||||||
prefetch: () => null,
|
|
||||||
asPath: '/hello',
|
|
||||||
events: {
|
|
||||||
on: () => null,
|
|
||||||
off: () => null
|
|
||||||
},
|
|
||||||
useRouter: () => {
|
|
||||||
return {
|
|
||||||
push: () => null,
|
|
||||||
prefetch: () => null,
|
|
||||||
asPath: '/hello',
|
|
||||||
events: {
|
|
||||||
on: () => null,
|
|
||||||
off: () => null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Router.router
|
|
@ -1 +1,6 @@
|
|||||||
module.exports = 'svg'
|
import React from 'react'
|
||||||
|
|
||||||
|
export default 'SvgrURL'
|
||||||
|
const SvgrMock = React.forwardRef((props, ref) => <span ref={ref} {...props} />)
|
||||||
|
|
||||||
|
export const ReactComponent = SvgrMock
|
||||||
|
4
tests/unit/babel.config.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
// this file only exists for Jest
|
||||||
|
module.exports = {
|
||||||
|
presets: ['babel-preset-gatsby', '@babel/preset-typescript']
|
||||||
|
}
|
@ -1,11 +1,7 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
rootDir: '../../',
|
rootDir: '../../',
|
||||||
preset: 'ts-jest/presets/js-with-ts',
|
transform: {
|
||||||
setupFilesAfterEnv: ['<rootDir>/tests/unit/setupTests.ts'],
|
'^.+\\.[jt]sx?$': ['babel-jest', { configFile: './jest/babel.config.js' }]
|
||||||
globals: {
|
|
||||||
'ts-jest': {
|
|
||||||
tsConfig: 'jest.tsconfig.json'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node', 'md'],
|
moduleFileExtensions: ['js', 'json', 'jsx', 'ts', 'tsx', 'node', 'md'],
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
@ -15,12 +11,13 @@ module.exports = {
|
|||||||
'\\.svg': '<rootDir>/tests/unit/__mocks__/svgrMock.js',
|
'\\.svg': '<rootDir>/tests/unit/__mocks__/svgrMock.js',
|
||||||
'next/router': '<rootDir>/tests/unit/__mocks__/nextRouter.js'
|
'next/router': '<rootDir>/tests/unit/__mocks__/nextRouter.js'
|
||||||
},
|
},
|
||||||
testPathIgnorePatterns: [
|
testPathIgnorePatterns: ['node_modules', '.cache', 'public', 'coverage'],
|
||||||
'<rootDir>/.next',
|
transformIgnorePatterns: ['node_modules/(?!(gatsby)/)'],
|
||||||
'<rootDir>/node_modules',
|
globals: {
|
||||||
'<rootDir>/build',
|
__PATH_PREFIX__: ''
|
||||||
'<rootDir>/coverage'
|
},
|
||||||
],
|
setupFiles: ['<rootDir>/tests/unit/loadershim.js'],
|
||||||
|
setupFilesAfterEnv: ['<rootDir>/tests/unit/setupTests.ts'],
|
||||||
collectCoverageFrom: [
|
collectCoverageFrom: [
|
||||||
'<rootDir>/src/**/*.{ts,tsx}',
|
'<rootDir>/src/**/*.{ts,tsx}',
|
||||||
'!<rootDir>/src/@types/**/*',
|
'!<rootDir>/src/@types/**/*',
|
||||||
|
3
tests/unit/loadershim.js
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
global.___loader = {
|
||||||
|
enqueue: jest.fn()
|
||||||
|
}
|
@ -7,7 +7,7 @@ import { DDO } from '@oceanprotocol/squid'
|
|||||||
const asset = new DDO(ddo)
|
const asset = new DDO(ddo)
|
||||||
const queryResult = {
|
const queryResult = {
|
||||||
results: [asset, asset, asset, asset, asset, asset].map(
|
results: [asset, asset, asset, asset, asset, asset].map(
|
||||||
asset => new DDO(asset)
|
(asset) => new DDO(asset)
|
||||||
),
|
),
|
||||||
page: 1,
|
page: 1,
|
||||||
totalPages: 100,
|
totalPages: 100,
|
||||||
|
@ -1,5 +1,9 @@
|
|||||||
import '@testing-library/jest-dom/extend-expect'
|
import '@testing-library/jest-dom/extend-expect'
|
||||||
|
|
||||||
|
if (typeof window.IntersectionObserver === 'undefined') {
|
||||||
|
import('intersection-observer')
|
||||||
|
}
|
||||||
|
|
||||||
beforeAll(() => {
|
beforeAll(() => {
|
||||||
require('./__mocks__/matchMedia')
|
require('./__mocks__/matchMedia')
|
||||||
jest.mock('web3')
|
jest.mock('web3')
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "esnext",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"module": "commonjs",
|
||||||
"allowJs": true,
|
"lib": ["dom", "es2017"],
|
||||||
"skipLibCheck": true,
|
|
||||||
"strict": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
|
||||||
"noEmit": true,
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"module": "esnext",
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"isolatedModules": true,
|
"jsx": "react",
|
||||||
"jsx": "preserve"
|
"esModuleInterop": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"skipLibCheck": true
|
||||||
},
|
},
|
||||||
"exclude": ["node_modules", ".next"],
|
"exclude": ["node_modules", "public", ".cache", "*.js"],
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
|
"include": ["./src/**/*", "./api/**/*", "./tests/**/*"]
|
||||||
}
|
}
|
||||||
|
23
vercel.json
@ -1,23 +1,4 @@
|
|||||||
{
|
{
|
||||||
"name": "market",
|
"cleanUrls": true,
|
||||||
"build": {
|
"trailingSlash": false
|
||||||
"env": {
|
|
||||||
"NODE_URI": "@node_uri",
|
|
||||||
"AQUARIUS_URI": "@aquarius_uri",
|
|
||||||
"BRIZO_URI": "@brizo_uri",
|
|
||||||
"BRIZO_ADDRESS": "@brizo_address",
|
|
||||||
"SECRET_STORE_URI": "@secret_store_uri",
|
|
||||||
"FAUCET_URI": "@faucet_uri",
|
|
||||||
"RATING_URI": "@rating_uri"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"env": {
|
|
||||||
"NODE_URI": "@node_uri",
|
|
||||||
"AQUARIUS_URI": "@aquarius_uri",
|
|
||||||
"BRIZO_URI": "@brizo_uri",
|
|
||||||
"BRIZO_ADDRESS": "@brizo_address",
|
|
||||||
"SECRET_STORE_URI": "@secret_store_uri",
|
|
||||||
"FAUCET_URI": "@faucet_uri",
|
|
||||||
"RATING_URI": "@rating_uri"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|