move to Next.js

This commit is contained in:
Matthias Kretschmann 2019-10-16 22:10:03 +02:00
parent 85a8214afc
commit e3623d00ae
Signed by: m
GPG Key ID: 606EEEF3C479A91F
17 changed files with 98 additions and 148 deletions

5
.gitignore vendored
View File

@ -1,6 +1,7 @@
node_modules
npm-debug.log
.DS_Store
dist
public
/.next/
/out/
/build
package-lock.json

View File

@ -8,7 +8,7 @@
[![Build Status](https://travis-ci.com/oceanprotocol/ipfs.svg?branch=master)](https://travis-ci.com/oceanprotocol/ipfs)
[![js oceanprotocol](https://img.shields.io/badge/js-oceanprotocol-7b1173.svg)](https://github.com/oceanprotocol/eslint-config-oceanprotocol)
This repo holds a simple React app built with Webpack serving as the frontpage of [ipfs.oceanprotocol.com](https://ipfs.oceanprotocol.com) from where you can add files to IPFS via drag and drop.
This repo holds a simple React app built with [Next.js](https://nextjs.org) serving as the frontpage of [ipfs.oceanprotocol.com](https://ipfs.oceanprotocol.com) from where you can add files to IPFS via drag and drop.
General IPFS integration within the Ocean Protocol stack is outlined in [OEP-15: Distributed Asset File Storage with IPFS](https://github.com/oceanprotocol/OEPs/tree/master/15).
@ -32,7 +32,7 @@ npm i
npm start
```
Will start a live-reloading local server, reachable under [localhost:8080](http://localhost:8080).
Will start a live-reloading local server, reachable under [localhost:3000](http://localhost:3000).
## Production

35
next.config.js Normal file
View File

@ -0,0 +1,35 @@
const withCSS = require('@zeit/next-css')
const withSvgr = (nextConfig = {}, nextComposePlugins = {}) => {
return Object.assign({}, 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
}
})
}
module.exports = withSvgr(
withCSS({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: '[local]___[hash:base64:5]'
}
})
)

View File

@ -3,8 +3,9 @@
"version": "1.0.0",
"description": "Ocean Protocol's Public IPFS Node.",
"scripts": {
"start": "webpack-dev-server",
"build": "NODE_ENV=production webpack",
"start": "next dev",
"build": "next build",
"server": "next start",
"test": "eslint ./src/**/*.{js,jsx}",
"format": "prettier ./src/**/*.{css,yml,js,jsx,json} --write"
},
@ -13,32 +14,21 @@
"dependencies": {
"@oceanprotocol/art": "^2.2.0",
"@oceanprotocol/typographies": "^0.1.0",
"@zeit/next-css": "^1.0.1",
"ipfs-http-client": "^38.2.0",
"next": "9.1.1",
"next-svgr": "0.0.2",
"react": "^16.10.2",
"react-dom": "^16.10.2",
"react-dropzone": "^10.1.10"
},
"devDependencies": {
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-class-properties": "^7.5.5",
"@babel/polyfill": "^7.6.0",
"@babel/preset-env": "^7.6.3",
"@babel/preset-react": "^7.6.3",
"@svgr/webpack": "^4.3.3",
"babel-loader": "^8.0.6",
"copy-webpack-plugin": "^5.0.4",
"css-loader": "^3.2.0",
"eslint": "^6.5.1",
"eslint-config-oceanprotocol": "^1.5.0",
"eslint-config-prettier": "^6.4.0",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-react": "^7.16.0",
"mini-css-extract-plugin": "^0.8.0",
"prettier": "^1.18.2",
"style-loader": "^1.0.0",
"webpack": "^4.41.2",
"webpack-cli": "^3.3.9",
"webpack-dev-server": "^3.8.2"
"prettier": "^1.18.2"
},
"eslintConfig": {
"extends": [

View File

@ -1,26 +0,0 @@
import '@babel/polyfill'
import React from 'react'
import './styles/global.css'
import './App.css'
import Add from './components/Add'
import Logo from '@oceanprotocol/art/logo/logo-white.svg'
import { title, description } from '../config'
import Footer from './components/Footer'
export default function App() {
return (
<div className="app">
<header className="header">
<Logo className="logo" />
<h1 className="appTitle">{title}</h1>
<p
className="appDescription"
dangerouslySetInnerHTML={{ __html: description }}
/>
</header>
<Add />
<Footer />
</div>
)
}

View File

@ -2,7 +2,7 @@ import React, { useState } from 'react'
import { saveToIpfs } from '../ipfs'
import { ipfsGateway } from '../../config'
import Dropzone from './Dropzone'
import './Add.css'
import styles from './Add.css'
import Spinner from './Spinner'
export default function Add() {
@ -17,7 +17,7 @@ export default function Add() {
}
return (
<div className="add">
<div className={styles.add}>
{loading ? (
<Spinner />
) : fileHash ? (

View File

@ -15,11 +15,13 @@
outline: 0;
}
.dropzone.dragover {
.dragover {
composes: dropzone;
border-color: var(--brand-pink);
}
.dropzone.disabled {
.disabled {
composes: dropzone;
opacity: 0.5;
pointer-events: none;
}

View File

@ -1,7 +1,7 @@
import React, { useCallback } from 'react'
import PropTypes from 'prop-types'
import { useDropzone } from 'react-dropzone'
import './Dropzone.css'
import styles from './Dropzone.css'
Dropzone.propTypes = {
handleOnDrop: PropTypes.func.isRequired,
@ -25,10 +25,10 @@ export default function Dropzone({ handleOnDrop, disabled, multiple }) {
<div
{...getRootProps({
className: isDragActive
? 'dragover'
? styles.dragover
: disabled
? 'disabled'
: 'dropzone'
? styles.disabled
: styles.dropzone
})}
>
<input {...getInputProps({ multiple })} />

View File

@ -1,12 +1,14 @@
import React from 'react'
import { links } from '../../config'
import './Footer.css'
import styles from './Footer.css'
export default function Footer() {
const year = new Date().getFullYear()
return (
<footer className="footer">
<footer className={styles.footer}>
<div>
© <span id="year">{Date.now()}</span>{' '}
© <span id="year">{year}</span>{' '}
<a href="https://oceanprotocol.com">Ocean Protocol Foundation Ltd.</a>
All Rights Reserved
</div>

View File

@ -1,6 +1,6 @@
import React from 'react'
import './Spinner.css'
import styles from './Spinner.css'
export default function Spinner() {
return <div className="spinner" />
return <div className={styles.spinner} />
}

View File

@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Ocean Protocol 💖 IPFS</title>
</head>
<body>
<div id="root"></div>
<script src="/bundle.js"></script>
</body>
</html>

View File

@ -1,5 +0,0 @@
import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
ReactDOM.render(<App />, document.getElementById('root'))

View File

@ -1,4 +1,4 @@
@import 'styles/_variables.css';
@import '../styles/_variables.css';
.app {
padding: var(--spacer);

33
src/pages/index.js Normal file
View File

@ -0,0 +1,33 @@
import React from 'react'
import Head from 'next/head'
import '@oceanprotocol/typographies/css/ocean-typo.css'
import '../styles/global.css'
import styles from './index.css'
import Add from '../components/Add'
import Logo from '@oceanprotocol/art/logo/logo-white.svg'
import { title, description } from '../../config'
import Footer from '../components/Footer'
const Home = () => (
<div className={styles.app}>
<Head>
<title>Ocean Protocol 💖 IPFS</title>
<link rel="icon" href="/favicon.ico" />
</Head>
<header className={styles.header}>
<Logo className={styles.logo} />
<h1 className={styles.appTitle}>{title}</h1>
<p
className={styles.appDescription}
dangerouslySetInnerHTML={{ __html: description }}
/>
</header>
<Add />
<Footer />
</div>
)
export default Home

BIN
src/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@ -1,4 +1,3 @@
@import '../../node_modules/@oceanprotocol/typographies/css/ocean-typo.css';
@import '_variables.css';
html,

View File

@ -1,68 +0,0 @@
const path = require('path')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const CopyPlugin = require('copy-webpack-plugin')
const defaultInclude = [path.resolve(__dirname, 'src')]
const isDevelopment = process.env.NODE_ENV !== 'production'
module.exports = {
mode: isDevelopment ? 'development' : 'production',
entry: path.resolve(__dirname, 'src', 'index.js'),
output: {
path: path.resolve(__dirname, 'public'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
include: defaultInclude,
use: [
{
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: ['@babel/plugin-proposal-class-properties']
}
}
]
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
include: defaultInclude
},
{
test: /\.(jpe?g|png|gif)$/,
use: ['file-loader?name=img/[name]__[hash:base64:5].[ext]'],
include: defaultInclude
},
{
test: /\.svg$/,
use: [
{
loader: '@svgr/webpack',
options: {
icon: true
}
}
]
}
]
},
resolve: {
extensions: ['*', '.js', '.jsx']
},
node: {
fs: 'empty',
net: 'empty',
tls: 'empty'
},
plugins: [
new MiniCssExtractPlugin({
filename: isDevelopment ? '[name].css' : '[name].[hash].css',
chunkFilename: isDevelopment ? '[id].css' : '[id].[hash].css'
}),
new CopyPlugin([{ from: './src/index.html', to: './', flatten: true }])
]
}